diff --git a/.gitmodules b/.gitmodules index 9cfc2efcd..bba7461f2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "Paper"] path = Paper url = https://github.com/PaperMC/Paper.git - branch = master + branch = ver/1.16 diff --git a/Paper b/Paper index a8ffecc74..d70195264 160000 --- a/Paper +++ b/Paper @@ -1 +1 @@ -Subproject commit a8ffecc741cd6aed770f7cce5309d0f6d2972e02 +Subproject commit d7019526454474a87111615800eb7af940c02a3a diff --git a/current-paper b/current-paper index f499469a2..dc7a25b0a 100644 --- a/current-paper +++ b/current-paper @@ -1 +1 @@ -1.15.2--90b89764e0f3941479dd66cc0184fd7291f302d4 +1.16.1--36526ee48c0bdbd573e11af2c13fe11141223723 diff --git a/patches/api/0002-Rebrand.patch b/patches/api/0001-Rebrand.patch similarity index 65% rename from patches/api/0002-Rebrand.patch rename to patches/api/0001-Rebrand.patch index fd04e9486..50fbcdea7 100644 --- a/patches/api/0002-Rebrand.patch +++ b/patches/api/0001-Rebrand.patch @@ -1,41 +1,41 @@ -From e03b6ebdad870f7d6c849061daed7f715e496918 Mon Sep 17 00:00:00 2001 +From 236214ae05f55fc6ae1305edf2eb85b1bcc5af66 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 4 May 2019 00:57:16 -0500 Subject: [PATCH] Rebrand --- - pom.xml | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) + pom.xml | 13 ++++++------- + 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml -index a2387a667..c4b9414fb 100644 +index dfc7c2f35..cb2dea442 100644 --- a/pom.xml +++ b/pom.xml -@@ -3,18 +3,18 @@ +@@ -3,18 +3,17 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 -- com.tuinity -- tuinity-parent +- com.destroystokyo.paper +- paper-parent + net.pl3x.purpur + purpur-parent dev-SNAPSHOT - ../pom.xml -- tuinity-api +- com.destroystokyo.paper +- paper-api + purpur-api - 1.15.2-R0.1-SNAPSHOT + 1.16.1-R0.1-SNAPSHOT jar -- Tuinity-API -- https://github.com/Spottedleaf/Tuinity +- Paper-API +- https://github.com/PaperMC/Paper + Purpur-API + https://github.com/pl3xgaming/Purpur An enhanced plugin API for Minecraft servers. -@@ -149,7 +149,7 @@ +@@ -149,7 +148,7 @@ diff --git a/patches/api/0001-Tuinity-API-Changes.patch b/patches/api/0001-Tuinity-API-Changes.patch deleted file mode 100644 index fc0502712..000000000 --- a/patches/api/0001-Tuinity-API-Changes.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 77e67dca85182e9899eba3e4065cabbe4e072e0d Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Fri, 14 Dec 2018 21:52:29 -0800 -Subject: [PATCH] Tuinity API Changes - ---- - pom.xml | 12 ++++++------ - src/main/java/org/bukkit/Server.java | 8 ++++++++ - 2 files changed, 14 insertions(+), 6 deletions(-) - -diff --git a/pom.xml b/pom.xml -index 20c473f52..a2387a667 100644 ---- a/pom.xml -+++ b/pom.xml -@@ -3,18 +3,18 @@ - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - 4.0.0 - -- com.destroystokyo.paper -- paper-parent -+ com.tuinity -+ tuinity-parent - dev-SNAPSHOT -+ ../pom.xml - - -- com.destroystokyo.paper -- paper-api -+ tuinity-api - 1.15.2-R0.1-SNAPSHOT - jar - -- Paper-API -- https://github.com/PaperMC/Paper -+ Tuinity-API -+ https://github.com/Spottedleaf/Tuinity - An enhanced plugin API for Minecraft servers. - - -diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index cc06492f4..cf20e7541 100644 ---- a/src/main/java/org/bukkit/Server.java -+++ b/src/main/java/org/bukkit/Server.java -@@ -1396,6 +1396,14 @@ public interface Server extends PluginMessageRecipient { - } - // Paper end - -+ // Tuinity start - add config to timings report -+ @NotNull -+ public org.bukkit.configuration.file.YamlConfiguration getTuinityConfig() -+ { -+ throw new UnsupportedOperationException("Not supported yet."); -+ } -+ // Tuinity end - add config to timings report -+ - /** - * Sends the component to the player - * --- -2.26.2 - diff --git a/patches/api/0003-Purpur-config-files.patch b/patches/api/0002-Purpur-config-files.patch similarity index 81% rename from patches/api/0003-Purpur-config-files.patch rename to patches/api/0002-Purpur-config-files.patch index d7f330843..9817d6a9e 100644 --- a/patches/api/0003-Purpur-config-files.patch +++ b/patches/api/0002-Purpur-config-files.patch @@ -1,4 +1,4 @@ -From bc7ef0c8f2a4e9310cac260ba83bd2534a77d49f Mon Sep 17 00:00:00 2001 +From 207d7356ada158abb9151799b2c290cef7e465d0 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Tue, 18 Feb 2020 20:30:03 -0600 Subject: [PATCH] Purpur config files @@ -8,12 +8,12 @@ Subject: [PATCH] Purpur config files 1 file changed, 12 insertions(+) diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index cf20e7541..ab1d082a4 100644 +index b464cc1a7..1a05a438c 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -1404,6 +1404,18 @@ public interface Server extends PluginMessageRecipient { +@@ -1424,6 +1424,18 @@ public interface Server extends PluginMessageRecipient { } - // Tuinity end - add config to timings report + // Paper end + // Purpur start + @NotNull diff --git a/patches/api/0004-Default-permissions.patch b/patches/api/0003-Default-permissions.patch similarity index 82% rename from patches/api/0004-Default-permissions.patch rename to patches/api/0003-Default-permissions.patch index a3b55e079..eea456ab4 100644 --- a/patches/api/0004-Default-permissions.patch +++ b/patches/api/0003-Default-permissions.patch @@ -1,4 +1,4 @@ -From 465547cca4e6f15f94abbc98fa5dbf0a5f7d2447 Mon Sep 17 00:00:00 2001 +From 77cf864ad36201a94e3c8ac0535064c98e5c175a Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Fri, 5 Jun 2020 23:32:38 -0500 Subject: [PATCH] Default permissions @@ -6,8 +6,8 @@ Subject: [PATCH] Default permissions --- .../util/permissions/CommandPermissions.java | 1 + .../util/permissions/DefaultPermissions.java | 2 + - .../util/permissions/PurpurPermissions.java | 62 +++++++++++++++++++ - 3 files changed, 65 insertions(+) + .../util/permissions/PurpurPermissions.java | 69 +++++++++++++++++++ + 3 files changed, 72 insertions(+) create mode 100644 src/main/java/org/bukkit/util/permissions/PurpurPermissions.java diff --git a/src/main/java/org/bukkit/util/permissions/CommandPermissions.java b/src/main/java/org/bukkit/util/permissions/CommandPermissions.java @@ -37,10 +37,10 @@ index e1a4ddf2c..8e481e381 100644 } diff --git a/src/main/java/org/bukkit/util/permissions/PurpurPermissions.java b/src/main/java/org/bukkit/util/permissions/PurpurPermissions.java new file mode 100644 -index 000000000..64fdd9230 +index 000000000..14cb78e3e --- /dev/null +++ b/src/main/java/org/bukkit/util/permissions/PurpurPermissions.java -@@ -0,0 +1,62 @@ +@@ -0,0 +1,69 @@ +package org.bukkit.util.permissions; + +import org.bukkit.entity.Entity; @@ -71,6 +71,13 @@ index 000000000..64fdd9230 + public static Permission registerPermissions() { + Permission purpur = DefaultPermissions.registerPermission(ROOT, "Gives the user the ability to use all Purpur utilities and commands"); + ++ DefaultPermissions.registerPermission(PREFIX + "enderchest.rows.six", "Gives the user six rows of enderchest space", org.bukkit.permissions.PermissionDefault.FALSE); ++ DefaultPermissions.registerPermission(PREFIX + "enderchest.rows.five", "Gives the user five rows of enderchest space", org.bukkit.permissions.PermissionDefault.FALSE); ++ DefaultPermissions.registerPermission(PREFIX + "enderchest.rows.four", "Gives the user four rows of enderchest space", org.bukkit.permissions.PermissionDefault.FALSE); ++ DefaultPermissions.registerPermission(PREFIX + "enderchest.rows.three", "Gives the user three rows of enderchest space", org.bukkit.permissions.PermissionDefault.FALSE); ++ DefaultPermissions.registerPermission(PREFIX + "enderchest.rows.two", "Gives the user two rows of enderchest space", org.bukkit.permissions.PermissionDefault.FALSE); ++ DefaultPermissions.registerPermission(PREFIX + "enderchest.rows.one", "Gives the user one row of enderchest space", org.bukkit.permissions.PermissionDefault.FALSE); ++ + DefaultPermissions.registerPermission(PREFIX + "debug.f3n", "Allows the user to use F3+N keybind to swap gamemodes", PermissionDefault.FALSE, purpur); + + DefaultPermissions.registerPermission(PREFIX + "drop.spawner", "Allows the user to drop spawner cage when broken with diamond pickaxe with silk touch", PermissionDefault.FALSE, purpur); diff --git a/patches/api/0007-Allow-inventory-resizing.patch b/patches/api/0004-Allow-inventory-resizing.patch similarity index 83% rename from patches/api/0007-Allow-inventory-resizing.patch rename to patches/api/0004-Allow-inventory-resizing.patch index e77a9bb43..132d2ef12 100644 --- a/patches/api/0007-Allow-inventory-resizing.patch +++ b/patches/api/0004-Allow-inventory-resizing.patch @@ -1,4 +1,4 @@ -From b188d7fb384b09a447261d6efcf8c65258799677 Mon Sep 17 00:00:00 2001 +From 683682367df0d1ec0605b5d75398d9a3f096ca2a Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Tue, 23 Jul 2019 06:50:55 -0500 Subject: [PATCH] Allow inventory resizing @@ -8,10 +8,10 @@ Subject: [PATCH] Allow inventory resizing 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/bukkit/event/inventory/InventoryType.java b/src/main/java/org/bukkit/event/inventory/InventoryType.java -index 10c3b6d75..931e5ff7b 100644 +index b59fec1ae..e3b77f565 100644 --- a/src/main/java/org/bukkit/event/inventory/InventoryType.java +++ b/src/main/java/org/bukkit/event/inventory/InventoryType.java -@@ -128,7 +128,7 @@ public enum InventoryType { +@@ -132,7 +132,7 @@ public enum InventoryType { STONECUTTER(2, "Stonecutter") ; @@ -20,7 +20,7 @@ index 10c3b6d75..931e5ff7b 100644 private final String title; private final boolean isCreatable; -@@ -142,6 +142,12 @@ public enum InventoryType { +@@ -146,6 +146,12 @@ public enum InventoryType { this.isCreatable = isCreatable; } diff --git a/patches/api/0015-Advancement-API-Additions.patch b/patches/api/0005-Advancement-API.patch similarity index 97% rename from patches/api/0015-Advancement-API-Additions.patch rename to patches/api/0005-Advancement-API.patch index 04af388e9..0db098970 100644 --- a/patches/api/0015-Advancement-API-Additions.patch +++ b/patches/api/0005-Advancement-API.patch @@ -1,7 +1,7 @@ -From a05e6fbef6eb46c46f84a91c09731a0d28ad8c2e Mon Sep 17 00:00:00 2001 +From c43598530aeb734560bda5aa9e33ba4ecc18ed2a Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Fri, 31 May 2019 21:24:21 -0500 -Subject: [PATCH] Advancement API Additions +Subject: [PATCH] Advancement API --- .../org/bukkit/advancement/Advancement.java | 9 ++++ diff --git a/patches/api/0005-Ridables.patch b/patches/api/0005-Ridables.patch deleted file mode 100644 index fe054cda4..000000000 --- a/patches/api/0005-Ridables.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 0c20fdc1cc34d29b9135326be5db514107bb6766 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sat, 4 May 2019 00:57:16 -0500 -Subject: [PATCH] Ridables - ---- - .../paper/entity/ai/VanillaGoal.java | 4 ++ - .../event/entity/RidableSpacebarEvent.java | 37 ++++++++++++++++++ - src/main/java/org/bukkit/entity/Entity.java | 38 +++++++++++++++++++ - 3 files changed, 79 insertions(+) - create mode 100644 src/main/java/net/pl3x/purpur/event/entity/RidableSpacebarEvent.java - -diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java -index d23ad96ee..36d37e9a3 100644 ---- a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java -+++ b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java -@@ -154,6 +154,10 @@ public interface VanillaGoal extends Goal { - GoalKey FOLLOW_ENTITY = GoalKey.of(Mob.class, NamespacedKey.minecraft("follow_entity")); - GoalKey FOLLOW_OWNER = GoalKey.of(Tameable.class, NamespacedKey.minecraft("follow_owner")); - GoalKey FOLLOW_PARENT = GoalKey.of(Animals.class, NamespacedKey.minecraft("follow_parent")); -+ // Purpur start -+ GoalKey FIND_CRYSTAL_GOAL = GoalKey.of(Phantom.class, NamespacedKey.minecraft("find_crystal_goal")); -+ GoalKey ORBIT_CRYSTAL_GOAL = GoalKey.of(Phantom.class, NamespacedKey.minecraft("orbit_crystal_goal")); -+ // Purpur end - GoalKey HORSE_TRAP = GoalKey.of(SkeletonHorse.class, NamespacedKey.minecraft("horse_trap")); - GoalKey HURT_BY_TARGET = GoalKey.of(Creature.class, NamespacedKey.minecraft("hurt_by_target")); - GoalKey INTERACT = GoalKey.of(Mob.class, NamespacedKey.minecraft("interact")); -diff --git a/src/main/java/net/pl3x/purpur/event/entity/RidableSpacebarEvent.java b/src/main/java/net/pl3x/purpur/event/entity/RidableSpacebarEvent.java -new file mode 100644 -index 000000000..c0ec5a130 ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/event/entity/RidableSpacebarEvent.java -@@ -0,0 +1,37 @@ -+package net.pl3x.purpur.event.entity; -+ -+import org.bukkit.entity.Entity; -+import org.bukkit.event.Cancellable; -+import org.bukkit.event.HandlerList; -+import org.bukkit.event.entity.EntityEvent; -+import org.jetbrains.annotations.NotNull; -+ -+public class RidableSpacebarEvent extends EntityEvent implements Cancellable { -+ private static final HandlerList handlers = new HandlerList(); -+ private boolean cancelled; -+ -+ public RidableSpacebarEvent(@NotNull Entity entity) { -+ super(entity); -+ } -+ -+ @Override -+ public boolean isCancelled() { -+ return cancelled; -+ } -+ -+ @Override -+ public void setCancelled(boolean cancel) { -+ cancelled = cancel; -+ } -+ -+ @Override -+ @NotNull -+ public HandlerList getHandlers() { -+ return handlers; -+ } -+ -+ @NotNull -+ public static HandlerList getHandlerList() { -+ return handlers; -+ } -+} -diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java -index 3f0f38031..25372c58b 100644 ---- a/src/main/java/org/bukkit/entity/Entity.java -+++ b/src/main/java/org/bukkit/entity/Entity.java -@@ -659,4 +659,42 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent - @NotNull - org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason getEntitySpawnReason(); - // Paper end -+ -+ // Purpur start -+ /** -+ * Get the riding player -+ * -+ * @return Riding player -+ */ -+ @Nullable -+ Player getRider(); -+ -+ /** -+ * Check if entity is being ridden -+ * -+ * @return True if being ridden -+ */ -+ boolean hasRider(); -+ -+ /** -+ * Check if entity is ridable -+ * -+ * @return True if ridable -+ */ -+ boolean isRidable(); -+ -+ /** -+ * Check if entity is ridable in water -+ * -+ * @return True if ridable in water -+ */ -+ boolean isRidableInWater(); -+ -+ /** -+ * Check if shift is required to mount this entity -+ * -+ * @return True if shift is required -+ */ -+ boolean requireShiftToMount(); -+ // Purpur end - } --- -2.26.2 - diff --git a/patches/api/0022-Add-more-llama-API.patch b/patches/api/0006-Llama-API.patch similarity index 98% rename from patches/api/0022-Add-more-llama-API.patch rename to patches/api/0006-Llama-API.patch index 3ab91907c..8ec68ac13 100644 --- a/patches/api/0022-Add-more-llama-API.patch +++ b/patches/api/0006-Llama-API.patch @@ -1,7 +1,7 @@ -From db2a7cb27f0b3422bfd8f786c8eb23ad55fc198c Mon Sep 17 00:00:00 2001 +From 3efaae899100095ab241d17882103707e439d625 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Fri, 18 Oct 2019 22:50:05 -0500 -Subject: [PATCH] Add more llama API +Subject: [PATCH] Llama API --- .../event/entity/LlamaJoinCaravanEvent.java | 61 ++++++++++++++++++ diff --git a/patches/api/0006-Remove-pointless-annotations-and-deprecations.patch b/patches/api/0006-Remove-pointless-annotations-and-deprecations.patch deleted file mode 100644 index 94bbf8116..000000000 --- a/patches/api/0006-Remove-pointless-annotations-and-deprecations.patch +++ /dev/null @@ -1,142 +0,0 @@ -From acabe1261f9db72988a29d0d72ee138b7c0cf221 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Tue, 31 Dec 2019 23:00:07 -0600 -Subject: [PATCH] Remove pointless annotations and deprecations - ---- - src/main/java/org/bukkit/Bukkit.java | 3 --- - src/main/java/org/bukkit/Server.java | 3 --- - src/main/java/org/bukkit/command/CommandExecutor.java | 2 +- - src/main/java/org/bukkit/command/TabCompleter.java | 2 +- - src/main/java/org/bukkit/inventory/ItemStack.java | 8 -------- - src/main/java/org/bukkit/plugin/java/JavaPlugin.java | 4 ++-- - src/test/java/org/bukkit/AnnotationTest.java | 5 +++++ - 7 files changed, 9 insertions(+), 18 deletions(-) - -diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index a9c10228e..780d603e4 100644 ---- a/src/main/java/org/bukkit/Bukkit.java -+++ b/src/main/java/org/bukkit/Bukkit.java -@@ -863,13 +863,10 @@ public final class Bukkit { - * This will return an object even if the player does not exist. To this - * method, all players will exist. - * -- * @deprecated Persistent storage of users should be by UUID as names are no longer -- * unique past a single session. - * @param name the name the player to retrieve - * @return an offline player - * @see #getOfflinePlayer(java.util.UUID) - */ -- @Deprecated - @NotNull - public static OfflinePlayer getOfflinePlayer(@NotNull String name) { - return server.getOfflinePlayer(name); -diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index ab1d082a4..a4cf71fb4 100644 ---- a/src/main/java/org/bukkit/Server.java -+++ b/src/main/java/org/bukkit/Server.java -@@ -722,13 +722,10 @@ public interface Server extends PluginMessageRecipient { - * This will return an object even if the player does not exist. To this - * method, all players will exist. - * -- * @deprecated Persistent storage of users should be by UUID as names are no longer -- * unique past a single session. - * @param name the name the player to retrieve - * @return an offline player - * @see #getOfflinePlayer(java.util.UUID) - */ -- @Deprecated - @NotNull - public OfflinePlayer getOfflinePlayer(@NotNull String name); - -diff --git a/src/main/java/org/bukkit/command/CommandExecutor.java b/src/main/java/org/bukkit/command/CommandExecutor.java -index 45cb8da12..383b43e1b 100644 ---- a/src/main/java/org/bukkit/command/CommandExecutor.java -+++ b/src/main/java/org/bukkit/command/CommandExecutor.java -@@ -19,5 +19,5 @@ public interface CommandExecutor { - * @param args Passed command arguments - * @return true if a valid command, otherwise false - */ -- public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args); -+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args); // Purpur - remove pointless annotations - } -diff --git a/src/main/java/org/bukkit/command/TabCompleter.java b/src/main/java/org/bukkit/command/TabCompleter.java -index e9cf71f5c..34d3462c7 100644 ---- a/src/main/java/org/bukkit/command/TabCompleter.java -+++ b/src/main/java/org/bukkit/command/TabCompleter.java -@@ -23,5 +23,5 @@ public interface TabCompleter { - * to default to the command executor - */ - @Nullable -- public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args); -+ public List onTabComplete(CommandSender sender, Command command, String alias, String[] args); // Purpur - remove pointless annotations - } -diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index ccd81fca2..a8ade268c 100644 ---- a/src/main/java/org/bukkit/inventory/ItemStack.java -+++ b/src/main/java/org/bukkit/inventory/ItemStack.java -@@ -204,13 +204,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable { - * Sets the durability of this item - * - * @param durability Durability of this item -- * @deprecated durability is now part of ItemMeta. To avoid confusion and -- * misuse, {@link #getItemMeta()}, {@link #setItemMeta(ItemMeta)} and -- * {@link Damageable#setDamage(int)} should be used instead. This is because -- * any call to this method will be overwritten by subsequent setting of -- * ItemMeta which was created before this call. - */ -- @Deprecated - public void setDurability(final short durability) { - ItemMeta meta = getItemMeta(); - if (meta != null) { -@@ -223,9 +217,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable { - * Gets the durability of this item - * - * @return Durability of this item -- * @deprecated see {@link #setDurability(short)} - */ -- @Deprecated - public short getDurability() { - ItemMeta meta = getItemMeta(); - return (meta == null) ? 0 : (short) ((Damageable) meta).getDamage(); -diff --git a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java -index 04fa3991f..24d65491c 100644 ---- a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java -+++ b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java -@@ -287,7 +287,7 @@ public abstract class JavaPlugin extends PluginBase { - * {@inheritDoc} - */ - @Override -- public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { -+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { // Purpur - remove pointless annotations - return false; - } - -@@ -296,7 +296,7 @@ public abstract class JavaPlugin extends PluginBase { - */ - @Override - @Nullable -- public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) { -+ public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { // Purpur - remove pointless annotations - return null; - } - -diff --git a/src/test/java/org/bukkit/AnnotationTest.java b/src/test/java/org/bukkit/AnnotationTest.java -index a48be38b1..951b81e79 100644 ---- a/src/test/java/org/bukkit/AnnotationTest.java -+++ b/src/test/java/org/bukkit/AnnotationTest.java -@@ -41,6 +41,11 @@ public class AnnotationTest { - "org/bukkit/plugin/java/PluginClassLoader", - // Generic functional interface - "org/bukkit/util/Consumer", -+ // Purpur start -+ "org/bukkit/command/CommandExecutor", -+ "org/bukkit/command/TabCompleter", -+ "org/bukkit/plugin/java/JavaPlugin", -+ // Purpur end - // Paper start - // Timings history is broken in terms of nullability due to guavas Function defining that the param is NonNull - "co/aikar/timings/TimingHistory$2", --- -2.26.2 - diff --git a/patches/api/0023-Add-more-evoker-API.patch b/patches/api/0007-Evoker-API.patch similarity index 90% rename from patches/api/0023-Add-more-evoker-API.patch rename to patches/api/0007-Evoker-API.patch index 677674216..3facccd62 100644 --- a/patches/api/0023-Add-more-evoker-API.patch +++ b/patches/api/0007-Evoker-API.patch @@ -1,7 +1,7 @@ -From f6443249943ce18e3d4b7379852b7aadf34262a7 Mon Sep 17 00:00:00 2001 +From bbc865bdfdd716cc526fbd7cc57e6eb0841d9926 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 19 Oct 2019 00:28:53 -0500 -Subject: [PATCH] Add more evoker API +Subject: [PATCH] Evoker API --- src/main/java/org/bukkit/entity/Evoker.java | 17 +++++++++++++++++ diff --git a/patches/api/0008-Implement-AFK-API.patch b/patches/api/0008-AFK-API.patch similarity index 94% rename from patches/api/0008-Implement-AFK-API.patch rename to patches/api/0008-AFK-API.patch index 577dc4095..62f9099f4 100644 --- a/patches/api/0008-Implement-AFK-API.patch +++ b/patches/api/0008-AFK-API.patch @@ -1,7 +1,7 @@ -From d94af99f8daf2617cad173e2a3f6400b213e5ae1 Mon Sep 17 00:00:00 2001 +From b01aba9c3138bfcde84036b1fbed0ec910617913 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 10 Aug 2019 22:19:56 -0500 -Subject: [PATCH] Implement AFK API +Subject: [PATCH] AFK API --- .../net/pl3x/purpur/event/PlayerAFKEvent.java | 70 +++++++++++++++++++ @@ -86,10 +86,10 @@ index 000000000..0c8b3e5e4 + } +} diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 787bb144b..edc481170 100644 +index 2eb312138..2dca16ac4 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -1830,4 +1830,25 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1870,4 +1870,25 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM @Override Spigot spigot(); // Spigot end diff --git a/patches/api/0009-Add-EntityPortalReadyEvent.patch b/patches/api/0009-Add-EntityPortalReadyEvent.patch deleted file mode 100644 index 36ad3cc3d..000000000 --- a/patches/api/0009-Add-EntityPortalReadyEvent.patch +++ /dev/null @@ -1,59 +0,0 @@ -From e503ea72858416dd97bd79c5aae85a2834f11195 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sat, 11 Jan 2020 23:12:00 -0600 -Subject: [PATCH] Add EntityPortalReadyEvent - ---- - .../event/entity/EntityPortalReadyEvent.java | 40 +++++++++++++++++++ - 1 file changed, 40 insertions(+) - create mode 100644 src/main/java/net/pl3x/purpur/event/entity/EntityPortalReadyEvent.java - -diff --git a/src/main/java/net/pl3x/purpur/event/entity/EntityPortalReadyEvent.java b/src/main/java/net/pl3x/purpur/event/entity/EntityPortalReadyEvent.java -new file mode 100644 -index 000000000..37f11c104 ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/event/entity/EntityPortalReadyEvent.java -@@ -0,0 +1,40 @@ -+package net.pl3x.purpur.event.entity; -+ -+import org.bukkit.entity.Entity; -+import org.bukkit.event.Cancellable; -+import org.bukkit.event.HandlerList; -+import org.bukkit.event.entity.EntityEvent; -+import org.jetbrains.annotations.NotNull; -+ -+/** -+ * Called when an entity is ready to travel through a portal -+ */ -+public class EntityPortalReadyEvent extends EntityEvent implements Cancellable { -+ private static final HandlerList handlers = new HandlerList(); -+ private boolean cancelled = false; -+ -+ public EntityPortalReadyEvent(@NotNull Entity entity) { -+ super(entity); -+ } -+ -+ @Override -+ public boolean isCancelled() { -+ return cancelled; -+ } -+ -+ @Override -+ public void setCancelled(boolean cancel) { -+ this.cancelled = cancel; -+ } -+ -+ @NotNull -+ @Override -+ public HandlerList getHandlers() { -+ return handlers; -+ } -+ -+ @NotNull -+ public static HandlerList getHandlerList() { -+ return handlers; -+ } -+} --- -2.26.2 - diff --git a/patches/api/0010-Bring-back-server-name.patch b/patches/api/0009-Bring-back-server-name.patch similarity index 83% rename from patches/api/0010-Bring-back-server-name.patch rename to patches/api/0009-Bring-back-server-name.patch index 72d038f3a..7516e7ea7 100644 --- a/patches/api/0010-Bring-back-server-name.patch +++ b/patches/api/0009-Bring-back-server-name.patch @@ -1,4 +1,4 @@ -From 53733732e9661eb0f898887c88afd73b93a808f6 Mon Sep 17 00:00:00 2001 +From 964c8bd13a95dd17362e4c9bf98acc1a7662e008 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 26 May 2019 15:18:40 -0500 Subject: [PATCH] Bring back server name @@ -9,10 +9,10 @@ Subject: [PATCH] Bring back server name 2 files changed, 20 insertions(+) diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index 780d603e4..33ccf2979 100644 +index 329e2dd1c..4f6f01939 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java -@@ -1714,4 +1714,15 @@ public final class Bukkit { +@@ -1749,4 +1749,15 @@ public final class Bukkit { public static Server.Spigot spigot() { return server.spigot(); } @@ -29,10 +29,10 @@ index 780d603e4..33ccf2979 100644 + // Purpur end } diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index a4cf71fb4..adfa27be9 100644 +index 1a05a438c..c8b50ec90 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -1513,4 +1513,13 @@ public interface Server extends PluginMessageRecipient { +@@ -1536,4 +1536,13 @@ public interface Server extends PluginMessageRecipient { @NotNull com.destroystokyo.paper.entity.ai.MobGoals getMobGoals(); // Paper end diff --git a/patches/api/0012-Add-ExecuteCommandEvent.patch b/patches/api/0010-ExecuteCommandEvent.patch similarity index 98% rename from patches/api/0012-Add-ExecuteCommandEvent.patch rename to patches/api/0010-ExecuteCommandEvent.patch index a599b178b..7650df629 100644 --- a/patches/api/0012-Add-ExecuteCommandEvent.patch +++ b/patches/api/0010-ExecuteCommandEvent.patch @@ -1,7 +1,7 @@ -From 280f0a2c26874110fea70cc278976440c33f58e3 Mon Sep 17 00:00:00 2001 +From c9d8ecde06f4f694ed59d1da743b79b003a55b3c Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Fri, 31 May 2019 00:08:28 -0500 -Subject: [PATCH] Add ExecuteCommandEvent +Subject: [PATCH] ExecuteCommandEvent --- .../purpur/event/ExecuteCommandEvent.java | 130 ++++++++++++++++++ diff --git a/patches/api/0011-Implement-LivingEntity-safeFallDistance.patch b/patches/api/0011-LivingEntity-safeFallDistance.patch similarity index 82% rename from patches/api/0011-Implement-LivingEntity-safeFallDistance.patch rename to patches/api/0011-LivingEntity-safeFallDistance.patch index b89110ae1..cf1171c05 100644 --- a/patches/api/0011-Implement-LivingEntity-safeFallDistance.patch +++ b/patches/api/0011-LivingEntity-safeFallDistance.patch @@ -1,17 +1,17 @@ -From d74d33e1db952f3058834e45fc7ec553efa4d913 Mon Sep 17 00:00:00 2001 +From 6e3bdc06356d7b63bb206d7319badf594e30d872 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 5 May 2019 12:58:19 -0500 -Subject: [PATCH] Implement LivingEntity safeFallDistance +Subject: [PATCH] LivingEntity safeFallDistance --- .../java/org/bukkit/entity/LivingEntity.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java -index 7f73e4b92..1192fef87 100644 +index a60523cc9..5b688cd04 100644 --- a/src/main/java/org/bukkit/entity/LivingEntity.java +++ b/src/main/java/org/bukkit/entity/LivingEntity.java -@@ -732,4 +732,20 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource +@@ -753,4 +753,20 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource */ void setJumping(boolean jumping); // Paper end diff --git a/patches/api/0020-Add-moon-phase-API.patch b/patches/api/0012-MoonPhase-API.patch similarity index 90% rename from patches/api/0020-Add-moon-phase-API.patch rename to patches/api/0012-MoonPhase-API.patch index 5d367bb9b..d85256934 100644 --- a/patches/api/0020-Add-moon-phase-API.patch +++ b/patches/api/0012-MoonPhase-API.patch @@ -1,7 +1,7 @@ -From 90c5505c1c2c90cc976c8eee480008146585fb72 Mon Sep 17 00:00:00 2001 +From 28381a87dfb15e899df91a30192d98eb2575dff8 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 1 Feb 2020 22:22:07 -0600 -Subject: [PATCH] Add moon phase API +Subject: [PATCH] MoonPhase API --- src/main/java/net/pl3x/purpur/MoonPhase.java | 36 ++++++++++++++++++++ @@ -52,10 +52,10 @@ index 000000000..f5ad98c62 + } +} diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index 9518da825..cf0d18283 100644 +index 75c9225bd..9955d7417 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java -@@ -3382,6 +3382,16 @@ public interface World extends PluginMessageRecipient, Metadatable { +@@ -3450,6 +3450,16 @@ public interface World extends PluginMessageRecipient, Metadatable { @NotNull public List getRaids(); diff --git a/patches/api/0013-Implement-ChunkTooLargeEvent.patch b/patches/api/0013-Implement-ChunkTooLargeEvent.patch deleted file mode 100644 index 47d4db63a..000000000 --- a/patches/api/0013-Implement-ChunkTooLargeEvent.patch +++ /dev/null @@ -1,128 +0,0 @@ -From 97b09e0112fecb7c4bd3dacf078e7cedcf402cdd Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Fri, 12 Jul 2019 02:09:58 -0500 -Subject: [PATCH] Implement ChunkTooLargeEvent - ---- - .../pl3x/purpur/event/ChunkTooLargeEvent.java | 109 ++++++++++++++++++ - 1 file changed, 109 insertions(+) - create mode 100644 src/main/java/net/pl3x/purpur/event/ChunkTooLargeEvent.java - -diff --git a/src/main/java/net/pl3x/purpur/event/ChunkTooLargeEvent.java b/src/main/java/net/pl3x/purpur/event/ChunkTooLargeEvent.java -new file mode 100644 -index 000000000..f9d4a42c6 ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/event/ChunkTooLargeEvent.java -@@ -0,0 +1,109 @@ -+package net.pl3x.purpur.event; -+ -+import org.bukkit.Bukkit; -+import org.bukkit.Location; -+import org.bukkit.World; -+import org.bukkit.event.Event; -+import org.bukkit.event.HandlerList; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+ -+/** -+ * Called when an oversized chunk loads or saves -+ */ -+public class ChunkTooLargeEvent extends Event { -+ private static final HandlerList handlers = new HandlerList(); -+ private final String worldName; -+ private final World world; -+ private final int chunkX; -+ private final int chunkZ; -+ private final boolean saving; -+ private final boolean overzealous; -+ -+ public ChunkTooLargeEvent(@NotNull String worldName, int chunkX, int chunkZ, boolean saving, boolean overzealous) { -+ super(!Bukkit.isPrimaryThread()); -+ this.worldName = worldName; -+ this.world = Bukkit.getWorld(worldName); -+ this.chunkX = chunkX; -+ this.chunkZ = chunkZ; -+ this.saving = saving; -+ this.overzealous = overzealous; -+ } -+ -+ /** -+ * Get the world name according to the save directory -+ * -+ * @return World name -+ */ -+ @NotNull -+ public String getWorldName() { -+ return worldName; -+ } -+ -+ /** -+ * Get the world -+ * -+ * @return World, or null if world not loaded -+ */ -+ @Nullable -+ public World getWorld() { -+ return world; -+ } -+ -+ /** -+ * Get the X chunk coordinate -+ * -+ * @return X chunk coordinate -+ */ -+ public int getChunkX() { -+ return chunkX; -+ } -+ -+ /** -+ * Get the Z chunk coordinate -+ * -+ * @return Z chunk coordinate -+ */ -+ public int getChunkZ() { -+ return chunkZ; -+ } -+ -+ /** -+ * Whether this happened during a save attempt. -+ * -+ * @return True if saving, false if loading -+ */ -+ public boolean isSaving() { -+ return saving; -+ } -+ -+ /** -+ * If saving, was this is overzealous mode -+ * -+ * @return True if saving in overzealous mode -+ */ -+ public boolean isOverzealous() { -+ return overzealous; -+ } -+ -+ /** -+ * Get the location -+ * -+ * @return Location, or null if world not loaded -+ */ -+ @Nullable -+ public Location getLocation() { -+ return world == null ? null : new Location(world, chunkX << 4, 128, chunkZ << 4); -+ } -+ -+ @NotNull -+ @Override -+ public HandlerList getHandlers() { -+ return handlers; -+ } -+ -+ @NotNull -+ public static HandlerList getHandlerList() { -+ return handlers; -+ } -+} --- -2.26.2 - diff --git a/patches/api/0014-Implement-lagging-threshold.patch b/patches/api/0013-Lagging-threshold.patch similarity index 80% rename from patches/api/0014-Implement-lagging-threshold.patch rename to patches/api/0013-Lagging-threshold.patch index 07c6b2a6c..4318e2b36 100644 --- a/patches/api/0014-Implement-lagging-threshold.patch +++ b/patches/api/0013-Lagging-threshold.patch @@ -1,7 +1,7 @@ -From ca1fcc1af2f85b551bf7543deef46acea22634c4 Mon Sep 17 00:00:00 2001 +From cc7269c63a9bf44a2ddf6d3e51d3d665d265f271 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Tue, 23 Jul 2019 10:07:24 -0500 -Subject: [PATCH] Implement lagging threshold +Subject: [PATCH] Lagging threshold --- src/main/java/org/bukkit/Bukkit.java | 9 +++++++++ @@ -9,10 +9,10 @@ Subject: [PATCH] Implement lagging threshold 2 files changed, 16 insertions(+) diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index 33ccf2979..ee8fe48aa 100644 +index 4f6f01939..4c410f6e1 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java -@@ -1724,5 +1724,14 @@ public final class Bukkit { +@@ -1759,5 +1759,14 @@ public final class Bukkit { public static String getServerName() { return server.getServerName(); } @@ -28,10 +28,10 @@ index 33ccf2979..ee8fe48aa 100644 // Purpur end } diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index adfa27be9..40bf67eb9 100644 +index c8b50ec90..dc6201365 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -1521,5 +1521,12 @@ public interface Server extends PluginMessageRecipient { +@@ -1544,5 +1544,12 @@ public interface Server extends PluginMessageRecipient { */ @NotNull String getServerName(); diff --git a/patches/api/0016-Implement-ItemFactory-getMonsterEgg.patch b/patches/api/0014-ItemFactory-getMonsterEgg.patch similarity index 88% rename from patches/api/0016-Implement-ItemFactory-getMonsterEgg.patch rename to patches/api/0014-ItemFactory-getMonsterEgg.patch index c1c0d99d3..f490fe151 100644 --- a/patches/api/0016-Implement-ItemFactory-getMonsterEgg.patch +++ b/patches/api/0014-ItemFactory-getMonsterEgg.patch @@ -1,7 +1,7 @@ -From 6736fb9a85fe44f9af5c97709ed00d248ae45d0d Mon Sep 17 00:00:00 2001 +From 3414a3777cd50ba9f807ed0f83284f7dd88e0137 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Fri, 5 Jul 2019 16:37:04 -0500 -Subject: [PATCH] Implement ItemFactory#getMonsterEgg +Subject: [PATCH] ItemFactory#getMonsterEgg --- src/main/java/org/bukkit/inventory/ItemFactory.java | 11 +++++++++++ diff --git a/patches/api/0017-Implement-PlayerSetSpawnerTypeWithEggEvent.patch b/patches/api/0015-PlayerSetSpawnerTypeWithEggEvent.patch similarity index 95% rename from patches/api/0017-Implement-PlayerSetSpawnerTypeWithEggEvent.patch rename to patches/api/0015-PlayerSetSpawnerTypeWithEggEvent.patch index 6572f26d8..3b6f626b7 100644 --- a/patches/api/0017-Implement-PlayerSetSpawnerTypeWithEggEvent.patch +++ b/patches/api/0015-PlayerSetSpawnerTypeWithEggEvent.patch @@ -1,7 +1,7 @@ -From ace36924c5ca7ff1d4ca22ede17a8fd5ba98c21d Mon Sep 17 00:00:00 2001 +From 793caade58c03633ae3b36b59ced116586950df6 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Fri, 5 Jul 2019 18:21:15 -0500 -Subject: [PATCH] Implement PlayerSetSpawnerTypeWithEggEvent +Subject: [PATCH] PlayerSetSpawnerTypeWithEggEvent --- .../PlayerSetSpawnerTypeWithEggEvent.java | 85 +++++++++++++++++++ diff --git a/patches/api/0018-Add-MonsterEggSpawnEvent.patch b/patches/api/0016-EMC-MonsterEggSpawnEvent.patch similarity index 91% rename from patches/api/0018-Add-MonsterEggSpawnEvent.patch rename to patches/api/0016-EMC-MonsterEggSpawnEvent.patch index 687d8c8b5..830267520 100644 --- a/patches/api/0018-Add-MonsterEggSpawnEvent.patch +++ b/patches/api/0016-EMC-MonsterEggSpawnEvent.patch @@ -1,7 +1,7 @@ -From 58a00947d50d1e9be98cac3ed1d51ced2d3bfd79 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sat, 19 Oct 2019 03:20:49 -0500 -Subject: [PATCH] Add MonsterEggSpawnEvent +From 6f446935210fd7f4676937654457d8d6c1faf2ca Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Mon, 21 Nov 2016 17:02:11 -0500 +Subject: [PATCH] EMC - MonsterEggSpawnEvent --- .../event/entity/MonsterEggSpawnEvent.java | 67 +++++++++++++++++++ diff --git a/patches/api/0021-Add-API-for-Villager-resetOffers.patch b/patches/api/0017-Villager-resetOffers.patch similarity index 87% rename from patches/api/0021-Add-API-for-Villager-resetOffers.patch rename to patches/api/0017-Villager-resetOffers.patch index 53a73e44d..76196e728 100644 --- a/patches/api/0021-Add-API-for-Villager-resetOffers.patch +++ b/patches/api/0017-Villager-resetOffers.patch @@ -1,7 +1,7 @@ -From 9ee7302f78720dc515a2bdcca1d53512de2ac975 Mon Sep 17 00:00:00 2001 +From 49323476e3d0ca119769a379c1080de43ebd3981 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Mon, 7 Oct 2019 00:15:28 -0500 -Subject: [PATCH] Add API for Villager#resetOffers() +Subject: [PATCH] Villager#resetOffers --- src/main/java/org/bukkit/entity/Villager.java | 7 +++++++ diff --git a/patches/api/0024-Add-getPlacementBlockData-to-World.patch b/patches/api/0018-World-getPlacementBlockData.patch similarity index 80% rename from patches/api/0024-Add-getPlacementBlockData-to-World.patch rename to patches/api/0018-World-getPlacementBlockData.patch index 1c01153bc..b062e9d8a 100644 --- a/patches/api/0024-Add-getPlacementBlockData-to-World.patch +++ b/patches/api/0018-World-getPlacementBlockData.patch @@ -1,17 +1,17 @@ -From 3474b0cb95240f60a13d4c4fc4d7d2ecdcf95620 Mon Sep 17 00:00:00 2001 +From f7b6857340ba29d5877523fa69ad968247143ae7 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 19 Oct 2019 00:34:36 -0500 -Subject: [PATCH] Add getPlacementBlockData to World +Subject: [PATCH] World#getPlacementBlockData --- src/main/java/org/bukkit/World.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index cf0d18283..3a7226cc9 100644 +index 9955d7417..950425979 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java -@@ -3390,6 +3390,16 @@ public interface World extends PluginMessageRecipient, Metadatable { +@@ -3458,6 +3458,16 @@ public interface World extends PluginMessageRecipient, Metadatable { */ @NotNull net.pl3x.purpur.MoonPhase getMoonPhase(); diff --git a/patches/api/0019-Add-ThrownEggHatchEvent.patch b/patches/api/0019-Add-ThrownEggHatchEvent.patch deleted file mode 100644 index e249244ff..000000000 --- a/patches/api/0019-Add-ThrownEggHatchEvent.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 46a1c768adda232530d684c5ac49b69b6271cd04 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sat, 19 Oct 2019 03:27:55 -0500 -Subject: [PATCH] Add ThrownEggHatchEvent - ---- - .../event/entity/ThrownEggHatchEvent.java | 113 ++++++++++++++++++ - 1 file changed, 113 insertions(+) - create mode 100644 src/main/java/net/pl3x/purpur/event/entity/ThrownEggHatchEvent.java - -diff --git a/src/main/java/net/pl3x/purpur/event/entity/ThrownEggHatchEvent.java b/src/main/java/net/pl3x/purpur/event/entity/ThrownEggHatchEvent.java -new file mode 100644 -index 000000000..815e871d0 ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/event/entity/ThrownEggHatchEvent.java -@@ -0,0 +1,113 @@ -+package net.pl3x.purpur.event.entity; -+ -+import org.bukkit.entity.Egg; -+import org.bukkit.entity.EntityType; -+import org.bukkit.event.Event; -+import org.bukkit.event.HandlerList; -+import org.jetbrains.annotations.NotNull; -+ -+/** -+ * Called when a thrown egg might hatch -+ */ -+public class ThrownEggHatchEvent extends Event { -+ private static final HandlerList handlers = new HandlerList(); -+ -+ private final Egg egg; -+ private boolean hatching; -+ private EntityType hatchType; -+ private byte numHatches; -+ -+ public ThrownEggHatchEvent(@NotNull final Egg egg, final boolean hatching, final byte numHatches, @NotNull final EntityType hatchingType) { -+ this.egg = egg; -+ this.hatching = hatching; -+ this.numHatches = numHatches; -+ this.hatchType = hatchingType; -+ } -+ -+ /** -+ * Gets the egg involved in this event. -+ * -+ * @return the egg involved in this event -+ */ -+ @NotNull -+ public Egg getEgg() { -+ return egg; -+ } -+ -+ /** -+ * Gets whether the egg is hatching or not. Will be what the server -+ * would've done without interaction. -+ * -+ * @return boolean Whether the egg is going to hatch or not -+ */ -+ public boolean isHatching() { -+ return hatching; -+ } -+ -+ /** -+ * Sets whether the egg will hatch or not. -+ * -+ * @param hatching true if you want the egg to hatch, false if you want it not to -+ */ -+ public void setHatching(boolean hatching) { -+ this.hatching = hatching; -+ } -+ -+ /** -+ * Get the type of the mob being hatched (EntityType.CHICKEN by default) -+ * -+ * @return The type of the mob being hatched by the egg -+ */ -+ @NotNull -+ public EntityType getHatchingType() { -+ return hatchType; -+ } -+ -+ /** -+ * Change the type of mob being hatched by the egg -+ * -+ * @param hatchType The type of the mob being hatched by the egg -+ */ -+ public void setHatchingType(@NotNull EntityType hatchType) { -+ if (!hatchType.isSpawnable()) throw new IllegalArgumentException("Can't spawn that entity type from an egg!"); -+ this.hatchType = hatchType; -+ } -+ -+ /** -+ * Get the number of mob hatches from the egg. By default the number will -+ * be the number the server would've done -+ *
    -+ *
  • 7/8 chance of being 0 -+ *
  • 31/256 ~= 1/8 chance to be 1 -+ *
  • 1/256 chance to be 4 -+ *
-+ * -+ * @return The number of mobs going to be hatched by the egg -+ */ -+ public byte getNumHatches() { -+ return numHatches; -+ } -+ -+ /** -+ * Change the number of mobs coming out of the hatched egg -+ *

-+ * The boolean hatching will override this number. Ie. If hatching = -+ * false, this number will not matter -+ * -+ * @param numHatches The number of mobs coming out of the egg -+ */ -+ public void setNumHatches(byte numHatches) { -+ this.numHatches = numHatches; -+ } -+ -+ @NotNull -+ @Override -+ public HandlerList getHandlers() { -+ return handlers; -+ } -+ -+ @NotNull -+ public static HandlerList getHandlerList() { -+ return handlers; -+ } -+} --- -2.26.2 - diff --git a/patches/api/0025-Add-playPickupItemAnimation-to-LivingEntity.patch b/patches/api/0019-LivingEntity-playPickupItemAnimation.patch similarity index 82% rename from patches/api/0025-Add-playPickupItemAnimation-to-LivingEntity.patch rename to patches/api/0019-LivingEntity-playPickupItemAnimation.patch index 6186b32b0..7f7a2f7e9 100644 --- a/patches/api/0025-Add-playPickupItemAnimation-to-LivingEntity.patch +++ b/patches/api/0019-LivingEntity-playPickupItemAnimation.patch @@ -1,17 +1,17 @@ -From 6172f928c68e5721317cacb90c6d32e5c45239f4 Mon Sep 17 00:00:00 2001 +From ee3249840f9b53b10d7df7434088c5be3a1cd1ea Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 19 Oct 2019 02:25:05 -0500 -Subject: [PATCH] Add playPickupItemAnimation to LivingEntity +Subject: [PATCH] LivingEntity#playPickupItemAnimation --- .../java/org/bukkit/entity/LivingEntity.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java -index 1192fef87..2a713adb5 100644 +index 5b688cd04..a0db76946 100644 --- a/src/main/java/org/bukkit/entity/LivingEntity.java +++ b/src/main/java/org/bukkit/entity/LivingEntity.java -@@ -747,5 +747,22 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource +@@ -768,5 +768,22 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource * @param safeFallDistance Safe fall distance */ void setSafeFallDistance(float safeFallDistance); diff --git a/patches/api/0026-Add-getPlayer-to-SkeletonHorseTrapEvent.patch b/patches/api/0020-SkeletonHorseTrapEvent-getPlayer.patch similarity index 94% rename from patches/api/0026-Add-getPlayer-to-SkeletonHorseTrapEvent.patch rename to patches/api/0020-SkeletonHorseTrapEvent-getPlayer.patch index 0132e6816..a8689b8ca 100644 --- a/patches/api/0026-Add-getPlayer-to-SkeletonHorseTrapEvent.patch +++ b/patches/api/0020-SkeletonHorseTrapEvent-getPlayer.patch @@ -1,7 +1,7 @@ -From 1f20a2388d7c234a15f667c52eb11e1e2e89153e Mon Sep 17 00:00:00 2001 +From 9dc21420ed45e161850891442fb6f6ab988eb2e8 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 19 Oct 2019 02:35:24 -0500 -Subject: [PATCH] Add getPlayer to SkeletonHorseTrapEvent +Subject: [PATCH] SkeletonHorseTrapEvent#getPlayer --- .../event/entity/SkeletonHorseTrapEvent.java | 24 +++++++++++++++++++ diff --git a/patches/api/0034-PlayerItemCooldownEvent.patch b/patches/api/0021-PaperPR-PlayerItemCooldownEvent.patch similarity index 95% rename from patches/api/0034-PlayerItemCooldownEvent.patch rename to patches/api/0021-PaperPR-PlayerItemCooldownEvent.patch index 89f4bb879..95326f510 100644 --- a/patches/api/0034-PlayerItemCooldownEvent.patch +++ b/patches/api/0021-PaperPR-PlayerItemCooldownEvent.patch @@ -1,7 +1,7 @@ -From b5e2f3328828a98fa1521fe61725cddd2d104590 Mon Sep 17 00:00:00 2001 +From 585d46d0b381d2dd334997acf9140f505b484bfe Mon Sep 17 00:00:00 2001 From: KennyTV Date: Mon, 20 Apr 2020 13:57:13 +0200 -Subject: [PATCH] PlayerItemCooldownEvent +Subject: [PATCH] PaperPR - PlayerItemCooldownEvent --- .../event/player/PlayerItemCooldownEvent.java | 77 +++++++++++++++++++ diff --git a/patches/api/0029-Implement-EntityMoveEvent.patch b/patches/api/0022-EntityMoveEvent.patch similarity index 96% rename from patches/api/0029-Implement-EntityMoveEvent.patch rename to patches/api/0022-EntityMoveEvent.patch index 1ff546144..4dddf5be9 100644 --- a/patches/api/0029-Implement-EntityMoveEvent.patch +++ b/patches/api/0022-EntityMoveEvent.patch @@ -1,7 +1,7 @@ -From ed866cae2228a4924e2ddba5b9f0377170d9555f Mon Sep 17 00:00:00 2001 +From e15332baaee66fbb5134bc7891a9ba0890d24e04 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Tue, 11 Feb 2020 21:56:38 -0600 -Subject: [PATCH] Implement EntityMoveEvent +Subject: [PATCH] EntityMoveEvent --- .../purpur/event/entity/EntityMoveEvent.java | 95 +++++++++++++++++++ diff --git a/patches/api/0031-Add-BellRingEvent.patch b/patches/api/0023-PaperPR-BellRingEvent.patch similarity index 86% rename from patches/api/0031-Add-BellRingEvent.patch rename to patches/api/0023-PaperPR-BellRingEvent.patch index 373c5efe6..c7296b421 100644 --- a/patches/api/0031-Add-BellRingEvent.patch +++ b/patches/api/0023-PaperPR-BellRingEvent.patch @@ -1,21 +1,21 @@ -From 5b7ad2395e52a542256545223baee7b6f57e0adf Mon Sep 17 00:00:00 2001 +From b9e5c3e951fb47294a74c6515e6c3f5442a8b8e7 Mon Sep 17 00:00:00 2001 From: Eearslya Sleiarion Date: Mon, 24 Jun 2019 21:27:39 -0700 -Subject: [PATCH] Add BellRingEvent +Subject: [PATCH] PaperPR - BellRingEvent Add a new event, BellRingEvent, to trigger whenever a player rings a village bell. Passes along the bell block and the player who rang it. --- - .../paper/event/block/BellRingEvent.java | 54 +++++++++++++++++++ - 1 file changed, 54 insertions(+) + .../paper/event/block/BellRingEvent.java | 53 +++++++++++++++++++ + 1 file changed, 53 insertions(+) create mode 100644 src/main/java/com/destroystokyo/paper/event/block/BellRingEvent.java diff --git a/src/main/java/com/destroystokyo/paper/event/block/BellRingEvent.java b/src/main/java/com/destroystokyo/paper/event/block/BellRingEvent.java new file mode 100644 -index 000000000..7b4de3f0a +index 000000000..82e0a747b --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/event/block/BellRingEvent.java -@@ -0,0 +1,54 @@ +@@ -0,0 +1,53 @@ +package com.destroystokyo.paper.event.block; + +import org.bukkit.block.Block; @@ -23,7 +23,6 @@ index 000000000..7b4de3f0a +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.block.BlockEvent; -+import org.bukkit.potion.PotionEffect; +import org.jetbrains.annotations.NotNull; + +/** diff --git a/patches/api/0035-Player-invulnerabilities.patch b/patches/api/0024-Player-invulnerabilities.patch similarity index 87% rename from patches/api/0035-Player-invulnerabilities.patch rename to patches/api/0024-Player-invulnerabilities.patch index 2237453d6..46bb6fc07 100644 --- a/patches/api/0035-Player-invulnerabilities.patch +++ b/patches/api/0024-Player-invulnerabilities.patch @@ -1,4 +1,4 @@ -From 02ff3b3a31c89fa3c48f228b8637803d919d0c9c Mon Sep 17 00:00:00 2001 +From be009f6bd10975040ad8ff9378eca1569132774b Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 2 May 2020 20:55:31 -0500 Subject: [PATCH] Player invulnerabilities @@ -8,10 +8,10 @@ Subject: [PATCH] Player invulnerabilities 1 file changed, 21 insertions(+) diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index edc481170..5d77b71d1 100644 +index 2dca16ac4..55edcd54b 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -1850,5 +1850,26 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1890,5 +1890,26 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * Reset the idle timer back to 0 */ void resetIdleTimer(); diff --git a/patches/api/0033-More-anvil-controls.patch b/patches/api/0025-Anvil-API.patch similarity index 97% rename from patches/api/0033-More-anvil-controls.patch rename to patches/api/0025-Anvil-API.patch index 37b018f52..17fb7298d 100644 --- a/patches/api/0033-More-anvil-controls.patch +++ b/patches/api/0025-Anvil-API.patch @@ -1,7 +1,7 @@ -From 3121b0887bf03835c9b9a6f1fd3fd2775af5681f Mon Sep 17 00:00:00 2001 +From 4b4840812bcfe1331263157f9b7b61ec8d79e672 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 19 Apr 2020 00:25:09 -0500 -Subject: [PATCH] More anvil controls +Subject: [PATCH] Anvil API --- .../event/inventory/AnvilTakeResultEvent.java | 52 +++++++++++++++++++ diff --git a/patches/api/0030-Add-ItemStack-convenience-methods.patch b/patches/api/0026-ItemStack-convenience-methods.patch similarity index 98% rename from patches/api/0030-Add-ItemStack-convenience-methods.patch rename to patches/api/0026-ItemStack-convenience-methods.patch index a98ef4718..78bfbd180 100644 --- a/patches/api/0030-Add-ItemStack-convenience-methods.patch +++ b/patches/api/0026-ItemStack-convenience-methods.patch @@ -1,7 +1,7 @@ -From 28d6279d8881deed20cc24abfecddfcffefb94c2 Mon Sep 17 00:00:00 2001 +From dc446f6d6e36a6b06f04d8395835257126454d27 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 15 Mar 2020 20:52:12 -0500 -Subject: [PATCH] Add ItemStack convenience methods +Subject: [PATCH] ItemStack convenience methods --- src/main/java/org/bukkit/Material.java | 32 + @@ -9,10 +9,10 @@ Subject: [PATCH] Add ItemStack convenience methods 2 files changed, 651 insertions(+) diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java -index b89fc2dc0..d5cf01dae 100644 +index 769c65e79..7126e5cba 100644 --- a/src/main/java/org/bukkit/Material.java +++ b/src/main/java/org/bukkit/Material.java -@@ -8021,4 +8021,36 @@ public enum Material implements Keyed { +@@ -8636,4 +8636,36 @@ public enum Material implements Keyed { // } } @@ -50,7 +50,7 @@ index b89fc2dc0..d5cf01dae 100644 + // Purpur end } diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index a8ade268c..cdc62301e 100644 +index ccd81fca2..c38fd8403 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java @@ -17,6 +17,18 @@ import org.bukkit.inventory.meta.ItemMeta; @@ -72,7 +72,7 @@ index a8ade268c..cdc62301e 100644 /** * Represents a stack of items. -@@ -783,4 +795,611 @@ public class ItemStack implements Cloneable, ConfigurationSerializable { +@@ -791,4 +803,611 @@ public class ItemStack implements Cloneable, ConfigurationSerializable { return itemMeta.hasItemFlag(flag); } // Paper end diff --git a/patches/api/0027-Add-LootableInventoryFirstFillEvent.patch b/patches/api/0027-Add-LootableInventoryFirstFillEvent.patch deleted file mode 100644 index 0fd71ee49..000000000 --- a/patches/api/0027-Add-LootableInventoryFirstFillEvent.patch +++ /dev/null @@ -1,61 +0,0 @@ -From f6f1059eb70c8286fafd421d629652abddeab72a Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sat, 19 Oct 2019 02:43:10 -0500 -Subject: [PATCH] Add LootableInventoryFirstFillEvent - ---- - .../LootableInventoryFirstFillEvent.java | 42 +++++++++++++++++++ - 1 file changed, 42 insertions(+) - create mode 100644 src/main/java/net/pl3x/purpur/event/block/LootableInventoryFirstFillEvent.java - -diff --git a/src/main/java/net/pl3x/purpur/event/block/LootableInventoryFirstFillEvent.java b/src/main/java/net/pl3x/purpur/event/block/LootableInventoryFirstFillEvent.java -new file mode 100644 -index 000000000..ef8eafb7c ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/event/block/LootableInventoryFirstFillEvent.java -@@ -0,0 +1,42 @@ -+package net.pl3x.purpur.event.block; -+ -+import com.destroystokyo.paper.loottable.LootableInventory; -+import org.bukkit.entity.Player; -+import org.bukkit.event.Event; -+import org.bukkit.event.HandlerList; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+ -+public class LootableInventoryFirstFillEvent extends Event { -+ @Nullable -+ private final Player player; -+ @NotNull -+ private final LootableInventory inventory; -+ -+ public LootableInventoryFirstFillEvent(@Nullable Player player, @NotNull LootableInventory inventory) { -+ this.player = player; -+ this.inventory = inventory; -+ } -+ -+ @Nullable -+ public Player getPlayer() { -+ return player; -+ } -+ -+ @NotNull -+ public LootableInventory getInventory() { -+ return inventory; -+ } -+ -+ private static final HandlerList handlers = new HandlerList(); -+ -+ @NotNull -+ public HandlerList getHandlers() { -+ return handlers; -+ } -+ -+ @NotNull -+ public static HandlerList getHandlerList() { -+ return handlers; -+ } -+} --- -2.26.2 - diff --git a/patches/api/0027-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch b/patches/api/0027-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch new file mode 100644 index 000000000..f247dbe12 --- /dev/null +++ b/patches/api/0027-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch @@ -0,0 +1,25 @@ +From 19065eff8026e396d1bf06bc2f87e7598c322c25 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Sun, 28 Jun 2020 21:50:55 -0500 +Subject: [PATCH] Phantoms attracted to crystals and crystals shoot phantoms + +--- + .../java/com/destroystokyo/paper/entity/ai/VanillaGoal.java | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java +index d7f1b2c84..8d25b6f09 100644 +--- a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java ++++ b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java +@@ -205,4 +205,8 @@ public interface VanillaGoal extends Goal { + GoalKey ZOMBIE_ATTACK = GoalKey.of(Zombie.class, NamespacedKey.minecraft("zombie_attack")); + GoalKey STROLL_VILLAGE_GOLEM = GoalKey.of(Creature.class, NamespacedKey.minecraft("stroll_village_golem")); + GoalKey UNIVERSAL_ANGER_RESET = GoalKey.of(Mob.class, NamespacedKey.minecraft("universal_anger_reset")); ++ // Purpur start ++ GoalKey FIND_CRYSTAL_GOAL = GoalKey.of(Phantom.class, NamespacedKey.minecraft("find_crystal_goal")); ++ GoalKey ORBIT_CRYSTAL_GOAL = GoalKey.of(Phantom.class, NamespacedKey.minecraft("orbit_crystal_goal")); ++ // Purpur end + } +-- +2.26.2 + diff --git a/patches/api/0028-Add-back-EntityCreatePortalEvent-for-EnderDragon.patch b/patches/api/0028-Add-back-EntityCreatePortalEvent-for-EnderDragon.patch deleted file mode 100644 index 80e5b31a1..000000000 --- a/patches/api/0028-Add-back-EntityCreatePortalEvent-for-EnderDragon.patch +++ /dev/null @@ -1,47 +0,0 @@ -From b08452c2c1e0893a931b924f80972baa4d007619 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sat, 19 Oct 2019 03:53:46 -0500 -Subject: [PATCH] Add back EntityCreatePortalEvent for EnderDragon - ---- - src/main/java/org/bukkit/PortalType.java | 7 +++++++ - .../org/bukkit/event/entity/EntityCreatePortalEvent.java | 4 +--- - 2 files changed, 8 insertions(+), 3 deletions(-) - -diff --git a/src/main/java/org/bukkit/PortalType.java b/src/main/java/org/bukkit/PortalType.java -index 427cfbb8b..e23565323 100644 ---- a/src/main/java/org/bukkit/PortalType.java -+++ b/src/main/java/org/bukkit/PortalType.java -@@ -15,6 +15,13 @@ public enum PortalType { - */ - ENDER, - -+ // Purpur start -+ /** -+ * This is an End Gateway portal -+ */ -+ END_GATEWAY, -+ // Purpur end -+ - /** - * This is a custom Plugin portal. - */ -diff --git a/src/main/java/org/bukkit/event/entity/EntityCreatePortalEvent.java b/src/main/java/org/bukkit/event/entity/EntityCreatePortalEvent.java -index 397baaefd..7456240b4 100644 ---- a/src/main/java/org/bukkit/event/entity/EntityCreatePortalEvent.java -+++ b/src/main/java/org/bukkit/event/entity/EntityCreatePortalEvent.java -@@ -11,10 +11,8 @@ import org.jetbrains.annotations.NotNull; - - /** - * Thrown when a Living Entity creates a portal in a world. -- * -- * @deprecated Use {@link PortalCreateEvent} - */ --@Deprecated -+// Purpur - un-deprecate - public class EntityCreatePortalEvent extends EntityEvent implements Cancellable { - private static final HandlerList handlers = new HandlerList(); - private final List blocks; --- -2.26.2 - diff --git a/patches/api/0032-Configurable-enchantment-max-level.patch b/patches/api/0032-Configurable-enchantment-max-level.patch deleted file mode 100644 index d314269d1..000000000 --- a/patches/api/0032-Configurable-enchantment-max-level.patch +++ /dev/null @@ -1,51 +0,0 @@ -From eb6271ac09f62253e19664c2a5e4b28f1dd5a914 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Wed, 1 Apr 2020 19:18:29 -0500 -Subject: [PATCH] Configurable enchantment max level - ---- - src/main/java/org/bukkit/enchantments/Enchantment.java | 9 +++++++++ - .../java/org/bukkit/enchantments/EnchantmentWrapper.java | 7 +++++++ - 2 files changed, 16 insertions(+) - -diff --git a/src/main/java/org/bukkit/enchantments/Enchantment.java b/src/main/java/org/bukkit/enchantments/Enchantment.java -index d1885f178..b277428d6 100644 ---- a/src/main/java/org/bukkit/enchantments/Enchantment.java -+++ b/src/main/java/org/bukkit/enchantments/Enchantment.java -@@ -232,6 +232,15 @@ public abstract class Enchantment implements Keyed { - */ - public abstract int getMaxLevel(); - -+ // Purpur start -+ /** -+ * Sets the maximum level that this Enchantment may become. -+ * -+ * @param maxLevel Maximum level of the Enchantment -+ */ -+ public abstract void setMaxLevel(int maxLevel); -+ // Purpur end -+ - /** - * Gets the level that this Enchantment should start at - * -diff --git a/src/main/java/org/bukkit/enchantments/EnchantmentWrapper.java b/src/main/java/org/bukkit/enchantments/EnchantmentWrapper.java -index 9566e4306..67e31fee3 100644 ---- a/src/main/java/org/bukkit/enchantments/EnchantmentWrapper.java -+++ b/src/main/java/org/bukkit/enchantments/EnchantmentWrapper.java -@@ -27,6 +27,13 @@ public class EnchantmentWrapper extends Enchantment { - return getEnchantment().getMaxLevel(); - } - -+ // Purpur start -+ @Override -+ public void setMaxLevel(int maxLevel) { -+ getEnchantment().setMaxLevel(maxLevel); -+ } -+ // Purpur end -+ - @Override - public int getStartLevel() { - return getEnchantment().getStartLevel(); --- -2.26.2 - diff --git a/patches/api/0036-Add-PrepareGrindstoneEvent.patch b/patches/api/0036-Add-PrepareGrindstoneEvent.patch deleted file mode 100644 index 65f9466fa..000000000 --- a/patches/api/0036-Add-PrepareGrindstoneEvent.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 520632fdade49977988e20c07bd90d360f86418a Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Thu, 18 Jun 2020 23:29:43 -0500 -Subject: [PATCH] Add PrepareGrindstoneEvent - ---- - .../inventory/PrepareGrindstoneEvent.java | 54 +++++++++++++++++++ - 1 file changed, 54 insertions(+) - create mode 100644 src/main/java/net/pl3x/purpur/event/inventory/PrepareGrindstoneEvent.java - -diff --git a/src/main/java/net/pl3x/purpur/event/inventory/PrepareGrindstoneEvent.java b/src/main/java/net/pl3x/purpur/event/inventory/PrepareGrindstoneEvent.java -new file mode 100644 -index 000000000..d0670bb72 ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/event/inventory/PrepareGrindstoneEvent.java -@@ -0,0 +1,54 @@ -+package net.pl3x.purpur.event.inventory; -+ -+import org.bukkit.event.HandlerList; -+import org.bukkit.event.inventory.InventoryEvent; -+import org.bukkit.inventory.GrindstoneInventory; -+import org.bukkit.inventory.InventoryView; -+import org.bukkit.inventory.ItemStack; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+ -+/** -+ * Called when an item is put in a grindstone slot. -+ */ -+public class PrepareGrindstoneEvent extends InventoryEvent { -+ -+ private static final HandlerList handlers = new HandlerList(); -+ private ItemStack result; -+ -+ public PrepareGrindstoneEvent(@NotNull InventoryView inventory, @Nullable ItemStack result) { -+ super(inventory); -+ this.result = result; -+ } -+ -+ @NotNull -+ @Override -+ public GrindstoneInventory getInventory() { -+ return (GrindstoneInventory) super.getInventory(); -+ } -+ -+ /** -+ * Get result item, may be null. -+ * -+ * @return result item -+ */ -+ @Nullable -+ public ItemStack getResult() { -+ return result; -+ } -+ -+ public void setResult(@Nullable ItemStack result) { -+ this.result = result; -+ } -+ -+ @NotNull -+ @Override -+ public HandlerList getHandlers() { -+ return handlers; -+ } -+ -+ @NotNull -+ public static HandlerList getHandlerList() { -+ return handlers; -+ } -+} --- -2.26.2 - diff --git a/patches/server/0002-Rebrand.patch b/patches/server/0001-Rebrand.patch similarity index 82% rename from patches/server/0002-Rebrand.patch rename to patches/server/0001-Rebrand.patch index 4de689a2c..33050be5d 100644 --- a/patches/server/0002-Rebrand.patch +++ b/patches/server/0001-Rebrand.patch @@ -1,44 +1,45 @@ -From e2ba591861d7dd7532a3a9e8669ce81dc81ef8d9 Mon Sep 17 00:00:00 2001 +From d8265c1939a992ff975a7d259bf3e60abec03067 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 4 May 2019 01:02:11 -0500 Subject: [PATCH] Rebrand --- - pom.xml | 34 ++++-- + pom.xml | 31 +++-- .../paper/console/PaperConsole.java | 2 +- .../net/minecraft/server/MinecraftServer.java | 2 +- .../net/pl3x/purpur/PurpurVersionFetcher.java | 115 ++++++++++++++++++ .../org/bukkit/craftbukkit/CraftServer.java | 2 +- .../craftbukkit/util/CraftMagicNumbers.java | 2 +- .../bukkit/craftbukkit/util/Versioning.java | 2 +- - 7 files changed, 144 insertions(+), 15 deletions(-) + 7 files changed, 142 insertions(+), 14 deletions(-) create mode 100644 src/main/java/net/pl3x/purpur/PurpurVersionFetcher.java diff --git a/pom.xml b/pom.xml -index 66517f30f..097c736bc 100644 +index ef8ee637a..97c73571b 100644 --- a/pom.xml +++ b/pom.xml -@@ -1,11 +1,11 @@ - 4.0.0 -- tuinity +- paper + purpur jar - 1.15.2-R0.1-SNAPSHOT -- Tuinity-Server -- https://github.com/Spottedleaf/Tuinity + 1.16.1-R0.1-SNAPSHOT +- Paper +- https://papermc.io +- + Purpur + http://pl3x.net UTF-8 -@@ -17,16 +17,16 @@ +@@ -18,16 +17,16 @@ -- com.tuinity -- tuinity-parent +- com.destroystokyo.paper +- paper-parent + net.pl3x.purpur + purpur-parent dev-SNAPSHOT @@ -47,14 +48,14 @@ index 66517f30f..097c736bc 100644 -- com.tuinity -- tuinity-api +- com.destroystokyo.paper +- paper-api + net.pl3x.purpur + purpur-api ${project.version} compile -@@ -42,6 +42,20 @@ +@@ -43,6 +42,20 @@ ${minecraft.version}-SNAPSHOT compile @@ -75,25 +76,15 @@ index 66517f30f..097c736bc 100644 net.minecrell terminalconsoleappender -@@ -163,15 +177,15 @@ +@@ -164,7 +177,7 @@ -- tuinity-${minecraft.version} -- install +- paper-${minecraft.version} + purpur-${minecraft.version} -+ clean install + clean install - com.lukegb.mojo - gitdescribe-maven-plugin - 1.3 - -- git-Tuinity- -+ git-Purpur- - .. - - diff --git a/src/main/java/com/destroystokyo/paper/console/PaperConsole.java b/src/main/java/com/destroystokyo/paper/console/PaperConsole.java index 74ed02fa9..c1280478e 100644 --- a/src/main/java/com/destroystokyo/paper/console/PaperConsole.java @@ -108,15 +99,15 @@ index 74ed02fa9..c1280478e 100644 .completer(new ConsoleCommandCompleter(this.server)) ); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 3c9392077..28d92cbce 100644 +index 5c862de2f..0d0998b06 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1630,7 +1630,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant // Spigot - Spigot > // CraftBukkit - cb > vanilla! -+ return "Purpur"; // Purpur // Tuinity // Paper // Spigot // CraftBukkit +- return "Paper"; //Paper - Paper > // Spigot - Spigot > // CraftBukkit - cb > vanilla! ++ return "Purpur"; // Purpur // Paper // Spigot // CraftBukkit } public CrashReport b(CrashReport crashreport) { @@ -242,23 +233,23 @@ index 000000000..d8b408f06 + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 760752eae..2a6fd01d6 100644 +index 25e012678..1026fd81b 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -205,7 +205,7 @@ import javax.annotation.Nullable; // Paper +@@ -229,7 +229,7 @@ import javax.annotation.Nullable; // Paper import javax.annotation.Nonnull; // Paper public final class CraftServer implements Server { -- private final String serverName = "Tuinity"; // Paper // Tuinity -+ private final String serverName = "Purpur"; // Paper // Tuinity // Purpur +- private final String serverName = "Paper"; // Paper ++ private final String serverName = "Purpur"; // Paper // Purpur private final String serverVersion; private final String bukkitVersion = Versioning.getBukkitVersion(); private final Logger logger = Logger.getLogger("Minecraft"); diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 004b6ce13..e1cfde4ff 100644 +index 257f46003..63db398ec 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -312,7 +312,7 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -317,7 +317,7 @@ public final class CraftMagicNumbers implements UnsafeValues { @Override public com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() { @@ -268,14 +259,14 @@ index 004b6ce13..e1cfde4ff 100644 @Override diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java -index 001b1e519..e9aee2d8a 100644 +index 674096cab..e9aee2d8a 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java +++ b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java @@ -11,7 +11,7 @@ public final class Versioning { public static String getBukkitVersion() { String result = "Unknown-Version"; -- InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/com.tuinity/tuinity-api/pom.properties"); // Tuinity +- InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/com.destroystokyo.paper/paper-api/pom.properties"); + InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/net.pl3x.purpur/purpur-api/pom.properties"); // Purpur Properties properties = new Properties(); diff --git a/patches/server/0001-Tuinity-Server-Changes.patch b/patches/server/0001-Tuinity-Server-Changes.patch deleted file mode 100644 index 7465799b1..000000000 --- a/patches/server/0001-Tuinity-Server-Changes.patch +++ /dev/null @@ -1,6978 +0,0 @@ -From ed82e825eb9705667b56300afc136bbc830131ae Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Fri, 14 Dec 2018 21:53:58 -0800 -Subject: [PATCH] Tuinity Server Changes - ---- - pom.xml | 23 +- - .../co/aikar/timings/MinecraftTimings.java | 2 + - .../java/co/aikar/timings/TimingsExport.java | 3 +- - .../paper/PaperVersionFetcher.java | 11 +- - .../paper/server/ticklist/PaperTickList.java | 9 + - .../chunk/SingleThreadChunkRegionManager.java | 159 ++++++ - .../tuinity/tuinity/config/TuinityConfig.java | 277 ++++++++++ - .../com/tuinity/tuinity/util/CachedLists.java | 53 ++ - .../com/tuinity/tuinity/util/TickThread.java | 41 ++ - .../IteratorSafeOrderedReferenceSet.java | 265 +++++++++ - .../tuinity/tuinity/voxel/AABBVoxelShape.java | 246 +++++++++ - .../net/minecraft/server/AxisAlignedBB.java | 115 ++++ - .../java/net/minecraft/server/BiomeBase.java | 12 + - .../java/net/minecraft/server/BlockChest.java | 4 +- - .../net/minecraft/server/BlockPiston.java | 31 +- - .../minecraft/server/BlockPistonMoving.java | 7 +- - src/main/java/net/minecraft/server/Chunk.java | 37 ++ - .../java/net/minecraft/server/ChunkMap.java | 1 + - .../minecraft/server/ChunkMapDistance.java | 94 +++- - .../minecraft/server/ChunkProviderServer.java | 278 ++++++++-- - .../minecraft/server/ChunkRegionLoader.java | 12 +- - .../net/minecraft/server/ChunkSection.java | 1 + - .../net/minecraft/server/ChunkStatus.java | 4 +- - .../minecraft/server/DataPaletteBlock.java | 1 + - .../net/minecraft/server/DedicatedServer.java | 1 + - src/main/java/net/minecraft/server/EULA.java | 2 +- - .../java/net/minecraft/server/Entity.java | 204 ++++++- - .../net/minecraft/server/EntityLiving.java | 9 +- - .../minecraft/server/EntityTrackerEntry.java | 1 + - .../java/net/minecraft/server/HeightMap.java | 5 +- - .../java/net/minecraft/server/IBlockData.java | 12 + - .../minecraft/server/ICollisionAccess.java | 39 +- - .../minecraft/server/LightEngineStorage.java | 5 +- - .../java/net/minecraft/server/MCUtil.java | 14 + - .../net/minecraft/server/MinecraftServer.java | 110 +++- - .../net/minecraft/server/NetworkManager.java | 59 +- - .../server/PacketPlayOutMapChunk.java | 117 ++-- - .../minecraft/server/PathfinderNormal.java | 13 +- - .../net/minecraft/server/PlayerChunk.java | 37 +- - .../net/minecraft/server/PlayerChunkMap.java | 64 ++- - .../minecraft/server/PlayerConnection.java | 34 +- - .../server/PlayerConnectionUtils.java | 26 + - .../server/PlayerInteractManager.java | 53 +- - .../java/net/minecraft/server/ProtoChunk.java | 16 +- - .../java/net/minecraft/server/RegionFile.java | 468 +++++++++++++++- - .../minecraft/server/RegionFileBitSet.java | 26 +- - .../net/minecraft/server/RegionFileCache.java | 45 +- - .../server/RegionFileCompression.java | 7 +- - .../java/net/minecraft/server/Ticket.java | 11 +- - .../java/net/minecraft/server/TicketType.java | 3 +- - .../java/net/minecraft/server/TileEntity.java | 49 +- - .../minecraft/server/TileEntityBeacon.java | 26 +- - .../minecraft/server/TileEntityBeehive.java | 7 + - .../server/TileEntityBrewingStand.java | 26 +- - .../net/minecraft/server/TileEntityChest.java | 16 + - .../minecraft/server/TileEntityConduit.java | 21 +- - .../minecraft/server/TileEntityFurnace.java | 26 +- - .../minecraft/server/TileEntityJukeBox.java | 7 + - .../minecraft/server/TileEntityLectern.java | 51 +- - .../minecraft/server/TileEntityPiston.java | 66 ++- - src/main/java/net/minecraft/server/Vec3D.java | 5 +- - .../net/minecraft/server/VillagePlace.java | 2 +- - .../java/net/minecraft/server/VoxelShape.java | 11 +- - .../net/minecraft/server/VoxelShapeArray.java | 72 +++ - .../net/minecraft/server/VoxelShapes.java | 79 ++- - src/main/java/net/minecraft/server/World.java | 41 +- - .../net/minecraft/server/WorldBorder.java | 37 +- - .../net/minecraft/server/WorldServer.java | 517 +++++++++++++++++- - .../net/minecraft/server/WorldUpgrader.java | 2 +- - .../craftbukkit/CraftChunkSnapshot.java | 2 +- - .../org/bukkit/craftbukkit/CraftServer.java | 17 +- - .../org/bukkit/craftbukkit/CraftWorld.java | 19 +- - .../java/org/bukkit/craftbukkit/Main.java | 9 +- - .../bukkit/craftbukkit/block/CraftBlock.java | 21 +- - .../craftbukkit/block/CraftBlockState.java | 2 +- - .../block/data/CraftBlockData.java | 2 +- - .../craftbukkit/entity/CraftEntity.java | 31 ++ - .../craftbukkit/generator/CraftChunkData.java | 2 +- - .../scoreboard/CraftScoreboardManager.java | 9 + - .../bukkit/craftbukkit/util/UnsafeList.java | 26 + - .../bukkit/craftbukkit/util/Versioning.java | 2 +- - src/main/java/org/spigotmc/AsyncCatcher.java | 2 +- - .../java/org/spigotmc/WatchdogThread.java | 79 +++ - 83 files changed, 3967 insertions(+), 384 deletions(-) - create mode 100644 src/main/java/com/tuinity/tuinity/chunk/SingleThreadChunkRegionManager.java - create mode 100644 src/main/java/com/tuinity/tuinity/config/TuinityConfig.java - create mode 100644 src/main/java/com/tuinity/tuinity/util/CachedLists.java - create mode 100644 src/main/java/com/tuinity/tuinity/util/TickThread.java - create mode 100644 src/main/java/com/tuinity/tuinity/util/maplist/IteratorSafeOrderedReferenceSet.java - create mode 100644 src/main/java/com/tuinity/tuinity/voxel/AABBVoxelShape.java - -diff --git a/pom.xml b/pom.xml -index e4c63bb76..66517f30f 100644 ---- a/pom.xml -+++ b/pom.xml -@@ -1,12 +1,11 @@ -- - 4.0.0 -- paper -+ tuinity - jar - 1.15.2-R0.1-SNAPSHOT -- Paper -- https://papermc.io -- -+ Tuinity-Server -+ https://github.com/Spottedleaf/Tuinity - - - UTF-8 -@@ -18,16 +17,16 @@ - - - -- com.destroystokyo.paper -- paper-parent -+ com.tuinity -+ tuinity-parent - dev-SNAPSHOT - ../pom.xml - - - - -- com.destroystokyo.paper -- paper-api -+ com.tuinity -+ tuinity-api - ${project.version} - compile - -@@ -164,15 +163,15 @@ - - - -- paper-${minecraft.version} -- clean install -+ tuinity-${minecraft.version} -+ install - - - com.lukegb.mojo - gitdescribe-maven-plugin - 1.3 - -- git-Paper- -+ git-Tuinity- - .. - - -diff --git a/src/main/java/co/aikar/timings/MinecraftTimings.java b/src/main/java/co/aikar/timings/MinecraftTimings.java -index dd0722397..2966c5731 100644 ---- a/src/main/java/co/aikar/timings/MinecraftTimings.java -+++ b/src/main/java/co/aikar/timings/MinecraftTimings.java -@@ -43,6 +43,8 @@ public final class MinecraftTimings { - public static final Timing antiXrayUpdateTimer = Timings.ofSafe("anti-xray - update"); - public static final Timing antiXrayObfuscateTimer = Timings.ofSafe("anti-xray - obfuscate"); - -+ public static final Timing scoreboardScoreSearch = Timings.ofSafe("Scoreboard score search"); // Tuinity - add timings for scoreboard search -+ - private static final Map, String> taskNameCache = new MapMaker().weakKeys().makeMap(); - - private MinecraftTimings() {} -diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java -index a3b41ce5f..b09981e9b 100644 ---- a/src/main/java/co/aikar/timings/TimingsExport.java -+++ b/src/main/java/co/aikar/timings/TimingsExport.java -@@ -229,7 +229,8 @@ public class TimingsExport extends Thread { - parent.put("config", createObject( - pair("spigot", mapAsJSON(Bukkit.spigot().getSpigotConfig(), null)), - pair("bukkit", mapAsJSON(Bukkit.spigot().getBukkitConfig(), null)), -- pair("paper", mapAsJSON(Bukkit.spigot().getPaperConfig(), null)) -+ pair("paper", mapAsJSON(Bukkit.spigot().getPaperConfig(), null)), // Tuinity - add config to timings report -+ pair("tuinity", mapAsJSON(Bukkit.spigot().getTuinityConfig(), null)) // Tuinity - add config to timings report - )); - - new TimingsExport(listeners, parent, history).start(); -diff --git a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java -index 49a38c660..255bbd6e4 100644 ---- a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java -+++ b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java -@@ -24,8 +24,8 @@ public class PaperVersionFetcher implements VersionFetcher { - @Nonnull - @Override - public String getVersionMessage(@Nonnull String serverVersion) { -- String[] parts = serverVersion.substring("git-Paper-".length()).split("[-\\s]"); -- String updateMessage = getUpdateStatusMessage("PaperMC/Paper", GITHUB_BRANCH_NAME, parts[0]); -+ String[] parts = serverVersion.substring("git-Tuinity-".length()).split("[-\\s]"); // Tuinity -+ String updateMessage = getUpdateStatusMessage("Spottedleaf/Tuinity", GITHUB_BRANCH_NAME, parts[0]); // Tuinity - String history = getHistory(); - - return history != null ? history + "\n" + updateMessage : updateMessage; -@@ -49,13 +49,10 @@ public class PaperVersionFetcher implements VersionFetcher { - - private static String getUpdateStatusMessage(@Nonnull String repo, @Nonnull String branch, @Nonnull String versionInfo) { - int distance; -- try { -- int jenkinsBuild = Integer.parseInt(versionInfo); -- distance = fetchDistanceFromSiteApi(jenkinsBuild, getMinecraftVersion()); -- } catch (NumberFormatException ignored) { -+ // Tuinity - we don't have jenkins setup - versionInfo = versionInfo.replace("\"", ""); - distance = fetchDistanceFromGitHub(repo, branch, versionInfo); -- } -+ // Tuinity - we don't have jenkins setup - - switch (distance) { - case -1: -diff --git a/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java b/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java -index ce653f6b4..a08bfb4b3 100644 ---- a/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java -+++ b/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java -@@ -189,6 +189,7 @@ public final class PaperTickList extends TickListServer { // extend to avo - } - - public void onChunkSetTicking(final int chunkX, final int chunkZ) { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("async tick list chunk ticking update"); // Tuinity - soft async catcher - final ArrayList> pending = this.pendingChunkTickLoad.remove(MCUtil.getCoordinateKey(chunkX, chunkZ)); - if (pending == null) { - return; -@@ -269,6 +270,7 @@ public final class PaperTickList extends TickListServer { // extend to avo - - @Override - public void tick() { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("async tick list tick"); // Tuinity - soft async catcher - final ChunkProviderServer chunkProvider = this.world.getChunkProvider(); - - this.world.getMethodProfiler().enter("cleaning"); -@@ -297,6 +299,7 @@ public final class PaperTickList extends TickListServer { // extend to avo - if (toTick.tickState == STATE_TICKING) { - toTick.tickState = STATE_TICKED; - } // else it's STATE_CANCELLED_TICK -+ MinecraftServer.getServer().executeMidTickTasks(); // Tuinity - exec chunk tasks during world tick - } else { - // re-schedule eventually - toTick.tickState = STATE_SCHEDULED; -@@ -414,6 +417,7 @@ public final class PaperTickList extends TickListServer { // extend to avo - } - - public void schedule(final BlockPosition pos, final T data, final long targetTick, final TickListPriority priority) { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("async tick list schedule"); // Tuinity - soft async catcher - final NextTickListEntry entry = new NextTickListEntry<>(pos, data, targetTick, priority); - if (this.excludeFromScheduling.test(entry.getData())) { - return; -@@ -473,6 +477,7 @@ public final class PaperTickList extends TickListServer { // extend to avo - - @Override - public List> getEntriesInBoundingBox(final StructureBoundingBox structureboundingbox, final boolean removeReturned, final boolean excludeTicked) { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("async tick list get in bounding box"); // Tuinity - soft async catcher - if (structureboundingbox.getMinX() == structureboundingbox.getMaxX() || structureboundingbox.getMinZ() == structureboundingbox.getMaxZ()) { - return Collections.emptyList(); // vanilla behaviour, check isBlockInSortof above - } -@@ -529,6 +534,7 @@ public final class PaperTickList extends TickListServer { // extend to avo - - @Override - public void copy(StructureBoundingBox structureboundingbox, BlockPosition blockposition) { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("async tick list copy"); // Tuinity - soft async catcher - // start copy from TickListServer // TODO check on update - List> list = this.getEntriesInBoundingBox(structureboundingbox, false, false); - Iterator> iterator = list.iterator(); -@@ -548,6 +554,7 @@ public final class PaperTickList extends TickListServer { // extend to avo - - @Override - public List> getEntriesInChunk(ChunkCoordIntPair chunkPos, boolean removeReturned, boolean excludeTicked) { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("async tick list get"); // Tuinity - soft async catcher - // Vanilla DOES get the entries 2 blocks out of the chunk too, but that doesn't matter since we ignore chunks - // not at ticking status, and ticking status requires neighbours loaded - // so with this method we will reduce scheduler churning -@@ -579,6 +586,7 @@ public final class PaperTickList extends TickListServer { // extend to avo - - @Override - public NBTTagList serialize(ChunkCoordIntPair chunkcoordintpair) { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("async tick list serialize"); // Tuinity - soft async catcher - // start copy from TickListServer // TODO check on update - List> list = this.getEntriesInChunk(chunkcoordintpair, false, true); - -@@ -588,6 +596,7 @@ public final class PaperTickList extends TickListServer { // extend to avo - - @Override - public int getTotalScheduledEntries() { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("async tick list get size"); // Tuinity - soft async catcher - // good thing this is only used in debug reports // TODO check on update - int ret = 0; - -diff --git a/src/main/java/com/tuinity/tuinity/chunk/SingleThreadChunkRegionManager.java b/src/main/java/com/tuinity/tuinity/chunk/SingleThreadChunkRegionManager.java -new file mode 100644 -index 000000000..97c4100c5 ---- /dev/null -+++ b/src/main/java/com/tuinity/tuinity/chunk/SingleThreadChunkRegionManager.java -@@ -0,0 +1,159 @@ -+package com.tuinity.tuinity.chunk; -+ -+import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -+import it.unimi.dsi.fastutil.longs.LongIterator; -+import it.unimi.dsi.fastutil.longs.LongOpenHashSet; -+import net.minecraft.server.MCUtil; -+import net.minecraft.server.WorldServer; -+import java.util.List; -+ -+public final class SingleThreadChunkRegionManager { -+ -+ static final int REGION_SECTION_MERGE_RADIUS = 1; -+ -+ static final int REGION_SECTION_CHUNK_SIZE = 8; -+ static final int REGION_SECTION_CHUNK_SIZE_SHIFT = 3; -+ -+ final Long2ObjectOpenHashMap regionsBySection = new Long2ObjectOpenHashMap<>(4096, 0.25f); -+ final LongOpenHashSet chunks = new LongOpenHashSet(8192, 0.25f); -+ -+ public final WorldServer world; -+ -+ public SingleThreadChunkRegionManager(final WorldServer world) { -+ this.world = world; -+ } -+ -+ public void addChunk(final int chunkX, final int chunkZ) { -+ this.addChunk(chunkX, chunkZ, true); -+ } -+ -+ void addChunk(final int chunkX, final int chunkZ, boolean addToChunks) { -+ final long coordinate = MCUtil.getCoordinateKey(chunkX, chunkZ); -+ final long sectionPos = MCUtil.getCoordinateKey(chunkX >> REGION_SECTION_CHUNK_SIZE_SHIFT, chunkZ >> REGION_SECTION_CHUNK_SIZE_SHIFT); -+ if (addToChunks) { -+ this.chunks.add(coordinate); -+ } -+ -+ // merge nearby regions first -+ -+ // gather regions to merge -+ -+ SingleThreadChunkRegionManager.ChunkRegion mergeIntoCandidate = null; -+ int mergeCandidateChunkCount = -1; -+ -+ List toMerge = null; -+ -+ final int regionSectionX = chunkX >> REGION_SECTION_CHUNK_SIZE_SHIFT; -+ final int regionSectionZ = chunkZ >> REGION_SECTION_CHUNK_SIZE_SHIFT; -+ -+ final int checkXStart = regionSectionX - REGION_SECTION_MERGE_RADIUS; -+ final int checkZStart = regionSectionZ - REGION_SECTION_MERGE_RADIUS; -+ final int checkXEnd = regionSectionX + REGION_SECTION_MERGE_RADIUS; -+ final int checkZEnd = regionSectionZ + REGION_SECTION_MERGE_RADIUS; -+ -+ // select the ideal region to merge into -+ for (int checkX = checkXStart; checkX <= checkXEnd; ++checkX) { -+ for (int checkZ = checkZStart; checkZ <= checkZEnd; ++checkZ) { -+ final SingleThreadChunkRegionManager.ChunkRegion region = this.regionsBySection.get(MCUtil.getCoordinateKey(checkX, checkZ)); -+ if (region == null) { -+ continue; -+ } -+ -+ final int coordinateSize = region.coordinates.size(); -+ if (coordinateSize > mergeCandidateChunkCount) { -+ mergeIntoCandidate = region; -+ mergeCandidateChunkCount = coordinateSize; -+ } -+ if (toMerge == null) { -+ toMerge = new java.util.ArrayList<>(4); -+ toMerge.add(region); -+ } -+ } -+ } -+ -+ // merge -+ if (toMerge != null) { -+ for (int i = 0, len = toMerge.size(); i < len; ++i) { -+ final SingleThreadChunkRegionManager.ChunkRegion needsMerge = toMerge.get(i); -+ if (needsMerge == mergeIntoCandidate) { -+ continue; -+ } -+ // this function forwards the sections -+ needsMerge.mergeInto(this, mergeIntoCandidate); -+ } -+ } else { -+ mergeIntoCandidate = new ChunkRegion(); -+ } -+ -+ mergeIntoCandidate.addChunk(coordinate); -+ if (mergeIntoCandidate.addSection(sectionPos)) { -+ this.regionsBySection.put(sectionPos, mergeIntoCandidate); -+ } -+ } -+ -+ public void removeChunk(final int chunkX, final int chunkZ) { -+ final long coordinate = MCUtil.getCoordinateKey(chunkX, chunkZ); -+ final long sectionPos = MCUtil.getCoordinateKey(chunkX >> REGION_SECTION_CHUNK_SIZE_SHIFT, chunkZ >> REGION_SECTION_CHUNK_SIZE_SHIFT); -+ this.chunks.remove(coordinate); -+ -+ final SingleThreadChunkRegionManager.ChunkRegion region = this.regionsBySection.get(sectionPos); -+ if (region == null) { -+ throw new IllegalStateException("Cannot remove chunk form no region"); -+ } -+ -+ if (!region.removeChunk(coordinate)) { -+ throw new IllegalStateException("Cannot remove chunk from region, has no chunk"); -+ } -+ } -+ -+ public void recalculateRegions() { -+ this.regionsBySection.clear(); -+ for (final LongIterator iterator = this.chunks.iterator(); iterator.hasNext();) { -+ final long coordinate = iterator.nextLong(); -+ this.addChunk(MCUtil.getCoordinateX(coordinate), MCUtil.getCoordinateZ(coordinate), false); -+ } -+ } -+ -+ static final class ChunkRegion { -+ private final LongOpenHashSet coordinates = new LongOpenHashSet(); -+ private final LongOpenHashSet sections = new LongOpenHashSet(); -+ private boolean dead; -+ -+ public void mergeInto(final SingleThreadChunkRegionManager regionManager, final ChunkRegion region) { -+ if (region.dead) { -+ throw new IllegalStateException("Attempting to merge into a dead region"); -+ } else if (this.dead) { -+ throw new IllegalStateException("Attempting to merge from a dead region"); -+ } -+ -+ for (final LongIterator iterator = this.coordinates.iterator(); iterator.hasNext();) { -+ final long coordinate = iterator.nextLong(); -+ if (!region.addChunk(coordinate)) { -+ throw new IllegalStateException("Regions cannot share chunks"); -+ } -+ } -+ -+ for (final LongIterator iterator = this.sections.iterator(); iterator.hasNext();) { -+ regionManager.regionsBySection.replace(iterator.nextLong(), region); -+ } -+ -+ this.dead = true; -+ } -+ -+ boolean addSection(final long sectionPos) { -+ return this.sections.add(sectionPos); -+ } -+ -+ boolean removeSection(final long sectionPos) { -+ return this.sections.remove(sectionPos); -+ } -+ -+ boolean addChunk(final long coordinate) { -+ return this.coordinates.add(coordinate); -+ } -+ -+ boolean removeChunk(final long coordinate) { -+ return this.coordinates.remove(coordinate); -+ } -+ } -+} -\ No newline at end of file -diff --git a/src/main/java/com/tuinity/tuinity/config/TuinityConfig.java b/src/main/java/com/tuinity/tuinity/config/TuinityConfig.java -new file mode 100644 -index 000000000..1ae1fd750 ---- /dev/null -+++ b/src/main/java/com/tuinity/tuinity/config/TuinityConfig.java -@@ -0,0 +1,277 @@ -+package com.tuinity.tuinity.config; -+ -+import com.destroystokyo.paper.util.SneakyThrow; -+import net.minecraft.server.TicketType; -+import org.bukkit.Bukkit; -+import org.bukkit.configuration.ConfigurationSection; -+import org.bukkit.configuration.file.YamlConfiguration; -+import java.io.File; -+import java.lang.reflect.Method; -+import java.lang.reflect.Modifier; -+import java.util.List; -+import java.util.logging.Level; -+ -+public final class TuinityConfig { -+ -+ public static final String CONFIG_HEADER = "Configuration file for Tuinity."; -+ public static final int CURRENT_CONFIG_VERSION = 2; -+ -+ private static final Object[] EMPTY = new Object[0]; -+ -+ private static File configFile; -+ public static YamlConfiguration config; -+ private static int configVersion; -+ -+ public static void init(final File file) { -+ // TODO remove this in the future... -+ final File tuinityConfig = new File(file.getParent(), "tuinity.yml"); -+ if (!tuinityConfig.exists()) { -+ final File oldConfig = new File(file.getParent(), "concrete.yml"); -+ oldConfig.renameTo(tuinityConfig); -+ } -+ TuinityConfig.configFile = file; -+ final YamlConfiguration config = new YamlConfiguration(); -+ config.options().header(CONFIG_HEADER); -+ config.options().copyDefaults(true); -+ -+ if (!file.exists()) { -+ try { -+ file.createNewFile(); -+ } catch (final Exception ex) { -+ Bukkit.getLogger().log(Level.SEVERE, "Failure to create tuinity config", ex); -+ } -+ } else { -+ try { -+ config.load(file); -+ } catch (final Exception ex) { -+ Bukkit.getLogger().log(Level.SEVERE, "Failure to load tuinity config", ex); -+ SneakyThrow.sneaky(ex); /* Rethrow, this is critical */ -+ throw new RuntimeException(ex); // unreachable -+ } -+ } -+ -+ TuinityConfig.load(config); -+ } -+ -+ public static void load(final YamlConfiguration config) { -+ TuinityConfig.config = config; -+ TuinityConfig.configVersion = TuinityConfig.getInt("config-version-please-do-not-modify-me", CURRENT_CONFIG_VERSION); -+ TuinityConfig.set("config-version-please-do-not-modify-me", CURRENT_CONFIG_VERSION); -+ -+ for (final Method method : TuinityConfig.class.getDeclaredMethods()) { -+ if (method.getReturnType() != void.class || method.getParameterCount() != 0 || -+ !Modifier.isPrivate(method.getModifiers()) || !Modifier.isStatic(method.getModifiers())) { -+ continue; -+ } -+ -+ try { -+ method.setAccessible(true); -+ method.invoke(null, EMPTY); -+ } catch (final Exception ex) { -+ SneakyThrow.sneaky(ex); /* Rethrow, this is critical */ -+ throw new RuntimeException(ex); // unreachable -+ } -+ } -+ -+ /* We re-save to add new options */ -+ try { -+ config.save(TuinityConfig.configFile); -+ } catch (final Exception ex) { -+ Bukkit.getLogger().log(Level.SEVERE, "Unable to save tuinity config", ex); -+ } -+ } -+ -+ static void set(final String path, final Object value) { -+ TuinityConfig.config.set(path, value); -+ } -+ -+ static boolean getBoolean(final String path, final boolean dfl) { -+ TuinityConfig.config.addDefault(path, Boolean.valueOf(dfl)); -+ return TuinityConfig.config.getBoolean(path, dfl); -+ } -+ -+ static int getInt(final String path, final int dfl) { -+ TuinityConfig.config.addDefault(path, Integer.valueOf(dfl)); -+ return TuinityConfig.config.getInt(path, dfl); -+ } -+ -+ static long getLong(final String path, final long dfl) { -+ TuinityConfig.config.addDefault(path, Long.valueOf(dfl)); -+ return TuinityConfig.config.getLong(path, dfl); -+ } -+ -+ static double getDouble(final String path, final double dfl) { -+ TuinityConfig.config.addDefault(path, Double.valueOf(dfl)); -+ return TuinityConfig.config.getDouble(path, dfl); -+ } -+ -+ public static boolean tickWorldsInParallel; -+ -+ /** -+ * if tickWorldsInParallel == true, then this value is used as a default only for worlds -+ */ -+ public static int tickThreads; -+ -+ /* -+ private static void worldticking() { -+ tickWorldsInParallel = TuinityConfig.getBoolean("tick-worlds-in-parallel", false); -+ tickThreads = TuinityConfig.getInt("server-tick-threads", 1); // will be 4 in the future -+ }*/ -+ -+ public static int delayChunkUnloadsBy; -+ -+ private static void delayChunkUnloadsBy() { -+ delayChunkUnloadsBy = TuinityConfig.getInt("delay-chunkunloads-by", 1) * 20; -+ if (delayChunkUnloadsBy >= 0) { -+ TicketType.DELAYED_UNLOAD.loadPeriod = delayChunkUnloadsBy; -+ } -+ } -+ -+ public static boolean lagCompensateBlockBreaking; -+ -+ private static void lagCompensateBlockBreaking() { -+ lagCompensateBlockBreaking = TuinityConfig.getBoolean("lag-compensate-block-breaking", true); -+ } -+ -+ public static boolean pistonsCanPushTileEntities; -+ -+ private static void pistonsCanPushTileEntities() { -+ pistonsCanPushTileEntities = TuinityConfig.getBoolean("pistons-can-push-tile-entities", false); -+ } -+ -+ public static final class WorldConfig { -+ -+ public final String worldName; -+ public ConfigurationSection config; -+ ConfigurationSection worldDefaults; -+ -+ public WorldConfig(final String worldName) { -+ this.worldName = worldName; -+ this.init(); -+ } -+ -+ public void init() { -+ this.worldDefaults = TuinityConfig.config.getConfigurationSection("world-settings.default"); -+ if (this.worldDefaults == null) { -+ this.worldDefaults = TuinityConfig.config.createSection("world-settings.default"); -+ } -+ -+ String worldSectionPath = TuinityConfig.configVersion < 1 ? this.worldName : "world-settings.".concat(this.worldName); -+ ConfigurationSection section = TuinityConfig.config.getConfigurationSection(worldSectionPath); -+ if (section == null) { -+ section = TuinityConfig.config.createSection(worldSectionPath); -+ } -+ TuinityConfig.config.set(worldSectionPath, section); -+ -+ this.load(section); -+ } -+ -+ public void load(final ConfigurationSection config) { -+ this.config = config; -+ -+ for (final Method method : TuinityConfig.WorldConfig.class.getDeclaredMethods()) { -+ if (method.getReturnType() != void.class || method.getParameterCount() != 0 || -+ !Modifier.isPrivate(method.getModifiers()) || Modifier.isStatic(method.getModifiers())) { -+ continue; -+ } -+ -+ try { -+ method.setAccessible(true); -+ method.invoke(this, EMPTY); -+ } catch (final Exception ex) { -+ SneakyThrow.sneaky(ex); /* Rethrow, this is critical */ -+ throw new RuntimeException(ex); // unreachable -+ } -+ } -+ -+ if (TuinityConfig.configVersion < 1) { -+ ConfigurationSection oldSection = TuinityConfig.config.getConfigurationSection(this.worldName); -+ TuinityConfig.config.set("world-settings.".concat(this.worldName), oldSection); -+ TuinityConfig.config.set(this.worldName, null); -+ } -+ -+ /* We re-save to add new options */ -+ try { -+ TuinityConfig.config.save(TuinityConfig.configFile); -+ } catch (final Exception ex) { -+ Bukkit.getLogger().log(Level.SEVERE, "Unable to save tuinity config", ex); -+ } -+ } -+ -+ /** -+ * update world defaults for the specified path, but also sets this world's config value for the path -+ * if it exists -+ */ -+ void set(final String path, final Object val) { -+ this.worldDefaults.set(path, val); -+ if (this.config.get(path) != null) { -+ this.config.set(path, val); -+ } -+ } -+ -+ boolean getBoolean(final String path, final boolean dfl) { -+ this.worldDefaults.addDefault(path, Boolean.valueOf(dfl)); -+ if (TuinityConfig.configVersion < 1) { -+ if (this.config.getBoolean(path) == dfl) { -+ this.config.set(path, null); -+ } -+ } -+ return this.config.getBoolean(path, this.worldDefaults.getBoolean(path)); -+ } -+ -+ int getInt(final String path, final int dfl) { -+ this.worldDefaults.addDefault(path, Integer.valueOf(dfl)); -+ if (TuinityConfig.configVersion < 1) { -+ if (this.config.getInt(path) == dfl) { -+ this.config.set(path, null); -+ } -+ } -+ return this.config.getInt(path, this.worldDefaults.getInt(path)); -+ } -+ -+ long getLong(final String path, final long dfl) { -+ this.worldDefaults.addDefault(path, Long.valueOf(dfl)); -+ if (TuinityConfig.configVersion < 1) { -+ if (this.config.getLong(path) == dfl) { -+ this.config.set(path, null); -+ } -+ } -+ return this.config.getLong(path, this.worldDefaults.getLong(path)); -+ } -+ -+ double getDouble(final String path, final double dfl) { -+ this.worldDefaults.addDefault(path, Double.valueOf(dfl)); -+ if (TuinityConfig.configVersion < 1) { -+ if (this.config.getDouble(path) == dfl) { -+ this.config.set(path, null); -+ } -+ } -+ return this.config.getDouble(path, this.worldDefaults.getDouble(path)); -+ } -+ -+ /** ignored if {@link TuinityConfig#tickWorldsInParallel} == false */ -+ public int threads; -+ -+ /* -+ private void worldthreading() { -+ final int threads = this.getInt("tick-threads", -1); -+ this.threads = threads == -1 ? TuinityConfig.tickThreads : threads; -+ }*/ -+ -+ public int spawnLimitMonsters; -+ public int spawnLimitAnimals; -+ public int spawnLimitWaterAnimals; -+ public int spawnLimitAmbient; -+ -+ private void perWorldSpawnLimit() { -+ final String path = "spawn-limits"; -+ -+ this.spawnLimitMonsters = this.getInt(path + ".monsters", -1); -+ this.spawnLimitAnimals = this.getInt(path + ".animals", -1); -+ this.spawnLimitWaterAnimals = this.getInt(path + ".water-animals", -1); -+ this.spawnLimitAmbient = this.getInt(path + ".ambient", -1); -+ } -+ -+ } -+ -+} -\ No newline at end of file -diff --git a/src/main/java/com/tuinity/tuinity/util/CachedLists.java b/src/main/java/com/tuinity/tuinity/util/CachedLists.java -new file mode 100644 -index 000000000..a54f516ba ---- /dev/null -+++ b/src/main/java/com/tuinity/tuinity/util/CachedLists.java -@@ -0,0 +1,53 @@ -+package com.tuinity.tuinity.util; -+ -+import net.minecraft.server.AxisAlignedBB; -+import net.minecraft.server.Entity; -+import org.bukkit.Bukkit; -+import org.bukkit.craftbukkit.util.UnsafeList; -+import java.util.List; -+ -+public class CachedLists { -+ -+ static final UnsafeList TEMP_COLLISION_LIST = new UnsafeList<>(1024); -+ static boolean tempCollisionListInUse; -+ -+ public static List getTempCollisionList() { -+ if (!Bukkit.isPrimaryThread() || tempCollisionListInUse) { -+ return new UnsafeList<>(16); -+ } -+ tempCollisionListInUse = true; -+ return TEMP_COLLISION_LIST; -+ } -+ -+ public static void returnTempCollisionList(List list) { -+ if (list != TEMP_COLLISION_LIST) { -+ return; -+ } -+ ((UnsafeList)list).setSize(0); -+ tempCollisionListInUse = false; -+ } -+ -+ static final UnsafeList TEMP_GET_ENTITIES_LIST = new UnsafeList<>(1024); -+ static boolean tempGetEntitiesListInUse; -+ -+ public static List getTempGetEntitiesList() { -+ if (!Bukkit.isPrimaryThread() || tempGetEntitiesListInUse) { -+ return new UnsafeList<>(16); -+ } -+ tempGetEntitiesListInUse = true; -+ return TEMP_GET_ENTITIES_LIST; -+ } -+ -+ public static void returnTempGetEntitiesList(List list) { -+ if (list != TEMP_GET_ENTITIES_LIST) { -+ return; -+ } -+ ((UnsafeList)list).setSize(0); -+ tempGetEntitiesListInUse = false; -+ } -+ -+ public static void reset() { -+ TEMP_COLLISION_LIST.completeReset(); -+ TEMP_GET_ENTITIES_LIST.completeReset(); -+ } -+} -diff --git a/src/main/java/com/tuinity/tuinity/util/TickThread.java b/src/main/java/com/tuinity/tuinity/util/TickThread.java -new file mode 100644 -index 000000000..08ed24325 ---- /dev/null -+++ b/src/main/java/com/tuinity/tuinity/util/TickThread.java -@@ -0,0 +1,41 @@ -+package com.tuinity.tuinity.util; -+ -+import net.minecraft.server.MinecraftServer; -+import org.bukkit.Bukkit; -+ -+public final class TickThread extends Thread { -+ -+ public static final boolean STRICT_THREAD_CHECKS = Boolean.getBoolean("tuinity.strict-thread-checks"); -+ -+ static { -+ if (STRICT_THREAD_CHECKS) { -+ MinecraftServer.LOGGER.warn("Strict thread checks enabled - performance may suffer"); -+ } -+ } -+ -+ public static void softEnsureTickThread(final String reason) { -+ if (!STRICT_THREAD_CHECKS) { -+ return; -+ } -+ ensureTickThread(reason); -+ } -+ -+ -+ public static void ensureTickThread(final String reason) { -+ if (!Bukkit.isPrimaryThread()) { -+ MinecraftServer.LOGGER.fatal("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); -+ throw new IllegalStateException(reason); -+ } -+ } -+ -+ public final int id; /* We don't override getId as the spec requires that it be unique (with respect to all other threads) */ -+ -+ public TickThread(final Runnable run, final String name, final int id) { -+ super(run, name); -+ this.id = id; -+ } -+ -+ public static TickThread getCurrentTickThread() { -+ return (TickThread)Thread.currentThread(); -+ } -+} -\ No newline at end of file -diff --git a/src/main/java/com/tuinity/tuinity/util/maplist/IteratorSafeOrderedReferenceSet.java b/src/main/java/com/tuinity/tuinity/util/maplist/IteratorSafeOrderedReferenceSet.java -new file mode 100644 -index 000000000..e12d09645 ---- /dev/null -+++ b/src/main/java/com/tuinity/tuinity/util/maplist/IteratorSafeOrderedReferenceSet.java -@@ -0,0 +1,265 @@ -+package com.tuinity.tuinity.util.maplist; -+ -+import it.unimi.dsi.fastutil.objects.Reference2IntLinkedOpenHashMap; -+import it.unimi.dsi.fastutil.objects.Reference2IntMap; -+import it.unimi.dsi.fastutil.objects.ReferenceLinkedOpenHashSet; -+import java.util.Arrays; -+import java.util.NoSuchElementException; -+ -+public final class IteratorSafeOrderedReferenceSet { -+ -+ protected final Reference2IntLinkedOpenHashMap indexMap; -+ protected int firstInvalidIndex = -1; -+ -+ protected final ReferenceLinkedOpenHashSet pendingAdditions; -+ -+ /* list impl */ -+ protected E[] listElements; -+ protected int listSize; -+ -+ protected final double maxFragFactor; -+ -+ protected int iteratorCount; -+ -+ public IteratorSafeOrderedReferenceSet() { -+ this(16, 0.75f, 16, 0.2); -+ } -+ -+ public IteratorSafeOrderedReferenceSet(final int setCapacity, final float setLoadFactor, final int arrayCapacity, final double maxFragFactor) { -+ this.indexMap = new Reference2IntLinkedOpenHashMap<>(setCapacity, setLoadFactor); -+ this.indexMap.defaultReturnValue(-1); -+ this.pendingAdditions = new ReferenceLinkedOpenHashSet<>(); -+ this.maxFragFactor = maxFragFactor; -+ this.listElements = (E[])new Object[arrayCapacity]; -+ } -+ -+ protected final double getFragFactor() { -+ return 1.0 - ((double)this.indexMap.size() / (double)this.listSize); -+ } -+ -+ public int createRawIterator() { -+ ++this.iteratorCount; -+ if (this.indexMap.isEmpty()) { -+ return -1; -+ } else { -+ return this.firstInvalidIndex == 0 ? this.indexMap.getInt(this.indexMap.firstKey()) : 0; -+ } -+ } -+ -+ public int advanceRawIterator(final int index) { -+ final E[] elements = this.listElements; -+ int ret = index + 1; -+ for (int len = this.listSize; ret < len; ++ret) { -+ if (elements[ret] != null) { -+ return ret; -+ } -+ } -+ -+ return -1; -+ } -+ -+ public void finishRawIterator() { -+ if (--this.iteratorCount == 0) { -+ if (this.getFragFactor() >= this.maxFragFactor) { -+ this.defrag(); -+ } -+ if (!this.pendingAdditions.isEmpty()) { -+ int index = this.listSize; -+ int neededLen = index + this.pendingAdditions.size(); -+ -+ if (neededLen < 0) { -+ throw new IllegalStateException("Too large"); -+ } -+ -+ if (neededLen > this.listElements.length) { -+ this.listElements = Arrays.copyOf(this.listElements, neededLen * 2); -+ } -+ -+ final E[] elements = this.listElements; -+ java.util.Iterator iterator = this.pendingAdditions.iterator(); -+ for (int i = index; i < neededLen; ++i) { -+ final E element = iterator.next(); -+ elements[i] = element; -+ this.indexMap.put(element, i); -+ } -+ -+ this.pendingAdditions.clear(); -+ this.listSize = neededLen; -+ } -+ } -+ } -+ -+ public boolean remove(final E element) { -+ final int index = this.indexMap.removeInt(element); -+ if (index >= 0) { -+ if (this.firstInvalidIndex < 0 || index < this.firstInvalidIndex) { -+ this.firstInvalidIndex = index; -+ } -+ this.listElements[index] = null; -+ return true; -+ } else { -+ return this.pendingAdditions.remove(element); -+ } -+ } -+ -+ public boolean add(final E element) { -+ if (this.iteratorCount > 0) { -+ if (this.indexMap.containsKey(element)) { -+ return true; -+ } -+ return this.pendingAdditions.add(element); -+ } else { -+ final int listSize = this.listSize; -+ -+ final int previous = this.indexMap.putIfAbsent(element, listSize); -+ if (previous != -1) { -+ return false; -+ } -+ -+ if (listSize >= this.listElements.length) { -+ this.listElements = Arrays.copyOf(this.listElements, listSize * 2); -+ } -+ this.listElements[listSize] = element; -+ this.listSize = listSize + 1; -+ -+ return true; -+ } -+ } -+ -+ protected void defrag() { -+ if (this.firstInvalidIndex < 0) { -+ return; // nothing to do -+ } -+ -+ if (this.indexMap.isEmpty()) { -+ Arrays.fill(this.listElements, 0, this.listSize, null); -+ this.listSize = 0; -+ this.firstInvalidIndex = -1; -+ return; -+ } -+ -+ final E[] backingArray = this.listElements; -+ -+ int lastValidIndex; -+ java.util.Iterator> iterator; -+ -+ if (this.firstInvalidIndex == 0) { -+ iterator = this.indexMap.reference2IntEntrySet().fastIterator(); -+ lastValidIndex = 0; -+ } else { -+ lastValidIndex = this.firstInvalidIndex; -+ final E key = backingArray[lastValidIndex - 1]; -+ iterator = this.indexMap.reference2IntEntrySet().fastIterator(new Reference2IntMap.Entry() { -+ @Override -+ public int getIntValue() { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ public int setValue(int i) { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ public E getKey() { -+ return key; -+ } -+ }); -+ } -+ -+ while (iterator.hasNext()) { -+ final Reference2IntMap.Entry entry = iterator.next(); -+ -+ final int newIndex = lastValidIndex++; -+ backingArray[newIndex] = entry.getKey(); -+ entry.setValue(newIndex); -+ } -+ -+ // cleanup end -+ Arrays.fill(backingArray, lastValidIndex, this.listSize, null); -+ this.listSize = lastValidIndex; -+ this.firstInvalidIndex = -1; -+ } -+ -+ public E rawGet(final int index) { -+ return this.listElements[index]; -+ } -+ -+ public int size() { -+ // always returns the correct amount - listSize can be different -+ return this.indexMap.size(); -+ } -+ -+ public IteratorSafeOrderedReferenceSet.Iterator iterator() { -+ ++this.iteratorCount; -+ return new BaseIterator<>(this); -+ } -+ -+ public static interface Iterator extends java.util.Iterator { -+ -+ public void finishedIterating(); -+ -+ } -+ -+ protected static final class BaseIterator implements IteratorSafeOrderedReferenceSet.Iterator { -+ -+ protected final IteratorSafeOrderedReferenceSet set; -+ protected int nextIndex; -+ protected E currentValue; -+ protected boolean finished; -+ -+ protected BaseIterator(final IteratorSafeOrderedReferenceSet set) { -+ this.set = set; -+ } -+ -+ @Override -+ public boolean hasNext() { -+ if (this.finished) { -+ return false; -+ } -+ if (this.currentValue != null) { -+ return true; -+ } -+ -+ final E[] elements = this.set.listElements; -+ int index, len; -+ for (index = this.nextIndex, len = this.set.listSize; index < len; ++index) { -+ final E element = elements[index]; -+ if (element != null) { -+ this.currentValue = element; -+ this.nextIndex = index + 1; -+ return true; -+ } -+ } -+ -+ this.nextIndex = index; -+ return false; -+ } -+ -+ @Override -+ public E next() { -+ if (!this.hasNext()) { -+ throw new NoSuchElementException(); -+ } -+ final E ret = this.currentValue; -+ -+ this.currentValue = null; -+ -+ return ret; -+ } -+ -+ @Override -+ public void remove() { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ public void finishedIterating() { -+ if (this.finished) { -+ throw new IllegalStateException(); -+ } -+ this.finished = true; -+ this.set.finishRawIterator(); -+ } -+ } -+} -diff --git a/src/main/java/com/tuinity/tuinity/voxel/AABBVoxelShape.java b/src/main/java/com/tuinity/tuinity/voxel/AABBVoxelShape.java -new file mode 100644 -index 000000000..76593df29 ---- /dev/null -+++ b/src/main/java/com/tuinity/tuinity/voxel/AABBVoxelShape.java -@@ -0,0 +1,246 @@ -+package com.tuinity.tuinity.voxel; -+ -+import it.unimi.dsi.fastutil.doubles.DoubleArrayList; -+import it.unimi.dsi.fastutil.doubles.DoubleList; -+import net.minecraft.server.AxisAlignedBB; -+import net.minecraft.server.EnumDirection; -+import net.minecraft.server.VoxelShape; -+import net.minecraft.server.VoxelShapes; -+import java.util.ArrayList; -+import java.util.List; -+ -+public final class AABBVoxelShape extends VoxelShape { -+ -+ public final AxisAlignedBB aabb; -+ private boolean isEmpty; -+ -+ public AABBVoxelShape(AxisAlignedBB aabb) { -+ super(VoxelShapes.getFullUnoptimisedCube().getShape()); -+ this.aabb = aabb; -+ this.isEmpty = (fuzzyEquals(aabb.minX, aabb.maxX) && fuzzyEquals(aabb.minY, aabb.maxY) && fuzzyEquals(aabb.minZ, aabb.maxZ)); -+ } -+ -+ static boolean fuzzyEquals(double d0, double d1) { -+ return Math.abs(d0 - d1) <= 1.0e-7; -+ } -+ -+ @Override -+ public boolean isEmpty() { -+ return this.isEmpty; -+ } -+ -+ @Override -+ public double b(EnumDirection.EnumAxis enumdirection_enumaxis) { // getMin -+ switch (enumdirection_enumaxis.ordinal()) { -+ case 0: -+ return this.aabb.minX; -+ case 1: -+ return this.aabb.minY; -+ case 2: -+ return this.aabb.minZ; -+ default: -+ throw new IllegalStateException("Unknown axis requested"); -+ } -+ } -+ -+ @Override -+ public double c(EnumDirection.EnumAxis enumdirection_enumaxis) { //getMax -+ switch (enumdirection_enumaxis.ordinal()) { -+ case 0: -+ return this.aabb.maxX; -+ case 1: -+ return this.aabb.maxY; -+ case 2: -+ return this.aabb.maxZ; -+ default: -+ throw new IllegalStateException("Unknown axis requested"); -+ } -+ } -+ -+ @Override -+ public AxisAlignedBB getBoundingBox() { // rets bounding box enclosing this entire shape -+ return this.aabb; -+ } -+ -+ // enum direction axis is from 0 -> 2, so we keep the lower bits for direction axis. -+ @Override -+ protected double a(EnumDirection.EnumAxis enumdirection_enumaxis, int i) { // getPointFromIndex -+ switch (enumdirection_enumaxis.ordinal() | (i << 2)) { -+ case (0 | (0 << 2)): -+ return this.aabb.minX; -+ case (1 | (0 << 2)): -+ return this.aabb.minY; -+ case (2 | (0 << 2)): -+ return this.aabb.minZ; -+ case (0 | (1 << 2)): -+ return this.aabb.maxX; -+ case (1 | (1 << 2)): -+ return this.aabb.maxY; -+ case (2 | (1 << 2)): -+ return this.aabb.maxZ; -+ default: -+ throw new IllegalStateException("Unknown axis requested"); -+ } -+ } -+ -+ private DoubleList cachedListX; -+ private DoubleList cachedListY; -+ private DoubleList cachedListZ; -+ -+ @Override -+ protected DoubleList a(EnumDirection.EnumAxis enumdirection_enumaxis) { // getPoints -+ switch (enumdirection_enumaxis.ordinal()) { -+ case 0: -+ return this.cachedListX == null ? this.cachedListX = DoubleArrayList.wrap(new double[] { this.aabb.minX, this.aabb.maxX }) : this.cachedListX; -+ case 1: -+ return this.cachedListY == null ? this.cachedListY = DoubleArrayList.wrap(new double[] { this.aabb.minY, this.aabb.maxY }) : this.cachedListY; -+ case 2: -+ return this.cachedListZ == null ? this.cachedListZ = DoubleArrayList.wrap(new double[] { this.aabb.minZ, this.aabb.maxZ }) : this.cachedListZ; -+ default: -+ throw new IllegalStateException("Unknown axis requested"); -+ } -+ } -+ -+ @Override -+ public VoxelShape a(double d0, double d1, double d2) { // createOffset -+ return new AABBVoxelShape(this.aabb.offset(d0, d1, d2)); -+ } -+ -+ @Override -+ public VoxelShape c() { // simplify -+ return this; -+ } -+ -+ @Override -+ public void b(VoxelShapes.a voxelshapes_a) { // forEachAABB -+ voxelshapes_a.consume(this.aabb.minX, this.aabb.minY, this.aabb.minZ, this.aabb.maxX, this.aabb.maxY, this.aabb.maxZ); -+ } -+ -+ @Override -+ public List d() { // getAABBs -+ List ret = new ArrayList<>(1); -+ ret.add(this.aabb); -+ return ret; -+ } -+ -+ @Override -+ protected int a(EnumDirection.EnumAxis enumdirection_enumaxis, double d0) { // findPointIndexAfterOffset -+ switch (enumdirection_enumaxis.ordinal()) { -+ case 0: -+ return d0 < this.aabb.maxX ? (d0 < this.aabb.minX ? -1 : 0) : 1; -+ case 1: -+ return d0 < this.aabb.maxY ? (d0 < this.aabb.minY ? -1 : 0) : 1; -+ case 2: -+ return d0 < this.aabb.maxZ ? (d0 < this.aabb.minZ ? -1 : 0) : 1; -+ default: -+ throw new IllegalStateException("Unknown axis requested"); -+ } -+ } -+ -+ @Override -+ protected boolean b(double d0, double d1, double d2) { // containsPoint -+ return this.aabb.contains(d0, d1, d2); -+ } -+ -+ @Override -+ public VoxelShape a(EnumDirection enumdirection) { // unknown -+ return super.a(enumdirection); -+ } -+ -+ @Override -+ public double a(EnumDirection.EnumAxis enumdirection_enumaxis, AxisAlignedBB axisalignedbb, double d0) { // collide -+ if (this.isEmpty) { -+ return d0; -+ } -+ if (Math.abs(d0) < 1.0e-7) { -+ return 0.0; -+ } -+ switch (enumdirection_enumaxis.ordinal()) { -+ case 0: -+ return this.collideX(axisalignedbb, d0); -+ case 1: -+ return this.collideY(axisalignedbb, d0); -+ case 2: -+ return this.collideZ(axisalignedbb, d0); -+ default: -+ throw new IllegalStateException("Unknown axis requested"); -+ } -+ } -+ -+ // collideX, collideY, collideZ are copied from 1.12 src and remapped -+ // so the code all belongs to mojang -+ -+ public double collideX(AxisAlignedBB axisalignedbb, double d0) { -+ if (axisalignedbb.maxY > this.aabb.minY && axisalignedbb.minY < this.aabb.maxY -+ && axisalignedbb.maxZ > this.aabb.minZ && axisalignedbb.minZ < this.aabb.maxZ) { -+ double d1; -+ -+ if (d0 > 0.0D && axisalignedbb.maxX <= this.aabb.minX) { -+ d1 = this.aabb.minX - axisalignedbb.maxX; -+ if (d1 < d0) { -+ d0 = d1; -+ } -+ } else if (d0 < 0.0D && axisalignedbb.minX >= this.aabb.maxX) { -+ d1 = this.aabb.maxX - axisalignedbb.minX; -+ if (d1 > d0) { -+ d0 = d1; -+ } -+ } -+ -+ return d0; -+ } else { -+ return d0; -+ } -+ } -+ -+ public double collideY(AxisAlignedBB axisalignedbb, double d0) { -+ if (axisalignedbb.maxX > this.aabb.minX && axisalignedbb.minX < this.aabb.maxX -+ && axisalignedbb.maxZ > this.aabb.minZ && axisalignedbb.minZ < this.aabb.maxZ) { -+ double d1; -+ -+ if (d0 > 0.0D && axisalignedbb.maxY <= this.aabb.minY) { -+ d1 = this.aabb.minY - axisalignedbb.maxY; -+ if (d1 < d0) { -+ d0 = d1; -+ } -+ } else if (d0 < 0.0D && axisalignedbb.minY >= this.aabb.maxY) { -+ d1 = this.aabb.maxY - axisalignedbb.minY; -+ if (d1 > d0) { -+ d0 = d1; -+ } -+ } -+ -+ return d0; -+ } else { -+ return d0; -+ } -+ } -+ -+ public double collideZ(AxisAlignedBB axisalignedbb, double d0) { -+ if (axisalignedbb.maxX > this.aabb.minX && axisalignedbb.minX < this.aabb.maxX -+ && axisalignedbb.maxY > this.aabb.minY && axisalignedbb.minY < this.aabb.maxY) { -+ double d1; -+ -+ if (d0 > 0.0D && axisalignedbb.maxZ <= this.aabb.minZ) { -+ d1 = this.aabb.minZ - axisalignedbb.maxZ; -+ if (d1 < d0) { -+ d0 = d1; -+ } -+ } else if (d0 < 0.0D && axisalignedbb.minZ >= this.aabb.maxZ) { -+ d1 = this.aabb.maxZ - axisalignedbb.minZ; -+ if (d1 > d0) { -+ d0 = d1; -+ } -+ } -+ -+ return d0; -+ } else { -+ return d0; -+ } -+ } -+ -+ @Override -+ public boolean intersects(AxisAlignedBB axisalingedbb) { -+ return this.aabb.intersects(axisalingedbb); -+ } -+} -diff --git a/src/main/java/net/minecraft/server/AxisAlignedBB.java b/src/main/java/net/minecraft/server/AxisAlignedBB.java -index 1a466e929..688c5b1bd 100644 ---- a/src/main/java/net/minecraft/server/AxisAlignedBB.java -+++ b/src/main/java/net/minecraft/server/AxisAlignedBB.java -@@ -13,6 +13,118 @@ public class AxisAlignedBB { - public final double maxY; - public final double maxZ; - -+ // Tuinity start -+ public final boolean isEmpty() { -+ return (this.maxX - this.minX) < 1.0E-7 && (this.maxY - this.minY) < 1.0E-7 && (this.maxZ - this.minZ) < 1.0E-7; -+ } -+ -+ public static AxisAlignedBB getBoxForChunk(int chunkX, int chunkZ) { -+ double x = (double)(chunkX << 4); -+ double z = (double)(chunkZ << 4); -+ return new AxisAlignedBB(x - 1.0E-7, 0.0, z - 1.0E-7, x + (16.0 + 1.0E-7), 255.0, z + (16.0 + 1.0E-7), false); -+ } -+ -+ // collideX, collideY, collideZ are copied from 1.12 src -+ // so the code all belongs to mojang -+ public double collideX(AxisAlignedBB axisalignedbb, double d0) { -+ if (axisalignedbb.maxY > this.minY && axisalignedbb.minY < this.maxY -+ && axisalignedbb.maxZ > this.minZ && axisalignedbb.minZ < this.maxZ) { -+ double d1; -+ -+ if (d0 > 0.0D && axisalignedbb.maxX <= this.minX) { -+ d1 = this.minX - axisalignedbb.maxX; -+ if (d1 < d0) { -+ d0 = d1; -+ } -+ } else if (d0 < 0.0D && axisalignedbb.minX >= this.maxX) { -+ d1 = this.maxX - axisalignedbb.minX; -+ if (d1 > d0) { -+ d0 = d1; -+ } -+ } -+ -+ return d0; -+ } else { -+ return d0; -+ } -+ } -+ -+ public double collideY(AxisAlignedBB axisalignedbb, double d0) { -+ if (axisalignedbb.maxX > this.minX && axisalignedbb.minX < this.maxX -+ && axisalignedbb.maxZ > this.minZ && axisalignedbb.minZ < this.maxZ) { -+ double d1; -+ -+ if (d0 > 0.0D && axisalignedbb.maxY <= this.minY) { -+ d1 = this.minY - axisalignedbb.maxY; -+ if (d1 < d0) { -+ d0 = d1; -+ } -+ } else if (d0 < 0.0D && axisalignedbb.minY >= this.maxY) { -+ d1 = this.maxY - axisalignedbb.minY; -+ if (d1 > d0) { -+ d0 = d1; -+ } -+ } -+ -+ return d0; -+ } else { -+ return d0; -+ } -+ } -+ -+ public double collideZ(AxisAlignedBB axisalignedbb, double d0) { -+ if (axisalignedbb.maxX > this.minX && axisalignedbb.minX < this.maxX -+ && axisalignedbb.maxY > this.minY && axisalignedbb.minY < this.maxY) { -+ double d1; -+ -+ if (d0 > 0.0D && axisalignedbb.maxZ <= this.minZ) { -+ d1 = this.minZ - axisalignedbb.maxZ; -+ if (d1 < d0) { -+ d0 = d1; -+ } -+ } else if (d0 < 0.0D && axisalignedbb.minZ >= this.maxZ) { -+ d1 = this.maxZ - axisalignedbb.minZ; -+ if (d1 > d0) { -+ d0 = d1; -+ } -+ } -+ -+ return d0; -+ } else { -+ return d0; -+ } -+ } -+ -+ public final AxisAlignedBB offsetX(double dx) { -+ return new AxisAlignedBB(this.minX + dx, this.minY, this.minZ, this.maxX + dx, this.maxY, this.maxZ, false); -+ } -+ -+ public final AxisAlignedBB offsetY(double dy) { -+ return new AxisAlignedBB(this.minX, this.minY + dy, this.minZ, this.maxX, this.maxY + dy, this.maxZ, false); -+ } -+ -+ public final AxisAlignedBB offsetZ(double dz) { -+ return new AxisAlignedBB(this.minX, this.minY, this.minZ + dz, this.maxX, this.maxY, this.maxZ + dz, false); -+ } -+ -+ public AxisAlignedBB(double d0, double d1, double d2, double d3, double d4, double d5, boolean dummy) { -+ this.minX = d0; -+ this.minY = d1; -+ this.minZ = d2; -+ this.maxX = d3; -+ this.maxY = d4; -+ this.maxZ = d5; -+ } -+ -+ public final AxisAlignedBB expandUpwards(double dy) { -+ return new AxisAlignedBB(this.minX, this.minY, this.minZ, this.maxX, this.maxY + dy, this.maxZ, false); -+ } -+ -+ public final AxisAlignedBB expandUpwardsAndCutBelow(double dy) { -+ return new AxisAlignedBB(this.minX, this.maxY, this.minZ, this.maxX, this.maxY + dy, this.maxZ, false); -+ } -+ // Tuinity end -+ - public AxisAlignedBB(double d0, double d1, double d2, double d3, double d4, double d5) { - this.minX = Math.min(d0, d3); - this.minY = Math.min(d1, d4); -@@ -181,6 +293,7 @@ public class AxisAlignedBB { - return new AxisAlignedBB(d0, d1, d2, d3, d4, d5); - } - -+ public final AxisAlignedBB offset(double d0, double d1, double d2) { return this.d(d0, d1, d2); } // Tuinity - OBFHELPER - public AxisAlignedBB d(double d0, double d1, double d2) { - return new AxisAlignedBB(this.minX + d0, this.minY + d1, this.minZ + d2, this.maxX + d0, this.maxY + d1, this.maxZ + d2); - } -@@ -189,6 +302,7 @@ public class AxisAlignedBB { - return new AxisAlignedBB(this.minX + (double) blockposition.getX(), this.minY + (double) blockposition.getY(), this.minZ + (double) blockposition.getZ(), this.maxX + (double) blockposition.getX(), this.maxY + (double) blockposition.getY(), this.maxZ + (double) blockposition.getZ()); - } - -+ public final AxisAlignedBB offset(Vec3D vec3d) { return this.b(vec3d); } // Tuinity - OBFHELPER - public AxisAlignedBB b(Vec3D vec3d) { - return this.d(vec3d.x, vec3d.y, vec3d.z); - } -@@ -208,6 +322,7 @@ public class AxisAlignedBB { - return this.e(vec3d.x, vec3d.y, vec3d.z); - } - -+ public final boolean contains(double d0, double d1, double d2) { return this.e(d0, d1, d2); } // Tuinity - OBFHELPER - public boolean e(double d0, double d1, double d2) { - return d0 >= this.minX && d0 < this.maxX && d1 >= this.minY && d1 < this.maxY && d2 >= this.minZ && d2 < this.maxZ; - } -diff --git a/src/main/java/net/minecraft/server/BiomeBase.java b/src/main/java/net/minecraft/server/BiomeBase.java -index 0102a170d..ef6c85557 100644 ---- a/src/main/java/net/minecraft/server/BiomeBase.java -+++ b/src/main/java/net/minecraft/server/BiomeBase.java -@@ -61,6 +61,18 @@ public abstract class BiomeBase { - return new WorldGenCarverWrapper<>(worldgencarverabstract, c0); - } - -+ // Tuinity start - optimise biome conversion -+ private org.bukkit.block.Biome bukkitBiome; -+ -+ public final org.bukkit.block.Biome getBukkitBiome() { -+ if (this.bukkitBiome == null) { -+ this.bukkitBiome = org.bukkit.block.Biome.valueOf(IRegistry.BIOME.getKey(this).getKey().toUpperCase(java.util.Locale.ENGLISH)); -+ } -+ -+ return this.bukkitBiome; -+ } -+ // Tuinity end - optimise biome conversion -+ - protected BiomeBase(BiomeBase.a biomebase_a) { - if (biomebase_a.a != null && biomebase_a.b != null && biomebase_a.c != null && biomebase_a.d != null && biomebase_a.e != null && biomebase_a.f != null && biomebase_a.g != null && biomebase_a.h != null && biomebase_a.i != null) { - this.n = biomebase_a.a; -diff --git a/src/main/java/net/minecraft/server/BlockChest.java b/src/main/java/net/minecraft/server/BlockChest.java -index 72fb92f7c..6ea29ffc0 100644 ---- a/src/main/java/net/minecraft/server/BlockChest.java -+++ b/src/main/java/net/minecraft/server/BlockChest.java -@@ -10,7 +10,7 @@ import javax.annotation.Nullable; - public class BlockChest extends BlockChestAbstract implements IBlockWaterlogged { - - public static final BlockStateDirection FACING = BlockFacingHorizontal.FACING; -- public static final BlockStateEnum c = BlockProperties.ay; -+ public static final BlockStateEnum c = BlockProperties.ay; public static final BlockStateEnum getChestTypeEnum() { return BlockChest.c; } // Tuinity - OBFHELPER - public static final BlockStateBoolean d = BlockProperties.C; - protected static final VoxelShape e = Block.a(1.0D, 0.0D, 0.0D, 15.0D, 14.0D, 15.0D); - protected static final VoxelShape f = Block.a(1.0D, 0.0D, 1.0D, 15.0D, 14.0D, 16.0D); -@@ -195,7 +195,7 @@ public class BlockChest extends BlockChestAbstract implements I - @Override - public void remove(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { - if (iblockdata.getBlock() != iblockdata1.getBlock()) { -- TileEntity tileentity = world.getTileEntity(blockposition); -+ TileEntity tileentity = world.getTileEntity(blockposition, false); // Tuinity - block has since changed. - - if (tileentity instanceof IInventory) { - InventoryUtils.dropInventory(world, blockposition, (IInventory) tileentity); -diff --git a/src/main/java/net/minecraft/server/BlockPiston.java b/src/main/java/net/minecraft/server/BlockPiston.java -index 73ac83832..8312ed779 100644 ---- a/src/main/java/net/minecraft/server/BlockPiston.java -+++ b/src/main/java/net/minecraft/server/BlockPiston.java -@@ -279,8 +279,10 @@ public class BlockPiston extends BlockDirectional { - } else if ((Boolean) iblockdata.get(BlockPiston.EXTENDED)) { - return false; - } -- -- return !block.isTileEntity(); -+ // Tuinity start - pushable TE's -+ TileEntity tileEntity; -+ return !block.isTileEntity() || ((tileEntity = world.getTileEntity(blockposition)) != null && tileEntity.isPushable()); -+ // Tuinity end - pushable TE's - } else { - return false; - } -@@ -377,7 +379,7 @@ public class BlockPiston extends BlockDirectional { - - for (k = list.size() - 1; k >= 0; --k) { - // Paper start - fix a variety of piston desync dupes -- boolean allowDesync = com.destroystokyo.paper.PaperConfig.allowPistonDuplication; -+ boolean allowDesync = com.destroystokyo.paper.PaperConfig.allowPistonDuplication && !list1.get(k).getBlock().isTileEntity(); // Tuinity - pushable TE's - BlockPosition oldPos = blockposition3 = (BlockPosition) list.get(k); - iblockdata1 = allowDesync ? world.getType(oldPos) : null; - // Paper end - fix a variety of piston desync dupes -@@ -389,10 +391,29 @@ public class BlockPiston extends BlockDirectional { - iblockdata1 = world.getType(oldPos); - map.replace(oldPos, iblockdata1); - } -- world.setTileEntity(blockposition3, BlockPistonMoving.a(allowDesync ? list1.get(k) : iblockdata1, enumdirection, flag, false)); -+ // Tuinity start - pushable TE's -+ TileEntity tileEntity = world.getTileEntity(oldPos); -+ if (tileEntity != null) { -+ if (!tileEntity.isPushable()) { -+ tileEntity = null; -+ } else { -+ // ensure the death of world tied state -+ if (tileEntity instanceof IInventory) { -+ MCUtil.closeInventory((IInventory)tileEntity, org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); -+ } -+ if (tileEntity instanceof TileEntityLectern) { -+ MCUtil.closeInventory(((TileEntityLectern)tileEntity).inventory, org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); -+ } -+ -+ // now copy -+ tileEntity = tileEntity.createCopyForPush((WorldServer)world, oldPos, blockposition3, iblockdata1); -+ } -+ } -+ // Tuinity end - pushable TE's - if (!allowDesync) { -- world.setTypeAndData(oldPos, Blocks.AIR.getBlockData(), 2 | 4 | 16 | 1024); // set air to prevent later physics updates from seeing this block -+ world.setTypeAndDataRaw(oldPos, Blocks.AIR.getBlockData(), null); // Tuinity - don't fire logic for removing the old block - } -+ world.setTileEntity(blockposition3, BlockPistonMoving.createPistonTile(allowDesync ? list1.get(k) : iblockdata1, enumdirection, flag, false, tileEntity)); // Tuinity - pushable TE's - // Paper end - fix a variety of piston desync dupes - --j; - aiblockdata[j] = iblockdata1; -diff --git a/src/main/java/net/minecraft/server/BlockPistonMoving.java b/src/main/java/net/minecraft/server/BlockPistonMoving.java -index 809ee9f9a..805fc6b88 100644 ---- a/src/main/java/net/minecraft/server/BlockPistonMoving.java -+++ b/src/main/java/net/minecraft/server/BlockPistonMoving.java -@@ -21,7 +21,12 @@ public class BlockPistonMoving extends BlockTileEntity { - } - - public static TileEntity a(IBlockData iblockdata, EnumDirection enumdirection, boolean flag, boolean flag1) { -- return new TileEntityPiston(iblockdata, enumdirection, flag, flag1); -+ // Tuinity start - add tileEntity parameter -+ return createPistonTile(iblockdata, enumdirection, flag, flag1, null); -+ } -+ public static TileEntity createPistonTile(IBlockData iblockdata, EnumDirection enumdirection, boolean flag, boolean flag1, TileEntity tileEntity) { -+ return new TileEntityPiston(iblockdata, enumdirection, flag, flag1, tileEntity); -+ // Tuinity end - add tileEntity parameter - } - - @Override -diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index d7beb47d9..5a360fdca 100644 ---- a/src/main/java/net/minecraft/server/Chunk.java -+++ b/src/main/java/net/minecraft/server/Chunk.java -@@ -509,8 +509,35 @@ public class Chunk implements IChunkAccess { - return this.setType(blockposition, iblockdata, flag, true); - } - -+ // Tuinity start -+ final void setTypeAndDataRaw(BlockPosition blockposition, IBlockData iblockdata) { -+ // copied from setType -+ int i = blockposition.getX() & 15; -+ int j = blockposition.getY(); -+ int k = blockposition.getZ() & 15; -+ ChunkSection chunksection = this.sections[j >> 4]; -+ -+ if (chunksection == Chunk.a) { -+ if (iblockdata.isAir()) { -+ return; -+ } -+ -+ chunksection = new ChunkSection(j >> 4 << 4, this, this.world, true); // Paper - Anti-Xray - Add parameters -+ this.sections[j >> 4] = chunksection; -+ } -+ -+ chunksection.setType(i, j & 15, k, iblockdata); -+ } -+ // Tuinity end -+ - @Nullable - public IBlockData setType(BlockPosition blockposition, IBlockData iblockdata, boolean flag, boolean doPlace) { -+ // Tuinity start - add tileEntity parameter -+ return this.setType(blockposition, iblockdata, flag, doPlace, null); -+ } -+ @Nullable -+ public IBlockData setType(BlockPosition blockposition, IBlockData iblockdata, boolean flag, boolean doPlace, TileEntity newTileEntity) { -+ // Tuinity end - add tileEntity parameter - // CraftBukkit end - int i = blockposition.getX() & 15; - int j = blockposition.getY(); -@@ -569,6 +596,10 @@ public class Chunk implements IChunkAccess { - } - - if (block instanceof ITileEntity) { -+ // Tuinity start - add tileEntity parameter -+ if (newTileEntity != null) { -+ this.world.setTileEntity(blockposition, newTileEntity); -+ } else { // Tuinity end - add tileEntity parameter - tileentity = this.a(blockposition, Chunk.EnumTileEntityState.CHECK); - if (tileentity == null) { - tileentity = ((ITileEntity) block).createTile(this.world); -@@ -576,6 +607,7 @@ public class Chunk implements IChunkAccess { - } else { - tileentity.invalidateBlockCache(); - } -+ } // Tuinity - add tileEntity parameter - } - - this.s = true; -@@ -591,6 +623,7 @@ public class Chunk implements IChunkAccess { - - @Override - public void a(Entity entity) { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Async addEntity call"); // Tuinity - this.q = true; - int i = MathHelper.floor(entity.locX() / 16.0D); - int j = MathHelper.floor(entity.locZ() / 16.0D); -@@ -660,6 +693,7 @@ public class Chunk implements IChunkAccess { - } - - public void a(Entity entity, int i) { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Async removeEntity call"); // Tuinity - if (i < 0) { - i = 0; - } -@@ -917,6 +951,7 @@ public class Chunk implements IChunkAccess { - } - - public void a(@Nullable Entity entity, AxisAlignedBB axisalignedbb, List list, @Nullable Predicate predicate) { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Async getEntities call"); // Tuinity - int i = MathHelper.floor((axisalignedbb.minY - 2.0D) / 16.0D); - int j = MathHelper.floor((axisalignedbb.maxY + 2.0D) / 16.0D); - -@@ -956,6 +991,7 @@ public class Chunk implements IChunkAccess { - } - - public void a(@Nullable EntityTypes entitytypes, AxisAlignedBB axisalignedbb, List list, Predicate predicate) { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Async getEntities call"); // Tuinity - int i = MathHelper.floor((axisalignedbb.minY - 2.0D) / 16.0D); - int j = MathHelper.floor((axisalignedbb.maxY + 2.0D) / 16.0D); - -@@ -986,6 +1022,7 @@ public class Chunk implements IChunkAccess { - } - - public void a(Class oclass, AxisAlignedBB axisalignedbb, List list, @Nullable Predicate predicate) { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Async getEntities call"); // Tuinity - int i = MathHelper.floor((axisalignedbb.minY - 2.0D) / 16.0D); - int j = MathHelper.floor((axisalignedbb.maxY + 2.0D) / 16.0D); - -diff --git a/src/main/java/net/minecraft/server/ChunkMap.java b/src/main/java/net/minecraft/server/ChunkMap.java -index 55f9f4e6e..15f0f86a3 100644 ---- a/src/main/java/net/minecraft/server/ChunkMap.java -+++ b/src/main/java/net/minecraft/server/ChunkMap.java -@@ -68,6 +68,7 @@ public abstract class ChunkMap extends LightEngineGraph { - - protected abstract int b(long i); - -+ public final void update(long coordinate, int level, boolean increaseInLevel) { this.b(coordinate, level, increaseInLevel); } // Tuinity - OBFHELPER - public void b(long i, int j, boolean flag) { - this.a(ChunkCoordIntPair.a, i, j, flag); - } -diff --git a/src/main/java/net/minecraft/server/ChunkMapDistance.java b/src/main/java/net/minecraft/server/ChunkMapDistance.java -index 9a84d1749..e0378f486 100644 ---- a/src/main/java/net/minecraft/server/ChunkMapDistance.java -+++ b/src/main/java/net/minecraft/server/ChunkMapDistance.java -@@ -31,7 +31,7 @@ public abstract class ChunkMapDistance { - private static final int b = 33 + ChunkStatus.a(ChunkStatus.FULL) - 2; - private final Long2ObjectMap> c = new Long2ObjectOpenHashMap(); - public final Long2ObjectOpenHashMap>> tickets = new Long2ObjectOpenHashMap(); -- private final ChunkMapDistance.a e = new ChunkMapDistance.a(); -+ private final ChunkMapDistance.a e = new ChunkMapDistance.a(); final ChunkMapDistance.a getTicketTracker() { return this.e; } // Tuinity - OBFHELPER - public static final int MOB_SPAWN_RANGE = 8; //private final ChunkMapDistance.b f = new ChunkMapDistance.b(8); // Paper - no longer used - private final ChunkMapDistance.c g = new ChunkMapDistance.c(33); - // Paper start use a queue, but still keep unique requirement -@@ -53,6 +53,47 @@ public abstract class ChunkMapDistance { - - PlayerChunkMap chunkMap; // Paper - -+ // Tuinity start - delay chunk unloads -+ private long nextUnloadId; // delay chunk unloads -+ private final Long2ObjectOpenHashMap> delayedChunks = new Long2ObjectOpenHashMap<>(); -+ public final void removeTickets(long chunk, TicketType type) { -+ ArraySetSorted> tickets = this.tickets.get(chunk); -+ if (tickets == null) { -+ return; -+ } -+ if (type == TicketType.DELAYED_UNLOAD) { -+ this.delayedChunks.remove(chunk); -+ } -+ boolean changed = tickets.removeIf((Ticket ticket) -> { -+ return ticket.getTicketType() == type; -+ }); -+ if (changed) { -+ this.getTicketTracker().update(chunk, getLowestTicketLevel(tickets), false); -+ } -+ } -+ -+ private final java.util.function.LongFunction> computeFuntion = (long key) -> { -+ Ticket ret = new Ticket<>(TicketType.DELAYED_UNLOAD, -1, ++ChunkMapDistance.this.nextUnloadId); -+ ret.isCached = true; -+ return ret; -+ }; -+ -+ private void computeDelayedTicketFor(long chunk, int removedLevel, ArraySetSorted> tickets) { -+ int lowestLevel = getLowestTicketLevel(tickets); -+ if (removedLevel > lowestLevel) { -+ return; -+ } -+ final Ticket ticket = this.delayedChunks.computeIfAbsent(chunk, this.computeFuntion); -+ if (ticket.getTicketLevel() != -1) { -+ // since we modify data used in sorting, we need to remove before -+ tickets.remove(ticket); -+ } -+ ticket.setCreationTick(this.currentTick); -+ ticket.setTicketLevel(removedLevel); -+ tickets.add(ticket); // re-add with new expire time and ticket level -+ } -+ // Tuinity end - delay chunk unloads -+ - protected ChunkMapDistance(Executor executor, Executor executor1) { - executor1.getClass(); - Mailbox mailbox = Mailbox.a("player ticket throttler", executor1::execute); -@@ -65,15 +106,34 @@ public abstract class ChunkMapDistance { - } - - protected void purgeTickets() { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Async purge tickets"); // Tuinity - ++this.currentTick; - ObjectIterator objectiterator = this.tickets.long2ObjectEntrySet().fastIterator(); - -+ int[] tempLevel = new int[] { PlayerChunkMap.GOLDEN_TICKET + 1 }; // Tuinity - delay chunk unloads - while (objectiterator.hasNext()) { - Entry>> entry = (Entry) objectiterator.next(); - - if ((entry.getValue()).removeIf((ticket) -> { // CraftBukkit - decompile error -- return ticket.b(this.currentTick); -+ // Tuinity start - delay chunk unloads -+ boolean ret = ticket.isExpired(this.currentTick); -+ if (com.tuinity.tuinity.config.TuinityConfig.delayChunkUnloadsBy <= 0) { -+ return ret; -+ } -+ if (ret && ticket.getTicketType() != TicketType.DELAYED_UNLOAD && ticket.getTicketLevel() < tempLevel[0]) { -+ tempLevel[0] = ticket.getTicketLevel(); -+ } -+ if (ticket.getTicketType() == TicketType.DELAYED_UNLOAD && ticket.isCached) { -+ this.delayedChunks.remove(entry.getLongKey(), ticket); // clean up ticket... -+ } -+ return ret; -+ // Tuinity end - delay chunk unloads - })) { -+ // Tuinity start - delay chunk unloads -+ if (tempLevel[0] < (PlayerChunkMap.GOLDEN_TICKET + 1)) { -+ this.computeDelayedTicketFor(entry.getLongKey(), tempLevel[0], entry.getValue()); -+ } -+ // Tuinity end - delay chunk unloads - this.e.b(entry.getLongKey(), a((ArraySetSorted) entry.getValue()), false); - } - -@@ -84,6 +144,7 @@ public abstract class ChunkMapDistance { - - } - -+ private static int getLowestTicketLevel(ArraySetSorted> arraysetsorted) { return a(arraysetsorted); } // Tuinity - OBFHELPER - private static int a(ArraySetSorted> arraysetsorted) { - AsyncCatcher.catchOp("ChunkMapDistance::getHighestTicketLevel"); // Paper - return !arraysetsorted.isEmpty() ? ((Ticket) arraysetsorted.b()).b() : PlayerChunkMap.GOLDEN_TICKET + 1; -@@ -98,6 +159,7 @@ public abstract class ChunkMapDistance { - protected abstract PlayerChunk a(long i, int j, @Nullable PlayerChunk playerchunk, int k); - - public boolean a(PlayerChunkMap playerchunkmap) { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Cannot tick ChunkMapDistance off of the main-thread");// Tuinity - //this.f.a(); // Paper - no longer used - AsyncCatcher.catchOp("DistanceManagerTick"); - this.g.a(); -@@ -176,27 +238,11 @@ public abstract class ChunkMapDistance { - boolean removed = false; // CraftBukkit - if (arraysetsorted.remove(ticket)) { - removed = true; // CraftBukkit -- // Paper start - delay chunk unloads for player tickets -- long delayChunkUnloadsBy = chunkMap.world.paperConfig.delayChunkUnloadsBy; -- if (ticket.getTicketType() == TicketType.PLAYER && delayChunkUnloadsBy > 0) { -- boolean hasPlayer = false; -- for (Ticket ticket1 : arraysetsorted) { -- if (ticket1.getTicketType() == TicketType.PLAYER) { -- hasPlayer = true; -- break; -- } -- } -- PlayerChunk playerChunk = chunkMap.getUpdatingChunk(i); -- if (!hasPlayer && playerChunk != null && playerChunk.isFullChunkReady()) { -- Ticket delayUnload = new Ticket(TicketType.DELAY_UNLOAD, 33, i); -- delayUnload.delayUnloadBy = delayChunkUnloadsBy; -- delayUnload.setCurrentTick(this.currentTick); -- arraysetsorted.remove(delayUnload); -- // refresh ticket -- arraysetsorted.add(delayUnload); -- } -+ // Tuinity start - delay chunk unloads -+ if (com.tuinity.tuinity.config.TuinityConfig.delayChunkUnloadsBy > 0 && ticket.getTicketType() != TicketType.DELAYED_UNLOAD) { -+ this.computeDelayedTicketFor(i, ticket.getTicketLevel(), arraysetsorted); - } -- // Paper end -+ // Tuinity end - delay chunk unloads - } - - if (arraysetsorted.isEmpty()) { -@@ -369,6 +415,7 @@ public abstract class ChunkMapDistance { - } - - private ArraySetSorted> e(long i) { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Async tickets compute"); // Tuinity - return (ArraySetSorted) this.tickets.computeIfAbsent(i, (j) -> { - return ArraySetSorted.a(4); - }); -@@ -386,6 +433,7 @@ public abstract class ChunkMapDistance { - } - - public void a(SectionPosition sectionposition, EntityPlayer entityplayer) { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Async player add"); // Tuinity - long i = sectionposition.u().pair(); - - ((ObjectSet) this.c.computeIfAbsent(i, (j) -> { -@@ -396,6 +444,7 @@ public abstract class ChunkMapDistance { - } - - public void b(SectionPosition sectionposition, EntityPlayer entityplayer) { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Async player remove"); // Tuinity - long i = sectionposition.u().pair(); - ObjectSet objectset = (ObjectSet) this.c.get(i); - -@@ -445,6 +494,7 @@ public abstract class ChunkMapDistance { - - // CraftBukkit start - public void removeAllTicketsFor(TicketType ticketType, int ticketLevel, T ticketIdentifier) { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Async ticket remove"); // Tuinity - Ticket target = new Ticket<>(ticketType, ticketLevel, ticketIdentifier); - - for (java.util.Iterator>>> iterator = this.tickets.long2ObjectEntrySet().fastIterator(); iterator.hasNext();) { -diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index 7d50b94cb..e8bf60507 100644 ---- a/src/main/java/net/minecraft/server/ChunkProviderServer.java -+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java -@@ -118,7 +118,7 @@ public class ChunkProviderServer extends IChunkProvider { - return (Chunk)this.getChunkAt(x, z, ChunkStatus.FULL, true); - } - -- private long chunkFutureAwaitCounter; -+ long chunkFutureAwaitCounter; // Tuinity - private -> package private - - public void getEntityTickingChunkAsync(int x, int z, java.util.function.Consumer onLoad) { - if (Thread.currentThread() != this.serverThread) { -@@ -180,9 +180,9 @@ public class ChunkProviderServer extends IChunkProvider { - - try { - if (onLoad != null) { -- playerChunkMap.callbackExecutor.execute(() -> { -+ // Tuinity - revert incorrect use of callback executor - onLoad.accept(either == null ? null : either.left().orElse(null)); // indicate failure to the callback. -- }); -+ // Tuinity - revert incorrect use of callback executor - } - } catch (Throwable thr) { - if (thr instanceof ThreadDeath) { -@@ -207,6 +207,163 @@ public class ChunkProviderServer extends IChunkProvider { - } - // Paper end - rewrite ticklistserver - -+ // Tuinity start -+ // this will try to avoid chunk neighbours for lighting -+ public final IChunkAccess getFullStatusChunkAt(int chunkX, int chunkZ) { -+ Chunk ifLoaded = this.getChunkAtIfLoadedImmediately(chunkX, chunkZ); -+ if (ifLoaded != null) { -+ return ifLoaded; -+ } -+ -+ IChunkAccess empty = this.getChunkAt(chunkX, chunkZ, ChunkStatus.EMPTY, true); -+ if (empty != null && empty.getChunkStatus() == ChunkStatus.FULL) { -+ return empty; -+ } -+ return this.getChunkAt(chunkX, chunkZ, ChunkStatus.FULL, true); -+ } -+ -+ public final IChunkAccess getFullStatusChunkAtIfLoaded(int chunkX, int chunkZ) { -+ Chunk ifLoaded = this.getChunkAtIfLoadedImmediately(chunkX, chunkZ); -+ if (ifLoaded != null) { -+ return ifLoaded; -+ } -+ -+ IChunkAccess ret = this.getChunkAtImmediately(chunkX, chunkZ); -+ if (ret != null && ret.getChunkStatus() == ChunkStatus.FULL) { -+ return ret; -+ } else { -+ return null; -+ } -+ } -+ -+ void getChunkAtAsynchronously(int chunkX, int chunkZ, int ticketLevel, -+ java.util.function.Consumer consumer) { -+ this.getChunkAtAsynchronously(chunkX, chunkZ, ticketLevel, (PlayerChunk playerChunk) -> { -+ if (ticketLevel <= 33) { -+ return (CompletableFuture)playerChunk.getFullChunkFuture(); -+ } else { -+ return playerChunk.getOrCreateFuture(PlayerChunk.getChunkStatus(ticketLevel), ChunkProviderServer.this.playerChunkMap); -+ } -+ }, consumer); -+ } -+ -+ void getChunkAtAsynchronously(int chunkX, int chunkZ, int ticketLevel, -+ java.util.function.Function>> function, -+ java.util.function.Consumer consumer) { -+ if (Thread.currentThread() != this.serverThread) { -+ throw new IllegalStateException(); -+ } -+ ChunkCoordIntPair chunkPos = new ChunkCoordIntPair(chunkX, chunkZ); -+ Long identifier = Long.valueOf(this.chunkFutureAwaitCounter++); -+ this.addTicketAtLevel(TicketType.FUTURE_AWAIT, chunkPos, ticketLevel, identifier); -+ this.tickDistanceManager(); -+ -+ PlayerChunk chunk = this.playerChunkMap.getUpdatingChunk(chunkPos.pair()); -+ -+ if (chunk == null) { -+ throw new IllegalStateException("Expected playerchunk " + chunkPos + " in world '" + this.world.getWorld().getName() + "'"); -+ } -+ -+ CompletableFuture> future = function.apply(chunk); -+ -+ future.whenCompleteAsync((either, throwable) -> { -+ try { -+ if (throwable != null) { -+ if (throwable instanceof ThreadDeath) { -+ throw (ThreadDeath)throwable; -+ } -+ MinecraftServer.LOGGER.fatal("Failed to complete future await for chunk " + chunkPos.toString() + " in world '" + ChunkProviderServer.this.world.getWorld().getName() + "'", throwable); -+ } else if (either.right().isPresent()) { -+ MinecraftServer.LOGGER.fatal("Failed to complete future await for chunk " + chunkPos.toString() + " in world '" + ChunkProviderServer.this.world.getWorld().getName() + "': " + either.right().get().toString()); -+ } -+ -+ try { -+ if (consumer != null) { -+ consumer.accept(either == null ? null : either.left().orElse(null)); // indicate failure to the callback. -+ } -+ } catch (Throwable thr) { -+ if (thr instanceof ThreadDeath) { -+ throw (ThreadDeath)thr; -+ } -+ MinecraftServer.LOGGER.fatal("Load callback for future await failed " + chunkPos.toString() + " in world '" + ChunkProviderServer.this.world.getWorld().getName() + "'", thr); -+ return; -+ } -+ } finally { -+ // due to odd behaviour with CB unload implementation we need to have these AFTER the load callback. -+ ChunkProviderServer.this.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, ticketLevel, chunkPos); -+ ChunkProviderServer.this.removeTicketAtLevel(TicketType.FUTURE_AWAIT, chunkPos, ticketLevel, identifier); -+ } -+ }, this.serverThreadQueue); -+ } -+ -+ void chunkLoadAccept(int chunkX, int chunkZ, IChunkAccess chunk, java.util.function.Consumer consumer) { -+ try { -+ consumer.accept(chunk); -+ } catch (Throwable throwable) { -+ if (throwable instanceof ThreadDeath) { -+ throw (ThreadDeath)throwable; -+ } -+ MinecraftServer.LOGGER.error("Load callback for chunk " + chunkX + "," + chunkZ + " in world '" + this.world.getWorld().getName() + "' threw an exception", throwable); -+ } -+ } -+ -+ public final void getChunkAtAsynchronously(int chunkX, int chunkZ, ChunkStatus status, boolean gen, boolean allowSubTicketLevel, java.util.function.Consumer onLoad) { -+ // try to fire sync -+ int chunkStatusTicketLevel = 33 + ChunkStatus.getTicketLevelOffset(status); -+ IChunkAccess immediate = this.getChunkAtImmediately(chunkX, chunkZ); -+ if (immediate != null) { -+ if (allowSubTicketLevel || this.playerChunkMap.getUpdatingChunk(MCUtil.getCoordinateKey(chunkX, chunkZ)).getTicketLevel() <= chunkStatusTicketLevel) { -+ if (immediate.getChunkStatus().isAtLeastStatus(status)) { -+ this.chunkLoadAccept(chunkX, chunkZ, immediate, onLoad); -+ } else { -+ if (gen) { -+ this.getChunkAtAsynchronously(chunkX, chunkZ, chunkStatusTicketLevel, onLoad); -+ } else { -+ this.chunkLoadAccept(chunkX, chunkZ, null, onLoad); -+ } -+ } -+ } else { -+ if (gen || immediate.getChunkStatus().isAtLeastStatus(status)) { -+ this.getChunkAtAsynchronously(chunkX, chunkZ, chunkStatusTicketLevel, onLoad); -+ } else { -+ this.chunkLoadAccept(chunkX, chunkZ, null, onLoad); -+ } -+ } -+ return; -+ } -+ -+ // need to fire async -+ -+ if (gen && !allowSubTicketLevel) { -+ this.getChunkAtAsynchronously(chunkX, chunkZ, chunkStatusTicketLevel, onLoad); -+ return; -+ } -+ -+ this.getChunkAtAsynchronously(chunkX, chunkZ, 33 + ChunkStatus.getTicketLevelOffset(ChunkStatus.EMPTY), (IChunkAccess chunk) -> { -+ if (chunk == null) { -+ throw new IllegalStateException("Chunk cannot be null"); -+ } -+ -+ if (!chunk.getChunkStatus().isAtLeastStatus(status)) { -+ if (gen) { -+ this.getChunkAtAsynchronously(chunkX, chunkZ, chunkStatusTicketLevel, onLoad); -+ return; -+ } else { -+ ChunkProviderServer.this.chunkLoadAccept(chunkX, chunkZ, null, onLoad); -+ return; -+ } -+ } else { -+ if (allowSubTicketLevel) { -+ ChunkProviderServer.this.chunkLoadAccept(chunkX, chunkZ, chunk, onLoad); -+ return; -+ } else { -+ this.getChunkAtAsynchronously(chunkX, chunkZ, chunkStatusTicketLevel, onLoad); -+ return; -+ } -+ } -+ }); -+ } -+ // Tuinity end - - public ChunkProviderServer(WorldServer worldserver, File file, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, ChunkGenerator chunkgenerator, int i, WorldLoadListener worldloadlistener, Supplier supplier) { - this.world = worldserver; -@@ -543,6 +700,8 @@ public class ChunkProviderServer extends IChunkProvider { - Arrays.fill(this.cacheChunk, (Object) null); - } - -+ private long syncLoadCounter; // Tuinity - prevent plugin unloads from removing our ticket -+ - private CompletableFuture> getChunkFutureMainThread(int i, int j, ChunkStatus chunkstatus, boolean flag) { - // Paper start - add isUrgent - old sig left in place for dirty nms plugins - return getChunkFutureMainThread(i, j, chunkstatus, flag, false); -@@ -561,9 +720,12 @@ public class ChunkProviderServer extends IChunkProvider { - PlayerChunk.State currentChunkState = PlayerChunk.getChunkState(playerchunk.getTicketLevel()); - currentlyUnloading = (oldChunkState.isAtLeast(PlayerChunk.State.BORDER) && !currentChunkState.isAtLeast(PlayerChunk.State.BORDER)); - } -+ final Long identifier; // Tuinity - prevent plugin unloads from removing our ticket - if (flag && !currentlyUnloading) { - // CraftBukkit end - this.chunkMapDistance.a(TicketType.UNKNOWN, chunkcoordintpair, l, chunkcoordintpair); -+ identifier = Long.valueOf(this.syncLoadCounter++); // Tuinity - prevent plugin unloads from removing our ticket -+ this.chunkMapDistance.addTicketAtLevel(TicketType.REQUIRED_LOAD, chunkcoordintpair, l, identifier); // Tuinity - prevent plugin unloads from removing our ticket - if (isUrgent) this.chunkMapDistance.markUrgent(chunkcoordintpair); // Paper - if (this.a(playerchunk, l)) { - GameProfilerFiller gameprofilerfiller = this.world.getMethodProfiler(); -@@ -574,12 +736,20 @@ public class ChunkProviderServer extends IChunkProvider { - playerchunk = this.getChunk(k); - gameprofilerfiller.exit(); - if (this.a(playerchunk, l)) { -+ this.chunkMapDistance.removeTicketAtLevel(TicketType.REQUIRED_LOAD, chunkcoordintpair, l, identifier); // Tuinity - throw (IllegalStateException) SystemUtils.c(new IllegalStateException("No chunk holder after ticket has been added")); - } - } -- } -+ } else { identifier = null; } // Tuinity - prevent plugin unloads from removing our ticket - // Paper start - CompletableFuture> future = this.a(playerchunk, l) ? PlayerChunk.UNLOADED_CHUNK_ACCESS_FUTURE : playerchunk.a(chunkstatus, this.playerChunkMap); -+ // Tuinity start - prevent plugin unloads from removing our ticket -+ if (flag && !currentlyUnloading) { -+ future.thenAcceptAsync((either) -> { -+ ChunkProviderServer.this.chunkMapDistance.removeTicketAtLevel(TicketType.REQUIRED_LOAD, chunkcoordintpair, l, identifier); -+ }, ChunkProviderServer.this.serverThreadQueue); -+ } -+ // Tuinity end - prevent plugin unloads from removing our ticket - if (isUrgent) { - future.thenAccept(either -> this.chunkMapDistance.clearUrgent(chunkcoordintpair)); - } -@@ -741,7 +911,7 @@ public class ChunkProviderServer extends IChunkProvider { - this.world.getMethodProfiler().enter("purge"); - this.world.timings.doChunkMap.startTiming(); // Spigot - this.chunkMapDistance.purgeTickets(); -- this.world.getMinecraftServer().midTickLoadChunks(); // Paper -+ // Tuinity - replace logic - this.tickDistanceManager(); - this.world.timings.doChunkMap.stopTiming(); // Spigot - this.world.getMethodProfiler().exitEnter("chunks"); -@@ -751,12 +921,22 @@ public class ChunkProviderServer extends IChunkProvider { - this.world.timings.doChunkUnload.startTiming(); // Spigot - this.world.getMethodProfiler().exitEnter("unload"); - this.playerChunkMap.unloadChunks(booleansupplier); -- this.world.getMinecraftServer().midTickLoadChunks(); // Paper -+ // Tuinity - replace logic - this.world.timings.doChunkUnload.stopTiming(); // Spigot - this.world.getMethodProfiler().exit(); - this.clearCache(); - } - -+ // Tuinity start - optimise chunk tick iteration -+ // We need this here because since we remove the COW op for chunk map, we also remove -+ // the iterator safety of the visible map - meaning the only way for us to still -+ // iterate is to use a copy. Not acceptable at all, so here we hack in an iterable safe -+ // chunk map that will give the same behaviour as previous - without COW. -+ final com.destroystokyo.paper.util.maplist.ChunkList entityTickingChunks = new com.destroystokyo.paper.util.maplist.ChunkList(); -+ boolean isTickingChunks; -+ final it.unimi.dsi.fastutil.objects.Object2BooleanLinkedOpenHashMap pendingEntityTickingChunkChanges = new it.unimi.dsi.fastutil.objects.Object2BooleanLinkedOpenHashMap<>(16, 0.8f); -+ // Tuinity end - optimise chunk tick iteration -+ - private void tickChunks() { - long i = this.world.getTime(); - long j = i - this.lastTickTime; -@@ -832,11 +1012,12 @@ public class ChunkProviderServer extends IChunkProvider { - this.world.timings.countNaturalMobs.stopTiming(); // Paper - timings - this.world.getMethodProfiler().exit(); - // Paper - replaced by above -- final int[] chunksTicked = {0}; this.playerChunkMap.forEachVisibleChunk((playerchunk) -> { // Paper - safe iterator incase chunk loads, also no wrapping -- Optional optional = ((Either) playerchunk.b().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); -- -- if (optional.isPresent()) { -- Chunk chunk = (Chunk) optional.get(); -+ // Tuinity start - optimise chunk tick iteration -+ this.isTickingChunks = true; -+ for (Chunk chunk : this.entityTickingChunks) { -+ PlayerChunk playerchunk = chunk.playerChunk; -+ if (playerchunk != null) { // make sure load event has been called along with the load logic we put there -+ // Tuinity end - optimise chunk tick iteration - - this.world.getMethodProfiler().enter("broadcast"); - this.world.timings.broadcastChunkUpdates.startTiming(); // Paper - timings -@@ -915,10 +1096,26 @@ public class ChunkProviderServer extends IChunkProvider { - this.world.timings.chunkTicks.startTiming(); // Spigot // Paper - this.world.a(chunk, k); - this.world.timings.chunkTicks.stopTiming(); // Spigot // Paper -- if (chunksTicked[0]++ % 10 == 0) this.world.getMinecraftServer().midTickLoadChunks(); // Paper -+ MinecraftServer.getServer().executeMidTickTasks(); // Tuinity - exec chunk tasks during world tick - } - } -- }); -+ } // Tuinity start - optimise chunk tick iteration -+ this.isTickingChunks = false; -+ if (!this.pendingEntityTickingChunkChanges.isEmpty()) { -+ // iterate backwards: fastutil maps have better remove times when iterating backwards -+ // (this is due to the fact that we likely wont shift entries on remove calls) -+ for (it.unimi.dsi.fastutil.objects.ObjectBidirectionalIterator> iterator = this.pendingEntityTickingChunkChanges.object2BooleanEntrySet().fastIterator(this.pendingEntityTickingChunkChanges.object2BooleanEntrySet().last()); iterator.hasPrevious();) { -+ it.unimi.dsi.fastutil.objects.Object2BooleanMap.Entry entry = iterator.previous(); -+ -+ if (entry.getBooleanValue()) { -+ this.entityTickingChunks.add(entry.getKey()); -+ } else { -+ this.entityTickingChunks.remove(entry.getKey()); -+ } -+ iterator.remove(); -+ } -+ } -+ // Tuinity end - optimise chunk tick iteration - this.world.getMethodProfiler().enter("customSpawners"); - if (flag1) { - try (co.aikar.timings.Timing ignored = this.world.timings.miscMobSpawning.startTiming()) { // Paper - timings -@@ -930,7 +1127,25 @@ public class ChunkProviderServer extends IChunkProvider { - this.world.getMethodProfiler().exit(); - } - -+ // Tuinity start - controlled flush for entity tracker packets -+ List disabledFlushes = new java.util.ArrayList<>(this.world.getPlayers().size()); -+ for (EntityPlayer player : this.world.getPlayers()) { -+ PlayerConnection connection = player.playerConnection; -+ if (connection != null) { -+ connection.networkManager.disableAutomaticFlush(); -+ disabledFlushes.add(connection.networkManager); -+ } -+ } -+ try { -+ // Tuinity end - controlled flush for entity tracker packets - this.playerChunkMap.g(); -+ // Tuinity start - controlled flush for entity tracker packets -+ } finally { -+ for (NetworkManager networkManager : disabledFlushes) { -+ networkManager.enableAutomaticFlush(); -+ } -+ } -+ // Tuinity end - controlled flush for entity tracker packets - } - - @Override -@@ -1056,44 +1271,11 @@ public class ChunkProviderServer extends IChunkProvider { - ChunkProviderServer.this.world.getMethodProfiler().c("runTask"); - super.executeTask(runnable); - } -- -- // Paper start -- private long lastMidTickChunkTask = 0; -- public boolean pollChunkLoadTasks() { -- if (com.destroystokyo.paper.io.chunk.ChunkTaskManager.pollChunkWaitQueue() || ChunkProviderServer.this.world.asyncChunkTaskManager.pollNextChunkTask()) { -- try { -- ChunkProviderServer.this.tickDistanceManager(); -- } finally { -- // from below: process pending Chunk loadCallback() and unloadCallback() after each run task -- playerChunkMap.callbackExecutor.run(); -- } -- return true; -- } -- return false; -- } -- public void midTickLoadChunks() { -- MinecraftServer server = ChunkProviderServer.this.world.getMinecraftServer(); -- // always try to load chunks, restrain generation/other updates only. don't count these towards tick count -- //noinspection StatementWithEmptyBody -- while (pollChunkLoadTasks()) {} -- -- if (System.nanoTime() - lastMidTickChunkTask < 200000) { -- return; -- } -- -- for (;server.midTickChunksTasksRan < com.destroystokyo.paper.PaperConfig.midTickChunkTasks && server.canSleepForTick();) { -- if (this.executeNext()) { -- server.midTickChunksTasksRan++; -- lastMidTickChunkTask = System.nanoTime(); -- } else { -- break; -- } -- } -- } -- // Paper end -+ // Tuinity - replace logic - - @Override - protected boolean executeNext() { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Cannot execute chunk tasks off-main thread");// Tuinity - // CraftBukkit start - process pending Chunk loadCallback() and unloadCallback() after each run task - try { - boolean execChunkTask = com.destroystokyo.paper.io.chunk.ChunkTaskManager.pollChunkWaitQueue() || ChunkProviderServer.this.world.asyncChunkTaskManager.pollNextChunkTask(); // Paper -diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java -index 1685237df..20b6b58bd 100644 ---- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java -+++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java -@@ -23,6 +23,14 @@ public class ChunkRegionLoader { - - private static final Logger LOGGER = LogManager.getLogger(); - -+ // Tuinity start -+ // TODO: Check on update -+ public static long getLastWorldSaveTime(NBTTagCompound chunkData) { -+ NBTTagCompound levelData = chunkData.getCompound("Level"); -+ return levelData.getLong("LastUpdate"); -+ } -+ // Tuinity end -+ - // Paper start - guard against serializing mismatching coordinates - // TODO Note: This needs to be re-checked each update - public static ChunkCoordIntPair getChunkCoordinate(NBTTagCompound chunkData) { -@@ -375,10 +383,10 @@ public class ChunkRegionLoader { - NBTTagCompound nbttagcompound1 = new NBTTagCompound(); - - nbttagcompound.setInt("DataVersion", SharedConstants.getGameVersion().getWorldVersion()); -- nbttagcompound.set("Level", nbttagcompound1); -+ nbttagcompound.set("Level", nbttagcompound1); // Tuinity - diff on change - nbttagcompound1.setInt("xPos", chunkcoordintpair.x); - nbttagcompound1.setInt("zPos", chunkcoordintpair.z); -- nbttagcompound1.setLong("LastUpdate", asyncsavedata != null ? asyncsavedata.worldTime : worldserver.getTime()); // Paper - async chunk unloading -+ nbttagcompound1.setLong("LastUpdate", asyncsavedata != null ? asyncsavedata.worldTime : worldserver.getTime()); // Paper - async chunk unloading // Tuinity - diff on change - nbttagcompound1.setLong("InhabitedTime", ichunkaccess.getInhabitedTime()); - nbttagcompound1.setString("Status", ichunkaccess.getChunkStatus().d()); - ChunkConverter chunkconverter = ichunkaccess.p(); -diff --git a/src/main/java/net/minecraft/server/ChunkSection.java b/src/main/java/net/minecraft/server/ChunkSection.java -index 4dcb111c7..2f56b12d9 100644 ---- a/src/main/java/net/minecraft/server/ChunkSection.java -+++ b/src/main/java/net/minecraft/server/ChunkSection.java -@@ -95,6 +95,7 @@ public class ChunkSection { - return iblockdata1; - } - -+ public final boolean isFullOfAir() { return this.c(); } // Tuinity - OBFHELPER - public boolean c() { - return this.nonEmptyBlockCount == 0; - } -diff --git a/src/main/java/net/minecraft/server/ChunkStatus.java b/src/main/java/net/minecraft/server/ChunkStatus.java -index 40ce30cdc..3ba8481de 100644 ---- a/src/main/java/net/minecraft/server/ChunkStatus.java -+++ b/src/main/java/net/minecraft/server/ChunkStatus.java -@@ -103,7 +103,7 @@ public class ChunkStatus { - private final ChunkStatus.c w; - private final int x; - private final ChunkStatus.Type y; -- private final EnumSet z; -+ private final EnumSet z; public final HeightMap.Type[] heightMaps; // Tuinity - - private static CompletableFuture> a(ChunkStatus chunkstatus, LightEngineThreaded lightenginethreaded, IChunkAccess ichunkaccess) { - boolean flag = a(chunkstatus, ichunkaccess); -@@ -165,7 +165,7 @@ public class ChunkStatus { - this.w = chunkstatus_c; - this.x = i; - this.y = chunkstatus_type; -- this.z = enumset; -+ this.z = enumset; this.heightMaps = new java.util.ArrayList<>(this.z).toArray(new HeightMap.Type[0]); // Tuinity - this.t = chunkstatus == null ? 0 : chunkstatus.c() + 1; - } - -diff --git a/src/main/java/net/minecraft/server/DataPaletteBlock.java b/src/main/java/net/minecraft/server/DataPaletteBlock.java -index 81362de54..599ce8062 100644 ---- a/src/main/java/net/minecraft/server/DataPaletteBlock.java -+++ b/src/main/java/net/minecraft/server/DataPaletteBlock.java -@@ -164,6 +164,7 @@ public class DataPaletteBlock implements DataPaletteExpandable { - return this.a(j << 8 | k << 4 | i); // Paper - inline - } - -+ public final T rawGet(int index) { return this.a(index); } // Tuinity - OBFHELPER - protected T a(int i) { - T t0 = this.h.a(this.a.a(i)); - -diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java -index 32cd645ab..1f1243ae8 100644 ---- a/src/main/java/net/minecraft/server/DedicatedServer.java -+++ b/src/main/java/net/minecraft/server/DedicatedServer.java -@@ -194,6 +194,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer - com.destroystokyo.paper.PaperConfig.registerCommands(); - com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // load version history now - // Paper end -+ com.tuinity.tuinity.config.TuinityConfig.init((File) options.valueOf("tuinity-settings")); // Tuinity - Server Config - - this.setSpawnAnimals(dedicatedserverproperties.spawnAnimals); - this.setSpawnNPCs(dedicatedserverproperties.spawnNpcs); -diff --git a/src/main/java/net/minecraft/server/EULA.java b/src/main/java/net/minecraft/server/EULA.java -index cf00f35a5..e54730f09 100644 ---- a/src/main/java/net/minecraft/server/EULA.java -+++ b/src/main/java/net/minecraft/server/EULA.java -@@ -70,7 +70,7 @@ public class EULA { - Properties properties = new Properties(); - - properties.setProperty("eula", "false"); -- properties.store(outputstream, "By changing the setting below to TRUE you are indicating your agreement to our EULA (https://account.mojang.com/documents/minecraft_eula).\nYou also agree that tacos are tasty, and the best food in the world."); // Paper - fix lag; -+ properties.store(outputstream, "By changing the setting below to TRUE you are indicating your agreement to our EULA (https://account.mojang.com/documents/minecraft_eula)."); // Paper - fix lag; // Tuinity - Tacos are disgusting - } catch (Throwable throwable1) { - throwable = throwable1; - throw throwable1; -diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index e0ab058bf..37f854764 100644 ---- a/src/main/java/net/minecraft/server/Entity.java -+++ b/src/main/java/net/minecraft/server/Entity.java -@@ -137,7 +137,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - public double E; - public double F; - public double G; -- public float H; -+ public float H; public final float getStepHeight() { return this.H; } // Tuinity - OBFHELPER - public boolean noclip; - public float J; - protected final Random random; -@@ -211,6 +211,14 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - } - // CraftBukkit end - -+ // Tuinity start -+ public final AxisAlignedBB getBoundingBoxAt(double x, double y, double z) { -+ double widthHalf = (double)this.size.width / 2.0; -+ double height = (double)this.size.height; -+ return new AxisAlignedBB(x - widthHalf, y, z - widthHalf, x + widthHalf, y + height, z + widthHalf); -+ } -+ // Tuinity end -+ - // Paper start - /** - * Overriding this field will cause memory leaks. -@@ -601,7 +609,44 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - return this.world.getCubes(this, axisalignedbb) && !this.world.containsLiquid(axisalignedbb); - } - -+ // Tuinity start - detailed watchdog information -+ private Vec3D moveVector; -+ private double moveStartX; -+ private double moveStartY; -+ private double moveStartZ; -+ -+ public final Vec3D getMoveVector() { -+ return this.moveVector; -+ } -+ -+ public final double getMoveStartX() { -+ return this.moveStartX; -+ } -+ -+ public final double getMoveStartY() { -+ return this.moveStartY; -+ } -+ -+ public final double getMoveStartZ() { -+ return this.moveStartZ; -+ } -+ // Tuinity end - detailed watchdog information -+ -+ boolean collidedOnSomething; // Tuinity - optimise collisions -+ boolean requiredRelaxedCollisionCheck; // Tuinity - optimise collisions -+ - public void move(EnumMoveType enummovetype, Vec3D vec3d) { -+ // Tuinity start - detailed watchdog information -+ com.tuinity.tuinity.util.TickThread.ensureTickThread("Cannot move an entity off-main"); -+ synchronized (this.posLock) { -+ this.moveStartX = this.locX(); -+ this.moveStartY = this.locY(); -+ this.moveStartZ = this.locZ(); -+ this.moveVector = vec3d; -+ } -+ this.collidedOnSomething = false; // Tuinity - optimise collisions -+ try { -+ // Tuinity end - detailed watchdog information - if (this.noclip) { - this.a(this.getBoundingBox().b(vec3d)); - this.recalcPosition(); -@@ -629,7 +674,8 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - // Paper end - - vec3d = this.a(vec3d, enummovetype); -- Vec3D vec3d1 = this.e(vec3d); -+ Vec3D vec3d1 = !this.requiredRelaxedCollisionCheck ? this.performCollision(vec3d) : this.performCollision(vec3d, 0.0625); // Tuinity - optimise collisions -+ this.collidedOnSomething = !vec3d.equals(vec3d1); // Tuinity - optimise collisions - - if (vec3d1.g() > 1.0E-7D) { - this.a(this.getBoundingBox().b(vec3d1)); -@@ -761,6 +807,13 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - - this.world.getMethodProfiler().exit(); - } -+ // Tuinity start - detailed watchdog information -+ } finally { -+ synchronized (this.posLock) { // Tuinity -+ this.moveVector = null; -+ } // Tuinity -+ } -+ // Tuinity end - detailed watchdog information - } - - protected BlockPosition ag() { -@@ -841,6 +894,138 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - return d0; - } - -+ // Tuinity start - optimise entity movement -+ private static double performCollisionsX(AxisAlignedBB currentBoundingBox, double value, List potentialCollisions) { -+ for (int i = 0, len = potentialCollisions.size(); i < len; ++i) { -+ if (Math.abs(value) < 1.0E-7) { -+ return 0.0; -+ } -+ AxisAlignedBB target = potentialCollisions.get(i); -+ value = target.collideX(currentBoundingBox, value); -+ } -+ -+ return value; -+ } -+ -+ private static double performCollisionsY(AxisAlignedBB currentBoundingBox, double value, List potentialCollisions) { -+ for (int i = 0, len = potentialCollisions.size(); i < len; ++i) { -+ if (Math.abs(value) < 1.0E-7) { -+ return 0.0; -+ } -+ AxisAlignedBB target = potentialCollisions.get(i); -+ value = target.collideY(currentBoundingBox, value); -+ } -+ -+ return value; -+ } -+ -+ private static double performCollisionsZ(AxisAlignedBB currentBoundingBox, double value, List potentialCollisions) { -+ for (int i = 0, len = potentialCollisions.size(); i < len; ++i) { -+ if (Math.abs(value) < 1.0E-7) { -+ return 0.0; -+ } -+ AxisAlignedBB target = potentialCollisions.get(i); -+ value = target.collideZ(currentBoundingBox, value); -+ } -+ -+ return value; -+ } -+ -+ private static Vec3D performCollisions(Vec3D moveVector, AxisAlignedBB axisalignedbb, List potentialCollisions) { -+ double x = moveVector.x; -+ double y = moveVector.y; -+ double z = moveVector.z; -+ -+ if (y != 0.0) { -+ y = Entity.performCollisionsY(axisalignedbb, y, potentialCollisions); -+ if (y != 0.0) { -+ axisalignedbb = axisalignedbb.offsetY(y); -+ } -+ } -+ -+ boolean xSmaller = Math.abs(x) < Math.abs(z); -+ -+ if (xSmaller && z != 0.0) { -+ z = Entity.performCollisionsZ(axisalignedbb, z, potentialCollisions); -+ if (z != 0.0) { -+ axisalignedbb = axisalignedbb.offsetZ(z); -+ } -+ } -+ -+ if (x != 0.0) { -+ x = Entity.performCollisionsX(axisalignedbb, x, potentialCollisions); -+ if (!xSmaller && x != 0.0) { -+ axisalignedbb = axisalignedbb.offsetX(x); -+ } -+ } -+ -+ if (!xSmaller && z != 0.0) { -+ z = Entity.performCollisionsZ(axisalignedbb, z, potentialCollisions); -+ } -+ -+ return new Vec3D(x, y, z); -+ } -+ -+ Vec3D performCollision(Vec3D moveVector) { -+ return this.performCollision(moveVector, 0.0); -+ } -+ Vec3D performCollision(Vec3D moveVector, double contractAmount) { -+ if (moveVector.getX() == 0.0 && moveVector.getY() == 0.0 && moveVector.getZ() == 0.0) { -+ return moveVector; -+ } -+ -+ WorldServer world = ((WorldServer)this.world); -+ AxisAlignedBB currBoundingBox = contractAmount == 0.0 ? this.getBoundingBox() : this.getBoundingBox().grow(-contractAmount); -+ -+ List potentialCollisions = com.tuinity.tuinity.util.CachedLists.getTempCollisionList(); -+ try { -+ // We take a fat guess that we actually need to do the step height checks. -+ // So we collect all of the AABB's we would ever need into one list, and use that list -+ // for every collision check we want. -+ AxisAlignedBB collisionBox; -+ double stepHeight = (double) this.getStepHeight(); -+ if ((this.onGround || (moveVector.y < 0.0)) && (moveVector.x != 0.0 || moveVector.z != 0.0)) { -+ // don't bother getting the collisions if we don't need them. -+ if (moveVector.y <= 0.0) { -+ collisionBox = currBoundingBox.expand(moveVector.x, moveVector.y, moveVector.z).expandUpwards(stepHeight); -+ } else { -+ collisionBox = currBoundingBox.expand(moveVector.x, Math.max(stepHeight, moveVector.y), moveVector.z); -+ } -+ } else { -+ collisionBox = currBoundingBox.expand(moveVector.x, moveVector.y, moveVector.z); -+ } -+ world.getCollisions(this, collisionBox, potentialCollisions, false); -+ -+ Vec3D limitedMoveVector = Entity.performCollisions(moveVector, currBoundingBox, potentialCollisions); -+ -+ if (stepHeight > 0.0 -+ && (this.onGround || (limitedMoveVector.y != moveVector.y && moveVector.y < 0.0)) -+ && (limitedMoveVector.x != moveVector.x || limitedMoveVector.z != moveVector.z)) { -+ Vec3D vec3d2 = Entity.performCollisions(new Vec3D(moveVector.x, stepHeight, moveVector.z), currBoundingBox, potentialCollisions); -+ Vec3D vec3d3 = Entity.performCollisions(new Vec3D(0.0, stepHeight, 0.0), currBoundingBox.expand(moveVector.x, 0.0, moveVector.z), potentialCollisions); -+ -+ if (vec3d3.y < stepHeight) { -+ Vec3D vec3d4 = Entity.performCollisions(new Vec3D(moveVector.x, 0.0D, moveVector.z), currBoundingBox.offset(vec3d3), potentialCollisions); -+ -+ if (Entity.getXZSquared(vec3d4) > Entity.getXZSquared(vec3d2)) { -+ vec3d2 = vec3d4; -+ } -+ } -+ -+ if (Entity.getXZSquared(vec3d2) > Entity.getXZSquared(limitedMoveVector)) { -+ return vec3d2.add(Entity.performCollisions(new Vec3D(0.0D, -vec3d2.y + moveVector.y, 0.0D), currBoundingBox.offset(vec3d2), potentialCollisions)); -+ } -+ -+ return limitedMoveVector; -+ } else { -+ return limitedMoveVector; -+ } -+ } finally { -+ com.tuinity.tuinity.util.CachedLists.returnTempCollisionList(potentialCollisions); -+ } -+ } -+ // Tuinity end - optimise entity movement -+ - private Vec3D e(Vec3D vec3d) { - AxisAlignedBB axisalignedbb = this.getBoundingBox(); - VoxelShapeCollision voxelshapecollision = VoxelShapeCollision.a(this); -@@ -874,6 +1059,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - return vec3d1; - } - -+ public static double getXZSquared(Vec3D vec3d) { return Entity.b(vec3d); } // Tuinity - OBFHELPER - public static double b(Vec3D vec3d) { - return vec3d.x * vec3d.x + vec3d.z * vec3d.z; - } -@@ -1138,8 +1324,8 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - } - - public final AxisAlignedBB getCollisionBox(){return au();} //Paper - OBFHELPER -- @Nullable -- public AxisAlignedBB au() { -+ @Nullable public final AxisAlignedBB getHardCollisionBox() { return this.au(); } // Tuinity - OBFHELPER -+ @Nullable public AxisAlignedBB au() { // Tuinity - OBFHELPER - return null; - } - -@@ -2057,8 +2243,8 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - } - - public final AxisAlignedBB getHardCollisionBox(Entity entity){ return j(entity);}//Paper - OBFHELPER -- @Nullable -- public AxisAlignedBB j(Entity entity) { -+ @Nullable public AxisAlignedBB getHardCollisionBoxWith(Entity entity) { return this.j(entity); } // Tuinity - OBFHELPER -+ @Nullable public AxisAlignedBB j(Entity entity) { // Tuinity - OBFHELPER - return null; - } - -@@ -3388,12 +3574,16 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - return new Vec3D(this.locX, this.locY, this.locZ); - } - -+ public final Object posLock = new Object(); // Tuinity - log detailed entity tick information -+ - public Vec3D getMot() { - return this.mot; - } - - public void setMot(Vec3D vec3d) { -+ synchronized (this.posLock) { // Tuinity - this.mot = vec3d; -+ } // Tuinity - } - - public void setMot(double d0, double d1, double d2) { -@@ -3449,9 +3639,11 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - this.setBoundingBox(new AxisAlignedBB(d0 - (double) f, d1, d2 - (double) f, d0 + (double) f, d1 + (double) f1, d2 + (double) f)); - } - // Paper end -+ synchronized (this.posLock) { // Tuinity - this.locX = d0; - this.locY = d1; - this.locZ = d2; -+ } // Tuinity - } - - public void checkDespawn() {} -diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java -index 3fc2360a1..a245cfab6 100644 ---- a/src/main/java/net/minecraft/server/EntityLiving.java -+++ b/src/main/java/net/minecraft/server/EntityLiving.java -@@ -2682,7 +2682,11 @@ public abstract class EntityLiving extends Entity { - return; - } - // Paper - end don't run getEntities if we're not going to use its result -- List list = this.world.getEntities(this, this.getBoundingBox(), IEntitySelector.a(this)); -+ // Tuinity start - reduce memory allocation from collideNearby -+ List list = com.tuinity.tuinity.util.CachedLists.getTempGetEntitiesList(); -+ this.world.getEntities(this, this.getBoundingBox(), IEntitySelector.a(this), list); -+ try { -+ // Tuinity end - reduce memory allocation from collideNearby - - if (!list.isEmpty()) { - // Paper - move up -@@ -2711,6 +2715,9 @@ public abstract class EntityLiving extends Entity { - this.C(entity); - } - } -+ } finally { // Tuinity start - reduce memory allocation from collideNearby -+ com.tuinity.tuinity.util.CachedLists.returnTempGetEntitiesList(list); -+ } // Tuinity end - reduce memory allocation from collideNearby - - } - -diff --git a/src/main/java/net/minecraft/server/EntityTrackerEntry.java b/src/main/java/net/minecraft/server/EntityTrackerEntry.java -index 5cc89c0cf..1bd703848 100644 ---- a/src/main/java/net/minecraft/server/EntityTrackerEntry.java -+++ b/src/main/java/net/minecraft/server/EntityTrackerEntry.java -@@ -72,6 +72,7 @@ public class EntityTrackerEntry { - - public final void tick() { this.a(); } // Paper - OBFHELPER - public void a() { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Tracker update"); // Tuinity - List list = this.tracker.getPassengers(); - - if (!list.equals(this.p)) { -diff --git a/src/main/java/net/minecraft/server/HeightMap.java b/src/main/java/net/minecraft/server/HeightMap.java -index 29cb545a8..aa7339610 100644 ---- a/src/main/java/net/minecraft/server/HeightMap.java -+++ b/src/main/java/net/minecraft/server/HeightMap.java -@@ -119,6 +119,7 @@ public class HeightMap { - } - } - -+ public final int get(int x, int z) { return this.a(x, z); } // Tuinity - OBFHELPER - public int a(int i, int j) { - return this.a(c(i, j)); - } -@@ -154,7 +155,7 @@ public class HeightMap { - private final String g; - private final HeightMap.Use h; - private final Predicate i; -- private static final Map j = (Map) SystemUtils.a((Object) Maps.newHashMap(), (hashmap) -> { -+ private static final Map j = SystemUtils.a(Maps.newHashMap(), (hashmap) -> { // Tuinity - decompile fix - HeightMap.Type[] aheightmap_type = values(); - int i = aheightmap_type.length; - -@@ -166,7 +167,7 @@ public class HeightMap { - - }); - -- private Type(String s, HeightMap.Use heightmap_use, Predicate predicate) { -+ private Type(String s, HeightMap.Use heightmap_use, Predicate predicate) { // Tuinity - decompile fix - this.g = s; - this.h = heightmap_use; - this.i = predicate; -diff --git a/src/main/java/net/minecraft/server/IBlockData.java b/src/main/java/net/minecraft/server/IBlockData.java -index b39554faf..41cac2741 100644 ---- a/src/main/java/net/minecraft/server/IBlockData.java -+++ b/src/main/java/net/minecraft/server/IBlockData.java -@@ -26,6 +26,18 @@ public class IBlockData extends BlockDataAbstract implements - private final boolean isTicking; // Paper - private final boolean canOcclude; // Paper - -+ // Tuinity start - optimise getType calls -+ org.bukkit.Material cachedMaterial; -+ -+ public final org.bukkit.Material getBukkitMaterial() { -+ if (this.cachedMaterial == null) { -+ this.cachedMaterial = org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(this.getBlock()); -+ } -+ -+ return this.cachedMaterial; -+ } -+ // Tuinity end - optimise getType calls -+ - public IBlockData(Block block, ImmutableMap, Comparable> immutablemap) { - super(block, immutablemap); - this.d = block.a(this); -diff --git a/src/main/java/net/minecraft/server/ICollisionAccess.java b/src/main/java/net/minecraft/server/ICollisionAccess.java -index 63dd5e98b..2001c2a39 100644 ---- a/src/main/java/net/minecraft/server/ICollisionAccess.java -+++ b/src/main/java/net/minecraft/server/ICollisionAccess.java -@@ -43,6 +43,11 @@ public interface ICollisionAccess extends IBlockAccess { - } - - default boolean a(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set) { -+ // Tuinity start - allow overriding in WorldServer -+ return this.getCubes(entity, axisalignedbb, set); -+ } -+ default boolean getCubes(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set) { -+ // Tuinity end - allow overriding in WorldServer - try { if (entity != null) entity.collisionLoadChunks = true; // Paper - // Paper start - reduce stream usage - java.util.List blockCollisions = getBlockCollision(entity, axisalignedbb, true); -@@ -96,10 +101,9 @@ public interface ICollisionAccess extends IBlockAccess { - if (entity != null) { - // Paper end - //VoxelShape voxelshape1 = ICollisionAccess.this.getWorldBorder().a(); // Paper - only make if collides -- boolean flag = !ICollisionAccess.this.getWorldBorder().isInBounds(entity.getBoundingBox().shrink(1.0E-7D)); // Paper -- boolean flag1 = !ICollisionAccess.this.getWorldBorder().isInBounds(entity.getBoundingBox().g(1.0E-7D)); // Paper -+ // Tuinity - optimise voxelshapes - -- if (!flag && flag1) { -+ if (ICollisionAccess.this.getWorldBorder().isCollidingOnBorderEdge(entity.getBoundingBox())) { // Tuinity - optimise voxelshapes - collisions.add(ICollisionAccess.this.getWorldBorder().a());// Paper - if (returnFast) return collisions; - } -@@ -112,26 +116,15 @@ public interface ICollisionAccess extends IBlockAccess { - int j2 = cursorposition.e(); - - if (j2 != 3) { -- // Paper start - ensure we don't load chunks -- //int k2 = k1 >> 4; -- //int l2 = i2 >> 4; -- boolean far = entity != null && MCUtil.distanceSq(entity.locX(), y, entity.locZ(), x, y, z) > 14; -- blockposition_mutableblockposition.setValues(x, y, z); -- -- boolean isRegionLimited = ICollisionAccess.this instanceof RegionLimitedWorldAccess; -- IBlockData iblockdata = isRegionLimited ? Blocks.VOID_AIR.getBlockData() : ((!far && entity instanceof EntityPlayer) || (entity != null && entity.collisionLoadChunks) -- ? ICollisionAccess.this.getType(blockposition_mutableblockposition) -- : ICollisionAccess.this.getTypeIfLoaded(blockposition_mutableblockposition) -- ); -- if (iblockdata == null) { -- if (!(entity instanceof EntityPlayer) || entity.world.paperConfig.preventMovingIntoUnloadedChunks) { -- collisions.add(VoxelShapes.of(far ? entity.getBoundingBox() : new AxisAlignedBB(new BlockPosition(x, y, z)))); -- if (returnFast) return collisions; -- } -- } else { -- //blockposition_mutableblockposition.d(k1, l1, i2); // moved up -- //IBlockData iblockdata = iblockaccess.getType(blockposition_mutableblockposition); // moved up -- // Paper end -+ // Tuinity start - revert to vanilla -+ int k2 = k1 >> 4; -+ int l2 = i2 >> 4; -+ IBlockAccess iblockaccess = ICollisionAccess.this.c(k2, l2); -+ -+ if (iblockaccess != null) { -+ blockposition_mutableblockposition.d(k1, l1, i2); -+ IBlockData iblockdata = iblockaccess.getType(blockposition_mutableblockposition); -+ // Tuinity end - revert to vanilla - - if (!iblockdata.isAir() && (j2 != 1 || iblockdata.f()) && (j2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) { // Paper - fast track air - VoxelShape voxelshape2 = iblockdata.b((IBlockAccess) ICollisionAccess.this, blockposition_mutableblockposition, voxelshapecollision); -diff --git a/src/main/java/net/minecraft/server/LightEngineStorage.java b/src/main/java/net/minecraft/server/LightEngineStorage.java -index f2575fb69..89985a61e 100644 ---- a/src/main/java/net/minecraft/server/LightEngineStorage.java -+++ b/src/main/java/net/minecraft/server/LightEngineStorage.java -@@ -23,7 +23,8 @@ public abstract class LightEngineStorage> e - protected final M f; protected final M updating; // Paper - diff on change, should be "updating" - protected final LongSet g = new LongOpenHashSet(); - protected final LongSet h = new LongOpenHashSet(); LongSet dirty = h; // Paper - OBFHELPER -- protected final Long2ObjectMap i = Long2ObjectMaps.synchronize(new Long2ObjectOpenHashMap()); -+ protected final Long2ObjectOpenHashMap i_synchronized_map_real = new Long2ObjectOpenHashMap<>(); // Tuinity - store wrapped map, we need fastIterator -+ protected final Long2ObjectMap i = Long2ObjectMaps.synchronize(this.i_synchronized_map_real); // Tuinity - store wrapped map, we need fastIterator - private final LongSet n = new LongOpenHashSet(); - private final LongSet o = new LongOpenHashSet(); - protected volatile boolean j; -@@ -246,7 +247,7 @@ public abstract class LightEngineStorage> e - - this.o.clear(); - this.j = false; -- ObjectIterator> objectiterator = Long2ObjectMaps.fastIterator(this.i); // Paper -+ ObjectIterator objectiterator = this.i_synchronized_map_real.long2ObjectEntrySet().fastIterator(); // Tuinity - use fast iterator to reduce entry creation - remove paper diff, it's ineffective - - Entry entry; - long j; -diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java -index 87d580021..973bdd25c 100644 ---- a/src/main/java/net/minecraft/server/MCUtil.java -+++ b/src/main/java/net/minecraft/server/MCUtil.java -@@ -48,6 +48,20 @@ public final class MCUtil { - new ThreadFactoryBuilder().setNameFormat("Paper Object Cleaner").build() - ); - -+ // Tuinity start -+ private static org.bukkit.entity.HumanEntity[] EMPTY_HUMAN_ARRAY = new org.bukkit.entity.HumanEntity[0]; -+ public static void closeInventory(IInventory inventory, org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) { -+ List viewers = inventory.getViewers(); -+ if (viewers.isEmpty()) { -+ return; -+ } -+ -+ for (org.bukkit.entity.HumanEntity viewer : viewers.toArray(EMPTY_HUMAN_ARRAY)) { -+ viewer.closeInventory(reason); -+ } -+ } -+ // Tuinity end -+ - public static final long INVALID_CHUNK_KEY = getCoordinateKey(Integer.MAX_VALUE, Integer.MAX_VALUE); - - -diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 4ab657903..3c9392077 100644 ---- a/src/main/java/net/minecraft/server/MinecraftServer.java -+++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -954,7 +954,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant worlds = (List)this.getWorlds(); // PaperWorldMap makes this a list. -+ for (int i = 0; i < worlds.size(); ++i) { -+ WorldServer world = worlds.get(i); -+ long currTime = System.nanoTime(); -+ if (currTime - world.lastMidTickExecuteFailure <= TASK_EXECUTION_FAILURE_BACKOFF) { -+ continue; -+ } -+ if (!world.getChunkProvider().runTasks()) { -+ // we need to back off if this fails -+ world.lastMidTickExecuteFailure = currTime; -+ } else { -+ executed = true; -+ } -+ } -+ -+ return executed; -+ } -+ -+ public final void executeMidTickTasks() { -+ org.spigotmc.AsyncCatcher.catchOp("mid tick chunk task execution"); -+ long startTime = System.nanoTime(); -+ if ((startTime - lastMidTickExecute) <= CHUNK_TASK_QUEUE_BACKOFF_MIN_TIME || (startTime - lastMidTickExecuteFailure) <= TASK_EXECUTION_FAILURE_BACKOFF) { -+ // it's shown to be bad to constantly hit the queue (chunk loads slow to a crawl), even if no tasks are executed. -+ // so, backoff to prevent this -+ return; -+ } -+ -+ co.aikar.timings.MinecraftTimings.midTickChunkTasks.startTiming(); -+ try { -+ for (;;) { -+ boolean moreTasks = this.tickMidTickTasks(); -+ long currTime = System.nanoTime(); -+ long diff = currTime - startTime; -+ -+ if (!moreTasks || diff >= MAX_CHUNK_EXEC_TIME) { -+ if (!moreTasks) { -+ lastMidTickExecuteFailure = currTime; -+ } -+ -+ // note: negative values reduce the time -+ long overuse = diff - MAX_CHUNK_EXEC_TIME; -+ if (overuse >= (10L * 1000L * 1000L)) { // 10ms -+ // make sure something like a GC or dumb plugin doesn't screw us over... -+ overuse = 10L * 1000L * 1000L; // 10ms -+ } -+ -+ double overuseCount = (double)overuse/(double)MAX_CHUNK_EXEC_TIME; -+ long extraSleep = (long)Math.round(overuseCount*CHUNK_TASK_QUEUE_BACKOFF_MIN_TIME); -+ -+ lastMidTickExecute = currTime + extraSleep; -+ return; -+ } -+ } -+ } finally { -+ co.aikar.timings.MinecraftTimings.midTickChunkTasks.stopTiming(); -+ } -+ } -+ // Tuinity end - execute chunk tasks mid tick -+ - private void executeModerately() { - this.executeAll(); - java.util.concurrent.locks.LockSupport.parkNanos("executing tasks", 1000L); -@@ -1061,22 +1133,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant { -- midTickLoadChunks(); // will only do loads since we are still considered !canSleepForTick -+ // Tuinity - replace logic - return !this.canOversleep(); - }); - isOversleep = false;MinecraftTimings.serverOversleep.stopTiming(); -@@ -1233,6 +1291,8 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant // Spigot - Spigot > // CraftBukkit - cb > vanilla! -+ return "Tuinity"; // Tuinity //Paper - Paper > // Spigot - Spigot > // CraftBukkit - cb > vanilla! - } - - public CrashReport b(CrashReport crashreport) { -diff --git a/src/main/java/net/minecraft/server/NetworkManager.java b/src/main/java/net/minecraft/server/NetworkManager.java -index 32886109d..5578818a0 100644 ---- a/src/main/java/net/minecraft/server/NetworkManager.java -+++ b/src/main/java/net/minecraft/server/NetworkManager.java -@@ -70,6 +70,39 @@ public class NetworkManager extends SimpleChannelInboundHandler> { - EnumProtocol protocol; - // Paper end - -+ // Tuinity start - allow controlled flushing -+ volatile boolean canFlush = true; -+ private final java.util.concurrent.atomic.AtomicInteger packetWrites = new java.util.concurrent.atomic.AtomicInteger(); -+ private int flushPacketsStart; -+ private final Object flushLock = new Object(); -+ -+ void disableAutomaticFlush() { -+ synchronized (this.flushLock) { -+ this.flushPacketsStart = this.packetWrites.get(); // must be volatile and before canFlush = false -+ this.canFlush = false; -+ } -+ } -+ -+ void enableAutomaticFlush() { -+ synchronized (this.flushLock) { -+ this.canFlush = true; -+ if (this.packetWrites.get() != this.flushPacketsStart) { // must be after canFlush = true -+ this.flush(); // only make the flush call if we need to -+ } -+ } -+ } -+ -+ private final void flush() { -+ if (this.channel.eventLoop().inEventLoop()) { -+ this.channel.flush(); -+ } else { -+ this.channel.eventLoop().execute(() -> { -+ this.channel.flush(); -+ }); -+ } -+ } -+ // Tuinity end - allow controlled flushing -+ - public NetworkManager(EnumProtocolDirection enumprotocoldirection) { - this.h = enumprotocoldirection; - } -@@ -217,7 +250,7 @@ public class NetworkManager extends SimpleChannelInboundHandler> { - MCUtil.isMainThread() && packet.isReady() && this.packetQueue.isEmpty() && - (packet.getExtraPackets() == null || packet.getExtraPackets().isEmpty()) - ))) { -- this.dispatchPacket(packet, genericfuturelistener); -+ this.writePacket(packet, genericfuturelistener, null); // Tuinity - return; - } - // write the packets to the queue, then flush - antixray hooks there already -@@ -243,6 +276,14 @@ public class NetworkManager extends SimpleChannelInboundHandler> { - - private void dispatchPacket(Packet packet, @Nullable GenericFutureListener> genericFutureListener) { this.b(packet, genericFutureListener); } // Paper - OBFHELPER - private void b(Packet packet, @Nullable GenericFutureListener> genericfuturelistener) { -+ // Tuinity start - add flush parameter -+ this.writePacket(packet, genericfuturelistener, Boolean.TRUE); -+ } -+ private void writePacket(Packet packet, @Nullable GenericFutureListener> genericfuturelistener, Boolean flushConditional) { -+ this.packetWrites.getAndIncrement(); // must be befeore using canFlush -+ boolean effectiveFlush = flushConditional == null ? this.canFlush : flushConditional.booleanValue(); -+ final boolean flush = effectiveFlush || packet instanceof PacketPlayOutKeepAlive || packet instanceof PacketPlayOutKickDisconnect; // no delay for certain packets -+ // Tuinity end - add flush parameter - EnumProtocol enumprotocol = EnumProtocol.a(packet); - EnumProtocol enumprotocol1 = (EnumProtocol) this.channel.attr(NetworkManager.c).get(); - -@@ -265,7 +306,7 @@ public class NetworkManager extends SimpleChannelInboundHandler> { - try { - // Paper end - -- ChannelFuture channelfuture = this.channel.writeAndFlush(packet); -+ ChannelFuture channelfuture = (flush) ? this.channel.writeAndFlush(packet) : this.channel.write(packet); // Tuinity - add flush parameter - - if (genericfuturelistener != null) { - channelfuture.addListener(genericfuturelistener); -@@ -297,7 +338,7 @@ public class NetworkManager extends SimpleChannelInboundHandler> { - } - try { - // Paper end -- ChannelFuture channelfuture1 = this.channel.writeAndFlush(packet); -+ ChannelFuture channelfuture1 = (flush) ? this.channel.writeAndFlush(packet) : this.channel.write(packet); // Tuinity - add flush parameter - - - if (genericfuturelistener != null) { -@@ -340,6 +381,8 @@ public class NetworkManager extends SimpleChannelInboundHandler> { - } - private boolean processQueue() { - if (this.packetQueue.isEmpty()) return true; -+ final boolean needsFlush = this.canFlush; // Tuinity - make only one flush call per sendPacketQueue() call -+ boolean hasWrotePacket = false; - // If we are on main, we are safe here in that nothing else should be processing queue off main anymore - // But if we are not on main due to login/status, the parent is synchronized on packetQueue - java.util.Iterator iterator = this.packetQueue.iterator(); -@@ -347,16 +390,22 @@ public class NetworkManager extends SimpleChannelInboundHandler> { - NetworkManager.QueuedPacket queued = iterator.next(); // poll -> peek - - // Fix NPE (Spigot bug caused by handleDisconnection()) -- if (queued == null) { -+ if (false && queued == null) { // Tuinity - diff on change, this logic is redundant: iterator guarantees ret of an element - on change, hook the flush logic here - return true; - } - - Packet packet = queued.getPacket(); - if (!packet.isReady()) { -+ // Tuinity start - make only one flush call per sendPacketQueue() call -+ if (hasWrotePacket && (needsFlush || this.canFlush)) { -+ this.flush(); -+ } -+ // Tuinity end - make only one flush call per sendPacketQueue() call - return false; - } else { - iterator.remove(); -- this.dispatchPacket(packet, queued.getGenericFutureListener()); -+ this.writePacket(packet, queued.getGenericFutureListener(), (!iterator.hasNext() && (needsFlush || this.canFlush)) ? Boolean.TRUE : Boolean.FALSE); // Tuinity - make only one flush call per sendPacketQueue() call -+ hasWrotePacket = true; // Tuinity - make only one flush call per sendPacketQueue() call - } - } - return true; -diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java -index 9b608d738..bf24cb0d2 100644 ---- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java -+++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java -@@ -19,7 +19,7 @@ public class PacketPlayOutMapChunk implements Packet { - @Nullable - private BiomeStorage e; - private byte[] f; private byte[] getData() { return this.f; } // Paper - OBFHELPER -- private List g; -+ private List g; private List getTileEntityData() { return this.g; } // Tuinity - OBFHELPER - private boolean h; - private volatile boolean ready; // Paper - Async-Anti-Xray - Ready flag for the network manager - -@@ -31,14 +31,16 @@ public class PacketPlayOutMapChunk implements Packet { - - // Paper start - private final java.util.List extraPackets = new java.util.ArrayList<>(); -- private static final int TE_LIMIT = Integer.getInteger("Paper.excessiveTELimit", 750); -+ private static final int TE_LIMIT = Integer.getInteger("tuinity.excessive-te-limit", 750); // Tuinity - handle oversized chunk data packets more robustly -+ private static final int TE_SPLIT_LIMIT = Math.max(4096 + 1, Integer.getInteger("tuinity.te-split-limit", 15_000)); // Tuinity - handle oversized chunk data packets more robustly -+ private boolean mustSplit; // Tuinity - handle oversized chunk data packets more robustly - - @Override - public java.util.List getExtraPackets() { - return extraPackets; - } - // Paper end -- public PacketPlayOutMapChunk(Chunk chunk, int i) { -+ public PacketPlayOutMapChunk(Chunk chunk, int i) { final int chunkSectionBitSet = i; // Tuinity - handle oversized chunk data packets more robustly - ChunkPacketInfo chunkPacketInfo = chunk.world.chunkPacketBlockController.getChunkPacketInfo(this, chunk, i); // Paper - Anti-Xray - Add chunk packet info - ChunkCoordIntPair chunkcoordintpair = chunk.getPos(); - -@@ -46,31 +48,12 @@ public class PacketPlayOutMapChunk implements Packet { - this.b = chunkcoordintpair.z; - this.h = i == 65535; - this.d = new NBTTagCompound(); -- Iterator iterator = chunk.f().iterator(); -- -- Entry entry; -- -- while (iterator.hasNext()) { -- entry = (Entry) iterator.next(); -- if (((HeightMap.Type) entry.getKey()).b()) { -- this.d.set(((HeightMap.Type) entry.getKey()).a(), new NBTTagLongArray(((HeightMap) entry.getValue()).a())); -- } -- } -- -- if (this.h) { -- this.e = chunk.getBiomeIndex().b(); -- } -- -- this.f = new byte[this.a(chunk, i)]; -- // Paper start - Anti-Xray - Add chunk packet info -- if (chunkPacketInfo != null) { -- chunkPacketInfo.setData(this.getData()); -- } -- this.c = this.writeChunk(new PacketDataSerializer(this.j()), chunk, i, chunkPacketInfo); -- // Paper end -+ // Tuinity start - improve oversized chunk data packet handling -+ // move the TE code up here so we can decide whether to split before writing - this.g = Lists.newArrayList(); -- iterator = chunk.getTileEntities().entrySet().iterator(); -- int totalTileEntities = 0; // Paper -+ Iterator iterator = chunk.getTileEntities().entrySet().iterator(); -+ Entry entry; -+ int totalTileEntities = 0; // Paper // Tuinity - - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); -@@ -79,14 +62,23 @@ public class PacketPlayOutMapChunk implements Packet { - int j = blockposition.getY() >> 4; - - if (this.f() || (i & 1 << j) != 0) { -- // Paper start - improve oversized chunk data packet handling -- if (++totalTileEntities > TE_LIMIT) { -+ // Paper start - send signs separately -+ // Tuinity start - improve oversized chunk data packet handling -+ ++totalTileEntities; -+ if (totalTileEntities > TE_SPLIT_LIMIT) { -+ this.mustSplit = true; -+ this.getTileEntityData().clear(); -+ this.extraPackets.clear(); -+ break; -+ } -+ if (totalTileEntities > TE_LIMIT) { - PacketPlayOutTileEntityData updatePacket = tileentity.getUpdatePacket(); - if (updatePacket != null) { - this.extraPackets.add(updatePacket); - continue; - } - } -+ // Tuinity end - // Paper end - NBTTagCompound nbttagcompound = tileentity.b(); - if (tileentity instanceof TileEntitySkull) { TileEntitySkull.sanitizeTileEntityUUID(nbttagcompound); } // Paper -@@ -94,7 +86,70 @@ public class PacketPlayOutMapChunk implements Packet { - this.g.add(nbttagcompound); - } - } -+ iterator = chunk.f().iterator(); -+ // Tuinity end -+ -+ while (iterator.hasNext()) { -+ entry = (Entry) iterator.next(); -+ if (((HeightMap.Type) entry.getKey()).b()) { -+ this.d.set(((HeightMap.Type) entry.getKey()).a(), new NBTTagLongArray(((HeightMap) entry.getValue()).a())); -+ } -+ } -+ -+ if (this.h) { -+ this.e = chunk.getBiomeIndex().b(); -+ } -+ -+ this.f = new byte[this.a(chunk, i)]; -+ // Paper start - Anti-Xray - Add chunk packet info -+ if (chunkPacketInfo != null) { -+ chunkPacketInfo.setData(this.getData()); -+ } -+ this.c = this.writeChunk(new PacketDataSerializer(this.j()), chunk, i, chunkPacketInfo); -+ // Paper end -+ // Tuinity start - improve oversized chunk data packet handling -+ // move the TE code up here so we can decide whether to split before writing -+// this.g = Lists.newArrayList(); -+// iterator = chunk.getTileEntities().entrySet().iterator(); -+// int totalTileEntities = 0; // Paper -+// -+// while (iterator.hasNext()) { -+// entry = (Entry) iterator.next(); -+// BlockPosition blockposition = (BlockPosition) entry.getKey(); -+// TileEntity tileentity = (TileEntity) entry.getValue(); -+// int j = blockposition.getY() >> 4; -+// -+// if (this.f() || (i & 1 << j) != 0) { -+// // Paper start - improve oversized chunk data packet handling -+// if (++totalTileEntities > TE_LIMIT) { -+// PacketPlayOutTileEntityData updatePacket = tileentity.getUpdatePacket(); -+// if (updatePacket != null) { -+// this.extraPackets.add(updatePacket); -+// continue; -+// } -+// } -+// // Paper end -+// NBTTagCompound nbttagcompound = tileentity.b(); -+// if (tileentity instanceof TileEntitySkull) { TileEntitySkull.sanitizeTileEntityUUID(nbttagcompound); } // Paper -+// -+// this.g.add(nbttagcompound); -+// } -+// } -+ // Tuinity end - improve oversized chunk data packet handling - chunk.world.chunkPacketBlockController.modifyBlocks(this, chunkPacketInfo); // Paper - Anti-Xray - Modify blocks -+ // Tuinity start - improve oversized chunk data packet handling -+ if (this.mustSplit) { -+ int chunkSectionBitSetCopy = chunkSectionBitSet; -+ for (int a = 0, len = Integer.bitCount(chunkSectionBitSet); a < len; ++a) { -+ int trailingBit = com.destroystokyo.paper.util.math.IntegerUtil.getTrailingBit(chunkSectionBitSetCopy); -+ int sectionIndex = Integer.numberOfTrailingZeros(trailingBit); -+ chunkSectionBitSetCopy ^= trailingBit; // move on to the next -+ -+ if (chunk.getSections()[sectionIndex] != null) { -+ this.extraPackets.add(new PacketPlayOutMapChunk(chunk, trailingBit)); -+ } -+ } -+ } // Tuinity end - improve oversized chunk data packet handling - } - - // Paper start - Async-Anti-Xray - Getter and Setter for the ready flag -@@ -185,7 +240,7 @@ public class PacketPlayOutMapChunk implements Packet { - for (int l = achunksection.length; k < l; ++k) { - ChunkSection chunksection = achunksection[k]; - -- if (chunksection != Chunk.a && (!this.f() || !chunksection.c()) && (i & 1 << k) != 0) { -+ if ((!this.mustSplit && chunksection != Chunk.a) && (!this.f() || !chunksection.c()) && (i & 1 << k) != 0) { // Tuinity - improve oversized chunk data packet handling - j |= 1 << k; - chunksection.writeChunkSection(packetdataserializer, chunkPacketInfo); // Paper - Anti-Xray - Add chunk packet info - } -@@ -202,7 +257,7 @@ public class PacketPlayOutMapChunk implements Packet { - for (int l = achunksection.length; k < l; ++k) { - ChunkSection chunksection = achunksection[k]; - -- if (chunksection != Chunk.a && (!this.f() || !chunksection.c()) && (i & 1 << k) != 0) { -+ if ((!this.mustSplit && chunksection != Chunk.a) && (!this.f() || !chunksection.c()) && (i & 1 << k) != 0) { - j += chunksection.j(); - } - } -diff --git a/src/main/java/net/minecraft/server/PathfinderNormal.java b/src/main/java/net/minecraft/server/PathfinderNormal.java -index 4240ca81c..61e4dbcd4 100644 ---- a/src/main/java/net/minecraft/server/PathfinderNormal.java -+++ b/src/main/java/net/minecraft/server/PathfinderNormal.java -@@ -444,7 +444,11 @@ public class PathfinderNormal extends PathfinderAbstract { - } - - protected static PathType c(IBlockAccess iblockaccess, int i, int j, int k) { -- BlockPosition blockposition = new BlockPosition(i, j, k); -+ // Tuinity start - reduce blockpos allocation -+ BlockPosition.PooledBlockPosition blockposition = BlockPosition.PooledBlockPosition.acquire(); -+ try { -+ blockposition.setValues(i, j, k); -+ // Tuinity end - reduce blockpos allocation - IBlockData iblockdata = iblockaccess.getTypeIfLoaded(blockposition); // Paper - if (iblockdata == null) return PathType.BLOCKED; // Paper - Block block = iblockdata.getBlock(); -@@ -474,7 +478,7 @@ public class PathfinderNormal extends PathfinderAbstract { - } else if (block instanceof BlockLeaves) { - return PathType.LEAVES; - } else if (!block.a(TagsBlock.FENCES) && !block.a(TagsBlock.WALLS) && (!(block instanceof BlockFenceGate) || (Boolean) iblockdata.get(BlockFenceGate.OPEN))) { -- Fluid fluid = iblockaccess.getFluid(blockposition); -+ Fluid fluid = iblockdata.getFluid(); // Tuinity - optimise out world#getFluid - - return fluid.a(TagsFluid.WATER) ? PathType.WATER : (fluid.a(TagsFluid.LAVA) ? PathType.LAVA : (iblockdata.a(iblockaccess, blockposition, PathMode.LAND) ? PathType.OPEN : PathType.BLOCKED)); - } else { -@@ -483,5 +487,10 @@ public class PathfinderNormal extends PathfinderAbstract { - } else { - return PathType.TRAPDOOR; - } -+ // Tuinity start - reduce blockpos allocation -+ } finally { -+ blockposition.close(); -+ } -+ // Tuinity end - reduce blockpos allocation - } - } -diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java -index 2edb4904d..44d6f2deb 100644 ---- a/src/main/java/net/minecraft/server/PlayerChunk.java -+++ b/src/main/java/net/minecraft/server/PlayerChunk.java -@@ -507,6 +507,7 @@ public class PlayerChunk { - // Paper end - per player view distance - } - -+ public final CompletableFuture> getOrCreateFuture(ChunkStatus chunkstatus, PlayerChunkMap playerchunkmap) { return this.a(chunkstatus, playerchunkmap); } // Tuinity - OBFHELPER - public CompletableFuture> a(ChunkStatus chunkstatus, PlayerChunkMap playerchunkmap) { - int i = chunkstatus.c(); - CompletableFuture> completablefuture = (CompletableFuture) this.statusFutures.get(i); -@@ -562,6 +563,7 @@ public class PlayerChunk { - } - - protected void a(PlayerChunkMap playerchunkmap) { -+ com.tuinity.tuinity.util.TickThread.ensureTickThread("Async ticket level update"); // Tuinity - ChunkStatus chunkstatus = getChunkStatus(this.oldTicketLevel); - ChunkStatus chunkstatus1 = getChunkStatus(this.ticketLevel); - boolean flag = this.oldTicketLevel <= PlayerChunkMap.GOLDEN_TICKET; -@@ -571,7 +573,8 @@ public class PlayerChunk { - // CraftBukkit start - // ChunkUnloadEvent: Called before the chunk is unloaded: isChunkLoaded is still true and chunk can still be modified by plugins. - if (playerchunk_state.isAtLeast(PlayerChunk.State.BORDER) && !playerchunk_state1.isAtLeast(PlayerChunk.State.BORDER)) { -- this.getStatusFutureUncheckedMain(ChunkStatus.FULL).thenAccept((either) -> { // Paper - ensure main -+ this.getStatusFutureUnchecked(ChunkStatus.FULL).thenAccept((either) -> { // Paper - ensure main // Tuinity - is always on main -+ com.tuinity.tuinity.util.TickThread.ensureTickThread("Async full status chunk future completion"); // Tuinity - Chunk chunk = (Chunk)either.left().orElse(null); - if (chunk != null) { - playerchunkmap.callbackExecutor.execute(() -> { -@@ -636,7 +639,8 @@ public class PlayerChunk { - if (!flag2 && flag3) { - // Paper start - cache ticking ready status - int expectCreateCount = ++this.fullChunkCreateCount; -- this.fullChunkFuture = playerchunkmap.b(this); ensureMain(this.fullChunkFuture).thenAccept((either) -> { // Paper - ensure main -+ this.fullChunkFuture = playerchunkmap.b(this); this.fullChunkFuture.thenAccept((either) -> { // Paper - ensure main // Tuinity - always fired on main -+ com.tuinity.tuinity.util.TickThread.ensureTickThread("Async full chunk future completion"); // Tuinity - if (either.left().isPresent() && PlayerChunk.this.fullChunkCreateCount == expectCreateCount) { - // note: Here is a very good place to add callbacks to logic waiting on this. - Chunk fullChunk = either.left().get(); -@@ -667,7 +671,8 @@ public class PlayerChunk { - - if (!flag4 && flag5) { - // Paper start - cache ticking ready status -- this.tickingFuture = playerchunkmap.a(this); ensureMain(this.tickingFuture).thenAccept((either) -> { // Paper - ensure main -+ this.tickingFuture = playerchunkmap.a(this); this.tickingFuture.thenAccept((either) -> { // Paper - ensure main // Tuinity - always completed on main -+ com.tuinity.tuinity.util.TickThread.ensureTickThread("Async ticking chunk future completion"); // Tuinity - if (either.left().isPresent()) { - // note: Here is a very good place to add callbacks to logic waiting on this. - Chunk tickingChunk = either.left().get(); -@@ -698,12 +703,20 @@ public class PlayerChunk { - } - - // Paper start - cache ticking ready status -- this.entityTickingFuture = playerchunkmap.b(this.location); ensureMain(this.entityTickingFuture).thenAccept((either) -> { // Paper ensureMain -+ this.entityTickingFuture = playerchunkmap.b(this.location); this.entityTickingFuture.thenAccept((either) -> { // Paper ensureMain // Tuinity - always completed on main -+ com.tuinity.tuinity.util.TickThread.ensureTickThread("Async entity ticking chunk future completion"); // Tuinity - if (either.left().isPresent()) { - // note: Here is a very good place to add callbacks to logic waiting on this. - Chunk entityTickingChunk = either.left().get(); - PlayerChunk.this.isEntityTickingReady = true; -- -+ // Tuinity start - optimise chunk tick iteration -+ ChunkProviderServer chunkProvider = PlayerChunk.this.chunkMap.world.getChunkProvider(); -+ if (chunkProvider.isTickingChunks) { -+ chunkProvider.pendingEntityTickingChunkChanges.put(entityTickingChunk, true); -+ } else { -+ chunkProvider.entityTickingChunks.add(entityTickingChunk); -+ } -+ // Tuinity end - optimise chunk tick iteration - - - -@@ -715,6 +728,17 @@ public class PlayerChunk { - - if (flag6 && !flag7) { - this.entityTickingFuture.complete(PlayerChunk.UNLOADED_CHUNK); this.isEntityTickingReady = false; // Paper - cache chunk ticking stage -+ // Tuinity start - optimise chunk tick iteration -+ ChunkProviderServer chunkProvider = PlayerChunk.this.chunkMap.world.getChunkProvider(); -+ Chunk chunk = this.getFullChunkIfCached(); -+ if (chunk != null) { -+ if (chunkProvider.isTickingChunks) { -+ chunkProvider.pendingEntityTickingChunkChanges.put(chunk, false); -+ } else { -+ chunkProvider.entityTickingChunks.remove(chunk); -+ } -+ } -+ // Tuinity end - optimise chunk tick iteration - this.entityTickingFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE; - } - // Paper start - raise IO/load priority if priority changes, use our preferred priority -@@ -740,7 +764,8 @@ public class PlayerChunk { - // CraftBukkit start - // ChunkLoadEvent: Called after the chunk is loaded: isChunkLoaded returns true and chunk is ready to be modified by plugins. - if (!playerchunk_state.isAtLeast(PlayerChunk.State.BORDER) && playerchunk_state1.isAtLeast(PlayerChunk.State.BORDER)) { -- this.getStatusFutureUncheckedMain(ChunkStatus.FULL).thenAccept((either) -> { // Paper - ensure main -+ this.getStatusFutureUnchecked(ChunkStatus.FULL).thenAccept((either) -> { // Paper - ensure main // Tuinity - is always on main -+ com.tuinity.tuinity.util.TickThread.ensureTickThread("Async full status chunk future completion"); // Tuinity - Chunk chunk = (Chunk)either.left().orElse(null); - if (chunk != null) { - playerchunkmap.callbackExecutor.execute(() -> { -diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 201221df6..34ec3b9d7 100644 ---- a/src/main/java/net/minecraft/server/PlayerChunkMap.java -+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java -@@ -117,31 +117,28 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - // CraftBukkit start - recursion-safe executor for Chunk loadCallback() and unloadCallback() - public final CallbackExecutor callbackExecutor = new CallbackExecutor(); - public static final class CallbackExecutor implements java.util.concurrent.Executor, Runnable { -- -- // Paper start - replace impl with recursive safe multi entry queue -- // it's possible to schedule multiple tasks currently, so it's vital we change this impl -- // If we recurse into the executor again, we will append to another queue, ensuring task order consistency -- private java.util.ArrayDeque queued = new java.util.ArrayDeque<>(); -+ // Tuinity start - revert paper's change -+ private Runnable queued; - - @Override - public void execute(Runnable runnable) { - AsyncCatcher.catchOp("Callback Executor execute"); -- if (queued == null) { -- queued = new java.util.ArrayDeque<>(); -+ if (queued != null) { -+ MinecraftServer.LOGGER.fatal("Failed to schedule runnable", new IllegalStateException("Already queued")); // Paper - make sure this is printed -+ throw new IllegalStateException("Already queued"); - } -- queued.add(runnable); -+ queued = runnable; - } -+ // Tuinity end - revert paper's change - - @Override - public void run() { - AsyncCatcher.catchOp("Callback Executor run"); -- if (queued == null) { -- return; -- } -- java.util.ArrayDeque queue = queued; -+ // Tuinity start - revert paper's change -+ Runnable task = queued; - queued = null; -- Runnable task; -- while ((task = queue.pollFirst()) != null) { -+ if (task != null) { -+ // Tuinity end - revert paper's change - task.run(); - } - } -@@ -192,6 +189,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - // Paper end - no-tick view distance - - void addPlayerToDistanceMaps(EntityPlayer player) { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Cannot update distance maps off of the main thread"); // Tuinity - int chunkX = MCUtil.getChunkCoordinate(player.locX()); - int chunkZ = MCUtil.getChunkCoordinate(player.locZ()); - // Note: players need to be explicitly added to distance maps before they can be updated -@@ -222,6 +220,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - } - - void removePlayerFromDistanceMaps(EntityPlayer player) { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Cannot update distance maps off of the main thread"); // Tuinity - // Paper start - use distance map to optimise tracker - for (int i = 0, len = TRACKING_RANGE_TYPES.length; i < len; ++i) { - this.playerEntityTrackerTrackMaps[i].remove(player); -@@ -239,6 +238,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - } - - void updateMaps(EntityPlayer player) { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Cannot update distance maps off of the main thread"); // Tuinity - int chunkX = MCUtil.getChunkCoordinate(player.locX()); - int chunkZ = MCUtil.getChunkCoordinate(player.locZ()); - // Note: players need to be explicitly added to distance maps before they can be updated -@@ -740,6 +740,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - - @Nullable - private PlayerChunk a(long i, int j, @Nullable PlayerChunk playerchunk, int k) { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Chunk holder update"); // Tuinity - if (k > PlayerChunkMap.GOLDEN_TICKET && j > PlayerChunkMap.GOLDEN_TICKET) { - return playerchunk; - } else { -@@ -953,7 +954,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - } - - com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave(this.world, chunkPos.x, chunkPos.z, -- poiData, null, com.destroystokyo.paper.io.PrioritizedTaskQueue.LOW_PRIORITY); -+ poiData, null, com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY); // Tuinity - use normal priority - - if (!chunk.isNeedsSaving()) { - return; -@@ -987,7 +988,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - asyncSaveData = ChunkRegionLoader.getAsyncSaveData(this.world, chunk); - } - -- this.world.asyncChunkTaskManager.scheduleChunkSave(chunkPos.x, chunkPos.z, com.destroystokyo.paper.io.PrioritizedTaskQueue.LOW_PRIORITY, -+ this.world.asyncChunkTaskManager.scheduleChunkSave(chunkPos.x, chunkPos.z, com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY, // Tuinity - use normal priority - asyncSaveData, chunk); - - chunk.setLastSaved(this.world.getTime()); -@@ -1042,6 +1043,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - } - - protected boolean b() { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Cannot update visibleChunks off of the main thread"); // Tuinity - if (!this.updatingChunksModified) { - return false; - } else { -@@ -1219,7 +1221,10 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - } - // Paper end - this.mailboxWorldGen.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); // CraftBukkit - decompile error -- }); -+ }).thenComposeAsync((either) -> { // Tuinity start - force competion on the main thread -+ return CompletableFuture.completedFuture(either); -+ }, this.mainInvokingExecutor); -+ // Tuinity end - force competion on the main thread - } - - protected void c(ChunkCoordIntPair chunkcoordintpair) { -@@ -1447,6 +1452,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - } - - public final void setViewDistance(int i) { // Paper - public -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Cannot update view distance off of the main thread"); // Tuinity - int j = MathHelper.clamp(i + 1, 3, 33); // Paper - diff on change, these make the lower view distance limit 2 and the upper 32 - - if (j != this.viewDistance) { -@@ -1460,6 +1466,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - - // Paper start - no-tick view distance - public final void setNoTickViewDistance(int viewDistance) { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Cannot update view distance off of the main thread"); // Tuinity - viewDistance = viewDistance == -1 ? -1 : MathHelper.clamp(viewDistance, 2, 32); - - this.noTickViewDistance = viewDistance; -@@ -1989,23 +1996,20 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - private final void processTrackQueue() { - this.world.timings.tracker1.startTiming(); - try { -- for (EntityTracker tracker : this.trackedEntities.values()) { -- // update tracker entry -- tracker.updatePlayers(tracker.tracker.getPlayersInTrackRange()); -+ for (Chunk chunk : this.world.getChunkProvider().entityTickingChunks) { -+ Entity[] entities = chunk.entities.getRawData(); -+ for (int i = 0, len = chunk.entities.size(); i < len; ++i) { -+ Entity entity = entities[i]; -+ EntityTracker tracker = this.trackedEntities.get(entity.getId()); -+ if (tracker != null) { -+ tracker.updatePlayers(tracker.tracker.getPlayersInTrackRange()); -+ tracker.trackerEntry.tick(); -+ } -+ } - } - } finally { - this.world.timings.tracker1.stopTiming(); - } -- -- -- this.world.timings.tracker2.startTiming(); -- try { -- for (EntityTracker tracker : this.trackedEntities.values()) { -- tracker.trackerEntry.tick(); -- } -- } finally { -- this.world.timings.tracker2.stopTiming(); -- } - } - // Paper end - optimised tracker - -diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java -index 10e3bf60f..e0da3a13b 100644 ---- a/src/main/java/net/minecraft/server/PlayerConnection.java -+++ b/src/main/java/net/minecraft/server/PlayerConnection.java -@@ -323,19 +323,24 @@ public class PlayerConnection implements PacketListenerPlayIn { - - if (entity != this.player && entity.getRidingPassenger() == this.player && entity == this.r) { - WorldServer worldserver = this.player.getWorldServer(); -- double d0 = entity.locX(); -- double d1 = entity.locY(); -- double d2 = entity.locZ(); -- double d3 = packetplayinvehiclemove.getX(); -- double d4 = packetplayinvehiclemove.getY(); -- double d5 = packetplayinvehiclemove.getZ(); -+ double d0 = entity.locX();double fromX = d0; // Tuinity - OBFHELPER -+ double d1 = entity.locY();double fromY = d1; // Tuinity - OBFHELPER -+ double d2 = entity.locZ();double fromZ = d2; // Tuinity - OBFHELPER -+ double d3 = packetplayinvehiclemove.getX();double toX = d3; // Tuinity - OBFHELPER -+ double d4 = packetplayinvehiclemove.getY();double toY = d4; // Tuinity - OBFHELPER -+ double d5 = packetplayinvehiclemove.getZ();double toZ = d5; // Tuinity - OBFHELPER - float f = packetplayinvehiclemove.getYaw(); - float f1 = packetplayinvehiclemove.getPitch(); - double d6 = d3 - this.s; - double d7 = d4 - this.t; - double d8 = d5 - this.u; - double d9 = entity.getMot().g(); -- double d10 = d6 * d6 + d7 * d7 + d8 * d8; -+ // Tuinity start - fix large move vectors killing the server -+ double currDeltaX = toX - fromX; -+ double currDeltaY = toY - fromY; -+ double currDeltaZ = toZ - fromZ; -+ double d10 = Math.max(d6 * d6 + d7 * d7 + d8 * d8, (currDeltaX * currDeltaX + currDeltaY * currDeltaY + currDeltaZ * currDeltaZ) - 1); -+ // Tuinity end - fix large move vectors killing the server - - - // CraftBukkit start - handle custom speeds and skipped ticks -@@ -364,7 +369,9 @@ public class PlayerConnection implements PacketListenerPlayIn { - speed *= 2f; // TODO: Get the speed of the vehicle instead of the player - - // Paper start - Prevent moving into unloaded chunks -- if (player.world.paperConfig.preventMovingIntoUnloadedChunks && worldserver.getChunkIfLoadedImmediately((int) Math.floor(packetplayinvehiclemove.getX()) >> 4, (int) Math.floor(packetplayinvehiclemove.getZ()) >> 4) == null) { -+ if (player.world.paperConfig.preventMovingIntoUnloadedChunks // Tuinity - improve this check -+ && (!worldserver.areChunksLoadedForMove(this.player.getBoundingBoxAt(this.player.locX(), this.player.locY(), this.player.locZ()).expand(toX - this.player.locX(), toY - this.player.locY(), toZ - this.player.locZ()))) // Tuinity - improve this check -+ || !worldserver.areChunksLoadedForMove(entity.getBoundingBoxAt(entity.locX(), entity.locY(), entity.locZ()).expand(toX - entity.locX(), toY - entity.locY(), toZ - entity.locZ()))) { // Tuinity - improve this check - this.networkManager.sendPacket(new PacketPlayOutVehicleMove(entity)); - return; - } -@@ -981,7 +988,7 @@ public class PlayerConnection implements PacketListenerPlayIn { - double d2 = this.player.locZ(); - double d3 = this.player.locY(); - double d4 = packetplayinflying.a(this.player.locX());double toX = d4; // Paper - OBFHELPER -- double d5 = packetplayinflying.b(this.player.locY()); -+ double d5 = packetplayinflying.b(this.player.locY());double toY = d5; // Tuinity - OBFHELPER - double d6 = packetplayinflying.c(this.player.locZ());double toZ = d6; // Paper - OBFHELPER - float f = packetplayinflying.a(this.player.yaw); - float f1 = packetplayinflying.b(this.player.pitch); -@@ -989,7 +996,12 @@ public class PlayerConnection implements PacketListenerPlayIn { - double d8 = d5 - this.m; - double d9 = d6 - this.n; - double d10 = this.player.getMot().g(); -- double d11 = d7 * d7 + d8 * d8 + d9 * d9; -+ // Tuinity start - fix large move vectors killing the server -+ double currDeltaX = toX - prevX; -+ double currDeltaY = toY - prevY; -+ double currDeltaZ = toZ - prevZ; -+ double d11 = Math.max(d7 * d7 + d8 * d8 + d9 * d9, (currDeltaX * currDeltaX + currDeltaY * currDeltaY + currDeltaZ * currDeltaZ) - 1); -+ // Tuinity end - fix large move vectors killing the server - - if (this.player.isSleeping()) { - if (d11 > 1.0D) { -@@ -1022,7 +1034,7 @@ public class PlayerConnection implements PacketListenerPlayIn { - speed = player.abilities.walkSpeed * 10f; - } - // Paper start - Prevent moving into unloaded chunks -- if (player.world.paperConfig.preventMovingIntoUnloadedChunks && (this.player.locX() != toX || this.player.locZ() != toZ) && worldserver.getChunkIfLoadedImmediately((int) Math.floor(toX) >> 4, (int) Math.floor(toZ) >> 4) == null) { // Paper - use getIfLoadedImmediately -+ if (player.world.paperConfig.preventMovingIntoUnloadedChunks && !((WorldServer)this.player.world).areChunksLoadedForMove(this.player.getBoundingBoxAt(this.player.locX(), this.player.locY(), this.player.locZ()).expand(toX - this.player.locX(), toY - this.player.locY(), toZ - this.player.locZ()))) { // Paper - use getIfLoadedImmediately // Tuinity - improve this check - this.internalTeleport(this.player.locX(), this.player.locY(), this.player.locZ(), this.player.yaw, this.player.pitch, Collections.emptySet()); - return; - } -diff --git a/src/main/java/net/minecraft/server/PlayerConnectionUtils.java b/src/main/java/net/minecraft/server/PlayerConnectionUtils.java -index eb3269e0e..d9c9d01ae 100644 ---- a/src/main/java/net/minecraft/server/PlayerConnectionUtils.java -+++ b/src/main/java/net/minecraft/server/PlayerConnectionUtils.java -@@ -13,10 +13,30 @@ public class PlayerConnectionUtils { - ensureMainThread(packet, t0, (IAsyncTaskHandler) worldserver.getMinecraftServer()); - } - -+ // Tuinity start - detailed watchdog information -+ private static final java.util.concurrent.ConcurrentLinkedDeque packetProcessing = new java.util.concurrent.ConcurrentLinkedDeque<>(); -+ private static final java.util.concurrent.atomic.AtomicLong totalMainThreadPacketsProcessed = new java.util.concurrent.atomic.AtomicLong(); -+ -+ public static long getTotalProcessedPackets() { -+ return totalMainThreadPacketsProcessed.get(); -+ } -+ -+ public static java.util.List getCurrentPacketProcessors() { -+ java.util.List ret = new java.util.ArrayList<>(4); -+ for (PacketListener listener : packetProcessing) { -+ ret.add(listener); -+ } -+ -+ return ret; -+ } -+ // Tuinity end - detailed watchdog information -+ - public static void ensureMainThread(Packet packet, T t0, IAsyncTaskHandler iasynctaskhandler) throws CancelledPacketHandleException { - if (!iasynctaskhandler.isMainThread()) { - Timing timing = MinecraftTimings.getPacketTiming(packet); // Paper - timings - iasynctaskhandler.execute(() -> { -+ packetProcessing.push(t0); // Tuinity - detailed watchdog information -+ try { // Tuinity - detailed watchdog information - if (MinecraftServer.getServer().hasStopped() || (t0 instanceof PlayerConnection && ((PlayerConnection) t0).processedDisconnect)) return; // CraftBukkit, MC-142590 - if (t0.a().isConnected()) { - try (Timing ignored = timing.startTiming()) { // Paper - timings -@@ -25,6 +45,12 @@ public class PlayerConnectionUtils { - } else { - PlayerConnectionUtils.LOGGER.debug("Ignoring packet due to disconnection: " + packet); - } -+ // Tuinity start - detailed watchdog information -+ } finally { -+ totalMainThreadPacketsProcessed.getAndIncrement(); -+ packetProcessing.pop(); -+ } -+ // Tuinity end - detailed watchdog information - - }); - throw CancelledPacketHandleException.INSTANCE; -diff --git a/src/main/java/net/minecraft/server/PlayerInteractManager.java b/src/main/java/net/minecraft/server/PlayerInteractManager.java -index 6df843461..272c1f0ea 100644 ---- a/src/main/java/net/minecraft/server/PlayerInteractManager.java -+++ b/src/main/java/net/minecraft/server/PlayerInteractManager.java -@@ -20,14 +20,29 @@ public class PlayerInteractManager { - public EntityPlayer player; - private EnumGamemode gamemode; - private boolean e; -- private int lastDigTick; -+ private int lastDigTick; private long lastDigTime; // Tuinity - lag compensate block breaking - private BlockPosition g; - private int currentTick; -- private boolean i; -+ private boolean i; private final boolean hasDestroyedTooFast() { return this.i; } // Tuinity - OBFHELPER - private BlockPosition j; -- private int k; -+ private int k; private final int getHasDestroyedTooFastStartTick() { return this.k; } // Tuinity - OBFHELPER -+ private long hasDestroyedTooFastStartTime; // Tuinity - lag compensate block breaking - private int l; - -+ // Tuinity start - lag compensate block breaking -+ private int getTimeDiggingLagCompensate() { -+ int lagCompensated = (int)((System.nanoTime() - this.lastDigTime) / (50L * 1000L * 1000L)); -+ int tickDiff = this.currentTick - this.lastDigTick; -+ return (com.tuinity.tuinity.config.TuinityConfig.lagCompensateBlockBreaking && lagCompensated > (tickDiff + 1)) ? lagCompensated : tickDiff; // add one to ensure we don't lag compensate unless we need to -+ } -+ -+ private int getTimeDiggingTooFastLagCompensate() { -+ int lagCompensated = (int)((System.nanoTime() - this.hasDestroyedTooFastStartTime) / (50L * 1000L * 1000L)); -+ int tickDiff = this.currentTick - this.getHasDestroyedTooFastStartTick(); -+ return (com.tuinity.tuinity.config.TuinityConfig.lagCompensateBlockBreaking && lagCompensated > (tickDiff + 1)) ? lagCompensated : tickDiff; // add one to ensure we don't lag compensate unless we need to -+ } -+ // Tuinity end -+ - public PlayerInteractManager(WorldServer worldserver) { - this.gamemode = EnumGamemode.NOT_SET; - this.g = BlockPosition.ZERO; -@@ -73,7 +88,7 @@ public class PlayerInteractManager { - if (iblockdata == null || iblockdata.isAir()) { // Paper - this.i = false; - } else { -- float f = this.a(iblockdata, this.j, this.k); -+ float f = this.updateBlockBreakAnimation(iblockdata, this.j, this.getTimeDiggingTooFastLagCompensate()); // Tuinity - lag compensate destroying blocks - - if (f >= 1.0F) { - this.i = false; -@@ -93,7 +108,7 @@ public class PlayerInteractManager { - this.l = -1; - this.e = false; - } else { -- this.a(iblockdata, this.g, this.lastDigTick); -+ this.updateBlockBreakAnimation(iblockdata, this.g, this.getTimeDiggingLagCompensate()); // Tuinity - lag compensate destroying blocks - } - } - -@@ -101,6 +116,12 @@ public class PlayerInteractManager { - - private float a(IBlockData iblockdata, BlockPosition blockposition, int i) { - int j = this.currentTick - i; -+ // Tuinity start - change i (startTime) to totalTime -+ return this.updateBlockBreakAnimation(iblockdata, blockposition, j); -+ } -+ private float updateBlockBreakAnimation(IBlockData iblockdata, BlockPosition blockposition, int totalTime) { -+ int j = totalTime; -+ // Tuinity end - float f = iblockdata.getDamage(this.player, this.player.world, blockposition) * (float) (j + 1); - int k = (int) (f * 10.0F); - -@@ -174,7 +195,7 @@ public class PlayerInteractManager { - } - - // this.world.douseFire((EntityHuman) null, blockposition, enumdirection); // CraftBukkit - Moved down -- this.lastDigTick = this.currentTick; -+ this.lastDigTick = this.currentTick; this.lastDigTime = System.nanoTime(); // Tuinity - lag compensate block breaking - float f = 1.0F; - - iblockdata = this.world.getType(blockposition); -@@ -229,12 +250,12 @@ public class PlayerInteractManager { - int j = (int) (f * 10.0F); - - this.world.a(this.player.getId(), blockposition, j); -- this.player.playerConnection.sendPacket(new PacketPlayOutBlockBreak(blockposition, this.world.getType(blockposition), packetplayinblockdig_enumplayerdigtype, true, "actual start of destroying")); -+ if (!com.tuinity.tuinity.config.TuinityConfig.lagCompensateBlockBreaking) this.player.playerConnection.sendPacket(new PacketPlayOutBlockBreak(blockposition, this.world.getType(blockposition), packetplayinblockdig_enumplayerdigtype, true, "actual start of destroying")); // Tuinity - on lagging servers this can cause the client to think it's only just started to destroy a block when it already has/will - this.l = j; - } - } else if (packetplayinblockdig_enumplayerdigtype == PacketPlayInBlockDig.EnumPlayerDigType.STOP_DESTROY_BLOCK) { - if (blockposition.equals(this.g)) { -- int k = this.currentTick - this.lastDigTick; -+ int k = this.getTimeDiggingLagCompensate(); // Tuinity - lag compensate block breaking - - iblockdata = this.world.getType(blockposition); - if (!iblockdata.isAir()) { -@@ -251,12 +272,18 @@ public class PlayerInteractManager { - this.e = false; - this.i = true; - this.j = blockposition; -- this.k = this.lastDigTick; -+ this.k = this.lastDigTick; this.hasDestroyedTooFastStartTime = this.lastDigTime; // Tuinity - lag compensate block breaking - } - } - } - -+ // Tuinity start - this can cause clients on a lagging server to think they're not currently destroying a block -+ if (com.tuinity.tuinity.config.TuinityConfig.lagCompensateBlockBreaking) { -+ this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); -+ } else { - this.player.playerConnection.sendPacket(new PacketPlayOutBlockBreak(blockposition, this.world.getType(blockposition), packetplayinblockdig_enumplayerdigtype, true, "stopped destroying")); -+ } -+ // Tuinity end - this can cause clients on a lagging server to think they're not currently destroying a block - } else if (packetplayinblockdig_enumplayerdigtype == PacketPlayInBlockDig.EnumPlayerDigType.ABORT_DESTROY_BLOCK) { - this.e = false; - if (!Objects.equals(this.g, blockposition) && !BlockPosition.ZERO.equals(this.g)) { // Paper -@@ -268,7 +295,7 @@ public class PlayerInteractManager { - } - - this.world.a(this.player.getId(), blockposition, -1); -- this.player.playerConnection.sendPacket(new PacketPlayOutBlockBreak(blockposition, this.world.getType(blockposition), packetplayinblockdig_enumplayerdigtype, true, "aborted destroying")); -+ if (!com.tuinity.tuinity.config.TuinityConfig.lagCompensateBlockBreaking) this.player.playerConnection.sendPacket(new PacketPlayOutBlockBreak(blockposition, this.world.getType(blockposition), packetplayinblockdig_enumplayerdigtype, true, "aborted destroying")); // Tuinity - this can cause clients on a lagging server to think they stopped destroying a block they're currently destroying - } - - } -@@ -278,7 +305,13 @@ public class PlayerInteractManager { - - public void a(BlockPosition blockposition, PacketPlayInBlockDig.EnumPlayerDigType packetplayinblockdig_enumplayerdigtype, String s) { - if (this.breakBlock(blockposition)) { -+ // Tuinity start - this can cause clients on a lagging server to think they're not currently destroying a block -+ if (com.tuinity.tuinity.config.TuinityConfig.lagCompensateBlockBreaking) { -+ this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); -+ } else { - this.player.playerConnection.sendPacket(new PacketPlayOutBlockBreak(blockposition, this.world.getType(blockposition), packetplayinblockdig_enumplayerdigtype, true, s)); -+ } -+ // Tuinity end - this can cause clients on a lagging server to think they're not currently destroying a block - } else { - this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); // CraftBukkit - SPIGOT-5196 - } -diff --git a/src/main/java/net/minecraft/server/ProtoChunk.java b/src/main/java/net/minecraft/server/ProtoChunk.java -index 2eb14bbf8..2be0b0803 100644 ---- a/src/main/java/net/minecraft/server/ProtoChunk.java -+++ b/src/main/java/net/minecraft/server/ProtoChunk.java -@@ -179,14 +179,11 @@ public class ProtoChunk implements IChunkAccess { - lightengine.a(blockposition); - } - -- EnumSet enumset = this.getChunkStatus().h(); -+ HeightMap.Type[] enumset = this.getChunkStatus().heightMaps; // Tuinity - reduce iterator creation - EnumSet enumset1 = null; -- Iterator iterator = enumset.iterator(); -+ // Tuinity - reduce iterator creation - -- HeightMap.Type heightmap_type; -- -- while (iterator.hasNext()) { -- heightmap_type = (HeightMap.Type) iterator.next(); -+ for (HeightMap.Type heightmap_type : enumset) { // Tuinity - reduce iterator creation - HeightMap heightmap = (HeightMap) this.f.get(heightmap_type); - - if (heightmap == null) { -@@ -202,10 +199,9 @@ public class ProtoChunk implements IChunkAccess { - HeightMap.a(this, enumset1); - } - -- iterator = enumset.iterator(); -- -- while (iterator.hasNext()) { -- heightmap_type = (HeightMap.Type) iterator.next(); -+ // Tuinity start - reduce iterator creation -+ for (HeightMap.Type heightmap_type : enumset) { -+ // Tuinity end - reduce iterator creation - ((HeightMap) this.f.get(heightmap_type)).a(i & 15, j, k & 15, iblockdata); - } - -diff --git a/src/main/java/net/minecraft/server/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java -index df728e2c0..a66b02baa 100644 ---- a/src/main/java/net/minecraft/server/RegionFile.java -+++ b/src/main/java/net/minecraft/server/RegionFile.java -@@ -28,14 +28,349 @@ public class RegionFile implements AutoCloseable { - private static final Logger LOGGER = LogManager.getLogger(); - private static final ByteBuffer b = ByteBuffer.allocateDirect(1); - private final FileChannel dataFile; -- private final java.nio.file.Path d; -- private final RegionFileCompression e; -+ private final java.nio.file.Path d; private final java.nio.file.Path getContainingDataFolder() { return this.d; } // Tuinity - OBFHELPER -+ private final RegionFileCompression e; private final RegionFileCompression getRegionFileCompression() { return this.e; } // Tuinity - OBFHELPER - private final ByteBuffer f; -- private final IntBuffer g; -- private final IntBuffer h; -+ private final IntBuffer g; private final IntBuffer getOffsets() { return this.g; } // Tuinity - OBFHELPER -+ private final IntBuffer h; private final IntBuffer getTimestamps() { return this.h; } // Tuinity - OBFHELPER - private final RegionFileBitSet freeSectors; - public final File file; - -+ // Tuinity start - try to recover from RegionFile header corruption -+ private static long roundToSectors(long bytes) { -+ long sectors = bytes >>> 12; // 4096 = 2^12 -+ long remainingBytes = bytes & 4095; -+ long sign = -remainingBytes; // sign is 1 if nonzero -+ return sectors + (sign >>> 63); -+ } -+ -+ private static final NBTTagCompound OVERSIZED_COMPOUND = new NBTTagCompound(); -+ -+ private NBTTagCompound attemptRead(long sector, int chunkDataLength, long fileLength) throws IOException { -+ try { -+ if (chunkDataLength < 0) { -+ return null; -+ } -+ -+ long offset = sector * 4096L + 4L; // offset for chunk data -+ -+ if ((offset + chunkDataLength) > fileLength) { -+ return null; -+ } -+ -+ ByteBuffer chunkData = ByteBuffer.allocate(chunkDataLength); -+ if (chunkDataLength != this.dataFile.read(chunkData, offset)) { -+ return null; -+ } -+ -+ ((java.nio.Buffer)chunkData).flip(); -+ -+ byte compressionType = chunkData.get(); -+ if (compressionType < 0) { // compressionType & 128 != 0 -+ // oversized chunk -+ return OVERSIZED_COMPOUND; -+ } -+ -+ RegionFileCompression compression = RegionFileCompression.getByType(compressionType); -+ if (compression == null) { -+ return null; -+ } -+ -+ InputStream input = compression.wrap(new ByteArrayInputStream(chunkData.array(), chunkData.position(), chunkDataLength - chunkData.position())); -+ -+ return NBTCompressedStreamTools.readNBT(new DataInputStream(new BufferedInputStream(input))); -+ } catch (Exception ex) { -+ return null; -+ } -+ } -+ -+ private int getLength(long sector) throws IOException { -+ ByteBuffer length = ByteBuffer.allocate(4); -+ if (4 != this.dataFile.read(length, sector * 4096L)) { -+ return -1; -+ } -+ -+ return length.getInt(0); -+ } -+ -+ private void backupRegionFile() { -+ File backup = new File(this.file.getParent(), this.file.getName() + "." + new java.util.Random().nextLong() + ".backup"); -+ this.backupRegionFile(backup); -+ } -+ -+ private void backupRegionFile(File to) { -+ try { -+ this.dataFile.force(true); -+ MinecraftServer.LOGGER.warn("Backing up regionfile \"" + this.file.getAbsolutePath() + "\" to " + to.getAbsolutePath()); -+ java.nio.file.Files.copy(this.file.toPath(), to.toPath()); -+ MinecraftServer.LOGGER.warn("Backed up the regionfile to " + to.getAbsolutePath()); -+ } catch (IOException ex) { -+ MinecraftServer.LOGGER.error("Failed to backup to " + to.getAbsolutePath(), ex); -+ } -+ } -+ -+ // note: only call for CHUNK regionfiles -+ void recalculateHeader() throws IOException { -+ if (!this.canRecalcHeader) { -+ return; -+ } -+ synchronized (this) { -+ MinecraftServer.LOGGER.warn("Corrupt regionfile header detected! Attempting to re-calculate header offsets for regionfile " + this.file.getAbsolutePath(), new Throwable()); -+ -+ // try to backup file so maybe it could be sent to us for further investigation -+ -+ this.backupRegionFile(); -+ NBTTagCompound[] compounds = new NBTTagCompound[32 * 32]; // only in the regionfile (i.e exclude mojang/aikar oversized data) -+ int[] rawLengths = new int[32 * 32]; // length of chunk data including 4 byte length field, bytes -+ int[] sectorOffsets = new int[32 * 32]; // in sectors -+ boolean[] hasAikarOversized = new boolean[32 * 32]; -+ -+ long fileLength = this.dataFile.size(); -+ long totalSectors = roundToSectors(fileLength); -+ -+ // search the regionfile from start to finish for the most up-to-date chunk data -+ -+ for (long i = 2, maxSector = Math.min((long)(Integer.MAX_VALUE >>> 8), totalSectors); i < maxSector; ++i) { // first two sectors are header, skip -+ int chunkDataLength = this.getLength(i); -+ NBTTagCompound compound = this.attemptRead(i, chunkDataLength, fileLength); -+ if (compound == null || compound == OVERSIZED_COMPOUND) { -+ continue; -+ } -+ -+ ChunkCoordIntPair chunkPos = ChunkRegionLoader.getChunkCoordinate(compound); -+ int location = (chunkPos.x & 31) | ((chunkPos.z & 31) << 5); -+ -+ NBTTagCompound otherCompound = compounds[location]; -+ -+ if (otherCompound != null && ChunkRegionLoader.getLastWorldSaveTime(otherCompound) > ChunkRegionLoader.getLastWorldSaveTime(compound)) { -+ continue; // don't overwrite newer data. -+ } -+ -+ // aikar oversized? -+ File aikarOversizedFile = this.getOversizedFile(chunkPos.x, chunkPos.z); -+ boolean isAikarOversized = false; -+ if (aikarOversizedFile.exists()) { -+ try { -+ NBTTagCompound aikarOversizedCompound = this.getOversizedData(chunkPos.x, chunkPos.z); -+ if (ChunkRegionLoader.getLastWorldSaveTime(compound) == ChunkRegionLoader.getLastWorldSaveTime(aikarOversizedCompound)) { -+ // best we got for an id. hope it's good enough -+ isAikarOversized = true; -+ } -+ } catch (Exception ex) { -+ MinecraftServer.LOGGER.error("Failed to read aikar oversized data for absolute chunk (" + chunkPos.x + "," + chunkPos.z + ") in regionfile " + this.file.getAbsolutePath() + ", oversized data for this chunk will be lost", ex); -+ // fall through, if we can't read aikar oversized we can't risk corrupting chunk data -+ } -+ } -+ -+ hasAikarOversized[location] = isAikarOversized; -+ compounds[location] = compound; -+ rawLengths[location] = chunkDataLength + 4; -+ sectorOffsets[location] = (int)i; -+ -+ int chunkSectorLength = (int)roundToSectors(rawLengths[location]); -+ i += chunkSectorLength; -+ --i; // gets incremented next iteration -+ } -+ -+ // forge style oversized data is already handled by the local search, and aikar data we just hope -+ // we get it right as aikar data has no identifiers we could use to try and find its corresponding -+ // local data compound -+ -+ java.nio.file.Path containingFolder = this.getContainingDataFolder(); -+ File[] regionFiles = containingFolder.toFile().listFiles(); -+ boolean[] oversized = new boolean[32 * 32]; -+ RegionFileCompression[] oversizedCompressionTypes = new RegionFileCompression[32 * 32]; -+ -+ if (regionFiles != null) { -+ ChunkCoordIntPair ourLowerLeftPosition = RegionFileCache.getRegionFileCoordinates(this.file); -+ -+ if (ourLowerLeftPosition == null) { -+ MinecraftServer.LOGGER.fatal("Unable to get chunk location of regionfile " + this.file.getAbsolutePath() + ", cannot recover oversized chunks"); -+ } else { -+ int lowerXBound = ourLowerLeftPosition.x; // inclusive -+ int lowerZBound = ourLowerLeftPosition.z; // inclusive -+ int upperXBound = lowerXBound + 32 - 1; // inclusive -+ int upperZBound = lowerZBound + 32 - 1; // inclusive -+ -+ // read mojang oversized data -+ for (File regionFile : regionFiles) { -+ ChunkCoordIntPair oversizedCoords = getOversizedChunkPair(regionFile); -+ if (oversizedCoords == null) { -+ continue; -+ } -+ -+ if ((oversizedCoords.x < lowerXBound || oversizedCoords.x > upperXBound) || (oversizedCoords.z < lowerZBound || oversizedCoords.z > upperZBound)) { -+ continue; // not in our regionfile -+ } -+ -+ // ensure oversized data is valid & is newer than data in the regionfile -+ -+ int location = (oversizedCoords.x & 31) | ((oversizedCoords.z & 31) << 5); -+ -+ byte[] chunkData; -+ try { -+ chunkData = Files.readAllBytes(regionFile.toPath()); -+ } catch (Exception ex) { -+ MinecraftServer.LOGGER.error("Failed to read oversized chunk data in file " + regionFile.getAbsolutePath(), ex); -+ continue; -+ } -+ -+ NBTTagCompound compound = null; -+ -+ // We do not know the compression type, as it's stored in the regionfile. So we need to try all of them -+ RegionFileCompression compression = null; -+ for (RegionFileCompression compressionType : RegionFileCompression.getCompressionTypes().values()) { -+ try { -+ DataInputStream in = new DataInputStream(new BufferedInputStream(compressionType.wrap(new ByteArrayInputStream(chunkData)))); // typical java -+ compound = NBTCompressedStreamTools.readNBT(in); -+ compression = compressionType; -+ break; // reaches here iff readNBT does not throw -+ } catch (Exception ex) { -+ continue; -+ } -+ } -+ -+ if (compound == null) { -+ MinecraftServer.LOGGER.error("Failed to read oversized chunk data in file " + regionFile.getAbsolutePath() + ", it's corrupt. Its data will be lost"); -+ continue; -+ } -+ -+ if (compounds[location] == null || ChunkRegionLoader.getLastWorldSaveTime(compound) > ChunkRegionLoader.getLastWorldSaveTime(compounds[location])) { -+ oversized[location] = true; -+ oversizedCompressionTypes[location] = compression; -+ } -+ } -+ } -+ } -+ -+ // now we need to calculate a new offset header -+ -+ int[] calculatedOffsets = new int[32 * 32]; -+ RegionFileBitSet newSectorAllocations = new RegionFileBitSet(); -+ newSectorAllocations.allocate(0, 2); // make space for header -+ -+ // allocate sectors for normal chunks -+ -+ for (int chunkX = 0; chunkX < 32; ++chunkX) { -+ for (int chunkZ = 0; chunkZ < 32; ++chunkZ) { -+ int location = chunkX | (chunkZ << 5); -+ -+ if (oversized[location]) { -+ continue; -+ } -+ -+ int rawLength = rawLengths[location]; // bytes -+ int sectorOffset = sectorOffsets[location]; // sectors -+ int sectorLength = (int)roundToSectors(rawLength); -+ -+ if (newSectorAllocations.tryAllocate(sectorOffset, sectorLength)) { -+ calculatedOffsets[location] = sectorOffset << 8 | (sectorLength > 255 ? 255 : sectorLength); // support forge style oversized -+ } else { -+ MinecraftServer.LOGGER.error("Failed to allocate space for local chunk (overlapping data??) at (" + chunkX + "," + chunkZ + ") in regionfile " + this.file.getAbsolutePath() + ", chunk will be regenerated"); -+ } -+ } -+ } -+ -+ // allocate sectors for oversized chunks -+ -+ for (int chunkX = 0; chunkX < 32; ++chunkX) { -+ for (int chunkZ = 0; chunkZ < 32; ++chunkZ) { -+ int location = chunkX | (chunkZ << 5); -+ -+ if (!oversized[location]) { -+ continue; -+ } -+ -+ int sectorOffset = newSectorAllocations.allocateNewSpace(1); -+ int sectorLength = 1; -+ -+ try { -+ this.dataFile.write(this.getOversizedChunkHolderData(oversizedCompressionTypes[location]), sectorOffset * 4096); -+ // only allocate in the new offsets if the write succeeds -+ calculatedOffsets[location] = sectorOffset << 8 | (sectorLength > 255 ? 255 : sectorLength); // support forge style oversized -+ } catch (IOException ex) { -+ newSectorAllocations.free(sectorOffset, sectorLength); -+ MinecraftServer.LOGGER.error("Failed to write new oversized chunk data holder, local chunk at (" + chunkX + "," + chunkZ + ") in regionfile " + this.file.getAbsolutePath() + " will be regenerated"); -+ } -+ } -+ } -+ -+ // rewrite aikar oversized data -+ -+ this.oversizedCount = 0; -+ for (int chunkX = 0; chunkX < 32; ++chunkX) { -+ for (int chunkZ = 0; chunkZ < 32; ++chunkZ) { -+ int location = chunkX | (chunkZ << 5); -+ int isAikarOversized = hasAikarOversized[location] ? 1 : 0; -+ -+ this.oversizedCount += isAikarOversized; -+ this.oversized[location] = (byte)isAikarOversized; -+ } -+ } -+ -+ if (this.oversizedCount > 0) { -+ try { -+ this.writeOversizedMeta(); -+ } catch (Exception ex) { -+ MinecraftServer.LOGGER.error("Failed to write aikar oversized chunk meta, all aikar style oversized chunk data will be lost for regionfile " + this.file.getAbsolutePath(), ex); -+ this.getOversizedMetaFile().delete(); -+ } -+ } else { -+ this.getOversizedMetaFile().delete(); -+ } -+ -+ this.freeSectors.copyFrom(newSectorAllocations); -+ -+ // before we overwrite the old sectors, print a summary of the chunks that got changed. -+ -+ MinecraftServer.LOGGER.info("Starting summary of changes for regionfile " + this.file.getAbsolutePath()); -+ -+ for (int chunkX = 0; chunkX < 32; ++chunkX) { -+ for (int chunkZ = 0; chunkZ < 32; ++chunkZ) { -+ int location = chunkX | (chunkZ << 5); -+ -+ int oldOffset = this.getOffsets().get(location); -+ int newOffset = calculatedOffsets[location]; -+ -+ if (oldOffset == newOffset) { -+ continue; -+ } -+ -+ this.getOffsets().put(location, newOffset); // overwrite incorrect offset -+ -+ if (oldOffset == 0) { -+ // found lost data -+ MinecraftServer.LOGGER.info("Found missing data for local chunk (" + chunkX + "," + chunkZ + ") in regionfile " + this.file.getAbsolutePath()); -+ } else if (newOffset == 0) { -+ MinecraftServer.LOGGER.warn("Data for local chunk (" + chunkX + "," + chunkZ + ") could not be recovered in regionfile " + this.file.getAbsolutePath() + ", it will be regenerated"); -+ } else { -+ MinecraftServer.LOGGER.info("Local chunk (" + chunkX + "," + chunkZ + ") changed to point to newer data or correct chunk in regionfile " + this.file.getAbsolutePath()); -+ } -+ } -+ } -+ -+ MinecraftServer.LOGGER.info("End of change summary for regionfile " + this.file.getAbsolutePath()); -+ -+ // simply destroy the timestamp header, it's not used -+ -+ for (int i = 0; i < 32 * 32; ++i) { -+ this.getTimestamps().put(i, calculatedOffsets[i] != 0 ? (int)System.currentTimeMillis() : 0); // write a valid timestamp for valid chunks, I do not want to find out whatever dumb program actually checks this -+ } -+ -+ // write new header -+ try { -+ this.flushHeader(); -+ this.dataFile.force(true); // try to ensure it goes through... -+ MinecraftServer.LOGGER.info("Successfully wrote new header to disk for regionfile " + this.file.getAbsolutePath()); -+ } catch (IOException ex) { -+ MinecraftServer.LOGGER.fatal("Failed to write new header to disk for regionfile " + this.file.getAbsolutePath(), ex); -+ } -+ } -+ } -+ -+ final boolean canRecalcHeader; // final forces compile fail on new constructor -+ // Tuinity end -+ - public final java.util.concurrent.locks.ReentrantLock fileLock = new java.util.concurrent.locks.ReentrantLock(true); // Paper - - // Paper start - Cache chunk status -@@ -63,10 +398,21 @@ public class RegionFile implements AutoCloseable { - // Paper end - - public RegionFile(File file, File file1) throws IOException { -- this(file.toPath(), file1.toPath(), RegionFileCompression.b); -+ // Tuinity start - add header recalculation boolean -+ this(file, file1, false); -+ } -+ public RegionFile(File file, File file1, boolean canRecalcHeader) throws IOException { -+ this(file.toPath(), file1.toPath(), RegionFileCompression.b, canRecalcHeader); -+ // Tuinity end - } - - public RegionFile(java.nio.file.Path java_nio_file_path, java.nio.file.Path java_nio_file_path1, RegionFileCompression regionfilecompression) throws IOException { -+ // Tuinity start - add header recalculation boolean -+ this(java_nio_file_path, java_nio_file_path1, regionfilecompression, false); -+ } -+ public RegionFile(java.nio.file.Path java_nio_file_path, java.nio.file.Path java_nio_file_path1, RegionFileCompression regionfilecompression, boolean canRecalcHeader) throws IOException { -+ this.canRecalcHeader = canRecalcHeader; -+ // Tuinity end - this.file = java_nio_file_path.toFile(); // Paper - this.f = ByteBuffer.allocateDirect(8192); - initOversizedState(); -@@ -90,12 +436,15 @@ public class RegionFile implements AutoCloseable { - RegionFile.LOGGER.warn("Region file {} has truncated header: {}", java_nio_file_path, i); - } - -- for (int j = 0; j < 1024; ++j) { -+ boolean needsHeaderRecalc = false; // Tuinity - recalculate header on header corruption -+ boolean hasBackedUp = false; // Tuinity - recalculate header on header corruption -+ -+ for (int j = 0; j < 1024; ++j) { // Tuinity - diff on change, we expect j to be the header location - int k = this.g.get(j); - - if (k != 0) { -- int l = b(k); -- int i1 = a(k); -+ int l = b(k); // Tuinity - diff on change, we expect l to be offset in file -+ int i1 = a(k); // Tuinity - diff on change, we expect i1 to be sector length of region - // Spigot start - if (i1 == 255) { - // We're maxed out, so we need to read the proper length from the section -@@ -105,20 +454,87 @@ public class RegionFile implements AutoCloseable { - } - // Spigot end - -- this.freeSectors.a(l, i1); -+ // Tuinity start - recalculate header on header corruption -+ if (l < 0 || i1 < 0 || (l + i1) < 0) { -+ if (canRecalcHeader) { -+ MinecraftServer.LOGGER.error("Detected invalid header for regionfile " + this.file.getAbsolutePath() + "! Recalculating header..."); -+ needsHeaderRecalc = true; -+ break; -+ } else { -+ // location = chunkX | (chunkZ << 5); -+ MinecraftServer.LOGGER.fatal("Detected invalid header for regionfile " + this.file.getAbsolutePath() + -+ "! Cannot recalculate, removing local chunk (" + (j & 31) + "," + (j >>> 5) + ") from header"); -+ if (!hasBackedUp) { -+ hasBackedUp = true; -+ this.backupRegionFile(); -+ } -+ this.getTimestamps().put(j, 0); // be consistent, delete the timestamp too -+ this.getOffsets().put(j, 0); // delete the entry from header -+ continue; -+ } -+ } -+ boolean failedToAllocate = !this.freeSectors.tryAllocate(l, i1); -+ if (failedToAllocate && !canRecalcHeader) { -+ // location = chunkX | (chunkZ << 5); -+ MinecraftServer.LOGGER.fatal("Detected invalid header for regionfile " + this.file.getAbsolutePath() + -+ "! Cannot recalculate, removing local chunk (" + (j & 31) + "," + (j >>> 5) + ") from header"); -+ if (!hasBackedUp) { -+ hasBackedUp = true; -+ this.backupRegionFile(); -+ } -+ this.getTimestamps().put(j, 0); // be consistent, delete the timestamp too -+ this.getOffsets().put(j, 0); // delete the entry from header -+ continue; -+ } -+ needsHeaderRecalc |= failedToAllocate; -+ // Tuinity end - recalculate header on header corruption - } - } -+ -+ // Tuinity start - recalculate header on header corruption -+ // we move the recalc here so comparison to old header is correct when logging to console -+ if (needsHeaderRecalc) { // true if header gave us overlapping allocations -+ MinecraftServer.LOGGER.error("Recalculating regionfile " + this.file.getAbsolutePath() + ", header gave conflicting offsets & locations"); -+ this.recalculateHeader(); -+ } -+ // Tuinity end - } - - } - } - -+ private final java.nio.file.Path getOversizedChunkPath(ChunkCoordIntPair chunkcoordintpair) { return this.e(chunkcoordintpair); } // Tuinity - OBFHELPER - private java.nio.file.Path e(ChunkCoordIntPair chunkcoordintpair) { -- String s = "c." + chunkcoordintpair.x + "." + chunkcoordintpair.z + ".mcc"; -+ String s = "c." + chunkcoordintpair.x + "." + chunkcoordintpair.z + ".mcc"; // Tuinity - diff on change - - return this.d.resolve(s); - } - -+ // Tuinity start -+ private static ChunkCoordIntPair getOversizedChunkPair(File file) { -+ String fileName = file.getName(); -+ -+ if (!fileName.startsWith("c.") || !fileName.endsWith(".mcc")) { -+ return null; -+ } -+ -+ String[] split = fileName.split("\\."); -+ -+ if (split.length != 4) { -+ return null; -+ } -+ -+ try { -+ int x = Integer.parseInt(split[1]); -+ int z = Integer.parseInt(split[2]); -+ -+ return new ChunkCoordIntPair(x, z); -+ } catch (NumberFormatException ex) { -+ return null; -+ } -+ } -+ // Tuinity end -+ - @Nullable public synchronized DataInputStream getReadStream(ChunkCoordIntPair chunkCoordIntPair) throws IOException { return a(chunkCoordIntPair);} // Paper - OBFHELPER - @Nullable - public synchronized DataInputStream a(ChunkCoordIntPair chunkcoordintpair) throws IOException { -@@ -142,6 +558,12 @@ public class RegionFile implements AutoCloseable { - this.dataFile.read(bytebuffer, (long) (j * 4096)); - ((java.nio.Buffer) bytebuffer).flip(); - if (bytebuffer.remaining() < 5) { -+ // Tuinity start - recalculate header on regionfile corruption -+ if (this.canRecalcHeader) { -+ this.recalculateHeader(); -+ return this.getReadStream(chunkcoordintpair); -+ } -+ // Tuinity end - RegionFile.LOGGER.error("Chunk {} header is truncated: expected {} but read {}", chunkcoordintpair, l, bytebuffer.remaining()); - return null; - } else { -@@ -150,6 +572,12 @@ public class RegionFile implements AutoCloseable { - - if (i1 == 0) { - RegionFile.LOGGER.warn("Chunk {} is allocated, but stream is missing", chunkcoordintpair); -+ // Tuinity start - recalculate header on regionfile corruption -+ if (this.canRecalcHeader) { -+ this.recalculateHeader(); -+ return this.getReadStream(chunkcoordintpair); -+ } -+ // Tuinity end - return null; - } else { - int j1 = i1 - 1; -@@ -162,9 +590,21 @@ public class RegionFile implements AutoCloseable { - return this.a(chunkcoordintpair, b(b0)); - } else if (j1 > bytebuffer.remaining()) { - RegionFile.LOGGER.error("Chunk {} stream is truncated: expected {} but read {}", chunkcoordintpair, j1, bytebuffer.remaining()); -+ // Tuinity start - recalculate header on regionfile corruption -+ if (this.canRecalcHeader) { -+ this.recalculateHeader(); -+ return this.getReadStream(chunkcoordintpair); -+ } -+ // Tuinity end - return null; - } else if (j1 < 0) { - RegionFile.LOGGER.error("Declared size {} of chunk {} is negative", i1, chunkcoordintpair); -+ // Tuinity start - recalculate header on regionfile corruption -+ if (this.canRecalcHeader) { -+ this.recalculateHeader(); -+ return this.getReadStream(chunkcoordintpair); -+ } -+ // Tuinity end - return null; - } else { - return this.a(chunkcoordintpair, b0, a(bytebuffer, j1)); -@@ -323,10 +763,15 @@ public class RegionFile implements AutoCloseable { - } - - private ByteBuffer a() { -+ // Tuinity start - add compressionType param -+ return this.getOversizedChunkHolderData(this.getRegionFileCompression()); -+ } -+ private ByteBuffer getOversizedChunkHolderData(RegionFileCompression compressionType) { -+ // Tuinity end - ByteBuffer bytebuffer = ByteBuffer.allocate(5); - - bytebuffer.putInt(1); -- bytebuffer.put((byte) (this.e.a() | 128)); -+ bytebuffer.put((byte) (compressionType.a() | 128)); // Tuinity - replace with compressionType - ((java.nio.Buffer) bytebuffer).flip(); - return bytebuffer; - } -@@ -363,6 +808,7 @@ public class RegionFile implements AutoCloseable { - }; - } - -+ private final void flushHeader() throws IOException { this.b(); } // Tuinity - OBFHELPER - private void b() throws IOException { - ((java.nio.Buffer) this.f).position(0); - this.dataFile.write(this.f, 0L); -diff --git a/src/main/java/net/minecraft/server/RegionFileBitSet.java b/src/main/java/net/minecraft/server/RegionFileBitSet.java -index 1ebdf73cc..cfa3ecb03 100644 ---- a/src/main/java/net/minecraft/server/RegionFileBitSet.java -+++ b/src/main/java/net/minecraft/server/RegionFileBitSet.java -@@ -4,18 +4,42 @@ import java.util.BitSet; - - public class RegionFileBitSet { - -- private final BitSet a = new BitSet(); -+ private final BitSet a = new BitSet(); private final BitSet getBitset() { return this.a; } // Tuinity - OBFHELPER - - public RegionFileBitSet() {} - -+ public final void allocate(int from, int length) { this.a(from, length); } // Tuinity - OBFHELPER - public void a(int i, int j) { - this.a.set(i, i + j); - } - -+ public final void free(int from, int length) { this.b(from, length); } // Tuinity - OBFHELPER - public void b(int i, int j) { - this.a.clear(i, i + j); - } - -+ // Tuinity start -+ public final void copyFrom(RegionFileBitSet other) { -+ BitSet thisBitset = this.getBitset(); -+ BitSet otherBitset = other.getBitset(); -+ -+ for (int i = 0; i < Math.max(thisBitset.size(), otherBitset.size()); ++i) { -+ thisBitset.set(i, otherBitset.get(i)); -+ } -+ } -+ -+ public final boolean tryAllocate(int from, int length) { -+ BitSet bitset = this.getBitset(); -+ int firstSet = bitset.nextSetBit(from); -+ if (firstSet > 0 && firstSet < (from + length)) { -+ return false; -+ } -+ bitset.set(from, from + length); -+ return true; -+ } -+ // Tuinity end -+ -+ public final int allocateNewSpace(final int requiredLength) { return this.a(requiredLength); } // Tuinity - OBFHELPER - public int a(int i) { - int j = 0; - -diff --git a/src/main/java/net/minecraft/server/RegionFileCache.java b/src/main/java/net/minecraft/server/RegionFileCache.java -index 72118a7dc..3eebeee4c 100644 ---- a/src/main/java/net/minecraft/server/RegionFileCache.java -+++ b/src/main/java/net/minecraft/server/RegionFileCache.java -@@ -18,6 +18,30 @@ public class RegionFileCache implements AutoCloseable { // Paper - no final - this.b = file; - } - -+ // Tuinity start -+ public static ChunkCoordIntPair getRegionFileCoordinates(File file) { -+ String fileName = file.getName(); -+ if (!fileName.startsWith("r.") || !fileName.endsWith(".mca")) { -+ return null; -+ } -+ -+ String[] split = fileName.split("\\."); -+ -+ if (split.length != 4) { -+ return null; -+ } -+ -+ try { -+ int x = Integer.parseInt(split[1]); -+ int z = Integer.parseInt(split[2]); -+ -+ return new ChunkCoordIntPair(x << 5, z << 5); -+ } catch (NumberFormatException ex) { -+ return null; -+ } -+ } -+ // Tuinity end -+ - - // Paper start - public synchronized RegionFile getRegionFileIfLoaded(ChunkCoordIntPair chunkcoordintpair) { // Paper - synchronize for async io -@@ -51,9 +75,9 @@ public class RegionFileCache implements AutoCloseable { // Paper - no final - this.b.mkdirs(); - } - -- File file = new File(this.b, "r." + chunkcoordintpair.getRegionX() + "." + chunkcoordintpair.getRegionZ() + ".mca"); -+ File file = new File(this.b, "r." + chunkcoordintpair.getRegionX() + "." + chunkcoordintpair.getRegionZ() + ".mca"); // Tuinity - diff on change - if (existingOnly && !file.exists()) return null; // CraftBukkit -- RegionFile regionfile1 = new RegionFile(file, this.b); -+ RegionFile regionfile1 = new RegionFile(file, this.b, this instanceof IChunkLoader); // Tuinity - allow for chunk regionfiles to regen header - - this.cache.putAndMoveToFirst(i, regionfile1); - // Paper start -@@ -142,6 +166,13 @@ public class RegionFileCache implements AutoCloseable { // Paper - no final - return null; - } - // CraftBukkit end -+ // Tuinity start - Add regionfile parameter -+ return this.readFromRegionFile(regionfile, chunkcoordintpair); -+ } -+ private NBTTagCompound readFromRegionFile(RegionFile regionfile, ChunkCoordIntPair chunkcoordintpair) throws IOException { -+ // We add the regionfile parameter to avoid the potential deadlock (on fileLock) if we went back to obtain a regionfile -+ // if we decide to re-read -+ // Tuinity end - try { // Paper - DataInputStream datainputstream = regionfile.a(chunkcoordintpair); - // Paper start -@@ -157,6 +188,16 @@ public class RegionFileCache implements AutoCloseable { // Paper - no final - try { - if (datainputstream != null) { - nbttagcompound = NBTCompressedStreamTools.a(datainputstream); -+ // Tuinity start - recover from corrupt regionfile header -+ if (this instanceof IChunkLoader) { -+ ChunkCoordIntPair chunkPos = ChunkRegionLoader.getChunkCoordinate(nbttagcompound); -+ if (!chunkPos.equals(chunkcoordintpair)) { -+ regionfile.recalculateHeader(); -+ regionfile.fileLock.lock(); // otherwise we will unlock twice and only lock once. -+ return this.readFromRegionFile(regionfile, chunkcoordintpair); -+ } -+ } -+ // Tuinity end - return nbttagcompound; - } - -diff --git a/src/main/java/net/minecraft/server/RegionFileCompression.java b/src/main/java/net/minecraft/server/RegionFileCompression.java -index 3382d678e..29137f495 100644 ---- a/src/main/java/net/minecraft/server/RegionFileCompression.java -+++ b/src/main/java/net/minecraft/server/RegionFileCompression.java -@@ -13,7 +13,7 @@ import javax.annotation.Nullable; - - public class RegionFileCompression { - -- private static final Int2ObjectMap d = new Int2ObjectOpenHashMap(); -+ private static final Int2ObjectMap d = new Int2ObjectOpenHashMap(); static final Int2ObjectMap getCompressionTypes() { return RegionFileCompression.d; } // Tuinity - OBFHELPER - public static final RegionFileCompression a = a(new RegionFileCompression(1, GZIPInputStream::new, GZIPOutputStream::new)); - public static final RegionFileCompression b = a(new RegionFileCompression(2, InflaterInputStream::new, DeflaterOutputStream::new)); - public static final RegionFileCompression c = a(new RegionFileCompression(3, (inputstream) -> { -@@ -36,8 +36,8 @@ public class RegionFileCompression { - return regionfilecompression; - } - -- @Nullable -- public static RegionFileCompression a(int i) { -+ @Nullable public static RegionFileCompression getByType(int type) { return RegionFileCompression.a(type); } // Tuinity - OBFHELPER -+ @Nullable public static RegionFileCompression a(int i) { // Tuinity - OBFHELPER - return (RegionFileCompression) RegionFileCompression.d.get(i); - } - -@@ -53,6 +53,7 @@ public class RegionFileCompression { - return (OutputStream) this.g.wrap(outputstream); - } - -+ public final InputStream wrap(InputStream inputstream) throws IOException { return this.a(inputstream); } // Tuinity - OBFHELPER - public InputStream a(InputStream inputstream) throws IOException { - return (InputStream) this.f.wrap(inputstream); - } -diff --git a/src/main/java/net/minecraft/server/Ticket.java b/src/main/java/net/minecraft/server/Ticket.java -index c79aa4a80..36916459c 100644 ---- a/src/main/java/net/minecraft/server/Ticket.java -+++ b/src/main/java/net/minecraft/server/Ticket.java -@@ -5,17 +5,17 @@ import java.util.Objects; - public final class Ticket implements Comparable> { - - private final TicketType a; -- private final int b; -+ private int b; public final void setTicketLevel(final int value) { this.b = value; } // Tuinity - remove final, add set OBFHELPER - public final T identifier; public final T getObjectReason() { return this.identifier; } // Paper - OBFHELPER -- private long d; public final long getCreationTick() { return this.d; } // Paper - OBFHELPER -+ private long d; public final long getCreationTick() { return this.d; } public final void setCreationTick(final long value) { this.d = value; } // Paper - OBFHELPER // Tuinity - OBFHELPER - public int priority = 0; // Paper -- public long delayUnloadBy; // Paper -+ boolean isCached; // Tuinity - delay chunk unloads, this defends against really stupid plugins - - protected Ticket(TicketType tickettype, int i, T t0) { - this.a = tickettype; - this.b = i; - this.identifier = t0; -- this.delayUnloadBy = tickettype.loadPeriod; // Paper -+ // Tuinity - delay chunk unloads - } - - public int compareTo(Ticket ticket) { -@@ -64,8 +64,9 @@ public final class Ticket implements Comparable> { - this.d = i; - } - -+ protected final boolean isExpired(long time) { return this.b(time); } // Tuinity - OBFHELPER - protected boolean b(long i) { -- long j = delayUnloadBy; // Paper -+ long j = this.a.b(); // Tuinity - delay chunk unloads - - return j != 0L && i - this.d > j; - } -diff --git a/src/main/java/net/minecraft/server/TicketType.java b/src/main/java/net/minecraft/server/TicketType.java -index 5c789b25f..4657b05a4 100644 ---- a/src/main/java/net/minecraft/server/TicketType.java -+++ b/src/main/java/net/minecraft/server/TicketType.java -@@ -26,7 +26,8 @@ public class TicketType { - public static final TicketType ASYNC_LOAD = a("async_load", Long::compareTo); // Paper - public static final TicketType PRIORITY = a("priority", Comparator.comparingLong(ChunkCoordIntPair::pair), 300); // Paper - public static final TicketType URGENT = a("urgent", Comparator.comparingLong(ChunkCoordIntPair::pair), 300); // Paper -- public static final TicketType DELAY_UNLOAD = a("delay_unload", Long::compareTo, 300); // Paper -+ public static final TicketType DELAYED_UNLOAD = a("delayed_unload", Long::compareTo); // Tuinity - delay chunk unloads -+ public static final TicketType REQUIRED_LOAD = a("required_load", Long::compareTo); // Tuinity - make sure getChunkAt does not fail - - public static TicketType a(String s, Comparator comparator) { - return new TicketType<>(s, comparator, 0L); -diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java -index a8e64dfda..652ad383a 100644 ---- a/src/main/java/net/minecraft/server/TileEntity.java -+++ b/src/main/java/net/minecraft/server/TileEntity.java -@@ -12,7 +12,7 @@ import org.bukkit.inventory.InventoryHolder; - import co.aikar.timings.MinecraftTimings; // Paper - import co.aikar.timings.Timing; // Paper - --public abstract class TileEntity implements KeyedObject { // Paper -+public abstract class TileEntity implements KeyedObject, Cloneable { // Paper // Tuinity - - public Timing tickTimer = MinecraftTimings.getTileEntityTimings(this); // Paper - // CraftBukkit start - data containers -@@ -27,7 +27,7 @@ public abstract class TileEntity implements KeyedObject { // Paper - protected BlockPosition position; - protected boolean f; - @Nullable -- private IBlockData c; -+ private IBlockData c; protected final IBlockData getBlockDataCache() { return this.c; } public final void setBlockDataCache(final IBlockData value) { this.c = value; } // Tuinity - OBFHELPER - private boolean g; - - public TileEntity(TileEntityTypes tileentitytypes) { -@@ -35,6 +35,51 @@ public abstract class TileEntity implements KeyedObject { // Paper - this.tileType = tileentitytypes; - } - -+ // Tuinity start - pushable TE's -+ public boolean isPushable() { -+ if (!com.tuinity.tuinity.config.TuinityConfig.pistonsCanPushTileEntities) { -+ return false; -+ } -+ IBlockData block = this.getBlock(); -+ if (this.isRemoved() || !this.tileType.isValidBlock(block.getBlock())) { -+ return false; -+ } -+ EnumPistonReaction reaction = block.getPushReaction(); -+ return reaction == EnumPistonReaction.NORMAL || reaction == EnumPistonReaction.PUSH_ONLY; -+ } -+ -+ @Override -+ protected final TileEntity clone() { -+ try { -+ return (TileEntity)super.clone(); -+ } catch (final Throwable thr) { -+ if (thr instanceof ThreadDeath) { -+ throw (ThreadDeath)thr; -+ } -+ throw new InternalError(thr); -+ } -+ } -+ -+ // this method presumes the old TE has been completely dropped from worldstate and has no ties to it anymore (this -+ // includes players interacting with them) -+ public TileEntity createCopyForPush(WorldServer world, BlockPosition oldPos, BlockPosition newPos, IBlockData blockData) { -+ final TileEntity copy = this.clone(); -+ -+ copy.world = world; -+ copy.position = newPos; -+ -+ // removed is manually set to false after placing the entity into the world. -+ copy.setBlockDataCache(blockData); -+ -+ return copy; -+ } -+ -+ // updates TE state to its new position -+ public void onPostPush() { -+ this.update(); -+ } -+ // Tuinity end - pushable TE's -+ - // Paper start - private String tileEntityKeyString = null; - private MinecraftKey tileEntityKey = null; -diff --git a/src/main/java/net/minecraft/server/TileEntityBeacon.java b/src/main/java/net/minecraft/server/TileEntityBeacon.java -index df2d6c3b0..9780ee07b 100644 ---- a/src/main/java/net/minecraft/server/TileEntityBeacon.java -+++ b/src/main/java/net/minecraft/server/TileEntityBeacon.java -@@ -35,7 +35,7 @@ public class TileEntityBeacon extends TileEntity implements ITileInventory, ITic - @Nullable - public IChatBaseComponent customName; - public ChestLock chestLock; -- private final IContainerProperties containerProperties; -+ private IContainerProperties containerProperties; // Tuinity - need non-final for `createCopyForPush` - // CraftBukkit start - add fields and methods - public PotionEffect getPrimaryEffect() { - return (this.primaryEffect != null) ? CraftPotionUtil.toBukkit(new MobEffect(this.primaryEffect, getLevel(), getAmplification(), true, true)) : null; -@@ -46,10 +46,10 @@ public class TileEntityBeacon extends TileEntity implements ITileInventory, ITic - } - // CraftBukkit end - -- public TileEntityBeacon() { -- super(TileEntityTypes.BEACON); -- this.chestLock = ChestLock.a; -- this.containerProperties = new IContainerProperties() { -+ // Tuinity start - pushable TE's -+ protected final IContainerProperties getNewContainerProperties() { -+ // moved from constructor - this should be re-copied if it changes -+ return new IContainerProperties() { - @Override - public int getProperty(int i) { - switch (i) { -@@ -90,6 +90,22 @@ public class TileEntityBeacon extends TileEntity implements ITileInventory, ITic - }; - } - -+ @Override -+ public TileEntity createCopyForPush(WorldServer world, BlockPosition oldPos, BlockPosition newPos, IBlockData blockData) { -+ TileEntityBeacon copy = (TileEntityBeacon)super.createCopyForPush(world, oldPos, newPos, blockData); -+ -+ copy.containerProperties = copy.getNewContainerProperties(); // old properties retains reference to old te -+ -+ return copy; -+ } -+ // Tuinity end - pushable TE's -+ -+ public TileEntityBeacon() { -+ super(TileEntityTypes.BEACON); -+ this.chestLock = ChestLock.a; -+ this.containerProperties = this.getNewContainerProperties(); // Tuinity - move into function -+ } -+ - @Override - public void tick() { - int i = this.position.getX(); -diff --git a/src/main/java/net/minecraft/server/TileEntityBeehive.java b/src/main/java/net/minecraft/server/TileEntityBeehive.java -index 417152d16..42374183b 100644 ---- a/src/main/java/net/minecraft/server/TileEntityBeehive.java -+++ b/src/main/java/net/minecraft/server/TileEntityBeehive.java -@@ -12,6 +12,13 @@ public class TileEntityBeehive extends TileEntity implements ITickable { - public BlockPosition flowerPos = null; - public int maxBees = 3; // CraftBukkit - allow setting max amount of bees a hive can hold - -+ // Tuinity start - pushable TE's -+ @Override -+ public boolean isPushable() { -+ return false; // TODO until there is a good solution to making the already existing bees in the world re-acquire this position, this cannot be done. -+ } -+ // Tuinity end - pushable TE's -+ - public TileEntityBeehive() { - super(TileEntityTypes.BEEHIVE); - } -diff --git a/src/main/java/net/minecraft/server/TileEntityBrewingStand.java b/src/main/java/net/minecraft/server/TileEntityBrewingStand.java -index 441157cf7..438d14dd2 100644 ---- a/src/main/java/net/minecraft/server/TileEntityBrewingStand.java -+++ b/src/main/java/net/minecraft/server/TileEntityBrewingStand.java -@@ -24,7 +24,7 @@ public class TileEntityBrewingStand extends TileEntityContainer implements IWorl - private boolean[] j; - private Item k; - public int fuelLevel; -- protected final IContainerProperties a; -+ protected IContainerProperties a; protected final void setContainerProperties(IContainerProperties value) { this.a = value; } // Tuinity - OBFHELPER // Tuinity - need non-final for `createCopyForPush` - // CraftBukkit start - add fields and methods - private int lastTick = MinecraftServer.currentTick; - public List transaction = new java.util.ArrayList(); -@@ -56,10 +56,10 @@ public class TileEntityBrewingStand extends TileEntityContainer implements IWorl - } - // CraftBukkit end - -- public TileEntityBrewingStand() { -- super(TileEntityTypes.BREWING_STAND); -- this.items = NonNullList.a(5, ItemStack.a); -- this.a = new IContainerProperties() { -+ // Tuinity start - pushable TE's -+ protected final IContainerProperties getNewContainerProperties() { -+ // moved from constructor - this should be re-copied if it changes -+ return new IContainerProperties() { - @Override - public int getProperty(int i) { - switch (i) { -@@ -91,6 +91,22 @@ public class TileEntityBrewingStand extends TileEntityContainer implements IWorl - }; - } - -+ @Override -+ public TileEntity createCopyForPush(WorldServer world, BlockPosition oldPos, BlockPosition newPos, IBlockData blockData) { -+ TileEntityBrewingStand copy = (TileEntityBrewingStand)super.createCopyForPush(world, oldPos, newPos, blockData); -+ -+ copy.setContainerProperties(copy.getNewContainerProperties()); // old properties retains reference to old te -+ -+ return copy; -+ } -+ // Tuinity end - pushable TE's -+ -+ public TileEntityBrewingStand() { -+ super(TileEntityTypes.BREWING_STAND); -+ this.items = NonNullList.a(5, ItemStack.a); -+ this.a = this.getNewContainerProperties(); -+ } -+ - @Override - protected IChatBaseComponent getContainerName() { - return new ChatMessage("container.brewing", new Object[0]); -diff --git a/src/main/java/net/minecraft/server/TileEntityChest.java b/src/main/java/net/minecraft/server/TileEntityChest.java -index 9a5f2da8c..50a8d59da 100644 ---- a/src/main/java/net/minecraft/server/TileEntityChest.java -+++ b/src/main/java/net/minecraft/server/TileEntityChest.java -@@ -45,6 +45,22 @@ public class TileEntityChest extends TileEntityLootable { // Paper - Remove ITic - } - // CraftBukkit end - -+ // Tuinity start -+ @Override -+ public boolean isPushable() { -+ if (!super.isPushable()) { -+ return false; -+ } -+ // what should happen when a double chest is moved is generally just a mess to deal with in the current -+ // codebase. -+ IBlockData type = this.getBlock(); -+ if (type.getBlock() == Blocks.CHEST || type.getBlock() == Blocks.TRAPPED_CHEST) { -+ return type.get(BlockChest.getChestTypeEnum()) == BlockPropertyChestType.SINGLE; -+ } -+ return false; -+ } -+ // Tuinity end -+ - protected TileEntityChest(TileEntityTypes tileentitytypes) { - super(tileentitytypes); - this.items = NonNullList.a(27, ItemStack.a); -diff --git a/src/main/java/net/minecraft/server/TileEntityConduit.java b/src/main/java/net/minecraft/server/TileEntityConduit.java -index 07f265b29..34c191d76 100644 ---- a/src/main/java/net/minecraft/server/TileEntityConduit.java -+++ b/src/main/java/net/minecraft/server/TileEntityConduit.java -@@ -16,15 +16,32 @@ public class TileEntityConduit extends TileEntity implements ITickable { - private static final Block[] b = new Block[]{Blocks.PRISMARINE, Blocks.PRISMARINE_BRICKS, Blocks.SEA_LANTERN, Blocks.DARK_PRISMARINE}; - public int a; - private float c; -- private boolean g; -+ private boolean g; private final void setActive(boolean value) { this.g = value; } // Tuinity - OBFHELPER - private boolean h; -- private final List i; -+ private final List i; private final List getPositionsActivating() { return this.i; } // Tuinity - OBFHELPER - @Nullable - private EntityLiving target; - @Nullable - private UUID k; - private long l; - -+ // Tuinity start - make TE's pushable -+ @Override -+ public TileEntity createCopyForPush(WorldServer world, BlockPosition oldPos, BlockPosition newPos, IBlockData blockData) { -+ final TileEntityConduit copy = (TileEntityConduit)super.createCopyForPush(world, oldPos, newPos, blockData); -+ -+ // the following states need to be re-calculated -+ copy.getPositionsActivating().clear(); -+ copy.setActive(false); -+ copy.target = null; -+ // also set our state because the copy and this share the same activating block list -+ this.setActive(false); -+ this.target = null; -+ -+ return copy; -+ } -+ // Tuinity end - make TE's pushable -+ - public TileEntityConduit() { - this(TileEntityTypes.CONDUIT); - } -diff --git a/src/main/java/net/minecraft/server/TileEntityFurnace.java b/src/main/java/net/minecraft/server/TileEntityFurnace.java -index d5432bfeb..7d50b7056 100644 ---- a/src/main/java/net/minecraft/server/TileEntityFurnace.java -+++ b/src/main/java/net/minecraft/server/TileEntityFurnace.java -@@ -30,14 +30,14 @@ public abstract class TileEntityFurnace extends TileEntityContainer implements I - public double cookSpeedMultiplier = 1.0; // Paper - cook speed multiplier API - public int cookTime; - public int cookTimeTotal; -- protected final IContainerProperties b; -+ protected IContainerProperties b; protected final void setContainerProperties(IContainerProperties value) { this.b = value; } // Tuinity - OBFHELPER // Tuinity - need non-final for `createCopyForPush` - private final Map n; - protected final Recipes c; - -- protected TileEntityFurnace(TileEntityTypes tileentitytypes, Recipes recipes) { -- super(tileentitytypes); -- this.items = NonNullList.a(3, ItemStack.a); -- this.b = new IContainerProperties() { -+ // Tuinity start - pushable TE's -+ protected final IContainerProperties getNewContainerProperties() { -+ // moved from constructor - this should be re-copied if it changes -+ return new IContainerProperties() { - @Override - public int getProperty(int i) { - switch (i) { -@@ -77,6 +77,22 @@ public abstract class TileEntityFurnace extends TileEntityContainer implements I - return 4; - } - }; -+ } -+ -+ @Override -+ public TileEntity createCopyForPush(WorldServer world, BlockPosition oldPos, BlockPosition newPos, IBlockData blockData) { -+ TileEntityFurnace copy = (TileEntityFurnace)super.createCopyForPush(world, oldPos, newPos, blockData); -+ -+ copy.setContainerProperties(copy.getNewContainerProperties()); // old properties retains reference to old te -+ -+ return copy; -+ } -+ // Tuinity end - pushable TE's -+ -+ protected TileEntityFurnace(TileEntityTypes tileentitytypes, Recipes recipes) { -+ super(tileentitytypes); -+ this.items = NonNullList.a(3, ItemStack.a); -+ this.b = this.getNewContainerProperties(); - this.n = Maps.newHashMap(); - this.c = recipes; - } -diff --git a/src/main/java/net/minecraft/server/TileEntityJukeBox.java b/src/main/java/net/minecraft/server/TileEntityJukeBox.java -index d66d9ff18..470f31083 100644 ---- a/src/main/java/net/minecraft/server/TileEntityJukeBox.java -+++ b/src/main/java/net/minecraft/server/TileEntityJukeBox.java -@@ -4,6 +4,13 @@ public class TileEntityJukeBox extends TileEntity implements Clearable { - - private ItemStack a; - -+ // Tuinity start - pushable TE's -+ @Override -+ public boolean isPushable() { -+ return false; // disabled due to buggy sound -+ } -+ // Tuinity end - pushable TE's -+ - public TileEntityJukeBox() { - super(TileEntityTypes.JUKEBOX); - this.a = ItemStack.a; -diff --git a/src/main/java/net/minecraft/server/TileEntityLectern.java b/src/main/java/net/minecraft/server/TileEntityLectern.java -index 6c2b48bdb..c3b854b6a 100644 ---- a/src/main/java/net/minecraft/server/TileEntityLectern.java -+++ b/src/main/java/net/minecraft/server/TileEntityLectern.java -@@ -16,7 +16,7 @@ import org.bukkit.inventory.InventoryHolder; - public class TileEntityLectern extends TileEntity implements Clearable, ITileInventory, ICommandListener { // CraftBukkit - ICommandListener - - // CraftBukkit start - add fields and methods -- public final IInventory inventory = new LecternInventory(); -+ public IInventory inventory = new LecternInventory(); // Tuinity - need non-final for `createCopyForPush` - public class LecternInventory implements IInventory { - - public List transaction = new ArrayList<>(); -@@ -136,29 +136,48 @@ public class TileEntityLectern extends TileEntity implements Clearable, ITileInv - @Override - public void clear() {} - }; -- private final IContainerProperties containerProperties = new IContainerProperties() { -- @Override -- public int getProperty(int i) { -- return i == 0 ? TileEntityLectern.this.page : 0; -- } -+ // Tuinity start - pushable TE's -+ private IContainerProperties containerProperties = this.getNewContainerProperties(); // Tuinity - need non-final for `createCopyForPush` -+ -+ protected final IContainerProperties getNewContainerProperties() { -+ return new IContainerProperties() { -+ @Override -+ public int getProperty(int i) { -+ return i == 0 ? TileEntityLectern.this.page : 0; -+ } -+ -+ @Override -+ public void setProperty(int i, int j) { -+ if (i == 0) { -+ TileEntityLectern.this.setPage(j); -+ } - -- @Override -- public void setProperty(int i, int j) { -- if (i == 0) { -- TileEntityLectern.this.setPage(j); - } - -- } -+ @Override -+ public int a() { -+ return 1; -+ } -+ }; -+ } -+ // Tuinity end - pushable TE's - -- @Override -- public int a() { -- return 1; -- } -- }; - private ItemStack book; - private int page; - private int maxPage; - -+ // Tuinity start - pushable TE's -+ @Override -+ public TileEntity createCopyForPush(WorldServer world, BlockPosition oldPos, BlockPosition newPos, IBlockData blockData) { -+ TileEntityLectern copy = (TileEntityLectern)super.createCopyForPush(world, oldPos, newPos, blockData); -+ -+ copy.inventory = copy.new LecternInventory(); -+ copy.containerProperties = copy.getNewContainerProperties(); // old properties retains reference to old te -+ -+ return copy; -+ } -+ // Tuinity end - pushable TE's -+ - public TileEntityLectern() { - super(TileEntityTypes.LECTERN); - this.book = ItemStack.a; -diff --git a/src/main/java/net/minecraft/server/TileEntityPiston.java b/src/main/java/net/minecraft/server/TileEntityPiston.java -index d700e8281..bd0ebacf7 100644 ---- a/src/main/java/net/minecraft/server/TileEntityPiston.java -+++ b/src/main/java/net/minecraft/server/TileEntityPiston.java -@@ -5,10 +5,10 @@ import java.util.List; - - public class TileEntityPiston extends TileEntity implements ITickable { - -- private IBlockData a; -+ private IBlockData a; protected final IBlockData getBlockData() { return this.a; } // Tuinity - OBFHELPER - private EnumDirection b; - private boolean c; -- private boolean g; -+ private boolean g; protected final boolean isSource() { return this.g; } // Tuinity - OBFHELPER - private static final ThreadLocal h = ThreadLocal.withInitial(() -> { - return null; - }); -@@ -16,12 +16,27 @@ public class TileEntityPiston extends TileEntity implements ITickable { - private float j; - private long k; - -+ // Tuinity start - pushable TE's -+ private TileEntity tileEntity; -+ -+ @Override -+ public boolean isPushable() { -+ return false; // fuck no. -+ } -+ // Tuinity end - pushable TE's -+ - public TileEntityPiston() { - super(TileEntityTypes.PISTON); - } - - public TileEntityPiston(IBlockData iblockdata, EnumDirection enumdirection, boolean flag, boolean flag1) { -+ // Tuinity start - add tileEntity parameter -+ this(iblockdata, enumdirection, flag, flag1, null); -+ } -+ public TileEntityPiston(IBlockData iblockdata, EnumDirection enumdirection, boolean flag, boolean flag1, TileEntity tileEntity) { - this(); -+ this.tileEntity = tileEntity; -+ // Tuinity end - add tileEntity parameter - this.a = iblockdata; - this.b = enumdirection; - this.c = flag; -@@ -30,7 +45,7 @@ public class TileEntityPiston extends TileEntity implements ITickable { - - @Override - public NBTTagCompound b() { -- return this.save(new NBTTagCompound()); -+ return this.save(new NBTTagCompound(), false); // Tuinity - clients don't need the copied tile entity. - } - - public boolean d() { -@@ -257,7 +272,25 @@ public class TileEntityPiston extends TileEntity implements ITickable { - iblockdata = Block.b(this.a, (GeneratorAccess) this.world, this.position); - } - -- this.world.setTypeAndData(this.position, iblockdata, 3); -+ // Tuinity start - pushable TE's -+ if ((iblockdata.isAir() && !this.isSource()) && !this.getBlockData().isAir()) { -+ // if the block can't exist at the location anymore, we need to fire drops for it, as -+ // setTypeAndData wont. -+ -+ // careful - the previous pos is moving_piston, which wont fire drops. So we're safe from dupes. -+ // but the setAir should be before the drop. -+ this.world.setAir(this.position, false); -+ Block.dropItems(this.getBlockData(), this.world, this.position, null, null, ItemStack.NULL_ITEM); -+ } else { -+ // need to set to air before else the setTypeAndData call will create a new TE and override -+ // the old one -+ this.world.setTypeAndDataRaw(this.position, Blocks.AIR.getBlockData(), null); -+ this.world.setTypeAndData(this.position, iblockdata, 3, iblockdata.getBlock() == this.getBlockData().getBlock() ? this.tileEntity : null); -+ } -+ if (this.tileEntity != null && this.world.getType(this.position).getBlock() == this.getBlockData().getBlock()) { -+ this.tileEntity.onPostPush(); -+ } -+ // Tuinity end - pushable TE's - this.world.a(this.position, iblockdata.getBlock(), this.position); - } - } -@@ -282,7 +315,12 @@ public class TileEntityPiston extends TileEntity implements ITickable { - iblockdata = (IBlockData) iblockdata.set(BlockProperties.C, false); - } - -- this.world.setTypeAndData(this.position, iblockdata, 67); -+ // Tuinity start - pushable TE's -+ this.world.setTypeAndData(this.position, iblockdata, 67, this.tileEntity); -+ if (this.tileEntity != null && this.world.getType(this.position).getBlock() == this.getBlockData().getBlock()) { -+ this.tileEntity.onPostPush(); -+ } -+ // Tuinity end - pushable TE's - this.world.a(this.position, iblockdata.getBlock(), this.position); - } - } -@@ -309,16 +347,34 @@ public class TileEntityPiston extends TileEntity implements ITickable { - this.j = this.i; - this.c = nbttagcompound.getBoolean("extending"); - this.g = nbttagcompound.getBoolean("source"); -+ // Tuinity start - pushable TE's -+ if (nbttagcompound.hasKey("Tuinity.tileEntity")) { -+ NBTTagCompound compound = nbttagcompound.getCompound("Tuinity.tileEntity"); -+ if (!compound.isEmpty()) { -+ this.tileEntity = TileEntity.create(compound); -+ } -+ } -+ // Tuinity end - pushable TE's - } - - @Override - public NBTTagCompound save(NBTTagCompound nbttagcompound) { -+ // Tuinity start - add saveTile param -+ return this.save(nbttagcompound, true); -+ } -+ public NBTTagCompound save(NBTTagCompound nbttagcompound, boolean saveTile) { -+ // Tuinity end - add saveTile param - super.save(nbttagcompound); - nbttagcompound.set("blockState", GameProfileSerializer.a(this.a)); - nbttagcompound.setInt("facing", this.b.b()); - nbttagcompound.setFloat("progress", this.j); - nbttagcompound.setBoolean("extending", this.c); - nbttagcompound.setBoolean("source", this.g); -+ // Tuinity start - pushable TE's -+ if (saveTile && this.tileEntity != null) { -+ nbttagcompound.set("Tuinity.tileEntity", this.tileEntity.save(new NBTTagCompound())); -+ } -+ // Tuinity end - pushable TE's - return nbttagcompound; - } - -diff --git a/src/main/java/net/minecraft/server/Vec3D.java b/src/main/java/net/minecraft/server/Vec3D.java -index 0c7f094e5..c2e4b5e8d 100644 ---- a/src/main/java/net/minecraft/server/Vec3D.java -+++ b/src/main/java/net/minecraft/server/Vec3D.java -@@ -4,7 +4,7 @@ import java.util.EnumSet; - - public class Vec3D implements IPosition { - -- public static final Vec3D a = new Vec3D(0.0D, 0.0D, 0.0D); -+ public static final Vec3D a = new Vec3D(0.0D, 0.0D, 0.0D); public static Vec3D getZeroVector() { return Vec3D.a; } // Tuinity - OBFHELPER - public final double x; - public final double y; - public final double z; -@@ -49,6 +49,7 @@ public class Vec3D implements IPosition { - return this.add(-d0, -d1, -d2); - } - -+ public final Vec3D add(Vec3D vec3d) { return this.e(vec3d); } // Tuinity - OBFHELPER - public Vec3D e(Vec3D vec3d) { - return this.add(vec3d.x, vec3d.y, vec3d.z); - } -@@ -93,10 +94,12 @@ public class Vec3D implements IPosition { - return new Vec3D(this.x * d0, this.y * d1, this.z * d2); - } - -+ public final double magnitude() { return this.f(); } // Tuinity - OBFHELPER - public double f() { - return (double) MathHelper.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); - } - -+ public final double magnitudeSquared() { return this.g(); } // Tuinity - OBFHELPER - public double g() { - return this.x * this.x + this.y * this.y + this.z * this.z; - } -diff --git a/src/main/java/net/minecraft/server/VillagePlace.java b/src/main/java/net/minecraft/server/VillagePlace.java -index 1a5ec6152..5b52b380e 100644 ---- a/src/main/java/net/minecraft/server/VillagePlace.java -+++ b/src/main/java/net/minecraft/server/VillagePlace.java -@@ -150,7 +150,7 @@ public class VillagePlace extends RegionFileSection { - data = this.getData(chunkcoordintpair); - } - com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave(this.world, -- chunkcoordintpair.x, chunkcoordintpair.z, data, null, com.destroystokyo.paper.io.PrioritizedTaskQueue.LOW_PRIORITY); -+ chunkcoordintpair.x, chunkcoordintpair.z, data, null, com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY); // Tuinity - use normal priority - } - } - // Paper end -diff --git a/src/main/java/net/minecraft/server/VoxelShape.java b/src/main/java/net/minecraft/server/VoxelShape.java -index 0f95bcbcc..cb47d466c 100644 ---- a/src/main/java/net/minecraft/server/VoxelShape.java -+++ b/src/main/java/net/minecraft/server/VoxelShape.java -@@ -8,11 +8,11 @@ import javax.annotation.Nullable; - - public abstract class VoxelShape { - -- protected final VoxelShapeDiscrete a; -+ protected final VoxelShapeDiscrete a; public final VoxelShapeDiscrete getShape() { return this.a; } // Tuinity - OBFHELPER - @Nullable - private VoxelShape[] b; - -- VoxelShape(VoxelShapeDiscrete voxelshapediscrete) { -+ protected VoxelShape(VoxelShapeDiscrete voxelshapediscrete) { // Tuinity - this.a = voxelshapediscrete; - } - -@@ -51,6 +51,12 @@ public abstract class VoxelShape { - return (VoxelShape) (this.isEmpty() ? VoxelShapes.a() : new VoxelShapeArray(this.a, new DoubleListOffset(this.a(EnumDirection.EnumAxis.X), d0), new DoubleListOffset(this.a(EnumDirection.EnumAxis.Y), d1), new DoubleListOffset(this.a(EnumDirection.EnumAxis.Z), d2))); - } - -+ // Tuinity start - optimise multi-aabb shapes -+ public boolean intersects(final AxisAlignedBB axisalingedbb) { -+ return VoxelShapes.applyOperation(this, new com.tuinity.tuinity.voxel.AABBVoxelShape(axisalingedbb), OperatorBoolean.AND); -+ } -+ // Tuinity end - optimise multi-aabb shapes -+ - public VoxelShape c() { - VoxelShape[] avoxelshape = new VoxelShape[]{VoxelShapes.a()}; - -@@ -70,6 +76,7 @@ public abstract class VoxelShape { - }, true); - } - -+ public final List getBoundingBoxesRepresentation() { return this.d(); } // Tuinity - OBFHELPER - public List d() { - List list = Lists.newArrayList(); - -diff --git a/src/main/java/net/minecraft/server/VoxelShapeArray.java b/src/main/java/net/minecraft/server/VoxelShapeArray.java -index caf297fe9..8d68c783f 100644 ---- a/src/main/java/net/minecraft/server/VoxelShapeArray.java -+++ b/src/main/java/net/minecraft/server/VoxelShapeArray.java -@@ -3,6 +3,7 @@ package net.minecraft.server; - import it.unimi.dsi.fastutil.doubles.DoubleArrayList; - import it.unimi.dsi.fastutil.doubles.DoubleList; - import java.util.Arrays; -+import java.util.List; - - public final class VoxelShapeArray extends VoxelShape { - -@@ -10,11 +11,25 @@ public final class VoxelShapeArray extends VoxelShape { - private final DoubleList c; - private final DoubleList d; - -+ // Tuinity start - optimise multi-aabb shapes -+ static final AxisAlignedBB[] EMPTY = new AxisAlignedBB[0]; -+ final AxisAlignedBB[] boundingBoxesRepresentation; -+ -+ final double offsetX; -+ final double offsetY; -+ final double offsetZ; -+ // Tuinity end - optimise multi-aabb shapes -+ - protected VoxelShapeArray(VoxelShapeDiscrete voxelshapediscrete, double[] adouble, double[] adouble1, double[] adouble2) { - this(voxelshapediscrete, (DoubleList) DoubleArrayList.wrap(Arrays.copyOf(adouble, voxelshapediscrete.b() + 1)), (DoubleList) DoubleArrayList.wrap(Arrays.copyOf(adouble1, voxelshapediscrete.c() + 1)), (DoubleList) DoubleArrayList.wrap(Arrays.copyOf(adouble2, voxelshapediscrete.d() + 1))); - } - - VoxelShapeArray(VoxelShapeDiscrete voxelshapediscrete, DoubleList doublelist, DoubleList doublelist1, DoubleList doublelist2) { -+ // Tuinity start - optimise multi-aabb shapes -+ this(voxelshapediscrete, doublelist, doublelist1, doublelist2, null, null, 0.0, 0.0, 0.0); -+ } -+ VoxelShapeArray(VoxelShapeDiscrete voxelshapediscrete, DoubleList doublelist, DoubleList doublelist1, DoubleList doublelist2, VoxelShapeArray original, AxisAlignedBB[] boundingBoxesRepresentation, double offsetX, double offsetY, double offsetZ) { -+ // Tuinity end - optimise multi-aabb shapes - super(voxelshapediscrete); - int i = voxelshapediscrete.b() + 1; - int j = voxelshapediscrete.c() + 1; -@@ -27,6 +42,18 @@ public final class VoxelShapeArray extends VoxelShape { - } else { - throw (IllegalArgumentException) SystemUtils.c(new IllegalArgumentException("Lengths of point arrays must be consistent with the size of the VoxelShape.")); - } -+ // Tuinity start - optimise multi-aabb shapes -+ this.boundingBoxesRepresentation = boundingBoxesRepresentation == null ? this.getBoundingBoxesRepresentation().toArray(EMPTY) : boundingBoxesRepresentation; // Tuinity - optimise multi-aabb shapes -+ if (original == null) { -+ this.offsetX = offsetX; -+ this.offsetY = offsetY; -+ this.offsetZ = offsetZ; -+ } else { -+ this.offsetX = offsetX + original.offsetX; -+ this.offsetY = offsetY + original.offsetY; -+ this.offsetZ = offsetZ + original.offsetZ; -+ } -+ // Tuinity end - optimise multi-aabb shapes - } - - @Override -@@ -42,4 +69,49 @@ public final class VoxelShapeArray extends VoxelShape { - throw new IllegalArgumentException(); - } - } -+ -+ // Tuinity start - optimise multi-aabb shapes -+ @Override -+ public VoxelShape a(double d0, double d1, double d2) { -+ if (this == VoxelShapes.getEmptyShape() || this.boundingBoxesRepresentation.length == 0) { -+ return this; -+ } -+ return new VoxelShapeArray(this.a, new DoubleListOffset(this.a(EnumDirection.EnumAxis.X), d0), new DoubleListOffset(this.a(EnumDirection.EnumAxis.Y), d1), new DoubleListOffset(this.a(EnumDirection.EnumAxis.Z), d2), this, this.boundingBoxesRepresentation, d0, d1, d2); -+ } -+ -+ public final AxisAlignedBB[] getBoundingBoxesRepresentationRaw() { -+ return this.boundingBoxesRepresentation; -+ } -+ -+ public final double getOffsetX() { -+ return this.offsetX; -+ } -+ -+ public final double getOffsetY() { -+ return this.offsetY; -+ } -+ -+ public final double getOffsetZ() { -+ return this.offsetZ; -+ } -+ -+ public final boolean intersects(AxisAlignedBB axisalingedbb) { -+ double minX = axisalingedbb.minX - this.offsetX; -+ double maxX = axisalingedbb.maxX - this.offsetX; -+ double minY = axisalingedbb.minY - this.offsetY; -+ double maxY = axisalingedbb.maxY - this.offsetY; -+ double minZ = axisalingedbb.minZ - this.offsetZ; -+ double maxZ = axisalingedbb.maxZ - this.offsetZ; -+ -+ // this can be optimised by checking an "overall shape" -+ -+ for (AxisAlignedBB boundingBox : this.boundingBoxesRepresentation) { -+ if (boundingBox.intersects(minX, minY, minZ, maxX, maxY, maxZ)) { -+ return true; -+ } -+ } -+ -+ return false; -+ } -+ // Tuinity end - optimise multi-aabb shapes - } -diff --git a/src/main/java/net/minecraft/server/VoxelShapes.java b/src/main/java/net/minecraft/server/VoxelShapes.java -index 4b3e632a8..5e24ce485 100644 ---- a/src/main/java/net/minecraft/server/VoxelShapes.java -+++ b/src/main/java/net/minecraft/server/VoxelShapes.java -@@ -17,18 +17,81 @@ public final class VoxelShapes { - - voxelshapebitset.a(0, 0, 0, true, true); - return new VoxelShapeCube(voxelshapebitset); -- }); -+ }); public static final VoxelShape getFullUnoptimisedCube() { return VoxelShapes.b; } // Tuinity - OBFHELPER - public static final VoxelShape a = create(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); -- private static final VoxelShape c = new VoxelShapeArray(new VoxelShapeBitSet(0, 0, 0), new DoubleArrayList(new double[]{0.0D}), new DoubleArrayList(new double[]{0.0D}), new DoubleArrayList(new double[]{0.0D})); -+ private static final VoxelShape c = new VoxelShapeArray(new VoxelShapeBitSet(0, 0, 0), new DoubleArrayList(new double[]{0.0D}), new DoubleArrayList(new double[]{0.0D}), new DoubleArrayList(new double[]{0.0D})); static final VoxelShape getEmptyShape() { return VoxelShapes.c; } // Tuinity - OBFHELPER -+ -+ // Tuinity start - optimise voxelshapes -+ public static boolean isEmpty(VoxelShape voxelshape) { -+ // helper function for determining empty shapes fast -+ return voxelshape == getEmptyShape() || voxelshape.isEmpty(); -+ } -+ // Tuinity end - optimise voxelshapes - - public static final VoxelShape empty() {return a();} // Paper - OBFHELPER - public static VoxelShape a() { - return VoxelShapes.c; - } - -+ static final com.tuinity.tuinity.voxel.AABBVoxelShape optimisedFullCube = new com.tuinity.tuinity.voxel.AABBVoxelShape(new AxisAlignedBB(0, 0, 0, 1.0, 1.0, 1.0)); // Tuinity - optimise voxelshape -+ -+ // Tuinity start - optimise voxelshapes -+ public static void addBoxesToIfIntersects(VoxelShape shape, AxisAlignedBB aabb, java.util.List list) { -+ if (shape instanceof com.tuinity.tuinity.voxel.AABBVoxelShape) { -+ com.tuinity.tuinity.voxel.AABBVoxelShape shapeCasted = (com.tuinity.tuinity.voxel.AABBVoxelShape)shape; -+ if (shapeCasted.aabb.intersects(aabb)) { -+ list.add(shapeCasted.aabb); -+ } -+ } else if (shape instanceof VoxelShapeArray) { -+ VoxelShapeArray shapeCasted = (VoxelShapeArray)shape; -+ double minX = aabb.minX - shapeCasted.offsetX; -+ double maxX = aabb.maxX - shapeCasted.offsetX; -+ double minY = aabb.minY - shapeCasted.offsetY; -+ double maxY = aabb.maxY - shapeCasted.offsetY; -+ double minZ = aabb.minZ - shapeCasted.offsetZ; -+ double maxZ = aabb.maxZ - shapeCasted.offsetZ; -+ -+ // this can be optimised by checking an "overall shape" -+ -+ for (AxisAlignedBB boundingBox : shapeCasted.boundingBoxesRepresentation) { -+ if (boundingBox.intersects(minX, minY, minZ, maxX, maxY, maxZ)) { -+ list.add(boundingBox.offset(shapeCasted.offsetX, shapeCasted.offsetY, shapeCasted.offsetZ)); -+ } -+ } -+ } else { -+ java.util.List boxes = shape.getBoundingBoxesRepresentation(); -+ for (int i = 0, len = boxes.size(); i < len; ++i) { -+ AxisAlignedBB box = boxes.get(i); -+ if (box.intersects(aabb)) { -+ list.add(box); -+ } -+ } -+ } -+ } -+ -+ public static void addBoxesTo(VoxelShape shape, java.util.List list) { -+ if (shape instanceof com.tuinity.tuinity.voxel.AABBVoxelShape) { -+ com.tuinity.tuinity.voxel.AABBVoxelShape shapeCasted = (com.tuinity.tuinity.voxel.AABBVoxelShape)shape; -+ list.add(shapeCasted.aabb); -+ } else if (shape instanceof VoxelShapeArray) { -+ VoxelShapeArray shapeCasted = (VoxelShapeArray)shape; -+ -+ for (AxisAlignedBB boundingBox : shapeCasted.boundingBoxesRepresentation) { -+ list.add(boundingBox.offset(shapeCasted.offsetX, shapeCasted.offsetY, shapeCasted.offsetZ)); -+ } -+ } else { -+ java.util.List boxes = shape.getBoundingBoxesRepresentation(); -+ for (int i = 0, len = boxes.size(); i < len; ++i) { -+ AxisAlignedBB box = boxes.get(i); -+ list.add(box); -+ } -+ } -+ } -+ // Tuinity end - optimise voxelshapes -+ - public static final VoxelShape fullCube() {return b();} // Paper - OBFHELPER - public static VoxelShape b() { -- return VoxelShapes.b; -+ return VoxelShapes.optimisedFullCube; // Tuinity - optimise voxelshape - } - - public static VoxelShape create(double d0, double d1, double d2, double d3, double d4, double d5) { -@@ -67,7 +130,7 @@ public final class VoxelShapes { - return new VoxelShapeCube(voxelshapebitset); - } - } else { -- return new VoxelShapeArray(VoxelShapes.b.a, new double[]{axisalignedbb.minX, axisalignedbb.maxX}, new double[]{axisalignedbb.minY, axisalignedbb.maxY}, new double[]{axisalignedbb.minZ, axisalignedbb.maxZ}); -+ return new com.tuinity.tuinity.voxel.AABBVoxelShape(axisalignedbb); // Tuinity - optimise VoxelShapes for single AABB shapes - } - } - -@@ -132,6 +195,14 @@ public final class VoxelShapes { - - public static final boolean applyOperation(VoxelShape voxelshape, VoxelShape voxelshape1, OperatorBoolean operatorboolean) { return VoxelShapes.c(voxelshape, voxelshape1, operatorboolean); } // Paper - OBFHELPER - public static boolean c(VoxelShape voxelshape, VoxelShape voxelshape1, OperatorBoolean operatorboolean) { -+ // Tuinity start - optimise voxelshape -+ if (operatorboolean == OperatorBoolean.AND && voxelshape instanceof com.tuinity.tuinity.voxel.AABBVoxelShape && voxelshape1 instanceof com.tuinity.tuinity.voxel.AABBVoxelShape) { -+ return ((com.tuinity.tuinity.voxel.AABBVoxelShape) voxelshape).aabb.intersects(((com.tuinity.tuinity.voxel.AABBVoxelShape) voxelshape1).aabb); -+ } -+ return abstract_c(voxelshape, voxelshape1, operatorboolean); -+ } -+ public static boolean abstract_c(VoxelShape voxelshape, VoxelShape voxelshape1, OperatorBoolean operatorboolean) { -+ // Tuinity end - optimise voxelshape - if (operatorboolean.apply(false, false)) { - throw (IllegalArgumentException) SystemUtils.c(new IllegalArgumentException()); - } else if (voxelshape == voxelshape1) { -diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 032b7acee..6ae9ec627 100644 ---- a/src/main/java/net/minecraft/server/World.java -+++ b/src/main/java/net/minecraft/server/World.java -@@ -88,6 +88,8 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - public final com.destroystokyo.paper.PaperWorldConfig paperConfig; // Paper - public final ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray - -+ public final com.tuinity.tuinity.config.TuinityConfig.WorldConfig tuinityConfig; // Tuinity - Server Config -+ - public final co.aikar.timings.WorldTimingsHandler timings; // Paper - public static BlockPosition lastPhysicsProblem; // Spigot - private org.spigotmc.TickLimiter entityLimiter; -@@ -137,6 +139,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - this.spigotConfig = new org.spigotmc.SpigotWorldConfig( worlddata.getName() ); // Spigot - this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig(worlddata.getName(), this.spigotConfig); // Paper - this.chunkPacketBlockController = this.paperConfig.antiXray ? new ChunkPacketBlockControllerAntiXray(this.paperConfig, executor) : ChunkPacketBlockController.NO_OPERATION_INSTANCE; // Paper - Anti-Xray -+ this.tuinityConfig = new com.tuinity.tuinity.config.TuinityConfig.WorldConfig(worlddata.getName()); // Tuinity - Server Config - this.generator = gen; - if (dimensionmanager.world == null) dimensionmanager.world = (WorldServer) this; // Paper - this.world = new CraftWorld((WorldServer) this, gen, env); -@@ -338,8 +341,28 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - } - } - -+ // Tuinity start -+ // Does not affect TE. This simply just a raw set type - runs no logic. -+ final void setTypeAndDataRaw(final BlockPosition pos, final IBlockData blockData, final TileEntity tileEntity) { -+ this.getChunkAt(pos.getX() >> 4, pos.getZ() >> 4).setTypeAndDataRaw(pos, blockData); -+ if (tileEntity == null) { -+ this.removeTileEntity(pos); -+ } else { -+ this.setTileEntity(pos, tileEntity); -+ } -+ ((WorldServer)this).getChunkProvider().flagDirty(pos); -+ } -+ // Tuinity end -+ - @Override - public boolean setTypeAndData(BlockPosition blockposition, IBlockData iblockdata, int i) { -+ // Tuinity start - add tileEntity parameter -+ return this.setTypeAndData(blockposition, iblockdata, i, null); -+ } -+ // Up to the caller to handle previous tile state. -+ public boolean setTypeAndData(BlockPosition blockposition, IBlockData iblockdata, int i, TileEntity tileEntity) { -+ // Tuinity end - add tileEntity parameter -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Async set type call"); // Tuinity - // CraftBukkit start - tree generation - if (this.captureTreeGeneration) { - // Paper start -@@ -372,7 +395,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - } - // CraftBukkit end - -- IBlockData iblockdata1 = chunk.setType(blockposition, iblockdata, (i & 64) != 0, (i & 1024) == 0); // CraftBukkit custom NO_PLACE flag -+ IBlockData iblockdata1 = chunk.setType(blockposition, iblockdata, (i & 64) != 0, (i & 1024) == 0, tileEntity); // CraftBukkit custom NO_PLACE flag // Tuinity - add tileEntity parameter - this.chunkPacketBlockController.onBlockChange(this, blockposition, iblockdata, iblockdata1, i); // Paper - Anti-Xray - - if (iblockdata1 == null) { -@@ -440,6 +463,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - - // CraftBukkit start - Split off from above in order to directly send client and physic updates - public void notifyAndUpdatePhysics(BlockPosition blockposition, Chunk chunk, IBlockData oldBlock, IBlockData newBlock, IBlockData actualBlock, int i) { -+ com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Async notify and update"); // Tuinity - IBlockData iblockdata = newBlock; - IBlockData iblockdata1 = oldBlock; - IBlockData iblockdata2 = actualBlock; -@@ -888,6 +912,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - return; - // Paper end - } -+ MinecraftServer.getServer().executeMidTickTasks(); // Tuinity - execute chunk tasks mid tick - } - - // Paper start - Prevent armor stands from doing entity lookups -@@ -1108,7 +1133,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - while (iterator.hasNext()) { - TileEntity tileentity1 = (TileEntity) iterator.next(); - -- if (tileentity1.getPosition().equals(blockposition)) { -+ if (tileentity != tileentity1 && tileentity1.getPosition().equals(blockposition)) { // Tuinity - don't remove us if we double set... - tileentity1.ab_(); - iterator.remove(); - } -@@ -1193,6 +1218,11 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - public List getHardCollidingEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb) { - // copied from below - List list = Lists.newArrayList(); -+ // Tuinity start - add list parameter -+ return this.getHardCollidingEntities(entity, axisalignedbb, list); -+ } -+ public List getHardCollidingEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb, List list) { -+ // Tuinity end - add list parameter - int i = MathHelper.floor((axisalignedbb.minX - 2.0D) / 16.0D); - int j = MathHelper.floor((axisalignedbb.maxX + 2.0D) / 16.0D); - int k = MathHelper.floor((axisalignedbb.minZ - 2.0D) / 16.0D); -@@ -1216,8 +1246,13 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - - @Override - public List getEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb, @Nullable Predicate predicate) { -- this.getMethodProfiler().c("getEntities"); -+ // Tuinity start - add list parameter - List list = Lists.newArrayList(); -+ return this.getEntities(entity, axisalignedbb, predicate, list); -+ } -+ public List getEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb, @Nullable Predicate predicate, List list) { -+ // Tuinity end - add list parameter -+ this.getMethodProfiler().c("getEntities"); - int i = MathHelper.floor((axisalignedbb.minX - 2.0D) / 16.0D); - int j = MathHelper.floor((axisalignedbb.maxX + 2.0D) / 16.0D); - int k = MathHelper.floor((axisalignedbb.minZ - 2.0D) / 16.0D); -diff --git a/src/main/java/net/minecraft/server/WorldBorder.java b/src/main/java/net/minecraft/server/WorldBorder.java -index 535d08ffb..079a73196 100644 ---- a/src/main/java/net/minecraft/server/WorldBorder.java -+++ b/src/main/java/net/minecraft/server/WorldBorder.java -@@ -45,12 +45,43 @@ public class WorldBorder { - return axisalignedbb.maxX > this.c() && axisalignedbb.minX < this.e() && axisalignedbb.maxZ > this.d() && axisalignedbb.minZ < this.f(); - } - -+ // Tuinity start - optimise collisions -+ // determines whether we are colliding with one of the wordborder faces. -+ public final boolean isCollidingOnBorderEdge(AxisAlignedBB boundingBox) { -+ return this.isCollidingOnBorderEdge(boundingBox.minX, boundingBox.maxX, boundingBox.minZ, boundingBox.maxZ); -+ } -+ -+ public final boolean isCollidingOnBorderEdge(double boxMinX, double boxMaxX, double boxMinZ, double boxMaxZ) { -+ double minX = this.getMinX() - 1.0E-7; -+ double maxX = this.getMaxX() + 1.0E-7; -+ -+ double minZ = this.getMinZ() - 1.0E-7; -+ double maxZ = this.getMaxZ() + 1.0E-7; -+ -+ return -+ // First, check if the worldborder is enclosing the specified box. -+ // We check this first as it's most likely to fail. -+ !(minX < boxMinX && maxX > boxMaxX && minZ < boxMinZ && maxZ > boxMaxZ) -+ && -+ -+ // Now we verify if we're even intersecting. -+ (minX < boxMaxX && maxX > boxMinX && minZ < boxMaxZ && maxZ > boxMinZ) -+ && -+ -+ // Now verify that the worldborder isn't being enclosed. -+ // This is never expected to happen, but is left here to ensure our logic -+ // is right 100% of the time. -+ !(boxMinX < minX && boxMaxX > maxX && boxMinZ < minZ && boxMaxZ > maxZ) -+ ; -+ } -+ // Tuinity end - optimise collisions -+ - public double a(Entity entity) { - return this.b(entity.locX(), entity.locZ()); - } - - public final VoxelShape asVoxelShape(){ return a();} // Paper - OBFHELPER -- -+ public final VoxelShape getCollisionShape() { return this.a(); } // Tuinity - OBFHELPER - public VoxelShape a() { - return this.i.m(); - } -@@ -66,18 +97,22 @@ public class WorldBorder { - return Math.min(d6, d3); - } - -+ public final double getMinX() { return this.c(); } // Tuinity - OBFHELPER - public double c() { - return this.i.a(); - } - -+ public final double getMinZ() { return this.d(); } // Tuinity - OBFHELPER - public double d() { - return this.i.c(); - } - -+ public final double getMaxX() { return this.e(); } // Tuinity - OBFHELPER - public double e() { - return this.i.b(); - } - -+ public final double getMaxZ() { return this.f(); } // Tuinity - OBFHELPER - public double f() { - return this.i.d(); - } -diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 46e261b65..24cd10c96 100644 ---- a/src/main/java/net/minecraft/server/WorldServer.java -+++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -55,7 +55,7 @@ public class WorldServer extends World { - - private static final Logger LOGGER = LogManager.getLogger(); - private final List globalEntityList = Lists.newArrayList(); -- public final Int2ObjectMap entitiesById = new Int2ObjectLinkedOpenHashMap(); -+ public final Int2ObjectMap entitiesById = new Int2ObjectLinkedOpenHashMap(); final com.tuinity.tuinity.util.maplist.IteratorSafeOrderedReferenceSet entitiesForIteration = new com.tuinity.tuinity.util.maplist.IteratorSafeOrderedReferenceSet<>(2048, 0.5f, 2048, 0.2); // Tuinity - make removing entities while ticking safe - private final Map entitiesByUUID = Maps.newHashMap(); - private final Queue entitiesToAdd = Queues.newArrayDeque(); - public final List players = Lists.newArrayList(); // Paper - private -> public -@@ -79,7 +79,7 @@ public class WorldServer extends World { - private final PortalTravelAgent portalTravelAgent; - private final TickListServer nextTickListBlock; - private final TickListServer nextTickListFluid; -- private final Set navigators; -+ private final Set navigators; final com.tuinity.tuinity.util.maplist.IteratorSafeOrderedReferenceSet navigatorsForIteration = new com.tuinity.tuinity.util.maplist.IteratorSafeOrderedReferenceSet<>(2048, 0.5f, 2048, 0.2); // Tuinity - make removing entities while ticking safe - protected final PersistentRaid persistentRaid; - private final ObjectLinkedOpenHashSet I; - private boolean ticking; -@@ -190,6 +190,100 @@ public class WorldServer extends World { - } - // Paper end - rewrite ticklistserver - -+ // Tuinity start -+ public final boolean areChunksLoadedForMove(AxisAlignedBB axisalignedbb) { -+ // copied code from collision methods, so that we can guarantee that they wont load chunks (we don't override -+ // ICollisionAccess methods for VoxelShapes) -+ // be more strict too, add a block (dumb plugins in move events?) -+ int minBlockX = MathHelper.floor(axisalignedbb.minX - 1.0E-7D) - 3; -+ int maxBlockX = MathHelper.floor(axisalignedbb.maxX + 1.0E-7D) + 3; -+ -+ int minBlockZ = MathHelper.floor(axisalignedbb.minZ - 1.0E-7D) - 3; -+ int maxBlockZ = MathHelper.floor(axisalignedbb.maxZ + 1.0E-7D) + 3; -+ -+ int minChunkX = minBlockX >> 4; -+ int maxChunkX = maxBlockX >> 4; -+ -+ int minChunkZ = minBlockZ >> 4; -+ int maxChunkZ = maxBlockZ >> 4; -+ -+ ChunkProviderServer chunkProvider = this.getChunkProvider(); -+ -+ for (int cx = minChunkX; cx <= maxChunkX; ++cx) { -+ for (int cz = minChunkZ; cz <= maxChunkZ; ++cz) { -+ if (chunkProvider.getChunkAtIfLoadedImmediately(cx, cz) == null) { -+ return false; -+ } -+ } -+ } -+ -+ return true; -+ } -+ -+ public final void loadChunksForMoveAsync(AxisAlignedBB axisalignedbb, double toX, double toZ, -+ java.util.function.Consumer> onLoad) { -+ if (Thread.currentThread() != this.serverThread) { -+ this.getChunkProvider().serverThreadQueue.execute(() -> { -+ this.loadChunksForMoveAsync(axisalignedbb, toX, toZ, onLoad); -+ }); -+ return; -+ } -+ List ret = new java.util.ArrayList<>(); -+ it.unimi.dsi.fastutil.ints.IntArrayList ticketLevels = new it.unimi.dsi.fastutil.ints.IntArrayList(); -+ -+ int minBlockX = MathHelper.floor(axisalignedbb.minX - 1.0E-7D) - 3; -+ int maxBlockX = MathHelper.floor(axisalignedbb.maxX + 1.0E-7D) + 3; -+ -+ int minBlockZ = MathHelper.floor(axisalignedbb.minZ - 1.0E-7D) - 3; -+ int maxBlockZ = MathHelper.floor(axisalignedbb.maxZ + 1.0E-7D) + 3; -+ -+ int minChunkX = minBlockX >> 4; -+ int maxChunkX = maxBlockX >> 4; -+ -+ int minChunkZ = minBlockZ >> 4; -+ int maxChunkZ = maxBlockZ >> 4; -+ -+ ChunkProviderServer chunkProvider = this.getChunkProvider(); -+ -+ int requiredChunks = (maxChunkX - minChunkX + 1) * (maxChunkZ - minChunkZ + 1); -+ int[] loadedChunks = new int[1]; -+ -+ Long holderIdentifier = Long.valueOf(chunkProvider.chunkFutureAwaitCounter++); -+ -+ java.util.function.Consumer consumer = (IChunkAccess chunk) -> { -+ if (chunk != null) { -+ int ticketLevel = Math.max(33, chunkProvider.playerChunkMap.getUpdatingChunk(chunk.getPos().pair()).getTicketLevel()); -+ ret.add(chunk); -+ ticketLevels.add(ticketLevel); -+ chunkProvider.addTicketAtLevel(TicketType.FUTURE_AWAIT, chunk.getPos(), ticketLevel, holderIdentifier); -+ } -+ if (++loadedChunks[0] == requiredChunks) { -+ try { -+ onLoad.accept(java.util.Collections.unmodifiableList(ret)); -+ } finally { -+ for (int i = 0, len = ret.size(); i < len; ++i) { -+ ChunkCoordIntPair chunkPos = ret.get(i).getPos(); -+ int ticketLevel = ticketLevels.getInt(i); -+ -+ chunkProvider.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, ticketLevel, chunkPos); -+ chunkProvider.removeTicketAtLevel(TicketType.FUTURE_AWAIT, chunkPos, ticketLevel, holderIdentifier); -+ } -+ } -+ } -+ }; -+ -+ for (int cx = minChunkX; cx <= maxChunkX; ++cx) { -+ for (int cz = minChunkZ; cz <= maxChunkZ; ++cz) { -+ chunkProvider.getChunkAtAsynchronously(cx, cz, ChunkStatus.FULL, true, false, consumer); -+ } -+ } -+ } -+ // Tuinity end -+ -+ // Tuinity start - execute chunk tasks mid tick -+ long lastMidTickExecuteFailure; -+ // Tuinity end - execute chunk tasks mid tick -+ - // Add env and gen to constructor - public WorldServer(MinecraftServer minecraftserver, Executor executor, WorldNBTStorage worldnbtstorage, WorldData worlddata, DimensionManager dimensionmanager, GameProfilerFiller gameprofilerfiller, WorldLoadListener worldloadlistener, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) { - super(worlddata, dimensionmanager, executor, (world, worldprovider) -> { // Paper - pass executor down -@@ -249,6 +343,349 @@ public class WorldServer extends World { - this.asyncChunkTaskManager = new com.destroystokyo.paper.io.chunk.ChunkTaskManager(this); // Paper - } - -+ // Tuinity start - optimise collision -+ public boolean collidesWithAnyBlockOrWorldBorder(@Nullable Entity entity, AxisAlignedBB axisalignedbb, boolean loadChunks) { -+ if (entity != null) { -+ if (this.getWorldBorder().isCollidingOnBorderEdge(axisalignedbb)) { -+ return true; -+ } -+ } -+ -+ int minBlockX = MathHelper.floor(axisalignedbb.minX - 1.0E-7D) - 1; -+ int maxBlockX = MathHelper.floor(axisalignedbb.maxX + 1.0E-7D) + 1; -+ -+ int minBlockY = MathHelper.floor(axisalignedbb.minY - 1.0E-7D) - 1; -+ int maxBlockY = MathHelper.floor(axisalignedbb.maxY + 1.0E-7D) + 1; -+ -+ int minBlockZ = MathHelper.floor(axisalignedbb.minZ - 1.0E-7D) - 1; -+ int maxBlockZ = MathHelper.floor(axisalignedbb.maxZ + 1.0E-7D) + 1; -+ -+ -+ BlockPosition.MutableBlockPosition mutablePos = new BlockPosition.MutableBlockPosition(); -+ VoxelShapeCollision collisionShape = entity == null ? VoxelShapeCollision.a() : VoxelShapeCollision.a(entity); // TODO make this lazy -+ -+ // special cases: -+ if (minBlockY > 255 || maxBlockY < 0) { -+ // no point in checking -+ return false; -+ } -+ -+ int minYIterate = Math.max(0, minBlockY); -+ int maxYIterate = Math.min(255, maxBlockY); -+ -+ int minChunkX = minBlockX >> 4; -+ int maxChunkX = maxBlockX >> 4; -+ -+ int minChunkZ = minBlockZ >> 4; -+ int maxChunkZ = maxBlockZ >> 4; -+ -+ ChunkProviderServer chunkProvider = (ChunkProviderServer)this.chunkProvider; -+ // TODO special case single chunk? -+ -+ for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) { -+ int minX = currChunkX == minChunkX ? minBlockX & 15 : 0; // coordinate in chunk -+ int maxX = currChunkX == maxChunkX ? maxBlockX & 15 : 15; // coordinate in chunk -+ -+ for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) { -+ int minZ = currChunkZ == minChunkZ ? minBlockZ & 15 : 0; // coordinate in chunk -+ int maxZ = currChunkZ == maxChunkZ ? maxBlockZ & 15 : 15; // coordinate in chunk -+ -+ int chunkXGlobalPos = currChunkX << 4; -+ int chunkZGlobalPos = currChunkZ << 4; -+ Chunk chunk = loadChunks ? chunkProvider.getChunkAt(currChunkX, currChunkZ, true) : chunkProvider.getChunkAtIfLoadedImmediately(currChunkX, currChunkZ); -+ -+ if (chunk == null) { -+ return true; -+ } -+ -+ ChunkSection[] sections = chunk.getSections(); -+ -+ // bound y -+ -+ for (int currY = minYIterate; currY <= maxYIterate; ++currY) { -+ ChunkSection section = sections[currY >>> 4]; -+ if (section == null || section.isFullOfAir()) { -+ // empty -+ // skip to next section -+ currY = (currY & ~(15)) + 15; // increment by 15: iterator loop increments by the extra one -+ continue; -+ } -+ -+ DataPaletteBlock blocks = section.blockIds; -+ int blockKeyY = (currY & 15) << 8; -+ -+ int edgeCountY = (currY == minBlockY || currY == maxBlockY) ? 1 : 0; -+ -+ for (int currX = minX; currX <= maxX; ++currX) { -+ int blockKeyXY = blockKeyY | currX; -+ int blockX = currX | chunkXGlobalPos; // world position -+ -+ int edgeCountXY; -+ if (blockX == minBlockX || blockX == maxBlockX) { -+ edgeCountXY = edgeCountY + 1; -+ } else { -+ edgeCountXY = edgeCountY; -+ } -+ -+ for (int currZ = minZ; currZ <= maxZ; ++currZ) { -+ int blockZ = currZ | chunkZGlobalPos; // world position -+ -+ int edgeCountFull; -+ if (blockZ == minBlockZ || blockZ == maxBlockZ) { -+ edgeCountFull = edgeCountXY + 1; -+ } else { -+ edgeCountFull = edgeCountXY; -+ } -+ -+ if (edgeCountFull == 3) { -+ continue; -+ } -+ -+ int blockKeyFull = blockKeyXY | (currZ << 4); -+ IBlockData blockData = blocks.rawGet(blockKeyFull); -+ -+ if (!blockData.isAir() && (edgeCountFull != 1 || blockData.f()) && (edgeCountFull != 2 || blockData.getBlock() == Blocks.MOVING_PISTON)) { -+ mutablePos.setValues(blockX, currY, blockZ); -+ VoxelShape voxelshape2 = blockData.getCollisionShape(this, mutablePos, collisionShape); -+ if (voxelshape2 != VoxelShapes.getEmptyShape()) { -+ VoxelShape voxelshape3 = voxelshape2.offset((double)blockX, (double)currY, (double)blockZ); -+ -+ if (voxelshape3.intersects(axisalignedbb)) { -+ return true; -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ -+ return false; -+ } -+ -+ public final boolean hardCollidesWithAnyEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb, @Nullable Set set) { -+ if (axisalignedbb.isEmpty()) { -+ return false; -+ } -+ AxisAlignedBB axisalignedbb1 = axisalignedbb.grow(1.0E-7D, 1.0E-7D, 1.0E-7D); -+ List entities = (entity != null && entity.hardCollides()) ? this.getEntities(entity, axisalignedbb) : this.getHardCollidingEntities(entity, axisalignedbb1); -+ -+ for (int i = 0, len = entities.size(); i < len; ++i) { -+ Entity otherEntity = entities.get(i); -+ -+ if (set != null && set.contains(otherEntity)) { -+ continue; -+ } -+ -+ if (entity != null) { -+ if (entity.isSameVehicle(otherEntity)) { -+ continue; -+ } -+ AxisAlignedBB hardCollisionBox = entity.getHardCollisionBoxWith(otherEntity); -+ if (hardCollisionBox != null && axisalignedbb1.intersects(hardCollisionBox)) { -+ return true; -+ } -+ } -+ -+ AxisAlignedBB hardCollisionBox = otherEntity.getHardCollisionBox(); -+ -+ if (hardCollisionBox != null && axisalignedbb1.intersects(hardCollisionBox)) { -+ return true; -+ } -+ } -+ -+ return false; -+ } -+ -+ public final boolean hasAnyCollisions(@Nullable Entity entity, AxisAlignedBB axisalignedbb) { -+ return this.hasAnyCollisions(entity, axisalignedbb, true); -+ } -+ -+ public final boolean hasAnyCollisions(@Nullable Entity entity, AxisAlignedBB axisalignedbb, boolean loadChunks) { -+ return this.collidesWithAnyBlockOrWorldBorder(entity, axisalignedbb, loadChunks) || this.hardCollidesWithAnyEntities(entity, axisalignedbb, null); -+ } -+ -+ // Tuinity start - optimise collision -+ public void getCollisionsForBlocksOrWorldBorder(@Nullable Entity entity, AxisAlignedBB axisalignedbb, List list, boolean loadChunks) { -+ if (entity != null) { -+ if (this.getWorldBorder().isCollidingOnBorderEdge(axisalignedbb)) { -+ VoxelShapes.addBoxesTo(this.getWorldBorder().getCollisionShape(), list); -+ } -+ } -+ -+ int minBlockX = MathHelper.floor(axisalignedbb.minX - 1.0E-7D) - 1; -+ int maxBlockX = MathHelper.floor(axisalignedbb.maxX + 1.0E-7D) + 1; -+ -+ int minBlockY = MathHelper.floor(axisalignedbb.minY - 1.0E-7D) - 1; -+ int maxBlockY = MathHelper.floor(axisalignedbb.maxY + 1.0E-7D) + 1; -+ -+ int minBlockZ = MathHelper.floor(axisalignedbb.minZ - 1.0E-7D) - 1; -+ int maxBlockZ = MathHelper.floor(axisalignedbb.maxZ + 1.0E-7D) + 1; -+ -+ -+ BlockPosition.MutableBlockPosition mutablePos = new BlockPosition.MutableBlockPosition(); -+ VoxelShapeCollision collisionShape = entity == null ? VoxelShapeCollision.a() : VoxelShapeCollision.a(entity); // TODO make this lazy -+ -+ // special cases: -+ if (minBlockY > 255 || maxBlockY < 0) { -+ // no point in checking -+ return; -+ } -+ -+ int minYIterate = Math.max(0, minBlockY); -+ int maxYIterate = Math.min(255, maxBlockY); -+ -+ int minChunkX = minBlockX >> 4; -+ int maxChunkX = maxBlockX >> 4; -+ -+ int minChunkZ = minBlockZ >> 4; -+ int maxChunkZ = maxBlockZ >> 4; -+ -+ ChunkProviderServer chunkProvider = (ChunkProviderServer)this.chunkProvider; -+ // TODO special case single chunk? -+ -+ for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) { -+ int minX = currChunkX == minChunkX ? minBlockX & 15 : 0; // coordinate in chunk -+ int maxX = currChunkX == maxChunkX ? maxBlockX & 15 : 15; // coordinate in chunk -+ -+ for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) { -+ int minZ = currChunkZ == minChunkZ ? minBlockZ & 15 : 0; // coordinate in chunk -+ int maxZ = currChunkZ == maxChunkZ ? maxBlockZ & 15 : 15; // coordinate in chunk -+ -+ int chunkXGlobalPos = currChunkX << 4; -+ int chunkZGlobalPos = currChunkZ << 4; -+ Chunk chunk = loadChunks ? chunkProvider.getChunkAt(currChunkX, currChunkZ, true) : chunkProvider.getChunkAtIfLoadedImmediately(currChunkX, currChunkZ); -+ -+ if (chunk == null) { -+ list.add(AxisAlignedBB.getBoxForChunk(currChunkX, currChunkZ)); -+ continue; -+ } -+ -+ ChunkSection[] sections = chunk.getSections(); -+ -+ // bound y -+ -+ for (int currY = minYIterate; currY <= maxYIterate; ++currY) { -+ ChunkSection section = sections[currY >>> 4]; -+ if (section == null || section.isFullOfAir()) { -+ // empty -+ // skip to next section -+ currY = (currY & ~(15)) + 15; // increment by 15: iterator loop increments by the extra one -+ continue; -+ } -+ -+ DataPaletteBlock blocks = section.blockIds; -+ int blockKeyY = (currY & 15) << 8; -+ -+ int edgeCountY = (currY == minBlockY || currY == maxBlockY) ? 1 : 0; -+ -+ for (int currX = minX; currX <= maxX; ++currX) { -+ int blockKeyXY = blockKeyY | currX; -+ int blockX = currX | chunkXGlobalPos; // world position -+ -+ int edgeCountXY; -+ if (blockX == minBlockX || blockX == maxBlockX) { -+ edgeCountXY = edgeCountY + 1; -+ } else { -+ edgeCountXY = edgeCountY; -+ } -+ -+ for (int currZ = minZ; currZ <= maxZ; ++currZ) { -+ int blockZ = currZ | chunkZGlobalPos; // world position -+ -+ int edgeCountFull; -+ if (blockZ == minBlockZ || blockZ == maxBlockZ) { -+ edgeCountFull = edgeCountXY + 1; -+ } else { -+ edgeCountFull = edgeCountXY; -+ } -+ -+ if (edgeCountFull == 3) { -+ continue; -+ } -+ -+ int blockKeyFull = blockKeyXY | (currZ << 4); -+ IBlockData blockData = blocks.rawGet(blockKeyFull); -+ -+ if (!blockData.isAir() && (edgeCountFull != 1 || blockData.f()) && (edgeCountFull != 2 || blockData.getBlock() == Blocks.MOVING_PISTON)) { -+ mutablePos.setValues(blockX, currY, blockZ); -+ VoxelShape voxelshape2 = blockData.getCollisionShape(this, mutablePos, collisionShape); -+ if (voxelshape2 != VoxelShapes.getEmptyShape()) { -+ VoxelShape voxelshape3 = voxelshape2.offset((double)blockX, (double)currY, (double)blockZ); -+ -+ VoxelShapes.addBoxesToIfIntersects(voxelshape3, axisalignedbb, list); -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ -+ public final void getEntityHardCollisions(@Nullable Entity entity, AxisAlignedBB axisalignedbb, @Nullable Set set, List list) { -+ if (axisalignedbb.isEmpty()) { -+ return; -+ } -+ AxisAlignedBB axisalignedbb1 = axisalignedbb.grow(1.0E-7D, 1.0E-7D, 1.0E-7D); -+ List entities = com.tuinity.tuinity.util.CachedLists.getTempGetEntitiesList(); -+ try { -+ if (entity != null && entity.hardCollides()) { -+ this.getEntities(entity, axisalignedbb, IEntitySelector.notSpectator(), entities); -+ } else { -+ this.getHardCollidingEntities(entity, axisalignedbb1, entities); -+ } -+ -+ for (int i = 0, len = entities.size(); i < len; ++i) { -+ Entity otherEntity = entities.get(i); -+ -+ if (set != null && set.contains(otherEntity)) { -+ continue; -+ } -+ -+ if (entity != null) { -+ if (entity.isSameVehicle(otherEntity)) { -+ continue; -+ } -+ AxisAlignedBB hardCollisionBox = entity.getHardCollisionBoxWith(otherEntity); -+ if (hardCollisionBox != null && axisalignedbb1.intersects(hardCollisionBox)) { -+ list.add(hardCollisionBox); -+ } -+ } -+ -+ AxisAlignedBB hardCollisionBox = otherEntity.getHardCollisionBox(); -+ -+ if (hardCollisionBox != null && axisalignedbb1.intersects(hardCollisionBox)) { -+ list.add(hardCollisionBox); -+ } -+ } -+ } finally { -+ com.tuinity.tuinity.util.CachedLists.returnTempGetEntitiesList(entities); -+ } -+ } -+ -+ public final void getCollisions(@Nullable Entity entity, AxisAlignedBB axisalignedbb, List list, boolean loadChunks) { -+ this.getCollisionsForBlocksOrWorldBorder(entity, axisalignedbb, list, loadChunks); -+ this.getEntityHardCollisions(entity, axisalignedbb, null, list); -+ } -+ -+ @Override -+ public boolean getCubes(Entity entity) { -+ return !this.hasAnyCollisions(entity, entity.getBoundingBox()); -+ } -+ -+ @Override -+ public boolean getCubes(@Nullable Entity entity, AxisAlignedBB axisalignedbb) { -+ return !this.hasAnyCollisions(entity, axisalignedbb); -+ } -+ -+ @Override -+ public boolean getCubes(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set) { -+ return !this.collidesWithAnyBlockOrWorldBorder(entity, axisalignedbb, true) && !this.hardCollidesWithAnyEntities(entity, axisalignedbb, set); -+ } -+ // Tuinity end - optimise collision -+ - // CraftBukkit start - @Override - protected TileEntity getTileEntity(BlockPosition pos, boolean validate) { -@@ -446,7 +883,7 @@ public class WorldServer extends World { - } - timings.scheduledBlocks.stopTiming(); // Spigot - -- this.getMinecraftServer().midTickLoadChunks(); // Paper -+ // Tuinity - replace logic - gameprofilerfiller.exitEnter("raid"); - this.timings.raids.startTiming(); // Paper - timings - this.persistentRaid.a(); -@@ -459,7 +896,7 @@ public class WorldServer extends World { - timings.doSounds.startTiming(); // Spigot - this.ad(); - timings.doSounds.stopTiming(); // Spigot -- this.getMinecraftServer().midTickLoadChunks(); // Paper -+ // Tuinity - replace logic - this.ticking = false; - gameprofilerfiller.exitEnter("entities"); - boolean flag3 = true || !this.players.isEmpty() || !this.getForceLoadedChunks().isEmpty(); // CraftBukkit - this prevents entity cleanup, other issues on servers with no players -@@ -493,14 +930,13 @@ public class WorldServer extends World { - - gameprofilerfiller.exitEnter("regular"); - this.tickingEntities = true; -- ObjectIterator objectiterator = this.entitiesById.int2ObjectEntrySet().iterator(); -+ com.tuinity.tuinity.util.maplist.IteratorSafeOrderedReferenceSet.Iterator objectiterator = this.entitiesForIteration.iterator(); // Tuinity - - org.spigotmc.ActivationRange.activateEntities(this); // Spigot - timings.entityTick.startTiming(); // Spigot - TimingHistory.entityTicks += this.globalEntityList.size(); // Paper - while (objectiterator.hasNext()) { -- Entry entry = (Entry) objectiterator.next(); -- Entity entity1 = (Entity) entry.getValue(); -+ Entity entity1 = (Entity) objectiterator.next(); // Tuinity - Entity entity2 = entity1.getVehicle(); - - /* CraftBukkit start - We prevent spawning in general, so this butchering is not needed -@@ -536,7 +972,7 @@ public class WorldServer extends World { - gameprofilerfiller.enter("remove"); - if (entity1.dead) { - this.removeEntityFromChunk(entity1); -- objectiterator.remove(); -+ this.entitiesById.remove(entity1.getId()); // Tuinity - this.unregisterEntity(entity1); - } - -@@ -544,6 +980,7 @@ public class WorldServer extends World { - } - timings.entityTick.stopTiming(); // Spigot - -+ objectiterator.finishedIterating(); // Tuinity - this.tickingEntities = false; - // Paper start - for (java.lang.Runnable run : this.afterEntityTickingTasks) { -@@ -555,7 +992,7 @@ public class WorldServer extends World { - } - this.afterEntityTickingTasks.clear(); - // Paper end -- this.getMinecraftServer().midTickLoadChunks(); // Paper -+ // Tuinity - replace logic - - try (co.aikar.timings.Timing ignored = this.timings.newEntities.startTiming()) { // Paper - timings - while ((entity = (Entity) this.entitiesToAdd.poll()) != null) { -@@ -566,7 +1003,7 @@ public class WorldServer extends World { - - gameprofilerfiller.exit(); - timings.tickEntities.stopTiming(); // Spigot -- this.getMinecraftServer().midTickLoadChunks(); // Paper -+ // Tuinity - replace logic - this.tickBlockEntities(); - } - -@@ -780,7 +1217,26 @@ public class WorldServer extends World { - - } - -+ // Tuinity start - log detailed entity tick information -+ static final java.util.concurrent.ConcurrentLinkedDeque currentlyTickingEntities = new java.util.concurrent.ConcurrentLinkedDeque<>(); -+ -+ public static List getCurrentlyTickingEntities() { -+ List ret = Lists.newArrayListWithCapacity(4); -+ -+ for (Entity entity : currentlyTickingEntities) { -+ ret.add(entity); -+ } -+ -+ return ret; -+ } -+ // Tuinity end - log detailed entity tick information -+ - public void entityJoinedWorld(Entity entity) { -+ // Tuinity start - log detailed entity tick information -+ com.tuinity.tuinity.util.TickThread.ensureTickThread("Cannot tick an entity off-main"); -+ try { -+ currentlyTickingEntities.push(entity); -+ // Tuinity end - log detailed entity tick information - if (entity instanceof EntityHuman || this.getChunkProvider().a(entity)) { - ++TimingHistory.entityTicks; // Paper - timings - // Spigot start -@@ -825,6 +1281,11 @@ public class WorldServer extends World { - } // Paper - timings - - } -+ // Tuinity start - log detailed entity tick information -+ } finally { -+ currentlyTickingEntities.pop(); -+ } -+ // Tuinity end - log detailed entity tick information - } - - public void a(Entity entity, Entity entity1) { -@@ -1340,7 +1801,7 @@ public class WorldServer extends World { - Entity entity = (Entity) iterator.next(); - - if (!(entity instanceof EntityPlayer)) { -- if (this.tickingEntities) { -+ if (false && this.tickingEntities) { // Tuinity - throw (IllegalStateException) SystemUtils.c(new IllegalStateException("Removing entity while ticking!")); - } - -@@ -1368,6 +1829,7 @@ public class WorldServer extends World { - - public void unregisterEntity(Entity entity) { - org.spigotmc.AsyncCatcher.catchOp("entity unregister"); // Spigot -+ this.entitiesForIteration.remove(entity); // Tuinity - // Paper start - fix entity registration issues - if (entity instanceof EntityComplexPart) { - // Usually this is a no-op for complex parts, and ID's should be removed, but go ahead and remove it anyways -@@ -1434,12 +1896,16 @@ public class WorldServer extends World { - this.getScoreboard().a(entity); - // CraftBukkit start - SPIGOT-5278 - if (entity instanceof EntityDrowned) { -- this.navigators.remove(((EntityDrowned) entity).navigationWater); -- this.navigators.remove(((EntityDrowned) entity).navigationLand); -+ // Tuinity start -+ this.navigators.remove(((EntityDrowned) entity).navigationWater); this.navigatorsForIteration.remove(((EntityDrowned) entity).navigationWater); -+ this.navigators.remove(((EntityDrowned) entity).navigationLand); this.navigatorsForIteration.remove(((EntityDrowned) entity).navigationLand); -+ // Tuinity end - } else - // CraftBukkit end - if (entity instanceof EntityInsentient) { -- this.navigators.remove(((EntityInsentient) entity).getNavigation()); -+ // Tuinity start -+ this.navigators.remove(((EntityInsentient) entity).getNavigation()); this.navigatorsForIteration.remove(((EntityInsentient) entity).getNavigation()); -+ // Tuinity end - } - new com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent(entity.getBukkitEntity()).callEvent(); // Paper - fire while valid - entity.valid = false; // CraftBukkit -@@ -1455,7 +1921,7 @@ public class WorldServer extends World { - return; - } - // Paper end -- if (this.tickingEntities) { -+ if (false && this.tickingEntities) { // Tuinity - if (!entity.isQueuedForRegister) { // Paper - this.entitiesToAdd.add(entity); - entity.isQueuedForRegister = true; // Paper -@@ -1463,6 +1929,7 @@ public class WorldServer extends World { - } else { - entity.isQueuedForRegister = false; // Paper - this.entitiesById.put(entity.getId(), entity); -+ this.entitiesForIteration.add(entity); // Tuinity - if (entity instanceof EntityEnderDragon) { - EntityComplexPart[] aentitycomplexpart = ((EntityEnderDragon) entity).eo(); - int i = aentitycomplexpart.length; -@@ -1471,6 +1938,7 @@ public class WorldServer extends World { - EntityComplexPart entitycomplexpart = aentitycomplexpart[j]; - - this.entitiesById.put(entitycomplexpart.getId(), entitycomplexpart); -+ this.entitiesForIteration.add(entitycomplexpart); // Tuinity - } - } - -@@ -1495,12 +1963,16 @@ public class WorldServer extends World { - // this.getChunkProvider().addEntity(entity); // Paper - moved down below valid=true - // CraftBukkit start - SPIGOT-5278 - if (entity instanceof EntityDrowned) { -- this.navigators.add(((EntityDrowned) entity).navigationWater); -- this.navigators.add(((EntityDrowned) entity).navigationLand); -+ // Tuinity start -+ this.navigators.add(((EntityDrowned) entity).navigationWater); this.navigatorsForIteration.add(((EntityDrowned) entity).navigationWater); -+ this.navigators.add(((EntityDrowned) entity).navigationLand); this.navigatorsForIteration.add(((EntityDrowned) entity).navigationLand); -+ // Tuinity end - } else - // CraftBukkit end - if (entity instanceof EntityInsentient) { -- this.navigators.add(((EntityInsentient) entity).getNavigation()); -+ // Tuinity start -+ this.navigators.add(((EntityInsentient) entity).getNavigation()); this.navigatorsForIteration.add(((EntityInsentient) entity).getNavigation()); -+ // Tuinity end - } - entity.valid = true; // CraftBukkit - this.getChunkProvider().addEntity(entity); // Paper - from above to be below valid=true -@@ -1516,7 +1988,7 @@ public class WorldServer extends World { - } - - public void removeEntity(Entity entity) { -- if (this.tickingEntities) { -+ if (false && this.tickingEntities) { // Tuinity - throw (IllegalStateException) SystemUtils.c(new IllegalStateException("Removing entity while ticking!")); - } else { - this.removeEntityFromChunk(entity); -@@ -1618,7 +2090,9 @@ public class WorldServer extends World { - - if (VoxelShapes.c(voxelshape, voxelshape1, OperatorBoolean.NOT_SAME)) { - boolean wasTicking = this.tickingEntities; this.tickingEntities = true; // Paper -- Iterator iterator = this.navigators.iterator(); -+ // Tuinity start -+ com.tuinity.tuinity.util.maplist.IteratorSafeOrderedReferenceSet.Iterator iterator = this.navigatorsForIteration.iterator(); -+ try { // Tuinity end - - while (iterator.hasNext()) { - NavigationAbstract navigationabstract = (NavigationAbstract) iterator.next(); -@@ -1627,6 +2101,9 @@ public class WorldServer extends World { - navigationabstract.b(blockposition); - } - } -+ } finally { // Tuinity start -+ iterator.finishedIterating(); -+ } // Tuinity end - - this.tickingEntities = wasTicking; // Paper - } -diff --git a/src/main/java/net/minecraft/server/WorldUpgrader.java b/src/main/java/net/minecraft/server/WorldUpgrader.java -index 3030c347e..76f0f258e 100644 ---- a/src/main/java/net/minecraft/server/WorldUpgrader.java -+++ b/src/main/java/net/minecraft/server/WorldUpgrader.java -@@ -220,7 +220,7 @@ public class WorldUpgrader { - int l = Integer.parseInt(matcher.group(2)) << 5; - - try { -- RegionFile regionfile = new RegionFile(file2, file1); -+ RegionFile regionfile = new RegionFile(file2, file1, true); // Tuinity - allow for chunk regionfiles to regen header - Throwable throwable = null; - - try { -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java b/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java -index b909af3d6..3c8166149 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java -@@ -75,7 +75,7 @@ public class CraftChunkSnapshot implements ChunkSnapshot { - public Material getBlockType(int x, int y, int z) { - CraftChunk.validateChunkCoordinates(x, y, z); - -- return CraftMagicNumbers.getMaterial(blockids[y >> 4].a(x, y & 0xF, z).getBlock()); -+ return blockids[y >> 4].a(x, y & 0xF, z).getBukkitMaterial(); // Tuinity - optimise getType calls - } - - @Override -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 568aefdf6..760752eae 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -205,7 +205,7 @@ import javax.annotation.Nullable; // Paper - import javax.annotation.Nonnull; // Paper - - public final class CraftServer implements Server { -- private final String serverName = "Paper"; // Paper -+ private final String serverName = "Tuinity"; // Paper // Tuinity - private final String serverVersion; - private final String bukkitVersion = Versioning.getBukkitVersion(); - private final Logger logger = Logger.getLogger("Minecraft"); -@@ -815,6 +815,7 @@ public final class CraftServer implements Server { - - org.spigotmc.SpigotConfig.init((File) console.options.valueOf("spigot-settings")); // Spigot - com.destroystokyo.paper.PaperConfig.init((File) console.options.valueOf("paper-settings")); // Paper -+ com.tuinity.tuinity.config.TuinityConfig.init((File) console.options.valueOf("tuinity-settings")); // Tuinity - Server Config - for (WorldServer world : console.getWorlds()) { - world.worldData.setDifficulty(config.difficulty); - world.setSpawnFlags(config.spawnMonsters, config.spawnAnimals); -@@ -843,6 +844,7 @@ public final class CraftServer implements Server { - } - world.spigotConfig.init(); // Spigot - world.paperConfig.init(); // Paper -+ world.tuinityConfig.init(); // Tuinity - Server Config - } - - Plugin[] pluginClone = pluginManager.getPlugins().clone(); // Paper -@@ -1747,7 +1749,10 @@ public final class CraftServer implements Server { - - @Override - public boolean isPrimaryThread() { -- return Thread.currentThread().equals(console.serverThread) || Thread.currentThread().equals(net.minecraft.server.MinecraftServer.getServer().shutdownThread); // Paper - Fix issues with detecting main thread properly, the only time Watchdog will be used is during a crash shutdown which is a "try our best" scenario -+ // Tuinity start -+ final Thread currThread = Thread.currentThread(); -+ return currThread == console.serverThread || currThread instanceof com.tuinity.tuinity.util.TickThread || currThread.equals(net.minecraft.server.MinecraftServer.getServer().shutdownThread); // Paper - Fix issues with detecting main thread properly, the only time Watchdog will be used is during a crash shutdown which is a "try our best" scenario -+ // Tuinity End - } - - @Override -@@ -2134,6 +2139,14 @@ public final class CraftServer implements Server { - return com.destroystokyo.paper.PaperConfig.config; - } - -+ // Tuinity start - add config to timings report -+ @Override -+ public YamlConfiguration getTuinityConfig() -+ { -+ return com.tuinity.tuinity.config.TuinityConfig.config; -+ } -+ // Tuinity end - add config to timings report -+ - @Override - public void restart() { - org.spigotmc.RestartCommand.restart(); -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 73ffc3c24..32d4aa0f4 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -333,6 +333,13 @@ public class CraftWorld implements World { - this.generator = gen; - - environment = env; -+ -+ //Tuinity start - per world spawn limits -+ monsterSpawn = world.tuinityConfig.spawnLimitMonsters; -+ animalSpawn = world.tuinityConfig.spawnLimitAnimals; -+ waterAnimalSpawn = world.tuinityConfig.spawnLimitWaterAnimals; -+ ambientSpawn = world.tuinityConfig.spawnLimitAmbient; -+ //Tuinity end - } - - @Override -@@ -399,14 +406,7 @@ public class CraftWorld implements World { - - @Override - public Chunk getChunkAt(int x, int z) { -- // Paper start - add ticket to hold chunk for a little while longer if plugin accesses it -- net.minecraft.server.Chunk chunk = world.getChunkProvider().getChunkAtIfLoadedImmediately(x, z); -- if (chunk == null) { -- addTicket(x, z); -- chunk = this.world.getChunkProvider().getChunkAt(x, z, true); -- } -- return chunk.bukkitChunk; -- // Paper end -+ return this.world.getChunkProvider().getChunkAt(x, z, true).bukkitChunk; // Tuinity - revert paper diff - } - - // Paper start -@@ -489,6 +489,7 @@ public class CraftWorld implements World { - org.spigotmc.AsyncCatcher.catchOp("chunk unload"); // Spigot - if (isChunkLoaded(x, z)) { - world.getChunkProvider().removeTicket(TicketType.PLUGIN, new ChunkCoordIntPair(x, z), 0, Unit.INSTANCE); // Paper -+ ((ChunkMapDistance)world.getChunkProvider().playerChunkMap.getChunkMapDistanceManager()).removeTickets(ChunkCoordIntPair.pair(x, z), TicketType.DELAYED_UNLOAD); // Tuinity - delay chunk unloads - let plugins override - } - - return true; -@@ -2504,7 +2505,7 @@ public class CraftWorld implements World { - } - return this.world.getChunkProvider().getChunkAtAsynchronously(x, z, gen, urgent).thenComposeAsync((either) -> { - net.minecraft.server.Chunk chunk = (net.minecraft.server.Chunk) either.left().orElse(null); -- if (chunk != null) addTicket(x, z); // Paper -+ if (false && chunk != null) addTicket(x, z); // Paper // Tuinity - revert - return CompletableFuture.completedFuture(chunk == null ? null : chunk.getBukkitChunk()); - }, MinecraftServer.getServer()); - } -diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index 2ea6f5b7d..cce21aaf3 100644 ---- a/src/main/java/org/bukkit/craftbukkit/Main.java -+++ b/src/main/java/org/bukkit/craftbukkit/Main.java -@@ -138,6 +138,13 @@ public class Main { - .defaultsTo(new File("paper.yml")) - .describedAs("Yml file"); - // Paper end -+ // Tuinity Start - Server Config -+ acceptsAll(asList("tuinity", "tuinity-settings"), "File for tuinity settings") -+ .withRequiredArg() -+ .ofType(File.class) -+ .defaultsTo(new File("tuinity.yml")) -+ .describedAs("Yml file"); -+ /* Conctete End - Server Config */ - - // Paper start - acceptsAll(asList("server-name"), "Name of the server") -@@ -252,7 +259,7 @@ public class Main { - if (buildDate.before(deadline.getTime())) { - // Paper start - This is some stupid bullshit - System.err.println("*** Warning, you've not updated in a while! ***"); -- System.err.println("*** Please download a new build as per instructions from https://papermc.io/downloads ***"); // Paper -+ System.err.println("*** Please download a new build ***"); // Paper // Tuinity - //System.err.println("*** Server will start in 20 seconds ***"); - //Thread.sleep(TimeUnit.SECONDS.toMillis(20)); - // Paper End -diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -index 382b50d37..0ba3d963c 100644 ---- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -@@ -207,7 +207,7 @@ public class CraftBlock implements Block { - - @Override - public Material getType() { -- return CraftMagicNumbers.getMaterial(world.getType(position).getBlock()); -+ return world.getType(position).getBukkitMaterial(); // Tuinity - optimise getType calls - } - - @Override -@@ -500,15 +500,30 @@ public class CraftBlock implements Block { - return null; - } - -- return Biome.valueOf(IRegistry.BIOME.getKey(base).getKey().toUpperCase(java.util.Locale.ENGLISH)); -+ return base.getBukkitBiome(); // Tuinity - optimise biome conversion - } - -+ private static final java.util.EnumMap BUKKIT_BIOME_TO_NMS_CACHE = new java.util.EnumMap<>(Biome.class); // Tuinity - optimise biome conversion -+ - public static BiomeBase biomeToBiomeBase(Biome bio) { - if (bio == null) { - return null; - } - -- return IRegistry.BIOME.get(new MinecraftKey(bio.name().toLowerCase(java.util.Locale.ENGLISH))); -+ // Tuinity start - optimise biome conversion -+ BiomeBase cached = BUKKIT_BIOME_TO_NMS_CACHE.get(bio); -+ -+ if (cached != null) { -+ return cached; -+ } -+ -+ BiomeBase ret = IRegistry.BIOME.get(new MinecraftKey(bio.name().toLowerCase(java.util.Locale.ENGLISH))); -+ synchronized (BUKKIT_BIOME_TO_NMS_CACHE) { -+ BUKKIT_BIOME_TO_NMS_CACHE.put(bio, ret); -+ } -+ -+ return ret; -+ // Tuinity end - optimise biome conversion - } - - @Override -diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java -index d3017db1b..8eaed6bfd 100644 ---- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java -+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java -@@ -139,7 +139,7 @@ public class CraftBlockState implements BlockState { - - @Override - public Material getType() { -- return CraftMagicNumbers.getMaterial(data.getBlock()); -+ return data.getBukkitMaterial(); // Tuinity - optimise getType calls - } - - public void setFlag(int flag) { -diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java -index a0746a169..adba4a8a2 100644 ---- a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java -+++ b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java -@@ -44,7 +44,7 @@ public class CraftBlockData implements BlockData { - - @Override - public Material getMaterial() { -- return CraftMagicNumbers.getMaterial(state.getBlock()); -+ return state.getBukkitMaterial(); // Tuinity - optimise getType calls - } - - public IBlockData getState() { -diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index d16d3fe58..5a7b714cc 100644 ---- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -519,6 +519,37 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { - return true; - } - -+ // Tuinity start - implement teleportAsync better -+ @Override -+ public java.util.concurrent.CompletableFuture teleportAsync(Location location, TeleportCause cause) { -+ Preconditions.checkArgument(location != null, "location"); -+ location.checkFinite(); -+ Location locationClone = location.clone(); // clone so we don't need to worry about mutations after this call. -+ -+ net.minecraft.server.WorldServer world = ((CraftWorld)locationClone.getWorld()).getHandle(); -+ java.util.concurrent.CompletableFuture ret = new java.util.concurrent.CompletableFuture<>(); -+ -+ world.loadChunksForMoveAsync(getHandle().getBoundingBoxAt(locationClone.getX(), locationClone.getY(), locationClone.getZ()), location.getX(), location.getZ(), (list) -> { -+ net.minecraft.server.ChunkProviderServer chunkProviderServer = world.getChunkProvider(); -+ for (net.minecraft.server.IChunkAccess chunk : list) { -+ chunkProviderServer.addTicketAtLevel(net.minecraft.server.TicketType.POST_TELEPORT, chunk.getPos(), 33, CraftEntity.this.getEntityId()); -+ } -+ net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(() -> { -+ try { -+ ret.complete(CraftEntity.this.teleport(locationClone, cause) ? Boolean.TRUE : Boolean.FALSE); -+ } catch (Throwable throwable) { -+ if (throwable instanceof ThreadDeath) { -+ throw (ThreadDeath)throwable; -+ } -+ ret.completeExceptionally(throwable); -+ } -+ }); -+ }); -+ -+ return ret; -+ } -+ // Tuinity end - implement teleportAsync better -+ - @Override - public boolean teleport(org.bukkit.entity.Entity destination) { - return teleport(destination.getLocation()); -diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CraftChunkData.java b/src/main/java/org/bukkit/craftbukkit/generator/CraftChunkData.java -index bb18740eb..b048ec8ea 100644 ---- a/src/main/java/org/bukkit/craftbukkit/generator/CraftChunkData.java -+++ b/src/main/java/org/bukkit/craftbukkit/generator/CraftChunkData.java -@@ -73,7 +73,7 @@ public final class CraftChunkData implements ChunkGenerator.ChunkData { - - @Override - public Material getType(int x, int y, int z) { -- return CraftMagicNumbers.getMaterial(getTypeId(x, y, z).getBlock()); -+ return getTypeId(x, y, z).getBukkitMaterial(); // Tuinity - optimise getType calls - } - - @Override -diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java -index ca2be3060..2c5701376 100644 ---- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java -+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java -@@ -100,9 +100,18 @@ public final class CraftScoreboardManager implements ScoreboardManager { - - // CraftBukkit method - public void getScoreboardScores(IScoreboardCriteria criteria, String name, Consumer consumer) { -+ // Tuinity start - add timings for scoreboard search -+ // plugins leaking scoreboards will make this very expensive, let server owners debug it easily -+ co.aikar.timings.MinecraftTimings.scoreboardScoreSearch.startTimingIfSync(); -+ try { -+ // Tuinity end - add timings for scoreboard search - for (CraftScoreboard scoreboard : scoreboards) { - Scoreboard board = scoreboard.board; - board.getObjectivesForCriteria(criteria, name, (score) -> consumer.accept(score)); - } -+ } finally { // Tuinity start - add timings for scoreboard search -+ co.aikar.timings.MinecraftTimings.scoreboardScoreSearch.stopTimingIfSync(); -+ } -+ // Tuinity end - add timings for scoreboard search - } - } -diff --git a/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java b/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java -index f72c13bed..50f855b93 100644 ---- a/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java -+++ b/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java -@@ -119,6 +119,32 @@ public class UnsafeList extends AbstractList implements List, RandomAcc - return indexOf(o) >= 0; - } - -+ // Tuinity start -+ protected transient int maxSize; -+ public void setSize(int size) { -+ if (this.maxSize < this.size) { -+ this.maxSize = this.size; -+ } -+ this.size = size; -+ } -+ -+ public void completeReset() { -+ if (this.data != null) { -+ Arrays.fill(this.data, 0, Math.max(this.size, this.maxSize), null); -+ } -+ this.size = 0; -+ this.maxSize = 0; -+ if (this.iterPool != null) { -+ for (Iterator temp : this.iterPool) { -+ if (temp == null) { -+ continue; -+ } -+ ((Itr)temp).valid = false; -+ } -+ } -+ } -+ // Tuinity end -+ - @Override - public void clear() { - // Create new array to reset memory usage to initial capacity -diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java -index 674096cab..001b1e519 100644 ---- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java -+++ b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java -@@ -11,7 +11,7 @@ public final class Versioning { - public static String getBukkitVersion() { - String result = "Unknown-Version"; - -- InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/com.destroystokyo.paper/paper-api/pom.properties"); -+ InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/com.tuinity/tuinity-api/pom.properties"); // Tuinity - Properties properties = new Properties(); - - if (stream != null) { -diff --git a/src/main/java/org/spigotmc/AsyncCatcher.java b/src/main/java/org/spigotmc/AsyncCatcher.java -index 9f7d2ef93..c3ac1a46c 100644 ---- a/src/main/java/org/spigotmc/AsyncCatcher.java -+++ b/src/main/java/org/spigotmc/AsyncCatcher.java -@@ -10,7 +10,7 @@ public class AsyncCatcher - - public static void catchOp(String reason) - { -- if ( enabled && Thread.currentThread() != MinecraftServer.getServer().serverThread ) -+ if ( ( enabled || com.tuinity.tuinity.util.TickThread.STRICT_THREAD_CHECKS ) && !org.bukkit.Bukkit.isPrimaryThread() ) // Tuinity - { - throw new IllegalStateException( "Asynchronous " + reason + "!" ); - } -diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java -index 513c1041c..7c1ef532d 100644 ---- a/src/main/java/org/spigotmc/WatchdogThread.java -+++ b/src/main/java/org/spigotmc/WatchdogThread.java -@@ -61,6 +61,84 @@ public class WatchdogThread extends Thread - } - } - -+ // Tuinity start - log detailed tick information -+ private void dumpTickingInfo() { -+ Logger log = Bukkit.getServer().getLogger(); -+ -+ // ticking entities -+ for (net.minecraft.server.Entity entity : net.minecraft.server.WorldServer.getCurrentlyTickingEntities()) { -+ double posX, posY, posZ; -+ net.minecraft.server.Vec3D mot; -+ double moveStartX, moveStartY, moveStartZ; -+ net.minecraft.server.Vec3D moveVec; -+ synchronized (entity.posLock) { -+ posX = entity.locX(); -+ posY = entity.locY(); -+ posZ = entity.locZ(); -+ mot = entity.getMot(); -+ moveStartX = entity.getMoveStartX(); -+ moveStartY = entity.getMoveStartY(); -+ moveStartZ = entity.getMoveStartZ(); -+ moveVec = entity.getMoveVector(); -+ } -+ -+ String entityType = entity.getMinecraftKey().toString(); -+ java.util.UUID entityUUID = entity.getUniqueID(); -+ net.minecraft.server.World world = entity.getWorld(); -+ -+ log.log(Level.SEVERE, "Ticking entity: " + entityType); -+ log.log(Level.SEVERE, "Position: world: '" + (world == null ? "unknown world?" : world.getWorldData().getName()) + "' at location (" + posX + ", " + posY + ", " + posZ + ")"); -+ log.log(Level.SEVERE, "Velocity: " + (mot == null ? "unknown velocity" : mot.toString()) + " (in blocks per tick)"); -+ if (moveVec != null) { -+ log.log(Level.SEVERE, "Move call information: "); -+ log.log(Level.SEVERE, "Start position: (" + moveStartX + ", " + moveStartY + ", " + moveStartZ + ")"); -+ log.log(Level.SEVERE, "Move vector: " + moveVec.toString()); -+ } -+ log.log(Level.SEVERE, "UUID: " + entityUUID); -+ } -+ -+ // packet processors -+ for (net.minecraft.server.PacketListener packetListener : net.minecraft.server.PlayerConnectionUtils.getCurrentPacketProcessors()) { -+ if (packetListener instanceof net.minecraft.server.PlayerConnection) { -+ net.minecraft.server.EntityPlayer player = ((net.minecraft.server.PlayerConnection)packetListener).player; -+ long totalPackets = net.minecraft.server.PlayerConnectionUtils.getTotalProcessedPackets(); -+ if (player == null) { -+ log.log(Level.SEVERE, "Handling packet for player connection (null player): " + packetListener); -+ log.log(Level.SEVERE, "Total packets processed on the main thread for all players: " + totalPackets); -+ } else { -+ // exclude velocity, this is set client side... Paper will also warn on high velocity set too -+ double posX, posY, posZ; -+ double moveStartX, moveStartY, moveStartZ; -+ net.minecraft.server.Vec3D moveVec; -+ synchronized (player.posLock) { -+ posX = player.locX(); -+ posY = player.locY(); -+ posZ = player.locZ(); -+ moveStartX = player.getMoveStartX(); -+ moveStartY = player.getMoveStartY(); -+ moveStartZ = player.getMoveStartZ(); -+ moveVec = player.getMoveVector(); -+ } -+ -+ java.util.UUID entityUUID = player.getUniqueID(); -+ net.minecraft.server.World world = player.getWorld(); -+ -+ log.log(Level.SEVERE, "Handling packet for player '" + player.getName() + "', UUID: " + entityUUID); -+ log.log(Level.SEVERE, "Position: world: '" + (world == null ? "unknown world?" : world.getWorldData().getName()) + "' at location (" + posX + ", " + posY + ", " + posZ + ")"); -+ if (moveVec != null) { -+ log.log(Level.SEVERE, "Move call information: "); -+ log.log(Level.SEVERE, "Start position: (" + moveStartX + ", " + moveStartY + ", " + moveStartZ + ")"); -+ log.log(Level.SEVERE, "Move vector: " + moveVec.toString()); -+ } -+ log.log(Level.SEVERE, "Total packets processed on the main thread for all players: " + totalPackets); -+ } -+ } else { -+ log.log(Level.SEVERE, "Handling packet for connection: " + packetListener); -+ } -+ } -+ } -+ // Tuinity end - log detailed tick information -+ - @Override - public void run() - { -@@ -117,6 +195,7 @@ public class WatchdogThread extends Thread - log.log( Level.SEVERE, "------------------------------" ); - log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper - ChunkTaskManager.dumpAllChunkLoadInfo(); // Paper -+ this.dumpTickingInfo(); // Tuinity - log detailed tick information - dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( server.serverThread.getId(), Integer.MAX_VALUE ), log ); - log.log( Level.SEVERE, "------------------------------" ); - // --- -2.26.2 - diff --git a/patches/server/0003-Purpur-config-files.patch b/patches/server/0002-Purpur-config-files.patch similarity index 90% rename from patches/server/0003-Purpur-config-files.patch rename to patches/server/0002-Purpur-config-files.patch index 915d65c2a..7d6aabe1d 100644 --- a/patches/server/0003-Purpur-config-files.patch +++ b/patches/server/0002-Purpur-config-files.patch @@ -1,4 +1,4 @@ -From ac0db702eab4e6197bb37c8e84a81b410eae71ba Mon Sep 17 00:00:00 2001 +From 99870e5b09eef243de5335b21a4efbeb4b427322 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Thu, 9 May 2019 18:09:43 -0500 Subject: [PATCH] Purpur config files @@ -42,16 +42,16 @@ index 24641501a..b767dd1d0 100644 metrics.addCustomChart(new Metrics.DrilldownPie("java_version", () -> { Map> map = new HashMap<>(); diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java -index 1f1243ae8..3190c709a 100644 +index 8b2755a3b..df75a9e8a 100644 --- a/src/main/java/net/minecraft/server/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/DedicatedServer.java -@@ -192,6 +192,15 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer +@@ -168,6 +168,15 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer return false; } com.destroystokyo.paper.PaperConfig.registerCommands(); + // Purpur start + try { -+ net.pl3x.purpur.PurpurConfig.init((File) options.valueOf("purpur-settings")); ++ net.pl3x.purpur.PurpurConfig.init((java.io.File) options.valueOf("purpur-settings")); + } catch (Exception e) { + DedicatedServer.LOGGER.error("Unable to load server configuration", e); + return false; @@ -60,12 +60,12 @@ index 1f1243ae8..3190c709a 100644 + // Purpur end com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // load version history now // Paper end - com.tuinity.tuinity.config.TuinityConfig.init((File) options.valueOf("tuinity-settings")); // Tuinity - Server Config + diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 6ae9ec627..bdb12d16f 100644 +index b598c4869..c59282ef3 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -85,6 +85,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { +@@ -91,6 +91,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { public boolean populating; public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot @@ -73,14 +73,14 @@ index 6ae9ec627..bdb12d16f 100644 public final com.destroystokyo.paper.PaperWorldConfig paperConfig; // Paper public final ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray -@@ -138,6 +139,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - protected World(WorldData worlddata, DimensionManager dimensionmanager, java.util.concurrent.Executor executor, BiFunction bifunction, GameProfilerFiller gameprofilerfiller, boolean flag, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env) { // Paper - executor - this.spigotConfig = new org.spigotmc.SpigotWorldConfig( worlddata.getName() ); // Spigot - this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig(worlddata.getName(), this.spigotConfig); // Paper -+ this.purpurConfig = new net.pl3x.purpur.PurpurWorldConfig(worlddata.getName(), this.paperConfig, this.spigotConfig); // Purpur +@@ -120,6 +121,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { + protected World(WorldDataMutable worlddatamutable, ResourceKey resourcekey, ResourceKey resourcekey1, DimensionManager dimensionmanager, Supplier supplier, boolean flag, boolean flag1, long i, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env, java.util.concurrent.Executor executor) { + this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((WorldDataServer) worlddatamutable).getName()); // Spigot + this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig((((WorldDataServer)worlddatamutable).getName()), this.spigotConfig); // Paper ++ this.purpurConfig = new net.pl3x.purpur.PurpurWorldConfig((((WorldDataServer)worlddatamutable).getName()), this.paperConfig, this.spigotConfig); // Purpur this.chunkPacketBlockController = this.paperConfig.antiXray ? new ChunkPacketBlockControllerAntiXray(this.paperConfig, executor) : ChunkPacketBlockController.NO_OPERATION_INSTANCE; // Paper - Anti-Xray - this.tuinityConfig = new com.tuinity.tuinity.config.TuinityConfig.WorldConfig(worlddata.getName()); // Tuinity - Server Config this.generator = gen; + this.world = new CraftWorld((WorldServer) this, gen, env); diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java new file mode 100644 index 000000000..333c880bf @@ -364,26 +364,26 @@ index 000000000..7d983d9a5 + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 2a6fd01d6..e3a012800 100644 +index 1026fd81b..6c602ef79 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -816,6 +816,7 @@ public final class CraftServer implements Server { +@@ -846,6 +846,7 @@ public final class CraftServer implements Server { + org.spigotmc.SpigotConfig.init((File) console.options.valueOf("spigot-settings")); // Spigot com.destroystokyo.paper.PaperConfig.init((File) console.options.valueOf("paper-settings")); // Paper - com.tuinity.tuinity.config.TuinityConfig.init((File) console.options.valueOf("tuinity-settings")); // Tuinity - Server Config + net.pl3x.purpur.PurpurConfig.init((File) console.options.valueOf("purpur-settings")); // Purpur for (WorldServer world : console.getWorlds()) { - world.worldData.setDifficulty(config.difficulty); + world.worldDataServer.setDifficulty(config.difficulty); world.setSpawnFlags(config.spawnMonsters, config.spawnAnimals); -@@ -845,6 +846,7 @@ public final class CraftServer implements Server { +@@ -880,6 +881,7 @@ public final class CraftServer implements Server { + } world.spigotConfig.init(); // Spigot world.paperConfig.init(); // Paper - world.tuinityConfig.init(); // Tuinity - Server Config + world.purpurConfig.init(); // Purpur } Plugin[] pluginClone = pluginManager.getPlugins().clone(); // Paper -@@ -863,6 +865,7 @@ public final class CraftServer implements Server { +@@ -898,6 +900,7 @@ public final class CraftServer implements Server { reloadData(); org.spigotmc.SpigotConfig.registerCommands(); // Spigot com.destroystokyo.paper.PaperConfig.registerCommands(); // Paper @@ -391,9 +391,9 @@ index 2a6fd01d6..e3a012800 100644 overrideAllCommandBlockCommands = commandsConfiguration.getStringList("command-block-overrides").contains("*"); ignoreVanillaPermissions = commandsConfiguration.getBoolean("ignore-vanilla-permissions"); -@@ -2147,6 +2150,18 @@ public final class CraftServer implements Server { +@@ -2204,6 +2207,18 @@ public final class CraftServer implements Server { + return com.destroystokyo.paper.PaperConfig.config; } - // Tuinity end - add config to timings report + // Purpur start + @Override @@ -411,12 +411,12 @@ index 2a6fd01d6..e3a012800 100644 public void restart() { org.spigotmc.RestartCommand.restart(); diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index 90a2f8fea..8d436d275 100644 +index 83151f3d7..8879c6421 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java -@@ -146,6 +146,14 @@ public class Main { +@@ -139,6 +139,14 @@ public class Main { .describedAs("Yml file"); - /* Conctete End - Server Config */ + // Paper end + // Purpur Start + acceptsAll(asList("purpur", "purpur-settings"), "File for purpur settings") diff --git a/patches/server/0004-Timings-stuff.patch b/patches/server/0003-Timings-stuff.patch similarity index 74% rename from patches/server/0004-Timings-stuff.patch rename to patches/server/0003-Timings-stuff.patch index 3a093b7f4..63da3fc9b 100644 --- a/patches/server/0004-Timings-stuff.patch +++ b/patches/server/0003-Timings-stuff.patch @@ -1,36 +1,34 @@ -From 8f0c3e0dbe590e8d7fd6e810a1a69e7c3959ce6c Mon Sep 17 00:00:00 2001 +From 89bd8621126f5990f782a9709221523940f229df Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Fri, 5 Jun 2020 21:30:19 -0500 Subject: [PATCH] Timings stuff --- - .../java/co/aikar/timings/TimingsExport.java | 27 +++++++++++++++---- - 1 file changed, 22 insertions(+), 5 deletions(-) + .../java/co/aikar/timings/TimingsExport.java | 25 ++++++++++++++++--- + 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java -index b09981e9b..3342201b3 100644 +index e33e889c2..29174d903 100644 --- a/src/main/java/co/aikar/timings/TimingsExport.java +++ b/src/main/java/co/aikar/timings/TimingsExport.java -@@ -227,10 +227,14 @@ public class TimingsExport extends Thread { +@@ -227,9 +227,13 @@ public class TimingsExport extends Thread { // Information on the users Config parent.put("config", createObject( - pair("spigot", mapAsJSON(Bukkit.spigot().getSpigotConfig(), null)), - pair("bukkit", mapAsJSON(Bukkit.spigot().getBukkitConfig(), null)), -- pair("paper", mapAsJSON(Bukkit.spigot().getPaperConfig(), null)), // Tuinity - add config to timings report -- pair("tuinity", mapAsJSON(Bukkit.spigot().getTuinityConfig(), null)) // Tuinity - add config to timings report +- pair("paper", mapAsJSON(Bukkit.spigot().getPaperConfig(), null)) + // Purpur start + pair("server.properties", mapAsJSON(Bukkit.spigot().getServerProperties())), + pair("bukkit", mapAsJSON(Bukkit.spigot().getBukkitConfig(), null)), + pair("spigot", mapAsJSON(Bukkit.spigot().getSpigotConfig(), null)), + pair("paper", mapAsJSON(Bukkit.spigot().getPaperConfig(), null)), -+ pair("tuinity", mapAsJSON(Bukkit.spigot().getTuinityConfig(), null)), + pair("purpur", mapAsJSON(Bukkit.spigot().getPurpurConfig(), null)) + // Purpur end )); new TimingsExport(listeners, parent, history).start(); -@@ -271,6 +275,19 @@ public class TimingsExport extends Thread { +@@ -270,6 +274,19 @@ public class TimingsExport extends Thread { return timingsCost; } @@ -50,12 +48,12 @@ index b09981e9b..3342201b3 100644 private static JSONObject mapAsJSON(ConfigurationSection config, String parentKey) { JSONObject object = new JSONObject(); -@@ -307,7 +324,7 @@ public class TimingsExport extends Thread { +@@ -306,7 +323,7 @@ public class TimingsExport extends Thread { String response = null; String timingsURL = null; try { - HttpURLConnection con = (HttpURLConnection) new URL("http://timings.aikar.co/post").openConnection(); -+ HttpURLConnection con = (HttpURLConnection) new URL(Bukkit.spigot().getPurpurConfig().getString("settings.timings.url", "https://timings.pl3x.net") + "/post").openConnection(); // Purpur ++ HttpURLConnection con = (HttpURLConnection) new URL(net.pl3x.purpur.PurpurConfig.timingsUrl + "/post").openConnection(); // Purpur con.setDoOutput(true); String hostName = "BrokenHost"; try { diff --git a/patches/server/0067-Enderchest-6-rows-plus-permissions.patch b/patches/server/0004-Barrels-and-enderchests-6-rows.patch similarity index 62% rename from patches/server/0067-Enderchest-6-rows-plus-permissions.patch rename to patches/server/0004-Barrels-and-enderchests-6-rows.patch index 2d3825f59..528ad77a4 100644 --- a/patches/server/0067-Enderchest-6-rows-plus-permissions.patch +++ b/patches/server/0004-Barrels-and-enderchests-6-rows.patch @@ -1,19 +1,19 @@ -From a45c6a3ab3401040e7ab6a00de1f3c847e183dc6 Mon Sep 17 00:00:00 2001 +From 6946e2a10fd1cb63084783c07c277936405d9b65 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath -Date: Sun, 23 Jun 2019 17:01:26 -0500 -Subject: [PATCH] Enderchest 6 rows (plus permissions) +Date: Thu, 23 May 2019 21:50:37 -0500 +Subject: [PATCH] Barrels and enderchests 6 rows --- - .../net/minecraft/server/BlockEnderChest.java | 21 +++++++++++++++++++ + .../net/minecraft/server/BlockEnderChest.java | 21 ++++++++++++++++ .../minecraft/server/InventoryEnderChest.java | 2 +- - .../java/net/pl3x/purpur/PurpurConfig.java | 8 +++++++ - .../craftbukkit/inventory/CraftContainer.java | 2 +- + .../minecraft/server/TileEntityBarrel.java | 5 ++-- + .../java/net/pl3x/purpur/PurpurConfig.java | 25 +++++++++++++++++++ + .../craftbukkit/inventory/CraftContainer.java | 4 ++- .../craftbukkit/inventory/CraftInventory.java | 2 +- - .../permissions/CraftDefaultPermissions.java | 8 +++++++ - 6 files changed, 40 insertions(+), 3 deletions(-) + 6 files changed, 54 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/minecraft/server/BlockEnderChest.java b/src/main/java/net/minecraft/server/BlockEnderChest.java -index 0a892a5f1..e7ef571dc 100644 +index af2819bb8..73ab299a4 100644 --- a/src/main/java/net/minecraft/server/BlockEnderChest.java +++ b/src/main/java/net/minecraft/server/BlockEnderChest.java @@ -48,6 +48,27 @@ public class BlockEnderChest extends BlockChestAbstract im @@ -45,7 +45,7 @@ index 0a892a5f1..e7ef571dc 100644 }, BlockEnderChest.e)); entityhuman.a(StatisticList.OPEN_ENDERCHEST); diff --git a/src/main/java/net/minecraft/server/InventoryEnderChest.java b/src/main/java/net/minecraft/server/InventoryEnderChest.java -index fd31b9a6d..903c02e9e 100644 +index bf8c5436b..d147377e5 100644 --- a/src/main/java/net/minecraft/server/InventoryEnderChest.java +++ b/src/main/java/net/minecraft/server/InventoryEnderChest.java @@ -20,7 +20,7 @@ public class InventoryEnderChest extends InventorySubcontainer { @@ -57,48 +57,95 @@ index fd31b9a6d..903c02e9e 100644 this.owner = owner; // CraftBukkit end } +diff --git a/src/main/java/net/minecraft/server/TileEntityBarrel.java b/src/main/java/net/minecraft/server/TileEntityBarrel.java +index 195abfdff..7e368a2ed 100644 +--- a/src/main/java/net/minecraft/server/TileEntityBarrel.java ++++ b/src/main/java/net/minecraft/server/TileEntityBarrel.java +@@ -54,7 +54,7 @@ public class TileEntityBarrel extends TileEntityLootable { + + private TileEntityBarrel(TileEntityTypes tileentitytypes) { + super(tileentitytypes); +- this.items = NonNullList.a(27, ItemStack.b); ++ this.items = NonNullList.a(net.pl3x.purpur.PurpurConfig.barrelSixRows ? 54 : 27, ItemStack.b); // Purpur + } + + public TileEntityBarrel() { +@@ -83,7 +83,7 @@ public class TileEntityBarrel extends TileEntityLootable { + + @Override + public int getSize() { +- return 27; ++ return net.pl3x.purpur.PurpurConfig.barrelSixRows ? 54 : 27; // Purpur + } + + @Override +@@ -103,6 +103,7 @@ public class TileEntityBarrel extends TileEntityLootable { + + @Override + protected Container createContainer(int i, PlayerInventory playerinventory) { ++ if (net.pl3x.purpur.PurpurConfig.barrelSixRows) return new ContainerChest(Containers.GENERIC_9X6, i, playerinventory, this, 6); // Purpur + return ContainerChest.a(i, playerinventory, this); + } + diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java -index 581e8eebe..c3ecd6fc7 100644 +index 333c880bf..fc38163b1 100644 --- a/src/main/java/net/pl3x/purpur/PurpurConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java -@@ -157,14 +157,22 @@ public class PurpurConfig { +@@ -7,6 +7,7 @@ import org.bukkit.Bukkit; + import org.bukkit.command.Command; + import org.bukkit.configuration.InvalidConfigurationException; + import org.bukkit.configuration.file.YamlConfiguration; ++import org.bukkit.event.inventory.InventoryType; - public static boolean barrelSixRows = false; - public static boolean slimeBlocksNotPushable = false; + import java.io.File; + import java.io.IOException; +@@ -127,4 +128,28 @@ public class PurpurConfig { + config.addDefault(path, def); + return config.getString(path, config.getString(path)); + } ++ ++ public static String timingsUrl = "https://timings.pl3x.net"; ++ private static void timingsSettings() { ++ timingsUrl = getString("settings.timings.url", timingsUrl); ++ } ++ ++ public static boolean barrelSixRows = false; + public static boolean enderChestSixRows = false; + public static boolean enderChestPermissionRows = false; - private static void blockSettings() { - if (version < 3) { - boolean oldValue = getBoolean("settings.barrel.packed-barrels", true); - set("settings.blocks.barrel.six-rows", oldValue); - set("settings.packed-barrels", null); ++ private static void blockSettings() { ++ if (version < 3) { ++ boolean oldValue = getBoolean("settings.barrel.packed-barrels", true); ++ set("settings.blocks.barrel.six-rows", oldValue); ++ set("settings.packed-barrels", null); + oldValue = getBoolean("settings.large-ender-chests", true); + set("settings.blocks.ender_chest.six-rows", oldValue); + set("settings.large-ender-chests", null); - } - barrelSixRows = getBoolean("settings.blocks.barrel.six-rows", barrelSixRows); - InventoryType.BARREL.setDefaultSize(barrelSixRows ? 54 : 27); ++ } ++ barrelSixRows = getBoolean("settings.blocks.barrel.six-rows", barrelSixRows); ++ InventoryType.BARREL.setDefaultSize(barrelSixRows ? 54 : 27); + enderChestSixRows = getBoolean("settings.blocks.ender_chest.six-rows", enderChestSixRows); + InventoryType.ENDER_CHEST.setDefaultSize(enderChestSixRows ? 54 : 27); + enderChestPermissionRows = getBoolean("settings.blocks.ender_chest.use-permissions-for-rows", enderChestPermissionRows); - slimeBlocksNotPushable = getBoolean("settings.blocks.slime.not-movable-by-piston", slimeBlocksNotPushable); - } - ++ } + } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java -index d295821c5..610cbbe85 100644 +index 8c714c743..cae362bae 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java -@@ -195,7 +195,7 @@ public class CraftContainer extends Container { +@@ -198,8 +198,10 @@ public class CraftContainer extends Container { case PLAYER: case CHEST: case ENDER_CHEST: -- delegate = new ContainerChest(Containers.GENERIC_9X3, windowId, bottom, top, top.getSize() / 9); // Purpur + delegate = new ContainerChest(net.pl3x.purpur.PurpurConfig.enderChestSixRows ? Containers.GENERIC_9X6 : Containers.GENERIC_9X3, windowId, bottom, top, top.getSize() / 9); // Purpur - break; // Purpur ++ break; // Purpur case BARREL: - delegate = new ContainerChest(net.pl3x.purpur.PurpurConfig.barrelSixRows ? Containers.GENERIC_9X6 : Containers.GENERIC_9X3, windowId, bottom, top, top.getSize() / 9); // Purpur +- delegate = new ContainerChest(Containers.GENERIC_9X3, windowId, bottom, top, top.getSize() / 9); ++ delegate = new ContainerChest(net.pl3x.purpur.PurpurConfig.barrelSixRows ? Containers.GENERIC_9X6 : Containers.GENERIC_9X3, windowId, bottom, top, top.getSize() / 9); // Purpur + break; + case DISPENSER: + case DROPPER: diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java -index 57858327a..d57ad13f7 100644 +index 726631348..a45100034 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java @@ -81,7 +81,7 @@ public class CraftInventory implements Inventory { @@ -110,25 +157,6 @@ index 57858327a..d57ad13f7 100644 throw new IllegalArgumentException("Invalid inventory size; expected " + getSize() + " or less"); } -diff --git a/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java b/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java -index a4a809f30..e7d19d67c 100644 ---- a/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java -+++ b/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java -@@ -18,6 +18,14 @@ public final class CraftDefaultPermissions { - DefaultPermissions.registerPermission(ROOT + ".debugstick.always", "Gives the user the ability to use the debug stick in all game modes", org.bukkit.permissions.PermissionDefault.FALSE, parent); - DefaultPermissions.registerPermission(ROOT + ".commandblock", "Gives the user the ability to use command blocks.", org.bukkit.permissions.PermissionDefault.OP, parent); // Paper - // Spigot end -+ // Purpur start -+ DefaultPermissions.registerPermission("purpur.enderchest.rows.six", "Gives the user six rows of enderchest space", org.bukkit.permissions.PermissionDefault.FALSE); -+ DefaultPermissions.registerPermission("purpur.enderchest.rows.five", "Gives the user five rows of enderchest space", org.bukkit.permissions.PermissionDefault.FALSE); -+ DefaultPermissions.registerPermission("purpur.enderchest.rows.four", "Gives the user four rows of enderchest space", org.bukkit.permissions.PermissionDefault.FALSE); -+ DefaultPermissions.registerPermission("purpur.enderchest.rows.three", "Gives the user three rows of enderchest space", org.bukkit.permissions.PermissionDefault.FALSE); -+ DefaultPermissions.registerPermission("purpur.enderchest.rows.two", "Gives the user two rows of enderchest space", org.bukkit.permissions.PermissionDefault.FALSE); -+ DefaultPermissions.registerPermission("purpur.enderchest.rows.one", "Gives the user one row of enderchest space", org.bukkit.permissions.PermissionDefault.FALSE); -+ // Purpur end - parent.recalculatePermissibles(); - } - } -- 2.26.2 diff --git a/patches/server/0059-Advancement-API-Additions.patch b/patches/server/0005-Advancement-API.patch similarity index 94% rename from patches/server/0059-Advancement-API-Additions.patch rename to patches/server/0005-Advancement-API.patch index 6266189a4..31e04800c 100644 --- a/patches/server/0059-Advancement-API-Additions.patch +++ b/patches/server/0005-Advancement-API.patch @@ -1,7 +1,7 @@ -From 334b15abb698261d55af562dca76653a34cac4a9 Mon Sep 17 00:00:00 2001 +From f38bc41c719f4ec2f111350a6fb57cdf1cb1444a Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Fri, 31 May 2019 21:24:33 -0500 -Subject: [PATCH] Advancement API Additions +Subject: [PATCH] Advancement API --- .../net/minecraft/server/Advancement.java | 2 +- @@ -14,10 +14,10 @@ Subject: [PATCH] Advancement API Additions create mode 100644 src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementDisplay.java diff --git a/src/main/java/net/minecraft/server/Advancement.java b/src/main/java/net/minecraft/server/Advancement.java -index 4b85551fa..4cba4187a 100644 +index 315a03cf5..07d4c4cfd 100644 --- a/src/main/java/net/minecraft/server/Advancement.java +++ b/src/main/java/net/minecraft/server/Advancement.java -@@ -65,7 +65,7 @@ public class Advancement { +@@ -64,7 +64,7 @@ public class Advancement { } @Nullable @@ -27,10 +27,10 @@ index 4b85551fa..4cba4187a 100644 } diff --git a/src/main/java/net/minecraft/server/AdvancementDisplay.java b/src/main/java/net/minecraft/server/AdvancementDisplay.java -index e8172d56f..976c85ef1 100644 +index 12c63a53b..0d3900456 100644 --- a/src/main/java/net/minecraft/server/AdvancementDisplay.java +++ b/src/main/java/net/minecraft/server/AdvancementDisplay.java -@@ -16,10 +16,11 @@ public class AdvancementDisplay { +@@ -15,10 +15,11 @@ public class AdvancementDisplay { private final MinecraftKey d; private final AdvancementFrameType e; private final boolean f; @@ -44,7 +44,7 @@ index e8172d56f..976c85ef1 100644 public AdvancementDisplay(ItemStack itemstack, IChatBaseComponent ichatbasecomponent, IChatBaseComponent ichatbasecomponent1, @Nullable MinecraftKey minecraftkey, AdvancementFrameType advancementframetype, boolean flag, boolean flag1, boolean flag2) { this.a = ichatbasecomponent; -@@ -37,22 +38,29 @@ public class AdvancementDisplay { +@@ -36,22 +37,29 @@ public class AdvancementDisplay { this.j = f1; } @@ -107,10 +107,10 @@ index a9c49a434..551a84547 100644 this.e = i; this.f = enumchatformat; diff --git a/src/main/java/net/minecraft/server/CriterionTrigger.java b/src/main/java/net/minecraft/server/CriterionTrigger.java -index 4fe732447..6e5d81daf 100644 +index cfb420a9c..6fd3671c3 100644 --- a/src/main/java/net/minecraft/server/CriterionTrigger.java +++ b/src/main/java/net/minecraft/server/CriterionTrigger.java -@@ -27,6 +27,7 @@ public interface CriterionTrigger { +@@ -26,6 +26,7 @@ public interface CriterionTrigger { this.c = s; } diff --git a/patches/server/0005-decompile-fixes.patch b/patches/server/0005-decompile-fixes.patch deleted file mode 100644 index e226adacb..000000000 --- a/patches/server/0005-decompile-fixes.patch +++ /dev/null @@ -1,1618 +0,0 @@ -From 1bcefd743dbd60759181f1ee12aa4a4526102698 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Thu, 27 Feb 2020 13:39:06 -0600 -Subject: [PATCH] decompile-fixes - ---- - .../minecraft/server/BiomeBambooJungle.java | 6 ++--- - .../server/BiomeBambooJungleHills.java | 6 ++--- - .../java/net/minecraft/server/BiomeBeach.java | 6 ++--- - .../net/minecraft/server/BiomeBigHills.java | 4 +-- - .../minecraft/server/BiomeBirchForest.java | 4 +-- - .../server/BiomeBirchForestHills.java | 4 +-- - .../server/BiomeBirchForestHillsMutated.java | 4 +-- - .../server/BiomeBirchForestMutated.java | 4 +-- - .../net/minecraft/server/BiomeColdBeach.java | 6 ++--- - .../minecraft/server/BiomeColdDeepOcean.java | 10 +++---- - .../net/minecraft/server/BiomeColdOcean.java | 8 +++--- - .../net/minecraft/server/BiomeColdTaiga.java | 6 ++--- - .../minecraft/server/BiomeColdTaigaHills.java | 4 +-- - .../server/BiomeColdTaigaMutated.java | 4 +-- - .../net/minecraft/server/BiomeDeepOcean.java | 10 +++---- - .../net/minecraft/server/BiomeDesert.java | 10 +++---- - .../minecraft/server/BiomeDesertHills.java | 6 ++--- - .../minecraft/server/BiomeDesertMutated.java | 4 +-- - .../server/BiomeExtremeHillsEdge.java | 4 +-- - .../server/BiomeExtremeHillsMutated.java | 4 +-- - .../server/BiomeExtremeHillsWithTrees.java | 4 +-- - .../BiomeExtremeHillsWithTreesMutated.java | 4 +-- - .../minecraft/server/BiomeFlowerForest.java | 10 +++---- - .../net/minecraft/server/BiomeForest.java | 6 ++--- - .../minecraft/server/BiomeForestHills.java | 6 ++--- - .../server/BiomeFrozenDeepOcean.java | 8 +++--- - .../minecraft/server/BiomeFrozenOcean.java | 6 ++--- - .../minecraft/server/BiomeFrozenRiver.java | 2 +- - .../java/net/minecraft/server/BiomeHell.java | 26 +++++++++---------- - .../minecraft/server/BiomeIceMountains.java | 4 +-- - .../net/minecraft/server/BiomeIcePlains.java | 10 +++---- - .../server/BiomeIcePlainsSpikes.java | 8 +++--- - .../net/minecraft/server/BiomeJungle.java | 6 ++--- - .../net/minecraft/server/BiomeJungleEdge.java | 4 +-- - .../server/BiomeJungleEdgeMutated.java | 4 +-- - .../minecraft/server/BiomeJungleHills.java | 6 ++--- - .../minecraft/server/BiomeJungleMutated.java | 4 +-- - .../server/BiomeLukewarmDeepOcean.java | 8 +++--- - .../minecraft/server/BiomeLukewarmOcean.java | 6 ++--- - .../server/BiomeMegaSpruceTaiga.java | 4 +-- - .../net/minecraft/server/BiomeMegaTaiga.java | 4 +-- - .../minecraft/server/BiomeMegaTaigaHills.java | 4 +-- - .../java/net/minecraft/server/BiomeMesa.java | 4 +-- - .../net/minecraft/server/BiomeMesaBryce.java | 4 +-- - .../minecraft/server/BiomeMesaPlataeu.java | 4 +-- - .../server/BiomeMesaPlataeuClear.java | 4 +-- - .../server/BiomeMesaPlateauClearMutated.java | 4 +-- - .../server/BiomeMesaPlateauMutated.java | 4 +-- - .../server/BiomeMushroomIslandShore.java | 4 +-- - .../net/minecraft/server/BiomeMushrooms.java | 4 +-- - .../java/net/minecraft/server/BiomeOcean.java | 8 +++--- - .../net/minecraft/server/BiomePlains.java | 8 +++--- - .../server/BiomeRedwoodTaigaHillsMutated.java | 4 +-- - .../java/net/minecraft/server/BiomeRiver.java | 4 +-- - .../minecraft/server/BiomeRoofedForest.java | 8 +++--- - .../server/BiomeRoofedForestMutated.java | 8 +++--- - .../net/minecraft/server/BiomeSavanna.java | 8 +++--- - .../minecraft/server/BiomeSavannaMutated.java | 4 +-- - .../minecraft/server/BiomeSavannaPlateau.java | 4 +-- - .../server/BiomeSavannaPlateauMutated.java | 4 +-- - .../net/minecraft/server/BiomeStoneBeach.java | 4 +-- - .../server/BiomeSunflowerPlains.java | 10 +++---- - .../java/net/minecraft/server/BiomeSwamp.java | 6 ++--- - .../server/BiomeSwamplandMutated.java | 2 +- - .../java/net/minecraft/server/BiomeTaiga.java | 8 +++--- - .../net/minecraft/server/BiomeTaigaHills.java | 4 +-- - .../minecraft/server/BiomeTaigaMutated.java | 4 +-- - .../net/minecraft/server/BiomeTheEnd.java | 2 +- - .../server/BiomeTheEndFloatingIslands.java | 2 +- - .../server/BiomeTheEndHighIsland.java | 6 ++--- - .../server/BiomeTheEndMediumIsland.java | 2 +- - .../java/net/minecraft/server/BiomeVoid.java | 2 +- - .../minecraft/server/BiomeWarmDeepOcean.java | 8 +++--- - .../net/minecraft/server/BiomeWarmOcean.java | 10 +++---- - .../net/minecraft/server/CommandDebug.java | 2 +- - .../net/minecraft/server/EntityBlaze.java | 2 +- - .../java/net/minecraft/server/EntityCat.java | 2 +- - .../minecraft/server/EntityEnderSignal.java | 2 +- - .../net/minecraft/server/EntityEndermite.java | 2 +- - .../net/minecraft/server/EntityEvoker.java | 2 +- - .../java/net/minecraft/server/EntityFish.java | 6 +---- - .../net/minecraft/server/EntityParrot.java | 4 +-- - .../net/minecraft/server/EntitySheep.java | 6 ++--- - .../net/minecraft/server/EntityWitch.java | 4 +-- - .../net/minecraft/server/GeneratorAccess.java | 2 +- - .../java/net/minecraft/server/MathHelper.java | 2 +- - .../server/WorldGenFeatureConfigured.java | 2 +- - .../server/WorldGenFeatureTreeBeehive.java | 2 +- - 88 files changed, 227 insertions(+), 233 deletions(-) - -diff --git a/src/main/java/net/minecraft/server/BiomeBambooJungle.java b/src/main/java/net/minecraft/server/BiomeBambooJungle.java -index de831ed87..9c38f8907 100644 ---- a/src/main/java/net/minecraft/server/BiomeBambooJungle.java -+++ b/src/main/java/net/minecraft/server/BiomeBambooJungle.java -@@ -4,9 +4,9 @@ public class BiomeBambooJungle extends BiomeBase { - - public BiomeBambooJungle() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.JUNGLE).a(0.1F).b(0.2F).c(0.95F).d(0.9F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.JUNGLE_TEMPLE.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.JUNGLE_TEMPLE.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeBambooJungleHills.java b/src/main/java/net/minecraft/server/BiomeBambooJungleHills.java -index 5ae19373d..2a6dafccd 100644 ---- a/src/main/java/net/minecraft/server/BiomeBambooJungleHills.java -+++ b/src/main/java/net/minecraft/server/BiomeBambooJungleHills.java -@@ -4,9 +4,9 @@ public final class BiomeBambooJungleHills extends BiomeBase { - - public BiomeBambooJungleHills() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.JUNGLE).a(0.45F).b(0.3F).c(0.95F).d(0.9F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.JUNGLE_TEMPLE.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.JUNGLE_TEMPLE.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeBeach.java b/src/main/java/net/minecraft/server/BiomeBeach.java -index 262740414..f4e9345ae 100644 ---- a/src/main/java/net/minecraft/server/BiomeBeach.java -+++ b/src/main/java/net/minecraft/server/BiomeBeach.java -@@ -4,9 +4,9 @@ public final class BiomeBeach extends BiomeBase { - - public BiomeBeach() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.z).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.BEACH).a(0.0F).b(0.025F).c(0.8F).d(0.4F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.BURIED_TREASURE.b((WorldGenFeatureConfiguration) (new WorldGenBuriedTreasureConfiguration(0.01F)))); -- this.a(WorldGenerator.SHIPWRECK.b((WorldGenFeatureConfiguration) (new WorldGenFeatureShipwreckConfiguration(true)))); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.BURIED_TREASURE.b(new WorldGenBuriedTreasureConfiguration(0.01F))); // Purpur - decompile error -+ this.a(WorldGenerator.SHIPWRECK.b(new WorldGenFeatureShipwreckConfiguration(true))); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeBigHills.java b/src/main/java/net/minecraft/server/BiomeBigHills.java -index a42098da5..58c30f652 100644 ---- a/src/main/java/net/minecraft/server/BiomeBigHills.java -+++ b/src/main/java/net/minecraft/server/BiomeBigHills.java -@@ -4,8 +4,8 @@ public final class BiomeBigHills extends BiomeBase { - - protected BiomeBigHills() { - super((new BiomeBase.a()).a(WorldGenSurface.H, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.EXTREME_HILLS).a(1.0F).b(0.5F).c(0.2F).d(0.3F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeBirchForest.java b/src/main/java/net/minecraft/server/BiomeBirchForest.java -index 27fa23801..9437438c8 100644 ---- a/src/main/java/net/minecraft/server/BiomeBirchForest.java -+++ b/src/main/java/net/minecraft/server/BiomeBirchForest.java -@@ -4,8 +4,8 @@ public final class BiomeBirchForest extends BiomeBase { - - public BiomeBirchForest() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.FOREST).a(0.1F).b(0.2F).c(0.6F).d(0.6F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeBirchForestHills.java b/src/main/java/net/minecraft/server/BiomeBirchForestHills.java -index 51b1d39f5..3e5c23d31 100644 ---- a/src/main/java/net/minecraft/server/BiomeBirchForestHills.java -+++ b/src/main/java/net/minecraft/server/BiomeBirchForestHills.java -@@ -4,8 +4,8 @@ public final class BiomeBirchForestHills extends BiomeBase { - - public BiomeBirchForestHills() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.FOREST).a(0.45F).b(0.3F).c(0.6F).d(0.6F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeBirchForestHillsMutated.java b/src/main/java/net/minecraft/server/BiomeBirchForestHillsMutated.java -index b74f23cff..d5eb5c91c 100644 ---- a/src/main/java/net/minecraft/server/BiomeBirchForestHillsMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeBirchForestHillsMutated.java -@@ -4,8 +4,8 @@ public final class BiomeBirchForestHillsMutated extends BiomeBase { - - public BiomeBirchForestHillsMutated() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.FOREST).a(0.55F).b(0.5F).c(0.6F).d(0.6F).a(4159204).b(329011).a("birch_forest_hills")); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeBirchForestMutated.java b/src/main/java/net/minecraft/server/BiomeBirchForestMutated.java -index 17fe3818d..e805f9568 100644 ---- a/src/main/java/net/minecraft/server/BiomeBirchForestMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeBirchForestMutated.java -@@ -4,8 +4,8 @@ public final class BiomeBirchForestMutated extends BiomeBase { - - public BiomeBirchForestMutated() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.FOREST).a(0.2F).b(0.4F).c(0.6F).d(0.6F).a(4159204).b(329011).a("birch_forest")); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeColdBeach.java b/src/main/java/net/minecraft/server/BiomeColdBeach.java -index 2c230be98..1b92f4567 100644 ---- a/src/main/java/net/minecraft/server/BiomeColdBeach.java -+++ b/src/main/java/net/minecraft/server/BiomeColdBeach.java -@@ -4,9 +4,9 @@ public final class BiomeColdBeach extends BiomeBase { - - public BiomeColdBeach() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.z).a(BiomeBase.Precipitation.SNOW).a(BiomeBase.Geography.BEACH).a(0.0F).b(0.025F).c(0.05F).d(0.3F).a(4020182).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.BURIED_TREASURE.b((WorldGenFeatureConfiguration) (new WorldGenBuriedTreasureConfiguration(0.01F)))); -- this.a(WorldGenerator.SHIPWRECK.b((WorldGenFeatureConfiguration) (new WorldGenFeatureShipwreckConfiguration(true)))); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.BURIED_TREASURE.b(new WorldGenBuriedTreasureConfiguration(0.01F))); // Purpur - decompile error -+ this.a(WorldGenerator.SHIPWRECK.b(new WorldGenFeatureShipwreckConfiguration(true))); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeColdDeepOcean.java b/src/main/java/net/minecraft/server/BiomeColdDeepOcean.java -index d96e820e0..b9a5cb63a 100644 ---- a/src/main/java/net/minecraft/server/BiomeColdDeepOcean.java -+++ b/src/main/java/net/minecraft/server/BiomeColdDeepOcean.java -@@ -4,10 +4,10 @@ public class BiomeColdDeepOcean extends BiomeBase { - - public BiomeColdDeepOcean() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.OCEAN).a(-1.8F).b(0.1F).c(0.5F).d(0.5F).a(4020182).b(329011).a((String) null)); -- this.a(WorldGenerator.OCEAN_RUIN.b((WorldGenFeatureConfiguration) (new WorldGenFeatureOceanRuinConfiguration(WorldGenFeatureOceanRuin.Temperature.COLD, 0.3F, 0.9F)))); -- this.a(WorldGenerator.OCEAN_MONUMENT.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.SHIPWRECK.b((WorldGenFeatureConfiguration) (new WorldGenFeatureShipwreckConfiguration(false)))); -+ this.a(WorldGenerator.OCEAN_RUIN.b(new WorldGenFeatureOceanRuinConfiguration(WorldGenFeatureOceanRuin.Temperature.COLD, 0.3F, 0.9F))); // Purpur - decompile error -+ this.a(WorldGenerator.OCEAN_MONUMENT.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.SHIPWRECK.b(new WorldGenFeatureShipwreckConfiguration(false))); // Purpur - decompile error - BiomeDecoratorGroups.b(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -@@ -21,7 +21,7 @@ public class BiomeColdDeepOcean extends BiomeBase { - BiomeDecoratorGroups.Z(this); - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); -- this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.SEAGRASS.b((WorldGenFeatureConfiguration) (new WorldGenFeatureSeaGrassConfiguration(40, 0.8D))).a(WorldGenDecorator.v.a((WorldGenFeatureDecoratorConfiguration) WorldGenFeatureDecoratorConfiguration.e))); -+ this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.SEAGRASS.b(new WorldGenFeatureSeaGrassConfiguration(40, 0.8D)).a(WorldGenDecorator.v.a(WorldGenFeatureDecoratorConfiguration.e))); // Purpur - decompile error - BiomeDecoratorGroups.ai(this); - BiomeDecoratorGroups.ah(this); - BiomeDecoratorGroups.ap(this); -diff --git a/src/main/java/net/minecraft/server/BiomeColdOcean.java b/src/main/java/net/minecraft/server/BiomeColdOcean.java -index c7ed2e134..571c3d139 100644 ---- a/src/main/java/net/minecraft/server/BiomeColdOcean.java -+++ b/src/main/java/net/minecraft/server/BiomeColdOcean.java -@@ -4,9 +4,9 @@ public class BiomeColdOcean extends BiomeBase { - - public BiomeColdOcean() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.OCEAN).a(-1.0F).b(0.1F).c(0.5F).d(0.5F).a(4020182).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.OCEAN_RUIN.b((WorldGenFeatureConfiguration) (new WorldGenFeatureOceanRuinConfiguration(WorldGenFeatureOceanRuin.Temperature.COLD, 0.3F, 0.9F)))); -- this.a(WorldGenerator.SHIPWRECK.b((WorldGenFeatureConfiguration) (new WorldGenFeatureShipwreckConfiguration(false)))); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.OCEAN_RUIN.b(new WorldGenFeatureOceanRuinConfiguration(WorldGenFeatureOceanRuin.Temperature.COLD, 0.3F, 0.9F))); // Purpur - decompile error -+ this.a(WorldGenerator.SHIPWRECK.b(new WorldGenFeatureShipwreckConfiguration(false))); // Purpur - decompile error - BiomeDecoratorGroups.b(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -@@ -20,7 +20,7 @@ public class BiomeColdOcean extends BiomeBase { - BiomeDecoratorGroups.Z(this); - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); -- this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.SEAGRASS.b((WorldGenFeatureConfiguration) (new WorldGenFeatureSeaGrassConfiguration(32, 0.3D))).a(WorldGenDecorator.v.a((WorldGenFeatureDecoratorConfiguration) WorldGenFeatureDecoratorConfiguration.e))); -+ this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.SEAGRASS.b(new WorldGenFeatureSeaGrassConfiguration(32, 0.3D)).a(WorldGenDecorator.v.a(WorldGenFeatureDecoratorConfiguration.e))); // Purpur - decompile error - BiomeDecoratorGroups.ai(this); - BiomeDecoratorGroups.ah(this); - BiomeDecoratorGroups.ap(this); -diff --git a/src/main/java/net/minecraft/server/BiomeColdTaiga.java b/src/main/java/net/minecraft/server/BiomeColdTaiga.java -index c766dedfa..88400e77b 100644 ---- a/src/main/java/net/minecraft/server/BiomeColdTaiga.java -+++ b/src/main/java/net/minecraft/server/BiomeColdTaiga.java -@@ -4,9 +4,9 @@ public final class BiomeColdTaiga extends BiomeBase { - - public BiomeColdTaiga() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.SNOW).a(BiomeBase.Geography.TAIGA).a(0.2F).b(0.2F).c(-0.5F).d(0.4F).a(4020182).b(329011).a((String) null)); -- this.a(WorldGenerator.IGLOO.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.IGLOO.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeColdTaigaHills.java b/src/main/java/net/minecraft/server/BiomeColdTaigaHills.java -index 187f11f58..8a8fc7dbd 100644 ---- a/src/main/java/net/minecraft/server/BiomeColdTaigaHills.java -+++ b/src/main/java/net/minecraft/server/BiomeColdTaigaHills.java -@@ -4,8 +4,8 @@ public final class BiomeColdTaigaHills extends BiomeBase { - - public BiomeColdTaigaHills() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.SNOW).a(BiomeBase.Geography.TAIGA).a(0.45F).b(0.3F).c(-0.5F).d(0.4F).a(4020182).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeColdTaigaMutated.java b/src/main/java/net/minecraft/server/BiomeColdTaigaMutated.java -index 97c56fb80..327e6847f 100644 ---- a/src/main/java/net/minecraft/server/BiomeColdTaigaMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeColdTaigaMutated.java -@@ -4,8 +4,8 @@ public final class BiomeColdTaigaMutated extends BiomeBase { - - public BiomeColdTaigaMutated() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.SNOW).a(BiomeBase.Geography.TAIGA).a(0.3F).b(0.4F).c(-0.5F).d(0.4F).a(4020182).b(329011).a("snowy_taiga")); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeDeepOcean.java b/src/main/java/net/minecraft/server/BiomeDeepOcean.java -index bea129314..651d44cb3 100644 ---- a/src/main/java/net/minecraft/server/BiomeDeepOcean.java -+++ b/src/main/java/net/minecraft/server/BiomeDeepOcean.java -@@ -4,10 +4,10 @@ public final class BiomeDeepOcean extends BiomeBase { - - public BiomeDeepOcean() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.OCEAN).a(-1.8F).b(0.1F).c(0.5F).d(0.5F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.OCEAN_MONUMENT.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.SHIPWRECK.b((WorldGenFeatureConfiguration) (new WorldGenFeatureShipwreckConfiguration(false)))); -- this.a(WorldGenerator.OCEAN_RUIN.b((WorldGenFeatureConfiguration) (new WorldGenFeatureOceanRuinConfiguration(WorldGenFeatureOceanRuin.Temperature.COLD, 0.3F, 0.9F)))); -+ this.a(WorldGenerator.OCEAN_MONUMENT.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.SHIPWRECK.b(new WorldGenFeatureShipwreckConfiguration(false))); // Purpur - decompile error -+ this.a(WorldGenerator.OCEAN_RUIN.b(new WorldGenFeatureOceanRuinConfiguration(WorldGenFeatureOceanRuin.Temperature.COLD, 0.3F, 0.9F))); // Purpur - decompile error - BiomeDecoratorGroups.b(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -@@ -21,7 +21,7 @@ public final class BiomeDeepOcean extends BiomeBase { - BiomeDecoratorGroups.Z(this); - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); -- this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.SEAGRASS.b((WorldGenFeatureConfiguration) (new WorldGenFeatureSeaGrassConfiguration(48, 0.8D))).a(WorldGenDecorator.v.a((WorldGenFeatureDecoratorConfiguration) WorldGenFeatureDecoratorConfiguration.e))); -+ this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.SEAGRASS.b(new WorldGenFeatureSeaGrassConfiguration(48, 0.8D)).a(WorldGenDecorator.v.a(WorldGenFeatureDecoratorConfiguration.e))); // Purpur - decompile error - BiomeDecoratorGroups.ai(this); - BiomeDecoratorGroups.ah(this); - BiomeDecoratorGroups.ap(this); -diff --git a/src/main/java/net/minecraft/server/BiomeDesert.java b/src/main/java/net/minecraft/server/BiomeDesert.java -index 7a8784f18..257732dad 100644 ---- a/src/main/java/net/minecraft/server/BiomeDesert.java -+++ b/src/main/java/net/minecraft/server/BiomeDesert.java -@@ -4,11 +4,11 @@ public final class BiomeDesert extends BiomeBase { - - public BiomeDesert() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.z).a(BiomeBase.Precipitation.NONE).a(BiomeBase.Geography.DESERT).a(0.125F).b(0.05F).c(2.0F).d(0.0F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.VILLAGE.b((WorldGenFeatureConfiguration) (new WorldGenFeatureVillageConfiguration("village/desert/town_centers", 6)))); -- this.a(WorldGenerator.PILLAGER_OUTPOST.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenerator.DESERT_PYRAMID.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.VILLAGE.b(new WorldGenFeatureVillageConfiguration("village/desert/town_centers", 6))); // Purpur - decompile error -+ this.a(WorldGenerator.PILLAGER_OUTPOST.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error -+ this.a(WorldGenerator.DESERT_PYRAMID.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.e(this); -diff --git a/src/main/java/net/minecraft/server/BiomeDesertHills.java b/src/main/java/net/minecraft/server/BiomeDesertHills.java -index 9f5e9abc4..3752fc450 100644 ---- a/src/main/java/net/minecraft/server/BiomeDesertHills.java -+++ b/src/main/java/net/minecraft/server/BiomeDesertHills.java -@@ -4,9 +4,9 @@ public final class BiomeDesertHills extends BiomeBase { - - public BiomeDesertHills() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.z).a(BiomeBase.Precipitation.NONE).a(BiomeBase.Geography.DESERT).a(0.45F).b(0.3F).c(2.0F).d(0.0F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.DESERT_PYRAMID.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.DESERT_PYRAMID.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.e(this); -diff --git a/src/main/java/net/minecraft/server/BiomeDesertMutated.java b/src/main/java/net/minecraft/server/BiomeDesertMutated.java -index f79e438dc..1a0b56932 100644 ---- a/src/main/java/net/minecraft/server/BiomeDesertMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeDesertMutated.java -@@ -4,8 +4,8 @@ public final class BiomeDesertMutated extends BiomeBase { - - public BiomeDesertMutated() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.z).a(BiomeBase.Precipitation.NONE).a(BiomeBase.Geography.DESERT).a(0.225F).b(0.25F).c(2.0F).d(0.0F).a(4159204).b(329011).a("desert")); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.e(this); -diff --git a/src/main/java/net/minecraft/server/BiomeExtremeHillsEdge.java b/src/main/java/net/minecraft/server/BiomeExtremeHillsEdge.java -index 58a612528..8e19e0688 100644 ---- a/src/main/java/net/minecraft/server/BiomeExtremeHillsEdge.java -+++ b/src/main/java/net/minecraft/server/BiomeExtremeHillsEdge.java -@@ -4,8 +4,8 @@ public final class BiomeExtremeHillsEdge extends BiomeBase { - - protected BiomeExtremeHillsEdge() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.EXTREME_HILLS).a(0.8F).b(0.3F).c(0.2F).d(0.3F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeExtremeHillsMutated.java b/src/main/java/net/minecraft/server/BiomeExtremeHillsMutated.java -index cd18533bb..69d4880c7 100644 ---- a/src/main/java/net/minecraft/server/BiomeExtremeHillsMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeExtremeHillsMutated.java -@@ -4,8 +4,8 @@ public final class BiomeExtremeHillsMutated extends BiomeBase { - - protected BiomeExtremeHillsMutated() { - super((new BiomeBase.a()).a(WorldGenSurface.J, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.EXTREME_HILLS).a(1.0F).b(0.5F).c(0.2F).d(0.3F).a(4159204).b(329011).a("mountains")); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeExtremeHillsWithTrees.java b/src/main/java/net/minecraft/server/BiomeExtremeHillsWithTrees.java -index 2c7f5940a..7661d5316 100644 ---- a/src/main/java/net/minecraft/server/BiomeExtremeHillsWithTrees.java -+++ b/src/main/java/net/minecraft/server/BiomeExtremeHillsWithTrees.java -@@ -4,8 +4,8 @@ public final class BiomeExtremeHillsWithTrees extends BiomeBase { - - protected BiomeExtremeHillsWithTrees() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.EXTREME_HILLS).a(1.0F).b(0.5F).c(0.2F).d(0.3F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeExtremeHillsWithTreesMutated.java b/src/main/java/net/minecraft/server/BiomeExtremeHillsWithTreesMutated.java -index 6e33c2363..05418f8fa 100644 ---- a/src/main/java/net/minecraft/server/BiomeExtremeHillsWithTreesMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeExtremeHillsWithTreesMutated.java -@@ -4,8 +4,8 @@ public final class BiomeExtremeHillsWithTreesMutated extends BiomeBase { - - protected BiomeExtremeHillsWithTreesMutated() { - super((new BiomeBase.a()).a(WorldGenSurface.J, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.EXTREME_HILLS).a(1.0F).b(0.5F).c(0.2F).d(0.3F).a(4159204).b(329011).a("wooded_mountains")); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeFlowerForest.java b/src/main/java/net/minecraft/server/BiomeFlowerForest.java -index c6ac9506a..1d3f62432 100644 ---- a/src/main/java/net/minecraft/server/BiomeFlowerForest.java -+++ b/src/main/java/net/minecraft/server/BiomeFlowerForest.java -@@ -6,18 +6,18 @@ public final class BiomeFlowerForest extends BiomeBase { - - public BiomeFlowerForest() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.FOREST).a(0.1F).b(0.4F).c(0.7F).d(0.8F).a(4159204).b(329011).a("forest")); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); - BiomeDecoratorGroups.f(this); -- this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.RANDOM_RANDOM_SELECTOR.b((WorldGenFeatureConfiguration) (new WorldGenFeatureRandomConfiguration(ImmutableList.of(WorldGenerator.RANDOM_PATCH.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.O), WorldGenerator.RANDOM_PATCH.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.P), WorldGenerator.RANDOM_PATCH.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.Q), WorldGenerator.FLOWER.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.B)), 2))).a(WorldGenDecorator.d.a((WorldGenFeatureDecoratorConfiguration) (new WorldGenDecoratorFrequencyConfiguration(5))))); -+ this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.RANDOM_RANDOM_SELECTOR.b(new WorldGenFeatureRandomConfiguration(ImmutableList.of(WorldGenerator.RANDOM_PATCH.b(BiomeDecoratorGroups.O), WorldGenerator.RANDOM_PATCH.b(BiomeDecoratorGroups.P), WorldGenerator.RANDOM_PATCH.b(BiomeDecoratorGroups.Q), WorldGenerator.FLOWER.b(BiomeDecoratorGroups.B)), 2)).a(WorldGenDecorator.d.a(new WorldGenDecoratorFrequencyConfiguration(5)))); // Purpur - decompile error - BiomeDecoratorGroups.g(this); - BiomeDecoratorGroups.h(this); - BiomeDecoratorGroups.l(this); -- this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.RANDOM_SELECTOR.b((WorldGenFeatureConfiguration) (new WorldGenFeatureRandomChoiceConfiguration(ImmutableList.of(WorldGenerator.NORMAL_TREE.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.BIRCH_TREE_BEES_002).a(0.2F), WorldGenerator.FANCY_TREE.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.FANCY_TREE_BEES_002).a(0.1F)), WorldGenerator.NORMAL_TREE.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.NORMAL_TREE_BEES_002)))).a(WorldGenDecorator.m.a((WorldGenFeatureDecoratorConfiguration) (new WorldGenDecoratorFrequencyExtraChanceConfiguration(6, 0.1F, 1))))); -- this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.FLOWER.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.F).a(WorldGenDecorator.d.a((WorldGenFeatureDecoratorConfiguration) (new WorldGenDecoratorFrequencyConfiguration(100))))); -+ this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.RANDOM_SELECTOR.b(new WorldGenFeatureRandomChoiceConfiguration(ImmutableList.of(WorldGenerator.NORMAL_TREE.b(BiomeDecoratorGroups.BIRCH_TREE_BEES_002).a(0.2F), WorldGenerator.FANCY_TREE.b(BiomeDecoratorGroups.FANCY_TREE_BEES_002).a(0.1F)), WorldGenerator.NORMAL_TREE.b(BiomeDecoratorGroups.NORMAL_TREE_BEES_002))).a(WorldGenDecorator.m.a(new WorldGenDecoratorFrequencyExtraChanceConfiguration(6, 0.1F, 1)))); // Purpur - decompile error -+ this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.FLOWER.b(BiomeDecoratorGroups.F).a(WorldGenDecorator.d.a(new WorldGenDecoratorFrequencyConfiguration(100)))); // Purpur - decompile error - BiomeDecoratorGroups.W(this); - BiomeDecoratorGroups.Z(this); - BiomeDecoratorGroups.aa(this); -diff --git a/src/main/java/net/minecraft/server/BiomeForest.java b/src/main/java/net/minecraft/server/BiomeForest.java -index 570a1f66f..e849b411c 100644 ---- a/src/main/java/net/minecraft/server/BiomeForest.java -+++ b/src/main/java/net/minecraft/server/BiomeForest.java -@@ -4,9 +4,9 @@ public final class BiomeForest extends BiomeBase { - - public BiomeForest() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.FOREST).a(0.1F).b(0.2F).c(0.7F).d(0.8F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeForestHills.java b/src/main/java/net/minecraft/server/BiomeForestHills.java -index 8179e1c60..f7dea38eb 100644 ---- a/src/main/java/net/minecraft/server/BiomeForestHills.java -+++ b/src/main/java/net/minecraft/server/BiomeForestHills.java -@@ -4,9 +4,9 @@ public final class BiomeForestHills extends BiomeBase { - - public BiomeForestHills() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.FOREST).a(0.45F).b(0.3F).c(0.7F).d(0.8F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeFrozenDeepOcean.java b/src/main/java/net/minecraft/server/BiomeFrozenDeepOcean.java -index 852c4bd9a..67d120bef 100644 ---- a/src/main/java/net/minecraft/server/BiomeFrozenDeepOcean.java -+++ b/src/main/java/net/minecraft/server/BiomeFrozenDeepOcean.java -@@ -6,10 +6,10 @@ public class BiomeFrozenDeepOcean extends BiomeBase { - - public BiomeFrozenDeepOcean() { - super((new BiomeBase.a()).a(WorldGenSurface.P, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.OCEAN).a(-1.8F).b(0.1F).c(0.5F).d(0.5F).a(3750089).b(329011).a((String) null)); -- this.a(WorldGenerator.OCEAN_RUIN.b((WorldGenFeatureConfiguration) (new WorldGenFeatureOceanRuinConfiguration(WorldGenFeatureOceanRuin.Temperature.COLD, 0.3F, 0.9F)))); -- this.a(WorldGenerator.OCEAN_MONUMENT.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.SHIPWRECK.b((WorldGenFeatureConfiguration) (new WorldGenFeatureShipwreckConfiguration(false)))); -+ this.a(WorldGenerator.OCEAN_RUIN.b(new WorldGenFeatureOceanRuinConfiguration(WorldGenFeatureOceanRuin.Temperature.COLD, 0.3F, 0.9F))); // Purpur - decompile error -+ this.a(WorldGenerator.OCEAN_MONUMENT.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.SHIPWRECK.b(new WorldGenFeatureShipwreckConfiguration(false))); // Purpur - decompile error - BiomeDecoratorGroups.b(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeFrozenOcean.java b/src/main/java/net/minecraft/server/BiomeFrozenOcean.java -index 3d649c600..2772bc6da 100644 ---- a/src/main/java/net/minecraft/server/BiomeFrozenOcean.java -+++ b/src/main/java/net/minecraft/server/BiomeFrozenOcean.java -@@ -6,9 +6,9 @@ public final class BiomeFrozenOcean extends BiomeBase { - - public BiomeFrozenOcean() { - super((new BiomeBase.a()).a(WorldGenSurface.P, WorldGenSurface.v).a(BiomeBase.Precipitation.SNOW).a(BiomeBase.Geography.OCEAN).a(-1.0F).b(0.1F).c(0.0F).d(0.5F).a(3750089).b(329011).a((String) null)); -- this.a(WorldGenerator.OCEAN_RUIN.b((WorldGenFeatureConfiguration) (new WorldGenFeatureOceanRuinConfiguration(WorldGenFeatureOceanRuin.Temperature.COLD, 0.3F, 0.9F)))); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.SHIPWRECK.b((WorldGenFeatureConfiguration) (new WorldGenFeatureShipwreckConfiguration(false)))); -+ this.a(WorldGenerator.OCEAN_RUIN.b(new WorldGenFeatureOceanRuinConfiguration(WorldGenFeatureOceanRuin.Temperature.COLD, 0.3F, 0.9F))); // Purpur - decompile error -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.SHIPWRECK.b(new WorldGenFeatureShipwreckConfiguration(false))); // Purpur - decompile error - BiomeDecoratorGroups.b(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeFrozenRiver.java b/src/main/java/net/minecraft/server/BiomeFrozenRiver.java -index 915f20042..4be53fc0f 100644 ---- a/src/main/java/net/minecraft/server/BiomeFrozenRiver.java -+++ b/src/main/java/net/minecraft/server/BiomeFrozenRiver.java -@@ -4,7 +4,7 @@ public final class BiomeFrozenRiver extends BiomeBase { - - public BiomeFrozenRiver() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.SNOW).a(BiomeBase.Geography.RIVER).a(-0.5F).b(0.0F).c(0.0F).d(0.5F).a(3750089).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeHell.java b/src/main/java/net/minecraft/server/BiomeHell.java -index f9ca6b889..888dfcd8d 100644 ---- a/src/main/java/net/minecraft/server/BiomeHell.java -+++ b/src/main/java/net/minecraft/server/BiomeHell.java -@@ -4,20 +4,20 @@ public final class BiomeHell extends BiomeBase { - - protected BiomeHell() { - super((new BiomeBase.a()).a(WorldGenSurface.Q, WorldGenSurface.E).a(BiomeBase.Precipitation.NONE).a(BiomeBase.Geography.NETHER).a(0.1F).b(0.2F).c(2.0F).d(0.0F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.NETHER_BRIDGE.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenStage.Features.AIR, a(WorldGenCarverAbstract.b, (WorldGenCarverConfiguration) (new WorldGenFeatureConfigurationChance(0.2F)))); -- this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.SPRING_FEATURE.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.ac).a(WorldGenDecorator.p.a((WorldGenFeatureDecoratorConfiguration) (new WorldGenFeatureChanceDecoratorCountConfiguration(20, 8, 16, 256))))); -+ this.a(WorldGenerator.NETHER_BRIDGE.b(WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenStage.Features.AIR, a(WorldGenCarverAbstract.b, new WorldGenFeatureConfigurationChance(0.2F))); // Purpur - decompile error -+ this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.SPRING_FEATURE.b(BiomeDecoratorGroups.ac).a(WorldGenDecorator.p.a(new WorldGenFeatureChanceDecoratorCountConfiguration(20, 8, 16, 256)))); // Purpur - decompile error - BiomeDecoratorGroups.Z(this); -- this.a(WorldGenStage.Decoration.UNDERGROUND_DECORATION, WorldGenerator.NETHER_BRIDGE.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e).a(WorldGenDecorator.a.a((WorldGenFeatureDecoratorConfiguration) WorldGenFeatureDecoratorConfiguration.e))); -- this.a(WorldGenStage.Decoration.UNDERGROUND_DECORATION, WorldGenerator.SPRING_FEATURE.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.ad).a(WorldGenDecorator.n.a((WorldGenFeatureDecoratorConfiguration) (new WorldGenFeatureChanceDecoratorCountConfiguration(8, 4, 8, 128))))); -- this.a(WorldGenStage.Decoration.UNDERGROUND_DECORATION, WorldGenerator.RANDOM_PATCH.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.K).a(WorldGenDecorator.A.a((WorldGenFeatureDecoratorConfiguration) (new WorldGenDecoratorFrequencyConfiguration(10))))); -- this.a(WorldGenStage.Decoration.UNDERGROUND_DECORATION, WorldGenerator.GLOWSTONE_BLOB.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e).a(WorldGenDecorator.I.a((WorldGenFeatureDecoratorConfiguration) (new WorldGenDecoratorFrequencyConfiguration(10))))); -- this.a(WorldGenStage.Decoration.UNDERGROUND_DECORATION, WorldGenerator.GLOWSTONE_BLOB.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e).a(WorldGenDecorator.n.a((WorldGenFeatureDecoratorConfiguration) (new WorldGenFeatureChanceDecoratorCountConfiguration(10, 0, 0, 128))))); -- this.a(WorldGenStage.Decoration.UNDERGROUND_DECORATION, WorldGenerator.RANDOM_PATCH.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.N).a(WorldGenDecorator.r.a((WorldGenFeatureDecoratorConfiguration) (new WorldGenFeatureChanceDecoratorRangeConfiguration(0.5F, 0, 0, 128))))); -- this.a(WorldGenStage.Decoration.UNDERGROUND_DECORATION, WorldGenerator.RANDOM_PATCH.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.M).a(WorldGenDecorator.r.a((WorldGenFeatureDecoratorConfiguration) (new WorldGenFeatureChanceDecoratorRangeConfiguration(0.5F, 0, 0, 128))))); -- this.a(WorldGenStage.Decoration.UNDERGROUND_DECORATION, WorldGenerator.ORE.b((WorldGenFeatureConfiguration) (new WorldGenFeatureOreConfiguration(WorldGenFeatureOreConfiguration.Target.NETHERRACK, Blocks.NETHER_QUARTZ_ORE.getBlockData(), 14))).a(WorldGenDecorator.n.a((WorldGenFeatureDecoratorConfiguration) (new WorldGenFeatureChanceDecoratorCountConfiguration(16, 10, 20, 128))))); -- this.a(WorldGenStage.Decoration.UNDERGROUND_DECORATION, WorldGenerator.ORE.b((WorldGenFeatureConfiguration) (new WorldGenFeatureOreConfiguration(WorldGenFeatureOreConfiguration.Target.NETHERRACK, Blocks.MAGMA_BLOCK.getBlockData(), 33))).a(WorldGenDecorator.B.a((WorldGenFeatureDecoratorConfiguration) (new WorldGenDecoratorFrequencyConfiguration(4))))); -- this.a(WorldGenStage.Decoration.UNDERGROUND_DECORATION, WorldGenerator.SPRING_FEATURE.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.ae).a(WorldGenDecorator.n.a((WorldGenFeatureDecoratorConfiguration) (new WorldGenFeatureChanceDecoratorCountConfiguration(16, 10, 20, 128))))); -+ this.a(WorldGenStage.Decoration.UNDERGROUND_DECORATION, WorldGenerator.NETHER_BRIDGE.b(WorldGenFeatureConfiguration.e).a(WorldGenDecorator.a.a(WorldGenFeatureDecoratorConfiguration.e))); // Purpur - decompile error -+ this.a(WorldGenStage.Decoration.UNDERGROUND_DECORATION, WorldGenerator.SPRING_FEATURE.b(BiomeDecoratorGroups.ad).a(WorldGenDecorator.n.a(new WorldGenFeatureChanceDecoratorCountConfiguration(8, 4, 8, 128)))); // Purpur - decompile error -+ this.a(WorldGenStage.Decoration.UNDERGROUND_DECORATION, WorldGenerator.RANDOM_PATCH.b(BiomeDecoratorGroups.K).a(WorldGenDecorator.A.a(new WorldGenDecoratorFrequencyConfiguration(10)))); // Purpur - decompile error -+ this.a(WorldGenStage.Decoration.UNDERGROUND_DECORATION, WorldGenerator.GLOWSTONE_BLOB.b(WorldGenFeatureConfiguration.e).a(WorldGenDecorator.I.a(new WorldGenDecoratorFrequencyConfiguration(10)))); // Purpur - decompile error -+ this.a(WorldGenStage.Decoration.UNDERGROUND_DECORATION, WorldGenerator.GLOWSTONE_BLOB.b(WorldGenFeatureConfiguration.e).a(WorldGenDecorator.n.a(new WorldGenFeatureChanceDecoratorCountConfiguration(10, 0, 0, 128)))); // Purpur - decompile error -+ this.a(WorldGenStage.Decoration.UNDERGROUND_DECORATION, WorldGenerator.RANDOM_PATCH.b(BiomeDecoratorGroups.N).a(WorldGenDecorator.r.a(new WorldGenFeatureChanceDecoratorRangeConfiguration(0.5F, 0, 0, 128)))); // Purpur - decompile error -+ this.a(WorldGenStage.Decoration.UNDERGROUND_DECORATION, WorldGenerator.RANDOM_PATCH.b(BiomeDecoratorGroups.M).a(WorldGenDecorator.r.a(new WorldGenFeatureChanceDecoratorRangeConfiguration(0.5F, 0, 0, 128)))); // Purpur - decompile error -+ this.a(WorldGenStage.Decoration.UNDERGROUND_DECORATION, WorldGenerator.ORE.b(new WorldGenFeatureOreConfiguration(WorldGenFeatureOreConfiguration.Target.NETHERRACK, Blocks.NETHER_QUARTZ_ORE.getBlockData(), 14)).a(WorldGenDecorator.n.a(new WorldGenFeatureChanceDecoratorCountConfiguration(16, 10, 20, 128)))); // Purpur - decompile error -+ this.a(WorldGenStage.Decoration.UNDERGROUND_DECORATION, WorldGenerator.ORE.b(new WorldGenFeatureOreConfiguration(WorldGenFeatureOreConfiguration.Target.NETHERRACK, Blocks.MAGMA_BLOCK.getBlockData(), 33)).a(WorldGenDecorator.B.a(new WorldGenDecoratorFrequencyConfiguration(4)))); // Purpur - decompile error -+ this.a(WorldGenStage.Decoration.UNDERGROUND_DECORATION, WorldGenerator.SPRING_FEATURE.b(BiomeDecoratorGroups.ae).a(WorldGenDecorator.n.a(new WorldGenFeatureChanceDecoratorCountConfiguration(16, 10, 20, 128)))); // Purpur - decompile error - this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.GHAST, 50, 4, 4)); - this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_PIGMAN, 100, 4, 4)); - this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.MAGMA_CUBE, 2, 4, 4)); -diff --git a/src/main/java/net/minecraft/server/BiomeIceMountains.java b/src/main/java/net/minecraft/server/BiomeIceMountains.java -index d5033de8a..ad9b4efe0 100644 ---- a/src/main/java/net/minecraft/server/BiomeIceMountains.java -+++ b/src/main/java/net/minecraft/server/BiomeIceMountains.java -@@ -4,8 +4,8 @@ public final class BiomeIceMountains extends BiomeBase { - - public BiomeIceMountains() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.SNOW).a(BiomeBase.Geography.ICY).a(0.45F).b(0.3F).c(0.0F).d(0.5F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeIcePlains.java b/src/main/java/net/minecraft/server/BiomeIcePlains.java -index 054b0e0ab..71606b0a7 100644 ---- a/src/main/java/net/minecraft/server/BiomeIcePlains.java -+++ b/src/main/java/net/minecraft/server/BiomeIcePlains.java -@@ -4,11 +4,11 @@ public final class BiomeIcePlains extends BiomeBase { - - public BiomeIcePlains() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.SNOW).a(BiomeBase.Geography.ICY).a(0.125F).b(0.05F).c(0.0F).d(0.5F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.VILLAGE.b((WorldGenFeatureConfiguration) (new WorldGenFeatureVillageConfiguration("village/snowy/town_centers", 6)))); -- this.a(WorldGenerator.IGLOO.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenerator.PILLAGER_OUTPOST.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.VILLAGE.b(new WorldGenFeatureVillageConfiguration("village/snowy/town_centers", 6))); // Purpur - decompile error -+ this.a(WorldGenerator.IGLOO.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error -+ this.a(WorldGenerator.PILLAGER_OUTPOST.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeIcePlainsSpikes.java b/src/main/java/net/minecraft/server/BiomeIcePlainsSpikes.java -index 44c410f75..984f94bb5 100644 ---- a/src/main/java/net/minecraft/server/BiomeIcePlainsSpikes.java -+++ b/src/main/java/net/minecraft/server/BiomeIcePlainsSpikes.java -@@ -4,14 +4,14 @@ public final class BiomeIcePlainsSpikes extends BiomeBase { - - public BiomeIcePlainsSpikes() { - super((new BiomeBase.a()).a(WorldGenSurface.G, new WorldGenSurfaceConfigurationBase(Blocks.SNOW_BLOCK.getBlockData(), Blocks.DIRT.getBlockData(), Blocks.GRAVEL.getBlockData())).a(BiomeBase.Precipitation.SNOW).a(BiomeBase.Geography.ICY).a(0.425F).b(0.45000002F).c(0.0F).d(0.5F).a(4159204).b(329011).a("snowy_tundra")); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); - BiomeDecoratorGroups.f(this); -- this.a(WorldGenStage.Decoration.SURFACE_STRUCTURES, WorldGenerator.ICE_SPIKE.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e).a(WorldGenDecorator.b.a((WorldGenFeatureDecoratorConfiguration) (new WorldGenDecoratorFrequencyConfiguration(3))))); -- this.a(WorldGenStage.Decoration.SURFACE_STRUCTURES, WorldGenerator.ICE_PATCH.b((WorldGenFeatureConfiguration) (new WorldGenFeatureRadiusConfiguration(2))).a(WorldGenDecorator.b.a((WorldGenFeatureDecoratorConfiguration) (new WorldGenDecoratorFrequencyConfiguration(2))))); -+ this.a(WorldGenStage.Decoration.SURFACE_STRUCTURES, WorldGenerator.ICE_SPIKE.b(WorldGenFeatureConfiguration.e).a(WorldGenDecorator.b.a(new WorldGenDecoratorFrequencyConfiguration(3)))); // Purpur - decompile error -+ this.a(WorldGenStage.Decoration.SURFACE_STRUCTURES, WorldGenerator.ICE_PATCH.b(new WorldGenFeatureRadiusConfiguration(2)).a(WorldGenDecorator.b.a(new WorldGenDecoratorFrequencyConfiguration(2)))); // Purpur - decompile error - BiomeDecoratorGroups.g(this); - BiomeDecoratorGroups.h(this); - BiomeDecoratorGroups.l(this); -diff --git a/src/main/java/net/minecraft/server/BiomeJungle.java b/src/main/java/net/minecraft/server/BiomeJungle.java -index 2f893ce91..95e501996 100644 ---- a/src/main/java/net/minecraft/server/BiomeJungle.java -+++ b/src/main/java/net/minecraft/server/BiomeJungle.java -@@ -4,9 +4,9 @@ public final class BiomeJungle extends BiomeBase { - - public BiomeJungle() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.JUNGLE).a(0.1F).b(0.2F).c(0.95F).d(0.9F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.JUNGLE_TEMPLE.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.JUNGLE_TEMPLE.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeJungleEdge.java b/src/main/java/net/minecraft/server/BiomeJungleEdge.java -index 485861785..e624f9764 100644 ---- a/src/main/java/net/minecraft/server/BiomeJungleEdge.java -+++ b/src/main/java/net/minecraft/server/BiomeJungleEdge.java -@@ -4,8 +4,8 @@ public final class BiomeJungleEdge extends BiomeBase { - - public BiomeJungleEdge() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.JUNGLE).a(0.1F).b(0.2F).c(0.95F).d(0.8F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeJungleEdgeMutated.java b/src/main/java/net/minecraft/server/BiomeJungleEdgeMutated.java -index a957f6124..1fe9c840a 100644 ---- a/src/main/java/net/minecraft/server/BiomeJungleEdgeMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeJungleEdgeMutated.java -@@ -4,8 +4,8 @@ public final class BiomeJungleEdgeMutated extends BiomeBase { - - public BiomeJungleEdgeMutated() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.JUNGLE).a(0.2F).b(0.4F).c(0.95F).d(0.8F).a(4159204).b(329011).a("jungle_edge")); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeJungleHills.java b/src/main/java/net/minecraft/server/BiomeJungleHills.java -index 7b9bc967a..e2970ab00 100644 ---- a/src/main/java/net/minecraft/server/BiomeJungleHills.java -+++ b/src/main/java/net/minecraft/server/BiomeJungleHills.java -@@ -4,9 +4,9 @@ public final class BiomeJungleHills extends BiomeBase { - - public BiomeJungleHills() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.JUNGLE).a(0.45F).b(0.3F).c(0.95F).d(0.9F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.JUNGLE_TEMPLE.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.JUNGLE_TEMPLE.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeJungleMutated.java b/src/main/java/net/minecraft/server/BiomeJungleMutated.java -index 02246950d..ffe6b4344 100644 ---- a/src/main/java/net/minecraft/server/BiomeJungleMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeJungleMutated.java -@@ -4,8 +4,8 @@ public final class BiomeJungleMutated extends BiomeBase { - - public BiomeJungleMutated() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.JUNGLE).a(0.2F).b(0.4F).c(0.95F).d(0.9F).a(4159204).b(329011).a("jungle")); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeLukewarmDeepOcean.java b/src/main/java/net/minecraft/server/BiomeLukewarmDeepOcean.java -index e6d4a2c39..b23c43305 100644 ---- a/src/main/java/net/minecraft/server/BiomeLukewarmDeepOcean.java -+++ b/src/main/java/net/minecraft/server/BiomeLukewarmDeepOcean.java -@@ -4,10 +4,10 @@ public class BiomeLukewarmDeepOcean extends BiomeBase { - - public BiomeLukewarmDeepOcean() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.A).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.OCEAN).a(-1.8F).b(0.1F).c(0.5F).d(0.5F).a(4566514).b(267827).a((String) null)); -- this.a(WorldGenerator.OCEAN_RUIN.b((WorldGenFeatureConfiguration) (new WorldGenFeatureOceanRuinConfiguration(WorldGenFeatureOceanRuin.Temperature.WARM, 0.3F, 0.9F)))); -- this.a(WorldGenerator.OCEAN_MONUMENT.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.SHIPWRECK.b((WorldGenFeatureConfiguration) (new WorldGenFeatureShipwreckConfiguration(false)))); -+ this.a(WorldGenerator.OCEAN_RUIN.b(new WorldGenFeatureOceanRuinConfiguration(WorldGenFeatureOceanRuin.Temperature.WARM, 0.3F, 0.9F))); // Purpur - decompile error -+ this.a(WorldGenerator.OCEAN_MONUMENT.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.SHIPWRECK.b(new WorldGenFeatureShipwreckConfiguration(false))); // Purpur - decompile error - BiomeDecoratorGroups.b(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeLukewarmOcean.java b/src/main/java/net/minecraft/server/BiomeLukewarmOcean.java -index f2dc5d1b5..efcb11bbe 100644 ---- a/src/main/java/net/minecraft/server/BiomeLukewarmOcean.java -+++ b/src/main/java/net/minecraft/server/BiomeLukewarmOcean.java -@@ -4,9 +4,9 @@ public class BiomeLukewarmOcean extends BiomeBase { - - public BiomeLukewarmOcean() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.A).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.OCEAN).a(-1.0F).b(0.1F).c(0.5F).d(0.5F).a(4566514).b(267827).a((String) null)); -- this.a(WorldGenerator.OCEAN_RUIN.b((WorldGenFeatureConfiguration) (new WorldGenFeatureOceanRuinConfiguration(WorldGenFeatureOceanRuin.Temperature.WARM, 0.3F, 0.9F)))); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.SHIPWRECK.b((WorldGenFeatureConfiguration) (new WorldGenFeatureShipwreckConfiguration(false)))); -+ this.a(WorldGenerator.OCEAN_RUIN.b(new WorldGenFeatureOceanRuinConfiguration(WorldGenFeatureOceanRuin.Temperature.WARM, 0.3F, 0.9F))); // Purpur - decompile error -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.SHIPWRECK.b(new WorldGenFeatureShipwreckConfiguration(false))); // Purpur - decompile error - BiomeDecoratorGroups.b(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeMegaSpruceTaiga.java b/src/main/java/net/minecraft/server/BiomeMegaSpruceTaiga.java -index f6ec90c2d..328e939a6 100644 ---- a/src/main/java/net/minecraft/server/BiomeMegaSpruceTaiga.java -+++ b/src/main/java/net/minecraft/server/BiomeMegaSpruceTaiga.java -@@ -4,8 +4,8 @@ public final class BiomeMegaSpruceTaiga extends BiomeBase { - - public BiomeMegaSpruceTaiga() { - super((new BiomeBase.a()).a(WorldGenSurface.K, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.TAIGA).a(0.2F).b(0.2F).c(0.25F).d(0.8F).a(4159204).b(329011).a("giant_tree_taiga")); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeMegaTaiga.java b/src/main/java/net/minecraft/server/BiomeMegaTaiga.java -index e9ad930d8..36bea710a 100644 ---- a/src/main/java/net/minecraft/server/BiomeMegaTaiga.java -+++ b/src/main/java/net/minecraft/server/BiomeMegaTaiga.java -@@ -4,8 +4,8 @@ public final class BiomeMegaTaiga extends BiomeBase { - - public BiomeMegaTaiga() { - super((new BiomeBase.a()).a(WorldGenSurface.K, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.TAIGA).a(0.2F).b(0.2F).c(0.3F).d(0.8F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeMegaTaigaHills.java b/src/main/java/net/minecraft/server/BiomeMegaTaigaHills.java -index cdc182c22..22474d682 100644 ---- a/src/main/java/net/minecraft/server/BiomeMegaTaigaHills.java -+++ b/src/main/java/net/minecraft/server/BiomeMegaTaigaHills.java -@@ -4,8 +4,8 @@ public final class BiomeMegaTaigaHills extends BiomeBase { - - public BiomeMegaTaigaHills() { - super((new BiomeBase.a()).a(WorldGenSurface.K, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.TAIGA).a(0.45F).b(0.3F).c(0.3F).d(0.8F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeMesa.java b/src/main/java/net/minecraft/server/BiomeMesa.java -index 95e602a95..65d606d51 100644 ---- a/src/main/java/net/minecraft/server/BiomeMesa.java -+++ b/src/main/java/net/minecraft/server/BiomeMesa.java -@@ -4,8 +4,8 @@ public final class BiomeMesa extends BiomeBase { - - public BiomeMesa() { - super((new BiomeBase.a()).a(WorldGenSurface.M, WorldGenSurface.C).a(BiomeBase.Precipitation.NONE).a(BiomeBase.Geography.MESA).a(0.1F).b(0.2F).c(2.0F).d(0.0F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.MESA)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.MESA))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeMesaBryce.java b/src/main/java/net/minecraft/server/BiomeMesaBryce.java -index 57ef10afb..5ecec62f1 100644 ---- a/src/main/java/net/minecraft/server/BiomeMesaBryce.java -+++ b/src/main/java/net/minecraft/server/BiomeMesaBryce.java -@@ -4,8 +4,8 @@ public final class BiomeMesaBryce extends BiomeBase { - - public BiomeMesaBryce() { - super((new BiomeBase.a()).a(WorldGenSurface.O, WorldGenSurface.C).a(BiomeBase.Precipitation.NONE).a(BiomeBase.Geography.MESA).a(0.1F).b(0.2F).c(2.0F).d(0.0F).a(4159204).b(329011).a("badlands")); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.MESA)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.MESA))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeMesaPlataeu.java b/src/main/java/net/minecraft/server/BiomeMesaPlataeu.java -index b9f81a044..14d4bd312 100644 ---- a/src/main/java/net/minecraft/server/BiomeMesaPlataeu.java -+++ b/src/main/java/net/minecraft/server/BiomeMesaPlataeu.java -@@ -4,8 +4,8 @@ public final class BiomeMesaPlataeu extends BiomeBase { - - public BiomeMesaPlataeu() { - super((new BiomeBase.a()).a(WorldGenSurface.N, WorldGenSurface.C).a(BiomeBase.Precipitation.NONE).a(BiomeBase.Geography.MESA).a(1.5F).b(0.025F).c(2.0F).d(0.0F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.MESA)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.MESA))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeMesaPlataeuClear.java b/src/main/java/net/minecraft/server/BiomeMesaPlataeuClear.java -index 3ce8d3cef..b5dab9d2a 100644 ---- a/src/main/java/net/minecraft/server/BiomeMesaPlataeuClear.java -+++ b/src/main/java/net/minecraft/server/BiomeMesaPlataeuClear.java -@@ -4,8 +4,8 @@ public final class BiomeMesaPlataeuClear extends BiomeBase { - - public BiomeMesaPlataeuClear() { - super((new BiomeBase.a()).a(WorldGenSurface.M, WorldGenSurface.C).a(BiomeBase.Precipitation.NONE).a(BiomeBase.Geography.MESA).a(1.5F).b(0.025F).c(2.0F).d(0.0F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.MESA)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.MESA))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeMesaPlateauClearMutated.java b/src/main/java/net/minecraft/server/BiomeMesaPlateauClearMutated.java -index 88b7b3746..d05cc38b5 100644 ---- a/src/main/java/net/minecraft/server/BiomeMesaPlateauClearMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeMesaPlateauClearMutated.java -@@ -4,8 +4,8 @@ public final class BiomeMesaPlateauClearMutated extends BiomeBase { - - public BiomeMesaPlateauClearMutated() { - super((new BiomeBase.a()).a(WorldGenSurface.M, WorldGenSurface.C).a(BiomeBase.Precipitation.NONE).a(BiomeBase.Geography.MESA).a(0.45F).b(0.3F).c(2.0F).d(0.0F).a(4159204).b(329011).a("badlands_plateau")); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.MESA)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.MESA))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeMesaPlateauMutated.java b/src/main/java/net/minecraft/server/BiomeMesaPlateauMutated.java -index 7254bcf3e..21a77ee81 100644 ---- a/src/main/java/net/minecraft/server/BiomeMesaPlateauMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeMesaPlateauMutated.java -@@ -4,8 +4,8 @@ public final class BiomeMesaPlateauMutated extends BiomeBase { - - public BiomeMesaPlateauMutated() { - super((new BiomeBase.a()).a(WorldGenSurface.N, WorldGenSurface.C).a(BiomeBase.Precipitation.NONE).a(BiomeBase.Geography.MESA).a(0.45F).b(0.3F).c(2.0F).d(0.0F).a(4159204).b(329011).a("wooded_badlands_plateau")); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.MESA)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.MESA))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeMushroomIslandShore.java b/src/main/java/net/minecraft/server/BiomeMushroomIslandShore.java -index 58bc1f234..0302efbdc 100644 ---- a/src/main/java/net/minecraft/server/BiomeMushroomIslandShore.java -+++ b/src/main/java/net/minecraft/server/BiomeMushroomIslandShore.java -@@ -4,8 +4,8 @@ public final class BiomeMushroomIslandShore extends BiomeBase { - - public BiomeMushroomIslandShore() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.D).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.MUSHROOM).a(0.0F).b(0.025F).c(0.9F).d(1.0F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeMushrooms.java b/src/main/java/net/minecraft/server/BiomeMushrooms.java -index cb620014b..51f92584b 100644 ---- a/src/main/java/net/minecraft/server/BiomeMushrooms.java -+++ b/src/main/java/net/minecraft/server/BiomeMushrooms.java -@@ -4,8 +4,8 @@ public final class BiomeMushrooms extends BiomeBase { - - public BiomeMushrooms() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.D).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.MUSHROOM).a(0.2F).b(0.3F).c(0.9F).d(1.0F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeOcean.java b/src/main/java/net/minecraft/server/BiomeOcean.java -index fd7e99106..ad9628b2a 100644 ---- a/src/main/java/net/minecraft/server/BiomeOcean.java -+++ b/src/main/java/net/minecraft/server/BiomeOcean.java -@@ -4,9 +4,9 @@ public final class BiomeOcean extends BiomeBase { - - public BiomeOcean() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.OCEAN).a(-1.0F).b(0.1F).c(0.5F).d(0.5F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.SHIPWRECK.b((WorldGenFeatureConfiguration) (new WorldGenFeatureShipwreckConfiguration(false)))); -- this.a(WorldGenerator.OCEAN_RUIN.b((WorldGenFeatureConfiguration) (new WorldGenFeatureOceanRuinConfiguration(WorldGenFeatureOceanRuin.Temperature.COLD, 0.3F, 0.9F)))); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.SHIPWRECK.b(new WorldGenFeatureShipwreckConfiguration(false))); // Purpur - decompile error -+ this.a(WorldGenerator.OCEAN_RUIN.b(new WorldGenFeatureOceanRuinConfiguration(WorldGenFeatureOceanRuin.Temperature.COLD, 0.3F, 0.9F))); // Purpur - decompile error - BiomeDecoratorGroups.b(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -@@ -20,7 +20,7 @@ public final class BiomeOcean extends BiomeBase { - BiomeDecoratorGroups.Z(this); - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); -- this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.SEAGRASS.b((WorldGenFeatureConfiguration) (new WorldGenFeatureSeaGrassConfiguration(48, 0.3D))).a(WorldGenDecorator.v.a((WorldGenFeatureDecoratorConfiguration) WorldGenFeatureDecoratorConfiguration.e))); -+ this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.SEAGRASS.b(new WorldGenFeatureSeaGrassConfiguration(48, 0.3D)).a(WorldGenDecorator.v.a(WorldGenFeatureDecoratorConfiguration.e))); // Purpur - decompile error - BiomeDecoratorGroups.ai(this); - BiomeDecoratorGroups.ah(this); - BiomeDecoratorGroups.ap(this); -diff --git a/src/main/java/net/minecraft/server/BiomePlains.java b/src/main/java/net/minecraft/server/BiomePlains.java -index efbb36d01..ff6090e3c 100644 ---- a/src/main/java/net/minecraft/server/BiomePlains.java -+++ b/src/main/java/net/minecraft/server/BiomePlains.java -@@ -4,10 +4,10 @@ public final class BiomePlains extends BiomeBase { - - protected BiomePlains() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.PLAINS).a(0.125F).b(0.05F).c(0.8F).d(0.4F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.VILLAGE.b((WorldGenFeatureConfiguration) (new WorldGenFeatureVillageConfiguration("village/plains/town_centers", 6)))); -- this.a(WorldGenerator.PILLAGER_OUTPOST.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.VILLAGE.b(new WorldGenFeatureVillageConfiguration("village/plains/town_centers", 6))); // Purpur - decompile error -+ this.a(WorldGenerator.PILLAGER_OUTPOST.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeRedwoodTaigaHillsMutated.java b/src/main/java/net/minecraft/server/BiomeRedwoodTaigaHillsMutated.java -index 7804a4e32..a28222eb1 100644 ---- a/src/main/java/net/minecraft/server/BiomeRedwoodTaigaHillsMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeRedwoodTaigaHillsMutated.java -@@ -4,8 +4,8 @@ public final class BiomeRedwoodTaigaHillsMutated extends BiomeBase { - - public BiomeRedwoodTaigaHillsMutated() { - super((new BiomeBase.a()).a(WorldGenSurface.K, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.TAIGA).a(0.2F).b(0.2F).c(0.25F).d(0.8F).a(4159204).b(329011).a("giant_tree_taiga_hills")); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeRiver.java b/src/main/java/net/minecraft/server/BiomeRiver.java -index 6522c8021..b84b868b1 100644 ---- a/src/main/java/net/minecraft/server/BiomeRiver.java -+++ b/src/main/java/net/minecraft/server/BiomeRiver.java -@@ -4,7 +4,7 @@ public final class BiomeRiver extends BiomeBase { - - public BiomeRiver() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.RIVER).a(-0.5F).b(0.0F).c(0.5F).d(0.5F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -@@ -18,7 +18,7 @@ public final class BiomeRiver extends BiomeBase { - BiomeDecoratorGroups.Z(this); - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); -- this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.SEAGRASS.b((WorldGenFeatureConfiguration) (new WorldGenFeatureSeaGrassConfiguration(48, 0.4D))).a(WorldGenDecorator.v.a((WorldGenFeatureDecoratorConfiguration) WorldGenFeatureDecoratorConfiguration.e))); -+ this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.SEAGRASS.b(new WorldGenFeatureSeaGrassConfiguration(48, 0.4D)).a(WorldGenDecorator.v.a(WorldGenFeatureDecoratorConfiguration.e))); // Purpur - decompile error - BiomeDecoratorGroups.ap(this); - this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SQUID, 2, 1, 4)); - this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SALMON, 5, 1, 5)); -diff --git a/src/main/java/net/minecraft/server/BiomeRoofedForest.java b/src/main/java/net/minecraft/server/BiomeRoofedForest.java -index 30d680224..16bcf9bff 100644 ---- a/src/main/java/net/minecraft/server/BiomeRoofedForest.java -+++ b/src/main/java/net/minecraft/server/BiomeRoofedForest.java -@@ -6,14 +6,14 @@ public final class BiomeRoofedForest extends BiomeBase { - - public BiomeRoofedForest() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.FOREST).a(0.1F).b(0.2F).c(0.7F).d(0.8F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.WOODLAND_MANSION.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.WOODLAND_MANSION.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); - BiomeDecoratorGroups.f(this); -- this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.RANDOM_SELECTOR.b((WorldGenFeatureConfiguration) (new WorldGenFeatureRandomChoiceConfiguration(ImmutableList.of(WorldGenerator.HUGE_BROWN_MUSHROOM.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.HUGE_BROWN_MUSHROOM).a(0.025F), WorldGenerator.HUGE_RED_MUSHROOM.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.HUGE_RED_MUSHROOM).a(0.05F), WorldGenerator.DARK_OAK_TREE.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.DARK_OAK_TREE).a(0.6666667F), WorldGenerator.NORMAL_TREE.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.BIRCH_TREE).a(0.2F), WorldGenerator.FANCY_TREE.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.FANCY_TREE).a(0.1F)), WorldGenerator.NORMAL_TREE.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.NORMAL_TREE)))).a(WorldGenDecorator.G.a((WorldGenFeatureDecoratorConfiguration) WorldGenFeatureDecoratorConfiguration.e))); -+ this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.RANDOM_SELECTOR.b(new WorldGenFeatureRandomChoiceConfiguration(ImmutableList.of(WorldGenerator.HUGE_BROWN_MUSHROOM.b(BiomeDecoratorGroups.HUGE_BROWN_MUSHROOM).a(0.025F), WorldGenerator.HUGE_RED_MUSHROOM.b(BiomeDecoratorGroups.HUGE_RED_MUSHROOM).a(0.05F), WorldGenerator.DARK_OAK_TREE.b(BiomeDecoratorGroups.DARK_OAK_TREE).a(0.6666667F), WorldGenerator.NORMAL_TREE.b(BiomeDecoratorGroups.BIRCH_TREE).a(0.2F), WorldGenerator.FANCY_TREE.b(BiomeDecoratorGroups.FANCY_TREE).a(0.1F)), WorldGenerator.NORMAL_TREE.b(BiomeDecoratorGroups.NORMAL_TREE))).a(WorldGenDecorator.G.a(WorldGenFeatureDecoratorConfiguration.e))); // Purpur - decompile error - BiomeDecoratorGroups.N(this); - BiomeDecoratorGroups.g(this); - BiomeDecoratorGroups.h(this); -diff --git a/src/main/java/net/minecraft/server/BiomeRoofedForestMutated.java b/src/main/java/net/minecraft/server/BiomeRoofedForestMutated.java -index 5c9ab0864..9fa84c87f 100644 ---- a/src/main/java/net/minecraft/server/BiomeRoofedForestMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeRoofedForestMutated.java -@@ -6,14 +6,14 @@ public final class BiomeRoofedForestMutated extends BiomeBase { - - public BiomeRoofedForestMutated() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.FOREST).a(0.2F).b(0.4F).c(0.7F).d(0.8F).a(4159204).b(329011).a("dark_forest")); -- this.a(WorldGenerator.WOODLAND_MANSION.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.WOODLAND_MANSION.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); - BiomeDecoratorGroups.f(this); -- this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.RANDOM_SELECTOR.b((WorldGenFeatureConfiguration) (new WorldGenFeatureRandomChoiceConfiguration(ImmutableList.of(WorldGenerator.HUGE_RED_MUSHROOM.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.HUGE_RED_MUSHROOM).a(0.025F), WorldGenerator.HUGE_BROWN_MUSHROOM.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.HUGE_BROWN_MUSHROOM).a(0.05F), WorldGenerator.DARK_OAK_TREE.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.DARK_OAK_TREE).a(0.6666667F), WorldGenerator.NORMAL_TREE.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.BIRCH_TREE).a(0.2F), WorldGenerator.FANCY_TREE.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.FANCY_TREE).a(0.1F)), WorldGenerator.NORMAL_TREE.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.NORMAL_TREE)))).a(WorldGenDecorator.G.a((WorldGenFeatureDecoratorConfiguration) WorldGenFeatureDecoratorConfiguration.e))); -+ this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.RANDOM_SELECTOR.b(new WorldGenFeatureRandomChoiceConfiguration(ImmutableList.of(WorldGenerator.HUGE_RED_MUSHROOM.b(BiomeDecoratorGroups.HUGE_RED_MUSHROOM).a(0.025F), WorldGenerator.HUGE_BROWN_MUSHROOM.b(BiomeDecoratorGroups.HUGE_BROWN_MUSHROOM).a(0.05F), WorldGenerator.DARK_OAK_TREE.b(BiomeDecoratorGroups.DARK_OAK_TREE).a(0.6666667F), WorldGenerator.NORMAL_TREE.b(BiomeDecoratorGroups.BIRCH_TREE).a(0.2F), WorldGenerator.FANCY_TREE.b(BiomeDecoratorGroups.FANCY_TREE).a(0.1F)), WorldGenerator.NORMAL_TREE.b(BiomeDecoratorGroups.NORMAL_TREE))).a(WorldGenDecorator.G.a(WorldGenFeatureDecoratorConfiguration.e))); // Purpur - decompile error - BiomeDecoratorGroups.N(this); - BiomeDecoratorGroups.g(this); - BiomeDecoratorGroups.h(this); -diff --git a/src/main/java/net/minecraft/server/BiomeSavanna.java b/src/main/java/net/minecraft/server/BiomeSavanna.java -index e023898b3..c12a89016 100644 ---- a/src/main/java/net/minecraft/server/BiomeSavanna.java -+++ b/src/main/java/net/minecraft/server/BiomeSavanna.java -@@ -4,10 +4,10 @@ public final class BiomeSavanna extends BiomeBase { - - protected BiomeSavanna() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.NONE).a(BiomeBase.Geography.SAVANNA).a(0.125F).b(0.05F).c(1.2F).d(0.0F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.VILLAGE.b((WorldGenFeatureConfiguration) (new WorldGenFeatureVillageConfiguration("village/savanna/town_centers", 6)))); -- this.a(WorldGenerator.PILLAGER_OUTPOST.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.VILLAGE.b(new WorldGenFeatureVillageConfiguration("village/savanna/town_centers", 6))); // Purpur - decompile error -+ this.a(WorldGenerator.PILLAGER_OUTPOST.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeSavannaMutated.java b/src/main/java/net/minecraft/server/BiomeSavannaMutated.java -index 8a0da661f..db8b20a6c 100644 ---- a/src/main/java/net/minecraft/server/BiomeSavannaMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeSavannaMutated.java -@@ -4,8 +4,8 @@ public final class BiomeSavannaMutated extends BiomeBase { - - public BiomeSavannaMutated() { - super((new BiomeBase.a()).a(WorldGenSurface.I, WorldGenSurface.v).a(BiomeBase.Precipitation.NONE).a(BiomeBase.Geography.SAVANNA).a(0.3625F).b(1.225F).c(1.1F).d(0.0F).a(4159204).b(329011).a("savanna")); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeSavannaPlateau.java b/src/main/java/net/minecraft/server/BiomeSavannaPlateau.java -index 1d2a37a41..2826c510d 100644 ---- a/src/main/java/net/minecraft/server/BiomeSavannaPlateau.java -+++ b/src/main/java/net/minecraft/server/BiomeSavannaPlateau.java -@@ -4,8 +4,8 @@ public final class BiomeSavannaPlateau extends BiomeBase { - - protected BiomeSavannaPlateau() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.NONE).a(BiomeBase.Geography.SAVANNA).a(1.5F).b(0.025F).c(1.0F).d(0.0F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeSavannaPlateauMutated.java b/src/main/java/net/minecraft/server/BiomeSavannaPlateauMutated.java -index 91e2b5903..e544a8f6b 100644 ---- a/src/main/java/net/minecraft/server/BiomeSavannaPlateauMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeSavannaPlateauMutated.java -@@ -4,8 +4,8 @@ public final class BiomeSavannaPlateauMutated extends BiomeBase { - - public BiomeSavannaPlateauMutated() { - super((new BiomeBase.a()).a(WorldGenSurface.I, WorldGenSurface.v).a(BiomeBase.Precipitation.NONE).a(BiomeBase.Geography.SAVANNA).a(1.05F).b(1.2125001F).c(1.0F).d(0.0F).a(4159204).b(329011).a("savanna_plateau")); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeStoneBeach.java b/src/main/java/net/minecraft/server/BiomeStoneBeach.java -index 501c36649..34660f9f8 100644 ---- a/src/main/java/net/minecraft/server/BiomeStoneBeach.java -+++ b/src/main/java/net/minecraft/server/BiomeStoneBeach.java -@@ -4,8 +4,8 @@ public final class BiomeStoneBeach extends BiomeBase { - - public BiomeStoneBeach() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.x).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.NONE).a(0.1F).b(0.8F).c(0.2F).d(0.3F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeSunflowerPlains.java b/src/main/java/net/minecraft/server/BiomeSunflowerPlains.java -index 62c1cfaef..8815c9590 100644 ---- a/src/main/java/net/minecraft/server/BiomeSunflowerPlains.java -+++ b/src/main/java/net/minecraft/server/BiomeSunflowerPlains.java -@@ -4,21 +4,21 @@ public final class BiomeSunflowerPlains extends BiomeBase { - - protected BiomeSunflowerPlains() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.PLAINS).a(0.125F).b(0.05F).c(0.8F).d(0.4F).a(4159204).b(329011).a("plains")); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); - BiomeDecoratorGroups.f(this); - BiomeDecoratorGroups.Y(this); -- this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.RANDOM_PATCH.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.R).a(WorldGenDecorator.d.a((WorldGenFeatureDecoratorConfiguration) (new WorldGenDecoratorFrequencyConfiguration(10))))); -+ this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.RANDOM_PATCH.b(BiomeDecoratorGroups.R).a(WorldGenDecorator.d.a(new WorldGenDecoratorFrequencyConfiguration(10)))); // Purpur - decompile error - BiomeDecoratorGroups.g(this); - BiomeDecoratorGroups.h(this); - BiomeDecoratorGroups.l(this); - BiomeDecoratorGroups.R(this); -- this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.RANDOM_PATCH.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.V).a(WorldGenDecorator.e.a((WorldGenFeatureDecoratorConfiguration) (new WorldGenDecoratorFrequencyConfiguration(10))))); -+ this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.RANDOM_PATCH.b(BiomeDecoratorGroups.V).a(WorldGenDecorator.e.a(new WorldGenDecoratorFrequencyConfiguration(10)))); // Purpur - decompile error - BiomeDecoratorGroups.Z(this); -- this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.RANDOM_PATCH.b((WorldGenFeatureConfiguration) BiomeDecoratorGroups.I).a(WorldGenDecorator.j.a((WorldGenFeatureDecoratorConfiguration) (new WorldGenDecoratorDungeonConfiguration(32))))); -+ this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.RANDOM_PATCH.b(BiomeDecoratorGroups.I).a(WorldGenDecorator.j.a(new WorldGenDecoratorDungeonConfiguration(32)))); // Purpur - decompile error - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); - this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -diff --git a/src/main/java/net/minecraft/server/BiomeSwamp.java b/src/main/java/net/minecraft/server/BiomeSwamp.java -index 29e448f5a..02584897e 100644 ---- a/src/main/java/net/minecraft/server/BiomeSwamp.java -+++ b/src/main/java/net/minecraft/server/BiomeSwamp.java -@@ -4,8 +4,8 @@ public final class BiomeSwamp extends BiomeBase { - - protected BiomeSwamp() { - super((new BiomeBase.a()).a(WorldGenSurface.L, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.SWAMP).a(-0.2F).b(0.1F).c(0.8F).d(0.9F).a(6388580).b(2302743).a((String) null)); -- this.a(WorldGenerator.SWAMP_HUT.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -+ this.a(WorldGenerator.SWAMP_HUT.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -@@ -17,7 +17,7 @@ public final class BiomeSwamp extends BiomeBase { - BiomeDecoratorGroups.Z(this); - BiomeDecoratorGroups.ae(this); - BiomeDecoratorGroups.am(this); -- this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.SEAGRASS.b((WorldGenFeatureConfiguration) (new WorldGenFeatureSeaGrassConfiguration(64, 0.6D))).a(WorldGenDecorator.v.a((WorldGenFeatureDecoratorConfiguration) WorldGenFeatureDecoratorConfiguration.e))); -+ this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.SEAGRASS.b(new WorldGenFeatureSeaGrassConfiguration(64, 0.6D)).a(WorldGenDecorator.v.a(WorldGenFeatureDecoratorConfiguration.e))); // Purpur - decompile error - BiomeDecoratorGroups.ag(this); - BiomeDecoratorGroups.ap(this); - this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -diff --git a/src/main/java/net/minecraft/server/BiomeSwamplandMutated.java b/src/main/java/net/minecraft/server/BiomeSwamplandMutated.java -index 1352daa25..d85b01b95 100644 ---- a/src/main/java/net/minecraft/server/BiomeSwamplandMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeSwamplandMutated.java -@@ -4,7 +4,7 @@ public final class BiomeSwamplandMutated extends BiomeBase { - - protected BiomeSwamplandMutated() { - super((new BiomeBase.a()).a(WorldGenSurface.L, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.SWAMP).a(-0.1F).b(0.3F).c(0.8F).d(0.9F).a(6388580).b(2302743).a("swamp")); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeTaiga.java b/src/main/java/net/minecraft/server/BiomeTaiga.java -index 5cd569dcd..ae6e6ca89 100644 ---- a/src/main/java/net/minecraft/server/BiomeTaiga.java -+++ b/src/main/java/net/minecraft/server/BiomeTaiga.java -@@ -4,10 +4,10 @@ public final class BiomeTaiga extends BiomeBase { - - public BiomeTaiga() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.TAIGA).a(0.2F).b(0.2F).c(0.25F).d(0.8F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.VILLAGE.b((WorldGenFeatureConfiguration) (new WorldGenFeatureVillageConfiguration("village/taiga/town_centers", 6)))); -- this.a(WorldGenerator.PILLAGER_OUTPOST.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.VILLAGE.b(new WorldGenFeatureVillageConfiguration("village/taiga/town_centers", 6))); // Purpur - decompile error -+ this.a(WorldGenerator.PILLAGER_OUTPOST.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeTaigaHills.java b/src/main/java/net/minecraft/server/BiomeTaigaHills.java -index e182f0400..4e19fe5ae 100644 ---- a/src/main/java/net/minecraft/server/BiomeTaigaHills.java -+++ b/src/main/java/net/minecraft/server/BiomeTaigaHills.java -@@ -4,8 +4,8 @@ public final class BiomeTaigaHills extends BiomeBase { - - public BiomeTaigaHills() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.TAIGA).a(0.45F).b(0.3F).c(0.25F).d(0.8F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeTaigaMutated.java b/src/main/java/net/minecraft/server/BiomeTaigaMutated.java -index 75d46c61d..05e833ffe 100644 ---- a/src/main/java/net/minecraft/server/BiomeTaigaMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeTaigaMutated.java -@@ -4,8 +4,8 @@ public final class BiomeTaigaMutated extends BiomeBase { - - public BiomeTaigaMutated() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.v).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.TAIGA).a(0.3F).b(0.4F).c(0.25F).d(0.8F).a(4159204).b(329011).a("taiga")); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.STRONGHOLD.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.STRONGHOLD.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.a(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeTheEnd.java b/src/main/java/net/minecraft/server/BiomeTheEnd.java -index 26fda2cf6..22e9789a3 100644 ---- a/src/main/java/net/minecraft/server/BiomeTheEnd.java -+++ b/src/main/java/net/minecraft/server/BiomeTheEnd.java -@@ -6,7 +6,7 @@ public final class BiomeTheEnd extends BiomeBase { - - public BiomeTheEnd() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.F).a(BiomeBase.Precipitation.NONE).a(BiomeBase.Geography.THEEND).a(0.1F).b(0.2F).c(0.5F).d(0.5F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenStage.Decoration.SURFACE_STRUCTURES, WorldGenerator.END_SPIKE.b((WorldGenFeatureConfiguration) (new WorldGenFeatureEndSpikeConfiguration(false, ImmutableList.of(), (BlockPosition) null))).a(WorldGenDecorator.a.a((WorldGenFeatureDecoratorConfiguration) WorldGenFeatureDecoratorConfiguration.e))); -+ this.a(WorldGenStage.Decoration.SURFACE_STRUCTURES, WorldGenerator.END_SPIKE.b(new WorldGenFeatureEndSpikeConfiguration(false, ImmutableList.of(), (BlockPosition) null)).a(WorldGenDecorator.a.a(WorldGenFeatureDecoratorConfiguration.e))); // Purpur - decompile error - BiomeDecoratorGroups.aq(this); - this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 4, 4)); - } -diff --git a/src/main/java/net/minecraft/server/BiomeTheEndFloatingIslands.java b/src/main/java/net/minecraft/server/BiomeTheEndFloatingIslands.java -index c06512864..a26d56aa4 100644 ---- a/src/main/java/net/minecraft/server/BiomeTheEndFloatingIslands.java -+++ b/src/main/java/net/minecraft/server/BiomeTheEndFloatingIslands.java -@@ -4,7 +4,7 @@ public class BiomeTheEndFloatingIslands extends BiomeBase { - - public BiomeTheEndFloatingIslands() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.F).a(BiomeBase.Precipitation.NONE).a(BiomeBase.Geography.THEEND).a(0.1F).b(0.2F).c(0.5F).d(0.5F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenStage.Decoration.RAW_GENERATION, WorldGenerator.END_ISLAND.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e).a(WorldGenDecorator.J.a((WorldGenFeatureDecoratorConfiguration) WorldGenFeatureDecoratorConfiguration.e))); -+ this.a(WorldGenStage.Decoration.RAW_GENERATION, WorldGenerator.END_ISLAND.b(WorldGenFeatureConfiguration.e).a(WorldGenDecorator.J.a(WorldGenFeatureDecoratorConfiguration.e))); // Purpur - decompile error - BiomeDecoratorGroups.aq(this); - this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 4, 4)); - } -diff --git a/src/main/java/net/minecraft/server/BiomeTheEndHighIsland.java b/src/main/java/net/minecraft/server/BiomeTheEndHighIsland.java -index 90e79b291..e47add3e4 100644 ---- a/src/main/java/net/minecraft/server/BiomeTheEndHighIsland.java -+++ b/src/main/java/net/minecraft/server/BiomeTheEndHighIsland.java -@@ -4,10 +4,10 @@ public class BiomeTheEndHighIsland extends BiomeBase { - - public BiomeTheEndHighIsland() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.F).a(BiomeBase.Precipitation.NONE).a(BiomeBase.Geography.THEEND).a(0.1F).b(0.2F).c(0.5F).d(0.5F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.END_CITY.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenStage.Decoration.SURFACE_STRUCTURES, WorldGenerator.END_GATEWAY.b((WorldGenFeatureConfiguration) WorldGenEndGatewayConfiguration.a(WorldProviderTheEnd.f, true)).a(WorldGenDecorator.L.a((WorldGenFeatureDecoratorConfiguration) WorldGenFeatureDecoratorConfiguration.e))); -+ this.a(WorldGenerator.END_CITY.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error -+ this.a(WorldGenStage.Decoration.SURFACE_STRUCTURES, WorldGenerator.END_GATEWAY.b(WorldGenEndGatewayConfiguration.a(WorldProviderTheEnd.f, true)).a(WorldGenDecorator.L.a(WorldGenFeatureDecoratorConfiguration.e))); // Purpur - decompile error - BiomeDecoratorGroups.aq(this); -- this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.CHORUS_PLANT.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e).a(WorldGenDecorator.K.a((WorldGenFeatureDecoratorConfiguration) WorldGenFeatureDecoratorConfiguration.e))); -+ this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.CHORUS_PLANT.b(WorldGenFeatureConfiguration.e).a(WorldGenDecorator.K.a(WorldGenFeatureDecoratorConfiguration.e))); // Purpur - decompile error - this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 4, 4)); - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeTheEndMediumIsland.java b/src/main/java/net/minecraft/server/BiomeTheEndMediumIsland.java -index c7d5317cc..ec92a8457 100644 ---- a/src/main/java/net/minecraft/server/BiomeTheEndMediumIsland.java -+++ b/src/main/java/net/minecraft/server/BiomeTheEndMediumIsland.java -@@ -4,7 +4,7 @@ public class BiomeTheEndMediumIsland extends BiomeBase { - - public BiomeTheEndMediumIsland() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.F).a(BiomeBase.Precipitation.NONE).a(BiomeBase.Geography.THEEND).a(0.1F).b(0.2F).c(0.5F).d(0.5F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenerator.END_CITY.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -+ this.a(WorldGenerator.END_CITY.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.aq(this); - this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 4, 4)); - } -diff --git a/src/main/java/net/minecraft/server/BiomeVoid.java b/src/main/java/net/minecraft/server/BiomeVoid.java -index 87fd7e146..c9ba33453 100644 ---- a/src/main/java/net/minecraft/server/BiomeVoid.java -+++ b/src/main/java/net/minecraft/server/BiomeVoid.java -@@ -4,6 +4,6 @@ public final class BiomeVoid extends BiomeBase { - - public BiomeVoid() { - super((new BiomeBase.a()).a(WorldGenSurface.R, WorldGenSurface.x).a(BiomeBase.Precipitation.NONE).a(BiomeBase.Geography.NONE).a(0.1F).b(0.2F).c(0.5F).d(0.5F).a(4159204).b(329011).a((String) null)); -- this.a(WorldGenStage.Decoration.TOP_LAYER_MODIFICATION, WorldGenerator.VOID_START_PLATFORM.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e).a(WorldGenDecorator.a.a((WorldGenFeatureDecoratorConfiguration) WorldGenFeatureDecoratorConfiguration.e))); -+ this.a(WorldGenStage.Decoration.TOP_LAYER_MODIFICATION, WorldGenerator.VOID_START_PLATFORM.b(WorldGenFeatureConfiguration.e).a(WorldGenDecorator.a.a(WorldGenFeatureDecoratorConfiguration.e))); // Purpur - decompile error - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeWarmDeepOcean.java b/src/main/java/net/minecraft/server/BiomeWarmDeepOcean.java -index 3f8e18a2c..11dc5f637 100644 ---- a/src/main/java/net/minecraft/server/BiomeWarmDeepOcean.java -+++ b/src/main/java/net/minecraft/server/BiomeWarmDeepOcean.java -@@ -4,10 +4,10 @@ public class BiomeWarmDeepOcean extends BiomeBase { - - public BiomeWarmDeepOcean() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.B).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.OCEAN).a(-1.8F).b(0.1F).c(0.5F).d(0.5F).a(4445678).b(270131).a((String) null)); -- this.a(WorldGenerator.OCEAN_RUIN.b((WorldGenFeatureConfiguration) (new WorldGenFeatureOceanRuinConfiguration(WorldGenFeatureOceanRuin.Temperature.WARM, 0.3F, 0.9F)))); -- this.a(WorldGenerator.OCEAN_MONUMENT.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e)); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.SHIPWRECK.b((WorldGenFeatureConfiguration) (new WorldGenFeatureShipwreckConfiguration(false)))); -+ this.a(WorldGenerator.OCEAN_RUIN.b(new WorldGenFeatureOceanRuinConfiguration(WorldGenFeatureOceanRuin.Temperature.WARM, 0.3F, 0.9F))); // Purpur - decompile error -+ this.a(WorldGenerator.OCEAN_MONUMENT.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.SHIPWRECK.b(new WorldGenFeatureShipwreckConfiguration(false))); // Purpur - decompile error - BiomeDecoratorGroups.b(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -diff --git a/src/main/java/net/minecraft/server/BiomeWarmOcean.java b/src/main/java/net/minecraft/server/BiomeWarmOcean.java -index dd7916c09..e4dc7d198 100644 ---- a/src/main/java/net/minecraft/server/BiomeWarmOcean.java -+++ b/src/main/java/net/minecraft/server/BiomeWarmOcean.java -@@ -6,9 +6,9 @@ public class BiomeWarmOcean extends BiomeBase { - - public BiomeWarmOcean() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.B).a(BiomeBase.Precipitation.RAIN).a(BiomeBase.Geography.OCEAN).a(-1.0F).b(0.1F).c(0.5F).d(0.5F).a(4445678).b(270131).a((String) null)); -- this.a(WorldGenerator.OCEAN_RUIN.b((WorldGenFeatureConfiguration) (new WorldGenFeatureOceanRuinConfiguration(WorldGenFeatureOceanRuin.Temperature.WARM, 0.3F, 0.9F)))); -- this.a(WorldGenerator.MINESHAFT.b((WorldGenFeatureConfiguration) (new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL)))); -- this.a(WorldGenerator.SHIPWRECK.b((WorldGenFeatureConfiguration) (new WorldGenFeatureShipwreckConfiguration(false)))); -+ this.a(WorldGenerator.OCEAN_RUIN.b(new WorldGenFeatureOceanRuinConfiguration(WorldGenFeatureOceanRuin.Temperature.WARM, 0.3F, 0.9F))); // Purpur - decompile error -+ this.a(WorldGenerator.MINESHAFT.b(new WorldGenMineshaftConfiguration(0.004D, WorldGenMineshaft.Type.NORMAL))); // Purpur - decompile error -+ this.a(WorldGenerator.SHIPWRECK.b(new WorldGenFeatureShipwreckConfiguration(false))); // Purpur - decompile error - BiomeDecoratorGroups.b(this); - BiomeDecoratorGroups.c(this); - BiomeDecoratorGroups.d(this); -@@ -22,9 +22,9 @@ public class BiomeWarmOcean extends BiomeBase { - BiomeDecoratorGroups.Z(this); - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); -- this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.SIMPLE_RANDOM_SELECTOR.b((WorldGenFeatureConfiguration) (new WorldGenFeatureRandom2(ImmutableList.of(WorldGenerator.CORAL_TREE.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e), WorldGenerator.CORAL_CLAW.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e), WorldGenerator.CORAL_MUSHROOM.b((WorldGenFeatureConfiguration) WorldGenFeatureConfiguration.e))))).a(WorldGenDecorator.x.a((WorldGenFeatureDecoratorConfiguration) (new WorldGenDecoratorNoiseConfiguration(20, 400.0D, 0.0D, HeightMap.Type.OCEAN_FLOOR_WG))))); -+ this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.SIMPLE_RANDOM_SELECTOR.b(new WorldGenFeatureRandom2(ImmutableList.of(WorldGenerator.CORAL_TREE.b(WorldGenFeatureConfiguration.e), WorldGenerator.CORAL_CLAW.b(WorldGenFeatureConfiguration.e), WorldGenerator.CORAL_MUSHROOM.b(WorldGenFeatureConfiguration.e)))).a(WorldGenDecorator.x.a(new WorldGenDecoratorNoiseConfiguration(20, 400.0D, 0.0D, HeightMap.Type.OCEAN_FLOOR_WG)))); // Purpur - decompile error - BiomeDecoratorGroups.aj(this); -- this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.SEA_PICKLE.b((WorldGenFeatureConfiguration) (new WorldGenFeatureKelpConfiguration(20))).a(WorldGenDecorator.l.a((WorldGenFeatureDecoratorConfiguration) (new WorldGenDecoratorDungeonConfiguration(16))))); -+ this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.SEA_PICKLE.b(new WorldGenFeatureKelpConfiguration(20)).a(WorldGenDecorator.l.a(new WorldGenDecoratorDungeonConfiguration(16)))); // Purpur - decompile error - BiomeDecoratorGroups.ap(this); - this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SQUID, 10, 4, 4)); - this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PUFFERFISH, 15, 1, 3)); -diff --git a/src/main/java/net/minecraft/server/CommandDebug.java b/src/main/java/net/minecraft/server/CommandDebug.java -index d384e9578..f0d72ea39 100644 ---- a/src/main/java/net/minecraft/server/CommandDebug.java -+++ b/src/main/java/net/minecraft/server/CommandDebug.java -@@ -25,7 +25,7 @@ public class CommandDebug { - @Nullable - private static final FileSystemProvider d = (FileSystemProvider) FileSystemProvider.installedProviders().stream().filter((filesystemprovider) -> { - return filesystemprovider.getScheme().equalsIgnoreCase("jar"); -- }).findFirst().orElse((Object) null); -+ }).findFirst().orElse(null); // Purpur - decompile error - - public static void a(com.mojang.brigadier.CommandDispatcher com_mojang_brigadier_commanddispatcher) { - com_mojang_brigadier_commanddispatcher.register((LiteralArgumentBuilder) ((LiteralArgumentBuilder) ((LiteralArgumentBuilder) ((LiteralArgumentBuilder) CommandDispatcher.a("debug").requires((commandlistenerwrapper) -> { -diff --git a/src/main/java/net/minecraft/server/EntityBlaze.java b/src/main/java/net/minecraft/server/EntityBlaze.java -index 5b1d2c7f5..da6a3fa2c 100644 ---- a/src/main/java/net/minecraft/server/EntityBlaze.java -+++ b/src/main/java/net/minecraft/server/EntityBlaze.java -@@ -24,7 +24,7 @@ public class EntityBlaze extends EntityMonster { - this.goalSelector.a(7, new PathfinderGoalRandomStrollLand(this, 1.0D, 0.0F)); - this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); - this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); -- this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[0])).a()); -+ this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this).a(new Class[0])); // Purpur - decompile error - this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); - } - -diff --git a/src/main/java/net/minecraft/server/EntityCat.java b/src/main/java/net/minecraft/server/EntityCat.java -index 57af3835e..b3bdc194a 100644 ---- a/src/main/java/net/minecraft/server/EntityCat.java -+++ b/src/main/java/net/minecraft/server/EntityCat.java -@@ -16,7 +16,7 @@ public class EntityCat extends EntityTameableAnimal { - private static final DataWatcherObject bC = DataWatcher.a(EntityCat.class, DataWatcherRegistry.i); - private static final DataWatcherObject bD = DataWatcher.a(EntityCat.class, DataWatcherRegistry.i); - private static final DataWatcherObject bE = DataWatcher.a(EntityCat.class, DataWatcherRegistry.b); -- public static final Map bz = (Map) SystemUtils.a(Maps.newHashMap(), (hashmap) -> { // CraftBukkit - decompile error -+ public static final Map bz = SystemUtils.a(Maps.newHashMap(), (hashmap) -> { // CraftBukkit - decompile error // Purpur - decompile error - hashmap.put(0, new MinecraftKey("textures/entity/cat/tabby.png")); - hashmap.put(1, new MinecraftKey("textures/entity/cat/black.png")); - hashmap.put(2, new MinecraftKey("textures/entity/cat/red.png")); -diff --git a/src/main/java/net/minecraft/server/EntityEnderSignal.java b/src/main/java/net/minecraft/server/EntityEnderSignal.java -index c13abc7e0..7ebd7da1c 100644 ---- a/src/main/java/net/minecraft/server/EntityEnderSignal.java -+++ b/src/main/java/net/minecraft/server/EntityEnderSignal.java -@@ -21,7 +21,7 @@ public class EntityEnderSignal extends Entity { - - public void b(ItemStack itemstack) { - if (itemstack.getItem() != Items.ENDER_EYE || itemstack.hasTag()) { -- this.getDataWatcher().set(EntityEnderSignal.b, SystemUtils.a((Object) itemstack.cloneItemStack(), (itemstack1) -> { -+ this.getDataWatcher().set(EntityEnderSignal.b, SystemUtils.a(itemstack.cloneItemStack(), (itemstack1) -> { // Purpur - decompile error - itemstack1.setCount(1); - })); - } -diff --git a/src/main/java/net/minecraft/server/EntityEndermite.java b/src/main/java/net/minecraft/server/EntityEndermite.java -index b34695f2d..e4bd2796a 100644 ---- a/src/main/java/net/minecraft/server/EntityEndermite.java -+++ b/src/main/java/net/minecraft/server/EntityEndermite.java -@@ -19,7 +19,7 @@ public class EntityEndermite extends EntityMonster { - this.goalSelector.a(3, new PathfinderGoalRandomStrollLand(this, 1.0D)); - this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); - this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); -- this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[0])).a()); -+ this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this).a(new Class[0])); // Purpur - decompile error - this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); - } - -diff --git a/src/main/java/net/minecraft/server/EntityEvoker.java b/src/main/java/net/minecraft/server/EntityEvoker.java -index 886268b09..b030fe957 100644 ---- a/src/main/java/net/minecraft/server/EntityEvoker.java -+++ b/src/main/java/net/minecraft/server/EntityEvoker.java -@@ -24,7 +24,7 @@ public class EntityEvoker extends EntityIllagerWizard { - this.goalSelector.a(8, new PathfinderGoalRandomStroll(this, 0.6D)); - this.goalSelector.a(9, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 3.0F, 1.0F)); - this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F)); -- this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a()); -+ this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, EntityRaider.class).a(new Class[0])); // Purpur - decompile error - this.targetSelector.a(2, (new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)).a(300)); - this.targetSelector.a(3, (new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, false)).a(300)); - this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, false)); -diff --git a/src/main/java/net/minecraft/server/EntityFish.java b/src/main/java/net/minecraft/server/EntityFish.java -index d332907b3..b853fd0d9 100644 ---- a/src/main/java/net/minecraft/server/EntityFish.java -+++ b/src/main/java/net/minecraft/server/EntityFish.java -@@ -73,11 +73,7 @@ public abstract class EntityFish extends EntityWaterAnimal { - protected void initPathfinder() { - super.initPathfinder(); - this.goalSelector.a(0, new PathfinderGoalPanic(this, 1.25D)); -- PathfinderGoalSelector pathfindergoalselector = this.goalSelector; -- Predicate predicate = IEntitySelector.f; -- -- predicate.getClass(); -- pathfindergoalselector.a(2, new PathfinderGoalAvoidTarget<>(this, EntityHuman.class, 8.0F, 1.6D, 1.4D, predicate::test)); -+ this.goalSelector.a(2, new PathfinderGoalAvoidTarget<>(this, EntityHuman.class, 8.0F, 1.6D, 1.4D, IEntitySelector.f::test)); // Purpur - decompile error - this.goalSelector.a(4, new EntityFish.b(this)); - } - -diff --git a/src/main/java/net/minecraft/server/EntityParrot.java b/src/main/java/net/minecraft/server/EntityParrot.java -index 140208761..94e57a2d8 100644 ---- a/src/main/java/net/minecraft/server/EntityParrot.java -+++ b/src/main/java/net/minecraft/server/EntityParrot.java -@@ -20,8 +20,8 @@ public class EntityParrot extends EntityPerchable implements EntityBird { - } - }; - private static final Item bF = Items.COOKIE; -- private static final Set bG = Sets.newHashSet(new Item[]{Items.WHEAT_SEEDS, Items.MELON_SEEDS, Items.PUMPKIN_SEEDS, Items.BEETROOT_SEEDS}); -- private static final Map, SoundEffect> bH = (Map) SystemUtils.a(Maps.newHashMap(), (hashmap) -> { // CraftBukkit - decompile error -+ private static final Set bG = Sets.newHashSet(Items.WHEAT_SEEDS, Items.MELON_SEEDS, Items.PUMPKIN_SEEDS, Items.BEETROOT_SEEDS); // Purpur - decompile error -+ private static final Map, SoundEffect> bH = SystemUtils.a(Maps.newHashMap(), (hashmap) -> { // CraftBukkit - decompile error // Purpur - decompile error - hashmap.put(EntityTypes.BLAZE, SoundEffects.ENTITY_PARROT_IMITATE_BLAZE); - hashmap.put(EntityTypes.CAVE_SPIDER, SoundEffects.ENTITY_PARROT_IMITATE_SPIDER); - hashmap.put(EntityTypes.CREEPER, SoundEffects.ENTITY_PARROT_IMITATE_CREEPER); -diff --git a/src/main/java/net/minecraft/server/EntitySheep.java b/src/main/java/net/minecraft/server/EntitySheep.java -index bb46247f2..f63528ca3 100644 ---- a/src/main/java/net/minecraft/server/EntitySheep.java -+++ b/src/main/java/net/minecraft/server/EntitySheep.java -@@ -18,7 +18,7 @@ import org.bukkit.inventory.InventoryView; - public class EntitySheep extends EntityAnimal { - - private static final DataWatcherObject bw = DataWatcher.a(EntitySheep.class, DataWatcherRegistry.a); -- private static final Map bx = (Map) SystemUtils.a(Maps.newEnumMap(EnumColor.class), (enummap) -> { // CraftBukkit - decompile error -+ private static final Map bx = SystemUtils.a(Maps.newEnumMap(EnumColor.class), (enummap) -> { // CraftBukkit - decompile error // Purpur - decompile error - enummap.put(EnumColor.WHITE, Blocks.WHITE_WOOL); - enummap.put(EnumColor.ORANGE, Blocks.ORANGE_WOOL); - enummap.put(EnumColor.MAGENTA, Blocks.MAGENTA_WOOL); -@@ -36,9 +36,7 @@ public class EntitySheep extends EntityAnimal { - enummap.put(EnumColor.RED, Blocks.RED_WOOL); - enummap.put(EnumColor.BLACK, Blocks.BLACK_WOOL); - }); -- private static final Map by = Maps.newEnumMap((Map) Arrays.stream(EnumColor.values()).collect(Collectors.toMap((enumcolor) -> { -- return enumcolor; -- }, EntitySheep::c))); -+ private static final Map by = Arrays.stream(EnumColor.values()).collect(Collectors.toMap((enumcolor) -> enumcolor, EntitySheep::c)); // Purpur - decompile error - private int bz; - private PathfinderGoalEatTile bA; - -diff --git a/src/main/java/net/minecraft/server/EntityWitch.java b/src/main/java/net/minecraft/server/EntityWitch.java -index 7b6b1ad17..1432d3f6b 100644 ---- a/src/main/java/net/minecraft/server/EntityWitch.java -+++ b/src/main/java/net/minecraft/server/EntityWitch.java -@@ -30,13 +30,13 @@ public class EntityWitch extends EntityRaider implements IRangedEntity { - this.bz = new PathfinderGoalNearestHealableRaider<>(this, EntityRaider.class, true, (entityliving) -> { - return entityliving != null && this.eF() && entityliving.getEntityType() != EntityTypes.WITCH; - }); -- this.bA = new PathfinderGoalNearestAttackableTargetWitch<>(this, EntityHuman.class, 10, true, false, (Predicate) null); -+ this.bA = new PathfinderGoalNearestAttackableTargetWitch<>(this, EntityHuman.class, 10, true, false, null); // Purpur - decompile error - this.goalSelector.a(1, new PathfinderGoalFloat(this)); - this.goalSelector.a(2, new PathfinderGoalArrowAttack(this, 1.0D, 60, 10.0F)); - this.goalSelector.a(2, new PathfinderGoalRandomStrollLand(this, 1.0D)); - this.goalSelector.a(3, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); - this.goalSelector.a(3, new PathfinderGoalRandomLookaround(this)); -- this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})); -+ this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, EntityRaider.class)); // Purpur - decompile error - this.targetSelector.a(2, this.bz); - this.targetSelector.a(3, this.bA); - } -diff --git a/src/main/java/net/minecraft/server/GeneratorAccess.java b/src/main/java/net/minecraft/server/GeneratorAccess.java -index 5648ba73c..304190fdc 100644 ---- a/src/main/java/net/minecraft/server/GeneratorAccess.java -+++ b/src/main/java/net/minecraft/server/GeneratorAccess.java -@@ -49,7 +49,7 @@ public interface GeneratorAccess extends IEntityAccess, IWorldReader, VirtualLev - void a(@Nullable EntityHuman entityhuman, int i, BlockPosition blockposition, int j); - - default void triggerEffect(int i, BlockPosition blockposition, int j) { -- this.a((EntityHuman) null, i, blockposition, j); -+ this.a(null, i, blockposition, j); // Purpur - decompile error - } - - @Override default java.util.List getEntityCollisions(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set, boolean returnFast) {return IEntityAccess.super.getEntityCollisions(entity, axisalignedbb, set, returnFast); } // Paper -diff --git a/src/main/java/net/minecraft/server/MathHelper.java b/src/main/java/net/minecraft/server/MathHelper.java -index 38b79b5b1..c4aa38ddf 100644 ---- a/src/main/java/net/minecraft/server/MathHelper.java -+++ b/src/main/java/net/minecraft/server/MathHelper.java -@@ -7,7 +7,7 @@ import java.util.function.IntPredicate; - public class MathHelper { - - public static final float a = c(2.0F); -- private static final float[] b = (float[]) SystemUtils.a((Object) (new float[65536]), (afloat) -> { -+ private static final float[] b = SystemUtils.a((new float[65536]), (afloat) -> { // Purpur - decompile error - for (int i = 0; i < afloat.length; ++i) { - afloat[i] = (float) Math.sin((double) i * 3.141592653589793D * 2.0D / 65536.0D); - } -diff --git a/src/main/java/net/minecraft/server/WorldGenFeatureConfigured.java b/src/main/java/net/minecraft/server/WorldGenFeatureConfigured.java -index de8f1874a..73402f2b5 100644 ---- a/src/main/java/net/minecraft/server/WorldGenFeatureConfigured.java -+++ b/src/main/java/net/minecraft/server/WorldGenFeatureConfigured.java -@@ -25,7 +25,7 @@ public class WorldGenFeatureConfigured a(WorldGenDecoratorConfigured worldgendecoratorconfigured) { - WorldGenerator worldgenerator = this.b instanceof WorldGenFlowers ? WorldGenerator.DECORATED_FLOWER : WorldGenerator.DECORATED; - -- return worldgenerator.b((WorldGenFeatureConfiguration) (new WorldGenFeatureCompositeConfiguration(this, worldgendecoratorconfigured))); -+ return worldgenerator.b(new WorldGenFeatureCompositeConfiguration(this, worldgendecoratorconfigured)); // Purpur - decompile error - } - - public WorldGenFeatureRandomChoiceConfigurationWeight a(float f) { -diff --git a/src/main/java/net/minecraft/server/WorldGenFeatureTreeBeehive.java b/src/main/java/net/minecraft/server/WorldGenFeatureTreeBeehive.java -index 979f3517c..5827b1ba1 100644 ---- a/src/main/java/net/minecraft/server/WorldGenFeatureTreeBeehive.java -+++ b/src/main/java/net/minecraft/server/WorldGenFeatureTreeBeehive.java -@@ -58,6 +58,6 @@ public class WorldGenFeatureTreeBeehive extends WorldGenFeatureTree { - - @Override - public T a(DynamicOps dynamicops) { -- return (new Dynamic(dynamicops, dynamicops.createMap(ImmutableMap.of(dynamicops.createString("type"), dynamicops.createString(IRegistry.w.getKey(this.a).toString()), dynamicops.createString("probability"), dynamicops.createFloat(this.b))))).getValue(); -+ return new Dynamic<>(dynamicops, dynamicops.createMap(ImmutableMap.of(dynamicops.createString("type"), dynamicops.createString(IRegistry.w.getKey(this.a).toString()), dynamicops.createString("probability"), dynamicops.createFloat(this.b)))).getValue(); // Purpur - decompile error - } - } --- -2.26.2 - diff --git a/patches/server/0006-Add-language-asset-purpur.lang.patch b/patches/server/0006-Add-language-asset-purpur.lang.patch deleted file mode 100644 index 5b9028817..000000000 --- a/patches/server/0006-Add-language-asset-purpur.lang.patch +++ /dev/null @@ -1,135 +0,0 @@ -From b1cd21795f45b71ae265cebd95060a23cfcf9310 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Thu, 26 Mar 2020 13:17:09 -0500 -Subject: [PATCH] Add language asset purpur.lang - ---- - .../net/minecraft/server/EntityPlayer.java | 1 + - .../net/minecraft/server/LocaleLanguage.java | 48 +++++++++++++++++-- - .../pl3x/purpur/command/PurpurCommand.java | 3 ++ - src/main/resources/purpur.lang | 1 + - 4 files changed, 49 insertions(+), 4 deletions(-) - create mode 100644 src/main/resources/purpur.lang - -diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java -index 39072ebdc..fe1e9ea61 100644 ---- a/src/main/java/net/minecraft/server/EntityPlayer.java -+++ b/src/main/java/net/minecraft/server/EntityPlayer.java -@@ -1582,6 +1582,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { - } - - public void a(IChatBaseComponent ichatbasecomponent, ChatMessageType chatmessagetype) { -+ if (ichatbasecomponent == null) return; // Purpur - this.playerConnection.a((Packet) (new PacketPlayOutChat(ichatbasecomponent, chatmessagetype)), (future) -> { - if (!future.isSuccess() && (chatmessagetype == ChatMessageType.GAME_INFO || chatmessagetype == ChatMessageType.SYSTEM)) { - boolean flag = true; -diff --git a/src/main/java/net/minecraft/server/LocaleLanguage.java b/src/main/java/net/minecraft/server/LocaleLanguage.java -index 601273933..75707adcd 100644 ---- a/src/main/java/net/minecraft/server/LocaleLanguage.java -+++ b/src/main/java/net/minecraft/server/LocaleLanguage.java -@@ -15,18 +15,41 @@ import java.util.Map.Entry; - import java.util.regex.Pattern; - import org.apache.logging.log4j.LogManager; - import org.apache.logging.log4j.Logger; -+import org.bukkit.ChatColor; - - public class LocaleLanguage { - - private static final Logger LOGGER = LogManager.getLogger(); - private static final Pattern b = Pattern.compile("%(\\d+\\$)?[\\d\\.]*[df]"); - private static final LocaleLanguage c = new LocaleLanguage(); -- private final Map d = Maps.newHashMap(); -- private long e; -+ private final Map d = Maps.newHashMap(); public Map getStorage() { return this.d; } // Purpur - OBFHELPER -+ private long e; public long getLastUpdateTime() { return this.e; } public void setLastUpdateTime(int time) { this.e = time; } // Purpur - OBFHELPER - - public LocaleLanguage() { -+ // Purpur start -+ reload(this); -+ } -+ -+ private void loadFromFile(String resource) { - try { -- InputStream inputstream = LocaleLanguage.class.getResourceAsStream("/assets/minecraft/lang/en_us.json"); -+ java.io.File file = new java.io.File(resource); -+ if (!file.exists()) { -+ java.nio.file.Files.copy(getClass().getResourceAsStream("/" + resource), file.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING); -+ } -+ loadFromJar("/" + resource); -+ loadFromStream(resource, new java.io.FileInputStream(file)); -+ } catch (IOException e) { -+ LOGGER.error("Couldn't read string from " + resource, e); -+ } -+ } -+ -+ private void loadFromJar(String resource) { -+ loadFromStream(resource, getClass().getResourceAsStream(resource)); -+ } -+ -+ private void loadFromStream(String resource, InputStream inputstream) { -+ try { -+ // Purpur end - Throwable throwable = null; - - try { -@@ -60,7 +83,7 @@ public class LocaleLanguage { - - } - } catch (JsonParseException | IOException ioexception) { -- LocaleLanguage.LOGGER.error("Couldn't read strings from /assets/minecraft/lang/en_us.json", ioexception); -+ LocaleLanguage.LOGGER.error("Couldn't read strings from " + resource, ioexception); // Purpur - } - - } -@@ -88,4 +111,21 @@ public class LocaleLanguage { - public long b() { - return this.e; - } -+ -+ // Purpur start -+ public static void reload(LocaleLanguage instance) { -+ instance.setLastUpdateTime(0); -+ instance.getStorage().clear(); -+ instance.loadFromJar("/assets/minecraft/lang/en_us.json"); -+ instance.loadFromFile("purpur.lang"); -+ } -+ -+ public static ChatMessage translate(String key, Object... args) { -+ String str = getInstance().translateKey(key); -+ if (str == null) return null; -+ str = ChatColor.translateAlternateColorCodes('&', str); -+ if (str.isEmpty()) return null; -+ return new ChatMessage(str, args); -+ } -+ // Purpur end - } -diff --git a/src/main/java/net/pl3x/purpur/command/PurpurCommand.java b/src/main/java/net/pl3x/purpur/command/PurpurCommand.java -index 7d983d9a5..36260e0ec 100644 ---- a/src/main/java/net/pl3x/purpur/command/PurpurCommand.java -+++ b/src/main/java/net/pl3x/purpur/command/PurpurCommand.java -@@ -1,5 +1,6 @@ - package net.pl3x.purpur.command; - -+import net.minecraft.server.LocaleLanguage; - import net.minecraft.server.MinecraftServer; - import net.minecraft.server.WorldServer; - import net.pl3x.purpur.PurpurConfig; -@@ -45,6 +46,8 @@ public class PurpurCommand extends Command { - Command.broadcastCommandMessage(sender, ChatColor.RED + "Please note that this command is not supported and may cause issues."); - Command.broadcastCommandMessage(sender, ChatColor.RED + "If you encounter any issues please use the /stop command to restart your server."); - -+ LocaleLanguage.reload(LocaleLanguage.getInstance()); -+ - MinecraftServer console = MinecraftServer.getServer(); - PurpurConfig.init((File) console.options.valueOf("purpur-settings")); - for (WorldServer world : console.getWorlds()) { -diff --git a/src/main/resources/purpur.lang b/src/main/resources/purpur.lang -new file mode 100644 -index 000000000..0967ef424 ---- /dev/null -+++ b/src/main/resources/purpur.lang -@@ -0,0 +1 @@ -+{} --- -2.26.2 - diff --git a/patches/server/0072-Add-more-llama-API.patch b/patches/server/0006-Llama-API.patch similarity index 79% rename from patches/server/0072-Add-more-llama-API.patch rename to patches/server/0006-Llama-API.patch index ea3296423..0a2edbaf4 100644 --- a/patches/server/0072-Add-more-llama-API.patch +++ b/patches/server/0006-Llama-API.patch @@ -1,7 +1,7 @@ -From eab02ae8ebe093cfce94311b02c3c76349add5bd Mon Sep 17 00:00:00 2001 +From ce23a90cbb5d648a846bdfc45696a55bab8a3ed9 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Fri, 18 Oct 2019 22:50:12 -0500 -Subject: [PATCH] Add more llama API +Subject: [PATCH] Llama API --- .../net/minecraft/server/EntityLlama.java | 18 ++++++-- @@ -10,20 +10,20 @@ Subject: [PATCH] Add more llama API 3 files changed, 61 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/minecraft/server/EntityLlama.java b/src/main/java/net/minecraft/server/EntityLlama.java -index c5f87cbdd..082aac258 100644 +index 4fe769c76..cf3192085 100644 --- a/src/main/java/net/minecraft/server/EntityLlama.java +++ b/src/main/java/net/minecraft/server/EntityLlama.java -@@ -12,7 +12,8 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn +@@ -13,7 +13,8 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn @Nullable - private EntityLlama bJ; + private EntityLlama bI; @Nullable -- private EntityLlama bK; -+ private EntityLlama bK; public EntityLlama getCaravanTail() { return bK; } // Purpur - OBFHELPER +- private EntityLlama bJ; ++ private EntityLlama bJ; public EntityLlama getCaravanTail() { return bJ; } // Purpur - OBFHELPER + public boolean shouldJoinCaravan = true; // Purpur public EntityLlama(EntityTypes entitytypes, World world) { super(entitytypes, world); -@@ -79,7 +80,7 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn +@@ -41,7 +42,7 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn if (!this.inventoryChest.getItem(1).isEmpty()) { nbttagcompound.set("DecorItem", this.inventoryChest.getItem(1).save(new NBTTagCompound())); } @@ -32,7 +32,7 @@ index c5f87cbdd..082aac258 100644 } @Override -@@ -90,7 +91,11 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn +@@ -52,7 +53,11 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn if (nbttagcompound.hasKeyOfType("DecorItem", 10)) { this.inventoryChest.setItem(1, ItemStack.a(nbttagcompound.getCompound("DecorItem"))); } @@ -42,45 +42,45 @@ index c5f87cbdd..082aac258 100644 + nbttagcompound.setBoolean("Purpur.ShouldJoinCaravan", shouldJoinCaravan); + } + // Purpur end - this.eI(); + this.ff(); } -@@ -413,19 +418,24 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn +@@ -387,19 +392,24 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn } } -+ public void leaveCaravan() { fb(); } // Purpur - OBFHELPER - public void fb() { - if (this.bJ != null) { ++ public void leaveCaravan() { fB(); } // Purpur - OBFHELPER + public void fB() { + if (this.bI != null) { + new net.pl3x.purpur.event.entity.LlamaLeaveCaravanEvent((org.bukkit.entity.Llama) getBukkitEntity()).callEvent(); // Purpur - this.bJ.bK = null; + this.bI.bJ = null; } - this.bJ = null; + this.bI = null; } + public void joinCaravan(EntityLlama entitiyllama) { a(entitiyllama); } // Purpur - OBFHELPER public void a(EntityLlama entityllama) { + if (!shouldJoinCaravan || !new net.pl3x.purpur.event.entity.LlamaJoinCaravanEvent((org.bukkit.entity.Llama) getBukkitEntity(), (org.bukkit.entity.Llama) entityllama.getBukkitEntity()).callEvent()) return; // Purpur - this.bJ = entityllama; - this.bJ.bK = this; + this.bI = entityllama; + this.bI.bJ = this; } -+ public boolean hasCaravanTail() { return fc(); } // Purpur - OBFHELPER - public boolean fc() { - return this.bK != null; ++ public boolean hasCaravanTail() { return fC(); } // Purpur - OBFHELPER + public boolean fC() { + return this.bJ != null; } -@@ -436,7 +446,7 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn +@@ -410,7 +420,7 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn } @Nullable -- public EntityLlama fe() { -+ public EntityLlama fe() { return getCaravanHead(); } public EntityLlama getCaravanHead() { // Purpur - OBFHELPER - return this.bJ; +- public EntityLlama fE() { ++ public EntityLlama fE() { return getCaravanHead(); } public EntityLlama getCaravanHead() { // Purpur - OBFHELPER + return this.bI; } diff --git a/src/main/java/net/minecraft/server/PathfinderGoalLlamaFollow.java b/src/main/java/net/minecraft/server/PathfinderGoalLlamaFollow.java -index e181d8350..8376f1dc4 100644 +index 938c271fa..e21901a72 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalLlamaFollow.java +++ b/src/main/java/net/minecraft/server/PathfinderGoalLlamaFollow.java @@ -6,7 +6,7 @@ import java.util.List; @@ -97,7 +97,7 @@ index e181d8350..8376f1dc4 100644 @Override public boolean a() { + if (!getLlama().shouldJoinCaravan) return false; // Purpur - if (!this.a.isLeashed() && !this.a.fd()) { + if (!this.a.isLeashed() && !this.a.fD()) { List list = this.a.world.getEntities(this.a, this.a.getBoundingBox().grow(9.0D, 4.0D, 9.0D), (entity) -> { EntityTypes entitytypes = entity.getEntityType(); @@ -77,6 +78,7 @@ public class PathfinderGoalLlamaFollow extends PathfinderGoal { @@ -105,8 +105,8 @@ index e181d8350..8376f1dc4 100644 @Override public boolean b() { + if (!getLlama().shouldJoinCaravan) return false; // Purpur - if (this.a.fd() && this.a.fe().isAlive() && this.a(this.a, 0)) { - double d0 = this.a.h((Entity) this.a.fe()); + if (this.a.fD() && this.a.fE().isAlive() && this.a(this.a, 0)) { + double d0 = this.a.h((Entity) this.a.fE()); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java index 3f94c5a92..a02763480 100644 diff --git a/patches/server/0007-Evoker-API.patch b/patches/server/0007-Evoker-API.patch new file mode 100644 index 000000000..807bf81cf --- /dev/null +++ b/patches/server/0007-Evoker-API.patch @@ -0,0 +1,74 @@ +From b509638d3539212f7aa2d9dd86aebaac925ac2ab Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Sat, 19 Oct 2019 00:29:02 -0500 +Subject: [PATCH] Evoker API + +--- + .../java/net/minecraft/server/EntityEvoker.java | 5 +++-- + .../bukkit/craftbukkit/entity/CraftEvoker.java | 17 +++++++++++++++++ + 2 files changed, 20 insertions(+), 2 deletions(-) + +diff --git a/src/main/java/net/minecraft/server/EntityEvoker.java b/src/main/java/net/minecraft/server/EntityEvoker.java +index dd55e5e5b..c37c2930e 100644 +--- a/src/main/java/net/minecraft/server/EntityEvoker.java ++++ b/src/main/java/net/minecraft/server/EntityEvoker.java +@@ -24,7 +24,7 @@ public class EntityEvoker extends EntityIllagerWizard { + this.goalSelector.a(8, new PathfinderGoalRandomStroll(this, 0.6D)); + this.goalSelector.a(9, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 3.0F, 1.0F)); + this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F)); +- this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a()); ++ this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a(new Class[0])); // Purpur - decompile error + this.targetSelector.a(2, (new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)).a(300)); + this.targetSelector.a(3, (new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, false)).a(300)); + this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, false)); +@@ -79,12 +79,13 @@ public class EntityEvoker extends EntityIllagerWizard { + return SoundEffects.ENTITY_EVOKER_HURT; + } + ++ public void setWololoTarget(@Nullable EntitySheep sheep) { a(sheep); } // Purpur - OBFHELPER + private void a(@Nullable EntitySheep entitysheep) { + this.bv = entitysheep; + } + + @Nullable +- private EntitySheep fh() { ++ private EntitySheep fh() { return getWololoTarget(); } public EntitySheep getWololoTarget() { // Purpur - OBFHELPER + return this.bv; + } + +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEvoker.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEvoker.java +index 0636d2647..a7a548421 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEvoker.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEvoker.java +@@ -5,6 +5,10 @@ import net.minecraft.server.EntityIllagerWizard; + import org.bukkit.craftbukkit.CraftServer; + import org.bukkit.entity.EntityType; + import org.bukkit.entity.Evoker; ++// Purpur start ++import net.minecraft.server.EntitySheep; ++import javax.annotation.Nullable; ++// Purpur end + + public class CraftEvoker extends CraftSpellcaster implements Evoker { + +@@ -36,4 +40,17 @@ public class CraftEvoker extends CraftSpellcaster implements Evoker { + public void setCurrentSpell(Evoker.Spell spell) { + getHandle().setSpell(spell == null ? EntityIllagerWizard.Spell.NONE : EntityIllagerWizard.Spell.a(spell.ordinal())); + } ++ ++ // Purpur start ++ @Nullable ++ public org.bukkit.entity.Sheep getWololoTarget() { ++ EntitySheep target = getHandle().getWololoTarget(); ++ return target == null ? null : (org.bukkit.entity.Sheep) target.getBukkitEntity(); ++ } ++ ++ @Override ++ public void setWololoTarget(@Nullable org.bukkit.entity.Sheep sheep) { ++ getHandle().setWololoTarget(sheep == null ? null : (EntitySheep) ((CraftEntity) sheep).getHandle()); ++ } ++ // Purpur end + } +-- +2.26.2 + diff --git a/patches/server/0039-Implement-AFK-API.patch b/patches/server/0008-AFK-API.patch similarity index 70% rename from patches/server/0039-Implement-AFK-API.patch rename to patches/server/0008-AFK-API.patch index 2bc2ec055..d35fcef19 100644 --- a/patches/server/0039-Implement-AFK-API.patch +++ b/patches/server/0008-AFK-API.patch @@ -1,27 +1,27 @@ -From fa7ce62a34d0cd0e28afe493de492cb5e8c0d4df Mon Sep 17 00:00:00 2001 +From d92c7dd2a708064c634e5a66ce12f673acddf32e Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Thu, 8 Aug 2019 15:29:15 -0500 -Subject: [PATCH] Implement AFK API +Subject: [PATCH] AFK API --- .../java/net/minecraft/server/Entity.java | 1 + .../net/minecraft/server/EntityHuman.java | 9 ++++ - .../net/minecraft/server/EntityPlayer.java | 43 +++++++++++++++++++ - .../net/minecraft/server/IEntityAccess.java | 34 ++++++--------- + .../net/minecraft/server/EntityPlayer.java | 46 +++++++++++++++++++ + .../net/minecraft/server/IEntityAccess.java | 34 +++++--------- .../net/minecraft/server/IEntitySelector.java | 2 + - .../minecraft/server/PlayerConnection.java | 12 +++++- + .../minecraft/server/PlayerConnection.java | 12 ++++- .../net/minecraft/server/WorldServer.java | 4 +- + .../java/net/pl3x/purpur/PurpurConfig.java | 8 ++++ .../net/pl3x/purpur/PurpurWorldConfig.java | 11 +++++ - .../craftbukkit/entity/CraftPlayer.java | 17 ++++++++ + .../craftbukkit/entity/CraftPlayer.java | 17 +++++++ .../java/org/spigotmc/ActivationRange.java | 1 + - src/main/resources/purpur.lang | 4 +- - 11 files changed, 112 insertions(+), 26 deletions(-) + 11 files changed, 120 insertions(+), 25 deletions(-) diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index 08645bd03..580843686 100644 +index 38887c1b7..3709f3386 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java -@@ -1623,6 +1623,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke +@@ -1384,6 +1384,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return MathHelper.c(f * f + f1 * f1 + f2 * f2); } @@ -30,10 +30,10 @@ index 08645bd03..580843686 100644 double d3 = this.locX() - d0; double d4 = this.locY() - d1; diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java -index 27cfc6654..d62174e9c 100644 +index 2cada09ce..a69a69859 100644 --- a/src/main/java/net/minecraft/server/EntityHuman.java +++ b/src/main/java/net/minecraft/server/EntityHuman.java -@@ -86,6 +86,15 @@ public abstract class EntityHuman extends EntityLiving { +@@ -84,6 +84,15 @@ public abstract class EntityHuman extends EntityLiving { } // CraftBukkit end @@ -46,17 +46,17 @@ index 27cfc6654..d62174e9c 100644 + } + // Purpur end + - public EntityHuman(World world, GameProfile gameprofile) { + public EntityHuman(World world, BlockPosition blockposition, GameProfile gameprofile) { super(EntityTypes.PLAYER, world); - this.bV = ItemStack.a; + this.bS = ItemStack.b; diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java -index b781aa3ae..d7ce31284 100644 +index c047d8ff1..6fbbe515c 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java -@@ -1646,8 +1646,51 @@ public class EntityPlayer extends EntityHuman implements ICrafting { +@@ -1755,8 +1755,54 @@ public class EntityPlayer extends EntityHuman implements ICrafting { public void resetIdleTimer() { - this.cj = SystemUtils.getMonotonicMillis(); + this.ch = SystemUtils.getMonotonicMillis(); + setAfk(false); // Purpur } @@ -68,8 +68,10 @@ index b781aa3ae..d7ce31284 100644 + if (this.isAfk == setAfk) { + return; + } ++ ++ String msg = setAfk ? net.pl3x.purpur.PurpurConfig.afkBroadcastAway : net.pl3x.purpur.PurpurConfig.afkBroadcastBack; + -+ net.pl3x.purpur.event.PlayerAFKEvent event = new net.pl3x.purpur.event.PlayerAFKEvent(getBukkitEntity(), setAfk, world.purpurConfig.idleTimeoutKick, LocaleLanguage.getInstance().translateKey("idle.timeout.broadcast." + (setAfk ? "away" : "back")), !Bukkit.isPrimaryThread()); ++ net.pl3x.purpur.event.PlayerAFKEvent event = new net.pl3x.purpur.event.PlayerAFKEvent(getBukkitEntity(), setAfk, world.purpurConfig.idleTimeoutKick, msg, !Bukkit.isPrimaryThread()); + if (!event.callEvent() || event.shouldKick()) { + return; + } @@ -80,8 +82,9 @@ index b781aa3ae..d7ce31284 100644 + resetIdleTimer(); + } + -+ if (event.getBroadcastMsg() != null && !event.getBroadcastMsg().isEmpty()) { -+ server.getPlayerList().sendAll(new PacketPlayOutChat(new ChatMessage(event.getBroadcastMsg(), getScoreboardDisplayName()))); ++ msg = event.getBroadcastMsg(); ++ if (msg != null && !msg.isEmpty()) { ++ server.getPlayerList().sendAll(new PacketPlayOutChat(new ChatMessage(msg, getScoreboardDisplayName()), ChatMessageType.SYSTEM, SystemUtils.getNullUUID())); + } + + if (world.purpurConfig.idleTimeoutUpdateTabList) { @@ -97,8 +100,8 @@ index b781aa3ae..d7ce31284 100644 + } + + @Override -+ public boolean isCollidable(boolean ignoreClimbing) { -+ return !isAfk() && super.isCollidable(ignoreClimbing); ++ public boolean isCollidable() { ++ return !isAfk() && super.isCollidable(); + } + // Purpur end + @@ -106,12 +109,12 @@ index b781aa3ae..d7ce31284 100644 return this.serverStatisticManager; } diff --git a/src/main/java/net/minecraft/server/IEntityAccess.java b/src/main/java/net/minecraft/server/IEntityAccess.java -index e0d97d2c8..e1a7926d7 100644 +index 267a6baae..d3ea51c27 100644 --- a/src/main/java/net/minecraft/server/IEntityAccess.java +++ b/src/main/java/net/minecraft/server/IEntityAccess.java -@@ -150,28 +150,18 @@ public interface IEntityAccess { - return entityhuman; +@@ -143,28 +143,18 @@ public interface IEntityAccess { } + // Paper end - default boolean isPlayerNearby(double d0, double d1, double d2, double d3) { - Iterator iterator = this.getPlayers().iterator(); @@ -128,7 +131,7 @@ index e0d97d2c8..e1a7926d7 100644 - } - - entityhuman = (EntityHuman) iterator.next(); -- } while (!IEntitySelector.f.test(entityhuman)); +- } while (!IEntitySelector.g.test(entityhuman)); - } while (!IEntitySelector.b.test(entityhuman)); - - d4 = entityhuman.g(d0, d1, d2); @@ -151,7 +154,7 @@ index e0d97d2c8..e1a7926d7 100644 @Nullable diff --git a/src/main/java/net/minecraft/server/IEntitySelector.java b/src/main/java/net/minecraft/server/IEntitySelector.java -index 1398c47a2..0bf1a14b7 100644 +index a52dd0c02..9b4795f3b 100644 --- a/src/main/java/net/minecraft/server/IEntitySelector.java +++ b/src/main/java/net/minecraft/server/IEntitySelector.java @@ -7,6 +7,7 @@ import javax.annotation.Nullable; @@ -162,19 +165,19 @@ index 1398c47a2..0bf1a14b7 100644 public static final Predicate b = EntityLiving::isAlive; public static final Predicate c = (entity) -> { return entity.isAlive() && !entity.isVehicle() && !entity.isPassenger(); -@@ -24,6 +25,7 @@ public final class IEntitySelector { +@@ -27,6 +28,7 @@ public final class IEntitySelector { return !entity.isSpectator(); }; public static Predicate isInsomniac = (player) -> MathHelper.clamp(((EntityPlayer) player).getStatisticManager().getStatisticValue(StatisticList.CUSTOM.get(StatisticList.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= 72000; // Paper + public static Predicate notAfk = (player) -> !player.isAfk(); // Purpur - public static Predicate a(double d0, double d1, double d2, double d3) { - double d4 = d3 * d3; + // Paper start + public static final Predicate affectsSpawning = (entity) -> { diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java -index 8a5059b4f..148beb1b6 100644 +index 5765e0f04..48a03c44f 100644 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java -@@ -233,6 +233,12 @@ public class PlayerConnection implements PacketListenerPlayIn { +@@ -232,6 +232,12 @@ public class PlayerConnection implements PacketListenerPlayIn { } if (this.player.F() > 0L && this.minecraftServer.getIdleTimeout() > 0 && SystemUtils.getMonotonicMillis() - this.player.F() > (long) (this.minecraftServer.getIdleTimeout() * 1000 * 60)) { @@ -185,18 +188,18 @@ index 8a5059b4f..148beb1b6 100644 + } + // Purpur end this.player.resetIdleTimer(); // CraftBukkit - SPIGOT-854 - this.disconnect(new ChatMessage("multiplayer.disconnect.idling", new Object[0])); + this.disconnect(new ChatMessage("multiplayer.disconnect.idling")); } -@@ -456,6 +462,8 @@ public class PlayerConnection implements PacketListenerPlayIn { +@@ -448,6 +454,8 @@ public class PlayerConnection implements PacketListenerPlayIn { this.lastYaw = to.getYaw(); this.lastPitch = to.getPitch(); -+ if (!to.getWorld().getUID().equals(from.getWorld().getUID()) || to.getBlockX() != from.getBlockX() || to.getBlockY() != from.getBlockY() || to.getBlockZ() != from.getBlockZ()) this.player.resetIdleTimer(); // Purpur ++ if (!to.getWorld().getUID().equals(from.getWorld().getUID()) || to.getBlockX() != from.getBlockX() || to.getBlockY() != from.getBlockY() || to.getBlockZ() != from.getBlockZ() || to.getYaw() != from.getYaw() || to.getPitch() != from.getPitch()) this.player.resetIdleTimer(); // Purpur + // Skip the first time we do this if (true) { // Spigot - don't skip any move events Location oldTo = to.clone(); -@@ -1112,7 +1120,7 @@ public class PlayerConnection implements PacketListenerPlayIn { +@@ -1117,7 +1125,7 @@ public class PlayerConnection implements PacketListenerPlayIn { if (!this.player.H() && d11 > org.spigotmc.SpigotConfig.movedWronglyThreshold && !this.player.isSleeping() && !this.player.playerInteractManager.isCreative() && this.player.playerInteractManager.getGameMode() != EnumGamemode.SPECTATOR) { // Spigot flag1 = true; @@ -205,21 +208,21 @@ index 8a5059b4f..148beb1b6 100644 } this.player.setLocation(d4, d5, d6, f, f1); -@@ -1158,6 +1166,8 @@ public class PlayerConnection implements PacketListenerPlayIn { - this.lastYaw = to.getYaw(); - this.lastPitch = to.getPitch(); +@@ -1156,6 +1164,8 @@ public class PlayerConnection implements PacketListenerPlayIn { + this.lastYaw = to.getYaw(); + this.lastPitch = to.getPitch(); -+ if (!to.getWorld().getUID().equals(from.getWorld().getUID()) || to.getBlockX() != from.getBlockX() || to.getBlockY() != from.getBlockY() || to.getBlockZ() != from.getBlockZ() || to.getYaw() != from.getYaw() || to.getPitch() != from.getPitch()) this.player.resetIdleTimer(); // Purpur ++ if (!to.getWorld().getUID().equals(from.getWorld().getUID()) || to.getBlockX() != from.getBlockX() || to.getBlockY() != from.getBlockY() || to.getBlockZ() != from.getBlockZ() || to.getYaw() != from.getYaw() || to.getPitch() != from.getPitch()) this.player.resetIdleTimer(); // Purpur + - // Skip the first time we do this - if (from.getX() != Double.MAX_VALUE) { - Location oldTo = to.clone(); + // Skip the first time we do this + if (from.getX() != Double.MAX_VALUE) { + Location oldTo = to.clone(); diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index edf24791b..156c87ed4 100644 +index f24c4def3..093fa8074 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -846,7 +846,7 @@ public class WorldServer extends World { - } +@@ -425,7 +425,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { + // CraftBukkit end if (this.everyoneSleeping && this.players.stream().noneMatch((entityplayer) -> { - return !entityplayer.isSpectator() && !entityplayer.isDeeplySleeping() && !entityplayer.fauxSleeping; // CraftBukkit @@ -227,7 +230,7 @@ index edf24791b..156c87ed4 100644 })) { // CraftBukkit start long l = this.worldData.getDayTime() + 24000L; -@@ -1165,7 +1165,7 @@ public class WorldServer extends World { +@@ -745,7 +745,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { while (iterator.hasNext()) { EntityPlayer entityplayer = (EntityPlayer) iterator.next(); @@ -236,33 +239,57 @@ index edf24791b..156c87ed4 100644 ++i; } else if (entityplayer.isSleeping()) { ++j; -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index d6405b2ec..41dd1b861 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -138,6 +138,17 @@ public class PurpurWorldConfig { - disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath); +diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java +index fc38163b1..cc08ad33e 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java +@@ -1,6 +1,7 @@ + package net.pl3x.purpur; + + import com.google.common.base.Throwables; ++import net.minecraft.server.LocaleLanguage; + import net.minecraft.server.MinecraftServer; + import net.pl3x.purpur.command.PurpurCommand; + import org.bukkit.Bukkit; +@@ -129,6 +130,13 @@ public class PurpurConfig { + return config.getString(path, config.getString(path)); } ++ public static String afkBroadcastAway = "§e§o%s is now AFK"; ++ public static String afkBroadcastBack = "§e§o%s is no longer AFK"; ++ private static void messages() { ++ afkBroadcastAway = getString("settings.messages.afk-broadcast-away", afkBroadcastAway); ++ afkBroadcastBack = getString("settings.messages.afk-broadcast-back", afkBroadcastBack); ++ } ++ + public static String timingsUrl = "https://timings.pl3x.net"; + private static void timingsSettings() { + timingsUrl = getString("settings.timings.url", timingsUrl); +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index eda37fa43..5fa333037 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -64,4 +64,15 @@ public class PurpurWorldConfig { + PurpurConfig.config.addDefault("world-settings.default." + path, def); + return PurpurConfig.config.getString("world-settings." + worldName + "." + path, PurpurConfig.config.getString("world-settings.default." + path)); + } ++ + public boolean idleTimeoutKick = true; + public boolean idleTimeoutTickNearbyEntities = true; + public boolean idleTimeoutCountAsSleeping = false; + public boolean idleTimeoutUpdateTabList = false; -+ private void idleTimeoutSettings() { ++ private void playerIdleTimeoutSettings() { + idleTimeoutKick = getBoolean("gameplay-mechanics.player.idle-timeout.kick-if-idle", idleTimeoutKick); + idleTimeoutTickNearbyEntities = getBoolean("gameplay-mechanics.player.idle-timeout.tick-nearby-entities", idleTimeoutTickNearbyEntities); + idleTimeoutCountAsSleeping = getBoolean("gameplay-mechanics.player.idle-timeout.count-as-sleeping", idleTimeoutCountAsSleeping); + idleTimeoutUpdateTabList = getBoolean("gameplay-mechanics.player.idle-timeout.update-tab-list", idleTimeoutUpdateTabList); + } -+ - public boolean batRidable = false; - public boolean batRidableInWater = false; - public boolean batRequireShiftToMount = true; + } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 141003ca7..e15c12387 100644 +index 97a24b4df..3bd2ffc20 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2086,4 +2086,21 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2128,4 +2128,21 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return spigot; } // Spigot end @@ -285,7 +312,7 @@ index 141003ca7..e15c12387 100644 + // Purpur end } diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index f735217e7..818f8070c 100644 +index f78e44e05..da4c49daf 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -207,6 +207,7 @@ public class ActivationRange @@ -296,17 +323,6 @@ index f735217e7..818f8070c 100644 maxBB = player.getBoundingBox().grow( maxRange, 256, maxRange ); ActivationType.MISC.boundingBox = player.getBoundingBox().grow( miscActivationRange, 256, miscActivationRange ); ActivationType.RAIDER.boundingBox = player.getBoundingBox().grow( raiderActivationRange, 256, raiderActivationRange ); -diff --git a/src/main/resources/purpur.lang b/src/main/resources/purpur.lang -index 7125c0477..e925e1374 100644 ---- a/src/main/resources/purpur.lang -+++ b/src/main/resources/purpur.lang -@@ -1,3 +1,5 @@ - { -- "cannot.ride.mob": "You cannot mount that mob" -+ "cannot.ride.mob": "You cannot mount that mob", -+ "idle.timeout.broadcast.away": "§e§o%s is now AFK", -+ "idle.timeout.broadcast.back": "§e§o%s is no longer AFK" - } -- 2.26.2 diff --git a/patches/server/0008-Host-our-own-timings.patch b/patches/server/0008-Host-our-own-timings.patch deleted file mode 100644 index fe664cdd5..000000000 --- a/patches/server/0008-Host-our-own-timings.patch +++ /dev/null @@ -1,25 +0,0 @@ -From fabde23890d8301331617afb56b2285ee9ec1765 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Tue, 18 Feb 2020 20:38:34 -0600 -Subject: [PATCH] Host our own timings - ---- - src/main/java/net/pl3x/purpur/PurpurConfig.java | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java -index 333c880bf..2673de821 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java -@@ -127,4 +127,8 @@ public class PurpurConfig { - config.addDefault(path, def); - return config.getString(path, config.getString(path)); - } -+ -+ private static void timingsSettings() { -+ getString("settings.timings.url", "https://timings.pl3x.net"); -+ } - } --- -2.26.2 - diff --git a/patches/server/0055-Bring-back-server-name.patch b/patches/server/0009-Bring-back-server-name.patch similarity index 75% rename from patches/server/0055-Bring-back-server-name.patch rename to patches/server/0009-Bring-back-server-name.patch index 8c758e657..7c56caf7a 100644 --- a/patches/server/0055-Bring-back-server-name.patch +++ b/patches/server/0009-Bring-back-server-name.patch @@ -1,15 +1,15 @@ -From 1ff4358c48066bbe6694b68332dd8a7c3088a4bf Mon Sep 17 00:00:00 2001 +From fb7aa2524aa13598c3a498a60c44795a2647522f Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 26 May 2019 15:19:14 -0500 Subject: [PATCH] Bring back server name --- - .../java/net/minecraft/server/DedicatedServerProperties.java | 1 + - src/main/java/org/bukkit/craftbukkit/CraftServer.java | 5 +++++ - 2 files changed, 6 insertions(+) + .../net/minecraft/server/DedicatedServerProperties.java | 1 + + src/main/java/org/bukkit/craftbukkit/CraftServer.java | 7 +++++++ + 2 files changed, 8 insertions(+) diff --git a/src/main/java/net/minecraft/server/DedicatedServerProperties.java b/src/main/java/net/minecraft/server/DedicatedServerProperties.java -index 0c3ec8357..309f5562b 100644 +index 6786fd094..8a9be3fdb 100644 --- a/src/main/java/net/minecraft/server/DedicatedServerProperties.java +++ b/src/main/java/net/minecraft/server/DedicatedServerProperties.java @@ -10,6 +10,7 @@ public class DedicatedServerProperties extends PropertyManager -Date: Thu, 6 Feb 2020 19:53:59 -0600 -Subject: [PATCH] Ridables - ---- - .../net/minecraft/server/AxisAlignedBB.java | 2 + - .../server/ControllerLookDolphin.java | 4 +- - .../net/minecraft/server/ControllerMove.java | 6 +- - .../net/minecraft/server/DamageSource.java | 3 + - .../java/net/minecraft/server/Entity.java | 68 +- - .../net/minecraft/server/EntityAgeable.java | 2 +- - .../java/net/minecraft/server/EntityBat.java | 58 ++ - .../java/net/minecraft/server/EntityBee.java | 118 +++- - .../net/minecraft/server/EntityBlaze.java | 51 ++ - .../java/net/minecraft/server/EntityCat.java | 34 +- - .../minecraft/server/EntityCaveSpider.java | 17 + - .../net/minecraft/server/EntityChicken.java | 19 + - .../java/net/minecraft/server/EntityCod.java | 17 + - .../minecraft/server/EntityComplexPart.java | 7 + - .../java/net/minecraft/server/EntityCow.java | 18 + - .../net/minecraft/server/EntityCreeper.java | 76 +++ - .../net/minecraft/server/EntityDolphin.java | 78 ++- - .../net/minecraft/server/EntityDrowned.java | 24 +- - .../minecraft/server/EntityEnderDragon.java | 87 ++- - .../net/minecraft/server/EntityEnderman.java | 33 +- - .../net/minecraft/server/EntityEndermite.java | 19 + - .../net/minecraft/server/EntityEvoker.java | 22 + - .../java/net/minecraft/server/EntityFish.java | 21 +- - .../java/net/minecraft/server/EntityFox.java | 57 +- - .../net/minecraft/server/EntityGhast.java | 46 +- - .../minecraft/server/EntityGiantZombie.java | 25 + - .../net/minecraft/server/EntityGuardian.java | 47 +- - .../minecraft/server/EntityGuardianElder.java | 17 + - .../net/minecraft/server/EntityHorse.java | 7 + - .../minecraft/server/EntityHorseAbstract.java | 22 +- - .../minecraft/server/EntityHorseDonkey.java | 7 + - .../net/minecraft/server/EntityHorseMule.java | 7 + - .../minecraft/server/EntityHorseSkeleton.java | 16 +- - .../minecraft/server/EntityHorseZombie.java | 14 +- - .../net/minecraft/server/EntityHuman.java | 14 +- - .../server/EntityIllagerIllusioner.java | 19 + - .../minecraft/server/EntityInsentient.java | 48 +- - .../net/minecraft/server/EntityIronGolem.java | 23 +- - .../net/minecraft/server/EntityLiving.java | 21 +- - .../net/minecraft/server/EntityLlama.java | 50 +- - .../minecraft/server/EntityLlamaTrader.java | 23 + - .../net/minecraft/server/EntityMagmaCube.java | 17 + - .../minecraft/server/EntityMushroomCow.java | 17 + - .../net/minecraft/server/EntityOcelot.java | 19 + - .../net/minecraft/server/EntityPanda.java | 47 +- - .../net/minecraft/server/EntityParrot.java | 77 ++- - .../net/minecraft/server/EntityPhantom.java | 97 ++- - .../java/net/minecraft/server/EntityPig.java | 48 +- - .../net/minecraft/server/EntityPigZombie.java | 17 + - .../net/minecraft/server/EntityPillager.java | 19 + - .../net/minecraft/server/EntityPlayer.java | 2 +- - .../net/minecraft/server/EntityPolarBear.java | 42 ++ - .../minecraft/server/EntityPufferFish.java | 19 +- - .../net/minecraft/server/EntityRabbit.java | 79 ++- - .../net/minecraft/server/EntityRavager.java | 19 + - .../net/minecraft/server/EntitySalmon.java | 17 + - .../net/minecraft/server/EntitySheep.java | 18 + - .../net/minecraft/server/EntityShulker.java | 21 +- - .../minecraft/server/EntitySilverfish.java | 20 + - .../net/minecraft/server/EntitySkeleton.java | 17 + - .../server/EntitySkeletonAbstract.java | 2 + - .../minecraft/server/EntitySkeletonStray.java | 17 + - .../server/EntitySkeletonWither.java | 17 + - .../net/minecraft/server/EntitySlime.java | 44 +- - .../net/minecraft/server/EntitySnowman.java | 24 +- - .../net/minecraft/server/EntitySpider.java | 19 + - .../net/minecraft/server/EntitySquid.java | 68 +- - .../server/EntityTameableAnimal.java | 1 + - .../minecraft/server/EntityTropicalFish.java | 17 + - .../net/minecraft/server/EntityTurtle.java | 115 +++- - .../net/minecraft/server/EntityTypes.java | 6 + - .../java/net/minecraft/server/EntityVex.java | 65 +- - .../net/minecraft/server/EntityVillager.java | 22 + - .../server/EntityVillagerTrader.java | 18 + - .../minecraft/server/EntityVindicator.java | 19 + - .../net/minecraft/server/EntityWitch.java | 21 +- - .../net/minecraft/server/EntityWither.java | 69 +- - .../java/net/minecraft/server/EntityWolf.java | 121 ++-- - .../net/minecraft/server/EntityZombie.java | 19 + - .../minecraft/server/EntityZombieHusk.java | 17 + - .../server/EntityZombieVillager.java | 17 + - .../java/net/minecraft/server/FoodInfo.java | 1 + - .../java/net/minecraft/server/ItemDye.java | 1 + - .../java/net/minecraft/server/MathHelper.java | 2 + - .../minecraft/server/PathfinderGoalSwell.java | 5 +- - .../minecraft/server/ProjectileHelper.java | 1 + - src/main/java/net/minecraft/server/Vec3D.java | 3 + - src/main/java/net/minecraft/server/World.java | 7 + - .../net/pl3x/purpur/PurpurWorldConfig.java | 599 ++++++++++++++++++ - .../purpur/controller/ControllerLookWASD.java | 75 +++ - .../purpur/controller/ControllerMoveWASD.java | 86 +++ - .../controller/ControllerMoveWASDFlying.java | 53 ++ - .../ControllerMoveWASDFlyingWithSpacebar.java | 61 ++ - .../controller/ControllerMoveWASDWater.java | 43 ++ - .../net/pl3x/purpur/entity/DolphinSpit.java | 119 ++++ - .../net/pl3x/purpur/entity/PhantomFlames.java | 126 ++++ - .../pathfinder/PathfinderGoalHasRider.java | 21 + - .../PathfinderGoalHorseHasRider.java | 21 + - .../craftbukkit/entity/CraftEntity.java | 27 + - src/main/resources/purpur.lang | 4 +- - 100 files changed, 3621 insertions(+), 211 deletions(-) - create mode 100644 src/main/java/net/pl3x/purpur/controller/ControllerLookWASD.java - create mode 100644 src/main/java/net/pl3x/purpur/controller/ControllerMoveWASD.java - create mode 100644 src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlying.java - create mode 100644 src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlyingWithSpacebar.java - create mode 100644 src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDWater.java - create mode 100644 src/main/java/net/pl3x/purpur/entity/DolphinSpit.java - create mode 100644 src/main/java/net/pl3x/purpur/entity/PhantomFlames.java - create mode 100644 src/main/java/net/pl3x/purpur/pathfinder/PathfinderGoalHasRider.java - create mode 100644 src/main/java/net/pl3x/purpur/pathfinder/PathfinderGoalHorseHasRider.java - -diff --git a/src/main/java/net/minecraft/server/AxisAlignedBB.java b/src/main/java/net/minecraft/server/AxisAlignedBB.java -index 688c5b1bd..b35bac0e2 100644 ---- a/src/main/java/net/minecraft/server/AxisAlignedBB.java -+++ b/src/main/java/net/minecraft/server/AxisAlignedBB.java -@@ -216,6 +216,7 @@ public class AxisAlignedBB { - return new AxisAlignedBB(d3, d4, d5, d6, d7, d8); - } - -+ public AxisAlignedBB expandTowards(Vec3D vec3d) { return a(vec3d); } // Purpur - OBFHELPER - public AxisAlignedBB a(Vec3D vec3d) { - return this.b(vec3d.x, vec3d.y, vec3d.z); - } -@@ -267,6 +268,7 @@ public class AxisAlignedBB { - return new AxisAlignedBB(d3, d4, d5, d6, d7, d8); - } - -+ public AxisAlignedBB expand(double size) { return g(size); } // Purpur - OBFHELPER - public AxisAlignedBB g(double d0) { - return this.grow(d0, d0, d0); - } -diff --git a/src/main/java/net/minecraft/server/ControllerLookDolphin.java b/src/main/java/net/minecraft/server/ControllerLookDolphin.java -index 1d9ba04da..2bade947e 100644 ---- a/src/main/java/net/minecraft/server/ControllerLookDolphin.java -+++ b/src/main/java/net/minecraft/server/ControllerLookDolphin.java -@@ -1,6 +1,6 @@ - package net.minecraft.server; - --public class ControllerLookDolphin extends ControllerLook { -+public class ControllerLookDolphin extends net.pl3x.purpur.controller.ControllerLookWASD { // Purpur - - private final int h; - -@@ -10,7 +10,7 @@ public class ControllerLookDolphin extends ControllerLook { - } - - @Override -- public void a() { -+ public void tick() { // Purpur - if (this.d) { - this.d = false; - this.a.aK = this.a(this.a.aK, this.h() + 20.0F, this.b); -diff --git a/src/main/java/net/minecraft/server/ControllerMove.java b/src/main/java/net/minecraft/server/ControllerMove.java -index a5c4cbb67..efe6afde9 100644 ---- a/src/main/java/net/minecraft/server/ControllerMove.java -+++ b/src/main/java/net/minecraft/server/ControllerMove.java -@@ -6,9 +6,9 @@ public class ControllerMove { - protected double b; - protected double c; - protected double d; -- protected double e; -- protected float f; -- protected float g; -+ protected double e; public double getSpeed() { return e; } public void setSpeed(double speed) { this.e = speed; } // Purpur - OBFHELPER -+ protected float f; public float getForward() { return f; } public void setForward(float forward) { this.f = forward; } // Purpur - OBFHELPER -+ protected float g; public float getStrafe() { return g; } public void setStrafe(float strafe) { this.g = strafe; } // Purpur - OBFHELPER - protected ControllerMove.Operation h; - - public ControllerMove(EntityInsentient entityinsentient) { -diff --git a/src/main/java/net/minecraft/server/DamageSource.java b/src/main/java/net/minecraft/server/DamageSource.java -index 816d301f1..f7344d3ae 100644 ---- a/src/main/java/net/minecraft/server/DamageSource.java -+++ b/src/main/java/net/minecraft/server/DamageSource.java -@@ -57,6 +57,7 @@ public class DamageSource { - return new EntityDamageSource("mob", entityliving); - } - -+ public static DamageSource indirectMobAttack(Entity entity, EntityLiving entityliving) { return a(entity, entityliving); } // Purpur - OBFHELPER - public static DamageSource a(Entity entity, EntityLiving entityliving) { - return new EntityDamageSourceIndirect("mob", entity, entityliving); - } -@@ -101,10 +102,12 @@ public class DamageSource { - return new DamageSourceNetherBed(); - } - -+ public boolean isProjectile() { return b(); } // Purpur - OBFHELPER - public boolean b() { - return this.C; - } - -+ public DamageSource setProjectile() { return c(); } // Purpur - OBFHELPER - public DamageSource c() { - this.C = true; - return this; -diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index 37f854764..dc72ee435 100644 ---- a/src/main/java/net/minecraft/server/Entity.java -+++ b/src/main/java/net/minecraft/server/Entity.java -@@ -79,7 +79,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData; // Paper - private CraftEntity bukkitEntity; - -- PlayerChunkMap.EntityTracker tracker; // Paper -+ PlayerChunkMap.EntityTracker tracker; public PlayerChunkMap.EntityTracker getTracker() { return tracker; } // Paper // Purpur - boolean collisionLoadChunks = false; // Paper - Throwable addedToWorldStack; // Paper - entity debug - public CraftEntity getBukkitEntity() { -@@ -104,7 +104,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - private int id; - public boolean i; public final boolean blocksEntitySpawning() { return this.i; } // Paper - OBFHELPER - public final List passengers; -- protected int j; -+ protected int j; public int getRideCooldown() { return j; } // Purpur - OBFHELPER - @Nullable - private Entity vehicle; - public boolean attachedToPlayer; -@@ -137,7 +137,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - public double E; - public double F; - public double G; -- public float H; public final float getStepHeight() { return this.H; } // Tuinity - OBFHELPER -+ public float H; public final float getStepHeight() { return this.H; } public void setStepHeight(float stepHeight) { this.H = stepHeight; } // Purpur // Tuinity - OBFHELPER - public boolean noclip; - public float J; - protected final Random random; -@@ -181,7 +181,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - private boolean aF; - private final double[] aG; - private long aH; -- private EntitySize size; -+ protected EntitySize size; // Purpur - private -> protected - private float headHeight; - // CraftBukkit start - public boolean persist = true; -@@ -1387,6 +1387,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - return flag; - } - -+ public boolean isInBubbleColumn() { return l(); } // Purpur - OBFHELPER - private boolean l() { - return this.world.getType(new BlockPosition(this)).getBlock() == Blocks.BUBBLE_COLUMN; - } -@@ -1400,8 +1401,9 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - return this.isInWater() || this.isInRain() || this.l(); - } - -+ public boolean isInWaterOrBubbleColumn() { return az(); } // Purpur - OBFHELPER - public boolean az() { -- return this.isInWater() || this.l(); -+ return this.isInWater() || this.isInBubbleColumn(); // Purpur - } - - public boolean aA() { -@@ -1532,6 +1534,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - return this.inLava; - } - -+ public void moveRelative(float speed, Vec3D motion) { this.a(speed, motion); } // Purpur - OBFHELPER - public void a(float f, Vec3D vec3d) { - Vec3D vec3d1 = a(vec3d, f, this.yaw); - -@@ -2367,7 +2370,13 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - } else { - this.passengers.add(entity); - } -- -+ // Purpur start -+ if (isRidable() && passengers.get(0) == entity && entity instanceof EntityHuman) { -+ EntityHuman entityhuman = (EntityHuman) entity; -+ onMount(entityhuman); -+ this.rider = entityhuman; -+ } -+ // Purpur end - } - return true; // CraftBukkit - } -@@ -2402,6 +2411,12 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - return false; - } - // Spigot end -+ // Purpur start -+ if (rider != null && passengers.get(0) == rider) { -+ onDismount(rider); -+ this.rider = null; -+ } -+ // Purpur end - this.passengers.remove(entity); - entity.j = 60; - } -@@ -2570,6 +2585,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - this.setFlag(4, flag); - } - -+ public boolean isGlowing() { return bt(); } // Purpur - OBFHELPER - public boolean bt() { - return this.glowing || this.world.isClientSide && this.getFlag(6); - } -@@ -2788,6 +2804,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - - public void setHeadRotation(float f) {} - -+ public void setBodyYaw(float yaw) { l(yaw); } // Purpur - OBFHELPER - public void l(float f) {} - - public boolean bA() { -@@ -3657,4 +3674,43 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - - void accept(Entity entity, double d0, double d1, double d2); - } -+ -+ // Purpur start -+ private EntityHuman rider; -+ -+ public EntityHuman getRider() { -+ return rider; -+ } -+ -+ public boolean hasRider() { -+ return rider != null; -+ } -+ -+ public boolean isRidable() { -+ return false; -+ } -+ -+ public boolean isRidableInWater() { -+ return false; -+ } -+ -+ public boolean requireShiftToMount() { -+ return true; -+ } -+ -+ public void onMount(EntityHuman entityhuman) { -+ if (this instanceof EntityInsentient) { -+ ((EntityInsentient) this).setGoalTarget(null, null, false); -+ ((EntityInsentient) this).getNavigation().stopPathfinding(); -+ } -+ entityhuman.setJumping(false); // fixes jump on mount -+ } -+ -+ public void onDismount(EntityHuman entityhuman) { -+ } -+ -+ public boolean onSpacebar() { -+ return false; -+ } -+ // Purpur end - } -diff --git a/src/main/java/net/minecraft/server/EntityAgeable.java b/src/main/java/net/minecraft/server/EntityAgeable.java -index 3d27f0964..822316a65 100644 ---- a/src/main/java/net/minecraft/server/EntityAgeable.java -+++ b/src/main/java/net/minecraft/server/EntityAgeable.java -@@ -86,7 +86,7 @@ public abstract class EntityAgeable extends EntityCreature { - - return true; - } else { -- return false; -+ return super.a(entityhuman, enumhand); // Purpur - } - } - -diff --git a/src/main/java/net/minecraft/server/EntityBat.java b/src/main/java/net/minecraft/server/EntityBat.java -index 34239160b..592408bac 100644 ---- a/src/main/java/net/minecraft/server/EntityBat.java -+++ b/src/main/java/net/minecraft/server/EntityBat.java -@@ -14,9 +14,44 @@ public class EntityBat extends EntityAmbient { - - public EntityBat(EntityTypes entitytypes, World world) { - super(entitytypes, world); -+ this.moveController = new net.pl3x.purpur.controller.ControllerMoveWASDFlyingWithSpacebar(this, 0.075F); // Purpur - this.setAsleep(true); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.batRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.batRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.batRequireShiftToMount; -+ } -+ -+ @Override -+ public double getMaxY() { -+ return world.purpurConfig.batMaxY; -+ } -+ -+ @Override -+ public void e(Vec3D vec3d) { -+ super.e(vec3d); -+ if (hasRider() && !onGround) { -+ float speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue(); -+ setSpeed(speed); -+ Vec3D mot = getMot(); -+ move(EnumMoveType.SELF, mot.multiply(speed, 1.0, speed)); -+ setMot(mot.a(0.9D)); -+ } -+ } -+ // Purpur end -+ - @Override - protected void initDatawatcher() { - super.initDatawatcher(); -@@ -64,6 +99,12 @@ public class EntityBat extends EntityAmbient { - protected void initAttributes() { - super.initAttributes(); - this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(6.0D); -+ // Purpur start -+ if (world != null && world.purpurConfig.batRidable) { -+ this.getAttributeMap().b(GenericAttributes.FLYING_SPEED); -+ this.getAttributeInstance(GenericAttributes.FLYING_SPEED).setValue(0.6000000238418579D); -+ } -+ // Purpur end - } - - public boolean isAsleep() { -@@ -95,6 +136,13 @@ public class EntityBat extends EntityAmbient { - - @Override - protected void mobTick() { -+ // Purpur start -+ if (hasRider()) { -+ Vec3D mot = getMot(); -+ setMot(mot.x, mot.y + (getVertical() > 0 ? 0.07D : 0.0D), mot.z); -+ return; -+ } -+ // Purpur end - super.mobTick(); - BlockPosition blockposition = new BlockPosition(this); - BlockPosition blockposition1 = blockposition.up(); -@@ -229,4 +277,14 @@ public class EntityBat extends EntityAmbient { - protected float b(EntityPose entitypose, EntitySize entitysize) { - return entitysize.height / 2.0F; - } -+ -+ // Purpur start -+ @Override -+ public void onMount(EntityHuman entityhuman) { -+ if (isAsleep()) { -+ setAsleep(false); -+ world.playEffect(null, 1025, new BlockPosition(this).up(), 0); -+ } -+ } -+ // Purpur end - } -diff --git a/src/main/java/net/minecraft/server/EntityBee.java b/src/main/java/net/minecraft/server/EntityBee.java -index dd1d246ae..f0f83baac 100644 ---- a/src/main/java/net/minecraft/server/EntityBee.java -+++ b/src/main/java/net/minecraft/server/EntityBee.java -@@ -36,9 +36,7 @@ public class EntityBee extends EntityAnimal implements EntityBird { - - public EntityBee(EntityTypes entitytypes, World world) { - super(entitytypes, world); -- // Paper start - apply gravity to bees when they get stuck in the void, fixes MC-167279 -- this.moveController = new ControllerMoveFlying(this, 20, true) { -- @Override -+ this.moveController = new ControllerMoveWASDBee(this, 20, true) { // Purpur - public void tick() { - if (getEntity().locY() <= 0) { - getEntity().setNoGravity(false); -@@ -46,13 +44,55 @@ public class EntityBee extends EntityAnimal implements EntityBird { - super.tick(); - } - }; -- // Paper end -- this.lookController = new EntityBee.j(this); -+ // Purpur start -+ this.lookController = new net.pl3x.purpur.controller.ControllerLookWASD(this) { -+ @Override -+ protected void tick() { -+ if (!((EntityBee) entity).isAngry()) { -+ super.tick(); -+ } -+ } -+ }; -+ // Purpur end - this.a(PathType.WATER, -1.0F); - this.a(PathType.COCOA, -1.0F); - this.a(PathType.FENCE, -1.0F); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.beeRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.beeRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.beeRequireShiftToMount; -+ } -+ -+ @Override -+ public double getMaxY() { -+ return world.purpurConfig.beeMaxY; -+ } -+ -+ @Override -+ public void e(Vec3D vec3d) { -+ super.e(vec3d); -+ if (hasRider() && !onGround) { -+ float speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue(); -+ setSpeed(speed); -+ Vec3D mot = getMot(); -+ move(EnumMoveType.SELF, mot.multiply(speed, speed, speed)); -+ setMot(mot.a(0.9D)); -+ } -+ } -+ // Purpur end -+ - @Override - protected void initDatawatcher() { - super.initDatawatcher(); -@@ -67,6 +107,7 @@ public class EntityBee extends EntityAnimal implements EntityBird { - - @Override - protected void initPathfinder() { -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(0, new EntityBee.b(this, 1.399999976158142D, true)); - this.goalSelector.a(1, new EntityBee.d()); - this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D)); -@@ -82,6 +123,7 @@ public class EntityBee extends EntityAnimal implements EntityBird { - this.goalSelector.a(7, new EntityBee.g()); - this.goalSelector.a(8, new EntityBee.l()); - this.goalSelector.a(9, new PathfinderGoalFloat(this)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, (new EntityBee.h(this)).a(new Class[0])); - this.targetSelector.a(2, new EntityBee.c(this)); - } -@@ -590,6 +632,7 @@ public class EntityBee extends EntityAnimal implements EntityBird { - - private d() { - super(); // CraftBukkit - decompile error -+ this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); // Purpur - enter hive - } - - @Override -@@ -652,6 +695,7 @@ public class EntityBee extends EntityAnimal implements EntityBird { - - private g() { - super(); // CraftBukkit - decompile error -+ this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); // Purpur - grow crop - } - - @Override -@@ -716,6 +760,7 @@ public class EntityBee extends EntityAnimal implements EntityBird { - - private i() { - super(); // CraftBukkit - decompile error -+ this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); // Purpur - go to hive - } - - @Override -@@ -1234,4 +1279,67 @@ public class EntityBee extends EntityAnimal implements EntityBird { - - } - } -+ -+ // Purpur start -+ public static class ControllerMoveWASDBee extends ControllerMoveFlying { -+ protected final EntityBee entity; -+ protected int tooHighCooldown = 0; -+ -+ public ControllerMoveWASDBee(EntityBee entity, int pitchDelta, boolean gravity) { -+ super(entity, pitchDelta, gravity); -+ this.entity = entity; -+ } -+ -+ // isUpdating -+ @Override -+ public boolean b() { -+ return entity.hasRider() || super.b(); -+ } -+ -+ // tick -+ @Override -+ public void a() { -+ if (entity.hasRider()) { -+ tick(entity.getRider()); -+ } else { -+ tick(); -+ } -+ } -+ -+ protected void tick(EntityHuman rider) { -+ float forward = Math.max(0.0F, rider.getForward()); -+ float vertical = forward == 0.0F ? 0.0F : -(rider.pitch / 90.0F); -+ float strafe = rider.getStrafe(); -+ -+ if (rider.jumping && net.pl3x.purpur.controller.ControllerMoveWASD.spacebarEvent(entity)) { -+ entity.onSpacebar(); -+ } -+ -+ if (entity.locY() >= entity.getMaxY() || --tooHighCooldown > 0) { -+ tooHighCooldown = 60; -+ entity.setMot(entity.getMot().add(0.0D, -0.05D, 0.0D)); -+ vertical = 0.0F; -+ } -+ -+ setSpeed(entity.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue()); -+ float speed = (float) getSpeed(); -+ -+ if (entity.onGround) { -+ speed *= 0.25F; -+ } -+ -+ entity.setSpeed(speed); -+ entity.setVertical(vertical); -+ entity.setStrafe(strafe); -+ entity.setForward(forward); -+ -+ setForward(entity.getForward()); -+ setStrafe(entity.getStrafe()); -+ -+ if (forward == 0 && strafe == 0) { -+ entity.setMot(entity.getMot().multiply(0.95, 0.9, 0.95)); -+ } -+ } -+ } -+ // Purpur end - } -diff --git a/src/main/java/net/minecraft/server/EntityBlaze.java b/src/main/java/net/minecraft/server/EntityBlaze.java -index da6a3fa2c..d02130e0d 100644 ---- a/src/main/java/net/minecraft/server/EntityBlaze.java -+++ b/src/main/java/net/minecraft/server/EntityBlaze.java -@@ -10,6 +10,7 @@ public class EntityBlaze extends EntityMonster { - - public EntityBlaze(EntityTypes entitytypes, World world) { - super(entitytypes, world); -+ this.moveController = new net.pl3x.purpur.controller.ControllerMoveWASDFlyingWithSpacebar(this, 0.3F); // Purpur - this.a(PathType.WATER, -1.0F); - this.a(PathType.LAVA, 8.0F); - this.a(PathType.DANGER_FIRE, 0.0F); -@@ -17,13 +18,49 @@ public class EntityBlaze extends EntityMonster { - this.f = 10; - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.blazeRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.blazeRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.blazeRequireShiftToMount; -+ } -+ -+ @Override -+ public double getMaxY() { -+ return world.purpurConfig.blazeMaxY; -+ } -+ -+ @Override -+ public void e(Vec3D vec3d) { -+ super.e(vec3d); -+ if (hasRider() && !onGround) { -+ float speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue(); -+ setSpeed(speed); -+ Vec3D mot = getMot(); -+ move(EnumMoveType.SELF, mot.multiply(speed, 1.0, speed)); -+ setMot(mot.a(0.9D)); -+ } -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(4, new EntityBlaze.PathfinderGoalBlazeFireball(this)); - this.goalSelector.a(5, new PathfinderGoalMoveTowardsRestriction(this, 1.0D)); - this.goalSelector.a(7, new PathfinderGoalRandomStrollLand(this, 1.0D, 0.0F)); - this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); - this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this).a(new Class[0])); // Purpur - decompile error - this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); - } -@@ -34,6 +71,12 @@ public class EntityBlaze extends EntityMonster { - this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(6.0D); - this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.23000000417232513D); - this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(48.0D); -+ // Purpur start -+ if (world != null && world.purpurConfig.blazeRidable) { -+ this.getAttributeMap().b(GenericAttributes.FLYING_SPEED); -+ this.getAttributeInstance(GenericAttributes.FLYING_SPEED).setValue(0.6000000238418579D); -+ } -+ // Purpur end - } - - @Override -@@ -87,6 +130,14 @@ public class EntityBlaze extends EntityMonster { - this.damageEntity(DamageSource.DROWN, 1.0F); - } - -+ // Purpur start -+ if (hasRider()) { -+ Vec3D mot = getMot(); -+ setMot(mot.x, getVertical() > 0 ? 0.07D : -0.07D, mot.z); -+ return; -+ } -+ // Purpur end -+ - --this.c; - if (this.c <= 0) { - this.c = 100; -diff --git a/src/main/java/net/minecraft/server/EntityCat.java b/src/main/java/net/minecraft/server/EntityCat.java -index b3bdc194a..8b9222d77 100644 ---- a/src/main/java/net/minecraft/server/EntityCat.java -+++ b/src/main/java/net/minecraft/server/EntityCat.java -@@ -42,6 +42,23 @@ public class EntityCat extends EntityTameableAnimal { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.catRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.catRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.catRequireShiftToMount; -+ } -+ // Purpur end -+ - public MinecraftKey ez() { - return (MinecraftKey) EntityCat.bz.getOrDefault(this.getCatType(), EntityCat.bz.get(0)); - } -@@ -50,7 +67,8 @@ public class EntityCat extends EntityTameableAnimal { - protected void initPathfinder() { - this.goalSit = new PathfinderGoalSit(this); - this.bG = new EntityCat.PathfinderGoalTemptChance(this, 0.6D, EntityCat.bA, true); -- this.goalSelector.a(1, new PathfinderGoalFloat(this)); -+ this.goalSelector.a(0, new PathfinderGoalFloat(this)); // Purpur -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(1, new EntityCat.b(this)); - this.goalSelector.a(2, this.goalSit); - this.goalSelector.a(3, this.bG); -@@ -62,6 +80,7 @@ public class EntityCat extends EntityTameableAnimal { - this.goalSelector.a(10, new PathfinderGoalBreed(this, 0.8D)); - this.goalSelector.a(11, new PathfinderGoalRandomStrollLand(this, 0.8D, 1.0000001E-5F)); - this.goalSelector.a(12, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 10.0F)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, new PathfinderGoalRandomTargetNonTamed<>(this, EntityRabbit.class, false, (Predicate) null)); - this.targetSelector.a(1, new PathfinderGoalRandomTargetNonTamed<>(this, EntityTurtle.class, false, EntityTurtle.bw)); - } -@@ -78,6 +97,7 @@ public class EntityCat extends EntityTameableAnimal { - this.datawatcher.set(EntityCat.bB, i); - } - -+ public void setSleepingWithOwner(boolean flag) { u(flag); } // Purpur - OBFHELPER - public void u(boolean flag) { - this.datawatcher.set(EntityCat.bC, flag); - } -@@ -86,6 +106,7 @@ public class EntityCat extends EntityTameableAnimal { - return (Boolean) this.datawatcher.get(EntityCat.bC); - } - -+ public void setHeadDown(boolean flag) { v(flag); } // Purpur - OBFHELPER - public void v(boolean flag) { - this.datawatcher.set(EntityCat.bD, flag); - } -@@ -306,6 +327,7 @@ public class EntityCat extends EntityTameableAnimal { - - @Override - public boolean a(EntityHuman entityhuman, EnumHand enumhand) { -+ if (hasRider()) return false; // Purpur - ItemStack itemstack = entityhuman.b(enumhand); - Item item = itemstack.getItem(); - -@@ -396,6 +418,15 @@ public class EntityCat extends EntityTameableAnimal { - - } - -+ // Purpur start -+ public void onMount(EntityHuman entityhuman) { -+ super.onMount(entityhuman); -+ setSitting(false); -+ setSleepingWithOwner(false); -+ setHeadDown(false); -+ } -+ // Purpur end -+ - static class b extends PathfinderGoal { - - private final EntityCat a; -@@ -405,6 +436,7 @@ public class EntityCat extends EntityTameableAnimal { - - public b(EntityCat entitycat) { - this.a = entitycat; -+ this.a(java.util.EnumSet.of(PathfinderGoal.Type.MOVE)); // Purpur - lay on owner - } - - @Override -diff --git a/src/main/java/net/minecraft/server/EntityCaveSpider.java b/src/main/java/net/minecraft/server/EntityCaveSpider.java -index 23ced2c7b..5b86b36f6 100644 ---- a/src/main/java/net/minecraft/server/EntityCaveSpider.java -+++ b/src/main/java/net/minecraft/server/EntityCaveSpider.java -@@ -8,6 +8,23 @@ public class EntityCaveSpider extends EntitySpider { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.caveSpiderRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.caveSpiderRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.caveSpiderRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initAttributes() { - super.initAttributes(); -diff --git a/src/main/java/net/minecraft/server/EntityChicken.java b/src/main/java/net/minecraft/server/EntityChicken.java -index 65795fc89..5505b7ee9 100644 ---- a/src/main/java/net/minecraft/server/EntityChicken.java -+++ b/src/main/java/net/minecraft/server/EntityChicken.java -@@ -17,9 +17,27 @@ public class EntityChicken extends EntityAnimal { - this.a(PathType.WATER, 0.0F); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.chickenRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.chickenRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.chickenRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { - this.goalSelector.a(0, new PathfinderGoalFloat(this)); -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.4D)); - this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D)); - this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.0D, false, EntityChicken.bD)); -@@ -66,6 +84,7 @@ public class EntityChicken extends EntityAnimal { - - this.bw += this.bA * 2.0F; - if (!this.world.isClientSide && this.isAlive() && !this.isBaby() && !this.isChickenJockey() && --this.eggLayTime <= 0) { -+ if (world.purpurConfig.chickenDontLayEggsWhenRidden) return; // Purpur - this.a(SoundEffects.ENTITY_CHICKEN_EGG, 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F); - this.forceDrops = true; // CraftBukkit - this.a((IMaterial) Items.EGG); -diff --git a/src/main/java/net/minecraft/server/EntityCod.java b/src/main/java/net/minecraft/server/EntityCod.java -index 1e3782122..0153a821e 100644 ---- a/src/main/java/net/minecraft/server/EntityCod.java -+++ b/src/main/java/net/minecraft/server/EntityCod.java -@@ -6,6 +6,23 @@ public class EntityCod extends EntityFishSchool { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.codRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.codRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.codRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected ItemStack l() { - return new ItemStack(Items.COD_BUCKET); -diff --git a/src/main/java/net/minecraft/server/EntityComplexPart.java b/src/main/java/net/minecraft/server/EntityComplexPart.java -index a0b35c869..144e89f22 100644 ---- a/src/main/java/net/minecraft/server/EntityComplexPart.java -+++ b/src/main/java/net/minecraft/server/EntityComplexPart.java -@@ -47,4 +47,11 @@ public class EntityComplexPart extends Entity { - public EntitySize a(EntityPose entitypose) { - return this.d; - } -+ -+ // Purpur start -+ @Override -+ public boolean b(EntityHuman entityhuman, EnumHand enumhand) { -+ return owner.isAlive() && owner.tryRide(entityhuman, enumhand); -+ } -+ // Purpur end - } -diff --git a/src/main/java/net/minecraft/server/EntityCow.java b/src/main/java/net/minecraft/server/EntityCow.java -index 2c8bbf20a..723a9fa1e 100644 ---- a/src/main/java/net/minecraft/server/EntityCow.java -+++ b/src/main/java/net/minecraft/server/EntityCow.java -@@ -11,9 +11,27 @@ public class EntityCow extends EntityAnimal { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.cowRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.cowRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.cowRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { - this.goalSelector.a(0, new PathfinderGoalFloat(this)); -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(1, new PathfinderGoalPanic(this, 2.0D)); - this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D)); - this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.25D, RecipeItemStack.a(Items.WHEAT), false)); -diff --git a/src/main/java/net/minecraft/server/EntityCreeper.java b/src/main/java/net/minecraft/server/EntityCreeper.java -index 45dfc8104..48fd8e716 100644 ---- a/src/main/java/net/minecraft/server/EntityCreeper.java -+++ b/src/main/java/net/minecraft/server/EntityCreeper.java -@@ -23,16 +23,35 @@ public class EntityCreeper extends EntityMonster { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.creeperRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.creeperRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.creeperRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { - this.goalSelector.a(1, new PathfinderGoalFloat(this)); - this.goalSelector.a(2, new PathfinderGoalSwell(this)); -+ this.goalSelector.a(3, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(3, new PathfinderGoalAvoidTarget<>(this, EntityOcelot.class, 6.0F, 1.0D, 1.2D)); - this.goalSelector.a(3, new PathfinderGoalAvoidTarget<>(this, EntityCat.class, 6.0F, 1.0D, 1.2D)); - this.goalSelector.a(4, new PathfinderGoalMeleeAttack(this, 1.0D, false)); - this.goalSelector.a(5, new PathfinderGoalRandomStrollLand(this, 0.8D)); - this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); - this.goalSelector.a(6, new PathfinderGoalRandomLookaround(this)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); - this.targetSelector.a(2, new PathfinderGoalHurtByTarget(this, new Class[0])); - } -@@ -165,6 +184,7 @@ public class EntityCreeper extends EntityMonster { - return (Integer) this.datawatcher.get(EntityCreeper.b); - } - -+ public void setSwellDirection(int i) { a(i); } // Purpur - OBFHELPER - public void a(int i) { - this.datawatcher.set(EntityCreeper.b, i); - } -@@ -265,6 +285,7 @@ public class EntityCreeper extends EntityMonster { - com.destroystokyo.paper.event.entity.CreeperIgniteEvent event = new com.destroystokyo.paper.event.entity.CreeperIgniteEvent((org.bukkit.entity.Creeper) getBukkitEntity(), ignited); - if (event.callEvent()) { - this.datawatcher.set(EntityCreeper.d, event.isIgnited()); -+ if (!event.isIgnited()) setSwellDirection(-1); - } - } - // Paper end -@@ -277,4 +298,59 @@ public class EntityCreeper extends EntityMonster { - public void setCausedHeadDrop() { - ++this.bA; - } -+ -+ // Purpur start -+ @Override -+ protected void mobTick() { -+ if (powerToggleDelay > 0) { -+ powerToggleDelay--; -+ } -+ if (hasRider()) { -+ if (getRider().getForward() != 0 || getRider().getStrafe() != 0) { -+ spacebarCharge = 0; -+ setIgnited(false); -+ } -+ if (spacebarCharge == prevSpacebarCharge) { -+ spacebarCharge = 0; -+ } -+ prevSpacebarCharge = spacebarCharge; -+ } -+ super.mobTick(); -+ } -+ -+ @Override -+ public void onMount(EntityHuman entityhuman) { -+ super.onMount(entityhuman); -+ setIgnited(false); -+ } -+ -+ private int spacebarCharge = 0; -+ private int prevSpacebarCharge = 0; -+ private int powerToggleDelay = 0; -+ -+ @Override -+ public boolean onSpacebar() { -+ if (powerToggleDelay > 0) { -+ return true; // just toggled power, do not jump or ignite -+ } -+ spacebarCharge++; -+ if (spacebarCharge > maxFuseTicks - 2) { -+ spacebarCharge = 0; -+ if (getRider().getBukkitEntity().hasPermission("allow.powered.creeper")) { -+ powerToggleDelay = 20; -+ setPowered(!isPowered()); -+ setIgnited(false); -+ return true; -+ } -+ } -+ if (!isIgnited()) { -+ if (hasRider() && getRider().getForward() == 0 && getRider().getStrafe() == 0 && -+ getRider().getBukkitEntity().hasPermission("allow.special.creeper")) { -+ setIgnited(true); -+ return true; -+ } -+ } -+ return getForward() == 0 && getStrafe() == 0; // do not jump if standing still -+ } -+ // Purpur end - } -diff --git a/src/main/java/net/minecraft/server/EntityDolphin.java b/src/main/java/net/minecraft/server/EntityDolphin.java -index ce78586ea..81570b37b 100644 ---- a/src/main/java/net/minecraft/server/EntityDolphin.java -+++ b/src/main/java/net/minecraft/server/EntityDolphin.java -@@ -1,5 +1,12 @@ - package net.minecraft.server; - -+// Purpur start -+import net.pl3x.purpur.entity.DolphinSpit; -+import org.bukkit.Location; -+import org.bukkit.craftbukkit.entity.CraftPlayer; -+import org.bukkit.util.Vector; -+// Purpur end -+ - import java.util.EnumSet; - import java.util.List; - import java.util.Random; -@@ -15,6 +22,7 @@ public class EntityDolphin extends EntityWaterAnimal { - public static final Predicate b = (entityitem) -> { - return !entityitem.p() && entityitem.isAlive() && entityitem.isInWater(); - }; -+ private int spitCooldown; // Purpur - - public EntityDolphin(EntityTypes entitytypes, World world) { - super(entitytypes, world); -@@ -23,6 +31,50 @@ public class EntityDolphin extends EntityWaterAnimal { - this.setCanPickupLoot(true); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.dolphinRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.dolphinRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.dolphinRequireShiftToMount; -+ } -+ -+ @Override -+ public boolean onSpacebar() { -+ if (spitCooldown == 0 && hasRider()) { -+ spitCooldown = world.purpurConfig.dolphinSpitCooldown; -+ if (!hasRider()) { -+ return false; -+ } -+ -+ CraftPlayer player = (CraftPlayer) getRider().getBukkitEntity(); -+ if (!player.hasPermission("allow.special.dolphin")) { -+ return false; -+ } -+ -+ Location loc = player.getEyeLocation(); -+ loc.setPitch(loc.getPitch() - 10); -+ Vector target = loc.getDirection().normalize().multiply(10).add(loc.toVector()); -+ -+ DolphinSpit spit = new DolphinSpit(world, this); -+ spit.shoot(target.getX() - locX(), target.getY() - locY(), target.getZ() - locZ(), world.purpurConfig.dolphinSpitSpeed, 5.0F); -+ -+ world.addEntity(spit); -+ playSound(SoundEffects.ENTITY_DOLPHIN_ATTACK, 1.0F, 1.0F + (random.nextFloat() - random.nextFloat()) * 0.2F); -+ return true; -+ } -+ return false; -+ } -+ // Purpur end -+ - @Nullable - @Override - public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { -@@ -97,6 +149,7 @@ public class EntityDolphin extends EntityWaterAnimal { - protected void initPathfinder() { - this.goalSelector.a(0, new PathfinderGoalBreath(this)); - this.goalSelector.a(0, new PathfinderGoalWater(this)); -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(1, new EntityDolphin.b(this)); - this.goalSelector.a(2, new EntityDolphin.c(this, 4.0D)); - this.goalSelector.a(4, new PathfinderGoalRandomSwim(this, 1.0D, 10)); -@@ -107,6 +160,7 @@ public class EntityDolphin extends EntityWaterAnimal { - this.goalSelector.a(8, new EntityDolphin.d()); - this.goalSelector.a(8, new PathfinderGoalFollowBoat(this)); - this.goalSelector.a(9, new PathfinderGoalAvoidTarget<>(this, EntityGuardian.class, 8.0F, 1.0D, 1.0D)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityGuardian.class})).a(new Class[0])); // CraftBukkit - decompile error - } - -@@ -163,7 +217,7 @@ public class EntityDolphin extends EntityWaterAnimal { - - @Override - protected boolean n(Entity entity) { -- return true; -+ return getRideCooldown() <= 0; // Purpur - make dolphin honor ride cooldown like all other non-boss mobs - } - - @Override -@@ -196,6 +250,9 @@ public class EntityDolphin extends EntityWaterAnimal { - @Override - public void tick() { - super.tick(); -+ if (spitCooldown > 0) { -+ spitCooldown--; -+ } - if (!this.isNoAI()) { - if (this.ay()) { - this.b(2400); -@@ -459,7 +516,7 @@ public class EntityDolphin extends EntityWaterAnimal { - - private int b; - -- private d() {} -+ private d() { this.a(java.util.EnumSet.of(PathfinderGoal.Type.MOVE)); } // Purpur - play with item - - @Override - public boolean a() { -@@ -527,7 +584,7 @@ public class EntityDolphin extends EntityWaterAnimal { - } - } - -- static class a extends ControllerMove { -+ static class a extends net.pl3x.purpur.controller.ControllerMoveWASDWater { // Purpur - - private final EntityDolphin i; - -@@ -537,7 +594,20 @@ public class EntityDolphin extends EntityWaterAnimal { - } - - @Override -- public void a() { -+ // Purpur start -+ public void tick(EntityHuman rider) { -+ if (this.i.getAirTicks() < 150) { -+ // if drowning override player WASD controls to find air -+ tick(); -+ } else { -+ super.tick(rider); -+ this.i.setMot(this.i.getMot().add(0.0D, 0.005D, 0.0D)); -+ } -+ } -+ -+ @Override -+ public void tick() { -+ // Purpur end - if (this.i.isInWater()) { - this.i.setMot(this.i.getMot().add(0.0D, 0.005D, 0.0D)); - } -diff --git a/src/main/java/net/minecraft/server/EntityDrowned.java b/src/main/java/net/minecraft/server/EntityDrowned.java -index 77885f67f..63f5969b1 100644 ---- a/src/main/java/net/minecraft/server/EntityDrowned.java -+++ b/src/main/java/net/minecraft/server/EntityDrowned.java -@@ -19,6 +19,23 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { - this.navigationLand = new Navigation(this, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.drownedRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.drownedRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.drownedRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void l() { - this.goalSelector.a(1, new EntityDrowned.c(this, 1.0D)); -@@ -200,7 +217,7 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { - this.bw = flag; - } - -- static class d extends ControllerMove { -+ static class d extends net.pl3x.purpur.controller.ControllerMoveWASD { // Purpur - - private final EntityDrowned i; - -@@ -210,7 +227,7 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { - } - - @Override -- public void a() { -+ public void tick() { // Purpur - EntityLiving entityliving = this.i.getGoalTarget(); - - if (this.i.ez() && this.i.isInWater()) { -@@ -243,7 +260,7 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { - this.i.setMot(this.i.getMot().add(0.0D, -0.008D, 0.0D)); - } - -- super.a(); -+ super.tick(); // Purpur - } - - } -@@ -382,6 +399,7 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { - this.a = entitydrowned; - this.b = d0; - this.c = i; -+ this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); // Purpur - swim up - } - - @Override -diff --git a/src/main/java/net/minecraft/server/EntityEnderDragon.java b/src/main/java/net/minecraft/server/EntityEnderDragon.java -index 7daebfdab..54b63395f 100644 ---- a/src/main/java/net/minecraft/server/EntityEnderDragon.java -+++ b/src/main/java/net/minecraft/server/EntityEnderDragon.java -@@ -46,6 +46,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { - private final int[] bS = new int[24]; - private final Path bT = new Path(); - private Explosion explosionSource = new Explosion(null, this, Double.NaN, Double.NaN, Double.NaN, Float.NaN, true, Explosion.Effect.DESTROY); // CraftBukkit - reusable source for CraftTNTPrimed.getSource() -+ private boolean hadRider; // Purpur - - public EntityEnderDragon(EntityTypes entitytypes, World world) { - super(EntityTypes.ENDER_DRAGON, world); -@@ -60,8 +61,50 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { - } - - this.bO = new DragonControllerManager(this); -+ -+ // Purpur start -+ this.moveController = new net.pl3x.purpur.controller.ControllerMoveWASDFlying(this) { -+ @Override -+ public void tick() { -+ // dragon doesn't use the controller. do nothing -+ } -+ }; -+ this.lookController = new net.pl3x.purpur.controller.ControllerLookWASD(this) { -+ @Override -+ public void tick() { -+ // dragon doesn't use the controller. do nothing -+ } -+ -+ @Override -+ public void tick(EntityHuman rider) { -+ setYawPitch(rider.yaw - 180F, rider.pitch * 0.5F); -+ } -+ }; -+ // Purpur end -+ } -+ -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.enderDragonRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.enderDragonRidableInWater; - } - -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.enderDragonRequireShiftToMount; -+ } -+ -+ @Override -+ public double getMaxY() { -+ return world.purpurConfig.enderDragonMaxY; -+ } -+ // Purpur end -+ - @Override - protected void initAttributes() { - super.initAttributes(); -@@ -96,6 +139,37 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { - - @Override - public void movementTick() { -+ // Purpur start -+ boolean hasRider = getRider() != null; -+ if (hasRider) { -+ if (!hadRider) { -+ hadRider = true; -+ noclip = false; -+ this.size = EntitySize.b(4.0F, 2.0F); -+ } -+ -+ // dragon doesn't use controllers, so must tick manually -+ moveController.a(); -+ lookController.a(); -+ -+ moveRelative((float) getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue() * 0.1F, new Vec3D(-getStrafe(), getVertical(), -getForward())); -+ Vec3D mot = getMot(); -+ setMot(mot); -+ move(EnumMoveType.PLAYER, mot); -+ -+ mot = mot.multiply(0.9F, 0.9F, 0.9F); -+ setMot(mot); -+ -+ // control wing flap speed on client -+ getDragonControllerManager().setControllerPhase(mot.getX() * mot.getX() + mot.getZ() * mot.getZ() < 0.005F ? DragonControllerPhase.HOVER : DragonControllerPhase.HOLDING_PATTERN); -+ } else if (hadRider) { -+ hadRider = false; -+ noclip = true; -+ this.size = EntitySize.b(16.0F, 8.0F); -+ getDragonControllerManager().setControllerPhase(DragonControllerPhase.HOLDING_PATTERN); // HoldingPattern -+ } -+ // Purpur end -+ - float f; - float f1; - -@@ -117,6 +191,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { - - this.bx = this.by; - if (this.getHealth() <= 0.0F) { -+ if (hasRider) ejectPassengers(); // Purpur - f = (this.random.nextFloat() - 0.5F) * 8.0F; - f1 = (this.random.nextFloat() - 0.5F) * 4.0F; - float f2 = (this.random.nextFloat() - 0.5F) * 8.0F; -@@ -128,9 +203,9 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { - - f1 = 0.2F / (MathHelper.sqrt(b(vec3d)) * 10.0F + 1.0F); - f1 *= (float) Math.pow(2.0D, vec3d.y); -- if (this.bO.a().a()) { -+ if (!hasRider && this.bO.a().a()) { // Purpur - this.by += 0.1F; -- } else if (this.bz) { -+ } else if (!hasRider && this.bz) { // Purpur - this.by += f1 * 0.5F; - } else { - this.by += f1; -@@ -174,7 +249,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { - } - - this.bO.a().b(); -- } else { -+ } else if (!hasRider) { // Purpur - IDragonController idragoncontroller = this.bO.a(); - - idragoncontroller.c(); -@@ -241,7 +316,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { - this.a(this.bH, (double) (f11 * 0.5F), 0.0D, (double) (-f12 * 0.5F)); - this.a(this.bL, (double) (f12 * 4.5F), 2.0D, (double) (f11 * 4.5F)); - this.a(this.bM, (double) (f12 * -4.5F), 2.0D, (double) (f11 * -4.5F)); -- if (!this.world.isClientSide && this.hurtTicks == 0) { -+ if (!hasRider && this.hurtTicks == 0) { // Purpur - this.a(this.world.getEntities(this, this.bL.getBoundingBox().grow(4.0D, 2.0D, 4.0D).d(0.0D, -2.0D, 0.0D), IEntitySelector.e)); - this.a(this.world.getEntities(this, this.bM.getBoundingBox().grow(4.0D, 2.0D, 4.0D).d(0.0D, -2.0D, 0.0D), IEntitySelector.e)); - this.b(this.world.getEntities(this, this.bw.getBoundingBox().g(1.0D), IEntitySelector.e)); -@@ -284,7 +359,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { - } - - if (!this.world.isClientSide) { -- this.bz = this.b(this.bw.getBoundingBox()) | this.b(this.bG.getBoundingBox()) | this.b(this.bH.getBoundingBox()); -+ this.bz = !hasRider && this.b(this.bw.getBoundingBox()) | this.b(this.bG.getBoundingBox()) | this.b(this.bH.getBoundingBox()); // Purpur - if (this.bN != null) { - this.bN.b(this); - } -@@ -953,7 +1028,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { - - @Override - protected boolean n(Entity entity) { -- return false; -+ return getRideCooldown() <= 0; // Purpur - } - - @Override -diff --git a/src/main/java/net/minecraft/server/EntityEnderman.java b/src/main/java/net/minecraft/server/EntityEnderman.java -index 212636dcb..de30ce483 100644 ---- a/src/main/java/net/minecraft/server/EntityEnderman.java -+++ b/src/main/java/net/minecraft/server/EntityEnderman.java -@@ -27,9 +27,27 @@ public class EntityEnderman extends EntityMonster { - this.a(PathType.WATER, -1.0F); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.endermanRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.endermanRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.endermanRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { - this.goalSelector.a(0, new PathfinderGoalFloat(this)); -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(1, new EntityEnderman.a(this)); - this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, 1.0D, false)); - this.goalSelector.a(7, new PathfinderGoalRandomStrollLand(this, 1.0D, 0.0F)); -@@ -37,6 +55,7 @@ public class EntityEnderman extends EntityMonster { - this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); - this.goalSelector.a(10, new EntityEnderman.PathfinderGoalEndermanPlaceBlock(this)); - this.goalSelector.a(11, new EntityEnderman.PathfinderGoalEndermanPickupBlock(this)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, new EntityEnderman.PathfinderGoalPlayerWhoLookedAtTarget(this)); - this.targetSelector.a(2, new PathfinderGoalHurtByTarget(this, new Class[0])); - this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityEndermite.class, 10, true, false, EntityEnderman.by)); -@@ -189,7 +208,7 @@ public class EntityEnderman extends EntityMonster { - this.damageEntity(DamageSource.DROWN, 1.0F); // Paper - copied in patch 13 (allow nerfed mobs to jump, float and take water damage) - } - -- if (this.world.isDay() && this.ticksLived >= this.bA + 600) { -+ if (!hasRider() && this.world.isDay() && this.ticksLived >= this.bA + 600) { // Purpur - no random teleporting - float f = this.aI(); - - if (f > 0.5F && this.world.f(new BlockPosition(this)) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.tryEscape(EndermanEscapeEvent.Reason.RUNAWAY)) { // Paper -@@ -290,6 +309,7 @@ public class EntityEnderman extends EntityMonster { - public boolean damageEntity(DamageSource damagesource, float f) { - if (this.isInvulnerable(damagesource)) { - return false; -+ } else if (hasRider()) { return super.damageEntity(damagesource, f); // Purpur - no teleporting on damage - } else if (!(damagesource instanceof EntityDamageSourceIndirect) && damagesource != DamageSource.FIREWORKS) { - boolean flag = super.damageEntity(damagesource, f); - -@@ -329,6 +349,7 @@ public class EntityEnderman extends EntityMonster { - - public PathfinderGoalEndermanPickupBlock(EntityEnderman entityenderman) { - this.enderman = entityenderman; -+ this.a(EnumSet.of(PathfinderGoal.Type.TARGET)); // Purpur - } - - @Override -@@ -367,11 +388,11 @@ public class EntityEnderman extends EntityMonster { - - static class PathfinderGoalEndermanPlaceBlock extends PathfinderGoal { - -- private EntityEnderman getEnderman() { return this.a; } // Paper - OBFHELPER -- private final EntityEnderman a; -+ private final EntityEnderman a; private EntityEnderman getEnderman() { return this.a; } // Paper - OBFHELPER - - public PathfinderGoalEndermanPlaceBlock(EntityEnderman entityenderman) { - this.a = entityenderman; -+ this.a(EnumSet.of(PathfinderGoal.Type.TARGET)); // Purpur - } - - @Override -@@ -381,6 +402,10 @@ public class EntityEnderman extends EntityMonster { - - @Override - public void e() { -+ // Purpur start -+ IBlockData carried = getEnderman().getCarried(); -+ if (carried == null) return; -+ // Purpur end - Random random = this.a.getRandom(); - World world = this.a.world; - int i = MathHelper.floor(this.a.locX() - 1.0D + random.nextDouble() * 2.0D); -@@ -391,7 +416,7 @@ public class EntityEnderman extends EntityMonster { - if (iblockdata == null) return; // Paper - BlockPosition blockposition1 = blockposition.down(); - IBlockData iblockdata1 = world.getType(blockposition1); -- IBlockData iblockdata2 = Block.getValidBlockForPosition(getEnderman().getCarried(), getEnderman().world, blockposition); // Paper - Fix MC-124320 -+ IBlockData iblockdata2 = Block.getValidBlockForPosition(carried, getEnderman().world, blockposition); // Paper - Fix MC-124320 // Purpur - - if (iblockdata2 != null && this.a(world, blockposition, iblockdata2, iblockdata, iblockdata1, blockposition1)) { - // CraftBukkit start - Place event -diff --git a/src/main/java/net/minecraft/server/EntityEndermite.java b/src/main/java/net/minecraft/server/EntityEndermite.java -index e4bd2796a..5eaf1920b 100644 ---- a/src/main/java/net/minecraft/server/EntityEndermite.java -+++ b/src/main/java/net/minecraft/server/EntityEndermite.java -@@ -12,13 +12,32 @@ public class EntityEndermite extends EntityMonster { - this.f = 3; - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.endermiteRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.endermiteRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.endermiteRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { - this.goalSelector.a(1, new PathfinderGoalFloat(this)); -+ this.goalSelector.a(1, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, 1.0D, false)); - this.goalSelector.a(3, new PathfinderGoalRandomStrollLand(this, 1.0D)); - this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); - this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this).a(new Class[0])); // Purpur - decompile error - this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); - } -diff --git a/src/main/java/net/minecraft/server/EntityEvoker.java b/src/main/java/net/minecraft/server/EntityEvoker.java -index b030fe957..179a26129 100644 ---- a/src/main/java/net/minecraft/server/EntityEvoker.java -+++ b/src/main/java/net/minecraft/server/EntityEvoker.java -@@ -12,10 +12,28 @@ public class EntityEvoker extends EntityIllagerWizard { - this.f = 10; - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.evokerRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.evokerRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.evokerRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { - super.initPathfinder(); - this.goalSelector.a(0, new PathfinderGoalFloat(this)); -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(1, new EntityEvoker.b()); - this.goalSelector.a(2, new PathfinderGoalAvoidTarget<>(this, EntityHuman.class, 8.0F, 0.6D, 1.0D)); - this.goalSelector.a(4, new EntityEvoker.c()); -@@ -24,6 +42,7 @@ public class EntityEvoker extends EntityIllagerWizard { - this.goalSelector.a(8, new PathfinderGoalRandomStroll(this, 0.6D)); - this.goalSelector.a(9, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 3.0F, 1.0F)); - this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, EntityRaider.class).a(new Class[0])); // Purpur - decompile error - this.targetSelector.a(2, (new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)).a(300)); - this.targetSelector.a(3, (new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, false)).a(300)); -@@ -108,6 +127,7 @@ public class EntityEvoker extends EntityIllagerWizard { - - public d() { - super(); -+ this.a(java.util.EnumSet.of(PathfinderGoal.Type.TARGET)); // Purpur - wolololo spell - } - - @Override -@@ -186,6 +206,7 @@ public class EntityEvoker extends EntityIllagerWizard { - private c() { - super(); - this.e = (new PathfinderTargetCondition()).a(16.0D).c().e().a().b(); -+ this.a(java.util.EnumSet.of(PathfinderGoal.Type.TARGET)); // Purpur - summon spell - } - - @Override -@@ -240,6 +261,7 @@ public class EntityEvoker extends EntityIllagerWizard { - - private a() { - super(); -+ this.a(java.util.EnumSet.of(PathfinderGoal.Type.TARGET)); // Purpur - attack with spell - } - - @Override -diff --git a/src/main/java/net/minecraft/server/EntityFish.java b/src/main/java/net/minecraft/server/EntityFish.java -index b853fd0d9..b8d786fad 100644 ---- a/src/main/java/net/minecraft/server/EntityFish.java -+++ b/src/main/java/net/minecraft/server/EntityFish.java -@@ -72,9 +72,10 @@ public abstract class EntityFish extends EntityWaterAnimal { - @Override - protected void initPathfinder() { - super.initPathfinder(); -- this.goalSelector.a(0, new PathfinderGoalPanic(this, 1.25D)); -- this.goalSelector.a(2, new PathfinderGoalAvoidTarget<>(this, EntityHuman.class, 8.0F, 1.6D, 1.4D, IEntitySelector.f::test)); // Purpur - decompile error -- this.goalSelector.a(4, new EntityFish.b(this)); -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur -+ this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.25D)); // Purpur -+ this.goalSelector.a(3, new PathfinderGoalAvoidTarget<>(this, EntityHuman.class, 8.0F, 1.6D, 1.4D, IEntitySelector.f::test)); // Purpur - decompile error -+ this.goalSelector.a(5, new EntityFish.b(this)); // Purpur - } - - @Override -@@ -85,7 +86,7 @@ public abstract class EntityFish extends EntityWaterAnimal { - @Override - public void e(Vec3D vec3d) { - if (this.doAITick() && this.isInWater()) { -- this.a(0.01F, vec3d); -+ this.a(hasRider() ? getSpeed() : 0.1F, vec3d); // Purpur - this.move(EnumMoveType.SELF, this.getMot()); - this.setMot(this.getMot().a(0.9D)); - if (this.getGoalTarget() == null) { -@@ -156,7 +157,7 @@ public abstract class EntityFish extends EntityWaterAnimal { - return SoundEffects.ENTITY_FISH_SWIM; - } - -- static class a extends ControllerMove { -+ static class a extends net.pl3x.purpur.controller.ControllerMoveWASDWater { // Purpur - - private final EntityFish i; - -@@ -165,8 +166,16 @@ public abstract class EntityFish extends EntityWaterAnimal { - this.i = entityfish; - } - -+ // Purpur start - @Override -- public void a() { -+ public void tick(EntityHuman rider) { -+ super.tick(rider); -+ this.i.setMot(this.i.getMot().add(0.0D, 0.005D, 0.0D)); -+ } -+ -+ @Override -+ public void tick() { -+ // Purpur end - if (this.i.a(TagsFluid.WATER)) { - this.i.setMot(this.i.getMot().add(0.0D, 0.005D, 0.0D)); - } -diff --git a/src/main/java/net/minecraft/server/EntityFox.java b/src/main/java/net/minecraft/server/EntityFox.java -index 82a32d5db..4f53090d3 100644 ---- a/src/main/java/net/minecraft/server/EntityFox.java -+++ b/src/main/java/net/minecraft/server/EntityFox.java -@@ -55,6 +55,23 @@ public class EntityFox extends EntityAnimal { - this.setCanPickupLoot(true); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.foxRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.foxRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.foxRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initDatawatcher() { - super.initDatawatcher(); -@@ -74,6 +91,7 @@ public class EntityFox extends EntityAnimal { - return entityliving instanceof EntityFishSchool; - }); - this.goalSelector.a(0, new EntityFox.g()); -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(1, new EntityFox.b()); - this.goalSelector.a(2, new EntityFox.n(2.2D)); - this.goalSelector.a(3, new EntityFox.e(1.0D)); -@@ -96,6 +114,7 @@ public class EntityFox extends EntityAnimal { - this.goalSelector.a(11, new EntityFox.p()); - this.goalSelector.a(12, new EntityFox.j(this, EntityHuman.class, 24.0F)); - this.goalSelector.a(13, new EntityFox.r()); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(3, new EntityFox.a(EntityLiving.class, false, false, (entityliving) -> { - return EntityFox.bB.test(entityliving) && !this.c(entityliving.getUniqueID()); - })); -@@ -376,6 +395,7 @@ public class EntityFox extends EntityAnimal { - return itemstack1.isEmpty() || this.bL > 0 && item.isFood() && !itemstack1.getItem().isFood(); - } - -+ public void spit(ItemStack itemstack) { k(itemstack); } // Purpur - OBFHELPER - private void k(ItemStack itemstack) { - if (!itemstack.isEmpty() && !this.world.isClientSide) { - EntityItem entityitem = new EntityItem(this.world, this.locX() + this.getLookDirection().x, this.locY() + 1.0D, this.locZ() + this.getLookDirection().z, itemstack); -@@ -469,6 +489,7 @@ public class EntityFox extends EntityAnimal { - return this.t(16); - } - -+ public void setChasing(boolean flag) { s(flag); } // Purpur - OBFHELPER - public void s(boolean flag) { - this.d(16, flag); - } -@@ -511,6 +532,7 @@ public class EntityFox extends EntityAnimal { - this.setSleeping(false); - } - -+ public void stopActions() { eH(); } // Purpur - OBFHELPER - private void eH() { - this.u(false); - this.setCrouching(false); -@@ -592,6 +614,29 @@ public class EntityFox extends EntityAnimal { - return deathEvent; // Paper - } - -+ // Purpur start -+ @Override -+ public float getJumpHeight() { -+ return !hasRider() ? super.getJumpHeight() : 0.5F; -+ } -+ -+ @Override -+ public void onMount(EntityHuman entityhuman) { -+ super.onMount(entityhuman); -+ setCanPickupLoot(false); -+ stopActions(); -+ setChasing(false); -+ spit(getEquipment(EnumItemSlot.MAINHAND)); -+ setSlot(EnumItemSlot.MAINHAND, ItemStack.NULL_ITEM); -+ } -+ -+ @Override -+ public void onDismount(EntityHuman entityhuman) { -+ super.onDismount(entityhuman); -+ setCanPickupLoot(true); -+ } -+ // Purpur end -+ - public static boolean a(EntityFox entityfox, EntityLiving entityliving) { - double d0 = entityliving.locZ() - entityfox.locZ(); - double d1 = entityliving.locX() - entityfox.locX(); -@@ -655,16 +700,16 @@ public class EntityFox extends EntityAnimal { - } - } - -- public class k extends ControllerLook { -+ public class k extends net.pl3x.purpur.controller.ControllerLookWASD { // Purpur - - public k() { - super(EntityFox.this); - } - - @Override -- public void a() { -+ public void tick() { // Purpur - if (!EntityFox.this.isSleeping()) { -- super.a(); -+ super.tick(); // Purpur - } - - } -@@ -1335,16 +1380,16 @@ public class EntityFox extends EntityAnimal { - } - } - -- class m extends ControllerMove { -+ class m extends net.pl3x.purpur.controller.ControllerMoveWASD { // Purpur - - public m() { - super(EntityFox.this); - } - - @Override -- public void a() { -+ public void tick() { // Purpur - if (EntityFox.this.eI()) { -- super.a(); -+ super.tick(); // Purpur - } - - } -diff --git a/src/main/java/net/minecraft/server/EntityGhast.java b/src/main/java/net/minecraft/server/EntityGhast.java -index e1c2540d1..46841df71 100644 ---- a/src/main/java/net/minecraft/server/EntityGhast.java -+++ b/src/main/java/net/minecraft/server/EntityGhast.java -@@ -14,11 +14,47 @@ public class EntityGhast extends EntityFlying implements IMonster { - this.moveController = new EntityGhast.ControllerGhast(this); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.ghastRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.ghastRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.ghastRequireShiftToMount; -+ } -+ -+ @Override -+ public double getMaxY() { -+ return world.purpurConfig.ghastMaxY; -+ } -+ -+ @Override -+ public void e(Vec3D vec3d) { -+ super.e(vec3d); -+ if (hasRider() && !onGround) { -+ float speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue(); -+ setSpeed(speed); -+ Vec3D mot = getMot(); -+ move(EnumMoveType.SELF, mot.multiply(speed, 1.0, speed)); -+ setMot(mot.a(0.9D)); -+ } -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(5, new EntityGhast.PathfinderGoalGhastIdleMove(this)); - this.goalSelector.a(7, new EntityGhast.PathfinderGoalGhastMoveTowardsTarget(this)); - this.goalSelector.a(7, new EntityGhast.PathfinderGoalGhastAttackTarget(this)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, 10, true, false, (entityliving) -> { - return Math.abs(entityliving.locY() - this.locY()) <= 4.0D; - })); -@@ -60,6 +96,12 @@ public class EntityGhast extends EntityFlying implements IMonster { - super.initAttributes(); - this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(10.0D); - this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(100.0D); -+ // Purpur start -+ if (world != null && world.purpurConfig.ghastRidable) { -+ this.getAttributeMap().b(GenericAttributes.FLYING_SPEED); -+ this.getAttributeInstance(GenericAttributes.FLYING_SPEED).setValue(0.6000000238418579D); -+ } -+ // Purpur end - } - - @Override -@@ -255,7 +297,7 @@ public class EntityGhast extends EntityFlying implements IMonster { - } - } - -- static class ControllerGhast extends ControllerMove { -+ static class ControllerGhast extends net.pl3x.purpur.controller.ControllerMoveWASDFlying { // Purpur - - private final EntityGhast i; - private int j; -@@ -266,7 +308,7 @@ public class EntityGhast extends EntityFlying implements IMonster { - } - - @Override -- public void a() { -+ public void tick() { // Purpur - if (this.h == ControllerMove.Operation.MOVE_TO) { - if (this.j-- <= 0) { - this.j += this.i.getRandom().nextInt(5) + 2; -diff --git a/src/main/java/net/minecraft/server/EntityGiantZombie.java b/src/main/java/net/minecraft/server/EntityGiantZombie.java -index d9e5eaad1..ff8a41a53 100644 ---- a/src/main/java/net/minecraft/server/EntityGiantZombie.java -+++ b/src/main/java/net/minecraft/server/EntityGiantZombie.java -@@ -4,8 +4,33 @@ public class EntityGiantZombie extends EntityMonster { - - public EntityGiantZombie(EntityTypes entitytypes, World world) { - super(entitytypes, world); -+ setStepHeight(world.purpurConfig.giantStepHeight); // Purpur - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.giantRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.giantRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.giantRequireShiftToMount; -+ } -+ -+ @Override -+ public float getJumpHeight() { -+ // make giants jump as high as everything else relative to their size -+ // 1.0 makes bottom of feet about as high as their waist when they jump -+ return world.purpurConfig.giantJumpHeight; -+ } -+ // Purpur end -+ - @Override - protected float b(EntityPose entitypose, EntitySize entitysize) { - return 10.440001F; -diff --git a/src/main/java/net/minecraft/server/EntityGuardian.java b/src/main/java/net/minecraft/server/EntityGuardian.java -index e69cb334f..97040872b 100644 ---- a/src/main/java/net/minecraft/server/EntityGuardian.java -+++ b/src/main/java/net/minecraft/server/EntityGuardian.java -@@ -24,15 +24,39 @@ public class EntityGuardian extends EntityMonster { - this.f = 10; - this.a(PathType.WATER, 0.0F); - this.moveController = new EntityGuardian.ControllerMoveGuardian(this); -- this.c = this.random.nextFloat(); -- this.d = this.c; -+ // Purpur start -+ this.lookController = new net.pl3x.purpur.controller.ControllerLookWASD(this) { -+ @Override -+ public void setYawPitch(float yaw, float pitch) { -+ super.setYawPitch(yaw, pitch * 0.35F); -+ } -+ }; -+ // Purpur end -+ } -+ -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.guardianRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.guardianRidableInWater; - } - -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.guardianRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { - PathfinderGoalMoveTowardsRestriction pathfindergoalmovetowardsrestriction = new PathfinderGoalMoveTowardsRestriction(this, 1.0D); - - this.goalRandomStroll = new PathfinderGoalRandomStroll(this, 1.0D, 80); -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(4, new EntityGuardian.PathfinderGoalGuardianAttack(this)); - this.goalSelector.a(5, pathfindergoalmovetowardsrestriction); - this.goalSelector.a(7, this.goalRandomStroll); -@@ -41,6 +65,7 @@ public class EntityGuardian extends EntityMonster { - this.goalSelector.a(9, new PathfinderGoalRandomLookaround(this)); - this.goalRandomStroll.a(EnumSet.of(PathfinderGoal.Type.MOVE, PathfinderGoal.Type.LOOK)); - pathfindergoalmovetowardsrestriction.a(EnumSet.of(PathfinderGoal.Type.MOVE, PathfinderGoal.Type.LOOK)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityLiving.class, 10, true, false, new EntityGuardian.EntitySelectorGuardianTargetHumanSquid(this))); - } - -@@ -79,6 +104,7 @@ public class EntityGuardian extends EntityMonster { - return (Boolean) this.datawatcher.get(EntityGuardian.b); - } - -+ private void setMovingFlag(boolean movingFlag) { r(movingFlag); } // Purpur - OBFHELPER - private void r(boolean flag) { - this.datawatcher.set(EntityGuardian.b, flag); - } -@@ -293,7 +319,7 @@ public class EntityGuardian extends EntityMonster { - @Override - public void e(Vec3D vec3d) { - if (this.doAITick() && this.isInWater()) { -- this.a(0.1F, vec3d); -+ this.a(hasRider() ? getSpeed(): 0.1F, vec3d); // Purpur - this.move(EnumMoveType.SELF, this.getMot()); - this.setMot(this.getMot().a(0.9D)); - if (!this.es() && this.getGoalTarget() == null) { -@@ -305,17 +331,26 @@ public class EntityGuardian extends EntityMonster { - - } - -- static class ControllerMoveGuardian extends ControllerMove { -+ static class ControllerMoveGuardian extends net.pl3x.purpur.controller.ControllerMoveWASDWater { // Purpur - -- private final EntityGuardian i; -+ private final EntityGuardian i; private EntityGuardian getGuardian() { return i; } // Purpur - OBFHELPER) - - public ControllerMoveGuardian(EntityGuardian entityguardian) { - super(entityguardian); - this.i = entityguardian; - } - -+ // Purpur start -+ @Override -+ public void tick(EntityHuman rider) { -+ super.tick(rider); -+ getGuardian().setMot(getGuardian().getMot().add(0.0D, 0.005D, 0.0D)); -+ getGuardian().setMovingFlag(getGuardian().getForward() > 0.0F); // control tail speed -+ } -+ - @Override -- public void a() { -+ public void tick() { -+ // Purpur end - if (this.h == ControllerMove.Operation.MOVE_TO && !this.i.getNavigation().m()) { - Vec3D vec3d = new Vec3D(this.b - this.i.locX(), this.c - this.i.locY(), this.d - this.i.locZ()); - double d0 = vec3d.f(); -diff --git a/src/main/java/net/minecraft/server/EntityGuardianElder.java b/src/main/java/net/minecraft/server/EntityGuardianElder.java -index 7484bfeea..f231340d9 100644 ---- a/src/main/java/net/minecraft/server/EntityGuardianElder.java -+++ b/src/main/java/net/minecraft/server/EntityGuardianElder.java -@@ -16,6 +16,23 @@ public class EntityGuardianElder extends EntityGuardian { - - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.elderGuardianRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.elderGuardianRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.elderGuardianRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - public void initAttributes() { - super.initAttributes(); -diff --git a/src/main/java/net/minecraft/server/EntityHorse.java b/src/main/java/net/minecraft/server/EntityHorse.java -index a6fb4ba5b..98b1e9375 100644 ---- a/src/main/java/net/minecraft/server/EntityHorse.java -+++ b/src/main/java/net/minecraft/server/EntityHorse.java -@@ -19,6 +19,13 @@ public class EntityHorse extends EntityHorseAbstract { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.horseRidableInWater; -+ } -+ // Purpur end -+ - @Override - protected void initDatawatcher() { - super.initDatawatcher(); -diff --git a/src/main/java/net/minecraft/server/EntityHorseAbstract.java b/src/main/java/net/minecraft/server/EntityHorseAbstract.java -index c56efe035..f31cb0554 100644 ---- a/src/main/java/net/minecraft/server/EntityHorseAbstract.java -+++ b/src/main/java/net/minecraft/server/EntityHorseAbstract.java -@@ -38,12 +38,32 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven - - protected EntityHorseAbstract(EntityTypes entitytypes, World world) { - super(entitytypes, world); -+ this.moveController = new ControllerMove(this); // Purpur - use vanilla controller -+ this.lookController = new ControllerLook(this); // Purpur - use vanilla controller - this.H = 1.0F; - this.loadChest(); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return false; // vanilla handles -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return false; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return false; // vanilla handles -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHorseHasRider(this)); // Purpur - this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.2D)); - this.goalSelector.a(1, new PathfinderGoalTame(this, 1.2D)); - this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D, EntityHorseAbstract.class)); -@@ -281,7 +301,7 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven - return true; - } - -- public boolean eL() { -+ public boolean eL() { return isSaddled(); } public boolean isSaddled() { // Purpur - OBFHELPER - return this.t(4); - } - -diff --git a/src/main/java/net/minecraft/server/EntityHorseDonkey.java b/src/main/java/net/minecraft/server/EntityHorseDonkey.java -index 9a52decdc..64d80081f 100644 ---- a/src/main/java/net/minecraft/server/EntityHorseDonkey.java -+++ b/src/main/java/net/minecraft/server/EntityHorseDonkey.java -@@ -6,6 +6,13 @@ public class EntityHorseDonkey extends EntityHorseChestedAbstract { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.donkeyRidableInWater; -+ } -+ // Purpur end -+ - @Override - protected SoundEffect getSoundAmbient() { - super.getSoundAmbient(); -diff --git a/src/main/java/net/minecraft/server/EntityHorseMule.java b/src/main/java/net/minecraft/server/EntityHorseMule.java -index 4dd4d91eb..a9f26efe6 100644 ---- a/src/main/java/net/minecraft/server/EntityHorseMule.java -+++ b/src/main/java/net/minecraft/server/EntityHorseMule.java -@@ -6,6 +6,13 @@ public class EntityHorseMule extends EntityHorseChestedAbstract { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.muleRidableInWater; -+ } -+ // Purpur end -+ - @Override - protected SoundEffect getSoundAmbient() { - super.getSoundAmbient(); -diff --git a/src/main/java/net/minecraft/server/EntityHorseSkeleton.java b/src/main/java/net/minecraft/server/EntityHorseSkeleton.java -index 290cb9337..7bf76e5a0 100644 ---- a/src/main/java/net/minecraft/server/EntityHorseSkeleton.java -+++ b/src/main/java/net/minecraft/server/EntityHorseSkeleton.java -@@ -12,6 +12,18 @@ public class EntityHorseSkeleton extends EntityHorseAbstract { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.skeletonHorseRidableInWater; -+ } -+ -+ @Override -+ public boolean isTamed() { -+ return true; -+ } -+ // Purpur end -+ - @Override - protected void initAttributes() { - super.initAttributes(); -@@ -21,7 +33,7 @@ public class EntityHorseSkeleton extends EntityHorseAbstract { - } - - @Override -- protected void ez() {} -+ protected void ez() { if (world.purpurConfig.skeletonHorseCanSwim) goalSelector.a(0, new PathfinderGoalFloat(this)); } // Purpur - - @Override - protected SoundEffect getSoundAmbient() { -@@ -116,7 +128,7 @@ public class EntityHorseSkeleton extends EntityHorseAbstract { - - @Override - public boolean bi() { -- return true; -+ return super.bi(); // Purpur - } - - @Override -diff --git a/src/main/java/net/minecraft/server/EntityHorseZombie.java b/src/main/java/net/minecraft/server/EntityHorseZombie.java -index 5782a25ec..c87fc523f 100644 ---- a/src/main/java/net/minecraft/server/EntityHorseZombie.java -+++ b/src/main/java/net/minecraft/server/EntityHorseZombie.java -@@ -8,6 +8,18 @@ public class EntityHorseZombie extends EntityHorseAbstract { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.zombieHorseRidableInWater; -+ } -+ -+ @Override -+ public boolean isTamed() { -+ return true; -+ } -+ // Purpur end -+ - @Override - protected void initAttributes() { - super.initAttributes(); -@@ -78,5 +90,5 @@ public class EntityHorseZombie extends EntityHorseAbstract { - } - - @Override -- protected void ez() {} -+ protected void ez() { if (world.purpurConfig.zombieHorseCanSwim) goalSelector.a(0, new PathfinderGoalFloat(this)); } // Purpur - } -diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java -index 7df24be46..27cfc6654 100644 ---- a/src/main/java/net/minecraft/server/EntityHuman.java -+++ b/src/main/java/net/minecraft/server/EntityHuman.java -@@ -374,9 +374,21 @@ public abstract class EntityHuman extends EntityLiving { - this.activeContainer = this.defaultContainer; - } - -+ // Purpur start -+ boolean mounting = false; -+ -+ @Override -+ public void setSneaking(boolean sneaking) { -+ if (this.mounting && !sneaking) { -+ this.mounting = false; -+ } -+ super.setSneaking(sneaking); -+ } -+ // Purpur end -+ - @Override - public void passengerTick() { -- if (!this.world.isClientSide && this.dU() && this.isPassenger()) { -+ if (this.isSneaking() && this.isPassenger() && !this.mounting) { // Purpur - this.stopRiding(); - this.setSneaking(false); - } else { -diff --git a/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java b/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java -index 81b7cd06f..3e6722cfc 100644 ---- a/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java -+++ b/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java -@@ -19,10 +19,28 @@ public class EntityIllagerIllusioner extends EntityIllagerWizard implements IRan - - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.illusionerRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.illusionerRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.illusionerRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { - super.initPathfinder(); - this.goalSelector.a(0, new PathfinderGoalFloat(this)); -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(1, new EntityIllagerWizard.b()); - this.goalSelector.a(4, new EntityIllagerIllusioner.b()); - this.goalSelector.a(5, new EntityIllagerIllusioner.a()); -@@ -30,6 +48,7 @@ public class EntityIllagerIllusioner extends EntityIllagerWizard implements IRan - this.goalSelector.a(8, new PathfinderGoalRandomStroll(this, 0.6D)); - this.goalSelector.a(9, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 3.0F, 1.0F)); - this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a(new Class[0])); // CraftBukkit - decompile error - this.targetSelector.a(2, (new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)).a(300)); - this.targetSelector.a(3, (new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, false)).a(300)); -diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java -index 5aca7a913..cbbbc875b 100644 ---- a/src/main/java/net/minecraft/server/EntityInsentient.java -+++ b/src/main/java/net/minecraft/server/EntityInsentient.java -@@ -28,7 +28,7 @@ public abstract class EntityInsentient extends EntityLiving { - protected int f; - protected ControllerLook lookController; - protected ControllerMove moveController; -- protected ControllerJump bq; -+ protected ControllerJump bq; public ControllerJump getJumpController() { return bq; } // Purpur - OBFHELPER - private final EntityAIBodyControl c; - protected NavigationAbstract navigation; - public PathfinderGoalSelector goalSelector; -@@ -66,8 +66,8 @@ public abstract class EntityInsentient extends EntityLiving { - this.bI = -1.0F; - this.goalSelector = new PathfinderGoalSelector(world != null && world.getMethodProfiler() != null ? world.getMethodProfiler() : null); - this.targetSelector = new PathfinderGoalSelector(world != null && world.getMethodProfiler() != null ? world.getMethodProfiler() : null); -- this.lookController = new ControllerLook(this); -- this.moveController = new ControllerMove(this); -+ this.moveController = new net.pl3x.purpur.controller.ControllerMoveWASD(this); // Purpur -+ this.lookController = new net.pl3x.purpur.controller.ControllerLookWASD(this); // Purpur - this.bq = new ControllerJump(this); - this.c = this.o(); - this.navigation = this.b(world); -@@ -502,7 +502,7 @@ public abstract class EntityInsentient extends EntityLiving { - return super.cW(); - } - -- public void r(float f) { -+ public void setForwardSpeed(float speed) { this.r(speed); } public void r(float f) { // Purpur - OBFHELPER - this.bb = f; - } - -@@ -514,8 +514,7 @@ public abstract class EntityInsentient extends EntityLiving { - this.aZ = f; - } - -- @Override -- public void o(float f) { -+ public void setSpeed(float speed) { o(speed); } @Override public void o(float f) { // Purpur - OBFHELPER - super.o(f); - this.r(f); - } -@@ -1082,7 +1081,7 @@ public abstract class EntityInsentient extends EntityLiving { - } - - protected boolean a(EntityHuman entityhuman, EnumHand enumhand) { -- return false; -+ return tryRide(entityhuman, enumhand); // Purpur - } - - public boolean ec() { -@@ -1381,4 +1380,39 @@ public abstract class EntityInsentient extends EntityLiving { - public boolean a(Item item) { - return this.getItemInMainHand().getItem() == item || this.getItemInOffHand().getItem() == item; - } -+ -+ // Purpur start -+ public double getMaxY() { -+ return world.getHeight(); -+ } -+ -+ public boolean tryRide(EntityHuman entityhuman, EnumHand enumhand) { -+ if (!isRidable()) { -+ return false; -+ } -+ if (enumhand != EnumHand.MAIN_HAND) { -+ return false; -+ } -+ if (requireShiftToMount() && !entityhuman.isSneaking()) { -+ return false; -+ } -+ if (!passengers.isEmpty() || entityhuman.isPassenger()) { -+ return false; -+ } -+ if (this instanceof EntityTameableAnimal) { -+ EntityTameableAnimal tameable = (EntityTameableAnimal) this; -+ if (tameable.isTamed() && !tameable.isOwner(entityhuman)) { -+ return false; -+ } -+ } -+ if (!entityhuman.getBukkitEntity().hasPermission("allow.ride." + getEntityType().getName())) { -+ entityhuman.sendMessage(LocaleLanguage.translate("cannot.ride.mob")); -+ return false; -+ } -+ entityhuman.mounting = true; -+ entityhuman.yaw = this.yaw; -+ entityhuman.pitch = this.pitch; -+ return entityhuman.startRiding(this) || (entityhuman.mounting = false); -+ } -+ // Purpur end - } -diff --git a/src/main/java/net/minecraft/server/EntityIronGolem.java b/src/main/java/net/minecraft/server/EntityIronGolem.java -index 7f6a56776..288a043fb 100644 ---- a/src/main/java/net/minecraft/server/EntityIronGolem.java -+++ b/src/main/java/net/minecraft/server/EntityIronGolem.java -@@ -17,8 +17,26 @@ public class EntityIronGolem extends EntityGolem { - this.H = 1.0F; - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.ironGolemRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.ironGolemRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.ironGolemRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(1, new PathfinderGoalMeleeAttack(this, 1.0D, true)); - this.goalSelector.a(2, new PathfinderGoalMoveTowardsTarget(this, 0.9D, 32.0F)); - this.goalSelector.a(2, new PathfinderGoalStrollVillage(this, 0.6D)); -@@ -29,6 +47,7 @@ public class EntityIronGolem extends EntityGolem { - this.goalSelector.a(6, new PathfinderGoalRandomStrollLand(this, 0.6D)); - this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); - this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, new PathfinderGoalDefendVillage(this)); - this.targetSelector.a(2, new PathfinderGoalHurtByTarget(this, new Class[0])); - this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityInsentient.class, 5, false, false, (entityliving) -> { -@@ -170,13 +189,13 @@ public class EntityIronGolem extends EntityGolem { - Item item = itemstack.getItem(); - - if (item != Items.IRON_INGOT) { -- return false; -+ return super.a(entityhuman, enumhand); // Purpur - } else { - float f = this.getHealth(); - - this.heal(25.0F); - if (this.getHealth() == f) { -- return false; -+ return super.a(entityhuman, enumhand); // Purpur - } else { - float f1 = 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F; - -diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java -index a245cfab6..14dc1318a 100644 ---- a/src/main/java/net/minecraft/server/EntityLiving.java -+++ b/src/main/java/net/minecraft/server/EntityLiving.java -@@ -75,7 +75,7 @@ public abstract class EntityLiving extends Entity { - public int maxNoDamageTicks; - public final float aG; - public final float aH; -- public float aI; -+ public float aI; public float getBodyRotation() { return aI; } // Purpur - OBFHELPER - public float aJ; - public float aK; - public float aL; -@@ -92,9 +92,9 @@ public abstract class EntityLiving extends Entity { - protected int aW; protected int getKillCount() { return this.aW; } // Paper - OBFHELPER - public float lastDamage; - public boolean jumping; // Paper -- public float aZ; -- public float ba; -- public float bb; -+ public float aZ; public float getStrafe() { return aZ; } public void setStrafe(float strafe) { aZ = strafe; } // Purpur - OBFHELPER -+ public float ba; public float getVertical() { return ba; } public void setVertical(float vertical) { ba = vertical; } // Purpur - OBFHELPER -+ public float bb; public float getForward() { return bb; } public void setForward(float forward) { bb = forward; } // Purpur - OBFHELPER - protected int bc; - protected double bd; - protected double be; -@@ -366,7 +366,7 @@ public abstract class EntityLiving extends Entity { - - @Override - public boolean bi() { -- return false; -+ return isRidableInWater(); // Purpur - } - - protected void cD() { -@@ -2098,12 +2098,12 @@ public abstract class EntityLiving extends Entity { - } - } - -- protected float dp() { -+ protected float dp() { return getJumpHeight(); } public float getJumpHeight() { // Purpur - OBFHELPER - return 0.42F * this.ah(); - } - -- protected void jump() { -- float f = this.dp(); -+ public void doJump() { jump(); } protected void jump() { // Purpur -+ float f = getJumpHeight(); // Purpur - - if (this.hasEffect(MobEffects.JUMP)) { - f += 0.1F * (float) (this.getEffect(MobEffects.JUMP).getAmplifier() + 1); -@@ -2111,6 +2111,7 @@ public abstract class EntityLiving extends Entity { - - Vec3D vec3d = this.getMot(); - -+ if (hasRider()) setMot(vec3d.x * 2D, (double) f, vec3d.z * 2D); else // Purpur - add small boost to velocity when jumping while being ridden - this.setMot(vec3d.x, (double) f, vec3d.z); - if (this.isSprinting()) { - float f1 = this.yaw * 0.017453292F; -@@ -2329,11 +2330,11 @@ public abstract class EntityLiving extends Entity { - return this.onGround ? this.dt() * (0.21600002F / (f * f * f)) : this.aM; - } - -- public float dt() { -+ public float getSpeed() { return dt(); } public float dt() { // Purpur - OBFHELPER - return this.bB; - } - -- public void o(float f) { -+ public void setSpeed(float speed) { o(speed); } public void o(float f) { // Purpur - OBFHELPER - this.bB = f; - } - -diff --git a/src/main/java/net/minecraft/server/EntityLlama.java b/src/main/java/net/minecraft/server/EntityLlama.java -index 193dbfc5f..c5f87cbdd 100644 ---- a/src/main/java/net/minecraft/server/EntityLlama.java -+++ b/src/main/java/net/minecraft/server/EntityLlama.java -@@ -16,7 +16,46 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn - - public EntityLlama(EntityTypes entitytypes, World world) { - super(entitytypes, world); -+ // Purpur start -+ this.moveController = new net.pl3x.purpur.controller.ControllerMoveWASD(this) { -+ @Override -+ public void a() { // tick -+ if (entity.hasRider() && isSaddled()) { -+ tick(entity.getRider()); -+ } else { -+ tick(); -+ } -+ } -+ }; -+ this.lookController = new net.pl3x.purpur.controller.ControllerLookWASD(this) { -+ @Override -+ public void a() { // tick -+ if (entity.hasRider() && isSaddled()) { -+ tick(entity.getRider()); -+ } else { -+ tick(); -+ } -+ } -+ }; -+ // Purpur end -+ } -+ -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.llamaRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.llamaRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return false; // shift reserved for opening inventory - } -+ // Purpur end - - public void setStrength(int i) { - this.datawatcher.set(EntityLlama.bF, Math.max(1, Math.min(5, i))); -@@ -58,6 +97,7 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn - @Override - protected void initPathfinder() { - this.goalSelector.a(0, new PathfinderGoalFloat(this)); -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHorseHasRider(this)); // Purpur - this.goalSelector.a(1, new PathfinderGoalTame(this, 1.2D)); - this.goalSelector.a(2, new PathfinderGoalLlamaFollow(this, 2.0999999046325684D)); - this.goalSelector.a(3, new PathfinderGoalArrowAttack(this, 1.25D, 40, 20.0F)); -@@ -67,6 +107,7 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn - this.goalSelector.a(6, new PathfinderGoalRandomStrollLand(this, 0.7D)); - this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); - this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHorseHasRider(this)); // Purpur - this.targetSelector.a(1, new EntityLlama.c(this)); - this.targetSelector.a(2, new EntityLlama.a(this)); - } -@@ -253,6 +294,13 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn - return false; - } - -+ // Purpur start -+ @Override -+ public boolean isSaddled() { -+ return isTamed() && getColor() != null; -+ } -+ // Purpur end -+ - @Override - public void a(IInventory iinventory) { - EnumColor enumcolor = this.eZ(); -@@ -286,7 +334,7 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn - } - - @Nullable -- public EnumColor eZ() { -+ public EnumColor eZ() { return getColor(); } public EnumColor getColor() { // Purpur - OBFHELPER - int i = (Integer) this.datawatcher.get(EntityLlama.bG); - - return i == -1 ? null : EnumColor.fromColorIndex(i); -diff --git a/src/main/java/net/minecraft/server/EntityLlamaTrader.java b/src/main/java/net/minecraft/server/EntityLlamaTrader.java -index 4cebd67e8..08c4ca3f3 100644 ---- a/src/main/java/net/minecraft/server/EntityLlamaTrader.java -+++ b/src/main/java/net/minecraft/server/EntityLlamaTrader.java -@@ -11,6 +11,23 @@ public class EntityLlamaTrader extends EntityLlama { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.llamaTraderRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.llamaTraderRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return false; // shift reserved for opening inventory -+ } -+ // Purpur end -+ - @Override - protected EntityLlama fa() { - return (EntityLlama) EntityTypes.TRADER_LLAMA.a(this.world); -@@ -79,6 +96,12 @@ public class EntityLlamaTrader extends EntityLlama { - return this.isLeashed() && !this.fh(); - } - -+ // Purpur start -+ public boolean isSaddled() { -+ return isTamed(); -+ } -+ // Purpur end -+ - @Nullable - @Override - public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { -diff --git a/src/main/java/net/minecraft/server/EntityMagmaCube.java b/src/main/java/net/minecraft/server/EntityMagmaCube.java -index 1fdc248ba..a5a36af21 100644 ---- a/src/main/java/net/minecraft/server/EntityMagmaCube.java -+++ b/src/main/java/net/minecraft/server/EntityMagmaCube.java -@@ -8,6 +8,23 @@ public class EntityMagmaCube extends EntitySlime { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.magmaCubeRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.magmaCubeRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.magmaCubeRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initAttributes() { - super.initAttributes(); -diff --git a/src/main/java/net/minecraft/server/EntityMushroomCow.java b/src/main/java/net/minecraft/server/EntityMushroomCow.java -index 8b199971b..53bc31287 100644 ---- a/src/main/java/net/minecraft/server/EntityMushroomCow.java -+++ b/src/main/java/net/minecraft/server/EntityMushroomCow.java -@@ -19,6 +19,23 @@ public class EntityMushroomCow extends EntityCow { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.mooshroomRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.mooshroomRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.mooshroomRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - public float a(BlockPosition blockposition, IWorldReader iworldreader) { - return iworldreader.getType(blockposition.down()).getBlock() == Blocks.MYCELIUM ? 10.0F : iworldreader.w(blockposition) - 0.5F; -diff --git a/src/main/java/net/minecraft/server/EntityOcelot.java b/src/main/java/net/minecraft/server/EntityOcelot.java -index d9a7b8ac1..8fdf34857 100644 ---- a/src/main/java/net/minecraft/server/EntityOcelot.java -+++ b/src/main/java/net/minecraft/server/EntityOcelot.java -@@ -16,6 +16,23 @@ public class EntityOcelot extends EntityAnimal { - this.eq(); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.ocelotRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.ocelotRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.ocelotRequireShiftToMount; -+ } -+ // Purpur end -+ - private boolean isTrusting() { - return (Boolean) this.datawatcher.get(EntityOcelot.bx); - } -@@ -47,12 +64,14 @@ public class EntityOcelot extends EntityAnimal { - protected void initPathfinder() { - this.bz = new EntityOcelot.b(this, 0.6D, EntityOcelot.bw, true); - this.goalSelector.a(1, new PathfinderGoalFloat(this)); -+ this.goalSelector.a(1, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(3, this.bz); - this.goalSelector.a(7, new PathfinderGoalLeapAtTarget(this, 0.3F)); - this.goalSelector.a(8, new PathfinderGoalOcelotAttack(this)); - this.goalSelector.a(9, new PathfinderGoalBreed(this, 0.8D)); - this.goalSelector.a(10, new PathfinderGoalRandomStrollLand(this, 0.8D, 1.0000001E-5F)); - this.goalSelector.a(11, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 10.0F)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityChicken.class, false)); - this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityTurtle.class, 10, false, false, EntityTurtle.bw)); - } -diff --git a/src/main/java/net/minecraft/server/EntityPanda.java b/src/main/java/net/minecraft/server/EntityPanda.java -index f50ed1908..87ed9a8ca 100644 ---- a/src/main/java/net/minecraft/server/EntityPanda.java -+++ b/src/main/java/net/minecraft/server/EntityPanda.java -@@ -46,6 +46,23 @@ public class EntityPanda extends EntityAnimal { - - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.pandaRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.pandaRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.pandaRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - public boolean e(ItemStack itemstack) { - EnumItemSlot enumitemslot = EntityInsentient.h(itemstack); -@@ -69,6 +86,7 @@ public class EntityPanda extends EntityAnimal { - return this.w(8); - } - -+ public void setScared(boolean scared) { this.r(scared); } // Purpur - OBFHELPER - public void r(boolean flag) { - this.d(8, flag); - } -@@ -77,6 +95,7 @@ public class EntityPanda extends EntityAnimal { - return this.w(16); - } - -+ public void setLayingOnBack(boolean layingOnBack) { this.s(layingOnBack); } // Purpur - OBFHELPER - public void s(boolean flag) { - this.d(16, flag); - } -@@ -85,6 +104,7 @@ public class EntityPanda extends EntityAnimal { - return (Integer) this.datawatcher.get(EntityPanda.bz) > 0; - } - -+ public void setEating(boolean eating) { this.t(eating); } // Purpur - OBFHELPER - public void t(boolean flag) { - this.datawatcher.set(EntityPanda.bz, flag ? 1 : 0); - } -@@ -201,6 +221,7 @@ public class EntityPanda extends EntityAnimal { - @Override - protected void initPathfinder() { - this.goalSelector.a(0, new PathfinderGoalFloat(this)); -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(2, new EntityPanda.i(this, 2.0D)); - this.goalSelector.a(2, new EntityPanda.d(this, 1.0D)); - this.goalSelector.a(3, new EntityPanda.b(this, 1.2000000476837158D, true)); -@@ -216,6 +237,7 @@ public class EntityPanda extends EntityAnimal { - this.goalSelector.a(12, new EntityPanda.j(this)); - this.goalSelector.a(13, new PathfinderGoalFollowParent(this, 1.25D)); - this.goalSelector.a(14, new PathfinderGoalRandomStrollLand(this, 1.0D)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, (new EntityPanda.e(this, new Class[0])).a(new Class[0])); - } - -@@ -541,7 +563,7 @@ public class EntityPanda extends EntityAnimal { - if (itemstack.getItem() instanceof ItemMonsterEgg) { - return super.a(entityhuman, enumhand); - } else if (this.eJ()) { -- return false; -+ return tryRide(entityhuman, enumhand); // Purpur; - } else if (this.et()) { - this.s(false); - return true; -@@ -558,7 +580,7 @@ public class EntityPanda extends EntityAnimal { - this.f(entityhuman); - } else { - if (this.world.isClientSide || this.es() || this.isInWater()) { -- return false; -+ return tryRide(entityhuman, enumhand); // Purpur; - } - - this.eX(); -@@ -576,10 +598,21 @@ public class EntityPanda extends EntityAnimal { - entityhuman.a(enumhand, true); - return true; - } else { -- return false; -+ return tryRide(entityhuman, enumhand); // Purpur - } - } - -+ // Purpur start -+ @Override -+ public void onMount(EntityHuman entityhuman) { -+ super.onMount(entityhuman); -+ this.setForwardSpeed(0.0F); -+ this.setScared(false); -+ this.setEating(false); -+ this.setLayingOnBack(false); -+ } -+ // Purpur end -+ - @Nullable - @Override - protected SoundEffect getSoundAmbient() { -@@ -689,6 +722,7 @@ public class EntityPanda extends EntityAnimal { - - public f(EntityPanda entitypanda) { - this.a = entitypanda; -+ this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); // Purpur - lay on back - } - - @Override -@@ -852,6 +886,7 @@ public class EntityPanda extends EntityAnimal { - - public l(EntityPanda entitypanda) { - this.a = entitypanda; -+ this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); // Purpur - sneeze - } - - @Override -@@ -981,7 +1016,7 @@ public class EntityPanda extends EntityAnimal { - } - } - -- static class h extends ControllerMove { -+ static class h extends net.pl3x.purpur.controller.ControllerMoveWASD { // Purpur - - private final EntityPanda i; - -@@ -991,9 +1026,9 @@ public class EntityPanda extends EntityAnimal { - } - - @Override -- public void a() { -+ public void tick() { // Purpur - if (this.i.eL()) { -- super.a(); -+ super.tick(); // Purpur - } - } - } -diff --git a/src/main/java/net/minecraft/server/EntityParrot.java b/src/main/java/net/minecraft/server/EntityParrot.java -index 94e57a2d8..7ba2f3a35 100644 ---- a/src/main/java/net/minecraft/server/EntityParrot.java -+++ b/src/main/java/net/minecraft/server/EntityParrot.java -@@ -62,12 +62,83 @@ public class EntityParrot extends EntityPerchable implements EntityBird { - - public EntityParrot(EntityTypes entitytypes, World world) { - super(entitytypes, world); -- this.moveController = new ControllerMoveFlying(this, 10, false); -+ // Purpur start -+ this.moveController = new net.pl3x.purpur.controller.ControllerMoveWASDFlyingWithSpacebar(this, 0.3F) { -+ @Override -+ protected void tick() { -+ // flying controller (from ControllerMoveFlying) -+ if (this.h == Operation.MOVE_TO) { -+ this.h = Operation.WAIT; -+ this.a.setNoGravity(true); -+ double var0 = this.b - this.a.locX(); -+ double var2 = this.c - this.a.locY(); -+ double var4 = this.d - this.a.locZ(); -+ double var6 = var0 * var0 + var2 * var2 + var4 * var4; -+ if (var6 < 2.500000277905201E-7D) { -+ this.a.s(0.0F); -+ this.a.r(0.0F); -+ return; -+ } -+ float var8 = (float)(MathHelper.d(var4, var0) * 57.2957763671875D) - 90.0F; -+ this.a.yaw = this.a(this.a.yaw, var8, 90.0F); -+ float var9; -+ if (this.a.onGround) { -+ var9 = (float)(this.e * this.a.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue()); -+ } else { -+ var9 = (float)(this.e * this.a.getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue()); -+ } -+ this.a.o(var9); -+ double var10 = (double)MathHelper.sqrt(var0 * var0 + var4 * var4); -+ float var12 = (float)(-(MathHelper.d(var2, var10) * 57.2957763671875D)); -+ this.a.pitch = this.a(this.a.pitch, var12, 10); -+ this.a.s(var2 > 0.0D ? var9 : -var9); -+ } else { -+ this.a.setNoGravity(false); -+ this.a.s(0.0F); -+ this.a.r(0.0F); -+ } -+ } -+ }; -+ // Purpur end - this.a(PathType.DANGER_FIRE, -1.0F); - this.a(PathType.DAMAGE_FIRE, -1.0F); - this.a(PathType.COCOA, -1.0F); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.parrotRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.parrotRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.parrotRequireShiftToMount; -+ } -+ -+ @Override -+ public double getMaxY() { -+ return world.purpurConfig.parrotMaxY; -+ } -+ -+ @Override -+ public void e(Vec3D vec3d) { -+ super.e(vec3d); -+ if (hasRider() && !onGround) { -+ float speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue(); -+ setSpeed(speed); -+ Vec3D mot = getMot(); -+ move(EnumMoveType.SELF, mot.multiply(speed, 1.0, speed)); -+ setMot(mot.a(0.9D)); -+ } -+ } -+ // Purpur end -+ - @Nullable - @Override - public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { -@@ -83,8 +154,10 @@ public class EntityParrot extends EntityPerchable implements EntityBird { - @Override - protected void initPathfinder() { - this.goalSit = new PathfinderGoalSit(this); -- this.goalSelector.a(0, new PathfinderGoalPanic(this, 1.25D)); -+ // this.goalSelector.a(0, new PathfinderGoalPanic(this, 1.25D)); // Purpur - move down - this.goalSelector.a(0, new PathfinderGoalFloat(this)); -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur -+ this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.25D)); // Purpur - this.goalSelector.a(1, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); - this.goalSelector.a(2, this.goalSit); - this.goalSelector.a(2, new PathfinderGoalFollowOwner(this, 1.0D, 5.0F, 1.0F, true)); -diff --git a/src/main/java/net/minecraft/server/EntityPhantom.java b/src/main/java/net/minecraft/server/EntityPhantom.java -index 96b4912c4..777bc95ee 100644 ---- a/src/main/java/net/minecraft/server/EntityPhantom.java -+++ b/src/main/java/net/minecraft/server/EntityPhantom.java -@@ -22,6 +22,40 @@ public class EntityPhantom extends EntityFlying implements IMonster { - this.lookController = new EntityPhantom.f(this); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.phantomRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.phantomRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.phantomRequireShiftToMount; -+ } -+ -+ @Override -+ public double getMaxY() { -+ return world.purpurConfig.phantomMaxY; -+ } -+ -+ @Override -+ public void e(Vec3D vec3d) { -+ super.e(vec3d); -+ if (hasRider() && !onGround) { -+ float speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue(); -+ setSpeed(speed); -+ Vec3D mot = getMot(); -+ move(EnumMoveType.SELF, mot.multiply(speed, speed, speed)); -+ setMot(mot.a(0.9D)); -+ } -+ } -+ // Purpur end -+ - @Override - protected EntityAIBodyControl o() { - return new EntityPhantom.d(this); -@@ -29,9 +63,11 @@ public class EntityPhantom extends EntityFlying implements IMonster { - - @Override - protected void initPathfinder() { -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(1, new EntityPhantom.c()); - this.goalSelector.a(2, new EntityPhantom.i()); - this.goalSelector.a(3, new EntityPhantom.e()); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, new EntityPhantom.b()); - } - -@@ -39,6 +75,12 @@ public class EntityPhantom extends EntityFlying implements IMonster { - protected void initAttributes() { - super.initAttributes(); - this.getAttributeMap().b(GenericAttributes.ATTACK_DAMAGE); -+ // Purpur start -+ if (world != null && world.purpurConfig.phantomRidable) { -+ this.getAttributeMap().b(GenericAttributes.FLYING_SPEED); -+ this.getAttributeInstance(GenericAttributes.FLYING_SPEED).setValue(3.0D); -+ } -+ // Purpur end - } - - @Override -@@ -103,7 +145,7 @@ public class EntityPhantom extends EntityFlying implements IMonster { - - @Override - public void movementTick() { -- if (this.isAlive() && this.en()) { -+ if (this.isAlive() && !hasRider() && this.isInDaylight()) { // Purpur - do not burn from daylight if has rider - this.setOnFire(8); - } - -@@ -115,6 +157,27 @@ public class EntityPhantom extends EntityFlying implements IMonster { - super.mobTick(); - } - -+ // Purpur start -+ @Override -+ public boolean onSpacebar() { -+ if (hasRider() && getRider().getBukkitEntity().hasPermission("allow.special.phantom")) { -+ shoot(); -+ } -+ return false; -+ } -+ -+ public boolean shoot() { -+ org.bukkit.Location loc = ((org.bukkit.entity.LivingEntity) getBukkitEntity()).getEyeLocation(); -+ loc.setPitch(-loc.getPitch()); -+ org.bukkit.util.Vector target = loc.getDirection().normalize().multiply(100).add(loc.toVector()); -+ -+ net.pl3x.purpur.entity.PhantomFlames flames = new net.pl3x.purpur.entity.PhantomFlames(world, this); -+ flames.shoot(target.getX() - locX(), target.getY() - locY(), target.getZ() - locZ(), 1.0F, 5.0F); -+ world.addEntity(flames); -+ return true; -+ } -+ // Purpur end -+ - @Override - public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { - this.d = (new BlockPosition(this)).up(5); -@@ -215,6 +278,7 @@ public class EntityPhantom extends EntityFlying implements IMonster { - - @Override - public boolean a() { -+ if (getRider() != null) return false; // Purpur - pathfinder does not have a flag - if (this.c > 0) { - --this.c; - return false; -@@ -245,6 +309,7 @@ public class EntityPhantom extends EntityFlying implements IMonster { - - @Override - public boolean b() { -+ if (getRider() != null) return false; // Purpur - pathfinder does not have a flag - EntityLiving entityliving = EntityPhantom.this.getGoalTarget(); - - return entityliving != null ? EntityPhantom.this.a(entityliving, PathfinderTargetCondition.a) : false; -@@ -259,6 +324,7 @@ public class EntityPhantom extends EntityFlying implements IMonster { - - @Override - public boolean a() { -+ if (getRider() != null) return false; // Purpur - pathfinder does not have a flag - EntityLiving entityliving = EntityPhantom.this.getGoalTarget(); - - return entityliving != null ? EntityPhantom.this.a(EntityPhantom.this.getGoalTarget(), PathfinderTargetCondition.a) : false; -@@ -448,14 +514,23 @@ public class EntityPhantom extends EntityFlying implements IMonster { - } - } - -- class f extends ControllerLook { -+ class f extends net.pl3x.purpur.controller.ControllerLookWASD { // Purpur - - public f(EntityInsentient entityinsentient) { - super(entityinsentient); - } - - @Override -- public void a() {} -+ // Purpur start -+ public void tick(EntityHuman rider) { -+ setYawPitch(rider.yaw, -rider.pitch * 0.75F); -+ } -+ -+ @Override -+ public void tick() { -+ // do nothing -+ } -+ // Purpur end - } - - class d extends EntityAIBodyControl { -@@ -471,7 +546,7 @@ public class EntityPhantom extends EntityFlying implements IMonster { - } - } - -- class g extends ControllerMove { -+ class g extends net.pl3x.purpur.controller.ControllerMoveWASDFlying { // Purpur - - private float j = 0.1F; - -@@ -480,7 +555,19 @@ public class EntityPhantom extends EntityFlying implements IMonster { - } - - @Override -- public void a() { -+ // Purpur start -+ public void tick(EntityHuman rider) { -+ if (!EntityPhantom.this.onGround) { -+ // phantom is always in motion when flying -+ // TODO - FIX THIS -+ // rider.setForward(1.0F); -+ } -+ super.tick(rider); -+ } -+ -+ @Override -+ public void tick() { -+ // Purpur end - if (EntityPhantom.this.positionChanged) { - EntityPhantom.this.yaw += 180.0F; - this.j = 0.1F; -diff --git a/src/main/java/net/minecraft/server/EntityPig.java b/src/main/java/net/minecraft/server/EntityPig.java -index 8d277566e..e6a7f8ef3 100644 ---- a/src/main/java/net/minecraft/server/EntityPig.java -+++ b/src/main/java/net/minecraft/server/EntityPig.java -@@ -19,9 +19,27 @@ public class EntityPig extends EntityAnimal { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.pigRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.pigRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return false; -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { - this.goalSelector.a(0, new PathfinderGoalFloat(this)); -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.25D)); - this.goalSelector.a(3, new PathfinderGoalBreed(this, 1.0D)); - this.goalSelector.a(4, new PathfinderGoalTempt(this, 1.2D, RecipeItemStack.a(Items.CARROT_ON_A_STICK), false)); -@@ -110,24 +128,22 @@ public class EntityPig extends EntityAnimal { - - @Override - public boolean a(EntityHuman entityhuman, EnumHand enumhand) { -- if (super.a(entityhuman, enumhand)) { -+ // Purpur start - reorder logic so super is last (so tryRide is last) -+ ItemStack itemstack = entityhuman.b(enumhand); -+ if (itemstack.getItem() == Items.NAME_TAG) { -+ itemstack.a(entityhuman, this, enumhand); -+ return true; -+ } -+ if (hasSaddle() && !isVehicle()) { -+ entityhuman.startRiding(this); -+ return true; -+ } -+ if (itemstack.getItem() == Items.SADDLE) { -+ itemstack.a(entityhuman, this, enumhand); - return true; -- } else { -- ItemStack itemstack = entityhuman.b(enumhand); -- -- if (itemstack.getItem() == Items.NAME_TAG) { -- itemstack.a(entityhuman, (EntityLiving) this, enumhand); -- return true; -- } else if (this.hasSaddle() && !this.isVehicle()) { -- if (!this.world.isClientSide) { -- entityhuman.startRiding(this); -- } -- -- return true; -- } else { -- return itemstack.getItem() == Items.SADDLE && itemstack.a(entityhuman, (EntityLiving) this, enumhand); -- } - } -+ return super.a(entityhuman, enumhand); -+ // Purpur end - } - - @Override -diff --git a/src/main/java/net/minecraft/server/EntityPigZombie.java b/src/main/java/net/minecraft/server/EntityPigZombie.java -index 9dd028b55..fb9ef88ea 100644 ---- a/src/main/java/net/minecraft/server/EntityPigZombie.java -+++ b/src/main/java/net/minecraft/server/EntityPigZombie.java -@@ -17,6 +17,23 @@ public class EntityPigZombie extends EntityZombie { - this.a(PathType.LAVA, 8.0F); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.zombiePigmanRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.zombiePigmanRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.zombiePigmanRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - public void setLastDamager(@Nullable EntityLiving entityliving) { - super.setLastDamager(entityliving); -diff --git a/src/main/java/net/minecraft/server/EntityPillager.java b/src/main/java/net/minecraft/server/EntityPillager.java -index 0357c9da9..98a657cec 100644 ---- a/src/main/java/net/minecraft/server/EntityPillager.java -+++ b/src/main/java/net/minecraft/server/EntityPillager.java -@@ -13,15 +13,34 @@ public class EntityPillager extends EntityIllagerAbstract implements ICrossbow, - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.pillagerRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.pillagerRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.pillagerRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { - super.initPathfinder(); - this.goalSelector.a(0, new PathfinderGoalFloat(this)); -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(2, new EntityRaider.a(this, 10.0F)); - this.goalSelector.a(3, new PathfinderGoalCrossbowAttack<>(this, 1.0D, 8.0F)); - this.goalSelector.a(8, new PathfinderGoalRandomStroll(this, 0.6D)); - this.goalSelector.a(9, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 15.0F, 1.0F)); - this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 15.0F)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a(new Class[0])); // CraftBukkit - decompile error - this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); - this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, false)); -diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java -index fe1e9ea61..51bae05ec 100644 ---- a/src/main/java/net/minecraft/server/EntityPlayer.java -+++ b/src/main/java/net/minecraft/server/EntityPlayer.java -@@ -1313,6 +1313,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { - } - - public void a(float f, float f1, boolean flag, boolean flag1) { -+ if (aZ != f || bb != f1 || jumping != flag || isSneaking() != flag1) resetIdleTimer(); // Purpur - if (this.isPassenger()) { - if (f >= -1.0F && f <= 1.0F) { - this.aZ = f; -@@ -1325,7 +1326,6 @@ public class EntityPlayer extends EntityHuman implements ICrafting { - this.jumping = flag; - this.setSneaking(flag1); - } -- - } - - @Override -diff --git a/src/main/java/net/minecraft/server/EntityPolarBear.java b/src/main/java/net/minecraft/server/EntityPolarBear.java -index f8e29a02d..0a3906bde 100644 ---- a/src/main/java/net/minecraft/server/EntityPolarBear.java -+++ b/src/main/java/net/minecraft/server/EntityPolarBear.java -@@ -17,6 +17,23 @@ public class EntityPolarBear extends EntityAnimal { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.polarBearRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.polarBearRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.polarBearRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - public EntityAgeable createChild(EntityAgeable entityageable) { - return (EntityAgeable) EntityTypes.POLAR_BEAR.a(this.world); -@@ -31,12 +48,14 @@ public class EntityPolarBear extends EntityAnimal { - protected void initPathfinder() { - super.initPathfinder(); - this.goalSelector.a(0, new PathfinderGoalFloat(this)); -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(1, new EntityPolarBear.c()); - this.goalSelector.a(1, new EntityPolarBear.d()); - this.goalSelector.a(4, new PathfinderGoalFollowParent(this, 1.25D)); - this.goalSelector.a(5, new PathfinderGoalRandomStroll(this, 1.0D)); - this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); - this.goalSelector.a(7, new PathfinderGoalRandomLookaround(this)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, new EntityPolarBear.b()); - this.targetSelector.a(2, new EntityPolarBear.a()); - this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityFox.class, 10, true, true, (Predicate) null)); -@@ -112,6 +131,11 @@ public class EntityPolarBear extends EntityAnimal { - --this.bz; - } - -+ // Purpur start -+ if (isStanding() && --standTimer <= 0) { -+ setStanding(false); -+ } -+ // Purpur end - } - - @Override -@@ -137,11 +161,14 @@ public class EntityPolarBear extends EntityAnimal { - return flag; - } - -+ public boolean isStanding() { return er(); } // Purpur - OBFHELPER - public boolean er() { - return (Boolean) this.datawatcher.get(EntityPolarBear.bw); - } - -+ public void setStanding(boolean standing) { r(standing); } // Purpur - OBFHELPER - public void r(boolean flag) { -+ standTimer = flag ? 20 : -1; // Purpur - this.datawatcher.set(EntityPolarBear.bw, flag); - } - -@@ -160,6 +187,21 @@ public class EntityPolarBear extends EntityAnimal { - return super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, (GroupDataEntity) groupdataentity, nbttagcompound); - } - -+ // Purpur start -+ private int standTimer = 0; -+ -+ @Override -+ public boolean onSpacebar() { -+ if (!isStanding()) { -+ if (hasRider() && getRider().getForward() == 0 && getRider().getStrafe() == 0) { -+ setStanding(true); -+ a(SoundEffects.ENTITY_POLAR_BEAR_WARNING, 1.0F, 1.0F); // playSound -+ } -+ } -+ return false; -+ } -+ // Purpur end -+ - class d extends PathfinderGoalPanic { - - public d() { -diff --git a/src/main/java/net/minecraft/server/EntityPufferFish.java b/src/main/java/net/minecraft/server/EntityPufferFish.java -index 98af9a223..d0e3e251e 100644 ---- a/src/main/java/net/minecraft/server/EntityPufferFish.java -+++ b/src/main/java/net/minecraft/server/EntityPufferFish.java -@@ -17,6 +17,23 @@ public class EntityPufferFish extends EntityFish { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.pufferfishRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.pufferfishRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.pufferfishRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initDatawatcher() { - super.initDatawatcher(); -@@ -60,7 +77,7 @@ public class EntityPufferFish extends EntityFish { - @Override - protected void initPathfinder() { - super.initPathfinder(); -- this.goalSelector.a(1, new EntityPufferFish.a(this)); -+ this.goalSelector.a(2, new EntityPufferFish.a(this)); // Purpur - } - - @Override -diff --git a/src/main/java/net/minecraft/server/EntityRabbit.java b/src/main/java/net/minecraft/server/EntityRabbit.java -index 2ed2d0b6b..9040ab1c5 100644 ---- a/src/main/java/net/minecraft/server/EntityRabbit.java -+++ b/src/main/java/net/minecraft/server/EntityRabbit.java -@@ -26,9 +26,27 @@ public class EntityRabbit extends EntityAnimal { - } - // CraftBukkit end - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.rabbitRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.rabbitRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.rabbitRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { -- this.goalSelector.a(1, new PathfinderGoalFloat(this)); -+ this.goalSelector.a(0, new PathfinderGoalFloat(this)); // Purpur -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(1, new EntityRabbit.PathfinderGoalRabbitPanic(this, 2.2D)); - this.goalSelector.a(2, new PathfinderGoalBreed(this, 0.8D)); - this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.0D, RecipeItemStack.a(Items.CARROT, Items.GOLDEN_CARROT, Blocks.DANDELION), false)); -@@ -41,7 +59,15 @@ public class EntityRabbit extends EntityAnimal { - } - - @Override -- protected float dp() { -+ // Purpur start -+ public float getJumpHeight() { -+ if (hasRider()) { -+ if (getForward() < 0) { -+ setSpeed(getForward() * 2F); -+ } -+ return actualJump ? 0.5F : 0.3F; -+ } -+ // Purpur end - if (!this.positionChanged && (!this.moveController.b() || this.moveController.e() <= this.locY() + 0.5D)) { - PathEntity pathentity = this.navigation.k(); - -@@ -92,6 +118,7 @@ public class EntityRabbit extends EntityAnimal { - - } - -+ public void startJumping() { eq(); } // Purpur - OBFHELPER - public void eq() { - this.setJumping(true); - this.bz = 10; -@@ -106,6 +133,12 @@ public class EntityRabbit extends EntityAnimal { - - @Override - public void mobTick() { -+ // Purpur start -+ if (hasRider()) { -+ handleJumping(); -+ return; -+ } -+ // Purpur end - if (this.bB > 0) { - --this.bB; - } -@@ -156,6 +189,39 @@ public class EntityRabbit extends EntityAnimal { - this.bA = this.onGround; - } - -+ // Purpur start -+ private boolean wasOnGround; -+ private boolean actualJump; -+ -+ private void handleJumping() { -+ if (onGround) { -+ ControllerJumpRabbit jumpController = (ControllerJumpRabbit) getJumpController(); -+ if (!wasOnGround) { -+ setJumping(false); -+ jumpController.setCanJump(false); -+ } -+ if (!jumpController.isJumping()) { -+ if (moveController.b()) { // isUpdating -+ startJumping(); -+ } -+ } else if (!jumpController.canJump()) { -+ jumpController.setCanJump(true); -+ } -+ } -+ wasOnGround = onGround; -+ } -+ -+ @Override -+ public boolean onSpacebar() { -+ if (onGround) { -+ actualJump = true; -+ jump(); -+ actualJump = false; -+ } -+ return true; -+ } -+ // Purpur end -+ - @Override - public void aE() {} - -@@ -472,7 +538,7 @@ public class EntityRabbit extends EntityAnimal { - } - } - -- static class ControllerMoveRabbit extends ControllerMove { -+ static class ControllerMoveRabbit extends net.pl3x.purpur.controller.ControllerMoveWASD { // Purpur - - private final EntityRabbit i; - private double j; -@@ -483,14 +549,14 @@ public class EntityRabbit extends EntityAnimal { - } - - @Override -- public void a() { -+ public void tick() { // Purpur - if (this.i.onGround && !this.i.jumping && !((EntityRabbit.ControllerJumpRabbit) this.i.bq).c()) { - this.i.i(0.0D); - } else if (this.b()) { - this.i.i(this.j); - } - -- super.a(); -+ super.tick(); // Purpur - } - - @Override -@@ -517,14 +583,17 @@ public class EntityRabbit extends EntityAnimal { - this.c = entityrabbit; - } - -+ public boolean isJumping() { return c(); } // Purpur - OBFHELPER - public boolean c() { - return this.a; - } - -+ public boolean canJump() { return d(); } // Purpur - OBFHELPER - public boolean d() { - return this.d; - } - -+ public void setCanJump(boolean canJump) { a(canJump); } // Purpur - OBFHELPER - public void a(boolean flag) { - this.d = flag; - } -diff --git a/src/main/java/net/minecraft/server/EntityRavager.java b/src/main/java/net/minecraft/server/EntityRavager.java -index fd25ce102..98d182a4c 100644 ---- a/src/main/java/net/minecraft/server/EntityRavager.java -+++ b/src/main/java/net/minecraft/server/EntityRavager.java -@@ -20,14 +20,33 @@ public class EntityRavager extends EntityRaider { - this.f = 20; - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.ravagerRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.ravagerRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.ravagerRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { - super.initPathfinder(); - this.goalSelector.a(0, new PathfinderGoalFloat(this)); -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(4, new EntityRavager.a()); - this.goalSelector.a(5, new PathfinderGoalRandomStrollLand(this, 0.4D)); - this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); - this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(2, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a(new Class[0])); // CraftBukkit - decompile error - this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); - this.targetSelector.a(4, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, true)); -diff --git a/src/main/java/net/minecraft/server/EntitySalmon.java b/src/main/java/net/minecraft/server/EntitySalmon.java -index 6be29f307..189515b0f 100644 ---- a/src/main/java/net/minecraft/server/EntitySalmon.java -+++ b/src/main/java/net/minecraft/server/EntitySalmon.java -@@ -6,6 +6,23 @@ public class EntitySalmon extends EntityFishSchool { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.salmonRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.salmonRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.salmonRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - public int es() { - return 5; -diff --git a/src/main/java/net/minecraft/server/EntitySheep.java b/src/main/java/net/minecraft/server/EntitySheep.java -index f63528ca3..43eefa46c 100644 ---- a/src/main/java/net/minecraft/server/EntitySheep.java -+++ b/src/main/java/net/minecraft/server/EntitySheep.java -@@ -55,10 +55,28 @@ public class EntitySheep extends EntityAnimal { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.sheepRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.sheepRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.sheepRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { - this.bA = new PathfinderGoalEatTile(this); - this.goalSelector.a(0, new PathfinderGoalFloat(this)); -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.25D)); - this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D)); - this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.1D, RecipeItemStack.a(Items.WHEAT), false)); -diff --git a/src/main/java/net/minecraft/server/EntityShulker.java b/src/main/java/net/minecraft/server/EntityShulker.java -index 0d2ceff6f..46379588c 100644 ---- a/src/main/java/net/minecraft/server/EntityShulker.java -+++ b/src/main/java/net/minecraft/server/EntityShulker.java -@@ -32,6 +32,23 @@ public class EntityShulker extends EntityGolem implements IMonster { - this.f = 5; - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.shulkerRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.shulkerRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.shulkerRequireShiftToMount; -+ } -+ // Purpur end -+ - @Nullable - @Override - public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { -@@ -46,10 +63,12 @@ public class EntityShulker extends EntityGolem implements IMonster { - - @Override - protected void initPathfinder() { -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(1, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); - this.goalSelector.a(4, new EntityShulker.a()); - this.goalSelector.a(7, new EntityShulker.e()); - this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[0])).a(new Class[0])); // CraftBukkit - decompile error - this.targetSelector.a(2, new EntityShulker.d(this)); - this.targetSelector.a(3, new EntityShulker.c(this)); -@@ -543,7 +562,7 @@ public class EntityShulker extends EntityGolem implements IMonster { - - private int b; - -- private e() {} -+ private e() { this.a(EnumSet.of(PathfinderGoal.Type.LOOK)); } // Purpur - peek - - @Override - public boolean a() { -diff --git a/src/main/java/net/minecraft/server/EntitySilverfish.java b/src/main/java/net/minecraft/server/EntitySilverfish.java -index 08c2a22f7..dff20567b 100644 ---- a/src/main/java/net/minecraft/server/EntitySilverfish.java -+++ b/src/main/java/net/minecraft/server/EntitySilverfish.java -@@ -11,13 +11,32 @@ public class EntitySilverfish extends EntityMonster { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.silverfishRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.silverfishRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.silverfishRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { - this.b = new EntitySilverfish.PathfinderGoalSilverfishWakeOthers(this); - this.goalSelector.a(1, new PathfinderGoalFloat(this)); -+ this.goalSelector.a(1, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(3, this.b); - this.goalSelector.a(4, new PathfinderGoalMeleeAttack(this, 1.0D, false)); - this.goalSelector.a(5, new EntitySilverfish.PathfinderGoalSilverfishHideInBlock(this)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[0])).a(new Class[0])); // CraftBukkit - decompile error - this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); - } -@@ -181,6 +200,7 @@ public class EntitySilverfish extends EntityMonster { - - public PathfinderGoalSilverfishWakeOthers(EntitySilverfish entitysilverfish) { - this.silverfish = entitysilverfish; -+ this.a(EnumSet.of(PathfinderGoal.Type.TARGET)); // Purpur - } - - public void g() { -diff --git a/src/main/java/net/minecraft/server/EntitySkeleton.java b/src/main/java/net/minecraft/server/EntitySkeleton.java -index 0e78d5c62..8e6efeb7b 100644 ---- a/src/main/java/net/minecraft/server/EntitySkeleton.java -+++ b/src/main/java/net/minecraft/server/EntitySkeleton.java -@@ -6,6 +6,23 @@ public class EntitySkeleton extends EntitySkeletonAbstract { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.skeletonRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.skeletonRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.skeletonRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected SoundEffect getSoundAmbient() { - return SoundEffects.ENTITY_SKELETON_AMBIENT; -diff --git a/src/main/java/net/minecraft/server/EntitySkeletonAbstract.java b/src/main/java/net/minecraft/server/EntitySkeletonAbstract.java -index 3c95c0428..8bc4e8515 100644 ---- a/src/main/java/net/minecraft/server/EntitySkeletonAbstract.java -+++ b/src/main/java/net/minecraft/server/EntitySkeletonAbstract.java -@@ -28,12 +28,14 @@ public abstract class EntitySkeletonAbstract extends EntityMonster implements IR - - @Override - protected void initPathfinder() { -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(2, new PathfinderGoalRestrictSun(this)); - this.goalSelector.a(3, new PathfinderGoalFleeSun(this, 1.0D)); - this.goalSelector.a(3, new PathfinderGoalAvoidTarget<>(this, EntityWolf.class, 6.0F, 1.0D, 1.2D)); - this.goalSelector.a(5, new PathfinderGoalRandomStrollLand(this, 1.0D)); - this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); - this.goalSelector.a(6, new PathfinderGoalRandomLookaround(this)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, new Class[0])); - this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); - this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, true)); -diff --git a/src/main/java/net/minecraft/server/EntitySkeletonStray.java b/src/main/java/net/minecraft/server/EntitySkeletonStray.java -index 2eb53864f..a930fb840 100644 ---- a/src/main/java/net/minecraft/server/EntitySkeletonStray.java -+++ b/src/main/java/net/minecraft/server/EntitySkeletonStray.java -@@ -8,6 +8,23 @@ public class EntitySkeletonStray extends EntitySkeletonAbstract { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.strayRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.strayRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.strayRequireShiftToMount; -+ } -+ // Purpur end -+ - public static boolean b(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { - return c(entitytypes, generatoraccess, enummobspawn, blockposition, random) && (enummobspawn == EnumMobSpawn.SPAWNER || generatoraccess.f(blockposition)); - } -diff --git a/src/main/java/net/minecraft/server/EntitySkeletonWither.java b/src/main/java/net/minecraft/server/EntitySkeletonWither.java -index 98e042424..8aa0a6699 100644 ---- a/src/main/java/net/minecraft/server/EntitySkeletonWither.java -+++ b/src/main/java/net/minecraft/server/EntitySkeletonWither.java -@@ -9,6 +9,23 @@ public class EntitySkeletonWither extends EntitySkeletonAbstract { - this.a(PathType.LAVA, 8.0F); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.witherSkeletonRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.witherSkeletonRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.witherSkeletonRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected SoundEffect getSoundAmbient() { - return SoundEffects.ENTITY_WITHER_SKELETON_AMBIENT; -diff --git a/src/main/java/net/minecraft/server/EntitySlime.java b/src/main/java/net/minecraft/server/EntitySlime.java -index 2efc18df9..1469e3b23 100644 ---- a/src/main/java/net/minecraft/server/EntitySlime.java -+++ b/src/main/java/net/minecraft/server/EntitySlime.java -@@ -32,12 +32,31 @@ public class EntitySlime extends EntityInsentient implements IMonster { - this.moveController = new EntitySlime.ControllerMoveSlime(this); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.slimeRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.slimeRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.slimeRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(1, new EntitySlime.PathfinderGoalSlimeRandomJump(this)); - this.goalSelector.a(2, new EntitySlime.PathfinderGoalSlimeNearestPlayer(this)); - this.goalSelector.a(3, new EntitySlime.PathfinderGoalSlimeRandomDirection(this)); - this.goalSelector.a(5, new EntitySlime.PathfinderGoalSlimeIdle(this)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, 10, true, false, (entityliving) -> { - return Math.abs(entityliving.locY() - this.locY()) <= 4.0D; - })); -@@ -496,10 +515,10 @@ public class EntitySlime extends EntityInsentient implements IMonster { - // Paper end - } - -- static class ControllerMoveSlime extends ControllerMove { -+ static class ControllerMoveSlime extends net.pl3x.purpur.controller.ControllerMoveWASD { // Purpur - - private float i; -- private int j; -+ private int j; private int getJumpDelay() { return j; } private void setJumpDelay(int delay) { j = delay; } // Purpur - OBFHELPER - private final EntitySlime k; - private boolean l; - -@@ -521,10 +540,23 @@ public class EntitySlime extends EntityInsentient implements IMonster { - - @Override - public void a() { -- this.a.yaw = this.a(this.a.yaw, this.i, 90.0F); -- this.a.aK = this.a.yaw; -- this.a.aI = this.a.yaw; -- if (this.h != ControllerMove.Operation.MOVE_TO) { -+ // Purpur start -+ if (entity.hasRider()) { -+ tick(entity.getRider()); -+ if (entity.getForward() != 0 || entity.getStrafe() != 0) { -+ if (getJumpDelay() > 10) { -+ setJumpDelay(6); -+ } -+ } else { -+ setJumpDelay(20); -+ } -+ } else { -+ this.a.yaw = this.a(this.a.yaw, this.i, 90.0F); -+ this.a.aK = this.a.yaw; -+ this.a.aI = this.a.yaw; -+ } -+ if (!entity.hasRider() && this.h != ControllerMove.Operation.MOVE_TO) { -+ // Purpur end - this.a.r(0.0F); - } else { - this.h = ControllerMove.Operation.WAIT; -diff --git a/src/main/java/net/minecraft/server/EntitySnowman.java b/src/main/java/net/minecraft/server/EntitySnowman.java -index dee55c5de..65d746899 100644 ---- a/src/main/java/net/minecraft/server/EntitySnowman.java -+++ b/src/main/java/net/minecraft/server/EntitySnowman.java -@@ -13,12 +13,31 @@ public class EntitySnowman extends EntityGolem implements IRangedEntity { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.snowGolemRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.snowGolemRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.snowGolemRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(1, new PathfinderGoalArrowAttack(this, 1.25D, 20, 10.0F)); - this.goalSelector.a(2, new PathfinderGoalRandomStrollLand(this, 1.0D, 1.0000001E-5F)); - this.goalSelector.a(3, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); - this.goalSelector.a(4, new PathfinderGoalRandomLookaround(this)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityInsentient.class, 10, true, false, (entityliving) -> { - return entityliving instanceof IMonster; - })); -@@ -72,6 +91,7 @@ public class EntitySnowman extends EntityGolem implements IRangedEntity { - return; - } - -+ if (hasRider() && !world.purpurConfig.snowGolemLeaveTrailWhenRidden) return; // Purpur - don't leave snow trail when being ridden - IBlockData iblockdata = Blocks.SNOW.getBlockData(); - - for (int l = 0; l < 4; ++l) { -@@ -115,7 +135,7 @@ public class EntitySnowman extends EntityGolem implements IRangedEntity { - if (!this.world.isClientSide) { - // CraftBukkit start - if (!CraftEventFactory.handlePlayerShearEntityEvent(entityhuman, this, itemstack, enumhand)) { -- return false; -+ return tryRide(entityhuman, enumhand); // Purpur - } - // CraftBukkit end - this.setHasPumpkin(false); -@@ -126,7 +146,7 @@ public class EntitySnowman extends EntityGolem implements IRangedEntity { - - return true; - } else { -- return false; -+ return tryRide(entityhuman, enumhand); // Purpur - } - } - -diff --git a/src/main/java/net/minecraft/server/EntitySpider.java b/src/main/java/net/minecraft/server/EntitySpider.java -index d02db5659..d3708a7b0 100644 ---- a/src/main/java/net/minecraft/server/EntitySpider.java -+++ b/src/main/java/net/minecraft/server/EntitySpider.java -@@ -11,14 +11,33 @@ public class EntitySpider extends EntityMonster { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.spiderRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.spiderRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.spiderRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { - this.goalSelector.a(1, new PathfinderGoalFloat(this)); -+ this.goalSelector.a(1, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(3, new PathfinderGoalLeapAtTarget(this, 0.4F)); - this.goalSelector.a(4, new EntitySpider.PathfinderGoalSpiderMeleeAttack(this)); - this.goalSelector.a(5, new PathfinderGoalRandomStrollLand(this, 0.8D)); - this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); - this.goalSelector.a(6, new PathfinderGoalRandomLookaround(this)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, new Class[0])); - this.targetSelector.a(2, new EntitySpider.PathfinderGoalSpiderNearestAttackableTarget<>(this, EntityHuman.class)); - this.targetSelector.a(3, new EntitySpider.PathfinderGoalSpiderNearestAttackableTarget<>(this, EntityIronGolem.class)); -diff --git a/src/main/java/net/minecraft/server/EntitySquid.java b/src/main/java/net/minecraft/server/EntitySquid.java -index 92efe4e7f..b967135ac 100644 ---- a/src/main/java/net/minecraft/server/EntitySquid.java -+++ b/src/main/java/net/minecraft/server/EntitySquid.java -@@ -25,10 +25,28 @@ public class EntitySquid extends EntityWaterAnimal { - this.bC = 1.0F / (this.random.nextFloat() + 1.0F) * 0.2F; - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.squidRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.squidRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.squidRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { - this.goalSelector.a(0, new EntitySquid.PathfinderGoalSquid(this)); -- this.goalSelector.a(1, new EntitySquid.a()); -+ this.goalSelector.a(1, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur -+ this.goalSelector.a(2, new EntitySquid.a()); // Purpur - } - - @Override -@@ -175,6 +193,7 @@ public class EntitySquid extends EntityWaterAnimal { - return blockposition.getY() > generatoraccess.getMinecraftWorld().spigotConfig.squidSpawnRangeMin && blockposition.getY() < maxHeight; // Spigot // Paper - } - -+ public void setMovementVector(float x, float y, float z) { a(x, y, z); } // Purpur - OBFHELPER - public void a(float f, float f1, float f2) { - this.bE = f; - this.bF = f1; -@@ -246,7 +265,7 @@ public class EntitySquid extends EntityWaterAnimal { - - class PathfinderGoalSquid extends PathfinderGoal { - -- private final EntitySquid b; -+ private final EntitySquid b; public EntitySquid getSquid() { return b; } // Purpur - OBFHELPER - - public PathfinderGoalSquid(EntitySquid entitysquid) { - this.b = entitysquid; -@@ -259,6 +278,39 @@ public class EntitySquid extends EntityWaterAnimal { - - @Override - public void e() { -+ // Purpur start -+ EntitySquid squid = getSquid(); -+ EntityHuman rider = squid.getRider(); -+ if (rider != null) { -+ if (rider.jumping) { -+ squid.onSpacebar(); -+ } -+ float forward = rider.getForward(); -+ float strafe = rider.getStrafe(); -+ float speed = (float) squid.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue() * 5F; -+ if (forward < 0.0F) { -+ speed *= -0.5; -+ } -+ org.bukkit.util.Vector dir = rider.getBukkitEntity().getEyeLocation().getDirection().normalize().multiply(speed / 20.0F); -+ if (strafe != 0.0F) { -+ if (forward == 0.0F) { -+ dir.setY(0); -+ rotateVectorAroundY(dir, strafe > 0.0F ? -90 : 90); -+ } else if (forward < 0.0F) { -+ rotateVectorAroundY(dir, strafe > 0.0F ? 45 : -45); -+ } else { -+ rotateVectorAroundY(dir, strafe > 0.0F ? -45 : 45); -+ } -+ } -+ if (forward != 0.0F || strafe != 0.0F) { -+ squid.setMovementVector((float) dir.getX(), (float) dir.getY(), (float) dir.getZ()); -+ } else { -+ squid.setMovementVector(0.0F, 0.0F, 0.0F); -+ } -+ return; -+ } -+ // Purpur end -+ - int i = this.b.cL(); - - if (i > 100) { -@@ -273,5 +325,17 @@ public class EntitySquid extends EntityWaterAnimal { - } - - } -+ -+ // Purpur start -+ private void rotateVectorAroundY(org.bukkit.util.Vector vector, double degrees) { -+ double rad = Math.toRadians(degrees); -+ double cos = Math.cos(rad); -+ double sine = Math.sin(rad); -+ double x = vector.getX(); -+ double z = vector.getZ(); -+ vector.setX(cos * x - sine * z); -+ vector.setZ(sine * x + cos * z); -+ } -+ // Purpur end - } - } -diff --git a/src/main/java/net/minecraft/server/EntityTameableAnimal.java b/src/main/java/net/minecraft/server/EntityTameableAnimal.java -index 9b2eea71c..d55c6cb33 100644 ---- a/src/main/java/net/minecraft/server/EntityTameableAnimal.java -+++ b/src/main/java/net/minecraft/server/EntityTameableAnimal.java -@@ -135,6 +135,7 @@ public abstract class EntityTameableAnimal extends EntityAnimal { - return this.i(entityliving) ? false : super.c(entityliving); - } - -+ public boolean isOwner(EntityLiving entityLiving) { return i(entityLiving); } // Purpur - OBFHELPER - public boolean i(EntityLiving entityliving) { - return entityliving == this.getOwner(); - } -diff --git a/src/main/java/net/minecraft/server/EntityTropicalFish.java b/src/main/java/net/minecraft/server/EntityTropicalFish.java -index ef8f373be..992978463 100644 ---- a/src/main/java/net/minecraft/server/EntityTropicalFish.java -+++ b/src/main/java/net/minecraft/server/EntityTropicalFish.java -@@ -19,6 +19,23 @@ public class EntityTropicalFish extends EntityFishSchool { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.tropicalFishRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.tropicalFishRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.tropicalFishRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initDatawatcher() { - super.initDatawatcher(); -diff --git a/src/main/java/net/minecraft/server/EntityTurtle.java b/src/main/java/net/minecraft/server/EntityTurtle.java -index b24a5100b..469549206 100644 ---- a/src/main/java/net/minecraft/server/EntityTurtle.java -+++ b/src/main/java/net/minecraft/server/EntityTurtle.java -@@ -27,6 +27,23 @@ public class EntityTurtle extends EntityAnimal { - this.H = 1.0F; - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.turtleRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.turtleRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.turtleRequireShiftToMount; -+ } -+ // Purpur end -+ - public final void setHome(BlockPosition pos) { g(pos); } // Paper - OBFHELPER - public void g(BlockPosition blockposition) { - this.datawatcher.set(EntityTurtle.bx, blockposition.immutableCopy()); // Paper - make sure home position can't change -@@ -141,12 +158,13 @@ public class EntityTurtle extends EntityAnimal { - - @Override - protected void initPathfinder() { -- this.goalSelector.a(0, new EntityTurtle.f(this, 1.2D)); -- this.goalSelector.a(1, new EntityTurtle.a(this, 1.0D)); -- this.goalSelector.a(1, new EntityTurtle.d(this, 1.0D)); -- this.goalSelector.a(2, new EntityTurtle.i(this, 1.1D, Blocks.SEAGRASS.getItem())); -- this.goalSelector.a(3, new EntityTurtle.c(this, 1.0D)); -- this.goalSelector.a(4, new EntityTurtle.b(this, 1.0D)); -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur -+ this.goalSelector.a(1, new EntityTurtle.f(this, 1.2D)); // Purpur -+ this.goalSelector.a(2, new EntityTurtle.a(this, 1.0D)); // Purpur -+ this.goalSelector.a(2, new EntityTurtle.d(this, 1.0D)); // Purpur -+ this.goalSelector.a(3, new EntityTurtle.i(this, 1.1D, Blocks.SEAGRASS.getItem())); // Purpur -+ this.goalSelector.a(4, new EntityTurtle.c(this, 1.0D)); // Purpur -+ this.goalSelector.a(5, new EntityTurtle.b(this, 1.0D)); // Purpur - this.goalSelector.a(7, new EntityTurtle.j(this, 1.0D)); - this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); - this.goalSelector.a(9, new EntityTurtle.h(this, 1.0D, 100)); -@@ -332,9 +350,9 @@ public class EntityTurtle extends EntityAnimal { - } - } - -- static class e extends ControllerMove { -+ static class e extends net.pl3x.purpur.controller.ControllerMoveWASD { // Purpur - -- private final EntityTurtle i; -+ private final EntityTurtle i; public EntityTurtle getTurtle() { return i; } // Purpur - OBFHELPER - - e(EntityTurtle entityturtle) { - super(entityturtle); -@@ -358,7 +376,86 @@ public class EntityTurtle extends EntityAnimal { - } - - @Override -- public void a() { -+ // Purpur start -+ public void tick(EntityHuman rider) { -+ if (getTurtle().isInWater()) { -+ // water controls (from ControllerMoveWASDWater) -+ float forward = rider.getForward() * 0.5F; -+ float strafe = rider.getStrafe() * 0.25F; // strafe slower by default -+ float vertical = -(rider.pitch / 90); -+ -+ if (forward == 0.0F) { -+ // strafe slower if not moving forward -+ strafe *= 0.5F; -+ // do not move vertically if not moving forward -+ vertical = 0.0F; -+ } else if (forward < 0.0F) { -+ // water animals can't swim backwards -+ forward = 0.0F; -+ vertical = 0.0F; -+ } -+ -+ if (rider.jumping) { -+ entity.onSpacebar(); -+ } -+ -+ setSpeed(entity.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue()); -+ entity.setSpeed((float) getSpeed() * 0.1F); -+ -+ entity.setForward(forward); -+ entity.setStrafe(strafe); -+ entity.setVertical(vertical * 2F); -+ -+ setForward(entity.getForward()); -+ setStrafe(entity.getStrafe()); -+ } else { -+ // land controls (from ControllerMoveWASD) -+ float forward = rider.getForward() * 0.5F; -+ float strafe = rider.getStrafe() * 0.25F; -+ -+ if (forward <= 0.0F) { -+ forward *= 0.5F; -+ } -+ -+ float yawOffset = 0; -+ if (strafe != 0) { -+ if (forward == 0) { -+ yawOffset += strafe > 0 ? -90 : 90; -+ forward = Math.abs(strafe * 2); -+ } else { -+ yawOffset += strafe > 0 ? -30 : 30; -+ strafe /= 2; -+ if (forward < 0) { -+ yawOffset += strafe > 0 ? -110 : 110; -+ forward *= -1; -+ } -+ } -+ } else if (forward < 0) { -+ yawOffset -= 180; -+ forward *= -1; -+ } -+ -+ ((net.pl3x.purpur.controller.ControllerLookWASD) entity.getControllerLook()).setOffsets(yawOffset, 0); -+ -+ if (rider.jumping) { -+ //RidableSpacebarEvent event = new RidableSpacebarEvent(entity); -+ if (/*event.callEvent() && !event.isHandled() &&*/ !entity.onSpacebar() && entity.onGround) { -+ entity.jump(); -+ } -+ } -+ -+ setSpeed(entity.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue()); -+ entity.setSpeed((float) getSpeed() * 0.1F); -+ entity.setForward(forward); -+ -+ setForward(entity.getForward()); -+ setStrafe(entity.getStrafe()); -+ } -+ } -+ -+ @Override -+ public void tick() { -+ // Purpur end - this.g(); - if (this.h == ControllerMove.Operation.MOVE_TO && !this.i.getNavigation().m()) { - double d0 = this.b - this.i.locX(); -diff --git a/src/main/java/net/minecraft/server/EntityTypes.java b/src/main/java/net/minecraft/server/EntityTypes.java -index 0f04bcc8b..5a7494947 100644 ---- a/src/main/java/net/minecraft/server/EntityTypes.java -+++ b/src/main/java/net/minecraft/server/EntityTypes.java -@@ -259,6 +259,12 @@ public class EntityTypes { - return this.bb; - } - -+ // Purpur start -+ public String getName() { -+ return IRegistry.ENTITY_TYPE.getKey(this).getKey(); -+ } -+ // Purpur end -+ - public String f() { - if (this.bg == null) { - this.bg = SystemUtils.a("entity", IRegistry.ENTITY_TYPE.getKey(this)); -diff --git a/src/main/java/net/minecraft/server/EntityVex.java b/src/main/java/net/minecraft/server/EntityVex.java -index cf274666c..d919f44ab 100644 ---- a/src/main/java/net/minecraft/server/EntityVex.java -+++ b/src/main/java/net/minecraft/server/EntityVex.java -@@ -19,6 +19,50 @@ public class EntityVex extends EntityMonster { - this.f = 3; - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.vexRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.vexRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.vexRequireShiftToMount; -+ } -+ -+ @Override -+ public double getMaxY() { -+ return world.purpurConfig.vexMaxY; -+ } -+ -+ @Override -+ public void e(Vec3D vec3d) { -+ super.e(vec3d); -+ if (hasRider()) { -+ float speed; -+ if (onGround) { -+ speed = (float) getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue() * 0.1F; -+ } else { -+ speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue(); -+ } -+ setSpeed(speed); -+ Vec3D mot = getMot(); -+ move(EnumMoveType.SELF, mot.multiply(speed, 1.0, speed)); -+ setMot(mot.a(0.9D)); -+ } -+ } -+ -+ @Override -+ public boolean b(float f, float f1) { -+ return false; // no fall damage please -+ } -+ // Purpur end -+ - @Override - public void move(EnumMoveType enummovetype, Vec3D vec3d) { - super.move(enummovetype, vec3d); -@@ -27,7 +71,7 @@ public class EntityVex extends EntityMonster { - - @Override - public void tick() { -- this.noclip = true; -+ this.noclip = !hasRider(); // Purpur - super.tick(); - this.noclip = false; - this.setNoGravity(true); -@@ -42,10 +86,12 @@ public class EntityVex extends EntityMonster { - protected void initPathfinder() { - super.initPathfinder(); - this.goalSelector.a(0, new PathfinderGoalFloat(this)); -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(4, new EntityVex.a()); - this.goalSelector.a(8, new EntityVex.d()); - this.goalSelector.a(9, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 3.0F, 1.0F)); - this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a(new Class[0])); // CraftBukkit - decompile error - this.targetSelector.a(2, new EntityVex.b(this)); - this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); -@@ -56,6 +102,12 @@ public class EntityVex extends EntityMonster { - super.initAttributes(); - this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(14.0D); - this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(4.0D); -+ // Purpur start -+ if (world != null && world.purpurConfig.vexRidable) { -+ this.getAttributeMap().b(GenericAttributes.FLYING_SPEED); -+ this.getAttributeInstance(GenericAttributes.FLYING_SPEED).setValue(0.6000000238418579D); -+ } -+ // Purpur end - } - - @Override -@@ -287,14 +339,21 @@ public class EntityVex extends EntityMonster { - } - } - -- class c extends ControllerMove { -+ class c extends net.pl3x.purpur.controller.ControllerMoveWASDFlying { // Purpur - - public c(EntityVex entityvex) { - super(entityvex); - } - - @Override -- public void a() { -+ // Purpur start -+ public void tick(EntityHuman rider) { -+ super.tick(rider); -+ } -+ -+ @Override -+ public void tick() { -+ // Purpur end - if (this.h == ControllerMove.Operation.MOVE_TO) { - Vec3D vec3d = new Vec3D(this.b - EntityVex.this.locX(), this.c - EntityVex.this.locY(), this.d - EntityVex.this.locZ()); - double d0 = vec3d.f(); -diff --git a/src/main/java/net/minecraft/server/EntityVillager.java b/src/main/java/net/minecraft/server/EntityVillager.java -index 7da267d28..5b0de0d9d 100644 ---- a/src/main/java/net/minecraft/server/EntityVillager.java -+++ b/src/main/java/net/minecraft/server/EntityVillager.java -@@ -68,6 +68,28 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation - this.bo = this.a(new Dynamic(DynamicOpsNBT.a, new NBTTagCompound())); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.villagerRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.villagerRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.villagerRequireShiftToMount; -+ } -+ -+ @Override -+ protected void initPathfinder() { -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur -+ } -+ // Purpur end -+ - @Override - public BehaviorController getBehaviorController() { - return (BehaviorController) super.getBehaviorController(); // CraftBukkit - decompile error -diff --git a/src/main/java/net/minecraft/server/EntityVillagerTrader.java b/src/main/java/net/minecraft/server/EntityVillagerTrader.java -index 2ad8dba5c..4e9c5e84a 100644 ---- a/src/main/java/net/minecraft/server/EntityVillagerTrader.java -+++ b/src/main/java/net/minecraft/server/EntityVillagerTrader.java -@@ -20,6 +20,23 @@ public class EntityVillagerTrader extends EntityVillagerAbstract { - this.attachedToPlayer = true; - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.villagerTraderRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.villagerTraderRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.villagerTraderRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { - this.goalSelector.a(0, new PathfinderGoalFloat(this)); -@@ -29,6 +46,7 @@ public class EntityVillagerTrader extends EntityVillagerAbstract { - this.goalSelector.a(0, new PathfinderGoalUseItem<>(this, new ItemStack(Items.MILK_BUCKET), SoundEffects.ENTITY_WANDERING_TRADER_REAPPEARED, (entityvillagertrader) -> { - return this.world.isDay() && entityvillagertrader.isInvisible(); - })); -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(1, new PathfinderGoalTradeWithPlayer(this)); - this.goalSelector.a(1, new PathfinderGoalAvoidTarget<>(this, EntityZombie.class, 8.0F, 0.5D, 0.5D)); - this.goalSelector.a(1, new PathfinderGoalAvoidTarget<>(this, EntityEvoker.class, 12.0F, 0.5D, 0.5D)); -diff --git a/src/main/java/net/minecraft/server/EntityVindicator.java b/src/main/java/net/minecraft/server/EntityVindicator.java -index c974c02e9..6ba920134 100644 ---- a/src/main/java/net/minecraft/server/EntityVindicator.java -+++ b/src/main/java/net/minecraft/server/EntityVindicator.java -@@ -17,14 +17,33 @@ public class EntityVindicator extends EntityIllagerAbstract { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.vindicatorRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.vindicatorRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.vindicatorRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { - super.initPathfinder(); - this.goalSelector.a(0, new PathfinderGoalFloat(this)); -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(1, new EntityVindicator.a(this)); - this.goalSelector.a(2, new EntityIllagerAbstract.b(this)); - this.goalSelector.a(3, new EntityRaider.a(this, 10.0F)); - this.goalSelector.a(4, new EntityVindicator.c(this)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a(new Class[0])); // Paper - decompile fix - this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); - this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, true)); -diff --git a/src/main/java/net/minecraft/server/EntityWitch.java b/src/main/java/net/minecraft/server/EntityWitch.java -index 1432d3f6b..447387bd7 100644 ---- a/src/main/java/net/minecraft/server/EntityWitch.java -+++ b/src/main/java/net/minecraft/server/EntityWitch.java -@@ -24,6 +24,23 @@ public class EntityWitch extends EntityRaider implements IRangedEntity { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.witchRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.witchRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.witchRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { - super.initPathfinder(); -@@ -31,11 +48,13 @@ public class EntityWitch extends EntityRaider implements IRangedEntity { - return entityliving != null && this.eF() && entityliving.getEntityType() != EntityTypes.WITCH; - }); - this.bA = new PathfinderGoalNearestAttackableTargetWitch<>(this, EntityHuman.class, 10, true, false, null); // Purpur - decompile error -- this.goalSelector.a(1, new PathfinderGoalFloat(this)); -+ this.goalSelector.a(0, new PathfinderGoalFloat(this)); // Purpur -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(2, new PathfinderGoalArrowAttack(this, 1.0D, 60, 10.0F)); - this.goalSelector.a(2, new PathfinderGoalRandomStrollLand(this, 1.0D)); - this.goalSelector.a(3, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); - this.goalSelector.a(3, new PathfinderGoalRandomLookaround(this)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, EntityRaider.class)); // Purpur - decompile error - this.targetSelector.a(2, this.bz); - this.targetSelector.a(3, this.bA); -diff --git a/src/main/java/net/minecraft/server/EntityWither.java b/src/main/java/net/minecraft/server/EntityWither.java -index 2f466af4d..8c1fa3717 100644 ---- a/src/main/java/net/minecraft/server/EntityWither.java -+++ b/src/main/java/net/minecraft/server/EntityWither.java -@@ -18,7 +18,7 @@ public class EntityWither extends EntityMonster implements IRangedEntity { - private static final DataWatcherObject b = DataWatcher.a(EntityWither.class, DataWatcherRegistry.b); - private static final DataWatcherObject c = DataWatcher.a(EntityWither.class, DataWatcherRegistry.b); - private static final DataWatcherObject d = DataWatcher.a(EntityWither.class, DataWatcherRegistry.b); -- private static final List> bw = ImmutableList.of(EntityWither.b, EntityWither.c, EntityWither.d); -+ private static final List> bw = ImmutableList.of(EntityWither.b, EntityWither.c, EntityWither.d); private static List> targetList() { return bw; } // Purpur - OBFHELPER - private static final DataWatcherObject bx = DataWatcher.a(EntityWither.class, DataWatcherRegistry.b); - private final float[] by = new float[2]; - private final float[] bz = new float[2]; -@@ -39,15 +39,59 @@ public class EntityWither extends EntityMonster implements IRangedEntity { - this.setHealth(this.getMaxHealth()); - this.getNavigation().d(true); - this.f = 50; -+ this.moveController = new net.pl3x.purpur.controller.ControllerMoveWASDFlyingWithSpacebar(this, 0.1F); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.witherRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.witherRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.witherRequireShiftToMount; -+ } -+ -+ @Override -+ public double getMaxY() { -+ return world.purpurConfig.witherMaxY; -+ } -+ -+ @Override -+ public void e(Vec3D vec3d) { -+ super.e(vec3d); -+ if (hasRider() && !onGround) { -+ float speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue(); -+ setSpeed(speed); -+ Vec3D mot = getMot(); -+ move(EnumMoveType.SELF, mot.multiply(speed, 0.5, speed)); -+ setMot(mot.a(0.9D)); -+ } -+ } -+ -+ @Override -+ public void onMount(EntityHuman entityhuman) { -+ this.datawatcher.set(targetList().get(0), 0); -+ this.datawatcher.set(targetList().get(1), 0); -+ this.datawatcher.set(targetList().get(2), 0); -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { -- this.goalSelector.a(0, new EntityWither.a()); -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur -+ this.goalSelector.a(1, new EntityWither.a()); // Purpur - this.goalSelector.a(2, new PathfinderGoalArrowAttack(this, 1.0D, 40, 20.0F)); - this.goalSelector.a(5, new PathfinderGoalRandomStrollLand(this, 1.0D)); - this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); - this.goalSelector.a(7, new PathfinderGoalRandomLookaround(this)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, new Class[0])); - this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityInsentient.class, 0, false, false, EntityWither.bG)); - } -@@ -125,7 +169,7 @@ public class EntityWither extends EntityMonster implements IRangedEntity { - } - - this.setMot(vec3d); -- if (b(vec3d) > 0.05D) { -+ if (!hasRider() && b(vec3d) > 0.05D) { // Purpur - this.yaw = (float) MathHelper.d(vec3d.z, vec3d.x) * 57.295776F - 90.0F; - } - -@@ -189,6 +233,13 @@ public class EntityWither extends EntityMonster implements IRangedEntity { - - @Override - protected void mobTick() { -+ // Purpur start -+ if (hasRider()) { -+ Vec3D mot = getMot(); -+ setMot(mot.x, mot.y + (getVertical() > 0 ? 0.07D : 0.0D), mot.z); -+ } -+ // Purpur end -+ - int i; - - if (this.eq() > 0) { -@@ -512,6 +563,12 @@ public class EntityWither extends EntityMonster implements IRangedEntity { - this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.6000000238418579D); - this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(40.0D); - this.getAttributeInstance(GenericAttributes.ARMOR).setValue(4.0D); -+ // Purpur start -+ if (world != null && world.purpurConfig.witherRidable) { -+ this.getAttributeMap().b(GenericAttributes.FLYING_SPEED); -+ this.getAttributeInstance(GenericAttributes.FLYING_SPEED).setValue(0.6000000238418579D); -+ } -+ // Purpur end - } - - public int eq() { -@@ -523,11 +580,11 @@ public class EntityWither extends EntityMonster implements IRangedEntity { - } - - public int getHeadTarget(int i) { -- return (Integer) this.datawatcher.get((DataWatcherObject) EntityWither.bw.get(i)); -+ return hasRider() ? 0 : this.datawatcher.get(EntityWither.bw.get(i)); // Purpur - } - - public void setHeadTarget(int i, int j) { -- this.datawatcher.set((DataWatcherObject) EntityWither.bw.get(i), j); -+ if (!hasRider()) this.datawatcher.set(EntityWither.bw.get(i), j); // Purpur - } - - public boolean J_() { -@@ -541,7 +598,7 @@ public class EntityWither extends EntityMonster implements IRangedEntity { - - @Override - protected boolean n(Entity entity) { -- return false; -+ return getRideCooldown() <= 0; // Purpur - } - - @Override -diff --git a/src/main/java/net/minecraft/server/EntityWolf.java b/src/main/java/net/minecraft/server/EntityWolf.java -index eec1e26b6..47f0b2df6 100644 ---- a/src/main/java/net/minecraft/server/EntityWolf.java -+++ b/src/main/java/net/minecraft/server/EntityWolf.java -@@ -30,10 +30,28 @@ public class EntityWolf extends EntityTameableAnimal { - this.setTamed(false); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.wolfRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.wolfRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.wolfRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { - this.goalSit = new PathfinderGoalSit(this); - this.goalSelector.a(1, new PathfinderGoalFloat(this)); -+ this.goalSelector.a(1, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(2, this.goalSit); - this.goalSelector.a(3, new EntityWolf.a<>(this, EntityLlama.class, 24.0F, 1.5D, 1.5D)); - this.goalSelector.a(4, new PathfinderGoalLeapAtTarget(this, 0.4F)); -@@ -44,6 +62,7 @@ public class EntityWolf extends EntityTameableAnimal { - this.goalSelector.a(9, new PathfinderGoalBeg(this, 8.0F)); - this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); - this.goalSelector.a(10, new PathfinderGoalRandomLookaround(this)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.targetSelector.a(1, new PathfinderGoalOwnerHurtByTarget(this)); - this.targetSelector.a(2, new PathfinderGoalOwnerHurtTarget(this)); - this.targetSelector.a(3, (new PathfinderGoalHurtByTarget(this, new Class[0])).a(new Class[0])); // CraftBukkit - decompile error -@@ -274,85 +293,56 @@ public class EntityWolf extends EntityTameableAnimal { - - @Override - public boolean a(EntityHuman entityhuman, EnumHand enumhand) { -- ItemStack itemstack = entityhuman.b(enumhand); -+ // Purpur start - rebuild entire method back to 1.14 standards -+ ItemStack itemstack = entityhuman.getItemInHand(enumhand); - Item item = itemstack.getItem(); - -- if (itemstack.getItem() instanceof ItemMonsterEgg) { -- return super.a(entityhuman, enumhand); -- } else if (this.world.isClientSide) { -- return this.i((EntityLiving) entityhuman) || item == Items.BONE && !this.isAngry(); -- } else { -- if (this.isTamed()) { -- if (item.isFood() && item.getFoodInfo().c() && this.getHealth() < this.getMaxHealth()) { -+ if (isTamed()) { -+ if (item.isFood()) { -+ if (item.getFoodInfo().isMeat() && getHealth() < getMaxHealth()) { - if (!entityhuman.abilities.canInstantlyBuild) { - itemstack.subtract(1); - } -- -- this.heal((float) item.getFoodInfo().getNutrition(), org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.EATING); // CraftBukkit -+ heal((float) item.getFoodInfo().getNutrition(), org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.EATING); // CraftBukkit - return true; - } -- -- if (!(item instanceof ItemDye)) { -- boolean flag = super.a(entityhuman, enumhand); -- -- if (!flag || this.isBaby()) { -- //this.goalSit.setSitting(!this.isSitting()); // Paper start - copied from below -- if (this.i((EntityLiving) entityhuman) && !this.i(itemstack)) { -- this.goalSit.setSitting(!this.isSitting()); -- this.jumping = false; -- this.navigation.o(); -- this.setGoalTarget((EntityLiving) null, TargetReason.FORGOT_TARGET, true); // CraftBukkit - reason -- } -- // Paper end - copied from below -- } -- -- return flag; -- } -- -- EnumColor enumcolor = ((ItemDye) item).d(); -- -- if (enumcolor != this.getCollarColor()) { -- this.setCollarColor(enumcolor); -+ } else if (item instanceof ItemDye) { -+ EnumColor color = ((ItemDye) item).getDyeColor(); -+ if (color != getCollarColor()) { - if (!entityhuman.abilities.canInstantlyBuild) { - itemstack.subtract(1); - } -- -+ setCollarColor(color); - return true; - } -- -- /* Paper start - Move into above -- if (this.i((EntityLiving) entityhuman) && !this.i(itemstack)) { -- this.goalSit.setSitting(!this.isSitting()); -- this.jumping = false; -- this.navigation.o(); -- this.setGoalTarget((EntityLiving) null, TargetReason.FORGOT_TARGET, true); // CraftBukkit - reason -- } -- */ // Paper end -- } else if (item == Items.BONE && !this.isAngry()) { -- if (!entityhuman.abilities.canInstantlyBuild) { -- itemstack.subtract(1); -- } -- -- // CraftBukkit - added event call and isCancelled check. -- if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) { -- this.tame(entityhuman); -- this.navigation.o(); -- this.setGoalTarget((EntityLiving) null); -- this.goalSit.setSitting(true); -- this.world.broadcastEntityEffect(this, (byte) 7); -- } else { -- this.world.broadcastEntityEffect(this, (byte) 6); -- } -- -- return true; - } -- -- return super.a(entityhuman, enumhand); -+ if (isOwner(entityhuman) && !isFood(itemstack)) { -+ goalSit.setSitting(!isSitting()); -+ jumping = false; -+ navigation.stopPathfinding(); -+ setGoalTarget(null, TargetReason.FORGOT_TARGET, true); // CraftBukkit - reason -+ } -+ } else if (item == Items.BONE && !isAngry()) { -+ if (!entityhuman.abilities.canInstantlyBuild) { -+ itemstack.subtract(1); -+ } -+ if (random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) { // CraftBukkit - added event call and isCancelled check. -+ tame(entityhuman); -+ navigation.stopPathfinding(); -+ setGoalTarget(null); -+ goalSit.setSitting(true); -+ world.broadcastEntityEffect(this, (byte) 7); -+ } else { -+ world.broadcastEntityEffect(this, (byte) 6); -+ } -+ return true; - } -+ return super.a(entityhuman, enumhand); -+ // Purpur end - } - - @Override -- public boolean i(ItemStack itemstack) { -+ public boolean i(ItemStack itemstack) { return isFood(itemstack); } public boolean isFood(ItemStack itemstack) { // Purpur - OBFHELPER - Item item = itemstack.getItem(); - - return item.isFood() && item.getFoodInfo().c(); -@@ -442,6 +432,13 @@ public class EntityWolf extends EntityTameableAnimal { - return !this.isAngry() && super.a(entityhuman); - } - -+ // Purpur start -+ public void onMount(EntityHuman entityhuman) { -+ super.onMount(entityhuman); -+ setSitting(false); -+ } -+ // Purpur end -+ - class a extends PathfinderGoalAvoidTarget { - - private final EntityWolf j; -diff --git a/src/main/java/net/minecraft/server/EntityZombie.java b/src/main/java/net/minecraft/server/EntityZombie.java -index 07ebc1d81..8d1f04415 100644 ---- a/src/main/java/net/minecraft/server/EntityZombie.java -+++ b/src/main/java/net/minecraft/server/EntityZombie.java -@@ -44,11 +44,30 @@ public class EntityZombie extends EntityMonster { - this(EntityTypes.ZOMBIE, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.zombieRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.zombieRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.zombieRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initPathfinder() { -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(4, new EntityZombie.a(this, 1.0D, 3)); - this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); - this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.l(); - } - -diff --git a/src/main/java/net/minecraft/server/EntityZombieHusk.java b/src/main/java/net/minecraft/server/EntityZombieHusk.java -index da8446d05..db252ba4e 100644 ---- a/src/main/java/net/minecraft/server/EntityZombieHusk.java -+++ b/src/main/java/net/minecraft/server/EntityZombieHusk.java -@@ -8,6 +8,23 @@ public class EntityZombieHusk extends EntityZombie { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.huskRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.huskRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.huskRequireShiftToMount; -+ } -+ // Purpur end -+ - public static boolean b(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { - return c(entitytypes, generatoraccess, enummobspawn, blockposition, random) && (enummobspawn == EnumMobSpawn.SPAWNER || generatoraccess.f(blockposition)); - } -diff --git a/src/main/java/net/minecraft/server/EntityZombieVillager.java b/src/main/java/net/minecraft/server/EntityZombieVillager.java -index 8082fa617..ebbfcb75a 100644 ---- a/src/main/java/net/minecraft/server/EntityZombieVillager.java -+++ b/src/main/java/net/minecraft/server/EntityZombieVillager.java -@@ -25,6 +25,23 @@ public class EntityZombieVillager extends EntityZombie implements VillagerDataHo - this.setVillagerData(this.getVillagerData().withProfession((VillagerProfession) IRegistry.VILLAGER_PROFESSION.a(this.random))); - } - -+ // Purpur start -+ @Override -+ public boolean isRidable() { -+ return world.purpurConfig.zombieVillagerRidable; -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return world.purpurConfig.zombieVillagerRidableInWater; -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return world.purpurConfig.zombieVillagerRequireShiftToMount; -+ } -+ // Purpur end -+ - @Override - protected void initDatawatcher() { - super.initDatawatcher(); -diff --git a/src/main/java/net/minecraft/server/FoodInfo.java b/src/main/java/net/minecraft/server/FoodInfo.java -index b35fe21a6..5b0f35c73 100644 ---- a/src/main/java/net/minecraft/server/FoodInfo.java -+++ b/src/main/java/net/minecraft/server/FoodInfo.java -@@ -30,6 +30,7 @@ public class FoodInfo { - return this.b; - } - -+ public boolean isMeat() { return c(); } // Purpur - OBFHELPER - public boolean c() { - return this.c; - } -diff --git a/src/main/java/net/minecraft/server/ItemDye.java b/src/main/java/net/minecraft/server/ItemDye.java -index da49f6e5a..7b5d60264 100644 ---- a/src/main/java/net/minecraft/server/ItemDye.java -+++ b/src/main/java/net/minecraft/server/ItemDye.java -@@ -42,6 +42,7 @@ public class ItemDye extends Item { - } - } - -+ public EnumColor getDyeColor() { return d(); } // Purpur - OBFHELPER - public EnumColor d() { - return this.b; - } -diff --git a/src/main/java/net/minecraft/server/MathHelper.java b/src/main/java/net/minecraft/server/MathHelper.java -index c4aa38ddf..3d52a396e 100644 ---- a/src/main/java/net/minecraft/server/MathHelper.java -+++ b/src/main/java/net/minecraft/server/MathHelper.java -@@ -263,6 +263,7 @@ public class MathHelper { - return (d0 - d1) / (d2 - d1); - } - -+ public static double atan2(double d0, double d1) { return d(d0, d1); } // Purpur - OBFHELPER - public static double d(double d0, double d1) { - double d2 = d1 * d1 + d0 * d0; - -@@ -407,6 +408,7 @@ public class MathHelper { - return i; - } - -+ public static float lerp(float f, float f1, float f2) { return g(f, f1, f2); } // Purpur - OBFHELPER - public static float g(float f, float f1, float f2) { - return f1 + f * (f2 - f1); - } -diff --git a/src/main/java/net/minecraft/server/PathfinderGoalSwell.java b/src/main/java/net/minecraft/server/PathfinderGoalSwell.java -index e07c7674a..3c077b687 100644 ---- a/src/main/java/net/minecraft/server/PathfinderGoalSwell.java -+++ b/src/main/java/net/minecraft/server/PathfinderGoalSwell.java -@@ -4,8 +4,8 @@ import java.util.EnumSet; - - public class PathfinderGoalSwell extends PathfinderGoal { - -- private final EntityCreeper a; -- private EntityLiving b; -+ private final EntityCreeper a; public EntityCreeper getCreeper() { return a; } // Purpur - OBFHELPER -+ private EntityLiving b; public void setTarget(EntityLiving target) { b = target; } // Purpur - OBFHELPER - - public PathfinderGoalSwell(EntityCreeper entitycreeper) { - this.a = entitycreeper; -@@ -32,6 +32,7 @@ public class PathfinderGoalSwell extends PathfinderGoal { - - @Override - public void e() { -+ setTarget(getCreeper().getGoalTarget()); // Purpur - if (this.b == null) { - this.a.a(-1); - } else if (this.a.h((Entity) this.b) > 49.0D) { -diff --git a/src/main/java/net/minecraft/server/ProjectileHelper.java b/src/main/java/net/minecraft/server/ProjectileHelper.java -index 1b796ba5b..7dbe3500e 100644 ---- a/src/main/java/net/minecraft/server/ProjectileHelper.java -+++ b/src/main/java/net/minecraft/server/ProjectileHelper.java -@@ -15,6 +15,7 @@ public final class ProjectileHelper { - }, entity.getBoundingBox().a(entity.getMot()).g(1.0D)); - } - -+ public static MovingObjectPosition getHitResult(Entity entity, AxisAlignedBB aabb, Predicate predicate, RayTrace.BlockCollisionOption option, boolean flag) { return a(entity, aabb, predicate, option, flag); } // Purpur - OBFHELPER - public static MovingObjectPosition a(Entity entity, AxisAlignedBB axisalignedbb, Predicate predicate, RayTrace.BlockCollisionOption raytrace_blockcollisionoption, boolean flag) { - return a(entity, flag, false, (Entity) null, raytrace_blockcollisionoption, false, predicate, axisalignedbb); - } -diff --git a/src/main/java/net/minecraft/server/Vec3D.java b/src/main/java/net/minecraft/server/Vec3D.java -index c2e4b5e8d..3838b3b3a 100644 ---- a/src/main/java/net/minecraft/server/Vec3D.java -+++ b/src/main/java/net/minecraft/server/Vec3D.java -@@ -27,6 +27,7 @@ public class Vec3D implements IPosition { - return new Vec3D(vec3d.x - this.x, vec3d.y - this.y, vec3d.z - this.z); - } - -+ public Vec3D normalize() { return d(); } // Purpur - OBFHELPER - public Vec3D d() { - double d0 = (double) MathHelper.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); - -@@ -82,6 +83,7 @@ public class Vec3D implements IPosition { - return d3 * d3 + d4 * d4 + d5 * d5; - } - -+ public Vec3D scale(double scale) { return a(scale); } // Purpur - OBFHELPER - public Vec3D a(double d0) { - return this.d(d0, d0, d0); - } -@@ -90,6 +92,7 @@ public class Vec3D implements IPosition { - return this.d(vec3d.x, vec3d.y, vec3d.z); - } - -+ public Vec3D multiply (double x, double y, double z) { return d(x, y, z); } // Purpur - OBFHELPER - public Vec3D d(double d0, double d1, double d2) { - return new Vec3D(this.x * d0, this.y * d1, this.z * d2); - } -diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index bdb12d16f..ad3b81a11 100644 ---- a/src/main/java/net/minecraft/server/World.java -+++ b/src/main/java/net/minecraft/server/World.java -@@ -1020,6 +1020,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - } - } - -+ public boolean containsMaterial(AxisAlignedBB aabb, Material mat) { return a(aabb, mat); } // Purpur - OBFHELPER - public boolean a(AxisAlignedBB axisalignedbb, Material material) { - int i = MathHelper.floor(axisalignedbb.minX); - int j = MathHelper.f(axisalignedbb.maxX); -@@ -1665,4 +1666,10 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - @Override public BiomeManager d() { - return this.biomeManager; - } -+ -+ // Purpur start -+ public void playEffect(@Nullable EntityHuman entityhuman, int i, BlockPosition blockposition, int j) { -+ this.a(entityhuman, i, blockposition, j); -+ } -+ // Purpur end - } -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index eda37fa43..69f99a993 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -64,4 +64,603 @@ public class PurpurWorldConfig { - PurpurConfig.config.addDefault("world-settings.default." + path, def); - return PurpurConfig.config.getString("world-settings." + worldName + "." + path, PurpurConfig.config.getString("world-settings.default." + path)); - } -+ -+ public boolean batRidable = false; -+ public boolean batRidableInWater = false; -+ public boolean batRequireShiftToMount = true; -+ public double batMaxY = 256D; -+ private void batSettings() { -+ batRidable = getBoolean("mobs.bat.ridable", batRidable); -+ batRidableInWater = getBoolean("mobs.bat.ridable-in-water", batRidableInWater); -+ batRequireShiftToMount = getBoolean("mobs.bat.require-shift-to-mount", batRequireShiftToMount); -+ batMaxY = getDouble("mobs.bat.ridable-max-y", batMaxY); -+ } -+ -+ public boolean beeRidable = false; -+ public boolean beeRidableInWater = false; -+ public boolean beeRequireShiftToMount = true; -+ public double beeMaxY = 256D; -+ private void beeSettings() { -+ beeRidable = getBoolean("mobs.bee.ridable", beeRidable); -+ beeRidableInWater = getBoolean("mobs.bee.ridable-in-water", beeRidableInWater); -+ beeRequireShiftToMount = getBoolean("mobs.bee.require-shift-to-mount", beeRequireShiftToMount); -+ beeMaxY = getDouble("mobs.bee.ridable-max-y", beeMaxY); -+ } -+ -+ public boolean blazeRidable = false; -+ public boolean blazeRidableInWater = false; -+ public boolean blazeRequireShiftToMount = true; -+ public double blazeMaxY = 256D; -+ private void blazeSettings() { -+ blazeRidable = getBoolean("mobs.blaze.ridable", blazeRidable); -+ blazeRidableInWater = getBoolean("mobs.blaze.ridable-in-water", blazeRidableInWater); -+ blazeRequireShiftToMount = getBoolean("mobs.blaze.require-shift-to-mount", blazeRequireShiftToMount); -+ blazeMaxY = getDouble("mobs.blaze.ridable-max-y", blazeMaxY); -+ } -+ -+ public boolean catRidable = false; -+ public boolean catRidableInWater = false; -+ public boolean catRequireShiftToMount = true; -+ private void catSettings() { -+ catRidable = getBoolean("mobs.cat.ridable", catRidable); -+ catRidableInWater = getBoolean("mobs.cat.ridable-in-water", catRidableInWater); -+ catRequireShiftToMount = getBoolean("mobs.cat.require-shift-to-mount", catRequireShiftToMount); -+ } -+ -+ public boolean caveSpiderRidable = false; -+ public boolean caveSpiderRidableInWater = false; -+ public boolean caveSpiderRequireShiftToMount = true; -+ private void caveSpiderSettings() { -+ caveSpiderRidable = getBoolean("mobs.cave_spider.ridable", caveSpiderRidable); -+ caveSpiderRidableInWater = getBoolean("mobs.cave_spider.ridable-in-water", caveSpiderRidableInWater); -+ caveSpiderRequireShiftToMount = getBoolean("mobs.cave_spider.require-shift-to-mount", caveSpiderRequireShiftToMount); -+ } -+ -+ public boolean chickenRidable = false; -+ public boolean chickenRidableInWater = false; -+ public boolean chickenRequireShiftToMount = true; -+ public boolean chickenDontLayEggsWhenRidden = false; -+ private void chickenSettings() { -+ chickenRidable = getBoolean("mobs.chicken.ridable", chickenRidable); -+ chickenRidableInWater = getBoolean("mobs.chicken.ridable-in-water", chickenRidableInWater); -+ chickenRequireShiftToMount = getBoolean("mobs.chicken.require-shift-to-mount", chickenRequireShiftToMount); -+ chickenDontLayEggsWhenRidden = getBoolean("mobs.chicken.dont-lay-eggs-when-ridden", chickenDontLayEggsWhenRidden); -+ } -+ -+ public boolean codRidable = false; -+ public boolean codRidableInWater = false; -+ public boolean codRequireShiftToMount = true; -+ private void codSettings() { -+ codRidable = getBoolean("mobs.cod.ridable", codRidable); -+ codRidableInWater = getBoolean("mobs.cod.ridable-in-water", codRidableInWater); -+ codRequireShiftToMount = getBoolean("mobs.cod.require-shift-to-mount", codRequireShiftToMount); -+ } -+ -+ public boolean cowRidable = false; -+ public boolean cowRidableInWater = false; -+ public boolean cowRequireShiftToMount = true; -+ private void cowSettings() { -+ cowRidable = getBoolean("mobs.cow.ridable", cowRidable); -+ cowRidableInWater = getBoolean("mobs.cow.ridable-in-water", cowRidableInWater); -+ cowRequireShiftToMount = getBoolean("mobs.cow.require-shift-to-mount", cowRequireShiftToMount); -+ } -+ -+ public boolean creeperRidable = false; -+ public boolean creeperRidableInWater = false; -+ public boolean creeperRequireShiftToMount = true; -+ private void creeperSettings() { -+ creeperRidable = getBoolean("mobs.creeper.ridable", creeperRidable); -+ creeperRidableInWater = getBoolean("mobs.creeper.ridable-in-water", creeperRidableInWater); -+ creeperRequireShiftToMount = getBoolean("mobs.creeper.require-shift-to-mount", creeperRequireShiftToMount); -+ } -+ -+ public boolean dolphinRidable = false; -+ public boolean dolphinRidableInWater = false; -+ public boolean dolphinRequireShiftToMount = true; -+ public int dolphinSpitCooldown = 20; -+ public float dolphinSpitSpeed = 1.0F; -+ public float dolphinSpitDamage = 2.0F; -+ private void dolphinSettings() { -+ dolphinRidable = getBoolean("mobs.dolphin.ridable", dolphinRidable); -+ dolphinRidableInWater = getBoolean("mobs.dolphin.ridable-in-water", dolphinRidableInWater); -+ dolphinRequireShiftToMount = getBoolean("mobs.dolphin.require-shift-to-mount", dolphinRequireShiftToMount); -+ dolphinSpitCooldown = getInt("mobs.dolphin.spit.cooldown", dolphinSpitCooldown); -+ dolphinSpitSpeed = (float) getDouble("mobs.dolphin.spit.speed", dolphinSpitSpeed); -+ dolphinSpitDamage = (float) getDouble("mobs.dolphin.spit.damage", dolphinSpitDamage); -+ } -+ -+ public boolean donkeyRidableInWater = false; -+ private void donkeySettings() { -+ donkeyRidableInWater = getBoolean("mobs.donkey.ridable-in-water", donkeyRidableInWater); -+ } -+ -+ public boolean drownedRidable = false; -+ public boolean drownedRidableInWater = false; -+ public boolean drownedRequireShiftToMount = true; -+ private void drownedSettings() { -+ drownedRidable = getBoolean("mobs.drowned.ridable", drownedRidable); -+ drownedRidableInWater = getBoolean("mobs.drowned.ridable-in-water", drownedRidableInWater); -+ drownedRequireShiftToMount = getBoolean("mobs.drowned.require-shift-to-mount", drownedRequireShiftToMount); -+ } -+ -+ public boolean elderGuardianRidable = false; -+ public boolean elderGuardianRidableInWater = false; -+ public boolean elderGuardianRequireShiftToMount = true; -+ private void elderGuardianSettings() { -+ elderGuardianRidable = getBoolean("mobs.elder_guardian.ridable", elderGuardianRidable); -+ elderGuardianRidableInWater = getBoolean("mobs.elder_guardian.ridable-in-water", elderGuardianRidableInWater); -+ elderGuardianRequireShiftToMount = getBoolean("mobs.elder_guardian.require-shift-to-mount", elderGuardianRequireShiftToMount); -+ } -+ -+ public boolean enderDragonRidable = false; -+ public boolean enderDragonRidableInWater = false; -+ public boolean enderDragonRequireShiftToMount = true; -+ public double enderDragonMaxY = 256D; -+ private void enderDragonSettings() { -+ enderDragonRidable = getBoolean("mobs.ender_dragon.ridable", enderDragonRidable); -+ enderDragonRidableInWater = getBoolean("mobs.ender_dragon.ridable-in-water", enderDragonRidableInWater); -+ enderDragonRequireShiftToMount = getBoolean("mobs.ender_dragon.require-shift-to-mount", enderDragonRequireShiftToMount); -+ enderDragonMaxY = getDouble("mobs.ender_dragon.ridable-max-y", enderDragonMaxY); -+ } -+ -+ public boolean endermanRidable = false; -+ public boolean endermanRidableInWater = false; -+ public boolean endermanRequireShiftToMount = true; -+ private void endermanSettings() { -+ endermanRidable = getBoolean("mobs.enderman.ridable", endermanRidable); -+ endermanRidableInWater = getBoolean("mobs.enderman.ridable-in-water", endermanRidableInWater); -+ endermanRequireShiftToMount = getBoolean("mobs.enderman.require-shift-to-mount", endermanRequireShiftToMount); -+ } -+ -+ public boolean endermiteRidable = false; -+ public boolean endermiteRidableInWater = false; -+ public boolean endermiteRequireShiftToMount = true; -+ private void endermiteSettings() { -+ endermiteRidable = getBoolean("mobs.endermite.ridable", endermiteRidable); -+ endermiteRidableInWater = getBoolean("mobs.endermite.ridable-in-water", endermiteRidableInWater); -+ endermiteRequireShiftToMount = getBoolean("mobs.endermite.require-shift-to-mount", endermiteRequireShiftToMount); -+ } -+ -+ public boolean evokerRidable = false; -+ public boolean evokerRidableInWater = false; -+ public boolean evokerRequireShiftToMount = true; -+ private void evokerSettings() { -+ evokerRidable = getBoolean("mobs.evoker.ridable", evokerRidable); -+ evokerRidableInWater = getBoolean("mobs.evoker.ridable-in-water", evokerRidableInWater); -+ evokerRequireShiftToMount = getBoolean("mobs.evoker.require-shift-to-mount", evokerRequireShiftToMount); -+ } -+ -+ public boolean foxRidable = false; -+ public boolean foxRidableInWater = false; -+ public boolean foxRequireShiftToMount = true; -+ private void foxSettings() { -+ foxRidable = getBoolean("mobs.fox.ridable", foxRidable); -+ foxRidableInWater = getBoolean("mobs.fox.ridable-in-water", foxRidableInWater); -+ foxRequireShiftToMount = getBoolean("mobs.fox.require-shift-to-mount", foxRequireShiftToMount); -+ } -+ -+ public boolean ghastRidable = false; -+ public boolean ghastRidableInWater = false; -+ public boolean ghastRequireShiftToMount = true; -+ public double ghastMaxY = 256D; -+ private void ghastSettings() { -+ ghastRidable = getBoolean("mobs.ghast.ridable", ghastRidable); -+ ghastRidableInWater = getBoolean("mobs.ghast.ridable-in-water", ghastRidableInWater); -+ ghastRequireShiftToMount = getBoolean("mobs.ghast.require-shift-to-mount", ghastRequireShiftToMount); -+ ghastMaxY = getDouble("mobs.ghast.ridable-max-y", ghastMaxY); -+ } -+ -+ public boolean giantRidable = false; -+ public boolean giantRidableInWater = false; -+ public boolean giantRequireShiftToMount = true; -+ public float giantStepHeight = 2.0F; -+ public float giantJumpHeight = 1.0F; -+ private void giantSettings() { -+ giantRidable = getBoolean("mobs.giant.ridable", giantRidable); -+ giantRidableInWater = getBoolean("mobs.giant.ridable-in-water", giantRidableInWater); -+ giantRequireShiftToMount = getBoolean("mobs.giant.require-shift-to-mount", giantRequireShiftToMount); -+ giantStepHeight = (float) getDouble("mobs.giant.step-height", giantStepHeight); -+ giantJumpHeight = (float) getDouble("mobs.giant.jump-height", giantJumpHeight); -+ } -+ -+ public boolean guardianRidable = false; -+ public boolean guardianRidableInWater = false; -+ public boolean guardianRequireShiftToMount = true; -+ private void guardianSettings() { -+ guardianRidable = getBoolean("mobs.guardian.ridable", guardianRidable); -+ guardianRidableInWater = getBoolean("mobs.guardian.ridable-in-water", guardianRidableInWater); -+ guardianRequireShiftToMount = getBoolean("mobs.guardian.require-shift-to-mount", guardianRequireShiftToMount); -+ } -+ -+ public boolean huskRidable = false; -+ public boolean huskRidableInWater = false; -+ public boolean huskRequireShiftToMount = true; -+ private void huskSettings() { -+ huskRidable = getBoolean("mobs.husk.ridable", huskRidable); -+ huskRidableInWater = getBoolean("mobs.husk.ridable-in-water", huskRidableInWater); -+ huskRequireShiftToMount = getBoolean("mobs.husk.require-shift-to-mount", huskRequireShiftToMount); -+ } -+ -+ public boolean horseRidableInWater = false; -+ private void horseSettings() { -+ horseRidableInWater = getBoolean("mobs.horse.ridable-in-water", horseRidableInWater); -+ } -+ -+ public boolean illusionerRidable = false; -+ public boolean illusionerRidableInWater = false; -+ public boolean illusionerRequireShiftToMount = true; -+ private void illusionerSettings() { -+ illusionerRidable = getBoolean("mobs.illusioner.ridable", illusionerRidable); -+ illusionerRidableInWater = getBoolean("mobs.illusioner.ridable-in-water", illusionerRidableInWater); -+ illusionerRequireShiftToMount = getBoolean("mobs.illusioner.require-shift-to-mount", illusionerRequireShiftToMount); -+ } -+ -+ public boolean ironGolemRidable = false; -+ public boolean ironGolemRidableInWater = false; -+ public boolean ironGolemRequireShiftToMount = true; -+ private void ironGolemSettings() { -+ ironGolemRidable = getBoolean("mobs.iron_golem.ridable", ironGolemRidable); -+ ironGolemRidableInWater = getBoolean("mobs.iron_golem.ridable-in-water", ironGolemRidableInWater); -+ ironGolemRequireShiftToMount = getBoolean("mobs.iron_golem.require-shift-to-mount", ironGolemRequireShiftToMount); -+ } -+ -+ public boolean llamaRidable = false; -+ public boolean llamaRidableInWater = false; -+ private void llamaSettings() { -+ llamaRidable = getBoolean("mobs.llama.ridable", llamaRidable); -+ llamaRidableInWater = getBoolean("mobs.llama.ridable-in-water", llamaRidableInWater); -+ } -+ -+ public boolean llamaTraderRidable = false; -+ public boolean llamaTraderRidableInWater = false; -+ private void llamaTraderSettings() { -+ llamaTraderRidable = getBoolean("mobs.trader_llama.ridable", llamaTraderRidable); -+ llamaTraderRidableInWater = getBoolean("mobs.trader_llama.ridable-in-water", llamaTraderRidableInWater); -+ } -+ -+ public boolean magmaCubeRidable = false; -+ public boolean magmaCubeRidableInWater = false; -+ public boolean magmaCubeRequireShiftToMount = true; -+ private void magmaCubeSettings() { -+ magmaCubeRidable = getBoolean("mobs.magma_cube.ridable", magmaCubeRidable); -+ magmaCubeRidableInWater = getBoolean("mobs.magma_cube.ridable-in-water", magmaCubeRidableInWater); -+ magmaCubeRequireShiftToMount = getBoolean("mobs.magma_cube.require-shift-to-mount", magmaCubeRequireShiftToMount); -+ } -+ -+ public boolean mooshroomRidable = false; -+ public boolean mooshroomRidableInWater = false; -+ public boolean mooshroomRequireShiftToMount = true; -+ private void mooshroomSettings() { -+ mooshroomRidable = getBoolean("mobs.mooshroom.ridable", mooshroomRidable); -+ mooshroomRidableInWater = getBoolean("mobs.mooshroom.ridable-in-water", mooshroomRidableInWater); -+ mooshroomRequireShiftToMount = getBoolean("mobs.mooshroom.require-shift-to-mount", mooshroomRequireShiftToMount); -+ } -+ -+ public boolean muleRidableInWater = false; -+ private void muleSettings() { -+ muleRidableInWater = getBoolean("mobs.mule.ridable-in-water", muleRidableInWater); -+ } -+ -+ public boolean ocelotRidable = false; -+ public boolean ocelotRidableInWater = false; -+ public boolean ocelotRequireShiftToMount = true; -+ private void ocelotSettings() { -+ ocelotRidable = getBoolean("mobs.ocelot.ridable", ocelotRidable); -+ ocelotRidableInWater = getBoolean("mobs.ocelot.ridable-in-water", ocelotRidableInWater); -+ ocelotRequireShiftToMount = getBoolean("mobs.ocelot.require-shift-to-mount", ocelotRequireShiftToMount); -+ } -+ -+ public boolean pandaRidable = false; -+ public boolean pandaRidableInWater = false; -+ public boolean pandaRequireShiftToMount = true; -+ private void pandaSettings() { -+ pandaRidable = getBoolean("mobs.panda.ridable", pandaRidable); -+ pandaRidableInWater = getBoolean("mobs.panda.ridable-in-water", pandaRidableInWater); -+ pandaRequireShiftToMount = getBoolean("mobs.panda.require-shift-to-mount", pandaRequireShiftToMount); -+ } -+ -+ public boolean parrotRidable = false; -+ public boolean parrotRidableInWater = false; -+ public boolean parrotRequireShiftToMount = true; -+ public double parrotMaxY = 256D; -+ private void parrotSettings() { -+ parrotRidable = getBoolean("mobs.parrot.ridable", parrotRidable); -+ parrotRidableInWater = getBoolean("mobs.parrot.ridable-in-water", parrotRidableInWater); -+ parrotRequireShiftToMount = getBoolean("mobs.parrot.require-shift-to-mount", parrotRequireShiftToMount); -+ parrotMaxY = getDouble("mobs.parrot.ridable-max-y", parrotMaxY); -+ } -+ -+ public boolean phantomRidable = false; -+ public boolean phantomRidableInWater = false; -+ public boolean phantomRequireShiftToMount = true; -+ public double phantomMaxY = 256D; -+ public float phantomFlameDamage = 1.0F; -+ public int phantomFlameFireTime = 8; -+ private void phantomSettings() { -+ phantomRidable = getBoolean("mobs.phantom.ridable", phantomRidable); -+ phantomRidableInWater = getBoolean("mobs.phantom.ridable-in-water", phantomRidableInWater); -+ phantomRequireShiftToMount = getBoolean("mobs.phantom.require-shift-to-mount", phantomRequireShiftToMount); -+ phantomMaxY = getDouble("mobs.phantom.ridable-max-y", phantomMaxY); -+ phantomFlameDamage = (float) getDouble("mobs.phantom.flames.damage", phantomFlameDamage); -+ phantomFlameFireTime = getInt("mobs.phantom.flames.fire-time", phantomFlameFireTime); -+ } -+ -+ public boolean pigRidable = false; -+ public boolean pigRidableInWater = false; -+ private void pigSettings() { -+ pigRidable = getBoolean("mobs.pig.ridable", pigRidable); -+ pigRidableInWater = getBoolean("mobs.pig.ridable-in-water", pigRidableInWater); -+ } -+ -+ public boolean pillagerRidable = false; -+ public boolean pillagerRidableInWater = false; -+ public boolean pillagerRequireShiftToMount = true; -+ private void pillagerSettings() { -+ pillagerRidable = getBoolean("mobs.pillager.ridable", pillagerRidable); -+ pillagerRidableInWater = getBoolean("mobs.pillager.ridable-in-water", pillagerRidableInWater); -+ pillagerRequireShiftToMount = getBoolean("mobs.pillager.require-shift-to-mount", pillagerRequireShiftToMount); -+ } -+ -+ public boolean polarBearRidable = false; -+ public boolean polarBearRidableInWater = false; -+ public boolean polarBearRequireShiftToMount = true; -+ private void polarBearSettings() { -+ polarBearRidable = getBoolean("mobs.polar_bear.ridable", polarBearRidable); -+ polarBearRidableInWater = getBoolean("mobs.polar_bear.ridable-in-water", polarBearRidableInWater); -+ polarBearRequireShiftToMount = getBoolean("mobs.polar_bear.require-shift-to-mount", polarBearRequireShiftToMount); -+ } -+ -+ public boolean pufferfishRidable = false; -+ public boolean pufferfishRidableInWater = false; -+ public boolean pufferfishRequireShiftToMount = true; -+ private void pufferfishSettings() { -+ pufferfishRidable = getBoolean("mobs.pufferfish.ridable", pufferfishRidable); -+ pufferfishRidableInWater = getBoolean("mobs.pufferfish.ridable-in-water", pufferfishRidableInWater); -+ pufferfishRequireShiftToMount = getBoolean("mobs.pufferfish.require-shift-to-mount", pufferfishRequireShiftToMount); -+ } -+ -+ public boolean rabbitRidable = false; -+ public boolean rabbitRidableInWater = false; -+ public boolean rabbitRequireShiftToMount = true; -+ private void rabbitSettings() { -+ rabbitRidable = getBoolean("mobs.rabbit.ridable", rabbitRidable); -+ rabbitRidableInWater = getBoolean("mobs.rabbit.ridable-in-water", rabbitRidableInWater); -+ rabbitRequireShiftToMount = getBoolean("mobs.rabbit.require-shift-to-mount", rabbitRequireShiftToMount); -+ } -+ -+ public boolean ravagerRidable = false; -+ public boolean ravagerRidableInWater = false; -+ public boolean ravagerRequireShiftToMount = true; -+ private void ravagerSettings() { -+ ravagerRidable = getBoolean("mobs.ravager.ridable", ravagerRidable); -+ ravagerRidableInWater = getBoolean("mobs.ravager.ridable-in-water", ravagerRidableInWater); -+ ravagerRequireShiftToMount = getBoolean("mobs.ravager.require-shift-to-mount", ravagerRequireShiftToMount); -+ } -+ -+ public boolean salmonRidable = false; -+ public boolean salmonRidableInWater = false; -+ public boolean salmonRequireShiftToMount = true; -+ private void salmonSettings() { -+ salmonRidable = getBoolean("mobs.salmon.ridable", salmonRidable); -+ salmonRidableInWater = getBoolean("mobs.salmon.ridable-in-water", salmonRidableInWater); -+ salmonRequireShiftToMount = getBoolean("mobs.salmon.require-shift-to-mount", salmonRequireShiftToMount); -+ } -+ -+ public boolean sheepRidable = false; -+ public boolean sheepRidableInWater = false; -+ public boolean sheepRequireShiftToMount = true; -+ private void sheepSettings() { -+ sheepRidable = getBoolean("mobs.sheep.ridable", sheepRidable); -+ sheepRidableInWater = getBoolean("mobs.sheep.ridable-in-water", sheepRidableInWater); -+ sheepRequireShiftToMount = getBoolean("mobs.sheep.require-shift-to-mount", sheepRequireShiftToMount); -+ } -+ -+ public boolean shulkerRidable = false; -+ public boolean shulkerRidableInWater = false; -+ public boolean shulkerRequireShiftToMount = true; -+ private void shulkerSettings() { -+ shulkerRidable = getBoolean("mobs.shulker.ridable", shulkerRidable); -+ shulkerRidableInWater = getBoolean("mobs.shulker.ridable-in-water", shulkerRidableInWater); -+ shulkerRequireShiftToMount = getBoolean("mobs.shulker.require-shift-to-mount", shulkerRequireShiftToMount); -+ } -+ -+ public boolean silverfishRidable = false; -+ public boolean silverfishRidableInWater = false; -+ public boolean silverfishRequireShiftToMount = true; -+ private void silverfishSettings() { -+ silverfishRidable = getBoolean("mobs.silverfish.ridable", silverfishRidable); -+ silverfishRidableInWater = getBoolean("mobs.silverfish.ridable-in-water", silverfishRidableInWater); -+ silverfishRequireShiftToMount = getBoolean("mobs.silverfish.require-shift-to-mount", silverfishRequireShiftToMount); -+ } -+ -+ public boolean skeletonRidable = false; -+ public boolean skeletonRidableInWater = false; -+ public boolean skeletonRequireShiftToMount = true; -+ private void skeletonSettings() { -+ skeletonRidable = getBoolean("mobs.skeleton.ridable", skeletonRidable); -+ skeletonRidableInWater = getBoolean("mobs.skeleton.ridable-in-water", skeletonRidableInWater); -+ skeletonRequireShiftToMount = getBoolean("mobs.skeleton.require-shift-to-mount", skeletonRequireShiftToMount); -+ } -+ -+ public boolean skeletonHorseCanSwim = false; -+ public boolean skeletonHorseRidableInWater = true; -+ private void skeletonHorseSettings() { -+ skeletonHorseCanSwim = getBoolean("mobs.skeleton_horse.can-swim", skeletonHorseCanSwim); -+ skeletonHorseRidableInWater = getBoolean("mobs.skeleton_horse.ridable-in-water", skeletonHorseRidableInWater); -+ } -+ -+ public boolean slimeRidable = false; -+ public boolean slimeRidableInWater = false; -+ public boolean slimeRequireShiftToMount = true; -+ private void slimeSettings() { -+ slimeRidable = getBoolean("mobs.slime.ridable", slimeRidable); -+ slimeRidableInWater = getBoolean("mobs.slime.ridable-in-water", slimeRidableInWater); -+ slimeRequireShiftToMount = getBoolean("mobs.slime.require-shift-to-mount", slimeRequireShiftToMount); -+ } -+ -+ public boolean snowGolemRidable = false; -+ public boolean snowGolemRidableInWater = false; -+ public boolean snowGolemRequireShiftToMount = true; -+ public boolean snowGolemLeaveTrailWhenRidden = false; -+ private void snowGolemSettings() { -+ snowGolemRidable = getBoolean("mobs.snow_golem.ridable", snowGolemRidable); -+ snowGolemRidableInWater = getBoolean("mobs.snow_golem.ridable-in-water", snowGolemRidableInWater); -+ snowGolemRequireShiftToMount = getBoolean("mobs.snow_golem.require-shift-to-mount", snowGolemRequireShiftToMount); -+ snowGolemLeaveTrailWhenRidden = getBoolean("mobs.snow_golem.leave-trail-when-ridden", snowGolemLeaveTrailWhenRidden); -+ } -+ -+ public boolean spiderRidable = false; -+ public boolean spiderRidableInWater = false; -+ public boolean spiderRequireShiftToMount = true; -+ private void spiderSettings() { -+ spiderRidable = getBoolean("mobs.spider.ridable", spiderRidable); -+ spiderRidableInWater = getBoolean("mobs.spider.ridable-in-water", spiderRidableInWater); -+ spiderRequireShiftToMount = getBoolean("mobs.spider.require-shift-to-mount", spiderRequireShiftToMount); -+ } -+ -+ public boolean squidRidable = false; -+ public boolean squidRidableInWater = false; -+ public boolean squidRequireShiftToMount = true; -+ private void squidSettings() { -+ squidRidable = getBoolean("mobs.squid.ridable", squidRidable); -+ squidRidableInWater = getBoolean("mobs.squid.ridable-in-water", squidRidableInWater); -+ squidRequireShiftToMount = getBoolean("mobs.squid.require-shift-to-mount", squidRequireShiftToMount); -+ } -+ -+ public boolean strayRidable = false; -+ public boolean strayRidableInWater = false; -+ public boolean strayRequireShiftToMount = true; -+ private void straySettings() { -+ strayRidable = getBoolean("mobs.stray.ridable", strayRidable); -+ strayRidableInWater = getBoolean("mobs.stray.ridable-in-water", strayRidableInWater); -+ strayRequireShiftToMount = getBoolean("mobs.stray.require-shift-to-mount", strayRequireShiftToMount); -+ } -+ -+ public boolean tropicalFishRidable = false; -+ public boolean tropicalFishRidableInWater = false; -+ public boolean tropicalFishRequireShiftToMount = true; -+ private void tropicalFishSettings() { -+ tropicalFishRidable = getBoolean("mobs.tropical_fish.ridable", tropicalFishRidable); -+ tropicalFishRidableInWater = getBoolean("mobs.tropical_fish.ridable-in-water", tropicalFishRidableInWater); -+ tropicalFishRequireShiftToMount = getBoolean("mobs.tropical_fish.require-shift-to-mount", tropicalFishRequireShiftToMount); -+ } -+ -+ public boolean turtleRidable = false; -+ public boolean turtleRidableInWater = false; -+ public boolean turtleRequireShiftToMount = true; -+ private void turtleSettings() { -+ turtleRidable = getBoolean("mobs.turtle.ridable", turtleRidable); -+ turtleRidableInWater = getBoolean("mobs.turtle.ridable-in-water", turtleRidableInWater); -+ turtleRequireShiftToMount = getBoolean("mobs.turtle.require-shift-to-mount", turtleRequireShiftToMount); -+ } -+ -+ public boolean vexRidable = false; -+ public boolean vexRidableInWater = false; -+ public boolean vexRequireShiftToMount = true; -+ public double vexMaxY = 256D; -+ private void vexSettings() { -+ vexRidable = getBoolean("mobs.vex.ridable", vexRidable); -+ vexRidableInWater = getBoolean("mobs.vex.ridable-in-water", vexRidableInWater); -+ vexRequireShiftToMount = getBoolean("mobs.vex.require-shift-to-mount", vexRequireShiftToMount); -+ vexMaxY = getDouble("mobs.vex.ridable-max-y", vexMaxY); -+ } -+ -+ public boolean villagerRidable = false; -+ public boolean villagerRidableInWater = false; -+ public boolean villagerRequireShiftToMount = true; -+ private void villagerSettings() { -+ villagerRidable = getBoolean("mobs.villager.ridable", villagerRidable); -+ villagerRidableInWater = getBoolean("mobs.villager.ridable-in-water", villagerRidableInWater); -+ villagerRequireShiftToMount = getBoolean("mobs.villager.require-shift-to-mount", villagerRequireShiftToMount); -+ } -+ -+ public boolean villagerTraderRidable = false; -+ public boolean villagerTraderRidableInWater = false; -+ public boolean villagerTraderRequireShiftToMount = true; -+ private void villagerTraderSettings() { -+ villagerTraderRidable = getBoolean("mobs.wandering_trader.ridable", villagerTraderRidable); -+ villagerTraderRidableInWater = getBoolean("mobs.wandering_trader.ridable-in-water", villagerTraderRidableInWater); -+ villagerTraderRequireShiftToMount = getBoolean("mobs.wandering_trader.require-shift-to-mount", villagerTraderRequireShiftToMount); -+ } -+ -+ public boolean vindicatorRidable = false; -+ public boolean vindicatorRidableInWater = false; -+ public boolean vindicatorRequireShiftToMount = true; -+ private void vindicatorSettings() { -+ vindicatorRidable = getBoolean("mobs.vindicator.ridable", vindicatorRidable); -+ vindicatorRidableInWater = getBoolean("mobs.vindicator.ridable-in-water", vindicatorRidableInWater); -+ vindicatorRequireShiftToMount = getBoolean("mobs.vindicator.require-shift-to-mount", vindicatorRequireShiftToMount); -+ } -+ -+ public boolean witchRidable = false; -+ public boolean witchRidableInWater = false; -+ public boolean witchRequireShiftToMount = true; -+ private void witchSettings() { -+ witchRidable = getBoolean("mobs.witch.ridable", witchRidable); -+ witchRidableInWater = getBoolean("mobs.witch.ridable-in-water", witchRidableInWater); -+ witchRequireShiftToMount = getBoolean("mobs.witch.require-shift-to-mount", witchRequireShiftToMount); -+ } -+ -+ public boolean witherRidable = false; -+ public boolean witherRidableInWater = false; -+ public boolean witherRequireShiftToMount = true; -+ public double witherMaxY = 256D; -+ private void witherSettings() { -+ witherRidable = getBoolean("mobs.wither.ridable", witherRidable); -+ witherRidableInWater = getBoolean("mobs.wither.ridable-in-water", witherRidableInWater); -+ witherRequireShiftToMount = getBoolean("mobs.wither.require-shift-to-mount", witherRequireShiftToMount); -+ witherMaxY = getDouble("mobs.wither.ridable-max-y", witherMaxY); -+ } -+ -+ public boolean witherSkeletonRidable = false; -+ public boolean witherSkeletonRidableInWater = false; -+ public boolean witherSkeletonRequireShiftToMount = true; -+ private void witherSkeletonSettings() { -+ witherSkeletonRidable = getBoolean("mobs.wither_skeleton.ridable", witherSkeletonRidable); -+ witherSkeletonRidableInWater = getBoolean("mobs.wither_skeleton.ridable-in-water", witherSkeletonRidableInWater); -+ witherSkeletonRequireShiftToMount = getBoolean("mobs.wither_skeleton.require-shift-to-mount", witherSkeletonRequireShiftToMount); -+ } -+ -+ public boolean wolfRidable = false; -+ public boolean wolfRidableInWater = false; -+ public boolean wolfRequireShiftToMount = true; -+ private void wolfSettings() { -+ wolfRidable = getBoolean("mobs.wolf.ridable", wolfRidable); -+ wolfRidableInWater = getBoolean("mobs.wolf.ridable-in-water", wolfRidableInWater); -+ wolfRequireShiftToMount = getBoolean("mobs.wolf.require-shift-to-mount", wolfRequireShiftToMount); -+ } -+ -+ public boolean zombieRidable = false; -+ public boolean zombieRidableInWater = false; -+ public boolean zombieRequireShiftToMount = true; -+ private void zombieSettings() { -+ zombieRidable = getBoolean("mobs.zombie.ridable", zombieRidable); -+ zombieRidableInWater = getBoolean("mobs.zombie.ridable-in-water", zombieRidableInWater); -+ zombieRequireShiftToMount = getBoolean("mobs.zombie.require-shift-to-mount", zombieRequireShiftToMount); -+ } -+ -+ public boolean zombieHorseCanSwim = false; -+ public boolean zombieHorseRidableInWater = false; -+ private void zombieHorseSettings() { -+ zombieHorseCanSwim = getBoolean("mobs.zombie_horse.can-swim", zombieHorseCanSwim); -+ zombieHorseRidableInWater = getBoolean("mobs.zombie_horse.ridable-in-water", zombieHorseRidableInWater); -+ } -+ -+ public boolean zombiePigmanRidable = false; -+ public boolean zombiePigmanRidableInWater = false; -+ public boolean zombiePigmanRequireShiftToMount = true; -+ private void zombiePigmanSettings() { -+ zombiePigmanRidable = getBoolean("mobs.zombie_pigman.ridable", zombiePigmanRidable); -+ zombiePigmanRidableInWater = getBoolean("mobs.zombie_pigman.ridable-in-water", zombiePigmanRidableInWater); -+ zombiePigmanRequireShiftToMount = getBoolean("mobs.zombie_pigman.require-shift-to-mount", zombiePigmanRequireShiftToMount); -+ } -+ -+ public boolean zombieVillagerRidable = false; -+ public boolean zombieVillagerRidableInWater = false; -+ public boolean zombieVillagerRequireShiftToMount = true; -+ private void zombieVillagerSettings() { -+ zombieVillagerRidable = getBoolean("mobs.zombie_villager.ridable", zombieVillagerRidable); -+ zombieVillagerRidableInWater = getBoolean("mobs.zombie_villager.ridable-in-water", zombieVillagerRidableInWater); -+ zombieVillagerRequireShiftToMount = getBoolean("mobs.zombie_villager.require-shift-to-mount", zombieVillagerRequireShiftToMount); -+ } - } -diff --git a/src/main/java/net/pl3x/purpur/controller/ControllerLookWASD.java b/src/main/java/net/pl3x/purpur/controller/ControllerLookWASD.java -new file mode 100644 -index 000000000..828e1b873 ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/controller/ControllerLookWASD.java -@@ -0,0 +1,75 @@ -+package net.pl3x.purpur.controller; -+ -+import net.minecraft.server.ControllerLook; -+import net.minecraft.server.EntityHuman; -+import net.minecraft.server.EntityInsentient; -+import net.minecraft.server.MathHelper; -+import net.minecraft.server.PacketPlayOutEntity; -+ -+public class ControllerLookWASD extends ControllerLook { -+ protected final EntityInsentient entity; -+ private float yawOffset = 0; -+ private float pitchOffset = 0; -+ -+ public ControllerLookWASD(EntityInsentient entity) { -+ super(entity); -+ this.entity = entity; -+ } -+ -+ // tick -+ @Override -+ public void a() { -+ if (entity.hasRider()) { -+ tick(entity.getRider()); -+ } else { -+ tick(); -+ } -+ } -+ -+ protected void tick() { -+ super.a(); // tick -+ } -+ -+ protected void tick(EntityHuman rider) { -+ setYawPitch(rider.yaw, rider.pitch); -+ } -+ -+ public void setYawPitch(float yaw, float pitch) { -+ entity.yaw = normalizeYaw(yaw + yawOffset); -+ entity.lastYaw = entity.yaw; -+ entity.setBodyYaw(entity.yaw); -+ entity.setHeadRotation(entity.yaw); -+ entity.pitch = normalizePitch(pitch + pitchOffset); -+ -+ entity.getTracker().broadcast(new PacketPlayOutEntity -+ .PacketPlayOutRelEntityMoveLook(entity.getId(), -+ (short) 0, (short) 0, (short) 0, -+ (byte) MathHelper.d(entity.yaw * 256.0F / 360.0F), -+ (byte) MathHelper.d(entity.pitch * 256.0F / 360.0F), -+ entity.onGround)); -+ } -+ -+ public void setOffsets(float yaw, float pitch) { -+ yawOffset = yaw; -+ pitchOffset = pitch; -+ } -+ -+ public float normalizeYaw(float yaw) { -+ yaw %= 360.0f; -+ if (yaw >= 180.0f) { -+ yaw -= 360.0f; -+ } else if (yaw < -180.0f) { -+ yaw += 360.0f; -+ } -+ return yaw; -+ } -+ -+ public float normalizePitch(float pitch) { -+ if (pitch > 90.0f) { -+ pitch = 90.0f; -+ } else if (pitch < -90.0f) { -+ pitch = -90.0f; -+ } -+ return pitch; -+ } -+} -diff --git a/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASD.java b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASD.java -new file mode 100644 -index 000000000..0a5d6d46c ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASD.java -@@ -0,0 +1,86 @@ -+package net.pl3x.purpur.controller; -+ -+import net.minecraft.server.ControllerMove; -+import net.minecraft.server.Entity; -+import net.minecraft.server.EntityHuman; -+import net.minecraft.server.EntityInsentient; -+import net.minecraft.server.GenericAttributes; -+import net.pl3x.purpur.event.entity.RidableSpacebarEvent; -+ -+public class ControllerMoveWASD extends ControllerMove { -+ protected final EntityInsentient entity; -+ -+ public ControllerMoveWASD(EntityInsentient entity) { -+ super(entity); -+ this.entity = entity; -+ } -+ -+ // isUpdating -+ @Override -+ public boolean b() { -+ return entity.hasRider() ? getForward() != 0 || getStrafe() != 0 : super.b(); -+ } -+ -+ // tick -+ @Override -+ public void a() { -+ if (entity.hasRider()) { -+ tick(entity.getRider()); -+ } else { -+ tick(); -+ } -+ } -+ -+ protected void tick() { -+ super.a(); // tick -+ } -+ -+ protected void tick(EntityHuman rider) { -+ float forward = rider.getForward() * 0.5F; -+ float strafe = rider.getStrafe() * 0.25F; -+ -+ if (forward <= 0.0F) { -+ forward *= 0.5F; -+ } -+ -+ float yawOffset = 0; -+ if (strafe != 0) { -+ if (forward == 0) { -+ yawOffset += strafe > 0 ? -90 : 90; -+ forward = Math.abs(strafe * 2); -+ } else { -+ yawOffset += strafe > 0 ? -30 : 30; -+ strafe /= 2; -+ if (forward < 0) { -+ yawOffset += strafe > 0 ? -110 : 110; -+ forward *= -1; -+ } -+ } -+ } else if (forward < 0) { -+ yawOffset -= 180; -+ forward *= -1; -+ } -+ -+ ((ControllerLookWASD) entity.getControllerLook()).setOffsets(yawOffset, 0); -+ -+ if (rider.jumping && spacebarEvent(entity) && !entity.onSpacebar() && entity.onGround) { -+ entity.doJump(); -+ } -+ -+ setSpeed(entity.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue()); -+ -+ entity.setSpeed((float) getSpeed()); -+ entity.setForward(forward); -+ -+ setForward(entity.getForward()); -+ setStrafe(entity.getStrafe()); -+ } -+ -+ public static boolean spacebarEvent(Entity entity) { -+ if (RidableSpacebarEvent.getHandlerList().getRegisteredListeners().length > 0) { -+ return new RidableSpacebarEvent(entity.getBukkitEntity()).callEvent(); -+ } else { -+ return true; -+ } -+ } -+} -diff --git a/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlying.java b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlying.java -new file mode 100644 -index 000000000..349125070 ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlying.java -@@ -0,0 +1,53 @@ -+package net.pl3x.purpur.controller; -+ -+import net.minecraft.server.EntityHuman; -+import net.minecraft.server.EntityInsentient; -+import net.minecraft.server.GenericAttributes; -+ -+public class ControllerMoveWASDFlying extends ControllerMoveWASD { -+ protected final float groundSpeedModifier; -+ protected int tooHighCooldown = 0; -+ -+ public ControllerMoveWASDFlying(EntityInsentient entity) { -+ this(entity, 1.0F); -+ } -+ -+ public ControllerMoveWASDFlying(EntityInsentient entity, float groundSpeedModifier) { -+ super(entity); -+ this.groundSpeedModifier = groundSpeedModifier; -+ } -+ -+ @Override -+ public void tick(EntityHuman rider) { -+ float forward = Math.max(0.0F, rider.getForward()); -+ float vertical = forward == 0.0F ? 0.0F : -(rider.pitch / 45.0F); -+ float strafe = rider.getStrafe(); -+ -+ if (rider.jumping && spacebarEvent(entity)) { -+ entity.onSpacebar(); -+ } -+ -+ if (entity.locY() >= entity.getMaxY() || --tooHighCooldown > 0) { -+ tooHighCooldown = 60; -+ entity.setMot(entity.getMot().add(0.0D, -0.05D, 0.0D)); -+ vertical = 0.0F; -+ } -+ -+ setSpeed(entity.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue()); -+ float speed = (float) getSpeed(); -+ -+ if (entity.onGround) { -+ speed *= groundSpeedModifier; // TODO = fix this! -+ } -+ -+ entity.setNoGravity(forward > 0); -+ -+ entity.setSpeed(speed); -+ entity.setVertical(vertical); -+ entity.setStrafe(strafe); -+ entity.setForward(forward); -+ -+ setForward(entity.getForward()); -+ setStrafe(entity.getStrafe()); -+ } -+} -diff --git a/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlyingWithSpacebar.java b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlyingWithSpacebar.java -new file mode 100644 -index 000000000..f75375936 ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlyingWithSpacebar.java -@@ -0,0 +1,61 @@ -+package net.pl3x.purpur.controller; -+ -+import net.minecraft.server.EntityHuman; -+import net.minecraft.server.EntityInsentient; -+import net.minecraft.server.GenericAttributes; -+import net.minecraft.server.Vec3D; -+ -+public class ControllerMoveWASDFlyingWithSpacebar extends ControllerMoveWASDFlying { -+ public ControllerMoveWASDFlyingWithSpacebar(EntityInsentient entity) { -+ super(entity); -+ } -+ -+ public ControllerMoveWASDFlyingWithSpacebar(EntityInsentient entity, float groundSpeedModifier) { -+ super(entity, groundSpeedModifier); -+ } -+ -+ @Override -+ public void tick(EntityHuman rider) { -+ float forward = rider.getForward(); -+ float strafe = rider.getStrafe() * 0.5F; -+ float vertical = 0; -+ -+ if (forward < 0.0F) { -+ forward *= 0.5F; -+ strafe *= 0.5F; -+ } -+ -+ float speed = (float) entity.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue(); -+ -+ if (entity.onGround) { -+ speed *= groundSpeedModifier; -+ } -+ -+ if (rider.jumping && spacebarEvent(entity) && !entity.onSpacebar()) { -+ entity.setNoGravity(true); -+ vertical = 1.0F; -+ } else { -+ entity.setNoGravity(false); -+ } -+ -+ if (entity.locY() >= entity.getMaxY() || --tooHighCooldown > 0) { -+ tooHighCooldown = 60; -+ entity.setMot(entity.getMot().add(0.0D, -0.2D, 0.0D)); -+ vertical = 0.0F; -+ } -+ -+ setSpeed(speed); -+ entity.setSpeed((float) getSpeed()); -+ entity.setVertical(vertical); -+ entity.setStrafe(strafe); -+ entity.setForward(forward); -+ -+ setForward(entity.getForward()); -+ setStrafe(entity.getStrafe()); -+ -+ Vec3D mot = entity.getMot(); -+ if (mot.y > 0.2D) { -+ entity.setMot(mot.x, 0.2D, mot.z); -+ } -+ } -+} -diff --git a/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDWater.java b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDWater.java -new file mode 100644 -index 000000000..e75e58067 ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDWater.java -@@ -0,0 +1,43 @@ -+package net.pl3x.purpur.controller; -+ -+import net.minecraft.server.EntityHuman; -+import net.minecraft.server.EntityInsentient; -+import net.minecraft.server.GenericAttributes; -+ -+public class ControllerMoveWASDWater extends ControllerMoveWASD { -+ public ControllerMoveWASDWater(EntityInsentient entity) { -+ super(entity); -+ } -+ -+ @Override -+ protected void tick(EntityHuman rider) { -+ float forward = rider.getForward(); -+ float strafe = rider.getStrafe() * 0.5F; // strafe slower by default -+ float vertical = -(rider.pitch / 90); -+ -+ if (forward == 0.0F) { -+ // strafe slower if not moving forward -+ strafe *= 0.5F; -+ // do not move vertically if not moving forward -+ vertical = 0.0F; -+ } else if (forward < 0.0F) { -+ // water animals can't swim backwards -+ forward = 0.0F; -+ vertical = 0.0F; -+ } -+ -+ if (rider.jumping && spacebarEvent(entity)) { -+ entity.onSpacebar(); -+ } -+ -+ setSpeed(entity.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue()); -+ entity.setSpeed((float) getSpeed() * 0.1F); -+ -+ entity.setForward(forward); -+ entity.setStrafe(strafe); -+ entity.setVertical(vertical); -+ -+ setForward(entity.getForward()); -+ setStrafe(entity.getStrafe()); -+ } -+} -diff --git a/src/main/java/net/pl3x/purpur/entity/DolphinSpit.java b/src/main/java/net/pl3x/purpur/entity/DolphinSpit.java -new file mode 100644 -index 000000000..7189cc569 ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/entity/DolphinSpit.java -@@ -0,0 +1,119 @@ -+package net.pl3x.purpur.entity; -+ -+import net.minecraft.server.DamageSource; -+import net.minecraft.server.Entity; -+import net.minecraft.server.EntityDolphin; -+import net.minecraft.server.EntityLiving; -+import net.minecraft.server.EntityLlamaSpit; -+import net.minecraft.server.EntityTypes; -+import net.minecraft.server.IProjectile; -+import net.minecraft.server.Material; -+import net.minecraft.server.MathHelper; -+import net.minecraft.server.MovingObjectPosition; -+import net.minecraft.server.MovingObjectPositionEntity; -+import net.minecraft.server.NBTTagCompound; -+import net.minecraft.server.Packet; -+import net.minecraft.server.PacketPlayOutSpawnEntity; -+import net.minecraft.server.Particles; -+import net.minecraft.server.ProjectileHelper; -+import net.minecraft.server.RayTrace; -+import net.minecraft.server.Vec3D; -+import net.minecraft.server.World; -+import net.minecraft.server.WorldServer; -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+ -+public class DolphinSpit extends EntityLlamaSpit implements IProjectile { -+ public EntityLiving dolphin; -+ public int ticksLived; -+ -+ public DolphinSpit(EntityTypes entitytypes, World world) { -+ super(entitytypes, world); -+ } -+ -+ public DolphinSpit(World world, EntityDolphin dolphin) { -+ this(EntityTypes.LLAMA_SPIT, world); -+ this.dolphin = dolphin; -+ -+ setPosition(dolphin.locX() - (double) (dolphin.getWidth() + 1.0F) * 0.5D * (double) MathHelper.sin(dolphin.getBodyRotation() * ((float) Math.PI / 180F)), dolphin.getHeadY() - (double) 0.1F, dolphin.locZ() + (double) (dolphin.getWidth() + 1.0F) * 0.5D * (double) MathHelper.cos(dolphin.getBodyRotation() * ((float) Math.PI / 180F))); -+ } -+ -+ @Override -+ public boolean canSaveToDisk() { -+ return false; -+ } -+ -+ @Override -+ public void tick() { -+ setFlag(6, isGlowing()); -+ entityBaseTick(); -+ -+ Vec3D mot = getMot(); -+ -+ MovingObjectPosition hitResult = ProjectileHelper.getHitResult(this, getBoundingBox().expandTowards(mot).expand(1.0D), (entity) -> !entity.isSpectator() && entity != dolphin && entity != dolphin.getRider(), RayTrace.BlockCollisionOption.OUTLINE, true); -+ if (hitResult != null) { -+ onHit(hitResult); -+ } -+ -+ mot = mot.scale(0.99F); -+ setMot(mot); -+ setPosition(locX() + mot.x, locY() + mot.y, locZ() + mot.z); -+ -+ for (int i = 0; i < 5; i++) { -+ ((WorldServer) world).sendParticles(null, Particles.BUBBLE, -+ locX() + random.nextFloat() / 2 - 0.25F, -+ locY() + random.nextFloat() / 2 - 0.25F, -+ locZ() + random.nextFloat() / 2 - 0.25F, -+ 1, 0, 0, 0, 0, true); -+ } -+ -+ if (++ticksLived > 20) { -+ die(); -+ } -+ } -+ -+ @Override -+ public void shoot(double x, double y, double z, float speed, float inaccuracy) { -+ setMot(new Vec3D(x, y, z).normalize().add( -+ random.nextGaussian() * (double) 0.0075F * (double) inaccuracy, -+ random.nextGaussian() * (double) 0.0075F * (double) inaccuracy, -+ random.nextGaussian() * (double) 0.0075F * (double) inaccuracy) -+ .scale(speed)); -+ } -+ -+ public void onHit(MovingObjectPosition rayTrace) { -+ CraftEventFactory.callProjectileHitEvent(this, rayTrace); -+ -+ switch (rayTrace.getType()) { -+ case BLOCK: -+ die(); -+ break; -+ case ENTITY: -+ if (dolphin != null) { -+ Entity entity = ((MovingObjectPositionEntity) rayTrace).getEntity(); -+ entity.damageEntity(DamageSource.indirectMobAttack(this, dolphin).setProjectile(), world.purpurConfig.dolphinSpitDamage); -+ } -+ die(); -+ } -+ } -+ -+ @Override -+ public void a(MovingObjectPosition movingobjectposition) { -+ } -+ -+ @Override -+ protected void initDatawatcher() { -+ } -+ -+ @Override -+ protected void a(NBTTagCompound nbttagcompound) { -+ } -+ -+ @Override -+ protected void b(NBTTagCompound nbttagcompound) { -+ } -+ -+ @Override -+ public Packet L() { -+ return new PacketPlayOutSpawnEntity(this); -+ } -+} -diff --git a/src/main/java/net/pl3x/purpur/entity/PhantomFlames.java b/src/main/java/net/pl3x/purpur/entity/PhantomFlames.java -new file mode 100644 -index 000000000..f9e680efd ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/entity/PhantomFlames.java -@@ -0,0 +1,126 @@ -+package net.pl3x.purpur.entity; -+ -+import net.minecraft.server.DamageSource; -+import net.minecraft.server.Entity; -+import net.minecraft.server.EntityLiving; -+import net.minecraft.server.EntityLlamaSpit; -+import net.minecraft.server.EntityPhantom; -+import net.minecraft.server.EntityTypes; -+import net.minecraft.server.IProjectile; -+import net.minecraft.server.Material; -+import net.minecraft.server.MathHelper; -+import net.minecraft.server.MovingObjectPosition; -+import net.minecraft.server.MovingObjectPositionEntity; -+import net.minecraft.server.NBTTagCompound; -+import net.minecraft.server.Packet; -+import net.minecraft.server.PacketPlayOutSpawnEntity; -+import net.minecraft.server.Particles; -+import net.minecraft.server.ProjectileHelper; -+import net.minecraft.server.RayTrace; -+import net.minecraft.server.Vec3D; -+import net.minecraft.server.World; -+import net.minecraft.server.WorldServer; -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+ -+public class PhantomFlames extends EntityLlamaSpit implements IProjectile { -+ public EntityLiving phantom; -+ public int ticksLived; -+ -+ public PhantomFlames(EntityTypes entitytypes, World world) { -+ super(entitytypes, world); -+ } -+ -+ public PhantomFlames(World world, EntityPhantom phantom) { -+ this(EntityTypes.LLAMA_SPIT, world); -+ this.phantom = phantom; -+ -+ setPosition(phantom.locX() - (double) (phantom.getWidth() + 1.0F) * 0.5D * (double) MathHelper.sin(phantom.getBodyRotation() * ((float) Math.PI / 180F)), phantom.getHeadY() - (double) 0.1F, phantom.locZ() + (double) (phantom.getWidth() + 1.0F) * 0.5D * (double) MathHelper.cos(phantom.getBodyRotation() * ((float) Math.PI / 180F))); -+ } -+ -+ @Override -+ public boolean canSaveToDisk() { -+ return false; -+ } -+ -+ @Override -+ public void tick() { -+ setFlag(6, isGlowing()); -+ entityBaseTick(); -+ -+ Vec3D mot = getMot(); -+ -+ MovingObjectPosition hitResult = ProjectileHelper.getHitResult(this, getBoundingBox().expandTowards(mot).expand(1.0D), (entity) -> !entity.isSpectator() && entity != phantom && entity != phantom.getRider(), RayTrace.BlockCollisionOption.OUTLINE, true); -+ if (hitResult != null) { -+ onHit(hitResult); -+ } -+ -+ mot = mot.scale(0.99F); -+ setMot(mot); -+ setPosition(locX() + mot.x, locY() + mot.y, locZ() + mot.z); -+ -+ Vec3D m = mot.scale(2.0); -+ for (int i = 0; i < 5; i++) { -+ ((WorldServer) world).sendParticles(null, Particles.FLAME, -+ locX() + random.nextFloat() / 2 - 0.25F, -+ locY() + random.nextFloat() / 2 - 0.25F, -+ locZ() + random.nextFloat() / 2 - 0.25F, -+ 0, m.getX(), m.getY(), m.getZ(), 0.1, true); -+ } -+ -+ if (!world.containsMaterial(getBoundingBox(), Material.AIR)) { -+ die(); -+ } -+ if (++ticksLived > 20) { -+ die(); -+ } -+ } -+ -+ @Override -+ public void shoot(double x, double y, double z, float speed, float inaccuracy) { -+ setMot(new Vec3D(x, y, z).normalize().add( -+ random.nextGaussian() * (double) 0.0075F * (double) inaccuracy, -+ random.nextGaussian() * (double) 0.0075F * (double) inaccuracy, -+ random.nextGaussian() * (double) 0.0075F * (double) inaccuracy) -+ .scale(speed)); -+ } -+ -+ public void onHit(MovingObjectPosition rayTrace) { -+ CraftEventFactory.callProjectileHitEvent(this, rayTrace); -+ -+ switch (rayTrace.getType()) { -+ case BLOCK: -+ die(); -+ break; -+ case ENTITY: -+ if (phantom != null) { -+ Entity entity = ((MovingObjectPositionEntity) rayTrace).getEntity(); -+ entity.damageEntity(DamageSource.indirectMobAttack(this, phantom).setProjectile(), world.purpurConfig.phantomFlameDamage); -+ if (world.purpurConfig.phantomFlameFireTime > 0) { -+ entity.setOnFire(world.purpurConfig.phantomFlameFireTime); -+ } -+ } -+ die(); -+ } -+ } -+ -+ @Override -+ public void a(MovingObjectPosition movingobjectposition) { -+ } -+ -+ @Override -+ protected void initDatawatcher() { -+ } -+ -+ @Override -+ protected void a(NBTTagCompound nbttagcompound) { -+ } -+ -+ @Override -+ protected void b(NBTTagCompound nbttagcompound) { -+ } -+ -+ @Override -+ public Packet L() { -+ return new PacketPlayOutSpawnEntity(this); -+ } -+} -diff --git a/src/main/java/net/pl3x/purpur/pathfinder/PathfinderGoalHasRider.java b/src/main/java/net/pl3x/purpur/pathfinder/PathfinderGoalHasRider.java -new file mode 100644 -index 000000000..6e50344c0 ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/pathfinder/PathfinderGoalHasRider.java -@@ -0,0 +1,21 @@ -+package net.pl3x.purpur.pathfinder; -+ -+import net.minecraft.server.Entity; -+import net.minecraft.server.PathfinderGoal; -+ -+import java.util.EnumSet; -+ -+public class PathfinderGoalHasRider extends PathfinderGoal { -+ public final Entity entity; -+ -+ public PathfinderGoalHasRider(Entity entity) { -+ this.entity = entity; -+ setTypes(EnumSet.of(Type.JUMP, Type.MOVE, Type.LOOK, Type.TARGET)); -+ } -+ -+ // shouldExecute -+ @Override -+ public boolean a() { -+ return entity.hasRider(); -+ } -+} -diff --git a/src/main/java/net/pl3x/purpur/pathfinder/PathfinderGoalHorseHasRider.java b/src/main/java/net/pl3x/purpur/pathfinder/PathfinderGoalHorseHasRider.java -new file mode 100644 -index 000000000..9bb9da22a ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/pathfinder/PathfinderGoalHorseHasRider.java -@@ -0,0 +1,21 @@ -+package net.pl3x.purpur.pathfinder; -+ -+import net.minecraft.server.EntityHorseAbstract; -+import net.minecraft.server.PathfinderGoal; -+ -+import java.util.EnumSet; -+ -+public class PathfinderGoalHorseHasRider extends PathfinderGoal { -+ public final EntityHorseAbstract entity; -+ -+ public PathfinderGoalHorseHasRider(EntityHorseAbstract entity) { -+ this.entity = entity; -+ setTypes(EnumSet.of(Type.JUMP, Type.MOVE, Type.LOOK, Type.TARGET)); -+ } -+ -+ // shouldExecute -+ @Override -+ public boolean a() { -+ return super.a() && entity.isSaddled(); -+ } -+} -diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 5a7b714cc..ab414917d 100644 ---- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -1089,4 +1089,31 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { - return getHandle().spawnReason; - } - // Paper end -+ -+ // Purpur start -+ @Override -+ public org.bukkit.entity.Player getRider() { -+ return hasRider() ? (org.bukkit.entity.Player) getHandle().getRider().getBukkitEntity() : null; -+ } -+ -+ @Override -+ public boolean hasRider() { -+ return getHandle().hasRider(); -+ } -+ -+ @Override -+ public boolean isRidable() { -+ return getHandle().isRidable(); -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return getHandle().isRidableInWater(); -+ } -+ -+ @Override -+ public boolean requireShiftToMount() { -+ return getHandle().requireShiftToMount(); -+ } -+ // Purpur end - } -diff --git a/src/main/resources/purpur.lang b/src/main/resources/purpur.lang -index 0967ef424..7125c0477 100644 ---- a/src/main/resources/purpur.lang -+++ b/src/main/resources/purpur.lang -@@ -1 +1,3 @@ --{} -+{ -+ "cannot.ride.mob": "You cannot mount that mob" -+} --- -2.26.2 - diff --git a/patches/server/0098-Configurable-server-mod-name.patch b/patches/server/0010-Configurable-server-mod-name.patch similarity index 68% rename from patches/server/0098-Configurable-server-mod-name.patch rename to patches/server/0010-Configurable-server-mod-name.patch index 44494ee5f..25ae27d8a 100644 --- a/patches/server/0098-Configurable-server-mod-name.patch +++ b/patches/server/0010-Configurable-server-mod-name.patch @@ -1,4 +1,4 @@ -From 9fd9d6cc9145840f9407ba06cac930d39d480d94 Mon Sep 17 00:00:00 2001 +From 8cabdcc1fff88ba9e699619de4a6898a2c3ab69d Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 21 Mar 2020 11:47:39 -0500 Subject: [PATCH] Configurable server mod name @@ -9,24 +9,24 @@ Subject: [PATCH] Configurable server mod name 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index d9e5eda9b..d91d3a82c 100644 +index 0d0998b06..377cd8812 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1648,7 +1648,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant -Date: Sat, 19 Oct 2019 00:52:12 -0500 -Subject: [PATCH] Logger settings (suppressing pointless logs) - ---- - .../net/minecraft/server/AdvancementDataPlayer.java | 1 + - .../java/net/minecraft/server/GenericAttributes.java | 1 + - .../minecraft/server/WorldGenFeatureConfigured.java | 1 + - src/main/java/net/pl3x/purpur/PurpurConfig.java | 11 +++++++++++ - .../org/bukkit/craftbukkit/legacy/CraftLegacy.java | 1 + - 5 files changed, 15 insertions(+) - -diff --git a/src/main/java/net/minecraft/server/AdvancementDataPlayer.java b/src/main/java/net/minecraft/server/AdvancementDataPlayer.java -index c41e13847..44331cea7 100644 ---- a/src/main/java/net/minecraft/server/AdvancementDataPlayer.java -+++ b/src/main/java/net/minecraft/server/AdvancementDataPlayer.java -@@ -162,6 +162,7 @@ public class AdvancementDataPlayer { - if (advancement == null) { - // CraftBukkit start - if (entry.getKey().getNamespace().equals("minecraft")) { -+ if (!net.pl3x.purpur.PurpurConfig.loggerSuppressIgnoredAdvancementWarnings) // Purpur - AdvancementDataPlayer.LOGGER.warn("Ignored advancement '{}' in progress file {} - it doesn't exist anymore?", entry.getKey(), this.e); - } - // CraftBukkit end -diff --git a/src/main/java/net/minecraft/server/GenericAttributes.java b/src/main/java/net/minecraft/server/GenericAttributes.java -index 469e293c2..ca58302cf 100644 ---- a/src/main/java/net/minecraft/server/GenericAttributes.java -+++ b/src/main/java/net/minecraft/server/GenericAttributes.java -@@ -79,6 +79,7 @@ public class GenericAttributes { - AttributeInstance attributeinstance = attributemapbase.a(nbttagcompound.getString("Name")); - - if (attributeinstance == null) { -+ if (!net.pl3x.purpur.PurpurConfig.loggerSuppressUnknownAttributeWarnings) // Purpur - GenericAttributes.LOGGER.warn("Ignoring unknown attribute '{}'", nbttagcompound.getString("Name")); - } else { - a(attributeinstance, nbttagcompound); -diff --git a/src/main/java/net/minecraft/server/WorldGenFeatureConfigured.java b/src/main/java/net/minecraft/server/WorldGenFeatureConfigured.java -index 73402f2b5..1c2320cc5 100644 ---- a/src/main/java/net/minecraft/server/WorldGenFeatureConfigured.java -+++ b/src/main/java/net/minecraft/server/WorldGenFeatureConfigured.java -@@ -47,6 +47,7 @@ public class WorldGenFeatureConfigured(worldgenerator, dynamic.get("config").orElseEmptyMap()); - } catch (RuntimeException runtimeexception) { -+ if (!net.pl3x.purpur.PurpurConfig.loggerSuppressWorldGenFeatureDeserializationError) // Purpur - WorldGenFeatureConfigured.LOGGER.warn("Error while deserializing {}", s); - return new WorldGenFeatureConfigured<>(WorldGenerator.NO_OP, WorldGenFeatureEmptyConfiguration.e); - } -diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java -index 2673de821..d6f82d119 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java -@@ -128,6 +128,17 @@ public class PurpurConfig { - return config.getString(path, config.getString(path)); - } - -+ public static boolean loggerSuppressUnknownAttributeWarnings = false; -+ public static boolean loggerSuppressInitLegacyMaterialError = false; -+ public static boolean loggerSuppressWorldGenFeatureDeserializationError = false; -+ public static boolean loggerSuppressIgnoredAdvancementWarnings = false; -+ private static void loggerSettings() { -+ loggerSuppressUnknownAttributeWarnings = getBoolean("settings.logger.suppress-unknown-attribute-warnings", loggerSuppressUnknownAttributeWarnings); -+ loggerSuppressInitLegacyMaterialError = getBoolean("settings.logger.suppress-init-legacy-material-errors", loggerSuppressInitLegacyMaterialError); -+ loggerSuppressWorldGenFeatureDeserializationError = getBoolean("settings.logger.suppress-world-gen-feature-deserialization-errors", loggerSuppressWorldGenFeatureDeserializationError); -+ loggerSuppressIgnoredAdvancementWarnings = getBoolean("settings.logger.suppress-ignored-advancement-warnings", loggerSuppressIgnoredAdvancementWarnings); -+ } -+ - private static void timingsSettings() { - getString("settings.timings.url", "https://timings.pl3x.net"); - } -diff --git a/src/main/java/org/bukkit/craftbukkit/legacy/CraftLegacy.java b/src/main/java/org/bukkit/craftbukkit/legacy/CraftLegacy.java -index 049e9f98d..1d179cd5b 100644 ---- a/src/main/java/org/bukkit/craftbukkit/legacy/CraftLegacy.java -+++ b/src/main/java/org/bukkit/craftbukkit/legacy/CraftLegacy.java -@@ -254,6 +254,7 @@ public final class CraftLegacy { - } - - static { -+ if (!net.pl3x.purpur.PurpurConfig.loggerSuppressInitLegacyMaterialError) // Purpur - System.err.println("Initializing Legacy Material Support. Unless you have legacy plugins and/or data this is a bug!"); - if (MinecraftServer.getServer() != null && MinecraftServer.getServer().isDebugging()) { - new Exception().printStackTrace(); --- -2.26.2 - diff --git a/patches/server/0057-Implement-LivingEntity-safeFallDistance.patch b/patches/server/0011-LivingEntity-safeFallDistance.patch similarity index 63% rename from patches/server/0057-Implement-LivingEntity-safeFallDistance.patch rename to patches/server/0011-LivingEntity-safeFallDistance.patch index 51e4dbc76..91690da65 100644 --- a/patches/server/0057-Implement-LivingEntity-safeFallDistance.patch +++ b/patches/server/0011-LivingEntity-safeFallDistance.patch @@ -1,34 +1,32 @@ -From 7922b68914319be86e725f89951217ee05ab2b59 Mon Sep 17 00:00:00 2001 +From cf295f5a020f34fbf464fb820db12df399df7586 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 5 May 2019 12:58:45 -0500 -Subject: [PATCH] Implement LivingEntity safeFallDistance +Subject: [PATCH] LivingEntity safeFallDistance --- - .../java/net/minecraft/server/EntityGiantZombie.java | 3 +++ + .../java/net/minecraft/server/EntityGiantZombie.java | 1 + .../net/minecraft/server/EntityHorseAbstract.java | 2 +- - src/main/java/net/minecraft/server/EntityLiving.java | 3 ++- + src/main/java/net/minecraft/server/EntityLiving.java | 7 ++++--- .../bukkit/craftbukkit/entity/CraftLivingEntity.java | 12 ++++++++++++ - 4 files changed, 18 insertions(+), 2 deletions(-) + 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/minecraft/server/EntityGiantZombie.java b/src/main/java/net/minecraft/server/EntityGiantZombie.java -index 4296aaa07..a2e3e6001 100644 +index 603fe5caa..37618126f 100644 --- a/src/main/java/net/minecraft/server/EntityGiantZombie.java +++ b/src/main/java/net/minecraft/server/EntityGiantZombie.java -@@ -5,6 +5,9 @@ public class EntityGiantZombie extends EntityMonster { +@@ -4,6 +4,7 @@ public class EntityGiantZombie extends EntityMonster { + public EntityGiantZombie(EntityTypes entitytypes, World world) { super(entitytypes, world); - setStepHeight(world.purpurConfig.giantStepHeight); // Purpur -+ // Purpur start -+ this.safeFallDistance = 10.0F; -+ // Purpur end ++ this.safeFallDistance = 10.0F; // Purpur } - // Purpur start + @Override diff --git a/src/main/java/net/minecraft/server/EntityHorseAbstract.java b/src/main/java/net/minecraft/server/EntityHorseAbstract.java -index 0ecdea671..e099ef9a0 100644 +index 364697e01..ee7a2fedd 100644 --- a/src/main/java/net/minecraft/server/EntityHorseAbstract.java +++ b/src/main/java/net/minecraft/server/EntityHorseAbstract.java -@@ -222,7 +222,7 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven +@@ -210,7 +210,7 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven @Override protected int e(float f, float f1) { @@ -38,18 +36,29 @@ index 0ecdea671..e099ef9a0 100644 protected int getChestSlots() { diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java -index 288942e9d..28e555d6e 100644 +index 7a2140e4b..732a3f21d 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java -@@ -125,6 +125,7 @@ public abstract class EntityLiving extends Entity { +@@ -132,6 +132,7 @@ public abstract class EntityLiving extends Entity { // CraftBukkit start public int expToDrop; public int maxAirTicks = 300; + public float safeFallDistance = 3.0F; // Purpur boolean forceDrops; ArrayList drops = new ArrayList(); - public org.bukkit.craftbukkit.attribute.CraftAttributeMap craftAttributes; -@@ -1546,7 +1547,7 @@ public abstract class EntityLiving extends Entity { + public final org.bukkit.craftbukkit.attribute.CraftAttributeMap craftAttributes; +@@ -226,8 +227,8 @@ public abstract class EntityLiving extends Entity { + this.cQ(); + } + +- if (!this.world.isClientSide && this.fallDistance > 3.0F && flag) { +- float f = (float) MathHelper.f(this.fallDistance - 3.0F); ++ if (!this.world.isClientSide && this.fallDistance > this.safeFallDistance && flag) { // Purpur ++ float f = (float) MathHelper.f(this.fallDistance - this.safeFallDistance); // Purpur + + if (!iblockdata.isAir()) { + double d1 = Math.min((double) (0.2F + f / 15.0F), 2.5D); +@@ -1681,7 +1682,7 @@ public abstract class EntityLiving extends Entity { MobEffect mobeffect = this.getEffect(MobEffects.JUMP); float f2 = mobeffect == null ? 0.0F : (float) (mobeffect.getAmplifier() + 1); @@ -57,12 +66,12 @@ index 288942e9d..28e555d6e 100644 + return MathHelper.f((f - this.safeFallDistance - f2) * f1); // Purpur } - protected void cZ() { + protected void playBlockStepSound() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index a461ac361..4874c2242 100644 +index 3777aba5f..2a82a2bb7 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -739,4 +739,16 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -752,4 +752,16 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { } // Paper end diff --git a/patches/server/0012-Add-obfhelpers-for-plugin-use.patch b/patches/server/0012-Add-obfhelpers-for-plugin-use.patch deleted file mode 100644 index 41fb71d09..000000000 --- a/patches/server/0012-Add-obfhelpers-for-plugin-use.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 7ad6f9948748ee7bc32a5f8682016e0d47b27a80 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Wed, 1 Jan 2020 20:12:39 -0600 -Subject: [PATCH] Add obfhelpers for plugin use - ---- - src/main/java/net/minecraft/server/IChatBaseComponent.java | 2 ++ - src/main/java/net/minecraft/server/ItemStack.java | 1 + - src/main/java/net/minecraft/server/NBTTagString.java | 1 + - 3 files changed, 4 insertions(+) - -diff --git a/src/main/java/net/minecraft/server/IChatBaseComponent.java b/src/main/java/net/minecraft/server/IChatBaseComponent.java -index fb97c51bb..50ed4001d 100644 ---- a/src/main/java/net/minecraft/server/IChatBaseComponent.java -+++ b/src/main/java/net/minecraft/server/IChatBaseComponent.java -@@ -145,6 +145,7 @@ public interface IChatBaseComponent extends Message, Iterable Date: Sat, 1 Feb 2020 22:22:16 -0600 -Subject: [PATCH] Add moon phase API +Subject: [PATCH] MoonPhase API --- - src/main/java/org/bukkit/craftbukkit/CraftWorld.java | 8 ++++++++ - 1 file changed, 8 insertions(+) + src/main/java/org/bukkit/craftbukkit/CraftWorld.java | 7 +++++++ + 1 file changed, 7 insertions(+) diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 32d4aa0f4..e55be5271 100644 +index fb24b9d07..192c99db1 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -2477,6 +2477,14 @@ public class CraftWorld implements World { - - return new CraftDragonBattle(((WorldProviderTheEnd) worldProvider).o()); // PAIL rename getDragonBattle +@@ -2604,4 +2604,11 @@ public class CraftWorld implements World { + return spigot; } + // Spigot end + + // Purpur start + @Override @@ -22,10 +22,7 @@ index 32d4aa0f4..e55be5271 100644 + return net.pl3x.purpur.MoonPhase.getPhase(getFullTime() / 24000L); + } + // Purpur end -+ - // Paper start - @Override - public CompletableFuture getChunkAtAsync(int x, int z, boolean gen, boolean urgent) { + } -- 2.26.2 diff --git a/patches/server/0049-Implement-lagging-threshold.patch b/patches/server/0013-Lagging-threshold.patch similarity index 64% rename from patches/server/0049-Implement-lagging-threshold.patch rename to patches/server/0013-Lagging-threshold.patch index 6a27933b4..a93a5130c 100644 --- a/patches/server/0049-Implement-lagging-threshold.patch +++ b/patches/server/0013-Lagging-threshold.patch @@ -1,19 +1,19 @@ -From 227bedf9b854210d5b7cd9408ca62f7547ff0170 Mon Sep 17 00:00:00 2001 +From 66165fa04ec062dbe138f99824d32840512a43c1 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Tue, 23 Jul 2019 10:07:16 -0500 -Subject: [PATCH] Implement lagging threshold +Subject: [PATCH] Lagging threshold --- src/main/java/net/minecraft/server/MinecraftServer.java | 2 ++ src/main/java/net/pl3x/purpur/PurpurConfig.java | 5 +++++ - src/main/java/org/bukkit/craftbukkit/CraftServer.java | 7 +++++++ - 3 files changed, 14 insertions(+) + src/main/java/org/bukkit/craftbukkit/CraftServer.java | 5 +++++ + 3 files changed, 12 insertions(+) diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index da8c98356..3568e076e 100644 +index 377cd8812..822798741 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -184,6 +184,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant -Date: Sun, 12 May 2019 00:43:12 -0500 -Subject: [PATCH] Give giants AI - ---- - .../minecraft/server/EntityGiantZombie.java | 47 +++++++++++++++++-- - .../minecraft/server/EntityInsentient.java | 2 + - .../net/pl3x/purpur/PurpurWorldConfig.java | 10 ++++ - 3 files changed, 55 insertions(+), 4 deletions(-) - -diff --git a/src/main/java/net/minecraft/server/EntityGiantZombie.java b/src/main/java/net/minecraft/server/EntityGiantZombie.java -index ff8a41a53..4296aaa07 100644 ---- a/src/main/java/net/minecraft/server/EntityGiantZombie.java -+++ b/src/main/java/net/minecraft/server/EntityGiantZombie.java -@@ -23,6 +23,45 @@ public class EntityGiantZombie extends EntityMonster { - return world.purpurConfig.giantRequireShiftToMount; - } - -+ protected void initPathfinder() { -+ if (world.purpurConfig.giantHaveAI) { -+ this.goalSelector.a(0, new PathfinderGoalFloat(this)); -+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur -+ this.goalSelector.a(7, new PathfinderGoalRandomStrollLand(this, 1.0D)); -+ this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 16.0F)); -+ this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); -+ this.goalSelector.a(5, new PathfinderGoalMoveTowardsRestriction(this, 1.0D)); -+ if (world.purpurConfig.giantHaveHostileAI) { -+ this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, 1.0D, false)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur -+ this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this).a(EntityPigZombie.class)); -+ this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); -+ this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillager.class, false)); -+ this.targetSelector.a(4, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, true)); -+ this.targetSelector.a(5, new PathfinderGoalNearestAttackableTarget<>(this, EntityTurtle.class, true)); -+ } -+ } -+ } -+ -+ @Override -+ public GroupDataEntity prepare(GeneratorAccess world, DifficultyDamageScaler difficulty, EnumMobSpawn enummobspawn, GroupDataEntity groupDataEntity, NBTTagCompound nbt) { -+ GroupDataEntity groupData = super.prepare(world, difficulty, enummobspawn, groupDataEntity, nbt); -+ if (groupData == null) { -+ setEquipmentBasedOnDifficulty(difficulty); -+ setEnchantmentBasedOnDifficulty(difficulty); -+ } -+ return groupData; -+ } -+ -+ @Override -+ protected void setEquipmentBasedOnDifficulty(DifficultyDamageScaler difficulty) { -+ super.setEquipmentBasedOnDifficulty(difficulty); -+ // TODO make configurable -+ if (random.nextFloat() < (world.getDifficulty() == EnumDifficulty.HARD ? 0.1F : 0.05F)) { -+ setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.IRON_SWORD)); -+ } -+ } -+ - @Override - public float getJumpHeight() { - // make giants jump as high as everything else relative to their size -@@ -39,13 +78,13 @@ public class EntityGiantZombie extends EntityMonster { - @Override - protected void initAttributes() { - super.initAttributes(); -- this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(100.0D); -- this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.5D); -- this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(50.0D); -+ this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(world.purpurConfig.giantMaxHealth); // Purpur -+ this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(world.purpurConfig.giantMovementSpeed); // Purpur -+ this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(world.purpurConfig.giantAttackDamage); // Purpur - } - - @Override - public float a(BlockPosition blockposition, IWorldReader iworldreader) { -- return iworldreader.w(blockposition) - 0.5F; -+ return super.a(blockposition, iworldreader); // Purpur - fix light requirements for natural spawns - } - } -diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java -index cbbbc875b..fbca42909 100644 ---- a/src/main/java/net/minecraft/server/EntityInsentient.java -+++ b/src/main/java/net/minecraft/server/EntityInsentient.java -@@ -867,6 +867,7 @@ public abstract class EntityInsentient extends EntityLiving { - return f; - } - -+ protected void setEquipmentBasedOnDifficulty(DifficultyDamageScaler difficultydamagescaler) { a(difficultydamagescaler); } // Purpur - OBFHELPER - protected void a(DifficultyDamageScaler difficultydamagescaler) { - if (this.random.nextFloat() < 0.15F * difficultydamagescaler.d()) { - int i = this.random.nextInt(2); -@@ -974,6 +975,7 @@ public abstract class EntityInsentient extends EntityLiving { - } - } - -+ protected void setEnchantmentBasedOnDifficulty(DifficultyDamageScaler difficultydamagescaler) { b(difficultydamagescaler); } // Purpur - OBFHELPER - protected void b(DifficultyDamageScaler difficultydamagescaler) { - float f = difficultydamagescaler.d(); - -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 69f99a993..7cf7ae3dc 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -255,12 +255,22 @@ public class PurpurWorldConfig { - public boolean giantRequireShiftToMount = true; - public float giantStepHeight = 2.0F; - public float giantJumpHeight = 1.0F; -+ public double giantMaxHealth = 100.0D; -+ public double giantMovementSpeed = 0.5D; -+ public double giantAttackDamage = 50.0D; -+ public boolean giantHaveAI = false; -+ public boolean giantHaveHostileAI = false; - private void giantSettings() { - giantRidable = getBoolean("mobs.giant.ridable", giantRidable); - giantRidableInWater = getBoolean("mobs.giant.ridable-in-water", giantRidableInWater); - giantRequireShiftToMount = getBoolean("mobs.giant.require-shift-to-mount", giantRequireShiftToMount); - giantStepHeight = (float) getDouble("mobs.giant.step-height", giantStepHeight); - giantJumpHeight = (float) getDouble("mobs.giant.jump-height", giantJumpHeight); -+ giantMaxHealth = getDouble("mobs.giant.max-health", giantMaxHealth); -+ giantMovementSpeed = getDouble("mobs.giant.movement-speed", giantMovementSpeed); -+ giantAttackDamage = getDouble("mobs.giant.attack-damage", giantAttackDamage); -+ giantHaveAI = getBoolean("mobs.giant.have-ai", giantHaveAI); -+ giantHaveHostileAI = getBoolean("mobs.giant.have-hostile-ai", giantHaveHostileAI); - } - - public boolean guardianRidable = false; --- -2.26.2 - diff --git a/patches/server/0061-Implement-ItemFactory-getMonsterEgg.patch b/patches/server/0014-ItemFactory-getMonsterEgg.patch similarity index 86% rename from patches/server/0061-Implement-ItemFactory-getMonsterEgg.patch rename to patches/server/0014-ItemFactory-getMonsterEgg.patch index 72128a261..e519e2f4d 100644 --- a/patches/server/0061-Implement-ItemFactory-getMonsterEgg.patch +++ b/patches/server/0014-ItemFactory-getMonsterEgg.patch @@ -1,7 +1,7 @@ -From 061042c1a14095bb5264328ecf40c63c20212dd6 Mon Sep 17 00:00:00 2001 +From 38fdad1ea7b019df25e4e4d00c6f0776795bc7e1 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Fri, 5 Jul 2019 16:36:55 -0500 -Subject: [PATCH] Implement ItemFactory#getMonsterEgg +Subject: [PATCH] ItemFactory#getMonsterEgg --- .../java/net/minecraft/server/ItemMonsterEgg.java | 2 +- @@ -9,10 +9,10 @@ Subject: [PATCH] Implement ItemFactory#getMonsterEgg 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/minecraft/server/ItemMonsterEgg.java b/src/main/java/net/minecraft/server/ItemMonsterEgg.java -index 24af4c11d..8ef2c3223 100644 +index 6d8321080..793e42072 100644 --- a/src/main/java/net/minecraft/server/ItemMonsterEgg.java +++ b/src/main/java/net/minecraft/server/ItemMonsterEgg.java -@@ -8,7 +8,7 @@ import javax.annotation.Nullable; +@@ -9,7 +9,7 @@ import javax.annotation.Nullable; public class ItemMonsterEgg extends Item { @@ -22,10 +22,10 @@ index 24af4c11d..8ef2c3223 100644 private final int c; private final EntityTypes d; diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java -index 23d775645..29161032c 100644 +index 0d62f3ae9..53038d096 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java -@@ -354,4 +354,18 @@ public final class CraftItemFactory implements ItemFactory { +@@ -345,4 +345,18 @@ public final class CraftItemFactory implements ItemFactory { return nms != null ? net.minecraft.server.LocaleLanguage.getInstance().translateKey(nms.getItem().getName()) : null; } // Paper end diff --git a/patches/server/0015-Illusioners-AI-settings.patch b/patches/server/0015-Illusioners-AI-settings.patch deleted file mode 100644 index faae34456..000000000 --- a/patches/server/0015-Illusioners-AI-settings.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 329d09c1593e86d9267736552d421f226208abda Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Fri, 5 Jul 2019 11:09:25 -0500 -Subject: [PATCH] Illusioners AI settings - ---- - .../java/net/minecraft/server/EntityIllagerIllusioner.java | 6 +++--- - src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 6 ++++++ - 2 files changed, 9 insertions(+), 3 deletions(-) - -diff --git a/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java b/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java -index 3e6722cfc..13545a8ef 100644 ---- a/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java -+++ b/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java -@@ -58,9 +58,9 @@ public class EntityIllagerIllusioner extends EntityIllagerWizard implements IRan - @Override - protected void initAttributes() { - super.initAttributes(); -- this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.5D); -- this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(18.0D); -- this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(32.0D); -+ this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(world.purpurConfig.illusionerMovementSpeed); // Purpur -+ this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(world.purpurConfig.illusionerFollowRange); // Purpur -+ this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(world.purpurConfig.illusionerMaxHealth); // Purpur - } - - @Override -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 7cf7ae3dc..96a66926f 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -299,10 +299,16 @@ public class PurpurWorldConfig { - public boolean illusionerRidable = false; - public boolean illusionerRidableInWater = false; - public boolean illusionerRequireShiftToMount = true; -+ public double illusionerMaxHealth = 32.0D; -+ public double illusionerMovementSpeed = 0.5D; -+ public double illusionerFollowRange = 18.0D; - private void illusionerSettings() { - illusionerRidable = getBoolean("mobs.illusioner.ridable", illusionerRidable); - illusionerRidableInWater = getBoolean("mobs.illusioner.ridable-in-water", illusionerRidableInWater); - illusionerRequireShiftToMount = getBoolean("mobs.illusioner.require-shift-to-mount", illusionerRequireShiftToMount); -+ illusionerMaxHealth = getDouble("mobs.illusioner.max-health", illusionerMaxHealth); -+ illusionerMovementSpeed = getDouble("mobs.illusioner.movement-speed", illusionerMovementSpeed); -+ illusionerFollowRange = getDouble("mobs.illusioner.follow-range", illusionerFollowRange); - } - - public boolean ironGolemRidable = false; --- -2.26.2 - diff --git a/patches/server/0015-PlayerSetSpawnerTypeWithEggEvent.patch b/patches/server/0015-PlayerSetSpawnerTypeWithEggEvent.patch new file mode 100644 index 000000000..994c87b07 --- /dev/null +++ b/patches/server/0015-PlayerSetSpawnerTypeWithEggEvent.patch @@ -0,0 +1,98 @@ +From 00f1a7cbcc9ae0a4f2ad78b44287a34d81ed54e7 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Fri, 5 Jul 2019 18:21:00 -0500 +Subject: [PATCH] PlayerSetSpawnerTypeWithEggEvent + +--- + .../net/minecraft/server/EntityTypes.java | 22 +++++++++++++++++++ + .../net/minecraft/server/ItemMonsterEgg.java | 16 ++++++++++++++ + 2 files changed, 38 insertions(+) + +diff --git a/src/main/java/net/minecraft/server/EntityTypes.java b/src/main/java/net/minecraft/server/EntityTypes.java +index 18a806ebb..7f2dcc1de 100644 +--- a/src/main/java/net/minecraft/server/EntityTypes.java ++++ b/src/main/java/net/minecraft/server/EntityTypes.java +@@ -142,10 +142,21 @@ public class EntityTypes { + return (EntityTypes) IRegistry.a((IRegistry) IRegistry.ENTITY_TYPE, s, (Object) entitytypes_builder.a(s)); + } + ++ // Purpur start ++ public static EntityTypes getFromBukkitType(org.bukkit.entity.EntityType bukkitType) { ++ return getFromKey(new MinecraftKey(bukkitType.getKey().toString())); ++ } ++ ++ public static EntityTypes getFromKey(MinecraftKey key) { ++ return IRegistry.ENTITY_TYPE.get(key); ++ } ++ // Purpur end ++ + public static MinecraftKey getName(EntityTypes entitytypes) { + return IRegistry.ENTITY_TYPE.getKey(entitytypes); + } + ++ public static Optional> getType(String name) { return a(name); } // Purpur - OBFHELPER + public static Optional> a(String s) { + return IRegistry.ENTITY_TYPE.getOptional(MinecraftKey.a(s)); + } +@@ -270,6 +281,16 @@ public class EntityTypes { + return this.bf; + } + ++ // Purpur start ++ public String getName() { ++ return IRegistry.ENTITY_TYPE.getKey(this).getKey(); ++ } ++ ++ public String getTranslatedName() { ++ return getNameComponent().getString(); ++ } ++ // Purpur end ++ + public String f() { + if (this.bn == null) { + this.bn = SystemUtils.a("entity", IRegistry.ENTITY_TYPE.getKey(this)); +@@ -278,6 +299,7 @@ public class EntityTypes { + return this.bn; + } + ++ public IChatBaseComponent getNameComponent() { return g(); } // Purpur - OBFHELPER + public IChatBaseComponent g() { + if (this.bo == null) { + this.bo = new ChatMessage(this.f()); +diff --git a/src/main/java/net/minecraft/server/ItemMonsterEgg.java b/src/main/java/net/minecraft/server/ItemMonsterEgg.java +index 793e42072..cf4c12ff8 100644 +--- a/src/main/java/net/minecraft/server/ItemMonsterEgg.java ++++ b/src/main/java/net/minecraft/server/ItemMonsterEgg.java +@@ -7,6 +7,13 @@ import java.util.Objects; + import java.util.Optional; + import javax.annotation.Nullable; + ++// Purpur start ++import net.pl3x.purpur.event.PlayerSetSpawnerTypeWithEggEvent; ++import org.bukkit.block.CreatureSpawner; ++import org.bukkit.entity.EntityType; ++import org.bukkit.entity.Player; ++// Purpur end ++ + public class ItemMonsterEgg extends Item { + + public static final Map, ItemMonsterEgg> a = Maps.newIdentityHashMap(); // Purpur - private -> public +@@ -41,6 +48,15 @@ public class ItemMonsterEgg extends Item { + MobSpawnerAbstract mobspawnerabstract = ((TileEntityMobSpawner) tileentity).getSpawner(); + EntityTypes entitytypes = this.a(itemstack.getTag()); + ++ // Purpur start ++ org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ PlayerSetSpawnerTypeWithEggEvent event = new PlayerSetSpawnerTypeWithEggEvent((Player) itemactioncontext.b.getBukkitEntity(), bukkitBlock, (CreatureSpawner) bukkitBlock.getState(), EntityType.fromName(entitytypes.getName())); ++ if (!event.callEvent()) { ++ return EnumInteractionResult.FAIL; ++ } ++ entitytypes = EntityTypes.getFromBukkitType(event.getEntityType()); ++ // Purpur end ++ + mobspawnerabstract.setMobName(entitytypes); + tileentity.update(); + world.notify(blockposition, iblockdata, iblockdata, 3); +-- +2.26.2 + diff --git a/patches/server/0121-EMC-MonsterEggSpawn-Event.patch b/patches/server/0016-EMC-MonsterEggSpawnEvent.patch similarity index 95% rename from patches/server/0121-EMC-MonsterEggSpawn-Event.patch rename to patches/server/0016-EMC-MonsterEggSpawnEvent.patch index c80b10b06..d2b30af15 100644 --- a/patches/server/0121-EMC-MonsterEggSpawn-Event.patch +++ b/patches/server/0016-EMC-MonsterEggSpawnEvent.patch @@ -1,17 +1,17 @@ -From ff08fe5bfa4a978c4db1e6e039d4eadea593d3f0 Mon Sep 17 00:00:00 2001 +From ebc3f075549750efdaf6d045a951b5082b1aa9c0 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 20 Jul 2013 22:40:56 -0400 -Subject: [PATCH] EMC - MonsterEggSpawn Event +Subject: [PATCH] EMC - MonsterEggSpawnEvent --- .../net/minecraft/server/EntityTypes.java | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/minecraft/server/EntityTypes.java b/src/main/java/net/minecraft/server/EntityTypes.java -index 8e8d392a1..ff11baa7c 100644 +index 7f2dcc1de..5aea85595 100644 --- a/src/main/java/net/minecraft/server/EntityTypes.java +++ b/src/main/java/net/minecraft/server/EntityTypes.java -@@ -163,19 +163,45 @@ public class EntityTypes { +@@ -176,19 +176,45 @@ public class EntityTypes { @Nullable public Entity spawnCreature(World world, @Nullable ItemStack itemstack, @Nullable EntityHuman entityhuman, BlockPosition blockposition, EnumMobSpawn enummobspawn, boolean flag, boolean flag1) { diff --git a/patches/server/0071-Add-API-for-Villager-resetOffers.patch b/patches/server/0017-Villager-resetOffers.patch similarity index 82% rename from patches/server/0071-Add-API-for-Villager-resetOffers.patch rename to patches/server/0017-Villager-resetOffers.patch index 0919213dd..f6bcd0c21 100644 --- a/patches/server/0071-Add-API-for-Villager-resetOffers.patch +++ b/patches/server/0017-Villager-resetOffers.patch @@ -1,7 +1,7 @@ -From f47732a9410ca8fffaa03331ac3deb642af7e1ed Mon Sep 17 00:00:00 2001 +From f78891becd000d9c7787bc38deb9d35aa797405b Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Mon, 7 Oct 2019 00:15:37 -0500 -Subject: [PATCH] Add API for Villager#resetOffers() +Subject: [PATCH] Villager#resetOffers --- .../java/net/minecraft/server/EntityVillagerAbstract.java | 8 ++++++++ @@ -9,10 +9,10 @@ Subject: [PATCH] Add API for Villager#resetOffers() 2 files changed, 15 insertions(+) diff --git a/src/main/java/net/minecraft/server/EntityVillagerAbstract.java b/src/main/java/net/minecraft/server/EntityVillagerAbstract.java -index 463528532..5fbd13512 100644 +index 81823b5d5..beb84a2ab 100644 --- a/src/main/java/net/minecraft/server/EntityVillagerAbstract.java +++ b/src/main/java/net/minecraft/server/EntityVillagerAbstract.java -@@ -84,6 +84,13 @@ public abstract class EntityVillagerAbstract extends EntityAgeable implements NP +@@ -86,6 +86,13 @@ public abstract class EntityVillagerAbstract extends EntityAgeable implements NP return this.tradingPlayer != null; } @@ -26,12 +26,12 @@ index 463528532..5fbd13512 100644 @Override public MerchantRecipeList getOffers() { if (this.trades == null) { -@@ -225,6 +232,7 @@ public abstract class EntityVillagerAbstract extends EntityAgeable implements NP +@@ -208,6 +215,7 @@ public abstract class EntityVillagerAbstract extends EntityAgeable implements NP return this.world; } -+ protected void updateTrades() { eC(); } // Purpur - protected abstract void eC(); ++ protected void updateTrades() { eW(); } // Purpur + protected abstract void eW(); protected void a(MerchantRecipeList merchantrecipelist, VillagerTrades.IMerchantRecipeOption[] avillagertrades_imerchantrecipeoption, int i) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java diff --git a/patches/server/0018-World-getPlacementBlockData.patch b/patches/server/0018-World-getPlacementBlockData.patch new file mode 100644 index 000000000..700ba0be3 --- /dev/null +++ b/patches/server/0018-World-getPlacementBlockData.patch @@ -0,0 +1,27 @@ +From ccf75c0f071428349a26221eb9c05d22d6c11466 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Sat, 8 Feb 2020 23:30:17 -0600 +Subject: [PATCH] World#getPlacementBlockData + +--- + src/main/java/org/bukkit/craftbukkit/CraftWorld.java | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +index 192c99db1..be2d2040c 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +@@ -2610,5 +2610,10 @@ public class CraftWorld implements World { + public net.pl3x.purpur.MoonPhase getMoonPhase() { + return net.pl3x.purpur.MoonPhase.getPhase(getFullTime() / 24000L); + } ++ ++ public BlockData getPlacementBlockData(BlockData blockdata, Location location) { ++ IBlockData validData = net.minecraft.server.Block.getValidBlockForPosition(((CraftBlockData) blockdata).getState(), getHandle(), net.minecraft.server.MCUtil.toBlockPosition(location)); ++ return CraftBlockData.fromData(validData == null ? Blocks.AIR.getBlockData() : validData); ++ } + // Purpur end + } +-- +2.26.2 + diff --git a/patches/server/0019-Cat-spawning-options.patch b/patches/server/0019-Cat-spawning-options.patch deleted file mode 100644 index 9b8e710a9..000000000 --- a/patches/server/0019-Cat-spawning-options.patch +++ /dev/null @@ -1,82 +0,0 @@ -From c673dd6d4a16db19278e99bd2355469d93c2a79f Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Thu, 26 Dec 2019 18:52:55 -0600 -Subject: [PATCH] Cat spawning options - ---- - .../net/minecraft/server/MobSpawnerCat.java | 23 +++++++++++++------ - .../net/pl3x/purpur/PurpurWorldConfig.java | 6 +++++ - 2 files changed, 22 insertions(+), 7 deletions(-) - -diff --git a/src/main/java/net/minecraft/server/MobSpawnerCat.java b/src/main/java/net/minecraft/server/MobSpawnerCat.java -index 6024478dc..4b55c07d4 100644 ---- a/src/main/java/net/minecraft/server/MobSpawnerCat.java -+++ b/src/main/java/net/minecraft/server/MobSpawnerCat.java -@@ -15,7 +15,7 @@ public class MobSpawnerCat { - if (this.a > 0) { - return 0; - } else { -- this.a = 1200; -+ this.a = worldserver.purpurConfig.catSpawnDelay; // Purpur - EntityPlayer entityplayer = worldserver.k(); - - if (entityplayer == null) { -@@ -49,10 +49,14 @@ public class MobSpawnerCat { - } - - private int a(WorldServer worldserver, BlockPosition blockposition) { -- boolean flag = true; -- -- if (worldserver.B().a(VillagePlaceType.q.c(), blockposition, 48, VillagePlace.Occupancy.IS_OCCUPIED) > 4L) { -- List list = worldserver.a(EntityCat.class, (new AxisAlignedBB(blockposition)).grow(48.0D, 8.0D, 48.0D)); -+ // Purpur start -+ int range = worldserver.purpurConfig.catSpawnVillageScanRange; -+ if (range <= 0) { -+ return 0; -+ } -+ if (worldserver.B().a(VillagePlaceType.q.c(), blockposition, range, VillagePlace.Occupancy.IS_OCCUPIED) > 4L) { -+ List list = worldserver.a(EntityCat.class, (new AxisAlignedBB(blockposition)).grow(range, 8.0D, range)); -+ // Purpur end - - if (list.size() < 5) { - return this.a(blockposition, (World) worldserver); -@@ -63,8 +67,13 @@ public class MobSpawnerCat { - } - - private int a(World world, BlockPosition blockposition) { -- boolean flag = true; -- List list = world.a(EntityCat.class, (new AxisAlignedBB(blockposition)).grow(16.0D, 8.0D, 16.0D)); -+ // Purpur start -+ int range = world.purpurConfig.catSpawnSwampHutScanRange; -+ if (range <= 0) { -+ return 0; -+ } -+ List list = world.a(EntityCat.class, (new AxisAlignedBB(blockposition)).grow(range, 8.0D, range)); -+ // Purpur end - - return list.size() < 1 ? this.a(blockposition, world) : 0; - } -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 4aaf75fcf..12fbdf65c 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -101,10 +101,16 @@ public class PurpurWorldConfig { - public boolean catRidable = false; - public boolean catRidableInWater = false; - public boolean catRequireShiftToMount = true; -+ public int catSpawnDelay = 1200; -+ public int catSpawnSwampHutScanRange = 16; -+ public int catSpawnVillageScanRange = 48; - private void catSettings() { - catRidable = getBoolean("mobs.cat.ridable", catRidable); - catRidableInWater = getBoolean("mobs.cat.ridable-in-water", catRidableInWater); - catRequireShiftToMount = getBoolean("mobs.cat.require-shift-to-mount", catRequireShiftToMount); -+ catSpawnDelay = getInt("mobs.cat.spawn-delay", catSpawnDelay); -+ catSpawnSwampHutScanRange = getInt("mobs.cat.scan-range-for-other-cats.swamp-hut", catSpawnSwampHutScanRange); -+ catSpawnVillageScanRange = getInt("mobs.cat.scan-range-for-other-cats.village", catSpawnVillageScanRange); - } - - public boolean caveSpiderRidable = false; --- -2.26.2 - diff --git a/patches/server/0069-Add-playPickupItemAnimation-to-LivingEntity.patch b/patches/server/0019-LivingEntity-playPickupItemAnimation.patch similarity index 79% rename from patches/server/0069-Add-playPickupItemAnimation-to-LivingEntity.patch rename to patches/server/0019-LivingEntity-playPickupItemAnimation.patch index ac1a5bbd4..c55b9fdc4 100644 --- a/patches/server/0069-Add-playPickupItemAnimation-to-LivingEntity.patch +++ b/patches/server/0019-LivingEntity-playPickupItemAnimation.patch @@ -1,17 +1,17 @@ -From 8d2281f398ecd5a18ce82bbe36815336b45564ca Mon Sep 17 00:00:00 2001 +From ad5c59131a490f3a1acf7e51ec0a25698f1d5d40 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 19 Oct 2019 02:25:16 -0500 -Subject: [PATCH] Add playPickupItemAnimation to LivingEntity +Subject: [PATCH] LivingEntity#playPickupItemAnimation --- .../org/bukkit/craftbukkit/entity/CraftLivingEntity.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 4874c2242..d8207b322 100644 +index 2a82a2bb7..a415707e9 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -750,5 +750,10 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -763,5 +763,10 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { public void setSafeFallDistance(float safeFallDistance) { getHandle().safeFallDistance = safeFallDistance; } diff --git a/patches/server/0079-Add-getPlayer-to-SkeletonHorseTrapEvent.patch b/patches/server/0020-SkeletonHorseTrapEvent-getPlayer.patch similarity index 88% rename from patches/server/0079-Add-getPlayer-to-SkeletonHorseTrapEvent.patch rename to patches/server/0020-SkeletonHorseTrapEvent-getPlayer.patch index 921673b71..cd70b6d78 100644 --- a/patches/server/0079-Add-getPlayer-to-SkeletonHorseTrapEvent.patch +++ b/patches/server/0020-SkeletonHorseTrapEvent-getPlayer.patch @@ -1,14 +1,14 @@ -From 8e48776996b8bb36d3834d576e20a70ffd0f332b Mon Sep 17 00:00:00 2001 +From 31aa2e07a779236b98b8415007409eed934d8452 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 19 Oct 2019 02:35:35 -0500 -Subject: [PATCH] Add getPlayer to SkeletonHorseTrapEvent +Subject: [PATCH] SkeletonHorseTrapEvent#getPlayer --- .../java/net/minecraft/server/PathfinderGoalHorseTrap.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/minecraft/server/PathfinderGoalHorseTrap.java b/src/main/java/net/minecraft/server/PathfinderGoalHorseTrap.java -index 37626f925..f8fd2d99c 100644 +index b37e4aa37..4d8c4ac07 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalHorseTrap.java +++ b/src/main/java/net/minecraft/server/PathfinderGoalHorseTrap.java @@ -2,7 +2,8 @@ package net.minecraft.server; @@ -33,9 +33,9 @@ index 37626f925..f8fd2d99c 100644 public void e() { - if (!new com.destroystokyo.paper.event.entity.SkeletonHorseTrapEvent((org.bukkit.entity.SkeletonHorse) this.a.getBukkitEntity()).callEvent()) return; // Paper + if (!new com.destroystokyo.paper.event.entity.SkeletonHorseTrapEvent((org.bukkit.entity.SkeletonHorse) this.a.getBukkitEntity(), (org.bukkit.entity.Player) player.getBukkitEntity()).callEvent()) return; // Paper // Purpur - DifficultyDamageScaler difficultydamagescaler = this.a.world.getDamageScaler(new BlockPosition(this.a)); + DifficultyDamageScaler difficultydamagescaler = this.a.world.getDamageScaler(this.a.getChunkCoordinates()); - this.a.r(false); + this.a.t(false); -- 2.26.2 diff --git a/patches/server/0123-PaperPR-PlayerItemCooldownEvent.patch b/patches/server/0021-PaperPR-PlayerItemCooldownEvent.patch similarity index 95% rename from patches/server/0123-PaperPR-PlayerItemCooldownEvent.patch rename to patches/server/0021-PaperPR-PlayerItemCooldownEvent.patch index 6b288459b..9a039c3da 100644 --- a/patches/server/0123-PaperPR-PlayerItemCooldownEvent.patch +++ b/patches/server/0021-PaperPR-PlayerItemCooldownEvent.patch @@ -1,4 +1,4 @@ -From 4ccb3f307363426180c14b91fd024e297f003f8e Mon Sep 17 00:00:00 2001 +From 8a99e19fa0556853736568a269dd892342449daf Mon Sep 17 00:00:00 2001 From: KennyTV Date: Mon, 20 Apr 2020 13:57:06 +0200 Subject: [PATCH] PaperPR - PlayerItemCooldownEvent diff --git a/patches/server/0089-Implement-EntityMoveEvent.patch b/patches/server/0022-EntityMoveEvent.patch similarity index 59% rename from patches/server/0089-Implement-EntityMoveEvent.patch rename to patches/server/0022-EntityMoveEvent.patch index 0d77590a7..d56992b8c 100644 --- a/patches/server/0089-Implement-EntityMoveEvent.patch +++ b/patches/server/0022-EntityMoveEvent.patch @@ -1,34 +1,26 @@ -From ba39fe270c169902970625051d27f30b23d54dc9 Mon Sep 17 00:00:00 2001 +From c61f071c2eb1be7789fc51fc08b363eacf5e0473 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Tue, 11 Feb 2020 21:56:48 -0600 -Subject: [PATCH] Implement EntityMoveEvent +Subject: [PATCH] EntityMoveEvent --- - .../java/net/minecraft/server/EntityLiving.java | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) + .../java/net/minecraft/server/EntityLiving.java | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java -index 28e555d6e..387f74fe1 100644 +index 732a3f21d..f917cd5df 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java -@@ -17,6 +17,7 @@ import java.util.Random; - import java.util.Set; - import java.util.UUID; - import javax.annotation.Nullable; -+import net.pl3x.purpur.event.entity.EntityMoveEvent; // Purpur - import org.apache.commons.lang3.tuple.Pair; - - // CraftBukkit start -@@ -2648,6 +2649,20 @@ public abstract class EntityLiving extends Entity { +@@ -2790,6 +2790,20 @@ public abstract class EntityLiving extends Entity { this.collideNearby(); this.world.getMethodProfiler().exit(); + // Purpur start -+ if (EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0) { ++ if (net.pl3x.purpur.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0) { + if (lastX != locX() || lastY != locY() || lastZ != locZ() || lastYaw != yaw || lastPitch != pitch) { + Location from = new Location(world.getWorld(), lastX, lastY, lastZ, lastYaw, lastPitch); + Location to = new Location (world.getWorld(), locX(), locY(), locZ(), yaw, pitch); -+ EntityMoveEvent event = new EntityMoveEvent(getBukkitLivingEntity(), from, to.clone()); ++ net.pl3x.purpur.event.entity.EntityMoveEvent event = new net.pl3x.purpur.event.entity.EntityMoveEvent(getBukkitLivingEntity(), from, to.clone()); + if (!event.callEvent()) { + setLocation(from.getX(), from.getY(), from.getZ(), from.getYaw(), from.getPitch()); + } else if (!to.equals(event.getTo())) { @@ -37,9 +29,9 @@ index 28e555d6e..387f74fe1 100644 + } + } + // Purpur end - } - - private void n() { + if (!this.world.isClientSide && this.dN() && this.aC()) { + this.damageEntity(DamageSource.DROWN, 1.0F); + } -- 2.26.2 diff --git a/patches/server/0022-Fix-cow-rotation-when-shearing-mooshroom.patch b/patches/server/0022-Fix-cow-rotation-when-shearing-mooshroom.patch deleted file mode 100644 index 6e36806f7..000000000 --- a/patches/server/0022-Fix-cow-rotation-when-shearing-mooshroom.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 2cafa9014b47d301c4f70ca2503bc8398c260a18 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Fri, 3 May 2019 23:53:16 -0500 -Subject: [PATCH] Fix cow rotation when shearing mooshroom - ---- - src/main/java/net/minecraft/server/EntityMushroomCow.java | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/src/main/java/net/minecraft/server/EntityMushroomCow.java b/src/main/java/net/minecraft/server/EntityMushroomCow.java -index 53bc31287..bf835aaf9 100644 ---- a/src/main/java/net/minecraft/server/EntityMushroomCow.java -+++ b/src/main/java/net/minecraft/server/EntityMushroomCow.java -@@ -114,7 +114,13 @@ public class EntityMushroomCow extends EntityCow { - - entitycow.setPositionRotation(this.locX(), this.locY(), this.locZ(), this.yaw, this.pitch); - entitycow.setHealth(this.getHealth()); -- entitycow.aI = this.aI; -+ // Purpur start - correctly copy rotation -+ entitycow.copyPositionRotation(this); -+ entitycow.setRenderYawOffset(this.getRenderYawOffset()); -+ entitycow.setHeadRotation(this.getHeadRotation()); -+ entitycow.lastYaw = this.lastYaw; -+ entitycow.lastPitch = this.lastPitch; -+ // Purpur end - if (this.hasCustomName()) { - entitycow.setCustomName(this.getCustomName()); - entitycow.setCustomNameVisible(this.getCustomNameVisible()); --- -2.26.2 - diff --git a/patches/server/0122-PaperPR-Add-BellRingEvent.patch b/patches/server/0023-PaperPR-Add-BellRingEvent.patch similarity index 72% rename from patches/server/0122-PaperPR-Add-BellRingEvent.patch rename to patches/server/0023-PaperPR-Add-BellRingEvent.patch index ed172727e..21a4a4272 100644 --- a/patches/server/0122-PaperPR-Add-BellRingEvent.patch +++ b/patches/server/0023-PaperPR-Add-BellRingEvent.patch @@ -1,4 +1,4 @@ -From 3e5f9a68fcae710e4090815afb8f635865e12f0b Mon Sep 17 00:00:00 2001 +From 0d8728d2c77181579b7efcc4ca6d588d45f1615a Mon Sep 17 00:00:00 2001 From: Eearslya Sleiarion Date: Mon, 24 Jun 2019 21:27:32 -0700 Subject: [PATCH] PaperPR - Add BellRingEvent @@ -8,19 +8,19 @@ Subject: [PATCH] PaperPR - Add BellRingEvent 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/minecraft/server/BlockBell.java b/src/main/java/net/minecraft/server/BlockBell.java -index dbdbfb8ad..0bbd1e159 100644 +index 2ef899c76..7db4e22c6 100644 --- a/src/main/java/net/minecraft/server/BlockBell.java +++ b/src/main/java/net/minecraft/server/BlockBell.java -@@ -45,7 +45,7 @@ public class BlockBell extends BlockTileEntity { - Entity entity1 = ((EntityArrow) entity).getShooter(); - EntityHuman entityhuman = entity1 instanceof EntityHuman ? (EntityHuman) entity1 : null; - -- this.a(world, iblockdata, movingobjectpositionblock, entityhuman, true); -+ this.handleBellRing(world, iblockdata, movingobjectpositionblock, entityhuman, true, entity); // Purpur - } +@@ -44,7 +44,7 @@ public class BlockBell extends BlockTileEntity { + Entity entity = iprojectile.getShooter(); + EntityHuman entityhuman = entity instanceof EntityHuman ? (EntityHuman) entity : null; +- this.a(world, iblockdata, movingobjectpositionblock, entityhuman, true); ++ this.handleBellRing(world, iblockdata, movingobjectpositionblock, entityhuman, true, entity); // Purpur } -@@ -56,11 +56,23 @@ public class BlockBell extends BlockTileEntity { + + @Override +@@ -53,11 +53,23 @@ public class BlockBell extends BlockTileEntity { } public boolean a(World world, IBlockData iblockdata, MovingObjectPositionBlock movingobjectpositionblock, @Nullable EntityHuman entityhuman, boolean flag) { @@ -37,7 +37,7 @@ index dbdbfb8ad..0bbd1e159 100644 if (flag1) { + // Purpur start - BellRingEvent + org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); -+ if (!new com.destroystokyo.paper.event.block.BellRingEvent(block, (org.bukkit.entity.Entity) entity.getBukkitEntity()).callEvent()) { ++ if (!new com.destroystokyo.paper.event.block.BellRingEvent(block, entity.getBukkitEntity()).callEvent()) { + return true; + } + // Purpur end diff --git a/patches/server/0023-Pigs-give-saddle-back.patch b/patches/server/0023-Pigs-give-saddle-back.patch deleted file mode 100644 index a56633f36..000000000 --- a/patches/server/0023-Pigs-give-saddle-back.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 1807f5647ff8b32508f3af2d41c656d755f46f39 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sun, 12 May 2019 01:14:46 -0500 -Subject: [PATCH] Pigs give saddle back - ---- - src/main/java/net/minecraft/server/EntityPig.java | 12 ++++++++++++ - src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 2 ++ - 2 files changed, 14 insertions(+) - -diff --git a/src/main/java/net/minecraft/server/EntityPig.java b/src/main/java/net/minecraft/server/EntityPig.java -index e6a7f8ef3..d78666dbb 100644 ---- a/src/main/java/net/minecraft/server/EntityPig.java -+++ b/src/main/java/net/minecraft/server/EntityPig.java -@@ -135,6 +135,18 @@ public class EntityPig extends EntityAnimal { - return true; - } - if (hasSaddle() && !isVehicle()) { -+ // Purpur start -+ if (world.purpurConfig.pigGiveSaddleBack && entityhuman.isSneaking()) { -+ setSaddle(false); -+ if (!entityhuman.abilities.canInstantlyBuild) { -+ ItemStack saddle = new ItemStack(Items.SADDLE); -+ if (!entityhuman.inventory.pickup(saddle)) { -+ entityhuman.drop(saddle, false); -+ } -+ } -+ return true; -+ } -+ // Purpur end - entityhuman.startRiding(this); - return true; - } -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 091f30727..85692500b 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -413,9 +413,11 @@ public class PurpurWorldConfig { - - public boolean pigRidable = false; - public boolean pigRidableInWater = false; -+ public boolean pigGiveSaddleBack = false; - private void pigSettings() { - pigRidable = getBoolean("mobs.pig.ridable", pigRidable); - pigRidableInWater = getBoolean("mobs.pig.ridable-in-water", pigRidableInWater); -+ pigGiveSaddleBack = getBoolean("mobs.pig.give-saddle-back", pigGiveSaddleBack); - } - - public boolean pillagerRidable = false; --- -2.26.2 - diff --git a/patches/server/0114-Player-invulnerabilities.patch b/patches/server/0024-Player-invulnerabilities.patch similarity index 72% rename from patches/server/0114-Player-invulnerabilities.patch rename to patches/server/0024-Player-invulnerabilities.patch index 015586259..f8b5b36b7 100644 --- a/patches/server/0114-Player-invulnerabilities.patch +++ b/patches/server/0024-Player-invulnerabilities.patch @@ -1,21 +1,21 @@ -From 7c51cf494632ddcecb2ee18c559a9930f3b4a681 Mon Sep 17 00:00:00 2001 +From 475fd521ac59a8425121d35cf70eb47039c89dab Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 2 May 2020 20:55:44 -0500 Subject: [PATCH] Player invulnerabilities --- - .../net/minecraft/server/EntityPlayer.java | 22 +++++++++++++++++-- + .../net/minecraft/server/EntityPlayer.java | 21 +++++++++++++++++-- .../minecraft/server/PlayerConnection.java | 1 + .../java/net/minecraft/server/PlayerList.java | 2 ++ - .../net/pl3x/purpur/PurpurWorldConfig.java | 4 ++++ + .../net/pl3x/purpur/PurpurWorldConfig.java | 7 +++++++ .../craftbukkit/entity/CraftPlayer.java | 15 +++++++++++++ - 5 files changed, 42 insertions(+), 2 deletions(-) + 5 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java -index 3e0e49dbb..e73b33721 100644 +index 6fbbe515c..c627ea053 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java -@@ -137,6 +137,8 @@ public class EntityPlayer extends EntityHuman implements ICrafting { +@@ -141,6 +141,8 @@ public class EntityPlayer extends EntityHuman implements ICrafting { this.canPickUpLoot = true; this.maxHealthCache = this.getMaxHealth(); this.cachedSingleMobDistanceMap = new com.destroystokyo.paper.util.PooledHashSets.PooledObjectLinkedOpenHashSet<>(this); // Paper @@ -24,7 +24,7 @@ index 3e0e49dbb..e73b33721 100644 } // Paper start public BlockPosition getPointInFront(double inFront) { -@@ -748,6 +750,12 @@ public class EntityPlayer extends EntityHuman implements ICrafting { +@@ -804,6 +806,12 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } @@ -37,25 +37,24 @@ index 3e0e49dbb..e73b33721 100644 @Override public boolean damageEntity(DamageSource damagesource, float f) { if (this.isInvulnerable(damagesource)) { -@@ -755,7 +763,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { +@@ -811,7 +819,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } else { - boolean flag = this.server.m() && this.canPvP() && "fall".equals(damagesource.translationIndex); + boolean flag = this.server.j() && this.canPvP() && "fall".equals(damagesource.translationIndex); - if (!flag && this.invulnerableTicks > 0 && damagesource != DamageSource.OUT_OF_WORLD) { + if (!flag && isSpawnInvulnerable() && damagesource != DamageSource.OUT_OF_WORLD) { // Purpur return false; } else { if (damagesource instanceof EntityDamageSource) { -@@ -1022,6 +1030,8 @@ public class EntityPlayer extends EntityHuman implements ICrafting { +@@ -1057,6 +1065,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { PlayerChangedWorldEvent changeEvent = new PlayerChangedWorldEvent(this.getBukkitEntity(), worldserver.getWorld()); this.world.getServer().getPluginManager().callEvent(changeEvent); // CraftBukkit end -+ + this.invulnerableTicks = worldserver.purpurConfig.playerSpawnInvulnerableTicks; // Purpur return this; } } -@@ -2010,9 +2020,17 @@ public class EntityPlayer extends EntityHuman implements ICrafting { +@@ -2152,9 +2161,17 @@ public class EntityPlayer extends EntityHuman implements ICrafting { @Override public boolean isFrozen() { // Paper - protected > public @@ -75,10 +74,10 @@ index 3e0e49dbb..e73b33721 100644 public Scoreboard getScoreboard() { return getBukkitEntity().getScoreboard().getHandle(); diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java -index 82faee937..86715ff3c 100644 +index 48a03c44f..85016aa76 100644 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java -@@ -1548,6 +1548,7 @@ public class PlayerConnection implements PacketListenerPlayIn { +@@ -1563,6 +1563,7 @@ public class PlayerConnection implements PacketListenerPlayIn { PlayerConnectionUtils.ensureMainThread(packetplayinresourcepackstatus, this, this.player.getWorldServer()); // Paper start PlayerResourcePackStatusEvent.Status packStatus = PlayerResourcePackStatusEvent.Status.values()[packetplayinresourcepackstatus.status.ordinal()]; @@ -87,10 +86,10 @@ index 82faee937..86715ff3c 100644 this.server.getPluginManager().callEvent(new PlayerResourcePackStatusEvent(getPlayer(), packStatus)); // Paper end diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java -index af2cdbf4d..5cacea602 100644 +index 3c5ba8f2f..5807e77da 100644 --- a/src/main/java/net/minecraft/server/PlayerList.java +++ b/src/main/java/net/minecraft/server/PlayerList.java -@@ -828,6 +828,8 @@ public abstract class PlayerList { +@@ -869,6 +869,8 @@ public abstract class PlayerList { } // Paper end @@ -100,32 +99,26 @@ index af2cdbf4d..5cacea602 100644 return entityplayer1; } diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index efdc176e6..81969d2dc 100644 +index 5fa333037..bd9b82dad 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -209,6 +209,8 @@ public class PurpurWorldConfig { - public boolean milkCuresBadOmen = true; - public String playerDeathExpDropEquation = "expLevel * 7"; - public int playerDeathExpDropMax = 100; +@@ -75,4 +75,11 @@ public class PurpurWorldConfig { + idleTimeoutCountAsSleeping = getBoolean("gameplay-mechanics.player.idle-timeout.count-as-sleeping", idleTimeoutCountAsSleeping); + idleTimeoutUpdateTabList = getBoolean("gameplay-mechanics.player.idle-timeout.update-tab-list", idleTimeoutUpdateTabList); + } ++ + public int playerSpawnInvulnerableTicks = 60; + public boolean playerInvulnerableWhileAcceptingResourcePack = false; - public boolean playerSleepOnlyWithCondition = false; - public String playerSleepCondition = "time >= 12541 && time <= 23458"; - public boolean useBetterMending = false; -@@ -254,6 +256,8 @@ public class PurpurWorldConfig { - milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen); - playerDeathExpDropEquation = getString("gameplay-mechanics.player.exp-dropped-on-death.equation", playerDeathExpDropEquation); - playerDeathExpDropMax = getInt("gameplay-mechanics.player.exp-dropped-on-death.maximum", playerDeathExpDropMax); ++ private void playerInvulnerabilities() { + playerSpawnInvulnerableTicks = getInt("gameplay-mechanics.player.spawn-invulnerable-ticks", playerSpawnInvulnerableTicks); + playerInvulnerableWhileAcceptingResourcePack = getBoolean("gameplay-mechanics.player.invulnerable-while-accepting-resource-pack", playerInvulnerableWhileAcceptingResourcePack); - playerSleepOnlyWithCondition = getBoolean("gameplay-mechanics.player.sleep.only-with-condition", playerSleepOnlyWithCondition); - playerSleepCondition = getString("gameplay-mechanics.player.sleep.condition", playerSleepCondition); - useBetterMending = getBoolean("gameplay-mechanics.use-better-mending", useBetterMending); ++ } + } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index e15c12387..137699c3e 100644 +index 3bd2ffc20..9b1c4d932 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2102,5 +2102,20 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2144,5 +2144,20 @@ public class CraftPlayer extends CraftHumanEntity implements Player { public void resetIdleTimer() { getHandle().resetIdleTimer(); } diff --git a/patches/server/0112-More-anvil-controls.patch b/patches/server/0025-Anvil-API.patch similarity index 62% rename from patches/server/0112-More-anvil-controls.patch rename to patches/server/0025-Anvil-API.patch index 20a3cbcd1..960844e98 100644 --- a/patches/server/0112-More-anvil-controls.patch +++ b/patches/server/0025-Anvil-API.patch @@ -1,53 +1,45 @@ -From aff14f5361f3b98c2bf66fa61d766e1db14af17e Mon Sep 17 00:00:00 2001 +From 44cafc5974e016c61841d8fd29e480e8605416b0 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 19 Apr 2020 00:17:56 -0500 -Subject: [PATCH] More anvil controls +Subject: [PATCH] Anvil API --- - .../net/minecraft/server/ContainerAnvil.java | 31 +++++++++++++++++-- - .../inventory/CraftInventoryAnvil.java | 24 +++++++++++++- - 2 files changed, 51 insertions(+), 4 deletions(-) + .../net/minecraft/server/ContainerAnvil.java | 29 +++++++++++++++++-- + .../inventory/CraftInventoryAnvil.java | 24 ++++++++++++++- + 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/minecraft/server/ContainerAnvil.java b/src/main/java/net/minecraft/server/ContainerAnvil.java -index 286b930dd..d418c0441 100644 +index 24631b2bc..126effe5b 100644 --- a/src/main/java/net/minecraft/server/ContainerAnvil.java +++ b/src/main/java/net/minecraft/server/ContainerAnvil.java -@@ -8,6 +8,7 @@ import org.apache.logging.log4j.Logger; - - // CraftBukkit start - import org.bukkit.craftbukkit.inventory.CraftInventoryView; -+import org.bukkit.inventory.AnvilInventory; - // CraftBukkit end - - public class ContainerAnvil extends Container { -@@ -25,6 +26,8 @@ public class ContainerAnvil extends Container { - private int lastLevelCost; +@@ -20,6 +20,8 @@ public class ContainerAnvil extends ContainerAnvilAbstract { + public int maximumRepairCost = 40; private CraftInventoryView bukkitEntity; - private PlayerInventory playerInventory; + // CraftBukkit end + public boolean bypassCost = false; // Purpur + public boolean canDoUnsafeEnchants = false; // Purpur - // CraftBukkit end public ContainerAnvil(int i, PlayerInventory playerinventory) { -@@ -56,12 +59,14 @@ public class ContainerAnvil extends Container { + this(i, playerinventory, ContainerAccess.a); +@@ -38,12 +40,14 @@ public class ContainerAnvil extends ContainerAnvilAbstract { - @Override - public boolean isAllowed(EntityHuman entityhuman) { -- return (entityhuman.abilities.canInstantlyBuild || entityhuman.expLevel >= ContainerAnvil.this.levelCost.get()) && ContainerAnvil.this.levelCost.get() > 0 && this.hasItem(); -+ return (entityhuman.abilities.canInstantlyBuild || entityhuman.expLevel >= ContainerAnvil.this.levelCost.get()) && (bypassCost || ContainerAnvil.this.levelCost.get() > 0) && this.hasItem(); // Purpur - } - - @Override - public ItemStack a(EntityHuman entityhuman, ItemStack itemstack) { -+ if (net.pl3x.purpur.event.inventory.AnvilTakeResultEvent.getHandlerList().getRegisteredListeners().length > 0) new net.pl3x.purpur.event.inventory.AnvilTakeResultEvent(entityhuman.getBukkitEntity(), getBukkitView(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)).callEvent(); // Purpur - if (!entityhuman.abilities.canInstantlyBuild) { -+ if (bypassCost) ((EntityPlayer) entityhuman).lastSentExp = -1; else // Purpur - entityhuman.levelDown(-ContainerAnvil.this.levelCost.get()); - } - -@@ -136,6 +141,12 @@ public class ContainerAnvil extends Container { + @Override + protected boolean b(EntityHuman entityhuman, boolean flag) { +- return (entityhuman.abilities.canInstantlyBuild || entityhuman.expLevel >= this.levelCost.get()) && this.levelCost.get() > 0; ++ return (entityhuman.abilities.canInstantlyBuild || entityhuman.expLevel >= this.levelCost.get()) && (bypassCost || this.levelCost.get() > 0); // Purpur } + @Override + protected ItemStack a(EntityHuman entityhuman, ItemStack itemstack) { ++ if (net.pl3x.purpur.event.inventory.AnvilTakeResultEvent.getHandlerList().getRegisteredListeners().length > 0) new net.pl3x.purpur.event.inventory.AnvilTakeResultEvent(entityhuman.getBukkitEntity(), getBukkitView(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)).callEvent(); // Purpur + if (!entityhuman.abilities.canInstantlyBuild) { ++ if (bypassCost) ((EntityPlayer) entityhuman).lastSentExp = -1; else // Purpur + entityhuman.levelDown(-this.levelCost.get()); + } + +@@ -94,6 +98,12 @@ public class ContainerAnvil extends ContainerAnvilAbstract { + + @Override public void e() { + // Purpur start + bypassCost = false; @@ -58,7 +50,7 @@ index 286b930dd..d418c0441 100644 ItemStack itemstack = this.repairInventory.getItem(0); this.levelCost.set(1); -@@ -212,7 +223,7 @@ public class ContainerAnvil extends Container { +@@ -170,7 +180,7 @@ public class ContainerAnvil extends ContainerAnvilAbstract { int i2 = (Integer) map1.get(enchantment); i2 = l1 == i2 ? i2 + 1 : Math.max(i2, l1); @@ -67,7 +59,7 @@ index 286b930dd..d418c0441 100644 if (this.player.abilities.canInstantlyBuild || itemstack.getItem() == Items.ENCHANTED_BOOK) { flag3 = true; -@@ -224,7 +235,7 @@ public class ContainerAnvil extends Container { +@@ -182,7 +192,7 @@ public class ContainerAnvil extends ContainerAnvilAbstract { Enchantment enchantment1 = (Enchantment) iterator1.next(); if (enchantment1 != enchantment && !enchantment.isCompatible(enchantment1)) { @@ -76,7 +68,7 @@ index 286b930dd..d418c0441 100644 ++i; } } -@@ -295,6 +306,13 @@ public class ContainerAnvil extends Container { +@@ -253,6 +263,13 @@ public class ContainerAnvil extends ContainerAnvilAbstract { this.levelCost.set(maximumRepairCost - 1); // CraftBukkit } @@ -88,9 +80,9 @@ index 286b930dd..d418c0441 100644 + // Purpur end + if (this.levelCost.get() >= maximumRepairCost && !this.player.abilities.canInstantlyBuild) { // CraftBukkit - itemstack1 = ItemStack.a; + itemstack1 = ItemStack.b; } -@@ -316,6 +334,12 @@ public class ContainerAnvil extends Container { +@@ -274,6 +291,12 @@ public class ContainerAnvil extends ContainerAnvilAbstract { org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareAnvilEvent(getBukkitView(), itemstack1); // CraftBukkit this.c(); @@ -103,14 +95,6 @@ index 286b930dd..d418c0441 100644 } } -@@ -349,6 +373,7 @@ public class ContainerAnvil extends Container { - - itemstack = itemstack1.cloneItemStack(); - if (i == 2) { -+ if (net.pl3x.purpur.event.inventory.AnvilTakeResultEvent.getHandlerList().getRegisteredListeners().length > 0) new net.pl3x.purpur.event.inventory.AnvilTakeResultEvent(entityhuman.getBukkitEntity(), getBukkitView(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)).callEvent(); // Purpur - if (!this.a(itemstack1, 3, 39, true)) { - return ItemStack.a; - } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java index 9374c2706..d45f356be 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java diff --git a/patches/server/0050-Implement-configurable-villager-brain-ticks.patch b/patches/server/0026-Configurable-villager-brain-ticks.patch similarity index 58% rename from patches/server/0050-Implement-configurable-villager-brain-ticks.patch rename to patches/server/0026-Configurable-villager-brain-ticks.patch index baac4e994..3200d6b14 100644 --- a/patches/server/0050-Implement-configurable-villager-brain-ticks.patch +++ b/patches/server/0026-Configurable-villager-brain-ticks.patch @@ -1,63 +1,60 @@ -From d24813dc8ea3cdfc744c0cf5c9a0e50e6e0ca301 Mon Sep 17 00:00:00 2001 +From c748533f4bbafc0c16603882168e2cbf46960287 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Tue, 23 Jul 2019 08:28:21 -0500 -Subject: [PATCH] Implement configurable villager brain ticks +Subject: [PATCH] Configurable villager brain ticks --- src/main/java/net/minecraft/server/EntityVillager.java | 6 ++++++ - src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 4 ++++ - 2 files changed, 10 insertions(+) + src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 7 +++++++ + 2 files changed, 13 insertions(+) diff --git a/src/main/java/net/minecraft/server/EntityVillager.java b/src/main/java/net/minecraft/server/EntityVillager.java -index 5b0de0d9d..843f22260 100644 +index bf019043a..7925c8991 100644 --- a/src/main/java/net/minecraft/server/EntityVillager.java +++ b/src/main/java/net/minecraft/server/EntityVillager.java -@@ -53,6 +53,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation +@@ -58,6 +58,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation }, MemoryModuleType.MEETING_POINT, (entityvillager, villageplacetype) -> { - return villageplacetype == VillagePlaceType.r; + return villageplacetype == VillagePlaceType.s; }); + private final int brainTickOffset; // Purpur public EntityVillager(EntityTypes entitytypes, World world) { this(entitytypes, world, VillagerType.PLAINS); -@@ -66,6 +67,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation +@@ -70,6 +71,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation + this.getNavigation().d(true); this.setCanPickupLoot(true); this.setVillagerData(this.getVillagerData().withType(villagertype).withProfession(VillagerProfession.NONE)); - this.bo = this.a(new Dynamic(DynamicOpsNBT.a, new NBTTagCompound())); -+ brainTickOffset = getRandom().nextInt(100); // Purpur ++ this.brainTickOffset = getRandom().nextInt(100); // Purpur } - // Purpur start -@@ -180,6 +182,10 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation + @Override +@@ -166,6 +168,10 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation + protected void mobTick() { mobTick(false); } protected void mobTick(boolean inactive) { - // Paper end - this.world.getMethodProfiler().enter("brain"); + this.world.getMethodProfiler().enter("villagerBrain"); + // Purpur start + boolean tick = (world.getTime() + brainTickOffset) % world.purpurConfig.villagerBrainTicks == 0; + if (((WorldServer) world).getMinecraftServer().lagging ? tick : world.purpurConfig.villagerUseBrainTicksOnlyWhenLagging || tick) + // Purpur end if (!inactive) this.getBehaviorController().a((WorldServer) this.world, this); // CraftBukkit - decompile error // Paper - this.world.getMethodProfiler().exit(); - if (!this.et() && this.bB > 0) { + if (this.bM) { + this.bM = false; diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 9c60855d6..f1ed653b3 100644 +index bd9b82dad..8f8e61442 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -737,10 +737,14 @@ public class PurpurWorldConfig { - public boolean villagerRidable = false; - public boolean villagerRidableInWater = false; - public boolean villagerRequireShiftToMount = true; +@@ -82,4 +82,11 @@ public class PurpurWorldConfig { + playerSpawnInvulnerableTicks = getInt("gameplay-mechanics.player.spawn-invulnerable-ticks", playerSpawnInvulnerableTicks); + playerInvulnerableWhileAcceptingResourcePack = getBoolean("gameplay-mechanics.player.invulnerable-while-accepting-resource-pack", playerInvulnerableWhileAcceptingResourcePack); + } ++ + public int villagerBrainTicks = 1; + public boolean villagerUseBrainTicksOnlyWhenLagging = true; - private void villagerSettings() { - villagerRidable = getBoolean("mobs.villager.ridable", villagerRidable); - villagerRidableInWater = getBoolean("mobs.villager.ridable-in-water", villagerRidableInWater); - villagerRequireShiftToMount = getBoolean("mobs.villager.require-shift-to-mount", villagerRequireShiftToMount); ++ private void villagerSettings() { + villagerBrainTicks = getInt("mobs.villager.brain-ticks", villagerBrainTicks); + villagerUseBrainTicksOnlyWhenLagging = getBoolean("mobs.villager.use-brain-ticks-only-when-lagging", villagerUseBrainTicksOnlyWhenLagging); - } - - public boolean villagerTraderRidable = false; ++ } + } -- 2.26.2 diff --git a/patches/server/0026-Ender-dragon-always-drop-egg.patch b/patches/server/0026-Ender-dragon-always-drop-egg.patch deleted file mode 100644 index db46b1d48..000000000 --- a/patches/server/0026-Ender-dragon-always-drop-egg.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 6e1fb8864c1acffb17aa73a8d86d2090c574f2b1 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Fri, 7 Feb 2020 04:42:57 -0600 -Subject: [PATCH] Ender dragon always drop egg - ---- - src/main/java/net/minecraft/server/EnderDragonBattle.java | 5 +++-- - src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 2 ++ - 2 files changed, 5 insertions(+), 2 deletions(-) - -diff --git a/src/main/java/net/minecraft/server/EnderDragonBattle.java b/src/main/java/net/minecraft/server/EnderDragonBattle.java -index 687efa022..ead334607 100644 ---- a/src/main/java/net/minecraft/server/EnderDragonBattle.java -+++ b/src/main/java/net/minecraft/server/EnderDragonBattle.java -@@ -21,7 +21,7 @@ public class EnderDragonBattle { - private static final Logger LOGGER = LogManager.getLogger(); - private static final Predicate b = IEntitySelector.a.and(IEntitySelector.a(0.0D, 128.0D, 0.0D, 192.0D)); - public final BossBattleServer bossBattle; -- public final WorldServer d; // CraftBukkit PAIL private -> public, rename world -+ public final WorldServer d; public WorldServer getWorld() { return d; } // Purpur - OBFHELPER - private final List e; - private final ShapeDetector f; - private int g; -@@ -358,7 +358,7 @@ public class EnderDragonBattle { - this.bossBattle.setVisible(false); - this.a(true); - this.n(); -- if (!this.l) { -+ if (getWorld().purpurConfig.enderDragonAlwaysDropsEggBlock || !wasPreviouslyKilled()) { // Purpur - always place dragon egg - this.d.setTypeUpdate(this.d.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, WorldGenEndTrophy.a), Blocks.DRAGON_EGG.getBlockData()); - } - -@@ -439,6 +439,7 @@ public class EnderDragonBattle { - - } - -+ public boolean wasPreviouslyKilled() { return d(); } // Purpur - OBFHELPER; - public boolean d() { - return this.l; - } -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 56b67c408..cc6f8563b 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -206,11 +206,13 @@ public class PurpurWorldConfig { - public boolean enderDragonRidableInWater = false; - public boolean enderDragonRequireShiftToMount = true; - public double enderDragonMaxY = 256D; -+ public boolean enderDragonAlwaysDropsEggBlock = false; - private void enderDragonSettings() { - enderDragonRidable = getBoolean("mobs.ender_dragon.ridable", enderDragonRidable); - enderDragonRidableInWater = getBoolean("mobs.ender_dragon.ridable-in-water", enderDragonRidableInWater); - enderDragonRequireShiftToMount = getBoolean("mobs.ender_dragon.require-shift-to-mount", enderDragonRequireShiftToMount); - enderDragonMaxY = getDouble("mobs.ender_dragon.ridable-max-y", enderDragonMaxY); -+ enderDragonAlwaysDropsEggBlock = getBoolean("mobs.ender_dragon.always-drop-egg-block", enderDragonAlwaysDropsEggBlock); - } - - public boolean endermanRidable = false; --- -2.26.2 - diff --git a/patches/server/0062-Alternative-Keepalive-Handling.patch b/patches/server/0027-Alternative-Keepalive-Handling.patch similarity index 86% rename from patches/server/0062-Alternative-Keepalive-Handling.patch rename to patches/server/0027-Alternative-Keepalive-Handling.patch index 5f6675c3e..526856747 100644 --- a/patches/server/0062-Alternative-Keepalive-Handling.patch +++ b/patches/server/0027-Alternative-Keepalive-Handling.patch @@ -1,13 +1,13 @@ -From ac25e2c7e75e91a4b246439af0fe5d213b369c34 Mon Sep 17 00:00:00 2001 +From 753e40b5abc1fde5f33910bd9b5a77898f44ea0d Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Fri, 11 Oct 2019 00:17:39 -0500 Subject: [PATCH] Alternative Keepalive Handling --- .../server/PacketPlayInKeepAlive.java | 1 + - .../minecraft/server/PlayerConnection.java | 27 +++++++++++++++++++ + .../minecraft/server/PlayerConnection.java | 26 +++++++++++++++++++ .../java/net/pl3x/purpur/PurpurConfig.java | 5 ++++ - 3 files changed, 33 insertions(+) + 3 files changed, 32 insertions(+) diff --git a/src/main/java/net/minecraft/server/PacketPlayInKeepAlive.java b/src/main/java/net/minecraft/server/PacketPlayInKeepAlive.java index 8e93f1540..470f92c4f 100644 @@ -22,7 +22,7 @@ index 8e93f1540..470f92c4f 100644 return this.a; } diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java -index 148beb1b6..82faee937 100644 +index 85016aa76..d2d96eacc 100644 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java @@ -75,6 +75,7 @@ public class PlayerConnection implements PacketListenerPlayIn { @@ -55,13 +55,12 @@ index 148beb1b6..82faee937 100644 if (this.isPendingPing()) { if (!this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // check keepalive limit, don't fire if already disconnected PlayerConnection.LOGGER.warn("{} was kicked due to keepalive timeout!", this.player.getName()); // more info -@@ -2683,6 +2699,17 @@ public class PlayerConnection implements PacketListenerPlayIn { +@@ -2704,6 +2720,16 @@ public class PlayerConnection implements PacketListenerPlayIn { @Override public void a(PacketPlayInKeepAlive packetplayinkeepalive) { + // Purpur start + if (net.pl3x.purpur.PurpurConfig.useAlternateKeepAlive) { -+ PlayerConnectionUtils.ensureMainThread(packetplayinkeepalive, this, player.getWorldServer()); // This SHOULD be on the main thread... + long id = packetplayinkeepalive.getId(); + if (keepAlives.size() > 0 && keepAlives.contains(id)) { + int ping = (int) (SystemUtils.getMonotonicMillis() - id); @@ -74,10 +73,10 @@ index 148beb1b6..82faee937 100644 if (this.awaitingKeepAlive && packetplayinkeepalive.b() == this.h) { int i = (int) (SystemUtils.getMonotonicMillis() - this.lastKeepAlive); diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java -index 72ad9dce7..ed2a31277 100644 +index d8b826f6b..571917ffa 100644 --- a/src/main/java/net/pl3x/purpur/PurpurConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java -@@ -144,6 +144,11 @@ public class PurpurConfig { +@@ -152,6 +152,11 @@ public class PurpurConfig { laggingThreshold = getDouble("settings.lagging-threshold", laggingThreshold); } @@ -86,9 +85,9 @@ index 72ad9dce7..ed2a31277 100644 + useAlternateKeepAlive = getBoolean("settings.use-alternate-keepalive", useAlternateKeepAlive); + } + - public static boolean dontSendUselessEntityPackets = false; - private static void dontSendUselessEntityPackets() { - dontSendUselessEntityPackets = getBoolean("settings.dont-send-useless-entity-packets", dontSendUselessEntityPackets); + public static boolean barrelSixRows = false; + public static boolean enderChestSixRows = false; + public static boolean enderChestPermissionRows = false; -- 2.26.2 diff --git a/patches/server/0013-Silk-touch-spawners.patch b/patches/server/0028-Silk-touch-spawners.patch similarity index 50% rename from patches/server/0013-Silk-touch-spawners.patch rename to patches/server/0028-Silk-touch-spawners.patch index da53e75bc..3a0ca02ec 100644 --- a/patches/server/0013-Silk-touch-spawners.patch +++ b/patches/server/0028-Silk-touch-spawners.patch @@ -1,19 +1,21 @@ -From bc8027e2ac0110d889bc31b125cbff05b13b7e70 Mon Sep 17 00:00:00 2001 +From 836c6dcd9b9cb396daeec8ddd59834f431bf1275 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Thu, 9 May 2019 14:27:37 -0500 Subject: [PATCH] Silk touch spawners --- src/main/java/net/minecraft/server/Block.java | 1 + - .../net/minecraft/server/BlockMobSpawner.java | 34 +++++++++++++++++++ - .../net/minecraft/server/EntityTypes.java | 12 +++++++ - 3 files changed, 47 insertions(+) + .../net/minecraft/server/BlockMobSpawner.java | 35 +++++++++++++++++++ + .../net/minecraft/server/ItemSpawner.java | 23 ++++++++++++ + src/main/java/net/minecraft/server/Items.java | 2 +- + 4 files changed, 60 insertions(+), 1 deletion(-) + create mode 100644 src/main/java/net/minecraft/server/ItemSpawner.java diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/minecraft/server/Block.java -index 66244a9d0..9c7faa2bd 100644 +index 81725611d..c7232047c 100644 --- a/src/main/java/net/minecraft/server/Block.java +++ b/src/main/java/net/minecraft/server/Block.java -@@ -502,6 +502,7 @@ public class Block implements IMaterial { +@@ -226,6 +226,7 @@ public class Block extends BlockBase implements IMaterial { iblockdata.dropNaturally(world, blockposition, itemstack); } @@ -22,7 +24,7 @@ index 66244a9d0..9c7faa2bd 100644 if (!world.isClientSide && !itemstack.isEmpty() && world.getGameRules().getBoolean(GameRules.DO_TILE_DROPS)) { float f = 0.5F; diff --git a/src/main/java/net/minecraft/server/BlockMobSpawner.java b/src/main/java/net/minecraft/server/BlockMobSpawner.java -index 5296fdf16..69d04f6cb 100644 +index 16f9fb8e5..cf059e982 100644 --- a/src/main/java/net/minecraft/server/BlockMobSpawner.java +++ b/src/main/java/net/minecraft/server/BlockMobSpawner.java @@ -11,6 +11,40 @@ public class BlockMobSpawner extends BlockTileEntity { @@ -66,47 +68,56 @@ index 5296fdf16..69d04f6cb 100644 @Override public void dropNaturally(IBlockData iblockdata, World world, BlockPosition blockposition, ItemStack itemstack) { super.dropNaturally(iblockdata, world, blockposition, itemstack); -diff --git a/src/main/java/net/minecraft/server/EntityTypes.java b/src/main/java/net/minecraft/server/EntityTypes.java -index 5a7494947..8e8d392a1 100644 ---- a/src/main/java/net/minecraft/server/EntityTypes.java -+++ b/src/main/java/net/minecraft/server/EntityTypes.java -@@ -136,10 +136,17 @@ public class EntityTypes { - return (EntityTypes) IRegistry.a((IRegistry) IRegistry.ENTITY_TYPE, s, (Object) entitytypes_a.a(s)); - } +@@ -23,6 +57,7 @@ public class BlockMobSpawner extends BlockTileEntity { -+ // Purpur start -+ public static EntityTypes getFromKey(MinecraftKey key) { -+ return IRegistry.ENTITY_TYPE.get(key); -+ } -+ // Purpur end + @Override + public int getExpDrop(IBlockData iblockdata, World world, BlockPosition blockposition, ItemStack itemstack) { ++ if (isSilkTouch(itemstack)) return 0; // Purpur + int i = 15 + world.random.nextInt(15) + world.random.nextInt(15); + + return i; +diff --git a/src/main/java/net/minecraft/server/ItemSpawner.java b/src/main/java/net/minecraft/server/ItemSpawner.java +new file mode 100644 +index 000000000..7dc68ffe9 +--- /dev/null ++++ b/src/main/java/net/minecraft/server/ItemSpawner.java +@@ -0,0 +1,23 @@ ++package net.minecraft.server; + - public static MinecraftKey getName(EntityTypes entitytypes) { - return IRegistry.ENTITY_TYPE.getKey(entitytypes); - } - -+ public static Optional> getType(String name) { return a(name); } // Purpur - OBFHELPER - public static Optional> a(String s) { - return IRegistry.ENTITY_TYPE.getOptional(MinecraftKey.a(s)); - } -@@ -263,6 +270,10 @@ public class EntityTypes { - public String getName() { - return IRegistry.ENTITY_TYPE.getKey(this).getKey(); - } -+ -+ public String getTranslatedName() { -+ return getNameComponent().getString(); ++public class ItemSpawner extends ItemBlock { ++ public ItemSpawner(Block block, Info info) { ++ super(block, info); + } - // Purpur end - - public String f() { -@@ -273,6 +284,7 @@ public class EntityTypes { - return this.bg; - } - -+ public IChatBaseComponent getNameComponent() { return g(); } // Purpur - OBFHELPER - public IChatBaseComponent g() { - if (this.bh == null) { - this.bh = new ChatMessage(this.f(), new Object[0]); ++ ++ @Override ++ protected boolean a(BlockPosition blockposition, World world, EntityHuman entityhuman, ItemStack itemstack, IBlockData iblockdata) { ++ boolean handled = super.a(blockposition, world, entityhuman, itemstack, iblockdata); ++ if (entityhuman.getBukkitEntity().hasPermission("purpur.place.spawners")) { ++ TileEntity spawner = world.getTileEntity(blockposition); ++ if (spawner instanceof TileEntityMobSpawner && itemstack.hasTag()) { ++ NBTTagCompound tag = itemstack.getTag(); ++ if (tag.hasKey("Purpur.mob_type")) { ++ EntityTypes.getType(tag.getString("Purpur.mob_type")).ifPresent(type -> ++ ((TileEntityMobSpawner) spawner).getSpawner().setMobName(type)); ++ } ++ } ++ } ++ return handled; ++ } ++} +diff --git a/src/main/java/net/minecraft/server/Items.java b/src/main/java/net/minecraft/server/Items.java +index 89a9eec99..619c40b27 100644 +--- a/src/main/java/net/minecraft/server/Items.java ++++ b/src/main/java/net/minecraft/server/Items.java +@@ -180,7 +180,7 @@ public class Items { + public static final Item ct = a(Blocks.PURPUR_BLOCK, CreativeModeTab.b); + public static final Item cu = a(Blocks.PURPUR_PILLAR, CreativeModeTab.b); + public static final Item cv = a(Blocks.PURPUR_STAIRS, CreativeModeTab.b); +- public static final Item cw = a(Blocks.SPAWNER); ++ public static final Item cw = a(Blocks.SPAWNER, new ItemSpawner(Blocks.SPAWNER, new Item.Info().a(EnumItemRarity.EPIC))); // Purpur + public static final Item cx = a(Blocks.OAK_STAIRS, CreativeModeTab.b); + public static final Item cy = a(Blocks.CHEST, CreativeModeTab.c); + public static final Item cz = a(Blocks.DIAMOND_ORE, CreativeModeTab.b); -- 2.26.2 diff --git a/patches/server/0117-MC-125757-Fix-Always-increment-arrow-despawn-counter.patch b/patches/server/0029-MC-125757-Fix-Always-increment-arrow-despawn-counter.patch similarity index 63% rename from patches/server/0117-MC-125757-Fix-Always-increment-arrow-despawn-counter.patch rename to patches/server/0029-MC-125757-Fix-Always-increment-arrow-despawn-counter.patch index 9b20c1d92..2c7049fe5 100644 --- a/patches/server/0117-MC-125757-Fix-Always-increment-arrow-despawn-counter.patch +++ b/patches/server/0029-MC-125757-Fix-Always-increment-arrow-despawn-counter.patch @@ -1,4 +1,4 @@ -From b9d6a9418690fed6b75e7f4ca46dcc7a9fa94200 Mon Sep 17 00:00:00 2001 +From 6bfbeb52d059e6241fbd31cb1c909fc4f4cd4e98 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Fri, 21 Feb 2020 17:04:51 -0600 Subject: [PATCH] MC-125757 Fix - Always increment arrow despawn counter @@ -8,33 +8,30 @@ Subject: [PATCH] MC-125757 Fix - Always increment arrow despawn counter 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/minecraft/server/EntityArrow.java b/src/main/java/net/minecraft/server/EntityArrow.java -index ae44f878f..4ab857853 100644 +index 6195a45e3..8ee76ca4b 100644 --- a/src/main/java/net/minecraft/server/EntityArrow.java +++ b/src/main/java/net/minecraft/server/EntityArrow.java -@@ -154,6 +154,8 @@ public abstract class EntityArrow extends Entity implements IProjectile { +@@ -124,11 +124,13 @@ public abstract class EntityArrow extends IProjectile { this.extinguish(); } + this.checkDespawnCounter(); // Purpur - moved from below - MC-125757 + if (this.inGround && !flag) { - if (this.aq != iblockdata && this.world.a(this.getBoundingBox().g(0.06D))) { - this.inGround = false; -@@ -161,7 +163,7 @@ public abstract class EntityArrow extends Entity implements IProjectile { - this.despawnCounter = 0; - this.as = 0; + if (this.an != iblockdata && this.u()) { + this.z(); } else if (!this.world.isClientSide) { -- this.i(); -+ // this.i(); // Purpur moved up - MC-125757 +- this.h(); ++ // this.h(); // Purpur - moved up MC-125757 } - ++this.d; -@@ -282,6 +284,7 @@ public abstract class EntityArrow extends Entity implements IProjectile { - } + ++this.c; +@@ -254,6 +256,7 @@ public abstract class EntityArrow extends IProjectile { + } + protected void checkDespawnCounter() { i(); } // Purpur - OBFHELPER - protected void i() { + protected void h() { ++this.despawnCounter; if (this.despawnCounter >= (fromPlayer == PickupStatus.CREATIVE_ONLY ? world.paperConfig.creativeArrowDespawnRate : (fromPlayer == PickupStatus.DISALLOWED ? world.paperConfig.nonPlayerArrowDespawnRate : ((this instanceof EntityThrownTrident) ? world.spigotConfig.tridentDespawnRate : world.spigotConfig.arrowDespawnRate)))) { // Spigot // Paper - TODO: Extract this to init? -- diff --git a/patches/server/0118-MC-168772-Fix-Add-turtle-egg-block-options.patch b/patches/server/0030-MC-168772-Fix-Add-turtle-egg-block-options.patch similarity index 73% rename from patches/server/0118-MC-168772-Fix-Add-turtle-egg-block-options.patch rename to patches/server/0030-MC-168772-Fix-Add-turtle-egg-block-options.patch index e205f3335..18fdbca5a 100644 --- a/patches/server/0118-MC-168772-Fix-Add-turtle-egg-block-options.patch +++ b/patches/server/0030-MC-168772-Fix-Add-turtle-egg-block-options.patch @@ -1,4 +1,4 @@ -From c127ee26dc42f88155087b8dcdf7b61c067088ec Mon Sep 17 00:00:00 2001 +From 3cdc8d59eb0d60369650ba50ff81fb65b9f5ecc3 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Thu, 6 Jun 2019 22:15:46 -0500 Subject: [PATCH] MC-168772 Fix - Add turtle egg block options @@ -9,14 +9,14 @@ Subject: [PATCH] MC-168772 Fix - Add turtle egg block options 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/minecraft/server/BlockTurtleEgg.java b/src/main/java/net/minecraft/server/BlockTurtleEgg.java -index cb36334e4..aa83ef169 100644 +index 553c8affa..92cca6c44 100644 --- a/src/main/java/net/minecraft/server/BlockTurtleEgg.java +++ b/src/main/java/net/minecraft/server/BlockTurtleEgg.java -@@ -157,6 +157,23 @@ public class BlockTurtleEgg extends Block { +@@ -163,6 +163,23 @@ public class BlockTurtleEgg extends Block { } private boolean a(World world, Entity entity) { -- return entity instanceof EntityTurtle ? false : (entity instanceof EntityLiving && !(entity instanceof EntityHuman) ? world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) : true); +- return !(entity instanceof EntityTurtle) && !(entity instanceof EntityBat) ? (!(entity instanceof EntityLiving) ? false : entity instanceof EntityHuman || world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) : false; + // Purpur start - fix MC-168772 + if (entity instanceof EntityTurtle) { + return false; @@ -38,11 +38,11 @@ index cb36334e4..aa83ef169 100644 } } diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 81969d2dc..296274896 100644 +index 8f8e61442..3367cfd47 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -191,6 +191,15 @@ public class PurpurWorldConfig { - signRightClickEdit = getBoolean("blocks.sign.right-click-edit", signRightClickEdit); +@@ -83,6 +83,15 @@ public class PurpurWorldConfig { + playerInvulnerableWhileAcceptingResourcePack = getBoolean("gameplay-mechanics.player.invulnerable-while-accepting-resource-pack", playerInvulnerableWhileAcceptingResourcePack); } + public boolean turtleEggsBreakFromExpOrbs = true; @@ -54,9 +54,9 @@ index 81969d2dc..296274896 100644 + turtleEggsBreakFromMinecarts = getBoolean("blocks.turtle_egg.break-from-minecarts", turtleEggsBreakFromMinecarts); + } + - public boolean boatEjectPlayersOnLand = false; - public float armorstandStepHeight = 0.0F; - public boolean controllableMinecarts = false; + public int villagerBrainTicks = 1; + public boolean villagerUseBrainTicksOnlyWhenLagging = true; + private void villagerSettings() { -- 2.26.2 diff --git a/patches/server/0119-MC-4-Fix-Item-position-desync.patch b/patches/server/0031-MC-4-Fix-Item-position-desync.patch similarity index 77% rename from patches/server/0119-MC-4-Fix-Item-position-desync.patch rename to patches/server/0031-MC-4-Fix-Item-position-desync.patch index 86d1beb27..de5cec3e0 100644 --- a/patches/server/0119-MC-4-Fix-Item-position-desync.patch +++ b/patches/server/0031-MC-4-Fix-Item-position-desync.patch @@ -1,4 +1,4 @@ -From fbb5d60cfb97f9a166ecea0361abdbcb72385ee7 Mon Sep 17 00:00:00 2001 +From eabe6232aad2e846f11e6082b5d9510ad3aa658c Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 6 Jul 2019 21:12:58 -0500 Subject: [PATCH] MC-4 Fix - Item position desync @@ -6,28 +6,28 @@ Subject: [PATCH] MC-4 Fix - Item position desync --- src/main/java/net/minecraft/server/EntityTrackerEntry.java | 6 ++++++ src/main/java/net/minecraft/server/PacketPlayOutEntity.java | 2 ++ - src/main/java/net/pl3x/purpur/PurpurConfig.java | 2 ++ - 3 files changed, 10 insertions(+) + src/main/java/net/pl3x/purpur/PurpurConfig.java | 5 +++++ + 3 files changed, 13 insertions(+) diff --git a/src/main/java/net/minecraft/server/EntityTrackerEntry.java b/src/main/java/net/minecraft/server/EntityTrackerEntry.java -index adf7c9180..20d98c206 100644 +index f75c09d44..10cae053b 100644 --- a/src/main/java/net/minecraft/server/EntityTrackerEntry.java +++ b/src/main/java/net/minecraft/server/EntityTrackerEntry.java -@@ -132,6 +132,12 @@ public class EntityTrackerEntry { +@@ -133,6 +133,12 @@ public class EntityTrackerEntry { double vec3d_dz = this.tracker.locZ() - 2.44140625E-4D*(this.zLoc); boolean flag1 = (vec3d_dx * vec3d_dx + vec3d_dy * vec3d_dy + vec3d_dz * vec3d_dz) >= 7.62939453125E-6D; // Paper end - reduce allocation of Vec3D here -+ // Purpur start - fixes MC-4 ++ // Purpur start - fix MC-4 + if (net.pl3x.purpur.PurpurConfig.fixItemPositionDesync && this.tracker instanceof EntityItem) { + Vec3D loc = PacketPlayOutEntity.decrypt(PacketPlayOutEntity.encrypt(tracker.locX()), PacketPlayOutEntity.encrypt(tracker.locY()), PacketPlayOutEntity.encrypt(tracker.locZ())); + tracker.setPosition(loc.getX(), loc.getY(), loc.getZ()); + } -+ // Purpur end ++ // Purpur end - fix MC-4 Packet packet1 = null; boolean flag2 = flag1 || this.tickCounter % 60 == 0; boolean flag3 = Math.abs(i - this.yRot) >= 1 || Math.abs(j - this.xRot) >= 1; diff --git a/src/main/java/net/minecraft/server/PacketPlayOutEntity.java b/src/main/java/net/minecraft/server/PacketPlayOutEntity.java -index 5b1d95935..0010448e3 100644 +index e5da2b19c..6d9d52e4f 100644 --- a/src/main/java/net/minecraft/server/PacketPlayOutEntity.java +++ b/src/main/java/net/minecraft/server/PacketPlayOutEntity.java @@ -14,10 +14,12 @@ public class PacketPlayOutEntity implements Packet { @@ -44,20 +44,19 @@ index 5b1d95935..0010448e3 100644 return (new Vec3D((double) i, (double) j, (double) k)).a(2.44140625E-4D); } diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java -index 68bad6a13..ab88636ca 100644 +index 571917ffa..4ac6fa44b 100644 --- a/src/main/java/net/pl3x/purpur/PurpurConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java -@@ -163,8 +163,10 @@ public class PurpurConfig { +@@ -175,4 +175,9 @@ public class PurpurConfig { + InventoryType.ENDER_CHEST.setDefaultSize(enderChestSixRows ? 54 : 27); + enderChestPermissionRows = getBoolean("settings.blocks.ender_chest.use-permissions-for-rows", enderChestPermissionRows); } - - public static boolean dontSendUselessEntityPackets = false; ++ + public static boolean fixItemPositionDesync = false; - private static void dontSendUselessEntityPackets() { - dontSendUselessEntityPackets = getBoolean("settings.dont-send-useless-entity-packets", dontSendUselessEntityPackets); ++ private static void fixItemPositionDesync() { + fixItemPositionDesync = getBoolean("settings.fix-item-position-desync", fixItemPositionDesync); - } - - public static boolean barrelSixRows = false; ++ } + } -- 2.26.2 diff --git a/patches/server/0007-Fix-vanilla-command-permission-handler.patch b/patches/server/0032-Fix-vanilla-command-permission-handler.patch similarity index 96% rename from patches/server/0007-Fix-vanilla-command-permission-handler.patch rename to patches/server/0032-Fix-vanilla-command-permission-handler.patch index fe97111da..32993412f 100644 --- a/patches/server/0007-Fix-vanilla-command-permission-handler.patch +++ b/patches/server/0032-Fix-vanilla-command-permission-handler.patch @@ -1,4 +1,4 @@ -From 630e9dc4596781fdc3a496147184301aac82dd31 Mon Sep 17 00:00:00 2001 +From 7627086a8214c93b0a9c2e61981377aeb30553c1 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 28 Mar 2020 01:51:32 -0500 Subject: [PATCH] Fix vanilla command permission handler diff --git a/patches/server/0033-Logger-settings-suppressing-pointless-logs.patch b/patches/server/0033-Logger-settings-suppressing-pointless-logs.patch new file mode 100644 index 000000000..2b32493e8 --- /dev/null +++ b/patches/server/0033-Logger-settings-suppressing-pointless-logs.patch @@ -0,0 +1,54 @@ +From f6bc74d6d724638fe97b923a0caa06deced56b92 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Sat, 19 Oct 2019 00:52:12 -0500 +Subject: [PATCH] Logger settings (suppressing pointless logs) + +--- + .../java/net/minecraft/server/AdvancementDataPlayer.java | 1 + + src/main/java/net/pl3x/purpur/PurpurConfig.java | 7 +++++++ + .../java/org/bukkit/craftbukkit/legacy/CraftLegacy.java | 1 + + 3 files changed, 9 insertions(+) + +diff --git a/src/main/java/net/minecraft/server/AdvancementDataPlayer.java b/src/main/java/net/minecraft/server/AdvancementDataPlayer.java +index 57b9d1344..c89e843e2 100644 +--- a/src/main/java/net/minecraft/server/AdvancementDataPlayer.java ++++ b/src/main/java/net/minecraft/server/AdvancementDataPlayer.java +@@ -165,6 +165,7 @@ public class AdvancementDataPlayer { + if (advancement == null) { + // CraftBukkit start + if (entry.getKey().getNamespace().equals("minecraft")) { ++ if (!net.pl3x.purpur.PurpurConfig.loggerSuppressIgnoredAdvancementWarnings) // Purpur + AdvancementDataPlayer.LOGGER.warn("Ignored advancement '{}' in progress file {} - it doesn't exist anymore?", entry.getKey(), this.f); + } + // CraftBukkit end +diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java +index 4ac6fa44b..b520cd28b 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java +@@ -180,4 +180,11 @@ public class PurpurConfig { + private static void fixItemPositionDesync() { + fixItemPositionDesync = getBoolean("settings.fix-item-position-desync", fixItemPositionDesync); + } ++ ++ public static boolean loggerSuppressInitLegacyMaterialError = false; ++ public static boolean loggerSuppressIgnoredAdvancementWarnings = false; ++ private static void loggerSettings() { ++ loggerSuppressInitLegacyMaterialError = getBoolean("settings.logger.suppress-init-legacy-material-errors", loggerSuppressInitLegacyMaterialError); ++ loggerSuppressIgnoredAdvancementWarnings = getBoolean("settings.logger.suppress-ignored-advancement-warnings", loggerSuppressIgnoredAdvancementWarnings); ++ } + } +diff --git a/src/main/java/org/bukkit/craftbukkit/legacy/CraftLegacy.java b/src/main/java/org/bukkit/craftbukkit/legacy/CraftLegacy.java +index b14333ce9..d25204f7d 100644 +--- a/src/main/java/org/bukkit/craftbukkit/legacy/CraftLegacy.java ++++ b/src/main/java/org/bukkit/craftbukkit/legacy/CraftLegacy.java +@@ -254,6 +254,7 @@ public final class CraftLegacy { + } + + static { ++ if (!net.pl3x.purpur.PurpurConfig.loggerSuppressInitLegacyMaterialError) // Purpur + System.err.println("Initializing Legacy Material Support. Unless you have legacy plugins and/or data this is a bug!"); + if (MinecraftServer.getServer() != null && MinecraftServer.getServer().isDebugging()) { + new Exception().printStackTrace(); +-- +2.26.2 + diff --git a/patches/server/0034-Campfires-have-regen-effect.patch b/patches/server/0034-Campfires-have-regen-effect.patch deleted file mode 100644 index b3df30504..000000000 --- a/patches/server/0034-Campfires-have-regen-effect.patch +++ /dev/null @@ -1,203 +0,0 @@ -From 9b77d9886cde434034d95d1dd086971e27e85222 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sun, 19 May 2019 18:11:53 -0500 -Subject: [PATCH] Campfires have regen effect - ---- - .../net/minecraft/server/BlockCampfire.java | 2 +- - .../net/minecraft/server/EntityLiving.java | 15 ++++++++-- - .../net/minecraft/server/EntityPotion.java | 26 ++++++++++++++++ - .../minecraft/server/TileEntityCampfire.java | 30 +++++++++++++++++++ - .../net/pl3x/purpur/PurpurWorldConfig.java | 23 ++++++++++++++ - 5 files changed, 92 insertions(+), 4 deletions(-) - -diff --git a/src/main/java/net/minecraft/server/BlockCampfire.java b/src/main/java/net/minecraft/server/BlockCampfire.java -index 6303be944..65f8d803b 100644 ---- a/src/main/java/net/minecraft/server/BlockCampfire.java -+++ b/src/main/java/net/minecraft/server/BlockCampfire.java -@@ -8,7 +8,7 @@ public class BlockCampfire extends BlockTileEntity implements IBlockWaterlogged - - protected static final VoxelShape a = Block.a(0.0D, 0.0D, 0.0D, 16.0D, 7.0D, 16.0D); - public static final BlockStateBoolean b = BlockProperties.r; -- public static final BlockStateBoolean c = BlockProperties.y; -+ public static final BlockStateBoolean c = BlockProperties.y; public static BlockStateBoolean signalFire() { return c; } // Purpur - OBFHELPER - public static final BlockStateBoolean d = BlockProperties.C; - public static final BlockStateDirection e = BlockProperties.N; - private static final VoxelShape f = Block.a(6.0D, 0.0D, 6.0D, 10.0D, 16.0D, 10.0D); -diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java -index 685538793..aaaa98318 100644 ---- a/src/main/java/net/minecraft/server/EntityLiving.java -+++ b/src/main/java/net/minecraft/server/EntityLiving.java -@@ -2799,10 +2799,19 @@ public abstract class EntityLiving extends Entity { - - public boolean hasLineOfSight(Entity entity) { - if (this.world != entity.world) return false; // CraftBukkit - SPIGOT-5675, SPIGOT-5798, MC-149563 -- Vec3D vec3d = new Vec3D(this.locX(), this.getHeadY(), this.locZ()); -- Vec3D vec3d1 = new Vec3D(entity.locX(), entity.getHeadY(), entity.locZ()); -+ // Purpur start -+ return hasLineOfSight(entity.locX(), entity.getHeadY(), entity.locZ()); -+ } -+ -+ public boolean hasLineOfSight(TileEntity te) { -+ return hasLineOfSight(te.position.getX() + 0.5, te.position.getY() + 0.5, te.position.getZ() + 0.5); -+ } - -- return this.world.rayTrace(new RayTrace(vec3d, vec3d1, RayTrace.BlockCollisionOption.COLLIDER, RayTrace.FluidCollisionOption.NONE, this)).getType() == MovingObjectPosition.EnumMovingObjectType.MISS; -+ public boolean hasLineOfSight(double x, double y, double z) { -+ Vec3D start = new Vec3D(locX(), getHeadY(), locZ()); -+ Vec3D end = new Vec3D(x, y, z); -+ return world.rayTrace(new RayTrace(start, end, RayTrace.BlockCollisionOption.COLLIDER, RayTrace.FluidCollisionOption.NONE, this)).getType() == MovingObjectPosition.EnumMovingObjectType.MISS; -+ // Purpur end - } - - @Override -diff --git a/src/main/java/net/minecraft/server/EntityPotion.java b/src/main/java/net/minecraft/server/EntityPotion.java -index b56b021b4..fcc5a5c23 100644 ---- a/src/main/java/net/minecraft/server/EntityPotion.java -+++ b/src/main/java/net/minecraft/server/EntityPotion.java -@@ -92,6 +92,7 @@ public class EntityPotion extends EntityProjectile { - } else { - this.a(list, movingobjectposition.getType() == MovingObjectPosition.EnumMovingObjectType.ENTITY ? ((MovingObjectPositionEntity) movingobjectposition).getEntity() : null); - } -+ splashCampfires(list); // Purpur - } - - int i = potionregistry.b() ? 2007 : 2002; -@@ -101,6 +102,31 @@ public class EntityPotion extends EntityProjectile { - } - } - -+ // Purpur start -+ private void splashCampfires(List list) { -+ AxisAlignedBB aabb = getBoundingBox().grow(4.0D, 2.0D, 4.0D); -+ for (int x = (int) aabb.minX; x <= aabb.maxX; x++) { -+ for (int z = (int) aabb.minZ; z <= aabb.maxZ; z++) { -+ for (int y = (int) aabb.minY; y <= aabb.maxY; y++) { -+ BlockPosition pos = new BlockPosition(x, y, z); -+ TileEntity te = world.getTileEntity(pos); -+ if (te instanceof TileEntityCampfire) { -+ for (MobEffect effect : list) { -+ if (effect.getMobEffect() == MobEffects.REGENERATION) { -+ for (int i = 0; i < 6 ; i++) { -+ ((WorldServer) world).sendParticles(((WorldServer) world).players, null, Particles.HEART, te.position.getX(), te.position.getY() + 1, te.position.getZ(), 1, 0.5, 0.5, 0.5, 0, true); -+ } -+ ((TileEntityCampfire) te).splashed = true; -+ break; -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ // Purpur end -+ - private void splash() { - AxisAlignedBB axisalignedbb = this.getBoundingBox().grow(4.0D, 2.0D, 4.0D); - List list = this.world.a(EntityLiving.class, axisalignedbb, EntityPotion.e); -diff --git a/src/main/java/net/minecraft/server/TileEntityCampfire.java b/src/main/java/net/minecraft/server/TileEntityCampfire.java -index a1580b8c6..618ca2d76 100644 ---- a/src/main/java/net/minecraft/server/TileEntityCampfire.java -+++ b/src/main/java/net/minecraft/server/TileEntityCampfire.java -@@ -14,6 +14,7 @@ public class TileEntityCampfire extends TileEntity implements Clearable, ITickab - private final NonNullList items; - public final int[] cookingTimes; - public final int[] cookingTotalTimes; -+ public boolean splashed = false; // Purpur - - public TileEntityCampfire() { - super(TileEntityTypes.CAMPFIRE); -@@ -34,6 +35,27 @@ public class TileEntityCampfire extends TileEntity implements Clearable, ITickab - - } else { - if (flag) { -+ // Purpur start -+ if ((splashed || !world.purpurConfig.campfireRequireRegenPotion) && world.purpurConfig.campfireRegenInterval > 0 && world.getTime() % world.purpurConfig.campfireRegenInterval == 0L) { -+ boolean signalBoost = getBlock().get(BlockCampfire.signalFire()); -+ int duration = signalBoost ? world.purpurConfig.campfireRegenBoostDuration : world.purpurConfig.campfireRegenDuration; -+ byte amp = (byte) (signalBoost ? world.purpurConfig.campfireRegenBoostAmp : world.purpurConfig.campfireRegenAmp); -+ int range = signalBoost ? world.purpurConfig.campfireRegenBoostRange : world.purpurConfig.campfireRegenRange; -+ MobEffect regeneration = new MobEffect(MobEffects.REGENERATION, duration, amp, true, true); -+ world.getEntitiesByClass(EntityHuman.class, new AxisAlignedBB(position).grow(range)).forEach(entityhuman -> { -+ boolean noLineOfSign = true; -+ if (!signalBoost && world.purpurConfig.campfireRegenRequireLineOfSight) { -+ noLineOfSign = false; -+ } -+ if (signalBoost && world.purpurConfig.campfireRegenBoostRequireLineOfSight) { -+ noLineOfSign = false; -+ } -+ if (noLineOfSign || entityhuman.hasLineOfSight(this)) { -+ entityhuman.addEffect(regeneration); -+ } -+ }); -+ } -+ // Purpur end - this.h(); - } else { - for (int i = 0; i < this.items.size(); ++i) { -@@ -41,6 +63,7 @@ public class TileEntityCampfire extends TileEntity implements Clearable, ITickab - this.cookingTimes[i] = MathHelper.clamp(this.cookingTimes[i] - 2, 0, this.cookingTotalTimes[i]); - } - } -+ splashed = false; // Purpur - } - - } -@@ -137,6 +160,12 @@ public class TileEntityCampfire extends TileEntity implements Clearable, ITickab - System.arraycopy(aint, 0, this.cookingTotalTimes, 0, Math.min(this.cookingTotalTimes.length, aint.length)); - } - -+ // Purpur start -+ if (nbttagcompound.hasKey("Purpur.splashed")) { -+ splashed = nbttagcompound.getBoolean("Purpur.splashed"); -+ } -+ // Purpur end -+ - } - - @Override -@@ -144,6 +173,7 @@ public class TileEntityCampfire extends TileEntity implements Clearable, ITickab - this.d(nbttagcompound); - nbttagcompound.setIntArray("CookingTimes", this.cookingTimes); - nbttagcompound.setIntArray("CookingTotalTimes", this.cookingTotalTimes); -+ nbttagcompound.setBoolean("Purpur.splashed", splashed); // Purpur - return nbttagcompound; - } - -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 94744c78b..d8d95d787 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -71,6 +71,29 @@ public class PurpurWorldConfig { - return PurpurConfig.config.getString("world-settings." + worldName + "." + path, PurpurConfig.config.getString("world-settings.default." + path)); - } - -+ public int campfireRegenInterval = 0; -+ public int campfireRegenDuration = 80; -+ public int campfireRegenRange = 5; -+ public int campfireRegenAmp = 0; -+ public boolean campfireRegenRequireLineOfSight = true; -+ public int campfireRegenBoostDuration = 0; -+ public int campfireRegenBoostRange = 10; -+ public int campfireRegenBoostAmp = 1; -+ public boolean campfireRegenBoostRequireLineOfSight = false; -+ public boolean campfireRequireRegenPotion = true; -+ private void campfireSettings() { -+ campfireRegenInterval = getInt("blocks.campfire.regen.interval", campfireRegenInterval); -+ campfireRegenDuration = getInt("blocks.campfire.regen.duration", campfireRegenDuration); -+ campfireRegenRange = getInt("blocks.campfire.regen.range", campfireRegenRange); -+ campfireRegenAmp = getInt("blocks.campfire.regen.amplifier", campfireRegenAmp); -+ campfireRegenRequireLineOfSight = getBoolean("blocks.campfire.regen.require-line-of-sight", campfireRegenRequireLineOfSight); -+ campfireRegenBoostDuration = getInt("blocks.campfire.regen.boost-duration", campfireRegenBoostDuration); -+ campfireRegenBoostRange = getInt("blocks.campfire.regen.boost-range", campfireRegenBoostRange); -+ campfireRegenBoostAmp = getInt("blocks.campfire.regen.boost-amplifier", campfireRegenBoostAmp); -+ campfireRegenBoostRequireLineOfSight = getBoolean("blocks.campfire.regen.boost-require-line-of-sight", campfireRegenBoostRequireLineOfSight); -+ campfireRequireRegenPotion = getBoolean("blocks.campfire.regen.requires-potion-to-activate", campfireRequireRegenPotion); -+ } -+ - public boolean farmlandGetsMoistFromBelow = false; - private void farmlandSettings() { - farmlandGetsMoistFromBelow = getBoolean("blocks.farmland.gets-moist-from-below", farmlandGetsMoistFromBelow); --- -2.26.2 - diff --git a/patches/server/0011-Disable-outdated-build-check.patch b/patches/server/0034-Disable-outdated-build-check.patch similarity index 77% rename from patches/server/0011-Disable-outdated-build-check.patch rename to patches/server/0034-Disable-outdated-build-check.patch index 6dfe616e9..2b67b4afc 100644 --- a/patches/server/0011-Disable-outdated-build-check.patch +++ b/patches/server/0034-Disable-outdated-build-check.patch @@ -1,4 +1,4 @@ -From 2094c83c3f1ac0a54a44a83a97dd93640767160f Mon Sep 17 00:00:00 2001 +From 1926ac0f3c9733e80ebe5b761edc0b805bc59ed0 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 15 Dec 2019 12:53:59 -0600 Subject: [PATCH] Disable outdated build check @@ -8,14 +8,14 @@ Subject: [PATCH] Disable outdated build check 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index 77b9ce301..b007840a5 100644 +index 8879c6421..2434a5af8 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java -@@ -259,7 +259,7 @@ public class Main { +@@ -252,7 +252,7 @@ public class Main { System.setProperty(TerminalConsoleAppender.JLINE_OVERRIDE_PROPERTY, "false"); // Paper } -- if (false && Main.class.getPackage().getImplementationVendor() != null && System.getProperty("IReallyKnowWhatIAmDoingISwear") == null) { +- if (Main.class.getPackage().getImplementationVendor() != null && System.getProperty("IReallyKnowWhatIAmDoingISwear") == null) { + if (false) { // Main.class.getPackage().getImplementationVendor() != null && System.getProperty("IReallyKnowWhatIAmDoingISwear") == null) { // Purpur Date buildDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").parse(Main.class.getPackage().getImplementationVendor()); // Paper diff --git a/patches/server/0035-Giants-AI-settings.patch b/patches/server/0035-Giants-AI-settings.patch new file mode 100644 index 000000000..5db8cff5f --- /dev/null +++ b/patches/server/0035-Giants-AI-settings.patch @@ -0,0 +1,200 @@ +From 44ff3cae556ebd8727d61cfc675f6d482b69fed6 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Sun, 12 May 2019 00:43:12 -0500 +Subject: [PATCH] Giants AI settings + +--- + .../minecraft/server/AttributeMapBase.java | 4 +- + .../java/net/minecraft/server/Entity.java | 2 +- + .../minecraft/server/EntityGiantZombie.java | 63 ++++++++++++++++++- + .../minecraft/server/EntityInsentient.java | 6 +- + .../net/minecraft/server/EntityLiving.java | 2 +- + .../net/pl3x/purpur/PurpurWorldConfig.java | 17 +++++ + 6 files changed, 87 insertions(+), 7 deletions(-) + +diff --git a/src/main/java/net/minecraft/server/AttributeMapBase.java b/src/main/java/net/minecraft/server/AttributeMapBase.java +index c57e23e16..772079a27 100644 +--- a/src/main/java/net/minecraft/server/AttributeMapBase.java ++++ b/src/main/java/net/minecraft/server/AttributeMapBase.java +@@ -41,8 +41,8 @@ public class AttributeMapBase { + }).collect(Collectors.toList()); + } + +- @Nullable +- public AttributeModifiable a(AttributeBase attributebase) { ++ @Nullable public AttributeModifiable getAttribute(AttributeBase attributebase) { return a(attributebase); } // Purpur - OBFHELPER ++ @Nullable public AttributeModifiable a(AttributeBase attributebase) { + return (AttributeModifiable) this.b.computeIfAbsent(attributebase, (attributebase1) -> { + return this.d.a(this::a, attributebase1); + }); +diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java +index 3709f3386..ee36c537d 100644 +--- a/src/main/java/net/minecraft/server/Entity.java ++++ b/src/main/java/net/minecraft/server/Entity.java +@@ -136,7 +136,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke + public double D; + public double E; + public double F; +- public float G; ++ public float G; public void setStepHeight(float stepHeight) { this.G = stepHeight; } // Purpur - OBFHELPER + public boolean noclip; + public float I; + protected final Random random; +diff --git a/src/main/java/net/minecraft/server/EntityGiantZombie.java b/src/main/java/net/minecraft/server/EntityGiantZombie.java +index 37618126f..4b8edc8df 100644 +--- a/src/main/java/net/minecraft/server/EntityGiantZombie.java ++++ b/src/main/java/net/minecraft/server/EntityGiantZombie.java +@@ -4,7 +4,10 @@ public class EntityGiantZombie extends EntityMonster { + + public EntityGiantZombie(EntityTypes entitytypes, World world) { + super(entitytypes, world); +- this.safeFallDistance = 10.0F; // Purpur ++ // Purpur start ++ this.safeFallDistance = 10.0F; ++ setStepHeight(world.purpurConfig.giantStepHeight); ++ // Purpur end + } + + @Override +@@ -18,6 +21,62 @@ public class EntityGiantZombie extends EntityMonster { + + @Override + public float a(BlockPosition blockposition, IWorldReader iworldreader) { +- return iworldreader.y(blockposition) - 0.5F; ++ return super.a(blockposition, iworldreader); // Purpur - fix light requirements for natural spawns + } ++ ++ // Purpur start ++ @Override ++ protected void initPathfinder() { ++ if (world.purpurConfig.giantHaveAI) { ++ this.goalSelector.a(0, new PathfinderGoalFloat(this)); ++ this.goalSelector.a(7, new PathfinderGoalRandomStrollLand(this, 1.0D)); ++ this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 16.0F)); ++ this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); ++ this.goalSelector.a(5, new PathfinderGoalMoveTowardsRestriction(this, 1.0D)); ++ if (world.purpurConfig.giantHaveHostileAI) { ++ this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, 1.0D, false)); ++ this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this).a(EntityPigZombie.class)); ++ this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); ++ this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillager.class, false)); ++ this.targetSelector.a(4, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, true)); ++ this.targetSelector.a(5, new PathfinderGoalNearestAttackableTarget<>(this, EntityTurtle.class, true)); ++ } ++ } ++ } ++ ++ @Override ++ protected void initAttributes(World world) { ++ if (world != null) { ++ getAttributeMap().getAttribute(GenericAttributes.MAX_HEALTH).setValue(world.purpurConfig.giantMaxHealth); ++ getAttributeMap().getAttribute(GenericAttributes.MOVEMENT_SPEED).setValue(world.purpurConfig.giantMovementSpeed); ++ getAttributeMap().getAttribute(GenericAttributes.ATTACK_DAMAGE).setValue(world.purpurConfig.giantAttackDamage); ++ } ++ } ++ ++ @Override ++ public GroupDataEntity prepare(GeneratorAccess world, DifficultyDamageScaler difficulty, EnumMobSpawn enummobspawn, GroupDataEntity groupDataEntity, NBTTagCompound nbt) { ++ GroupDataEntity groupData = super.prepare(world, difficulty, enummobspawn, groupDataEntity, nbt); ++ if (groupData == null) { ++ setEquipmentBasedOnDifficulty(difficulty); ++ setEnchantmentBasedOnDifficulty(difficulty); ++ } ++ return groupData; ++ } ++ ++ @Override ++ protected void setEquipmentBasedOnDifficulty(DifficultyDamageScaler difficulty) { ++ super.setEquipmentBasedOnDifficulty(difficulty); ++ // TODO make configurable ++ if (random.nextFloat() < (world.getDifficulty() == EnumDifficulty.HARD ? 0.1F : 0.05F)) { ++ setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.IRON_SWORD)); ++ } ++ } ++ ++ @Override ++ public float getJumpHeight() { ++ // make giants jump as high as everything else relative to their size ++ // 1.0 makes bottom of feet about as high as their waist when they jump ++ return world.purpurConfig.giantJumpHeight; ++ } ++ // Purpur end + } +diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java +index 605bbf017..93714e5d9 100644 +--- a/src/main/java/net/minecraft/server/EntityInsentient.java ++++ b/src/main/java/net/minecraft/server/EntityInsentient.java +@@ -939,6 +939,7 @@ public abstract class EntityInsentient extends EntityLiving { + return f; + } + ++ protected void setEquipmentBasedOnDifficulty(DifficultyDamageScaler difficultydamagescaler) { a(difficultydamagescaler); } // Purpur - OBFHELPER + protected void a(DifficultyDamageScaler difficultydamagescaler) { + if (this.random.nextFloat() < 0.15F * difficultydamagescaler.d()) { + int i = this.random.nextInt(2); +@@ -1046,6 +1047,7 @@ public abstract class EntityInsentient extends EntityLiving { + } + } + ++ protected void setEnchantmentBasedOnDifficulty(DifficultyDamageScaler difficultydamagescaler) { b(difficultydamagescaler); } // Purpur - OBFHELPER + protected void b(DifficultyDamageScaler difficultydamagescaler) { + float f = difficultydamagescaler.d(); + +@@ -1078,10 +1080,12 @@ public abstract class EntityInsentient extends EntityLiving { + } else { + this.setLeftHanded(false); + } +- ++ initAttributes(world.getMinecraftWorld()); // Purpur + return groupdataentity; + } + ++ protected void initAttributes(World world) {} // Purpur ++ + public boolean es() { + return false; + } +diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java +index f917cd5df..03477c6e9 100644 +--- a/src/main/java/net/minecraft/server/EntityLiving.java ++++ b/src/main/java/net/minecraft/server/EntityLiving.java +@@ -2150,7 +2150,7 @@ public abstract class EntityLiving extends Entity { + this.enderTeleportTo(vec3d.x, vec3d.y, vec3d.z); + } + +- protected float dI() { ++ protected float dI() { return getJumpHeight(); } public float getJumpHeight() { // Purpur - OBFHELPER + return 0.42F * this.getBlockJumpFactor(); + } + +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index 3367cfd47..2db2dd26d 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -92,6 +92,23 @@ public class PurpurWorldConfig { + turtleEggsBreakFromMinecarts = getBoolean("blocks.turtle_egg.break-from-minecarts", turtleEggsBreakFromMinecarts); + } + ++ public float giantStepHeight = 2.0F; ++ public float giantJumpHeight = 1.0F; ++ public double giantMaxHealth = 100.0D; ++ public double giantMovementSpeed = 0.5D; ++ public double giantAttackDamage = 50.0D; ++ public boolean giantHaveAI = false; ++ public boolean giantHaveHostileAI = false; ++ private void giantSettings() { ++ giantStepHeight = (float) getDouble("mobs.giant.step-height", giantStepHeight); ++ giantJumpHeight = (float) getDouble("mobs.giant.jump-height", giantJumpHeight); ++ giantMaxHealth = getDouble("mobs.giant.max-health", giantMaxHealth); ++ giantMovementSpeed = getDouble("mobs.giant.movement-speed", giantMovementSpeed); ++ giantAttackDamage = getDouble("mobs.giant.attack-damage", giantAttackDamage); ++ giantHaveAI = getBoolean("mobs.giant.have-ai", giantHaveAI); ++ giantHaveHostileAI = getBoolean("mobs.giant.have-hostile-ai", giantHaveHostileAI); ++ } ++ + public int villagerBrainTicks = 1; + public boolean villagerUseBrainTicksOnlyWhenLagging = true; + private void villagerSettings() { +-- +2.26.2 + diff --git a/patches/server/0036-Campfires-burn-out-in-rain.patch b/patches/server/0036-Campfires-burn-out-in-rain.patch deleted file mode 100644 index bb4753ff0..000000000 --- a/patches/server/0036-Campfires-burn-out-in-rain.patch +++ /dev/null @@ -1,82 +0,0 @@ -From e95433c37c07dd0343e1336c9a49661974ddc28f Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Thu, 6 Jun 2019 21:30:49 -0500 -Subject: [PATCH] Campfires burn out in rain - ---- - src/main/java/net/minecraft/server/Block.java | 2 +- - .../net/minecraft/server/BlockCampfire.java | 17 ++++++++++++++++- - .../java/net/pl3x/purpur/PurpurWorldConfig.java | 2 ++ - 3 files changed, 19 insertions(+), 2 deletions(-) - -diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/minecraft/server/Block.java -index 9c7faa2bd..97e553b38 100644 ---- a/src/main/java/net/minecraft/server/Block.java -+++ b/src/main/java/net/minecraft/server/Block.java -@@ -395,7 +395,7 @@ public class Block implements IMaterial { - PacketDebug.a(world, blockposition); - } - -- public int a(IWorldReader iworldreader) { -+ public int a(IWorldReader world) { return tickRate(world); } public int tickRate(IWorldReader world) { // Purpur - OBFHELPER - return 10; - } - -diff --git a/src/main/java/net/minecraft/server/BlockCampfire.java b/src/main/java/net/minecraft/server/BlockCampfire.java -index 65f8d803b..3b95dfaaa 100644 ---- a/src/main/java/net/minecraft/server/BlockCampfire.java -+++ b/src/main/java/net/minecraft/server/BlockCampfire.java -@@ -7,7 +7,7 @@ import javax.annotation.Nullable; - public class BlockCampfire extends BlockTileEntity implements IBlockWaterlogged { - - protected static final VoxelShape a = Block.a(0.0D, 0.0D, 0.0D, 16.0D, 7.0D, 16.0D); -- public static final BlockStateBoolean b = BlockProperties.r; -+ public static final BlockStateBoolean b = BlockProperties.r; public static BlockStateBoolean lit() { return b; } // Purpur - OBFHELPER - public static final BlockStateBoolean c = BlockProperties.y; public static BlockStateBoolean signalFire() { return c; } // Purpur - OBFHELPER - public static final BlockStateBoolean d = BlockProperties.C; - public static final BlockStateDirection e = BlockProperties.N; -@@ -74,6 +74,21 @@ public class BlockCampfire extends BlockTileEntity implements IBlockWaterlogged - return (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.getBlockData().set(BlockCampfire.d, flag)).set(BlockCampfire.c, this.h(world.getType(blockposition.down())))).set(BlockCampfire.b, !flag)).set(BlockCampfire.e, blockactioncontext.f()); - } - -+ // Purpur start -+ @Override -+ public void tick(IBlockData iblockdata, WorldServer world, BlockPosition pos, Random random) { -+ if (world.purpurConfig.campfireBurnOutInRain && world.getTime() % 20 == 0L && iblockdata.get(lit()) && world.isRainingAt(pos.shift(EnumDirection.UP))) { -+ world.setTypeAndData(pos, iblockdata.set(lit(), false), 3); -+ } -+ world.getBlockTickList().a(pos, this, tickRate(world)); -+ } -+ -+ @Override -+ public int tickRate(IWorldReader world) { -+ return 1; -+ } -+ // Purpur end -+ - @Override - public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { - if ((Boolean) iblockdata.get(BlockCampfire.d)) { -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 8c84431e5..a761b2c73 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -81,6 +81,7 @@ public class PurpurWorldConfig { - public int campfireRegenBoostAmp = 1; - public boolean campfireRegenBoostRequireLineOfSight = false; - public boolean campfireRequireRegenPotion = true; -+ public boolean campfireBurnOutInRain = false; - private void campfireSettings() { - campfireRegenInterval = getInt("blocks.campfire.regen.interval", campfireRegenInterval); - campfireRegenDuration = getInt("blocks.campfire.regen.duration", campfireRegenDuration); -@@ -92,6 +93,7 @@ public class PurpurWorldConfig { - campfireRegenBoostAmp = getInt("blocks.campfire.regen.boost-amplifier", campfireRegenBoostAmp); - campfireRegenBoostRequireLineOfSight = getBoolean("blocks.campfire.regen.boost-require-line-of-sight", campfireRegenBoostRequireLineOfSight); - campfireRequireRegenPotion = getBoolean("blocks.campfire.regen.requires-potion-to-activate", campfireRequireRegenPotion); -+ campfireBurnOutInRain = getBoolean("blocks.campfire.burn-out-in-rain", campfireBurnOutInRain); - } - - public boolean farmlandGetsMoistFromBelow = false; --- -2.26.2 - diff --git a/patches/server/0036-Illusioners-AI-settings.patch b/patches/server/0036-Illusioners-AI-settings.patch new file mode 100644 index 000000000..16a351524 --- /dev/null +++ b/patches/server/0036-Illusioners-AI-settings.patch @@ -0,0 +1,55 @@ +From 441173477d957d8b8af8f86d72cb50e22c99bfb8 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Fri, 5 Jul 2019 11:09:25 -0500 +Subject: [PATCH] Illusioners AI settings + +--- + .../net/minecraft/server/EntityIllagerIllusioner.java | 11 +++++++++++ + src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 9 +++++++++ + 2 files changed, 20 insertions(+) + +diff --git a/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java b/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java +index 76fd0513f..1a5b9a0f0 100644 +--- a/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java ++++ b/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java +@@ -40,6 +40,17 @@ public class EntityIllagerIllusioner extends EntityIllagerWizard implements IRan + return EntityMonster.eS().a(GenericAttributes.MOVEMENT_SPEED, 0.5D).a(GenericAttributes.FOLLOW_RANGE, 18.0D).a(GenericAttributes.MAX_HEALTH, 32.0D); + } + ++ // Purpur start ++ @Override ++ protected void initAttributes(World world) { ++ if (world != null) { ++ getAttributeMap().getAttribute(GenericAttributes.MOVEMENT_SPEED).setValue(world.purpurConfig.illusionerMovementSpeed); ++ getAttributeMap().getAttribute(GenericAttributes.FOLLOW_RANGE).setValue(world.purpurConfig.illusionerFollowRange); ++ getAttributeMap().getAttribute(GenericAttributes.MAX_HEALTH).setValue(world.purpurConfig.illusionerMaxHealth); ++ } ++ } ++ // Purpur end ++ + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + this.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.BOW)); +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index 2db2dd26d..d79a7e242 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -109,6 +109,15 @@ public class PurpurWorldConfig { + giantHaveHostileAI = getBoolean("mobs.giant.have-hostile-ai", giantHaveHostileAI); + } + ++ public double illusionerMaxHealth = 32.0D; ++ public double illusionerMovementSpeed = 0.5D; ++ public double illusionerFollowRange = 18.0D; ++ private void illusionerSettings() { ++ illusionerMaxHealth = getDouble("mobs.illusioner.max-health", illusionerMaxHealth); ++ illusionerMovementSpeed = getDouble("mobs.illusioner.movement-speed", illusionerMovementSpeed); ++ illusionerFollowRange = getDouble("mobs.illusioner.follow-range", illusionerFollowRange); ++ } ++ + public int villagerBrainTicks = 1; + public boolean villagerUseBrainTicksOnlyWhenLagging = true; + private void villagerSettings() { +-- +2.26.2 + diff --git a/patches/server/0037-Campfires-should-fall-with-gravity.patch b/patches/server/0037-Campfires-should-fall-with-gravity.patch deleted file mode 100644 index 0db8bb44b..000000000 --- a/patches/server/0037-Campfires-should-fall-with-gravity.patch +++ /dev/null @@ -1,83 +0,0 @@ -From dd79210dd48515873533b7a50d14eab5db537495 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Thu, 23 May 2019 16:20:21 -0500 -Subject: [PATCH] Campfires should fall with gravity - ---- - .../java/net/minecraft/server/BlockCampfire.java | 16 ++++++++++++++-- - .../java/net/pl3x/purpur/PurpurWorldConfig.java | 2 ++ - 2 files changed, 16 insertions(+), 2 deletions(-) - -diff --git a/src/main/java/net/minecraft/server/BlockCampfire.java b/src/main/java/net/minecraft/server/BlockCampfire.java -index 3b95dfaaa..418fa6d1f 100644 ---- a/src/main/java/net/minecraft/server/BlockCampfire.java -+++ b/src/main/java/net/minecraft/server/BlockCampfire.java -@@ -9,7 +9,7 @@ public class BlockCampfire extends BlockTileEntity implements IBlockWaterlogged - protected static final VoxelShape a = Block.a(0.0D, 0.0D, 0.0D, 16.0D, 7.0D, 16.0D); - public static final BlockStateBoolean b = BlockProperties.r; public static BlockStateBoolean lit() { return b; } // Purpur - OBFHELPER - public static final BlockStateBoolean c = BlockProperties.y; public static BlockStateBoolean signalFire() { return c; } // Purpur - OBFHELPER -- public static final BlockStateBoolean d = BlockProperties.C; -+ public static final BlockStateBoolean d = BlockProperties.C; public static BlockStateBoolean waterlogged() { return d; } // Purpur - OBFHELPER - public static final BlockStateDirection e = BlockProperties.N; - private static final VoxelShape f = Block.a(6.0D, 0.0D, 6.0D, 10.0D, 16.0D, 10.0D); - -@@ -75,8 +75,19 @@ public class BlockCampfire extends BlockTileEntity implements IBlockWaterlogged - } - - // Purpur start -+ @Override -+ public void onPlace(IBlockData iblockdata, World world, BlockPosition pos, IBlockData iblockdata1, boolean flag) { -+ world.getBlockTickList().a(pos, this, tickRate(world)); -+ } -+ - @Override - public void tick(IBlockData iblockdata, WorldServer world, BlockPosition pos, Random random) { -+ if (world.purpurConfig.campfireFallWithGravity && BlockFalling.canFallThrough(world.getType(pos.down())) && pos.getY() >= 0) { -+ world.addEntity(new EntityFallingBlock(world, pos.getX() + 0.5D, pos.getY(), pos.getZ() + 0.5D, world.getType(pos))); -+ } -+ if (iblockdata.get(waterlogged()) && iblockdata.get(lit())) { -+ world.setTypeAndData(pos, iblockdata.set(lit(), false), 3); -+ } - if (world.purpurConfig.campfireBurnOutInRain && world.getTime() % 20 == 0L && iblockdata.get(lit()) && world.isRainingAt(pos.shift(EnumDirection.UP))) { - world.setTypeAndData(pos, iblockdata.set(lit(), false), 3); - } -@@ -91,6 +102,7 @@ public class BlockCampfire extends BlockTileEntity implements IBlockWaterlogged - - @Override - public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { -+ generatoraccess.getBlockTickList().a(blockposition, this, tickRate(generatoraccess)); // Purpur - Campfires should fall with gravity - if ((Boolean) iblockdata.get(BlockCampfire.d)) { - generatoraccess.getFluidTickList().a(blockposition, FluidTypes.WATER, FluidTypes.WATER.a((IWorldReader) generatoraccess)); - } -@@ -119,7 +131,7 @@ public class BlockCampfire extends BlockTileEntity implements IBlockWaterlogged - - @Override - public boolean place(GeneratorAccess generatoraccess, BlockPosition blockposition, IBlockData iblockdata, Fluid fluid) { -- if (!(Boolean) iblockdata.get(BlockProperties.C) && fluid.getType() == FluidTypes.WATER) { -+ if (!(Boolean) iblockdata.get(BlockCampfire.d) && fluid.getType() == FluidTypes.WATER) { // Purpur - boolean flag = (Boolean) iblockdata.get(BlockCampfire.b); - - if (flag) { -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index a761b2c73..d6405b2ec 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -82,6 +82,7 @@ public class PurpurWorldConfig { - public boolean campfireRegenBoostRequireLineOfSight = false; - public boolean campfireRequireRegenPotion = true; - public boolean campfireBurnOutInRain = false; -+ public boolean campfireFallWithGravity = false; - private void campfireSettings() { - campfireRegenInterval = getInt("blocks.campfire.regen.interval", campfireRegenInterval); - campfireRegenDuration = getInt("blocks.campfire.regen.duration", campfireRegenDuration); -@@ -94,6 +95,7 @@ public class PurpurWorldConfig { - campfireRegenBoostRequireLineOfSight = getBoolean("blocks.campfire.regen.boost-require-line-of-sight", campfireRegenBoostRequireLineOfSight); - campfireRequireRegenPotion = getBoolean("blocks.campfire.regen.requires-potion-to-activate", campfireRequireRegenPotion); - campfireBurnOutInRain = getBoolean("blocks.campfire.burn-out-in-rain", campfireBurnOutInRain); -+ campfireFallWithGravity = getBoolean("blocks.campfire.fall-with-gravity", campfireFallWithGravity); - } - - public boolean farmlandGetsMoistFromBelow = false; --- -2.26.2 - diff --git a/patches/server/0016-Zombie-horse-naturally-spawn.patch b/patches/server/0037-Zombie-horse-naturally-spawn.patch similarity index 68% rename from patches/server/0016-Zombie-horse-naturally-spawn.patch rename to patches/server/0037-Zombie-horse-naturally-spawn.patch index 784a83537..fd8138dc1 100644 --- a/patches/server/0016-Zombie-horse-naturally-spawn.patch +++ b/patches/server/0037-Zombie-horse-naturally-spawn.patch @@ -1,24 +1,24 @@ -From cae7ca5f7ee6a31f421a401abed8141b9037c9a3 Mon Sep 17 00:00:00 2001 +From 08672f6e86a74640abb8a9b29f440da692558a85 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 7 Jul 2019 19:52:16 -0500 Subject: [PATCH] Zombie horse naturally spawn --- .../java/net/minecraft/server/WorldServer.java | 18 ++++++++++++------ - .../net/pl3x/purpur/PurpurWorldConfig.java | 2 ++ - 2 files changed, 14 insertions(+), 6 deletions(-) + .../net/pl3x/purpur/PurpurWorldConfig.java | 5 +++++ + 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 24cd10c96..edf24791b 100644 +index 093fa8074..7955a079b 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -1038,12 +1038,18 @@ public class WorldServer extends World { +@@ -622,12 +622,18 @@ public class WorldServer extends World implements GeneratorAccessSeed { boolean flag1 = this.getGameRules().getBoolean(GameRules.DO_MOB_SPAWNING) && this.random.nextDouble() < (double) difficultydamagescaler.b() * paperConfig.skeleHorseSpawnChance; // Paper if (flag1) { - EntityHorseSkeleton entityhorseskeleton = (EntityHorseSkeleton) EntityTypes.SKELETON_HORSE.a((World) this); - -- entityhorseskeleton.r(true); +- entityhorseskeleton.t(true); - entityhorseskeleton.setAgeRaw(0); - entityhorseskeleton.setPosition((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ()); - this.addEntity(entityhorseskeleton, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); // CraftBukkit @@ -36,23 +36,21 @@ index 24cd10c96..edf24791b 100644 + // Purpur end } - this.strikeLightning(new EntityLightning(this, (double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D, flag1), org.bukkit.event.weather.LightningStrikeEvent.Cause.WEATHER); // CraftBukkit + EntityLightning entitylightning = (EntityLightning) EntityTypes.LIGHTNING_BOLT.a((World) this); diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 96a66926f..4c7469b90 100644 +index d79a7e242..3dad7bded 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -657,9 +657,11 @@ public class PurpurWorldConfig { - - public boolean zombieHorseCanSwim = false; - public boolean zombieHorseRidableInWater = false; -+ public double zombieHorseSpawnChance = 0.0D; - private void zombieHorseSettings() { - zombieHorseCanSwim = getBoolean("mobs.zombie_horse.can-swim", zombieHorseCanSwim); - zombieHorseRidableInWater = getBoolean("mobs.zombie_horse.ridable-in-water", zombieHorseRidableInWater); -+ zombieHorseSpawnChance = getDouble("mobs.zombie_horse.spawn-chance", zombieHorseSpawnChance); +@@ -124,4 +124,9 @@ public class PurpurWorldConfig { + villagerBrainTicks = getInt("mobs.villager.brain-ticks", villagerBrainTicks); + villagerUseBrainTicksOnlyWhenLagging = getBoolean("mobs.villager.use-brain-ticks-only-when-lagging", villagerUseBrainTicksOnlyWhenLagging); } - - public boolean zombiePigmanRidable = false; ++ ++ public double zombieHorseSpawnChance = 0.0D; ++ private void zombieHorseSettings() { ++ zombieHorseSpawnChance = getDouble("mobs.zombie_horse.spawn-chance", zombieHorseSpawnChance); ++ } + } -- 2.26.2 diff --git a/patches/server/0017-Charged-creeper-naturally-spawn.patch b/patches/server/0038-Charged-creeper-naturally-spawn.patch similarity index 58% rename from patches/server/0017-Charged-creeper-naturally-spawn.patch rename to patches/server/0038-Charged-creeper-naturally-spawn.patch index 0726e7f73..7e0c3a2fb 100644 --- a/patches/server/0017-Charged-creeper-naturally-spawn.patch +++ b/patches/server/0038-Charged-creeper-naturally-spawn.patch @@ -1,21 +1,22 @@ -From 2de0a875233bb6be5ed54394ac9cba44a7b32764 Mon Sep 17 00:00:00 2001 +From 4e0bfa3879efb2558a9e2139c4fd0f5554b59a45 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Fri, 29 Nov 2019 22:37:44 -0600 Subject: [PATCH] Charged creeper naturally spawn --- src/main/java/net/minecraft/server/EntityCreeper.java | 11 +++++++++++ - src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 2 ++ - 2 files changed, 13 insertions(+) + src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 5 +++++ + 2 files changed, 16 insertions(+) diff --git a/src/main/java/net/minecraft/server/EntityCreeper.java b/src/main/java/net/minecraft/server/EntityCreeper.java -index 48fd8e716..ce366f401 100644 +index 5e7f3af37..ec5287fa5 100644 --- a/src/main/java/net/minecraft/server/EntityCreeper.java +++ b/src/main/java/net/minecraft/server/EntityCreeper.java -@@ -87,6 +87,17 @@ public class EntityCreeper extends EntityMonster { - this.datawatcher.register(EntityCreeper.d, false); +@@ -275,4 +275,15 @@ public class EntityCreeper extends EntityMonster { + public void setCausedHeadDrop() { + ++this.bz; } - ++ + // Purpur start + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, GroupDataEntity groupdataentity, NBTTagCompound nbttagcompound) { @@ -26,27 +27,23 @@ index 48fd8e716..ce366f401 100644 + return super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); + } + // Purpur end -+ - @Override - public void b(NBTTagCompound nbttagcompound) { - super.b(nbttagcompound); + } diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 4c7469b90..bbae44ddb 100644 +index 3dad7bded..d9c4ffbe8 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -148,10 +148,12 @@ public class PurpurWorldConfig { - public boolean creeperRidable = false; - public boolean creeperRidableInWater = false; - public boolean creeperRequireShiftToMount = true; -+ public double creeperChargedChance = 0.0D; - private void creeperSettings() { - creeperRidable = getBoolean("mobs.creeper.ridable", creeperRidable); - creeperRidableInWater = getBoolean("mobs.creeper.ridable-in-water", creeperRidableInWater); - creeperRequireShiftToMount = getBoolean("mobs.creeper.require-shift-to-mount", creeperRequireShiftToMount); -+ creeperChargedChance = getDouble("mobs.creeper.naturally-charged-chance", creeperChargedChance); +@@ -92,6 +92,11 @@ public class PurpurWorldConfig { + turtleEggsBreakFromMinecarts = getBoolean("blocks.turtle_egg.break-from-minecarts", turtleEggsBreakFromMinecarts); } - public boolean dolphinRidable = false; ++ public double creeperChargedChance = 0.0D; ++ private void creeperSettings() { ++ creeperChargedChance = getDouble("mobs.creeper.naturally-charged-chance", creeperChargedChance); ++ } ++ + public float giantStepHeight = 2.0F; + public float giantJumpHeight = 1.0F; + public double giantMaxHealth = 100.0D; -- 2.26.2 diff --git a/patches/server/0018-Rabbit-naturally-spawn-toast-and-killer.patch b/patches/server/0039-Rabbit-naturally-spawn-toast-and-killer.patch similarity index 62% rename from patches/server/0018-Rabbit-naturally-spawn-toast-and-killer.patch rename to patches/server/0039-Rabbit-naturally-spawn-toast-and-killer.patch index c9193d920..1a96fb108 100644 --- a/patches/server/0018-Rabbit-naturally-spawn-toast-and-killer.patch +++ b/patches/server/0039-Rabbit-naturally-spawn-toast-and-killer.patch @@ -1,20 +1,20 @@ -From aeb5f32f4179df8b3e0eace094ed06a31e65b87c Mon Sep 17 00:00:00 2001 +From 65ded2f0ce2ede0d1b623971d998474e1b52c791 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 31 Aug 2019 17:47:11 -0500 Subject: [PATCH] Rabbit naturally spawn toast and killer --- .../java/net/minecraft/server/EntityRabbit.java | 14 ++++++++++++++ - .../java/net/pl3x/purpur/PurpurWorldConfig.java | 4 ++++ - 2 files changed, 18 insertions(+) + .../java/net/pl3x/purpur/PurpurWorldConfig.java | 7 +++++++ + 2 files changed, 21 insertions(+) diff --git a/src/main/java/net/minecraft/server/EntityRabbit.java b/src/main/java/net/minecraft/server/EntityRabbit.java -index 9040ab1c5..0232226f0 100644 +index 00c9233f8..1be0f943b 100644 --- a/src/main/java/net/minecraft/server/EntityRabbit.java +++ b/src/main/java/net/minecraft/server/EntityRabbit.java -@@ -364,6 +364,10 @@ public class EntityRabbit extends EntityAnimal { +@@ -297,6 +297,10 @@ public class EntityRabbit extends EntityAnimal { if (!this.hasCustomName()) { - this.setCustomName(new ChatMessage(SystemUtils.a("entity", EntityRabbit.bx), new Object[0])); + this.setCustomName(new ChatMessage(SystemUtils.a("entity", EntityRabbit.bw))); } + // Purpur start + } else if (i == 98) { @@ -22,8 +22,8 @@ index 9040ab1c5..0232226f0 100644 + // Purpur end } - this.datawatcher.set(EntityRabbit.bw, i); -@@ -385,6 +389,16 @@ public class EntityRabbit extends EntityAnimal { + this.datawatcher.set(EntityRabbit.bv, i); +@@ -318,6 +322,16 @@ public class EntityRabbit extends EntityAnimal { } private int a(GeneratorAccess generatoraccess) { @@ -36,29 +36,28 @@ index 9040ab1c5..0232226f0 100644 + return 98; + } + // Purpur end -+ - BiomeBase biomebase = generatoraccess.getBiome(new BlockPosition(this)); ++ + BiomeBase biomebase = generatoraccess.getBiome(this.getChunkCoordinates()); int i = this.random.nextInt(100); diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index bbae44ddb..4aaf75fcf 100644 +index d9c4ffbe8..9e144a369 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -440,10 +440,14 @@ public class PurpurWorldConfig { - public boolean rabbitRidable = false; - public boolean rabbitRidableInWater = false; - public boolean rabbitRequireShiftToMount = true; -+ public double rabbitNaturalToast = 0.0D; -+ public double rabbitNaturalKiller = 0.0D; - private void rabbitSettings() { - rabbitRidable = getBoolean("mobs.rabbit.ridable", rabbitRidable); - rabbitRidableInWater = getBoolean("mobs.rabbit.ridable-in-water", rabbitRidableInWater); - rabbitRequireShiftToMount = getBoolean("mobs.rabbit.require-shift-to-mount", rabbitRequireShiftToMount); -+ rabbitNaturalToast = getDouble("mobs.rabbit.spawn-toast-chance", rabbitNaturalToast); -+ rabbitNaturalKiller = getDouble("mobs.rabbit.spawn-killer-rabbit-chance", rabbitNaturalKiller); +@@ -123,6 +123,13 @@ public class PurpurWorldConfig { + illusionerFollowRange = getDouble("mobs.illusioner.follow-range", illusionerFollowRange); } - public boolean ravagerRidable = false; ++ public double rabbitNaturalToast = 0.0D; ++ public double rabbitNaturalKiller = 0.0D; ++ private void rabbitSettings() { ++ rabbitNaturalToast = getDouble("mobs.rabbit.spawn-toast-chance", rabbitNaturalToast); ++ rabbitNaturalKiller = getDouble("mobs.rabbit.spawn-killer-rabbit-chance", rabbitNaturalKiller); ++ } ++ + public int villagerBrainTicks = 1; + public boolean villagerUseBrainTicksOnlyWhenLagging = true; + private void villagerSettings() { -- 2.26.2 diff --git a/patches/server/0029-Fix-outdated-server-showing-in-ping-before-server-fu.patch b/patches/server/0040-Fix-outdated-server-showing-in-ping-before-server-fu.patch similarity index 91% rename from patches/server/0029-Fix-outdated-server-showing-in-ping-before-server-fu.patch rename to patches/server/0040-Fix-outdated-server-showing-in-ping-before-server-fu.patch index caeb8e5a9..ae7e7f005 100644 --- a/patches/server/0029-Fix-outdated-server-showing-in-ping-before-server-fu.patch +++ b/patches/server/0040-Fix-outdated-server-showing-in-ping-before-server-fu.patch @@ -1,4 +1,4 @@ -From 8dc9cf85d82ebcfb89d97fb0bd172bb58794b9d4 Mon Sep 17 00:00:00 2001 +From d465dcaf5f07f171e1293db0e0066c7120d7fe19 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Tue, 4 Jun 2019 15:50:08 -0500 Subject: [PATCH] Fix 'outdated server' showing in ping before server fully @@ -9,7 +9,7 @@ Subject: [PATCH] Fix 'outdated server' showing in ping before server fully 1 file changed, 1 insertion(+) diff --git a/src/main/java/net/minecraft/server/PacketStatusListener.java b/src/main/java/net/minecraft/server/PacketStatusListener.java -index 4bb21c48b..30f16db02 100644 +index da804a990..6b32bc233 100644 --- a/src/main/java/net/minecraft/server/PacketStatusListener.java +++ b/src/main/java/net/minecraft/server/PacketStatusListener.java @@ -135,6 +135,7 @@ public class PacketStatusListener implements PacketStatusInListener { diff --git a/patches/server/0030-Make-Iron-Golems-Swim.patch b/patches/server/0041-Make-Iron-Golems-Swim.patch similarity index 54% rename from patches/server/0030-Make-Iron-Golems-Swim.patch rename to patches/server/0041-Make-Iron-Golems-Swim.patch index ed5c72caa..3540a6f6f 100644 --- a/patches/server/0030-Make-Iron-Golems-Swim.patch +++ b/patches/server/0041-Make-Iron-Golems-Swim.patch @@ -1,42 +1,41 @@ -From 2379deeae65cfb447a5c515621504e1092df675f Mon Sep 17 00:00:00 2001 +From a74080199c03418349b2f1857905c2349fce12c4 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 15 Jun 2019 03:12:15 -0500 Subject: [PATCH] Make Iron Golems Swim --- src/main/java/net/minecraft/server/EntityIronGolem.java | 1 + - src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 2 ++ - 2 files changed, 3 insertions(+) + src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 5 +++++ + 2 files changed, 6 insertions(+) diff --git a/src/main/java/net/minecraft/server/EntityIronGolem.java b/src/main/java/net/minecraft/server/EntityIronGolem.java -index 288a043fb..0cc3b8eb0 100644 +index e38a675be..ab0731c2a 100644 --- a/src/main/java/net/minecraft/server/EntityIronGolem.java +++ b/src/main/java/net/minecraft/server/EntityIronGolem.java -@@ -36,6 +36,7 @@ public class EntityIronGolem extends EntityGolem { +@@ -24,6 +24,7 @@ public class EntityIronGolem extends EntityGolem implements IEntityAngerable { @Override protected void initPathfinder() { + if (world.purpurConfig.ironGolemCanSwim) this.goalSelector.a(0, new PathfinderGoalFloat(this)); // Purpur - this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(1, new PathfinderGoalMeleeAttack(this, 1.0D, true)); this.goalSelector.a(2, new PathfinderGoalMoveTowardsTarget(this, 0.9D, 32.0F)); + this.goalSelector.a(2, new PathfinderGoalStrollVillage(this, 0.6D, false)); diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index f098a36b5..a07781929 100644 +index 9e144a369..c89d2221b 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -333,10 +333,12 @@ public class PurpurWorldConfig { - public boolean ironGolemRidable = false; - public boolean ironGolemRidableInWater = false; - public boolean ironGolemRequireShiftToMount = true; -+ public boolean ironGolemCanSwim = false; - private void ironGolemSettings() { - ironGolemRidable = getBoolean("mobs.iron_golem.ridable", ironGolemRidable); - ironGolemRidableInWater = getBoolean("mobs.iron_golem.ridable-in-water", ironGolemRidableInWater); - ironGolemRequireShiftToMount = getBoolean("mobs.iron_golem.require-shift-to-mount", ironGolemRequireShiftToMount); -+ ironGolemCanSwim = getBoolean("mobs.iron_golem.can-swim", ironGolemCanSwim); +@@ -123,6 +123,11 @@ public class PurpurWorldConfig { + illusionerFollowRange = getDouble("mobs.illusioner.follow-range", illusionerFollowRange); } - public boolean llamaRidable = false; ++ public boolean ironGolemCanSwim = false; ++ private void ironGolemSettings() { ++ ironGolemCanSwim = getBoolean("mobs.iron_golem.can-swim", ironGolemCanSwim); ++ } ++ + public double rabbitNaturalToast = 0.0D; + public double rabbitNaturalKiller = 0.0D; + private void rabbitSettings() { -- 2.26.2 diff --git a/patches/server/0038-Dont-send-useless-entity-packets.patch b/patches/server/0042-Dont-send-useless-entity-packets.patch similarity index 84% rename from patches/server/0038-Dont-send-useless-entity-packets.patch rename to patches/server/0042-Dont-send-useless-entity-packets.patch index 51a4484dc..14b9676aa 100644 --- a/patches/server/0038-Dont-send-useless-entity-packets.patch +++ b/patches/server/0042-Dont-send-useless-entity-packets.patch @@ -1,4 +1,4 @@ -From 610bf17eeaba736705cb6223e21e9f03327de3b3 Mon Sep 17 00:00:00 2001 +From 2e265fe093ff3fefc0579df66571791c61b4e0e4 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 6 Jul 2019 17:00:04 -0500 Subject: [PATCH] Dont send useless entity packets @@ -10,10 +10,10 @@ Subject: [PATCH] Dont send useless entity packets 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/minecraft/server/EntityTrackerEntry.java b/src/main/java/net/minecraft/server/EntityTrackerEntry.java -index 1bd703848..adf7c9180 100644 +index 10cae053b..509df9bab 100644 --- a/src/main/java/net/minecraft/server/EntityTrackerEntry.java +++ b/src/main/java/net/minecraft/server/EntityTrackerEntry.java -@@ -170,6 +170,7 @@ public class EntityTrackerEntry { +@@ -177,6 +177,7 @@ public class EntityTrackerEntry { this.o = 0; packet1 = new PacketPlayOutEntityTeleport(this.tracker); } @@ -21,7 +21,7 @@ index 1bd703848..adf7c9180 100644 } if ((this.e || this.tracker.impulse || this.tracker instanceof EntityLiving && ((EntityLiving) this.tracker).isGliding()) && this.tickCounter > 0) { -@@ -256,6 +257,22 @@ public class EntityTrackerEntry { +@@ -263,6 +264,22 @@ public class EntityTrackerEntry { } @@ -45,7 +45,7 @@ index 1bd703848..adf7c9180 100644 this.tracker.c(entityplayer); entityplayer.c(this.tracker); diff --git a/src/main/java/net/minecraft/server/PacketPlayOutEntity.java b/src/main/java/net/minecraft/server/PacketPlayOutEntity.java -index e5da2b19c..5b1d95935 100644 +index 6d9d52e4f..0010448e3 100644 --- a/src/main/java/net/minecraft/server/PacketPlayOutEntity.java +++ b/src/main/java/net/minecraft/server/PacketPlayOutEntity.java @@ -5,11 +5,11 @@ import java.io.IOException; @@ -66,11 +66,11 @@ index e5da2b19c..5b1d95935 100644 protected boolean h; protected boolean i; diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java -index d6f82d119..d3e1c8c40 100644 +index b520cd28b..e8a0438ec 100644 --- a/src/main/java/net/pl3x/purpur/PurpurConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java -@@ -139,6 +139,11 @@ public class PurpurConfig { - loggerSuppressIgnoredAdvancementWarnings = getBoolean("settings.logger.suppress-ignored-advancement-warnings", loggerSuppressIgnoredAdvancementWarnings); +@@ -176,6 +176,11 @@ public class PurpurConfig { + enderChestPermissionRows = getBoolean("settings.blocks.ender_chest.use-permissions-for-rows", enderChestPermissionRows); } + public static boolean dontSendUselessEntityPackets = false; @@ -78,9 +78,9 @@ index d6f82d119..d3e1c8c40 100644 + dontSendUselessEntityPackets = getBoolean("settings.dont-send-useless-entity-packets", dontSendUselessEntityPackets); + } + - private static void timingsSettings() { - getString("settings.timings.url", "https://timings.pl3x.net"); - } + public static boolean fixItemPositionDesync = false; + private static void fixItemPositionDesync() { + fixItemPositionDesync = getBoolean("settings.fix-item-position-desync", fixItemPositionDesync); -- 2.26.2 diff --git a/patches/server/0042-Tulips-change-fox-type.patch b/patches/server/0042-Tulips-change-fox-type.patch deleted file mode 100644 index d19767963..000000000 --- a/patches/server/0042-Tulips-change-fox-type.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 5b624aa8deb3cfbba28a2f8dbee3ac28b61afad6 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sat, 13 Jul 2019 15:56:22 -0500 -Subject: [PATCH] Tulips change fox type - ---- - .../java/net/minecraft/server/EntityFox.java | 33 +++++++++++++++++-- - src/main/java/net/minecraft/server/Items.java | 4 +-- - .../net/pl3x/purpur/PurpurWorldConfig.java | 2 ++ - 3 files changed, 34 insertions(+), 5 deletions(-) - -diff --git a/src/main/java/net/minecraft/server/EntityFox.java b/src/main/java/net/minecraft/server/EntityFox.java -index 4f53090d3..13afd7bcd 100644 ---- a/src/main/java/net/minecraft/server/EntityFox.java -+++ b/src/main/java/net/minecraft/server/EntityFox.java -@@ -37,9 +37,9 @@ public class EntityFox extends EntityAnimal { - private static final Predicate bD = (entity) -> { - return !entity.bm() && IEntitySelector.e.test(entity); - }; -- private PathfinderGoal bE; -- private PathfinderGoal bF; -- private PathfinderGoal bG; -+ private PathfinderGoal bE; private PathfinderGoal attackAnimalGoal() { return bE; } // Purpur - OBFHELPER -+ private PathfinderGoal bF; private PathfinderGoal attackTurtleGoal() { return bF; } // Purpur - OBFHELPER -+ private PathfinderGoal bG; private PathfinderGoal attackFishGoal() { return bG; } // Purpur - OBFHELPER - private float bH; - private float bI; - private float bJ; -@@ -245,6 +245,11 @@ public class EntityFox extends EntityAnimal { - } - - private void initializePathFinderGoals() { -+ // Purpur start - do not add duplicate goals -+ this.targetSelector.a(attackAnimalGoal()); -+ this.targetSelector.a(attackTurtleGoal()); -+ this.targetSelector.a(attackFishGoal()); -+ // Purpur end - if (this.getFoxType() == EntityFox.Type.RED) { - this.targetSelector.a(4, this.bE); - this.targetSelector.a(4, this.bF); -@@ -277,6 +282,7 @@ public class EntityFox extends EntityAnimal { - - public void setFoxType(EntityFox.Type entityfox_type) { - this.datawatcher.set(EntityFox.bw, entityfox_type.c()); -+ initializePathFinderGoals(); // Purpur - fix API bug not updating pathfinders on type change - } - - private List eE() { -@@ -620,6 +626,27 @@ public class EntityFox extends EntityAnimal { - return !hasRider() ? super.getJumpHeight() : 0.5F; - } - -+ @Override -+ public boolean a(EntityHuman entityhuman, EnumHand enumhand) { -+ if (world.purpurConfig.foxTypeChangesWithTulips) { -+ ItemStack itemstack = entityhuman.b(enumhand); -+ if (getFoxType() == Type.RED && itemstack.getItem() == Items.whiteTulip()) { -+ setFoxType(Type.SNOW); -+ if (!entityhuman.abilities.canInstantlyBuild) { -+ itemstack.subtract(1); -+ } -+ return true; -+ } else if (getFoxType() == Type.SNOW && itemstack.getItem() == Items.orangeTulip()) { -+ setFoxType(Type.RED); -+ if (!entityhuman.abilities.canInstantlyBuild) { -+ itemstack.subtract(1); -+ } -+ return true; -+ } -+ } -+ return super.a(entityhuman, enumhand); -+ } -+ - @Override - public void onMount(EntityHuman entityhuman) { - super.onMount(entityhuman); -diff --git a/src/main/java/net/minecraft/server/Items.java b/src/main/java/net/minecraft/server/Items.java -index 54670f64c..9c9b93f28 100644 ---- a/src/main/java/net/minecraft/server/Items.java -+++ b/src/main/java/net/minecraft/server/Items.java -@@ -106,8 +106,8 @@ public class Items { - public static final Item aX = a(Blocks.ALLIUM, CreativeModeTab.c); - public static final Item aY = a(Blocks.AZURE_BLUET, CreativeModeTab.c); - public static final Item aZ = a(Blocks.RED_TULIP, CreativeModeTab.c); -- public static final Item ba = a(Blocks.ORANGE_TULIP, CreativeModeTab.c); -- public static final Item bb = a(Blocks.WHITE_TULIP, CreativeModeTab.c); -+ public static final Item ba = a(Blocks.ORANGE_TULIP, CreativeModeTab.c); public static Item orangeTulip() { return ba; } // Purpur - OBFHELPER -+ public static final Item bb = a(Blocks.WHITE_TULIP, CreativeModeTab.c); public static Item whiteTulip() { return bb; } // Purpur - OBFHELPER - public static final Item bc = a(Blocks.PINK_TULIP, CreativeModeTab.c); - public static final Item bd = a(Blocks.OXEYE_DAISY, CreativeModeTab.c); - public static final Item be = a(Blocks.CORNFLOWER, CreativeModeTab.c); -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index b76a8c5be..a2fce0c63 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -335,10 +335,12 @@ public class PurpurWorldConfig { - public boolean foxRidable = false; - public boolean foxRidableInWater = false; - public boolean foxRequireShiftToMount = true; -+ public boolean foxTypeChangesWithTulips = false; - private void foxSettings() { - foxRidable = getBoolean("mobs.fox.ridable", foxRidable); - foxRidableInWater = getBoolean("mobs.fox.ridable-in-water", foxRidableInWater); - foxRequireShiftToMount = getBoolean("mobs.fox.require-shift-to-mount", foxRequireShiftToMount); -+ foxTypeChangesWithTulips = getBoolean("mobs.fox.tulips-change-type", foxTypeChangesWithTulips); - } - - public boolean ghastRidable = false; --- -2.26.2 - diff --git a/patches/server/0043-Pillager-limits-and-leaders-chance.patch b/patches/server/0043-Pillager-limits-and-leaders-chance.patch deleted file mode 100644 index 788736703..000000000 --- a/patches/server/0043-Pillager-limits-and-leaders-chance.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 48d14d7c57478a6af1c85d20a59ebef69b43ec9e Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Mon, 22 Jul 2019 14:24:26 -0500 -Subject: [PATCH] Pillager limits and leaders chance - ---- - .../java/net/minecraft/server/ChunkProviderGenerate.java | 1 + - .../java/net/minecraft/server/EntityMonsterPatrolling.java | 7 ++++++- - src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 6 ++++++ - 3 files changed, 13 insertions(+), 1 deletion(-) - -diff --git a/src/main/java/net/minecraft/server/ChunkProviderGenerate.java b/src/main/java/net/minecraft/server/ChunkProviderGenerate.java -index 70f43c515..fa08b8e1a 100644 ---- a/src/main/java/net/minecraft/server/ChunkProviderGenerate.java -+++ b/src/main/java/net/minecraft/server/ChunkProviderGenerate.java -@@ -143,6 +143,7 @@ public class ChunkProviderGenerate extends ChunkGeneratorAbstract +Date: Sat, 13 Jul 2019 15:56:22 -0500 +Subject: [PATCH] Tulips change fox type + +--- + .../java/net/minecraft/server/EntityFox.java | 33 +++++++++++++++++-- + src/main/java/net/minecraft/server/Items.java | 4 +-- + .../net/pl3x/purpur/PurpurWorldConfig.java | 5 +++ + 3 files changed, 37 insertions(+), 5 deletions(-) + +diff --git a/src/main/java/net/minecraft/server/EntityFox.java b/src/main/java/net/minecraft/server/EntityFox.java +index e6275a9fe..90b01adbe 100644 +--- a/src/main/java/net/minecraft/server/EntityFox.java ++++ b/src/main/java/net/minecraft/server/EntityFox.java +@@ -37,9 +37,9 @@ public class EntityFox extends EntityAnimal { + private static final Predicate bC = (entity) -> { + return !entity.bt() && IEntitySelector.e.test(entity); + }; +- private PathfinderGoal bD; +- private PathfinderGoal bE; +- private PathfinderGoal bF; ++ private PathfinderGoal bD; private PathfinderGoal attackAnimalGoal() { return bD; } // Purpur - OBFHELPER ++ private PathfinderGoal bE; private PathfinderGoal attackTurtleGoal() { return bE; } // Purpur - OBFHELPER ++ private PathfinderGoal bF; private PathfinderGoal attackFishGoal() { return bF; } // Purpur - OBFHELPER + private float bG; + private float bH; + private float bI; +@@ -227,6 +227,11 @@ public class EntityFox extends EntityAnimal { + } + + private void initializePathFinderGoals() { ++ // Purpur start - do not add duplicate goals ++ this.targetSelector.a(attackAnimalGoal()); ++ this.targetSelector.a(attackTurtleGoal()); ++ this.targetSelector.a(attackFishGoal()); ++ // Purpur end + if (this.getFoxType() == EntityFox.Type.RED) { + this.targetSelector.a(4, this.bD); + this.targetSelector.a(4, this.bE); +@@ -259,6 +264,7 @@ public class EntityFox extends EntityAnimal { + + public void setFoxType(EntityFox.Type entityfox_type) { + this.datawatcher.set(EntityFox.bv, entityfox_type.c()); ++ initializePathFinderGoals(); // Purpur - fix API bug not updating pathfinders on type change + } + + private List fb() { +@@ -575,6 +581,27 @@ public class EntityFox extends EntityAnimal { + return this.fb().contains(uuid); + } + ++ @Override ++ public EnumInteractionResult b(EntityHuman entityhuman, EnumHand enumhand) { ++ if (world.purpurConfig.foxTypeChangesWithTulips) { ++ ItemStack itemstack = entityhuman.b(enumhand); ++ if (getFoxType() == Type.RED && itemstack.getItem() == Items.whiteTulip()) { ++ setFoxType(Type.SNOW); ++ if (!entityhuman.abilities.canInstantlyBuild) { ++ itemstack.subtract(1); ++ } ++ return EnumInteractionResult.SUCCESS; ++ } else if (getFoxType() == Type.SNOW && itemstack.getItem() == Items.orangeTulip()) { ++ setFoxType(Type.RED); ++ if (!entityhuman.abilities.canInstantlyBuild) { ++ itemstack.subtract(1); ++ } ++ return EnumInteractionResult.SUCCESS; ++ } ++ } ++ return super.b(entityhuman, enumhand); ++ } ++ + @Override + protected org.bukkit.event.entity.EntityDeathEvent d(DamageSource damagesource) { // Paper + ItemStack itemstack = this.getEquipment(EnumItemSlot.MAINHAND).cloneItemStack(); // Paper +diff --git a/src/main/java/net/minecraft/server/Items.java b/src/main/java/net/minecraft/server/Items.java +index 619c40b27..b5305eaa9 100644 +--- a/src/main/java/net/minecraft/server/Items.java ++++ b/src/main/java/net/minecraft/server/Items.java +@@ -119,8 +119,8 @@ public class Items { + public static final Item bk = a(Blocks.ALLIUM, CreativeModeTab.c); + public static final Item bl = a(Blocks.AZURE_BLUET, CreativeModeTab.c); + public static final Item bm = a(Blocks.RED_TULIP, CreativeModeTab.c); +- public static final Item bn = a(Blocks.ORANGE_TULIP, CreativeModeTab.c); +- public static final Item bo = a(Blocks.WHITE_TULIP, CreativeModeTab.c); ++ public static final Item bn = a(Blocks.ORANGE_TULIP, CreativeModeTab.c); public static Item orangeTulip() { return bn; } // Purpur - OBFHELPER ++ public static final Item bo = a(Blocks.WHITE_TULIP, CreativeModeTab.c); public static Item whiteTulip() { return bo; } // Purpur - OBFHELPER + public static final Item bp = a(Blocks.PINK_TULIP, CreativeModeTab.c); + public static final Item bq = a(Blocks.OXEYE_DAISY, CreativeModeTab.c); + public static final Item br = a(Blocks.CORNFLOWER, CreativeModeTab.c); +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index c89d2221b..8d620b4ef 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -97,6 +97,11 @@ public class PurpurWorldConfig { + creeperChargedChance = getDouble("mobs.creeper.naturally-charged-chance", creeperChargedChance); + } + ++ public boolean foxTypeChangesWithTulips = false; ++ private void foxSettings() { ++ foxTypeChangesWithTulips = getBoolean("mobs.fox.tulips-change-type", foxTypeChangesWithTulips); ++ } ++ + public float giantStepHeight = 2.0F; + public float giantJumpHeight = 1.0F; + public double giantMaxHealth = 100.0D; +-- +2.26.2 + diff --git a/patches/server/0101-Breedable-Polar-Bears.patch b/patches/server/0044-Breedable-Polar-Bears.patch similarity index 59% rename from patches/server/0101-Breedable-Polar-Bears.patch rename to patches/server/0044-Breedable-Polar-Bears.patch index f3b5ca71c..4e1cf3cb5 100644 --- a/patches/server/0101-Breedable-Polar-Bears.patch +++ b/patches/server/0044-Breedable-Polar-Bears.patch @@ -1,22 +1,26 @@ -From 1ee64e547cf37152de6744d3774470e7a29f945e Mon Sep 17 00:00:00 2001 +From de732dfe84607cb98f4cda698738c786db24a793 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Thu, 26 Mar 2020 19:46:44 -0500 Subject: [PATCH] Breedable Polar Bears --- - .../net/minecraft/server/EntityPolarBear.java | 30 ++++++++++++++++++- - .../net/pl3x/purpur/PurpurWorldConfig.java | 5 ++++ - 2 files changed, 34 insertions(+), 1 deletion(-) + .../net/minecraft/server/EntityPolarBear.java | 34 ++++++++++++++++++- + .../net/pl3x/purpur/PurpurWorldConfig.java | 12 +++++++ + 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/minecraft/server/EntityPolarBear.java b/src/main/java/net/minecraft/server/EntityPolarBear.java -index 0a3906bde..42fef3aba 100644 +index 69e5c1aed..6506e0055 100644 --- a/src/main/java/net/minecraft/server/EntityPolarBear.java +++ b/src/main/java/net/minecraft/server/EntityPolarBear.java -@@ -32,6 +32,28 @@ public class EntityPolarBear extends EntityAnimal { - public boolean requireShiftToMount() { - return world.purpurConfig.polarBearRequireShiftToMount; +@@ -28,15 +28,45 @@ public class EntityPolarBear extends EntityAnimal implements IEntityAngerable { + + @Override + public boolean k(ItemStack itemstack) { +- return false; ++ return world.purpurConfig.polarBearBreedableItem != null && itemstack.getItem() == world.purpurConfig.polarBearBreedableItem; // Purpur; } -+ + ++ // Purpur start + @Override + public boolean mate(EntityAnimal entityanimal) { + if (entityanimal == this) { @@ -38,20 +42,12 @@ index 0a3906bde..42fef3aba 100644 + return this.isInLove() && polarbear.isInLove(); + } + } - // Purpur end - ++ // Purpur end ++ @Override -@@ -41,7 +63,7 @@ public class EntityPolarBear extends EntityAnimal { - - @Override - public boolean i(ItemStack itemstack) { -- return false; -+ return world.purpurConfig.polarBearBreedableItem != null && itemstack.getItem() == world.purpurConfig.polarBearBreedableItem; // Purpur - } - - @Override -@@ -51,6 +73,12 @@ public class EntityPolarBear extends EntityAnimal { - this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur + protected void initPathfinder() { + super.initPathfinder(); + this.goalSelector.a(0, new PathfinderGoalFloat(this)); this.goalSelector.a(1, new EntityPolarBear.c()); this.goalSelector.a(1, new EntityPolarBear.d()); + // Purpur start @@ -63,26 +59,49 @@ index 0a3906bde..42fef3aba 100644 this.goalSelector.a(4, new PathfinderGoalFollowParent(this, 1.25D)); this.goalSelector.a(5, new PathfinderGoalRandomStroll(this, 1.0D)); this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); +@@ -178,10 +208,12 @@ public class EntityPolarBear extends EntityAnimal implements IEntityAngerable { + return flag; + } + ++ public boolean isStanding() { return eN(); } // Purpur - OBFHELPER + public boolean eN() { + return (Boolean) this.datawatcher.get(EntityPolarBear.bv); + } + ++ public void setStanding(boolean standing) { t(standing); } // Purpur - OBFHELPER + public void t(boolean flag) { + this.datawatcher.set(EntityPolarBear.bv, flag); + } diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 01b8fffe1..ced9edf82 100644 +index 8d620b4ef..12e263d21 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -666,10 +666,15 @@ public class PurpurWorldConfig { - public boolean polarBearRidable = false; - public boolean polarBearRidableInWater = false; - public boolean polarBearRequireShiftToMount = true; +@@ -1,6 +1,10 @@ + package net.pl3x.purpur; + + import com.destroystokyo.paper.PaperWorldConfig; ++import net.minecraft.server.IRegistry; ++import net.minecraft.server.Item; ++import net.minecraft.server.Items; ++import net.minecraft.server.MinecraftKey; + import org.bukkit.configuration.ConfigurationSection; + import org.spigotmc.SpigotWorldConfig; + +@@ -133,6 +137,14 @@ public class PurpurWorldConfig { + ironGolemCanSwim = getBoolean("mobs.iron_golem.can-swim", ironGolemCanSwim); + } + + public String polarBearBreedableItemString = ""; + public Item polarBearBreedableItem = null; - private void polarBearSettings() { - polarBearRidable = getBoolean("mobs.polar_bear.ridable", polarBearRidable); - polarBearRidableInWater = getBoolean("mobs.polar_bear.ridable-in-water", polarBearRidableInWater); - polarBearRequireShiftToMount = getBoolean("mobs.polar_bear.require-shift-to-mount", polarBearRequireShiftToMount); ++ private void polarBearSettings() { + polarBearBreedableItemString = getString("mobs.polar_bear.breedable-item", polarBearBreedableItemString); + Item item = IRegistry.ITEM.get(new MinecraftKey(polarBearBreedableItemString)); + if (item != Items.AIR) polarBearBreedableItem = item; - } - - public boolean pufferfishRidable = false; ++ } ++ + public double rabbitNaturalToast = 0.0D; + public double rabbitNaturalKiller = 0.0D; + private void rabbitSettings() { -- 2.26.2 diff --git a/patches/server/0044-Make-the-GUI-better.patch b/patches/server/0044-Make-the-GUI-better.patch deleted file mode 100644 index b7b71f05a..000000000 --- a/patches/server/0044-Make-the-GUI-better.patch +++ /dev/null @@ -1,1205 +0,0 @@ -From c7bf2097ea8720ae860d8ad95a6a989a91094161 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Thu, 16 Jan 2020 14:59:16 -0600 -Subject: [PATCH] Make the GUI better - ---- - .../net/minecraft/server/DedicatedServer.java | 9 +- - .../net/minecraft/server/MinecraftServer.java | 1 + - .../java/net/pl3x/purpur/gui/ServerGUI.java | 123 +++++++++++++++ - .../purpur/gui/console/JColorTextPane.java | 81 ++++++++++ - .../purpur/gui/console/JConsolePanel.java | 128 ++++++++++++++++ - .../gui/info/DetailsListSelectionModel.java | 21 +++ - .../net/pl3x/purpur/gui/info/JInfoPanel.java | 42 +++++ - .../net/pl3x/purpur/gui/info/RAMDetails.java | 59 +++++++ - .../purpur/gui/info/graph/GraphColor.java | 44 ++++++ - .../pl3x/purpur/gui/info/graph/GraphData.java | 47 ++++++ - .../pl3x/purpur/gui/info/graph/RAMGraph.java | 144 ++++++++++++++++++ - .../purpur/gui/playerlist/JPlayerList.java | 57 +++++++ - .../playerlist/PlayerListCellRenderer.java | 22 +++ - .../gui/playerlist/PlayerListModel.java | 47 ++++++ - .../playerlist/PlayerListMouseAdapter.java | 32 ++++ - .../net/pl3x/purpur/gui/util/GUIColor.java | 54 +++++++ - .../purpur/util/HighlightErrorConverter.java | 86 +++++++++++ - src/main/resources/log4j2.xml | 13 +- - 18 files changed, 1005 insertions(+), 5 deletions(-) - create mode 100644 src/main/java/net/pl3x/purpur/gui/ServerGUI.java - create mode 100644 src/main/java/net/pl3x/purpur/gui/console/JColorTextPane.java - create mode 100644 src/main/java/net/pl3x/purpur/gui/console/JConsolePanel.java - create mode 100644 src/main/java/net/pl3x/purpur/gui/info/DetailsListSelectionModel.java - create mode 100644 src/main/java/net/pl3x/purpur/gui/info/JInfoPanel.java - create mode 100644 src/main/java/net/pl3x/purpur/gui/info/RAMDetails.java - create mode 100644 src/main/java/net/pl3x/purpur/gui/info/graph/GraphColor.java - create mode 100644 src/main/java/net/pl3x/purpur/gui/info/graph/GraphData.java - create mode 100644 src/main/java/net/pl3x/purpur/gui/info/graph/RAMGraph.java - create mode 100644 src/main/java/net/pl3x/purpur/gui/playerlist/JPlayerList.java - create mode 100644 src/main/java/net/pl3x/purpur/gui/playerlist/PlayerListCellRenderer.java - create mode 100644 src/main/java/net/pl3x/purpur/gui/playerlist/PlayerListModel.java - create mode 100644 src/main/java/net/pl3x/purpur/gui/playerlist/PlayerListMouseAdapter.java - create mode 100644 src/main/java/net/pl3x/purpur/gui/util/GUIColor.java - create mode 100644 src/main/java/net/pl3x/purpur/util/HighlightErrorConverter.java - -diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java -index 3190c709a..7f2db5f0b 100644 ---- a/src/main/java/net/minecraft/server/DedicatedServer.java -+++ b/src/main/java/net/minecraft/server/DedicatedServer.java -@@ -8,6 +8,8 @@ import com.mojang.authlib.GameProfileRepository; - import com.mojang.authlib.minecraft.MinecraftSessionService; - import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; - import com.mojang.datafixers.DataFixer; -+ -+import java.awt.GraphicsEnvironment; - import java.io.BufferedReader; - import java.io.File; - import java.io.IOException; -@@ -51,7 +53,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer - public DedicatedServerSettings propertyManager; - private EnumGamemode o; - @Nullable -- private ServerGUI p; -+ private net.pl3x.purpur.gui.ServerGUI p; // Purpur - - // CraftBukkit start - Signature changed - public DedicatedServer(joptsimple.OptionSet options, DedicatedServerSettings dedicatedserversettings, DataFixer datafixer, YggdrasilAuthenticationService yggdrasilauthenticationservice, MinecraftSessionService minecraftsessionservice, GameProfileRepository gameprofilerepository, UserCache usercache, WorldLoadListenerFactory worldloadlistenerfactory, String s) { -@@ -87,6 +89,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer - return; - } - // Paper start - Use TerminalConsoleAppender -+ if (DedicatedServer.this.p == null || System.console() != null) // Purpur - has no GUI or has console (did not double click) - new com.destroystokyo.paper.console.PaperConsole(DedicatedServer.this).start(); - /* - jline.console.ConsoleReader bufferedreader = reader; -@@ -421,7 +424,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer - @Override - public void exit() { - if (this.p != null) { -- this.p.b(); -+ this.p.close(); // Purpur - } - - if (this.remoteControlListener != null) { -@@ -521,7 +524,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer - - public void bc() { - if (this.p == null) { -- this.p = ServerGUI.a(this); -+ this.p = net.pl3x.purpur.gui.ServerGUI.create(this); // Purpur - } - - } -diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 28d92cbce..da8c98356 100644 ---- a/src/main/java/net/minecraft/server/MinecraftServer.java -+++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1435,6 +1435,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant finalizers = Lists.newArrayList(); -+ private final AtomicBoolean isClosing = new AtomicBoolean(); -+ -+ private JConsolePanel consolePanel; -+ -+ public static ServerGUI create(final DedicatedServer dedicatedserver) { -+ try { -+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); -+ } catch (Exception ignore) { -+ } -+ -+ JFrame window = new JFrame("Purpur Minecraft Server"); -+ ServerGUI serverGUI = new ServerGUI(dedicatedserver); -+ -+ window.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); -+ window.add(serverGUI); -+ window.pack(); -+ window.setLocationRelativeTo(null); -+ window.setVisible(true); -+ -+ window.addWindowListener(new WindowAdapter() { -+ @Override -+ public void windowClosing(WindowEvent windowevent) { -+ if (!serverGUI.isClosing.getAndSet(true)) { -+ window.setTitle("Purpur Minecraft Server - Shutting Down!"); -+ dedicatedserver.safeShutdown(true); -+ serverGUI.runFinalizers(); -+ } -+ -+ } -+ }); -+ -+ serverGUI.addFinalizer(window::dispose); -+ serverGUI.start(); -+ -+ return serverGUI; -+ } -+ -+ private ServerGUI(DedicatedServer dedicatedserver) { -+ this.server = dedicatedserver; -+ -+ setPreferredSize(new Dimension(854, 480)); -+ setLayout(new BorderLayout()); -+ -+ consolePanel = new JConsolePanel(server); -+ -+ try { -+ add(consolePanel, "Center"); -+ add(buildInfoPanel(), "West"); -+ } catch (Exception exception) { -+ LOGGER.error("Couldn't build server GUI", exception); -+ } -+ } -+ -+ private void addFinalizer(Runnable runnable) { -+ finalizers.add(runnable); -+ } -+ -+ private JComponent buildInfoPanel() { -+ JPanel jpanel = new JPanel(new BorderLayout()); -+ -+ JInfoPanel serverInfo = new JInfoPanel(server); -+ finalizers.add(serverInfo::stop); -+ -+ jpanel.add(serverInfo, "North"); -+ jpanel.add(buildPlayerPanel(), "Center"); -+ -+ jpanel.setBorder(new TitledBorder(new EtchedBorder(), "Stats")); -+ return jpanel; -+ } -+ -+ private JComponent buildPlayerPanel() { -+ JScrollPane jscrollpane = new JScrollPane(new JPlayerList(server), ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); -+ jscrollpane.setBorder(new TitledBorder(new EtchedBorder(), "Players")); -+ return jscrollpane; -+ } -+ -+ public void start() { -+ consolePanel.start(); -+ } -+ -+ public void close() { -+ if (!isClosing.getAndSet(true)) { -+ runFinalizers(); -+ } -+ -+ } -+ -+ private void runFinalizers() { -+ finalizers.forEach(Runnable::run); -+ } -+} -diff --git a/src/main/java/net/pl3x/purpur/gui/console/JColorTextPane.java b/src/main/java/net/pl3x/purpur/gui/console/JColorTextPane.java -new file mode 100644 -index 000000000..55feec811 ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/gui/console/JColorTextPane.java -@@ -0,0 +1,81 @@ -+package net.pl3x.purpur.gui.console; -+ -+import net.md_5.bungee.api.ChatColor; -+import net.md_5.bungee.api.chat.BaseComponent; -+import net.md_5.bungee.api.chat.TextComponent; -+import net.pl3x.purpur.gui.util.GUIColor; -+ -+import javax.swing.JTextPane; -+import javax.swing.Timer; -+import javax.swing.text.AttributeSet; -+import javax.swing.text.BadLocationException; -+import javax.swing.text.SimpleAttributeSet; -+import javax.swing.text.StyleConstants; -+import javax.swing.text.StyleContext; -+import java.util.HashSet; -+import java.util.Set; -+ -+public class JColorTextPane extends JTextPane { -+ private static final GUIColor DEFAULT_COLOR = GUIColor.BLACK; -+ -+ public void append(String str) { -+ BaseComponent[] components = TextComponent.fromLegacyText(DEFAULT_COLOR.getCode() + str, ChatColor.BLACK); -+ for (BaseComponent component : components) { -+ String text = component.toPlainText(); -+ if (text == null || text.isEmpty()) { -+ continue; -+ } -+ -+ GUIColor guiColor = GUIColor.getColor(component.getColor()); -+ -+ StyleContext context = StyleContext.getDefaultStyleContext(); -+ AttributeSet attr = context.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, guiColor.getColor()); -+ attr = context.addAttribute(attr, StyleConstants.CharacterConstants.Bold, component.isBold() || guiColor != DEFAULT_COLOR); -+ attr = context.addAttribute(attr, StyleConstants.CharacterConstants.Italic, component.isItalic()); -+ attr = context.addAttribute(attr, StyleConstants.CharacterConstants.Underline, component.isUnderlined()); -+ attr = context.addAttribute(attr, StyleConstants.CharacterConstants.StrikeThrough, component.isStrikethrough()); -+ //attr = context.addAttribute(attr, StyleConstants.CharacterConstants.Blink, component.isObfuscated()); // no such thing as Blink, sadly -+ -+ try { -+ int pos = getDocument().getLength(); -+ getDocument().insertString(pos, text, attr); -+ -+ if (component.isObfuscated()) { -+ // dirty hack to blink some text -+ Blink blink = new Blink(pos, text.length(), attr, context.addAttribute(attr, StyleConstants.Foreground, getBackground())); -+ BLINKS.add(blink); -+ } -+ } catch (BadLocationException e) { -+ e.printStackTrace(); -+ } -+ } -+ } -+ -+ private static final Set BLINKS = new HashSet<>(); -+ private static boolean SYNC_BLINK; -+ -+ static { -+ Timer timer = new Timer(500, e -> { -+ SYNC_BLINK = !SYNC_BLINK; -+ BLINKS.forEach(Blink::blink); -+ }); -+ timer.start(); -+ } -+ -+ public class Blink { -+ private final int start, length; -+ private final AttributeSet attr1; -+ private final AttributeSet attr2; -+ -+ private Blink(int start, int length, AttributeSet attr1, AttributeSet attr2) { -+ this.start = start; -+ this.length = length; -+ this.attr1 = attr1; -+ this.attr2 = attr2; -+ } -+ -+ private void blink() { -+ getStyledDocument().setCharacterAttributes(start, length, SYNC_BLINK ? attr1 : attr2, true); -+ } -+ } -+} -diff --git a/src/main/java/net/pl3x/purpur/gui/console/JConsolePanel.java b/src/main/java/net/pl3x/purpur/gui/console/JConsolePanel.java -new file mode 100644 -index 000000000..fb017a070 ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/gui/console/JConsolePanel.java -@@ -0,0 +1,128 @@ -+package net.pl3x.purpur.gui.console; -+ -+import com.mojang.util.QueueLogAppender; -+import net.minecraft.server.DedicatedServer; -+import net.minecraft.server.DefaultUncaughtExceptionHandler; -+import org.apache.logging.log4j.LogManager; -+import org.apache.logging.log4j.Logger; -+ -+import javax.swing.AbstractAction; -+import javax.swing.JPanel; -+import javax.swing.JScrollBar; -+import javax.swing.JScrollPane; -+import javax.swing.JTextField; -+import javax.swing.KeyStroke; -+import javax.swing.ScrollPaneConstants; -+import javax.swing.SwingUtilities; -+import javax.swing.border.EtchedBorder; -+import javax.swing.border.TitledBorder; -+import java.awt.BorderLayout; -+import java.awt.Font; -+import java.awt.event.ActionEvent; -+import java.util.LinkedList; -+ -+public class JConsolePanel extends JPanel { -+ private static final Font MONOSPACED = new Font("Monospaced", Font.PLAIN, 12); -+ private static final Logger LOGGER = LogManager.getLogger(); -+ -+ private final CommandHistory history = new CommandHistory(); -+ private String currentCommand = ""; -+ private int historyIndex = 0; -+ -+ private Thread logAppenderThread; -+ -+ public JConsolePanel(DedicatedServer server) { -+ super(new BorderLayout()); -+ -+ JColorTextPane console = new JColorTextPane(); -+ console.setEditable(false); -+ console.setFont(MONOSPACED); -+ -+ JTextField jtextfield = new JTextField(); -+ jtextfield.addActionListener((actionevent) -> { -+ String msg = jtextfield.getText().trim(); -+ if (!msg.isEmpty()) { -+ server.issueCommand(msg, server.getServerCommandListener()); -+ history.add(msg); -+ historyIndex = -1; -+ } -+ jtextfield.setText(""); -+ }); -+ jtextfield.getInputMap().put(KeyStroke.getKeyStroke("UP"), "up"); -+ jtextfield.getInputMap().put(KeyStroke.getKeyStroke("DOWN"), "down"); -+ jtextfield.getActionMap().put("up", new AbstractAction() { -+ @Override -+ public void actionPerformed(ActionEvent actionEvent) { -+ if (historyIndex < 0) { -+ currentCommand = jtextfield.getText(); -+ } -+ if (historyIndex < history.size() - 1) { -+ jtextfield.setText(history.get(++historyIndex)); -+ } -+ } -+ }); -+ jtextfield.getActionMap().put("down", new AbstractAction() { -+ @Override -+ public void actionPerformed(ActionEvent actionEvent) { -+ if (historyIndex >= 0) { -+ if (historyIndex == 0) { -+ --historyIndex; -+ jtextfield.setText(currentCommand); -+ } else { -+ --historyIndex; -+ jtextfield.setText(history.get(historyIndex)); -+ } -+ } -+ } -+ }); -+ -+ JScrollPane jscrollpane = new JScrollPane(console, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); -+ -+ add(jscrollpane, "Center"); -+ add(jtextfield, "South"); -+ setBorder(new TitledBorder(new EtchedBorder(), "Console")); -+ -+ logAppenderThread = new Thread(() -> { -+ String msg; -+ while ((msg = QueueLogAppender.getNextLogEvent("ServerGuiConsole")) != null) { -+ this.print(console, jscrollpane, msg); -+ } -+ -+ }); -+ logAppenderThread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LOGGER)); -+ logAppenderThread.setDaemon(true); -+ } -+ -+ public void start() { -+ logAppenderThread.start(); -+ } -+ -+ private void print(JColorTextPane console, JScrollPane jscrollpane, String str) { -+ if (!SwingUtilities.isEventDispatchThread()) { -+ SwingUtilities.invokeLater(() -> print(console, jscrollpane, str)); -+ } else { -+ JScrollBar jscrollbar = jscrollpane.getVerticalScrollBar(); -+ boolean scrollToBottom = false; -+ -+ if (jscrollpane.getViewport().getView() == console) { -+ scrollToBottom = (double) jscrollbar.getValue() + jscrollbar.getSize().getHeight() + (double) (MONOSPACED.getSize() * 4) > (double) jscrollbar.getMaximum(); -+ } -+ -+ console.append(str); -+ -+ if (scrollToBottom) { -+ jscrollbar.setValue(Integer.MAX_VALUE); -+ } -+ } -+ } -+ -+ public static class CommandHistory extends LinkedList { -+ @Override -+ public boolean add(String command) { -+ if (size() > 1000) { -+ remove(); -+ } -+ return super.offerFirst(command); -+ } -+ } -+} -diff --git a/src/main/java/net/pl3x/purpur/gui/info/DetailsListSelectionModel.java b/src/main/java/net/pl3x/purpur/gui/info/DetailsListSelectionModel.java -new file mode 100644 -index 000000000..4e0b80fdd ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/gui/info/DetailsListSelectionModel.java -@@ -0,0 +1,21 @@ -+package net.pl3x.purpur.gui.info; -+ -+import javax.swing.DefaultListSelectionModel; -+ -+public class DetailsListSelectionModel extends DefaultListSelectionModel { -+ @Override -+ public void setAnchorSelectionIndex(final int anchorIndex) { -+ } -+ -+ @Override -+ public void setLeadAnchorNotificationEnabled(final boolean flag) { -+ } -+ -+ @Override -+ public void setLeadSelectionIndex(final int leadIndex) { -+ } -+ -+ @Override -+ public void setSelectionInterval(final int index0, final int index1) { -+ } -+} -diff --git a/src/main/java/net/pl3x/purpur/gui/info/JInfoPanel.java b/src/main/java/net/pl3x/purpur/gui/info/JInfoPanel.java -new file mode 100644 -index 000000000..c4903c7db ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/gui/info/JInfoPanel.java -@@ -0,0 +1,42 @@ -+package net.pl3x.purpur.gui.info; -+ -+import net.minecraft.server.MinecraftServer; -+import net.pl3x.purpur.gui.info.graph.RAMGraph; -+ -+import javax.swing.JPanel; -+import javax.swing.Timer; -+import java.awt.BorderLayout; -+import java.awt.Dimension; -+ -+public class JInfoPanel extends JPanel { -+ private final Timer timer; -+ private final RAMGraph ramGraph; -+ -+ public JInfoPanel(MinecraftServer server) { -+ super(new BorderLayout()); -+ -+ setOpaque(false); -+ -+ ramGraph = new RAMGraph(); -+ RAMDetails ramDetails = new RAMDetails(server); -+ -+ add(ramGraph, "North"); -+ add(ramDetails, "Center"); -+ -+ timer = new Timer(500, (event) -> { -+ ramGraph.update(); -+ ramDetails.update(); -+ }); -+ timer.start(); -+ } -+ -+ @Override -+ public Dimension getPreferredSize() { -+ return new Dimension(350, 200); -+ } -+ -+ public void stop() { -+ timer.stop(); -+ ramGraph.stop(); -+ } -+} -diff --git a/src/main/java/net/pl3x/purpur/gui/info/RAMDetails.java b/src/main/java/net/pl3x/purpur/gui/info/RAMDetails.java -new file mode 100644 -index 000000000..1e049d575 ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/gui/info/RAMDetails.java -@@ -0,0 +1,59 @@ -+package net.pl3x.purpur.gui.info; -+ -+import net.minecraft.server.MinecraftServer; -+import net.minecraft.server.SystemUtils; -+import net.pl3x.purpur.gui.info.graph.GraphData; -+import net.pl3x.purpur.gui.info.graph.RAMGraph; -+import org.bukkit.Bukkit; -+ -+import javax.swing.DefaultListCellRenderer; -+import javax.swing.JList; -+import javax.swing.border.EmptyBorder; -+import java.awt.Dimension; -+import java.text.DecimalFormat; -+import java.text.DecimalFormatSymbols; -+import java.util.Locale; -+import java.util.Vector; -+ -+public class RAMDetails extends JList { -+ private static final DecimalFormat DECIMAL_FORMAT = SystemUtils.a(new DecimalFormat("########0.000"), (format) -+ -> format.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ROOT))); -+ -+ private final MinecraftServer server; -+ -+ public RAMDetails(MinecraftServer server) { -+ this.server = server; -+ -+ setBorder(new EmptyBorder(0, 10, 0, 0)); -+ setFixedCellHeight(20); -+ setOpaque(false); -+ -+ DefaultListCellRenderer renderer = new DefaultListCellRenderer(); -+ renderer.setOpaque(false); -+ setCellRenderer(renderer); -+ -+ setSelectionModel(new DetailsListSelectionModel()); -+ } -+ -+ @Override -+ public Dimension getPreferredSize() { -+ return new Dimension(350, 100); -+ } -+ -+ public void update() { -+ GraphData data = RAMGraph.DATA.peekLast(); -+ Vector vector = new Vector<>(); -+ vector.add("Memory use: " + (data.getUsedMem() / 1024L / 1024L) + " mb (" + (data.getFree() * 100L / data.getMax()) + "% free)"); -+ vector.add("Heap: " + (data.getTotal() / 1024L / 1024L) + " / " + (data.getMax() / 1024L / 1024L) + " mb"); -+ vector.add("Avg tick: " + DECIMAL_FORMAT.format(server.tickTimes5s.getAverage()) + " ms"); -+ setListData(vector); -+ } -+ -+ private double getAverage(long[] values) { -+ long total = 0L; -+ for (long value : values) { -+ total += value; -+ } -+ return (double) total / (double) values.length; -+ } -+} -diff --git a/src/main/java/net/pl3x/purpur/gui/info/graph/GraphColor.java b/src/main/java/net/pl3x/purpur/gui/info/graph/GraphColor.java -new file mode 100644 -index 000000000..2fdb9bdd0 ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/gui/info/graph/GraphColor.java -@@ -0,0 +1,44 @@ -+package net.pl3x.purpur.gui.info.graph; -+ -+import java.awt.Color; -+ -+public class GraphColor { -+ private static final Color[] colorLine = new Color[101]; -+ private static final Color[] colorFill = new Color[101]; -+ -+ static { -+ for (int i = 0; i < 101; i++) { -+ Color color = createColor(i); -+ colorLine[i] = new Color(color.getRed() / 2, color.getGreen() / 2, color.getBlue() / 2, 255); -+ colorFill[i] = new Color(colorLine[i].getRed(), colorLine[i].getGreen(), colorLine[i].getBlue(), 125); -+ } -+ } -+ -+ public static Color getLineColor(int percent) { -+ return colorLine[percent]; -+ } -+ -+ public static Color getFillColor(int percent) { -+ return colorFill[percent]; -+ } -+ -+ private static Color createColor(int percent) { -+ if (percent <= 50) { -+ return new Color(0X00FF00); -+ } -+ -+ int value = 510 - (int) (Math.min(Math.max(0, ((percent - 50) / 50F)), 1) * 510); -+ -+ int red, green; -+ if (value < 255) { -+ red = 255; -+ green = (int) (Math.sqrt(value) * 16); -+ } else { -+ green = 255; -+ value = value - 255; -+ red = 255 - (value * value / 255); -+ } -+ -+ return new Color(red, green, 0); -+ } -+} -diff --git a/src/main/java/net/pl3x/purpur/gui/info/graph/GraphData.java b/src/main/java/net/pl3x/purpur/gui/info/graph/GraphData.java -new file mode 100644 -index 000000000..85babad9c ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/gui/info/graph/GraphData.java -@@ -0,0 +1,47 @@ -+package net.pl3x.purpur.gui.info.graph; -+ -+import java.awt.Color; -+ -+public class GraphData { -+ private long total; -+ private long free; -+ private long max; -+ private long usedMem; -+ private int usedPercent; -+ -+ public GraphData(long total, long free, long max) { -+ this.total = total; -+ this.free = free; -+ this.max = max; -+ this.usedMem = total - free; -+ this.usedPercent = usedMem == 0 ? 0 : (int) (usedMem * 100L / max); -+ } -+ -+ public long getTotal() { -+ return total; -+ } -+ -+ public long getFree() { -+ return free; -+ } -+ -+ public long getMax() { -+ return max; -+ } -+ -+ public long getUsedMem() { -+ return usedMem; -+ } -+ -+ public int getUsedPercent() { -+ return usedPercent; -+ } -+ -+ public Color getFillColor() { -+ return GraphColor.getFillColor(usedPercent); -+ } -+ -+ public Color getLineColor() { -+ return GraphColor.getLineColor(usedPercent); -+ } -+} -diff --git a/src/main/java/net/pl3x/purpur/gui/info/graph/RAMGraph.java b/src/main/java/net/pl3x/purpur/gui/info/graph/RAMGraph.java -new file mode 100644 -index 000000000..0c0c73bee ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/gui/info/graph/RAMGraph.java -@@ -0,0 +1,144 @@ -+package net.pl3x.purpur.gui.info.graph; -+ -+import javax.swing.JComponent; -+import javax.swing.SwingUtilities; -+import javax.swing.Timer; -+import javax.swing.ToolTipManager; -+import java.awt.Color; -+import java.awt.Dimension; -+import java.awt.Graphics; -+import java.awt.MouseInfo; -+import java.awt.Point; -+import java.awt.PointerInfo; -+import java.awt.event.MouseAdapter; -+import java.awt.event.MouseEvent; -+import java.text.SimpleDateFormat; -+import java.util.Date; -+import java.util.LinkedList; -+import java.util.concurrent.TimeUnit; -+ -+public class RAMGraph extends JComponent { -+ public static final LinkedList DATA = new LinkedList() { -+ @Override -+ public boolean add(GraphData data) { -+ if (size() >= 348) { -+ remove(); -+ } -+ return super.add(data); -+ } -+ }; -+ -+ static { -+ GraphData empty = new GraphData(0, 0, 0); -+ for (int i = 0; i < 350; i++) { -+ DATA.add(empty); -+ } -+ } -+ -+ private final Timer timer; -+ private final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm:ss"); -+ -+ private int currentTick; -+ -+ public RAMGraph() { -+ ToolTipManager.sharedInstance().setInitialDelay(0); -+ -+ addMouseListener(new MouseAdapter() { -+ final int defaultDismissTimeout = ToolTipManager.sharedInstance().getDismissDelay(); -+ final int dismissDelayMinutes = (int) TimeUnit.MINUTES.toMillis(10); -+ -+ @Override -+ public void mouseEntered(MouseEvent me) { -+ ToolTipManager.sharedInstance().setDismissDelay(dismissDelayMinutes); -+ } -+ -+ @Override -+ public void mouseExited(MouseEvent me) { -+ ToolTipManager.sharedInstance().setDismissDelay(defaultDismissTimeout); -+ } -+ }); -+ -+ timer = new Timer(50, (event) -> repaint()); -+ timer.start(); -+ } -+ -+ @Override -+ public Dimension getPreferredSize() { -+ return new Dimension(350, 110); -+ } -+ -+ public void update() { -+ Runtime jvm = Runtime.getRuntime(); -+ DATA.add(new GraphData(jvm.totalMemory(), jvm.freeMemory(), jvm.maxMemory())); -+ -+ PointerInfo pointerInfo = MouseInfo.getPointerInfo(); -+ if (pointerInfo != null) { -+ Point point = pointerInfo.getLocation(); -+ if (point != null) { -+ Point loc = new Point(point); -+ SwingUtilities.convertPointFromScreen(loc, this); -+ if (this.contains(loc)) { -+ ToolTipManager.sharedInstance().mouseMoved( -+ new MouseEvent(this, -1, System.currentTimeMillis(), 0, loc.x, loc.y, -+ point.x, point.y, 0, false, 0)); -+ } -+ } -+ } -+ -+ currentTick++; -+ } -+ -+ @Override -+ public void paint(Graphics graphics) { -+ graphics.setColor(new Color(0xFFFFFFFF)); -+ graphics.fillRect(0, 0, 350, 100); -+ -+ graphics.setColor(new Color(0x888888)); -+ graphics.drawLine(1, 25, 348, 25); -+ graphics.drawLine(1, 50, 348, 50); -+ graphics.drawLine(1, 75, 348, 75); -+ -+ int i = 0; -+ for (GraphData data : DATA) { -+ i++; -+ if ((i + currentTick) % 120 == 0) { -+ graphics.setColor(new Color(0x888888)); -+ graphics.drawLine(i, 1, i, 99); -+ } -+ int used = data.getUsedPercent(); -+ if (used > 0) { -+ Color color = data.getLineColor(); -+ graphics.setColor(data.getFillColor()); -+ graphics.fillRect(i, 100 - used, 1, used); -+ graphics.setColor(color); -+ graphics.fillRect(i, 100 - used, 1, 1); -+ } -+ } -+ -+ graphics.setColor(new Color(0xFF000000)); -+ graphics.drawRect(0, 0, 348, 100); -+ -+ Point m = getMousePosition(); -+ if (m != null && m.x > 0 && m.x < 348 && m.y > 0 && m.y < 100) { -+ GraphData data = DATA.get(m.x); -+ int used = data.getUsedPercent(); -+ graphics.setColor(new Color(0x000000)); -+ graphics.drawLine(m.x, 1, m.x, 99); -+ graphics.drawOval(m.x - 2, 100 - used - 2, 5, 5); -+ graphics.setColor(data.getLineColor()); -+ graphics.fillOval(m.x - 2, 100 - used - 2, 5, 5); -+ setToolTipText(String.format("Used: %s mb (%s%%)
%s", -+ Math.round(data.getUsedMem() / 1024F / 1024F), -+ used, getTime(m.x))); -+ } -+ } -+ -+ public String getTime(int halfSeconds) { -+ int millis = (348 - halfSeconds) / 2 * 1000; -+ return TIME_FORMAT.format(new Date((System.currentTimeMillis() - millis))); -+ } -+ -+ public void stop() { -+ timer.stop(); -+ } -+} -diff --git a/src/main/java/net/pl3x/purpur/gui/playerlist/JPlayerList.java b/src/main/java/net/pl3x/purpur/gui/playerlist/JPlayerList.java -new file mode 100644 -index 000000000..17e75a207 ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/gui/playerlist/JPlayerList.java -@@ -0,0 +1,57 @@ -+package net.pl3x.purpur.gui.playerlist; -+ -+import net.minecraft.server.EntityPlayer; -+import net.minecraft.server.MinecraftServer; -+ -+import javax.swing.JList; -+import javax.swing.JMenuItem; -+import javax.swing.JPopupMenu; -+import javax.swing.ListSelectionModel; -+import java.awt.Dimension; -+ -+public class JPlayerList extends JList { -+ private final MinecraftServer server; -+ private final PlayerListModel model; -+ private final JPopupMenu popupMenu; -+ private int currentSelection = -1; -+ private int tickCount; -+ -+ public JPlayerList(MinecraftServer server) { -+ this.server = server; -+ server.addTickable(this::tick); -+ -+ setModel(model = new PlayerListModel(this)); -+ setSelectionMode(ListSelectionModel.SINGLE_SELECTION); -+ addListSelectionListener(event -> currentSelection = event.getFirstIndex()); -+ addMouseListener(new PlayerListMouseAdapter(this)); -+ setCellRenderer(new PlayerListCellRenderer()); -+ -+ popupMenu = new JPopupMenu(); -+ popupMenu.add(new JMenuItem("Details")); -+ popupMenu.add(new JPopupMenu.Separator()); -+ popupMenu.add(new JMenuItem("Kick")); -+ popupMenu.add(new JMenuItem("Ban")); -+ popupMenu.add(new JPopupMenu.Separator()); -+ popupMenu.add(new JMenuItem("Op")); -+ } -+ -+ @Override -+ public Dimension getPreferredSize() { -+ Dimension superPref = super.getPreferredSize(); -+ return new Dimension(330, superPref.height); -+ } -+ -+ public void tick() { -+ if (tickCount++ % 20 == 0) { -+ model.update(server.getPlayerList().getPlayers()); -+ } -+ } -+ -+ public int getCurrentSelection() { -+ return currentSelection; -+ } -+ -+ public JPopupMenu getPopupMenu() { -+ return popupMenu; -+ } -+} -diff --git a/src/main/java/net/pl3x/purpur/gui/playerlist/PlayerListCellRenderer.java b/src/main/java/net/pl3x/purpur/gui/playerlist/PlayerListCellRenderer.java -new file mode 100644 -index 000000000..2f02e9adc ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/gui/playerlist/PlayerListCellRenderer.java -@@ -0,0 +1,22 @@ -+package net.pl3x.purpur.gui.playerlist; -+ -+import com.mojang.authlib.GameProfile; -+import net.minecraft.server.EntityPlayer; -+ -+import javax.swing.DefaultListCellRenderer; -+import javax.swing.JList; -+import java.awt.Component; -+ -+public class PlayerListCellRenderer extends DefaultListCellRenderer { -+ @Override -+ public Component getListCellRendererComponent(JList list, Object player, int index, boolean isSelected, boolean cellHasFocus) { -+ super.getListCellRendererComponent(list, player, index, isSelected, cellHasFocus); -+ if (player instanceof EntityPlayer) { -+ GameProfile profile = ((EntityPlayer) player).getProfile(); -+ setText(profile.getName()); -+ setToolTipText(String.format("%s
%s", -+ profile.getName(), profile.getId())); -+ } -+ return this; -+ } -+} -diff --git a/src/main/java/net/pl3x/purpur/gui/playerlist/PlayerListModel.java b/src/main/java/net/pl3x/purpur/gui/playerlist/PlayerListModel.java -new file mode 100644 -index 000000000..edbf45416 ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/gui/playerlist/PlayerListModel.java -@@ -0,0 +1,47 @@ -+package net.pl3x.purpur.gui.playerlist; -+ -+import net.minecraft.server.EntityPlayer; -+ -+import javax.swing.DefaultListModel; -+import java.util.Collection; -+import java.util.HashSet; -+import java.util.Set; -+ -+public class PlayerListModel extends DefaultListModel { -+ private final Set datas = new HashSet<>(); -+ private final JPlayerList parent; -+ -+ public PlayerListModel(JPlayerList parent) { -+ this.parent = parent; -+ } -+ -+ public void update(Collection players) { -+ boolean hadFocus = parent.hasFocus(); -+ -+ players.forEach(this::add); -+ -+ Set result = new HashSet<>(datas); -+ result.removeIf(players::contains); -+ result.forEach(this::remove); -+ -+ if (parent.getCurrentSelection() >= 0) { -+ parent.setSelectedIndex(parent.getCurrentSelection()); -+ } -+ -+ if (hadFocus) { -+ parent.grabFocus(); -+ } -+ } -+ -+ public void add(EntityPlayer player) { -+ if (datas.add(player)) { -+ addElement(player); -+ } -+ } -+ -+ public void remove(EntityPlayer player) { -+ if (datas.remove(player)) { -+ removeElement(player); -+ } -+ } -+} -diff --git a/src/main/java/net/pl3x/purpur/gui/playerlist/PlayerListMouseAdapter.java b/src/main/java/net/pl3x/purpur/gui/playerlist/PlayerListMouseAdapter.java -new file mode 100644 -index 000000000..13a5eb3ad ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/gui/playerlist/PlayerListMouseAdapter.java -@@ -0,0 +1,32 @@ -+package net.pl3x.purpur.gui.playerlist; -+ -+import javax.swing.SwingUtilities; -+import java.awt.event.MouseAdapter; -+import java.awt.event.MouseEvent; -+ -+public class PlayerListMouseAdapter extends MouseAdapter { -+ private final JPlayerList parent; -+ -+ public PlayerListMouseAdapter(JPlayerList parent) { -+ this.parent = parent; -+ } -+ -+ @Override -+ public void mousePressed(MouseEvent event) { -+ if (!SwingUtilities.isRightMouseButton(event)) { -+ return; -+ } -+ -+ parent.setSelectedIndex(parent.locationToIndex(event.getPoint())); -+ -+ if (parent.isSelectionEmpty()) { -+ return; -+ } -+ -+ if (parent.locationToIndex(event.getPoint()) != parent.getSelectedIndex()) { -+ return; -+ } -+ -+ parent.getPopupMenu().show(parent, event.getX(), event.getY()); -+ } -+} -diff --git a/src/main/java/net/pl3x/purpur/gui/util/GUIColor.java b/src/main/java/net/pl3x/purpur/gui/util/GUIColor.java -new file mode 100644 -index 000000000..973c8ddf9 ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/gui/util/GUIColor.java -@@ -0,0 +1,54 @@ -+package net.pl3x.purpur.gui.util; -+ -+import net.md_5.bungee.api.ChatColor; -+ -+import java.awt.Color; -+import java.util.HashMap; -+import java.util.Map; -+ -+public enum GUIColor { -+ BLACK(ChatColor.BLACK, new Color(0x000000)), -+ DARK_BLUE(ChatColor.DARK_BLUE, new Color(0x0000AA)), -+ DARK_GREEN(ChatColor.DARK_GREEN, new Color(0x00AA00)), -+ DARK_AQUA(ChatColor.DARK_AQUA, new Color(0x009999)), -+ DARK_RED(ChatColor.DARK_RED, new Color(0xAA0000)), -+ DARK_PURPLE(ChatColor.DARK_PURPLE, new Color(0xAA00AA)), -+ GOLD(ChatColor.GOLD, new Color(0xBB8800)), -+ GRAY(ChatColor.GRAY, new Color(0x888888)), -+ DARK_GRAY(ChatColor.DARK_GRAY, new Color(0x444444)), -+ BLUE(ChatColor.BLUE, new Color(0x5555FF)), -+ GREEN(ChatColor.GREEN, new Color(0x55FF55)), -+ AQUA(ChatColor.AQUA, new Color(0x55DDDD)), -+ RED(ChatColor.RED, new Color(0xFF5555)), -+ LIGHT_PURPLE(ChatColor.LIGHT_PURPLE, new Color(0xFF55FF)), -+ YELLOW(ChatColor.YELLOW, new Color(0xFFBB00)), -+ WHITE(ChatColor.WHITE, new Color(0xBBBBBB)); -+ -+ private final ChatColor chat; -+ private final Color color; -+ -+ private static final Map BY_CHAT = new HashMap<>(); -+ -+ GUIColor(ChatColor chat, Color color) { -+ this.chat = chat; -+ this.color = color; -+ } -+ -+ public Color getColor() { -+ return color; -+ } -+ -+ public String getCode() { -+ return chat.toString(); -+ } -+ -+ public static GUIColor getColor(ChatColor chat) { -+ return BY_CHAT.get(chat); -+ } -+ -+ static { -+ for (GUIColor color : values()) { -+ BY_CHAT.put(color.chat, color); -+ } -+ } -+} -diff --git a/src/main/java/net/pl3x/purpur/util/HighlightErrorConverter.java b/src/main/java/net/pl3x/purpur/util/HighlightErrorConverter.java -new file mode 100644 -index 000000000..4b340b88a ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/util/HighlightErrorConverter.java -@@ -0,0 +1,86 @@ -+package net.pl3x.purpur.util; -+ -+import org.apache.logging.log4j.Level; -+import org.apache.logging.log4j.core.LogEvent; -+import org.apache.logging.log4j.core.config.Configuration; -+import org.apache.logging.log4j.core.config.plugins.Plugin; -+import org.apache.logging.log4j.core.layout.PatternLayout; -+import org.apache.logging.log4j.core.pattern.ConverterKeys; -+import org.apache.logging.log4j.core.pattern.LogEventPatternConverter; -+import org.apache.logging.log4j.core.pattern.PatternConverter; -+import org.apache.logging.log4j.core.pattern.PatternFormatter; -+import org.apache.logging.log4j.core.pattern.PatternParser; -+import org.apache.logging.log4j.util.PerformanceSensitive; -+ -+import java.util.List; -+ -+@Plugin(name = "highlightGUIError", category = PatternConverter.CATEGORY) -+@ConverterKeys({"highlightGUIError"}) -+@PerformanceSensitive("allocation") -+public final class HighlightErrorConverter extends LogEventPatternConverter { -+ -+ private static final String ERROR = "\u00A74\u00A7l"; // Bold Red -+ private static final String WARN = "\u00A7e\u00A7l"; // Bold Yellow -+ -+ private final List formatters; -+ -+ protected HighlightErrorConverter(List formatters) { -+ super("highlightGUIError", null); -+ this.formatters = formatters; -+ } -+ -+ @Override -+ public void format(LogEvent event, StringBuilder toAppendTo) { -+ Level level = event.getLevel(); -+ if (level.isMoreSpecificThan(Level.ERROR)) { -+ format(ERROR, event, toAppendTo); -+ return; -+ } else if (level.isMoreSpecificThan(Level.WARN)) { -+ format(WARN, event, toAppendTo); -+ return; -+ } -+ for (PatternFormatter formatter : formatters) { -+ formatter.format(event, toAppendTo); -+ } -+ } -+ -+ private void format(String style, LogEvent event, StringBuilder toAppendTo) { -+ int start = toAppendTo.length(); -+ toAppendTo.append(style); -+ int end = toAppendTo.length(); -+ -+ for (PatternFormatter formatter : formatters) { -+ formatter.format(event, toAppendTo); -+ } -+ -+ if (toAppendTo.length() == end) { -+ toAppendTo.setLength(start); -+ } -+ } -+ -+ @Override -+ public boolean handlesThrowable() { -+ for (final PatternFormatter formatter : formatters) { -+ if (formatter.handlesThrowable()) { -+ return true; -+ } -+ } -+ return false; -+ } -+ -+ public static HighlightErrorConverter newInstance(Configuration config, String[] options) { -+ if (options.length != 1) { -+ LOGGER.error("Incorrect number of options on highlightGUIError. Expected 1 received " + options.length); -+ return null; -+ } -+ if (options[0] == null) { -+ LOGGER.error("No pattern supplied on highlightGUIError"); -+ return null; -+ } -+ -+ PatternParser parser = PatternLayout.createPatternParser(config); -+ List formatters = parser.parse(options[0]); -+ return new HighlightErrorConverter(formatters); -+ } -+ -+} -diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml -index 8af159abd..5bc278a99 100644 ---- a/src/main/resources/log4j2.xml -+++ b/src/main/resources/log4j2.xml -@@ -1,8 +1,17 @@ - -- -+ - - -- -+ -+ -+ -+ -+ -+ -+ -+ -+ - - - --- -2.26.2 - diff --git a/patches/server/0045-Chickens-can-retaliate.patch b/patches/server/0045-Chickens-can-retaliate.patch new file mode 100644 index 000000000..f787b58bc --- /dev/null +++ b/patches/server/0045-Chickens-can-retaliate.patch @@ -0,0 +1,68 @@ +From c4779abb7e9a4c114128b2c3358b6f88f7fc3578 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Sun, 12 Apr 2020 13:19:34 -0500 +Subject: [PATCH] Chickens can retaliate + +--- + .../net/minecraft/server/EntityChicken.java | 21 ++++++++++++++++++- + .../net/pl3x/purpur/PurpurWorldConfig.java | 5 +++++ + 2 files changed, 25 insertions(+), 1 deletion(-) + +diff --git a/src/main/java/net/minecraft/server/EntityChicken.java b/src/main/java/net/minecraft/server/EntityChicken.java +index c6ee92343..ae1f4cb49 100644 +--- a/src/main/java/net/minecraft/server/EntityChicken.java ++++ b/src/main/java/net/minecraft/server/EntityChicken.java +@@ -20,14 +20,33 @@ public class EntityChicken extends EntityAnimal { + @Override + protected void initPathfinder() { + this.goalSelector.a(0, new PathfinderGoalFloat(this)); +- this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.4D)); ++ //this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.4D)); // Purpur - moved down + this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D)); + this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.0D, false, EntityChicken.bC)); + this.goalSelector.a(4, new PathfinderGoalFollowParent(this, 1.1D)); + this.goalSelector.a(5, new PathfinderGoalRandomStrollLand(this, 1.0D)); + this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); + this.goalSelector.a(7, new PathfinderGoalRandomLookaround(this)); ++ // Purpur start ++ if (world.purpurConfig.chickenRetaliate) { ++ this.goalSelector.a(1, new PathfinderGoalMeleeAttack(this, 1.0D, false)); ++ this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this)); ++ } else { ++ this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.4D)); ++ } ++ // Purpur end ++ } ++ ++ // Purpur start ++ @Override ++ protected void initAttributes(World world) { ++ if (world != null) { ++ if (world.purpurConfig.chickenRetaliate) { ++ this.getAttributeMap().getAttribute(GenericAttributes.ATTACK_DAMAGE).setValue(2.0D); ++ } ++ } + } ++ // Purpur end + + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index 12e263d21..77cdd94d5 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -96,6 +96,11 @@ public class PurpurWorldConfig { + turtleEggsBreakFromMinecarts = getBoolean("blocks.turtle_egg.break-from-minecarts", turtleEggsBreakFromMinecarts); + } + ++ public boolean chickenRetaliate = false; ++ private void chickenSettings() { ++ chickenRetaliate = getBoolean("mobs.chicken.retaliate", chickenRetaliate); ++ } ++ + public double creeperChargedChance = 0.0D; + private void creeperSettings() { + creeperChargedChance = getDouble("mobs.creeper.naturally-charged-chance", creeperChargedChance); +-- +2.26.2 + diff --git a/patches/server/0046-Add-EntityPortalReadyEvent.patch b/patches/server/0046-Add-EntityPortalReadyEvent.patch deleted file mode 100644 index 09550ff51..000000000 --- a/patches/server/0046-Add-EntityPortalReadyEvent.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 76ab9614c42d949915127a45567be02453e414ef Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sat, 11 Jan 2020 23:12:52 -0600 -Subject: [PATCH] Add EntityPortalReadyEvent - ---- - .../java/net/minecraft/server/BlockPortal.java | 16 +++++++++------- - src/main/java/net/minecraft/server/Entity.java | 7 ++++--- - .../net/minecraft/server/PortalTravelAgent.java | 5 +++-- - .../java/net/minecraft/server/WorldServer.java | 2 +- - 4 files changed, 17 insertions(+), 13 deletions(-) - -diff --git a/src/main/java/net/minecraft/server/BlockPortal.java b/src/main/java/net/minecraft/server/BlockPortal.java -index 09c7c1318..6880cdd7f 100644 ---- a/src/main/java/net/minecraft/server/BlockPortal.java -+++ b/src/main/java/net/minecraft/server/BlockPortal.java -@@ -54,6 +54,7 @@ public class BlockPortal extends Block { - - } - -+ public boolean createPortal(GeneratorAccess generatoraccess, BlockPosition blockposition) { return a(generatoraccess, blockposition); } // Purpur - OBFHELPER - public boolean a(GeneratorAccess generatoraccess, BlockPosition blockposition) { - BlockPortal.Shape blockportal_shape = this.b(generatoraccess, blockposition); - -@@ -67,8 +68,8 @@ public class BlockPortal extends Block { - } - } - -- @Nullable -- public BlockPortal.Shape b(GeneratorAccess generatoraccess, BlockPosition blockposition) { -+ public BlockPortal.Shape createShape(GeneratorAccess generatoraccess, BlockPosition blockposition) { return b(generatoraccess, blockposition); } // Purpur - OBFHELPER -+ @Nullable public BlockPortal.Shape b(GeneratorAccess generatoraccess, BlockPosition blockposition) { - BlockPortal.Shape blockportal_shape = new BlockPortal.Shape(generatoraccess, blockposition, EnumDirection.EnumAxis.X); - - if (blockportal_shape.d() && blockportal_shape.e == 0) { -@@ -189,6 +190,7 @@ public class BlockPortal extends Block { - private int height; - private int width; - java.util.List blocks = new java.util.ArrayList(); // CraftBukkit - add field -+ public static Block FRAME_BLOCK = Blocks.OBSIDIAN; // Purpur - - public Shape(GeneratorAccess generatoraccess, BlockPosition blockposition, EnumDirection.EnumAxis enumdirection_enumaxis) { - this.a = generatoraccess; -@@ -228,14 +230,14 @@ public class BlockPortal extends Block { - for (i = 0; i < 22; ++i) { - BlockPosition blockposition1 = blockposition.shift(enumdirection, i); - -- if (!this.a(this.a.getType(blockposition1)) || this.a.getType(blockposition1.down()).getBlock() != Blocks.OBSIDIAN) { -+ if (!this.a(this.a.getType(blockposition1)) || this.a.getType(blockposition1.down()).getBlock() != FRAME_BLOCK) { // Purpur - break; - } - } - - Block block = this.a.getType(blockposition.shift(enumdirection, i)).getBlock(); - -- return block == Blocks.OBSIDIAN ? i : 0; -+ return block == FRAME_BLOCK ? i : 0; // Purpur - } - - public int a() { -@@ -270,7 +272,7 @@ public class BlockPortal extends Block { - - if (i == 0) { - block = this.a.getType(blockposition.shift(this.d)).getBlock(); -- if (block != Blocks.OBSIDIAN) { -+ if (block != FRAME_BLOCK) { // Purpur - break label56; - // CraftBukkit start - add the block to our list - } else { -@@ -280,7 +282,7 @@ public class BlockPortal extends Block { - } - } else if (i == this.width - 1) { - block = this.a.getType(blockposition.shift(this.c)).getBlock(); -- if (block != Blocks.OBSIDIAN) { -+ if (block != FRAME_BLOCK) { // Purpur - break label56; - // CraftBukkit start - add the block to our list - } else { -@@ -293,7 +295,7 @@ public class BlockPortal extends Block { - } - - for (i = 0; i < this.width; ++i) { -- if (this.a.getType(this.position.shift(this.c, i).up(this.height)).getBlock() != Blocks.OBSIDIAN) { -+ if (this.a.getType(this.position.shift(this.c, i).up(this.height)).getBlock() != FRAME_BLOCK) { // Purpur - this.height = 0; - break; - // CraftBukkit start - add the block to our list -diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index 580843686..bdf79302b 100644 ---- a/src/main/java/net/minecraft/server/Entity.java -+++ b/src/main/java/net/minecraft/server/Entity.java -@@ -170,9 +170,9 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - protected boolean af; public final boolean inPortal() { return this.af; } // Paper - OBFHELPER - protected int ag; - public DimensionManager dimension; -- protected BlockPosition ai; -- protected Vec3D aj; -- protected EnumDirection ak; -+ public BlockPosition ai; // Purpur - protected -> public -+ public Vec3D aj; // Purpur - protected -> public -+ public EnumDirection ak; // Purpur - protected -> public - private boolean invulnerable; - protected UUID uniqueID; - protected String am; -@@ -2472,6 +2472,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - this.world.getMethodProfiler().enter("portal"); - this.ag = i; - this.portalCooldown = this.ba(); -+ if (new net.pl3x.purpur.event.entity.EntityPortalReadyEvent(getBukkitEntity()).callEvent()) // Purpur - // CraftBukkit start - if (this instanceof EntityPlayer) { - ((EntityPlayer) this).a(this.world.worldProvider.getDimensionManager().getType() == DimensionManager.NETHER ? DimensionManager.OVERWORLD : DimensionManager.NETHER, PlayerTeleportEvent.TeleportCause.NETHER_PORTAL); -diff --git a/src/main/java/net/minecraft/server/PortalTravelAgent.java b/src/main/java/net/minecraft/server/PortalTravelAgent.java -index f84dd6d9b..f50e9670b 100644 ---- a/src/main/java/net/minecraft/server/PortalTravelAgent.java -+++ b/src/main/java/net/minecraft/server/PortalTravelAgent.java -@@ -11,6 +11,7 @@ public class PortalTravelAgent { - - private final WorldServer world; - private final Random b; -+ public Block FRAME_BLOCK = Blocks.OBSIDIAN; // Purpur - - public PortalTravelAgent(WorldServer worldserver) { - this.world = worldserver; -@@ -233,7 +234,7 @@ public class PortalTravelAgent { - boolean flag1 = l2 < 0; - - blockposition_mutableblockposition.d(j3, l3, i4); -- blockList.setTypeAndData(blockposition_mutableblockposition, flag1 ? Blocks.OBSIDIAN.getBlockData() : Blocks.AIR.getBlockData(), 3); // CraftBukkit -+ blockList.setTypeAndData(blockposition_mutableblockposition, flag1 ? FRAME_BLOCK.getBlockData() : Blocks.AIR.getBlockData(), 3); // CraftBukkit // Purpur - } - } - } -@@ -243,7 +244,7 @@ public class PortalTravelAgent { - for (i3 = -1; i3 < 4; ++i3) { - if (k2 == -1 || k2 == 2 || i3 == -1 || i3 == 3) { - blockposition_mutableblockposition.d(i5 + k2 * k5, j5 + i3, j2 + k2 * l5); -- blockList.setTypeAndData(blockposition_mutableblockposition, Blocks.OBSIDIAN.getBlockData(), 3); // CraftBukkit -+ blockList.setTypeAndData(blockposition_mutableblockposition, FRAME_BLOCK.getBlockData(), 3); // CraftBukkit // Purpur - } - } - } -diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 156c87ed4..610542dc8 100644 ---- a/src/main/java/net/minecraft/server/WorldServer.java -+++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -76,7 +76,7 @@ public class WorldServer extends World { - public boolean savingDisabled; - private boolean everyoneSleeping; - private int emptyTime; -- private final PortalTravelAgent portalTravelAgent; -+ public PortalTravelAgent portalTravelAgent; // Purpur - private final -> public non-final - private final TickListServer nextTickListBlock; - private final TickListServer nextTickListFluid; - private final Set navigators; final com.tuinity.tuinity.util.maplist.IteratorSafeOrderedReferenceSet navigatorsForIteration = new com.tuinity.tuinity.util.maplist.IteratorSafeOrderedReferenceSet<>(2048, 0.5f, 2048, 0.2); // Tuinity - make removing entities while ticking safe --- -2.26.2 - diff --git a/patches/server/0046-Add-option-to-set-armorstand-step-height.patch b/patches/server/0046-Add-option-to-set-armorstand-step-height.patch new file mode 100644 index 000000000..8d8837242 --- /dev/null +++ b/patches/server/0046-Add-option-to-set-armorstand-step-height.patch @@ -0,0 +1,41 @@ +From 400fc0a593ffa7945c7d199507bcddd2273666e0 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Sun, 6 Oct 2019 12:46:35 -0500 +Subject: [PATCH] Add option to set armorstand step height + +--- + src/main/java/net/minecraft/server/EntityArmorStand.java | 1 + + src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 5 +++++ + 2 files changed, 6 insertions(+) + +diff --git a/src/main/java/net/minecraft/server/EntityArmorStand.java b/src/main/java/net/minecraft/server/EntityArmorStand.java +index 250bccee4..7543f2cee 100644 +--- a/src/main/java/net/minecraft/server/EntityArmorStand.java ++++ b/src/main/java/net/minecraft/server/EntityArmorStand.java +@@ -615,6 +615,7 @@ public class EntityArmorStand extends EntityLiving { + + @Override + public void tick() { ++ setStepHeight(world.purpurConfig.armorstandStepHeight); // Purpur + // Paper start + if (!this.canTick) { + if (this.noTickPoseDirty) { +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index 77cdd94d5..d403450e2 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -69,6 +69,11 @@ public class PurpurWorldConfig { + return PurpurConfig.config.getString("world-settings." + worldName + "." + path, PurpurConfig.config.getString("world-settings.default." + path)); + } + ++ public float armorstandStepHeight = 0.0F; ++ private void armorstandSettings() { ++ armorstandStepHeight = (float) getDouble("gameplay-mechanics.armorstand.step-height", armorstandStepHeight); ++ } ++ + public boolean idleTimeoutKick = true; + public boolean idleTimeoutTickNearbyEntities = true; + public boolean idleTimeoutCountAsSleeping = false; +-- +2.26.2 + diff --git a/patches/server/0047-Cat-spawning-options.patch b/patches/server/0047-Cat-spawning-options.patch new file mode 100644 index 000000000..494b98d3d --- /dev/null +++ b/patches/server/0047-Cat-spawning-options.patch @@ -0,0 +1,143 @@ +From 55b3a3d0f209f9fed5b1973bb36c08b6534aaafc Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Thu, 26 Dec 2019 18:52:55 -0600 +Subject: [PATCH] Cat spawning options + +--- + .../net/minecraft/server/IEntityAccess.java | 1 + + .../net/minecraft/server/MobSpawnerCat.java | 24 ++++++++++++------- + .../net/minecraft/server/VillagePlace.java | 1 + + .../minecraft/server/VillagePlaceType.java | 3 ++- + .../net/minecraft/server/WorldServer.java | 1 + + .../net/pl3x/purpur/PurpurWorldConfig.java | 9 +++++++ + 6 files changed, 30 insertions(+), 9 deletions(-) + +diff --git a/src/main/java/net/minecraft/server/IEntityAccess.java b/src/main/java/net/minecraft/server/IEntityAccess.java +index d3ea51c27..c9a808e22 100644 +--- a/src/main/java/net/minecraft/server/IEntityAccess.java ++++ b/src/main/java/net/minecraft/server/IEntityAccess.java +@@ -45,6 +45,7 @@ public interface IEntityAccess { + } + } + ++ default List getEntitiesInAABB(Class oclass, AxisAlignedBB axisalignedbb) { return a(oclass, axisalignedbb); } // Purpur - OBFHELPER + default List a(Class oclass, AxisAlignedBB axisalignedbb) { + return this.a(oclass, axisalignedbb, IEntitySelector.g); + } +diff --git a/src/main/java/net/minecraft/server/MobSpawnerCat.java b/src/main/java/net/minecraft/server/MobSpawnerCat.java +index 67c20747a..68d37121f 100644 +--- a/src/main/java/net/minecraft/server/MobSpawnerCat.java ++++ b/src/main/java/net/minecraft/server/MobSpawnerCat.java +@@ -16,7 +16,7 @@ public class MobSpawnerCat implements MobSpawner { + if (this.a > 0) { + return 0; + } else { +- this.a = 1200; ++ this.a = worldserver.purpurConfig.catSpawnDelay; // Purpur; + EntityPlayer entityplayer = worldserver.h(); + + if (entityplayer == null) { +@@ -50,10 +50,14 @@ public class MobSpawnerCat implements MobSpawner { + } + + private int a(WorldServer worldserver, BlockPosition blockposition) { +- boolean flag = true; +- +- if (worldserver.x().a(VillagePlaceType.r.c(), blockposition, 48, VillagePlace.Occupancy.IS_OCCUPIED) > 4L) { +- List list = worldserver.a(EntityCat.class, (new AxisAlignedBB(blockposition)).grow(48.0D, 8.0D, 48.0D)); ++ // Purpur start ++ int range = worldserver.purpurConfig.catSpawnVillageScanRange; ++ if (range <= 0) { ++ return 0; ++ } ++ if (worldserver.getVillagePlace().count(VillagePlaceType.home().predicate(), blockposition, range, VillagePlace.Occupancy.IS_OCCUPIED) > 4L) { ++ List list = worldserver.a(EntityCat.class, (new AxisAlignedBB(blockposition)).grow(range, 8.0D, range)); ++ // Purpur end + + if (list.size() < 5) { + return this.a(blockposition, (World) worldserver); +@@ -64,9 +68,13 @@ public class MobSpawnerCat implements MobSpawner { + } + + private int a(World world, BlockPosition blockposition) { +- boolean flag = true; +- List list = world.a(EntityCat.class, (new AxisAlignedBB(blockposition)).grow(16.0D, 8.0D, 16.0D)); +- ++ // Purpur start ++ int range = world.purpurConfig.catSpawnSwampHutScanRange; ++ if (range <= 0) { ++ return 0; ++ } ++ List list = world.getEntitiesInAABB(EntityCat.class, (new AxisAlignedBB(blockposition)).grow(range, 8.0D, range)); ++ // Purpur end + return list.size() < 1 ? this.a(blockposition, world) : 0; + } + +diff --git a/src/main/java/net/minecraft/server/VillagePlace.java b/src/main/java/net/minecraft/server/VillagePlace.java +index 303f6b095..11d16842d 100644 +--- a/src/main/java/net/minecraft/server/VillagePlace.java ++++ b/src/main/java/net/minecraft/server/VillagePlace.java +@@ -45,6 +45,7 @@ public class VillagePlace extends RegionFileSection { + ((VillagePlaceSection) this.e(SectionPosition.a(blockposition).s())).a(blockposition); + } + ++ public long count(Predicate predicate, BlockPosition blockposition, int i, VillagePlace.Occupancy villageplace_occupancy) { return a(predicate, blockposition, i, villageplace_occupancy); } // Purpur - OBFHELPER + public long a(Predicate predicate, BlockPosition blockposition, int i, VillagePlace.Occupancy villageplace_occupancy) { + return this.c(predicate, blockposition, i, villageplace_occupancy).count(); + } +diff --git a/src/main/java/net/minecraft/server/VillagePlaceType.java b/src/main/java/net/minecraft/server/VillagePlaceType.java +index 5bd3bcc2b..5f2bb140a 100644 +--- a/src/main/java/net/minecraft/server/VillagePlaceType.java ++++ b/src/main/java/net/minecraft/server/VillagePlaceType.java +@@ -44,7 +44,7 @@ public class VillagePlaceType { + public static final VillagePlaceType o = a("shepherd", a(Blocks.LOOM), 1, 1); + public static final VillagePlaceType p = a("toolsmith", a(Blocks.SMITHING_TABLE), 1, 1); + public static final VillagePlaceType q = a("weaponsmith", a(Blocks.GRINDSTONE), 1, 1); +- public static final VillagePlaceType r = a("home", VillagePlaceType.z, 1, 1); ++ public static final VillagePlaceType r = a("home", VillagePlaceType.z, 1, 1); public static VillagePlaceType home() { return r; } // Purpur - OBFHELPER + public static final VillagePlaceType s = a("meeting", a(Blocks.BELL), 32, 6); + public static final VillagePlaceType t = a("beehive", a(Blocks.BEEHIVE), 0, 1); + public static final VillagePlaceType u = a("bee_nest", a(Blocks.BEE_NEST), 0, 1); +@@ -83,6 +83,7 @@ public class VillagePlaceType { + return this.D; + } + ++ public Predicate predicate() { return c(); } // Purpur - OBFHELPER + public Predicate c() { + return this.E; + } +diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java +index 7955a079b..149a0ada4 100644 +--- a/src/main/java/net/minecraft/server/WorldServer.java ++++ b/src/main/java/net/minecraft/server/WorldServer.java +@@ -1881,6 +1881,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { + } + } + ++ public VillagePlace getVillagePlace() { return x(); } // Purpur - OBFHELPER + public VillagePlace x() { + return this.getChunkProvider().j(); + } +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index d403450e2..ec490745b 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -101,6 +101,15 @@ public class PurpurWorldConfig { + turtleEggsBreakFromMinecarts = getBoolean("blocks.turtle_egg.break-from-minecarts", turtleEggsBreakFromMinecarts); + } + ++ public int catSpawnDelay = 1200; ++ public int catSpawnSwampHutScanRange = 16; ++ public int catSpawnVillageScanRange = 48; ++ private void catSettings() { ++ catSpawnDelay = getInt("mobs.cat.spawn-delay", catSpawnDelay); ++ catSpawnSwampHutScanRange = getInt("mobs.cat.scan-range-for-other-cats.swamp-hut", catSpawnSwampHutScanRange); ++ catSpawnVillageScanRange = getInt("mobs.cat.scan-range-for-other-cats.village", catSpawnVillageScanRange); ++ } ++ + public boolean chickenRetaliate = false; + private void chickenSettings() { + chickenRetaliate = getBoolean("mobs.chicken.retaliate", chickenRetaliate); +-- +2.26.2 + diff --git a/patches/server/0048-Add-blacklist-option-for-grindstone.patch b/patches/server/0048-Add-blacklist-option-for-grindstone.patch deleted file mode 100644 index 86a85242d..000000000 --- a/patches/server/0048-Add-blacklist-option-for-grindstone.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 5de138cbdf306a02f264c50f32f22c6864d001f1 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Thu, 1 Aug 2019 19:15:12 -0500 -Subject: [PATCH] Add blacklist option for grindstone - ---- - .../minecraft/server/ContainerGrindstone.java | 17 +++++++++++++++++ - .../java/net/minecraft/server/ItemStack.java | 6 ++++++ - .../java/net/pl3x/purpur/PurpurWorldConfig.java | 12 ++++++++++++ - 3 files changed, 35 insertions(+) - -diff --git a/src/main/java/net/minecraft/server/ContainerGrindstone.java b/src/main/java/net/minecraft/server/ContainerGrindstone.java -index 83cb0cd64..2a849d0ec 100644 ---- a/src/main/java/net/minecraft/server/ContainerGrindstone.java -+++ b/src/main/java/net/minecraft/server/ContainerGrindstone.java -@@ -61,12 +61,24 @@ public class ContainerGrindstone extends Container { - this.a(new Slot(this.craftInventory, 0, 49, 19) { - @Override - public boolean isAllowed(ItemStack itemstack) { -+ // Purpur start -+ if (containeraccess.getWorld().purpurConfig.grindstoneBlacklistDisallowPlacement && containeraccess.getWorld().purpurConfig.grindstoneBlacklist.contains(itemstack.getId())) { -+ getBukkitView().getTopInventory().getViewers().forEach(viewer -> ((Player) viewer).updateInventory()); -+ return false; -+ } -+ // Purpur end - return itemstack.e() || itemstack.getItem() == Items.ENCHANTED_BOOK || itemstack.hasEnchantments(); - } - }); - this.a(new Slot(this.craftInventory, 1, 49, 40) { - @Override - public boolean isAllowed(ItemStack itemstack) { -+ // Purpur start -+ if (containeraccess.getWorld().purpurConfig.grindstoneBlacklistDisallowPlacement && containeraccess.getWorld().purpurConfig.grindstoneBlacklist.contains(itemstack.getId())) { -+ getBukkitView().getTopInventory().getViewers().forEach(viewer -> ((Player) viewer).updateInventory()); -+ return false; -+ } -+ // Purpur end - return itemstack.e() || itemstack.getItem() == Items.ENCHANTED_BOOK || itemstack.hasEnchantments(); - } - }); -@@ -110,6 +122,11 @@ public class ContainerGrindstone extends Container { - } - - private int e(ItemStack itemstack) { -+ // Purpur start -+ if (containeraccess.getWorld().purpurConfig.grindstoneBlacklistReturnsZeroExp && containeraccess.getWorld().purpurConfig.grindstoneBlacklist.contains(itemstack.getId())) { -+ return 0; -+ } -+ // Purpur end - int j = 0; - Map map = EnchantmentManager.a(itemstack); - Iterator iterator = map.entrySet().iterator(); -diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java -index 8c3bbef66..d5e0578b2 100644 ---- a/src/main/java/net/minecraft/server/ItemStack.java -+++ b/src/main/java/net/minecraft/server/ItemStack.java -@@ -542,6 +542,12 @@ public final class ItemStack { - return !this.e() ? this.doMaterialsMatch(itemstack) : !itemstack.isEmpty() && this.getItem() == itemstack.getItem(); - } - -+ // Purpur start -+ public String getId() { -+ return IRegistry.ITEM.getKey(getItem()).toString(); -+ } -+ // Purpur end -+ - public String j() { - return this.getItem().f(this); - } -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 5318a8e32..9c60855d6 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -8,6 +8,7 @@ import net.minecraft.server.MinecraftKey; - import org.bukkit.configuration.ConfigurationSection; - import org.spigotmc.SpigotWorldConfig; - -+import java.util.ArrayList; - import java.util.HashMap; - import java.util.List; - import java.util.Map; -@@ -103,6 +104,17 @@ public class PurpurWorldConfig { - farmlandGetsMoistFromBelow = getBoolean("blocks.farmland.gets-moist-from-below", farmlandGetsMoistFromBelow); - } - -+ public List grindstoneBlacklist = new ArrayList<>(); -+ public boolean grindstoneBlacklistDisallowPlacement = true; -+ public boolean grindstoneBlacklistReturnsZeroExp = true; -+ private void grindstoneBlacklist() { -+ List blacklist = getList("blocks.grindstone.blacklist.blacklisted-items", grindstoneBlacklist); -+ grindstoneBlacklistDisallowPlacement = getBoolean("blocks.grindstone.blacklist.disallow-placement", grindstoneBlacklistDisallowPlacement); -+ grindstoneBlacklistReturnsZeroExp = getBoolean("blocks.grindstone.blacklist.returns-zero-exp", grindstoneBlacklistReturnsZeroExp); -+ grindstoneBlacklist.clear(); -+ grindstoneBlacklist.addAll(blacklist); -+ } -+ - public boolean signAllowColors = false; - public boolean signRightClickEdit = false; - private void signSettings() { --- -2.26.2 - diff --git a/patches/server/0020-Fix-non-black-cat-types-spawning-in-swamp-huts.patch b/patches/server/0048-MC-147659-Fix-non-black-cats-spawning-in-swamp-huts.patch similarity index 81% rename from patches/server/0020-Fix-non-black-cat-types-spawning-in-swamp-huts.patch rename to patches/server/0048-MC-147659-Fix-non-black-cats-spawning-in-swamp-huts.patch index 91009edbb..fcefc2a3c 100644 --- a/patches/server/0020-Fix-non-black-cat-types-spawning-in-swamp-huts.patch +++ b/patches/server/0048-MC-147659-Fix-non-black-cats-spawning-in-swamp-huts.patch @@ -1,17 +1,17 @@ -From 7f22b67baa5bb382abe62b70dfb1ec5bb7ce5929 Mon Sep 17 00:00:00 2001 +From 6cef8b3a0a207fe01ddf73117cc3770203e8c01c Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Thu, 2 Jan 2020 01:23:22 -0600 -Subject: [PATCH] Fix non black cat types spawning in swamp huts +Subject: [PATCH] MC-147659 - Fix non black cats spawning in swamp huts --- src/main/java/net/minecraft/server/MobSpawnerCat.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/minecraft/server/MobSpawnerCat.java b/src/main/java/net/minecraft/server/MobSpawnerCat.java -index 4b55c07d4..fa2222355 100644 +index 68d37121f..318d051b0 100644 --- a/src/main/java/net/minecraft/server/MobSpawnerCat.java +++ b/src/main/java/net/minecraft/server/MobSpawnerCat.java -@@ -84,8 +84,9 @@ public class MobSpawnerCat { +@@ -84,8 +84,9 @@ public class MobSpawnerCat implements MobSpawner { if (entitycat == null) { return 0; } else { diff --git a/patches/server/0021-Cows-eat-mushrooms.patch b/patches/server/0049-Cows-eat-mushrooms.patch similarity index 67% rename from patches/server/0021-Cows-eat-mushrooms.patch rename to patches/server/0049-Cows-eat-mushrooms.patch index 4191db0a9..bdc1ee4bd 100644 --- a/patches/server/0021-Cows-eat-mushrooms.patch +++ b/patches/server/0049-Cows-eat-mushrooms.patch @@ -1,28 +1,20 @@ -From e3b69abad347357a82d5891d9d16bd203d99891f Mon Sep 17 00:00:00 2001 +From 9f6feaf7259dfa214dc7e781eee36b81382ba624 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 4 May 2019 01:10:30 -0500 Subject: [PATCH] Cows eat mushrooms --- - .../java/net/minecraft/server/Entity.java | 2 + + .../java/net/minecraft/server/Entity.java | 1 + .../java/net/minecraft/server/EntityCow.java | 70 +++++++++++++++++++ - .../net/minecraft/server/EntityLiving.java | 5 +- - .../net/pl3x/purpur/PurpurWorldConfig.java | 2 + - 4 files changed, 77 insertions(+), 2 deletions(-) + .../net/minecraft/server/EntityLiving.java | 2 +- + .../net/pl3x/purpur/PurpurWorldConfig.java | 5 ++ + 4 files changed, 77 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index dc72ee435..f5ea12b02 100644 +index ee36c537d..028f94a88 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java -@@ -1283,6 +1283,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - return false; - } - -+ public void playSound(SoundEffect soundeffect, float volume, float pitch) { a(soundeffect, volume, pitch); } // Paper - OBFHELPER - public void a(SoundEffect soundeffect, float f, float f1) { - if (!this.isSilent()) { - this.world.playSound((EntityHuman) null, this.locX(), this.locY(), this.locZ(), soundeffect, this.getSoundCategory(), f, f1); -@@ -2831,6 +2832,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke +@@ -2555,6 +2555,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke this.invulnerable = flag; } @@ -31,27 +23,27 @@ index dc72ee435..f5ea12b02 100644 this.setPositionRotation(entity.locX(), entity.locY(), entity.locZ(), entity.yaw, entity.pitch); } diff --git a/src/main/java/net/minecraft/server/EntityCow.java b/src/main/java/net/minecraft/server/EntityCow.java -index 723a9fa1e..f56fd7c01 100644 +index 30ee6df6b..d6baddb9d 100644 --- a/src/main/java/net/minecraft/server/EntityCow.java +++ b/src/main/java/net/minecraft/server/EntityCow.java -@@ -34,6 +34,7 @@ public class EntityCow extends EntityAnimal { - this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur +@@ -16,6 +16,7 @@ public class EntityCow extends EntityAnimal { + this.goalSelector.a(0, new PathfinderGoalFloat(this)); this.goalSelector.a(1, new PathfinderGoalPanic(this, 2.0D)); this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D)); + if (world.purpurConfig.cowFeedMushrooms > 0) this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.25D, RecipeItemStack.a(Items.WHEAT, Blocks.RED_MUSHROOM.getItem(), Blocks.BROWN_MUSHROOM.getItem()), false)); else // Purpur this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.25D, RecipeItemStack.a(Items.WHEAT), false)); this.goalSelector.a(4, new PathfinderGoalFollowParent(this, 1.25D)); this.goalSelector.a(5, new PathfinderGoalRandomStrollLand(this, 1.0D)); -@@ -96,11 +97,80 @@ public class EntityCow extends EntityAnimal { - // CraftBukkit end +@@ -70,11 +71,80 @@ public class EntityCow extends EntityAnimal { - return true; -+ // Purpur start - feed mushroom to change to mooshroom + entityhuman.a(enumhand, itemstack1); + return EnumInteractionResult.a(this.world.isClientSide); ++ // Purpur start - feed mushroom to change to mooshroom + } else if (world.purpurConfig.cowFeedMushrooms > 0 && getEntityType() != EntityTypes.MOOSHROOM && isMushroom(itemstack)) { + return feedMushroom(entityhuman, itemstack); -+ // Purpur end ++ // Purpur end } else { - return super.a(entityhuman, enumhand); + return super.b(entityhuman, enumhand); } } @@ -71,18 +63,18 @@ index 723a9fa1e..f56fd7c01 100644 + } + } + -+ private boolean feedMushroom(EntityHuman entityhuman, ItemStack itemstack) { ++ private EnumInteractionResult feedMushroom(EntityHuman entityhuman, ItemStack itemstack) { + world.broadcastEntityEffect(this, (byte) 18); // hearts + playSound(SoundEffects.ENTITY_COW_MILK, 1.0F, 1.0F); + if (incrementFeedCount(itemstack) < world.purpurConfig.cowFeedMushrooms) { + if (!entityhuman.abilities.canInstantlyBuild) { + itemstack.subtract(1); + } -+ return true; // require 5 mushrooms to transform (prevents mushroom duping) ++ return EnumInteractionResult.CONSUME; // require 5 mushrooms to transform (prevents mushroom duping) + } + EntityMushroomCow mooshroom = EntityTypes.MOOSHROOM.create(world); + if (mooshroom == null) { -+ return false; ++ return EnumInteractionResult.PASS; + } + if (itemstack.getItem() == Blocks.BROWN_MUSHROOM.getItem()) { + mooshroom.setVariant(EntityMushroomCow.Type.BROWN); @@ -101,10 +93,10 @@ index 723a9fa1e..f56fd7c01 100644 + mooshroom.setCustomName(this.getCustomName()); + } + if (CraftEventFactory.callEntityTransformEvent(this, mooshroom, org.bukkit.event.entity.EntityTransformEvent.TransformReason.INFECTION).isCancelled()) { -+ return false; ++ return EnumInteractionResult.PASS; + } + if (!new com.destroystokyo.paper.event.entity.EntityTransformedEvent(this.getBukkitEntity(), mooshroom.getBukkitEntity(), com.destroystokyo.paper.event.entity.EntityTransformedEvent.TransformedReason.INFECTED).callEvent()) { -+ return false; ++ return EnumInteractionResult.PASS; + } + this.world.addEntity(mooshroom); + this.die(); @@ -116,7 +108,7 @@ index 723a9fa1e..f56fd7c01 100644 + locX() + random.nextFloat(), locY() + (random.nextFloat() * 2), locZ() + random.nextFloat(), 1, + random.nextGaussian() * 0.05D, random.nextGaussian() * 0.05D, random.nextGaussian() * 0.05D, 0, true); + } -+ return true; ++ return EnumInteractionResult.SUCCESS; + } + // Purpur end + @@ -124,38 +116,34 @@ index 723a9fa1e..f56fd7c01 100644 public EntityCow createChild(EntityAgeable entityageable) { return (EntityCow) EntityTypes.COW.a(this.world); diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java -index a3db0e92d..685538793 100644 +index 03477c6e9..63cff85af 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java -@@ -2839,8 +2839,9 @@ public abstract class EntityLiving extends Entity { - this.aK = f; - } - -- @Override -- public void l(float f) { -+ public float getRenderYawOffset() { return this.aI; } // Purpur - OBFHELPER -+ public void setRenderYawOffset(float f) { this.l(f); } // Purpur - OBFHELPER -+ @Override public void l(float f) { - this.aI = f; - } - +@@ -80,7 +80,7 @@ public abstract class EntityLiving extends Entity { + public int maxNoDamageTicks; + public final float aF; + public final float aG; +- public float aH; ++ public float aH; public float getRenderYawOffset() { return this.aH; } public void setRenderYawOffset(float f) { this.aH = f; } // Purpur - OBFHELPER + public float aI; + public float aJ; + public float aK; diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 12fbdf65c..091f30727 100644 +index ec490745b..faddf7c4b 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -145,10 +145,12 @@ public class PurpurWorldConfig { - public boolean cowRidable = false; - public boolean cowRidableInWater = false; - public boolean cowRequireShiftToMount = true; -+ public int cowFeedMushrooms = 0; - private void cowSettings() { - cowRidable = getBoolean("mobs.cow.ridable", cowRidable); - cowRidableInWater = getBoolean("mobs.cow.ridable-in-water", cowRidableInWater); - cowRequireShiftToMount = getBoolean("mobs.cow.require-shift-to-mount", cowRequireShiftToMount); -+ cowFeedMushrooms = getInt("mobs.cow.feed-mushrooms-for-mooshroom", cowFeedMushrooms); +@@ -115,6 +115,11 @@ public class PurpurWorldConfig { + chickenRetaliate = getBoolean("mobs.chicken.retaliate", chickenRetaliate); } - public boolean creeperRidable = false; ++ public int cowFeedMushrooms = 0; ++ private void cowSettings() { ++ cowFeedMushrooms = getInt("mobs.cow.feed-mushrooms-for-mooshroom", cowFeedMushrooms); ++ } ++ + public double creeperChargedChance = 0.0D; + private void creeperSettings() { + creeperChargedChance = getDouble("mobs.creeper.naturally-charged-chance", creeperChargedChance); -- 2.26.2 diff --git a/patches/server/0050-Fix-cow-rotation-when-shearing-mooshroom.patch b/patches/server/0050-Fix-cow-rotation-when-shearing-mooshroom.patch new file mode 100644 index 000000000..62b90947d --- /dev/null +++ b/patches/server/0050-Fix-cow-rotation-when-shearing-mooshroom.patch @@ -0,0 +1,31 @@ +From bb7737a02a0e52a0c6fceadc31e30de3957cc147 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Fri, 3 May 2019 23:53:16 -0500 +Subject: [PATCH] Fix cow rotation when shearing mooshroom + +--- + src/main/java/net/minecraft/server/EntityMushroomCow.java | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/main/java/net/minecraft/server/EntityMushroomCow.java b/src/main/java/net/minecraft/server/EntityMushroomCow.java +index 23ef03306..ecbdc65ec 100644 +--- a/src/main/java/net/minecraft/server/EntityMushroomCow.java ++++ b/src/main/java/net/minecraft/server/EntityMushroomCow.java +@@ -135,7 +135,13 @@ public class EntityMushroomCow extends EntityCow implements IShearable { + + entitycow.setPositionRotation(this.locX(), this.locY(), this.locZ(), this.yaw, this.pitch); + entitycow.setHealth(this.getHealth()); +- entitycow.aH = this.aH; ++ // Purpur start - correctly copy rotation ++ entitycow.copyPositionRotation(this); ++ entitycow.setRenderYawOffset(this.getRenderYawOffset()); ++ entitycow.setHeadRotation(this.getHeadRotation()); ++ entitycow.lastYaw = this.lastYaw; ++ entitycow.lastPitch = this.lastPitch; ++ // Purpur end + if (this.hasCustomName()) { + entitycow.setCustomName(this.getCustomName()); + entitycow.setCustomNameVisible(this.getCustomNameVisible()); +-- +2.26.2 + diff --git a/patches/server/0051-Pigs-give-saddle-back.patch b/patches/server/0051-Pigs-give-saddle-back.patch new file mode 100644 index 000000000..35862b1b9 --- /dev/null +++ b/patches/server/0051-Pigs-give-saddle-back.patch @@ -0,0 +1,52 @@ +From e4a7d439a42b6139c1fe3308fdeaf1b5f8857b1a Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Sun, 12 May 2019 01:14:46 -0500 +Subject: [PATCH] Pigs give saddle back + +--- + src/main/java/net/minecraft/server/EntityPig.java | 12 ++++++++++++ + src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 5 +++++ + 2 files changed, 17 insertions(+) + +diff --git a/src/main/java/net/minecraft/server/EntityPig.java b/src/main/java/net/minecraft/server/EntityPig.java +index cd0a94794..cf2df391a 100644 +--- a/src/main/java/net/minecraft/server/EntityPig.java ++++ b/src/main/java/net/minecraft/server/EntityPig.java +@@ -109,6 +109,18 @@ public class EntityPig extends EntityAnimal implements ISteerable, ISaddleable { + + if (!flag && this.hasSaddle() && !this.isVehicle()) { + if (!this.world.isClientSide) { ++ // Purpur start ++ if (world.purpurConfig.pigGiveSaddleBack && entityhuman.isSneaking()) { ++ this.saddleStorage.setSaddle(false); ++ if (!entityhuman.abilities.canInstantlyBuild) { ++ ItemStack saddle = new ItemStack(Items.SADDLE); ++ if (!entityhuman.inventory.pickup(saddle)) { ++ entityhuman.drop(saddle, false); ++ } ++ } ++ return EnumInteractionResult.SUCCESS; ++ } ++ // Purpur end + entityhuman.startRiding(this); + } + +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index faddf7c4b..84c025c4a 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -161,6 +161,11 @@ public class PurpurWorldConfig { + ironGolemCanSwim = getBoolean("mobs.iron_golem.can-swim", ironGolemCanSwim); + } + ++ public boolean pigGiveSaddleBack = false; ++ private void pigSettings() { ++ pigGiveSaddleBack = getBoolean("mobs.pig.give-saddle-back", pigGiveSaddleBack); ++ } ++ + public String polarBearBreedableItemString = ""; + public Item polarBearBreedableItem = null; + private void polarBearSettings() { +-- +2.26.2 + diff --git a/patches/server/0025-Snowman-drop-and-put-back-pumpkin.patch b/patches/server/0052-Snowman-drop-and-put-back-pumpkin.patch similarity index 65% rename from patches/server/0025-Snowman-drop-and-put-back-pumpkin.patch rename to patches/server/0052-Snowman-drop-and-put-back-pumpkin.patch index 0ac03dfc8..6680aa9f5 100644 --- a/patches/server/0025-Snowman-drop-and-put-back-pumpkin.patch +++ b/patches/server/0052-Snowman-drop-and-put-back-pumpkin.patch @@ -1,26 +1,26 @@ -From 5081aa5658129a710de30dd52ed5053707b0887e Mon Sep 17 00:00:00 2001 +From 71ef94f480dde9459ce85b48fab104f511800038 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Fri, 3 May 2019 23:58:44 -0500 Subject: [PATCH] Snowman drop and put back pumpkin --- .../net/minecraft/server/EntitySnowman.java | 17 +++++++++++++++++ - .../java/net/pl3x/purpur/PurpurWorldConfig.java | 4 ++++ - 2 files changed, 21 insertions(+) + .../java/net/pl3x/purpur/PurpurWorldConfig.java | 7 +++++++ + 2 files changed, 24 insertions(+) diff --git a/src/main/java/net/minecraft/server/EntitySnowman.java b/src/main/java/net/minecraft/server/EntitySnowman.java -index 65d746899..3f6f8ad45 100644 +index 15b886d9b..dfe615814 100644 --- a/src/main/java/net/minecraft/server/EntitySnowman.java +++ b/src/main/java/net/minecraft/server/EntitySnowman.java @@ -7,6 +7,7 @@ import org.bukkit.craftbukkit.event.CraftEventFactory; - public class EntitySnowman extends EntityGolem implements IRangedEntity { + public class EntitySnowman extends EntityGolem implements IShearable, IRangedEntity { + private static final RecipeItemStack PUMPKIN = RecipeItemStack.a(Blocks.PUMPKIN.getItem(), Blocks.CARVED_PUMPKIN.getItem(), Blocks.JACK_O_LANTERN.getItem()); // Purpur private static final DataWatcherObject b = DataWatcher.a(EntitySnowman.class, DataWatcherRegistry.a); public EntitySnowman(EntityTypes entitytypes, World world) { -@@ -142,9 +143,25 @@ public class EntitySnowman extends EntityGolem implements IRangedEntity { +@@ -120,9 +121,25 @@ public class EntitySnowman extends EntityGolem implements IShearable, IRangedEnt itemstack.damage(1, entityhuman, (entityhuman1) -> { entityhuman1.broadcastItemBreak(enumhand); }); @@ -29,43 +29,41 @@ index 65d746899..3f6f8ad45 100644 + EntityItem pumpkin = new EntityItem(world, locX(), locY(), locZ(), new ItemStack(Blocks.CARVED_PUMPKIN.getItem())); + pumpkin.pickupDelay = 10; + world.addEntity(pumpkin); -+ return true; ++ return EnumInteractionResult.SUCCESS; + } + // Purpur end } - return true; + return EnumInteractionResult.a(this.world.isClientSide); + // Purpur start + } else if (world.purpurConfig.snowGolemPutPumpkinBack && !hasPumpkin() && PUMPKIN.test(itemstack)) { + setHasPumpkin(true); + if (!entityhuman.abilities.canInstantlyBuild) { + itemstack.subtract(1); + } -+ return true; ++ return EnumInteractionResult.SUCCESS; + // Purpur end } else { - return tryRide(entityhuman, enumhand); // Purpur + return EnumInteractionResult.PASS; } diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index c9b41cebd..56b67c408 100644 +index 84c025c4a..ce443f9d7 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -540,11 +540,15 @@ public class PurpurWorldConfig { - public boolean snowGolemRidableInWater = false; - public boolean snowGolemRequireShiftToMount = true; - public boolean snowGolemLeaveTrailWhenRidden = false; -+ public boolean snowGolemDropsPumpkin = false; -+ public boolean snowGolemPutPumpkinBack = false; - private void snowGolemSettings() { - snowGolemRidable = getBoolean("mobs.snow_golem.ridable", snowGolemRidable); - snowGolemRidableInWater = getBoolean("mobs.snow_golem.ridable-in-water", snowGolemRidableInWater); - snowGolemRequireShiftToMount = getBoolean("mobs.snow_golem.require-shift-to-mount", snowGolemRequireShiftToMount); - snowGolemLeaveTrailWhenRidden = getBoolean("mobs.snow_golem.leave-trail-when-ridden", snowGolemLeaveTrailWhenRidden); -+ snowGolemDropsPumpkin = getBoolean("mobs.snow_golem.drop-pumpkin-when-sheared", snowGolemDropsPumpkin); -+ snowGolemPutPumpkinBack = getBoolean("mobs.snow_golem.pumpkin-can-be-added-back", snowGolemPutPumpkinBack); +@@ -181,6 +181,13 @@ public class PurpurWorldConfig { + rabbitNaturalKiller = getDouble("mobs.rabbit.spawn-killer-rabbit-chance", rabbitNaturalKiller); } - public boolean spiderRidable = false; ++ public boolean snowGolemDropsPumpkin = false; ++ public boolean snowGolemPutPumpkinBack = false; ++ private void snowGolemSettings() { ++ snowGolemDropsPumpkin = getBoolean("mobs.snow_golem.drop-pumpkin-when-sheared", snowGolemDropsPumpkin); ++ snowGolemPutPumpkinBack = getBoolean("mobs.snow_golem.pumpkin-can-be-added-back", snowGolemPutPumpkinBack); ++ } ++ + public int villagerBrainTicks = 1; + public boolean villagerUseBrainTicksOnlyWhenLagging = true; + private void villagerSettings() { -- 2.26.2 diff --git a/patches/server/0053-Ender-dragon-always-drop-egg.patch b/patches/server/0053-Ender-dragon-always-drop-egg.patch new file mode 100644 index 000000000..6837c1df0 --- /dev/null +++ b/patches/server/0053-Ender-dragon-always-drop-egg.patch @@ -0,0 +1,42 @@ +From cd0557107ef93a0cebc2242260df1d5a841de62d Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Fri, 7 Feb 2020 04:42:57 -0600 +Subject: [PATCH] Ender dragon always drop egg + +--- + src/main/java/net/minecraft/server/EnderDragonBattle.java | 2 +- + src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 5 +++++ + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/main/java/net/minecraft/server/EnderDragonBattle.java b/src/main/java/net/minecraft/server/EnderDragonBattle.java +index 69faefbdb..ecd6af04d 100644 +--- a/src/main/java/net/minecraft/server/EnderDragonBattle.java ++++ b/src/main/java/net/minecraft/server/EnderDragonBattle.java +@@ -358,7 +358,7 @@ public class EnderDragonBattle { + this.bossBattle.setVisible(false); + this.a(true); + this.n(); +- if (!this.previouslyKilled) { ++ if (this.world.purpurConfig.enderDragonAlwaysDropsEggBlock || !this.previouslyKilled) { // Purpur - always place dragon egg + this.world.setTypeUpdate(this.world.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, WorldGenEndTrophy.a), Blocks.DRAGON_EGG.getBlockData()); + } + +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index ce443f9d7..c76b15bef 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -125,6 +125,11 @@ public class PurpurWorldConfig { + creeperChargedChance = getDouble("mobs.creeper.naturally-charged-chance", creeperChargedChance); + } + ++ public boolean enderDragonAlwaysDropsEggBlock = false; ++ private void enderDragonSettings() { ++ enderDragonAlwaysDropsEggBlock = getBoolean("mobs.ender_dragon.always-drop-egg-block", enderDragonAlwaysDropsEggBlock); ++ } ++ + public boolean foxTypeChangesWithTulips = false; + private void foxSettings() { + foxTypeChangesWithTulips = getBoolean("mobs.fox.tulips-change-type", foxTypeChangesWithTulips); +-- +2.26.2 + diff --git a/patches/server/0027-Ender-dragon-always-drop-full-exp.patch b/patches/server/0054-Ender-dragon-always-drop-full-exp.patch similarity index 61% rename from patches/server/0027-Ender-dragon-always-drop-full-exp.patch rename to patches/server/0054-Ender-dragon-always-drop-full-exp.patch index 81238d5cd..4c52fdad8 100644 --- a/patches/server/0027-Ender-dragon-always-drop-full-exp.patch +++ b/patches/server/0054-Ender-dragon-always-drop-full-exp.patch @@ -1,4 +1,4 @@ -From fad47974bd2b9b98b527eca3f3f4322f4fe6ba4f Mon Sep 17 00:00:00 2001 +From f9a625ee7814a6561dbd3793117358008f98d1dd Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 24 Aug 2019 14:42:54 -0500 Subject: [PATCH] Ender dragon always drop full exp @@ -9,37 +9,33 @@ Subject: [PATCH] Ender dragon always drop full exp 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/minecraft/server/EntityEnderDragon.java b/src/main/java/net/minecraft/server/EntityEnderDragon.java -index 54b63395f..e89b96605 100644 +index 63a759cc1..08fa5a975 100644 --- a/src/main/java/net/minecraft/server/EntityEnderDragon.java +++ b/src/main/java/net/minecraft/server/EntityEnderDragon.java -@@ -641,7 +641,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { +@@ -564,7 +564,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { boolean flag = this.world.getGameRules().getBoolean(GameRules.DO_MOB_LOOT); short short0 = 500; -- if (this.bN != null && !this.bN.d()) { -+ if (getEnderDragonBattle() != null && (world.purpurConfig.enderDragonAlwaysDropsFullExp || !getEnderDragonBattle().wasPreviouslyKilled())) { // Purpur +- if (this.bM != null && !this.bM.isPreviouslyKilled()) { ++ if (getEnderDragonBattle() != null && (world.purpurConfig.enderDragonAlwaysDropsFullExp || !getEnderDragonBattle().isPreviouslyKilled())) { // Purpur short0 = 12000; } diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index cc6f8563b..426e6f18b 100644 +index c76b15bef..328a0b4fe 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -207,12 +207,14 @@ public class PurpurWorldConfig { - public boolean enderDragonRequireShiftToMount = true; - public double enderDragonMaxY = 256D; +@@ -126,8 +126,10 @@ public class PurpurWorldConfig { + } + public boolean enderDragonAlwaysDropsEggBlock = false; + public boolean enderDragonAlwaysDropsFullExp = false; private void enderDragonSettings() { - enderDragonRidable = getBoolean("mobs.ender_dragon.ridable", enderDragonRidable); - enderDragonRidableInWater = getBoolean("mobs.ender_dragon.ridable-in-water", enderDragonRidableInWater); - enderDragonRequireShiftToMount = getBoolean("mobs.ender_dragon.require-shift-to-mount", enderDragonRequireShiftToMount); - enderDragonMaxY = getDouble("mobs.ender_dragon.ridable-max-y", enderDragonMaxY); enderDragonAlwaysDropsEggBlock = getBoolean("mobs.ender_dragon.always-drop-egg-block", enderDragonAlwaysDropsEggBlock); + enderDragonAlwaysDropsFullExp = getBoolean("mobs.ender_dragon.always-drop-full-exp", enderDragonAlwaysDropsFullExp); } - public boolean endermanRidable = false; + public boolean foxTypeChangesWithTulips = false; -- 2.26.2 diff --git a/patches/server/0054-Option-for-slimes-not-pushable.patch b/patches/server/0054-Option-for-slimes-not-pushable.patch deleted file mode 100644 index e06afcab3..000000000 --- a/patches/server/0054-Option-for-slimes-not-pushable.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 9b4138db851b38e9c42ecd40ede122f9b75f2ce1 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Fri, 23 Aug 2019 21:56:31 -0500 -Subject: [PATCH] Option for slimes not pushable - ---- - src/main/java/net/minecraft/server/BlockPiston.java | 10 ++++++++++ - src/main/java/net/minecraft/server/BlockSlime.java | 7 +++++++ - src/main/java/net/pl3x/purpur/PurpurConfig.java | 5 +++++ - 3 files changed, 22 insertions(+) - -diff --git a/src/main/java/net/minecraft/server/BlockPiston.java b/src/main/java/net/minecraft/server/BlockPiston.java -index 8312ed779..a1721c63d 100644 ---- a/src/main/java/net/minecraft/server/BlockPiston.java -+++ b/src/main/java/net/minecraft/server/BlockPiston.java -@@ -347,6 +347,16 @@ public class BlockPiston extends BlockDirectional { - } else { - event = new BlockPistonRetractEvent(bblock, blocks, CraftBlock.notchToBlockFace(enumdirection1)); - } -+ // Purpur start -+ if (net.pl3x.purpur.PurpurConfig.slimeBlocksNotPushable) { -+ for (org.bukkit.block.Block block : blocks) { -+ if (block.getType() == org.bukkit.Material.SLIME_BLOCK) { -+ event.setCancelled(true); -+ break; -+ } -+ } -+ } -+ // Purpur end - world.getServer().getPluginManager().callEvent(event); - - if (event.isCancelled()) { -diff --git a/src/main/java/net/minecraft/server/BlockSlime.java b/src/main/java/net/minecraft/server/BlockSlime.java -index 01f32659d..52ab86f0b 100644 ---- a/src/main/java/net/minecraft/server/BlockSlime.java -+++ b/src/main/java/net/minecraft/server/BlockSlime.java -@@ -49,4 +49,11 @@ public class BlockSlime extends BlockHalfTransparent { - - super.stepOn(world, blockposition, entity); - } -+ -+ // Purpur start -+ @Override -+ public EnumPistonReaction getPushReaction(IBlockData iblockdata) { -+ return net.pl3x.purpur.PurpurConfig.slimeBlocksNotPushable ? EnumPistonReaction.BLOCK : super.getPushReaction(iblockdata); -+ } -+ // Purpur end - } -diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java -index ab20fa2fa..72ad9dce7 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java -@@ -149,6 +149,11 @@ public class PurpurConfig { - dontSendUselessEntityPackets = getBoolean("settings.dont-send-useless-entity-packets", dontSendUselessEntityPackets); - } - -+ public static boolean slimeBlocksNotPushable = false; -+ private static void blockSettings() { -+ slimeBlocksNotPushable = getBoolean("settings.blocks.slime.not-movable-by-piston", slimeBlocksNotPushable); -+ } -+ - private static void timingsSettings() { - getString("settings.timings.url", "https://timings.pl3x.net"); - } --- -2.26.2 - diff --git a/patches/server/0028-Signs-editable-on-right-click.patch b/patches/server/0055-Signs-editable-on-right-click.patch similarity index 80% rename from patches/server/0028-Signs-editable-on-right-click.patch rename to patches/server/0055-Signs-editable-on-right-click.patch index b0d8f7fa5..e8370bb3a 100644 --- a/patches/server/0028-Signs-editable-on-right-click.patch +++ b/patches/server/0055-Signs-editable-on-right-click.patch @@ -1,4 +1,4 @@ -From ce9eea9c6ac12ed7d3a82601390684864ab5f0c2 Mon Sep 17 00:00:00 2001 +From ee9e1bedb34e6afdc80e72d7a35ca24a9a5a1aab Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Fri, 24 May 2019 02:39:25 -0500 Subject: [PATCH] Signs editable on right click @@ -10,7 +10,7 @@ Subject: [PATCH] Signs editable on right click 3 files changed, 17 insertions(+) diff --git a/src/main/java/net/minecraft/server/BlockSign.java b/src/main/java/net/minecraft/server/BlockSign.java -index 8a31054a1..d20849ce2 100644 +index cfc1da1f5..3a9871dbc 100644 --- a/src/main/java/net/minecraft/server/BlockSign.java +++ b/src/main/java/net/minecraft/server/BlockSign.java @@ -56,6 +56,17 @@ public abstract class BlockSign extends BlockTileEntity implements IBlockWaterlo @@ -32,10 +32,10 @@ index 8a31054a1..d20849ce2 100644 } else { return EnumInteractionResult.PASS; diff --git a/src/main/java/net/minecraft/server/TileEntitySign.java b/src/main/java/net/minecraft/server/TileEntitySign.java -index 0e9a90b70..099d98e04 100644 +index c4b0d8720..e1ab29975 100644 --- a/src/main/java/net/minecraft/server/TileEntitySign.java +++ b/src/main/java/net/minecraft/server/TileEntitySign.java -@@ -109,6 +109,7 @@ public class TileEntitySign extends TileEntity implements ICommandListener { // +@@ -113,6 +113,7 @@ public class TileEntitySign extends TileEntity implements ICommandListener { // return this.isEditable; } @@ -44,11 +44,11 @@ index 0e9a90b70..099d98e04 100644 // Paper start //this.c = entityhuman; diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 426e6f18b..f098a36b5 100644 +index 328a0b4fe..ed6102b40 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -65,6 +65,11 @@ public class PurpurWorldConfig { - return PurpurConfig.config.getString("world-settings." + worldName + "." + path, PurpurConfig.config.getString("world-settings.default." + path)); +@@ -92,6 +92,11 @@ public class PurpurWorldConfig { + playerInvulnerableWhileAcceptingResourcePack = getBoolean("gameplay-mechanics.player.invulnerable-while-accepting-resource-pack", playerInvulnerableWhileAcceptingResourcePack); } + public boolean signRightClickEdit = false; @@ -56,9 +56,9 @@ index 426e6f18b..f098a36b5 100644 + signRightClickEdit = getBoolean("blocks.sign.right-click-edit", signRightClickEdit); + } + - public boolean batRidable = false; - public boolean batRidableInWater = false; - public boolean batRequireShiftToMount = true; + public boolean turtleEggsBreakFromExpOrbs = true; + public boolean turtleEggsBreakFromItems = true; + public boolean turtleEggsBreakFromMinecarts = true; -- 2.26.2 diff --git a/patches/server/0033-Signs-allow-color-codes.patch b/patches/server/0056-Signs-allow-color-codes.patch similarity index 57% rename from patches/server/0033-Signs-allow-color-codes.patch rename to patches/server/0056-Signs-allow-color-codes.patch index efcfbcd15..436c0cb13 100644 --- a/patches/server/0033-Signs-allow-color-codes.patch +++ b/patches/server/0056-Signs-allow-color-codes.patch @@ -1,32 +1,45 @@ -From 724e01f51f459443dd24030bbe0e7d73f142ac3d Mon Sep 17 00:00:00 2001 +From 1239cbcedd86d3ba666166ac3bc63063ea77188d Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Thu, 6 Jun 2019 17:40:30 -0500 Subject: [PATCH] Signs allow color codes --- - .../java/net/minecraft/server/EntityPlayer.java | 1 + - .../net/minecraft/server/PlayerConnection.java | 8 ++++++++ - .../java/net/minecraft/server/TileEntitySign.java | 15 +++++++++++++++ - .../java/net/pl3x/purpur/PurpurWorldConfig.java | 2 ++ - 4 files changed, 26 insertions(+) + .../net/minecraft/server/EntityPlayer.java | 1 + + .../minecraft/server/IChatBaseComponent.java | 1 + + .../minecraft/server/PlayerConnection.java | 8 +++++++ + .../net/minecraft/server/TileEntitySign.java | 23 +++++++++++++++++++ + .../net/pl3x/purpur/PurpurWorldConfig.java | 3 +++ + 5 files changed, 36 insertions(+) diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java -index 51bae05ec..b781aa3ae 100644 +index be90231e6..17476e908 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java -@@ -1153,6 +1153,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { - @Override +@@ -1272,6 +1272,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { public void openSign(TileEntitySign tileentitysign) { tileentitysign.a((EntityHuman) this); -+ if (world.purpurConfig.signAllowColors) this.playerConnection.sendPacket(tileentitysign.getTranslatedUpdatePacket()); // Purpur this.playerConnection.sendPacket(new PacketPlayOutOpenSignEditor(tileentitysign.getPosition())); ++ if (world.purpurConfig.signAllowColors) this.playerConnection.sendPacket(tileentitysign.getTranslatedUpdatePacket()); // Purpur } + public int nextContainerCounter() { // CraftBukkit - void -> int +diff --git a/src/main/java/net/minecraft/server/IChatBaseComponent.java b/src/main/java/net/minecraft/server/IChatBaseComponent.java +index fd3e6cda6..750896fc8 100644 +--- a/src/main/java/net/minecraft/server/IChatBaseComponent.java ++++ b/src/main/java/net/minecraft/server/IChatBaseComponent.java +@@ -344,6 +344,7 @@ public interface IChatBaseComponent extends Message, IChatFormatted, Iterable Date: Fri, 21 Jun 2019 14:37:10 -0500 Subject: [PATCH] Allow soil to moisten from water directly under it --- - .../java/net/minecraft/server/BlockSoil.java | 20 +++++++------------ + .../java/net/minecraft/server/BlockSoil.java | 19 +++++++------------ .../net/pl3x/purpur/PurpurWorldConfig.java | 5 +++++ - 2 files changed, 12 insertions(+), 13 deletions(-) + 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/net/minecraft/server/BlockSoil.java b/src/main/java/net/minecraft/server/BlockSoil.java -index b6561f2c7..f2ab3ee01 100644 +index a315e2628..8dd48669c 100644 --- a/src/main/java/net/minecraft/server/BlockSoil.java +++ b/src/main/java/net/minecraft/server/BlockSoil.java -@@ -1,6 +1,5 @@ - package net.minecraft.server; - --import java.util.Iterator; - import java.util.Random; - - // CraftBukkit start -@@ -112,19 +111,14 @@ public class BlockSoil extends Block { +@@ -116,19 +116,14 @@ public class BlockSoil extends Block { } private static boolean a(IWorldReader iworldreader, BlockPosition blockposition) { @@ -37,7 +30,7 @@ index b6561f2c7..f2ab3ee01 100644 } - - blockposition1 = (BlockPosition) iterator.next(); -- } while (!iworldreader.getFluid(blockposition1).a(TagsFluid.WATER)); +- } while (!iworldreader.getFluid(blockposition1).a((Tag) TagsFluid.WATER)); - - return true; + } @@ -47,11 +40,11 @@ index b6561f2c7..f2ab3ee01 100644 @Override diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index a07781929..e2bda806e 100644 +index 5df442c5b..c28c241ad 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -65,6 +65,11 @@ public class PurpurWorldConfig { - return PurpurConfig.config.getString("world-settings." + worldName + "." + path, PurpurConfig.config.getString("world-settings.default." + path)); +@@ -92,6 +92,11 @@ public class PurpurWorldConfig { + playerInvulnerableWhileAcceptingResourcePack = getBoolean("gameplay-mechanics.player.invulnerable-while-accepting-resource-pack", playerInvulnerableWhileAcceptingResourcePack); } + public boolean farmlandGetsMoistFromBelow = false; @@ -59,9 +52,9 @@ index a07781929..e2bda806e 100644 + farmlandGetsMoistFromBelow = getBoolean("blocks.farmland.gets-moist-from-below", farmlandGetsMoistFromBelow); + } + + public boolean signAllowColors = false; public boolean signRightClickEdit = false; private void signSettings() { - signRightClickEdit = getBoolean("blocks.sign.right-click-edit", signRightClickEdit); -- 2.26.2 diff --git a/patches/server/0032-Controllable-Minecarts.patch b/patches/server/0058-Controllable-Minecarts.patch similarity index 68% rename from patches/server/0032-Controllable-Minecarts.patch rename to patches/server/0058-Controllable-Minecarts.patch index a2055db59..bff8b34fe 100644 --- a/patches/server/0032-Controllable-Minecarts.patch +++ b/patches/server/0058-Controllable-Minecarts.patch @@ -1,32 +1,68 @@ -From 541d671db22a2a086ddeba4f4c5ba8eaf434c54c Mon Sep 17 00:00:00 2001 +From 250f0664cec36bf8a6d9f0dde52344f3ff47ca2a Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 29 Jun 2019 02:32:40 -0500 Subject: [PATCH] Controllable Minecarts --- + .../net/minecraft/server/BlockPosition.java | 6 +++ .../java/net/minecraft/server/Entity.java | 1 + + .../net/minecraft/server/EntityLiving.java | 6 +-- .../server/EntityMinecartAbstract.java | 38 +++++++++++++++++++ .../net/minecraft/server/ItemMinecart.java | 8 ++-- - .../net/pl3x/purpur/PurpurWorldConfig.java | 32 ++++++++++++++++ - 4 files changed, 76 insertions(+), 3 deletions(-) + .../net/pl3x/purpur/PurpurWorldConfig.java | 30 +++++++++++++++ + 6 files changed, 83 insertions(+), 6 deletions(-) +diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java +index 551ca4471..32757e231 100644 +--- a/src/main/java/net/minecraft/server/BlockPosition.java ++++ b/src/main/java/net/minecraft/server/BlockPosition.java +@@ -33,6 +33,12 @@ public class BlockPosition extends BaseBlockPosition { + private static final int l = BlockPosition.h; + private static final int m = BlockPosition.h + BlockPosition.g; + ++ // Purpur start ++ public BlockPosition(Entity entity) { ++ super(entity.locX(), entity.locY(), entity.locZ()); ++ } ++ // Purpur end ++ + public BlockPosition(int i, int j, int k) { + super(i, j, k); + } diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index d470c586a..08645bd03 100644 +index 028f94a88..e72975ff6 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java -@@ -1531,6 +1531,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke +@@ -1286,6 +1286,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke this.inLava = true; } -+ public boolean isInLava() { return aH(); } // Purpur - OBFHELPER - public boolean aH() { ++ public boolean isInLava() { return aN(); } // Purpur - OBFHELPER + public boolean aN() { return this.inLava; } +diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java +index 63cff85af..cbfb62cd4 100644 +--- a/src/main/java/net/minecraft/server/EntityLiving.java ++++ b/src/main/java/net/minecraft/server/EntityLiving.java +@@ -98,9 +98,9 @@ public abstract class EntityLiving extends Entity { + protected int aV; protected int getKillCount() { return this.aV; } // Paper - OBFHELPER + public float lastDamage; + public boolean jumping; // Paper protected -> public +- public float aY; +- public float aZ; +- public float ba; ++ public float aY; public float getStrafe() { return aY; } public void setStrafe(float strafe) { aY = strafe; } // Purpur - OBFHELPER ++ public float aZ; public float getVertical() { return aZ; } public void setVertical(float vertical) { aZ = vertical; } // Purpur - OBFHELPER ++ public float ba; public float getForward() { return ba; } public void setForward(float forward) { ba = forward; } // Purpur - OBFHELPER + protected int bb; + protected double bc; + protected double bd; diff --git a/src/main/java/net/minecraft/server/EntityMinecartAbstract.java b/src/main/java/net/minecraft/server/EntityMinecartAbstract.java -index 665bbe07f..1f3e5bd28 100644 +index 6e038905e..cdbe1a32e 100644 --- a/src/main/java/net/minecraft/server/EntityMinecartAbstract.java +++ b/src/main/java/net/minecraft/server/EntityMinecartAbstract.java -@@ -357,12 +357,50 @@ public abstract class EntityMinecartAbstract extends Entity { +@@ -432,12 +432,50 @@ public abstract class EntityMinecartAbstract extends Entity { public void a(int i, int j, int k, boolean flag) {} @@ -45,7 +81,7 @@ index 665bbe07f..1f3e5bd28 100644 + } + // Purpur end + - protected void i() { + protected void h() { double d0 = this.getMaxSpeed(); Vec3D vec3d = this.getMot(); @@ -78,13 +114,13 @@ index 665bbe07f..1f3e5bd28 100644 this.setMot(new Vec3D(this.getMot().x * this.derailedX, this.getMot().y * this.derailedY, this.getMot().z * this.derailedZ)); // CraftBukkit end diff --git a/src/main/java/net/minecraft/server/ItemMinecart.java b/src/main/java/net/minecraft/server/ItemMinecart.java -index b73e317fb..e1337a9c0 100644 +index dc7decb06..0da16c200 100644 --- a/src/main/java/net/minecraft/server/ItemMinecart.java +++ b/src/main/java/net/minecraft/server/ItemMinecart.java @@ -103,8 +103,10 @@ public class ItemMinecart extends Item { IBlockData iblockdata = world.getType(blockposition); - if (!iblockdata.a(TagsBlock.RAILS)) { + if (!iblockdata.a((Tag) TagsBlock.RAILS)) { - return EnumInteractionResult.FAIL; - } else { + // Purpur start - place minecarts anywhere @@ -97,23 +133,25 @@ index b73e317fb..e1337a9c0 100644 @@ -131,6 +133,6 @@ public class ItemMinecart extends Item { itemstack.subtract(1); - return EnumInteractionResult.SUCCESS; + return EnumInteractionResult.a(world.isClientSide); - } + //} // Purpur - place minecarts anywhere } } diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index e2bda806e..f8992136a 100644 +index c28c241ad..d3d09d9a4 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -1,10 +1,16 @@ +@@ -1,6 +1,8 @@ package net.pl3x.purpur; import com.destroystokyo.paper.PaperWorldConfig; +import net.minecraft.server.Block; +import net.minecraft.server.Blocks; -+import net.minecraft.server.IRegistry; -+import net.minecraft.server.MinecraftKey; + import net.minecraft.server.IRegistry; + import net.minecraft.server.Item; + import net.minecraft.server.Items; +@@ -8,7 +10,9 @@ import net.minecraft.server.MinecraftKey; import org.bukkit.configuration.ConfigurationSection; import org.spigotmc.SpigotWorldConfig; @@ -123,8 +161,8 @@ index e2bda806e..f8992136a 100644 import static net.pl3x.purpur.PurpurConfig.log; -@@ -75,6 +81,32 @@ public class PurpurWorldConfig { - signRightClickEdit = getBoolean("blocks.sign.right-click-edit", signRightClickEdit); +@@ -74,6 +78,32 @@ public class PurpurWorldConfig { + armorstandStepHeight = (float) getDouble("gameplay-mechanics.armorstand.step-height", armorstandStepHeight); } + public boolean controllableMinecarts = false; @@ -133,7 +171,7 @@ index e2bda806e..f8992136a 100644 + public double controllableMinecartsHopBoost = 0.5D; + public double controllableMinecartsBaseSpeed = 0.1D; + public Map controllableMinecartsBlockSpeeds = new HashMap<>(); -+ private void gameplayMechanicsSettings() { ++ private void controllableMinecartsSettings() { + controllableMinecarts = getBoolean("gameplay-mechanics.controllable-minecarts.enabled", controllableMinecarts); + controllableMinecartsPlaceAnywhere = getBoolean("gameplay-mechanics.controllable-minecarts.place-anywhere", controllableMinecartsPlaceAnywhere); + controllableMinecartsStepHeight = (float) getDouble("gameplay-mechanics.controllable-minecarts.step-height", controllableMinecartsStepHeight); @@ -153,9 +191,9 @@ index e2bda806e..f8992136a 100644 + } + } + - public boolean batRidable = false; - public boolean batRidableInWater = false; - public boolean batRequireShiftToMount = true; + public boolean idleTimeoutKick = true; + public boolean idleTimeoutTickNearbyEntities = true; + public boolean idleTimeoutCountAsSleeping = false; -- 2.26.2 diff --git a/patches/server/0035-Disable-loot-drops-on-death-by-cramming.patch b/patches/server/0059-Disable-loot-drops-on-death-by-cramming.patch similarity index 53% rename from patches/server/0035-Disable-loot-drops-on-death-by-cramming.patch rename to patches/server/0059-Disable-loot-drops-on-death-by-cramming.patch index f7935765b..11b5f2981 100644 --- a/patches/server/0035-Disable-loot-drops-on-death-by-cramming.patch +++ b/patches/server/0059-Disable-loot-drops-on-death-by-cramming.patch @@ -1,21 +1,21 @@ -From 0052f3bced71e7dbbf3d28cfb11bfb2824596d94 Mon Sep 17 00:00:00 2001 +From 973be464795e3636e5b966303568ca44dc9d8858 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Wed, 3 Jul 2019 23:58:31 -0500 Subject: [PATCH] Disable loot drops on death by cramming --- src/main/java/net/minecraft/server/EntityLiving.java | 2 ++ - src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 2 ++ - 2 files changed, 4 insertions(+) + src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 5 +++++ + 2 files changed, 7 insertions(+) diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java -index 10af384d6..4e23d6d3a 100644 +index cbfb62cd4..f570f8955 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java -@@ -1374,8 +1374,10 @@ public abstract class EntityLiving extends Entity { +@@ -1484,8 +1484,10 @@ public abstract class EntityLiving extends Entity { this.dropInventory(); // CraftBukkit - from below org.bukkit.event.entity.EntityDeathEvent deathEvent; // Paper - if (this.isDropExperience() && this.world.getGameRules().getBoolean(GameRules.DO_MOB_LOOT)) { + if (this.cV() && this.world.getGameRules().getBoolean(GameRules.DO_MOB_LOOT)) { + if (!(damagesource == DamageSource.CRAMMING && world.purpurConfig.disableDropsOnCrammingDeath)) { // Purpur this.a(damagesource, flag); this.dropDeathLoot(damagesource, i, flag); @@ -24,25 +24,21 @@ index 10af384d6..4e23d6d3a 100644 deathEvent = CraftEventFactory.callEntityDeathEvent(this, this.drops); // Paper } else { diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index d8d95d787..8c84431e5 100644 +index d3d09d9a4..0e0f59c96 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -112,6 +112,7 @@ public class PurpurWorldConfig { - public double controllableMinecartsHopBoost = 0.5D; - public double controllableMinecartsBaseSpeed = 0.1D; - public Map controllableMinecartsBlockSpeeds = new HashMap<>(); -+ public boolean disableDropsOnCrammingDeath = false; - private void gameplayMechanicsSettings() { - controllableMinecarts = getBoolean("gameplay-mechanics.controllable-minecarts.enabled", controllableMinecarts); - controllableMinecartsPlaceAnywhere = getBoolean("gameplay-mechanics.controllable-minecarts.place-anywhere", controllableMinecartsPlaceAnywhere); -@@ -130,6 +131,7 @@ public class PurpurWorldConfig { - set("gameplay-mechanics.controllable-minecarts.block-speed.grass-block", 0.3D); - set("gameplay-mechanics.controllable-minecarts.block-speed.stone", 0.5D); - } -+ disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath); +@@ -115,6 +115,11 @@ public class PurpurWorldConfig { + idleTimeoutUpdateTabList = getBoolean("gameplay-mechanics.player.idle-timeout.update-tab-list", idleTimeoutUpdateTabList); } - public boolean batRidable = false; ++ public boolean disableDropsOnCrammingDeath = false; ++ private void miscGameplayMechanicsSettings() { ++ disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath); ++ } ++ + public int playerSpawnInvulnerableTicks = 60; + public boolean playerInvulnerableWhileAcceptingResourcePack = false; + private void playerInvulnerabilities() { -- 2.26.2 diff --git a/patches/server/0060-Add-option-to-set-armorstand-step-height.patch b/patches/server/0060-Add-option-to-set-armorstand-step-height.patch deleted file mode 100644 index 1391f3885..000000000 --- a/patches/server/0060-Add-option-to-set-armorstand-step-height.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 4536501e5239e68ff4e8bebc65bed6fb08b96284 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sun, 6 Oct 2019 12:46:35 -0500 -Subject: [PATCH] Add option to set armorstand step height - ---- - src/main/java/net/minecraft/server/EntityArmorStand.java | 2 +- - src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 2 ++ - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/src/main/java/net/minecraft/server/EntityArmorStand.java b/src/main/java/net/minecraft/server/EntityArmorStand.java -index d4aa9b24f..d65544953 100644 ---- a/src/main/java/net/minecraft/server/EntityArmorStand.java -+++ b/src/main/java/net/minecraft/server/EntityArmorStand.java -@@ -62,7 +62,6 @@ public class EntityArmorStand extends EntityLiving { - this.leftLegPose = EntityArmorStand.bv; - this.rightLegPose = EntityArmorStand.bw; - if (world != null) this.canTick = world.paperConfig.armorStandTick; // Paper - armour stand ticking -- this.H = 0.0F; - } - - public EntityArmorStand(World world, double d0, double d1, double d2) { -@@ -615,6 +614,7 @@ public class EntityArmorStand extends EntityLiving { - - @Override - public void tick() { -+ setStepHeight(world.purpurConfig.armorstandStepHeight); // Purpur - // Paper start - if (!this.canTick) { - if (this.noTickPoseDirty) { -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 2271d13f1..4bb5ddea4 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -135,6 +135,7 @@ public class PurpurWorldConfig { - } - - public boolean boatEjectPlayersOnLand = false; -+ public float armorstandStepHeight = 0.0F; - public boolean controllableMinecarts = false; - public boolean controllableMinecartsPlaceAnywhere = false; - public float controllableMinecartsStepHeight = 1.0F; -@@ -147,6 +148,7 @@ public class PurpurWorldConfig { - public boolean useBetterMending = false; - private void gameplayMechanicsSettings() { - boatEjectPlayersOnLand = getBoolean("gameplay-mechanics.boat.eject-players-on-land", boatEjectPlayersOnLand); -+ armorstandStepHeight = (float) getDouble("gameplay-mechanics.armorstand.step-height", armorstandStepHeight); - controllableMinecarts = getBoolean("gameplay-mechanics.controllable-minecarts.enabled", controllableMinecarts); - controllableMinecartsPlaceAnywhere = getBoolean("gameplay-mechanics.controllable-minecarts.place-anywhere", controllableMinecartsPlaceAnywhere); - controllableMinecartsStepHeight = (float) getDouble("gameplay-mechanics.controllable-minecarts.step-height", controllableMinecartsStepHeight); --- -2.26.2 - diff --git a/patches/server/0045-Players-should-not-cram-to-death.patch b/patches/server/0060-Players-should-not-cram-to-death.patch similarity index 85% rename from patches/server/0045-Players-should-not-cram-to-death.patch rename to patches/server/0060-Players-should-not-cram-to-death.patch index b586eb6a7..a34a64658 100644 --- a/patches/server/0045-Players-should-not-cram-to-death.patch +++ b/patches/server/0060-Players-should-not-cram-to-death.patch @@ -1,4 +1,4 @@ -From 180a11a08582be6b68f188b6e5b5f7cefbcab4fa Mon Sep 17 00:00:00 2001 +From 54e723d0928f87ed9cd5be90508fb9b6f07bb40e Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 21 Jul 2019 18:01:46 -0500 Subject: [PATCH] Players should not cram to death @@ -8,10 +8,10 @@ Subject: [PATCH] Players should not cram to death 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java -index d7ce31284..3e0e49dbb 100644 +index 17476e908..b54960d25 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java -@@ -1126,7 +1126,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { +@@ -1246,7 +1246,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { @Override public boolean isInvulnerable(DamageSource damagesource) { diff --git a/patches/server/0040-Option-to-toggle-milk-curing-bad-omen.patch b/patches/server/0061-Option-to-toggle-milk-curing-bad-omen.patch similarity index 60% rename from patches/server/0040-Option-to-toggle-milk-curing-bad-omen.patch rename to patches/server/0061-Option-to-toggle-milk-curing-bad-omen.patch index e1170f238..2828d73c5 100644 --- a/patches/server/0040-Option-to-toggle-milk-curing-bad-omen.patch +++ b/patches/server/0061-Option-to-toggle-milk-curing-bad-omen.patch @@ -1,48 +1,42 @@ -From 1b2547a4ad9ca6eaa524538e0d6a747cf617a600 Mon Sep 17 00:00:00 2001 +From b3e7d2a10bc7014139373f7f4d54b8469ecbc14b Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Wed, 10 Jul 2019 20:43:05 -0500 Subject: [PATCH] Option to toggle milk curing bad omen --- - src/main/java/net/minecraft/server/ItemMilkBucket.java | 3 +++ + src/main/java/net/minecraft/server/ItemMilkBucket.java | 2 ++ src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 2 ++ - 2 files changed, 5 insertions(+) + 2 files changed, 4 insertions(+) diff --git a/src/main/java/net/minecraft/server/ItemMilkBucket.java b/src/main/java/net/minecraft/server/ItemMilkBucket.java -index 6b255e09a..e1d3894ab 100644 +index fcf254bba..79554e18f 100644 --- a/src/main/java/net/minecraft/server/ItemMilkBucket.java +++ b/src/main/java/net/minecraft/server/ItemMilkBucket.java -@@ -20,7 +20,10 @@ public class ItemMilkBucket extends Item { +@@ -20,7 +20,9 @@ public class ItemMilkBucket extends Item { } if (!world.isClientSide) { + MobEffect badOmen = entityliving.getEffect(MobEffects.BAD_OMEN); // Purpur entityliving.removeAllEffects(org.bukkit.event.entity.EntityPotionEffectEvent.Cause.MILK); // CraftBukkit + if (!world.purpurConfig.milkCuresBadOmen && badOmen != null) entityliving.addEffect(badOmen); // Purpur -+ } return itemstack.isEmpty() ? new ItemStack(Items.BUCKET) : itemstack; diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 41dd1b861..7cbb1df7a 100644 +index 0e0f59c96..b6bcbd1e6 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -117,6 +117,7 @@ public class PurpurWorldConfig { - public double controllableMinecartsBaseSpeed = 0.1D; - public Map controllableMinecartsBlockSpeeds = new HashMap<>(); +@@ -116,8 +116,10 @@ public class PurpurWorldConfig { + } + public boolean disableDropsOnCrammingDeath = false; + public boolean milkCuresBadOmen = true; - private void gameplayMechanicsSettings() { - controllableMinecarts = getBoolean("gameplay-mechanics.controllable-minecarts.enabled", controllableMinecarts); - controllableMinecartsPlaceAnywhere = getBoolean("gameplay-mechanics.controllable-minecarts.place-anywhere", controllableMinecartsPlaceAnywhere); -@@ -136,6 +137,7 @@ public class PurpurWorldConfig { - set("gameplay-mechanics.controllable-minecarts.block-speed.stone", 0.5D); - } + private void miscGameplayMechanicsSettings() { disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath); + milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen); } - public boolean idleTimeoutKick = true; + public int playerSpawnInvulnerableTicks = 60; -- 2.26.2 diff --git a/patches/server/0099-End-gateway-should-check-if-entity-can-use-portal.patch b/patches/server/0062-End-gateway-should-check-if-entity-can-use-portal.patch similarity index 81% rename from patches/server/0099-End-gateway-should-check-if-entity-can-use-portal.patch rename to patches/server/0062-End-gateway-should-check-if-entity-can-use-portal.patch index 7aa9aa939..806847f8f 100644 --- a/patches/server/0099-End-gateway-should-check-if-entity-can-use-portal.patch +++ b/patches/server/0062-End-gateway-should-check-if-entity-can-use-portal.patch @@ -1,4 +1,4 @@ -From 880fd629acbb50e1198acaf479127bfebe3817d6 Mon Sep 17 00:00:00 2001 +From 2ed2dad2f015763bcf4bf54e56ebadece69521bb Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 21 Mar 2020 18:33:05 -0500 Subject: [PATCH] End gateway should check if entity can use portal @@ -8,7 +8,7 @@ Subject: [PATCH] End gateway should check if entity can use portal 1 file changed, 1 insertion(+) diff --git a/src/main/java/net/minecraft/server/TileEntityEndGateway.java b/src/main/java/net/minecraft/server/TileEntityEndGateway.java -index 87aef515c..55294b5df 100644 +index aebb6b6b2..c6b26f665 100644 --- a/src/main/java/net/minecraft/server/TileEntityEndGateway.java +++ b/src/main/java/net/minecraft/server/TileEntityEndGateway.java @@ -122,6 +122,7 @@ public class TileEntityEndGateway extends TileEntityEnderPortal implements ITick @@ -17,7 +17,7 @@ index 87aef515c..55294b5df 100644 if (this.world instanceof WorldServer && !this.f()) { + if (!entity.canPortal()) return; // Purpur this.c = 100; - if (this.exitPortal == null && this.world.worldProvider instanceof WorldProviderTheEnd) { + if (this.exitPortal == null && this.world.getDimensionKey() == World.THE_END) { this.a((WorldServer) this.world); -- 2.26.2 diff --git a/patches/server/0108-Debug-stick-should-not-update-neighbors.patch b/patches/server/0063-Debug-stick-should-not-update-neighbors.patch similarity index 86% rename from patches/server/0108-Debug-stick-should-not-update-neighbors.patch rename to patches/server/0063-Debug-stick-should-not-update-neighbors.patch index 1ba1aad03..127972fd6 100644 --- a/patches/server/0108-Debug-stick-should-not-update-neighbors.patch +++ b/patches/server/0063-Debug-stick-should-not-update-neighbors.patch @@ -1,4 +1,4 @@ -From fb61a83a73f9de95c06c77f7f788d4df811c82f4 Mon Sep 17 00:00:00 2001 +From e7b70b3784621d00d4579121864fa57f4e9c8b8a Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 4 Apr 2020 17:16:30 -0500 Subject: [PATCH] Debug stick should not update neighbors @@ -8,10 +8,10 @@ Subject: [PATCH] Debug stick should not update neighbors 1 file changed, 5 insertions(+) diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java -index d5e0578b2..bc465a47d 100644 +index 007255297..2b2d914de 100644 --- a/src/main/java/net/minecraft/server/ItemStack.java +++ b/src/main/java/net/minecraft/server/ItemStack.java -@@ -186,6 +186,11 @@ public final class ItemStack { +@@ -190,6 +190,11 @@ public final class ItemStack { if (this.getItem() == Items.BONE_MEAL) { world.captureTreeGeneration = true; } diff --git a/patches/server/0063-Implement-PlayerSetSpawnerTypeWithEggEvent.patch b/patches/server/0063-Implement-PlayerSetSpawnerTypeWithEggEvent.patch deleted file mode 100644 index 90142cd35..000000000 --- a/patches/server/0063-Implement-PlayerSetSpawnerTypeWithEggEvent.patch +++ /dev/null @@ -1,44 +0,0 @@ -From dc386a10b38cdbe4de2d942d8e70138b7bf593f5 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Fri, 5 Jul 2019 18:21:00 -0500 -Subject: [PATCH] Implement PlayerSetSpawnerTypeWithEggEvent - ---- - .../java/net/minecraft/server/ItemMonsterEgg.java | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/src/main/java/net/minecraft/server/ItemMonsterEgg.java b/src/main/java/net/minecraft/server/ItemMonsterEgg.java -index 8ef2c3223..237fdeda5 100644 ---- a/src/main/java/net/minecraft/server/ItemMonsterEgg.java -+++ b/src/main/java/net/minecraft/server/ItemMonsterEgg.java -@@ -2,6 +2,11 @@ package net.minecraft.server; - - import com.google.common.collect.Iterables; - import com.google.common.collect.Maps; -+import net.pl3x.purpur.event.PlayerSetSpawnerTypeWithEggEvent; -+import org.bukkit.block.CreatureSpawner; -+import org.bukkit.entity.EntityType; -+import org.bukkit.entity.Player; -+ - import java.util.Map; - import java.util.Objects; - import javax.annotation.Nullable; -@@ -41,6 +46,15 @@ public class ItemMonsterEgg extends Item { - MobSpawnerAbstract mobspawnerabstract = ((TileEntityMobSpawner) tileentity).getSpawner(); - EntityTypes entitytypes = this.b(itemstack.getTag()); - -+ // Purpur start -+ org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); -+ PlayerSetSpawnerTypeWithEggEvent event = new PlayerSetSpawnerTypeWithEggEvent((Player) itemactioncontext.b.getBukkitEntity(), bukkitBlock, (CreatureSpawner) bukkitBlock.getState(), EntityType.fromName(entitytypes.getName())); -+ if (!event.callEvent()) { -+ return EnumInteractionResult.FAIL; -+ } -+ entitytypes = EntityTypes.getFromKey(new MinecraftKey(event.getEntityType().getKey().toString())); -+ // Purpur end -+ - mobspawnerabstract.setMobName(entitytypes); - tileentity.update(); - world.notify(blockposition, iblockdata, iblockdata, 3); --- -2.26.2 - diff --git a/patches/server/0115-Do-not-strip-colors-from-death-messages.patch b/patches/server/0064-Do-not-strip-colors-from-death-messages.patch similarity index 86% rename from patches/server/0115-Do-not-strip-colors-from-death-messages.patch rename to patches/server/0064-Do-not-strip-colors-from-death-messages.patch index 01c21faf5..931640538 100644 --- a/patches/server/0115-Do-not-strip-colors-from-death-messages.patch +++ b/patches/server/0064-Do-not-strip-colors-from-death-messages.patch @@ -1,4 +1,4 @@ -From 4a8ac41e8b4ea8f138e46d0ef993a5ea6598fc2b Mon Sep 17 00:00:00 2001 +From cb512084b525bac9346f5a0c4786ed30ecc163d5 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 7 Jun 2020 13:16:02 -0500 Subject: [PATCH] Do not strip colors from death messages @@ -8,10 +8,10 @@ Subject: [PATCH] Do not strip colors from death messages 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java -index e73b33721..9eeefa1ca 100644 +index b54960d25..9801d87f0 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java -@@ -622,7 +622,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { +@@ -665,7 +665,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { IChatBaseComponent defaultMessage = this.getCombatTracker().getDeathMessage(); diff --git a/patches/server/0065-Add-getPlacementBlockData-to-World.patch b/patches/server/0065-Add-getPlacementBlockData-to-World.patch deleted file mode 100644 index a8c2bb791..000000000 --- a/patches/server/0065-Add-getPlacementBlockData-to-World.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 64163a967be7513c8c46cc26d795e81c41446fb1 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sat, 8 Feb 2020 23:30:17 -0600 -Subject: [PATCH] Add getPlacementBlockData to World - ---- - .../net/minecraft/server/BlockMobSpawner.java | 1 + - .../net/minecraft/server/ItemSpawner.java | 23 +++++++++++++++++++ - src/main/java/net/minecraft/server/Items.java | 2 +- - .../org/bukkit/craftbukkit/CraftWorld.java | 5 ++++ - 4 files changed, 30 insertions(+), 1 deletion(-) - create mode 100644 src/main/java/net/minecraft/server/ItemSpawner.java - -diff --git a/src/main/java/net/minecraft/server/BlockMobSpawner.java b/src/main/java/net/minecraft/server/BlockMobSpawner.java -index 69d04f6cb..901d45f28 100644 ---- a/src/main/java/net/minecraft/server/BlockMobSpawner.java -+++ b/src/main/java/net/minecraft/server/BlockMobSpawner.java -@@ -57,6 +57,7 @@ public class BlockMobSpawner extends BlockTileEntity { - - @Override - public int getExpDrop(IBlockData iblockdata, World world, BlockPosition blockposition, ItemStack itemstack) { -+ if (isSilkTouch(itemstack)) return 0; // Purpur - int i = 15 + world.random.nextInt(15) + world.random.nextInt(15); - - return i; -diff --git a/src/main/java/net/minecraft/server/ItemSpawner.java b/src/main/java/net/minecraft/server/ItemSpawner.java -new file mode 100644 -index 000000000..7dc68ffe9 ---- /dev/null -+++ b/src/main/java/net/minecraft/server/ItemSpawner.java -@@ -0,0 +1,23 @@ -+package net.minecraft.server; -+ -+public class ItemSpawner extends ItemBlock { -+ public ItemSpawner(Block block, Info info) { -+ super(block, info); -+ } -+ -+ @Override -+ protected boolean a(BlockPosition blockposition, World world, EntityHuman entityhuman, ItemStack itemstack, IBlockData iblockdata) { -+ boolean handled = super.a(blockposition, world, entityhuman, itemstack, iblockdata); -+ if (entityhuman.getBukkitEntity().hasPermission("purpur.place.spawners")) { -+ TileEntity spawner = world.getTileEntity(blockposition); -+ if (spawner instanceof TileEntityMobSpawner && itemstack.hasTag()) { -+ NBTTagCompound tag = itemstack.getTag(); -+ if (tag.hasKey("Purpur.mob_type")) { -+ EntityTypes.getType(tag.getString("Purpur.mob_type")).ifPresent(type -> -+ ((TileEntityMobSpawner) spawner).getSpawner().setMobName(type)); -+ } -+ } -+ } -+ return handled; -+ } -+} -diff --git a/src/main/java/net/minecraft/server/Items.java b/src/main/java/net/minecraft/server/Items.java -index 9c9b93f28..74a722cce 100644 ---- a/src/main/java/net/minecraft/server/Items.java -+++ b/src/main/java/net/minecraft/server/Items.java -@@ -155,7 +155,7 @@ public class Items { - public static final Item bU = a(Blocks.PURPUR_BLOCK, CreativeModeTab.b); - public static final Item bV = a(Blocks.PURPUR_PILLAR, CreativeModeTab.b); - public static final Item bW = a(Blocks.PURPUR_STAIRS, CreativeModeTab.b); -- public static final Item bX = a(Blocks.SPAWNER); -+ public static final Item bX = a(Blocks.SPAWNER, new ItemSpawner(Blocks.SPAWNER, new Item.Info().a(EnumItemRarity.EPIC))); // Purpur - public static final Item bY = a(Blocks.OAK_STAIRS, CreativeModeTab.b); - public static final Item bZ = a(Blocks.CHEST, CreativeModeTab.c); - public static final Item ca = a(Blocks.DIAMOND_ORE, CreativeModeTab.b); -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index e55be5271..8b5003436 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -2483,6 +2483,11 @@ public class CraftWorld implements World { - public net.pl3x.purpur.MoonPhase getMoonPhase() { - return net.pl3x.purpur.MoonPhase.getPhase(getFullTime() / 24000L); - } -+ -+ public BlockData getPlacementBlockData(BlockData blockdata, Location location) { -+ IBlockData validData = net.minecraft.server.Block.getValidBlockForPosition(((CraftBlockData) blockdata).getState(), getHandle(), net.minecraft.server.MCUtil.toBlockPosition(location)); -+ return CraftBlockData.fromData(validData == null ? Blocks.AIR.getBlockData() : validData); -+ } - // Purpur end - - // Paper start --- -2.26.2 - diff --git a/patches/server/0116-Fix-reloading-paper.yml.patch b/patches/server/0065-Fix-reloading-paper.yml.patch similarity index 92% rename from patches/server/0116-Fix-reloading-paper.yml.patch rename to patches/server/0065-Fix-reloading-paper.yml.patch index f4e09a329..fc0346512 100644 --- a/patches/server/0116-Fix-reloading-paper.yml.patch +++ b/patches/server/0065-Fix-reloading-paper.yml.patch @@ -1,4 +1,4 @@ -From dcebd276461c63a590cd35b73ece127106eb7d6a Mon Sep 17 00:00:00 2001 +From c16950236ff5a5b2cccdd3cb8c8a6bfd69dc36b0 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Fri, 19 Jun 2020 21:36:16 -0500 Subject: [PATCH] Fix reloading paper.yml @@ -8,7 +8,7 @@ Subject: [PATCH] Fix reloading paper.yml 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index ecacb72b9..284ea05dc 100644 +index e471e7649..09fda504d 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java @@ -20,7 +20,7 @@ public class PaperWorldConfig { diff --git a/patches/server/0066-Barrels-have-6-rows.patch b/patches/server/0066-Barrels-have-6-rows.patch deleted file mode 100644 index 4c78ce266..000000000 --- a/patches/server/0066-Barrels-have-6-rows.patch +++ /dev/null @@ -1,89 +0,0 @@ -From bdd2fd8f778a66a3f234c7ad24dba470f2f1d0a3 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Thu, 23 May 2019 21:50:37 -0500 -Subject: [PATCH] Barrels have 6 rows - ---- - src/main/java/net/minecraft/server/TileEntityBarrel.java | 5 +++-- - src/main/java/net/pl3x/purpur/PurpurConfig.java | 9 +++++++++ - .../org/bukkit/craftbukkit/inventory/CraftContainer.java | 4 +++- - 3 files changed, 15 insertions(+), 3 deletions(-) - -diff --git a/src/main/java/net/minecraft/server/TileEntityBarrel.java b/src/main/java/net/minecraft/server/TileEntityBarrel.java -index 1e27abbea..ca3b6c9aa 100644 ---- a/src/main/java/net/minecraft/server/TileEntityBarrel.java -+++ b/src/main/java/net/minecraft/server/TileEntityBarrel.java -@@ -54,7 +54,7 @@ public class TileEntityBarrel extends TileEntityLootable { - - private TileEntityBarrel(TileEntityTypes tileentitytypes) { - super(tileentitytypes); -- this.items = NonNullList.a(27, ItemStack.a); -+ this.items = NonNullList.a(net.pl3x.purpur.PurpurConfig.barrelSixRows ? 54 : 27, ItemStack.a); // Purpur - } - - public TileEntityBarrel() { -@@ -83,7 +83,7 @@ public class TileEntityBarrel extends TileEntityLootable { - - @Override - public int getSize() { -- return 27; -+ return net.pl3x.purpur.PurpurConfig.barrelSixRows ? 54 : 27; // Purpur - } - - @Override -@@ -103,6 +103,7 @@ public class TileEntityBarrel extends TileEntityLootable { - - @Override - protected Container createContainer(int i, PlayerInventory playerinventory) { -+ if (net.pl3x.purpur.PurpurConfig.barrelSixRows) return new ContainerChest(Containers.GENERIC_9X6, i, playerinventory, this, 6); // Purpur - return ContainerChest.a(i, playerinventory, this); - } - -diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java -index ed2a31277..581e8eebe 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java -@@ -7,6 +7,7 @@ import org.bukkit.Bukkit; - import org.bukkit.command.Command; - import org.bukkit.configuration.InvalidConfigurationException; - import org.bukkit.configuration.file.YamlConfiguration; -+import org.bukkit.event.inventory.InventoryType; - - import java.io.File; - import java.io.IOException; -@@ -154,8 +155,16 @@ public class PurpurConfig { - dontSendUselessEntityPackets = getBoolean("settings.dont-send-useless-entity-packets", dontSendUselessEntityPackets); - } - -+ public static boolean barrelSixRows = false; - public static boolean slimeBlocksNotPushable = false; - private static void blockSettings() { -+ if (version < 3) { -+ boolean oldValue = getBoolean("settings.barrel.packed-barrels", true); -+ set("settings.blocks.barrel.six-rows", oldValue); -+ set("settings.packed-barrels", null); -+ } -+ barrelSixRows = getBoolean("settings.blocks.barrel.six-rows", barrelSixRows); -+ InventoryType.BARREL.setDefaultSize(barrelSixRows ? 54 : 27); - slimeBlocksNotPushable = getBoolean("settings.blocks.slime.not-movable-by-piston", slimeBlocksNotPushable); - } - -diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java -index 454ec3c76..d295821c5 100644 ---- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java -+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java -@@ -195,8 +195,10 @@ public class CraftContainer extends Container { - case PLAYER: - case CHEST: - case ENDER_CHEST: -+ delegate = new ContainerChest(Containers.GENERIC_9X3, windowId, bottom, top, top.getSize() / 9); // Purpur -+ break; // Purpur - case BARREL: -- delegate = new ContainerChest(Containers.GENERIC_9X3, windowId, bottom, top, top.getSize() / 9); -+ delegate = new ContainerChest(net.pl3x.purpur.PurpurConfig.barrelSixRows ? Containers.GENERIC_9X6 : Containers.GENERIC_9X3, windowId, bottom, top, top.getSize() / 9); // Purpur - break; - case DISPENSER: - case DROPPER: --- -2.26.2 - diff --git a/patches/server/0095-Fix-the-dead-lagging-the-server.patch b/patches/server/0066-Fix-the-dead-lagging-the-server.patch similarity index 69% rename from patches/server/0095-Fix-the-dead-lagging-the-server.patch rename to patches/server/0066-Fix-the-dead-lagging-the-server.patch index 2c08f64ba..4337491c9 100644 --- a/patches/server/0095-Fix-the-dead-lagging-the-server.patch +++ b/patches/server/0066-Fix-the-dead-lagging-the-server.patch @@ -1,4 +1,4 @@ -From 151f9b4605ac2ec1d7788f860ad5d331e25754a6 Mon Sep 17 00:00:00 2001 +From c266a969a6ad3581ec51a0815b2eef864c3ac0b7 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Fri, 6 Mar 2020 13:37:26 -0600 Subject: [PATCH] Fix the dead lagging the server @@ -9,23 +9,23 @@ Subject: [PATCH] Fix the dead lagging the server 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index a20660a9b..cb6dec517 100644 +index e72975ff6..a219443b3 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java -@@ -1592,7 +1592,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke +@@ -1345,7 +1345,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke this.pitch = MathHelper.a(f1, -90.0F, 90.0F) % 360.0F; this.lastYaw = this.yaw; this.lastPitch = this.pitch; -- if (valid) world.getChunkAt((int) Math.floor(this.locX) >> 4, (int) Math.floor(this.locZ) >> 4); // CraftBukkit // Paper -+ if (valid && !dead) world.getChunkAt((int) Math.floor(this.locX) >> 4, (int) Math.floor(this.locZ) >> 4); // CraftBukkit // Paper // Purpur +- if (valid) world.getChunkAt((int) Math.floor(this.locX()) >> 4, (int) Math.floor(this.locZ()) >> 4); // CraftBukkit // Paper ++ if (valid && !dead) world.getChunkAt((int) Math.floor(this.locX()) >> 4, (int) Math.floor(this.locZ()) >> 4); // CraftBukkit // Paper // Purpur } - public void setPositionRotation(BlockPosition blockposition, float f, float f1) { + public void c(Vec3D vec3d) { diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java -index 387f74fe1..dae35c55e 100644 +index f570f8955..f86499c87 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java -@@ -2398,7 +2398,7 @@ public abstract class EntityLiving extends Entity { +@@ -2468,7 +2468,7 @@ public abstract class EntityLiving extends Entity { } } diff --git a/patches/server/0107-Skip-events-if-there-s-no-listeners.patch b/patches/server/0067-Skip-events-if-there-s-no-listeners.patch similarity index 93% rename from patches/server/0107-Skip-events-if-there-s-no-listeners.patch rename to patches/server/0067-Skip-events-if-there-s-no-listeners.patch index 8b8126322..8876a3fac 100644 --- a/patches/server/0107-Skip-events-if-there-s-no-listeners.patch +++ b/patches/server/0067-Skip-events-if-there-s-no-listeners.patch @@ -1,4 +1,4 @@ -From 67afec34bd04c7397e1079296ef6da3659175aa8 Mon Sep 17 00:00:00 2001 +From 333eaf6ecdb008426410030c2c27f5ce006d6c35 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 4 Apr 2020 03:07:59 -0500 Subject: [PATCH] Skip events if there's no listeners @@ -8,7 +8,7 @@ Subject: [PATCH] Skip events if there's no listeners 1 file changed, 2 insertions(+) diff --git a/src/main/java/net/minecraft/server/CommandDispatcher.java b/src/main/java/net/minecraft/server/CommandDispatcher.java -index 5aa10d16b..3b61298fa 100644 +index e59151d01..4ace0e79c 100644 --- a/src/main/java/net/minecraft/server/CommandDispatcher.java +++ b/src/main/java/net/minecraft/server/CommandDispatcher.java @@ -275,6 +275,7 @@ public class CommandDispatcher { diff --git a/patches/server/0083-Add-permission-for-F3-N-debug.patch b/patches/server/0068-Add-permission-for-F3-N-debug.patch similarity index 83% rename from patches/server/0083-Add-permission-for-F3-N-debug.patch rename to patches/server/0068-Add-permission-for-F3-N-debug.patch index fd7960a60..46fd008b6 100644 --- a/patches/server/0083-Add-permission-for-F3-N-debug.patch +++ b/patches/server/0068-Add-permission-for-F3-N-debug.patch @@ -1,4 +1,4 @@ -From 437e55dc3cde421e1c239bd7f834ff858fd3f4fc Mon Sep 17 00:00:00 2001 +From 606a4d55a58761fdd9882c0da7bf710359c8eb8f Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 28 Dec 2019 04:21:54 -0600 Subject: [PATCH] Add permission for F3+N debug @@ -8,10 +8,10 @@ Subject: [PATCH] Add permission for F3+N debug 1 file changed, 1 insertion(+) diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java -index ab8247eb7..af2cdbf4d 100644 +index 5807e77da..ec2bbd52c 100644 --- a/src/main/java/net/minecraft/server/PlayerList.java +++ b/src/main/java/net/minecraft/server/PlayerList.java -@@ -980,6 +980,7 @@ public abstract class PlayerList { +@@ -1023,6 +1023,7 @@ public abstract class PlayerList { } else { b0 = (byte) (24 + i); } diff --git a/patches/server/0087-Add-wither-skeleton-takes-wither-damage-option.patch b/patches/server/0069-Add-wither-skeleton-takes-wither-damage-option.patch similarity index 58% rename from patches/server/0087-Add-wither-skeleton-takes-wither-damage-option.patch rename to patches/server/0069-Add-wither-skeleton-takes-wither-damage-option.patch index 72ec5bcdb..873b39724 100644 --- a/patches/server/0087-Add-wither-skeleton-takes-wither-damage-option.patch +++ b/patches/server/0069-Add-wither-skeleton-takes-wither-damage-option.patch @@ -1,18 +1,18 @@ -From 02fc90e6d67242d23da3b9f79ff650bd100240aa Mon Sep 17 00:00:00 2001 +From 4f2a4bdb16c57bde9625687d6052f2fc09914ae1 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Tue, 14 Jan 2020 19:43:40 -0600 Subject: [PATCH] Add wither skeleton takes wither damage option --- src/main/java/net/minecraft/server/EntitySkeletonWither.java | 2 +- - src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 2 ++ - 2 files changed, 3 insertions(+), 1 deletion(-) + src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 5 +++++ + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/minecraft/server/EntitySkeletonWither.java b/src/main/java/net/minecraft/server/EntitySkeletonWither.java -index 8aa0a6699..0fd740e71 100644 +index 1819432e1..f415775ea 100644 --- a/src/main/java/net/minecraft/server/EntitySkeletonWither.java +++ b/src/main/java/net/minecraft/server/EntitySkeletonWither.java -@@ -108,6 +108,6 @@ public class EntitySkeletonWither extends EntitySkeletonAbstract { +@@ -97,6 +97,6 @@ public class EntitySkeletonWither extends EntitySkeletonAbstract { @Override public boolean d(MobEffect mobeffect) { @@ -21,22 +21,21 @@ index 8aa0a6699..0fd740e71 100644 } } diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index c238607ac..d4b4dfdd3 100644 +index b6bcbd1e6..5549a984d 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -844,10 +844,12 @@ public class PurpurWorldConfig { - public boolean witherSkeletonRidable = false; - public boolean witherSkeletonRidableInWater = false; - public boolean witherSkeletonRequireShiftToMount = true; -+ public boolean witherSkeletonTakesWitherDamage = false; - private void witherSkeletonSettings() { - witherSkeletonRidable = getBoolean("mobs.wither_skeleton.ridable", witherSkeletonRidable); - witherSkeletonRidableInWater = getBoolean("mobs.wither_skeleton.ridable-in-water", witherSkeletonRidableInWater); - witherSkeletonRequireShiftToMount = getBoolean("mobs.wither_skeleton.require-shift-to-mount", witherSkeletonRequireShiftToMount); -+ witherSkeletonTakesWitherDamage = getBoolean("mobs.wither_skeleton.takes-wither-damage", witherSkeletonTakesWitherDamage); +@@ -252,6 +252,11 @@ public class PurpurWorldConfig { + villagerUseBrainTicksOnlyWhenLagging = getBoolean("mobs.villager.use-brain-ticks-only-when-lagging", villagerUseBrainTicksOnlyWhenLagging); } - public boolean wolfRidable = false; ++ public boolean witherSkeletonTakesWitherDamage = false; ++ private void witherSkeletonSettings() { ++ witherSkeletonTakesWitherDamage = getBoolean("mobs.wither_skeleton.takes-wither-damage", witherSkeletonTakesWitherDamage); ++ } ++ + public double zombieHorseSpawnChance = 0.0D; + private void zombieHorseSettings() { + zombieHorseSpawnChance = getDouble("mobs.zombie_horse.spawn-chance", zombieHorseSpawnChance); -- 2.26.2 diff --git a/patches/server/0070-Add-more-evoker-API.patch b/patches/server/0070-Add-more-evoker-API.patch deleted file mode 100644 index 7e2ca757e..000000000 --- a/patches/server/0070-Add-more-evoker-API.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 4f5ad157197bfb5a3447e104eb705317f82b935a Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sat, 19 Oct 2019 00:29:02 -0500 -Subject: [PATCH] Add more evoker API - ---- - .../java/net/minecraft/server/EntityEvoker.java | 6 ++++-- - .../org/bukkit/craftbukkit/entity/CraftEvoker.java | 13 +++++++++++++ - 2 files changed, 17 insertions(+), 2 deletions(-) - -diff --git a/src/main/java/net/minecraft/server/EntityEvoker.java b/src/main/java/net/minecraft/server/EntityEvoker.java -index 179a26129..e7d0d0f5e 100644 ---- a/src/main/java/net/minecraft/server/EntityEvoker.java -+++ b/src/main/java/net/minecraft/server/EntityEvoker.java -@@ -102,12 +102,14 @@ public class EntityEvoker extends EntityIllagerWizard { - return SoundEffects.ENTITY_EVOKER_HURT; - } - -+ public void setWololoTarget(@Nullable EntitySheep sheep) { a(sheep); } // Purpur - OBFHELPER - private void a(@Nullable EntitySheep entitysheep) { - this.bw = entitysheep; - } - -- @Nullable -- private EntitySheep eK() { -+ -+ @Nullable public EntitySheep getWololoTarget() { return eK(); } // Purpur - OBFHELPER -+ @Nullable private EntitySheep eK() { - return this.bw; - } - -diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEvoker.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEvoker.java -index 0636d2647..4ccb93890 100644 ---- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEvoker.java -+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEvoker.java -@@ -36,4 +36,17 @@ public class CraftEvoker extends CraftSpellcaster implements Evoker { - public void setCurrentSpell(Evoker.Spell spell) { - getHandle().setSpell(spell == null ? EntityIllagerWizard.Spell.NONE : EntityIllagerWizard.Spell.a(spell.ordinal())); - } -+ -+ // Purpur start -+ @javax.annotation.Nullable -+ public org.bukkit.entity.Sheep getWololoTarget() { -+ net.minecraft.server.EntitySheep target = getHandle().getWololoTarget(); -+ return target == null ? null : (org.bukkit.entity.Sheep) target.getBukkitEntity(); -+ } -+ -+ @Override -+ public void setWololoTarget(@javax.annotation.Nullable org.bukkit.entity.Sheep sheep) { -+ getHandle().setWololoTarget(sheep == null ? null : (net.minecraft.server.EntitySheep) ((CraftEntity) sheep).getHandle()); -+ } -+ // Purpur end - } --- -2.26.2 - diff --git a/patches/server/0100-Configurable-TPS-Catchup.patch b/patches/server/0070-Configurable-TPS-Catchup.patch similarity index 54% rename from patches/server/0100-Configurable-TPS-Catchup.patch rename to patches/server/0070-Configurable-TPS-Catchup.patch index f46c812df..4e4a7630f 100644 --- a/patches/server/0100-Configurable-TPS-Catchup.patch +++ b/patches/server/0070-Configurable-TPS-Catchup.patch @@ -1,47 +1,46 @@ -From 68b264656f252e5a829e2a70024ffe9e74fb8e6c Mon Sep 17 00:00:00 2001 +From 02da1438e3d0845b34082ffe6a80bf7471790dc9 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Thu, 26 Mar 2020 19:06:22 -0500 Subject: [PATCH] Configurable TPS Catchup --- - src/main/java/net/minecraft/server/MinecraftServer.java | 7 +++++++ + src/main/java/net/minecraft/server/MinecraftServer.java | 8 +++++++- src/main/java/net/pl3x/purpur/PurpurConfig.java | 5 +++++ - 2 files changed, 12 insertions(+) + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index d91d3a82c..40da7a05c 100644 +index 822798741..b7915d2ff 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -988,6 +988,13 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant Date: Thu, 19 Mar 2020 19:39:34 -0500 Subject: [PATCH] Add option to allow loyalty on tridents to work in the void @@ -9,38 +9,34 @@ Subject: [PATCH] Add option to allow loyalty on tridents to work in the void 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/minecraft/server/EntityThrownTrident.java b/src/main/java/net/minecraft/server/EntityThrownTrident.java -index 59bb039ad..b975cc7fb 100644 +index c68002ffe..9be919986 100644 --- a/src/main/java/net/minecraft/server/EntityThrownTrident.java +++ b/src/main/java/net/minecraft/server/EntityThrownTrident.java @@ -38,7 +38,7 @@ public class EntityThrownTrident extends EntityArrow { Entity entity = this.getShooter(); -- if ((this.as || this.v()) && entity != null) { -+ if ((this.as || this.v() || (world.purpurConfig.tridentLoyaltyVoidReturnHeight < 0.0D && locY() < world.purpurConfig.tridentLoyaltyVoidReturnHeight)) && entity != null) { // Purpur - byte b0 = (Byte) this.datawatcher.get(EntityThrownTrident.ap); +- if ((this.ap || this.t()) && entity != null) { ++ if ((this.ap || this.t() || (world.purpurConfig.tridentLoyaltyVoidReturnHeight < 0.0D && locY() < world.purpurConfig.tridentLoyaltyVoidReturnHeight)) && entity != null) { // Purpur + byte b0 = (Byte) this.datawatcher.get(EntityThrownTrident.g); if (b0 > 0 && !this.z()) { diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 53c8782b5..01b8fffe1 100644 +index 5549a984d..e571b3628 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -189,6 +189,7 @@ public class PurpurWorldConfig { - public String playerSleepCondition = "time >= 12541 && time <= 23458"; - public boolean useBetterMending = false; - public boolean saveProjectilesToDisk = true; +@@ -117,9 +117,11 @@ public class PurpurWorldConfig { + + public boolean disableDropsOnCrammingDeath = false; + public boolean milkCuresBadOmen = true; + public double tridentLoyaltyVoidReturnHeight = 0.0D; - public double voidDamageHeight = -64.0D; - private void gameplayMechanicsSettings() { - boatEjectPlayersOnLand = getBoolean("gameplay-mechanics.boat.eject-players-on-land", boatEjectPlayersOnLand); -@@ -246,6 +247,7 @@ public class PurpurWorldConfig { - set("gameplay-mechanics.saveProjectilesToDisk", null); - } - saveProjectilesToDisk = getBoolean("gameplay-mechanics.save-projectiles-to-disk", saveProjectilesToDisk); + private void miscGameplayMechanicsSettings() { + disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath); + milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen); + tridentLoyaltyVoidReturnHeight = getDouble("gameplay-mechanics.trident-loyalty-void-return-height", tridentLoyaltyVoidReturnHeight); - voidDamageHeight = getDouble("gameplay-mechanics.void-damage-height", voidDamageHeight); } + public int playerSpawnInvulnerableTicks = 60; -- 2.26.2 diff --git a/patches/server/0109-Add-enderman-and-creeper-griefing-controls.patch b/patches/server/0072-Add-enderman-and-creeper-griefing-controls.patch similarity index 63% rename from patches/server/0109-Add-enderman-and-creeper-griefing-controls.patch rename to patches/server/0072-Add-enderman-and-creeper-griefing-controls.patch index 48d8d5a35..69cc42704 100644 --- a/patches/server/0109-Add-enderman-and-creeper-griefing-controls.patch +++ b/patches/server/0072-Add-enderman-and-creeper-griefing-controls.patch @@ -1,4 +1,4 @@ -From 1f2cea0e76872e923b9351c848918889ec610af4 Mon Sep 17 00:00:00 2001 +From cb1c37ea2302e7d0dd55ce91ecbac3e3ebe561fb Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 26 Apr 2020 16:28:38 -0500 Subject: [PATCH] Add enderman and creeper griefing controls @@ -6,14 +6,14 @@ Subject: [PATCH] Add enderman and creeper griefing controls --- src/main/java/net/minecraft/server/EntityCreeper.java | 2 +- src/main/java/net/minecraft/server/EntityEnderman.java | 2 ++ - src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 4 ++++ - 3 files changed, 7 insertions(+), 1 deletion(-) + src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 7 +++++++ + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/minecraft/server/EntityCreeper.java b/src/main/java/net/minecraft/server/EntityCreeper.java -index ce366f401..93efc7977 100644 +index ec5287fa5..848944230 100644 --- a/src/main/java/net/minecraft/server/EntityCreeper.java +++ b/src/main/java/net/minecraft/server/EntityCreeper.java -@@ -237,7 +237,7 @@ public class EntityCreeper extends EntityMonster { +@@ -204,7 +204,7 @@ public class EntityCreeper extends EntityMonster { public void explode() { if (!this.world.isClientSide) { @@ -23,10 +23,10 @@ index ce366f401..93efc7977 100644 // CraftBukkit start diff --git a/src/main/java/net/minecraft/server/EntityEnderman.java b/src/main/java/net/minecraft/server/EntityEnderman.java -index de30ce483..68165d72d 100644 +index b61de3351..245fc38de 100644 --- a/src/main/java/net/minecraft/server/EntityEnderman.java +++ b/src/main/java/net/minecraft/server/EntityEnderman.java -@@ -354,6 +354,7 @@ public class EntityEnderman extends EntityMonster { +@@ -370,6 +370,7 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable { @Override public boolean a() { @@ -34,7 +34,7 @@ index de30ce483..68165d72d 100644 return this.enderman.getCarried() != null ? false : (!this.enderman.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) ? false : this.enderman.getRandom().nextInt(20) == 0); } -@@ -397,6 +398,7 @@ public class EntityEnderman extends EntityMonster { +@@ -413,6 +414,7 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable { @Override public boolean a() { @@ -43,36 +43,32 @@ index de30ce483..68165d72d 100644 } diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 0347b729c..e6ab2fde4 100644 +index e571b3628..bd9ac998f 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -394,11 +394,13 @@ public class PurpurWorldConfig { - public boolean creeperRidableInWater = false; - public boolean creeperRequireShiftToMount = true; - public double creeperChargedChance = 0.0D; +@@ -172,8 +172,10 @@ public class PurpurWorldConfig { + cowFeedMushrooms = getInt("mobs.cow.feed-mushrooms-for-mooshroom", cowFeedMushrooms); + } + + public boolean creeperAllowGriefing = true; + public double creeperChargedChance = 0.0D; private void creeperSettings() { - creeperRidable = getBoolean("mobs.creeper.ridable", creeperRidable); - creeperRidableInWater = getBoolean("mobs.creeper.ridable-in-water", creeperRidableInWater); - creeperRequireShiftToMount = getBoolean("mobs.creeper.require-shift-to-mount", creeperRequireShiftToMount); - creeperChargedChance = getDouble("mobs.creeper.naturally-charged-chance", creeperChargedChance); + creeperAllowGriefing = getBoolean("mobs.creeper.allow-griefing", creeperAllowGriefing); + creeperChargedChance = getDouble("mobs.creeper.naturally-charged-chance", creeperChargedChance); + } + +@@ -184,6 +186,11 @@ public class PurpurWorldConfig { + enderDragonAlwaysDropsFullExp = getBoolean("mobs.ender_dragon.always-drop-full-exp", enderDragonAlwaysDropsFullExp); } - public boolean dolphinRidable = false; -@@ -463,10 +465,12 @@ public class PurpurWorldConfig { - public boolean endermanRidable = false; - public boolean endermanRidableInWater = false; - public boolean endermanRequireShiftToMount = true; + public boolean endermanAllowGriefing = true; - private void endermanSettings() { - endermanRidable = getBoolean("mobs.enderman.ridable", endermanRidable); - endermanRidableInWater = getBoolean("mobs.enderman.ridable-in-water", endermanRidableInWater); - endermanRequireShiftToMount = getBoolean("mobs.enderman.require-shift-to-mount", endermanRequireShiftToMount); ++ private void endermanSettings() { + endermanAllowGriefing = getBoolean("mobs.enderman.allow-griefing", endermanAllowGriefing); - } - - public boolean endermiteRidable = false; ++ } ++ + public boolean foxTypeChangesWithTulips = false; + private void foxSettings() { + foxTypeChangesWithTulips = getBoolean("mobs.fox.tulips-change-type", foxTypeChangesWithTulips); -- 2.26.2 diff --git a/patches/server/0111-Entities-pick-up-loot-bypass-mob-griefing-gamerule.patch b/patches/server/0073-Entities-pick-up-loot-bypass-mob-griefing-gamerule.patch similarity index 63% rename from patches/server/0111-Entities-pick-up-loot-bypass-mob-griefing-gamerule.patch rename to patches/server/0073-Entities-pick-up-loot-bypass-mob-griefing-gamerule.patch index 2f529b2dc..2682c39f5 100644 --- a/patches/server/0111-Entities-pick-up-loot-bypass-mob-griefing-gamerule.patch +++ b/patches/server/0073-Entities-pick-up-loot-bypass-mob-griefing-gamerule.patch @@ -1,4 +1,4 @@ -From 02641240d37f617ad72ad74f28ddc87d950e0e7a Mon Sep 17 00:00:00 2001 +From ed8fe7b9c7b1da77811da03d30016b39f0268a5a Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Fri, 24 Apr 2020 09:33:11 -0500 Subject: [PATCH] Entities pick up loot bypass mob-griefing gamerule @@ -9,38 +9,35 @@ Subject: [PATCH] Entities pick up loot bypass mob-griefing gamerule 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java -index eb0befb35..4e5b71046 100644 +index 93714e5d9..b23674625 100644 --- a/src/main/java/net/minecraft/server/EntityInsentient.java +++ b/src/main/java/net/minecraft/server/EntityInsentient.java -@@ -525,7 +525,7 @@ public abstract class EntityInsentient extends EntityLiving { +@@ -542,7 +542,7 @@ public abstract class EntityInsentient extends EntityLiving { public void movementTick() { super.movementTick(); this.world.getMethodProfiler().enter("looting"); - if (!this.world.isClientSide && this.canPickupLoot() && this.isAlive() && !this.killed && this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) { -+ if (!this.world.isClientSide && this.canPickupLoot() && this.isAlive() && !this.killed && (this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) || world.purpurConfig.entitiesPickUpLootBypassMobGriefing)) { ++ if (!this.world.isClientSide && this.canPickupLoot() && this.isAlive() && !this.killed && (this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) || world.purpurConfig.entitiesPickUpLootBypassMobGriefing)) { // Purpur List list = this.world.a(EntityItem.class, this.getBoundingBox().grow(1.0D, 0.0D, 1.0D)); Iterator iterator = list.iterator(); diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 6962d17b9..e57299f1e 100644 +index bd9ac998f..7217c07e5 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -200,6 +200,7 @@ public class PurpurWorldConfig { - public double controllableMinecartsBaseSpeed = 0.1D; - public Map controllableMinecartsBlockSpeeds = new HashMap<>(); +@@ -116,10 +116,12 @@ public class PurpurWorldConfig { + } + public boolean disableDropsOnCrammingDeath = false; + public boolean entitiesPickUpLootBypassMobGriefing = false; - public boolean fixClimbingBypassingCrammingRule = false; - public boolean itemFloatInLava = false; - public List itemImmuneToExplosion = new ArrayList<>(); -@@ -235,6 +236,7 @@ public class PurpurWorldConfig { - set("gameplay-mechanics.controllable-minecarts.block-speed.stone", 0.5D); - } + public boolean milkCuresBadOmen = true; + public double tridentLoyaltyVoidReturnHeight = 0.0D; + private void miscGameplayMechanicsSettings() { disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath); + entitiesPickUpLootBypassMobGriefing = getBoolean("gameplay-mechanics.entities-pick-up-loot-bypass-mob-griefing", entitiesPickUpLootBypassMobGriefing); - fixClimbingBypassingCrammingRule = getBoolean("gameplay-mechanics.fix-climbing-bypassing-cramming-rule", fixClimbingBypassingCrammingRule); - itemFloatInLava = getBoolean("gameplay-mechanics.item.float-in-lava", itemFloatInLava); - getList("gameplay-mechanics.item.immune.explosion", itemImmuneToExplosion).forEach(key -> { + milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen); + tridentLoyaltyVoidReturnHeight = getDouble("gameplay-mechanics.trident-loyalty-void-return-height", tridentLoyaltyVoidReturnHeight); + } -- 2.26.2 diff --git a/patches/server/0073-Fix-furnace-cook-speed-multiplier-using-values-betwe.patch b/patches/server/0073-Fix-furnace-cook-speed-multiplier-using-values-betwe.patch deleted file mode 100644 index 421e185ff..000000000 --- a/patches/server/0073-Fix-furnace-cook-speed-multiplier-using-values-betwe.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 2773516386b1b074024a5129b2dac38d1d1d0ec9 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sat, 19 Oct 2019 03:36:52 -0500 -Subject: [PATCH] Fix furnace cook speed multiplier using values between 0 and - 1 - ---- - src/main/java/net/minecraft/server/TileEntityFurnace.java | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/src/main/java/net/minecraft/server/TileEntityFurnace.java b/src/main/java/net/minecraft/server/TileEntityFurnace.java -index 7d50b7056..c5e643292 100644 ---- a/src/main/java/net/minecraft/server/TileEntityFurnace.java -+++ b/src/main/java/net/minecraft/server/TileEntityFurnace.java -@@ -307,8 +307,10 @@ public abstract class TileEntityFurnace extends TileEntityContainer implements I - } - - if (this.isBurning() && this.canBurn(irecipe)) { -- this.cookTime += cookSpeedMultiplier; // Paper - cook speed multiplier API -- if (this.cookTime >= this.cookTimeTotal) { // Paper - cook speed multiplier API -+ // Purpur start - fix cook speed multiplier API -+ ++this.cookTime; -+ if (this.cookTime >= this.cookTimeTotal / this.cookSpeedMultiplier) { -+ // Purpur end - fix cook speed multiplier API - this.cookTime = 0; - this.cookTimeTotal = this.getRecipeCookingTime(); - this.burn(irecipe); --- -2.26.2 - diff --git a/patches/server/0113-Villagers-farming-can-bypass-mob-griefing-gamerule.patch b/patches/server/0074-Villagers-farming-can-bypass-mob-griefing-gamerule.patch similarity index 59% rename from patches/server/0113-Villagers-farming-can-bypass-mob-griefing-gamerule.patch rename to patches/server/0074-Villagers-farming-can-bypass-mob-griefing-gamerule.patch index b0647d59c..102d834ee 100644 --- a/patches/server/0113-Villagers-farming-can-bypass-mob-griefing-gamerule.patch +++ b/patches/server/0074-Villagers-farming-can-bypass-mob-griefing-gamerule.patch @@ -1,4 +1,4 @@ -From 4fec6b17576670bee04b5fe77d3aac03c348d251 Mon Sep 17 00:00:00 2001 +From e041a3ff936aea8dc97bc6ddbac5b9e0dd52fef8 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Fri, 24 Apr 2020 09:37:29 -0500 Subject: [PATCH] Villagers farming can bypass mob-griefing gamerule @@ -9,38 +9,34 @@ Subject: [PATCH] Villagers farming can bypass mob-griefing gamerule 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/minecraft/server/BehaviorFarm.java b/src/main/java/net/minecraft/server/BehaviorFarm.java -index e05e97727..cf3126a65 100644 +index 54a555509..0ff202c0d 100644 --- a/src/main/java/net/minecraft/server/BehaviorFarm.java +++ b/src/main/java/net/minecraft/server/BehaviorFarm.java -@@ -20,7 +20,7 @@ public class BehaviorFarm extends Behavior { +@@ -18,7 +18,7 @@ public class BehaviorFarm extends Behavior { } protected boolean a(WorldServer worldserver, EntityVillager entityvillager) { - if (!worldserver.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) { -+ if (!worldserver.getGameRules().getBoolean(GameRules.MOB_GRIEFING) && !worldserver.purpurConfig.villagerFarmingBypassMobGriefing) { ++ if (!worldserver.getGameRules().getBoolean(GameRules.MOB_GRIEFING) && !worldserver.purpurConfig.villagerFarmingBypassMobGriefing) { // Purpur return false; } else if (entityvillager.getVillagerData().getProfession() != VillagerProfession.FARMER) { return false; diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index e57299f1e..efdc176e6 100644 +index 7217c07e5..15dc4e222 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -892,6 +892,7 @@ public class PurpurWorldConfig { - public boolean villagerCanBeLeashed = false; - public int villagerSpawnIronGolemRadius = 0; - public int villagerSpawnIronGolemLimit = 0; +@@ -258,9 +258,11 @@ public class PurpurWorldConfig { + + public int villagerBrainTicks = 1; + public boolean villagerUseBrainTicksOnlyWhenLagging = true; + public boolean villagerFarmingBypassMobGriefing = false; private void villagerSettings() { - villagerRidable = getBoolean("mobs.villager.ridable", villagerRidable); - villagerRidableInWater = getBoolean("mobs.villager.ridable-in-water", villagerRidableInWater); -@@ -902,6 +903,7 @@ public class PurpurWorldConfig { - villagerCanBeLeashed = getBoolean("mobs.villager.can-be-leashed", villagerCanBeLeashed); - villagerSpawnIronGolemRadius = getInt("mobs.villager.spawn-iron-golem.radius", villagerSpawnIronGolemRadius); - villagerSpawnIronGolemLimit = getInt("mobs.villager.spawn-iron-golem.limit", villagerSpawnIronGolemLimit); + villagerBrainTicks = getInt("mobs.villager.brain-ticks", villagerBrainTicks); + villagerUseBrainTicksOnlyWhenLagging = getBoolean("mobs.villager.use-brain-ticks-only-when-lagging", villagerUseBrainTicksOnlyWhenLagging); + villagerFarmingBypassMobGriefing = getBoolean("mobs.villager.bypass-mob-griefing", villagerFarmingBypassMobGriefing); } - public boolean villagerTraderRidable = false; + public boolean witherSkeletonTakesWitherDamage = false; -- 2.26.2 diff --git a/patches/server/0075-Despawn-egg-hatches-chicken.patch b/patches/server/0075-Despawn-egg-hatches-chicken.patch deleted file mode 100644 index 4e5018c28..000000000 --- a/patches/server/0075-Despawn-egg-hatches-chicken.patch +++ /dev/null @@ -1,65 +0,0 @@ -From ab9d1fa681708fd626c0c7a02291cd17d8bdff0c Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Fri, 29 Nov 2019 23:47:42 -0600 -Subject: [PATCH] Despawn egg hatches chicken - ---- - .../java/net/minecraft/server/EntityItem.java | 21 +++++++++++++++++++ - .../net/pl3x/purpur/PurpurWorldConfig.java | 4 ++++ - 2 files changed, 25 insertions(+) - -diff --git a/src/main/java/net/minecraft/server/EntityItem.java b/src/main/java/net/minecraft/server/EntityItem.java -index 2926fbb95..bbb9ca1ef 100644 ---- a/src/main/java/net/minecraft/server/EntityItem.java -+++ b/src/main/java/net/minecraft/server/EntityItem.java -@@ -165,6 +165,27 @@ public class EntityItem extends Entity { - } - // Spigot end - -+ // Purpur start -+ @Override -+ public void die() { -+ if (!dead && world.purpurConfig.chickenEggsHatchWhenDespawnedMax > 0) { -+ ItemStack item = getItemStack(); -+ if (item != null && item.getItem() == Items.EGG) { -+ int range = world.purpurConfig.chickenEggsHatchWhenDespawnedRange; -+ if (world.getEntitiesByClass(EntityChicken.class, new AxisAlignedBB(locX() - range, locY() - range, locZ() - range, locX() + range, locY() + range, locZ() + range)).size() < world.purpurConfig.chickenEggsHatchWhenDespawnedMax) { -+ EntityChicken chicken = EntityTypes.CHICKEN.create(world); -+ if (chicken != null) { -+ chicken.setPosition(locX(), locY(), locZ()); -+ chicken.setAge(-24000); -+ world.addEntity(chicken, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EGG); -+ } -+ } -+ } -+ } -+ super.die(); -+ } -+ // Purpur end -+ - private void u() { - Vec3D vec3d = this.getMot(); - -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 5b042a609..647bece31 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -262,11 +262,15 @@ public class PurpurWorldConfig { - public boolean chickenRidableInWater = false; - public boolean chickenRequireShiftToMount = true; - public boolean chickenDontLayEggsWhenRidden = false; -+ public int chickenEggsHatchWhenDespawnedMax = 0; -+ public int chickenEggsHatchWhenDespawnedRange = 10; - private void chickenSettings() { - chickenRidable = getBoolean("mobs.chicken.ridable", chickenRidable); - chickenRidableInWater = getBoolean("mobs.chicken.ridable-in-water", chickenRidableInWater); - chickenRequireShiftToMount = getBoolean("mobs.chicken.require-shift-to-mount", chickenRequireShiftToMount); - chickenDontLayEggsWhenRidden = getBoolean("mobs.chicken.dont-lay-eggs-when-ridden", chickenDontLayEggsWhenRidden); -+ chickenEggsHatchWhenDespawnedMax = getInt("mobs.chicken.eggs-hatch-when-despawned.max", chickenEggsHatchWhenDespawnedMax); -+ chickenEggsHatchWhenDespawnedRange = getInt("mobs.chicken.eggs-hatch-when-despawned.range", chickenEggsHatchWhenDespawnedRange); - } - - public boolean codRidable = false; --- -2.26.2 - diff --git a/patches/server/0081-Villagers-follow-emerald-blocks.patch b/patches/server/0075-Villagers-follow-emerald-blocks.patch similarity index 60% rename from patches/server/0081-Villagers-follow-emerald-blocks.patch rename to patches/server/0075-Villagers-follow-emerald-blocks.patch index 7465b26c8..bb585486f 100644 --- a/patches/server/0081-Villagers-follow-emerald-blocks.patch +++ b/patches/server/0075-Villagers-follow-emerald-blocks.patch @@ -1,45 +1,51 @@ -From 284ff850e9d523d2465658b3b4c6c219eadee509 Mon Sep 17 00:00:00 2001 +From ba294b5f9e120d06131cd1642e2bb0a80d6bfcff Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Fri, 29 Nov 2019 22:10:12 -0600 Subject: [PATCH] Villagers follow emerald blocks --- - src/main/java/net/minecraft/server/EntityVillager.java | 1 + - .../java/net/minecraft/server/EntityVillagerAbstract.java | 2 +- - src/main/java/net/minecraft/server/EntityVillagerTrader.java | 1 + - src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 4 ++++ - 4 files changed, 7 insertions(+), 1 deletion(-) + src/main/java/net/minecraft/server/EntityVillager.java | 7 +++++++ + .../java/net/minecraft/server/EntityVillagerAbstract.java | 2 ++ + .../java/net/minecraft/server/EntityVillagerTrader.java | 1 + + src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 7 +++++++ + 4 files changed, 17 insertions(+) diff --git a/src/main/java/net/minecraft/server/EntityVillager.java b/src/main/java/net/minecraft/server/EntityVillager.java -index 843f22260..a30ac7cc0 100644 +index 7925c8991..3e10ee440 100644 --- a/src/main/java/net/minecraft/server/EntityVillager.java +++ b/src/main/java/net/minecraft/server/EntityVillager.java -@@ -89,6 +89,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation - @Override - protected void initPathfinder() { - this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur -+ if (world.purpurConfig.villagerFollowEmeraldBlock) this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.0D, false, TEMPT_ITEMS)); +@@ -74,6 +74,13 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation + this.brainTickOffset = getRandom().nextInt(100); // Purpur } - // Purpur end ++ // Purpur start ++ @Override ++ protected void initPathfinder() { ++ if (world.purpurConfig.villagerFollowEmeraldBlock) this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.0D, false, TEMPT_ITEMS)); ++ } ++ // Purpur end ++ + @Override + public BehaviorController getBehaviorController() { + return (BehaviorController) super.getBehaviorController(); // CraftBukkit - decompile error diff --git a/src/main/java/net/minecraft/server/EntityVillagerAbstract.java b/src/main/java/net/minecraft/server/EntityVillagerAbstract.java -index 5fbd13512..13063f006 100644 +index beb84a2ab..a3b4a59fd 100644 --- a/src/main/java/net/minecraft/server/EntityVillagerAbstract.java +++ b/src/main/java/net/minecraft/server/EntityVillagerAbstract.java -@@ -13,7 +13,7 @@ import org.bukkit.event.entity.VillagerAcquireTradeEvent; - // CraftBukkit end +@@ -14,6 +14,8 @@ import org.bukkit.event.entity.VillagerAcquireTradeEvent; public abstract class EntityVillagerAbstract extends EntityAgeable implements NPC, IMerchant { -- + + static final RecipeItemStack TEMPT_ITEMS = RecipeItemStack.a(Blocks.EMERALD_BLOCK.getItem()); // Purpur ++ // CraftBukkit start private CraftMerchant craftMerchant; diff --git a/src/main/java/net/minecraft/server/EntityVillagerTrader.java b/src/main/java/net/minecraft/server/EntityVillagerTrader.java -index 4e9c5e84a..14ca5fc36 100644 +index a0841cfaf..ab5e97e39 100644 --- a/src/main/java/net/minecraft/server/EntityVillagerTrader.java +++ b/src/main/java/net/minecraft/server/EntityVillagerTrader.java -@@ -57,6 +57,7 @@ public class EntityVillagerTrader extends EntityVillagerAbstract { +@@ -40,6 +40,7 @@ public class EntityVillagerTrader extends EntityVillagerAbstract { this.goalSelector.a(1, new PathfinderGoalPanic(this, 0.5D)); this.goalSelector.a(1, new PathfinderGoalLookAtTradingPlayer(this)); this.goalSelector.a(2, new EntityVillagerTrader.a(this, 2.0D, 0.35D)); @@ -48,35 +54,27 @@ index 4e9c5e84a..14ca5fc36 100644 this.goalSelector.a(8, new PathfinderGoalRandomStrollLand(this, 0.35D)); this.goalSelector.a(9, new PathfinderGoalInteract(this, EntityHuman.class, 3.0F, 1.0F)); diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index a4a09874f..7d2c51a2f 100644 +index 15dc4e222..1f22ee61b 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -775,21 +775,25 @@ public class PurpurWorldConfig { - public boolean villagerRequireShiftToMount = true; +@@ -259,10 +259,17 @@ public class PurpurWorldConfig { public int villagerBrainTicks = 1; public boolean villagerUseBrainTicksOnlyWhenLagging = true; + public boolean villagerFarmingBypassMobGriefing = false; + public boolean villagerFollowEmeraldBlock = false; private void villagerSettings() { - villagerRidable = getBoolean("mobs.villager.ridable", villagerRidable); - villagerRidableInWater = getBoolean("mobs.villager.ridable-in-water", villagerRidableInWater); - villagerRequireShiftToMount = getBoolean("mobs.villager.require-shift-to-mount", villagerRequireShiftToMount); villagerBrainTicks = getInt("mobs.villager.brain-ticks", villagerBrainTicks); villagerUseBrainTicksOnlyWhenLagging = getBoolean("mobs.villager.use-brain-ticks-only-when-lagging", villagerUseBrainTicksOnlyWhenLagging); + villagerFarmingBypassMobGriefing = getBoolean("mobs.villager.bypass-mob-griefing", villagerFarmingBypassMobGriefing); + villagerFollowEmeraldBlock = getBoolean("mobs.villager.follow-emerald-blocks", villagerFollowEmeraldBlock); - } - - public boolean villagerTraderRidable = false; - public boolean villagerTraderRidableInWater = false; - public boolean villagerTraderRequireShiftToMount = true; ++ } ++ + public boolean villagerTraderFollowEmeraldBlock = false; - private void villagerTraderSettings() { - villagerTraderRidable = getBoolean("mobs.wandering_trader.ridable", villagerTraderRidable); - villagerTraderRidableInWater = getBoolean("mobs.wandering_trader.ridable-in-water", villagerTraderRidableInWater); - villagerTraderRequireShiftToMount = getBoolean("mobs.wandering_trader.require-shift-to-mount", villagerTraderRequireShiftToMount); ++ private void villagerTraderSettings() { + villagerTraderFollowEmeraldBlock = getBoolean("mobs.wandering_trader.follow-emerald-blocks", villagerTraderFollowEmeraldBlock); } - public boolean vindicatorRidable = false; + public boolean witherSkeletonTakesWitherDamage = false; -- 2.26.2 diff --git a/patches/server/0084-Allow-leashing-villagers.patch b/patches/server/0076-Allow-leashing-villagers.patch similarity index 66% rename from patches/server/0084-Allow-leashing-villagers.patch rename to patches/server/0076-Allow-leashing-villagers.patch index f849cc3b9..f5fc56480 100644 --- a/patches/server/0084-Allow-leashing-villagers.patch +++ b/patches/server/0076-Allow-leashing-villagers.patch @@ -1,92 +1,87 @@ -From 2e855c9499f82ddbf21cbd5e1e33d5d5d9e1250c Mon Sep 17 00:00:00 2001 +From 48558630bb0b0715005ce6ef0345f82de1a7c875 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Thu, 3 Oct 2019 18:08:03 -0500 Subject: [PATCH] Allow leashing villagers --- src/main/java/net/minecraft/server/EntityInsentient.java | 1 + - src/main/java/net/minecraft/server/EntityVillager.java | 7 +++++++ + src/main/java/net/minecraft/server/EntityVillager.java | 5 +++++ .../java/net/minecraft/server/EntityVillagerTrader.java | 7 +++++++ src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 4 ++++ - 4 files changed, 19 insertions(+) + 4 files changed, 17 insertions(+) diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java -index bf9d044b0..3adc3434e 100644 +index b23674625..744552fda 100644 --- a/src/main/java/net/minecraft/server/EntityInsentient.java +++ b/src/main/java/net/minecraft/server/EntityInsentient.java -@@ -1062,6 +1062,7 @@ public abstract class EntityInsentient extends EntityLiving { +@@ -1129,6 +1129,7 @@ public abstract class EntityInsentient extends EntityLiving { if (!this.isAlive()) { - return false; + return EnumInteractionResult.PASS; } else if (this.getLeashHolder() == entityhuman) { -+ if (enumhand == EnumHand.OFF_HAND && (world.purpurConfig.villagerCanBeLeashed || world.purpurConfig.villagerTraderCanBeLeashed) && this instanceof EntityVillagerAbstract) return true; // Purpur ++ if (enumhand == EnumHand.OFF_HAND && (world.purpurConfig.villagerCanBeLeashed || world.purpurConfig.villagerTraderCanBeLeashed) && this instanceof EntityVillagerAbstract) return EnumInteractionResult.CONSUME; // Purpur // CraftBukkit start - fire PlayerUnleashEntityEvent if (CraftEventFactory.callPlayerUnleashEntityEvent(this, entityhuman).isCancelled()) { ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutAttachEntity(this, this.getLeashHolder())); diff --git a/src/main/java/net/minecraft/server/EntityVillager.java b/src/main/java/net/minecraft/server/EntityVillager.java -index a30ac7cc0..e3322fedd 100644 +index 3e10ee440..97eb26482 100644 --- a/src/main/java/net/minecraft/server/EntityVillager.java +++ b/src/main/java/net/minecraft/server/EntityVillager.java -@@ -1031,4 +1031,11 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation - this.bL = restocksToday; +@@ -79,6 +79,11 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation + protected void initPathfinder() { + if (world.purpurConfig.villagerFollowEmeraldBlock) this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.0D, false, TEMPT_ITEMS)); } - // Paper end + -+ // Purpur - start + @Override + public boolean a(EntityHuman entityhuman) { + return world.purpurConfig.villagerCanBeLeashed && !this.isLeashed(); + } -+ // Purpur - end - } + // Purpur end + + @Override diff --git a/src/main/java/net/minecraft/server/EntityVillagerTrader.java b/src/main/java/net/minecraft/server/EntityVillagerTrader.java -index 14ca5fc36..427c58907 100644 +index ab5e97e39..9985afb12 100644 --- a/src/main/java/net/minecraft/server/EntityVillagerTrader.java +++ b/src/main/java/net/minecraft/server/EntityVillagerTrader.java -@@ -283,4 +283,11 @@ public class EntityVillagerTrader extends EntityVillagerAbstract { - return !blockposition.a((IPosition) this.a.getPositionVector(), d0); - } +@@ -47,6 +47,13 @@ public class EntityVillagerTrader extends EntityVillagerAbstract { + this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F)); } -+ + + // Purpur - start + @Override + public boolean a(EntityHuman entityhuman) { + return world.purpurConfig.villagerTraderCanBeLeashed && !this.isLeashed(); + } + // Purpur - end - } ++ + @Nullable + @Override + public EntityAgeable createChild(EntityAgeable entityageable) { diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index caf7f0e84..284054db4 100644 +index 1f22ee61b..f82288126 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -780,6 +780,7 @@ public class PurpurWorldConfig { +@@ -258,17 +258,21 @@ public class PurpurWorldConfig { + public int villagerBrainTicks = 1; public boolean villagerUseBrainTicksOnlyWhenLagging = true; - public boolean villagerFollowEmeraldBlock = false; + public boolean villagerCanBeLeashed = false; + public boolean villagerFarmingBypassMobGriefing = false; + public boolean villagerFollowEmeraldBlock = false; private void villagerSettings() { - villagerRidable = getBoolean("mobs.villager.ridable", villagerRidable); - villagerRidableInWater = getBoolean("mobs.villager.ridable-in-water", villagerRidableInWater); -@@ -787,17 +788,20 @@ public class PurpurWorldConfig { villagerBrainTicks = getInt("mobs.villager.brain-ticks", villagerBrainTicks); villagerUseBrainTicksOnlyWhenLagging = getBoolean("mobs.villager.use-brain-ticks-only-when-lagging", villagerUseBrainTicksOnlyWhenLagging); - villagerFollowEmeraldBlock = getBoolean("mobs.villager.follow-emerald-blocks", villagerFollowEmeraldBlock); + villagerCanBeLeashed = getBoolean("mobs.villager.can-be-leashed", villagerCanBeLeashed); + villagerFarmingBypassMobGriefing = getBoolean("mobs.villager.bypass-mob-griefing", villagerFarmingBypassMobGriefing); + villagerFollowEmeraldBlock = getBoolean("mobs.villager.follow-emerald-blocks", villagerFollowEmeraldBlock); } - public boolean villagerTraderRidable = false; - public boolean villagerTraderRidableInWater = false; - public boolean villagerTraderRequireShiftToMount = true; - public boolean villagerTraderFollowEmeraldBlock = false; + public boolean villagerTraderCanBeLeashed = false; + public boolean villagerTraderFollowEmeraldBlock = false; private void villagerTraderSettings() { - villagerTraderRidable = getBoolean("mobs.wandering_trader.ridable", villagerTraderRidable); - villagerTraderRidableInWater = getBoolean("mobs.wandering_trader.ridable-in-water", villagerTraderRidableInWater); - villagerTraderRequireShiftToMount = getBoolean("mobs.wandering_trader.require-shift-to-mount", villagerTraderRequireShiftToMount); - villagerTraderFollowEmeraldBlock = getBoolean("mobs.wandering_trader.follow-emerald-blocks", villagerTraderFollowEmeraldBlock); + villagerTraderCanBeLeashed = getBoolean("mobs.wandering_trader.can-be-leashed", villagerTraderCanBeLeashed); + villagerTraderFollowEmeraldBlock = getBoolean("mobs.wandering_trader.follow-emerald-blocks", villagerTraderFollowEmeraldBlock); } - public boolean vindicatorRidable = false; -- 2.26.2 diff --git a/patches/server/0076-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch b/patches/server/0076-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch deleted file mode 100644 index 2dc748509..000000000 --- a/patches/server/0076-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 324ade06e16035915b27500e54ab4fb1f1c29a32 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sat, 19 Oct 2019 01:42:50 -0500 -Subject: [PATCH] Fix SpawnChangeEvent not firing for all use-cases - ---- - src/main/java/net/minecraft/server/World.java | 3 +++ - src/main/java/org/bukkit/craftbukkit/CraftWorld.java | 12 ++++++++---- - 2 files changed, 11 insertions(+), 4 deletions(-) - -diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index ad3b81a11..b24191d81 100644 ---- a/src/main/java/net/minecraft/server/World.java -+++ b/src/main/java/net/minecraft/server/World.java -@@ -1472,8 +1472,11 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - return blockposition; - } - -+ public void setSpawn(BlockPosition blockposition) { v(blockposition); } // Purpur - OBFHELPER - public void a_(BlockPosition blockposition) { -+ BlockPosition prevPos = getSpawn(); // Purpur - this.worldData.setSpawn(blockposition); -+ new org.bukkit.event.world.SpawnChangeEvent(world, MCUtil.toLocation(this, prevPos)).callEvent(); // Purpur - } - - public boolean a(EntityHuman entityhuman, BlockPosition blockposition) { -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 3d27028e8..85922aaa9 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -391,12 +391,16 @@ public class CraftWorld implements World { - @Override - public boolean setSpawnLocation(int x, int y, int z) { - try { -- Location previousLocation = getSpawnLocation(); -- world.worldData.setSpawn(new BlockPosition(x, y, z)); -+ // Purpur start - move to World#setSpawn() -+ //Location previousLocation = getSpawnLocation(); -+ //world.worldData.setSpawn(new BlockPosition(x, y, z)); - - // Notify anyone who's listening. -- SpawnChangeEvent event = new SpawnChangeEvent(this, previousLocation); -- server.getPluginManager().callEvent(event); -+ //SpawnChangeEvent event = new SpawnChangeEvent(this, previousLocation); -+ //server.getPluginManager().callEvent(event); -+ -+ world.setSpawn(new BlockPosition(x, y, z)); -+ // Purpur end - - return true; - } catch (Exception e) { --- -2.26.2 - diff --git a/patches/server/0077-Add-sleep-options.patch b/patches/server/0077-Add-sleep-options.patch deleted file mode 100644 index 76ae93017..000000000 --- a/patches/server/0077-Add-sleep-options.patch +++ /dev/null @@ -1,79 +0,0 @@ -From ace26bd42b6a6b5de262a011df936981c281c91e Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sat, 30 Nov 2019 03:30:17 -0600 -Subject: [PATCH] Add sleep options - ---- - .../net/minecraft/server/EntityHuman.java | 19 +++++++++++++++++-- - .../net/pl3x/purpur/PurpurWorldConfig.java | 4 ++++ - 2 files changed, 21 insertions(+), 2 deletions(-) - -diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java -index d62174e9c..22e17e3de 100644 ---- a/src/main/java/net/minecraft/server/EntityHuman.java -+++ b/src/main/java/net/minecraft/server/EntityHuman.java -@@ -143,6 +143,21 @@ public abstract class EntityHuman extends EntityLiving { - this.datawatcher.register(EntityHuman.bt, new NBTTagCompound()); - } - -+ // Purpur start -+ private javax.script.ScriptEngine scriptEngine = new javax.script.ScriptEngineManager().getEngineByName("rhino"); -+ -+ private boolean unableToSleepRightNow() { -+ if (world.purpurConfig.playerSleepOnlyWithCondition) { -+ try { -+ scriptEngine.eval("time = " + world.getDayTime()); -+ return !(Boolean) scriptEngine.eval(world.purpurConfig.playerSleepCondition); -+ } catch (Exception ignore) { -+ } -+ } -+ return world.isDay(); -+ } -+ // Purpur end -+ - @Override - public void tick() { - this.noclip = this.isSpectator(); -@@ -160,7 +175,7 @@ public abstract class EntityHuman extends EntityLiving { - this.sleepTicks = 100; - } - -- if (!this.world.isClientSide && this.world.isDay()) { -+ if (!this.world.isClientSide && unableToSleepRightNow()) { // Purpur - this.wakeup(false, true); - } - } else if (this.sleepTicks > 0) { -@@ -1334,7 +1349,7 @@ public abstract class EntityHuman extends EntityLiving { - return Either.left(EntityHuman.EnumBedResult.NOT_POSSIBLE_HERE); - } - -- if (this.world.isDay()) { -+ if (unableToSleepRightNow()) { // Purpur - this.setRespawnPosition(blockposition, false, true); - return Either.left(EntityHuman.EnumBedResult.NOT_POSSIBLE_NOW); - } -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 647bece31..08fb0bae3 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -150,6 +150,8 @@ public class PurpurWorldConfig { - public boolean disableDropsOnCrammingDeath = false; - public boolean fixClimbingBypassingCrammingRule = false; - public boolean milkCuresBadOmen = true; -+ public boolean playerSleepOnlyWithCondition = false; -+ public String playerSleepCondition = "time >= 12541 && time <= 23458"; - public boolean useBetterMending = false; - private void gameplayMechanicsSettings() { - boatEjectPlayersOnLand = getBoolean("gameplay-mechanics.boat.eject-players-on-land", boatEjectPlayersOnLand); -@@ -174,6 +176,8 @@ public class PurpurWorldConfig { - disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath); - fixClimbingBypassingCrammingRule = getBoolean("gameplay-mechanics.fix-climbing-bypassing-cramming-rule", fixClimbingBypassingCrammingRule); - milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen); -+ playerSleepOnlyWithCondition = getBoolean("gameplay-mechanics.player.sleep.only-with-condition", playerSleepOnlyWithCondition); -+ playerSleepCondition = getString("gameplay-mechanics.player.sleep.condition", playerSleepCondition); - useBetterMending = getBoolean("gameplay-mechanics.use-better-mending", useBetterMending); - } - --- -2.26.2 - diff --git a/patches/server/0085-Implement-configurable-search-radius-for-villagers-t.patch b/patches/server/0077-Implement-configurable-search-radius-for-villagers-t.patch similarity index 73% rename from patches/server/0085-Implement-configurable-search-radius-for-villagers-t.patch rename to patches/server/0077-Implement-configurable-search-radius-for-villagers-t.patch index 8907487b0..ae43a5b8d 100644 --- a/patches/server/0085-Implement-configurable-search-radius-for-villagers-t.patch +++ b/patches/server/0077-Implement-configurable-search-radius-for-villagers-t.patch @@ -1,4 +1,4 @@ -From fdca75e7798f5c40990ede9e078f8e68587c9530 Mon Sep 17 00:00:00 2001 +From d50f653f50d0cbbaf6f220714631338bfa8732fd Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Mon, 22 Jul 2019 17:32:17 -0500 Subject: [PATCH] Implement configurable search radius for villagers to spawn @@ -10,39 +10,38 @@ Subject: [PATCH] Implement configurable search radius for villagers to spawn 2 files changed, 5 insertions(+) diff --git a/src/main/java/net/minecraft/server/EntityVillager.java b/src/main/java/net/minecraft/server/EntityVillager.java -index e3322fedd..2153b36a3 100644 +index 97eb26482..86de40d15 100644 --- a/src/main/java/net/minecraft/server/EntityVillager.java +++ b/src/main/java/net/minecraft/server/EntityVillager.java -@@ -918,6 +918,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation +@@ -904,6 +904,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation @Nullable - private EntityIronGolem fb() { + private EntityIronGolem fw() { + if (world.purpurConfig.villagerSpawnIronGolemRadius > 0 && world.a(EntityIronGolem.class, getBoundingBox().grow(world.purpurConfig.villagerSpawnIronGolemRadius)).size() > world.purpurConfig.villagerSpawnIronGolemLimit) return null; // Purpur - BlockPosition blockposition = new BlockPosition(this); - int i = 0; + BlockPosition blockposition = this.getChunkCoordinates(); + for (int i = 0; i < 10; ++i) { diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 284054db4..f60c4b629 100644 +index f82288126..224f1e9a0 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -781,6 +781,8 @@ public class PurpurWorldConfig { - public boolean villagerUseBrainTicksOnlyWhenLagging = true; - public boolean villagerFollowEmeraldBlock = false; +@@ -261,12 +261,16 @@ public class PurpurWorldConfig { public boolean villagerCanBeLeashed = false; + public boolean villagerFarmingBypassMobGriefing = false; + public boolean villagerFollowEmeraldBlock = false; + public int villagerSpawnIronGolemRadius = 0; + public int villagerSpawnIronGolemLimit = 0; private void villagerSettings() { - villagerRidable = getBoolean("mobs.villager.ridable", villagerRidable); - villagerRidableInWater = getBoolean("mobs.villager.ridable-in-water", villagerRidableInWater); -@@ -789,6 +791,8 @@ public class PurpurWorldConfig { + villagerBrainTicks = getInt("mobs.villager.brain-ticks", villagerBrainTicks); villagerUseBrainTicksOnlyWhenLagging = getBoolean("mobs.villager.use-brain-ticks-only-when-lagging", villagerUseBrainTicksOnlyWhenLagging); - villagerFollowEmeraldBlock = getBoolean("mobs.villager.follow-emerald-blocks", villagerFollowEmeraldBlock); villagerCanBeLeashed = getBoolean("mobs.villager.can-be-leashed", villagerCanBeLeashed); + villagerFarmingBypassMobGriefing = getBoolean("mobs.villager.bypass-mob-griefing", villagerFarmingBypassMobGriefing); + villagerFollowEmeraldBlock = getBoolean("mobs.villager.follow-emerald-blocks", villagerFollowEmeraldBlock); + villagerSpawnIronGolemRadius = getInt("mobs.villager.spawn-iron-golem.radius", villagerSpawnIronGolemRadius); + villagerSpawnIronGolemLimit = getInt("mobs.villager.spawn-iron-golem.limit", villagerSpawnIronGolemLimit); } - public boolean villagerTraderRidable = false; + public boolean villagerTraderCanBeLeashed = false; -- 2.26.2 diff --git a/patches/server/0074-Implement-infinite-lava.patch b/patches/server/0078-Implement-infinite-lava.patch similarity index 61% rename from patches/server/0074-Implement-infinite-lava.patch rename to patches/server/0078-Implement-infinite-lava.patch index 24b737cd2..3afdc88c2 100644 --- a/patches/server/0074-Implement-infinite-lava.patch +++ b/patches/server/0078-Implement-infinite-lava.patch @@ -1,20 +1,19 @@ -From c4409a74149d47ea97ddf49b1f235070b46c3208 Mon Sep 17 00:00:00 2001 +From 8f7a8f71e03e9518cbb906145f2632db03b87447 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 23 Nov 2019 17:55:42 -0600 Subject: [PATCH] Implement infinite lava --- - .../java/net/minecraft/server/FluidTypeFlowing.java | 10 +++++++++- - src/main/java/net/minecraft/server/FluidTypeLava.java | 7 +++++++ - src/main/java/net/minecraft/server/WorldProvider.java | 2 +- - src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 5 +++++ - 4 files changed, 22 insertions(+), 2 deletions(-) + src/main/java/net/minecraft/server/FluidTypeFlowing.java | 9 ++++++++- + src/main/java/net/minecraft/server/FluidTypeLava.java | 7 +++++++ + src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 5 +++++ + 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/minecraft/server/FluidTypeFlowing.java b/src/main/java/net/minecraft/server/FluidTypeFlowing.java -index 376dca188..1a14fe4a2 100644 +index d72a88e92..e9656641b 100644 --- a/src/main/java/net/minecraft/server/FluidTypeFlowing.java +++ b/src/main/java/net/minecraft/server/FluidTypeFlowing.java -@@ -219,7 +219,7 @@ public abstract class FluidTypeFlowing extends FluidType { +@@ -195,7 +195,7 @@ public abstract class FluidTypeFlowing extends FluidType { } } @@ -23,7 +22,7 @@ index 376dca188..1a14fe4a2 100644 IBlockData iblockdata2 = iworldreader.getType(blockposition.down()); Fluid fluid1 = iblockdata2.getFluid(); -@@ -290,6 +290,14 @@ public abstract class FluidTypeFlowing extends FluidType { +@@ -266,6 +266,13 @@ public abstract class FluidTypeFlowing extends FluidType { return (Fluid) this.e().h().set(FluidTypeFlowing.FALLING, flag); } @@ -34,12 +33,11 @@ index 376dca188..1a14fe4a2 100644 + // Purpur end + + protected boolean infinite() { return f(); } // Purpur - OBFHELPER -+ protected abstract boolean f(); protected void a(GeneratorAccess generatoraccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection, Fluid fluid) { diff --git a/src/main/java/net/minecraft/server/FluidTypeLava.java b/src/main/java/net/minecraft/server/FluidTypeLava.java -index d25368d03..09f82c2d9 100644 +index 29930e801..9e543449c 100644 --- a/src/main/java/net/minecraft/server/FluidTypeLava.java +++ b/src/main/java/net/minecraft/server/FluidTypeLava.java @@ -147,6 +147,13 @@ public abstract class FluidTypeLava extends FluidTypeFlowing { @@ -49,32 +47,19 @@ index d25368d03..09f82c2d9 100644 + // Purpur start + @Override + protected boolean infinite(IWorldReader iworldreader) { -+ return iworldreader.getWorldProvider().getWorld().purpurConfig.lavaInfinite; ++ return iworldreader.getWorldBorder().world.purpurConfig.lavaInfinite; + } + // Purpur end + @Override protected boolean f() { return false; -diff --git a/src/main/java/net/minecraft/server/WorldProvider.java b/src/main/java/net/minecraft/server/WorldProvider.java -index 9eba9a12c..39252e687 100644 ---- a/src/main/java/net/minecraft/server/WorldProvider.java -+++ b/src/main/java/net/minecraft/server/WorldProvider.java -@@ -5,7 +5,7 @@ import javax.annotation.Nullable; - public abstract class WorldProvider { - - public static final float[] a = new float[]{1.0F, 0.75F, 0.5F, 0.25F, 0.0F, 0.25F, 0.5F, 0.75F}; -- protected final World b; -+ protected final World b; public World getWorld() { return b; } // Purpur - OBFHELPER - private final DimensionManager f; - protected boolean c; - protected boolean d; diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 4bb5ddea4..5b042a609 100644 +index 224f1e9a0..01e5253e2 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -127,6 +127,11 @@ public class PurpurWorldConfig { - grindstoneBlacklist.addAll(blacklist); +@@ -138,6 +138,11 @@ public class PurpurWorldConfig { + farmlandGetsMoistFromBelow = getBoolean("blocks.farmland.gets-moist-from-below", farmlandGetsMoistFromBelow); } + public boolean lavaInfinite = false; diff --git a/patches/server/0078-Option-for-hay-block-fall-damage.patch b/patches/server/0078-Option-for-hay-block-fall-damage.patch deleted file mode 100644 index 3c5c387aa..000000000 --- a/patches/server/0078-Option-for-hay-block-fall-damage.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 670ad16925b34ff2bf80abea7613073586291c86 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sat, 30 Nov 2019 01:31:09 -0600 -Subject: [PATCH] Option for hay block fall damage - ---- - src/main/java/net/minecraft/server/BlockHay.java | 2 +- - src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 5 +++++ - 2 files changed, 6 insertions(+), 1 deletion(-) - -diff --git a/src/main/java/net/minecraft/server/BlockHay.java b/src/main/java/net/minecraft/server/BlockHay.java -index ca81c49f0..1f8f60542 100644 ---- a/src/main/java/net/minecraft/server/BlockHay.java -+++ b/src/main/java/net/minecraft/server/BlockHay.java -@@ -9,6 +9,6 @@ public class BlockHay extends BlockRotatable { - - @Override - public void fallOn(World world, BlockPosition blockposition, Entity entity, float f) { -- entity.b(f, 0.2F); -+ entity.b(f, world.purpurConfig.hayBlockFallDamage); // Purpur - } - } -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 08fb0bae3..a4a09874f 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -127,6 +127,11 @@ public class PurpurWorldConfig { - grindstoneBlacklist.addAll(blacklist); - } - -+ public float hayBlockFallDamage = 0.2F; -+ private void hayBlockFallDamage() { -+ hayBlockFallDamage = (float) getDouble("blocks.hay_block.fall-damage", hayBlockFallDamage); -+ } -+ - public boolean lavaInfinite = false; - private void lavaSettings() { - lavaInfinite = getBoolean("blocks.lava.infinite-source", lavaInfinite); --- -2.26.2 - diff --git a/patches/server/0086-Make-lava-flow-speed-configurable.patch b/patches/server/0079-Make-lava-flow-speed-configurable.patch similarity index 56% rename from patches/server/0086-Make-lava-flow-speed-configurable.patch rename to patches/server/0079-Make-lava-flow-speed-configurable.patch index 8b2eadab0..61ff95d9c 100644 --- a/patches/server/0086-Make-lava-flow-speed-configurable.patch +++ b/patches/server/0079-Make-lava-flow-speed-configurable.patch @@ -1,44 +1,31 @@ -From e1fc4760dc7cf41b2258c1351cad5246f733429b Mon Sep 17 00:00:00 2001 +From a55981acf82a6eb09645fe19574b2752bc306d3d Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Thu, 2 Jan 2020 11:31:36 -0600 Subject: [PATCH] Make lava flow speed configurable --- src/main/java/net/minecraft/server/FluidTypeLava.java | 2 +- - src/main/java/net/minecraft/server/WorldProvider.java | 1 + src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 4 ++++ - 3 files changed, 6 insertions(+), 1 deletion(-) + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/minecraft/server/FluidTypeLava.java b/src/main/java/net/minecraft/server/FluidTypeLava.java -index 09f82c2d9..470e9bfd0 100644 +index 9e543449c..fb501a6c5 100644 --- a/src/main/java/net/minecraft/server/FluidTypeLava.java +++ b/src/main/java/net/minecraft/server/FluidTypeLava.java @@ -129,7 +129,7 @@ public abstract class FluidTypeLava extends FluidTypeFlowing { @Override public int a(IWorldReader iworldreader) { -- return iworldreader.getWorldProvider().g() ? 10 : 30; -+ return iworldreader.getWorldProvider().isHell() ? iworldreader.getWorldProvider().getWorld().purpurConfig.lavaSpeedNether : iworldreader.getWorldProvider().getWorld().purpurConfig.lavaSpeedNotNether; // Purpur +- return iworldreader.getDimensionManager().isNether() ? 10 : 30; ++ return iworldreader.getDimensionManager().isNether() ? iworldreader.getWorldBorder().world.purpurConfig.lavaSpeedNether : iworldreader.getWorldBorder().world.purpurConfig.lavaSpeedNotNether; // Purpur } @Override -diff --git a/src/main/java/net/minecraft/server/WorldProvider.java b/src/main/java/net/minecraft/server/WorldProvider.java -index 39252e687..75f8441ab 100644 ---- a/src/main/java/net/minecraft/server/WorldProvider.java -+++ b/src/main/java/net/minecraft/server/WorldProvider.java -@@ -42,6 +42,7 @@ public abstract class WorldProvider { - return this.f.hasSkyLight(); - } - -+ public boolean isHell() { return g(); } // Purpur - OBFHELPER - public boolean g() { - return this.d; - } diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index f60c4b629..c238607ac 100644 +index 01e5253e2..a053ac84c 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -133,8 +133,12 @@ public class PurpurWorldConfig { +@@ -139,8 +139,12 @@ public class PurpurWorldConfig { } public boolean lavaInfinite = false; diff --git a/patches/server/0080-Add-LootableInventoryFirstFillEvent.patch b/patches/server/0080-Add-LootableInventoryFirstFillEvent.patch deleted file mode 100644 index 646548f00..000000000 --- a/patches/server/0080-Add-LootableInventoryFirstFillEvent.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 5cb92f4ecb97c800374f4c632b3f3c371241a0c9 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sat, 19 Oct 2019 02:43:17 -0500 -Subject: [PATCH] Add LootableInventoryFirstFillEvent - ---- - .../paper/loottable/PaperLootableInventoryData.java | 4 ++++ - .../paper/loottable/PaperTileEntityLootableInventory.java | 5 ++++- - 2 files changed, 8 insertions(+), 1 deletion(-) - -diff --git a/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java -index b5401eaf9..1decf0e89 100644 ---- a/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java -+++ b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java -@@ -49,6 +49,10 @@ public class PaperLootableInventoryData { - - // ALWAYS process the first fill or if the feature is disabled - if (this.lastFill == -1 || !this.lootable.getNMSWorld().paperConfig.autoReplenishLootables) { -+ // Purpur start -+ LootableInventory inventory = lootable.getAPILootableInventory(); -+ if (inventory != null) new net.pl3x.purpur.event.block.LootableInventoryFirstFillEvent(player == null ? null : (Player) player.getBukkitEntity(), inventory).callEvent(); -+ // Purpur end - return true; - } - -diff --git a/src/main/java/com/destroystokyo/paper/loottable/PaperTileEntityLootableInventory.java b/src/main/java/com/destroystokyo/paper/loottable/PaperTileEntityLootableInventory.java -index d50410532..2f24e5a70 100644 ---- a/src/main/java/com/destroystokyo/paper/loottable/PaperTileEntityLootableInventory.java -+++ b/src/main/java/com/destroystokyo/paper/loottable/PaperTileEntityLootableInventory.java -@@ -57,7 +57,10 @@ public class PaperTileEntityLootableInventory implements PaperLootableBlockInven - if (world == null) { - return null; - } -- return (LootableInventory) getBukkitWorld().getBlockAt(MCUtil.toLocation(world, tileEntityLootable.getPosition())).getState(); -+ // Purpur start -+ org.bukkit.block.BlockState state = getBukkitWorld().getBlockAt(MCUtil.toLocation(world, tileEntityLootable.getPosition())).getState(); -+ return state instanceof LootableInventory ? (LootableInventory) state : null; -+ // Purpur end - } - - @Override --- -2.26.2 - diff --git a/patches/server/0082-Add-player-death-exp-control-options.patch b/patches/server/0080-Add-player-death-exp-control-options.patch similarity index 55% rename from patches/server/0082-Add-player-death-exp-control-options.patch rename to patches/server/0080-Add-player-death-exp-control-options.patch index f685f41fb..0606aa9a3 100644 --- a/patches/server/0082-Add-player-death-exp-control-options.patch +++ b/patches/server/0080-Add-player-death-exp-control-options.patch @@ -1,18 +1,27 @@ -From 1cb56387d6a23b9496102a3022d2ad9ee58280da Mon Sep 17 00:00:00 2001 +From 7197feebf806f4be952a0d70efc4b3bd6bcb1493 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Thu, 26 Dec 2019 22:08:37 -0600 Subject: [PATCH] Add player death exp control options --- - .../java/net/minecraft/server/EntityHuman.java | 15 ++++++++++++--- - .../java/net/pl3x/purpur/PurpurWorldConfig.java | 4 ++++ - 2 files changed, 16 insertions(+), 3 deletions(-) + .../java/net/minecraft/server/EntityHuman.java | 17 ++++++++++++++--- + .../java/net/pl3x/purpur/PurpurWorldConfig.java | 7 +++++++ + 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java -index 22e17e3de..14b57d678 100644 +index a69a69859..ea4144371 100644 --- a/src/main/java/net/minecraft/server/EntityHuman.java +++ b/src/main/java/net/minecraft/server/EntityHuman.java -@@ -1862,9 +1862,18 @@ public abstract class EntityHuman extends EntityLiving { +@@ -85,6 +85,8 @@ public abstract class EntityHuman extends EntityLiving { + // CraftBukkit end + + // Purpur start ++ private javax.script.ScriptEngine scriptEngine = new javax.script.ScriptEngineManager().getEngineByName("rhino"); ++ + public void setAfk(boolean setAfk){ + } + +@@ -1713,9 +1715,18 @@ public abstract class EntityHuman extends EntityLiving { @Override protected int getExpValue(EntityHuman entityhuman) { if (!this.world.getGameRules().getBoolean(GameRules.KEEP_INVENTORY) && !this.isSpectator()) { @@ -35,27 +44,23 @@ index 22e17e3de..14b57d678 100644 return 0; } diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 7d2c51a2f..caf7f0e84 100644 +index a053ac84c..54208a018 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -155,6 +155,8 @@ public class PurpurWorldConfig { - public boolean disableDropsOnCrammingDeath = false; - public boolean fixClimbingBypassingCrammingRule = false; - public boolean milkCuresBadOmen = true; +@@ -126,6 +126,13 @@ public class PurpurWorldConfig { + tridentLoyaltyVoidReturnHeight = getDouble("gameplay-mechanics.trident-loyalty-void-return-height", tridentLoyaltyVoidReturnHeight); + } + + public String playerDeathExpDropEquation = "expLevel * 7"; + public int playerDeathExpDropMax = 100; - public boolean playerSleepOnlyWithCondition = false; - public String playerSleepCondition = "time >= 12541 && time <= 23458"; - public boolean useBetterMending = false; -@@ -181,6 +183,8 @@ public class PurpurWorldConfig { - disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath); - fixClimbingBypassingCrammingRule = getBoolean("gameplay-mechanics.fix-climbing-bypassing-cramming-rule", fixClimbingBypassingCrammingRule); - milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen); ++ private void playerDeathExpSettings() { + playerDeathExpDropEquation = getString("gameplay-mechanics.player.exp-dropped-on-death.equation", playerDeathExpDropEquation); + playerDeathExpDropMax = getInt("gameplay-mechanics.player.exp-dropped-on-death.maximum", playerDeathExpDropMax); - playerSleepOnlyWithCondition = getBoolean("gameplay-mechanics.player.sleep.only-with-condition", playerSleepOnlyWithCondition); - playerSleepCondition = getString("gameplay-mechanics.player.sleep.condition", playerSleepCondition); - useBetterMending = getBoolean("gameplay-mechanics.use-better-mending", useBetterMending); ++ } ++ + public int playerSpawnInvulnerableTicks = 60; + public boolean playerInvulnerableWhileAcceptingResourcePack = false; + private void playerInvulnerabilities() { -- 2.26.2 diff --git a/patches/server/0081-Add-option-to-disable-saving-projectiles-to-disk.patch b/patches/server/0081-Add-option-to-disable-saving-projectiles-to-disk.patch new file mode 100644 index 000000000..baab13ace --- /dev/null +++ b/patches/server/0081-Add-option-to-disable-saving-projectiles-to-disk.patch @@ -0,0 +1,103 @@ +From 9282eae4be5cd0125c1e71e4038064cf433c7596 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Tue, 18 Feb 2020 20:07:08 -0600 +Subject: [PATCH] Add option to disable saving projectiles to disk + +--- + .../java/net/minecraft/server/ChunkRegionLoader.java | 1 + + src/main/java/net/minecraft/server/Entity.java | 6 ++++++ + .../java/net/minecraft/server/EntityEnderSignal.java | 9 ++++++++- + src/main/java/net/minecraft/server/IProjectile.java | 7 +++++++ + src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 2 ++ + 5 files changed, 24 insertions(+), 1 deletion(-) + +diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java +index ac58fcb79..0041027ec 100644 +--- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java ++++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java +@@ -467,6 +467,7 @@ public class ChunkRegionLoader { + + while (iterator1.hasNext()) { + Entity entity = (Entity) iterator1.next(); ++ if (!entity.canSaveToDisk()) continue; // Purpur + NBTTagCompound nbttagcompound4 = new NBTTagCompound(); + // Paper start + if (asyncsavedata == null && !entity.dead && (int) Math.floor(entity.locX()) >> 4 != chunk.getPos().x || (int) Math.floor(entity.locZ()) >> 4 != chunk.getPos().z) { +diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java +index a219443b3..35edfaa15 100644 +--- a/src/main/java/net/minecraft/server/Entity.java ++++ b/src/main/java/net/minecraft/server/Entity.java +@@ -303,6 +303,12 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke + this.headHeight = this.getHeadHeight(EntityPose.STANDING, this.size); + } + ++ // Purpur start ++ public boolean canSaveToDisk() { ++ return true; ++ } ++ // Purpur end ++ + public boolean isSpectator() { + return false; + } +diff --git a/src/main/java/net/minecraft/server/EntityEnderSignal.java b/src/main/java/net/minecraft/server/EntityEnderSignal.java +index 84bf27299..82a5aaf5b 100644 +--- a/src/main/java/net/minecraft/server/EntityEnderSignal.java ++++ b/src/main/java/net/minecraft/server/EntityEnderSignal.java +@@ -19,9 +19,16 @@ public class EntityEnderSignal extends Entity { + this.setPosition(d0, d1, d2); + } + ++ // Purpur start ++ @Override ++ public boolean canSaveToDisk() { ++ return world != null && world.purpurConfig.saveProjectilesToDisk; ++ } ++ // Purpur end ++ + public void b(ItemStack itemstack) { + if (itemstack.getItem() != Items.ENDER_EYE || itemstack.hasTag()) { +- this.getDataWatcher().set(EntityEnderSignal.b, SystemUtils.a((Object) itemstack.cloneItemStack(), (itemstack1) -> { ++ this.getDataWatcher().set(EntityEnderSignal.b, SystemUtils.a(itemstack.cloneItemStack(), (itemstack1) -> { // Purpur - decompile error + itemstack1.setCount(1); + })); + } +diff --git a/src/main/java/net/minecraft/server/IProjectile.java b/src/main/java/net/minecraft/server/IProjectile.java +index a961f5d5d..c5d788f22 100644 +--- a/src/main/java/net/minecraft/server/IProjectile.java ++++ b/src/main/java/net/minecraft/server/IProjectile.java +@@ -18,6 +18,13 @@ public abstract class IProjectile extends Entity { + super(entitytypes, world); + } + ++ // Purpur start ++ @Override ++ public boolean canSaveToDisk() { ++ return world != null && world.purpurConfig.saveProjectilesToDisk; ++ } ++ // Purpur end ++ + public void setShooter(@Nullable Entity entity) { + if (entity != null) { + this.shooter = entity.getUniqueID(); +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index 54208a018..551d0ae31 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -118,11 +118,13 @@ public class PurpurWorldConfig { + public boolean disableDropsOnCrammingDeath = false; + public boolean entitiesPickUpLootBypassMobGriefing = false; + public boolean milkCuresBadOmen = true; ++ public boolean saveProjectilesToDisk = true; + public double tridentLoyaltyVoidReturnHeight = 0.0D; + private void miscGameplayMechanicsSettings() { + disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath); + entitiesPickUpLootBypassMobGriefing = getBoolean("gameplay-mechanics.entities-pick-up-loot-bypass-mob-griefing", entitiesPickUpLootBypassMobGriefing); + milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen); ++ saveProjectilesToDisk = getBoolean("gameplay-mechanics.save-projectiles-to-disk", saveProjectilesToDisk); + tridentLoyaltyVoidReturnHeight = getDouble("gameplay-mechanics.trident-loyalty-void-return-height", tridentLoyaltyVoidReturnHeight); + } + +-- +2.26.2 + diff --git a/patches/server/0082-Configurable-void-damage-height.patch b/patches/server/0082-Configurable-void-damage-height.patch new file mode 100644 index 000000000..d54cc8fb5 --- /dev/null +++ b/patches/server/0082-Configurable-void-damage-height.patch @@ -0,0 +1,45 @@ +From 58399a97e089d56caecfb268af8d625cf188f27e Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Thu, 27 Feb 2020 21:42:19 -0600 +Subject: [PATCH] Configurable void damage height + +--- + src/main/java/net/minecraft/server/Entity.java | 2 +- + src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 2 ++ + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java +index 35edfaa15..dca384ea2 100644 +--- a/src/main/java/net/minecraft/server/Entity.java ++++ b/src/main/java/net/minecraft/server/Entity.java +@@ -526,7 +526,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke + + // Paper start + protected void performVoidDamage() { +- if (this.locY() < -64.0D || (this.world.getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER ++ if (this.locY() < world.purpurConfig.voidDamageHeight || (this.world.getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER // Purpur + && world.paperConfig.doNetherTopVoidDamage() + && this.locY() >= world.paperConfig.netherVoidTopDamageHeight)) { + +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index 551d0ae31..b51b00014 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -120,12 +120,14 @@ public class PurpurWorldConfig { + public boolean milkCuresBadOmen = true; + public boolean saveProjectilesToDisk = true; + public double tridentLoyaltyVoidReturnHeight = 0.0D; ++ public double voidDamageHeight = -64.0D; + private void miscGameplayMechanicsSettings() { + disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath); + entitiesPickUpLootBypassMobGriefing = getBoolean("gameplay-mechanics.entities-pick-up-loot-bypass-mob-griefing", entitiesPickUpLootBypassMobGriefing); + milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen); + saveProjectilesToDisk = getBoolean("gameplay-mechanics.save-projectiles-to-disk", saveProjectilesToDisk); + tridentLoyaltyVoidReturnHeight = getDouble("gameplay-mechanics.trident-loyalty-void-return-height", tridentLoyaltyVoidReturnHeight); ++ voidDamageHeight = getDouble("gameplay-mechanics.void-damage-height", voidDamageHeight); + } + + public String playerDeathExpDropEquation = "expLevel * 7"; +-- +2.26.2 + diff --git a/patches/server/0051-Add-option-for-zombies-targetting-turtle-eggs.patch b/patches/server/0083-Add-option-for-zombies-targetting-turtle-eggs.patch similarity index 54% rename from patches/server/0051-Add-option-for-zombies-targetting-turtle-eggs.patch rename to patches/server/0083-Add-option-for-zombies-targetting-turtle-eggs.patch index e7b36c347..ec6c3c850 100644 --- a/patches/server/0051-Add-option-for-zombies-targetting-turtle-eggs.patch +++ b/patches/server/0083-Add-option-for-zombies-targetting-turtle-eggs.patch @@ -1,43 +1,42 @@ -From 89e2ea5817f0cde07833d0f18aecc3fe3ff51a3b Mon Sep 17 00:00:00 2001 +From 58e263369c31fa15ebbd365150e7a40e948b595c Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 17 Aug 2019 15:27:09 -0500 Subject: [PATCH] Add option for zombies targetting turtle eggs --- src/main/java/net/minecraft/server/EntityZombie.java | 2 +- - src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 2 ++ - 2 files changed, 3 insertions(+), 1 deletion(-) + src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 5 +++++ + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/minecraft/server/EntityZombie.java b/src/main/java/net/minecraft/server/EntityZombie.java -index 8d1f04415..95ae6f349 100644 +index ad8b1f0e4..7182c0ead 100644 --- a/src/main/java/net/minecraft/server/EntityZombie.java +++ b/src/main/java/net/minecraft/server/EntityZombie.java -@@ -64,7 +64,7 @@ public class EntityZombie extends EntityMonster { +@@ -46,7 +46,7 @@ public class EntityZombie extends EntityMonster { + @Override protected void initPathfinder() { - this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(4, new EntityZombie.a(this, 1.0D, 3)); + if (world.purpurConfig.zombieTargetTurtleEggs) this.goalSelector.a(4, new EntityZombie.a(this, 1.0D, 3)); // Purpur this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); - this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur + this.m(); diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index f1ed653b3..114cd3f80 100644 +index b51b00014..b6fc0c04e 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -806,10 +806,12 @@ public class PurpurWorldConfig { - public boolean zombieRidable = false; - public boolean zombieRidableInWater = false; - public boolean zombieRequireShiftToMount = true; -+ public boolean zombieTargetTurtleEggs = true; - private void zombieSettings() { - zombieRidable = getBoolean("mobs.zombie.ridable", zombieRidable); - zombieRidableInWater = getBoolean("mobs.zombie.ridable-in-water", zombieRidableInWater); - zombieRequireShiftToMount = getBoolean("mobs.zombie.require-shift-to-mount", zombieRequireShiftToMount); -+ zombieTargetTurtleEggs = getBoolean("mobs.zombie.target-turtle-eggs", zombieTargetTurtleEggs); +@@ -305,6 +305,11 @@ public class PurpurWorldConfig { + witherSkeletonTakesWitherDamage = getBoolean("mobs.wither_skeleton.takes-wither-damage", witherSkeletonTakesWitherDamage); } - public boolean zombieHorseCanSwim = false; ++ public boolean zombieTargetTurtleEggs = true; ++ private void zombieSettings() { ++ zombieTargetTurtleEggs = getBoolean("mobs.zombie.target-turtle-eggs", zombieTargetTurtleEggs); ++ } ++ + public double zombieHorseSpawnChance = 0.0D; + private void zombieHorseSettings() { + zombieHorseSpawnChance = getDouble("mobs.zombie_horse.spawn-chance", zombieHorseSpawnChance); -- 2.26.2 diff --git a/patches/server/0056-Dispenser-curse-of-binding-protection.patch b/patches/server/0084-Dispenser-curse-of-binding-protection.patch similarity index 75% rename from patches/server/0056-Dispenser-curse-of-binding-protection.patch rename to patches/server/0084-Dispenser-curse-of-binding-protection.patch index 83730b733..41648f6e7 100644 --- a/patches/server/0056-Dispenser-curse-of-binding-protection.patch +++ b/patches/server/0084-Dispenser-curse-of-binding-protection.patch @@ -1,4 +1,4 @@ -From dd5ff2d86f41eba0265941c0834215f86d9b9606 Mon Sep 17 00:00:00 2001 +From 59a413ca970256d86c354a148e96f31c124c73da Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 25 Aug 2019 00:09:52 -0500 Subject: [PATCH] Dispenser curse of binding protection @@ -10,10 +10,10 @@ Subject: [PATCH] Dispenser curse of binding protection 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java -index fbca42909..bf9d044b0 100644 +index 744552fda..8def5fbfb 100644 --- a/src/main/java/net/minecraft/server/EntityInsentient.java +++ b/src/main/java/net/minecraft/server/EntityInsentient.java -@@ -913,6 +913,13 @@ public abstract class EntityInsentient extends EntityLiving { +@@ -985,6 +985,13 @@ public abstract class EntityInsentient extends EntityLiving { } @@ -23,25 +23,25 @@ index fbca42909..bf9d044b0 100644 + } + // Purpur end + -+ public static EnumItemSlot getSlotForItemStack(ItemStack itemstack) { return h(itemstack); } // Purpur - OBFHELPER - public static EnumItemSlot h(ItemStack itemstack) { ++ public static EnumItemSlot getSlotForItemStack(ItemStack itemstack) { return j(itemstack); } // Purpur - OBFHELPER + public static EnumItemSlot j(ItemStack itemstack) { Item item = itemstack.getItem(); diff --git a/src/main/java/net/minecraft/server/ItemArmor.java b/src/main/java/net/minecraft/server/ItemArmor.java -index df8c42bfb..a4b3d0c29 100644 +index 885458d54..c7d67d729 100644 --- a/src/main/java/net/minecraft/server/ItemArmor.java +++ b/src/main/java/net/minecraft/server/ItemArmor.java -@@ -31,7 +31,7 @@ public class ItemArmor extends Item { +@@ -35,7 +35,7 @@ public class ItemArmor extends Item implements ItemWearable { return false; } else { EntityLiving entityliving = (EntityLiving) list.get(0); -- EnumItemSlot enumitemslot = EntityInsentient.h(itemstack); +- EnumItemSlot enumitemslot = EntityInsentient.j(itemstack); + EnumItemSlot enumitemslot = isourceblock.getWorld().purpurConfig.dispenserApplyCursedArmor ? EntityInsentient.getSlotForItemStack(itemstack) : EntityInsentient.getSlotForDispenser(itemstack); // Purpur ItemStack itemstack1 = itemstack.cloneAndSubtract(1); // CraftBukkit start World world = isourceblock.getWorld(); -@@ -79,6 +79,7 @@ public class ItemArmor extends Item { - BlockDispenser.a((IMaterial) this, ItemArmor.a); +@@ -94,6 +94,7 @@ public class ItemArmor extends Item implements ItemWearable { + this.m = builder.build(); } + public EnumItemSlot getEquipmentSlot() { return b(); } // Purpur - OBFHELPER @@ -49,11 +49,11 @@ index df8c42bfb..a4b3d0c29 100644 return this.b; } diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 1a2512b52..b8754ba2d 100644 +index b6fc0c04e..3deb3b8e3 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -106,6 +106,11 @@ public class PurpurWorldConfig { - campfireFallWithGravity = getBoolean("blocks.campfire.fall-with-gravity", campfireFallWithGravity); +@@ -144,6 +144,11 @@ public class PurpurWorldConfig { + playerInvulnerableWhileAcceptingResourcePack = getBoolean("gameplay-mechanics.player.invulnerable-while-accepting-resource-pack", playerInvulnerableWhileAcceptingResourcePack); } + public boolean dispenserApplyCursedArmor = true; diff --git a/patches/server/0058-Add-option-for-boats-to-eject-players-on-land.patch b/patches/server/0085-Add-option-for-boats-to-eject-players-on-land.patch similarity index 53% rename from patches/server/0058-Add-option-for-boats-to-eject-players-on-land.patch rename to patches/server/0085-Add-option-for-boats-to-eject-players-on-land.patch index 5e0cfd5db..12f469a3f 100644 --- a/patches/server/0058-Add-option-for-boats-to-eject-players-on-land.patch +++ b/patches/server/0085-Add-option-for-boats-to-eject-players-on-land.patch @@ -1,4 +1,4 @@ -From c42c2b9207be73a2feed8fa32b321cc9a1ffc1ce Mon Sep 17 00:00:00 2001 +From b98930c63332989ba65c906fa2a7ac85e255034d Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 7 Sep 2019 22:47:59 -0500 Subject: [PATCH] Add option for boats to eject players on land @@ -9,37 +9,37 @@ Subject: [PATCH] Add option for boats to eject players on land 2 files changed, 3 insertions(+) diff --git a/src/main/java/net/minecraft/server/EntityBoat.java b/src/main/java/net/minecraft/server/EntityBoat.java -index 563fc8ced..479ed7c7b 100644 +index 409e0ac0a..a20d6feb8 100644 --- a/src/main/java/net/minecraft/server/EntityBoat.java +++ b/src/main/java/net/minecraft/server/EntityBoat.java -@@ -431,6 +431,7 @@ public class EntityBoat extends Entity { +@@ -433,6 +433,7 @@ public class EntityBoat extends Entity { if (f > 0.0F) { - this.aE = f; + this.aD = f; + if (world.purpurConfig.boatEjectPlayersOnLand) ejectPassengers(); // Purpur return EntityBoat.EnumStatus.ON_LAND; } else { return EntityBoat.EnumStatus.IN_AIR; diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index b8754ba2d..2271d13f1 100644 +index 3deb3b8e3..99235e56e 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -134,6 +134,7 @@ public class PurpurWorldConfig { - signRightClickEdit = getBoolean("blocks.sign.right-click-edit", signRightClickEdit); +@@ -115,6 +115,7 @@ public class PurpurWorldConfig { + idleTimeoutUpdateTabList = getBoolean("gameplay-mechanics.player.idle-timeout.update-tab-list", idleTimeoutUpdateTabList); } + public boolean boatEjectPlayersOnLand = false; - public boolean controllableMinecarts = false; - public boolean controllableMinecartsPlaceAnywhere = false; - public float controllableMinecartsStepHeight = 1.0F; -@@ -145,6 +146,7 @@ public class PurpurWorldConfig { + public boolean disableDropsOnCrammingDeath = false; + public boolean entitiesPickUpLootBypassMobGriefing = false; public boolean milkCuresBadOmen = true; - public boolean useBetterMending = false; - private void gameplayMechanicsSettings() { +@@ -122,6 +123,7 @@ public class PurpurWorldConfig { + public double tridentLoyaltyVoidReturnHeight = 0.0D; + public double voidDamageHeight = -64.0D; + private void miscGameplayMechanicsSettings() { + boatEjectPlayersOnLand = getBoolean("gameplay-mechanics.boat.eject-players-on-land", boatEjectPlayersOnLand); - controllableMinecarts = getBoolean("gameplay-mechanics.controllable-minecarts.enabled", controllableMinecarts); - controllableMinecartsPlaceAnywhere = getBoolean("gameplay-mechanics.controllable-minecarts.place-anywhere", controllableMinecartsPlaceAnywhere); - controllableMinecartsStepHeight = (float) getDouble("gameplay-mechanics.controllable-minecarts.step-height", controllableMinecartsStepHeight); + disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath); + entitiesPickUpLootBypassMobGriefing = getBoolean("gameplay-mechanics.entities-pick-up-loot-bypass-mob-griefing", entitiesPickUpLootBypassMobGriefing); + milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen); -- 2.26.2 diff --git a/patches/server/0086-Add-obfhelpers-for-plugin-use.patch b/patches/server/0086-Add-obfhelpers-for-plugin-use.patch new file mode 100644 index 000000000..2be872db5 --- /dev/null +++ b/patches/server/0086-Add-obfhelpers-for-plugin-use.patch @@ -0,0 +1,37 @@ +From 6a57aa27852f1b9af9b4794172996ba6e0c6ef50 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Wed, 1 Jan 2020 20:12:39 -0600 +Subject: [PATCH] Add obfhelpers for plugin use + +--- + src/main/java/net/minecraft/server/ItemStack.java | 1 + + src/main/java/net/minecraft/server/NBTTagString.java | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java +index 2b2d914de..c2e57a976 100644 +--- a/src/main/java/net/minecraft/server/ItemStack.java ++++ b/src/main/java/net/minecraft/server/ItemStack.java +@@ -605,6 +605,7 @@ public final class ItemStack { + return this.tag; + } + ++ public NBTTagCompound getOrCreateSubTag(String s) { return a(s); } // Purpur - OBFHELPER + public NBTTagCompound a(String s) { + if (this.tag != null && this.tag.hasKeyOfType(s, 10)) { + return this.tag.getCompound(s); +diff --git a/src/main/java/net/minecraft/server/NBTTagString.java b/src/main/java/net/minecraft/server/NBTTagString.java +index 7ef237831..44121316c 100644 +--- a/src/main/java/net/minecraft/server/NBTTagString.java ++++ b/src/main/java/net/minecraft/server/NBTTagString.java +@@ -40,6 +40,7 @@ public class NBTTagString implements NBTBase { + this.data = s; + } + ++ public static NBTTagString create(String s) { return a(s); } // Purpur - OBFHELPER + public static NBTTagString a(String s) { + return s.isEmpty() ? NBTTagString.b : new NBTTagString(s); + } +-- +2.26.2 + diff --git a/patches/server/0041-Mending-mends-most-damages-equipment-first.patch b/patches/server/0087-Mending-mends-most-damages-equipment-first.patch similarity index 74% rename from patches/server/0041-Mending-mends-most-damages-equipment-first.patch rename to patches/server/0087-Mending-mends-most-damages-equipment-first.patch index a8e309589..19561fa13 100644 --- a/patches/server/0041-Mending-mends-most-damages-equipment-first.patch +++ b/patches/server/0087-Mending-mends-most-damages-equipment-first.patch @@ -1,20 +1,20 @@ -From 0b0660101e3557de12bb44ca705c1d736861c7f6 Mon Sep 17 00:00:00 2001 +From 56d87207ff10970b820cc21e05f8e5f566965b62 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 14 Jul 2019 19:52:47 -0500 Subject: [PATCH] Mending mends most damages equipment first --- - .../minecraft/server/EnchantmentManager.java | 25 ++++++++++++++++++- + .../minecraft/server/EnchantmentManager.java | 26 ++++++++++++++++++- .../minecraft/server/EntityExperienceOrb.java | 2 +- .../java/net/minecraft/server/ItemStack.java | 9 +++++++ .../net/pl3x/purpur/PurpurWorldConfig.java | 2 ++ - 4 files changed, 36 insertions(+), 2 deletions(-) + 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/minecraft/server/EnchantmentManager.java b/src/main/java/net/minecraft/server/EnchantmentManager.java -index d96c03a1a..da1cfc1d3 100644 +index 92ceb8bb7..1acfea287 100644 --- a/src/main/java/net/minecraft/server/EnchantmentManager.java +++ b/src/main/java/net/minecraft/server/EnchantmentManager.java -@@ -246,9 +246,32 @@ public class EnchantmentManager { +@@ -251,9 +251,33 @@ public class EnchantmentManager { return getEnchantmentLevel(Enchantments.CHANNELING, itemstack) > 0; } @@ -45,27 +45,28 @@ index d96c03a1a..da1cfc1d3 100644 public static @javax.annotation.Nonnull ItemStack getRandomEquippedItemWithEnchant(Enchantment enchantment, EntityLiving entityliving) { - Entry entry = b(enchantment, entityliving); + Entry entry = enchantment == Enchantments.MENDING && entityliving.world.purpurConfig.useBetterMending ? getMostDamagedEquipment(enchantment, entityliving) : b(enchantment, entityliving); // Purpur ++ return entry != null ? entry.getValue() : ItemStack.NULL_ITEM; } @Nullable diff --git a/src/main/java/net/minecraft/server/EntityExperienceOrb.java b/src/main/java/net/minecraft/server/EntityExperienceOrb.java -index 53c6c3389..0fae3693c 100644 +index 2396b4d6f..0124fa547 100644 --- a/src/main/java/net/minecraft/server/EntityExperienceOrb.java +++ b/src/main/java/net/minecraft/server/EntityExperienceOrb.java -@@ -225,7 +225,7 @@ public class EntityExperienceOrb extends Entity { - if (this.d == 0 && entityhuman.bC == 0 && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(((EntityPlayer) entityhuman).getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) { // Paper - entityhuman.bC = 2; +@@ -220,7 +220,7 @@ public class EntityExperienceOrb extends Entity { + if (this.d == 0 && entityhuman.bB == 0 && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(((EntityPlayer) entityhuman).getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) { // Paper + entityhuman.bB = 2; entityhuman.receive(this, 1); -- Entry entry = EnchantmentManager.b(Enchantments.MENDING, (EntityLiving) entityhuman); -+ Entry entry = world.purpurConfig.useBetterMending ? EnchantmentManager.getMostDamagedEquipment(Enchantments.MENDING, entityhuman) : EnchantmentManager.b(Enchantments.MENDING, entityhuman); // Purpur +- Entry entry = EnchantmentManager.a(Enchantments.MENDING, (EntityLiving) entityhuman, ItemStack::f); ++ Entry entry = world.purpurConfig.useBetterMending ? EnchantmentManager.getMostDamagedEquipment(Enchantments.MENDING, entityhuman) : EnchantmentManager.a(Enchantments.MENDING, entityhuman, ItemStack::isDamaged); // Purpur if (entry != null) { ItemStack itemstack = (ItemStack) entry.getValue(); diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java -index 413b888a0..ce6a46685 100644 +index c2e57a976..51e70db21 100644 --- a/src/main/java/net/minecraft/server/ItemStack.java +++ b/src/main/java/net/minecraft/server/ItemStack.java -@@ -370,10 +370,19 @@ public final class ItemStack { +@@ -379,10 +379,19 @@ public final class ItemStack { } } @@ -86,25 +87,25 @@ index 413b888a0..ce6a46685 100644 return this.tag == null ? 0 : this.tag.getInt("Damage"); } diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 7cbb1df7a..b76a8c5be 100644 +index 99235e56e..abfa1d79b 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -118,6 +118,7 @@ public class PurpurWorldConfig { - public Map controllableMinecartsBlockSpeeds = new HashMap<>(); - public boolean disableDropsOnCrammingDeath = false; - public boolean milkCuresBadOmen = true; -+ public boolean useBetterMending = false; - private void gameplayMechanicsSettings() { - controllableMinecarts = getBoolean("gameplay-mechanics.controllable-minecarts.enabled", controllableMinecarts); - controllableMinecartsPlaceAnywhere = getBoolean("gameplay-mechanics.controllable-minecarts.place-anywhere", controllableMinecartsPlaceAnywhere); -@@ -138,6 +139,7 @@ public class PurpurWorldConfig { - } - disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath); - milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen); -+ useBetterMending = getBoolean("gameplay-mechanics.use-better-mending", useBetterMending); +@@ -115,6 +115,7 @@ public class PurpurWorldConfig { + idleTimeoutUpdateTabList = getBoolean("gameplay-mechanics.player.idle-timeout.update-tab-list", idleTimeoutUpdateTabList); } - public boolean idleTimeoutKick = true; ++ public boolean useBetterMending = false; + public boolean boatEjectPlayersOnLand = false; + public boolean disableDropsOnCrammingDeath = false; + public boolean entitiesPickUpLootBypassMobGriefing = false; +@@ -123,6 +124,7 @@ public class PurpurWorldConfig { + public double tridentLoyaltyVoidReturnHeight = 0.0D; + public double voidDamageHeight = -64.0D; + private void miscGameplayMechanicsSettings() { ++ useBetterMending = getBoolean("gameplay-mechanics.use-better-mending", useBetterMending); + boatEjectPlayersOnLand = getBoolean("gameplay-mechanics.boat.eject-players-on-land", boatEjectPlayersOnLand); + disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath); + entitiesPickUpLootBypassMobGriefing = getBoolean("gameplay-mechanics.entities-pick-up-loot-bypass-mob-griefing", entitiesPickUpLootBypassMobGriefing); -- 2.26.2 diff --git a/patches/server/0052-Implement-bamboo-growth-settings.patch b/patches/server/0088-Implement-bamboo-growth-settings.patch similarity index 58% rename from patches/server/0052-Implement-bamboo-growth-settings.patch rename to patches/server/0088-Implement-bamboo-growth-settings.patch index d3b670a59..6494c7377 100644 --- a/patches/server/0052-Implement-bamboo-growth-settings.patch +++ b/patches/server/0088-Implement-bamboo-growth-settings.patch @@ -1,27 +1,18 @@ -From 1a9676ebff9a4a1dc9b6127c2adff3d42f1dbcad Mon Sep 17 00:00:00 2001 +From b5225a87d8287f91f4e06ce13c54f98cb0118c78 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Fri, 23 Aug 2019 20:57:29 -0500 Subject: [PATCH] Implement bamboo growth settings --- - .../java/net/minecraft/server/BlockBamboo.java | 14 +++++++------- - .../java/net/pl3x/purpur/PurpurWorldConfig.java | 7 +++++++ - 2 files changed, 14 insertions(+), 7 deletions(-) + src/main/java/net/minecraft/server/BlockBamboo.java | 12 ++++++------ + src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 7 +++++++ + 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/minecraft/server/BlockBamboo.java b/src/main/java/net/minecraft/server/BlockBamboo.java -index 02c548dd9..016ceebb9 100644 +index 14790c167..bac1b8b30 100644 --- a/src/main/java/net/minecraft/server/BlockBamboo.java +++ b/src/main/java/net/minecraft/server/BlockBamboo.java -@@ -10,7 +10,7 @@ public class BlockBamboo extends Block implements IBlockFragilePlantElement { - protected static final VoxelShape c = Block.a(6.5D, 0.0D, 6.5D, 9.5D, 16.0D, 9.5D); - public static final BlockStateInteger d = BlockProperties.Y; - public static final BlockStateEnum e = BlockProperties.aG; -- public static final BlockStateInteger f = BlockProperties.au; -+ public static final BlockStateInteger f = BlockProperties.au; private BlockStateInteger stage() { return f; } // Purpur - OBFHELPER - - public BlockBamboo(Block.Info block_info) { - super(block_info); -@@ -89,7 +89,7 @@ public class BlockBamboo extends Block implements IBlockFragilePlantElement { +@@ -97,7 +97,7 @@ public class BlockBamboo extends Block implements IBlockFragilePlantElement { if (random.nextInt(Math.max(1, (int) (100.0F / worldserver.spigotConfig.bambooModifier) * 3)) == 0 && worldserver.isEmpty(blockposition.up()) && worldserver.getLightLevel(blockposition.up(), 0) >= 9) { // Spigot int i = this.b(worldserver, blockposition) + 1; @@ -30,57 +21,57 @@ index 02c548dd9..016ceebb9 100644 this.a(iblockdata, (World) worldserver, blockposition, random, i); } } -@@ -120,7 +120,7 @@ public class BlockBamboo extends Block implements IBlockFragilePlantElement { +@@ -128,7 +128,7 @@ public class BlockBamboo extends Block implements IBlockFragilePlantElement { int i = this.a(iblockaccess, blockposition); int j = this.b(iblockaccess, blockposition); - return i + j + 1 < 16 && (Integer) iblockaccess.getType(blockposition.up(i)).get(BlockBamboo.f) != 1; -+ return i + j + 1 < ((World) iblockaccess).purpurConfig.bambooMaxHeight && iblockaccess.getType(blockposition.up(i)).get(stage()) != 1; // Purpur ++ return i + j + 1 < ((World) iblockaccess).purpurConfig.bambooMaxHeight && iblockaccess.getType(blockposition.up(i)).get(BlockBamboo.f) != 1; // Purpur } @Override -@@ -139,7 +139,7 @@ public class BlockBamboo extends Block implements IBlockFragilePlantElement { +@@ -147,7 +147,7 @@ public class BlockBamboo extends Block implements IBlockFragilePlantElement { BlockPosition blockposition1 = blockposition.up(i); IBlockData iblockdata1 = worldserver.getType(blockposition1); - if (k >= 16 || (Integer) iblockdata1.get(BlockBamboo.f) == 1 || !worldserver.isEmpty(blockposition1.up())) { -+ if (k >= worldserver.purpurConfig.bambooMaxHeight || iblockdata1.get(stage()) == 1 || !worldserver.isEmpty(blockposition1.up())) { // Purpur ++ if (k >= worldserver.purpurConfig.bambooMaxHeight || iblockdata1.get(BlockBamboo.f) == 1 || !worldserver.isEmpty(blockposition1.up())) { // Purpur return; } -@@ -180,7 +180,7 @@ public class BlockBamboo extends Block implements IBlockFragilePlantElement { +@@ -188,7 +188,7 @@ public class BlockBamboo extends Block implements IBlockFragilePlantElement { } - int j = (Integer) iblockdata.get(BlockBamboo.d) != 1 && iblockdata2.getBlock() != Blocks.BAMBOO ? 0 : 1; + int j = (Integer) iblockdata.get(BlockBamboo.d) != 1 && !iblockdata2.a(Blocks.BAMBOO) ? 0 : 1; - int k = (i < 11 || random.nextFloat() >= 0.25F) && i != 15 ? 0 : 1; -+ int k = (i <= world.purpurConfig.bambooSmallHeight || random.nextFloat() >= 0.25F) && i != (world.purpurConfig.bambooMaxHeight - 1) ? 0 : 1; // Purpur ++ int k = (i < world.purpurConfig.bambooSmallHeight || random.nextFloat() >= 0.25F) && i != (world.purpurConfig.bambooMaxHeight - 1) ? 0 : 1; // Purpur // CraftBukkit start if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(world, blockposition, blockposition.up(), (IBlockData) ((IBlockData) ((IBlockData) this.getBlockData().set(BlockBamboo.d, j)).set(BlockBamboo.e, blockpropertybamboosize)).set(BlockBamboo.f, k), 3)) { -@@ -195,7 +195,7 @@ public class BlockBamboo extends Block implements IBlockFragilePlantElement { +@@ -203,7 +203,7 @@ public class BlockBamboo extends Block implements IBlockFragilePlantElement { protected int a(IBlockAccess iblockaccess, BlockPosition blockposition) { int i; -- for (i = 0; i < 16 && iblockaccess.getType(blockposition.up(i + 1)).getBlock() == Blocks.BAMBOO; ++i) { -+ for (i = 0; i < ((World) iblockaccess).purpurConfig.bambooMaxHeight && iblockaccess.getType(blockposition.up(i + 1)).getBlock() == Blocks.BAMBOO; ++i) { // Purpur +- for (i = 0; i < 16 && iblockaccess.getType(blockposition.up(i + 1)).a(Blocks.BAMBOO); ++i) { ++ for (i = 0; i < ((World) iblockaccess).purpurConfig.bambooMaxHeight && iblockaccess.getType(blockposition.up(i + 1)).a(Blocks.BAMBOO); ++i) { // Purpur ; } -@@ -205,7 +205,7 @@ public class BlockBamboo extends Block implements IBlockFragilePlantElement { +@@ -213,7 +213,7 @@ public class BlockBamboo extends Block implements IBlockFragilePlantElement { protected int b(IBlockAccess iblockaccess, BlockPosition blockposition) { int i; -- for (i = 0; i < 16 && iblockaccess.getType(blockposition.down(i + 1)).getBlock() == Blocks.BAMBOO; ++i) { -+ for (i = 0; i < ((World) iblockaccess).purpurConfig.bambooMaxHeight && iblockaccess.getType(blockposition.down(i + 1)).getBlock() == Blocks.BAMBOO; ++i) { // Purpur +- for (i = 0; i < 16 && iblockaccess.getType(blockposition.down(i + 1)).a(Blocks.BAMBOO); ++i) { ++ for (i = 0; i < ((World) iblockaccess).purpurConfig.bambooMaxHeight && iblockaccess.getType(blockposition.down(i + 1)).a(Blocks.BAMBOO); ++i) { // Purpur ; } diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 114cd3f80..61c19661c 100644 +index abfa1d79b..f21b01565 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -72,6 +72,13 @@ public class PurpurWorldConfig { - return PurpurConfig.config.getString("world-settings." + worldName + "." + path, PurpurConfig.config.getString("world-settings.default." + path)); +@@ -148,6 +148,13 @@ public class PurpurWorldConfig { + playerInvulnerableWhileAcceptingResourcePack = getBoolean("gameplay-mechanics.player.invulnerable-while-accepting-resource-pack", playerInvulnerableWhileAcceptingResourcePack); } + public int bambooMaxHeight = 16; @@ -90,9 +81,9 @@ index 114cd3f80..61c19661c 100644 + bambooSmallHeight = getInt("blocks.bamboo.small-height", bambooSmallHeight); + } + - public int campfireRegenInterval = 0; - public int campfireRegenDuration = 80; - public int campfireRegenRange = 5; + public boolean dispenserApplyCursedArmor = true; + private void dispenserSettings() { + dispenserApplyCursedArmor = getBoolean("blocks.dispenser.apply-cursed-to-armor-slots", dispenserApplyCursedArmor); -- 2.26.2 diff --git a/patches/server/0088-UPnP-Port-Forwarding-Service.patch b/patches/server/0088-UPnP-Port-Forwarding-Service.patch deleted file mode 100644 index f5db87def..000000000 --- a/patches/server/0088-UPnP-Port-Forwarding-Service.patch +++ /dev/null @@ -1,200 +0,0 @@ -From cbe470f55a4b73c26d920e28b5a34244ccbfb9cf Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Wed, 22 Jan 2020 20:13:40 -0600 -Subject: [PATCH] UPnP Port Forwarding Service - ---- - pom.xml | 10 ++++ - .../net/minecraft/server/DedicatedServer.java | 25 ++++++++++ - .../net/minecraft/server/MinecraftServer.java | 10 ++++ - .../java/net/pl3x/purpur/PurpurConfig.java | 5 ++ - .../net/pl3x/purpur/gui/info/JInfoPanel.java | 3 ++ - .../pl3x/purpur/gui/info/UPnPComponent.java | 47 +++++++++++++++++++ - 6 files changed, 100 insertions(+) - create mode 100644 src/main/java/net/pl3x/purpur/gui/info/UPnPComponent.java - -diff --git a/pom.xml b/pom.xml -index 097c736bc..adf7f78da 100644 ---- a/pom.xml -+++ b/pom.xml -@@ -55,6 +55,12 @@ - 1.7.7.1 - compile -
-+ -+ com.dosse.upnp -+ UPnP -+ 1.0 -+ compile -+ - - - net.minecrell -@@ -166,6 +172,10 @@ - spigotmc-public - https://hub.spigotmc.org/nexus/content/groups/public/ - -+ -+ pl3x -+ https://repo.pl3x.net/ -+ - - - -diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java -index 7f2db5f0b..5cfb6fd3d 100644 ---- a/src/main/java/net/minecraft/server/DedicatedServer.java -+++ b/src/main/java/net/minecraft/server/DedicatedServer.java -@@ -242,6 +242,31 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer - return false; - } - -+ // Purpur start -+ if (net.pl3x.purpur.PurpurConfig.useUPnP) { -+ LOGGER.info("[UPnP] Attempting to start UPnP port forwarding service..."); -+ com.dosse.upnp.UPnP.NAME = "Purpur UPnP"; -+ if (com.dosse.upnp.UPnP.isUPnPAvailable()) { -+ if (com.dosse.upnp.UPnP.isMappedTCP(getPort())) { -+ upnp = false; -+ LOGGER.info("[UPnP] Port " + getPort() + " is already open"); -+ } else if (com.dosse.upnp.UPnP.openPortTCP(getPort())) { -+ upnp = true; -+ LOGGER.info("[UPnP] Successfully opened port " + getPort()); -+ } else { -+ upnp = false; -+ LOGGER.info("[UPnP] Failed to open port " + getPort()); -+ } -+ if (upnp) { -+ LOGGER.info("[UPnP] " + com.dosse.upnp.UPnP.getExternalIP() + ":" + getPort()); -+ } -+ } else { -+ upnp = false; -+ LOGGER.error("[UPnP] Service is unavailable"); -+ } -+ } -+ // Purpur end -+ - // CraftBukkit start - // this.a((PlayerList) (new DedicatedPlayerList(this))); // Spigot - moved up - server.loadPlugins(); -diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index f23fdd5f2..d9e5eda9b 100644 ---- a/src/main/java/net/minecraft/server/MinecraftServer.java -+++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -187,6 +187,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant { - ramGraph.update(); - ramDetails.update(); -+ upnpComponent.repaint(); - }); - timer.start(); - } -diff --git a/src/main/java/net/pl3x/purpur/gui/info/UPnPComponent.java b/src/main/java/net/pl3x/purpur/gui/info/UPnPComponent.java -new file mode 100644 -index 000000000..b0465d360 ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/gui/info/UPnPComponent.java -@@ -0,0 +1,47 @@ -+package net.pl3x.purpur.gui.info; -+ -+import net.minecraft.server.MinecraftServer; -+import net.pl3x.purpur.PurpurConfig; -+ -+import javax.swing.JTextPane; -+import javax.swing.border.EmptyBorder; -+import java.awt.Color; -+import java.awt.Dimension; -+import java.awt.Graphics; -+ -+public class UPnPComponent extends JTextPane { -+ private final MinecraftServer server; -+ -+ public UPnPComponent(MinecraftServer server) { -+ this.server = server; -+ setBorder(new EmptyBorder(0, 30, 0, 10)); -+ setEditable(false); -+ setText("UPnP Status"); -+ setOpaque(false); -+ setHighlighter(null); -+ } -+ -+ @Override -+ public Dimension getPreferredSize() { -+ return new Dimension(350, 20); -+ } -+ -+ @Override -+ public void paint(Graphics graphics) { -+ super.paint(graphics); -+ graphics.setColor(server.isUPnPEnabled() ? Color.GREEN : Color.RED); -+ graphics.fillOval(10, 0, 15, 15); -+ setToolTipText(getTooltip()); -+ } -+ -+ private String getTooltip() { -+ if (!PurpurConfig.useUPnP) { -+ return "UPnP Disabled"; -+ } -+ if (server.isUPnPEnabled()) { -+ return "UPnP Enabled"; -+ } else { -+ return "UPnP Unavailable"; -+ } -+ } -+} --- -2.26.2 - diff --git a/patches/server/0053-Climbing-should-not-bypass-cramming-gamerule.patch b/patches/server/0089-Climbing-should-not-bypass-cramming-gamerule.patch similarity index 62% rename from patches/server/0053-Climbing-should-not-bypass-cramming-gamerule.patch rename to patches/server/0089-Climbing-should-not-bypass-cramming-gamerule.patch index 1d59dff41..684a6de13 100644 --- a/patches/server/0053-Climbing-should-not-bypass-cramming-gamerule.patch +++ b/patches/server/0089-Climbing-should-not-bypass-cramming-gamerule.patch @@ -1,4 +1,4 @@ -From f725aa440b07c03d51e5931eecc2f2b2d740d2a1 Mon Sep 17 00:00:00 2001 +From aab19aea2352bd8dc687ee85f603f67edac0b137 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 21 Jul 2019 18:06:20 -0500 Subject: [PATCH] Climbing should not bypass cramming gamerule @@ -9,18 +9,19 @@ Subject: [PATCH] Climbing should not bypass cramming gamerule src/main/java/net/minecraft/server/EntityBat.java | 2 +- src/main/java/net/minecraft/server/EntityBoat.java | 2 +- .../java/net/minecraft/server/EntityHorseAbstract.java | 2 +- - src/main/java/net/minecraft/server/EntityLiving.java | 8 +++++--- + src/main/java/net/minecraft/server/EntityLiving.java | 6 +++--- .../java/net/minecraft/server/EntityMinecartAbstract.java | 2 +- - src/main/java/net/minecraft/server/EntityParrot.java | 2 +- + src/main/java/net/minecraft/server/EntityParrot.java | 4 ++-- + src/main/java/net/minecraft/server/EntityPlayer.java | 2 +- src/main/java/net/minecraft/server/IEntitySelector.java | 8 +++++++- src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 2 ++ - 10 files changed, 26 insertions(+), 10 deletions(-) + 11 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index bdf79302b..92b77ce34 100644 +index dca384ea2..7f209e26f 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java -@@ -1758,6 +1758,12 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke +@@ -1525,6 +1525,12 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } public boolean isCollidable() { @@ -34,7 +35,7 @@ index bdf79302b..92b77ce34 100644 } diff --git a/src/main/java/net/minecraft/server/EntityArmorStand.java b/src/main/java/net/minecraft/server/EntityArmorStand.java -index d35a0b2d9..d4aa9b24f 100644 +index 7543f2cee..c3cde1568 100644 --- a/src/main/java/net/minecraft/server/EntityArmorStand.java +++ b/src/main/java/net/minecraft/server/EntityArmorStand.java @@ -318,7 +318,7 @@ public class EntityArmorStand extends EntityLiving { @@ -47,10 +48,10 @@ index d35a0b2d9..d4aa9b24f 100644 } diff --git a/src/main/java/net/minecraft/server/EntityBat.java b/src/main/java/net/minecraft/server/EntityBat.java -index 592408bac..7a740f676 100644 +index 3dd3b8913..99bae2dcb 100644 --- a/src/main/java/net/minecraft/server/EntityBat.java +++ b/src/main/java/net/minecraft/server/EntityBat.java -@@ -85,7 +85,7 @@ public class EntityBat extends EntityAmbient { +@@ -50,7 +50,7 @@ public class EntityBat extends EntityAmbient { } @Override @@ -60,10 +61,10 @@ index 592408bac..7a740f676 100644 } diff --git a/src/main/java/net/minecraft/server/EntityBoat.java b/src/main/java/net/minecraft/server/EntityBoat.java -index fdf306e80..563fc8ced 100644 +index a20d6feb8..92c1d1794 100644 --- a/src/main/java/net/minecraft/server/EntityBoat.java +++ b/src/main/java/net/minecraft/server/EntityBoat.java -@@ -98,7 +98,7 @@ public class EntityBoat extends Entity { +@@ -104,7 +104,7 @@ public class EntityBoat extends Entity { } @Override @@ -73,10 +74,10 @@ index fdf306e80..563fc8ced 100644 } diff --git a/src/main/java/net/minecraft/server/EntityHorseAbstract.java b/src/main/java/net/minecraft/server/EntityHorseAbstract.java -index f31cb0554..0ecdea671 100644 +index ee7a2fedd..c9ab80ccd 100644 --- a/src/main/java/net/minecraft/server/EntityHorseAbstract.java +++ b/src/main/java/net/minecraft/server/EntityHorseAbstract.java -@@ -181,7 +181,7 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven +@@ -165,7 +165,7 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven } @Override @@ -86,36 +87,34 @@ index f31cb0554..0ecdea671 100644 } diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java -index 94be35603..2d0ccff03 100644 +index f86499c87..bc9e2e0c7 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java -@@ -2694,7 +2694,7 @@ public abstract class EntityLiving extends Entity { +@@ -2852,7 +2852,7 @@ public abstract class EntityLiving extends Entity { + return; + } // Paper - end don't run getEntities if we're not going to use its result - // Tuinity start - reduce memory allocation from collideNearby - List list = com.tuinity.tuinity.util.CachedLists.getTempGetEntitiesList(); -- this.world.getEntities(this, this.getBoundingBox(), IEntitySelector.a(this), list); -+ this.world.getEntities(this, this.getBoundingBox(), IEntitySelector.pushable(this, world.purpurConfig.fixClimbingBypassingCrammingRule), list); // Purpur - try { - // Tuinity end - reduce memory allocation from collideNearby +- List list = this.world.getEntities(this, this.getBoundingBox(), IEntitySelector.a(this)); ++ List list = this.world.getEntities(this, this.getBoundingBox(), IEntitySelector.pushable(this, world.purpurConfig.fixClimbingBypassingCrammingRule)); // Purpur -@@ -2838,8 +2838,10 @@ public abstract class EntityLiving extends Entity { + if (!list.isEmpty()) { + // Paper - move up +@@ -2991,8 +2991,8 @@ public abstract class EntityLiving extends Entity { } @Override - public boolean isCollidable() { - return this.isAlive() && !this.isClimbing() && this.collides; // CraftBukkit -+ // Purpur start -+ public boolean isCollidable(boolean ignoreClimbing) { -+ return this.isAlive() && (ignoreClimbing || !isClimbing()) && this.collides; // CraftBukkit -+ // Purpur end ++ public boolean isCollidable(boolean ignoreClimbing) { // Purpur ++ return this.isAlive() && (ignoreClimbing || !isClimbing()) && this.collides; // CraftBukkit // Purpur } - @Override + // CraftBukkit start - collidable API diff --git a/src/main/java/net/minecraft/server/EntityMinecartAbstract.java b/src/main/java/net/minecraft/server/EntityMinecartAbstract.java -index 1f3e5bd28..ae4758f25 100644 +index cdbe1a32e..c33b5c950 100644 --- a/src/main/java/net/minecraft/server/EntityMinecartAbstract.java +++ b/src/main/java/net/minecraft/server/EntityMinecartAbstract.java -@@ -105,7 +105,7 @@ public abstract class EntityMinecartAbstract extends Entity { +@@ -108,7 +108,7 @@ public abstract class EntityMinecartAbstract extends Entity { } @Override @@ -125,23 +124,38 @@ index 1f3e5bd28..ae4758f25 100644 } diff --git a/src/main/java/net/minecraft/server/EntityParrot.java b/src/main/java/net/minecraft/server/EntityParrot.java -index 7ba2f3a35..dd2cd7b21 100644 +index 2172fcefb..7afdb3060 100644 --- a/src/main/java/net/minecraft/server/EntityParrot.java +++ b/src/main/java/net/minecraft/server/EntityParrot.java -@@ -392,7 +392,7 @@ public class EntityParrot extends EntityPerchable implements EntityBird { +@@ -314,8 +314,8 @@ public class EntityParrot extends EntityPerchable implements EntityBird { + } + + @Override +- public boolean isCollidable() { +- return super.isCollidable(); // CraftBukkit - collidable API ++ public boolean isCollidable(boolean ignoreClimbing) { // Purpur ++ return super.isCollidable(ignoreClimbing); // CraftBukkit - collidable API // Purpur + } + + @Override +diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java +index 9801d87f0..7c666abe3 100644 +--- a/src/main/java/net/minecraft/server/EntityPlayer.java ++++ b/src/main/java/net/minecraft/server/EntityPlayer.java +@@ -1808,7 +1808,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } @Override - public boolean isCollidable() { + public boolean isCollidable(boolean ignoreClimbing) { // Purpur - return true; + return !isAfk() && super.isCollidable(); } - + // Purpur end diff --git a/src/main/java/net/minecraft/server/IEntitySelector.java b/src/main/java/net/minecraft/server/IEntitySelector.java -index 0bf1a14b7..9f5860ca8 100644 +index 9b4795f3b..192d9798c 100644 --- a/src/main/java/net/minecraft/server/IEntitySelector.java +++ b/src/main/java/net/minecraft/server/IEntitySelector.java -@@ -36,11 +36,17 @@ public final class IEntitySelector { +@@ -45,11 +45,17 @@ public final class IEntitySelector { } public static Predicate a(Entity entity) { @@ -150,36 +164,36 @@ index 0bf1a14b7..9f5860ca8 100644 + } + + public static Predicate pushable(Entity entity, boolean ignoreClimbing) { -+ // Purpur end ++ // Purpur end ScoreboardTeamBase scoreboardteambase = entity.getScoreboardTeam(); ScoreboardTeamBase.EnumTeamPush scoreboardteambase_enumteampush = scoreboardteambase == null ? ScoreboardTeamBase.EnumTeamPush.ALWAYS : scoreboardteambase.getCollisionRule(); - return (Predicate) (scoreboardteambase_enumteampush == ScoreboardTeamBase.EnumTeamPush.NEVER ? Predicates.alwaysFalse() : IEntitySelector.f.and((entity1) -> { -- if (!entity1.isCollidable()) { -+ if (!entity1.isCollidable(ignoreClimbing)) { + return (Predicate) (scoreboardteambase_enumteampush == ScoreboardTeamBase.EnumTeamPush.NEVER ? Predicates.alwaysFalse() : IEntitySelector.g.and((entity1) -> { +- if (!entity1.canCollideWith(entity) || !entity.canCollideWith(entity1)) { // CraftBukkit - collidable API ++ if (!entity1.isCollidable(ignoreClimbing) || !entity1.canCollideWith(entity) || !entity.canCollideWith(entity1)) { // CraftBukkit - collidable API return false; - } else if (entity.world.isClientSide && (!(entity1 instanceof EntityHuman) || !((EntityHuman) entity1).ec())) { + } else if (entity.world.isClientSide && (!(entity1 instanceof EntityHuman) || !((EntityHuman) entity1).ey())) { return false; diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 61c19661c..1a2512b52 100644 +index f21b01565..39163634c 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -136,6 +136,7 @@ public class PurpurWorldConfig { - public double controllableMinecartsBaseSpeed = 0.1D; - public Map controllableMinecartsBlockSpeeds = new HashMap<>(); +@@ -119,6 +119,7 @@ public class PurpurWorldConfig { + public boolean boatEjectPlayersOnLand = false; public boolean disableDropsOnCrammingDeath = false; + public boolean entitiesPickUpLootBypassMobGriefing = false; + public boolean fixClimbingBypassingCrammingRule = false; public boolean milkCuresBadOmen = true; - public boolean useBetterMending = false; - private void gameplayMechanicsSettings() { -@@ -157,6 +158,7 @@ public class PurpurWorldConfig { - set("gameplay-mechanics.controllable-minecarts.block-speed.stone", 0.5D); - } + public boolean saveProjectilesToDisk = true; + public double tridentLoyaltyVoidReturnHeight = 0.0D; +@@ -128,6 +129,7 @@ public class PurpurWorldConfig { + boatEjectPlayersOnLand = getBoolean("gameplay-mechanics.boat.eject-players-on-land", boatEjectPlayersOnLand); disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath); + entitiesPickUpLootBypassMobGriefing = getBoolean("gameplay-mechanics.entities-pick-up-loot-bypass-mob-griefing", entitiesPickUpLootBypassMobGriefing); + fixClimbingBypassingCrammingRule = getBoolean("gameplay-mechanics.fix-climbing-bypassing-cramming-rule", fixClimbingBypassingCrammingRule); milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen); - useBetterMending = getBoolean("gameplay-mechanics.use-better-mending", useBetterMending); - } + saveProjectilesToDisk = getBoolean("gameplay-mechanics.save-projectiles-to-disk", saveProjectilesToDisk); + tridentLoyaltyVoidReturnHeight = getDouble("gameplay-mechanics.trident-loyalty-void-return-height", tridentLoyaltyVoidReturnHeight); -- 2.26.2 diff --git a/patches/server/0068-Add-5-second-tps-average-in-tps.patch b/patches/server/0090-Add-5-second-tps-average-in-tps.patch similarity index 75% rename from patches/server/0068-Add-5-second-tps-average-in-tps.patch rename to patches/server/0090-Add-5-second-tps-average-in-tps.patch index 29867e50e..1d032d8c8 100644 --- a/patches/server/0068-Add-5-second-tps-average-in-tps.patch +++ b/patches/server/0090-Add-5-second-tps-average-in-tps.patch @@ -1,4 +1,4 @@ -From e803339774dfdcd4aa5f27f6dcb231bd5932704b Mon Sep 17 00:00:00 2001 +From 22cdb2e6b0d2cd0f9d0903a8b85afd7e113e3a22 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 28 Jul 2019 01:27:37 -0500 Subject: [PATCH] Add 5 second tps average in /tps @@ -10,10 +10,10 @@ Subject: [PATCH] Add 5 second tps average in /tps 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 3568e076e..f23fdd5f2 100644 +index da0c2d529..a156fe255 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -183,7 +183,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant 0 && args[0].equals("mem") && sender.hasPermission("bukkit.command.tpsmemory")) { + sender.sendMessage(ChatColor.GOLD + "Current Memory Usage: " + ChatColor.GREEN + ((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (1024 * 1024)) + "/" + (Runtime.getRuntime().totalMemory() / (1024 * 1024)) + " mb (Max: " + (Runtime.getRuntime().maxMemory() / (1024 * 1024)) + " mb)"); + if (!hasShownMemoryWarning) { -- 2.26.2 diff --git a/patches/server/0090-Add-option-to-disable-saving-projectiles-to-disk.patch b/patches/server/0090-Add-option-to-disable-saving-projectiles-to-disk.patch deleted file mode 100644 index 0845ee84b..000000000 --- a/patches/server/0090-Add-option-to-disable-saving-projectiles-to-disk.patch +++ /dev/null @@ -1,172 +0,0 @@ -From 712f5b54a7f584f4299d2643945661221eb2593d Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Tue, 18 Feb 2020 20:07:08 -0600 -Subject: [PATCH] Add option to disable saving projectiles to disk - ---- - .../net/minecraft/server/ChunkRegionLoader.java | 1 + - src/main/java/net/minecraft/server/Entity.java | 6 ++++++ - .../java/net/minecraft/server/EntityArrow.java | 7 +++++++ - .../net/minecraft/server/EntityEnderSignal.java | 7 +++++++ - .../net/minecraft/server/EntityFireworks.java | 7 +++++++ - .../net/minecraft/server/EntityLlamaSpit.java | 7 +++++++ - .../net/minecraft/server/EntityProjectile.java | 7 +++++++ - .../java/net/pl3x/purpur/PurpurWorldConfig.java | 16 ++++++++++++++++ - 8 files changed, 58 insertions(+) - -diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java -index 20b6b58bd..6278b8d45 100644 ---- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java -+++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java -@@ -476,6 +476,7 @@ public class ChunkRegionLoader { - - while (iterator1.hasNext()) { - Entity entity = (Entity) iterator1.next(); -+ if (!entity.canSaveToDisk()) continue; // Purpur - NBTTagCompound nbttagcompound4 = new NBTTagCompound(); - // Paper start - if (asyncsavedata == null && !entity.dead && (int) Math.floor(entity.locX()) >> 4 != chunk.getPos().x || (int) Math.floor(entity.locZ()) >> 4 != chunk.getPos().z) { -diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index 92b77ce34..4fb6a3fd7 100644 ---- a/src/main/java/net/minecraft/server/Entity.java -+++ b/src/main/java/net/minecraft/server/Entity.java -@@ -1775,6 +1775,12 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - - } - -+ // Purpur start -+ public boolean canSaveToDisk() { -+ return true; -+ } -+ // Purpur end -+ - public boolean c(NBTTagCompound nbttagcompound) { - String s = this.getSaveID(); - -diff --git a/src/main/java/net/minecraft/server/EntityArrow.java b/src/main/java/net/minecraft/server/EntityArrow.java -index e66f6b300..ae44f878f 100644 ---- a/src/main/java/net/minecraft/server/EntityArrow.java -+++ b/src/main/java/net/minecraft/server/EntityArrow.java -@@ -68,6 +68,13 @@ public abstract class EntityArrow extends Entity implements IProjectile { - - } - -+ // Purpur start -+ @Override -+ public boolean canSaveToDisk() { -+ return world != null && world.purpurConfig.saveProjectilesToDisk; -+ } -+ // Purpur end -+ - public void a(SoundEffect soundeffect) { - this.av = soundeffect; - } -diff --git a/src/main/java/net/minecraft/server/EntityEnderSignal.java b/src/main/java/net/minecraft/server/EntityEnderSignal.java -index 7ebd7da1c..74f8257ec 100644 ---- a/src/main/java/net/minecraft/server/EntityEnderSignal.java -+++ b/src/main/java/net/minecraft/server/EntityEnderSignal.java -@@ -19,6 +19,13 @@ public class EntityEnderSignal extends Entity { - this.setPosition(d0, d1, d2); - } - -+ // Purpur start -+ @Override -+ public boolean canSaveToDisk() { -+ return world != null && world.purpurConfig.saveProjectilesToDisk; -+ } -+ // Purpur end -+ - public void b(ItemStack itemstack) { - if (itemstack.getItem() != Items.ENDER_EYE || itemstack.hasTag()) { - this.getDataWatcher().set(EntityEnderSignal.b, SystemUtils.a(itemstack.cloneItemStack(), (itemstack1) -> { // Purpur - decompile error -diff --git a/src/main/java/net/minecraft/server/EntityFireworks.java b/src/main/java/net/minecraft/server/EntityFireworks.java -index 5c3731f68..ce3168e5d 100644 ---- a/src/main/java/net/minecraft/server/EntityFireworks.java -+++ b/src/main/java/net/minecraft/server/EntityFireworks.java -@@ -21,6 +21,13 @@ public class EntityFireworks extends Entity implements IProjectile { - super(entitytypes, world); - } - -+ // Purpur start -+ @Override -+ public boolean canSaveToDisk() { -+ return world != null && world.purpurConfig.saveProjectilesToDisk; -+ } -+ // Purpur end -+ - // Spigot Start - copied from tick - @Override - public void inactiveTick() { -diff --git a/src/main/java/net/minecraft/server/EntityLlamaSpit.java b/src/main/java/net/minecraft/server/EntityLlamaSpit.java -index b7a92e100..b95ee50a4 100644 ---- a/src/main/java/net/minecraft/server/EntityLlamaSpit.java -+++ b/src/main/java/net/minecraft/server/EntityLlamaSpit.java -@@ -19,6 +19,13 @@ public class EntityLlamaSpit extends Entity implements IProjectile { - this.setPosition(entityllama.locX() - (double) (entityllama.getWidth() + 1.0F) * 0.5D * (double) MathHelper.sin(entityllama.aI * 0.017453292F), entityllama.getHeadY() - 0.10000000149011612D, entityllama.locZ() + (double) (entityllama.getWidth() + 1.0F) * 0.5D * (double) MathHelper.cos(entityllama.aI * 0.017453292F)); - } - -+ // Purpur start -+ @Override -+ public boolean canSaveToDisk() { -+ return world != null && world.purpurConfig.saveProjectilesToDisk; -+ } -+ // Purpur end -+ - @Override - public void tick() { - super.tick(); -diff --git a/src/main/java/net/minecraft/server/EntityProjectile.java b/src/main/java/net/minecraft/server/EntityProjectile.java -index f5c8074dc..674f2ccc7 100644 ---- a/src/main/java/net/minecraft/server/EntityProjectile.java -+++ b/src/main/java/net/minecraft/server/EntityProjectile.java -@@ -35,6 +35,13 @@ public abstract class EntityProjectile extends Entity implements IProjectile { - this.projectileSource = (org.bukkit.entity.LivingEntity) entityliving.getBukkitEntity(); // CraftBukkit - } - -+ // Purpur start -+ @Override -+ public boolean canSaveToDisk() { -+ return world != null && world.purpurConfig.saveProjectilesToDisk; -+ } -+ // Purpur end -+ - public void a(Entity entity, float f, float f1, float f2, float f3, float f4) { - float f5 = -MathHelper.sin(f1 * 0.017453292F) * MathHelper.cos(f * 0.017453292F); - float f6 = -MathHelper.sin((f + f2) * 0.017453292F); -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index d4b4dfdd3..51585a7d8 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -164,6 +164,7 @@ public class PurpurWorldConfig { - public boolean playerSleepOnlyWithCondition = false; - public String playerSleepCondition = "time >= 12541 && time <= 23458"; - public boolean useBetterMending = false; -+ public boolean saveProjectilesToDisk = true; - private void gameplayMechanicsSettings() { - boatEjectPlayersOnLand = getBoolean("gameplay-mechanics.boat.eject-players-on-land", boatEjectPlayersOnLand); - armorstandStepHeight = (float) getDouble("gameplay-mechanics.armorstand.step-height", armorstandStepHeight); -@@ -192,6 +193,21 @@ public class PurpurWorldConfig { - playerSleepOnlyWithCondition = getBoolean("gameplay-mechanics.player.sleep.only-with-condition", playerSleepOnlyWithCondition); - playerSleepCondition = getString("gameplay-mechanics.player.sleep.condition", playerSleepCondition); - useBetterMending = getBoolean("gameplay-mechanics.use-better-mending", useBetterMending); -+ if (PurpurConfig.version < 4) { -+ Object oldVal = PurpurConfig.config.get("world-settings.default.gameplay-mechanics.saveProjectilesToDisk"); -+ if (oldVal instanceof Boolean) { -+ PurpurConfig.config.addDefault("world-settings.default.gameplay-mechanics.save-projectiles-to-disk", oldVal); -+ PurpurConfig.config.set("world-settings.default.gameplay-mechanics.save-projectiles-to-disk", oldVal); -+ saveProjectilesToDisk = (boolean) oldVal; -+ } -+ oldVal = PurpurConfig.config.get("world-settings." + worldName + ".gameplay-mechanics.saveProjectilesToDisk"); -+ if (oldVal instanceof Boolean) { -+ PurpurConfig.config.set("world-settings." + worldName + ".gameplay-mechanics.save-projectiles-to-disk", oldVal); -+ saveProjectilesToDisk = (boolean) oldVal; -+ } -+ set("gameplay-mechanics.saveProjectilesToDisk", null); -+ } -+ saveProjectilesToDisk = getBoolean("gameplay-mechanics.save-projectiles-to-disk", saveProjectilesToDisk); - } - - public int elytraDamagePerSecond = 1; --- -2.26.2 - diff --git a/patches/server/0091-Implement-bed-explosion-options.patch b/patches/server/0091-Implement-bed-explosion-options.patch deleted file mode 100644 index ea5a5ef0e..000000000 --- a/patches/server/0091-Implement-bed-explosion-options.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 6dc574dbdbe31a99b139d32473070ac089288cc8 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sat, 22 Feb 2020 15:04:29 -0600 -Subject: [PATCH] Implement bed explosion options - ---- - .../java/net/minecraft/server/BlockBed.java | 2 +- - .../net/pl3x/purpur/PurpurWorldConfig.java | 18 ++++++++++++++++++ - 2 files changed, 19 insertions(+), 1 deletion(-) - -diff --git a/src/main/java/net/minecraft/server/BlockBed.java b/src/main/java/net/minecraft/server/BlockBed.java -index e0bc6080e..61a5e06a2 100644 ---- a/src/main/java/net/minecraft/server/BlockBed.java -+++ b/src/main/java/net/minecraft/server/BlockBed.java -@@ -84,7 +84,7 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity { - world.a(blockposition1, false); - } - -- world.createExplosion((Entity) null, DamageSource.a(), (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, 5.0F, true, Explosion.Effect.DESTROY); -+ if (world.purpurConfig.bedExplode) world.createExplosion(null, DamageSource.a(), blockposition.getX() + 0.5D, blockposition.getY() + 0.5D, blockposition.getZ() + 0.5D, (float) world.purpurConfig.bedExplosionPower, world.purpurConfig.bedExplosionFire, world.purpurConfig.bedExplosionEffect); // Purpur - return EnumInteractionResult.SUCCESS; - // CraftBukkit end - } -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 51585a7d8..0e34414a7 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -3,6 +3,7 @@ package net.pl3x.purpur; - import com.destroystokyo.paper.PaperWorldConfig; - import net.minecraft.server.Block; - import net.minecraft.server.Blocks; -+import net.minecraft.server.Explosion; - import net.minecraft.server.IRegistry; - import net.minecraft.server.MinecraftKey; - import org.bukkit.configuration.ConfigurationSection; -@@ -12,6 +13,7 @@ import java.util.ArrayList; - import java.util.HashMap; - import java.util.List; - import java.util.Map; -+import java.util.logging.Level; - - import static net.pl3x.purpur.PurpurConfig.log; - -@@ -79,6 +81,22 @@ public class PurpurWorldConfig { - bambooSmallHeight = getInt("blocks.bamboo.small-height", bambooSmallHeight); - } - -+ public boolean bedExplode = true; -+ public double bedExplosionPower = 5.0D; -+ public boolean bedExplosionFire = true; -+ public Explosion.Effect bedExplosionEffect = Explosion.Effect.DESTROY; -+ private void bedSettings() { -+ bedExplode = getBoolean("blocks.bed.explode", bedExplode); -+ bedExplosionPower = getDouble("blocks.bed.explosion-power", bedExplosionPower); -+ bedExplosionFire = getBoolean("blocks.bed.explosion-fire", bedExplosionFire); -+ try { -+ bedExplosionEffect = Explosion.Effect.valueOf(getString("blocks.bed.explosion-effect", bedExplosionEffect.name())); -+ } catch (IllegalArgumentException e) { -+ log(Level.SEVERE, "Unknown value for `blocks.bed.explosion-effect`! Using default of `DESTROY`"); -+ bedExplosionEffect = Explosion.Effect.DESTROY; -+ } -+ } -+ - public int campfireRegenInterval = 0; - public int campfireRegenDuration = 80; - public int campfireRegenRange = 5; --- -2.26.2 - diff --git a/patches/server/0047-Implement-elytra-settings.patch b/patches/server/0091-Implement-elytra-settings.patch similarity index 76% rename from patches/server/0047-Implement-elytra-settings.patch rename to patches/server/0091-Implement-elytra-settings.patch index 5dd308246..c4ff76001 100644 --- a/patches/server/0047-Implement-elytra-settings.patch +++ b/patches/server/0091-Implement-elytra-settings.patch @@ -1,27 +1,26 @@ -From 2e3222b946ccfa16d3474c905c0882cc8476fb57 Mon Sep 17 00:00:00 2001 +From 01778cab614b676ab4f3057404351c395d605e11 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Thu, 25 Jul 2019 18:07:37 -0500 Subject: [PATCH] Implement elytra settings --- - .../java/net/minecraft/server/EntityLiving.java | 13 ++++++++++--- + .../java/net/minecraft/server/EntityLiving.java | 11 ++++++++++- .../java/net/minecraft/server/ItemFireworks.java | 8 ++++++++ src/main/java/net/minecraft/server/ItemStack.java | 8 +++++++- src/main/java/net/minecraft/server/ItemTrident.java | 10 ++++++++++ + src/main/java/net/minecraft/server/Vec3D.java | 2 ++ .../java/net/pl3x/purpur/PurpurWorldConfig.java | 13 +++++++++++++ - 5 files changed, 48 insertions(+), 4 deletions(-) + 6 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java -index 4e23d6d3a..677c2dc4f 100644 +index bc9e2e0c7..ec0e31b27 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java -@@ -2658,9 +2658,16 @@ public abstract class EntityLiving extends Entity { - if (itemstack.getItem() == Items.ELYTRA && ItemElytra.e(itemstack)) { +@@ -2825,7 +2825,16 @@ public abstract class EntityLiving extends Entity { + if (itemstack.getItem() == Items.ELYTRA && ItemElytra.d(itemstack)) { flag = true; - if (!this.world.isClientSide && (this.bm + 1) % 20 == 0) { + if (!this.world.isClientSide && (this.bl + 1) % 20 == 0) { - itemstack.damage(1, this, (entityliving) -> { -- entityliving.broadcastItemBreak(EnumItemSlot.CHEST); -- }); + // Purpur start + int damage = world.purpurConfig.elytraDamagePerSecond; + if (world.purpurConfig.elytraDamageMultiplyBySpeed > 0) { @@ -30,13 +29,13 @@ index 4e23d6d3a..677c2dc4f 100644 + damage *= (int) speed; + } + } -+ itemstack.damage(damage, this, (entityliving) -> entityliving.broadcastItemBreak(EnumItemSlot.CHEST)); ++ itemstack.damage(damage, this, (entityliving) -> { + // Purpur end + entityliving.broadcastItemBreak(EnumItemSlot.CHEST); + }); } - } else { - flag = false; diff --git a/src/main/java/net/minecraft/server/ItemFireworks.java b/src/main/java/net/minecraft/server/ItemFireworks.java -index bd524a35b..c0e8cd0cd 100644 +index 885c03f62..3a33ad181 100644 --- a/src/main/java/net/minecraft/server/ItemFireworks.java +++ b/src/main/java/net/minecraft/server/ItemFireworks.java @@ -39,6 +39,14 @@ public class ItemFireworks extends Item { @@ -55,10 +54,10 @@ index bd524a35b..c0e8cd0cd 100644 itemstack.subtract(1); } else ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java -index ce6a46685..8c3bbef66 100644 +index 51e70db21..54421c56c 100644 --- a/src/main/java/net/minecraft/server/ItemStack.java +++ b/src/main/java/net/minecraft/server/ItemStack.java -@@ -402,7 +402,7 @@ public final class ItemStack { +@@ -411,7 +411,7 @@ public final class ItemStack { int j; if (i > 0) { @@ -67,7 +66,7 @@ index ce6a46685..8c3bbef66 100644 int k = 0; for (int l = 0; j > 0 && l < i; ++l) { -@@ -448,6 +448,12 @@ public final class ItemStack { +@@ -457,6 +457,12 @@ public final class ItemStack { if (this.isDamaged(i, t0.getRandom(), t0 instanceof EntityPlayer ? (EntityPlayer) t0 : null)) { consumer.accept(t0); Item item = this.getItem(); @@ -81,10 +80,10 @@ index ce6a46685..8c3bbef66 100644 if (this.count == 1 && t0 instanceof EntityHuman) { org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent((EntityHuman) t0, this); diff --git a/src/main/java/net/minecraft/server/ItemTrident.java b/src/main/java/net/minecraft/server/ItemTrident.java -index f571a1586..c26300eac 100644 +index 32982bb47..a0e4d46ab 100644 --- a/src/main/java/net/minecraft/server/ItemTrident.java +++ b/src/main/java/net/minecraft/server/ItemTrident.java -@@ -100,6 +100,16 @@ public class ItemTrident extends Item { +@@ -102,6 +102,16 @@ public class ItemTrident extends Item implements ItemVanishable { f2 *= f6 / f5; f3 *= f6 / f5; f4 *= f6 / f5; @@ -100,13 +99,30 @@ index f571a1586..c26300eac 100644 + entityhuman.h((double) f2, (double) f3, (double) f4); entityhuman.r(20); - if (entityhuman.onGround) { + if (entityhuman.isOnGround()) { +diff --git a/src/main/java/net/minecraft/server/Vec3D.java b/src/main/java/net/minecraft/server/Vec3D.java +index 3048ba008..2a00569d4 100644 +--- a/src/main/java/net/minecraft/server/Vec3D.java ++++ b/src/main/java/net/minecraft/server/Vec3D.java +@@ -109,10 +109,12 @@ public class Vec3D implements IPosition { + return new Vec3D(this.x * d0, this.y * d1, this.z * d2); + } + ++ public double magnitude() { return f(); } // Purpur - OBFHELPER + public double f() { + return (double) MathHelper.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); + } + ++ public double magnitudeSquared() { return g(); } // Purpur - OBFHELPER + public double g() { + return this.x * this.x + this.y * this.y + this.z * this.z; + } diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 299b080c8..5318a8e32 100644 +index 39163634c..3f49a6a0b 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -142,6 +142,19 @@ public class PurpurWorldConfig { - useBetterMending = getBoolean("gameplay-mechanics.use-better-mending", useBetterMending); +@@ -136,6 +136,19 @@ public class PurpurWorldConfig { + voidDamageHeight = getDouble("gameplay-mechanics.void-damage-height", voidDamageHeight); } + public int elytraDamagePerSecond = 1; @@ -122,9 +138,9 @@ index 299b080c8..5318a8e32 100644 + elytraDamagePerTridentBoost = getInt("gameplay-mechanics.elytra.damage-per-boost.trident", elytraDamagePerTridentBoost); + } + - public boolean idleTimeoutKick = true; - public boolean idleTimeoutTickNearbyEntities = true; - public boolean idleTimeoutCountAsSleeping = false; + public String playerDeathExpDropEquation = "expLevel * 7"; + public int playerDeathExpDropMax = 100; + private void playerDeathExpSettings() { -- 2.26.2 diff --git a/patches/server/0092-Add-item-entity-options.patch b/patches/server/0092-Add-item-entity-options.patch index f1c34c477..2bb7c0ab9 100644 --- a/patches/server/0092-Add-item-entity-options.patch +++ b/patches/server/0092-Add-item-entity-options.patch @@ -1,89 +1,67 @@ -From 803cabc8255b5c859f12d23d9b40c48e97dc0789 Mon Sep 17 00:00:00 2001 +From 76f7a1f6f82f246c6c01016a1750dc9693e566de Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 22 Feb 2020 15:54:08 -0600 Subject: [PATCH] Add item entity options --- - .../java/net/minecraft/server/Entity.java | 1 + - .../java/net/minecraft/server/EntityItem.java | 9 ++++++++- - .../net/pl3x/purpur/PurpurWorldConfig.java | 19 +++++++++++++++++++ - 3 files changed, 28 insertions(+), 1 deletion(-) + src/main/java/net/minecraft/server/Entity.java | 1 + + src/main/java/net/minecraft/server/EntityItem.java | 4 +++- + .../java/net/pl3x/purpur/PurpurWorldConfig.java | 14 ++++++++++++++ + 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index 4fb6a3fd7..5a8005291 100644 +index 7f209e26f..3ae0cf87a 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java -@@ -1506,6 +1506,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke +@@ -1284,6 +1284,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } + public boolean isInLiquid(Tag tag) { return a(tag); } // Purpur - OBFHELPER public boolean a(Tag tag) { - return this.a(tag, false); + return this.O == tag; } diff --git a/src/main/java/net/minecraft/server/EntityItem.java b/src/main/java/net/minecraft/server/EntityItem.java -index bbb9ca1ef..262a7935e 100644 +index a7860cb4d..77e970c30 100644 --- a/src/main/java/net/minecraft/server/EntityItem.java +++ b/src/main/java/net/minecraft/server/EntityItem.java -@@ -71,7 +71,7 @@ public class EntityItem extends Entity { - this.lastZ = this.locZ(); - Vec3D vec3d = this.getMot(); +@@ -258,7 +258,7 @@ public class EntityItem extends Entity { -- if (this.a(TagsFluid.WATER)) { -+ if (isInLiquid(TagsFluid.WATER) || (world.purpurConfig.itemFloatInLava && isInLiquid(TagsFluid.LAVA))) { // Purpur - this.u(); - } else if (!this.isNoGravity()) { - this.setMot(this.getMot().add(0.0D, -0.04D, 0.0D)); -@@ -105,6 +105,7 @@ public class EntityItem extends Entity { + @Override + public boolean isFireProof() { +- return this.getItemStack().getItem().u() || super.isFireProof(); ++ return this.getItemStack().getItem().u() || super.isFireProof() || world.purpurConfig.itemImmuneToFire.contains(getItemStack().getItem()); + } - if (this.ticksLived % i == 0) { - if (this.world.getFluid(new BlockPosition(this)).a(TagsFluid.LAVA)) { -+ if (!world.purpurConfig.itemImmuneToLava.contains(getItemStack().getItem())) // Purpur - this.setMot((double) ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F), 0.20000000298023224D, (double) ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F)); - this.a(SoundEffects.ENTITY_GENERIC_BURN, 0.4F, 2.0F + this.random.nextFloat() * 0.4F); - } -@@ -282,6 +283,12 @@ public class EntityItem extends Entity { - } else if (!this.getItemStack().isEmpty() && this.getItemStack().getItem() == Items.NETHER_STAR && damagesource.isExplosion()) { + @Override +@@ -269,6 +269,8 @@ public class EntityItem extends Entity { return false; + } else if (!this.getItemStack().getItem().a(damagesource)) { + return false; ++ } else if ((damagesource.isFire() || damagesource == DamageSource.FIRE) && world.purpurConfig.itemImmuneToFire.contains(getItemStack().getItem())) { return false; // Purpur ++ } else if (damagesource.isExplosion() && world.purpurConfig.itemImmuneToExplosion.contains(getItemStack().getItem())) { return false; // Purpur } else { -+ // Purpur start -+ Item item = getItemStack().getItem(); -+ if (world.purpurConfig.itemImmuneToLava.contains(item) && damagesource == DamageSource.LAVA) return false; -+ if (world.purpurConfig.itemImmuneToFire.contains(item) && (damagesource.isFire() || damagesource == DamageSource.FIRE)) return false; -+ if (world.purpurConfig.itemImmuneToExplosion.contains(item) && damagesource.isExplosion()) return false; -+ // Purpur end // CraftBukkit start if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f)) { - return false; diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 0e34414a7..4cb856ebb 100644 +index 3f49a6a0b..b018bfe03 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -5,6 +5,8 @@ import net.minecraft.server.Block; - import net.minecraft.server.Blocks; - import net.minecraft.server.Explosion; - import net.minecraft.server.IRegistry; -+import net.minecraft.server.Item; -+import net.minecraft.server.Items; - import net.minecraft.server.MinecraftKey; +@@ -10,6 +10,7 @@ import net.minecraft.server.MinecraftKey; import org.bukkit.configuration.ConfigurationSection; import org.spigotmc.SpigotWorldConfig; -@@ -176,6 +178,10 @@ public class PurpurWorldConfig { - public Map controllableMinecartsBlockSpeeds = new HashMap<>(); - public boolean disableDropsOnCrammingDeath = false; - public boolean fixClimbingBypassingCrammingRule = false; -+ public boolean itemFloatInLava = false; + ++import java.util.ArrayList; + import java.util.HashMap; + import java.util.List; + import java.util.Map; +@@ -104,6 +105,19 @@ public class PurpurWorldConfig { + } + } + + public List itemImmuneToExplosion = new ArrayList<>(); + public List itemImmuneToFire = new ArrayList<>(); -+ public List itemImmuneToLava = new ArrayList<>(); - public boolean milkCuresBadOmen = true; - public String playerDeathExpDropEquation = "expLevel * 7"; - public int playerDeathExpDropMax = 100; -@@ -205,6 +211,19 @@ public class PurpurWorldConfig { - } - disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath); - fixClimbingBypassingCrammingRule = getBoolean("gameplay-mechanics.fix-climbing-bypassing-cramming-rule", fixClimbingBypassingCrammingRule); -+ itemFloatInLava = getBoolean("gameplay-mechanics.item.float-in-lava", itemFloatInLava); ++ private void itemSettings() { + getList("gameplay-mechanics.item.immune.explosion", itemImmuneToExplosion).forEach(key -> { + Item item = IRegistry.ITEM.get(new MinecraftKey((String) key)); + if (item != Items.AIR) itemImmuneToExplosion.add(item); @@ -92,13 +70,11 @@ index 0e34414a7..4cb856ebb 100644 + Item item = IRegistry.ITEM.get(new MinecraftKey((String) key)); + if (item != Items.AIR) itemImmuneToFire.add(item); + }); -+ getList("gameplay-mechanics.item.immune.lava", itemImmuneToLava).forEach(key -> { -+ Item item = IRegistry.ITEM.get(new MinecraftKey((String) key)); -+ if (item != Items.AIR) itemImmuneToLava.add(item); -+ }); - milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen); - playerDeathExpDropEquation = getString("gameplay-mechanics.player.exp-dropped-on-death.equation", playerDeathExpDropEquation); - playerDeathExpDropMax = getInt("gameplay-mechanics.player.exp-dropped-on-death.maximum", playerDeathExpDropMax); ++ } ++ + public boolean idleTimeoutKick = true; + public boolean idleTimeoutTickNearbyEntities = true; + public boolean idleTimeoutCountAsSleeping = false; -- 2.26.2 diff --git a/patches/server/0096-Add-ping-command.patch b/patches/server/0093-Add-ping-command.patch similarity index 73% rename from patches/server/0096-Add-ping-command.patch rename to patches/server/0093-Add-ping-command.patch index 5262e9951..0f6647a9c 100644 --- a/patches/server/0096-Add-ping-command.patch +++ b/patches/server/0093-Add-ping-command.patch @@ -1,4 +1,4 @@ -From e6af557e52c617e3ee4ef0931ce39c2a0829e52b Mon Sep 17 00:00:00 2001 +From 45840d21a9b5121e6d790b947b56c73b06987daa Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Fri, 13 Mar 2020 22:29:10 -0500 Subject: [PATCH] Add /ping command @@ -7,13 +7,13 @@ Subject: [PATCH] Add /ping command .../net/minecraft/server/ArgumentEntity.java | 2 ++ .../minecraft/server/CommandDispatcher.java | 5 ++- .../server/CommandListenerWrapper.java | 1 + - .../net/pl3x/purpur/command/PingCommand.java | 33 +++++++++++++++++++ - src/main/resources/purpur.lang | 1 + - 5 files changed, 41 insertions(+), 1 deletion(-) + .../java/net/pl3x/purpur/PurpurConfig.java | 2 ++ + .../net/pl3x/purpur/command/PingCommand.java | 34 +++++++++++++++++++ + 5 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 src/main/java/net/pl3x/purpur/command/PingCommand.java diff --git a/src/main/java/net/minecraft/server/ArgumentEntity.java b/src/main/java/net/minecraft/server/ArgumentEntity.java -index 39a6a9ac0..5568649b7 100644 +index 1194f91a5..9141976d1 100644 --- a/src/main/java/net/minecraft/server/ArgumentEntity.java +++ b/src/main/java/net/minecraft/server/ArgumentEntity.java @@ -69,10 +69,12 @@ public class ArgumentEntity implements ArgumentType { @@ -30,27 +30,27 @@ index 39a6a9ac0..5568649b7 100644 List list = ((EntitySelector) commandcontext.getArgument(s, EntitySelector.class)).d((CommandListenerWrapper) commandcontext.getSource()); diff --git a/src/main/java/net/minecraft/server/CommandDispatcher.java b/src/main/java/net/minecraft/server/CommandDispatcher.java -index 2d512aa4f..5aa10d16b 100644 +index 4ace0e79c..5e004f063 100644 --- a/src/main/java/net/minecraft/server/CommandDispatcher.java +++ b/src/main/java/net/minecraft/server/CommandDispatcher.java -@@ -30,7 +30,7 @@ import org.bukkit.event.server.ServerCommandEvent; +@@ -28,7 +28,7 @@ import org.bukkit.event.server.ServerCommandEvent; public class CommandDispatcher { private static final Logger LOGGER = LogManager.getLogger(); - private final com.mojang.brigadier.CommandDispatcher b = new com.mojang.brigadier.CommandDispatcher(); + private final com.mojang.brigadier.CommandDispatcher b = new com.mojang.brigadier.CommandDispatcher(); private com.mojang.brigadier.CommandDispatcher getDispatcher() { return b; } // Purpur - OBFHELPER - // CraftBukkit start - public final CommandDispatcher init(boolean flag) { -@@ -106,6 +106,7 @@ public class CommandDispatcher { + public CommandDispatcher(CommandDispatcher.ServerType commanddispatcher_servertype) { + this(); // CraftBukkit +@@ -105,6 +105,7 @@ public class CommandDispatcher { CommandIdleTimeout.a(this.b); CommandStop.a(this.b); CommandWhitelist.a(this.b); + net.pl3x.purpur.command.PingCommand.register(getDispatcher()); // Purpur } - this.b.findAmbiguities((commandnode, commandnode1, commandnode2, collection) -> { -@@ -332,10 +333,12 @@ public class CommandDispatcher { + if (commanddispatcher_servertype.d) { +@@ -335,10 +336,12 @@ public class CommandDispatcher { } @@ -64,10 +64,10 @@ index 2d512aa4f..5aa10d16b 100644 return RequiredArgumentBuilder.argument(s, argumenttype); } diff --git a/src/main/java/net/minecraft/server/CommandListenerWrapper.java b/src/main/java/net/minecraft/server/CommandListenerWrapper.java -index c988c929f..5c980b70c 100644 +index fa0f247e5..c8d53a854 100644 --- a/src/main/java/net/minecraft/server/CommandListenerWrapper.java +++ b/src/main/java/net/minecraft/server/CommandListenerWrapper.java -@@ -178,6 +178,7 @@ public class CommandListenerWrapper implements ICompletionProvider, com.destroys +@@ -179,6 +179,7 @@ public class CommandListenerWrapper implements ICompletionProvider, com.destroys } } @@ -75,19 +75,36 @@ index c988c929f..5c980b70c 100644 public EntityPlayer h() throws CommandSyntaxException { if (!(this.k instanceof EntityPlayer)) { throw CommandListenerWrapper.a.create(); +diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java +index f7e5d12cf..066ae1fec 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java +@@ -132,9 +132,11 @@ public class PurpurConfig { + + public static String afkBroadcastAway = "§e§o%s is now AFK"; + public static String afkBroadcastBack = "§e§o%s is no longer AFK"; ++ public static String pingCommandOutput = "§a%s's ping is %sms"; + private static void messages() { + afkBroadcastAway = getString("settings.messages.afk-broadcast-away", afkBroadcastAway); + afkBroadcastBack = getString("settings.messages.afk-broadcast-back", afkBroadcastBack); ++ pingCommandOutput = getString("settings.messages.ping-command-output", pingCommandOutput); + } + + public static String serverModName = "Purpur"; diff --git a/src/main/java/net/pl3x/purpur/command/PingCommand.java b/src/main/java/net/pl3x/purpur/command/PingCommand.java new file mode 100644 -index 000000000..dac3083bf +index 000000000..4b0f38b0a --- /dev/null +++ b/src/main/java/net/pl3x/purpur/command/PingCommand.java -@@ -0,0 +1,33 @@ +@@ -0,0 +1,34 @@ +package net.pl3x.purpur.command; + +import net.minecraft.server.ArgumentEntity; +import net.minecraft.server.CommandDispatcher; +import net.minecraft.server.CommandListenerWrapper; +import net.minecraft.server.EntityPlayer; -+import net.minecraft.server.LocaleLanguage; ++import net.pl3x.purpur.PurpurConfig; ++import org.bukkit.craftbukkit.util.CraftChatMessage; + +import java.util.Collection; +import java.util.Collections; @@ -109,22 +126,11 @@ index 000000000..dac3083bf + + private static int execute(CommandListenerWrapper sender, Collection targets) { + for (EntityPlayer player : targets) { -+ sender.sendMessage(LocaleLanguage.translate("commands.purpur.ping", player.getScoreboardDisplayName(), player.ping), false); ++ sender.sendMessage(CraftChatMessage.fromString(PurpurConfig.pingCommandOutput)[0], false); + } + return targets.size(); + } +} -diff --git a/src/main/resources/purpur.lang b/src/main/resources/purpur.lang -index e925e1374..e81beea7f 100644 ---- a/src/main/resources/purpur.lang -+++ b/src/main/resources/purpur.lang -@@ -1,5 +1,6 @@ - { - "cannot.ride.mob": "You cannot mount that mob", -+ "commands.purpur.ping": "§a%s's ping is %sms", - "idle.timeout.broadcast.away": "§e§o%s is now AFK", - "idle.timeout.broadcast.back": "§e§o%s is no longer AFK" - } -- 2.26.2 diff --git a/patches/server/0093-Make-natural-spawns-per-biome-configurable.patch b/patches/server/0093-Make-natural-spawns-per-biome-configurable.patch deleted file mode 100644 index de4ba4529..000000000 --- a/patches/server/0093-Make-natural-spawns-per-biome-configurable.patch +++ /dev/null @@ -1,2967 +0,0 @@ -From bbb6f2f3b18209e87ea8c20a18e88a90eac64f7e Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Thu, 27 Feb 2020 13:39:06 -0600 -Subject: [PATCH] Make natural spawns per biome configurable - ---- - .../minecraft/server/BiomeBambooJungle.java | 18 +- - .../server/BiomeBambooJungleHills.java | 18 +- - .../java/net/minecraft/server/BiomeBase.java | 31 +- - .../java/net/minecraft/server/BiomeBeach.java | 11 +- - .../net/minecraft/server/BiomeBigHills.java | 15 +- - .../minecraft/server/BiomeBirchForest.java | 14 +- - .../server/BiomeBirchForestHills.java | 14 +- - .../server/BiomeBirchForestHillsMutated.java | 14 +- - .../server/BiomeBirchForestMutated.java | 14 +- - .../net/minecraft/server/BiomeColdBeach.java | 10 +- - .../minecraft/server/BiomeColdDeepOcean.java | 14 +- - .../net/minecraft/server/BiomeColdOcean.java | 14 +- - .../net/minecraft/server/BiomeColdTaiga.java | 17 +- - .../minecraft/server/BiomeColdTaigaHills.java | 17 +- - .../server/BiomeColdTaigaMutated.java | 17 +- - .../net/minecraft/server/BiomeDeepOcean.java | 14 +- - .../net/minecraft/server/BiomeDesert.java | 12 +- - .../minecraft/server/BiomeDesertHills.java | 12 +- - .../minecraft/server/BiomeDesertMutated.java | 12 +- - .../server/BiomeExtremeHillsEdge.java | 15 +- - .../server/BiomeExtremeHillsMutated.java | 15 +- - .../server/BiomeExtremeHillsWithTrees.java | 15 +- - .../BiomeExtremeHillsWithTreesMutated.java | 15 +- - .../minecraft/server/BiomeFlowerForest.java | 15 +- - .../net/minecraft/server/BiomeForest.java | 15 +- - .../minecraft/server/BiomeForestHills.java | 15 +- - .../server/BiomeFrozenDeepOcean.java | 14 +- - .../minecraft/server/BiomeFrozenOcean.java | 14 +- - .../minecraft/server/BiomeFrozenRiver.java | 13 +- - .../java/net/minecraft/server/BiomeHell.java | 5 +- - .../minecraft/server/BiomeIceMountains.java | 13 +- - .../net/minecraft/server/BiomeIcePlains.java | 13 +- - .../server/BiomeIcePlainsSpikes.java | 13 +- - .../net/minecraft/server/BiomeJungle.java | 18 +- - .../net/minecraft/server/BiomeJungleEdge.java | 15 +- - .../server/BiomeJungleEdgeMutated.java | 15 +- - .../minecraft/server/BiomeJungleHills.java | 18 +- - .../minecraft/server/BiomeJungleMutated.java | 17 +- - .../server/BiomeLukewarmDeepOcean.java | 16 +- - .../minecraft/server/BiomeLukewarmOcean.java | 16 +- - .../server/BiomeMegaSpruceTaiga.java | 17 +- - .../net/minecraft/server/BiomeMegaTaiga.java | 17 +- - .../minecraft/server/BiomeMegaTaigaHills.java | 17 +- - .../java/net/minecraft/server/BiomeMesa.java | 10 +- - .../net/minecraft/server/BiomeMesaBryce.java | 10 +- - .../minecraft/server/BiomeMesaPlataeu.java | 10 +- - .../server/BiomeMesaPlataeuClear.java | 10 +- - .../server/BiomeMesaPlateauClearMutated.java | 10 +- - .../server/BiomeMesaPlateauMutated.java | 10 +- - .../server/BiomeMushroomIslandShore.java | 3 +- - .../net/minecraft/server/BiomeMushrooms.java | 3 +- - .../java/net/minecraft/server/BiomeOcean.java | 14 +- - .../net/minecraft/server/BiomePlains.java | 16 +- - .../server/BiomeRedwoodTaigaHillsMutated.java | 17 +- - .../java/net/minecraft/server/BiomeRiver.java | 13 +- - .../minecraft/server/BiomeRoofedForest.java | 14 +- - .../server/BiomeRoofedForestMutated.java | 14 +- - .../net/minecraft/server/BiomeSavanna.java | 16 +- - .../minecraft/server/BiomeSavannaMutated.java | 16 +- - .../minecraft/server/BiomeSavannaPlateau.java | 17 +- - .../server/BiomeSavannaPlateauMutated.java | 16 +- - .../net/minecraft/server/BiomeStoneBeach.java | 10 +- - .../server/BiomeSunflowerPlains.java | 16 +- - .../java/net/minecraft/server/BiomeSwamp.java | 15 +- - .../server/BiomeSwamplandMutated.java | 15 +- - .../java/net/minecraft/server/BiomeTaiga.java | 17 +- - .../net/minecraft/server/BiomeTaigaHills.java | 17 +- - .../minecraft/server/BiomeTaigaMutated.java | 17 +- - .../net/minecraft/server/BiomeTheEnd.java | 2 +- - .../server/BiomeTheEndBarrenIsland.java | 2 +- - .../server/BiomeTheEndFloatingIslands.java | 2 +- - .../server/BiomeTheEndHighIsland.java | 2 +- - .../server/BiomeTheEndMediumIsland.java | 2 +- - .../java/net/minecraft/server/BiomeVoid.java | 1 + - .../minecraft/server/BiomeWarmDeepOcean.java | 14 +- - .../net/minecraft/server/BiomeWarmOcean.java | 14 +- - .../java/net/minecraft/server/Biomes.java | 28 + - src/main/resources/biomes.yml | 1042 +++++++++++++++++ - 78 files changed, 1174 insertions(+), 905 deletions(-) - create mode 100644 src/main/resources/biomes.yml - -diff --git a/src/main/java/net/minecraft/server/BiomeBambooJungle.java b/src/main/java/net/minecraft/server/BiomeBambooJungle.java -index 9c38f8907..3980504d9 100644 ---- a/src/main/java/net/minecraft/server/BiomeBambooJungle.java -+++ b/src/main/java/net/minecraft/server/BiomeBambooJungle.java -@@ -22,22 +22,6 @@ public class BiomeBambooJungle extends BiomeBase { - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ac(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PARROT, 40, 1, 2)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PANDA, 80, 1, 2)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.OCELOT, 2, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeBambooJungleHills.java b/src/main/java/net/minecraft/server/BiomeBambooJungleHills.java -index 2a6dafccd..501314da9 100644 ---- a/src/main/java/net/minecraft/server/BiomeBambooJungleHills.java -+++ b/src/main/java/net/minecraft/server/BiomeBambooJungleHills.java -@@ -22,22 +22,6 @@ public final class BiomeBambooJungleHills extends BiomeBase { - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ac(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PARROT, 10, 1, 1)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PANDA, 80, 1, 2)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.OCELOT, 2, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeBase.java b/src/main/java/net/minecraft/server/BiomeBase.java -index ef6c85557..51bc8643f 100644 ---- a/src/main/java/net/minecraft/server/BiomeBase.java -+++ b/src/main/java/net/minecraft/server/BiomeBase.java -@@ -17,8 +17,25 @@ import org.apache.logging.log4j.Logger; - - public abstract class BiomeBase { - -+ // Purpur start -+ protected static org.bukkit.configuration.file.YamlConfiguration biomeData; -+ -+ static { -+ String filename = "biomes.yml"; -+ java.io.File file = new java.io.File(filename); -+ if (!file.exists()) { -+ try { -+ java.nio.file.Files.copy(BiomeBase.class.getResourceAsStream("/" + filename), file.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING); -+ } catch (Exception e) { -+ MinecraftServer.LOGGER.error("Unable to save biomes.yml!", e); -+ } -+ } -+ biomeData = org.bukkit.configuration.file.YamlConfiguration.loadConfiguration(file); -+ } -+ // Purpur end -+ - public static final Logger LOGGER = LogManager.getLogger(); -- public static final Set b = Sets.newHashSet(); -+ public static final Set b = Sets.newHashSet(); public static Set getBiomes() { return b; } // Purpur - OBFHELPER - public static final RegistryBlockID c = new RegistryBlockID<>(); - protected static final NoiseGenerator3 d = new NoiseGenerator3(new SeededRandom(1234L), 0, 0); - public static final NoiseGenerator3 e = new NoiseGenerator3(new SeededRandom(2345L), 0, 0); -@@ -40,7 +57,7 @@ public abstract class BiomeBase { - protected final Map>> r = Maps.newHashMap(); - protected final List> s = Lists.newArrayList(); - protected final Map, WorldGenFeatureConfiguration> t = Maps.newHashMap(); -- private final java.util.EnumMap> v = Maps.newEnumMap(EnumCreatureType.class); // Paper -+ private final java.util.EnumMap> v = Maps.newEnumMap(EnumCreatureType.class); private java.util.EnumMap> getSpawnData() { return v; } // Paper // Purpur - OBFHELPER - private final ThreadLocal w = ThreadLocal.withInitial(() -> { - return (Long2FloatLinkedOpenHashMap) SystemUtils.a(() -> { - Long2FloatLinkedOpenHashMap long2floatlinkedopenhashmap = new Long2FloatLinkedOpenHashMap(1024, 0.25F) { -@@ -124,6 +141,16 @@ public abstract class BiomeBase { - return MathHelper.f(0.62222224F - f * 0.05F, 0.5F + f * 0.1F, 1.0F); - } - -+ // Purpur start -+ protected void addMobSpawn(EntityTypes type, int weight, int min, int max) { -+ getSpawnData().get(type.getEnumCreatureType()).add(new BiomeMeta(type, weight, min, max)); -+ } -+ -+ public String getName() { -+ return IRegistry.BIOME.getKey(this).getKey(); -+ } -+ // Purpur end -+ - protected void a(EnumCreatureType enumcreaturetype, BiomeBase.BiomeMeta biomebase_biomemeta) { - ((List) this.v.get(enumcreaturetype)).add(biomebase_biomemeta); - } -diff --git a/src/main/java/net/minecraft/server/BiomeBeach.java b/src/main/java/net/minecraft/server/BiomeBeach.java -index f4e9345ae..d8ff2c9a2 100644 ---- a/src/main/java/net/minecraft/server/BiomeBeach.java -+++ b/src/main/java/net/minecraft/server/BiomeBeach.java -@@ -20,15 +20,6 @@ public final class BiomeBeach extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.TURTLE, 5, 2, 5)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeBigHills.java b/src/main/java/net/minecraft/server/BiomeBigHills.java -index 58c30f652..710726742 100644 ---- a/src/main/java/net/minecraft/server/BiomeBigHills.java -+++ b/src/main/java/net/minecraft/server/BiomeBigHills.java -@@ -22,19 +22,6 @@ public final class BiomeBigHills extends BiomeBase { - BiomeDecoratorGroups.j(this); - BiomeDecoratorGroups.k(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.LLAMA, 5, 4, 6)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeBirchForest.java b/src/main/java/net/minecraft/server/BiomeBirchForest.java -index 9437438c8..1749c258b 100644 ---- a/src/main/java/net/minecraft/server/BiomeBirchForest.java -+++ b/src/main/java/net/minecraft/server/BiomeBirchForest.java -@@ -21,18 +21,6 @@ public final class BiomeBirchForest extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeBirchForestHills.java b/src/main/java/net/minecraft/server/BiomeBirchForestHills.java -index 3e5c23d31..5d262c971 100644 ---- a/src/main/java/net/minecraft/server/BiomeBirchForestHills.java -+++ b/src/main/java/net/minecraft/server/BiomeBirchForestHills.java -@@ -21,18 +21,6 @@ public final class BiomeBirchForestHills extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeBirchForestHillsMutated.java b/src/main/java/net/minecraft/server/BiomeBirchForestHillsMutated.java -index d5eb5c91c..de048fb48 100644 ---- a/src/main/java/net/minecraft/server/BiomeBirchForestHillsMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeBirchForestHillsMutated.java -@@ -21,18 +21,6 @@ public final class BiomeBirchForestHillsMutated extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeBirchForestMutated.java b/src/main/java/net/minecraft/server/BiomeBirchForestMutated.java -index e805f9568..2115b05ca 100644 ---- a/src/main/java/net/minecraft/server/BiomeBirchForestMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeBirchForestMutated.java -@@ -21,18 +21,6 @@ public final class BiomeBirchForestMutated extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeColdBeach.java b/src/main/java/net/minecraft/server/BiomeColdBeach.java -index 1b92f4567..210226e19 100644 ---- a/src/main/java/net/minecraft/server/BiomeColdBeach.java -+++ b/src/main/java/net/minecraft/server/BiomeColdBeach.java -@@ -20,14 +20,6 @@ public final class BiomeColdBeach extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeColdDeepOcean.java b/src/main/java/net/minecraft/server/BiomeColdDeepOcean.java -index b9a5cb63a..3622ef669 100644 ---- a/src/main/java/net/minecraft/server/BiomeColdDeepOcean.java -+++ b/src/main/java/net/minecraft/server/BiomeColdDeepOcean.java -@@ -25,18 +25,6 @@ public class BiomeColdDeepOcean extends BiomeBase { - BiomeDecoratorGroups.ai(this); - BiomeDecoratorGroups.ah(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SQUID, 3, 1, 4)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COD, 15, 3, 6)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SALMON, 15, 1, 5)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.DROWNED, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeColdOcean.java b/src/main/java/net/minecraft/server/BiomeColdOcean.java -index 571c3d139..c640aa9ee 100644 ---- a/src/main/java/net/minecraft/server/BiomeColdOcean.java -+++ b/src/main/java/net/minecraft/server/BiomeColdOcean.java -@@ -24,18 +24,6 @@ public class BiomeColdOcean extends BiomeBase { - BiomeDecoratorGroups.ai(this); - BiomeDecoratorGroups.ah(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SQUID, 3, 1, 4)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COD, 15, 3, 6)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SALMON, 15, 1, 5)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.DROWNED, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeColdTaiga.java b/src/main/java/net/minecraft/server/BiomeColdTaiga.java -index 88400e77b..caaa8ec99 100644 ---- a/src/main/java/net/minecraft/server/BiomeColdTaiga.java -+++ b/src/main/java/net/minecraft/server/BiomeColdTaiga.java -@@ -23,21 +23,6 @@ public final class BiomeColdTaiga extends BiomeBase { - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.p(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.WOLF, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.RABBIT, 4, 2, 3)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.FOX, 8, 2, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeColdTaigaHills.java b/src/main/java/net/minecraft/server/BiomeColdTaigaHills.java -index 8a8fc7dbd..323f20452 100644 ---- a/src/main/java/net/minecraft/server/BiomeColdTaigaHills.java -+++ b/src/main/java/net/minecraft/server/BiomeColdTaigaHills.java -@@ -22,21 +22,6 @@ public final class BiomeColdTaigaHills extends BiomeBase { - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.p(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.WOLF, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.RABBIT, 4, 2, 3)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.FOX, 8, 2, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeColdTaigaMutated.java b/src/main/java/net/minecraft/server/BiomeColdTaigaMutated.java -index 327e6847f..973eb8eeb 100644 ---- a/src/main/java/net/minecraft/server/BiomeColdTaigaMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeColdTaigaMutated.java -@@ -22,21 +22,6 @@ public final class BiomeColdTaigaMutated extends BiomeBase { - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.p(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.WOLF, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.RABBIT, 4, 2, 3)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.FOX, 8, 2, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeDeepOcean.java b/src/main/java/net/minecraft/server/BiomeDeepOcean.java -index 651d44cb3..7088603b1 100644 ---- a/src/main/java/net/minecraft/server/BiomeDeepOcean.java -+++ b/src/main/java/net/minecraft/server/BiomeDeepOcean.java -@@ -25,18 +25,6 @@ public final class BiomeDeepOcean extends BiomeBase { - BiomeDecoratorGroups.ai(this); - BiomeDecoratorGroups.ah(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SQUID, 1, 1, 4)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COD, 10, 3, 6)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.DOLPHIN, 1, 1, 2)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.DROWNED, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeDesert.java b/src/main/java/net/minecraft/server/BiomeDesert.java -index 257732dad..168614fe5 100644 ---- a/src/main/java/net/minecraft/server/BiomeDesert.java -+++ b/src/main/java/net/minecraft/server/BiomeDesert.java -@@ -24,16 +24,6 @@ public final class BiomeDesert extends BiomeBase { - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.af(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.RABBIT, 4, 2, 3)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 19, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 1, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.HUSK, 80, 4, 4)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeDesertHills.java b/src/main/java/net/minecraft/server/BiomeDesertHills.java -index 3752fc450..4df443701 100644 ---- a/src/main/java/net/minecraft/server/BiomeDesertHills.java -+++ b/src/main/java/net/minecraft/server/BiomeDesertHills.java -@@ -22,16 +22,6 @@ public final class BiomeDesertHills extends BiomeBase { - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.af(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.RABBIT, 4, 2, 3)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 19, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 1, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.HUSK, 80, 4, 4)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeDesertMutated.java b/src/main/java/net/minecraft/server/BiomeDesertMutated.java -index 1a0b56932..ac565c382 100644 ---- a/src/main/java/net/minecraft/server/BiomeDesertMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeDesertMutated.java -@@ -21,16 +21,6 @@ public final class BiomeDesertMutated extends BiomeBase { - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.af(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.RABBIT, 4, 2, 3)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 19, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 1, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.HUSK, 80, 4, 4)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeExtremeHillsEdge.java b/src/main/java/net/minecraft/server/BiomeExtremeHillsEdge.java -index 8e19e0688..93f9c55bb 100644 ---- a/src/main/java/net/minecraft/server/BiomeExtremeHillsEdge.java -+++ b/src/main/java/net/minecraft/server/BiomeExtremeHillsEdge.java -@@ -22,19 +22,6 @@ public final class BiomeExtremeHillsEdge extends BiomeBase { - BiomeDecoratorGroups.j(this); - BiomeDecoratorGroups.k(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.LLAMA, 5, 4, 6)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeExtremeHillsMutated.java b/src/main/java/net/minecraft/server/BiomeExtremeHillsMutated.java -index 69d4880c7..5c73ee4fb 100644 ---- a/src/main/java/net/minecraft/server/BiomeExtremeHillsMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeExtremeHillsMutated.java -@@ -22,19 +22,6 @@ public final class BiomeExtremeHillsMutated extends BiomeBase { - BiomeDecoratorGroups.j(this); - BiomeDecoratorGroups.k(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.LLAMA, 5, 4, 6)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeExtremeHillsWithTrees.java b/src/main/java/net/minecraft/server/BiomeExtremeHillsWithTrees.java -index 7661d5316..7bc4631db 100644 ---- a/src/main/java/net/minecraft/server/BiomeExtremeHillsWithTrees.java -+++ b/src/main/java/net/minecraft/server/BiomeExtremeHillsWithTrees.java -@@ -22,19 +22,6 @@ public final class BiomeExtremeHillsWithTrees extends BiomeBase { - BiomeDecoratorGroups.j(this); - BiomeDecoratorGroups.k(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.LLAMA, 5, 4, 6)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeExtremeHillsWithTreesMutated.java b/src/main/java/net/minecraft/server/BiomeExtremeHillsWithTreesMutated.java -index 05418f8fa..b618c7e33 100644 ---- a/src/main/java/net/minecraft/server/BiomeExtremeHillsWithTreesMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeExtremeHillsWithTreesMutated.java -@@ -22,19 +22,6 @@ public final class BiomeExtremeHillsWithTreesMutated extends BiomeBase { - BiomeDecoratorGroups.j(this); - BiomeDecoratorGroups.k(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.LLAMA, 5, 4, 6)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeFlowerForest.java b/src/main/java/net/minecraft/server/BiomeFlowerForest.java -index 1d3f62432..1d0809c2c 100644 ---- a/src/main/java/net/minecraft/server/BiomeFlowerForest.java -+++ b/src/main/java/net/minecraft/server/BiomeFlowerForest.java -@@ -23,19 +23,6 @@ public final class BiomeFlowerForest extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.RABBIT, 4, 2, 3)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeForest.java b/src/main/java/net/minecraft/server/BiomeForest.java -index e849b411c..2b69a128a 100644 ---- a/src/main/java/net/minecraft/server/BiomeForest.java -+++ b/src/main/java/net/minecraft/server/BiomeForest.java -@@ -22,19 +22,6 @@ public final class BiomeForest extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.WOLF, 5, 4, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeForestHills.java b/src/main/java/net/minecraft/server/BiomeForestHills.java -index f7dea38eb..57c709181 100644 ---- a/src/main/java/net/minecraft/server/BiomeForestHills.java -+++ b/src/main/java/net/minecraft/server/BiomeForestHills.java -@@ -22,19 +22,6 @@ public final class BiomeForestHills extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.WOLF, 5, 4, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeFrozenDeepOcean.java b/src/main/java/net/minecraft/server/BiomeFrozenDeepOcean.java -index 67d120bef..f1ab35f2f 100644 ---- a/src/main/java/net/minecraft/server/BiomeFrozenDeepOcean.java -+++ b/src/main/java/net/minecraft/server/BiomeFrozenDeepOcean.java -@@ -26,19 +26,7 @@ public class BiomeFrozenDeepOcean extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SQUID, 1, 1, 4)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SALMON, 15, 1, 5)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.POLAR_BEAR, 1, 1, 2)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.DROWNED, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - - @Override -diff --git a/src/main/java/net/minecraft/server/BiomeFrozenOcean.java b/src/main/java/net/minecraft/server/BiomeFrozenOcean.java -index 2772bc6da..3941438d9 100644 ---- a/src/main/java/net/minecraft/server/BiomeFrozenOcean.java -+++ b/src/main/java/net/minecraft/server/BiomeFrozenOcean.java -@@ -25,19 +25,7 @@ public final class BiomeFrozenOcean extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SQUID, 1, 1, 4)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SALMON, 15, 1, 5)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.POLAR_BEAR, 1, 1, 2)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.DROWNED, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - - @Override -diff --git a/src/main/java/net/minecraft/server/BiomeFrozenRiver.java b/src/main/java/net/minecraft/server/BiomeFrozenRiver.java -index 4be53fc0f..f5d98bcac 100644 ---- a/src/main/java/net/minecraft/server/BiomeFrozenRiver.java -+++ b/src/main/java/net/minecraft/server/BiomeFrozenRiver.java -@@ -19,17 +19,6 @@ public final class BiomeFrozenRiver extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SQUID, 2, 1, 4)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SALMON, 5, 1, 5)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.DROWNED, 1, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeHell.java b/src/main/java/net/minecraft/server/BiomeHell.java -index 888dfcd8d..dd3375ef8 100644 ---- a/src/main/java/net/minecraft/server/BiomeHell.java -+++ b/src/main/java/net/minecraft/server/BiomeHell.java -@@ -18,9 +18,6 @@ public final class BiomeHell extends BiomeBase { - this.a(WorldGenStage.Decoration.UNDERGROUND_DECORATION, WorldGenerator.ORE.b(new WorldGenFeatureOreConfiguration(WorldGenFeatureOreConfiguration.Target.NETHERRACK, Blocks.NETHER_QUARTZ_ORE.getBlockData(), 14)).a(WorldGenDecorator.n.a(new WorldGenFeatureChanceDecoratorCountConfiguration(16, 10, 20, 128)))); // Purpur - decompile error - this.a(WorldGenStage.Decoration.UNDERGROUND_DECORATION, WorldGenerator.ORE.b(new WorldGenFeatureOreConfiguration(WorldGenFeatureOreConfiguration.Target.NETHERRACK, Blocks.MAGMA_BLOCK.getBlockData(), 33)).a(WorldGenDecorator.B.a(new WorldGenDecoratorFrequencyConfiguration(4)))); // Purpur - decompile error - this.a(WorldGenStage.Decoration.UNDERGROUND_DECORATION, WorldGenerator.SPRING_FEATURE.b(BiomeDecoratorGroups.ae).a(WorldGenDecorator.n.a(new WorldGenFeatureChanceDecoratorCountConfiguration(16, 10, 20, 128)))); // Purpur - decompile error -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.GHAST, 50, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_PIGMAN, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.MAGMA_CUBE, 2, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 1, 4, 4)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeIceMountains.java b/src/main/java/net/minecraft/server/BiomeIceMountains.java -index ad9b4efe0..0e98efb9e 100644 ---- a/src/main/java/net/minecraft/server/BiomeIceMountains.java -+++ b/src/main/java/net/minecraft/server/BiomeIceMountains.java -@@ -20,18 +20,7 @@ public final class BiomeIceMountains extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.RABBIT, 10, 2, 3)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.POLAR_BEAR, 1, 1, 2)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 20, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.STRAY, 80, 4, 4)); -+ // Purpur - remove hardcoded natural spawn data - } - - @Override -diff --git a/src/main/java/net/minecraft/server/BiomeIcePlains.java b/src/main/java/net/minecraft/server/BiomeIcePlains.java -index 71606b0a7..ba0a16faa 100644 ---- a/src/main/java/net/minecraft/server/BiomeIcePlains.java -+++ b/src/main/java/net/minecraft/server/BiomeIcePlains.java -@@ -23,18 +23,7 @@ public final class BiomeIcePlains extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.RABBIT, 10, 2, 3)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.POLAR_BEAR, 1, 1, 2)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 20, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.STRAY, 80, 4, 4)); -+ // Purpur - remove hardcoded natural spawn data - } - - @Override -diff --git a/src/main/java/net/minecraft/server/BiomeIcePlainsSpikes.java b/src/main/java/net/minecraft/server/BiomeIcePlainsSpikes.java -index 984f94bb5..375ccf9c4 100644 ---- a/src/main/java/net/minecraft/server/BiomeIcePlainsSpikes.java -+++ b/src/main/java/net/minecraft/server/BiomeIcePlainsSpikes.java -@@ -22,18 +22,7 @@ public final class BiomeIcePlainsSpikes extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.RABBIT, 10, 2, 3)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.POLAR_BEAR, 1, 1, 2)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 20, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.STRAY, 80, 4, 4)); -+ // Purpur - remove hardcoded natural spawn data - } - - @Override -diff --git a/src/main/java/net/minecraft/server/BiomeJungle.java b/src/main/java/net/minecraft/server/BiomeJungle.java -index 95e501996..2b154a276 100644 ---- a/src/main/java/net/minecraft/server/BiomeJungle.java -+++ b/src/main/java/net/minecraft/server/BiomeJungle.java -@@ -23,22 +23,6 @@ public final class BiomeJungle extends BiomeBase { - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ac(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PARROT, 40, 1, 2)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PANDA, 1, 1, 2)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.OCELOT, 2, 1, 3)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeJungleEdge.java b/src/main/java/net/minecraft/server/BiomeJungleEdge.java -index e624f9764..e6cf5d853 100644 ---- a/src/main/java/net/minecraft/server/BiomeJungleEdge.java -+++ b/src/main/java/net/minecraft/server/BiomeJungleEdge.java -@@ -21,19 +21,6 @@ public final class BiomeJungleEdge extends BiomeBase { - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ac(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeJungleEdgeMutated.java b/src/main/java/net/minecraft/server/BiomeJungleEdgeMutated.java -index 1fe9c840a..d4c9907b2 100644 ---- a/src/main/java/net/minecraft/server/BiomeJungleEdgeMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeJungleEdgeMutated.java -@@ -21,19 +21,6 @@ public final class BiomeJungleEdgeMutated extends BiomeBase { - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ac(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeJungleHills.java b/src/main/java/net/minecraft/server/BiomeJungleHills.java -index e2970ab00..9e7b702c8 100644 ---- a/src/main/java/net/minecraft/server/BiomeJungleHills.java -+++ b/src/main/java/net/minecraft/server/BiomeJungleHills.java -@@ -23,22 +23,6 @@ public final class BiomeJungleHills extends BiomeBase { - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ac(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PARROT, 10, 1, 1)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PANDA, 1, 1, 2)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.OCELOT, 2, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeJungleMutated.java b/src/main/java/net/minecraft/server/BiomeJungleMutated.java -index ffe6b4344..f308e0dd4 100644 ---- a/src/main/java/net/minecraft/server/BiomeJungleMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeJungleMutated.java -@@ -21,21 +21,6 @@ public final class BiomeJungleMutated extends BiomeBase { - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ac(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PARROT, 10, 1, 1)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.OCELOT, 2, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeLukewarmDeepOcean.java b/src/main/java/net/minecraft/server/BiomeLukewarmDeepOcean.java -index b23c43305..092233c50 100644 ---- a/src/main/java/net/minecraft/server/BiomeLukewarmDeepOcean.java -+++ b/src/main/java/net/minecraft/server/BiomeLukewarmDeepOcean.java -@@ -25,20 +25,6 @@ public class BiomeLukewarmDeepOcean extends BiomeBase { - BiomeDecoratorGroups.ai(this); - BiomeDecoratorGroups.al(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SQUID, 8, 1, 4)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COD, 8, 3, 6)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PUFFERFISH, 5, 1, 3)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.TROPICAL_FISH, 25, 8, 8)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.DOLPHIN, 2, 1, 2)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.DROWNED, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeLukewarmOcean.java b/src/main/java/net/minecraft/server/BiomeLukewarmOcean.java -index efcb11bbe..1cebd5ce7 100644 ---- a/src/main/java/net/minecraft/server/BiomeLukewarmOcean.java -+++ b/src/main/java/net/minecraft/server/BiomeLukewarmOcean.java -@@ -23,20 +23,6 @@ public class BiomeLukewarmOcean extends BiomeBase { - BiomeDecoratorGroups.aj(this); - BiomeDecoratorGroups.al(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SQUID, 10, 1, 2)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COD, 15, 3, 6)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PUFFERFISH, 5, 1, 3)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.TROPICAL_FISH, 25, 8, 8)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.DOLPHIN, 2, 1, 2)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.DROWNED, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeMegaSpruceTaiga.java b/src/main/java/net/minecraft/server/BiomeMegaSpruceTaiga.java -index 328e939a6..d0fe6c449 100644 ---- a/src/main/java/net/minecraft/server/BiomeMegaSpruceTaiga.java -+++ b/src/main/java/net/minecraft/server/BiomeMegaSpruceTaiga.java -@@ -23,21 +23,6 @@ public final class BiomeMegaSpruceTaiga extends BiomeBase { - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.q(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.WOLF, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.RABBIT, 4, 2, 3)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.FOX, 8, 2, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeMegaTaiga.java b/src/main/java/net/minecraft/server/BiomeMegaTaiga.java -index 36bea710a..e3aad431e 100644 ---- a/src/main/java/net/minecraft/server/BiomeMegaTaiga.java -+++ b/src/main/java/net/minecraft/server/BiomeMegaTaiga.java -@@ -23,21 +23,6 @@ public final class BiomeMegaTaiga extends BiomeBase { - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.q(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.WOLF, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.RABBIT, 4, 2, 3)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.FOX, 8, 2, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 25, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeMegaTaigaHills.java b/src/main/java/net/minecraft/server/BiomeMegaTaigaHills.java -index 22474d682..2ef445ce6 100644 ---- a/src/main/java/net/minecraft/server/BiomeMegaTaigaHills.java -+++ b/src/main/java/net/minecraft/server/BiomeMegaTaigaHills.java -@@ -23,21 +23,6 @@ public final class BiomeMegaTaigaHills extends BiomeBase { - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.q(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.WOLF, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.RABBIT, 4, 2, 3)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.FOX, 8, 2, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 25, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeMesa.java b/src/main/java/net/minecraft/server/BiomeMesa.java -index 65d606d51..8906115d4 100644 ---- a/src/main/java/net/minecraft/server/BiomeMesa.java -+++ b/src/main/java/net/minecraft/server/BiomeMesa.java -@@ -19,14 +19,6 @@ public final class BiomeMesa extends BiomeBase { - BiomeDecoratorGroups.ab(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeMesaBryce.java b/src/main/java/net/minecraft/server/BiomeMesaBryce.java -index 5ecec62f1..401fbd2d1 100644 ---- a/src/main/java/net/minecraft/server/BiomeMesaBryce.java -+++ b/src/main/java/net/minecraft/server/BiomeMesaBryce.java -@@ -19,14 +19,6 @@ public final class BiomeMesaBryce extends BiomeBase { - BiomeDecoratorGroups.ab(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeMesaPlataeu.java b/src/main/java/net/minecraft/server/BiomeMesaPlataeu.java -index 14d4bd312..77a5828f0 100644 ---- a/src/main/java/net/minecraft/server/BiomeMesaPlataeu.java -+++ b/src/main/java/net/minecraft/server/BiomeMesaPlataeu.java -@@ -20,14 +20,6 @@ public final class BiomeMesaPlataeu extends BiomeBase { - BiomeDecoratorGroups.ab(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeMesaPlataeuClear.java b/src/main/java/net/minecraft/server/BiomeMesaPlataeuClear.java -index b5dab9d2a..a88831255 100644 ---- a/src/main/java/net/minecraft/server/BiomeMesaPlataeuClear.java -+++ b/src/main/java/net/minecraft/server/BiomeMesaPlataeuClear.java -@@ -19,14 +19,6 @@ public final class BiomeMesaPlataeuClear extends BiomeBase { - BiomeDecoratorGroups.ab(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeMesaPlateauClearMutated.java b/src/main/java/net/minecraft/server/BiomeMesaPlateauClearMutated.java -index d05cc38b5..be0738713 100644 ---- a/src/main/java/net/minecraft/server/BiomeMesaPlateauClearMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeMesaPlateauClearMutated.java -@@ -19,14 +19,6 @@ public final class BiomeMesaPlateauClearMutated extends BiomeBase { - BiomeDecoratorGroups.ab(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeMesaPlateauMutated.java b/src/main/java/net/minecraft/server/BiomeMesaPlateauMutated.java -index 21a77ee81..2a213025b 100644 ---- a/src/main/java/net/minecraft/server/BiomeMesaPlateauMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeMesaPlateauMutated.java -@@ -20,14 +20,6 @@ public final class BiomeMesaPlateauMutated extends BiomeBase { - BiomeDecoratorGroups.ab(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeMushroomIslandShore.java b/src/main/java/net/minecraft/server/BiomeMushroomIslandShore.java -index 0302efbdc..f0be681aa 100644 ---- a/src/main/java/net/minecraft/server/BiomeMushroomIslandShore.java -+++ b/src/main/java/net/minecraft/server/BiomeMushroomIslandShore.java -@@ -18,7 +18,6 @@ public final class BiomeMushroomIslandShore extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.MOOSHROOM, 8, 4, 8)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeMushrooms.java b/src/main/java/net/minecraft/server/BiomeMushrooms.java -index 51f92584b..0118df023 100644 ---- a/src/main/java/net/minecraft/server/BiomeMushrooms.java -+++ b/src/main/java/net/minecraft/server/BiomeMushrooms.java -@@ -18,7 +18,6 @@ public final class BiomeMushrooms extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.MOOSHROOM, 8, 4, 8)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeOcean.java b/src/main/java/net/minecraft/server/BiomeOcean.java -index ad9628b2a..5f4617c0a 100644 ---- a/src/main/java/net/minecraft/server/BiomeOcean.java -+++ b/src/main/java/net/minecraft/server/BiomeOcean.java -@@ -24,18 +24,6 @@ public final class BiomeOcean extends BiomeBase { - BiomeDecoratorGroups.ai(this); - BiomeDecoratorGroups.ah(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SQUID, 1, 1, 4)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COD, 10, 3, 6)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.DOLPHIN, 1, 1, 2)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.DROWNED, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomePlains.java b/src/main/java/net/minecraft/server/BiomePlains.java -index ff6090e3c..266f4165a 100644 ---- a/src/main/java/net/minecraft/server/BiomePlains.java -+++ b/src/main/java/net/minecraft/server/BiomePlains.java -@@ -21,20 +21,6 @@ public final class BiomePlains extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.HORSE, 5, 2, 6)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.DONKEY, 1, 1, 3)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeRedwoodTaigaHillsMutated.java b/src/main/java/net/minecraft/server/BiomeRedwoodTaigaHillsMutated.java -index a28222eb1..f35557dfd 100644 ---- a/src/main/java/net/minecraft/server/BiomeRedwoodTaigaHillsMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeRedwoodTaigaHillsMutated.java -@@ -23,21 +23,6 @@ public final class BiomeRedwoodTaigaHillsMutated extends BiomeBase { - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.q(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.WOLF, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.RABBIT, 4, 2, 3)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.FOX, 8, 2, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeRiver.java b/src/main/java/net/minecraft/server/BiomeRiver.java -index b84b868b1..405cc2bff 100644 ---- a/src/main/java/net/minecraft/server/BiomeRiver.java -+++ b/src/main/java/net/minecraft/server/BiomeRiver.java -@@ -20,17 +20,6 @@ public final class BiomeRiver extends BiomeBase { - BiomeDecoratorGroups.am(this); - this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.SEAGRASS.b(new WorldGenFeatureSeaGrassConfiguration(48, 0.4D)).a(WorldGenDecorator.v.a(WorldGenFeatureDecoratorConfiguration.e))); // Purpur - decompile error - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SQUID, 2, 1, 4)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SALMON, 5, 1, 5)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.DROWNED, 100, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeRoofedForest.java b/src/main/java/net/minecraft/server/BiomeRoofedForest.java -index 16bcf9bff..f02a8a03c 100644 ---- a/src/main/java/net/minecraft/server/BiomeRoofedForest.java -+++ b/src/main/java/net/minecraft/server/BiomeRoofedForest.java -@@ -24,18 +24,6 @@ public final class BiomeRoofedForest extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeRoofedForestMutated.java b/src/main/java/net/minecraft/server/BiomeRoofedForestMutated.java -index 9fa84c87f..9ee0fc6a4 100644 ---- a/src/main/java/net/minecraft/server/BiomeRoofedForestMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeRoofedForestMutated.java -@@ -24,18 +24,6 @@ public final class BiomeRoofedForestMutated extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeSavanna.java b/src/main/java/net/minecraft/server/BiomeSavanna.java -index c12a89016..a539fc362 100644 ---- a/src/main/java/net/minecraft/server/BiomeSavanna.java -+++ b/src/main/java/net/minecraft/server/BiomeSavanna.java -@@ -23,20 +23,6 @@ public final class BiomeSavanna extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.HORSE, 1, 2, 6)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.DONKEY, 1, 1, 1)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeSavannaMutated.java b/src/main/java/net/minecraft/server/BiomeSavannaMutated.java -index db8b20a6c..e041fcd41 100644 ---- a/src/main/java/net/minecraft/server/BiomeSavannaMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeSavannaMutated.java -@@ -20,20 +20,6 @@ public final class BiomeSavannaMutated extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.HORSE, 1, 2, 6)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.DONKEY, 1, 1, 1)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeSavannaPlateau.java b/src/main/java/net/minecraft/server/BiomeSavannaPlateau.java -index 2826c510d..08407ea3e 100644 ---- a/src/main/java/net/minecraft/server/BiomeSavannaPlateau.java -+++ b/src/main/java/net/minecraft/server/BiomeSavannaPlateau.java -@@ -21,21 +21,6 @@ public final class BiomeSavannaPlateau extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.HORSE, 1, 2, 6)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.DONKEY, 1, 1, 1)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.LLAMA, 8, 4, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeSavannaPlateauMutated.java b/src/main/java/net/minecraft/server/BiomeSavannaPlateauMutated.java -index e544a8f6b..337310263 100644 ---- a/src/main/java/net/minecraft/server/BiomeSavannaPlateauMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeSavannaPlateauMutated.java -@@ -20,20 +20,6 @@ public final class BiomeSavannaPlateauMutated extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.HORSE, 1, 2, 6)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.DONKEY, 1, 1, 1)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeStoneBeach.java b/src/main/java/net/minecraft/server/BiomeStoneBeach.java -index 34660f9f8..3a96c2aeb 100644 ---- a/src/main/java/net/minecraft/server/BiomeStoneBeach.java -+++ b/src/main/java/net/minecraft/server/BiomeStoneBeach.java -@@ -19,14 +19,6 @@ public final class BiomeStoneBeach extends BiomeBase { - BiomeDecoratorGroups.aa(this); - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeSunflowerPlains.java b/src/main/java/net/minecraft/server/BiomeSunflowerPlains.java -index 8815c9590..f971bc4bc 100644 ---- a/src/main/java/net/minecraft/server/BiomeSunflowerPlains.java -+++ b/src/main/java/net/minecraft/server/BiomeSunflowerPlains.java -@@ -21,20 +21,6 @@ public final class BiomeSunflowerPlains extends BiomeBase { - this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.RANDOM_PATCH.b(BiomeDecoratorGroups.I).a(WorldGenDecorator.j.a(new WorldGenDecoratorDungeonConfiguration(32)))); // Purpur - decompile error - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.HORSE, 5, 2, 6)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.DONKEY, 1, 1, 3)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeSwamp.java b/src/main/java/net/minecraft/server/BiomeSwamp.java -index 02584897e..011628fff 100644 ---- a/src/main/java/net/minecraft/server/BiomeSwamp.java -+++ b/src/main/java/net/minecraft/server/BiomeSwamp.java -@@ -20,19 +20,6 @@ public final class BiomeSwamp extends BiomeBase { - this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.SEAGRASS.b(new WorldGenFeatureSeaGrassConfiguration(64, 0.6D)).a(WorldGenDecorator.v.a(WorldGenFeatureDecoratorConfiguration.e))); // Purpur - decompile error - BiomeDecoratorGroups.ag(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 1, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeSwamplandMutated.java b/src/main/java/net/minecraft/server/BiomeSwamplandMutated.java -index d85b01b95..10c6b4eb3 100644 ---- a/src/main/java/net/minecraft/server/BiomeSwamplandMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeSwamplandMutated.java -@@ -18,19 +18,6 @@ public final class BiomeSwamplandMutated extends BiomeBase { - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.ag(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 1, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeTaiga.java b/src/main/java/net/minecraft/server/BiomeTaiga.java -index ae6e6ca89..456b6b174 100644 ---- a/src/main/java/net/minecraft/server/BiomeTaiga.java -+++ b/src/main/java/net/minecraft/server/BiomeTaiga.java -@@ -24,21 +24,6 @@ public final class BiomeTaiga extends BiomeBase { - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.q(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.WOLF, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.RABBIT, 4, 2, 3)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.FOX, 8, 2, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeTaigaHills.java b/src/main/java/net/minecraft/server/BiomeTaigaHills.java -index 4e19fe5ae..cc699e354 100644 ---- a/src/main/java/net/minecraft/server/BiomeTaigaHills.java -+++ b/src/main/java/net/minecraft/server/BiomeTaigaHills.java -@@ -22,21 +22,6 @@ public final class BiomeTaigaHills extends BiomeBase { - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.q(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.WOLF, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.RABBIT, 4, 2, 3)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.FOX, 8, 2, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeTaigaMutated.java b/src/main/java/net/minecraft/server/BiomeTaigaMutated.java -index 05e833ffe..3c722f50a 100644 ---- a/src/main/java/net/minecraft/server/BiomeTaigaMutated.java -+++ b/src/main/java/net/minecraft/server/BiomeTaigaMutated.java -@@ -22,21 +22,6 @@ public final class BiomeTaigaMutated extends BiomeBase { - BiomeDecoratorGroups.am(this); - BiomeDecoratorGroups.q(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SHEEP, 12, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PIG, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.CHICKEN, 10, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.COW, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.WOLF, 8, 4, 4)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.RABBIT, 4, 2, 3)); -- this.a(EnumCreatureType.CREATURE, new BiomeBase.BiomeMeta(EntityTypes.FOX, 8, 2, 4)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeTheEnd.java b/src/main/java/net/minecraft/server/BiomeTheEnd.java -index 22e9789a3..6a5a8a991 100644 ---- a/src/main/java/net/minecraft/server/BiomeTheEnd.java -+++ b/src/main/java/net/minecraft/server/BiomeTheEnd.java -@@ -8,6 +8,6 @@ public final class BiomeTheEnd extends BiomeBase { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.F).a(BiomeBase.Precipitation.NONE).a(BiomeBase.Geography.THEEND).a(0.1F).b(0.2F).c(0.5F).d(0.5F).a(4159204).b(329011).a((String) null)); - this.a(WorldGenStage.Decoration.SURFACE_STRUCTURES, WorldGenerator.END_SPIKE.b(new WorldGenFeatureEndSpikeConfiguration(false, ImmutableList.of(), (BlockPosition) null)).a(WorldGenDecorator.a.a(WorldGenFeatureDecoratorConfiguration.e))); // Purpur - decompile error - BiomeDecoratorGroups.aq(this); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 4, 4)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeTheEndBarrenIsland.java b/src/main/java/net/minecraft/server/BiomeTheEndBarrenIsland.java -index 5b068299c..07d72737b 100644 ---- a/src/main/java/net/minecraft/server/BiomeTheEndBarrenIsland.java -+++ b/src/main/java/net/minecraft/server/BiomeTheEndBarrenIsland.java -@@ -5,6 +5,6 @@ public class BiomeTheEndBarrenIsland extends BiomeBase { - public BiomeTheEndBarrenIsland() { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.F).a(BiomeBase.Precipitation.NONE).a(BiomeBase.Geography.THEEND).a(0.1F).b(0.2F).c(0.5F).d(0.5F).a(4159204).b(329011).a((String) null)); - BiomeDecoratorGroups.aq(this); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 4, 4)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeTheEndFloatingIslands.java b/src/main/java/net/minecraft/server/BiomeTheEndFloatingIslands.java -index a26d56aa4..839d3e616 100644 ---- a/src/main/java/net/minecraft/server/BiomeTheEndFloatingIslands.java -+++ b/src/main/java/net/minecraft/server/BiomeTheEndFloatingIslands.java -@@ -6,6 +6,6 @@ public class BiomeTheEndFloatingIslands extends BiomeBase { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.F).a(BiomeBase.Precipitation.NONE).a(BiomeBase.Geography.THEEND).a(0.1F).b(0.2F).c(0.5F).d(0.5F).a(4159204).b(329011).a((String) null)); - this.a(WorldGenStage.Decoration.RAW_GENERATION, WorldGenerator.END_ISLAND.b(WorldGenFeatureConfiguration.e).a(WorldGenDecorator.J.a(WorldGenFeatureDecoratorConfiguration.e))); // Purpur - decompile error - BiomeDecoratorGroups.aq(this); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 4, 4)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeTheEndHighIsland.java b/src/main/java/net/minecraft/server/BiomeTheEndHighIsland.java -index e47add3e4..53aa6243d 100644 ---- a/src/main/java/net/minecraft/server/BiomeTheEndHighIsland.java -+++ b/src/main/java/net/minecraft/server/BiomeTheEndHighIsland.java -@@ -8,6 +8,6 @@ public class BiomeTheEndHighIsland extends BiomeBase { - this.a(WorldGenStage.Decoration.SURFACE_STRUCTURES, WorldGenerator.END_GATEWAY.b(WorldGenEndGatewayConfiguration.a(WorldProviderTheEnd.f, true)).a(WorldGenDecorator.L.a(WorldGenFeatureDecoratorConfiguration.e))); // Purpur - decompile error - BiomeDecoratorGroups.aq(this); - this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.CHORUS_PLANT.b(WorldGenFeatureConfiguration.e).a(WorldGenDecorator.K.a(WorldGenFeatureDecoratorConfiguration.e))); // Purpur - decompile error -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 4, 4)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeTheEndMediumIsland.java b/src/main/java/net/minecraft/server/BiomeTheEndMediumIsland.java -index ec92a8457..2452f1801 100644 ---- a/src/main/java/net/minecraft/server/BiomeTheEndMediumIsland.java -+++ b/src/main/java/net/minecraft/server/BiomeTheEndMediumIsland.java -@@ -6,6 +6,6 @@ public class BiomeTheEndMediumIsland extends BiomeBase { - super((new BiomeBase.a()).a(WorldGenSurface.G, WorldGenSurface.F).a(BiomeBase.Precipitation.NONE).a(BiomeBase.Geography.THEEND).a(0.1F).b(0.2F).c(0.5F).d(0.5F).a(4159204).b(329011).a((String) null)); - this.a(WorldGenerator.END_CITY.b(WorldGenFeatureConfiguration.e)); // Purpur - decompile error - BiomeDecoratorGroups.aq(this); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 4, 4)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeVoid.java b/src/main/java/net/minecraft/server/BiomeVoid.java -index c9ba33453..5549d6142 100644 ---- a/src/main/java/net/minecraft/server/BiomeVoid.java -+++ b/src/main/java/net/minecraft/server/BiomeVoid.java -@@ -5,5 +5,6 @@ public final class BiomeVoid extends BiomeBase { - public BiomeVoid() { - super((new BiomeBase.a()).a(WorldGenSurface.R, WorldGenSurface.x).a(BiomeBase.Precipitation.NONE).a(BiomeBase.Geography.NONE).a(0.1F).b(0.2F).c(0.5F).d(0.5F).a(4159204).b(329011).a((String) null)); - this.a(WorldGenStage.Decoration.TOP_LAYER_MODIFICATION, WorldGenerator.VOID_START_PLATFORM.b(WorldGenFeatureConfiguration.e).a(WorldGenDecorator.a.a(WorldGenFeatureDecoratorConfiguration.e))); // Purpur - decompile error -+ // Purpur - no hardcoded natural spawn data to remove, commenting here just for completeness - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeWarmDeepOcean.java b/src/main/java/net/minecraft/server/BiomeWarmDeepOcean.java -index 11dc5f637..c3fc79fb3 100644 ---- a/src/main/java/net/minecraft/server/BiomeWarmDeepOcean.java -+++ b/src/main/java/net/minecraft/server/BiomeWarmDeepOcean.java -@@ -24,18 +24,6 @@ public class BiomeWarmDeepOcean extends BiomeBase { - BiomeDecoratorGroups.ak(this); - BiomeDecoratorGroups.ai(this); - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SQUID, 5, 1, 4)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.TROPICAL_FISH, 25, 8, 8)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.DOLPHIN, 2, 1, 2)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.DROWNED, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/BiomeWarmOcean.java b/src/main/java/net/minecraft/server/BiomeWarmOcean.java -index e4dc7d198..00f94b906 100644 ---- a/src/main/java/net/minecraft/server/BiomeWarmOcean.java -+++ b/src/main/java/net/minecraft/server/BiomeWarmOcean.java -@@ -26,18 +26,6 @@ public class BiomeWarmOcean extends BiomeBase { - BiomeDecoratorGroups.aj(this); - this.a(WorldGenStage.Decoration.VEGETAL_DECORATION, WorldGenerator.SEA_PICKLE.b(new WorldGenFeatureKelpConfiguration(20)).a(WorldGenDecorator.l.a(new WorldGenDecoratorDungeonConfiguration(16)))); // Purpur - decompile error - BiomeDecoratorGroups.ap(this); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.SQUID, 10, 4, 4)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.PUFFERFISH, 15, 1, 3)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.TROPICAL_FISH, 25, 8, 8)); -- this.a(EnumCreatureType.WATER_CREATURE, new BiomeBase.BiomeMeta(EntityTypes.DOLPHIN, 2, 1, 2)); -- this.a(EnumCreatureType.AMBIENT, new BiomeBase.BiomeMeta(EntityTypes.BAT, 10, 8, 8)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SPIDER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE, 95, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ZOMBIE_VILLAGER, 5, 1, 1)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SKELETON, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.CREEPER, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.SLIME, 100, 4, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.ENDERMAN, 10, 1, 4)); -- this.a(EnumCreatureType.MONSTER, new BiomeBase.BiomeMeta(EntityTypes.WITCH, 5, 1, 1)); -+ // Purpur - remove hardcoded natural spawn data - } - } -diff --git a/src/main/java/net/minecraft/server/Biomes.java b/src/main/java/net/minecraft/server/Biomes.java -index 12742870c..a448c7726 100644 ---- a/src/main/java/net/minecraft/server/Biomes.java -+++ b/src/main/java/net/minecraft/server/Biomes.java -@@ -87,6 +87,34 @@ public abstract class Biomes { - BiomeBase.c.a(biomebase, IRegistry.BIOME.a(IRegistry.BIOME.get(new MinecraftKey(biomebase.m)))); - } - -+ // Purpur start -+ org.bukkit.configuration.ConfigurationSection section = BiomeBase.biomeData.getConfigurationSection(biomebase.getName() + ".spawn-data"); -+ if (section != null) { -+ for (String entity : section.getKeys(false)) { -+ EntityTypes type = EntityTypes.getType(entity).orElse(null); -+ if (type == null) { -+ MinecraftServer.LOGGER.error("Unknown entity type in biomes.yml for " + biomebase.getName() + "." + entity); -+ continue; -+ } -+ String raw = section.getString(entity); -+ if (raw == null || raw.isEmpty()) { -+ continue; -+ } -+ int weight, min, max; -+ try { -+ String[] split = raw.trim().replace(" ", "").split(","); -+ weight = Integer.parseInt(split[0]); -+ min = Integer.parseInt(split[1]); -+ max = Integer.parseInt(split[2]); -+ } catch (Exception e) { -+ MinecraftServer.LOGGER.error("Error parsing data in biomes.yml for " + biomebase.getName() + "." + entity, e); -+ continue; -+ } -+ biomebase.addMobSpawn(type, weight, min, max); -+ } -+ } -+ //Purpur end -+ - return biomebase; - } - -diff --git a/src/main/resources/biomes.yml b/src/main/resources/biomes.yml -new file mode 100644 -index 000000000..f0ea65299 ---- /dev/null -+++ b/src/main/resources/biomes.yml -@@ -0,0 +1,1042 @@ -+ocean: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ drowned: 5,1,1 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ bat: 10,8,8 -+ squid: 1,1,4 -+ cod: 10,3,6 -+ dolphin: 1,1,2 -+plains: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ horse: 5,2,6 -+ donkey: 1,1,3 -+ bat: 10,8,8 -+desert: -+ spawn-data: -+ spider: 100,4,4 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ zombie: 19,4,4 -+ zombie_villager: 1,1,1 -+ husk: 80,4,4 -+ rabbit: 4,2,3 -+ bat: 10,8,8 -+mountains: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ llama: 5,4,6 -+ bat: 10,8,8 -+forest: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ wolf: 5,4,4 -+ bat: 10,8,8 -+taiga: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ wolf: 8,4,4 -+ rabbit: 4,2,3 -+ fox: 8,2,4 -+ bat: 10,8,8 -+swamp: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 1,1,1 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ bat: 10,8,8 -+river: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ drowned: 100,1,1 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ bat: 10,8,8 -+ squid: 2,1,4 -+ salmon: 5,1,5 -+nether: -+ spawn-data: -+ ghast: 50,4,4 -+ zombie_pigman: 100,4,4 -+ magma_cube: 2,4,4 -+ enderman: 1,4,4 -+the_end: -+ spawn-data: -+ enderman: 10,4,4 -+frozen_ocean: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ drowned: 5,1,1 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ polar_bear: 1,1,2 -+ bat: 10,8,8 -+ squid: 1,1,4 -+ salmon: 15,1,5 -+frozen_river: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ drowned: 1,1,1 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ bat: 10,8,8 -+ squid: 2,1,4 -+ salmon: 5,1,5 -+snowy_tundra: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ skeleton: 20,4,4 -+ stray: 80,4,4 -+ rabbit: 10,2,3 -+ polar_bear: 1,1,2 -+ bat: 10,8,8 -+snowy_mountains: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ skeleton: 20,4,4 -+ stray: 80,4,4 -+ rabbit: 10,2,3 -+ polar_bear: 1,1,2 -+ bat: 10,8,8 -+mushroom_fields: -+ spawn-data: -+ mooshroom: 8,4,8 -+ bat: 10,8,8 -+mushroom_field_shore: -+ spawn-data: -+ mooshroom: 8,4,8 -+ bat: 10,8,8 -+beach: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ turtle: 5,2,5 -+ bat: 10,8,8 -+desert_hills: -+ spawn-data: -+ spider: 100,4,4 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ zombie: 19,4,4 -+ zombie_villager: 1,1,1 -+ husk: 80,4,4 -+ rabbit: 4,2,3 -+ bat: 10,8,8 -+wooded_hills: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ wolf: 5,4,4 -+ bat: 10,8,8 -+taiga_hills: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ wolf: 8,4,4 -+ rabbit: 4,2,3 -+ fox: 8,2,4 -+ bat: 10,8,8 -+mountain_edge: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ llama: 5,4,6 -+ bat: 10,8,8 -+jungle: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ ocelot: 2,1,3 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ parrot: 40,1,2 -+ panda: 1,1,2 -+ bat: 10,8,8 -+jungle_hills: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ ocelot: 2,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ parrot: 10,1,1 -+ panda: 1,1,2 -+ bat: 10,8,8 -+jungle_edge: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ bat: 10,8,8 -+deep_ocean: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ drowned: 5,1,1 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ bat: 10,8,8 -+ squid: 1,1,4 -+ cod: 10,3,6 -+ dolphin: 1,1,2 -+stone_shore: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ bat: 10,8,8 -+snowy_beach: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ bat: 10,8,8 -+birch_forest: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ bat: 10,8,8 -+birch_forest_hills: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ bat: 10,8,8 -+dark_forest: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ bat: 10,8,8 -+snowy_taiga: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ wolf: 8,4,4 -+ rabbit: 4,2,3 -+ fox: 8,2,4 -+ bat: 10,8,8 -+snowy_taiga_hills: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ wolf: 8,4,4 -+ rabbit: 4,2,3 -+ fox: 8,2,4 -+ bat: 10,8,8 -+giant_tree_taiga: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 100,4,4 -+ skeleton: 100,4,4 -+ zombie_villager: 25,1,1 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ wolf: 8,4,4 -+ rabbit: 4,2,3 -+ fox: 8,2,4 -+ bat: 10,8,8 -+giant_tree_taiga_hills: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 100,4,4 -+ skeleton: 100,4,4 -+ zombie_villager: 25,1,1 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ wolf: 8,4,4 -+ rabbit: 4,2,3 -+ fox: 8,2,4 -+ bat: 10,8,8 -+wooded_mountains: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ llama: 5,4,6 -+ bat: 10,8,8 -+savanna: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ horse: 1,2,6 -+ donkey: 1,1,1 -+ bat: 10,8,8 -+savanna_plateau: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ horse: 1,2,6 -+ donkey: 1,1,1 -+ llama: 8,4,4 -+ bat: 10,8,8 -+badlands: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ bat: 10,8,8 -+wooded_badlands_plateau: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ bat: 10,8,8 -+badlands_plateau: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ bat: 10,8,8 -+small_end_islands: -+ spawn-data: -+ enderman: 10,4,4 -+end_midlands: -+ spawn-data: -+ enderman: 10,4,4 -+end_highlands: -+ spawn-data: -+ enderman: 10,4,4 -+end_barrens: -+ spawn-data: -+ enderman: 10,4,4 -+warm_ocean: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ bat: 10,8,8 -+ squid: 10,4,4 -+ pufferfish: 15,1,3 -+ tropical_fish: 25,8,8 -+ dolphin: 2,1,2 -+lukewarm_ocean: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ drowned: 5,1,1 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ bat: 10,8,8 -+ squid: 10,1,2 -+ cod: 15,3,6 -+ pufferfish: 5,1,3 -+ tropical_fish: 25,8,8 -+ dolphin: 2,1,2 -+cold_ocean: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ drowned: 5,1,1 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ bat: 10,8,8 -+ squid: 3,1,4 -+ cod: 15,3,6 -+ salmon: 15,1,5 -+deep_warm_ocean: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ drowned: 5,1,1 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ bat: 10,8,8 -+ squid: 5,1,4 -+ tropical_fish: 25,8,8 -+ dolphin: 2,1,2 -+deep_lukewarm_ocean: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ drowned: 5,1,1 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ bat: 10,8,8 -+ squid: 8,1,4 -+ cod: 8,3,6 -+ pufferfish: 5,1,3 -+ tropical_fish: 25,8,8 -+ dolphin: 2,1,2 -+deep_cold_ocean: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ drowned: 5,1,1 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ bat: 10,8,8 -+ squid: 3,1,4 -+ cod: 15,3,6 -+ salmon: 15,1,5 -+deep_frozen_ocean: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ drowned: 5,1,1 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ polar_bear: 1,1,2 -+ bat: 10,8,8 -+ squid: 1,1,4 -+ salmon: 15,1,5 -+sunflower_plains: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ horse: 5,2,6 -+ donkey: 1,1,3 -+ bat: 10,8,8 -+desert_lakes: -+ spawn-data: -+ spider: 100,4,4 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ zombie: 19,4,4 -+ zombie_villager: 1,1,1 -+ husk: 80,4,4 -+ rabbit: 4,2,3 -+ bat: 10,8,8 -+gravelly_mountains: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ llama: 5,4,6 -+ bat: 10,8,8 -+flower_forest: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ rabbit: 4,2,3 -+ bat: 10,8,8 -+taiga_mountains: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ wolf: 8,4,4 -+ rabbit: 4,2,3 -+ fox: 8,2,4 -+ bat: 10,8,8 -+swamp_hills: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 1,1,1 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ bat: 10,8,8 -+ice_spikes: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ skeleton: 20,4,4 -+ stray: 80,4,4 -+ rabbit: 10,2,3 -+ polar_bear: 1,1,2 -+ bat: 10,8,8 -+modified_jungle: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ ocelot: 2,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ parrot: 10,1,1 -+ bat: 10,8,8 -+modified_jungle_edge: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ bat: 10,8,8 -+tall_birch_forest: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ bat: 10,8,8 -+tall_birch_hills: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ bat: 10,8,8 -+dark_forest_hills: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ bat: 10,8,8 -+snowy_taiga_mountains: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ wolf: 8,4,4 -+ rabbit: 4,2,3 -+ fox: 8,2,4 -+ bat: 10,8,8 -+giant_spruce_taiga: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ wolf: 8,4,4 -+ rabbit: 4,2,3 -+ fox: 8,2,4 -+ bat: 10,8,8 -+giant_spruce_taiga_hills: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ wolf: 8,4,4 -+ rabbit: 4,2,3 -+ fox: 8,2,4 -+ bat: 10,8,8 -+modified_gravelly_mountains: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ llama: 5,4,6 -+ bat: 10,8,8 -+shattered_savanna: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ horse: 1,2,6 -+ donkey: 1,1,1 -+ bat: 10,8,8 -+shattered_savanna_plateau: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ horse: 1,2,6 -+ donkey: 1,1,1 -+ bat: 10,8,8 -+eroded_badlands: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ bat: 10,8,8 -+modified_wooded_badlands_plateau: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ bat: 10,8,8 -+modified_badlands_plateau: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ bat: 10,8,8 -+bamboo_jungle: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ ocelot: 2,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ parrot: 40,1,2 -+ panda: 80,1,2 -+ bat: 10,8,8 -+bamboo_jungle_hills: -+ spawn-data: -+ spider: 100,4,4 -+ zombie: 95,4,4 -+ zombie_villager: 5,1,1 -+ skeleton: 100,4,4 -+ creeper: 100,4,4 -+ slime: 100,4,4 -+ enderman: 10,1,4 -+ witch: 5,1,1 -+ ocelot: 2,1,1 -+ sheep: 12,4,4 -+ pig: 10,4,4 -+ chicken: 10,4,4 -+ cow: 8,4,4 -+ parrot: 10,1,1 -+ panda: 80,1,2 -+ bat: 10,8,8 --- -2.26.2 - diff --git a/patches/server/0094-Configurable-jockey-options.patch b/patches/server/0094-Configurable-jockey-options.patch new file mode 100644 index 000000000..ea95758aa --- /dev/null +++ b/patches/server/0094-Configurable-jockey-options.patch @@ -0,0 +1,279 @@ +From da4438dfd9163481bd950221235e8617d3b9ca69 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Thu, 26 Mar 2020 21:39:32 -0500 +Subject: [PATCH] Configurable jockey options + +--- + .../net/minecraft/server/EntityDrowned.java | 17 ++++++++ + .../net/minecraft/server/EntityPigZombie.java | 17 ++++++++ + .../net/minecraft/server/EntityZombie.java | 31 ++++++++++---- + .../minecraft/server/EntityZombieHusk.java | 17 ++++++++ + .../server/EntityZombieVillager.java | 17 ++++++++ + .../net/pl3x/purpur/PurpurWorldConfig.java | 42 +++++++++++++++++++ + 6 files changed, 134 insertions(+), 7 deletions(-) + +diff --git a/src/main/java/net/minecraft/server/EntityDrowned.java b/src/main/java/net/minecraft/server/EntityDrowned.java +index e6425bdf1..455b1d922 100644 +--- a/src/main/java/net/minecraft/server/EntityDrowned.java ++++ b/src/main/java/net/minecraft/server/EntityDrowned.java +@@ -45,6 +45,23 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { + return groupdataentity; + } + ++ // Purpur start ++ @Override ++ public boolean jockeyOnlyBaby() { ++ return world.purpurConfig.drownedJockeyOnlyBaby; ++ } ++ ++ @Override ++ public double jockeyChance() { ++ return world.purpurConfig.drownedJockeyChance; ++ } ++ ++ @Override ++ public boolean jockeyTryExistingChickens() { ++ return world.purpurConfig.drownedJockeyTryExistingChickens; ++ } ++ // Purpur end ++ + public static boolean b(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { + BiomeBase biomebase = generatoraccess.getBiome(blockposition); + boolean flag = generatoraccess.getDifficulty() != EnumDifficulty.PEACEFUL && a(generatoraccess, blockposition, random) && (enummobspawn == EnumMobSpawn.SPAWNER || generatoraccess.getFluid(blockposition).a((Tag) TagsFluid.WATER)); +diff --git a/src/main/java/net/minecraft/server/EntityPigZombie.java b/src/main/java/net/minecraft/server/EntityPigZombie.java +index 19f585022..4f89e2f4f 100644 +--- a/src/main/java/net/minecraft/server/EntityPigZombie.java ++++ b/src/main/java/net/minecraft/server/EntityPigZombie.java +@@ -44,6 +44,23 @@ public class EntityPigZombie extends EntityZombie implements IEntityAngerable { + return EntityZombie.eT().a(GenericAttributes.SPAWN_REINFORCEMENTS, 0.0D).a(GenericAttributes.MOVEMENT_SPEED, 0.23000000417232513D).a(GenericAttributes.ATTACK_DAMAGE, 5.0D); + } + ++ // Purpur start ++ @Override ++ public boolean jockeyOnlyBaby() { ++ return world.purpurConfig.zombifiedPiglinJockeyOnlyBaby; ++ } ++ ++ @Override ++ public double jockeyChance() { ++ return world.purpurConfig.zombifiedPiglinJockeyChance; ++ } ++ ++ @Override ++ public boolean jockeyTryExistingChickens() { ++ return world.purpurConfig.zombifiedPiglinJockeyTryExistingChickens; ++ } ++ // Purpur end ++ + @Override + protected boolean eO() { + return false; +diff --git a/src/main/java/net/minecraft/server/EntityZombie.java b/src/main/java/net/minecraft/server/EntityZombie.java +index 7182c0ead..6084cb84c 100644 +--- a/src/main/java/net/minecraft/server/EntityZombie.java ++++ b/src/main/java/net/minecraft/server/EntityZombie.java +@@ -3,6 +3,7 @@ package net.minecraft.server; + import com.mojang.serialization.DynamicOps; + import java.time.LocalDate; + import java.time.temporal.ChronoField; ++import java.util.Collections; + import java.util.List; + import java.util.Random; + import java.util.UUID; +@@ -75,6 +76,20 @@ public class EntityZombie extends EntityMonster { + this.getDataWatcher().register(EntityZombie.DROWN_CONVERTING, false); + } + ++ // Purpur start ++ public boolean jockeyOnlyBaby() { ++ return world.purpurConfig.zombieJockeyOnlyBaby; ++ } ++ ++ public double jockeyChance() { ++ return world.purpurConfig.zombieJockeyChance; ++ } ++ ++ public boolean jockeyTryExistingChickens() { ++ return world.purpurConfig.zombieJockeyTryExistingChickens; ++ } ++ // Purpur end ++ + public boolean isDrowning() { return isDrownConverting(); } // Paper - OBFHELPER + public boolean isDrownConverting() { + return (Boolean) this.getDataWatcher().get(EntityZombie.DROWN_CONVERTING); +@@ -460,19 +475,20 @@ public class EntityZombie extends EntityMonster { + if (object instanceof EntityZombie.GroupDataZombie) { + EntityZombie.GroupDataZombie entityzombie_groupdatazombie = (EntityZombie.GroupDataZombie) object; + +- if (entityzombie_groupdatazombie.a) { +- this.setBaby(true); ++ // Purpur start ++ if (!jockeyOnlyBaby() || entityzombie_groupdatazombie.isBaby()) { ++ this.setBaby(entityzombie_groupdatazombie.isBaby()); + if (entityzombie_groupdatazombie.b) { +- if ((double) generatoraccess.getRandom().nextFloat() < 0.05D) { +- List list = generatoraccess.a(EntityChicken.class, this.getBoundingBox().grow(5.0D, 3.0D, 5.0D), IEntitySelector.c); ++ if ((double) generatoraccess.getRandom().nextFloat() < jockeyChance()) { ++ List list = jockeyTryExistingChickens() ? generatoraccess.a(EntityChicken.class, this.getBoundingBox().grow(5.0D, 3.0D, 5.0D), IEntitySelector.c) : Collections.emptyList(); ++ // Purpur end + + if (!list.isEmpty()) { + EntityChicken entitychicken = (EntityChicken) list.get(0); + + entitychicken.setChickenJockey(true); + this.startRiding(entitychicken); +- } +- } else if ((double) generatoraccess.getRandom().nextFloat() < 0.05D) { ++ } else { // Purpur + EntityChicken entitychicken1 = (EntityChicken) EntityTypes.CHICKEN.a(this.world); + + entitychicken1.setPositionRotation(this.locX(), this.locY(), this.locZ(), this.yaw, 0.0F); +@@ -480,6 +496,7 @@ public class EntityZombie extends EntityMonster { + entitychicken1.setChickenJockey(true); + this.startRiding(entitychicken1); + generatoraccess.addEntity(entitychicken1, CreatureSpawnEvent.SpawnReason.MOUNT); // CraftBukkit ++ } // Purpur + } + } + } +@@ -582,7 +599,7 @@ public class EntityZombie extends EntityMonster { + + public static class GroupDataZombie implements GroupDataEntity { + +- public final boolean a; ++ public final boolean a; public boolean isBaby() { return a; } // Purpur - OBFHELPER + public final boolean b; + + public GroupDataZombie(boolean flag, boolean flag1) { +diff --git a/src/main/java/net/minecraft/server/EntityZombieHusk.java b/src/main/java/net/minecraft/server/EntityZombieHusk.java +index 143b9123e..2daff8562 100644 +--- a/src/main/java/net/minecraft/server/EntityZombieHusk.java ++++ b/src/main/java/net/minecraft/server/EntityZombieHusk.java +@@ -8,6 +8,23 @@ public class EntityZombieHusk extends EntityZombie { + super(entitytypes, world); + } + ++ // Purpur start ++ @Override ++ public boolean jockeyOnlyBaby() { ++ return world.purpurConfig.huskJockeyOnlyBaby; ++ } ++ ++ @Override ++ public double jockeyChance() { ++ return world.purpurConfig.huskJockeyChance; ++ } ++ ++ @Override ++ public boolean jockeyTryExistingChickens() { ++ return world.purpurConfig.huskJockeyTryExistingChickens; ++ } ++ // Purpur end ++ + public static boolean b(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { + return c(entitytypes, generatoraccess, enummobspawn, blockposition, random) && (enummobspawn == EnumMobSpawn.SPAWNER || generatoraccess.f(blockposition)); + } +diff --git a/src/main/java/net/minecraft/server/EntityZombieVillager.java b/src/main/java/net/minecraft/server/EntityZombieVillager.java +index 9b920332b..68fca8a8d 100644 +--- a/src/main/java/net/minecraft/server/EntityZombieVillager.java ++++ b/src/main/java/net/minecraft/server/EntityZombieVillager.java +@@ -34,6 +34,23 @@ public class EntityZombieVillager extends EntityZombie implements VillagerDataHo + this.datawatcher.register(EntityZombieVillager.c, new VillagerData(VillagerType.PLAINS, VillagerProfession.NONE, 1)); + } + ++ // Purpur start ++ @Override ++ public boolean jockeyOnlyBaby() { ++ return world.purpurConfig.zombieVillagerJockeyOnlyBaby; ++ } ++ ++ @Override ++ public double jockeyChance() { ++ return world.purpurConfig.zombieVillagerJockeyChance; ++ } ++ ++ @Override ++ public boolean jockeyTryExistingChickens() { ++ return world.purpurConfig.zombieVillagerJockeyTryExistingChickens; ++ } ++ // Purpur end ++ + @Override + public void saveData(NBTTagCompound nbttagcompound) { + super.saveData(nbttagcompound); +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index b018bfe03..8ce344c2a 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -246,6 +246,15 @@ public class PurpurWorldConfig { + creeperChargedChance = getDouble("mobs.creeper.naturally-charged-chance", creeperChargedChance); + } + ++ public boolean drownedJockeyOnlyBaby = true; ++ public double drownedJockeyChance = 0.05D; ++ public boolean drownedJockeyTryExistingChickens = true; ++ private void drownedSettings() { ++ drownedJockeyOnlyBaby = getBoolean("mobs.drowned.jockey.only-babies", drownedJockeyOnlyBaby); ++ drownedJockeyChance = getDouble("mobs.drowned.jockey.chance", drownedJockeyChance); ++ drownedJockeyTryExistingChickens = getBoolean("mobs.drowned.jockey.try-existing-chickens", drownedJockeyTryExistingChickens); ++ } ++ + public boolean enderDragonAlwaysDropsEggBlock = false; + public boolean enderDragonAlwaysDropsFullExp = false; + private void enderDragonSettings() { +@@ -280,6 +289,15 @@ public class PurpurWorldConfig { + giantHaveHostileAI = getBoolean("mobs.giant.have-hostile-ai", giantHaveHostileAI); + } + ++ public boolean huskJockeyOnlyBaby = true; ++ public double huskJockeyChance = 0.05D; ++ public boolean huskJockeyTryExistingChickens = true; ++ private void huskSettings() { ++ huskJockeyOnlyBaby = getBoolean("mobs.husk.jockey.only-babies", huskJockeyOnlyBaby); ++ huskJockeyChance = getDouble("mobs.husk.jockey.chance", huskJockeyChance); ++ huskJockeyTryExistingChickens = getBoolean("mobs.husk.jockey.try-existing-chickens", huskJockeyTryExistingChickens); ++ } ++ + public double illusionerMaxHealth = 32.0D; + public double illusionerMovementSpeed = 0.5D; + public double illusionerFollowRange = 18.0D; +@@ -351,12 +369,36 @@ public class PurpurWorldConfig { + } + + public boolean zombieTargetTurtleEggs = true; ++ public boolean zombieJockeyOnlyBaby = true; ++ public double zombieJockeyChance = 0.05D; ++ public boolean zombieJockeyTryExistingChickens = true; + private void zombieSettings() { + zombieTargetTurtleEggs = getBoolean("mobs.zombie.target-turtle-eggs", zombieTargetTurtleEggs); ++ zombieJockeyOnlyBaby = getBoolean("mobs.zombie.jockey.only-babies", zombieJockeyOnlyBaby); ++ zombieJockeyChance = getDouble("mobs.zombie.jockey.chance", zombieJockeyChance); ++ zombieJockeyTryExistingChickens = getBoolean("mobs.zombie.jockey.try-existing-chickens", zombieJockeyTryExistingChickens); + } + + public double zombieHorseSpawnChance = 0.0D; + private void zombieHorseSettings() { + zombieHorseSpawnChance = getDouble("mobs.zombie_horse.spawn-chance", zombieHorseSpawnChance); + } ++ ++ public boolean zombifiedPiglinJockeyOnlyBaby = true; ++ public double zombifiedPiglinJockeyChance = 0.05D; ++ public boolean zombifiedPiglinJockeyTryExistingChickens = true; ++ private void zombifiedPiglinSettings() { ++ zombifiedPiglinJockeyOnlyBaby = getBoolean("mobs.zombified_piglin.jockey.only-babies", zombifiedPiglinJockeyOnlyBaby); ++ zombifiedPiglinJockeyChance = getDouble("mobs.zombified_piglin.jockey.chance", zombifiedPiglinJockeyChance); ++ zombifiedPiglinJockeyTryExistingChickens = getBoolean("mobs.zombified_piglin.jockey.try-existing-chickens", zombifiedPiglinJockeyTryExistingChickens); ++ } ++ ++ public boolean zombieVillagerJockeyOnlyBaby = true; ++ public double zombieVillagerJockeyChance = 0.05D; ++ public boolean zombieVillagerJockeyTryExistingChickens = true; ++ private void zombieVillagerSettings() { ++ zombieVillagerJockeyOnlyBaby = getBoolean("mobs.zombie_villager.jockey.only-babies", zombieVillagerJockeyOnlyBaby); ++ zombieVillagerJockeyChance = getDouble("mobs.zombie_villager.jockey.chance", zombieVillagerJockeyChance); ++ zombieVillagerJockeyTryExistingChickens = getBoolean("mobs.zombie_villager.jockey.try-existing-chickens", zombieVillagerJockeyTryExistingChickens); ++ } + } +-- +2.26.2 + diff --git a/patches/server/0094-Configurable-void-damage-height.patch b/patches/server/0094-Configurable-void-damage-height.patch deleted file mode 100644 index f22e01764..000000000 --- a/patches/server/0094-Configurable-void-damage-height.patch +++ /dev/null @@ -1,46 +0,0 @@ -From ea7f180ce6845e25f45c03d5c90c73b36f6c5cac Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Thu, 27 Feb 2020 21:42:19 -0600 -Subject: [PATCH] Configurable void damage height - ---- - src/main/java/net/minecraft/server/Entity.java | 2 +- - src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 2 ++ - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index 5a8005291..a20660a9b 100644 ---- a/src/main/java/net/minecraft/server/Entity.java -+++ b/src/main/java/net/minecraft/server/Entity.java -@@ -512,7 +512,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - - // Paper start - protected void performVoidDamage() { -- if (this.locY < -64.0D || (this.world.getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER -+ if (this.locY < world.purpurConfig.voidDamageHeight || (this.world.getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER - && world.paperConfig.doNetherTopVoidDamage() - && this.locY >= world.paperConfig.netherVoidTopDamageHeight)) { - -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 4cb856ebb..53c8782b5 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -189,6 +189,7 @@ public class PurpurWorldConfig { - public String playerSleepCondition = "time >= 12541 && time <= 23458"; - public boolean useBetterMending = false; - public boolean saveProjectilesToDisk = true; -+ public double voidDamageHeight = -64.0D; - private void gameplayMechanicsSettings() { - boatEjectPlayersOnLand = getBoolean("gameplay-mechanics.boat.eject-players-on-land", boatEjectPlayersOnLand); - armorstandStepHeight = (float) getDouble("gameplay-mechanics.armorstand.step-height", armorstandStepHeight); -@@ -245,6 +246,7 @@ public class PurpurWorldConfig { - set("gameplay-mechanics.saveProjectilesToDisk", null); - } - saveProjectilesToDisk = getBoolean("gameplay-mechanics.save-projectiles-to-disk", saveProjectilesToDisk); -+ voidDamageHeight = getDouble("gameplay-mechanics.void-damage-height", voidDamageHeight); - } - - public int elytraDamagePerSecond = 1; --- -2.26.2 - diff --git a/patches/server/0024-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch b/patches/server/0095-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch similarity index 73% rename from patches/server/0024-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch rename to patches/server/0095-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch index dde6c7fbf..6865d64d4 100644 --- a/patches/server/0024-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch +++ b/patches/server/0095-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch @@ -1,22 +1,21 @@ -From 63057fd5e7b4ad844bafe3ef1c87705ff1cd31f7 Mon Sep 17 00:00:00 2001 +From d913c34bd6b7fd8188c09bc53a25c05ca0ad8af3 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Thu, 9 May 2019 18:26:06 -0500 Subject: [PATCH] Phantoms attracted to crystals and crystals shoot phantoms --- .../net/minecraft/server/DamageSource.java | 1 + - .../java/net/minecraft/server/Entity.java | 8 +- + .../java/net/minecraft/server/Entity.java | 5 +- .../minecraft/server/EntityEnderCrystal.java | 49 +++++ - .../net/minecraft/server/EntityPhantom.java | 172 +++++++++++++++++- - .../net/minecraft/server/IEntityAccess.java | 1 + - .../net/pl3x/purpur/PurpurWorldConfig.java | 6 + - 6 files changed, 226 insertions(+), 11 deletions(-) + .../net/minecraft/server/EntityPhantom.java | 174 +++++++++++++++++- + .../net/pl3x/purpur/PurpurWorldConfig.java | 9 + + 5 files changed, 229 insertions(+), 9 deletions(-) diff --git a/src/main/java/net/minecraft/server/DamageSource.java b/src/main/java/net/minecraft/server/DamageSource.java -index f7344d3ae..f6c0165f9 100644 +index 6fe5678cf..bd0267ee4 100644 --- a/src/main/java/net/minecraft/server/DamageSource.java +++ b/src/main/java/net/minecraft/server/DamageSource.java -@@ -82,6 +82,7 @@ public class DamageSource { +@@ -88,6 +88,7 @@ public class DamageSource { return (new EntityDamageSourceIndirect("thrown", entity, entity1)).c(); } @@ -25,18 +24,18 @@ index f7344d3ae..f6c0165f9 100644 return (new EntityDamageSourceIndirect("indirectMagic", entity, entity1)).setIgnoreArmor().setMagic(); } diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index f5ea12b02..d470c586a 100644 +index 3ae0cf87a..7f01b3274 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java -@@ -1630,6 +1630,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke +@@ -1401,6 +1401,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return d3 * d3 + d4 * d4 + d5 * d5; } + public double getDistanceSq(Entity entity) { return this.h(entity); } // Purpur - OBFHELPER public double h(Entity entity) { - return this.c(entity.getPositionVector()); + return this.d(entity.getPositionVector()); } -@@ -2159,14 +2160,13 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke +@@ -1928,8 +1929,8 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return this.a(new ItemStack(imaterial), (float) i); } @@ -47,15 +46,8 @@ index f5ea12b02..d470c586a 100644 return this.a(itemstack, 0.0F); } - @Nullable public final EntityItem dropItem(ItemStack itemstack, float offset) { return this.a(itemstack, offset); } // Paper - OBFHELPER -- @Nullable -- public EntityItem a(ItemStack itemstack, float f) { -+ @Nullable public EntityItem a(ItemStack itemstack, float f) { - if (itemstack.isEmpty()) { - return null; - } else if (this.world.isClientSide) { diff --git a/src/main/java/net/minecraft/server/EntityEnderCrystal.java b/src/main/java/net/minecraft/server/EntityEnderCrystal.java -index a57d0089d..02952c3af 100644 +index 21dfe7f42..71a440d69 100644 --- a/src/main/java/net/minecraft/server/EntityEnderCrystal.java +++ b/src/main/java/net/minecraft/server/EntityEnderCrystal.java @@ -13,6 +13,12 @@ public class EntityEnderCrystal extends Entity { @@ -81,7 +73,7 @@ index a57d0089d..02952c3af 100644 + } + + if (targetPhantom == null) { -+ for (EntityPhantom phantom : world.getEntitiesByClass(EntityPhantom.class, getBoundingBox().grow(world.purpurConfig.phantomAttackedByCrystalRadius))) { ++ for (EntityPhantom phantom : world.getEntitiesInAABB(EntityPhantom.class, getBoundingBox().grow(world.purpurConfig.phantomAttackedByCrystalRadius))) { + if (phantom.hasLineOfSight(this)) { + attackPhantom(phantom); + break; @@ -121,34 +113,34 @@ index a57d0089d..02952c3af 100644 + // Purpur end @Override - protected void b(NBTTagCompound nbttagcompound) { + protected void saveData(NBTTagCompound nbttagcompound) { diff --git a/src/main/java/net/minecraft/server/EntityPhantom.java b/src/main/java/net/minecraft/server/EntityPhantom.java -index 777bc95ee..265077048 100644 +index 3cb78924d..ec09ec241 100644 --- a/src/main/java/net/minecraft/server/EntityPhantom.java +++ b/src/main/java/net/minecraft/server/EntityPhantom.java -@@ -8,9 +8,10 @@ import javax.annotation.Nullable; +@@ -9,9 +9,10 @@ import javax.annotation.Nullable; public class EntityPhantom extends EntityFlying implements IMonster { private static final DataWatcherObject b = DataWatcher.a(EntityPhantom.class, DataWatcherRegistry.b); - private Vec3D c; - private BlockPosition d; -- private EntityPhantom.AttackPhase bw; +- private EntityPhantom.AttackPhase bv; + private Vec3D c; public void setHomeOffset(Vec3D offset) { this.c = offset; } public Vec3D getHomeOffset() { return this.c; } // Purpur - OBFHELPER + private BlockPosition d; public void setHome(BlockPosition home) { this.d = home; } public BlockPosition getHome() { return this.d; } // Purpur - OBFHELPER -+ private EntityPhantom.AttackPhase bw; public AttackPhase getAttackPhase() { return this.bw; } // Purpur - OBFHELPER -+ private BlockPosition crystalPosition; // Purpur ++ private EntityPhantom.AttackPhase bv; public AttackPhase getAttackPhase() { return this.bv; } // Purpur - OBFHELPER ++ private Vec3D crystalPosition; // Purpur public EntityPhantom(EntityTypes entitytypes, World world) { super(entitytypes, world); -@@ -63,12 +64,18 @@ public class EntityPhantom extends EntityFlying implements IMonster { +@@ -30,11 +31,37 @@ public class EntityPhantom extends EntityFlying implements IMonster { @Override protected void initPathfinder() { -+ // Purpur start - this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(1, new EntityPhantom.c()); - this.goalSelector.a(2, new EntityPhantom.i()); - this.goalSelector.a(3, new EntityPhantom.e()); +- this.targetSelector.a(1, new EntityPhantom.b()); ++ // Purpur start + if (world.purpurConfig.phantomOrbitCrystalRadius > 0) { + this.goalSelector.a(1, new FindCrystalGoal(this)); + this.goalSelector.a(2, new OrbitCrystalGoal(this)); @@ -156,17 +148,11 @@ index 777bc95ee..265077048 100644 + this.goalSelector.a(3, new EntityPhantom.c()); // PickAttackGoal + this.goalSelector.a(4, new EntityPhantom.i()); // SweepAttackGoal + this.goalSelector.a(5, new EntityPhantom.e()); // OrbitPointGoal - this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur -- this.targetSelector.a(1, new EntityPhantom.b()); -+ this.targetSelector.a(1, new EntityPhantom.b()); // AttackPlayerGoal ++ this.targetSelector.a(1, new EntityPhantom.b()); // AttackPlayer Goal + // Purpur end - } - - @Override -@@ -158,6 +165,24 @@ public class EntityPhantom extends EntityFlying implements IMonster { - } - - // Purpur start ++ } ++ ++ // Purpur start + @Override + protected LootTableInfo.Builder a(boolean wasRecentlyHit, DamageSource damagesource) { // dropLoot + boolean dropped = false; @@ -183,12 +169,12 @@ index 777bc95ee..265077048 100644 + + public boolean isCirclingCrystal() { + return crystalPosition != null; -+ } -+ + } ++ // Purpur end + @Override - public boolean onSpacebar() { - if (hasRider() && getRider().getBukkitEntity().hasPermission("allow.special.phantom")) { -@@ -266,6 +291,136 @@ public class EntityPhantom extends EntityFlying implements IMonster { + protected void initDatawatcher() { +@@ -198,6 +225,136 @@ public class EntityPhantom extends EntityFlying implements IMonster { } // Paper end @@ -207,7 +193,7 @@ index 777bc95ee..265077048 100644 + @Override + public boolean a() { // shouldExecute + double range = maxTargetRange(); -+ List crystals = world.getEntitiesByClass(EntityEnderCrystal.class, phantom.getBoundingBox().grow(range)); ++ List crystals = world.getEntitiesInAABB(EntityEnderCrystal.class, phantom.getBoundingBox().grow(range)); + if (crystals.isEmpty()) { + return false; + } @@ -231,7 +217,7 @@ index 777bc95ee..265077048 100644 + + @Override + public void c() { // startExecuting -+ phantom.crystalPosition = new BlockPosition(crystal).add(0, phantom.getRandom().nextInt(10) + 10, 0); ++ phantom.crystalPosition = new Vec3D(crystal.locX(), crystal.locY() + (phantom.getRandom().nextInt(10) + 10), crystal.locZ()); + } + + @Override @@ -314,10 +300,10 @@ index 777bc95ee..265077048 100644 + + private void updateOffset() { + this.offset += this.direction * 15.0F * 0.017453292F; -+ phantom.setHomeOffset(new Vec3D(phantom.crystalPosition).add( -+ (double) (this.radius * MathHelper.cos(this.offset)), -+ (double) (-4.0F + this.verticalChange), -+ (double) (this.radius * MathHelper.sin(this.offset)))); ++ phantom.setHomeOffset(phantom.crystalPosition.add( ++ this.radius * MathHelper.cos(this.offset), ++ -4.0F + this.verticalChange, ++ this.radius * MathHelper.sin(this.offset))); + } + } + // Purpur end @@ -325,66 +311,50 @@ index 777bc95ee..265077048 100644 class b extends PathfinderGoal { private final PathfinderTargetCondition b; -@@ -279,6 +434,7 @@ public class EntityPhantom extends EntityFlying implements IMonster { +@@ -210,6 +367,7 @@ public class EntityPhantom extends EntityFlying implements IMonster { + @Override public boolean a() { - if (getRider() != null) return false; // Purpur - pathfinder does not have a flag + if (isCirclingCrystal()) return false; // Purpur - pathfinder does not have a flag if (this.c > 0) { --this.c; return false; -@@ -310,6 +466,7 @@ public class EntityPhantom extends EntityFlying implements IMonster { +@@ -238,6 +396,7 @@ public class EntityPhantom extends EntityFlying implements IMonster { + @Override public boolean b() { - if (getRider() != null) return false; // Purpur - pathfinder does not have a flag + if (isCirclingCrystal()) return false; // Purpur - pathfinder does not have a flag EntityLiving entityliving = EntityPhantom.this.getGoalTarget(); return entityliving != null ? EntityPhantom.this.a(entityliving, PathfinderTargetCondition.a) : false; -@@ -325,6 +482,7 @@ public class EntityPhantom extends EntityFlying implements IMonster { +@@ -252,6 +411,7 @@ public class EntityPhantom extends EntityFlying implements IMonster { + @Override public boolean a() { - if (getRider() != null) return false; // Purpur - pathfinder does not have a flag + if (isCirclingCrystal()) return false; // Purpur - pathfinder does not have a flag EntityLiving entityliving = EntityPhantom.this.getGoalTarget(); return entityliving != null ? EntityPhantom.this.a(EntityPhantom.this.getGoalTarget(), PathfinderTargetCondition.a) : false; -diff --git a/src/main/java/net/minecraft/server/IEntityAccess.java b/src/main/java/net/minecraft/server/IEntityAccess.java -index 3bc57ef91..e0d97d2c8 100644 ---- a/src/main/java/net/minecraft/server/IEntityAccess.java -+++ b/src/main/java/net/minecraft/server/IEntityAccess.java -@@ -34,6 +34,7 @@ public interface IEntityAccess { - }); - } - -+ default List getEntitiesByClass(Class oclass, AxisAlignedBB axisalignedbb) { return a(oclass, axisalignedbb); } // Purpur - OBFHELPER - default List a(Class oclass, AxisAlignedBB axisalignedbb) { - return this.a(oclass, axisalignedbb, IEntitySelector.f); - } diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 85692500b..c9b41cebd 100644 +index 8ce344c2a..080a53544 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -402,6 +402,9 @@ public class PurpurWorldConfig { - public double phantomMaxY = 256D; - public float phantomFlameDamage = 1.0F; - public int phantomFlameFireTime = 8; +@@ -312,6 +312,15 @@ public class PurpurWorldConfig { + ironGolemCanSwim = getBoolean("mobs.iron_golem.can-swim", ironGolemCanSwim); + } + + public double phantomAttackedByCrystalRadius = 0.0D; + public float phantomAttackedByCrystalDamage = 1.0F; + public double phantomOrbitCrystalRadius = 0.0D; - private void phantomSettings() { - phantomRidable = getBoolean("mobs.phantom.ridable", phantomRidable); - phantomRidableInWater = getBoolean("mobs.phantom.ridable-in-water", phantomRidableInWater); -@@ -409,6 +412,9 @@ public class PurpurWorldConfig { - phantomMaxY = getDouble("mobs.phantom.ridable-max-y", phantomMaxY); - phantomFlameDamage = (float) getDouble("mobs.phantom.flames.damage", phantomFlameDamage); - phantomFlameFireTime = getInt("mobs.phantom.flames.fire-time", phantomFlameFireTime); ++ private void phantomSettings() { + phantomAttackedByCrystalRadius = getDouble("mobs.phantom.attacked-by-crystal-range", phantomAttackedByCrystalRadius); + phantomAttackedByCrystalDamage = (float) getDouble("mobs.phantom.attacked-by-crystal-damage", phantomAttackedByCrystalDamage); + phantomOrbitCrystalRadius = getDouble("mobs.phantom.orbit-crystal-radius", phantomOrbitCrystalRadius); - } - - public boolean pigRidable = false; ++ } ++ + public boolean pigGiveSaddleBack = false; + private void pigSettings() { + pigGiveSaddleBack = getBoolean("mobs.pig.give-saddle-back", pigGiveSaddleBack); -- 2.26.2 diff --git a/patches/server/0102-Configurable-jockey-options.patch b/patches/server/0102-Configurable-jockey-options.patch deleted file mode 100644 index 37b32ad21..000000000 --- a/patches/server/0102-Configurable-jockey-options.patch +++ /dev/null @@ -1,282 +0,0 @@ -From e08b23e89c1207ccb55349347521cc0de0cc37cd Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Thu, 26 Mar 2020 21:39:32 -0500 -Subject: [PATCH] Configurable jockey options - ---- - .../net/minecraft/server/EntityDrowned.java | 15 ++++++++++ - .../net/minecraft/server/EntityPigZombie.java | 15 ++++++++++ - .../net/minecraft/server/EntityZombie.java | 29 +++++++++++++----- - .../minecraft/server/EntityZombieHusk.java | 15 ++++++++++ - .../server/EntityZombieVillager.java | 15 ++++++++++ - .../net/pl3x/purpur/PurpurWorldConfig.java | 30 +++++++++++++++++++ - 6 files changed, 112 insertions(+), 7 deletions(-) - -diff --git a/src/main/java/net/minecraft/server/EntityDrowned.java b/src/main/java/net/minecraft/server/EntityDrowned.java -index 63f5969b1..f32950cc9 100644 ---- a/src/main/java/net/minecraft/server/EntityDrowned.java -+++ b/src/main/java/net/minecraft/server/EntityDrowned.java -@@ -34,6 +34,21 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { - public boolean requireShiftToMount() { - return world.purpurConfig.drownedRequireShiftToMount; - } -+ -+ @Override -+ public boolean jockeyOnlyBaby() { -+ return world.purpurConfig.drownedJockeyOnlyBaby; -+ } -+ -+ @Override -+ public double jockeyChance() { -+ return world.purpurConfig.drownedJockeyChance; -+ } -+ -+ @Override -+ public boolean jockeyTryExistingChickens() { -+ return world.purpurConfig.drownedJockeyTryExistingChickens; -+ } - // Purpur end - - @Override -diff --git a/src/main/java/net/minecraft/server/EntityPigZombie.java b/src/main/java/net/minecraft/server/EntityPigZombie.java -index fb9ef88ea..90bf12c73 100644 ---- a/src/main/java/net/minecraft/server/EntityPigZombie.java -+++ b/src/main/java/net/minecraft/server/EntityPigZombie.java -@@ -32,6 +32,21 @@ public class EntityPigZombie extends EntityZombie { - public boolean requireShiftToMount() { - return world.purpurConfig.zombiePigmanRequireShiftToMount; - } -+ -+ @Override -+ public boolean jockeyOnlyBaby() { -+ return world.purpurConfig.zombiePigmanJockeyOnlyBaby; -+ } -+ -+ @Override -+ public double jockeyChance() { -+ return world.purpurConfig.zombiePigmanJockeyChance; -+ } -+ -+ @Override -+ public boolean jockeyTryExistingChickens() { -+ return world.purpurConfig.zombiePigmanJockeyTryExistingChickens; -+ } - // Purpur end - - @Override -diff --git a/src/main/java/net/minecraft/server/EntityZombie.java b/src/main/java/net/minecraft/server/EntityZombie.java -index 95ae6f349..e60e4adc1 100644 ---- a/src/main/java/net/minecraft/server/EntityZombie.java -+++ b/src/main/java/net/minecraft/server/EntityZombie.java -@@ -3,6 +3,7 @@ package net.minecraft.server; - import com.mojang.datafixers.types.DynamicOps; - import java.time.LocalDate; - import java.time.temporal.ChronoField; -+import java.util.Collections; - import java.util.List; - import java.util.UUID; - import java.util.function.Predicate; -@@ -59,6 +60,18 @@ public class EntityZombie extends EntityMonster { - public boolean requireShiftToMount() { - return world.purpurConfig.zombieRequireShiftToMount; - } -+ -+ public boolean jockeyOnlyBaby() { -+ return world.purpurConfig.zombieJockeyOnlyBaby; -+ } -+ -+ public double jockeyChance() { -+ return world.purpurConfig.zombieJockeyChance; -+ } -+ -+ public boolean jockeyTryExistingChickens() { -+ return world.purpurConfig.zombieJockeyTryExistingChickens; -+ } - // Purpur end - - @Override -@@ -542,18 +555,19 @@ public class EntityZombie extends EntityMonster { - if (object instanceof EntityZombie.GroupDataZombie) { - EntityZombie.GroupDataZombie entityzombie_groupdatazombie = (EntityZombie.GroupDataZombie) object; - -- if (entityzombie_groupdatazombie.a) { -- this.setBaby(true); -- if ((double) generatoraccess.getRandom().nextFloat() < 0.05D) { -- List list = generatoraccess.a(EntityChicken.class, this.getBoundingBox().grow(5.0D, 3.0D, 5.0D), IEntitySelector.c); -+ // Purpur start -+ if (!jockeyOnlyBaby() || entityzombie_groupdatazombie.isBaby()) { -+ this.setBaby(entityzombie_groupdatazombie.isBaby()); -+ if ((double) generatoraccess.getRandom().nextFloat() < jockeyChance()) { -+ List list = jockeyTryExistingChickens() ? generatoraccess.a(EntityChicken.class, this.getBoundingBox().grow(5.0D, 3.0D, 5.0D), IEntitySelector.c) : Collections.emptyList(); -+ // Purpur end - - if (!list.isEmpty()) { - EntityChicken entitychicken = (EntityChicken) list.get(0); - - entitychicken.r(true); - this.startRiding(entitychicken); -- } -- } else if ((double) generatoraccess.getRandom().nextFloat() < 0.05D) { -+ } else { // Purpur - EntityChicken entitychicken1 = (EntityChicken) EntityTypes.CHICKEN.a(this.world); - - entitychicken1.setPositionRotation(this.locX(), this.locY(), this.locZ(), this.yaw, 0.0F); -@@ -561,6 +575,7 @@ public class EntityZombie extends EntityMonster { - entitychicken1.r(true); - generatoraccess.addEntity(entitychicken1, CreatureSpawnEvent.SpawnReason.MOUNT); // CraftBukkit - this.startRiding(entitychicken1); -+ } // Purpur - } - } - -@@ -653,7 +668,7 @@ public class EntityZombie extends EntityMonster { - - public class GroupDataZombie implements GroupDataEntity { - -- public final boolean a; -+ public final boolean a; public boolean isBaby() { return a; } // Purpur - OBFHELPER - - private GroupDataZombie(boolean flag) { - this.a = flag; -diff --git a/src/main/java/net/minecraft/server/EntityZombieHusk.java b/src/main/java/net/minecraft/server/EntityZombieHusk.java -index db252ba4e..e8b099d6c 100644 ---- a/src/main/java/net/minecraft/server/EntityZombieHusk.java -+++ b/src/main/java/net/minecraft/server/EntityZombieHusk.java -@@ -23,6 +23,21 @@ public class EntityZombieHusk extends EntityZombie { - public boolean requireShiftToMount() { - return world.purpurConfig.huskRequireShiftToMount; - } -+ -+ @Override -+ public boolean jockeyOnlyBaby() { -+ return world.purpurConfig.huskJockeyOnlyBaby; -+ } -+ -+ @Override -+ public double jockeyChance() { -+ return world.purpurConfig.huskJockeyChance; -+ } -+ -+ @Override -+ public boolean jockeyTryExistingChickens() { -+ return world.purpurConfig.huskJockeyTryExistingChickens; -+ } - // Purpur end - - public static boolean b(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { -diff --git a/src/main/java/net/minecraft/server/EntityZombieVillager.java b/src/main/java/net/minecraft/server/EntityZombieVillager.java -index ebbfcb75a..8532385d8 100644 ---- a/src/main/java/net/minecraft/server/EntityZombieVillager.java -+++ b/src/main/java/net/minecraft/server/EntityZombieVillager.java -@@ -40,6 +40,21 @@ public class EntityZombieVillager extends EntityZombie implements VillagerDataHo - public boolean requireShiftToMount() { - return world.purpurConfig.zombieVillagerRequireShiftToMount; - } -+ -+ @Override -+ public boolean jockeyOnlyBaby() { -+ return world.purpurConfig.zombieVillagerJockeyOnlyBaby; -+ } -+ -+ @Override -+ public double jockeyChance() { -+ return world.purpurConfig.zombieVillagerJockeyChance; -+ } -+ -+ @Override -+ public boolean jockeyTryExistingChickens() { -+ return world.purpurConfig.zombieVillagerJockeyTryExistingChickens; -+ } - // Purpur end - - @Override -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index ced9edf82..adcdc6b8f 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -401,10 +401,16 @@ public class PurpurWorldConfig { - public boolean drownedRidable = false; - public boolean drownedRidableInWater = false; - public boolean drownedRequireShiftToMount = true; -+ public boolean drownedJockeyOnlyBaby = true; -+ public double drownedJockeyChance = 0.05D; -+ public boolean drownedJockeyTryExistingChickens = true; - private void drownedSettings() { - drownedRidable = getBoolean("mobs.drowned.ridable", drownedRidable); - drownedRidableInWater = getBoolean("mobs.drowned.ridable-in-water", drownedRidableInWater); - drownedRequireShiftToMount = getBoolean("mobs.drowned.require-shift-to-mount", drownedRequireShiftToMount); -+ drownedJockeyOnlyBaby = getBoolean("mobs.drowned.jockey.only-babies", drownedJockeyOnlyBaby); -+ drownedJockeyChance = getDouble("mobs.drowned.jockey.chance", drownedJockeyChance); -+ drownedJockeyTryExistingChickens = getBoolean("mobs.drowned.jockey.try-existing-chickens", drownedJockeyTryExistingChickens); - } - - public boolean elderGuardianRidable = false; -@@ -515,10 +521,16 @@ public class PurpurWorldConfig { - public boolean huskRidable = false; - public boolean huskRidableInWater = false; - public boolean huskRequireShiftToMount = true; -+ public boolean huskJockeyOnlyBaby = true; -+ public double huskJockeyChance = 0.05D; -+ public boolean huskJockeyTryExistingChickens = true; - private void huskSettings() { - huskRidable = getBoolean("mobs.husk.ridable", huskRidable); - huskRidableInWater = getBoolean("mobs.husk.ridable-in-water", huskRidableInWater); - huskRequireShiftToMount = getBoolean("mobs.husk.require-shift-to-mount", huskRequireShiftToMount); -+ huskJockeyOnlyBaby = getBoolean("mobs.husk.jockey.only-babies", huskJockeyOnlyBaby); -+ huskJockeyChance = getDouble("mobs.husk.jockey.chance", huskJockeyChance); -+ huskJockeyTryExistingChickens = getBoolean("mobs.husk.jockey.try-existing-chickens", huskJockeyTryExistingChickens); - } - - public boolean horseRidableInWater = false; -@@ -927,11 +939,17 @@ public class PurpurWorldConfig { - public boolean zombieRidableInWater = false; - public boolean zombieRequireShiftToMount = true; - public boolean zombieTargetTurtleEggs = true; -+ public boolean zombieJockeyOnlyBaby = true; -+ public double zombieJockeyChance = 0.05D; -+ public boolean zombieJockeyTryExistingChickens = true; - private void zombieSettings() { - zombieRidable = getBoolean("mobs.zombie.ridable", zombieRidable); - zombieRidableInWater = getBoolean("mobs.zombie.ridable-in-water", zombieRidableInWater); - zombieRequireShiftToMount = getBoolean("mobs.zombie.require-shift-to-mount", zombieRequireShiftToMount); - zombieTargetTurtleEggs = getBoolean("mobs.zombie.target-turtle-eggs", zombieTargetTurtleEggs); -+ zombieJockeyOnlyBaby = getBoolean("mobs.zombie.jockey.only-babies", zombieJockeyOnlyBaby); -+ zombieJockeyChance = getDouble("mobs.zombie.jockey.chance", zombieJockeyChance); -+ zombieJockeyTryExistingChickens = getBoolean("mobs.zombie.jockey.try-existing-chickens", zombieJockeyTryExistingChickens); - } - - public boolean zombieHorseCanSwim = false; -@@ -946,18 +964,30 @@ public class PurpurWorldConfig { - public boolean zombiePigmanRidable = false; - public boolean zombiePigmanRidableInWater = false; - public boolean zombiePigmanRequireShiftToMount = true; -+ public boolean zombiePigmanJockeyOnlyBaby = true; -+ public double zombiePigmanJockeyChance = 0.05D; -+ public boolean zombiePigmanJockeyTryExistingChickens = true; - private void zombiePigmanSettings() { - zombiePigmanRidable = getBoolean("mobs.zombie_pigman.ridable", zombiePigmanRidable); - zombiePigmanRidableInWater = getBoolean("mobs.zombie_pigman.ridable-in-water", zombiePigmanRidableInWater); - zombiePigmanRequireShiftToMount = getBoolean("mobs.zombie_pigman.require-shift-to-mount", zombiePigmanRequireShiftToMount); -+ zombiePigmanJockeyOnlyBaby = getBoolean("mobs.zombie_pigman.jockey.only-babies", zombiePigmanJockeyOnlyBaby); -+ zombiePigmanJockeyChance = getDouble("mobs.zombie_pigman.jockey.chance", zombiePigmanJockeyChance); -+ zombiePigmanJockeyTryExistingChickens = getBoolean("mobs.zombie_pigman.jockey.try-existing-chickens", zombiePigmanJockeyTryExistingChickens); - } - - public boolean zombieVillagerRidable = false; - public boolean zombieVillagerRidableInWater = false; - public boolean zombieVillagerRequireShiftToMount = true; -+ public boolean zombieVillagerJockeyOnlyBaby = true; -+ public double zombieVillagerJockeyChance = 0.05D; -+ public boolean zombieVillagerJockeyTryExistingChickens = true; - private void zombieVillagerSettings() { - zombieVillagerRidable = getBoolean("mobs.zombie_villager.ridable", zombieVillagerRidable); - zombieVillagerRidableInWater = getBoolean("mobs.zombie_villager.ridable-in-water", zombieVillagerRidableInWater); - zombieVillagerRequireShiftToMount = getBoolean("mobs.zombie_villager.require-shift-to-mount", zombieVillagerRequireShiftToMount); -+ zombieVillagerJockeyOnlyBaby = getBoolean("mobs.zombie_villager.jockey.only-babies", zombieVillagerJockeyOnlyBaby); -+ zombieVillagerJockeyChance = getDouble("mobs.zombie_villager.jockey.chance", zombieVillagerJockeyChance); -+ zombieVillagerJockeyTryExistingChickens = getBoolean("mobs.zombie_villager.jockey.try-existing-chickens", zombieVillagerJockeyTryExistingChickens); - } - } --- -2.26.2 - diff --git a/patches/server/0103-Configurable-enchantment-max-level.patch b/patches/server/0103-Configurable-enchantment-max-level.patch deleted file mode 100644 index a34f2fcd4..000000000 --- a/patches/server/0103-Configurable-enchantment-max-level.patch +++ /dev/null @@ -1,788 +0,0 @@ -From df05bfbcf31d32354e0286477ecf261279eb244d Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Wed, 1 Apr 2020 17:21:42 -0500 -Subject: [PATCH] Configurable enchantment max level - ---- - src/main/java/net/minecraft/server/Enchantment.java | 12 ++++++++++-- - .../net/minecraft/server/EnchantmentArrowDamage.java | 6 +----- - .../minecraft/server/EnchantmentArrowKnockback.java | 6 +----- - .../net/minecraft/server/EnchantmentBinding.java | 6 +----- - .../minecraft/server/EnchantmentDepthStrider.java | 6 +----- - .../net/minecraft/server/EnchantmentDigging.java | 6 +----- - .../net/minecraft/server/EnchantmentDurability.java | 6 +----- - .../java/net/minecraft/server/EnchantmentFire.java | 6 +----- - .../net/minecraft/server/EnchantmentFlameArrows.java | 6 +----- - .../net/minecraft/server/EnchantmentFrostWalker.java | 6 +----- - .../minecraft/server/EnchantmentInfiniteArrows.java | 6 +----- - .../net/minecraft/server/EnchantmentKnockback.java | 6 +----- - .../net/minecraft/server/EnchantmentLootBonus.java | 6 +----- - .../java/net/minecraft/server/EnchantmentLure.java | 6 +----- - .../net/minecraft/server/EnchantmentMending.java | 6 +----- - .../net/minecraft/server/EnchantmentMultishot.java | 6 +----- - .../java/net/minecraft/server/EnchantmentOxygen.java | 6 +----- - .../net/minecraft/server/EnchantmentPiercing.java | 6 +----- - .../net/minecraft/server/EnchantmentProtection.java | 7 +------ - .../net/minecraft/server/EnchantmentQuickCharge.java | 6 +----- - .../net/minecraft/server/EnchantmentSilkTouch.java | 6 +----- - .../net/minecraft/server/EnchantmentSweeping.java | 6 +----- - .../java/net/minecraft/server/EnchantmentThorns.java | 6 +----- - .../server/EnchantmentTridentChanneling.java | 6 +----- - .../minecraft/server/EnchantmentTridentImpaling.java | 6 +----- - .../minecraft/server/EnchantmentTridentLoyalty.java | 6 +----- - .../minecraft/server/EnchantmentTridentRiptide.java | 6 +----- - .../net/minecraft/server/EnchantmentVanishing.java | 6 +----- - .../net/minecraft/server/EnchantmentWaterWorker.java | 6 +----- - .../minecraft/server/EnchantmentWeaponDamage.java | 6 +----- - src/main/java/net/pl3x/purpur/PurpurConfig.java | 10 ++++++++++ - .../craftbukkit/enchantments/CraftEnchantment.java | 7 +++++++ - 32 files changed, 56 insertions(+), 148 deletions(-) - -diff --git a/src/main/java/net/minecraft/server/Enchantment.java b/src/main/java/net/minecraft/server/Enchantment.java -index 70cd4a483..0ab96ea34 100644 ---- a/src/main/java/net/minecraft/server/Enchantment.java -+++ b/src/main/java/net/minecraft/server/Enchantment.java -@@ -44,9 +44,17 @@ public abstract class Enchantment { - return 1; - } - -- public int getMaxLevel() { -- return 1; -+ // Purpur start -+ private int maxLevel = 1; -+ -+ public final int getMaxLevel() { -+ return maxLevel; -+ } -+ -+ public final void setMaxLevel(int maxLevel) { -+ this.maxLevel = maxLevel; - } -+ // Purpur end - - public int a(int i) { - return 1 + i * 10; -diff --git a/src/main/java/net/minecraft/server/EnchantmentArrowDamage.java b/src/main/java/net/minecraft/server/EnchantmentArrowDamage.java -index ffa1d19cb..1040e7e08 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentArrowDamage.java -+++ b/src/main/java/net/minecraft/server/EnchantmentArrowDamage.java -@@ -4,6 +4,7 @@ public class EnchantmentArrowDamage extends Enchantment { - - public EnchantmentArrowDamage(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.BOW, aenumitemslot); -+ setMaxLevel(5); // Purpur - } - - @Override -@@ -15,9 +16,4 @@ public class EnchantmentArrowDamage extends Enchantment { - public int b(int i) { - return this.a(i) + 15; - } -- -- @Override -- public int getMaxLevel() { -- return 5; -- } - } -diff --git a/src/main/java/net/minecraft/server/EnchantmentArrowKnockback.java b/src/main/java/net/minecraft/server/EnchantmentArrowKnockback.java -index 9103f3c61..67f487b9e 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentArrowKnockback.java -+++ b/src/main/java/net/minecraft/server/EnchantmentArrowKnockback.java -@@ -4,6 +4,7 @@ public class EnchantmentArrowKnockback extends Enchantment { - - public EnchantmentArrowKnockback(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.BOW, aenumitemslot); -+ setMaxLevel(2); // Purpur - } - - @Override -@@ -15,9 +16,4 @@ public class EnchantmentArrowKnockback extends Enchantment { - public int b(int i) { - return this.a(i) + 25; - } -- -- @Override -- public int getMaxLevel() { -- return 2; -- } - } -diff --git a/src/main/java/net/minecraft/server/EnchantmentBinding.java b/src/main/java/net/minecraft/server/EnchantmentBinding.java -index b49154b13..ec4dad3cf 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentBinding.java -+++ b/src/main/java/net/minecraft/server/EnchantmentBinding.java -@@ -4,6 +4,7 @@ public class EnchantmentBinding extends Enchantment { - - public EnchantmentBinding(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.WEARABLE, aenumitemslot); -+ setMaxLevel(1); // Purpur - } - - @Override -@@ -16,11 +17,6 @@ public class EnchantmentBinding extends Enchantment { - return 50; - } - -- @Override -- public int getMaxLevel() { -- return 1; -- } -- - @Override - public boolean isTreasure() { - return true; -diff --git a/src/main/java/net/minecraft/server/EnchantmentDepthStrider.java b/src/main/java/net/minecraft/server/EnchantmentDepthStrider.java -index 669fbd268..07d566cd9 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentDepthStrider.java -+++ b/src/main/java/net/minecraft/server/EnchantmentDepthStrider.java -@@ -4,6 +4,7 @@ public class EnchantmentDepthStrider extends Enchantment { - - public EnchantmentDepthStrider(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.ARMOR_FEET, aenumitemslot); -+ setMaxLevel(3); // Purpur - } - - @Override -@@ -16,11 +17,6 @@ public class EnchantmentDepthStrider extends Enchantment { - return this.a(i) + 15; - } - -- @Override -- public int getMaxLevel() { -- return 3; -- } -- - @Override - public boolean a(Enchantment enchantment) { - return super.a(enchantment) && enchantment != Enchantments.FROST_WALKER; -diff --git a/src/main/java/net/minecraft/server/EnchantmentDigging.java b/src/main/java/net/minecraft/server/EnchantmentDigging.java -index 798b3c250..16a7c38bc 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentDigging.java -+++ b/src/main/java/net/minecraft/server/EnchantmentDigging.java -@@ -4,6 +4,7 @@ public class EnchantmentDigging extends Enchantment { - - protected EnchantmentDigging(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.DIGGER, aenumitemslot); -+ setMaxLevel(5); // Purpur - } - - @Override -@@ -16,11 +17,6 @@ public class EnchantmentDigging extends Enchantment { - return super.a(i) + 50; - } - -- @Override -- public int getMaxLevel() { -- return 5; -- } -- - @Override - public boolean canEnchant(ItemStack itemstack) { - return itemstack.getItem() == Items.SHEARS ? true : super.canEnchant(itemstack); -diff --git a/src/main/java/net/minecraft/server/EnchantmentDurability.java b/src/main/java/net/minecraft/server/EnchantmentDurability.java -index c946326fb..6deccef55 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentDurability.java -+++ b/src/main/java/net/minecraft/server/EnchantmentDurability.java -@@ -6,6 +6,7 @@ public class EnchantmentDurability extends Enchantment { - - protected EnchantmentDurability(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.BREAKABLE, aenumitemslot); -+ setMaxLevel(3); // Purpur - } - - @Override -@@ -18,11 +19,6 @@ public class EnchantmentDurability extends Enchantment { - return super.a(i) + 50; - } - -- @Override -- public int getMaxLevel() { -- return 3; -- } -- - @Override - public boolean canEnchant(ItemStack itemstack) { - return itemstack.e() ? true : super.canEnchant(itemstack); -diff --git a/src/main/java/net/minecraft/server/EnchantmentFire.java b/src/main/java/net/minecraft/server/EnchantmentFire.java -index c4da4378c..f2664c18e 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentFire.java -+++ b/src/main/java/net/minecraft/server/EnchantmentFire.java -@@ -4,6 +4,7 @@ public class EnchantmentFire extends Enchantment { - - protected EnchantmentFire(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.WEAPON, aenumitemslot); -+ setMaxLevel(2); // Purpur - } - - @Override -@@ -15,9 +16,4 @@ public class EnchantmentFire extends Enchantment { - public int b(int i) { - return super.a(i) + 50; - } -- -- @Override -- public int getMaxLevel() { -- return 2; -- } - } -diff --git a/src/main/java/net/minecraft/server/EnchantmentFlameArrows.java b/src/main/java/net/minecraft/server/EnchantmentFlameArrows.java -index a0b4da25b..af3db770f 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentFlameArrows.java -+++ b/src/main/java/net/minecraft/server/EnchantmentFlameArrows.java -@@ -4,6 +4,7 @@ public class EnchantmentFlameArrows extends Enchantment { - - public EnchantmentFlameArrows(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.BOW, aenumitemslot); -+ setMaxLevel(1); // Purpur - } - - @Override -@@ -15,9 +16,4 @@ public class EnchantmentFlameArrows extends Enchantment { - public int b(int i) { - return 50; - } -- -- @Override -- public int getMaxLevel() { -- return 1; -- } - } -diff --git a/src/main/java/net/minecraft/server/EnchantmentFrostWalker.java b/src/main/java/net/minecraft/server/EnchantmentFrostWalker.java -index b5de6c740..8c4fd331c 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentFrostWalker.java -+++ b/src/main/java/net/minecraft/server/EnchantmentFrostWalker.java -@@ -10,6 +10,7 @@ public class EnchantmentFrostWalker extends Enchantment { - - public EnchantmentFrostWalker(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.ARMOR_FEET, aenumitemslot); -+ setMaxLevel(2); // Purpur - } - - @Override -@@ -27,11 +28,6 @@ public class EnchantmentFrostWalker extends Enchantment { - return true; - } - -- @Override -- public int getMaxLevel() { -- return 2; -- } -- - public static void a(EntityLiving entityliving, World world, BlockPosition blockposition, int i) { - if (entityliving.onGround) { - IBlockData iblockdata = Blocks.FROSTED_ICE.getBlockData(); -diff --git a/src/main/java/net/minecraft/server/EnchantmentInfiniteArrows.java b/src/main/java/net/minecraft/server/EnchantmentInfiniteArrows.java -index 408cfa460..1dbedc0ad 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentInfiniteArrows.java -+++ b/src/main/java/net/minecraft/server/EnchantmentInfiniteArrows.java -@@ -4,6 +4,7 @@ public class EnchantmentInfiniteArrows extends Enchantment { - - public EnchantmentInfiniteArrows(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.BOW, aenumitemslot); -+ setMaxLevel(1); // Purpur - } - - @Override -@@ -16,11 +17,6 @@ public class EnchantmentInfiniteArrows extends Enchantment { - return 50; - } - -- @Override -- public int getMaxLevel() { -- return 1; -- } -- - @Override - public boolean a(Enchantment enchantment) { - return enchantment instanceof EnchantmentMending ? false : super.a(enchantment); -diff --git a/src/main/java/net/minecraft/server/EnchantmentKnockback.java b/src/main/java/net/minecraft/server/EnchantmentKnockback.java -index 362ce7bc4..04062c255 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentKnockback.java -+++ b/src/main/java/net/minecraft/server/EnchantmentKnockback.java -@@ -4,6 +4,7 @@ public class EnchantmentKnockback extends Enchantment { - - protected EnchantmentKnockback(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.WEAPON, aenumitemslot); -+ setMaxLevel(2); // Purpur - } - - @Override -@@ -15,9 +16,4 @@ public class EnchantmentKnockback extends Enchantment { - public int b(int i) { - return super.a(i) + 50; - } -- -- @Override -- public int getMaxLevel() { -- return 2; -- } - } -diff --git a/src/main/java/net/minecraft/server/EnchantmentLootBonus.java b/src/main/java/net/minecraft/server/EnchantmentLootBonus.java -index b5232facc..c27e20e06 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentLootBonus.java -+++ b/src/main/java/net/minecraft/server/EnchantmentLootBonus.java -@@ -4,6 +4,7 @@ public class EnchantmentLootBonus extends Enchantment { - - protected EnchantmentLootBonus(Enchantment.Rarity enchantment_rarity, EnchantmentSlotType enchantmentslottype, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, enchantmentslottype, aenumitemslot); -+ setMaxLevel(3); // Purpur - } - - @Override -@@ -16,11 +17,6 @@ public class EnchantmentLootBonus extends Enchantment { - return super.a(i) + 50; - } - -- @Override -- public int getMaxLevel() { -- return 3; -- } -- - @Override - public boolean a(Enchantment enchantment) { - return super.a(enchantment) && enchantment != Enchantments.SILK_TOUCH; -diff --git a/src/main/java/net/minecraft/server/EnchantmentLure.java b/src/main/java/net/minecraft/server/EnchantmentLure.java -index 1ffb91c57..c5a9e61f9 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentLure.java -+++ b/src/main/java/net/minecraft/server/EnchantmentLure.java -@@ -4,6 +4,7 @@ public class EnchantmentLure extends Enchantment { - - protected EnchantmentLure(Enchantment.Rarity enchantment_rarity, EnchantmentSlotType enchantmentslottype, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, enchantmentslottype, aenumitemslot); -+ setMaxLevel(3); // Purpur - } - - @Override -@@ -15,9 +16,4 @@ public class EnchantmentLure extends Enchantment { - public int b(int i) { - return super.a(i) + 50; - } -- -- @Override -- public int getMaxLevel() { -- return 3; -- } - } -diff --git a/src/main/java/net/minecraft/server/EnchantmentMending.java b/src/main/java/net/minecraft/server/EnchantmentMending.java -index dafc29399..ace2e19a6 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentMending.java -+++ b/src/main/java/net/minecraft/server/EnchantmentMending.java -@@ -4,6 +4,7 @@ public class EnchantmentMending extends Enchantment { - - public EnchantmentMending(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.BREAKABLE, aenumitemslot); -+ setMaxLevel(1); // Purpur - } - - @Override -@@ -20,9 +21,4 @@ public class EnchantmentMending extends Enchantment { - public boolean isTreasure() { - return true; - } -- -- @Override -- public int getMaxLevel() { -- return 1; -- } - } -diff --git a/src/main/java/net/minecraft/server/EnchantmentMultishot.java b/src/main/java/net/minecraft/server/EnchantmentMultishot.java -index 6f423e753..5fb8a624c 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentMultishot.java -+++ b/src/main/java/net/minecraft/server/EnchantmentMultishot.java -@@ -4,6 +4,7 @@ public class EnchantmentMultishot extends Enchantment { - - public EnchantmentMultishot(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.CROSSBOW, aenumitemslot); -+ setMaxLevel(1); // Purpur - } - - @Override -@@ -16,11 +17,6 @@ public class EnchantmentMultishot extends Enchantment { - return 50; - } - -- @Override -- public int getMaxLevel() { -- return 1; -- } -- - @Override - public boolean a(Enchantment enchantment) { - return super.a(enchantment) && enchantment != Enchantments.PIERCING; -diff --git a/src/main/java/net/minecraft/server/EnchantmentOxygen.java b/src/main/java/net/minecraft/server/EnchantmentOxygen.java -index c1bc97f6e..a5726d36d 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentOxygen.java -+++ b/src/main/java/net/minecraft/server/EnchantmentOxygen.java -@@ -4,6 +4,7 @@ public class EnchantmentOxygen extends Enchantment { - - public EnchantmentOxygen(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.ARMOR_HEAD, aenumitemslot); -+ setMaxLevel(3);// Purpur - } - - @Override -@@ -15,9 +16,4 @@ public class EnchantmentOxygen extends Enchantment { - public int b(int i) { - return this.a(i) + 30; - } -- -- @Override -- public int getMaxLevel() { -- return 3; -- } - } -diff --git a/src/main/java/net/minecraft/server/EnchantmentPiercing.java b/src/main/java/net/minecraft/server/EnchantmentPiercing.java -index 1a2e8e31f..0e8993e86 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentPiercing.java -+++ b/src/main/java/net/minecraft/server/EnchantmentPiercing.java -@@ -4,6 +4,7 @@ public class EnchantmentPiercing extends Enchantment { - - public EnchantmentPiercing(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.CROSSBOW, aenumitemslot); -+ setMaxLevel(4); // Purpur - } - - @Override -@@ -16,11 +17,6 @@ public class EnchantmentPiercing extends Enchantment { - return 50; - } - -- @Override -- public int getMaxLevel() { -- return 4; -- } -- - @Override - public boolean a(Enchantment enchantment) { - return super.a(enchantment) && enchantment != Enchantments.MULTISHOT; -diff --git a/src/main/java/net/minecraft/server/EnchantmentProtection.java b/src/main/java/net/minecraft/server/EnchantmentProtection.java -index 416e57caa..b29cb5467 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentProtection.java -+++ b/src/main/java/net/minecraft/server/EnchantmentProtection.java -@@ -10,7 +10,7 @@ public class EnchantmentProtection extends Enchantment { - if (enchantmentprotection_damagetype == EnchantmentProtection.DamageType.FALL) { - this.itemTarget = EnchantmentSlotType.ARMOR_FEET; - } -- -+ setMaxLevel(4); // Purpur - } - - @Override -@@ -23,11 +23,6 @@ public class EnchantmentProtection extends Enchantment { - return this.a(i) + this.a.c(); - } - -- @Override -- public int getMaxLevel() { -- return 4; -- } -- - @Override - public int a(int i, DamageSource damagesource) { - return damagesource.ignoresInvulnerability() ? 0 : (this.a == EnchantmentProtection.DamageType.ALL ? i : (this.a == EnchantmentProtection.DamageType.FIRE && damagesource.isFire() ? i * 2 : (this.a == EnchantmentProtection.DamageType.FALL && damagesource == DamageSource.FALL ? i * 3 : (this.a == EnchantmentProtection.DamageType.EXPLOSION && damagesource.isExplosion() ? i * 2 : (this.a == EnchantmentProtection.DamageType.PROJECTILE && damagesource.b() ? i * 2 : 0))))); -diff --git a/src/main/java/net/minecraft/server/EnchantmentQuickCharge.java b/src/main/java/net/minecraft/server/EnchantmentQuickCharge.java -index e624b63aa..762642ce5 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentQuickCharge.java -+++ b/src/main/java/net/minecraft/server/EnchantmentQuickCharge.java -@@ -4,6 +4,7 @@ public class EnchantmentQuickCharge extends Enchantment { - - public EnchantmentQuickCharge(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.CROSSBOW, aenumitemslot); -+ setMaxLevel(3); // Purpur - } - - @Override -@@ -15,9 +16,4 @@ public class EnchantmentQuickCharge extends Enchantment { - public int b(int i) { - return 50; - } -- -- @Override -- public int getMaxLevel() { -- return 3; -- } - } -diff --git a/src/main/java/net/minecraft/server/EnchantmentSilkTouch.java b/src/main/java/net/minecraft/server/EnchantmentSilkTouch.java -index 04aa8e1d5..d0eac6dbc 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentSilkTouch.java -+++ b/src/main/java/net/minecraft/server/EnchantmentSilkTouch.java -@@ -4,6 +4,7 @@ public class EnchantmentSilkTouch extends Enchantment { - - protected EnchantmentSilkTouch(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.DIGGER, aenumitemslot); -+ setMaxLevel(1); // Purpur - } - - @Override -@@ -16,11 +17,6 @@ public class EnchantmentSilkTouch extends Enchantment { - return super.a(i) + 50; - } - -- @Override -- public int getMaxLevel() { -- return 1; -- } -- - @Override - public boolean a(Enchantment enchantment) { - return super.a(enchantment) && enchantment != Enchantments.LOOT_BONUS_BLOCKS; -diff --git a/src/main/java/net/minecraft/server/EnchantmentSweeping.java b/src/main/java/net/minecraft/server/EnchantmentSweeping.java -index a20b1c8f5..7804e0a0a 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentSweeping.java -+++ b/src/main/java/net/minecraft/server/EnchantmentSweeping.java -@@ -4,6 +4,7 @@ public class EnchantmentSweeping extends Enchantment { - - public EnchantmentSweeping(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.WEAPON, aenumitemslot); -+ setMaxLevel(3); // Purpur - } - - @Override -@@ -16,11 +17,6 @@ public class EnchantmentSweeping extends Enchantment { - return this.a(i) + 15; - } - -- @Override -- public int getMaxLevel() { -- return 3; -- } -- - public static float e(int i) { - return 1.0F - 1.0F / (float) (i + 1); - } -diff --git a/src/main/java/net/minecraft/server/EnchantmentThorns.java b/src/main/java/net/minecraft/server/EnchantmentThorns.java -index fd0255c89..df7c9b24b 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentThorns.java -+++ b/src/main/java/net/minecraft/server/EnchantmentThorns.java -@@ -7,6 +7,7 @@ public class EnchantmentThorns extends Enchantment { - - public EnchantmentThorns(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.ARMOR_CHEST, aenumitemslot); -+ setMaxLevel(3); // Purpur - } - - @Override -@@ -19,11 +20,6 @@ public class EnchantmentThorns extends Enchantment { - return super.a(i) + 50; - } - -- @Override -- public int getMaxLevel() { -- return 3; -- } -- - @Override - public boolean canEnchant(ItemStack itemstack) { - return itemstack.getItem() instanceof ItemArmor ? true : super.canEnchant(itemstack); -diff --git a/src/main/java/net/minecraft/server/EnchantmentTridentChanneling.java b/src/main/java/net/minecraft/server/EnchantmentTridentChanneling.java -index 14115ecc7..2533b2cab 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentTridentChanneling.java -+++ b/src/main/java/net/minecraft/server/EnchantmentTridentChanneling.java -@@ -4,6 +4,7 @@ public class EnchantmentTridentChanneling extends Enchantment { - - public EnchantmentTridentChanneling(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.TRIDENT, aenumitemslot); -+ setMaxLevel(1); // Purpur - } - - @Override -@@ -16,11 +17,6 @@ public class EnchantmentTridentChanneling extends Enchantment { - return 50; - } - -- @Override -- public int getMaxLevel() { -- return 1; -- } -- - @Override - public boolean a(Enchantment enchantment) { - return super.a(enchantment); -diff --git a/src/main/java/net/minecraft/server/EnchantmentTridentImpaling.java b/src/main/java/net/minecraft/server/EnchantmentTridentImpaling.java -index f64fc401e..b47d8284f 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentTridentImpaling.java -+++ b/src/main/java/net/minecraft/server/EnchantmentTridentImpaling.java -@@ -4,6 +4,7 @@ public class EnchantmentTridentImpaling extends Enchantment { - - public EnchantmentTridentImpaling(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.TRIDENT, aenumitemslot); -+ setMaxLevel(5); // Purpur - } - - @Override -@@ -16,11 +17,6 @@ public class EnchantmentTridentImpaling extends Enchantment { - return this.a(i) + 20; - } - -- @Override -- public int getMaxLevel() { -- return 5; -- } -- - @Override - public float a(int i, EnumMonsterType enummonstertype) { - return enummonstertype == EnumMonsterType.e ? (float) i * 2.5F : 0.0F; -diff --git a/src/main/java/net/minecraft/server/EnchantmentTridentLoyalty.java b/src/main/java/net/minecraft/server/EnchantmentTridentLoyalty.java -index dd91bed6e..826f4d875 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentTridentLoyalty.java -+++ b/src/main/java/net/minecraft/server/EnchantmentTridentLoyalty.java -@@ -4,6 +4,7 @@ public class EnchantmentTridentLoyalty extends Enchantment { - - public EnchantmentTridentLoyalty(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.TRIDENT, aenumitemslot); -+ setMaxLevel(3); // Purpur - } - - @Override -@@ -16,11 +17,6 @@ public class EnchantmentTridentLoyalty extends Enchantment { - return 50; - } - -- @Override -- public int getMaxLevel() { -- return 3; -- } -- - @Override - public boolean a(Enchantment enchantment) { - return super.a(enchantment); -diff --git a/src/main/java/net/minecraft/server/EnchantmentTridentRiptide.java b/src/main/java/net/minecraft/server/EnchantmentTridentRiptide.java -index 0f669dc7a..81d6ccc35 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentTridentRiptide.java -+++ b/src/main/java/net/minecraft/server/EnchantmentTridentRiptide.java -@@ -4,6 +4,7 @@ public class EnchantmentTridentRiptide extends Enchantment { - - public EnchantmentTridentRiptide(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.TRIDENT, aenumitemslot); -+ setMaxLevel(3); // Purpur - } - - @Override -@@ -16,11 +17,6 @@ public class EnchantmentTridentRiptide extends Enchantment { - return 50; - } - -- @Override -- public int getMaxLevel() { -- return 3; -- } -- - @Override - public boolean a(Enchantment enchantment) { - return super.a(enchantment) && enchantment != Enchantments.LOYALTY && enchantment != Enchantments.CHANNELING; -diff --git a/src/main/java/net/minecraft/server/EnchantmentVanishing.java b/src/main/java/net/minecraft/server/EnchantmentVanishing.java -index 4ef59d7f1..5d7b6ca57 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentVanishing.java -+++ b/src/main/java/net/minecraft/server/EnchantmentVanishing.java -@@ -4,6 +4,7 @@ public class EnchantmentVanishing extends Enchantment { - - public EnchantmentVanishing(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.ALL, aenumitemslot); -+ setMaxLevel(1); // Purpur - } - - @Override -@@ -16,11 +17,6 @@ public class EnchantmentVanishing extends Enchantment { - return 50; - } - -- @Override -- public int getMaxLevel() { -- return 1; -- } -- - @Override - public boolean isTreasure() { - return true; -diff --git a/src/main/java/net/minecraft/server/EnchantmentWaterWorker.java b/src/main/java/net/minecraft/server/EnchantmentWaterWorker.java -index cf0999095..bea57861b 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentWaterWorker.java -+++ b/src/main/java/net/minecraft/server/EnchantmentWaterWorker.java -@@ -4,6 +4,7 @@ public class EnchantmentWaterWorker extends Enchantment { - - public EnchantmentWaterWorker(Enchantment.Rarity enchantment_rarity, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.ARMOR_HEAD, aenumitemslot); -+ setMaxLevel(1); // Purpur - } - - @Override -@@ -15,9 +16,4 @@ public class EnchantmentWaterWorker extends Enchantment { - public int b(int i) { - return this.a(i) + 40; - } -- -- @Override -- public int getMaxLevel() { -- return 1; -- } - } -diff --git a/src/main/java/net/minecraft/server/EnchantmentWeaponDamage.java b/src/main/java/net/minecraft/server/EnchantmentWeaponDamage.java -index 4571cdf02..aa3cbd523 100644 ---- a/src/main/java/net/minecraft/server/EnchantmentWeaponDamage.java -+++ b/src/main/java/net/minecraft/server/EnchantmentWeaponDamage.java -@@ -11,6 +11,7 @@ public class EnchantmentWeaponDamage extends Enchantment { - public EnchantmentWeaponDamage(Enchantment.Rarity enchantment_rarity, int i, EnumItemSlot... aenumitemslot) { - super(enchantment_rarity, EnchantmentSlotType.WEAPON, aenumitemslot); - this.a = i; -+ setMaxLevel(5); // Purpur - } - - @Override -@@ -23,11 +24,6 @@ public class EnchantmentWeaponDamage extends Enchantment { - return this.a(i) + EnchantmentWeaponDamage.g[this.a]; - } - -- @Override -- public int getMaxLevel() { -- return 5; -- } -- - @Override - public float a(int i, EnumMonsterType enummonstertype) { - return this.a == 0 ? 1.0F + (float) Math.max(0, i - 1) * 0.5F : (this.a == 1 && enummonstertype == EnumMonsterType.UNDEAD ? (float) i * 2.5F : (this.a == 2 && enummonstertype == EnumMonsterType.ARTHROPOD ? (float) i * 2.5F : 0.0F)); -diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java -index 7bea36213..68bad6a13 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java -@@ -1,6 +1,8 @@ - package net.pl3x.purpur; - - import com.google.common.base.Throwables; -+import net.minecraft.server.Enchantment; -+import net.minecraft.server.IRegistry; - import net.minecraft.server.MinecraftServer; - import net.pl3x.purpur.command.PurpurCommand; - import org.bukkit.Bukkit; -@@ -194,4 +196,12 @@ public class PurpurConfig { - private static void timingsSettings() { - getString("settings.timings.url", "https://timings.pl3x.net"); - } -+ -+ private static void enchantmentSettings() { -+ for (Enchantment enchantment : IRegistry.ENCHANTMENT) { -+ String name = IRegistry.ENCHANTMENT.getKey(enchantment).getKey(); -+ int maxLevel = getInt("settings.enchantment." + name + ".max-level", enchantment.getMaxLevel()); -+ enchantment.setMaxLevel(maxLevel); -+ } -+ } - } -diff --git a/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java b/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java -index 64ceeda1a..0e9fa3441 100644 ---- a/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java -+++ b/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java -@@ -23,6 +23,13 @@ public class CraftEnchantment extends Enchantment { - return target.getMaxLevel(); - } - -+ // Purpur start -+ @Override -+ public void setMaxLevel(int maxLevel) { -+ target.setMaxLevel(maxLevel); -+ } -+ // Purpur end -+ - @Override - public int getStartLevel() { - return target.getStartLevel(); --- -2.26.2 - diff --git a/patches/server/0104-Optimize-Chunk-Ticks.patch b/patches/server/0104-Optimize-Chunk-Ticks.patch deleted file mode 100644 index 006c56655..000000000 --- a/patches/server/0104-Optimize-Chunk-Ticks.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 4d4c1ccec681b4363afd0772013d59b6de57b351 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Thu, 2 Apr 2020 00:28:06 -0500 -Subject: [PATCH] Optimize Chunk Ticks - ---- - .../minecraft/server/ChunkProviderServer.java | 50 ++++--------------- - .../minecraft/server/EnumCreatureType.java | 14 ++++++ - 2 files changed, 25 insertions(+), 39 deletions(-) - -diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index e8bf60507..93abf7493 100644 ---- a/src/main/java/net/minecraft/server/ChunkProviderServer.java -+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java -@@ -981,11 +981,12 @@ public class ChunkProviderServer extends IChunkProvider { - int k = this.world.getGameRules().getInt(GameRules.RANDOM_TICK_SPEED); - BlockPosition blockposition = this.world.getSpawn(); - // CraftBukkit start - Other mob type spawn tick rate -- boolean spawnAnimalThisTick = world.ticksPerAnimalSpawns != 0L && worlddata.getTime() % world.ticksPerAnimalSpawns == 0L; -- boolean spawnMonsterThisTick = world.ticksPerMonsterSpawns != 0L && worlddata.getTime() % world.ticksPerMonsterSpawns == 0L; -- boolean spawnWaterThisTick = world.ticksPerWaterSpawns != 0L && worlddata.getTime() % world.ticksPerWaterSpawns == 0L; -- boolean spawnAmbientThisTick = world.ticksPerAmbientSpawns != 0L && worlddata.getTime() % world.ticksPerAmbientSpawns == 0L; -- boolean flag2 = spawnAnimalThisTick; -+ // Purpur start -+ EnumCreatureType.CREATURE.setLimitThisTick(world.ticksPerAnimalSpawns != 0L && i % world.ticksPerAnimalSpawns == 0L ? world.getWorld().getAnimalSpawnLimit() : -1); -+ EnumCreatureType.MONSTER.setLimitThisTick(world.ticksPerMonsterSpawns != 0L && i % world.ticksPerMonsterSpawns == 0L ? world.getWorld().getMonsterSpawnLimit() : -1); -+ EnumCreatureType.WATER_CREATURE.setLimitThisTick(world.ticksPerWaterSpawns != 0L && i % world.ticksPerWaterSpawns == 0L ? world.getWorld().getWaterAnimalSpawnLimit() : -1); -+ EnumCreatureType.AMBIENT.setLimitThisTick(world.ticksPerAmbientSpawns != 0L && i % world.ticksPerAmbientSpawns == 0L ? world.getWorld().getAmbientSpawnLimit() : -1); -+ // Purpur end - // CraftBukkit end - - this.world.getMethodProfiler().enter("naturalSpawnCount"); -@@ -1032,40 +1033,11 @@ public class ChunkProviderServer extends IChunkProvider { - if (flag1 && (this.allowMonsters || this.allowAnimals) && this.world.getWorldBorder().isInBounds(chunk.getPos()) && !this.playerChunkMap.isOutsideOfRange(playerchunk, chunkcoordintpair, true)) { // Spigot // Paper - optimise isOutsideOfRange - this.world.getMethodProfiler().enter("spawner"); - this.world.timings.mobSpawn.startTiming(); // Spigot -- EnumCreatureType[] aenumcreaturetype1 = aenumcreaturetype; -- int i1 = aenumcreaturetype.length; -- -- for (int j1 = 0; j1 < i1; ++j1) { -- EnumCreatureType enumcreaturetype = aenumcreaturetype1[j1]; -- -- // CraftBukkit start - Use per-world spawn limits -- boolean spawnThisTick = true; -- int limit = enumcreaturetype.b(); -- switch (enumcreaturetype) { -- case MONSTER: -- spawnThisTick = spawnMonsterThisTick; -- limit = world.getWorld().getMonsterSpawnLimit(); -- break; -- case CREATURE: -- spawnThisTick = spawnAnimalThisTick; -- limit = world.getWorld().getAnimalSpawnLimit(); -- break; -- case WATER_CREATURE: -- spawnThisTick = spawnWaterThisTick; -- limit = world.getWorld().getWaterAnimalSpawnLimit(); -- break; -- case AMBIENT: -- spawnThisTick = spawnAmbientThisTick; -- limit = world.getWorld().getAmbientSpawnLimit(); -- break; -- } -- -- if (!spawnThisTick || limit == 0) { -- continue; -- } -- // CraftBukkit end -- -- if (enumcreaturetype != EnumCreatureType.MISC && (!enumcreaturetype.c() || this.allowAnimals) && (enumcreaturetype.c() || this.allowMonsters) && (!enumcreaturetype.d() || flag2)) { -+ // Purpur start -+ for (EnumCreatureType enumcreaturetype : aenumcreaturetype) { -+ int limit = enumcreaturetype.getLimitThisTick(); -+ if (limit > 0 && enumcreaturetype != EnumCreatureType.MISC && (!enumcreaturetype.isFriendly() || this.allowAnimals) && (enumcreaturetype.isFriendly() || this.allowMonsters)) { -+ // Purpur end - int k1 = limit * l / ChunkProviderServer.b; // CraftBukkit - use per-world limits - - // Paper start - only allow spawns upto the limit per chunk and update count afterwards -diff --git a/src/main/java/net/minecraft/server/EnumCreatureType.java b/src/main/java/net/minecraft/server/EnumCreatureType.java -index 3ed7fa324..7f236585d 100644 ---- a/src/main/java/net/minecraft/server/EnumCreatureType.java -+++ b/src/main/java/net/minecraft/server/EnumCreatureType.java -@@ -31,11 +31,25 @@ public enum EnumCreatureType { - return this.g; - } - -+ public boolean isFriendly() { return c(); } // Purpur - OBFHELPER - public boolean c() { - return this.h; - } - -+ public boolean isPersistent() { return d(); } // Purpur - OBFHELPER - public boolean d() { - return this.i; - } -+ -+ // Purpur start -+ private int limitThisTick = -1; -+ -+ void setLimitThisTick(int cap) { -+ this.limitThisTick = cap; -+ } -+ -+ int getLimitThisTick() { -+ return this.limitThisTick; -+ } -+ // Purpur end - } --- -2.26.2 - diff --git a/patches/server/0105-Add-configurable-beehive-generation-chance.patch b/patches/server/0105-Add-configurable-beehive-generation-chance.patch deleted file mode 100644 index 86ca731e0..000000000 --- a/patches/server/0105-Add-configurable-beehive-generation-chance.patch +++ /dev/null @@ -1,107 +0,0 @@ -From a4900735eb07249132c6a813145a613e4d86026b Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Thu, 2 Apr 2020 03:39:34 -0500 -Subject: [PATCH] Add configurable beehive generation chance - ---- - .../server/WorldGenFeatureTreeBeehive.java | 18 +++++++++++++-- - .../server/WorldGenTreeProvider.java | 5 +++- - .../net/pl3x/purpur/PurpurWorldConfig.java | 23 +++++++++++++++++++ - 3 files changed, 43 insertions(+), 3 deletions(-) - -diff --git a/src/main/java/net/minecraft/server/WorldGenFeatureTreeBeehive.java b/src/main/java/net/minecraft/server/WorldGenFeatureTreeBeehive.java -index 5827b1ba1..5ef9ae16e 100644 ---- a/src/main/java/net/minecraft/server/WorldGenFeatureTreeBeehive.java -+++ b/src/main/java/net/minecraft/server/WorldGenFeatureTreeBeehive.java -@@ -10,7 +10,7 @@ import java.util.stream.Collectors; - - public class WorldGenFeatureTreeBeehive extends WorldGenFeatureTree { - -- private final float b; -+ private final float b; public float getChance() { return b; } // Purpur - OBFHELPER - - public WorldGenFeatureTreeBeehive(float f) { - super(WorldGenFeatureTrees.d); -@@ -23,7 +23,7 @@ public class WorldGenFeatureTreeBeehive extends WorldGenFeatureTree { - - @Override - public void a(GeneratorAccess generatoraccess, Random random, List list, List list1, Set set, StructureBoundingBox structureboundingbox) { -- if (random.nextFloat() < this.b) { -+ if (random.nextFloat() < getChance(generatoraccess.getMinecraftWorld(), list.get(0))) { - EnumDirection enumdirection = BlockBeehive.a[random.nextInt(BlockBeehive.a.length)]; - int i = !list1.isEmpty() ? Math.max(((BlockPosition) list1.get(0)).getY() - 1, ((BlockPosition) list.get(0)).getY()) : Math.min(((BlockPosition) list.get(0)).getY() + 1 + random.nextInt(3), ((BlockPosition) list.get(list.size() - 1)).getY()); - List list2 = (List) list.stream().filter((blockposition) -> { -@@ -56,6 +56,20 @@ public class WorldGenFeatureTreeBeehive extends WorldGenFeatureTree { - } - } - -+ private float getChance(World world, BlockPosition position) { -+ BiomeBase biome = world.getBiome(position); -+ if (biome == Biomes.PLAINS) return world.purpurConfig.beehivesGeneratePlainsChance; -+ else if (biome == Biomes.SUNFLOWER_PLAINS) return world.purpurConfig.beehivesGenerateSunflowerPlainsChance; -+ else if (biome == Biomes.FLOWER_FOREST) return world.purpurConfig.beehivesGenerateFlowerForestChance; -+ else if (biome == Biomes.FOREST) return world.purpurConfig.beehivesGenerateForestChance; -+ else if (biome == Biomes.WOODED_HILLS) return world.purpurConfig.beehivesGenerateWoodedHillsChance; -+ else if (biome == Biomes.BIRCH_FOREST) return world.purpurConfig.beehivesGenerateBirchForestChance; -+ else if (biome == Biomes.TALL_BIRCH_FOREST) return world.purpurConfig.beehivesGenerateTallBirchForestChance; -+ else if (biome == Biomes.BIRCH_FOREST_HILLS) return world.purpurConfig.beehivesGenerateBirchForestHillsChance; -+ else if (biome == Biomes.TALL_BIRCH_HILLS) return world.purpurConfig.beehivesGenerateTallBirchHillsChance; -+ return getChance(); -+ } -+ - @Override - public T a(DynamicOps dynamicops) { - return new Dynamic<>(dynamicops, dynamicops.createMap(ImmutableMap.of(dynamicops.createString("type"), dynamicops.createString(IRegistry.w.getKey(this.a).toString()), dynamicops.createString("probability"), dynamicops.createFloat(this.b)))).getValue(); // Purpur - decompile error -diff --git a/src/main/java/net/minecraft/server/WorldGenTreeProvider.java b/src/main/java/net/minecraft/server/WorldGenTreeProvider.java -index b9dee0e25..9e9d9e643 100644 ---- a/src/main/java/net/minecraft/server/WorldGenTreeProvider.java -+++ b/src/main/java/net/minecraft/server/WorldGenTreeProvider.java -@@ -31,7 +31,10 @@ public abstract class WorldGenTreeProvider { - } - - private boolean a(GeneratorAccess generatoraccess, BlockPosition blockposition) { -- Iterator iterator = BlockPosition.MutableBlockPosition.a(blockposition.down().north(2).west(2), blockposition.up().south(2).east(2)).iterator(); -+ // Purpur start -+ int r = generatoraccess.getMinecraftWorld().purpurConfig.beehivesSaplingFlowerRadius; -+ Iterator iterator = BlockPosition.MutableBlockPosition.a(blockposition.down().north(r).west(r), blockposition.up().south(r).east(r)).iterator(); -+ // Purpur end - - BlockPosition blockposition1; - -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index adcdc6b8f..0347b729c 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -99,6 +99,29 @@ public class PurpurWorldConfig { - } - } - -+ public int beehivesSaplingFlowerRadius = 2; -+ public float beehivesGeneratePlainsChance = 0.05F; -+ public float beehivesGenerateSunflowerPlainsChance = 0.05F; -+ public float beehivesGenerateFlowerForestChance = 0.01F; -+ public float beehivesGenerateForestChance; -+ public float beehivesGenerateWoodedHillsChance; -+ public float beehivesGenerateBirchForestChance; -+ public float beehivesGenerateTallBirchForestChance; -+ public float beehivesGenerateBirchForestHillsChance; -+ public float beehivesGenerateTallBirchHillsChance; -+ private void beehiveSettings() { -+ beehivesSaplingFlowerRadius = getInt("beehive.grow-sapling-flower-check-radius", beehivesSaplingFlowerRadius); -+ beehivesGeneratePlainsChance = (float) getDouble("beehive.generation-chance.plains", beehivesGeneratePlainsChance); -+ beehivesGenerateSunflowerPlainsChance = (float) getDouble("beehive.generation-chance.sunflower-plains", beehivesGenerateSunflowerPlainsChance); -+ beehivesGenerateFlowerForestChance = (float) getDouble("beehive.generation-chance.flower-forest", beehivesGenerateFlowerForestChance); -+ beehivesGenerateForestChance = (float) getDouble("beehive.generation-chance.forest", beehivesGenerateForestChance); -+ beehivesGenerateWoodedHillsChance = (float) getDouble("beehive.generation-chance.wooded-hills", beehivesGenerateWoodedHillsChance); -+ beehivesGenerateBirchForestChance = (float) getDouble("beehive.generation-chance.birch-forest", beehivesGenerateBirchForestChance); -+ beehivesGenerateTallBirchForestChance = (float) getDouble("beehive.generation-chance.tall-birch-forest", beehivesGenerateTallBirchForestChance); -+ beehivesGenerateBirchForestHillsChance = (float) getDouble("beehive.generation-chance.birch-forest-hills", beehivesGenerateBirchForestHillsChance); -+ beehivesGenerateTallBirchHillsChance = (float) getDouble("beehive.generation-chance.tall-birch-hills", beehivesGenerateTallBirchHillsChance); -+ } -+ - public int campfireRegenInterval = 0; - public int campfireRegenDuration = 80; - public int campfireRegenRange = 5; --- -2.26.2 - diff --git a/patches/server/0106-Add-more-timings-timers.patch b/patches/server/0106-Add-more-timings-timers.patch deleted file mode 100644 index 31d92ff4e..000000000 --- a/patches/server/0106-Add-more-timings-timers.patch +++ /dev/null @@ -1,224 +0,0 @@ -From 758523eb133359d46e347782229675a02ee5a1e9 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sat, 4 Apr 2020 02:36:45 -0500 -Subject: [PATCH] Add more timings timers - ---- - .../co/aikar/timings/MinecraftTimings.java | 22 +++++++++++++++++++ - .../minecraft/server/EntityInsentient.java | 14 ++++++++++++ - .../net/minecraft/server/EntityLiving.java | 12 ++++++++++ - .../server/PathfinderGoalSelector.java | 6 +++++ - .../net/minecraft/server/WorldServer.java | 2 ++ - 5 files changed, 56 insertions(+) - -diff --git a/src/main/java/co/aikar/timings/MinecraftTimings.java b/src/main/java/co/aikar/timings/MinecraftTimings.java -index 2966c5731..f663f019b 100644 ---- a/src/main/java/co/aikar/timings/MinecraftTimings.java -+++ b/src/main/java/co/aikar/timings/MinecraftTimings.java -@@ -45,6 +45,28 @@ public final class MinecraftTimings { - - public static final Timing scoreboardScoreSearch = Timings.ofSafe("Scoreboard score search"); // Tuinity - add timings for scoreboard search - -+ // Purpur start -+ public static final Timing goalCleanup = Timings.ofSafe("PathfinderGoal - Cleanup"); -+ public static final Timing goalUpdate = Timings.ofSafe("PathfinderGoal - Update"); -+ public static final Timing goalTick = Timings.ofSafe("PathfinderGoal - Tick"); -+ -+ public static final Timing entityMovementTick = Timings.ofSafe("Entity Movement"); -+ public static final Timing entityMovementTickAI = Timings.ofSafe("Entity Movement - AI"); -+ public static final Timing entityMovementTickNewAI = Timings.ofSafe("Entity Movement - New AI"); -+ public static final Timing entityMovementTickJump = Timings.ofSafe("Entity Movement - Jump"); -+ public static final Timing entityMovementTickTravel = Timings.ofSafe("Entity Movement - Travel"); -+ public static final Timing entityMovementTickPush = Timings.ofSafe("Entity Movement - Push"); -+ -+ public static final Timing entityInsentientSensing = Timings.ofSafe("Entity Insentient - Sensing"); -+ public static final Timing entityInsentientTargetSelector = Timings.ofSafe("Entity Insentient - TargetSelector"); -+ public static final Timing entityInsentientGoalSelector = Timings.ofSafe("Entity Insentient - GoalSelector"); -+ public static final Timing entityInsentientNavigation = Timings.ofSafe("Entity Insentient - Navigation"); -+ public static final Timing entityInsentientMobTick = Timings.ofSafe("Entity Insentient - MobTick"); -+ public static final Timing entityInsentientControls = Timings.ofSafe("Entity Insentient - Controls"); -+ -+ public static final Timing passengerTick = Timings.ofSafe("Passenger Tick"); -+ // Purpur end -+ - private static final Map, String> taskNameCache = new MapMaker().weakKeys().makeMap(); - - private MinecraftTimings() {} -diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java -index 3adc3434e..eb0befb35 100644 ---- a/src/main/java/net/minecraft/server/EntityInsentient.java -+++ b/src/main/java/net/minecraft/server/EntityInsentient.java -@@ -1,5 +1,7 @@ - package net.minecraft.server; - -+import co.aikar.timings.Timing; -+import co.aikar.timings.Timings; - import com.google.common.collect.Maps; - import java.util.Arrays; - import java.util.Iterator; -@@ -676,21 +678,32 @@ public abstract class EntityInsentient extends EntityLiving { - } - // Paper end - this.world.getMethodProfiler().enter("sensing"); -+ co.aikar.timings.MinecraftTimings.entityInsentientSensing.startTiming(); // Purpur - this.bw.a(); -+ co.aikar.timings.MinecraftTimings.entityInsentientSensing.stopTiming(); // Purpur - this.world.getMethodProfiler().exit(); - this.world.getMethodProfiler().enter("targetSelector"); -+ co.aikar.timings.MinecraftTimings.entityInsentientTargetSelector.startTiming(); // Purpur - this.targetSelector.doTick(); -+ co.aikar.timings.MinecraftTimings.entityInsentientTargetSelector.stopTiming(); // Purpur - this.world.getMethodProfiler().exit(); - this.world.getMethodProfiler().enter("goalSelector"); -+ co.aikar.timings.MinecraftTimings.entityInsentientGoalSelector.startTiming(); // Purpur - this.goalSelector.doTick(); -+ co.aikar.timings.MinecraftTimings.entityInsentientGoalSelector.stopTiming(); // Purpur - this.world.getMethodProfiler().exit(); - this.world.getMethodProfiler().enter("navigation"); -+ co.aikar.timings.MinecraftTimings.entityInsentientNavigation.startTiming(); // Purpur - this.navigation.c(); -+ co.aikar.timings.MinecraftTimings.entityInsentientNavigation.stopTiming(); // Purpur - this.world.getMethodProfiler().exit(); - this.world.getMethodProfiler().enter("mob tick"); -+ co.aikar.timings.MinecraftTimings.entityInsentientMobTick.startTiming(); // Purpur - this.mobTick(); -+ co.aikar.timings.MinecraftTimings.entityInsentientMobTick.stopTiming(); // Purpur - this.world.getMethodProfiler().exit(); - this.world.getMethodProfiler().enter("controls"); -+ co.aikar.timings.MinecraftTimings.entityInsentientControls.startTiming(); // Purpur - this.world.getMethodProfiler().enter("move"); - this.moveController.a(); - this.world.getMethodProfiler().exitEnter("look"); -@@ -698,6 +711,7 @@ public abstract class EntityInsentient extends EntityLiving { - this.world.getMethodProfiler().exitEnter("jump"); - this.bq.b(); - this.world.getMethodProfiler().exit(); -+ co.aikar.timings.MinecraftTimings.entityInsentientControls.stopTiming(); // Purpur - this.world.getMethodProfiler().exit(); - this.K(); - } -diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java -index dae35c55e..3b5e38608 100644 ---- a/src/main/java/net/minecraft/server/EntityLiving.java -+++ b/src/main/java/net/minecraft/server/EntityLiving.java -@@ -2398,7 +2398,9 @@ public abstract class EntityLiving extends Entity { - } - } - -+ MinecraftTimings.entityMovementTick.startTiming(); // Purpur - if (!dead) this.movementTick(); // Purpur -+ MinecraftTimings.entityMovementTick.stopTiming(); // Purpur - double d0 = this.locX() - this.lastX; - double d1 = this.locZ() - this.lastZ; - float f = (float) (d0 * d0 + d1 * d1); -@@ -2605,18 +2607,23 @@ public abstract class EntityLiving extends Entity { - - this.setMot(d4, d5, d6); - this.world.getMethodProfiler().enter("ai"); -+ co.aikar.timings.MinecraftTimings.entityMovementTickAI.startTiming(); // Purpur - if (this.isFrozen()) { - this.jumping = false; - this.aZ = 0.0F; - this.bb = 0.0F; - } else if (this.doAITick()) { - this.world.getMethodProfiler().enter("newAi"); -+ co.aikar.timings.MinecraftTimings.entityMovementTickNewAI.startTiming(); // Purpur - this.doTick(); -+ co.aikar.timings.MinecraftTimings.entityMovementTickNewAI.stopTiming(); // Purpur - this.world.getMethodProfiler().exit(); - } - -+ co.aikar.timings.MinecraftTimings.entityMovementTickAI.stopTiming(); // Purpur - this.world.getMethodProfiler().exit(); - this.world.getMethodProfiler().enter("jump"); -+ co.aikar.timings.MinecraftTimings.entityMovementTickJump.startTiming(); // Purpur - if (this.jumping) { - if (this.N > 0.0D && (!this.onGround || this.N > 0.4D)) { - this.c(TagsFluid.WATER); -@@ -2632,22 +2639,27 @@ public abstract class EntityLiving extends Entity { - this.jumpTicks = 0; - } - -+ co.aikar.timings.MinecraftTimings.entityMovementTickJump.stopTiming(); // Purpur - this.world.getMethodProfiler().exit(); - this.world.getMethodProfiler().enter("travel"); -+ co.aikar.timings.MinecraftTimings.entityMovementTickTravel.startTiming(); // Purpur - this.aZ *= 0.98F; - this.bb *= 0.98F; - this.n(); - AxisAlignedBB axisalignedbb = this.getBoundingBox(); - - this.e(new Vec3D((double) this.aZ, (double) this.ba, (double) this.bb)); -+ co.aikar.timings.MinecraftTimings.entityMovementTickTravel.stopTiming(); // Purpur - this.world.getMethodProfiler().exit(); - this.world.getMethodProfiler().enter("push"); -+ co.aikar.timings.MinecraftTimings.entityMovementTickPush.startTiming(); // Purpur - if (this.bn > 0) { - --this.bn; - this.a(axisalignedbb, this.getBoundingBox()); - } - - this.collideNearby(); -+ co.aikar.timings.MinecraftTimings.entityMovementTickPush.stopTiming(); // Purpur - this.world.getMethodProfiler().exit(); - // Purpur start - if (EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0) { -diff --git a/src/main/java/net/minecraft/server/PathfinderGoalSelector.java b/src/main/java/net/minecraft/server/PathfinderGoalSelector.java -index a68fc11ec..4b277a6f6 100644 ---- a/src/main/java/net/minecraft/server/PathfinderGoalSelector.java -+++ b/src/main/java/net/minecraft/server/PathfinderGoalSelector.java -@@ -78,6 +78,7 @@ public class PathfinderGoalSelector { - private static final PathfinderGoal.Type[] PATHFINDER_GOAL_TYPES = PathfinderGoal.Type.values(); // Paper - remove streams from pathfindergoalselector - - public void doTick() { -+ co.aikar.timings.MinecraftTimings.goalCleanup.startTiming(); - this.e.enter("goalCleanup"); - // Paper start - remove streams from pathfindergoalselector - for (Iterator iterator = this.d.iterator(); iterator.hasNext();) { -@@ -97,8 +98,10 @@ public class PathfinderGoalSelector { - } - - }); -+ co.aikar.timings.MinecraftTimings.goalCleanup.stopTiming(); - this.e.exit(); - this.e.enter("goalUpdate"); -+ co.aikar.timings.MinecraftTimings.goalUpdate.startTiming(); - // Paper start - remove streams from pathfindergoalselector - goal_update_loop: for (Iterator iterator = this.d.iterator(); iterator.hasNext();) { - PathfinderGoalWrapped wrappedGoal = iterator.next(); -@@ -141,8 +144,10 @@ public class PathfinderGoalSelector { - wrappedGoal.c(); - } - // Paper end - remove streams from pathfindergoalselector -+ co.aikar.timings.MinecraftTimings.goalUpdate.stopTiming(); - this.e.exit(); - this.e.enter("goalTick"); -+ co.aikar.timings.MinecraftTimings.goalTick.startTiming(); - // Paper start - remove streams from pathfindergoalselector - for (Iterator iterator = this.d.iterator(); iterator.hasNext();) { - PathfinderGoalWrapped wrappedGoal = iterator.next(); -@@ -151,6 +156,7 @@ public class PathfinderGoalSelector { - } - } - // Paper end - remove streams from pathfindergoalselector -+ co.aikar.timings.MinecraftTimings.goalTick.stopTiming(); - this.e.exit(); - } - -diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 610542dc8..23d832914 100644 ---- a/src/main/java/net/minecraft/server/WorldServer.java -+++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -1308,7 +1308,9 @@ public class WorldServer extends World { - return IRegistry.ENTITY_TYPE.getKey(entity1.getEntityType()).toString(); - }); - gameprofilerfiller.c("tickPassenger"); -+ co.aikar.timings.MinecraftTimings.passengerTick.startTiming(); // Purpur - entity1.passengerTick(); -+ co.aikar.timings.MinecraftTimings.passengerTick.stopTiming(); // Purpur - gameprofilerfiller.exit(); - } - --- -2.26.2 - diff --git a/patches/server/0110-Chickens-can-retaliate.patch b/patches/server/0110-Chickens-can-retaliate.patch deleted file mode 100644 index 5418d6382..000000000 --- a/patches/server/0110-Chickens-can-retaliate.patch +++ /dev/null @@ -1,71 +0,0 @@ -From fe4b5892ead117ebd0db78ba6415bdb129f81cff Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sun, 12 Apr 2020 13:19:34 -0500 -Subject: [PATCH] Chickens can retaliate - ---- - .../java/net/minecraft/server/EntityChicken.java | 14 +++++++++++++- - .../java/net/pl3x/purpur/PurpurWorldConfig.java | 2 ++ - 2 files changed, 15 insertions(+), 1 deletion(-) - -diff --git a/src/main/java/net/minecraft/server/EntityChicken.java b/src/main/java/net/minecraft/server/EntityChicken.java -index 5505b7ee9..1c9b0ce61 100644 ---- a/src/main/java/net/minecraft/server/EntityChicken.java -+++ b/src/main/java/net/minecraft/server/EntityChicken.java -@@ -38,13 +38,22 @@ public class EntityChicken extends EntityAnimal { - protected void initPathfinder() { - this.goalSelector.a(0, new PathfinderGoalFloat(this)); - this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur -- this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.4D)); -+ //this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.4D)); // Purpur - moved down - this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D)); - this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.0D, false, EntityChicken.bD)); - this.goalSelector.a(4, new PathfinderGoalFollowParent(this, 1.1D)); - this.goalSelector.a(5, new PathfinderGoalRandomStrollLand(this, 1.0D)); - this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); - this.goalSelector.a(7, new PathfinderGoalRandomLookaround(this)); -+ // Purpur start -+ if (world.purpurConfig.chickenRetaliate) { -+ this.goalSelector.a(1, new PathfinderGoalMeleeAttack(this, 1.0D, false)); -+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); -+ this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this)); -+ } else { -+ this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.4D)); -+ } -+ // Purpur end - } - - @Override -@@ -57,6 +66,9 @@ public class EntityChicken extends EntityAnimal { - super.initAttributes(); - this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(4.0D); - this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.25D); -+ if (world.purpurConfig.chickenRetaliate) { -+ this.getAttributeMap().b(GenericAttributes.ATTACK_DAMAGE).setValue(2.0D); -+ } - } - - @Override -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index e6ab2fde4..6962d17b9 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -361,6 +361,7 @@ public class PurpurWorldConfig { - public boolean chickenDontLayEggsWhenRidden = false; - public int chickenEggsHatchWhenDespawnedMax = 0; - public int chickenEggsHatchWhenDespawnedRange = 10; -+ public boolean chickenRetaliate = false; - private void chickenSettings() { - chickenRidable = getBoolean("mobs.chicken.ridable", chickenRidable); - chickenRidableInWater = getBoolean("mobs.chicken.ridable-in-water", chickenRidableInWater); -@@ -368,6 +369,7 @@ public class PurpurWorldConfig { - chickenDontLayEggsWhenRidden = getBoolean("mobs.chicken.dont-lay-eggs-when-ridden", chickenDontLayEggsWhenRidden); - chickenEggsHatchWhenDespawnedMax = getInt("mobs.chicken.eggs-hatch-when-despawned.max", chickenEggsHatchWhenDespawnedMax); - chickenEggsHatchWhenDespawnedRange = getInt("mobs.chicken.eggs-hatch-when-despawned.range", chickenEggsHatchWhenDespawnedRange); -+ chickenRetaliate = getBoolean("mobs.chicken.retaliate", chickenRetaliate); - } - - public boolean codRidable = false; --- -2.26.2 - diff --git a/patches/server/0120-MC-56653-Fix-pig-zombies-aggro.patch b/patches/server/0120-MC-56653-Fix-pig-zombies-aggro.patch deleted file mode 100644 index ad750f66b..000000000 --- a/patches/server/0120-MC-56653-Fix-pig-zombies-aggro.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 709d9ada46d90e86bde0c82e0dc0960c3e7c86b7 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Tue, 9 Jul 2019 20:56:47 -0500 -Subject: [PATCH] MC-56653 Fix - pig zombies aggro - ---- - src/main/java/net/minecraft/server/EntityPigZombie.java | 9 ++++++++- - src/main/java/net/pl3x/purpur/PurpurWorldConfig.java | 2 ++ - 2 files changed, 10 insertions(+), 1 deletion(-) - -diff --git a/src/main/java/net/minecraft/server/EntityPigZombie.java b/src/main/java/net/minecraft/server/EntityPigZombie.java -index 90bf12c73..c78876fc4 100644 ---- a/src/main/java/net/minecraft/server/EntityPigZombie.java -+++ b/src/main/java/net/minecraft/server/EntityPigZombie.java -@@ -170,6 +170,7 @@ public class EntityPigZombie extends EntityZombie { - boolean result = super.damageEntity(damagesource, f); - - if (result && entity instanceof EntityHuman && !((EntityHuman) entity).isCreative() && this.hasLineOfSight(entity)) { -+ if (world.purpurConfig.zombiePigmanDontTargetUnlessHit) this.setLastDamager((EntityHuman) entity); // Purpur - fix MC-56653 - this.i((EntityLiving) entity); - } - -@@ -188,7 +189,7 @@ public class EntityPigZombie extends EntityZombie { - this.angerLevel = event.getNewAnger(); - // CraftBukkit end - this.soundDelay = this.random.nextInt(40); -- this.setLastDamager(entityliving); -+ if (!world.purpurConfig.zombiePigmanDontTargetUnlessHit) this.setLastDamager(entityliving); // Purpur - fix MC-56653 - return true; - } - -@@ -230,6 +231,12 @@ public class EntityPigZombie extends EntityZombie { - return this.eA(); - } - -+ // Purpur start - fix MC-56653 -+ protected boolean isDropExperience() { -+ return super.isDropExperience() && (!world.purpurConfig.zombiePigmanDontTargetUnlessHit || getLastDamager() instanceof EntityHuman); -+ } -+ // Purpur end -+ - static class PathfinderGoalAnger extends PathfinderGoalNearestAttackableTarget { - - public PathfinderGoalAnger(EntityPigZombie entitypigzombie) { -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 296274896..7e7f10351 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -1013,6 +1013,7 @@ public class PurpurWorldConfig { - public boolean zombiePigmanJockeyOnlyBaby = true; - public double zombiePigmanJockeyChance = 0.05D; - public boolean zombiePigmanJockeyTryExistingChickens = true; -+ public boolean zombiePigmanDontTargetUnlessHit = false; - private void zombiePigmanSettings() { - zombiePigmanRidable = getBoolean("mobs.zombie_pigman.ridable", zombiePigmanRidable); - zombiePigmanRidableInWater = getBoolean("mobs.zombie_pigman.ridable-in-water", zombiePigmanRidableInWater); -@@ -1020,6 +1021,7 @@ public class PurpurWorldConfig { - zombiePigmanJockeyOnlyBaby = getBoolean("mobs.zombie_pigman.jockey.only-babies", zombiePigmanJockeyOnlyBaby); - zombiePigmanJockeyChance = getDouble("mobs.zombie_pigman.jockey.chance", zombiePigmanJockeyChance); - zombiePigmanJockeyTryExistingChickens = getBoolean("mobs.zombie_pigman.jockey.try-existing-chickens", zombiePigmanJockeyTryExistingChickens); -+ zombiePigmanDontTargetUnlessHit = getBoolean("mobs.zombie_pigman.dont-target-unless-hit", zombiePigmanDontTargetUnlessHit); - } - - public boolean zombieVillagerRidable = false; --- -2.26.2 - diff --git a/patches/server/0124-YAPFA-Disable-mojang-profiler.patch b/patches/server/0124-YAPFA-Disable-mojang-profiler.patch deleted file mode 100644 index 5152957eb..000000000 --- a/patches/server/0124-YAPFA-Disable-mojang-profiler.patch +++ /dev/null @@ -1,175 +0,0 @@ -From 1b1a21c1dc6b4bbfbe85b0743ee29c22385882f9 Mon Sep 17 00:00:00 2001 -From: tr7zw -Date: Thu, 5 Mar 2020 23:08:01 +0100 -Subject: [PATCH] YAPFA - Disable mojang profiler - ---- - .../net/minecraft/server/CommandDebug.java | 5 ++ - .../net/minecraft/server/MinecraftServer.java | 5 +- - .../net/pl3x/purpur/GameProfilerNoop.java | 68 +++++++++++++++++++ - .../java/org/bukkit/craftbukkit/Main.java | 2 + - src/main/resources/purpur.lang | 1 + - 5 files changed, 80 insertions(+), 1 deletion(-) - create mode 100644 src/main/java/net/pl3x/purpur/GameProfilerNoop.java - -diff --git a/src/main/java/net/minecraft/server/CommandDebug.java b/src/main/java/net/minecraft/server/CommandDebug.java -index f0d72ea39..e38a68406 100644 ---- a/src/main/java/net/minecraft/server/CommandDebug.java -+++ b/src/main/java/net/minecraft/server/CommandDebug.java -@@ -22,6 +22,7 @@ public class CommandDebug { - private static final Logger LOGGER = LogManager.getLogger(); - private static final SimpleCommandExceptionType b = new SimpleCommandExceptionType(new ChatMessage("commands.debug.notRunning", new Object[0])); - private static final SimpleCommandExceptionType c = new SimpleCommandExceptionType(new ChatMessage("commands.debug.alreadyRunning", new Object[0])); -+ private static final SimpleCommandExceptionType disabled = new SimpleCommandExceptionType(new ChatMessage("commands.purpur.debug.disabled")); // Purpur - @Nullable - private static final FileSystemProvider d = (FileSystemProvider) FileSystemProvider.installedProviders().stream().filter((filesystemprovider) -> { - return filesystemprovider.getScheme().equalsIgnoreCase("jar"); -@@ -43,6 +44,8 @@ public class CommandDebug { - MinecraftServer minecraftserver = commandlistenerwrapper.getServer(); - GameProfiler gameprofiler = minecraftserver.getMethodProfiler(); - -+ if (gameprofiler instanceof net.pl3x.purpur.GameProfilerNoop) throw CommandDebug.disabled.create(); // Purpur -+ - if (gameprofiler.d().a()) { - throw CommandDebug.c.create(); - } else { -@@ -56,6 +59,8 @@ public class CommandDebug { - MinecraftServer minecraftserver = commandlistenerwrapper.getServer(); - GameProfiler gameprofiler = minecraftserver.getMethodProfiler(); - -+ if (gameprofiler instanceof net.pl3x.purpur.GameProfilerNoop) throw CommandDebug.disabled.create(); // Purpur -+ - if (!gameprofiler.d().a()) { - throw CommandDebug.b.create(); - } else { -diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 40da7a05c..6928d2492 100644 ---- a/src/main/java/net/minecraft/server/MinecraftServer.java -+++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -80,7 +80,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant tickables = Lists.newArrayList(); -- private final GameProfiler methodProfiler = new GameProfiler(this::ak); -+ protected GameProfiler methodProfiler = new net.pl3x.purpur.GameProfilerNoop(this::getTickCount); // Purpur - private ServerConnection serverConnection; - public final WorldLoadListenerFactory worldLoadListenerFactory; - private final ServerPing serverPing = new ServerPing(); -@@ -1529,6 +1529,8 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant supplier) { -+ } -+ -+ @Override -+ public void exit() { -+ } -+ -+ @Override -+ public void exitEnter(String s) { -+ } -+ -+ @Override -+ public void c(String s) { -+ } -+ -+ @Override -+ public void c(Supplier supplier) { -+ } -+ -+ static class EmptyProfiler implements GameProfiler.a { -+ @Override -+ public boolean a() { // isEnabled -+ return false; -+ } -+ -+ @Override -+ public MethodProfilerResults b() { // disable -+ return MethodProfilerResultsEmpty.a; // empty -+ } -+ -+ @Override -+ public void d() { // enable -+ } -+ } -+} -diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index b007840a5..1916bfb5d 100644 ---- a/src/main/java/org/bukkit/craftbukkit/Main.java -+++ b/src/main/java/org/bukkit/craftbukkit/Main.java -@@ -152,6 +152,8 @@ public class Main { - .ofType(File.class) - .defaultsTo(new File("purpur.yml")) - .describedAs("Yml file"); -+ -+ acceptsAll(asList("enableProfiler"), "Enables the vanilla profiler"); - // Purpur end - - // Paper start -diff --git a/src/main/resources/purpur.lang b/src/main/resources/purpur.lang -index e81beea7f..5c3536b26 100644 ---- a/src/main/resources/purpur.lang -+++ b/src/main/resources/purpur.lang -@@ -1,5 +1,6 @@ - { - "cannot.ride.mob": "You cannot mount that mob", -+ "commands.purpur.debug.disabled": "The debug profiler is disabled", - "commands.purpur.ping": "§a%s's ping is %sms", - "idle.timeout.broadcast.away": "§e§o%s is now AFK", - "idle.timeout.broadcast.back": "§e§o%s is no longer AFK" --- -2.26.2 -