-Date: Mon, 25 Sep 2023 03:15:07 +0000
+Date: Mon, 29 Apr 2024 09:05:40 +0000
Subject: [PATCH] Purpur API Changes
Original license: MIT
Original project: https://github.com/PurpurMC/Purpur
-Commit: 6b1ee98f813ee19f8046b3c528feeee61840a35b
+Commit: a90a4730d672968428e371f024c8317b64eba9af
Patches below are removed in this patch:
Pufferfish-API-Changes.patch
@@ -14,7 +14,6 @@ Fix-pufferfish-issues.patch
Build-System-Changes.patch
Remove-Timings.patch
Add-log-suppression-for-LibraryLoader.patch
-Fire-Immunity-API.patch
diff --git a/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java b/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java
index a736d7bcdc5861a01b66ba36158db1c716339346..22fc165fd9c95f0f3ae1be7a0857e48cc50fad5b 100644
@@ -34,10 +33,10 @@ index a736d7bcdc5861a01b66ba36158db1c716339346..22fc165fd9c95f0f3ae1be7a0857e48c
@Override
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
-index d8201747ede92a0123eec012844a7a674e6947f5..e0ecc43fc6a952b4897c530af2e89f2c0558740e 100644
+index 1a4eae45a9352fcc55b8c8a63a126d734604e8c6..a3c696dfb2d6b00ba3f681b74e2cd56c65cf16b2 100644
--- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java
-@@ -2951,4 +2951,127 @@ public final class Bukkit {
+@@ -2974,4 +2974,127 @@ public final class Bukkit {
public static Server.Spigot spigot() {
return server.spigot();
}
@@ -256,10 +255,10 @@ index 918a045165cdcde264bc24082b7afebb407271de..687d11619379aead7f665d4a5f8f8bcc
+ // Purpur end
}
diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java
-index ec117c47401ea1a04beb0e5ee9d4d394db7c5c4e..5b058d709751a5b720e209931774e09fcc9c960c 100644
+index 82d009c0bbe4b3026a535e02d6e0ed20c7bd525d..0366400fe6dea7af40badaa3335b49ff5992a516 100644
--- a/src/main/java/org/bukkit/Material.java
+++ b/src/main/java/org/bukkit/Material.java
-@@ -11559,4 +11559,40 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla
+@@ -11653,4 +11653,40 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla
public boolean isEnabledByFeature(@NotNull World world) {
return Bukkit.getDataPackManager().isEnabledByFeature(this, world);
}
@@ -412,10 +411,10 @@ index 30298a629b39bd43ce14b414fc697b2dfcbea89c..ce00af9121de7a910aaea4e0685a06d4
+ // Purpur end - OfflinePlayer API
}
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
-index 80499cd30914ca97576532bd86967cbfaabe2577..98311ea5696f722b431444a569f0f172a9d32973 100644
+index defa5be01d2f396a1e46c3ad9aa1d20e7c505424..20b9547f892e6da0337e1f19015fbb2d144cf871 100644
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
-@@ -2288,6 +2288,18 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
+@@ -2307,6 +2307,18 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
// Paper end
@@ -434,14 +433,13 @@ index 80499cd30914ca97576532bd86967cbfaabe2577..98311ea5696f722b431444a569f0f172
// Leaf start
@NotNull
public org.bukkit.configuration.file.YamlConfiguration getLeafConfig()
-@@ -2605,4 +2617,111 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
+@@ -2624,4 +2636,104 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
long getLastTickOversleepTime();
// Gale end - YAPFA - last tick time - API
+ // Purpur start
+ /**
+ * Get the name of this server
-+ *
+ * @return the name of the server
+ */
+ @NotNull
@@ -473,7 +471,6 @@ index 80499cd30914ca97576532bd86967cbfaabe2577..98311ea5696f722b431444a569f0f172
+ * Creates debug block highlight on specified block location and show it to all players on the server.
+ *
+ * Clients may be inconsistent in displaying it.
-+ *
+ * @param location Location to highlight
+ * @param duration Duration for highlight to show in milliseconds
+ */
@@ -483,10 +480,9 @@ index 80499cd30914ca97576532bd86967cbfaabe2577..98311ea5696f722b431444a569f0f172
+ * Creates debug block highlight on specified block location and show it to all players on the server.
+ *
+ * Clients may be inconsistent in displaying it.
-+ *
+ * @param location Location to highlight
+ * @param duration Duration for highlight to show in milliseconds
-+ * @param argb Color of the highlight. ARGB int. Will be ignored on some versions of vanilla client
++ * @param argb Color of the highlight. ARGB int. Will be ignored on some versions of vanilla client
+ */
+ void sendBlockHighlight(@NotNull Location location, int duration, int argb);
+
@@ -494,10 +490,9 @@ index 80499cd30914ca97576532bd86967cbfaabe2577..98311ea5696f722b431444a569f0f172
+ * Creates debug block highlight on specified block location and show it to all players on the server.
+ *
+ * Clients may be inconsistent in displaying it.
-+ *
+ * @param location Location to highlight
+ * @param duration Duration for highlight to show in milliseconds
-+ * @param text Text to show above the highlight
++ * @param text Text to show above the highlight
+ */
+ void sendBlockHighlight(@NotNull Location location, int duration, @NotNull String text);
+
@@ -505,11 +500,10 @@ index 80499cd30914ca97576532bd86967cbfaabe2577..98311ea5696f722b431444a569f0f172
+ * Creates debug block highlight on specified block location and show it to all players on the server.
+ *
+ * Clients may be inconsistent in displaying it.
-+ *
+ * @param location Location to highlight
+ * @param duration Duration for highlight to show in milliseconds
-+ * @param text Text to show above the highlight
-+ * @param argb Color of the highlight. ARGB int. Will be ignored on some versions of vanilla client
++ * @param text Text to show above the highlight
++ * @param argb Color of the highlight. ARGB int. Will be ignored on some versions of vanilla client
+ */
+ void sendBlockHighlight(@NotNull Location location, int duration, @NotNull String text, int argb);
+
@@ -517,10 +511,9 @@ index 80499cd30914ca97576532bd86967cbfaabe2577..98311ea5696f722b431444a569f0f172
+ * Creates debug block highlight on specified block location and show it to all players on the server.
+ *
+ * Clients may be inconsistent in displaying it.
-+ *
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ * @param color Color of the highlight. Will be ignored on some versions of vanilla client
++ * @param location Location to highlight
++ * @param duration Duration for highlight to show in milliseconds
++ * @param color Color of the highlight. Will be ignored on some versions of vanilla client
+ * @param transparency Transparency of the highlight
+ * @throws IllegalArgumentException If transparency is outside 0-255 range
+ */
@@ -530,11 +523,10 @@ index 80499cd30914ca97576532bd86967cbfaabe2577..98311ea5696f722b431444a569f0f172
+ * Creates debug block highlight on specified block location and show it to all players on the server.
+ *
+ * Clients may be inconsistent in displaying it.
-+ *
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ * @param text Text to show above the highlight
-+ * @param color Color of the highlight. Will be ignored on some versions of vanilla client
++ * @param location Location to highlight
++ * @param duration Duration for highlight to show in milliseconds
++ * @param text Text to show above the highlight
++ * @param color Color of the highlight. Will be ignored on some versions of vanilla client
+ * @param transparency Transparency of the highlight
+ * @throws IllegalArgumentException If transparency is outside 0-255 range
+ */
@@ -547,10 +539,10 @@ index 80499cd30914ca97576532bd86967cbfaabe2577..98311ea5696f722b431444a569f0f172
+ // Purpur end
}
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
-index e6f66d70d024cf4f0536a5bf8e51bf7b306335df..07e75978b4fc0e446e8aa46a40be5e371dc1c11b 100644
+index 97f97ea5c6aa513c439f86a9c82821e0f7d9cd1e..83a5b68c785a88594e6e3824ed282844086f7f1a 100644
--- a/src/main/java/org/bukkit/World.java
+++ b/src/main/java/org/bukkit/World.java
-@@ -4233,6 +4233,86 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
+@@ -4249,6 +4249,86 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
@Nullable
public DragonBattle getEnderDragonBattle();
@@ -667,7 +659,7 @@ index 739911cda33b373f99df627a3a378b37d7d461aa..51e78c22cd021722b963fe31d1d9175d
* Add an entity to the block.
*
diff --git a/src/main/java/org/bukkit/command/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java
-index ac9a28922f8a556944a4c3649d74c32c622f0cb0..e43d0e0a2c5edfcc82a677b6c4db9314006c9bf4 100644
+index ac9a28922f8a556944a4c3649d74c32c622f0cb0..e842d13febca67ffa1c89fb2c1324d2609fb81fd 100644
--- a/src/main/java/org/bukkit/command/SimpleCommandMap.java
+++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java
@@ -143,6 +143,19 @@ public class SimpleCommandMap implements CommandMap {
@@ -690,6 +682,15 @@ index ac9a28922f8a556944a4c3649d74c32c622f0cb0..e43d0e0a2c5edfcc82a677b6c4db9314
// Paper start - Plugins do weird things to workaround normal registration
if (target.timings == null) {
target.timings = co.aikar.timings.TimingsManager.getCommandTiming(null, target);
+@@ -152,7 +165,7 @@ public class SimpleCommandMap implements CommandMap {
+ try {
+ try (co.aikar.timings.Timing ignored = target.timings.startTiming()) { // Paper - use try with resources
+ // Note: we don't return the result of target.execute as thats success / failure, we return handled (true) or not handled (false)
+- target.execute(sender, sentCommandLabel, Arrays.copyOfRange(args, 1, args.length));
++ target.execute(sender, sentCommandLabel, parsedArgs); // Purpur
+ } // target.timings.stopTiming(); // Spigot // Paper
+ } catch (CommandException ex) {
+ server.getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerCommandException(ex, target, sender, args))); // Paper
diff --git a/src/main/java/org/bukkit/command/defaults/VersionCommand.java b/src/main/java/org/bukkit/command/defaults/VersionCommand.java
index fd5d9881abfd930bb883120f018f76dc78b62b14..d3dadad49df09e85c724c93e8cc88da2c985e9b4 100644
--- a/src/main/java/org/bukkit/command/defaults/VersionCommand.java
@@ -786,10 +787,10 @@ index 138d2530de2410f4a9424dabd3e5ce0cd1c1dcd2..10a8d64ad2da0be2c14f34c3e7d1957c
// Paper start
/**
diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java
-index 23def071492ccd715693d534cc506936e18f0f46..51ae4b559a6ebb5c324ac029c86e5b5a6b894d7e 100644
+index 62e3793903905b94eb1a120345015149abb33713..07b8c0dd049ff783fd2e408be634642479bf8b1e 100644
--- a/src/main/java/org/bukkit/entity/Entity.java
+++ b/src/main/java/org/bukkit/entity/Entity.java
-@@ -1144,4 +1144,42 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent
+@@ -1155,4 +1155,55 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent
*/
@NotNull String getScoreboardEntryName();
// Paper end - entity scoreboard name
@@ -830,6 +831,19 @@ index 23def071492ccd715693d534cc506936e18f0f46..51ae4b559a6ebb5c324ac029c86e5b5a
+ * @return True if in daylight
+ */
+ boolean isInDaylight();
++
++ /**
++ * Checks if the entity is fire immune
++ *
++ * @return True if fire immune
++ */
++ boolean isImmuneToFire();
++
++ /**
++ * Sets if the entity is fire immune
++ * Set this to null to restore the entity type default
++ */
++ void setImmuneToFire(@Nullable Boolean fireImmune);
+ // Purpur end
}
diff --git a/src/main/java/org/bukkit/entity/IronGolem.java b/src/main/java/org/bukkit/entity/IronGolem.java
@@ -925,30 +939,16 @@ index bcc6ba95bd21c7972865838c636a03f50b6c1f1a..c3fcd8dd7dbb1e1a18e17c014c1e6411
+ // Purpur end
}
diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java
-index 65112eae8b92344796850b1e4c89e75443eab2fe..5369d802d37863a1efc0c031520147ceedcadc78 100644
+index b777e530122549455dcce6fac8d4a151c1c0af42..61a046584acf48693489ff551a0dd4c4b16af9ff 100644
--- a/src/main/java/org/bukkit/entity/LivingEntity.java
+++ b/src/main/java/org/bukkit/entity/LivingEntity.java
-@@ -1445,4 +1445,41 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource
+@@ -1447,4 +1447,27 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource
*/
void setBodyYaw(float bodyYaw);
// Paper end - body yaw API
+
+ // Purpur start
+ /**
-+ * Gets the distance (in blocks) this entity can safely fall without taking damage
-+ *
-+ * @return Safe fall distance
-+ */
-+ float getSafeFallDistance();
-+
-+ /**
-+ * Set the distance (in blocks) this entity can safely fall without taking damage
-+ *
-+ * @param safeFallDistance Safe fall distance
-+ */
-+ void setSafeFallDistance(float safeFallDistance);
-+
-+ /**
+ * Play item break animation for the item in specified equipment slot
+ *
+ * @param slot Equipment slot to play break animation for
@@ -996,10 +996,10 @@ index bc84b892cae5fe7019a3ad481e9da79956efa1fe..48eb5b00c460cccde29d327cef1d63fc
+ // Purpur end
}
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
-index db3dfc95ca2997745092cf4632c60705d05a6640..6a9ce422d1def472ef4bbd3cc716426385be0cc4 100644
+index 0b3a1f3285fc0d8954f4204a93d3905df01cd828..2ba39b38a97333f867bcabdf593448ca14255703 100644
--- a/src/main/java/org/bukkit/entity/Player.java
+++ b/src/main/java/org/bukkit/entity/Player.java
-@@ -3762,4 +3762,123 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
+@@ -3806,4 +3806,123 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
@Override
Spigot spigot();
// Spigot end
@@ -1193,13 +1193,13 @@ index 14543c2238b45c526dd9aebea2aa5c22f5df54dc..5312daf33405704c74e2c9e109754285
+ // Purpur end
}
diff --git a/src/main/java/org/bukkit/entity/Wolf.java b/src/main/java/org/bukkit/entity/Wolf.java
-index 84db38388bf7a58e66d6cd29620b4fe64b0a897e..82ebd99549ce9f9e6427a50cef424e9007735708 100644
+index 4b84c04675775e2a606630b00de8afe51665cebc..ccbaf40a3131f477b4be2264401ad893725c1162 100644
--- a/src/main/java/org/bukkit/entity/Wolf.java
+++ b/src/main/java/org/bukkit/entity/Wolf.java
-@@ -69,4 +69,20 @@ public interface Wolf extends Tameable, Sittable, io.papermc.paper.entity.Collar
- * @param interested Whether the wolf is interested
- */
- public void setInterested(boolean interested);
+@@ -112,4 +112,20 @@ public interface Wolf extends Tameable, Sittable, io.papermc.paper.entity.Collar
+ return variant;
+ }
+ }
+
+ // Purpur start
+ /**
@@ -1249,10 +1249,10 @@ index c9f395064656dd0126410eb3c6e197baa450c063..13156a12e5df50cdc1e465dc0bd9d941
* When a player gets bad omen after killing a patrol captain.
*/
diff --git a/src/main/java/org/bukkit/event/inventory/InventoryType.java b/src/main/java/org/bukkit/event/inventory/InventoryType.java
-index daa1306a7324d946d66ad5a674bbc84371d8d4d6..f3b2d7b6fda051211add2b3215f120fb6911aeed 100644
+index 59b375569a75cb1e1f7c610f96078e102ec0d3ed..a3f74891abbdc51dbbddaeb511f2754e0603c904 100644
--- a/src/main/java/org/bukkit/event/inventory/InventoryType.java
+++ b/src/main/java/org/bukkit/event/inventory/InventoryType.java
-@@ -165,7 +165,7 @@ public enum InventoryType {
+@@ -166,7 +166,7 @@ public enum InventoryType {
SMITHING_NEW(4, "Upgrade Gear"),
;
@@ -1278,33 +1278,13 @@ index c60be4fd24c7fdf65251dd6169e5e1ac3b588d95..569deccd2f1cf21da9b5906433ac493c
+ boolean canDoUnsafeEnchants();
+
+ void setDoUnsafeEnchants(boolean canDoUnsafeEnchants);
-+ // Purpur end
- }
-diff --git a/src/main/java/org/bukkit/inventory/ItemFactory.java b/src/main/java/org/bukkit/inventory/ItemFactory.java
-index f680545b6b59bf8d2ad154b0472dda4cba42a162..3709ff939acdcaec124c2875a37c4a07745cdaab 100644
---- a/src/main/java/org/bukkit/inventory/ItemFactory.java
-+++ b/src/main/java/org/bukkit/inventory/ItemFactory.java
-@@ -353,4 +353,15 @@ public interface ItemFactory {
- */
- @NotNull ItemStack enchantWithLevels(@NotNull ItemStack itemStack, @org.jetbrains.annotations.Range(from = 1, to = 30) int levels, boolean allowTreasure, @NotNull java.util.Random random);
- // Paper end - enchantWithLevels API
-+
-+ // Purpur start
-+ /**
-+ * Returns the lines of text shown when hovering over an item
-+ *
-+ * @param itemStack The ItemStack
-+ * @param advanced Whether advanced tooltips are shown
-+ * @return the list of Components
-+ */
-+ @NotNull java.util.List getHoverLines(@NotNull ItemStack itemStack, boolean advanced);
+ // Purpur end
}
diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java
-index 7414b4fa690d393a8e9557cc1fd1ce12fa426940..e0f8cab6d78110a43c29d3b5256539d62ba03abf 100644
+index 84a7bf0936d35bf42b5ed038d295d5c31740f472..6e9b4cbc81878616b1c48add5db534286d267b05 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;
+@@ -17,6 +17,17 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.material.MaterialData;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -1318,12 +1298,11 @@ index 7414b4fa690d393a8e9557cc1fd1ce12fa426940..e0f8cab6d78110a43c29d3b5256539d6
+import org.bukkit.inventory.meta.Repairable;
+import org.bukkit.persistence.PersistentDataContainer;
+import org.bukkit.persistence.PersistentDataHolder;
-+import com.destroystokyo.paper.Namespaced;
+// Purpur end
/**
* Represents a stack of items.
-@@ -1061,4 +1073,636 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat
+@@ -1073,4 +1084,565 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat
return Bukkit.getUnsafe().computeTooltipLines(this, tooltipContext, player);
}
// Paper end - expose itemstack tooltip lines
@@ -1808,67 +1787,6 @@ index 7414b4fa690d393a8e9557cc1fd1ce12fa426940..e0f8cab6d78110a43c29d3b5256539d6
+ }
+
+ /**
-+ * Gets the collection of namespaced keys that the item can destroy in {@link org.bukkit.GameMode#ADVENTURE}
-+ *
-+ * @return Set of {@link com.destroystokyo.paper.Namespaced}
-+ */
-+ @NotNull
-+ public java.util.Set getDestroyableKeys() {
-+ return getItemMeta().getDestroyableKeys();
-+ }
-+
-+ /**
-+ * Sets the collection of namespaced keys that the item can destroy in {@link org.bukkit.GameMode#ADVENTURE}
-+ *
-+ * @param canDestroy Collection of {@link com.destroystokyo.paper.Namespaced}
-+ */
-+ public void setDestroyableKeys(@NotNull Collection canDestroy) {
-+ ItemMeta itemMeta = getItemMeta();
-+ itemMeta.setDestroyableKeys(canDestroy);
-+ setItemMeta(itemMeta);
-+ }
-+
-+ /**
-+ * Gets the collection of namespaced keys that the item can be placed on in {@link org.bukkit.GameMode#ADVENTURE}
-+ *
-+ * @return Set of {@link com.destroystokyo.paper.Namespaced}
-+ */
-+ @NotNull
-+ public java.util.Set getPlaceableKeys() {
-+ return getItemMeta().getPlaceableKeys();
-+ }
-+
-+ /**
-+ * Sets the set of namespaced keys that the item can be placed on in {@link org.bukkit.GameMode#ADVENTURE}
-+ *
-+ * @param canPlaceOn Collection of {@link com.destroystokyo.paper.Namespaced}
-+ */
-+ @NotNull
-+ public void setPlaceableKeys(@NotNull Collection canPlaceOn) {
-+ ItemMeta itemMeta = getItemMeta();
-+ itemMeta.setPlaceableKeys(canPlaceOn);
-+ setItemMeta(itemMeta);
-+ }
-+
-+ /**
-+ * Checks for the existence of any keys that the item can be placed on
-+ *
-+ * @return true if this item has placeable keys
-+ */
-+ public boolean hasPlaceableKeys() {
-+ return hasItemMeta() && getItemMeta().hasPlaceableKeys();
-+ }
-+
-+ /**
-+ * Checks for the existence of any keys that the item can destroy
-+ *
-+ * @return true if this item has destroyable keys
-+ */
-+ public boolean hasDestroyableKeys() {
-+ return hasItemMeta() && getItemMeta().hasDestroyableKeys();
-+ }
-+
-+ /**
+ * Repairs this item by 1 durability
+ */
+ public void repair() {
@@ -1913,7 +1831,7 @@ index 7414b4fa690d393a8e9557cc1fd1ce12fa426940..e0f8cab6d78110a43c29d3b5256539d6
+ public boolean damage(int amount, boolean ignoreUnbreaking) {
+ Damageable damageable = (Damageable) getItemMeta();
+ if (amount > 0) {
-+ int unbreaking = getEnchantLevel(Enchantment.DURABILITY);
++ int unbreaking = getEnchantLevel(Enchantment.UNBREAKING);
+ int reduce = 0;
+ for (int i = 0; unbreaking > 0 && i < amount; ++i) {
+ if (reduceDamage(java.util.concurrent.ThreadLocalRandom.current(), unbreaking)) {
@@ -1948,16 +1866,6 @@ index 7414b4fa690d393a8e9557cc1fd1ce12fa426940..e0f8cab6d78110a43c29d3b5256539d6
+ }
+ return random.nextInt(unbreaking + 1) > 0;
+ }
-+
-+ /**
-+ * Returns the lines of text shown when hovering over the item
-+ *
-+ * @param advanced Whether advanced tooltips are shown
-+ * @return the list of Components
-+ */
-+ public @NotNull List getHoverLines(boolean advanced) {
-+ return Bukkit.getItemFactory().getHoverLines(this, advanced);
-+ }
+ // Purpur end
}
diff --git a/src/main/java/org/bukkit/inventory/RecipeChoice.java b/src/main/java/org/bukkit/inventory/RecipeChoice.java
@@ -2045,205 +1953,6 @@ index cd3296fea01648592d2af89b3d80135acb6d0958..45797a6fbae1d8edc4211cb30def24ad
String lname = name.toLowerCase(java.util.Locale.ENGLISH);
permissions.put(lname, new PermissionAttachmentInfo(parent, lname, attachment, value));
-diff --git a/src/main/java/org/bukkit/potion/PotionEffect.java b/src/main/java/org/bukkit/potion/PotionEffect.java
-index c8ab330ef171795d08fa201cf8320703c7f1c66b..ea656ed39ebc9875f93f99bea274b0ea4456fcf5 100644
---- a/src/main/java/org/bukkit/potion/PotionEffect.java
-+++ b/src/main/java/org/bukkit/potion/PotionEffect.java
-@@ -33,6 +33,7 @@ public class PotionEffect implements ConfigurationSerializable {
- private static final String AMBIENT = "ambient";
- private static final String PARTICLES = "has-particles";
- private static final String ICON = "has-icon";
-+ private static final String KEY = "namespacedKey"; // Purpur
- private final int amplifier;
- private final int duration;
- private final PotionEffectType type;
-@@ -40,6 +41,7 @@ public class PotionEffect implements ConfigurationSerializable {
- private final boolean particles;
- private final boolean icon;
- private final PotionEffect hiddenEffect; // Paper
-+ @Nullable private final NamespacedKey key; // Purpur
-
- /**
- * Creates a potion effect.
-@@ -50,11 +52,12 @@ public class PotionEffect implements ConfigurationSerializable {
- * @param ambient the ambient status, see {@link PotionEffect#isAmbient()}
- * @param particles the particle status, see {@link PotionEffect#hasParticles()}
- * @param icon the icon status, see {@link PotionEffect#hasIcon()}
-+ * @param key the namespacedKey, see {@link PotionEffect#getKey()}
- * @param hiddenEffect the hidden PotionEffect
- * @hidden Internal-- hidden effects are only shown internally
- */
- @org.jetbrains.annotations.ApiStatus.Internal // Paper
-- public PotionEffect(@NotNull PotionEffectType type, int duration, int amplifier, boolean ambient, boolean particles, boolean icon, @Nullable PotionEffect hiddenEffect) { // Paper
-+ public PotionEffect(@NotNull PotionEffectType type, int duration, int amplifier, boolean ambient, boolean particles, boolean icon, @Nullable PotionEffect hiddenEffect, @Nullable NamespacedKey key) { // Paper // Purpur
- Preconditions.checkArgument(type != null, "effect type cannot be null");
- this.type = type;
- this.duration = duration;
-@@ -62,6 +65,7 @@ public class PotionEffect implements ConfigurationSerializable {
- this.ambient = ambient;
- this.particles = particles;
- this.icon = icon;
-+ this.key = key; // Purpur
- // Paper start
- this.hiddenEffect = hiddenEffect;
- }
-@@ -77,10 +81,28 @@ public class PotionEffect implements ConfigurationSerializable {
- * @param icon the icon status, see {@link PotionEffect#hasIcon()}
- */
- public PotionEffect(@NotNull PotionEffectType type, int duration, int amplifier, boolean ambient, boolean particles, boolean icon) {
-- this(type, duration, amplifier, ambient, particles, icon, null);
-+ this(type, duration, amplifier, ambient, particles, icon, null, null); // Purpur
- // Paper end
- }
-
-+ // Purpur start
-+ /**
-+ * Creates a potion effect.
-+ *
-+ * @param type effect type
-+ * @param duration measured in ticks, see {@link
-+ * PotionEffect#getDuration()}
-+ * @param amplifier the amplifier, see {@link PotionEffect#getAmplifier()}
-+ * @param ambient the ambient status, see {@link PotionEffect#isAmbient()}
-+ * @param particles the particle status, see {@link PotionEffect#hasParticles()}
-+ * @param icon the icon status, see {@link PotionEffect#hasIcon()}
-+ * @param key the namespacedKey, see {@link PotionEffect#getKey()}
-+ */
-+ public PotionEffect(@NotNull PotionEffectType type, int duration, int amplifier, boolean ambient, boolean particles, boolean icon, @Nullable NamespacedKey key) {
-+ this(type, duration, amplifier, ambient, particles, icon, null, key);
-+ }
-+ // Purpur end
-+
- /**
- * Creates a potion effect with no defined color.
- *
-@@ -126,33 +148,33 @@ public class PotionEffect implements ConfigurationSerializable {
- * @param map the map to deserialize from
- */
- public PotionEffect(@NotNull Map map) {
-- this(getEffectType(map), getInt(map, DURATION), getInt(map, AMPLIFIER), getBool(map, AMBIENT, false), getBool(map, PARTICLES, true), getBool(map, ICON, getBool(map, PARTICLES, true)), (PotionEffect) map.get(HIDDEN_EFFECT)); // Paper
-+ this(getEffectType(map), getInt(map, DURATION), getInt(map, AMPLIFIER), getBool(map, AMBIENT, false), getBool(map, PARTICLES, true), getBool(map, ICON, getBool(map, PARTICLES, true)), (PotionEffect) map.get(HIDDEN_EFFECT), getKey(map)); // Paper // Purpur - getKey
- }
-
- // Paper start
- @NotNull
- public PotionEffect withType(@NotNull PotionEffectType type) {
-- return new PotionEffect(type, duration, amplifier, ambient, particles, icon);
-+ return new PotionEffect(type, duration, amplifier, ambient, particles, icon, key); // Purpur - add key
- }
- @NotNull
- public PotionEffect withDuration(int duration) {
-- return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon);
-+ return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon, key); // Purpur - add key
- }
- @NotNull
- public PotionEffect withAmplifier(int amplifier) {
-- return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon);
-+ return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon, key); // Purpur - add key
- }
- @NotNull
- public PotionEffect withAmbient(boolean ambient) {
-- return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon);
-+ return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon, key); // Purpur - add key
- }
- @NotNull
- public PotionEffect withParticles(boolean particles) {
-- return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon);
-+ return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon, key); // Purpur - add key
- }
- @NotNull
- public PotionEffect withIcon(boolean icon) {
-- return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon);
-+ return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon, key); // Purpur - add key
- }
-
- /**
-@@ -169,6 +191,13 @@ public class PotionEffect implements ConfigurationSerializable {
- }
- // Paper end
-
-+ // Purpur start
-+ @NotNull
-+ public PotionEffect withKey(@Nullable NamespacedKey key) {
-+ return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon, key);
-+ }
-+ // Purpur end
-+
- @NotNull
- private static PotionEffectType getEffectType(@NotNull Map, ?> map) {
- PotionEffectType effect;
-@@ -201,6 +230,17 @@ public class PotionEffect implements ConfigurationSerializable {
- return def;
- }
-
-+ // Purpur start
-+ @Nullable
-+ private static NamespacedKey getKey(@NotNull Map, ?> map) {
-+ Object key = map.get(KEY);
-+ if (key instanceof String stringKey) {
-+ return NamespacedKey.fromString(stringKey);
-+ }
-+ return null;
-+ }
-+ // Purpur end
-+
- @Override
- @NotNull
- public Map serialize() {
-@@ -215,6 +255,11 @@ public class PotionEffect implements ConfigurationSerializable {
- if (this.hiddenEffect != null) {
- builder.put(HIDDEN_EFFECT, this.hiddenEffect);
- }
-+ // Purpur start
-+ if (key != null) {
-+ builder.put(KEY, key.toString());
-+ }
-+ // Purpur end
- return builder.build();
- // Paper end
- }
-@@ -243,7 +288,7 @@ public class PotionEffect implements ConfigurationSerializable {
- return false;
- }
- PotionEffect that = (PotionEffect) obj;
-- return this.type.equals(that.type) && this.ambient == that.ambient && this.amplifier == that.amplifier && this.duration == that.duration && this.particles == that.particles && this.icon == that.icon && java.util.Objects.equals(this.hiddenEffect, that.hiddenEffect); // Paper
-+ return this.type.equals(that.type) && this.ambient == that.ambient && this.amplifier == that.amplifier && this.duration == that.duration && this.particles == that.particles && this.icon == that.icon && java.util.Objects.equals(this.hiddenEffect, that.hiddenEffect) && this.key == that.key; // Paper // Purpur - add key
- }
-
- /**
-@@ -339,6 +384,24 @@ public class PotionEffect implements ConfigurationSerializable {
- return icon;
- }
-
-+
-+ // Purpur start
-+ /**
-+ * @return if the key isn't the default namespacedKey
-+ */
-+ public boolean hasKey() {
-+ return key != null;
-+ }
-+
-+ /**
-+ * @return the key attached to the potion
-+ */
-+ @Nullable
-+ public NamespacedKey getKey() {
-+ return key;
-+ }
-+ // Purpur end
-+
- @Override
- public int hashCode() {
- int hash = 1;
-@@ -354,6 +417,6 @@ public class PotionEffect implements ConfigurationSerializable {
-
- @Override
- public String toString() {
-- return "PotionEffect{" + "amplifier=" + amplifier + ", duration=" + duration + ", type=" + type + ", ambient=" + ambient + ", particles=" + particles + ", icon=" + icon + ", hiddenEffect=" + hiddenEffect + '}'; // Paper
-+ return "PotionEffect{" + "amplifier=" + amplifier + ", duration=" + duration + ", type=" + type + ", ambient=" + ambient + ", particles=" + particles + ", icon=" + icon + ", hiddenEffect=" + hiddenEffect + ", key=" + key + '}'; // Paper // Purpur - add key
- }
- }
diff --git a/src/main/java/org/bukkit/util/permissions/CommandPermissions.java b/src/main/java/org/bukkit/util/permissions/CommandPermissions.java
index 7763d6101ac61900db1e2310966b99584539fd0e..d5a42707d365ffd72532bbb1a59a1ca7145f9918 100644
--- a/src/main/java/org/bukkit/util/permissions/CommandPermissions.java
@@ -2770,10 +2479,10 @@ index 0000000000000000000000000000000000000000..519809eab5d926dc7b0a7bad5d446d0d
+}
diff --git a/src/main/java/org/purpurmc/purpur/event/PreBlockExplodeEvent.java b/src/main/java/org/purpurmc/purpur/event/PreBlockExplodeEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..32602b398ede24a35ed8a996faa2b23455615a7b
+index 0000000000000000000000000000000000000000..8ea97ddceedb7c719e8a50a0dd8f3f0919ca1647
--- /dev/null
+++ b/src/main/java/org/purpurmc/purpur/event/PreBlockExplodeEvent.java
-@@ -0,0 +1,54 @@
+@@ -0,0 +1,53 @@
+package org.purpurmc.purpur.event;
+
+import org.bukkit.block.Block;
@@ -2782,7 +2491,6 @@ index 0000000000000000000000000000000000000000..32602b398ede24a35ed8a996faa2b234
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.block.BlockExplodeEvent;
+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
+import java.util.Collections;
+
+/**
@@ -2793,8 +2501,8 @@ index 0000000000000000000000000000000000000000..32602b398ede24a35ed8a996faa2b234
+ private boolean cancelled;
+ private final float yield;
+
-+ public PreBlockExplodeEvent(@NotNull final Block what, final float yield, @Nullable BlockState explodedBlockState) {
-+ super(what, Collections.emptyList(), yield, explodedBlockState);
++ public PreBlockExplodeEvent(@NotNull final Block what, final float yield, @NotNull BlockState explodedBlockState) {
++ super(what, explodedBlockState, Collections.emptyList(), yield);
+ this.yield = yield;
+ this.cancelled = false;
+ }
@@ -3695,60 +3403,6 @@ index 0000000000000000000000000000000000000000..eebb5d124456b8209d1b8e8cc4cb772d
+ return handlers;
+ }
+}
-diff --git a/src/main/java/org/purpurmc/purpur/event/packet/NetworkItemSerializeEvent.java b/src/main/java/org/purpurmc/purpur/event/packet/NetworkItemSerializeEvent.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..c0da73d2ea83a6055e34894ba1c7506fc8667712
---- /dev/null
-+++ b/src/main/java/org/purpurmc/purpur/event/packet/NetworkItemSerializeEvent.java
-@@ -0,0 +1,48 @@
-+package org.purpurmc.purpur.event.packet;
-+
-+import org.bukkit.event.Event;
-+import org.bukkit.event.HandlerList;
-+import org.bukkit.inventory.ItemStack;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
-+
-+/**
-+ * Called when an item is about to be written to a packet.
-+ */
-+public class NetworkItemSerializeEvent extends Event {
-+ private ItemStack itemStack;
-+
-+ public NetworkItemSerializeEvent(@NotNull ItemStack itemStack) {
-+ super(!org.bukkit.Bukkit.isPrimaryThread());
-+ this.itemStack = itemStack;
-+ }
-+
-+ /**
-+ * @return The item that is about to be serialized. Not mutable
-+ */
-+ @NotNull
-+ public ItemStack getItemStack() {
-+ return itemStack;
-+ }
-+
-+ /**
-+ * Sets the item that will be serialized.
-+ *
-+ * @param itemStack The item
-+ */
-+ public void setItemStack(@Nullable ItemStack itemStack) {
-+ this.itemStack = itemStack;
-+ }
-+
-+ private static final HandlerList handlers = new HandlerList();
-+
-+ @NotNull
-+ public HandlerList getHandlers() {
-+ return handlers;
-+ }
-+
-+ @NotNull
-+ public static HandlerList getHandlerList() {
-+ return handlers;
-+ }
-+}
diff --git a/src/main/java/org/purpurmc/purpur/event/player/PlayerBookTooLargeEvent.java b/src/main/java/org/purpurmc/purpur/event/player/PlayerBookTooLargeEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..c88394336bc9ab0f66a2af24d393f4a176a234d5
diff --git a/patches/api/0004-Remove-Timings.patch b/patches/api/0004-Remove-Timings.patch
index 307d14e5..4343639f 100644
--- a/patches/api/0004-Remove-Timings.patch
+++ b/patches/api/0004-Remove-Timings.patch
@@ -2830,29 +2830,19 @@ index 3e61a926620a67daec3af54b72a1b911eaef2ed4..00000000000000000000000000000000
- }
-}
diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java
-index b9a07b2db8a3dcdb72c33c8ceda129921b2c02f1..d2e8e1f000277343801261d2dde4d1e5b91035ea 100644
+index a3ba9249e636d1fb8dad98fab413436009fe04df..0a4d7e3b8eda50ec10a7cdb4110628b51b771ef8 100644
--- a/src/main/java/org/bukkit/UnsafeValues.java
+++ b/src/main/java/org/bukkit/UnsafeValues.java
-@@ -40,7 +40,6 @@ public interface UnsafeValues {
- net.kyori.adventure.text.Component resolveWithContext(net.kyori.adventure.text.Component component, org.bukkit.command.CommandSender context, org.bukkit.entity.Entity scoreboardSubject, boolean bypassPermissions) throws java.io.IOException;
- // Paper end
-
-- void reportTimings(); // Paper
- Material toLegacy(Material material);
-
- Material fromLegacy(Material material);
-@@ -141,11 +140,6 @@ public interface UnsafeValues {
- // Paper end
+@@ -142,7 +142,8 @@ public interface UnsafeValues {
// Paper start
-- /**
-- * Server name to report to timings v2
-- * @return name
-- */
-- String getTimingsServerName();
-
/**
- * Called once by the version command on first use, then cached.
+- * Server name to report to timings v2
++ * Server name
++ *
+ * @return name
+ */
+ String getTimingsServerName();
diff --git a/src/main/java/org/bukkit/command/BufferedCommandSender.java b/src/main/java/org/bukkit/command/BufferedCommandSender.java
deleted file mode 100644
index f9a00aecca5ec41b460bf41dfe1c69694768cf98..0000000000000000000000000000000000000000
@@ -2881,7 +2871,7 @@ index f9a00aecca5ec41b460bf41dfe1c69694768cf98..00000000000000000000000000000000
- }
-}
diff --git a/src/main/java/org/bukkit/command/Command.java b/src/main/java/org/bukkit/command/Command.java
-index b791358f90fe92bc2264d9a26492245763813af3..dc5860f9735ec4767ef9f6ee013006a3da0c67dd 100644
+index b3a2c274f05156fd603bcc7a68ab41265f2eaf44..7c94976e6bac4a0adbe4bbdb25764040aa5c447d 100644
--- a/src/main/java/org/bukkit/command/Command.java
+++ b/src/main/java/org/bukkit/command/Command.java
@@ -33,8 +33,6 @@ public abstract class Command {
@@ -2917,7 +2907,7 @@ index 9d4f553c04784cca63901a56a7aea62a5cae1d72..0f96873eff87ea267f9c1875b3893f35
return i >= j && i <= k;
}
diff --git a/src/main/java/org/bukkit/command/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java
-index e43d0e0a2c5edfcc82a677b6c4db9314006c9bf4..68fafa73d2e8d832acc7ce47591477749128b007 100644
+index e842d13febca67ffa1c89fb2c1324d2609fb81fd..3a146a9c2fc99ea8f9f6a8c2c1d053bf68aeb853 100644
--- a/src/main/java/org/bukkit/command/SimpleCommandMap.java
+++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java
@@ -34,7 +34,6 @@ public class SimpleCommandMap implements CommandMap {
@@ -2949,7 +2939,7 @@ index e43d0e0a2c5edfcc82a677b6c4db9314006c9bf4..68fafa73d2e8d832acc7ce4759147774
try {
- try (co.aikar.timings.Timing ignored = target.timings.startTiming()) { // Paper - use try with resources
// Note: we don't return the result of target.execute as thats success / failure, we return handled (true) or not handled (false)
- target.execute(sender, sentCommandLabel, Arrays.copyOfRange(args, 1, args.length));
+ target.execute(sender, sentCommandLabel, parsedArgs); // Purpur
- } // target.timings.stopTiming(); // Spigot // Paper
} catch (CommandException ex) {
server.getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerCommandException(ex, target, sender, args))); // Paper
@@ -2961,7 +2951,7 @@ index e43d0e0a2c5edfcc82a677b6c4db9314006c9bf4..68fafa73d2e8d832acc7ce4759147774
server.getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerCommandException(ex, target, sender, args))); // Paper
throw new CommandException(msg, ex);
diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
-index 899d67fa782fac639fe7fb096e05c551d75bd647..4e93f49d1c54f3b061be456c0b8f11aa58f5a3af 100644
+index 5dc64d8c9aeae612fd31af0673f3530a9e777dfc..b598ad80bbcc256c1440a5ab79321b93ae9f12ed 100644
--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java
+++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
@@ -60,7 +60,6 @@ public final class SimplePluginManager implements PluginManager {
@@ -2972,7 +2962,7 @@ index 899d67fa782fac639fe7fb096e05c551d75bd647..4e93f49d1c54f3b061be456c0b8f11aa
public SimplePluginManager(@NotNull Server instance, @NotNull SimpleCommandMap commandMap) {
server = instance;
-@@ -711,12 +710,7 @@ public final class SimplePluginManager implements PluginManager {
+@@ -723,12 +722,7 @@ public final class SimplePluginManager implements PluginManager {
throw new IllegalPluginAccessException("Plugin attempted to register " + event + " while not enabled");
}
@@ -2986,7 +2976,7 @@ index 899d67fa782fac639fe7fb096e05c551d75bd647..4e93f49d1c54f3b061be456c0b8f11aa
}
@NotNull
-@@ -946,17 +940,7 @@ public final class SimplePluginManager implements PluginManager {
+@@ -958,17 +952,7 @@ public final class SimplePluginManager implements PluginManager {
@Override
public boolean useTimings() {
diff --git a/patches/api/0005-Bump-Dependencies.patch b/patches/api/0005-Bump-Dependencies.patch
index 6c72a9ed..e165bd45 100644
--- a/patches/api/0005-Bump-Dependencies.patch
+++ b/patches/api/0005-Bump-Dependencies.patch
@@ -5,25 +5,23 @@ Subject: [PATCH] Bump Dependencies
diff --git a/build.gradle.kts b/build.gradle.kts
-index 4a9deabf03236533aa86860326f0da21650dd38f..673548d13590cb99f293f0799b05d974e6cd660b 100644
+index a085f6fa2cfb3721752b38096a2c35fcdd114d02..b3410e3fcead1deec4c052bf813a243f55b3b0cd 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
-@@ -9,11 +9,11 @@ java {
- withJavadocJar()
- }
-
--val annotationsVersion = "24.0.1"
-+val annotationsVersion = "24.1.0" // Leaf - Bump Dependencies
+@@ -12,8 +12,10 @@ java {
+ val annotationsVersion = "24.1.0"
val bungeeCordChatVersion = "1.20-R0.2"
- val adventureVersion = "4.16.0"
+ val adventureVersion = "4.17.0-SNAPSHOT"
-val slf4jVersion = "2.0.9"
-val log4jVersion = "2.17.1"
-+val slf4jVersion = "2.0.13" // Leaf - Bump Dependencies
-+val log4jVersion = "2.23.1" // Leaf - Bump Dependencies
++// Leaf start - Bump Dependencies
++val slf4jVersion = "2.0.13"
++val log4jVersion = "2.23.1"
++// Leaf end - Bump Dependencies
val apiAndDocs: Configuration by configurations.creating {
attributes {
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.DOCUMENTATION))
-@@ -28,7 +28,7 @@ configurations.api {
+@@ -28,7 +30,7 @@ configurations.api {
dependencies {
// api dependencies are listed transitively to API consumers
@@ -32,7 +30,7 @@ index 4a9deabf03236533aa86860326f0da21650dd38f..673548d13590cb99f293f0799b05d974
api("com.google.code.gson:gson:2.10.1")
// Paper start - adventure
api("net.md-5:bungeecord-chat:$bungeeCordChatVersion-deprecated+build.18") {
-@@ -41,7 +41,7 @@ dependencies {
+@@ -41,7 +43,7 @@ dependencies {
api("com.googlecode.json-simple:json-simple:1.1.1") {
isTransitive = false // includes junit
}
@@ -41,7 +39,7 @@ index 4a9deabf03236533aa86860326f0da21650dd38f..673548d13590cb99f293f0799b05d974
apiAndDocs(platform("net.kyori:adventure-bom:$adventureVersion"))
apiAndDocs("net.kyori:adventure-api")
apiAndDocs("net.kyori:adventure-text-minimessage")
-@@ -51,28 +51,30 @@ dependencies {
+@@ -51,28 +53,32 @@ dependencies {
apiAndDocs("net.kyori:adventure-text-logger-slf4j")
api("org.apache.logging.log4j:log4j-api:$log4jVersion")
api("org.slf4j:slf4j-api:$slf4jVersion")
@@ -55,8 +53,10 @@ index 4a9deabf03236533aa86860326f0da21650dd38f..673548d13590cb99f293f0799b05d974
api("org.apache.maven:maven-resolver-provider:3.9.6") // Paper - make API dependency for Paper Plugins
- compileOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.18")
- compileOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.9.18")
++ // Leaf start - Bump Dependencies
+ compileOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.19")
+ compileOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.9.19")
++ // Leaf end - Bump Dependencies
val annotations = "org.jetbrains:annotations:$annotationsVersion" // Paper - we don't want Java 5 annotations...
compileOnly(annotations)
@@ -70,15 +70,15 @@ index 4a9deabf03236533aa86860326f0da21650dd38f..673548d13590cb99f293f0799b05d974
// Paper end
- testImplementation("org.apache.commons:commons-lang3:3.12.0")
-- testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")
+- testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
+ // Leaf start - Bump Dependencies
+ testImplementation("org.apache.commons:commons-lang3:3.14.0")
-+ testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
-+ // Leaf end
++ testImplementation("org.junit.jupiter:junit-jupiter:5.11.0-M1")
++ // Leaf end - Bump Dependencies
testImplementation("org.hamcrest:hamcrest:2.2")
testImplementation("org.mockito:mockito-core:5.11.0")
testImplementation("org.ow2.asm:asm-tree:9.7")
-@@ -143,12 +145,12 @@ tasks.withType {
+@@ -143,12 +149,12 @@ tasks.withType {
options.use()
options.isDocFilesSubDirs = true
options.links(
@@ -93,9 +93,9 @@ index 4a9deabf03236533aa86860326f0da21650dd38f..673548d13590cb99f293f0799b05d974
"https://www.javadoc.io/doc/com.google.code.gson/gson/2.10.1",
// Paper end
// Paper start
-@@ -159,9 +161,9 @@ tasks.withType {
- "https://jd.advntr.dev/text-serializer-plain/$adventureVersion/",
- "https://jd.advntr.dev/text-logger-slf4j/$adventureVersion/",
+@@ -159,9 +165,9 @@ tasks.withType {
+ //"https://jd.advntr.dev/text-serializer-plain/$adventureVersion/",
+ //"https://jd.advntr.dev/text-logger-slf4j/$adventureVersion/",
"https://javadoc.io/doc/org.slf4j/slf4j-api/$slf4jVersion/",
- "https://javadoc.io/doc/org.apache.logging.log4j/log4j-api/$log4jVersion/",
+ "https://javadoc.io/doc/org.apache.logging.log4j/log4j-api/2.20.0", // Leaf - Bump Dependencies
@@ -105,13 +105,15 @@ index 4a9deabf03236533aa86860326f0da21650dd38f..673548d13590cb99f293f0799b05d974
)
options.tags("apiNote:a:API Note:")
-@@ -204,6 +206,9 @@ val scanJar = tasks.register("scanJarForBadCalls", io.papermc.paperweight.tasks.
+@@ -204,6 +210,11 @@ val scanJar = tasks.register("scanJarForBadCalls", io.papermc.paperweight.tasks.
jarToScan.set(tasks.jar.flatMap { it.archiveFile })
classpath.from(configurations.compileClasspath)
}
++// Leaf start - Bump Dependencies
+repositories {
+ mavenCentral()
+}
++// Leaf end - Bump Dependencies
tasks.check {
dependsOn(scanJar)
}
diff --git a/patches/api/0007-KeYi-Player-Skull-API.patch b/patches/api/0007-KeYi-Player-Skull-API.patch
index 468c27ee..717de8ce 100644
--- a/patches/api/0007-KeYi-Player-Skull-API.patch
+++ b/patches/api/0007-KeYi-Player-Skull-API.patch
@@ -7,21 +7,10 @@ Original license: MIT
Original project: https://github.com/KeYiMC/KeYi
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
-index 6a9ce422d1def472ef4bbd3cc716426385be0cc4..89d124342522743206f8065a32f6e36b954b3b73 100644
+index 2ba39b38a97333f867bcabdf593448ca14255703..fbe4f03bec652e096c46496f1f52080ce43982eb 100644
--- a/src/main/java/org/bukkit/entity/Player.java
+++ b/src/main/java/org/bukkit/entity/Player.java
-@@ -9,6 +9,10 @@ import java.util.Date;
- import java.util.Map;
- import java.util.UUID;
- import org.bukkit.BanEntry;
-+// Leaf start - KeYi - Player Skull API
-+import java.util.concurrent.CompletableFuture;
-+import net.kyori.adventure.text.Component;
-+// Leaf start - KeYi
- import org.bukkit.DyeColor;
- import org.bukkit.Effect;
- import org.bukkit.GameMode;
-@@ -3881,4 +3885,22 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
+@@ -3925,4 +3925,22 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
sendDeathScreen(message);
}
// Purpur end
diff --git a/patches/api/0008-Slice-Smooth-Teleports.patch b/patches/api/0008-Slice-Smooth-Teleports.patch
index 0f8d9512..1f2aa941 100644
--- a/patches/api/0008-Slice-Smooth-Teleports.patch
+++ b/patches/api/0008-Slice-Smooth-Teleports.patch
@@ -7,10 +7,10 @@ Original license: MIT
Original project: https://github.com/Cryptite/Slice
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
-index 69ba1660dae4ac69ec4e92f94dd6f95e9f70427d..dbd5e9faaf92d718c20ceaf076f2afd867232116 100644
+index fbe4f03bec652e096c46496f1f52080ce43982eb..55a578e216cbc160d98d5f5675d8e3c52fa8c178 100644
--- a/src/main/java/org/bukkit/entity/Player.java
+++ b/src/main/java/org/bukkit/entity/Player.java
-@@ -3588,6 +3588,19 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
+@@ -3628,6 +3628,19 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
String getClientBrandName();
// Paper end
diff --git a/patches/api/0009-Configurable-LibraryLoader-maven-repos.patch b/patches/api/0009-Configurable-LibraryLoader-maven-repos.patch
index 174c7403..f524b260 100644
--- a/patches/api/0009-Configurable-LibraryLoader-maven-repos.patch
+++ b/patches/api/0009-Configurable-LibraryLoader-maven-repos.patch
@@ -9,32 +9,24 @@ Add JVM flag `-DLeaf.library-download-repo=link` to choose library download repo
e.g. `-DLeaf.library-download-repo=https://maven.aliyun.com/repository/public`
diff --git a/src/main/java/org/bukkit/plugin/java/LibraryLoader.java b/src/main/java/org/bukkit/plugin/java/LibraryLoader.java
-index 78a6e7a31a81bc82d3e3687661e16c6d8ebc4617..d1052c9e8f64619170548336b25a62c863c5ee2b 100644
+index 72b20fa06b461d89f0eeff7b2fbbbe89bae0027c..1e8720e1bf492e2cf1a1638071514e62ac66391d 100644
--- a/src/main/java/org/bukkit/plugin/java/LibraryLoader.java
+++ b/src/main/java/org/bukkit/plugin/java/LibraryLoader.java
-@@ -6,7 +6,6 @@ import java.net.MalformedURLException;
- import java.net.URL;
- import java.net.URLClassLoader;
- import java.util.ArrayList;
--import java.util.Arrays;
- import java.util.List;
- import java.util.logging.Level;
- import java.util.logging.Logger;
-@@ -46,6 +45,7 @@ public class LibraryLoader
+@@ -46,6 +46,7 @@ public class LibraryLoader
private final RepositorySystem repository;
private final DefaultRepositorySystemSession session;
private final List repositories;
-+ private final String REPO = System.getProperty("Leaf.library-download-repo") != null ? System.getProperty("Leaf.library-download-repo") : "https://repo.maven.apache.org/maven2"; // Leaf - Configurable maven repos
++ private final String repositoryAddress = System.getProperty("Leaf.library-download-repo") != null ? System.getProperty("Leaf.library-download-repo") : "https://repo.maven.apache.org/maven2"; // Leaf - Configurable maven repos
+ public static java.util.function.BiFunction LIBRARY_LOADER_FACTORY; // Paper - rewrite reflection in libraries
+ public static java.util.function.Function, List> REMAPPER; // Paper - remap libraries
- public LibraryLoader(@NotNull Logger logger)
- {
-@@ -72,7 +72,17 @@ public class LibraryLoader
- } );
+@@ -79,7 +80,17 @@ public class LibraryLoader
+ session.setSystemProperties( System.getProperties() );
session.setReadOnly();
- this.repositories = repository.newResolutionRepositories( session, Arrays.asList( new RemoteRepository.Builder( "central", "default", "https://repo.maven.apache.org/maven2" ).build() ) );
+ // Leaf start - Configurable maven repos
-+ this.repositories = repository.newResolutionRepositories( session, List.of( new RemoteRepository.Builder( "central", "default", REPO ).build() ) );
++ this.repositories = repository.newResolutionRepositories( session, List.of( new RemoteRepository.Builder( "central", "default", repositoryAddress ).build() ) );
+ /* // Dreeam TODO
+ this.repositories = repository.newResolutionRepositories(session, List.of(
+ new RemoteRepository.Builder("central", "default", "https://repo.maven.apache.org/maven2").build(),
@@ -43,7 +35,7 @@ index 78a6e7a31a81bc82d3e3687661e16c6d8ebc4617..d1052c9e8f64619170548336b25a62c8
+ new RemoteRepository.Builder("huaweicloud", "default", "https://repo.huaweicloud.com/repository/maven/").build()
+ ));
+ */
-+ // Leaf end
++ // Leaf end - Configurable maven repos
}
@Nullable
diff --git a/patches/generated-api/0001-Purpur-generated-api-Changes.patch b/patches/generated-api/0001-Purpur-generated-api-Changes.patch
index 81094d2d..2783be27 100644
--- a/patches/generated-api/0001-Purpur-generated-api-Changes.patch
+++ b/patches/generated-api/0001-Purpur-generated-api-Changes.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Purpur generated-api Changes
Original license: MIT
Original project: https://github.com/PurpurMC/Purpur
-Commit: 6b1ee98f813ee19f8046b3c528feeee61840a35b
+Commit: a90a4730d672968428e371f024c8317b64eba9af
diff --git a/com/destroystokyo/paper/entity/ai/VanillaGoal.java b/com/destroystokyo/paper/entity/ai/VanillaGoal.java
-index 069f2668f5229b0368b796e65eef1648fba0a097..9b991201a2f6cc9feccccf7f4e7bcded64117764 100644
+index 43f4deacef349502cbb207aafc4f9cb7a75177c5..6b692c24a62e2172116a6b9c371b1c0e2411c27e 100644
--- a/com/destroystokyo/paper/entity/ai/VanillaGoal.java
+++ b/com/destroystokyo/paper/entity/ai/VanillaGoal.java
@@ -442,6 +442,18 @@ public interface VanillaGoal extends Goal {
diff --git a/patches/server/0036-Fix-Make-log4j-compatible-with-future-release.patch b/patches/removed/server/0036-Fix-Make-log4j-compatible-with-future-release.patch
similarity index 100%
rename from patches/server/0036-Fix-Make-log4j-compatible-with-future-release.patch
rename to patches/removed/server/0036-Fix-Make-log4j-compatible-with-future-release.patch
diff --git a/patches/server/0053-LinearPurpur-Add-Linear-region-format.patch b/patches/removed/server/0053-LinearPurpur-Add-Linear-region-format.patch
similarity index 100%
rename from patches/server/0053-LinearPurpur-Add-Linear-region-format.patch
rename to patches/removed/server/0053-LinearPurpur-Add-Linear-region-format.patch
diff --git a/patches/server/0054-LinearPurpur-Just-remove-all-locks-on-region-files.patch b/patches/removed/server/0054-LinearPurpur-Just-remove-all-locks-on-region-files.patch
similarity index 100%
rename from patches/server/0054-LinearPurpur-Just-remove-all-locks-on-region-files.patch
rename to patches/removed/server/0054-LinearPurpur-Just-remove-all-locks-on-region-files.patch
diff --git a/patches/server/0065-Fix-MC-249136-lag-when-attempting-to-locate-a-buried.patch b/patches/removed/server/0065-Fix-MC-249136-lag-when-attempting-to-locate-a-buried.patch
similarity index 100%
rename from patches/server/0065-Fix-MC-249136-lag-when-attempting-to-locate-a-buried.patch
rename to patches/removed/server/0065-Fix-MC-249136-lag-when-attempting-to-locate-a-buried.patch
diff --git a/patches/server/0068-Fix-MC-172047.patch b/patches/removed/server/0068-Fix-MC-172047.patch
similarity index 100%
rename from patches/server/0068-Fix-MC-172047.patch
rename to patches/removed/server/0068-Fix-MC-172047.patch
diff --git a/patches/server/0075-Use-a-shadow-fork-that-supports-Java-21.patch b/patches/removed/server/0075-Use-a-shadow-fork-that-supports-Java-21.patch
similarity index 100%
rename from patches/server/0075-Use-a-shadow-fork-that-supports-Java-21.patch
rename to patches/removed/server/0075-Use-a-shadow-fork-that-supports-Java-21.patch
diff --git a/patches/server/0001-Rebrand.patch b/patches/server/0001-Rebrand.patch
index c8a24a1b..07858171 100644
--- a/patches/server/0001-Rebrand.patch
+++ b/patches/server/0001-Rebrand.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Rebrand
diff --git a/build.gradle.kts b/build.gradle.kts
-index c9784da0a87d61e80a41fb0358614053682e942b..960fe37a4cf0100b552401f835900c6d8b6af523 100644
+index e9b050f744391444714c8803835d78d0415f96ce..344b87ffcf53f21f8e1a25d1e35fa5246d37f99d 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
-@@ -15,7 +15,7 @@ val alsoShade: Configuration by configurations.creating
+@@ -14,7 +14,7 @@ val alsoShade: Configuration by configurations.creating
dependencies {
// Gale start - project setup
// Depend on own API
@@ -17,7 +17,7 @@ index c9784da0a87d61e80a41fb0358614053682e942b..960fe37a4cf0100b552401f835900c6d
// Depend on Paper MojangAPI
implementation("io.papermc.paper:paper-mojangapi:${project.version}") {
exclude("io.papermc.paper", "paper-api")
-@@ -88,7 +88,7 @@ tasks.jar {
+@@ -95,7 +95,7 @@ tasks.jar {
attributes(
"Main-Class" to "org.bukkit.craftbukkit.Main",
"Implementation-Title" to "CraftBukkit",
@@ -72,11 +72,26 @@ index e45e6b44b2a8f2cdae6e0048a812b92126aa17ca..b5f3f213da8a40d5184098af017c8e26
.variable(LineReader.HISTORY_FILE, java.nio.file.Paths.get(".console_history"))
.completer(new ConsoleCommandCompleter(this.server))
.option(LineReader.Option.COMPLETE_IN_WORD, true);
+diff --git a/src/main/java/net/minecraft/CrashReport.java b/src/main/java/net/minecraft/CrashReport.java
+index 4f3cc14d48690bb183d09bb7a5ba1e23e8a0c08a..d8ebcd1c94ce0f78e9d16c603a79a492263990fd 100644
+--- a/src/main/java/net/minecraft/CrashReport.java
++++ b/src/main/java/net/minecraft/CrashReport.java
+@@ -125,6 +125,10 @@ public class CrashReport {
+ StringBuilder stringbuilder = new StringBuilder();
+
+ stringbuilder.append("---- Minecraft Crash Report ----\n");
++ // Leaf start - Purpur
++ stringbuilder.append("// ");
++ stringbuilder.append("// DO NOT REPORT THIS TO PAPER OR GALE! REPORT TO LEAF INSTEAD!");
++ // Leaf end - Purpur
+ stringbuilder.append("// ");
+ stringbuilder.append(CrashReport.getErrorComment());
+ stringbuilder.append("\n\n");
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index fbdc65a01b04abae4c3770666c6a77e0e85be502..9e7119152664e785e23f08e3a702f0bc60d817a0 100644
+index a77d650fd3b58cc883f284e1d2e41459ae0a77cd..ff4603d4749afdd3ff388c4b5d02ae6620140d63 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
-@@ -940,7 +940,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop
Date: Wed, 12 Oct 2022 10:42:15 -0400
Subject: [PATCH] Leaf Config
-TODO - Dreeam: Add header comment, config hot-reload, world config
+TODO - Dreeam: Add header comment, world config
Co-authored-by: MrHua269
diff --git a/build.gradle.kts b/build.gradle.kts
-index 91a7a0b81bf2b800847b27de890855c312aecfcb..a3e03a735131513324babe930dbf642acbcb5365 100644
+index 344b87ffcf53f21f8e1a25d1e35fa5246d37f99d..34335e3c6aeee7c29ce968170ce4d7b6c9872149 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
-@@ -21,6 +21,9 @@ dependencies {
+@@ -20,6 +20,9 @@ dependencies {
exclude("io.papermc.paper", "paper-api")
}
// Gale end - project setup
@@ -22,14 +22,15 @@ index 91a7a0b81bf2b800847b27de890855c312aecfcb..a3e03a735131513324babe930dbf642a
implementation("org.jline:jline-terminal-jansi:3.21.0")
implementation("net.minecrell:terminalconsoleappender:1.3.0")
diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java
-index 465a7787f15c934b2cef1a58e4b18f1ae9b4cae7..0b090797eb873b703730559049937163f2db8ecb 100644
+index 76a1b31a55b1838dc80b796f997edaddbcaa755c..bbeb88843f210abdf1cafed11394380cfcab0e09 100644
--- a/src/main/java/net/minecraft/server/Main.java
+++ b/src/main/java/net/minecraft/server/Main.java
-@@ -121,6 +121,7 @@ public class Main {
+@@ -123,6 +123,8 @@ public class Main {
Bootstrap.bootStrap();
Bootstrap.validate();
Util.startTimerHackThread();
+ org.dreeam.leaf.config.LeafConfig.loadConfig(); // Leaf
++ org.dreeam.leaf.config.LeafConfig.setupLatch(); // Leaf
Path path1 = Paths.get("server.properties");
DedicatedServerSettings dedicatedserversettings = new DedicatedServerSettings(optionset); // CraftBukkit - CLI argument support
@@ -91,6 +92,20 @@ index 0000000000000000000000000000000000000000..f69663d0cfebcdb598ac808d06cb0695
+ return this.baseKeyName;
+ }
+}
+diff --git a/src/main/java/org/dreeam/leaf/config/HotReloadUnsupported.java b/src/main/java/org/dreeam/leaf/config/HotReloadUnsupported.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..f7ab1ff5f298ff1e5e16fe5396d1e9e62a55fdfb
+--- /dev/null
++++ b/src/main/java/org/dreeam/leaf/config/HotReloadUnsupported.java
+@@ -0,0 +1,8 @@
++package org.dreeam.leaf.config;
++
++import java.lang.annotation.Retention;
++import java.lang.annotation.RetentionPolicy;
++
++@Retention(RetentionPolicy.RUNTIME)
++public @interface HotReloadUnsupported {
++}
diff --git a/src/main/java/org/dreeam/leaf/config/IConfigModule.java b/src/main/java/org/dreeam/leaf/config/IConfigModule.java
new file mode 100644
index 0000000000000000000000000000000000000000..da1474fa0512e50bedc8dda787bf6a1214f1ce37
@@ -122,13 +137,14 @@ index 0000000000000000000000000000000000000000..da1474fa0512e50bedc8dda787bf6a12
+}
diff --git a/src/main/java/org/dreeam/leaf/config/LeafConfig.java b/src/main/java/org/dreeam/leaf/config/LeafConfig.java
new file mode 100644
-index 0000000000000000000000000000000000000000..a2acd60fc5e34c9e2807589d1d7fed490d5671ed
+index 0000000000000000000000000000000000000000..b20ad36bb89e5226d94928832fdbcce7e096d6e2
--- /dev/null
+++ b/src/main/java/org/dreeam/leaf/config/LeafConfig.java
-@@ -0,0 +1,193 @@
+@@ -0,0 +1,220 @@
+package org.dreeam.leaf.config;
+
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
++import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
@@ -141,11 +157,13 @@ index 0000000000000000000000000000000000000000..a2acd60fc5e34c9e2807589d1d7fed49
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
++import java.util.concurrent.CompletableFuture;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
++import org.bukkit.craftbukkit.scheduler.MinecraftInternalPlugin;
+
+public class LeafConfig {
+ public static final Logger LOGGER = LogManager.getLogger(LeafConfig.class.getName());
@@ -153,6 +171,30 @@ index 0000000000000000000000000000000000000000..a2acd60fc5e34c9e2807589d1d7fed49
+ private static final File baseConfigFile = new File(baseConfigFolder, "leaf_global_config.toml");
+ private static final Set allInstanced = new HashSet<>();
+ private static CommentedFileConfig configFileInstance;
++ public static boolean alreadyInited = false;
++ private static MinecraftInternalPlugin NULL_PLUGIN = new MinecraftInternalPlugin();
++
++ public static void setupLatch() {
++ alreadyInited = true;
++ }
++
++ public static void reload() {
++ dropAllInstanced();
++ try {
++ loadConfig();
++ } catch (Exception e) {
++ LOGGER.error(e);
++ }
++ }
++
++ @Contract(" -> new")
++ public static @NotNull CompletableFuture reloadAsync() {
++ return new CompletableFuture<>();
++ }
++
++ public static void dropAllInstanced() {
++ allInstanced.clear();
++ }
+
+ public static void loadConfig() throws IOException {
+ baseConfigFolder.mkdirs();
@@ -164,7 +206,7 @@ index 0000000000000000000000000000000000000000..a2acd60fc5e34c9e2807589d1d7fed49
+ configFileInstance = CommentedFileConfig.ofConcurrent(baseConfigFile);
+
+ configFileInstance.load();
-+ configFileInstance.getComment("""
++ configFileInstance.setComment("", """
+ Leaf Config
+ Github Repo: https://github.com/Winds-Studio/Leaf
+ Discord: dreeam___ | QQ: 2682173972"""); // Leaf TODO - need to fix
@@ -201,7 +243,7 @@ index 0000000000000000000000000000000000000000..a2acd60fc5e34c9e2807589d1d7fed49
+ for (Field field : fields) {
+ int modifiers = field.getModifiers();
+ if (Modifier.isStatic(modifiers) && !Modifier.isFinal(modifiers)) {
-+ boolean skipLoad = field.getAnnotation(DoNotLoad.class) != null;
++ boolean skipLoad = field.getAnnotation(DoNotLoad.class) != null || (alreadyInited && field.getAnnotation(HotReloadUnsupported.class) != null);
+ ConfigInfo configInfo = field.getAnnotation(ConfigInfo.class);
+
+ if (skipLoad || configInfo == null) {
diff --git a/patches/server/0003-Leaf-Config-legacy-converter.patch b/patches/server/0003-Leaf-Config-legacy-converter.patch
index 420f681d..69d5bb25 100644
--- a/patches/server/0003-Leaf-Config-legacy-converter.patch
+++ b/patches/server/0003-Leaf-Config-legacy-converter.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Leaf Config legacy converter
diff --git a/build.gradle.kts b/build.gradle.kts
-index 722e9b39f03b1f41dcf9cd791324e5b6be6d45e8..6fbaa00e7bf665bab2c54e7b4c3e68a5cf14533d 100644
+index 34335e3c6aeee7c29ce968170ce4d7b6c9872149..663d5bfd7c541a193a1636e6f6f8ae5b656b080b 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
-@@ -24,6 +24,13 @@ dependencies {
+@@ -23,6 +23,13 @@ dependencies {
implementation("com.electronwill.night-config:toml:3.6.7") // Leaf - Night config
@@ -17,27 +17,27 @@ index 722e9b39f03b1f41dcf9cd791324e5b6be6d45e8..6fbaa00e7bf665bab2c54e7b4c3e68a5
+ implementation("com.github.Carleslc.Simple-YAML:Simple-Yaml:1.8.4") {
+ exclude(group = "org.yaml", module = "snakeyaml")
+ }
-+ // Leaf end
++ // Leaf end - Legacy config
+
// Paper start
implementation("org.jline:jline-terminal-jansi:3.21.0")
implementation("net.minecrell:terminalconsoleappender:1.3.0")
diff --git a/src/main/java/org/dreeam/leaf/config/LeafConfig.java b/src/main/java/org/dreeam/leaf/config/LeafConfig.java
-index a2acd60fc5e34c9e2807589d1d7fed490d5671ed..b9351fbb5d003911d2fd554d4f1eb33fd1ada55d 100644
+index b20ad36bb89e5226d94928832fdbcce7e096d6e2..c8da60bfb123079e85dd2f4b1f8925513e018297 100644
--- a/src/main/java/org/dreeam/leaf/config/LeafConfig.java
+++ b/src/main/java/org/dreeam/leaf/config/LeafConfig.java
-@@ -21,7 +21,9 @@ import org.apache.logging.log4j.Logger;
+@@ -24,7 +24,9 @@ import org.bukkit.craftbukkit.scheduler.MinecraftInternalPlugin;
public class LeafConfig {
public static final Logger LOGGER = LogManager.getLogger(LeafConfig.class.getName());
- private static final File baseConfigFolder = new File("leaf_config");
-+ public static long beginTime;
-+ private static final File legacyConfig = new File("leaf.yml");
++ public static long beginTime; // Leaf legacy config convert timer
++ private static final File legacyConfig = new File("leaf.yml"); // Leaf legacy config
+ public static final File baseConfigFolder = new File("leaf_config");
private static final File baseConfigFile = new File(baseConfigFolder, "leaf_global_config.toml");
private static final Set allInstanced = new HashSet<>();
private static CommentedFileConfig configFileInstance;
-@@ -49,6 +51,7 @@ public class LeafConfig {
+@@ -76,6 +78,7 @@ public class LeafConfig {
}
configFileInstance.save();
@@ -45,7 +45,7 @@ index a2acd60fc5e34c9e2807589d1d7fed490d5671ed..b9351fbb5d003911d2fd554d4f1eb33f
}
private static void loadAllModules() throws IllegalAccessException {
-@@ -190,4 +193,21 @@ public class LeafConfig {
+@@ -217,4 +220,21 @@ public class LeafConfig {
}
}
}
diff --git a/patches/server/0004-Pufferfish-Utils.patch b/patches/server/0004-Pufferfish-Utils.patch
index ee082d52..a25bf0da 100644
--- a/patches/server/0004-Pufferfish-Utils.patch
+++ b/patches/server/0004-Pufferfish-Utils.patch
@@ -44,14 +44,15 @@ index 46954db7ecd35ac4018fdf476df7c8020d7ce6c8..1ad890a244bdf6df48a8db68cb43450e
super();
diff --git a/src/main/java/gg/pufferfish/pufferfish/PufferfishLogger.java b/src/main/java/gg/pufferfish/pufferfish/PufferfishLogger.java
new file mode 100644
-index 0000000000000000000000000000000000000000..53f2df00c6809618a9ee3d2ea72e85e8052fbcf1
+index 0000000000000000000000000000000000000000..53aab67aea0a28c004c6106aa775443c30457141
--- /dev/null
+++ b/src/main/java/gg/pufferfish/pufferfish/PufferfishLogger.java
-@@ -0,0 +1,16 @@
+@@ -0,0 +1,17 @@
+package gg.pufferfish.pufferfish;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
++
+import org.bukkit.Bukkit;
+
+public class PufferfishLogger extends Logger {
diff --git a/patches/server/0005-Pufferfish-Sentry.patch b/patches/server/0005-Pufferfish-Sentry.patch
index d31aae01..2c70260c 100644
--- a/patches/server/0005-Pufferfish-Sentry.patch
+++ b/patches/server/0005-Pufferfish-Sentry.patch
@@ -8,10 +8,10 @@ Original project: https://github.com/pufferfish-gg/Pufferfish
diff --git a/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java b/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java
new file mode 100644
-index 0000000000000000000000000000000000000000..9ce570ddf314deda7a9980ab607af110a05aee16
+index 0000000000000000000000000000000000000000..7ba5790b4e73827daf14f08069190a8e8052f081
--- /dev/null
+++ b/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java
-@@ -0,0 +1,137 @@
+@@ -0,0 +1,130 @@
+package gg.pufferfish.pufferfish.sentry;
+
+import com.google.common.reflect.TypeToken;
@@ -109,20 +109,13 @@ index 0000000000000000000000000000000000000000..9ce570ddf314deda7a9980ab607af110
+ }
+
+ private SentryLevel getLevel(Level level) {
-+ switch (level.getStandardLevel()) {
-+ case TRACE:
-+ case DEBUG:
-+ return SentryLevel.DEBUG;
-+ case WARN:
-+ return SentryLevel.WARNING;
-+ case ERROR:
-+ return SentryLevel.ERROR;
-+ case FATAL:
-+ return SentryLevel.FATAL;
-+ case INFO:
-+ default:
-+ return SentryLevel.INFO;
-+ }
++ return switch (level.getStandardLevel()) {
++ case TRACE, DEBUG -> SentryLevel.DEBUG;
++ case WARN -> SentryLevel.WARNING;
++ case ERROR -> SentryLevel.ERROR;
++ case FATAL -> SentryLevel.FATAL;
++ default -> SentryLevel.INFO;
++ };
+ }
+
+ private static class SentryFilter extends AbstractFilter {
diff --git a/patches/server/0006-Pufferfish-Optimize-mob-spawning.patch b/patches/server/0006-Pufferfish-Optimize-mob-spawning.patch
index 87964f63..939f1cc3 100644
--- a/patches/server/0006-Pufferfish-Optimize-mob-spawning.patch
+++ b/patches/server/0006-Pufferfish-Optimize-mob-spawning.patch
@@ -20,23 +20,23 @@ and, in my opinion, worth the low risk of minor mob-spawning-related
inconsistencies.
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 46a223d184bdc91058b90692df4002ed1da4516c..90eb43f08fe781aafe2f8ac7921bdf148178761b 100644
+index ff4603d4749afdd3ff388c4b5d02ae6620140d63..fffe9e1c307e83b0dcb6c40bf0820f9f9f5c4528 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
-@@ -297,6 +297,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) {
AtomicReference atomicreference = new AtomicReference();
Thread thread = new io.papermc.paper.util.TickThread(() -> { // Paper - rewrite chunk system
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
-index 2c8eb9294890955f71382ed3884874cc827bab5e..04406e7fcba1f399648a864d2961a30fb757f9f1 100644
+index c58b52acafdc43f41bcc786de56d3d75eb220678..01ebdd21c29651e53d8f649926564a4815be0a9d 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
-@@ -350,6 +350,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
+@@ -365,6 +365,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
DedicatedServer.LOGGER.info("JMX monitoring enabled");
}
@@ -45,10 +45,10 @@ index 2c8eb9294890955f71382ed3884874cc827bab5e..04406e7fcba1f399648a864d2961a30f
}
}
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 1a5f1c825598dbc05f446273632ed8c4a45ef43a..de511a1d43aa78ec79c12d78635175336f77b62c 100644
+index a2c5b824a3126f0c7970550f509db9407c66ee28..c8b898e8482f846641505531e8286d9d113c92f9 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -243,7 +243,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -246,7 +246,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// Paper end
// Paper start - optimise chunk tick iteration
public final it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet needsChangeBroadcasting = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>();
@@ -58,10 +58,10 @@ index 1a5f1c825598dbc05f446273632ed8c4a45ef43a..de511a1d43aa78ec79c12d7863517533
public ChunkMap(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor executor, BlockableEventLoop mainThreadExecutor, LightChunkGetter chunkProvider, ChunkGenerator chunkGenerator, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier persistentStateManagerFactory, int viewDistance, boolean dsync) {
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-index 68ad7cb06d85c428f3560f95ed46bca32187e729..6587ce30d88983cb42822e6ff3e012047d3ce16d 100644
+index 94689992b4d159ab996e00ae20afa8fef0e84db2..af4fe64e190e73dcc5f2495d0b533547d8f57f1d 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-@@ -76,6 +76,9 @@ public class ServerChunkCache extends ChunkSource {
+@@ -74,6 +74,9 @@ public class ServerChunkCache extends ChunkSource {
private final LevelChunk[] lastLoadedChunks = new LevelChunk[4 * 4];
// Paper end
@@ -71,7 +71,7 @@ index 68ad7cb06d85c428f3560f95ed46bca32187e729..6587ce30d88983cb42822e6ff3e01204
public ServerChunkCache(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor workerExecutor, ChunkGenerator chunkGenerator, int viewDistance, int simulationDistance, boolean dsync, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier persistentStateManagerFactory) {
this.level = world;
this.mainThreadProcessor = new ServerChunkCache.MainThreadExecutor(world);
-@@ -510,6 +513,7 @@ public class ServerChunkCache extends ChunkSource {
+@@ -508,6 +511,7 @@ public class ServerChunkCache extends ChunkSource {
// Paper start - Optional per player mob spawns
int naturalSpawnChunkCount = k;
if ((this.spawnFriendlies || this.spawnEnemies) && this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { // don't count mobs when animals and monsters are disabled
@@ -79,7 +79,7 @@ index 68ad7cb06d85c428f3560f95ed46bca32187e729..6587ce30d88983cb42822e6ff3e01204
// re-set mob counts
for (ServerPlayer player : this.level.players) {
// Paper start - per player mob spawning backoff
-@@ -524,17 +528,21 @@ public class ServerChunkCache extends ChunkSource {
+@@ -522,14 +526,18 @@ public class ServerChunkCache extends ChunkSource {
}
// Paper end - per player mob spawning backoff
}
@@ -100,12 +100,8 @@ index 68ad7cb06d85c428f3560f95ed46bca32187e729..6587ce30d88983cb42822e6ff3e01204
+ //this.lastSpawnState = spawnercreature_d; // Pufferfish - this is managed asynchronously
// Gale start - MultiPaper - skip unnecessary mob spawning computations
} else {
-- spawnercreature_d = null;
-+ lastSpawnState = null; // Leaf - Pufferfish - Optimize mob spawning
- }
- // Gale end - MultiPaper - skip unnecessary mob spawning computations
-
-@@ -624,8 +632,8 @@ public class ServerChunkCache extends ChunkSource {
+ spawnercreature_d = null;
+@@ -622,8 +630,8 @@ public class ServerChunkCache extends ChunkSource {
if (tick && chunk1.chunkStatus.isOrAfter(net.minecraft.server.level.FullChunkStatus.ENTITY_TICKING)) {
// Paper end - optimise chunk tick iteration
chunk1.incrementInhabitedTime(j);
@@ -116,7 +112,7 @@ index 68ad7cb06d85c428f3560f95ed46bca32187e729..6587ce30d88983cb42822e6ff3e01204
}
if (true || this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { // Paper - optimise chunk tick iteration
-@@ -668,6 +676,40 @@ public class ServerChunkCache extends ChunkSource {
+@@ -666,6 +674,40 @@ public class ServerChunkCache extends ChunkSource {
this.level.timings.broadcastChunkUpdates.stopTiming(); // Paper - timing
// Paper - optimise chunk tick iteration
}
diff --git a/patches/server/0007-Pufferfish-Dynamic-Activation-of-Brain.patch b/patches/server/0007-Pufferfish-Dynamic-Activation-of-Brain.patch
index 12b544c5..0eeda541 100644
--- a/patches/server/0007-Pufferfish-Dynamic-Activation-of-Brain.patch
+++ b/patches/server/0007-Pufferfish-Dynamic-Activation-of-Brain.patch
@@ -3,6 +3,8 @@ From: Paul Sauve
Date: Fri, 15 Jan 2021 19:05:01 -0600
Subject: [PATCH] Pufferfish: Dynamic Activation of Brain
+Dreeam TODO: waiting Paper dealing with the newGoalRate
+
Original license: GPL v3
Original project: https://github.com/pufferfish-gg/Pufferfish
@@ -30,10 +32,10 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index ab0ac738f3e3d231d8fbc663230892d3a5f07660..a26a756c35c77830a3407ae0dfbf8509141f30fa 100644
+index cf51f108753a19e3ab97a6df3e5cecaa4d39f293..cdcbd708b7ee74002428ca8a148d857912ce14ab 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -880,6 +880,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -886,6 +886,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
org.spigotmc.ActivationRange.activateEntities(this); // Spigot
this.timings.entityTick.startTiming(); // Spigot
this.entityTickList.forEach((entity) -> {
@@ -42,26 +44,23 @@ index ab0ac738f3e3d231d8fbc663230892d3a5f07660..a26a756c35c77830a3407ae0dfbf8509
if (false && this.shouldDiscardEntity(entity)) { // CraftBukkit - We prevent spawning in general, so this butchering is not needed
entity.discard();
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 7e84b05e8e4261dd36db725ae83dc0a1b48613fd..3b7a00ab7ad3c1b9ce8ce323154d67cbbfb724f9 100644
+index 615193fbe7574d4d1d9e24a48655931edc2a35d3..b2396234112460925bc4f308f463d16e92efe679 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
-@@ -504,6 +504,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
- }
- // Paper end - optimise entity tracking
+@@ -427,6 +427,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+ private UUID originWorld;
+ public boolean freezeLocked = false; // Paper - Freeze Tick Lock API
+ public boolean fixedPose = false; // Paper - Expand Pose API
++ public boolean activatedPriorityReset = false; // Pufferfish - DAB
++ public int activatedPriority = org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.maximumActivationPrio; // Pufferfish - DAB (golf score)
-+ // Pufferfish start
-+ public boolean activatedPriorityReset = false; // DAB
-+ public int activatedPriority = org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.maximumActivationPrio; // golf score
-+ // Pufferfish end
-+
- public float getBukkitYaw() {
- return this.yRot;
- }
+ public void setOrigin(@javax.annotation.Nonnull Location location) {
+ this.origin = location.toVector();
diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java
-index 09e8445a3f8c6b3ebc852a75a9a25b41a51ba659..d86c34111ede6a1454dde5e7223d7caf2ab39ef3 100644
+index a46bf73c608641bf1f00fd55242de71a0f2ee06e..58298a1f85f462abc4f07deffe913abb1bac9f99 100644
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
-@@ -305,6 +305,7 @@ public class EntityType implements FeatureElement, EntityTypeT
+@@ -316,6 +316,7 @@ public class EntityType implements FeatureElement, EntityTypeT
private final boolean canSpawnFarFromPlayer;
private final int clientTrackingRange;
private final int updateInterval;
@@ -70,10 +69,10 @@ index 09e8445a3f8c6b3ebc852a75a9a25b41a51ba659..d86c34111ede6a1454dde5e7223d7caf
private String descriptionId;
@Nullable
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
-index a676228a7f4d8d4b7e54a641c1df1f1b0d262f10..43beb25bb42f19832da83f6f7f022cb5c85830c1 100644
+index e0e7c35fa9c9395eec5b4504e250ee2d58f98e30..c9240785d65227b33f2b1cce28cb3de9d854ad8b 100644
--- a/src/main/java/net/minecraft/world/entity/Mob.java
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
-@@ -228,10 +228,10 @@ public abstract class Mob extends LivingEntity implements Targeting {
+@@ -242,10 +242,10 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
@Override
public void inactiveTick() {
super.inactiveTick();
@@ -86,8 +85,8 @@ index a676228a7f4d8d4b7e54a641c1df1f1b0d262f10..43beb25bb42f19832da83f6f7f022cb5
this.targetSelector.tick();
}
}
-@@ -906,10 +906,14 @@ public abstract class Mob extends LivingEntity implements Targeting {
- int i = this.level().getServer().getTickCount() + this.getId();
+@@ -963,10 +963,14 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
+ int i = this.tickCount + this.getId();
if (i % 2 != 0 && this.tickCount > 1) {
+ if (this.targetSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking
@@ -119,29 +118,30 @@ index 758f62416ca9c02351348ac0d41deeb4624abc0e..69130969c9a434ec2361e573c9a1ec9f
}
}
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
-index fc16161d352221be549760dcdd8c62dfba6a6798..011e04a06f4583722d97e4bc847bd8445910692a 100644
+index 8ac1a3b86bf0eee6a27985d6b9dbc98b6fedbb15..95d20cd10ef0b3da32a6168c5d4a9bc4abc63e22 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
-@@ -50,9 +50,12 @@ public class GoalSelector {
+@@ -39,9 +39,13 @@ public class GoalSelector {
}
// Paper start
- public boolean inactiveTick() {
+ public boolean inactiveTick(int tickRate, boolean inactive) { // Pufferfish start
+ if (inactive && !org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.enabled) tickRate = 4; // reset to Paper's
-+ tickRate = Math.min(tickRate, this.newGoalRate);
++ tickRate = Math.min(tickRate, 3); // Dreeam TODO - Waiting Paper
this.curRate++;
-- return this.curRate % this.newGoalRate == 0;
+- return this.curRate % 3 == 0; // TODO newGoalRate was already unused in 1.20.4, check if this is correct
++ //return this.curRate % 3 == 0; // TODO newGoalRate was already unused in 1.20.4, check if this is correct
+ return this.curRate % tickRate == 0;
+ // Pufferfish end
}
public boolean hasTasks() {
for (WrappedGoal task : this.availableGoals) {
diff --git a/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java b/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java
-index 26731a659fe3c40fc20135d473bacf105cc15300..c521ff04be40bfa892021f67acc1b324551fcd5e 100644
+index 29802fa506042c80bd1a03cf88f4ab326dfb94b5..34c1df5bd7655bfbcba3ae872a8eec621ace5835 100644
--- a/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java
+++ b/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java
-@@ -221,8 +221,10 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS
+@@ -215,8 +215,10 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS
return 0.4F;
}
@@ -153,10 +153,10 @@ index 26731a659fe3c40fc20135d473bacf105cc15300..c521ff04be40bfa892021f67acc1b324
AllayAi.updateActivity(this);
super.customServerAiStep();
diff --git a/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java b/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java
-index 207d41b91bc02d94c5b40799619f7314ef84e41d..d0c624a6a000c2a41e41d14dd785a7bf9612afe8 100644
+index 8a14e3c2bd2162e36634f532fa86a7fba0548541..d339e9c0b81a50d20048375bd8b4141618fc1d2a 100644
--- a/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java
+++ b/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java
-@@ -275,8 +275,10 @@ public class Axolotl extends Animal implements LerpingModel, VariantHolder {
- }
+@@ -181,8 +181,10 @@ public class Frog extends Animal implements VariantHolder> {
+ .ifPresent(this::setVariant);
}
+ private int behaviorTick = 0; // Pufferfish
@@ -183,10 +183,10 @@ index dfb1f7db2db231049cebf0283ab879618eddaba6..791791fa03c402998fa99b5da9e9f969
FrogAi.updateActivity(this);
super.customServerAiStep();
diff --git a/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java b/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java
-index 1ee12f16e7013521a288a3160dcc424c4e385204..257687004b03e17cf3f5c0ea4c4cfeb7f34033e4 100644
+index 53dbe9d296a89d23b19f2551b20b464731ee800e..40dad395aabb04c21ac26fadce823ce8b4f79b3a 100644
--- a/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java
+++ b/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java
-@@ -80,8 +80,10 @@ public class Tadpole extends AbstractFish {
+@@ -83,8 +83,10 @@ public class Tadpole extends AbstractFish {
return SoundEvents.TADPOLE_FLOP;
}
@@ -198,10 +198,10 @@ index 1ee12f16e7013521a288a3160dcc424c4e385204..257687004b03e17cf3f5c0ea4c4cfeb7
TadpoleAi.updateActivity(this);
super.customServerAiStep();
diff --git a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
-index c6ff7c756aff281e7de094c05749740370988fe5..d75178611f2c74af45e39c9e37770e2c56773b1d 100644
+index 55d2144af223a2813b784e6e249fe94f610ef079..1bf1e2714f210188202a97219765428f9cf2c956 100644
--- a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
+++ b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
-@@ -191,8 +191,10 @@ public class Goat extends Animal {
+@@ -190,8 +190,10 @@ public class Goat extends Animal {
return (Brain) super.getBrain(); // CraftBukkit - decompile error
}
@@ -213,10 +213,10 @@ index c6ff7c756aff281e7de094c05749740370988fe5..d75178611f2c74af45e39c9e37770e2c
GoatAi.updateActivity(this);
super.customServerAiStep();
diff --git a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java
-index 6b0f5aa9e49c7ff8784ae7a016c4403acf98ca1e..fde1a076d1a490cf7bdea7f89a8714b4661a0d7d 100644
+index 910c3df3e8232db8b7140c51df010f0a9bdcad68..837ae63b1621a4fabba4a44145279d5f95f57f6b 100644
--- a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java
+++ b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java
-@@ -155,8 +155,10 @@ public class Hoglin extends Animal implements Enemy, HoglinBase {
+@@ -153,8 +153,10 @@ public class Hoglin extends Animal implements Enemy, HoglinBase {
return (Brain)super.getBrain();
}
@@ -228,10 +228,10 @@ index 6b0f5aa9e49c7ff8784ae7a016c4403acf98ca1e..fde1a076d1a490cf7bdea7f89a8714b4
HoglinAi.updateActivity(this);
if (this.isConverting()) {
diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java
-index 104f3ed9230f6397bfe306b7fbfb9893b7c8e94d..2eeb23ce4125b2538e92e19bf73f55398d2dbfc0 100644
+index 74ffc0c8ac95590c39e86893bb4f270eb63efd49..5ea7cc29c2f9c4e2ee7741b4cead8ea78c296c5d 100644
--- a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java
+++ b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java
-@@ -300,8 +300,10 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento
+@@ -294,8 +294,10 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento
return !this.cannotHunt;
}
@@ -243,10 +243,10 @@ index 104f3ed9230f6397bfe306b7fbfb9893b7c8e94d..2eeb23ce4125b2538e92e19bf73f5539
PiglinAi.updateActivity(this);
super.customServerAiStep();
diff --git a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java
-index b73bccfcb1b94936f500926a06a28a6a134bbc33..5cad15c512919ce6b0cae9f45e9011dd66134622 100644
+index f41898080a0cce6e1c2d50c3a7f1a0d67df5605a..7350e339c673c3c59bc36843f03f86ab1ef5e925 100644
--- a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java
+++ b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java
-@@ -273,10 +273,12 @@ public class Warden extends Monster implements VibrationSystem {
+@@ -271,10 +271,12 @@ public class Warden extends Monster implements VibrationSystem {
}
@@ -260,7 +260,7 @@ index b73bccfcb1b94936f500926a06a28a6a134bbc33..5cad15c512919ce6b0cae9f45e9011dd
super.customServerAiStep();
if ((this.tickCount + this.getId()) % 120 == 0) {
diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java
-index d88cebe9a348ec99bff05c650d101c80cc38c747..34812d4ab115f31a6ad1cf8cbc345dda4339c075 100644
+index de41f5b57cb4220daf312cc8724cc32d3dd6f7a6..e32c928dc21def1df0f6d334405cff5dc8e999cd 100644
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
@@ -145,6 +145,8 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
diff --git a/patches/server/0008-Pufferfish-Throttle-goal-selector-during-inactive-ti.patch b/patches/server/0008-Pufferfish-Throttle-goal-selector-during-inactive-ti.patch
index aae6cf6a..198f55d8 100644
--- a/patches/server/0008-Pufferfish-Throttle-goal-selector-during-inactive-ti.patch
+++ b/patches/server/0008-Pufferfish-Throttle-goal-selector-during-inactive-ti.patch
@@ -7,10 +7,10 @@ Original license: GPL v3
Original project: https://github.com/pufferfish-gg/Pufferfish
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
-index 43beb25bb42f19832da83f6f7f022cb5c85830c1..1c729ea3e40b12ddb95294c666f1568bd69ce4c0 100644
+index c9240785d65227b33f2b1cce28cb3de9d854ad8b..ad08008a9d3f50bab1ae05603aab4cf3be8e2d54 100644
--- a/src/main/java/net/minecraft/world/entity/Mob.java
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
-@@ -224,11 +224,13 @@ public abstract class Mob extends LivingEntity implements Targeting {
+@@ -238,11 +238,13 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
return this.lookControl;
}
diff --git a/patches/server/0009-Pufferfish-Entity-TTL.patch b/patches/server/0009-Pufferfish-Entity-TTL.patch
index f62c375e..3645a43a 100644
--- a/patches/server/0009-Pufferfish-Entity-TTL.patch
+++ b/patches/server/0009-Pufferfish-Entity-TTL.patch
@@ -7,16 +7,16 @@ Original license: GPL v3
Original project: https://github.com/pufferfish-gg/Pufferfish
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 1482310673c2c2ac9180ea80a96c24d4094e11c9..f146fb4a599d36e0a9492936312e609cbbfed641 100644
+index b2396234112460925bc4f308f463d16e92efe679..9c20cead889a736aab17ef8ef1f3c932b0dd37f1 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
-@@ -827,6 +827,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
+@@ -868,6 +868,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
public void tick() {
+ // Pufferfish start - entity TTL
+ if (type != EntityType.PLAYER && type.ttl >= 0 && this.tickCount >= type.ttl) {
-+ discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); // Purpur
++ discard();
+ return;
+ }
+ // Pufferfish end - entity TTL
@@ -24,10 +24,10 @@ index 1482310673c2c2ac9180ea80a96c24d4094e11c9..f146fb4a599d36e0a9492936312e609c
}
diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java
-index d86c34111ede6a1454dde5e7223d7caf2ab39ef3..dc11683ee4d8a6b7a1c42bcae36dc6e8105cd994 100644
+index 58298a1f85f462abc4f07deffe913abb1bac9f99..e6edbe6177b168d85759bd9c414dc87ea8a394fe 100644
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
-@@ -306,6 +306,7 @@ public class EntityType implements FeatureElement, EntityTypeT
+@@ -317,6 +317,7 @@ public class EntityType implements FeatureElement, EntityTypeT
private final int clientTrackingRange;
private final int updateInterval;
public boolean dabEnabled = false; // Pufferfish
diff --git a/patches/server/0010-Purpur-Server-Changes.patch b/patches/server/0010-Purpur-Server-Changes.patch
index fd62f65e..76c8e771 100644
--- a/patches/server/0010-Purpur-Server-Changes.patch
+++ b/patches/server/0010-Purpur-Server-Changes.patch
@@ -1,41 +1,41 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Github Actions
-Date: Mon, 25 Sep 2023 03:15:20 +0000
+Date: Mon, 29 Apr 2024 09:05:40 +0000
Subject: [PATCH] Purpur Server Changes
TODO - Dreeam: Check TODOs in ServerGamePacketListenerImpl & Tadpole
+Fix-pufferfish-issues.patch
Original license: MIT
Original project: https://github.com/PurpurMC/Purpur
-Commit: 6b1ee98f813ee19f8046b3c528feeee61840a35b
+Commit: a90a4730d672968428e371f024c8317b64eba9af
Patches below are removed in this patch:
-Metrics change in Purpur-config-files.patch
-Brand change in Rebrand.patch
-some code in Fix-pufferfish-issues.patch
+Metrics changes in Purpur-config-files.patch
+Brand changes in Rebrand.patch
+Fix-pufferfish-issues.patch
Fix-decompile-errors.patch
Alternative-Keepalive-Handling.patch
Logger-settings-suppressing-pointless-logs.patch
+Add-log-suppression-for-LibraryLoader.patch
Fix-outdated-server-showing-in-ping-before-server-fu.patch
Fix-cow-rotation-when-shearing-mooshroom.patch
End-gateway-should-check-if-entity-can-use-portal.patch
Skip-events-if-there-s-no-listeners.patch
Add-5-second-tps-average-in-tps.patch
Arrows-should-not-reset-despawn-counter.patch
-Add-toggle-for-sand-duping-fix.patch
Halloween-options-and-optimizations.patch
MC-238526-Fix-spawner-not-spawning-water-animals-cor.patch
Remove-Timings.patch
Remove-Mojang-Profiler.patch
MC-121706-Fix-mobs-not-looking-up-and-down-when-stra.patch
-Fire-Immunity-API.patch
diff --git a/build.gradle.kts b/build.gradle.kts
-index a52369f6e9588568cb0e8ee45ce59bcb685cc502..0d72b6e0a9d9c12b7d4555aa85dcedde9123c5c1 100644
+index 663d5bfd7c541a193a1636e6f6f8ae5b656b080b..2e0bb52941718f4ae2600e293bbe4126d0889f40 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
-@@ -66,6 +66,12 @@ dependencies {
+@@ -63,6 +63,12 @@ dependencies {
runtimeOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.18")
runtimeOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.9.18")
@@ -46,9 +46,9 @@ index a52369f6e9588568cb0e8ee45ce59bcb685cc502..0d72b6e0a9d9c12b7d4555aa85dcedde
+ // Purpur end
+
testImplementation("io.github.classgraph:classgraph:4.8.47") // Paper - mob goal test
- testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")
+ testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
testImplementation("org.hamcrest:hamcrest:2.2")
-@@ -177,7 +183,7 @@ fun TaskContainer.registerRunTask(
+@@ -164,7 +170,7 @@ fun TaskContainer.registerRunTask(
name: String,
block: JavaExec.() -> Unit
): TaskProvider = register(name) {
@@ -148,8 +148,33 @@ index 0000000000000000000000000000000000000000..15a226e3854d731f7724025ea3459c8a
+ return new HighlightErrorConverter(formatters);
+ }
+}
+diff --git a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
+index 03f5ec3c4f8eac9cecfef0f257b90090aece5017..77ee490b58f60cfea946cca4e335882dd324bd47 100644
+--- a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
++++ b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
+@@ -4,6 +4,7 @@ import com.google.common.base.Charsets;
+ import com.google.common.io.Resources;
+ import com.google.gson.Gson;
+ import com.google.gson.JsonArray;
++import com.google.gson.JsonElement;
+ import com.google.gson.JsonObject;
+ import com.google.gson.JsonSyntaxException;
+ import org.galemc.gale.version.AbstractPaperVersionFetcher;
+@@ -44,11 +45,7 @@ public class PaperVersionFetcher extends AbstractPaperVersionFetcher {
+ Charsets.UTF_8
+ ).openBufferedStream()) {
+ JsonObject json = new Gson().fromJson(reader, JsonObject.class);
+- JsonArray builds = json.getAsJsonArray("builds");
+- int latest = StreamSupport.stream(builds.spliterator(), false)
+- .mapToInt(e -> e.getAsInt())
+- .max()
+- .getAsInt();
++ int latest = json.getAsJsonObject("builds").getAsJsonPrimitive("latest").getAsInt(); // Purpur
+ return latest - jenkinsBuild;
+ } catch (JsonSyntaxException ex) {
+ ex.printStackTrace();
diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java b/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java
-index 59699c59fdfc611177fdb3136f84ab539b17d9c9..4819c043e193603581598c91d44d407a08ecd5fb 100644
+index c72d6bccf7d72d08d388c65936a89c92261c7860..ee746753515c9cea8dd246f4f56e6781956726c1 100644
--- a/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java
+++ b/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java
@@ -137,6 +137,10 @@ public class MobGoalHelper {
@@ -303,10 +328,10 @@ index a8e813ca89b033f061e695288b3383bdcf128531..1ab65af9359d19530bba7f985a604d2a
}
if (SysoutCatcher.NAG_INTERVAL > 0 || SysoutCatcher.NAG_TIMEOUT > 0) {
diff --git a/src/main/java/io/papermc/paper/plugin/PluginInitializerManager.java b/src/main/java/io/papermc/paper/plugin/PluginInitializerManager.java
-index 708e5bb9bbf0476fcc2c4b92c6830b094703b43e..6141f716b15ad47ac2ac4c9ce92a3897b3ad8807 100644
+index 6f14cb9a73faa1d0ae2939d08809d9f6c2a99e1d..4e98745670032038f7b4f8e1adabc1e00e7f15bf 100644
--- a/src/main/java/io/papermc/paper/plugin/PluginInitializerManager.java
+++ b/src/main/java/io/papermc/paper/plugin/PluginInitializerManager.java
-@@ -104,6 +104,7 @@ public class PluginInitializerManager {
+@@ -112,6 +112,7 @@ public class PluginInitializerManager {
@SuppressWarnings("unchecked")
java.util.List files = ((java.util.List) optionSet.valuesOf("add-plugin")).stream().map(File::toPath).toList();
io.papermc.paper.plugin.util.EntrypointUtil.registerProvidersFromSource(io.papermc.paper.plugin.provider.source.PluginFlagProviderSource.INSTANCE, files);
@@ -436,7 +461,7 @@ index 0000000000000000000000000000000000000000..cb78dac8e072b5cb3c6e52e17c9ecdf7
+ }
+}
diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java
-index f341813e9713e39bfe142ca34b751de3d8efd25b..546ff84046856ecfe0f2a07d3ba3f886f8df4dca 100644
+index e6c7f62ed379a78645933670299e4fcda8540ed1..7475aaac2673729091eabc741c8ebb561aeec8f1 100644
--- a/src/main/java/net/minecraft/commands/CommandSourceStack.java
+++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java
@@ -230,6 +230,19 @@ public class CommandSourceStack implements ExecutionCommandSource entityType, Direction direction) {
+ }
diff --git a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java
-index 8d65cdb013706a932c2c73231108b2810b99e1c7..5b1938fc849db743e65cd7eed0f83ba059b9525e 100644
+index a024c697a65bbab27408da1d6a75e531d9719b47..e4fab82b369f2c2ea0d8c8acd814d06140d551fc 100644
--- a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java
+++ b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java
-@@ -104,7 +104,7 @@ public class ShearsDispenseItemBehavior extends OptionalDispenseItemBehavior {
+@@ -105,7 +105,7 @@ public class ShearsDispenseItemBehavior extends OptionalDispenseItemBehavior {
if (ishearable.readyForShearing()) {
// CraftBukkit start
// Paper start - Add drops to shear events
- org.bukkit.event.block.BlockShearEntityEvent event = CraftEventFactory.callBlockShearEntityEvent(entityliving, bukkitBlock, craftItem, ishearable.generateDefaultDrops());
-+ org.bukkit.event.block.BlockShearEntityEvent event = CraftEventFactory.callBlockShearEntityEvent(entityliving, bukkitBlock, craftItem, ishearable.generateDefaultDrops(net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.MOB_LOOTING, CraftItemStack.asNMSCopy(craftItem)))); // Purpur
++ org.bukkit.event.block.BlockShearEntityEvent event = CraftEventFactory.callBlockShearEntityEvent(entityliving, bukkitBlock, craftItem, ishearable.generateDefaultDrops(net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.LOOTING, CraftItemStack.asNMSCopy(craftItem)))); // Purpur
if (event.isCancelled()) {
// Paper end - Add drops to shear events
continue;
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
-index 63b303a68edd7d39f85c8cb56760b2bf46dcb67a..9e5a7fb07edbdf234bddcab13afd3dde8c43197b 100644
+index 6da6a7befa2dc8988900abee03d24ba894939932..8c9e214f6d77b3118750f63398a5f3881989cb42 100644
--- a/src/main/java/net/minecraft/network/Connection.java
+++ b/src/main/java/net/minecraft/network/Connection.java
-@@ -571,11 +571,20 @@ public class Connection extends SimpleChannelInboundHandler> {
+@@ -608,11 +608,20 @@ public class Connection extends SimpleChannelInboundHandler> {
private static final int MAX_PER_TICK = io.papermc.paper.configuration.GlobalConfiguration.get().misc.maxJoinsPerTick; // Paper - Buffer joins to world
private static int joinAttemptsThisTick; // Paper - Buffer joins to world
private static int currTick; // Paper - Buffer joins to world
@@ -657,44 +681,13 @@ index 63b303a68edd7d39f85c8cb56760b2bf46dcb67a..9e5a7fb07edbdf234bddcab13afd3dde
Connection.joinAttemptsThisTick = 0;
}
// Paper end - Buffer joins to world
-diff --git a/src/main/java/net/minecraft/network/FriendlyByteBuf.java b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
-index b863249ff7e13cf4939c8961601f0564c62fd661..bdcfd80f937c34956911373905d66424bbff8e1d 100644
---- a/src/main/java/net/minecraft/network/FriendlyByteBuf.java
-+++ b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
-@@ -95,6 +95,8 @@ public class FriendlyByteBuf extends ByteBuf {
- private static final int MAX_PUBLIC_KEY_LENGTH = 512;
- private static final Gson GSON = new Gson();
-
-+ public static boolean hasItemSerializeEvent = false; // Purpur
-+
- public FriendlyByteBuf(ByteBuf parent) {
- this.source = parent;
- }
-@@ -640,6 +642,17 @@ public class FriendlyByteBuf extends ByteBuf {
- this.writeBoolean(false);
- } else {
- this.writeBoolean(true);
-+ // Purpur start
-+ if (hasItemSerializeEvent) {
-+ var event = new org.purpurmc.purpur.event.packet.NetworkItemSerializeEvent(stack.asBukkitCopy());
-+ event.callEvent();
-+ ItemStack newStack = ItemStack.fromBukkitCopy(event.getItemStack());
-+ if (org.purpurmc.purpur.PurpurConfig.fixNetworkSerializedItemsInCreative && !ItemStack.matches(stack, newStack)) {
-+ stack.save(newStack.getOrCreateTagElement("Purpur.OriginalItem"));
-+ }
-+ stack = newStack;
-+ }
-+ // Purpur end
- Item item = stack.getItem();
-
- this.writeId(BuiltInRegistries.ITEM, item);
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetTimePacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetTimePacket.java
-index 9ec6145fe04ec64bbee8ec6a837719caebdbc6f5..358d610ad020cada1bb83e393deeeaaec05a2791 100644
+index 76ef195a5074006b009acd9cc1744667c6aecbb9..659577549e132754281df76a7a1bfd884443c56a 100644
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetTimePacket.java
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetTimePacket.java
-@@ -5,7 +5,7 @@ import net.minecraft.network.protocol.Packet;
-
- public class ClientboundSetTimePacket implements Packet {
+@@ -10,7 +10,7 @@ public class ClientboundSetTimePacket implements Packet processQueue = new java.util.concurrent.ConcurrentLinkedQueue();
public int autosavePeriod;
public Commands vanillaCommandDispatcher;
-@@ -286,12 +287,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Purpur
- Iterator iterator = this.getAllLevels().iterator(); // Paper - Throw exception on world create while being ticked; move down
- while (iterator.hasNext()) {
- ServerLevel worldserver = (ServerLevel) iterator.next();
- worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - BlockPhysicsEvent
+@@ -1746,6 +1766,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - Add EntityMoveEvent
-+ worldserver.hasRidableMoveEvent = org.purpurmc.purpur.event.entity.RidableMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Purpur
net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - Perf: Optimize Hoppers
worldserver.updateLagCompensationTick(); // Paper - lag compensation
++ worldserver.hasRidableMoveEvent = org.purpurmc.purpur.event.entity.RidableMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Purpur
+ /* Drop global time updates
+ if (this.tickCount % 20 == 0) {
diff --git a/src/main/java/net/minecraft/server/PlayerAdvancements.java b/src/main/java/net/minecraft/server/PlayerAdvancements.java
-index b954c85f4aaf58f36fbeee67691a18b03c398767..b7c6717efcefe4efae3fd69ebaa3697bfd3dc9c8 100644
+index e3c6e5cf297d32c62bc6bb9f8682a665e98470a1..2d3f733c70ff63f7d0d272b205496ad1e0811e3d 100644
--- a/src/main/java/net/minecraft/server/PlayerAdvancements.java
+++ b/src/main/java/net/minecraft/server/PlayerAdvancements.java
@@ -250,6 +250,7 @@ public class PlayerAdvancements {
@@ -837,7 +807,7 @@ index b954c85f4aaf58f36fbeee67691a18b03c398767..b7c6717efcefe4efae3fd69ebaa3697b
// Paper end
}
diff --git a/src/main/java/net/minecraft/server/commands/EnchantCommand.java b/src/main/java/net/minecraft/server/commands/EnchantCommand.java
-index 15bfe2e58d16864af29b04c17181ebf45fa21eba..f2e6b3a2b9502ba1652bd0debd4d8d0c84dc9c41 100644
+index 84f1ba6275f04624f46ccd772924b5e075e7b205..bfb455fb74f0a9645212f90acb54f68d1c7d9772 100644
--- a/src/main/java/net/minecraft/server/commands/EnchantCommand.java
+++ b/src/main/java/net/minecraft/server/commands/EnchantCommand.java
@@ -70,7 +70,7 @@ public class EnchantCommand {
@@ -853,8 +823,8 @@ index 15bfe2e58d16864af29b04c17181ebf45fa21eba..f2e6b3a2b9502ba1652bd0debd4d8d0c
ItemStack itemStack = livingEntity.getMainHandItem();
if (!itemStack.isEmpty()) {
if (enchantment2.canEnchant(itemStack)
-- && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantments(itemStack).keySet(), enchantment2)) {
-+ && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantments(itemStack).keySet(), enchantment2) || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchantCommand && !itemStack.hasEnchantment(enchantment2))) { // Purpur
+- && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(itemStack).keySet(), enchantment2)) {
++ && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(itemStack).keySet(), enchantment2) || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchantCommand && !itemStack.hasEnchantment(enchantment2))) { // Purpur
itemStack.enchant(enchantment2, level);
i++;
} else if (targets.size() == 1) {
@@ -882,22 +852,22 @@ index d1da3600dc07107309b20ebe6e7c0c4da0e8de76..244b4719c689f153fa36381a60acc280
for (ServerPlayer serverPlayer : targets) {
diff --git a/src/main/java/net/minecraft/server/commands/GiveCommand.java b/src/main/java/net/minecraft/server/commands/GiveCommand.java
-index 1b459a8ee8a6bc039e742d65796bc76660a1c765..599172b994d75484f7c7e0ce6d3d3d771c1c44d0 100644
+index 47355158e5e762540a10dc67b23092a0fc53bce3..9f1c8a62bda242781a0966fa2fc01534261423c7 100644
--- a/src/main/java/net/minecraft/server/commands/GiveCommand.java
+++ b/src/main/java/net/minecraft/server/commands/GiveCommand.java
-@@ -59,6 +59,7 @@ public class GiveCommand {
+@@ -92,6 +92,7 @@ public class GiveCommand {
boolean flag = entityplayer.getInventory().add(itemstack1);
ItemEntity entityitem;
+ if (org.purpurmc.purpur.PurpurConfig.disableGiveCommandDrops) continue; // Purpur - add config option for toggling give command dropping
if (flag && itemstack1.isEmpty()) {
- itemstack1.setCount(1);
- entityitem = entityplayer.drop(itemstack1, false, false, false); // CraftBukkit - SPIGOT-2942: Add boolean to call event
+ entityitem = entityplayer.drop(itemstack, false, false, false); // CraftBukkit - SPIGOT-2942: Add boolean to call event
+ if (entityitem != null) {
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
-index 04406e7fcba1f399648a864d2961a30fb757f9f1..2d8676336d0bc4cb858e9ed3d7601173a33c0adf 100644
+index 01ebdd21c29651e53d8f649926564a4815be0a9d..615a9dfe30d51bf0aeaec301e2c5a2c7fd98c5d2 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
-@@ -98,6 +98,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
+@@ -109,6 +109,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
return;
}
// Paper start - Use TerminalConsoleAppender
@@ -905,7 +875,7 @@ index 04406e7fcba1f399648a864d2961a30fb757f9f1..2d8676336d0bc4cb858e9ed3d7601173
new com.destroystokyo.paper.console.PaperConsole(DedicatedServer.this).start();
/*
jline.console.ConsoleReader bufferedreader = DedicatedServer.this.reader;
-@@ -223,6 +224,15 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
+@@ -236,6 +237,15 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command
GaleCommands.registerCommands(this); // Gale - Gale commands - register commands
com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Paper - start metrics
@@ -921,7 +891,7 @@ index 04406e7fcba1f399648a864d2961a30fb757f9f1..2d8676336d0bc4cb858e9ed3d7601173
com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - load version history now
io.papermc.paper.brigadier.PaperBrigadierProviderImpl.INSTANCE.getClass(); // Paper - init PaperBrigadierProvider
-@@ -279,6 +289,30 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
+@@ -292,6 +302,30 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
if (true) throw new IllegalStateException("Failed to bind to port", ioexception); // Paper - Propagate failed to bind to port error
return false;
}
@@ -952,7 +922,7 @@ index 04406e7fcba1f399648a864d2961a30fb757f9f1..2d8676336d0bc4cb858e9ed3d7601173
// CraftBukkit start
// this.setPlayerList(new DedicatedPlayerList(this, this.registries(), this.playerDataStorage)); // Spigot - moved up
-@@ -351,6 +385,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
+@@ -366,6 +400,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
}
if (org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled) mobSpawnExecutor.start(); // Pufferfish
@@ -962,10 +932,10 @@ index 04406e7fcba1f399648a864d2961a30fb757f9f1..2d8676336d0bc4cb858e9ed3d7601173
}
}
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java
-index aa46e6e22998c62c89a56fbcabc13fdf58dd7dba..ee22ca05dccba4914d32125586299c1b7433a532 100644
+index 4323ffee716380bd67eb04a4a7bb62bc4ba2f7df..307a7596024528ad194eb01d6468aff1f5fe02cf 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java
-@@ -57,6 +57,7 @@ public class DedicatedServerProperties extends Settings> trackedDataValues;
// CraftBukkit start
- private final Set trackedPlayers;
-+ public final Set trackedPlayers; // Purpur - package -> public
++ public final Set trackedPlayers; // Purpur - private -> public
public ServerEntity(ServerLevel worldserver, Entity entity, int i, boolean flag, Consumer> consumer, Set trackedPlayers) {
this.trackedPlayers = trackedPlayers;
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba120824a80ab1 100644
+index cdcbd708b7ee74002428ca8a148d857912ce14ab..bda8c6af98945d3e5fa671b9b3bc016d7b384dc3 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -214,6 +214,8 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -219,6 +219,8 @@ public class ServerLevel extends Level implements WorldGenLevel {
private final StructureManager structureManager;
private final StructureCheck structureCheck;
private final boolean tickTime;
@@ -1136,7 +1106,7 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208
private final RandomSequences randomSequences;
public long lastMidTickExecuteFailure; // Paper - execute chunk tasks mid tick
-@@ -223,6 +225,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -228,6 +230,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
public boolean hasPhysicsEvent = true; // Paper - BlockPhysicsEvent
public boolean hasEntityMoveEvent; // Paper - Add EntityMoveEvent
private final alternate.current.wire.WireHandler wireHandler = new alternate.current.wire.WireHandler(this); // Paper - optimize redstone (Alternate Current)
@@ -1144,7 +1114,7 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208
public LevelChunk getChunkIfLoaded(int x, int z) {
return this.chunkSource.getChunkAtIfLoadedImmediately(x, z); // Paper - Use getChunkIfLoadedImmediately
-@@ -708,7 +711,24 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -714,7 +717,24 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.dragonParts = new Int2ObjectOpenHashMap();
this.tickTime = flag1;
this.server = minecraftserver;
@@ -1170,7 +1140,7 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208
this.serverLevelData = iworlddataserver;
ChunkGenerator chunkgenerator = worlddimension.generator();
// CraftBukkit start
-@@ -770,6 +790,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -776,6 +796,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.chunkTaskScheduler = new io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler(this, io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.workerThreads); // Paper - rewrite chunk system
this.entityLookup = new io.papermc.paper.chunk.system.entity.EntityLookup(this, new EntityCallbacks()); // Paper - rewrite chunk system
@@ -1178,7 +1148,7 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208
}
// Paper start
-@@ -816,7 +837,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -822,7 +843,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
int i = this.getGameRules().getInt(GameRules.RULE_PLAYERS_SLEEPING_PERCENTAGE);
long j;
@@ -1187,16 +1157,7 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208
// CraftBukkit start
j = this.levelData.getDayTime() + 24000L;
TimeSkipEvent event = new TimeSkipEvent(this.getWorld(), TimeSkipEvent.SkipReason.NIGHT_SKIP, (j - j % 24000L) - this.getDayTime());
-@@ -907,7 +928,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
- final String msg = String.format("Entity threw exception at %s:%s,%s,%s", entity.level().getWorld().getName(), entity.getX(), entity.getY(), entity.getZ());
- MinecraftServer.LOGGER.error(msg, throwable);
- getCraftServer().getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerInternalException(msg, throwable)));
-- entity.discard();
-+ entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); // Purpur
- // Paper end
- }
- // Gale end - Airplane - remove lambda from ticking guard - copied from guardEntityTick
-@@ -938,6 +959,13 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -944,6 +965,13 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.serverLevelData.setGameTime(i);
this.serverLevelData.getScheduledEvents().tick(this.server, i);
if (this.levelData.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)) {
@@ -1210,7 +1171,7 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208
this.setDayTime(this.levelData.getDayTime() + 1L);
}
-@@ -946,8 +974,22 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -952,8 +980,22 @@ public class ServerLevel extends Level implements WorldGenLevel {
public void setDayTime(long timeOfDay) {
this.serverLevelData.setDayTime(timeOfDay);
@@ -1233,7 +1194,7 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208
public void tickCustomSpawners(boolean spawnMonsters, boolean spawnAnimals) {
Iterator iterator = this.customSpawners.iterator();
-@@ -990,10 +1032,18 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -996,10 +1038,18 @@ public class ServerLevel extends Level implements WorldGenLevel {
boolean flag1 = this.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && this.random.nextDouble() < (double) difficultydamagescaler.getEffectiveDifficulty() * this.paperConfig().entities.spawning.skeletonHorseThunderSpawnChance.or(0.01D) && !this.getBlockState(blockposition.below()).is(Blocks.LIGHTNING_ROD); // Paper - Configurable spawn chances for skeleton horses
if (flag1) {
@@ -1254,7 +1215,7 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208
entityhorseskeleton.setAge(0);
entityhorseskeleton.setPos((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ());
this.addFreshEntity(entityhorseskeleton, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); // CraftBukkit
-@@ -1113,7 +1163,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1119,7 +1169,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
return holder.is(PoiTypes.LIGHTNING_ROD);
}, (blockposition1) -> {
return blockposition1.getY() == this.getHeight(Heightmap.Types.WORLD_SURFACE, blockposition1.getX(), blockposition1.getZ()) - 1;
@@ -1263,7 +1224,7 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208
return optional.map((blockposition1) -> {
return blockposition1.above(1);
-@@ -1162,11 +1212,27 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1168,11 +1218,27 @@ public class ServerLevel extends Level implements WorldGenLevel {
if (this.canSleepThroughNights()) {
if (!this.getServer().isSingleplayer() || this.getServer().isPublished()) {
int i = this.getGameRules().getInt(GameRules.RULE_PLAYERS_SLEEPING_PERCENTAGE);
@@ -1292,7 +1253,7 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208
ichatmutablecomponent = Component.translatable("sleep.players_sleeping", this.sleepStatus.amountSleeping(), this.sleepStatus.sleepersNeeded(i));
}
-@@ -1306,6 +1372,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1312,6 +1378,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
@VisibleForTesting
public void resetWeatherCycle() {
// CraftBukkit start
@@ -1300,7 +1261,7 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208
this.serverLevelData.setRaining(false, org.bukkit.event.weather.WeatherChangeEvent.Cause.SLEEP); // Paper - Add cause to Weather/ThunderChangeEvents
// If we stop due to everyone sleeping we should reset the weather duration to some other random value.
// Not that everyone ever manages to get the whole server to sleep at the same time....
-@@ -1313,6 +1380,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1319,6 +1386,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.serverLevelData.setRainTime(0);
}
// CraftBukkit end
@@ -1308,7 +1269,7 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208
this.serverLevelData.setThundering(false, org.bukkit.event.weather.ThunderChangeEvent.Cause.SLEEP); // Paper - Add cause to Weather/ThunderChangeEvents
// CraftBukkit start
// If we stop due to everyone sleeping we should reset the weather duration to some other random value.
-@@ -2820,7 +2888,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -2771,7 +2839,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
// Spigot Start
if (entity.getBukkitEntity() instanceof org.bukkit.inventory.InventoryHolder && (!(entity instanceof ServerPlayer) || entity.getRemovalReason() != Entity.RemovalReason.KILLED)) { // SPIGOT-6876: closeInventory clears death message
// Paper start - Fix merchant inventory not closing on entity removal
@@ -1318,10 +1279,10 @@ index a26a756c35c77830a3407ae0dfbf8509141f30fa..9eb2bc23a2e7dce3594d67ec97ba1208
}
// Paper end - Fix merchant inventory not closing on entity removal
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 172315c2a965b82773dff797d4667d2f80ec8c7a..82aa92a106f844578959158ce1518eb7d0766951 100644
+index f4829e31111bb640901e8143ed3afa4de3e28b7d..ada4956a0b204cb098e90979aff14db32455f481 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -282,6 +282,10 @@ public class ServerPlayer extends Player {
+@@ -299,6 +299,10 @@ public class ServerPlayer extends Player {
public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent
public @Nullable String clientBrandName = null; // Paper - Brand support
public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event
@@ -1332,19 +1293,19 @@ index 172315c2a965b82773dff797d4667d2f80ec8c7a..82aa92a106f844578959158ce1518eb7
// Paper start - replace player chunk loader
private final java.util.concurrent.atomic.AtomicReference viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1));
-@@ -569,6 +573,9 @@ public class ServerPlayer extends Player {
- }
+@@ -609,6 +613,9 @@ public class ServerPlayer extends Player {
+ });
}
-+ if (nbt.contains("Purpur.RamBar")) { this.ramBar = nbt.getBoolean("Purpur.RamBar"); } // Purpur
+ if (nbt.contains("Purpur.TPSBar")) { this.tpsBar = nbt.getBoolean("Purpur.TPSBar"); } // Purpur
+ if (nbt.contains("Purpur.CompassBar")) { this.compassBar = nbt.getBoolean("Purpur.CompassBar"); } // Purpur
++ if (nbt.contains("Purpur.RamBar")) { this.ramBar = nbt.getBoolean("Purpur.RamBar"); } // Purpur
}
@Override
-@@ -635,6 +642,9 @@ public class ServerPlayer extends Player {
+@@ -685,6 +692,9 @@ public class ServerPlayer extends Player {
+ });
}
- this.getBukkitEntity().setExtraData(nbt); // CraftBukkit
+ nbt.putBoolean("Purpur.RamBar", this.ramBar); // Purpur
+ nbt.putBoolean("Purpur.TPSBar", this.tpsBar); // Purpur
@@ -1352,9 +1313,9 @@ index 172315c2a965b82773dff797d4667d2f80ec8c7a..82aa92a106f844578959158ce1518eb7
}
// CraftBukkit start - World fallback code, either respawn location or global spawn
-@@ -763,6 +773,15 @@ public class ServerPlayer extends Player {
- this.trackStartFallingPosition();
+@@ -814,6 +824,15 @@ public class ServerPlayer extends Player {
this.trackEnteredOrExitedLavaOnVehicle();
+ this.updatePlayerAttributes();
this.advancements.flushDirty(this);
+
+ // Purpur start
@@ -1367,8 +1328,8 @@ index 172315c2a965b82773dff797d4667d2f80ec8c7a..82aa92a106f844578959158ce1518eb7
+ // Purpur end
}
- public void doTick() {
-@@ -1000,6 +1019,7 @@ public class ServerPlayer extends Player {
+ private void updatePlayerAttributes() {
+@@ -1077,6 +1096,7 @@ public class ServerPlayer extends Player {
}));
PlayerTeam scoreboardteam = this.getTeam();
@@ -1376,7 +1337,7 @@ index 172315c2a965b82773dff797d4667d2f80ec8c7a..82aa92a106f844578959158ce1518eb7
if (scoreboardteam != null && scoreboardteam.getDeathMessageVisibility() != Team.Visibility.ALWAYS) {
if (scoreboardteam.getDeathMessageVisibility() == Team.Visibility.HIDE_FOR_OTHER_TEAMS) {
this.server.getPlayerList().broadcastSystemToTeam(this, ichatbasecomponent);
-@@ -1103,6 +1123,16 @@ public class ServerPlayer extends Player {
+@@ -1180,6 +1200,16 @@ public class ServerPlayer extends Player {
if (this.isInvulnerableTo(source)) {
return false;
} else {
@@ -1393,7 +1354,7 @@ index 172315c2a965b82773dff797d4667d2f80ec8c7a..82aa92a106f844578959158ce1518eb7
boolean flag = this.server.isDedicatedServer() && this.isPvpAllowed() && source.is(DamageTypeTags.IS_FALL);
if (!flag && this.spawnInvulnerableTime > 0 && !source.is(DamageTypeTags.BYPASSES_INVULNERABILITY)) {
-@@ -1246,6 +1276,7 @@ public class ServerPlayer extends Player {
+@@ -1323,6 +1353,7 @@ public class ServerPlayer extends Player {
playerlist.sendPlayerPermissionLevel(this);
worldserver1.removePlayerImmediately(this, Entity.RemovalReason.CHANGED_DIMENSION);
this.unsetRemoved();
@@ -1401,7 +1362,7 @@ index 172315c2a965b82773dff797d4667d2f80ec8c7a..82aa92a106f844578959158ce1518eb7
// CraftBukkit end
this.setServerLevel(worldserver);
-@@ -1401,7 +1432,7 @@ public class ServerPlayer extends Player {
+@@ -1478,7 +1509,7 @@ public class ServerPlayer extends Player {
return entitymonster.isPreventingPlayerRest(this);
});
@@ -1410,7 +1371,7 @@ index 172315c2a965b82773dff797d4667d2f80ec8c7a..82aa92a106f844578959158ce1518eb7
return Either.left(Player.BedSleepingProblem.NOT_SAFE);
}
}
-@@ -1441,7 +1472,19 @@ public class ServerPlayer extends Player {
+@@ -1518,7 +1549,19 @@ public class ServerPlayer extends Player {
});
if (!this.serverLevel().canSleepThroughNights()) {
@@ -1431,15 +1392,7 @@ index 172315c2a965b82773dff797d4667d2f80ec8c7a..82aa92a106f844578959158ce1518eb7
}
((ServerLevel) this.level()).updateSleepingPlayerList();
-@@ -1546,6 +1589,7 @@ public class ServerPlayer extends Player {
-
- @Override
- public void openTextEdit(SignBlockEntity sign, boolean front) {
-+ if (level().purpurConfig.signAllowColors) this.connection.send(sign.getTranslatedUpdatePacket(textFilteringEnabled, front)); // Purpur
- this.connection.send(new ClientboundBlockUpdatePacket(this.level(), sign.getBlockPos()));
- this.connection.send(new ClientboundOpenSignEditorPacket(sign.getBlockPos(), front));
- }
-@@ -1880,6 +1924,26 @@ public class ServerPlayer extends Player {
+@@ -1974,6 +2017,26 @@ public class ServerPlayer extends Player {
this.lastSentExp = -1; // CraftBukkit - Added to reset
}
@@ -1466,7 +1419,7 @@ index 172315c2a965b82773dff797d4667d2f80ec8c7a..82aa92a106f844578959158ce1518eb7
@Override
public void displayClientMessage(Component message, boolean overlay) {
this.sendSystemMessage(message, overlay);
-@@ -2207,8 +2271,68 @@ public class ServerPlayer extends Player {
+@@ -2299,8 +2362,68 @@ public class ServerPlayer extends Player {
public void resetLastActionTime() {
this.lastActionTime = Util.getMillis();
@@ -1535,7 +1488,7 @@ index 172315c2a965b82773dff797d4667d2f80ec8c7a..82aa92a106f844578959158ce1518eb7
public ServerStatsCounter getStats() {
return this.stats;
}
-@@ -2760,4 +2884,50 @@ public class ServerPlayer extends Player {
+@@ -2868,4 +2991,50 @@ public class ServerPlayer extends Player {
return (CraftPlayer) super.getBukkitEntity();
}
// CraftBukkit end
@@ -1587,10 +1540,10 @@ index 172315c2a965b82773dff797d4667d2f80ec8c7a..82aa92a106f844578959158ce1518eb7
+ // Purpur end
}
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
-index 840dc3c57dd60d5f16155fc0c6f8c9fea49685c9..8e87d799586103b8a743ebc0cfb8da7fca3c856a 100644
+index 5cedce1f432f6b809b25269242a16477682c824f..6d194797d8fe2cd6e5652d596f4bc66ffc3b6375 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
-@@ -397,6 +397,7 @@ public class ServerPlayerGameMode {
+@@ -400,6 +400,7 @@ public class ServerPlayerGameMode {
} else {capturedBlockEntity = true;} // Paper - Send block entities after destroy prediction
return false;
}
@@ -1598,24 +1551,24 @@ index 840dc3c57dd60d5f16155fc0c6f8c9fea49685c9..8e87d799586103b8a743ebc0cfb8da7f
}
// CraftBukkit end
-@@ -516,6 +517,7 @@ public class ServerPlayerGameMode {
+@@ -512,6 +513,7 @@ public class ServerPlayerGameMode {
public InteractionHand interactHand;
public ItemStack interactItemStack;
public InteractionResult useItemOn(ServerPlayer player, Level world, ItemStack stack, InteractionHand hand, BlockHitResult hitResult) {
+ if (shiftClickMended(stack)) return InteractionResult.SUCCESS; // Purpur
BlockPos blockposition = hitResult.getBlockPos();
BlockState iblockdata = world.getBlockState(blockposition);
- InteractionResult enuminteractionresult = InteractionResult.PASS;
-@@ -577,7 +579,7 @@ public class ServerPlayerGameMode {
- boolean flag1 = player.isSecondaryUseActive() && flag;
+ boolean cancelledBlock = false;
+@@ -573,7 +575,7 @@ public class ServerPlayerGameMode {
ItemStack itemstack1 = stack.copy();
+ InteractionResult enuminteractionresult;
- if (!flag1) {
+ if (!flag1 || (player.level().purpurConfig.composterBulkProcess && iblockdata.is(Blocks.COMPOSTER))) { // Purpur
- enuminteractionresult = iblockdata.use(world, player, hand, hitResult);
+ ItemInteractionResult iteminteractionresult = iblockdata.useItemOn(player.getItemInHand(hand), world, player, hand, hitResult);
- if (enuminteractionresult.consumesAction()) {
-@@ -618,4 +620,18 @@ public class ServerPlayerGameMode {
+ if (iteminteractionresult.consumesAction()) {
+@@ -621,4 +623,18 @@ public class ServerPlayerGameMode {
public void setLevel(ServerLevel world) {
this.level = world;
}
@@ -1635,10 +1588,10 @@ index 840dc3c57dd60d5f16155fc0c6f8c9fea49685c9..8e87d799586103b8a743ebc0cfb8da7f
+ // Purpur end
}
diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
-index d791c2f2facfc46d8664225c8b28f95f92df3413..61cd58a5bb3d228b29b9cc4db11be03d4c833223 100644
+index 83196467cf7152ba756f5f6d179ee17c00a4325f..5972362c1c968dbabb799824227c6ae3aef0b61e 100644
--- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
-@@ -64,6 +64,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
+@@ -86,6 +86,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
private static final long KEEPALIVE_LIMIT = KEEPALIVE_LIMIT_IN_SECONDS * 1000;
// Gale end - Purpur - send multiple keep-alive packets
protected static final ResourceLocation MINECRAFT_BRAND = new ResourceLocation("brand"); // Paper - Brand support
@@ -1646,7 +1599,7 @@ index d791c2f2facfc46d8664225c8b28f95f92df3413..61cd58a5bb3d228b29b9cc4db11be03d
public ServerCommonPacketListenerImpl(MinecraftServer minecraftserver, Connection networkmanager, CommonListenerCookie commonlistenercookie, ServerPlayer player) { // CraftBukkit
this.server = minecraftserver;
-@@ -157,6 +158,13 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
+@@ -189,6 +190,13 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t register custom payload", ex);
this.disconnect("Invalid payload REGISTER!", org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PAYLOAD); // Paper - kick event cause
}
@@ -1661,12 +1614,12 @@ index d791c2f2facfc46d8664225c8b28f95f92df3413..61cd58a5bb3d228b29b9cc4db11be03d
try {
String channels = payload.toString(com.google.common.base.Charsets.UTF_8);
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index 98b23811f5c1a00d3fd1d9881cd598ef06a897e3..27869528524ba32e007d4a674ece118c60dbdf45 100644
+index 5d02133cffb226ea7e48f517c1414ee7933b300f..45cf2c58fac237fe169a4be75c9a445a002389dd 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -335,6 +335,20 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
- }
- // Gale end - make max interaction distance configurable
+@@ -336,6 +336,20 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
+ private boolean justTeleported = false;
+ // CraftBukkit end
+ // Purpur start
+ private final com.google.common.cache.LoadingCache kickPermissionCache = com.google.common.cache.CacheBuilder.newBuilder()
@@ -1685,7 +1638,7 @@ index 98b23811f5c1a00d3fd1d9881cd598ef06a897e3..27869528524ba32e007d4a674ece118c
@Override
public void tick() {
if (this.ackBlockChangesUpTo > -1) {
-@@ -402,6 +416,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
+@@ -403,6 +417,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
}
if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) this.server.getPlayerIdleTimeout() * 1000L * 60L && !this.player.wonGame) { // Paper - Prevent AFK kick while watching end credits
@@ -1698,7 +1651,7 @@ index 98b23811f5c1a00d3fd1d9881cd598ef06a897e3..27869528524ba32e007d4a674ece118c
this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854
this.disconnect(Component.translatable("multiplayer.disconnect.idling"), org.bukkit.event.player.PlayerKickEvent.Cause.IDLING); // Paper - kick event cause
}
-@@ -649,10 +669,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
+@@ -662,6 +682,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
this.lastYaw = to.getYaw();
this.lastPitch = to.getPitch();
@@ -1707,11 +1660,7 @@ index 98b23811f5c1a00d3fd1d9881cd598ef06a897e3..27869528524ba32e007d4a674ece118c
Location oldTo = to.clone();
PlayerMoveEvent event = new PlayerMoveEvent(player, from, to);
this.cserver.getPluginManager().callEvent(event);
--
- // If the event is cancelled we move the player back to their old location.
- if (event.isCancelled()) {
- this.teleport(from);
-@@ -722,6 +743,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
+@@ -735,6 +757,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
if (packet.getId() == this.awaitingTeleport) {
if (this.awaitingPositionFromClient == null) {
this.disconnect(Component.translatable("multiplayer.disconnect.invalid_player_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PLAYER_MOVEMENT); // Paper - kick event cause
@@ -1719,12 +1668,12 @@ index 98b23811f5c1a00d3fd1d9881cd598ef06a897e3..27869528524ba32e007d4a674ece118c
return;
}
-@@ -1158,10 +1180,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
+@@ -1170,10 +1193,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
int maxBookPageSize = io.papermc.paper.configuration.GlobalConfiguration.get().itemValidation.bookSize.pageMax;
double multiplier = Math.max(0.3D, Math.min(1D, io.papermc.paper.configuration.GlobalConfiguration.get().itemValidation.bookSize.totalMultiplier));
long byteAllowed = maxBookPageSize;
+ // Purpur start
-+ int slot = packet.getSlot();
++ int slot = packet.slot();
+ ItemStack itemstack = Inventory.isHotbarSlot(slot) || slot == Inventory.SLOT_OFFHAND ? this.player.getInventory().getItem(slot) : ItemStack.EMPTY;
+ // Purpur end
for (String testString : pageList) {
@@ -1735,7 +1684,7 @@ index 98b23811f5c1a00d3fd1d9881cd598ef06a897e3..27869528524ba32e007d4a674ece118c
server.scheduleOnMain(() -> this.disconnect("Book too large!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION)); // Paper - kick event cause
return;
}
-@@ -1185,6 +1212,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
+@@ -1197,6 +1225,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
if (byteTotal > byteAllowed) {
ServerGamePacketListenerImpl.LOGGER.warn(this.player.getScoreboardName() + " tried to send too large of a book. Book Size: " + byteTotal + " - Allowed: "+ byteAllowed + " - Pages: " + pageList.size());
@@ -1743,74 +1692,7 @@ index 98b23811f5c1a00d3fd1d9881cd598ef06a897e3..27869528524ba32e007d4a674ece118c
server.scheduleOnMain(() -> this.disconnect("Book too large!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION)); // Paper - kick event cause
return;
}
-@@ -1238,13 +1266,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
- itemstack1.setTag(nbttagcompound.copy());
- }
-
-+ // Purpur start
-+ boolean hasPerm = getCraftPlayer().hasPermission("purpur.book.color.edit") || getCraftPlayer().hasPermission("purpur.book.color.sign");
- itemstack1.addTagElement("author", StringTag.valueOf(this.player.getName().getString()));
- if (this.player.isTextFilteringEnabled()) {
-- itemstack1.addTagElement("title", StringTag.valueOf(title.filteredOrEmpty()));
-+ itemstack1.addTagElement("title", StringTag.valueOf(color(title.filteredOrEmpty(), hasPerm)));
- } else {
-- itemstack1.addTagElement("filtered_title", StringTag.valueOf(title.filteredOrEmpty()));
-- itemstack1.addTagElement("title", StringTag.valueOf(title.raw()));
-+ itemstack1.addTagElement("filtered_title", StringTag.valueOf(color(title.filteredOrEmpty(), hasPerm)));
-+ itemstack1.addTagElement("title", StringTag.valueOf(color(title.raw(), hasPerm)));
- }
-+ // Purpur end
-
- this.updateBookPages(pages, (s) -> {
- return Component.Serializer.toJson(Component.literal(s));
-@@ -1256,10 +1287,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
- private void updateBookPages(List list, UnaryOperator unaryoperator, ItemStack itemstack, int slot, ItemStack handItem) { // CraftBukkit
- ListTag nbttaglist = new ListTag();
-
-+ // Purpur start
-+ boolean hasPerm = getCraftPlayer().hasPermission("purpur.book.color.edit");
- if (this.player.isTextFilteringEnabled()) {
-- Stream stream = list.stream().map((filteredtext) -> { // CraftBukkit - decompile error
-- return StringTag.valueOf((String) unaryoperator.apply(filteredtext.filteredOrEmpty()));
-+ Stream stream = list.stream().map(s -> color(s.filteredOrEmpty(), hasPerm, false)).map((s) -> { // CraftBukkit - decompile error
-+ return StringTag.valueOf((String) unaryoperator.apply(s));
- });
-+ // Purpur end
-
- Objects.requireNonNull(nbttaglist);
- stream.forEach(nbttaglist::add);
-@@ -1269,11 +1303,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
-
- for (int j = list.size(); i < j; ++i) {
- FilteredText filteredtext = (FilteredText) list.get(i);
-- String s = filteredtext.raw();
-+ String s = color(filteredtext.raw(), hasPerm, false); // Purpur
-
- nbttaglist.add(StringTag.valueOf((String) unaryoperator.apply(s)));
- if (filteredtext.isFiltered()) {
-- nbttagcompound.putString(String.valueOf(i), (String) unaryoperator.apply(filteredtext.filteredOrEmpty()));
-+ nbttagcompound.putString(String.valueOf(i), (String) unaryoperator.apply((String) color(filteredtext.filteredOrEmpty(), hasPerm, false))); // Purpur
- }
- }
-
-@@ -1286,6 +1320,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
- this.player.getInventory().setItem(slot, CraftEventFactory.handleEditBookEvent(this.player, slot, handItem, itemstack)); // CraftBukkit // Paper - Don't ignore result (see other callsite for handleEditBookEvent)
- }
-
-+ // Purpur start
-+ private String color(String str, boolean hasPerm) {
-+ return color(str, hasPerm, true);
-+ }
-+
-+ private String color(String str, boolean hasPerm, boolean parseHex) {
-+ return hasPerm ? org.bukkit.ChatColor.color(str, parseHex) : str;
-+ }
-+ // Purpur end
-+
- @Override
- public void handleEntityTagQuery(ServerboundEntityTagQuery packet) {
- PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
-@@ -1335,8 +1379,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
+@@ -1315,8 +1344,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@Override
public void handleMovePlayer(ServerboundMovePlayerPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
@@ -1828,16 +1710,16 @@ index 98b23811f5c1a00d3fd1d9881cd598ef06a897e3..27869528524ba32e007d4a674ece118c
} else {
ServerLevel worldserver = this.player.serverLevel();
-@@ -1520,7 +1572,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
- if (!event.isAllowed()) {
+@@ -1503,7 +1540,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
movedWrongly = true;
if (event.getLogWarning())
+ // Paper end
- ServerGamePacketListenerImpl.LOGGER.warn("{} moved wrongly!", this.player.getName().getString());
+ ServerGamePacketListenerImpl.LOGGER.warn("{} moved wrongly!, ({})", this.player.getName().getString(), d11); // Purpur
- }
+ } // Paper
}
-@@ -1587,6 +1639,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
+@@ -1571,6 +1608,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
this.lastYaw = to.getYaw();
this.lastPitch = to.getPitch();
@@ -1846,8 +1728,8 @@ index 98b23811f5c1a00d3fd1d9881cd598ef06a897e3..27869528524ba32e007d4a674ece118c
Location oldTo = to.clone();
PlayerMoveEvent event = new PlayerMoveEvent(player, from, to);
this.cserver.getPluginManager().callEvent(event);
-@@ -1622,6 +1676,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
- this.player.resetFallDistance();
+@@ -1612,6 +1651,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
+ this.player.resetCurrentImpulseContext();
}
+ // Purpur Start
@@ -1860,30 +1742,32 @@ index 98b23811f5c1a00d3fd1d9881cd598ef06a897e3..27869528524ba32e007d4a674ece118c
this.player.checkMovementStatistics(this.player.getX() - d3, this.player.getY() - d4, this.player.getZ() - d5);
this.lastGoodX = this.player.getX();
this.lastGoodY = this.player.getY();
-@@ -1661,6 +1722,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
+@@ -1651,6 +1697,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
return false;
}
// Paper end - optimise out extra getCubes
+
+ // Purpur start
+ public boolean isScissor(ItemStack stack) {
-+ return stack.is(Items.SHEARS) && (stack.getTag() == null || stack.getTag().getInt("CustomModelData") == 0);
++ if (!stack.is(Items.SHEARS)) return false;
++ net.minecraft.world.item.component.CustomModelData customModelData = stack.get(net.minecraft.core.component.DataComponents.CUSTOM_MODEL_DATA);
++ return customModelData == null || customModelData.value() == 0;
+ }
+ // Purpur end
+
private boolean isPlayerCollidingWithAnythingNew(LevelReader world, AABB box, double newX, double newY, double newZ) {
AABB axisalignedbb1 = this.player.getBoundingBox().move(newX - this.player.getX(), newY - this.player.getY(), newZ - this.player.getZ());
Iterable iterable = world.getCollisions(this.player, axisalignedbb1.deflate(9.999999747378752E-6D));
-@@ -1671,7 +1739,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
+@@ -1661,7 +1716,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
do {
if (!iterator.hasNext()) {
- return false;
-+ return !org.purpurmc.purpur.PurpurConfig.kickForOutOfOrderChat; // Purpur // Leaf TODO - Need check this
++ return !org.purpurmc.purpur.PurpurConfig.kickForOutOfOrderChat; // Purpur
}
voxelshape1 = (VoxelShape) iterator.next();
-@@ -2006,6 +2074,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
+@@ -1999,6 +2054,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
boolean cancelled;
if (movingobjectposition == null || movingobjectposition.getType() != HitResult.Type.BLOCK) {
@@ -1891,15 +1775,15 @@ index 98b23811f5c1a00d3fd1d9881cd598ef06a897e3..27869528524ba32e007d4a674ece118c
org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.RIGHT_CLICK_AIR, itemstack, enumhand);
cancelled = event.useItemInHand() == Event.Result.DENY;
} else {
-@@ -2728,6 +2797,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
+@@ -2783,6 +2839,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
AABB axisalignedbb = entity.getBoundingBox();
- if (axisalignedbb.distanceToSqr(this.player.getEyePosition()) < ServerGamePacketListenerImpl.getMaxInteractionDistanceSquared(this.player.level())) { // Gale - make max interaction distance configurable
+ if (this.player.canInteractWithEntity(axisalignedbb, 1.0D)) {
+ if (entity instanceof Mob mob) mob.ticksSinceLastInteraction = 0; // Purpur
packet.dispatch(new ServerboundInteractPacket.Handler() {
private void performInteraction(InteractionHand enumhand, ServerGamePacketListenerImpl.EntityInteraction playerconnection_a, PlayerInteractEntityEvent event) { // CraftBukkit
ItemStack itemstack = ServerGamePacketListenerImpl.this.player.getItemInHand(enumhand);
-@@ -2741,6 +2811,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
+@@ -2796,6 +2853,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
ServerGamePacketListenerImpl.this.cserver.getPluginManager().callEvent(event);
@@ -1907,25 +1791,12 @@ index 98b23811f5c1a00d3fd1d9881cd598ef06a897e3..27869528524ba32e007d4a674ece118c
+
// Entity in bucket - SPIGOT-4048 and SPIGOT-6859a
if ((entity instanceof Bucketable && entity instanceof LivingEntity && origItem != null && origItem.asItem() == Items.WATER_BUCKET) && (event.isCancelled() || ServerGamePacketListenerImpl.this.player.getInventory().getSelected() == null || ServerGamePacketListenerImpl.this.player.getInventory().getSelected().getItem() != origItem)) {
- entity.getEntityData().resendPossiblyDesyncedEntity(player); // Paper - The entire mob gets deleted, so resend it.
-@@ -3328,6 +3400,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
- }
- }
- }
-+ // Purpur start
-+ if (org.purpurmc.purpur.PurpurConfig.fixNetworkSerializedItemsInCreative) {
-+ var tag = itemstack.getTagElement("Purpur.OriginalItem");
-+ if (tag != null) itemstack = ItemStack.of(tag);
-+ }
-+ // Purpur end
-
- boolean flag1 = packet.getSlotNum() >= 1 && packet.getSlotNum() <= 45;
- boolean flag2 = itemstack.isEmpty() || itemstack.getDamageValue() >= 0 && itemstack.getCount() <= 64 && !itemstack.isEmpty();
+ entity.resendPossiblyDesyncedEntityData(ServerGamePacketListenerImpl.this.player); // Paper - The entire mob gets deleted, so resend it.
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
-index e072edfb1f51f3e219e6deb10b19b4b2502ea87f..4bd1d7c4328e13ae3e173836ced22125857bcae1 100644
+index a2c9ca5bab0b78fdddcfb110aed9718f9ac99c06..52c5ce7339029d7cc3bb1164131a9f96598760c0 100644
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
-@@ -285,7 +285,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
+@@ -330,7 +330,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
ServerLoginPacketListenerImpl.LOGGER.warn("Failed to verify username but will let them in anyway!");
ServerLoginPacketListenerImpl.this.startClientVerification(ServerLoginPacketListenerImpl.this.createOfflineProfile(s1)); // Spigot
} else {
@@ -1935,10 +1806,10 @@ index e072edfb1f51f3e219e6deb10b19b4b2502ea87f..4bd1d7c4328e13ae3e173836ced22125
}
} catch (AuthenticationUnavailableException authenticationunavailableexception) {
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 893e034895d7f49662720c4f76b2c37f70199e76..3c6002e33d1b86b60ccfa11ef615aa8f7adaf81b 100644
+index 0e570a7320eb6c65cb5d43fd7912d17a54b64eb3..743e1487048f70ed577452c27c7919d74d26ab19 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -503,6 +503,7 @@ public abstract class PlayerList {
+@@ -502,6 +502,7 @@ public abstract class PlayerList {
scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam);
}
// Paper end - Configurable player collision
@@ -1946,7 +1817,7 @@ index 893e034895d7f49662720c4f76b2c37f70199e76..3c6002e33d1b86b60ccfa11ef615aa8f
if (GaleGlobalConfiguration.get().logToConsole.playerLoginLocations) { // Gale - JettPack - make logging login location configurable
PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", player.getName().getString(), s1, player.getId(), worldserver1.serverLevelData.getLevelName(), player.getX(), player.getY(), player.getZ());
// Gale start - JettPack - make logging login location configurable
-@@ -621,6 +622,7 @@ public abstract class PlayerList {
+@@ -619,6 +620,7 @@ public abstract class PlayerList {
}
public net.kyori.adventure.text.Component remove(ServerPlayer entityplayer, net.kyori.adventure.text.Component leaveMessage) {
// Paper end - Fix kick event leave message not being sent
@@ -1954,7 +1825,7 @@ index 893e034895d7f49662720c4f76b2c37f70199e76..3c6002e33d1b86b60ccfa11ef615aa8f
ServerLevel worldserver = entityplayer.serverLevel();
entityplayer.awardStat(Stats.LEAVE_GAME);
-@@ -776,7 +778,7 @@ public abstract class PlayerList {
+@@ -775,7 +777,7 @@ public abstract class PlayerList {
event.disallow(PlayerLoginEvent.Result.KICK_BANNED, io.papermc.paper.adventure.PaperAdventure.asAdventure(ichatmutablecomponent)); // Paper - Adventure
} else {
// return this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameprofile) ? IChatBaseComponent.translatable("multiplayer.disconnect.server_full") : null;
@@ -1963,7 +1834,7 @@ index 893e034895d7f49662720c4f76b2c37f70199e76..3c6002e33d1b86b60ccfa11ef615aa8f
event.disallow(PlayerLoginEvent.Result.KICK_FULL, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.serverFullMessage)); // Spigot // Paper - Adventure
}
}
-@@ -1128,6 +1130,20 @@ public abstract class PlayerList {
+@@ -1127,6 +1129,20 @@ public abstract class PlayerList {
}
// CraftBukkit end
@@ -1984,7 +1855,7 @@ index 893e034895d7f49662720c4f76b2c37f70199e76..3c6002e33d1b86b60ccfa11ef615aa8f
public void broadcastAll(Packet> packet, ResourceKey dimension) {
Iterator iterator = this.players.iterator();
-@@ -1231,6 +1247,7 @@ public abstract class PlayerList {
+@@ -1230,6 +1246,7 @@ public abstract class PlayerList {
} else {
b0 = (byte) (24 + permissionLevel);
}
@@ -1992,7 +1863,7 @@ index 893e034895d7f49662720c4f76b2c37f70199e76..3c6002e33d1b86b60ccfa11ef615aa8f
player.connection.send(new ClientboundEntityEventPacket(player, b0));
}
-@@ -1239,6 +1256,27 @@ public abstract class PlayerList {
+@@ -1238,6 +1255,27 @@ public abstract class PlayerList {
player.getBukkitEntity().recalculatePermissions(); // CraftBukkit
this.server.getCommands().sendCommands(player);
} // Paper - Add sendOpLevel API
@@ -2042,17 +1913,32 @@ index 823efad652d8ff9e96b99375b102fef6f017716e..caa8a69bde0c212c36dd990a67836ac2
++this.sleepingPlayers;
}
// CraftBukkit start
+diff --git a/src/main/java/net/minecraft/util/StringUtil.java b/src/main/java/net/minecraft/util/StringUtil.java
+index 0bd191acb9596d3aa21c337230d26f09d26f6888..20211f40aeeade9217ece087688974bdf55afc56 100644
+--- a/src/main/java/net/minecraft/util/StringUtil.java
++++ b/src/main/java/net/minecraft/util/StringUtil.java
+@@ -69,6 +69,7 @@ public class StringUtil {
+
+ // Paper start - Username validation
+ public static boolean isReasonablePlayerName(final String name) {
++ if (true) return org.purpurmc.purpur.PurpurConfig.usernameValidCharactersPattern.matcher(name).matches(); // Purpur
+ if (name.isEmpty() || name.length() > 16) {
+ return false;
+ }
diff --git a/src/main/java/net/minecraft/world/damagesource/CombatRules.java b/src/main/java/net/minecraft/world/damagesource/CombatRules.java
-index ccbfcef3e83b1bef364447657bfd08a92d615cf6..aa2331c6df4e79d4bb0add071a0b11d2a3a08b88 100644
+index ddc880ac0c8378bc1132be5deba746c1484c941c..7a8e4b9a9f2e1e5a9c38ad330c75df1f880d3e8b 100644
--- a/src/main/java/net/minecraft/world/damagesource/CombatRules.java
+++ b/src/main/java/net/minecraft/world/damagesource/CombatRules.java
-@@ -11,12 +11,12 @@ public class CombatRules {
+@@ -12,7 +12,7 @@ public class CombatRules {
- public static float getDamageAfterAbsorb(float damage, float armor, float armorToughness) {
- float f = 2.0F + armorToughness / 4.0F;
+ public static float getDamageAfterAbsorb(float damage, DamageSource source, float armor, float armorToughnesss) {
+ float f = 2.0F + armorToughnesss / 4.0F;
- float g = Mth.clamp(armor - damage / f, armor * 0.2F, 20.0F);
+ float g = Mth.clamp(armor - damage / f, armor * 0.2F, org.purpurmc.purpur.PurpurConfig.limitArmor ? 20F : Float.MAX_VALUE); // Purpur
- return damage * (1.0F - g / 25.0F);
+ float h = g / 25.0F;
+ float i = EnchantmentHelper.calculateArmorBreach(source.getEntity(), h);
+ float j = 1.0F - i;
+@@ -20,7 +20,7 @@ public class CombatRules {
}
public static float getDamageAfterMagicAbsorb(float damageDealt, float protection) {
@@ -2062,19 +1948,19 @@ index ccbfcef3e83b1bef364447657bfd08a92d615cf6..aa2331c6df4e79d4bb0add071a0b11d2
}
}
diff --git a/src/main/java/net/minecraft/world/damagesource/CombatTracker.java b/src/main/java/net/minecraft/world/damagesource/CombatTracker.java
-index 7056c8ca7a87748f14142c6af274aae492f29f1c..bf06bb78d060bb54d9aaade3605d42ce837d598b 100644
+index 99a7e9eb75231c15bd8bb24fbb4e296bc9fdedff..4fb025a63628eb60509d90b680922a0220104bcb 100644
--- a/src/main/java/net/minecraft/world/damagesource/CombatTracker.java
+++ b/src/main/java/net/minecraft/world/damagesource/CombatTracker.java
-@@ -53,7 +53,7 @@ public class CombatTracker {
+@@ -54,7 +54,7 @@ public class CombatTracker {
private Component getMessageForAssistedFall(Entity attacker, Component attackerDisplayName, String itemDeathTranslationKey, String deathTranslationKey) {
ItemStack itemStack = attacker instanceof LivingEntity livingEntity ? livingEntity.getMainHandItem() : ItemStack.EMPTY;
-- return !itemStack.isEmpty() && itemStack.hasCustomHoverName()
-+ return !itemStack.isEmpty() && (org.purpurmc.purpur.PurpurConfig.playerDeathsAlwaysShowItem || itemStack.hasCustomHoverName()) // Purpur
+- return !itemStack.isEmpty() && itemStack.has(DataComponents.CUSTOM_NAME)
++ return !itemStack.isEmpty() && (org.purpurmc.purpur.PurpurConfig.playerDeathsAlwaysShowItem || itemStack.has(DataComponents.CUSTOM_NAME)) // Purpur
? Component.translatable(itemDeathTranslationKey, this.mob.getDisplayName(), attackerDisplayName, itemStack.getDisplayName())
: Component.translatable(deathTranslationKey, this.mob.getDisplayName(), attackerDisplayName);
}
-@@ -97,6 +97,13 @@ public class CombatTracker {
+@@ -98,6 +98,13 @@ public class CombatTracker {
Component component = ComponentUtils.wrapInSquareBrackets(Component.translatable(string + ".link")).withStyle(INTENTIONAL_GAME_DESIGN_STYLE);
return Component.translatable(string + ".message", this.mob.getDisplayName(), component);
} else {
@@ -2089,10 +1975,10 @@ index 7056c8ca7a87748f14142c6af274aae492f29f1c..bf06bb78d060bb54d9aaade3605d42ce
}
}
diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSource.java b/src/main/java/net/minecraft/world/damagesource/DamageSource.java
-index b26e4d58ea1898a5e4b31c3d6ab33f38835ab2c6..a1724d2d545aa808ea380f910c0190658fc7881b 100644
+index 359a2f0492a9b938a4f015c546e100e0092ae1d4..25e614be19b2b29b36af136b823f27f85e1650fa 100644
--- a/src/main/java/net/minecraft/world/damagesource/DamageSource.java
+++ b/src/main/java/net/minecraft/world/damagesource/DamageSource.java
-@@ -27,6 +27,8 @@ public class DamageSource {
+@@ -29,6 +29,8 @@ public class DamageSource {
private boolean withSweep = false;
private boolean melting = false;
private boolean poison = false;
@@ -2101,7 +1987,7 @@ index b26e4d58ea1898a5e4b31c3d6ab33f38835ab2c6..a1724d2d545aa808ea380f910c019065
@Nullable
private Entity customEventDamager = null; // This field is a helper for when causing entity damage is not set by vanilla // Paper - fix DamageSource API
-@@ -57,6 +59,26 @@ public class DamageSource {
+@@ -59,6 +61,26 @@ public class DamageSource {
return this.poison;
}
@@ -2128,7 +2014,7 @@ index b26e4d58ea1898a5e4b31c3d6ab33f38835ab2c6..a1724d2d545aa808ea380f910c019065
// Paper start - fix DamageSource API
public @Nullable Entity getCustomEventDamager() {
return (this.customEventDamager != null) ? this.customEventDamager : this.directEntity;
-@@ -100,6 +122,8 @@ public class DamageSource {
+@@ -101,6 +123,8 @@ public class DamageSource {
damageSource.withSweep = this.isSweep();
damageSource.poison = this.isPoison();
damageSource.melting = this.isMelting();
@@ -2137,12 +2023,12 @@ index b26e4d58ea1898a5e4b31c3d6ab33f38835ab2c6..a1724d2d545aa808ea380f910c019065
return damageSource;
}
// CraftBukkit end
-@@ -172,10 +196,19 @@ public class DamageSource {
+@@ -173,10 +197,19 @@ public class DamageSource {
ItemStack itemstack1 = itemstack;
-- return !itemstack1.isEmpty() && itemstack1.hasCustomHoverName() ? Component.translatable(s + ".item", killed.getDisplayName(), ichatbasecomponent, itemstack1.getDisplayName()) : Component.translatable(s, killed.getDisplayName(), ichatbasecomponent);
-+ return !itemstack1.isEmpty() && (org.purpurmc.purpur.PurpurConfig.playerDeathsAlwaysShowItem || itemstack1.hasCustomHoverName()) ? Component.translatable(s + ".item", killed.getDisplayName(), ichatbasecomponent, itemstack1.getDisplayName()) : Component.translatable(s, killed.getDisplayName(), ichatbasecomponent);
+- return !itemstack1.isEmpty() && itemstack1.has(DataComponents.CUSTOM_NAME) ? Component.translatable(s + ".item", killed.getDisplayName(), ichatbasecomponent, itemstack1.getDisplayName()) : Component.translatable(s, killed.getDisplayName(), ichatbasecomponent);
++ return !itemstack1.isEmpty() && (org.purpurmc.purpur.PurpurConfig.playerDeathsAlwaysShowItem || itemstack1.has(DataComponents.CUSTOM_NAME)) ? Component.translatable(s + ".item", killed.getDisplayName(), ichatbasecomponent, itemstack1.getDisplayName()) : Component.translatable(s, killed.getDisplayName(), ichatbasecomponent);
}
}
@@ -2159,7 +2045,7 @@ index b26e4d58ea1898a5e4b31c3d6ab33f38835ab2c6..a1724d2d545aa808ea380f910c019065
return this.type().msgId();
}
diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSources.java b/src/main/java/net/minecraft/world/damagesource/DamageSources.java
-index a47473c9875c70c52b9a61e0156e55961f34c694..b88fed81a7df6c81521f74425bd81443b4841137 100644
+index a1c53f04c2dd505e6af72e512e111d7994786035..5ffe772e29dfd422b664e8123e7f5cf396158674 100644
--- a/src/main/java/net/minecraft/world/damagesource/DamageSources.java
+++ b/src/main/java/net/minecraft/world/damagesource/DamageSources.java
@@ -44,11 +44,15 @@ public class DamageSources {
@@ -2178,206 +2064,68 @@ index a47473c9875c70c52b9a61e0156e55961f34c694..b88fed81a7df6c81521f74425bd81443
// CraftBukkit end
this.inFire = this.source(DamageTypes.IN_FIRE);
this.lightningBolt = this.source(DamageTypes.LIGHTNING_BOLT);
-@@ -277,4 +281,13 @@ public class DamageSources {
- public DamageSource genericKill() {
- return this.genericKill;
+@@ -97,6 +101,15 @@ public class DamageSources {
}
+ // CraftBukkit end
+
+ // Purpur start
+ public DamageSource scissors() {
+ return this.scissors;
+ }
-+
+ public DamageSource stonecutter() {
+ return this.stonecutter;
+ }
+ // Purpur end
- }
++
+ public DamageSource inFire() {
+ return this.inFire;
+ }
diff --git a/src/main/java/net/minecraft/world/effect/HungerMobEffect.java b/src/main/java/net/minecraft/world/effect/HungerMobEffect.java
-index 3aad6bd0a1fb7bb3f9b7dab2c10c875864900750..31bd845130e363dd11c225dfd1e9dd896aea8aac 100644
+index a476b56ed98d0a1afc6a396ce29424df78f24ada..5119ff3414fbd9a1ae0a8db0fd15bd3c57c8e148 100644
--- a/src/main/java/net/minecraft/world/effect/HungerMobEffect.java
+++ b/src/main/java/net/minecraft/world/effect/HungerMobEffect.java
-@@ -15,7 +15,7 @@ class HungerMobEffect extends MobEffect {
- if (entity instanceof Player) {
- Player entityhuman = (Player) entity;
-
+@@ -12,7 +12,7 @@ class HungerMobEffect extends MobEffect {
+ @Override
+ public boolean applyEffectTick(LivingEntity entity, int amplifier) {
+ if (entity instanceof Player entityhuman) {
- entityhuman.causeFoodExhaustion(0.005F * (float) (amplifier + 1), org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.HUNGER_EFFECT); // CraftBukkit - EntityExhaustionEvent
+ entityhuman.causeFoodExhaustion(entity.level().purpurConfig.humanHungerExhaustionAmount * (float) (amplifier + 1), org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.HUNGER_EFFECT); // CraftBukkit - EntityExhaustionEvent // Purpur
}
- }
-diff --git a/src/main/java/net/minecraft/world/effect/MobEffectInstance.java b/src/main/java/net/minecraft/world/effect/MobEffectInstance.java
-index 5c9a0c91ae53b575d325a294c702668d30252fcf..0758ddbd37a519d03ae134731368f4a69c2f8aab 100644
---- a/src/main/java/net/minecraft/world/effect/MobEffectInstance.java
-+++ b/src/main/java/net/minecraft/world/effect/MobEffectInstance.java
-@@ -36,6 +36,7 @@ public class MobEffectInstance implements Comparable {
- private boolean showIcon;
- @Nullable
- public MobEffectInstance hiddenEffect;
-+ private org.bukkit.NamespacedKey key; // Purpur - add key
- private final Optional factorData;
-
- public MobEffectInstance(MobEffect type) {
-@@ -54,8 +55,14 @@ public class MobEffectInstance implements Comparable {
- this(type, duration, amplifier, ambient, visible, visible);
- }
-
-+ // Purpur start
-+ public MobEffectInstance(MobEffect type, int duration, int amplifier, boolean ambient, boolean showParticles, boolean showIcon, @Nullable org.bukkit.NamespacedKey key) {
-+ this(type, duration, amplifier, ambient, showParticles, showIcon, null, key, type.createFactorData());
-+ }
-+ // Purpur end
-+
- public MobEffectInstance(MobEffect type, int duration, int amplifier, boolean ambient, boolean showParticles, boolean showIcon) {
-- this(type, duration, amplifier, ambient, showParticles, showIcon, null, type.createFactorData());
-+ this(type, duration, amplifier, ambient, showParticles, showIcon, null, null, type.createFactorData()); // Purpur
- }
-
- public MobEffectInstance(
-@@ -66,6 +73,7 @@ public class MobEffectInstance implements Comparable {
- boolean showParticles,
- boolean showIcon,
- @Nullable MobEffectInstance hiddenEffect,
-+ @Nullable org.bukkit.NamespacedKey key, // Purpur
- Optional factorCalculationData
- ) {
- this.effect = type;
-@@ -74,6 +82,7 @@ public class MobEffectInstance implements Comparable {
- this.ambient = ambient;
- this.visible = showParticles;
- this.showIcon = showIcon;
-+ this.key = key; // Purpur - add key
- this.hiddenEffect = hiddenEffect;
- this.factorData = factorCalculationData;
- }
-@@ -94,6 +103,7 @@ public class MobEffectInstance implements Comparable {
- this.ambient = that.ambient;
- this.visible = that.visible;
- this.showIcon = that.showIcon;
-+ this.key = that.key; // Purpur - add key
- }
-
- public boolean update(MobEffectInstance that) {
-@@ -138,6 +148,13 @@ public class MobEffectInstance implements Comparable {
- bl = true;
- }
-
-+ // Purpur start
-+ if (that.key != this.key) {
-+ this.key = that.key;
-+ bl = true;
-+ }
-+ // Purpur end
-+
- return bl;
- }
-
-@@ -181,6 +198,17 @@ public class MobEffectInstance implements Comparable {
- return this.showIcon;
- }
-
-+ // Purpur start
-+ public boolean hasKey() {
-+ return this.key != null;
-+ }
-+
-+ @Nullable
-+ public org.bukkit.NamespacedKey getKey() {
-+ return this.key;
-+ }
-+ // Purpur end
-+
- public boolean tick(LivingEntity entity, Runnable overwriteCallback) {
- if (this.hasRemainingDuration()) {
- int i = this.isInfiniteDuration() ? entity.tickCount : this.duration;
-@@ -237,6 +265,12 @@ public class MobEffectInstance implements Comparable {
- string = string + ", Show Icon: false";
- }
-
-+ // Purpur start
-+ if (this.hasKey()) {
-+ string = string + ", Key: " + this.key;
-+ }
-+ // Purpur end
-+
- return string;
- }
-
-@@ -251,6 +285,7 @@ public class MobEffectInstance implements Comparable {
- && this.duration == mobEffectInstance.duration
- && this.amplifier == mobEffectInstance.amplifier
- && this.ambient == mobEffectInstance.ambient
-+ && this.key == mobEffectInstance.key // Purpur - add key
- && this.effect.equals(mobEffectInstance.effect);
- }
-
-@@ -275,6 +310,11 @@ public class MobEffectInstance implements Comparable {
- nbt.putBoolean("ambient", this.isAmbient());
- nbt.putBoolean("show_particles", this.isVisible());
- nbt.putBoolean("show_icon", this.showIcon());
-+ // Purpur start
-+ if (this.key != null) {
-+ nbt.putString("key", this.key.toString());
-+ }
-+ // Purpur end
- if (this.hiddenEffect != null) {
- CompoundTag compoundTag = new CompoundTag();
- this.hiddenEffect.save(compoundTag);
-@@ -311,6 +351,13 @@ public class MobEffectInstance implements Comparable {
- bl3 = nbt.getBoolean("show_icon");
- }
-
-+ // Purpur start
-+ org.bukkit.NamespacedKey key = null;
-+ if (nbt.contains("key")) {
-+ key = org.bukkit.NamespacedKey.fromString(nbt.getString("key"));
-+ }
-+ // Purpur end
-+
- MobEffectInstance mobEffectInstance = null;
- if (nbt.contains("hidden_effect", 10)) {
- mobEffectInstance = loadSpecifiedEffect(type, nbt.getCompound("hidden_effect"));
-@@ -325,7 +372,7 @@ public class MobEffectInstance implements Comparable {
- optional = Optional.empty();
- }
-
-- return new MobEffectInstance(type, j, Math.max(i, 0), bl, bl2, bl3, mobEffectInstance, optional);
-+ return new MobEffectInstance(type, j, Math.max(i, 0), bl, bl2, bl3, mobEffectInstance, key, optional); // Purpur - add key
- }
-
- @Override
+ return true;
diff --git a/src/main/java/net/minecraft/world/effect/PoisonMobEffect.java b/src/main/java/net/minecraft/world/effect/PoisonMobEffect.java
-index 196204a8661c7750408997e052ec706f44161fc6..393cd9fac5b2fd39e4248d0abd4930e6b2ff73a4 100644
+index 3e7a703632251e0a5234259e3702b58b332e5ef0..f2cc43fbccb5d2ba012b350268065c2cfe014faf 100644
--- a/src/main/java/net/minecraft/world/effect/PoisonMobEffect.java
+++ b/src/main/java/net/minecraft/world/effect/PoisonMobEffect.java
-@@ -11,8 +11,8 @@ class PoisonMobEffect extends MobEffect {
+@@ -10,8 +10,8 @@ class PoisonMobEffect extends MobEffect {
+
@Override
- public void applyEffectTick(LivingEntity entity, int amplifier) {
- super.applyEffectTick(entity, amplifier);
+ public boolean applyEffectTick(LivingEntity entity, int amplifier) {
- if (entity.getHealth() > 1.0F) {
- entity.hurt(entity.damageSources().poison(), 1.0F); // CraftBukkit - DamageSource.MAGIC -> CraftEventFactory.POISON
+ if (entity.getHealth() > entity.level().purpurConfig.entityMinimalHealthPoison) { // Purpur
+ entity.hurt(entity.damageSources().poison(), entity.level().purpurConfig.entityPoisonDegenerationAmount); // CraftBukkit - DamageSource.MAGIC -> CraftEventFactory.POISON // Purpur
}
- }
+ return true;
diff --git a/src/main/java/net/minecraft/world/effect/RegenerationMobEffect.java b/src/main/java/net/minecraft/world/effect/RegenerationMobEffect.java
-index 551b20f86347aeca4824b7a424ad7de7c0ff072e..06bb4ad98aa9ca38b8d423681b1ad4b821f5e47d 100644
+index 4dba3e813e054951cbfbe0b323c1f5d973469cc0..426f61d55b9692cf085368df4e4df6f6997aa420 100644
--- a/src/main/java/net/minecraft/world/effect/RegenerationMobEffect.java
+++ b/src/main/java/net/minecraft/world/effect/RegenerationMobEffect.java
-@@ -12,7 +12,7 @@ class RegenerationMobEffect extends MobEffect {
- public void applyEffectTick(LivingEntity entity, int amplifier) {
- super.applyEffectTick(entity, amplifier);
+@@ -11,7 +11,7 @@ class RegenerationMobEffect extends MobEffect {
+ @Override
+ public boolean applyEffectTick(LivingEntity entity, int amplifier) {
if (entity.getHealth() < entity.getMaxHealth()) {
- entity.heal(1.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.MAGIC_REGEN); // CraftBukkit
+ entity.heal(entity.level().purpurConfig.entityHealthRegenAmount, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.MAGIC_REGEN); // CraftBukkit // Purpur
}
- }
+ return true;
diff --git a/src/main/java/net/minecraft/world/effect/SaturationMobEffect.java b/src/main/java/net/minecraft/world/effect/SaturationMobEffect.java
-index b994ae09621934df2cdd6a83a7d8ecb44649fb16..c2b812c992db1ac9cd391da902c8d819a6ec2e6d 100644
+index 7b415dca88f50dc472fe4be96e5ef0996f117913..2bb872f29350d15db46b32c686aef78fc1b6fa29 100644
--- a/src/main/java/net/minecraft/world/effect/SaturationMobEffect.java
+++ b/src/main/java/net/minecraft/world/effect/SaturationMobEffect.java
-@@ -23,7 +23,7 @@ class SaturationMobEffect extends InstantenousMobEffect {
+@@ -20,7 +20,7 @@ class SaturationMobEffect extends InstantenousMobEffect {
int oldFoodLevel = entityhuman.getFoodData().foodLevel;
org.bukkit.event.entity.FoodLevelChangeEvent event = CraftEventFactory.callFoodLevelChangeEvent(entityhuman, amplifier + 1 + oldFoodLevel);
if (!event.isCancelled()) {
@@ -2387,41 +2135,40 @@ index b994ae09621934df2cdd6a83a7d8ecb44649fb16..c2b812c992db1ac9cd391da902c8d819
((CraftPlayer) entityhuman.getBukkitEntity()).sendHealthUpdate();
diff --git a/src/main/java/net/minecraft/world/effect/WitherMobEffect.java b/src/main/java/net/minecraft/world/effect/WitherMobEffect.java
-index cc45fd864185a7842c465e26304b36f7c744bb93..434390a6b88eac7bd41ad6b05d223c78571885fb 100644
+index f43bf280999ff3860cc702def50cc62b131eb1bd..66d9e99a351f5fc6cf58be3bee4397d92c932d64 100644
--- a/src/main/java/net/minecraft/world/effect/WitherMobEffect.java
+++ b/src/main/java/net/minecraft/world/effect/WitherMobEffect.java
-@@ -10,7 +10,7 @@ class WitherMobEffect extends MobEffect {
+@@ -9,7 +9,7 @@ class WitherMobEffect extends MobEffect {
+
@Override
- public void applyEffectTick(LivingEntity entity, int amplifier) {
- super.applyEffectTick(entity, amplifier);
+ public boolean applyEffectTick(LivingEntity entity, int amplifier) {
- entity.hurt(entity.damageSources().wither(), 1.0F);
+ entity.hurt(entity.damageSources().wither(), entity.level().purpurConfig.entityWitherDegenerationAmount); // Purpur
+ return true;
}
- @Override
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e03bcde31 100644
+index 9c20cead889a736aab17ef8ef1f3c932b0dd37f1..88ef23e08df880d90fbf879f901c8c7afab90526 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
-@@ -160,7 +160,7 @@ import org.bukkit.plugin.PluginManager;
+@@ -163,7 +163,7 @@ import org.bukkit.plugin.PluginManager;
// CraftBukkit end
- public abstract class Entity implements Nameable, EntityAccess, CommandSource, ScoreHolder {
+ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, CommandSource, ScoreHolder {
-
+ public static javax.script.ScriptEngine scriptEngine = new javax.script.ScriptEngineManager().getEngineByName("rhino"); // Purpur
// CraftBukkit start
private static final int CURRENT_LEVEL = 2;
public boolean preserveMotion = true; // Paper - Fix Entity Teleportation and cancel velocity if teleported; keep initial motion on first setPositionRotation
-@@ -338,7 +338,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
+@@ -341,6 +341,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
public double xOld;
public double yOld;
public double zOld;
-- private float maxUpStep;
-+ public float maxUpStep; // Purpur - private -> public
++ public float maxUpStep; // Purpur
public boolean noPhysics;
public final RandomSource random;
public int tickCount;
-@@ -380,7 +380,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
+@@ -382,7 +383,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
private final Set tags;
private final double[] pistonDeltas;
private long pistonDeltasGameTime;
@@ -2430,7 +2177,15 @@ index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e
private float eyeHeight;
public boolean isInPowderSnow;
public boolean wasInPowderSnow;
-@@ -562,6 +562,25 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
+@@ -429,6 +430,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+ public boolean fixedPose = false; // Paper - Expand Pose API
+ public boolean activatedPriorityReset = false; // Pufferfish - DAB
+ public int activatedPriority = org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.maximumActivationPrio; // Pufferfish - DAB (golf score)
++ public @Nullable Boolean immuneToFire = null; // Purpur - Fire immune API
+
+ public void setOrigin(@javax.annotation.Nonnull Location location) {
+ this.origin = location.toVector();
+@@ -561,6 +563,25 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return false;
}
@@ -2456,7 +2211,7 @@ index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e
public final boolean hardCollides() {
return this.hardCollides;
}
-@@ -582,7 +601,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
+@@ -581,7 +602,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
this.bb = Entity.INITIAL_AABB;
this.stuckSpeedMultiplier = Vec3.ZERO;
this.nextStep = 1.0F;
@@ -2465,7 +2220,7 @@ index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e
this.remainingFireTicks = -this.getFireImmuneTicks();
this.fluidHeight = new Object2DoubleArrayMap(2);
this.fluidOnEyes = new HashSet();
-@@ -920,10 +939,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
+@@ -961,10 +982,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
public void checkBelowWorld() {
// Paper start - Configurable nether ceiling damage
@@ -2478,7 +2233,16 @@ index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e
this.onBelowWorld();
}
-@@ -1896,7 +1916,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
+@@ -1879,7 +1901,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+ }
+
+ public boolean fireImmune() {
+- return this.getType().fireImmune();
++ return this.immuneToFire != null ? immuneToFire : this.getType().fireImmune(); // Purpur - add fire immune API
+ }
+
+ public boolean causeFallDamage(float fallDistance, float damageMultiplier, DamageSource damageSource) {
+@@ -1952,7 +1974,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return this.isInWater() || flag;
}
@@ -2486,8 +2250,32 @@ index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e
+ public void updateInWaterStateAndDoWaterCurrentPushing() { // Purpur - package-private -> public
Entity entity = this.getVehicle();
- if (entity instanceof Boat) {
-@@ -3050,6 +3070,13 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
+ if (entity instanceof Boat entityboat) {
+@@ -2584,6 +2606,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+ nbttagcompound.putBoolean("Paper.FreezeLock", true);
+ }
+ // Paper end
++ // Purpur start
++ if (immuneToFire != null) {
++ nbttagcompound.putBoolean("Purpur.FireImmune", immuneToFire);
++ }
++ // Purpur end
+ return nbttagcompound;
+ } catch (Throwable throwable) {
+ CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT");
+@@ -2731,6 +2758,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+ freezeLocked = nbt.getBoolean("Paper.FreezeLock");
+ }
+ // Paper end
++ // Purpur start
++ if (nbt.contains("Purpur.FireImmune")) {
++ immuneToFire = nbt.getBoolean("Purpur.FireImmune");
++ }
++ // Purpur end
+
+ } catch (Throwable throwable) {
+ CrashReport crashreport = CrashReport.forThrowable(throwable, "Loading entity NBT");
+@@ -3109,6 +3141,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
this.passengers = ImmutableList.copyOf(list);
}
@@ -2501,7 +2289,7 @@ index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e
this.gameEvent(GameEvent.ENTITY_MOUNT, passenger);
}
}
-@@ -3089,6 +3116,14 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
+@@ -3148,6 +3187,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return false;
}
// CraftBukkit end
@@ -2516,7 +2304,7 @@ index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e
if (this.passengers.size() == 1 && this.passengers.get(0) == entity) {
this.passengers = ImmutableList.of();
} else {
-@@ -3168,12 +3203,15 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
+@@ -3226,12 +3273,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return Vec3.directionFromRotation(this.getRotationVector());
}
@@ -2533,7 +2321,7 @@ index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e
}
this.isInsidePortal = true;
-@@ -3412,7 +3450,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
+@@ -3456,7 +3506,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
public int getMaxAirSupply() {
@@ -2542,7 +2330,7 @@ index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e
}
public int getAirSupply() {
-@@ -3877,7 +3915,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
+@@ -3923,7 +3973,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
public boolean canChangeDimensions() {
@@ -2551,7 +2339,7 @@ index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e
}
public float getBlockExplosionResistance(Explosion explosion, BlockGetter world, BlockPos pos, BlockState blockState, FluidState fluidState, float max) {
-@@ -4180,6 +4218,20 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
+@@ -4224,6 +4274,20 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return SlotAccess.NULL;
}
@@ -2572,7 +2360,7 @@ index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e
@Override
public void sendSystemMessage(Component message) {}
-@@ -4457,6 +4509,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
+@@ -4511,6 +4575,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
this.yRotO = this.getYRot();
}
@@ -2585,11 +2373,19 @@ index 51d4fd6e38c383122af207f54ffc206f3c0448b2..f5fa8e5534431d35be946aac56c4a90e
public boolean updateFluidHeightAndDoFluidPushing(TagKey tag, double speed) {
if (false && this.touchingUnloadedChunk()) { // Gale - Airplane - reduce entity fluid lookups if no fluids - cost of a lookup here is the same cost as below, so skip
return false;
-@@ -5035,4 +5093,45 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
+@@ -4919,7 +4989,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+ }
+
+ public float maxUpStep() {
+- return 0.0F;
++ return maxUpStep;
+ }
+
+ public void onExplosionHit(@Nullable Entity entity) {}
+@@ -5091,4 +5161,44 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return ((net.minecraft.server.level.ServerChunkCache) level.getChunkSource()).isPositionTicking(this);
}
// Paper end - Expose entity id counter
-+
+ // Purpur start
+ @Nullable
+ private Player rider = null;
@@ -2644,19 +2440,20 @@ index d8cc5614502db7025349e085381b6b32ad32296a..f1b9e83206cc67e6ef29ebe088351b0a
private EntitySelector() {}
// Paper start - Affects Spawning API
diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java
-index dc11683ee4d8a6b7a1c42bcae36dc6e8105cd994..a9e2a758669550530eb29475ba99fe42e520f6ae 100644
+index e6edbe6177b168d85759bd9c414dc87ea8a394fe..32a1b5a1d01fd4dc603a76fde259f3a0d4749fad 100644
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
-@@ -313,13 +313,24 @@ public class EntityType implements FeatureElement, EntityTypeT
+@@ -324,7 +324,8 @@ public class EntityType implements FeatureElement, EntityTypeT
private Component description;
@Nullable
- private ResourceLocation lootTable;
+ private ResourceKey lootTable;
- private final EntityDimensions dimensions;
+ private EntityDimensions dimensions; // Purpur - remove final
+ public void setDimensions(EntityDimensions dimensions) { this.dimensions = dimensions; } // Purpur
+ private final float spawnDimensionsScale;
private final FeatureFlagSet requiredFeatures;
- private static EntityType register(String id, EntityType.Builder type) { // CraftBukkit - decompile error
+@@ -332,6 +333,16 @@ public class EntityType implements FeatureElement, EntityTypeT
return (EntityType) Registry.register(BuiltInRegistries.ENTITY_TYPE, id, (EntityType) type.build(id)); // CraftBukkit - decompile error
}
@@ -2673,7 +2470,7 @@ index dc11683ee4d8a6b7a1c42bcae36dc6e8105cd994..a9e2a758669550530eb29475ba99fe42
public static ResourceLocation getKey(EntityType> type) {
return BuiltInRegistries.ENTITY_TYPE.getKey(type);
}
-@@ -531,6 +542,16 @@ public class EntityType implements FeatureElement, EntityTypeT
+@@ -539,6 +550,16 @@ public class EntityType implements FeatureElement, EntityTypeT
return this.category;
}
@@ -2690,7 +2487,7 @@ index dc11683ee4d8a6b7a1c42bcae36dc6e8105cd994..a9e2a758669550530eb29475ba99fe42
public String getDescriptionId() {
if (this.descriptionId == null) {
this.descriptionId = Util.makeDescriptionId("entity", BuiltInRegistries.ENTITY_TYPE.getKey(this));
-@@ -598,6 +619,12 @@ public class EntityType implements FeatureElement, EntityTypeT
+@@ -606,6 +627,12 @@ public class EntityType implements FeatureElement, EntityTypeT
entity.load(nbt);
}, () -> {
EntityType.LOGGER.warn("Skipping Entity with id {}", nbt.getString("id"));
@@ -2704,10 +2501,10 @@ index dc11683ee4d8a6b7a1c42bcae36dc6e8105cd994..a9e2a758669550530eb29475ba99fe42
}
diff --git a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
-index 36422fb394a158f36c84ba0ee03cc704956c91b2..9a3210e34decb4096533c58f36687e31330198c4 100644
+index a207a31d80a302dbdfe80f8727222542d3a78da2..f5debc8ddc496cd3e2d8b253511ee5cc9a723b38 100644
--- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
+++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
-@@ -314,7 +314,7 @@ public class ExperienceOrb extends Entity {
+@@ -320,7 +320,7 @@ public class ExperienceOrb extends Entity {
public void playerTouch(Player player) {
if (!this.level().isClientSide) {
if (player.takeXpDelay == 0 && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) { // Paper - PlayerPickupExperienceEvent
@@ -2716,7 +2513,7 @@ index 36422fb394a158f36c84ba0ee03cc704956c91b2..9a3210e34decb4096533c58f36687e31
player.take(this, 1);
int i = this.repairPlayerItems(player, this.value);
-@@ -332,7 +332,7 @@ public class ExperienceOrb extends Entity {
+@@ -338,7 +338,7 @@ public class ExperienceOrb extends Entity {
}
private int repairPlayerItems(Player player, int amount) {
@@ -2725,7 +2522,7 @@ index 36422fb394a158f36c84ba0ee03cc704956c91b2..9a3210e34decb4096533c58f36687e31
if (entry != null) {
ItemStack itemstack = (ItemStack) entry.getValue();
-@@ -360,13 +360,15 @@ public class ExperienceOrb extends Entity {
+@@ -366,13 +366,15 @@ public class ExperienceOrb extends Entity {
}
}
@@ -2744,7 +2541,7 @@ index 36422fb394a158f36c84ba0ee03cc704956c91b2..9a3210e34decb4096533c58f36687e31
public int getValue() {
return this.value;
diff --git a/src/main/java/net/minecraft/world/entity/GlowSquid.java b/src/main/java/net/minecraft/world/entity/GlowSquid.java
-index 5de938f4a7f16fd3caff783564cbb7e6b2924f9a..09181e9a0d4ceac30d20f4ff488a85b0ab5b1d04 100644
+index 09fdea983772612ef3fff6b2da3cf469a34e4ec0..3e2ea26c23e88c395856b65001f2895db6a52bd4 100644
--- a/src/main/java/net/minecraft/world/entity/GlowSquid.java
+++ b/src/main/java/net/minecraft/world/entity/GlowSquid.java
@@ -23,6 +23,39 @@ public class GlowSquid extends Squid {
@@ -2788,10 +2585,10 @@ index 5de938f4a7f16fd3caff783564cbb7e6b2924f9a..09181e9a0d4ceac30d20f4ff488a85b0
protected ParticleOptions getInkParticle() {
return ParticleTypes.GLOW_SQUID_INK;
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
-index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f8797fdddf76 100644
+index d688c41ccfec36ab1715f4ae70fbd1adde3525a8..8fdcb4d25f7398aad76f907be60c146413667353 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
-@@ -218,9 +218,9 @@ public abstract class LivingEntity extends Entity implements Attackable {
+@@ -228,9 +228,9 @@ public abstract class LivingEntity extends Entity implements Attackable {
protected int deathScore;
public float lastHurt;
public boolean jumping;
@@ -2804,15 +2601,7 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879
protected int lerpSteps;
protected double lerpX;
protected double lerpY;
-@@ -253,6 +253,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
- protected boolean skipDropExperience;
- // CraftBukkit start
- public int expToDrop;
-+ public float safeFallDistance = 3.0F; // Purpur
- public boolean forceDrops;
- public ArrayList drops = new ArrayList<>(); // Paper - Restore vanilla drops behavior
- public final org.bukkit.craftbukkit.attribute.CraftAttributeMap craftAttributes;
-@@ -262,6 +263,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
+@@ -273,6 +273,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
public org.bukkit.craftbukkit.entity.CraftLivingEntity getBukkitLivingEntity() { return (org.bukkit.craftbukkit.entity.CraftLivingEntity) super.getBukkitEntity(); } // Paper
public boolean silentDeath = false; // Paper - mark entity as dying silently for cancellable death event
public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Friction API
@@ -2820,17 +2609,17 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879
@Override
public float getBukkitYaw() {
-@@ -286,7 +288,8 @@ public abstract class LivingEntity extends Entity implements Attackable {
- this.effectsDirty = true;
+@@ -299,7 +300,8 @@ public abstract class LivingEntity extends Entity implements Attackable {
this.useItem = ItemStack.EMPTY;
this.lastClimbablePos = Optional.empty();
+ this.appliedScale = 1.0F;
- this.attributes = new AttributeMap(DefaultAttributes.getSupplier(type));
+ this.attributes = new AttributeMap(DefaultAttributes.getSupplier(type), this); // Purpur
+ this.initAttributes(); // Purpur
this.craftAttributes = new CraftAttributeMap(this.attributes); // CraftBukkit
// CraftBukkit - setHealth(getMaxHealth()) inlined and simplified to skip the instanceof check for EntityPlayer, as getBukkitEntity() is not initialized in constructor
this.entityData.set(LivingEntity.DATA_HEALTH_ID, (float) this.getAttribute(Attributes.MAX_HEALTH).getValue());
-@@ -302,6 +305,8 @@ public abstract class LivingEntity extends Entity implements Attackable {
+@@ -314,6 +316,8 @@ public abstract class LivingEntity extends Entity implements Attackable {
this.brain = this.makeBrain(new Dynamic(dynamicopsnbt, (Tag) dynamicopsnbt.createMap((Map) ImmutableMap.of(dynamicopsnbt.createString("memories"), (Tag) dynamicopsnbt.emptyMap()))));
}
@@ -2839,33 +2628,15 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879
public Brain> getBrain() {
return this.brain;
}
-@@ -337,6 +342,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
+@@ -349,6 +353,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
public static AttributeSupplier.Builder createLivingAttributes() {
- return AttributeSupplier.builder().add(Attributes.MAX_HEALTH).add(Attributes.KNOCKBACK_RESISTANCE).add(Attributes.MOVEMENT_SPEED).add(Attributes.ARMOR).add(Attributes.ARMOR_TOUGHNESS).add(Attributes.MAX_ABSORPTION);
+ return AttributeSupplier.builder().add(Attributes.MAX_HEALTH).add(Attributes.KNOCKBACK_RESISTANCE).add(Attributes.MOVEMENT_SPEED).add(Attributes.ARMOR).add(Attributes.ARMOR_TOUGHNESS).add(Attributes.MAX_ABSORPTION).add(Attributes.STEP_HEIGHT).add(Attributes.SCALE).add(Attributes.GRAVITY).add(Attributes.SAFE_FALL_DISTANCE).add(Attributes.FALL_DAMAGE_MULTIPLIER).add(Attributes.JUMP_STRENGTH);
}
+ public boolean shouldSendAttribute(Attribute attribute) { return true; } // Purpur
@Override
protected void checkFallDamage(double heightDifference, boolean onGround, BlockState state, BlockPos landedPosition) {
-@@ -349,7 +355,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
- this.tryAddSoulSpeed();
- }
-
-- if (!this.level().isClientSide && this.fallDistance > 3.0F && onGround && !state.isAir()) {
-+ if (!this.level().isClientSide && this.fallDistance > this.safeFallDistance && onGround && !state.isAir()) { // Purpur
- double d1 = this.getX();
- double d2 = this.getY();
- double d3 = this.getZ();
-@@ -364,7 +370,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
- d3 = (double) landedPosition.getZ() + 0.5D + d5 / d6 * 0.5D;
- }
-
-- float f = (float) Mth.ceil(this.fallDistance - 3.0F);
-+ float f = (float) Mth.ceil(this.fallDistance - this.safeFallDistance); // Purpur
- double d7 = Math.min((double) (0.2F + f / 15.0F), 2.5D);
- int i = (int) (150.0D * d7);
-
-@@ -424,6 +430,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
+@@ -437,6 +442,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
double d1 = this.level().getWorldBorder().getDamagePerBlock();
if (d1 > 0.0D) {
@@ -2873,7 +2644,7 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879
this.hurt(this.damageSources().outOfBorder(), (float) Math.max(1, Mth.floor(-d0 * d1)));
}
}
-@@ -435,7 +442,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
+@@ -448,7 +454,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
if (flag1) {
this.setAirSupply(this.decreaseAirSupply(this.getAirSupply()));
@@ -2882,7 +2653,7 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879
this.setAirSupply(0);
Vec3 vec3d = this.getDeltaMovement();
-@@ -447,7 +454,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
+@@ -460,7 +466,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
this.level().addParticle(ParticleTypes.BUBBLE, this.getX() + d2, this.getY() + d3, this.getZ() + d4, vec3d.x, vec3d.y, vec3d.z);
}
@@ -2891,7 +2662,7 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879
}
}
-@@ -804,6 +811,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
+@@ -835,6 +841,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
dataresult.resultOrPartial(logger::error).ifPresent((nbtbase) -> {
nbt.put("Brain", nbtbase);
});
@@ -2899,7 +2670,7 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879
}
@Override
-@@ -890,6 +898,11 @@ public abstract class LivingEntity extends Entity implements Attackable {
+@@ -922,6 +929,11 @@ public abstract class LivingEntity extends Entity implements Attackable {
this.brain = this.makeBrain(new Dynamic(NbtOps.INSTANCE, nbt.get("Brain")));
}
@@ -2911,21 +2682,22 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879
}
// CraftBukkit start
-@@ -1033,10 +1046,31 @@ public abstract class LivingEntity extends Entity implements Attackable {
-
+@@ -1056,9 +1068,28 @@ public abstract class LivingEntity extends Entity implements Attackable {
if (entity != null) {
EntityType> entitytypes = entity.getType();
-+ // Gale start - Petal - reduce skull ItemStack lookups for reduced visibility
+
+- if (entitytypes == EntityType.SKELETON && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.SKELETON_SKULL) || entitytypes == EntityType.ZOMBIE && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.ZOMBIE_HEAD) || entitytypes == EntityType.PIGLIN && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.PIGLIN_HEAD) || entitytypes == EntityType.PIGLIN_BRUTE && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.PIGLIN_HEAD) || entitytypes == EntityType.CREEPER && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.CREEPER_HEAD)) { // Gale - Petal - reduce skull ItemStack lookups for reduced visibility
+- d0 *= 0.5D;
+ // Purpur start
-+ if (entitytypes == EntityType.SKELETON && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.SKELETON_SKULL)) {
++ if (entitytypes == EntityType.SKELETON && itemstack.is(Items.SKELETON_SKULL)) {
+ d0 *= entity.level().purpurConfig.skeletonHeadVisibilityPercent;
-+ } else if (entitytypes == EntityType.ZOMBIE && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.ZOMBIE_HEAD)) {
++ } else if (entitytypes == EntityType.ZOMBIE && itemstack.is(Items.ZOMBIE_HEAD)) {
+ d0 *= entity.level().purpurConfig.zombieHeadVisibilityPercent;
-+ } else if (entitytypes == EntityType.CREEPER && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.CREEPER_HEAD)) {
++ } else if (entitytypes == EntityType.CREEPER && itemstack.is(Items.CREEPER_HEAD)) {
+ d0 *= entity.level().purpurConfig.creeperHeadVisibilityPercent;
-+ } else if ((entitytypes == EntityType.PIGLIN || entitytypes == EntityType.PIGLIN_BRUTE) && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.PIGLIN_HEAD)) {
++ } else if ((entitytypes == EntityType.PIGLIN || entitytypes == EntityType.PIGLIN_BRUTE) && itemstack.is(Items.PIGLIN_HEAD)) {
+ d0 *= entity.level().purpurConfig.piglinHeadVisibilityPercent;
-+ }
+ }
+ // Purpur end
+
+ // Purpur start
@@ -2936,24 +2708,20 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879
+ d0 *= this.level().purpurConfig.mobsBlindnessMultiplier;
+ }
+ }
-
-- if (entitytypes == EntityType.SKELETON && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.SKELETON_SKULL) || entitytypes == EntityType.ZOMBIE && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.ZOMBIE_HEAD) || entitytypes == EntityType.PIGLIN && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.PIGLIN_HEAD) || entitytypes == EntityType.PIGLIN_BRUTE && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.PIGLIN_HEAD) || entitytypes == EntityType.CREEPER && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.CREEPER_HEAD)) { // Gale - Petal - reduce skull ItemStack lookups for reduced visibility
-- d0 *= 0.5D;
- }
++ }
+ // Purpur end
-+ // Gale end
}
return d0;
-@@ -1096,6 +1130,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
+@@ -1117,6 +1148,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
for (flag = false; iterator.hasNext(); flag = true) {
// CraftBukkit start
MobEffectInstance effect = (MobEffectInstance) iterator.next();
-+ if (cause == EntityPotionEffectEvent.Cause.MILK && !this.level().purpurConfig.milkClearsBeneficialEffects && effect.getEffect().isBeneficial()) continue; // Purpur
++ if (cause == EntityPotionEffectEvent.Cause.MILK && !this.level().purpurConfig.milkClearsBeneficialEffects && effect.getEffect().value().isBeneficial()) continue; // Purpur
EntityPotionEffectEvent event = CraftEventFactory.callEntityPotionEffectChangeEvent(this, effect, null, cause, EntityPotionEffectEvent.Action.CLEARED);
if (event.isCancelled()) {
continue;
-@@ -1514,13 +1549,13 @@ public abstract class LivingEntity extends Entity implements Attackable {
+@@ -1533,13 +1565,13 @@ public abstract class LivingEntity extends Entity implements Attackable {
if (entity1 instanceof net.minecraft.world.entity.player.Player) {
net.minecraft.world.entity.player.Player entityhuman = (net.minecraft.world.entity.player.Player) entity1;
@@ -2969,7 +2737,7 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879
LivingEntity entityliving2 = entitywolf.getOwner();
if (entityliving2 instanceof net.minecraft.world.entity.player.Player) {
-@@ -1628,6 +1663,18 @@ public abstract class LivingEntity extends Entity implements Attackable {
+@@ -1654,6 +1686,18 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
}
@@ -2988,7 +2756,7 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879
org.bukkit.inventory.EquipmentSlot handSlot = (hand != null) ? org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand) : null;
EntityResurrectEvent event = new EntityResurrectEvent((org.bukkit.entity.LivingEntity) this.getBukkitEntity(), handSlot);
event.setCancelled(itemstack == null);
-@@ -1794,7 +1841,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
+@@ -1820,7 +1864,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
boolean flag = false;
if (this.dead && adversary instanceof WitherBoss) { // Paper
@@ -2997,7 +2765,7 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879
BlockPos blockposition = this.blockPosition();
BlockState iblockdata = Blocks.WITHER_ROSE.defaultBlockState();
-@@ -1840,6 +1887,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
+@@ -1866,6 +1910,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
this.dropEquipment(); // CraftBukkit - from below
if (this.shouldDropLoot() && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
@@ -3005,7 +2773,7 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879
this.dropFromLootTable(source, flag);
// Paper start
final boolean prev = this.clearEquipmentSlots;
-@@ -1848,6 +1896,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
+@@ -1874,6 +1919,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
// Paper end
this.dropCustomDeathLoot(source, i, flag);
this.clearEquipmentSlots = prev; // Paper
@@ -3013,37 +2781,29 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879
}
// CraftBukkit start - Call death event // Paper start - call advancement triggers with correct entity equipment
org.bukkit.event.entity.EntityDeathEvent deathEvent = CraftEventFactory.callEntityDeathEvent(this, this.drops, () -> {
-@@ -2131,7 +2180,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
- MobEffectInstance mobeffect = this.getEffect(MobEffects.JUMP);
- float f2 = mobeffect == null ? 0.0F : (float) (mobeffect.getAmplifier() + 1);
-
-- return Mth.ceil((fallDistance - 3.0F - f2) * damageMultiplier);
-+ return Mth.ceil((fallDistance - this.safeFallDistance - f2) * damageMultiplier); // Purpur
- }
- }
-
-@@ -2354,6 +2403,20 @@ public abstract class LivingEntity extends Entity implements Attackable {
+@@ -2407,6 +2453,21 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
}
-+ // Purpur start
-+ if (damagesource.getEntity() instanceof net.minecraft.world.entity.player.Player player && damagesource.getEntity().level().purpurConfig.creativeOnePunch) {
-+ if (player.isCreative()) {
-+ double attackDamage = 0;
-+ for (AttributeModifier modifier : player.getMainHandItem().getAttributeModifiers(EquipmentSlot.MAINHAND).get(Attributes.ATTACK_DAMAGE)) {
-+ attackDamage += modifier.getAmount();
-+ }
-+ if (attackDamage == 0) {
-+ this.setHealth(0);
-+ }
-+ }
-+ }
-+ // Purpur end
++ // Purpur start
++ if (damagesource.getEntity() instanceof net.minecraft.world.entity.player.Player player && damagesource.getEntity().level().purpurConfig.creativeOnePunch) {
++ if (player.isCreative()) {
++ double attackDamage;
++ net.minecraft.world.item.component.ItemAttributeModifiers itemattributemodifiers = player.getMainHandItem().getOrDefault(DataComponents.ATTRIBUTE_MODIFIERS, net.minecraft.world.item.component.ItemAttributeModifiers.EMPTY);
++
++ attackDamage = itemattributemodifiers.compute(player.getAttributeBaseValue(Attributes.ATTACK_DAMAGE), EquipmentSlot.MAINHAND);
++
++ if (attackDamage == 1.0D) {
++ this.setHealth(0);
++ }
++ }
++ }
++ // Purpur end
+
if (f > 0 || !human) {
if (human) {
// PAIL: Be sure to drag all this code from the EntityHuman subclass each update.
-@@ -2574,7 +2637,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
+@@ -2630,7 +2691,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
@Override
protected void onBelowWorld() {
@@ -3052,16 +2812,16 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879
}
protected void updateSwingTime() {
-@@ -2768,7 +2831,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
+@@ -2825,7 +2886,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
protected long lastJumpTime = 0L; // Paper - Prevent excessive velocity through repeated crits
- protected void jumpFromGround() {
+ public void jumpFromGround() { // Purpur - protected -> public
- Vec3 vec3d = this.getDeltaMovement();
- // Paper start - Prevent excessive velocity through repeated crits
- long time = System.nanoTime();
-@@ -2920,6 +2983,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
+ float f = this.getJumpPower();
+
+ if (f > 1.0E-5F) {
+@@ -2985,6 +3046,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
if (f3 > 0.0F) {
this.playSound(this.getFallDamageSound((int) f3), 1.0F, 1.0F);
@@ -3069,7 +2829,7 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879
this.hurt(this.damageSources().flyIntoWall(), f3);
}
}
-@@ -3530,8 +3594,10 @@ public abstract class LivingEntity extends Entity implements Attackable {
+@@ -3522,8 +3584,10 @@ public abstract class LivingEntity extends Entity implements Attackable {
this.pushEntities();
// Paper start - Add EntityMoveEvent
@@ -3082,7 +2842,7 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879
Location from = new Location(this.level().getWorld(), this.xo, this.yo, this.zo, this.yRotO, this.xRotO);
Location to = new Location(this.level().getWorld(), this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot());
io.papermc.paper.event.entity.EntityMoveEvent event = new io.papermc.paper.event.entity.EntityMoveEvent(this.getBukkitLivingEntity(), from, to.clone());
-@@ -3541,12 +3607,48 @@ public abstract class LivingEntity extends Entity implements Attackable {
+@@ -3533,12 +3597,48 @@ public abstract class LivingEntity extends Entity implements Attackable {
this.absMoveTo(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ(), event.getTo().getYaw(), event.getTo().getPitch());
}
}
@@ -3123,7 +2883,7 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879
+ flag = false;
+ }
+ if (flag) {
-+ this.setSecondsOnFire(8);
++ this.igniteForSeconds(8);
+ }
+ }
+ }
@@ -3131,11 +2891,11 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879
}
public boolean isSensitiveToWater() {
-@@ -3567,7 +3669,16 @@ public abstract class LivingEntity extends Entity implements Attackable {
+@@ -3559,7 +3659,16 @@ public abstract class LivingEntity extends Entity implements Attackable {
int j = i / 10;
if (j % 2 == 0) {
-- itemstack.hurtAndBreak(1, this, (entityliving) -> {
+- itemstack.hurtAndBreak(1, this, EquipmentSlot.CHEST);
+ // Purpur start
+ int damage = level().purpurConfig.elytraDamagePerSecond;
+ if (level().purpurConfig.elytraDamageMultiplyBySpeed > 0) {
@@ -3144,24 +2904,24 @@ index 6e1598826bdf173573ad17e51ec396cfa65b524d..a37244bdd21c27d15e0ce6731c28f879
+ damage *= (int) speed;
+ }
+ }
-+ itemstack.hurtAndBreak(damage, this, (entityliving) -> {
++ itemstack.hurtAndBreak(damage, this, EquipmentSlot.CHEST);
+ // Purpur end
- entityliving.broadcastBreakEvent(EquipmentSlot.CHEST);
- });
}
+
+ this.gameEvent(GameEvent.ELYTRA_GLIDE);
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
-index 13f8fc584d356cd89021266b55374fab4ee344cf..61f7a9f761a04011b2fa4caa7fef424ccb88793d 100644
+index ad08008a9d3f50bab1ae05603aab4cf3be8e2d54..446237ffe4f40cf287c57c28a9866dfea39ed1bb 100644
--- a/src/main/java/net/minecraft/world/entity/Mob.java
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
-@@ -66,6 +66,7 @@ import net.minecraft.world.item.ProjectileWeaponItem;
- import net.minecraft.world.item.SpawnEggItem;
+@@ -74,6 +74,7 @@ import net.minecraft.world.item.SpawnEggItem;
import net.minecraft.world.item.SwordItem;
+ import net.minecraft.world.item.component.ItemAttributeModifiers;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
+import net.minecraft.world.item.enchantment.Enchantments;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.Level;
-@@ -136,6 +137,7 @@ public abstract class Mob extends LivingEntity implements Targeting {
+@@ -150,6 +151,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
private BlockPos restrictCenter;
private float restrictRadius;
@@ -3169,7 +2929,7 @@ index 13f8fc584d356cd89021266b55374fab4ee344cf..61f7a9f761a04011b2fa4caa7fef424c
public boolean aware = true; // CraftBukkit
protected Mob(EntityType extends Mob> type, Level world) {
-@@ -151,8 +153,8 @@ public abstract class Mob extends LivingEntity implements Targeting {
+@@ -166,8 +168,8 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
this.goalSelector = new GoalSelector();
this.targetSelector = new GoalSelector();
// Gale end - Purpur - remove vanilla profiler
@@ -3180,7 +2940,7 @@ index 13f8fc584d356cd89021266b55374fab4ee344cf..61f7a9f761a04011b2fa4caa7fef424c
this.jumpControl = new JumpControl(this);
this.bodyRotationControl = this.createBodyControl();
this.navigation = this.createNavigation(world);
-@@ -327,6 +329,7 @@ public abstract class Mob extends LivingEntity implements Targeting {
+@@ -341,6 +343,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
entityliving = null;
}
}
@@ -3188,7 +2948,7 @@ index 13f8fc584d356cd89021266b55374fab4ee344cf..61f7a9f761a04011b2fa4caa7fef424c
this.target = entityliving;
return true;
// CraftBukkit end
-@@ -371,8 +374,28 @@ public abstract class Mob extends LivingEntity implements Targeting {
+@@ -380,8 +383,28 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
this.resetAmbientSoundTime();
this.playAmbientSound();
}
@@ -3215,9 +2975,9 @@ index 13f8fc584d356cd89021266b55374fab4ee344cf..61f7a9f761a04011b2fa4caa7fef424c
+ // Purpur end
+
@Override
- protected void playHurtSound(DamageSource source) {
+ protected void playHurtSound(DamageSource damageSource) {
this.resetAmbientSoundTime();
-@@ -562,6 +585,7 @@ public abstract class Mob extends LivingEntity implements Targeting {
+@@ -584,6 +607,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
}
nbt.putBoolean("Bukkit.Aware", this.aware); // CraftBukkit
@@ -3225,7 +2985,7 @@ index 13f8fc584d356cd89021266b55374fab4ee344cf..61f7a9f761a04011b2fa4caa7fef424c
}
@Override
-@@ -632,6 +656,11 @@ public abstract class Mob extends LivingEntity implements Targeting {
+@@ -668,6 +692,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
this.aware = nbt.getBoolean("Bukkit.Aware");
}
// CraftBukkit end
@@ -3237,7 +2997,7 @@ index 13f8fc584d356cd89021266b55374fab4ee344cf..61f7a9f761a04011b2fa4caa7fef424c
}
@Override
-@@ -675,7 +704,7 @@ public abstract class Mob extends LivingEntity implements Targeting {
+@@ -718,7 +747,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
@Override
public void aiStep() {
super.aiStep();
@@ -3246,7 +3006,7 @@ index 13f8fc584d356cd89021266b55374fab4ee344cf..61f7a9f761a04011b2fa4caa7fef424c
Vec3i baseblockposition = this.getPickupReach();
List list = this.level().getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate((double) baseblockposition.getX(), (double) baseblockposition.getY(), (double) baseblockposition.getZ()));
Iterator iterator = list.iterator();
-@@ -1159,6 +1188,12 @@ public abstract class Mob extends LivingEntity implements Targeting {
+@@ -1289,6 +1318,12 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
}
@@ -3259,24 +3019,24 @@ index 13f8fc584d356cd89021266b55374fab4ee344cf..61f7a9f761a04011b2fa4caa7fef424c
@Nullable
public static Item getEquipmentForSlot(EquipmentSlot equipmentSlot, int equipmentLevel) {
switch (equipmentSlot) {
-@@ -1253,7 +1288,7 @@ public abstract class Mob extends LivingEntity implements Targeting {
+@@ -1383,7 +1418,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
RandomSource randomsource = world.getRandom();
- this.getAttribute(Attributes.FOLLOW_RANGE).addPermanentModifier(new AttributeModifier("Random spawn bonus", randomsource.triangle(0.0D, 0.11485000000000001D), AttributeModifier.Operation.MULTIPLY_BASE));
-- if (randomsource.nextFloat() < 0.05F) {
-+ if (randomsource.nextFloat() < world.getLevel().purpurConfig.entityLeftHandedChance) { // Purpur
- this.setLeftHanded(true);
- } else {
- this.setLeftHanded(false);
-@@ -1301,6 +1336,7 @@ public abstract class Mob extends LivingEntity implements Targeting {
+ this.getAttribute(Attributes.FOLLOW_RANGE).addPermanentModifier(new AttributeModifier("Random spawn bonus", randomsource.triangle(0.0D, 0.11485000000000001D), AttributeModifier.Operation.ADD_MULTIPLIED_BASE));
+- this.setLeftHanded(randomsource.nextFloat() < 0.05F);
++ this.setLeftHanded(randomsource.nextFloat() < world.getLevel().purpurConfig.entityLeftHandedChance); // Purpur
+ return entityData;
+ }
+
+@@ -1430,6 +1465,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
if (!this.isAlive()) {
return InteractionResult.PASS;
} else if (this.getLeashHolder() == player) {
+ if (hand == InteractionHand.OFF_HAND && (level().purpurConfig.villagerCanBeLeashed || level().purpurConfig.wanderingTraderCanBeLeashed) && this instanceof net.minecraft.world.entity.npc.AbstractVillager) return InteractionResult.CONSUME; // Purpur
// CraftBukkit start - fire PlayerUnleashEntityEvent
// Paper start - Expand EntityUnleashEvent
- org.bukkit.event.player.PlayerUnleashEntityEvent event = CraftEventFactory.callPlayerUnleashEntityEvent(this, player, hand, !player.getAbilities().instabuild);
-@@ -1375,7 +1411,7 @@ public abstract class Mob extends LivingEntity implements Targeting {
+ org.bukkit.event.player.PlayerUnleashEntityEvent event = CraftEventFactory.callPlayerUnleashEntityEvent(this, player, hand, !player.hasInfiniteMaterials());
+@@ -1505,7 +1541,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
protected void onOffspringSpawnedFromEgg(Player player, Mob child) {}
protected InteractionResult mobInteract(Player player, InteractionHand hand) {
@@ -3285,7 +3045,7 @@ index 13f8fc584d356cd89021266b55374fab4ee344cf..61f7a9f761a04011b2fa4caa7fef424c
}
public boolean isWithinRestriction() {
-@@ -1686,6 +1722,7 @@ public abstract class Mob extends LivingEntity implements Targeting {
+@@ -1820,6 +1856,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
this.setLastHurtMob(target);
}
@@ -3293,7 +3053,7 @@ index 13f8fc584d356cd89021266b55374fab4ee344cf..61f7a9f761a04011b2fa4caa7fef424c
return flag;
}
-@@ -1711,28 +1748,7 @@ public abstract class Mob extends LivingEntity implements Targeting {
+@@ -1829,28 +1866,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
// Gale end - JettPack - optimize sun burn tick - cache eye blockpos
public boolean isSunBurnTick() {
@@ -3323,7 +3083,7 @@ index 13f8fc584d356cd89021266b55374fab4ee344cf..61f7a9f761a04011b2fa4caa7fef424c
}
@Override
-@@ -1780,4 +1796,56 @@ public abstract class Mob extends LivingEntity implements Targeting {
+@@ -1898,4 +1914,56 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
return itemmonsteregg == null ? null : new ItemStack(itemmonsteregg);
}
@@ -3394,13 +3154,13 @@ index 2ee48ac3b665db2b02bcb1a30ec972d43a3725b0..59e8f5431ce5026209e1428b5fa5b548
}
// Paper end - custom shear drops
diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
-index 12458621cadf5d186307c8b08edcb48f9c70c4f0..94082358b0dd573e09e61b167af2a54f8aa4bb2a 100644
+index 665fbe3362dcd9de4bd290b71a1b1f2fed218eeb..894082d9a8e2aa05f86948bfd335090f37a4ba07 100644
--- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
+++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
-@@ -27,14 +27,22 @@ public class AttributeMap {
- // Gale end - Lithium - replace AI attributes with optimized collections
+@@ -23,14 +23,22 @@ public class AttributeMap {
+ private final Set dirtyAttributes = new ObjectOpenHashSet<>();
private final AttributeSupplier supplier;
- private final java.util.function.Function createInstance; // Gale - Airplane - reduce entity allocations
+ private final java.util.function.Function, AttributeInstance> createInstance; // Gale - Airplane - reduce entity allocations
+ private final net.minecraft.world.entity.LivingEntity entity; // Purpur
public AttributeMap(AttributeSupplier defaultAttributes) {
@@ -3412,29 +3172,29 @@ index 12458621cadf5d186307c8b08edcb48f9c70c4f0..94082358b0dd573e09e61b167af2a54f
+ this.entity = entity;
+ // Purpur end
this.supplier = defaultAttributes;
- this.createInstance = attribute -> this.supplier.createInstance(this::onAttributeModified, attribute); // Gale - Airplane - reduce entity allocations
+ this.createInstance = attributex -> this.supplier.createInstance(this::onAttributeModified, attributex); // Gale - Airplane - reduce entity allocations
}
private void onAttributeModified(AttributeInstance instance) {
-- if (instance.getAttribute().isClientSyncable()) {
-+ if (instance.getAttribute().isClientSyncable() && (entity == null || entity.shouldSendAttribute(instance.getAttribute()))) { // Purpur
+- if (instance.getAttribute().value().isClientSyncable()) {
++ if (instance.getAttribute().value().isClientSyncable() && (entity == null || entity.shouldSendAttribute(instance.getAttribute().value()))) { // Purpur
this.dirtyAttributes.add(instance);
}
}
-@@ -44,7 +52,7 @@ public class AttributeMap {
+@@ -40,7 +48,7 @@ public class AttributeMap {
}
public Collection getSyncableAttributes() {
-- return this.attributes.values().stream().filter(attribute -> attribute.getAttribute().isClientSyncable()).collect(Collectors.toList());
-+ return this.attributes.values().stream().filter(attribute -> attribute.getAttribute().isClientSyncable() && (entity == null || entity.shouldSendAttribute(attribute.getAttribute()))).collect(Collectors.toList()); // Purpur
+- return this.attributes.values().stream().filter(attribute -> attribute.getAttribute().value().isClientSyncable()).collect(Collectors.toList());
++ return this.attributes.values().stream().filter(attribute -> attribute.getAttribute().value().isClientSyncable() && (entity == null || entity.shouldSendAttribute(attribute.getAttribute().value()))).collect(Collectors.toList()); // Purpur
}
@Nullable
diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java b/src/main/java/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java
-index c92583b6d1527db32f4a644f30c8f8468e9e2fc2..b8f65dc8f0db4bbe5f9c223e4ba129738fbfd795 100644
+index 10a1434313b11dae8210484583c6bf3b627416f7..35af18f371b3beaf81fcdca79fefe85e0a862b50 100644
--- a/src/main/java/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java
+++ b/src/main/java/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java
-@@ -123,7 +123,7 @@ public class DefaultAttributes {
+@@ -129,7 +129,7 @@ public class DefaultAttributes {
.put(EntityType.OCELOT, Ocelot.createAttributes().build())
.put(EntityType.PANDA, Panda.createAttributes().build())
.put(EntityType.PARROT, Parrot.createAttributes().build())
@@ -3456,7 +3216,7 @@ index f0703302e7dbbda88de8c648d20d87c55ed9b1e0..a913ebabaa5f443afa987b972355a8f8
}
}
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java b/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
-index b5242f2d450f863a3eb774d8a14bb00cbe699a16..4d2b6e69ed98aca98ffc50fefc6e535c1afb759d 100644
+index b5242f2d450f863a3eb774d8a14bb00cbe699a16..c72ce539f3e339c6e87138e744f033d2143abc7a 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
@@ -82,7 +82,7 @@ public class AcquirePoi {
@@ -3464,15 +3224,15 @@ index b5242f2d450f863a3eb774d8a14bb00cbe699a16..4d2b6e69ed98aca98ffc50fefc6e535c
// Paper start - optimise POI access
java.util.List, BlockPos>> poiposes = new java.util.ArrayList<>();
- io.papermc.paper.util.PoiAccess.findNearestPoiPositions(poiManager, poiPredicate, predicate2, entity.blockPosition(), 48, 48*48, PoiManager.Occupancy.HAS_SPACE, false, 5, poiposes);
-+ io.papermc.paper.util.PoiAccess.findNearestPoiPositions(poiManager, poiPredicate, predicate2, entity.blockPosition(), world.purpurConfig.villagerAcquirePoiSearchRadius, world.purpurConfig.villagerAcquirePoiSearchRadius*world.purpurConfig.villagerAcquirePoiSearchRadius, PoiManager.Occupancy.HAS_SPACE, false, 5, poiposes); // Purpur
++ io.papermc.paper.util.PoiAccess.findNearestPoiPositions(poiManager, poiPredicate, predicate2, entity.blockPosition(), world.purpurConfig.villagerAcquirePoiSearchRadius, world.purpurConfig.villagerAcquirePoiSearchRadius*world.purpurConfig.villagerAcquirePoiSearchRadius, PoiManager.Occupancy.HAS_SPACE, false, 5, poiposes); // Purpur
Set, BlockPos>> set = new java.util.HashSet<>(poiposes);
// Paper end - optimise POI access
Path path = findPathToPois(entity, set);
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java b/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java
-index d3a2a6dee2d83b3df0ddc521c080f7d72b709461..a1acc479c9d6a838e3180da3ac8a3a02d22db5c1 100644
+index 2ade08d1466660ee1787fa97908002ef56389712..8d4e206aa05b95b7bfec5d23496085cf55a3e1de 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java
-@@ -40,17 +40,19 @@ public class HarvestFarmland extends Behavior {
+@@ -41,17 +41,19 @@ public class HarvestFarmland extends Behavior {
private long nextOkStartTime;
private int timeWorkedSoFar;
private final List validFarmlandAroundVillager = Lists.newArrayList();
@@ -3494,7 +3254,7 @@ index d3a2a6dee2d83b3df0ddc521c080f7d72b709461..a1acc479c9d6a838e3180da3ac8a3a02
BlockPos.MutableBlockPos blockposition_mutableblockposition = entity.blockPosition().mutable();
this.validFarmlandAroundVillager.clear();
-@@ -81,6 +83,7 @@ public class HarvestFarmland extends Behavior {
+@@ -82,6 +84,7 @@ public class HarvestFarmland extends Behavior {
Block block = iblockdata.getBlock();
Block block1 = world.getBlockState(pos.below()).getBlock();
@@ -3502,7 +3262,7 @@ index d3a2a6dee2d83b3df0ddc521c080f7d72b709461..a1acc479c9d6a838e3180da3ac8a3a02
return block instanceof CropBlock && ((CropBlock) block).isMaxAge(iblockdata) || iblockdata.isAir() && block1 instanceof FarmBlock;
}
-@@ -106,20 +109,20 @@ public class HarvestFarmland extends Behavior {
+@@ -107,20 +110,20 @@ public class HarvestFarmland extends Behavior {
Block block = iblockdata.getBlock();
Block block1 = world.getBlockState(this.aboveFarmlandPos.below()).getBlock();
@@ -3526,7 +3286,7 @@ index d3a2a6dee2d83b3df0ddc521c080f7d72b709461..a1acc479c9d6a838e3180da3ac8a3a02
Item item = itemstack.getItem();
if (item instanceof BlockItem) {
-@@ -135,7 +138,7 @@ public class HarvestFarmland extends Behavior {
+@@ -136,7 +139,7 @@ public class HarvestFarmland extends Behavior {
}
if (flag) {
@@ -3536,7 +3296,7 @@ index d3a2a6dee2d83b3df0ddc521c080f7d72b709461..a1acc479c9d6a838e3180da3ac8a3a02
if (itemstack.isEmpty()) {
inventorysubcontainer.setItem(j, ItemStack.EMPTY);
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java b/src/main/java/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java
-index 42ae4d293a420f0b8eb476df6389b2e7a693895f..97c20c5b89e6d7e4ed844eff39ee55dfa8988d37 100644
+index 736f46d552d558bf0edd9a86601b5fbb6940815b..cf039181dfe0ddb3ccda44064a5d8a2f6c5c432c 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java
@@ -57,7 +57,7 @@ public class InteractWithDoor {
@@ -3579,15 +3339,15 @@ index 18dad0825616c4167a0a7555689ee64910a87e09..6945992491027d43eca4f1ca697ad45c
&& this.lookTime > 0
&& entity.getBrain().getMemory(MemoryModuleType.INTERACTION_TARGET).isPresent();
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java b/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java
-index a866e254b7faf50e2e64829a7e40db62d4d26424..753587e4d9582605951461f2bea37aff3bf28fcd 100644
+index 3232f40ef11f59091cec469f0dd40c60ee2a16e9..7db823e9edd70808c5629f0a7efd84fe40f42dd9 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java
-@@ -65,6 +65,12 @@ public class TradeWithVillager extends Behavior {
+@@ -63,6 +63,12 @@ public class TradeWithVillager extends Behavior {
throwHalfStack(entity, Villager.FOOD_POINTS_KEY_ARRAY, villager); // Gale - optimize villager data storage
}
+ // Purpur start
-+ if (world.purpurConfig.villagerClericsFarmWarts && world.purpurConfig.villagerClericFarmersThrowWarts && entity.getVillagerData().getProfession() == VillagerProfession.CLERIC && entity.getInventory().countItem(Items.NETHER_WART) > Items.NETHER_WART.getMaxStackSize() / 2) {
++ if (world.purpurConfig.villagerClericsFarmWarts && world.purpurConfig.villagerClericFarmersThrowWarts && entity.getVillagerData().getProfession() == VillagerProfession.CLERIC && entity.getInventory().countItem(Items.NETHER_WART) > Items.NETHER_WART.getDefaultMaxStackSize() / 2) {
+ throwHalfStack(entity, ImmutableSet.of(Items.NETHER_WART), villager);
+ }
+ // Purpur end
@@ -3596,10 +3356,10 @@ index a866e254b7faf50e2e64829a7e40db62d4d26424..753587e4d9582605951461f2bea37aff
if (this.trades != null && entity.getInventory().hasAnyOf(this.trades)) {
throwHalfStack(entity, this.trades, villager);
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java b/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java
-index d2917f9b215919890f28b513601863ccaced17c7..58338e240079f2de1669e8c2ce839451511feafd 100644
+index f000a6c1e61198e6dd06ae5f084d12fdf309f50a..3091d985ba9c55d404332576320718840538722e 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java
-@@ -49,8 +49,13 @@ public class VillagerGoalPackages {
+@@ -52,8 +52,13 @@ public class VillagerGoalPackages {
}
public static ImmutableList>> getWorkPackage(VillagerProfession profession, float speed) {
@@ -3615,10 +3375,10 @@ index d2917f9b215919890f28b513601863ccaced17c7..58338e240079f2de1669e8c2ce839451
} else {
workAtPoi = new WorkAtPoi();
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java b/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java
-index 0cc411dd39d981187c9e9a3c5eb8043b19a09b98..f7032f4ea55f5aca293c2640686238b7af0f9c80 100644
+index 0a608418f87b71d5d71706712e1f82da0d7e4d34..03e7ca83e4c28dfaa5b52bcb100bd542db105970 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java
-@@ -127,8 +127,10 @@ public class VillagerMakeLove extends Behavior {
+@@ -125,8 +125,10 @@ public class VillagerMakeLove extends Behavior {
return Optional.empty();
}
// Move age setting down
@@ -3632,7 +3392,7 @@ index 0cc411dd39d981187c9e9a3c5eb8043b19a09b98..f7032f4ea55f5aca293c2640686238b7
// CraftBukkit end
world.broadcastEntityEvent(entityvillager2, (byte) 12);
diff --git a/src/main/java/net/minecraft/world/entity/ai/control/MoveControl.java b/src/main/java/net/minecraft/world/entity/ai/control/MoveControl.java
-index ca02566b20dd52a59bc7b150529a1d68bc560ab0..10265fd19c90cea34372a786bb272dbcdd91b993 100644
+index c8fd5696de7c3623cdb4f498190a5c2708cf843e..e403d9dfeeaa3dcf53be790d761e7e922419efb0 100644
--- a/src/main/java/net/minecraft/world/entity/ai/control/MoveControl.java
+++ b/src/main/java/net/minecraft/world/entity/ai/control/MoveControl.java
@@ -29,6 +29,20 @@ public class MoveControl implements Control {
@@ -3734,7 +3494,7 @@ index df695b444fa2a993d381e2f197182c3e91a68502..0f4f546cd0eda4bd82b47446ae23ac32
double d = this.llama.distanceToSqr(this.llama.getCaravanHead());
if (d > 676.0) {
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java
-index 5580a396a56c6e0f364a5368985ee99b9e2be0a8..3facfd6eee17cb0b59425494c966e19833660dd2 100644
+index 6634228ef002cbef67980272a26be4a75c954116..a61abba840a55fb4fbc9716a5e05eb2778068785 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java
@@ -40,7 +40,7 @@ public class RemoveBlockGoal extends MoveToBlockGoal {
@@ -3747,7 +3507,7 @@ index 5580a396a56c6e0f364a5368985ee99b9e2be0a8..3facfd6eee17cb0b59425494c966e198
} else if (this.nextStartTick > 0) {
--this.nextStartTick;
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/RunAroundLikeCrazyGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/RunAroundLikeCrazyGoal.java
-index b0944fa1f3849dd24cd010fa0a6638f5fd7179d1..a3074ec9b430c9d0a0ef33fe353db643849fab7d 100644
+index b0944fa1f3849dd24cd010fa0a6638f5fd7179d1..d409ae987088df3d47192128401d7491aaabc87c 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/RunAroundLikeCrazyGoal.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/RunAroundLikeCrazyGoal.java
@@ -67,7 +67,7 @@ public class RunAroundLikeCrazyGoal extends Goal {
@@ -3755,7 +3515,7 @@ index b0944fa1f3849dd24cd010fa0a6638f5fd7179d1..a3074ec9b430c9d0a0ef33fe353db643
int j = this.horse.getMaxTemper();
- if (j > 0 && this.horse.getRandom().nextInt(j) < i && !CraftEventFactory.callEntityTameEvent(this.horse, ((CraftHumanEntity) this.horse.getBukkitEntity().getPassenger()).getHandle()).isCancelled()) { // CraftBukkit - fire EntityTameEvent
-+ if ((this.horse.level().purpurConfig.alwaysTameInCreative && ((Player) entity).getAbilities().instabuild) || (j > 0 && this.horse.getRandom().nextInt(j) < i && !CraftEventFactory.callEntityTameEvent(this.horse, ((CraftHumanEntity) this.horse.getBukkitEntity().getPassenger()).getHandle()).isCancelled())) { // CraftBukkit - fire EntityTameEvent // Purpur
++ if ((this.horse.level().purpurConfig.alwaysTameInCreative && entityhuman.hasInfiniteMaterials()) || (j > 0 && this.horse.getRandom().nextInt(j) < i && !CraftEventFactory.callEntityTameEvent(this.horse, ((CraftHumanEntity) this.horse.getBukkitEntity().getPassenger()).getHandle()).isCancelled())) { // CraftBukkit - fire EntityTameEvent // Purpur
this.horse.tameWithName(entityhuman);
return;
}
@@ -3779,10 +3539,10 @@ index 137ec75ee803789deb7b1ca93dd9369c9af362b9..ca95d25af3e9a0536868b0c7fd8e7d2f
}
}
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/TemptGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/TemptGoal.java
-index 0d9b194781d152e842c9a4b8d6f23d307b2e4452..00cf59524477ec79d4354cc403fc3e75a63b81a0 100644
+index 13f8c2cb42334ba3b573ca44ace1d3df76e41ff7..baca552e52c728867fcb0527b6c3eb394b2b9c7f 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/TemptGoal.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/TemptGoal.java
-@@ -62,7 +62,7 @@ public class TemptGoal extends Goal {
+@@ -64,7 +64,7 @@ public class TemptGoal extends Goal {
}
private boolean shouldFollow(LivingEntity entity) {
@@ -3847,18 +3607,10 @@ index 68bc8699a9389d118411ea7134ea0e0588adf8dc..1731147abd53ca2149683ea593e96523
if (baseEntity == null) {
if (this.isCombat && (!targetEntity.canBeSeenAsEnemy() || targetEntity.level().getDifficulty() == Difficulty.PEACEFUL)) {
diff --git a/src/main/java/net/minecraft/world/entity/ambient/Bat.java b/src/main/java/net/minecraft/world/entity/ambient/Bat.java
-index 4f7e6f5c7b38ad19beeb5010b3a385c2efc5ef4a..51a8c84f13268d97b1d052db1efe464dad395c6f 100644
+index f223e369dd8d781e32e1f06572b2ae717afd6f32..f1a3e05d993e87cb93e6916d2c5a130d7d852b6a 100644
--- a/src/main/java/net/minecraft/world/entity/ambient/Bat.java
+++ b/src/main/java/net/minecraft/world/entity/ambient/Bat.java
-@@ -19,6 +19,7 @@ import net.minecraft.world.entity.EntityDimensions;
- import net.minecraft.world.entity.EntityType;
- import net.minecraft.world.entity.Mob;
- import net.minecraft.world.entity.MobSpawnType;
-+import net.minecraft.world.entity.MoverType;
- import net.minecraft.world.entity.Pose;
- import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
- import net.minecraft.world.entity.ai.attributes.Attributes;
-@@ -46,12 +47,59 @@ public class Bat extends AmbientCreature {
+@@ -44,12 +44,59 @@ public class Bat extends AmbientCreature {
public Bat(EntityType extends Bat> type, Level world) {
super(type, world);
@@ -3909,7 +3661,7 @@ index 4f7e6f5c7b38ad19beeb5010b3a385c2efc5ef4a..51a8c84f13268d97b1d052db1efe464d
+ float speed = (float) getAttributeValue(Attributes.FLYING_SPEED) * 2;
+ setSpeed(speed);
+ Vec3 mot = getDeltaMovement();
-+ move(MoverType.SELF, mot.multiply(speed, 0.25, speed));
++ move(net.minecraft.world.entity.MoverType.SELF, mot.multiply(speed, 0.25, speed));
+ setDeltaMovement(mot.scale(0.9D));
+ }
+ }
@@ -3918,7 +3670,7 @@ index 4f7e6f5c7b38ad19beeb5010b3a385c2efc5ef4a..51a8c84f13268d97b1d052db1efe464d
@Override
public boolean isFlapping() {
return !this.isResting() && (float) this.tickCount % 10.0F == 0.0F;
-@@ -101,7 +149,7 @@ public class Bat extends AmbientCreature {
+@@ -99,7 +146,7 @@ public class Bat extends AmbientCreature {
protected void pushEntities() {}
public static AttributeSupplier.Builder createAttributes() {
@@ -3927,7 +3679,7 @@ index 4f7e6f5c7b38ad19beeb5010b3a385c2efc5ef4a..51a8c84f13268d97b1d052db1efe464d
}
public boolean isResting() {
-@@ -134,6 +182,14 @@ public class Bat extends AmbientCreature {
+@@ -132,6 +179,14 @@ public class Bat extends AmbientCreature {
@Override
protected void customServerAiStep() {
@@ -3942,7 +3694,7 @@ index 4f7e6f5c7b38ad19beeb5010b3a385c2efc5ef4a..51a8c84f13268d97b1d052db1efe464d
super.customServerAiStep();
BlockPos blockposition = this.blockPosition();
BlockPos blockposition1 = blockposition.above();
-@@ -212,6 +268,28 @@ public class Bat extends AmbientCreature {
+@@ -210,6 +265,28 @@ public class Bat extends AmbientCreature {
}
}
@@ -3972,10 +3724,10 @@ index 4f7e6f5c7b38ad19beeb5010b3a385c2efc5ef4a..51a8c84f13268d97b1d052db1efe464d
public void readAdditionalSaveData(CompoundTag nbt) {
super.readAdditionalSaveData(nbt);
diff --git a/src/main/java/net/minecraft/world/entity/animal/AbstractFish.java b/src/main/java/net/minecraft/world/entity/animal/AbstractFish.java
-index 401cffccd3c6adedcbd3986cd13733772953b31b..b8f973505b184cf198b6782a6f423c921c3881a7 100644
+index 3231eaa6af2ddfe4095ff2d650f580ebd4d43aea..e8cb124d232f7316cc8c35dd8bd12f79bbcda7d6 100644
--- a/src/main/java/net/minecraft/world/entity/animal/AbstractFish.java
+++ b/src/main/java/net/minecraft/world/entity/animal/AbstractFish.java
-@@ -94,6 +94,7 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable {
+@@ -87,6 +87,7 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable {
@Override
protected void registerGoals() {
super.registerGoals();
@@ -3983,7 +3735,7 @@ index 401cffccd3c6adedcbd3986cd13733772953b31b..b8f973505b184cf198b6782a6f423c92
this.goalSelector.addGoal(0, new PanicGoal(this, 1.25));
this.goalSelector.addGoal(2, new AvoidEntityGoal<>(this, Player.class, 8.0F, 1.6, 1.4, EntitySelector.NO_SPECTATORS::test));
this.goalSelector.addGoal(4, new AbstractFish.FishSwimGoal(this));
-@@ -107,7 +108,7 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable {
+@@ -100,7 +101,7 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable {
@Override
public void travel(Vec3 movementInput) {
if (this.isEffectiveAi() && this.isInWater()) {
@@ -3992,7 +3744,7 @@ index 401cffccd3c6adedcbd3986cd13733772953b31b..b8f973505b184cf198b6782a6f423c92
this.move(MoverType.SELF, this.getDeltaMovement());
this.setDeltaMovement(this.getDeltaMovement().scale(0.9));
if (this.getTarget() == null) {
-@@ -168,7 +169,7 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable {
+@@ -161,7 +162,7 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable {
protected void playStepSound(BlockPos pos, BlockState state) {
}
@@ -4001,7 +3753,7 @@ index 401cffccd3c6adedcbd3986cd13733772953b31b..b8f973505b184cf198b6782a6f423c92
private final AbstractFish fish;
FishMoveControl(AbstractFish owner) {
-@@ -176,14 +177,22 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable {
+@@ -169,14 +170,22 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable {
this.fish = owner;
}
@@ -4027,7 +3779,7 @@ index 401cffccd3c6adedcbd3986cd13733772953b31b..b8f973505b184cf198b6782a6f423c92
double d = this.wantedX - this.fish.getX();
double e = this.wantedY - this.fish.getY();
diff --git a/src/main/java/net/minecraft/world/entity/animal/Animal.java b/src/main/java/net/minecraft/world/entity/animal/Animal.java
-index 081d1e38b7b1f286e138b0981aaa760e58761215..a64ab2058d4e3439bf6ee418f3192b83c346eb85 100644
+index 5193cf1d3c922d750a11e492b7636215e23ad0d6..7f90a0d8f65c96844df06b7c4fa3da28a6f51dd1 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Animal.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Animal.java
@@ -42,6 +42,7 @@ public abstract class Animal extends AgeableMob {
@@ -4038,7 +3790,7 @@ index 081d1e38b7b1f286e138b0981aaa760e58761215..a64ab2058d4e3439bf6ee418f3192b83
protected Animal(EntityType extends Animal> type, Level world) {
super(type, world);
-@@ -151,7 +152,7 @@ public abstract class Animal extends AgeableMob {
+@@ -146,7 +147,7 @@ public abstract class Animal extends AgeableMob {
if (this.isFood(itemstack)) {
int i = this.getAge();
@@ -4047,7 +3799,7 @@ index 081d1e38b7b1f286e138b0981aaa760e58761215..a64ab2058d4e3439bf6ee418f3192b83
final ItemStack breedCopy = itemstack.copy(); // Paper - Fix EntityBreedEvent copying
this.usePlayerItem(player, hand, itemstack);
this.setInLove(player, breedCopy); // Paper - Fix EntityBreedEvent copying
-@@ -242,12 +243,20 @@ public abstract class Animal extends AgeableMob {
+@@ -234,12 +235,20 @@ public abstract class Animal extends AgeableMob {
AgeableMob entityageable = this.getBreedOffspring(world, other);
if (entityageable != null) {
@@ -4071,7 +3823,7 @@ index 081d1e38b7b1f286e138b0981aaa760e58761215..a64ab2058d4e3439bf6ee418f3192b83
int experience = this.getRandom().nextInt(7) + 1;
EntityBreedEvent entityBreedEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreedEvent(entityageable, this, other, breeder, this.breedItem, experience);
if (entityBreedEvent.isCancelled()) {
-@@ -275,8 +284,10 @@ public abstract class Animal extends AgeableMob {
+@@ -267,8 +276,10 @@ public abstract class Animal extends AgeableMob {
entityplayer.awardStat(Stats.ANIMALS_BRED);
CriteriaTriggers.BRED_ANIMALS.trigger(entityplayer, this, entityanimal, entityageable);
} // Paper
@@ -4085,18 +3837,10 @@ index 081d1e38b7b1f286e138b0981aaa760e58761215..a64ab2058d4e3439bf6ee418f3192b83
entityanimal.resetLove();
worldserver.broadcastEntityEvent(this, (byte) 18);
diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java
-index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd6473ba96 100644
+index 0dfb8109fd8c022b079da00f6a0e3fc85b57bf7a..539170813921de2dfcd7ef84dd7512d73cd27e68 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Bee.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java
-@@ -43,6 +43,7 @@ import net.minecraft.world.entity.EntityType;
- import net.minecraft.world.entity.LivingEntity;
- import net.minecraft.world.entity.Mob;
- import net.minecraft.world.entity.MobType;
-+import net.minecraft.world.entity.MoverType;
- import net.minecraft.world.entity.NeutralMob;
- import net.minecraft.world.entity.PathfinderMob;
- import net.minecraft.world.entity.Pose;
-@@ -147,6 +148,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
+@@ -143,6 +143,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
public Bee(EntityType extends Bee> type, Level world) {
super(type, world);
this.remainingCooldownBeforeLocatingNewFlower = Mth.nextInt(this.random, 20, 60);
@@ -4104,7 +3848,7 @@ index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd
// Paper start - Fix MC-167279
class BeeFlyingMoveControl extends FlyingMoveControl {
public BeeFlyingMoveControl(final Mob entity, final int maxPitchChange, final boolean noGravity) {
-@@ -155,22 +157,69 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
+@@ -151,22 +152,69 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
@Override
public void tick() {
@@ -4130,12 +3874,12 @@ index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd
this.moveControl = new BeeFlyingMoveControl(this, 20, true);
// Paper end - Fix MC-167279
this.lookControl = new Bee.BeeLookControl(this);
- this.setPathfindingMalus(BlockPathTypes.DANGER_FIRE, -1.0F);
-- this.setPathfindingMalus(BlockPathTypes.WATER, -1.0F);
-+ if (isSensitiveToWater()) this.setPathfindingMalus(BlockPathTypes.WATER, -1.0F); // Purpur
- this.setPathfindingMalus(BlockPathTypes.WATER_BORDER, 16.0F);
- this.setPathfindingMalus(BlockPathTypes.COCOA, -1.0F);
- this.setPathfindingMalus(BlockPathTypes.FENCE, -1.0F);
+ this.setPathfindingMalus(PathType.DANGER_FIRE, -1.0F);
+- this.setPathfindingMalus(PathType.WATER, -1.0F);
++ if (isSensitiveToWater()) this.setPathfindingMalus(PathType.WATER, -1.0F); // Purpur
+ this.setPathfindingMalus(PathType.WATER_BORDER, 16.0F);
+ this.setPathfindingMalus(PathType.COCOA, -1.0F);
+ this.setPathfindingMalus(PathType.FENCE, -1.0F);
}
+ // Purpur start
@@ -4166,16 +3910,16 @@ index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd
+ float speed = (float) getAttributeValue(Attributes.FLYING_SPEED) * 2;
+ setSpeed(speed);
+ Vec3 mot = getDeltaMovement();
-+ move(MoverType.SELF, mot.multiply(speed, speed, speed));
++ move(net.minecraft.world.entity.MoverType.SELF, mot.multiply(speed, speed, speed));
+ setDeltaMovement(mot.scale(0.9D));
+ }
+ }
+ // Purpur end
+
@Override
- protected void defineSynchedData() {
- super.defineSynchedData();
-@@ -185,6 +234,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
+ protected void defineSynchedData(SynchedEntityData.Builder builder) {
+ super.defineSynchedData(builder);
+@@ -181,6 +229,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
@Override
protected void registerGoals() {
@@ -4183,7 +3927,7 @@ index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd
this.goalSelector.addGoal(0, new Bee.BeeAttackGoal(this, 1.399999976158142D, true));
this.goalSelector.addGoal(1, new Bee.BeeEnterHiveGoal());
this.goalSelector.addGoal(2, new BreedGoal(this, 1.0D));
-@@ -200,6 +250,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
+@@ -198,6 +247,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
this.goalSelector.addGoal(7, new Bee.BeeGrowCropGoal());
this.goalSelector.addGoal(8, new Bee.BeeWanderGoal());
this.goalSelector.addGoal(9, new FloatGoal(this));
@@ -4191,7 +3935,7 @@ index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd
this.targetSelector.addGoal(1, (new Bee.BeeHurtByOtherGoal(this)).setAlertOthers(new Class[0]));
this.targetSelector.addGoal(2, new Bee.BeeBecomeAngryTargetGoal(this));
this.targetSelector.addGoal(3, new ResetUniversalAngerTargetGoal<>(this, true));
-@@ -355,7 +406,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
+@@ -345,7 +395,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
boolean wantsToEnterHive() {
if (this.stayOutOfHiveCountdown <= 0 && !this.beePollinateGoal.isPollinating() && !this.hasStung() && this.getTarget() == null) {
@@ -4200,7 +3944,7 @@ index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd
return flag && !this.isHiveNearFire();
} else {
-@@ -395,6 +446,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
+@@ -385,6 +435,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
this.hurt(this.damageSources().drown(), 1.0F);
}
@@ -4208,7 +3952,7 @@ index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd
if (flag) {
++this.timeSinceSting;
if (this.timeSinceSting % 5 == 0 && this.random.nextInt(Mth.clamp(1200 - this.timeSinceSting, 1, 1200)) == 0) {
-@@ -427,6 +479,26 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
+@@ -417,6 +468,26 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
}
}
@@ -4235,7 +3979,7 @@ index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd
@Override
public int getRemainingPersistentAngerTime() {
return (Integer) this.entityData.get(Bee.DATA_REMAINING_ANGER_TIME);
-@@ -742,6 +814,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
+@@ -726,6 +797,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
if (optional.isPresent()) {
Bee.this.savedFlowerPos = (BlockPos) optional.get();
Bee.this.navigation.moveTo((double) Bee.this.savedFlowerPos.getX() + 0.5D, (double) Bee.this.savedFlowerPos.getY() + 0.5D, (double) Bee.this.savedFlowerPos.getZ() + 0.5D, 1.2000000476837158D);
@@ -4243,7 +3987,7 @@ index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd
return true;
} else {
Bee.this.remainingCooldownBeforeLocatingNewFlower = Mth.nextInt(Bee.this.random, 20, 60);
-@@ -798,6 +871,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
+@@ -782,6 +854,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
this.pollinating = false;
Bee.this.navigation.stop();
Bee.this.remainingCooldownBeforeLocatingNewFlower = 200;
@@ -4251,7 +3995,7 @@ index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd
}
@Override
-@@ -844,6 +918,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
+@@ -828,6 +901,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
this.setWantedPos();
}
@@ -4259,14 +4003,14 @@ index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd
++this.successfulPollinatingTicks;
if (Bee.this.random.nextFloat() < 0.05F && this.successfulPollinatingTicks > this.lastSoundPlayedTick + 60) {
this.lastSoundPlayedTick = this.successfulPollinatingTicks;
-@@ -888,16 +963,16 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
+@@ -872,16 +946,16 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
}
}
- private class BeeLookControl extends LookControl {
+ private class BeeLookControl extends org.purpurmc.purpur.controller.LookControllerWASD { // Purpur
- BeeLookControl(Mob entity) {
+ BeeLookControl(final Mob entity) {
super(entity);
}
@@ -4280,11 +4024,11 @@ index f9521a6e115f0c975a7885b024c99eae300b63bf..997ab942be9f742804041b07d607e7dd
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/Cat.java b/src/main/java/net/minecraft/world/entity/animal/Cat.java
-index f760ce7d9df79ef58f8963de3e901cba3e12fcaa..6af5e1dfcfd739e0bc857f648c189151d5a795c8 100644
+index 07559b9629d4ecb40b511256f400a781e39820e0..3e1345f1c534320e07820d573f5c8dba49746425 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Cat.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Cat.java
-@@ -98,6 +98,51 @@ public class Cat extends TamableAnimal implements VariantHolder {
- super(type, world);
+@@ -104,6 +104,53 @@ public class Cat extends TamableAnimal implements VariantHolder {
- protected void registerGoals() {
- this.temptGoal = new Cat.CatTemptGoal(this, 0.6D, Cat.TEMPT_INGREDIENT, true);
+@@ -114,6 +161,7 @@ public class Cat extends TamableAnimal implements VariantHolder {
+@@ -126,6 +174,7 @@ public class Cat extends TamableAnimal implements VariantHolder(this, Rabbit.class, false, (Predicate) null));
this.targetSelector.addGoal(1, new NonTameRandomTargetGoal<>(this, Turtle.class, false, Turtle.BABY_ON_LAND_SELECTOR));
}
-@@ -309,6 +356,14 @@ public class Cat extends TamableAnimal implements VariantHolder {
+@@ -318,6 +367,14 @@ public class Cat extends TamableAnimal implements VariantHolder {
+@@ -377,6 +434,7 @@ public class Cat extends TamableAnimal implements VariantHolder {
- }
- } else if (this.isFood(itemstack)) {
- this.usePlayerItem(player, hand, itemstack);
-- if (this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit
-+ if ((this.level().purpurConfig.alwaysTameInCreative && player.getAbilities().instabuild) || (this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled())) { // CraftBukkit // Purpur
- this.tame(player);
- this.setOrderedToSit(true);
- this.level().broadcastEntityEvent(this, (byte) 7);
+ private void tryToTame(Player player) {
+- if (this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit
++ if ((this.level().purpurConfig.alwaysTameInCreative && player.hasInfiniteMaterials()) || this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit
+ this.tame(player);
+ this.setOrderedToSit(true);
+ this.level().broadcastEntityEvent(this, (byte) 7);
diff --git a/src/main/java/net/minecraft/world/entity/animal/Chicken.java b/src/main/java/net/minecraft/world/entity/animal/Chicken.java
-index 5e7e6526e2750d508a870dfbdbb46e520d201796..0388ff9ce0ffe1029d977a65a528a0d9f228a3ee 100644
+index 0a4d4cb4ad7cda7c50c46151c03586865d56c797..d8fe8f86ccc9b26b2208b090bb6572b483d14bae 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Chicken.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Chicken.java
-@@ -55,16 +55,65 @@ public class Chicken extends Animal {
- this.setPathfindingMalus(BlockPathTypes.WATER, 0.0F);
+@@ -54,10 +54,51 @@ public class Chicken extends Animal {
+ this.setPathfindingMalus(PathType.WATER, 0.0F);
}
+ // Purpur start
@@ -4438,8 +4184,9 @@ index 5e7e6526e2750d508a870dfbdbb46e520d201796..0388ff9ce0ffe1029d977a65a528a0d9
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur
+ // this.goalSelector.addGoal(1, new PanicGoal(this, 1.4D)); // Purpur - moved down
this.goalSelector.addGoal(2, new BreedGoal(this, 1.0D));
- this.goalSelector.addGoal(3, new TemptGoal(this, 1.0D, Chicken.FOOD_ITEMS, false));
- this.goalSelector.addGoal(4, new FollowParentGoal(this, 1.1D));
+ this.goalSelector.addGoal(3, new TemptGoal(this, 1.0D, (itemstack) -> {
+ return itemstack.is(ItemTags.CHICKEN_FOOD);
+@@ -66,6 +107,14 @@ public class Chicken extends Animal {
this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 1.0D));
this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 6.0F));
this.goalSelector.addGoal(7, new RandomLookAroundGoal(this));
@@ -4454,7 +4201,7 @@ index 5e7e6526e2750d508a870dfbdbb46e520d201796..0388ff9ce0ffe1029d977a65a528a0d9
}
@Override
-@@ -73,7 +122,7 @@ public class Chicken extends Animal {
+@@ -74,7 +123,7 @@ public class Chicken extends Animal {
}
public static AttributeSupplier.Builder createAttributes() {
@@ -4502,7 +4249,7 @@ index 824e5e4fe7619ae46061c3c978c9a044db8c84ab..f0b6118a9995bb41836685bbf94d2e7f
public ItemStack getBucketItemStack() {
return new ItemStack(Items.COD_BUCKET);
diff --git a/src/main/java/net/minecraft/world/entity/animal/Cow.java b/src/main/java/net/minecraft/world/entity/animal/Cow.java
-index 3cdd9f379c7e2d46ea47c9ef55b121c93ec0bb4a..be4ccc42d6f598cbaaf39aafbd49b594ac7b06fe 100644
+index 5a7b1be351834a6b8889b1380cede1be025cb302..1691a98caabf27ea092a9b422649ac84bc0a7235 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Cow.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Cow.java
@@ -2,6 +2,7 @@ package net.minecraft.world.entity.animal;
@@ -4513,21 +4260,23 @@ index 3cdd9f379c7e2d46ea47c9ef55b121c93ec0bb4a..be4ccc42d6f598cbaaf39aafbd49b594
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
-@@ -30,6 +31,7 @@ import net.minecraft.world.item.ItemUtils;
+@@ -29,6 +30,7 @@ import net.minecraft.world.item.ItemStack;
+ import net.minecraft.world.item.ItemUtils;
import net.minecraft.world.item.Items;
- import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.level.Level;
+import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
- import org.joml.Vector3f;
-
-@@ -40,25 +42,74 @@ import org.bukkit.event.player.PlayerBucketFillEvent;
+ // CraftBukkit start
+ import org.bukkit.craftbukkit.event.CraftEventFactory;
+@@ -37,6 +39,7 @@ import org.bukkit.event.player.PlayerBucketFillEvent;
// CraftBukkit end
public class Cow extends Animal {
+ private boolean isNaturallyAggressiveToPlayers; // Purpur
- public Cow(EntityType extends Cow> type, Level world) {
+ private static final EntityDimensions BABY_DIMENSIONS = EntityType.COW.getDimensions().scale(0.5F).withEyeHeight(0.665F);
+
+@@ -44,18 +47,65 @@ public class Cow extends Animal {
super(type, world);
}
@@ -4565,9 +4314,9 @@ index 3cdd9f379c7e2d46ea47c9ef55b121c93ec0bb4a..be4ccc42d6f598cbaaf39aafbd49b594
+ }
+
+ @Override
-+ public net.minecraft.world.entity.SpawnGroupData finalizeSpawn(net.minecraft.world.level.ServerLevelAccessor world, net.minecraft.world.DifficultyInstance difficulty, net.minecraft.world.entity.MobSpawnType spawnReason, net.minecraft.world.entity.SpawnGroupData entityData, net.minecraft.nbt.CompoundTag entityNbt) {
++ public net.minecraft.world.entity.SpawnGroupData finalizeSpawn(net.minecraft.world.level.ServerLevelAccessor world, net.minecraft.world.DifficultyInstance difficulty, net.minecraft.world.entity.MobSpawnType spawnReason, net.minecraft.world.entity.SpawnGroupData entityData) {
+ this.isNaturallyAggressiveToPlayers = world.getLevel().purpurConfig.cowNaturallyAggressiveToPlayersChance > 0.0D && random.nextDouble() <= world.getLevel().purpurConfig.cowNaturallyAggressiveToPlayersChance;
-+ return super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityNbt);
++ return super.finalizeSpawn(world, difficulty, spawnReason, entityData);
+ }
+
+ @Override
@@ -4582,8 +4331,10 @@ index 3cdd9f379c7e2d46ea47c9ef55b121c93ec0bb4a..be4ccc42d6f598cbaaf39aafbd49b594
this.goalSelector.addGoal(1, new PanicGoal(this, 2.0D));
+ this.goalSelector.addGoal(1, new net.minecraft.world.entity.ai.goal.MeleeAttackGoal(this, 1.2000000476837158D, true)); // Purpur
this.goalSelector.addGoal(2, new BreedGoal(this, 1.0D));
-+ if (level().purpurConfig.cowFeedMushrooms > 0) this.goalSelector.addGoal(3, new TemptGoal(this, 1.25D, Ingredient.of(Items.WHEAT, Blocks.RED_MUSHROOM.asItem(), Blocks.BROWN_MUSHROOM.asItem()), false)); else // Purpur
- this.goalSelector.addGoal(3, new TemptGoal(this, 1.25D, Ingredient.of(Items.WHEAT), false));
+ this.goalSelector.addGoal(3, new TemptGoal(this, 1.25D, (itemstack) -> {
+- return itemstack.is(ItemTags.COW_FOOD);
++ return level().purpurConfig.cowFeedMushrooms > 0 && (itemstack.is(Blocks.RED_MUSHROOM.asItem()) || itemstack.is(Blocks.BROWN_MUSHROOM.asItem())) || itemstack.is(ItemTags.COW_FOOD); // Purpur
+ }, false));
this.goalSelector.addGoal(4, new FollowParentGoal(this, 1.25D));
this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 1.0D));
this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 6.0F));
@@ -4591,13 +4342,17 @@ index 3cdd9f379c7e2d46ea47c9ef55b121c93ec0bb4a..be4ccc42d6f598cbaaf39aafbd49b594
+ this.targetSelector.addGoal(0, new net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, target -> isNaturallyAggressiveToPlayers)); // Purpur
}
+ @Override
+@@ -64,7 +114,7 @@ public class Cow extends Animal {
+ }
+
public static AttributeSupplier.Builder createAttributes() {
- return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 10.0D).add(Attributes.MOVEMENT_SPEED, 0.20000000298023224D);
+ return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 10.0D).add(Attributes.MOVEMENT_SPEED, 0.20000000298023224D).add(Attributes.ATTACK_DAMAGE, 0.0D); // Purpur
}
@Override
-@@ -88,6 +139,7 @@ public class Cow extends Animal {
+@@ -94,6 +144,7 @@ public class Cow extends Animal {
@Override
public InteractionResult mobInteract(Player player, InteractionHand hand) {
@@ -4605,7 +4360,7 @@ index 3cdd9f379c7e2d46ea47c9ef55b121c93ec0bb4a..be4ccc42d6f598cbaaf39aafbd49b594
ItemStack itemstack = player.getItemInHand(hand);
if (itemstack.is(Items.BUCKET) && !this.isBaby()) {
-@@ -95,7 +147,7 @@ public class Cow extends Animal {
+@@ -101,7 +152,7 @@ public class Cow extends Animal {
PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level(), player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET, hand);
if (event.isCancelled()) {
@@ -4614,7 +4369,7 @@ index 3cdd9f379c7e2d46ea47c9ef55b121c93ec0bb4a..be4ccc42d6f598cbaaf39aafbd49b594
}
// CraftBukkit end
-@@ -104,6 +156,10 @@ public class Cow extends Animal {
+@@ -110,6 +161,10 @@ public class Cow extends Animal {
player.setItemInHand(hand, itemstack1);
return InteractionResult.sidedSuccess(this.level().isClientSide);
@@ -4625,9 +4380,9 @@ index 3cdd9f379c7e2d46ea47c9ef55b121c93ec0bb4a..be4ccc42d6f598cbaaf39aafbd49b594
} else {
return super.mobInteract(player, hand);
}
-@@ -124,4 +180,69 @@ public class Cow extends Animal {
- protected Vector3f getPassengerAttachmentPoint(Entity passenger, EntityDimensions dimensions, float scaleFactor) {
- return new Vector3f(0.0F, dimensions.height - 0.03125F * scaleFactor, 0.0F);
+@@ -125,4 +180,69 @@ public class Cow extends Animal {
+ public EntityDimensions getDefaultDimensions(Pose pose) {
+ return this.isBaby() ? Cow.BABY_DIMENSIONS : super.getDefaultDimensions(pose);
}
+
+ // Purpur start - feed mushroom to change to mooshroom
@@ -4696,10 +4451,10 @@ index 3cdd9f379c7e2d46ea47c9ef55b121c93ec0bb4a..be4ccc42d6f598cbaaf39aafbd49b594
+ // Purpur end
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java
-index 45646c69ea73936a8916756fde37dd3f39db0d04..61bb29de8f1eaa833db95fcc38ab6e18c1a2243c 100644
+index 1b1cb0e4d54e52ebe794199e386c54c5d84b3719..c1a9a87ef0fefc499c0e1edbe1031f47cc432b31 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java
-@@ -83,19 +83,104 @@ public class Dolphin extends WaterAnimal {
+@@ -81,19 +81,104 @@ public class Dolphin extends WaterAnimal {
public static final Predicate ALLOWED_ITEMS = (entityitem) -> {
return !entityitem.hasPickUpDelay() && entityitem.isAlive() && entityitem.isInWater();
};
@@ -4798,14 +4553,14 @@ index 45646c69ea73936a8916756fde37dd3f39db0d04..61bb29de8f1eaa833db95fcc38ab6e18
+
@Nullable
@Override
- public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType spawnReason, @Nullable SpawnGroupData entityData, @Nullable CompoundTag entityNbt) {
+ public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType spawnReason, @Nullable SpawnGroupData entityData) {
this.setAirSupply(this.getMaxAirSupply());
this.setXRot(0.0F);
+ this.isNaturallyAggressiveToPlayers = world.getLevel().purpurConfig.dolphinNaturallyAggressiveToPlayersChance > 0.0D && random.nextDouble() <= world.getLevel().purpurConfig.dolphinNaturallyAggressiveToPlayersChance; // Purpur
- return super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityNbt);
+ return super.finalizeSpawn(world, difficulty, spawnReason, entityData);
}
-@@ -160,17 +245,21 @@ public class Dolphin extends WaterAnimal {
+@@ -158,17 +243,21 @@ public class Dolphin extends WaterAnimal {
protected void registerGoals() {
this.goalSelector.addGoal(0, new BreathAirGoal(this));
this.goalSelector.addGoal(0, new TryFindWaterGoal(this));
@@ -4828,7 +4583,7 @@ index 45646c69ea73936a8916756fde37dd3f39db0d04..61bb29de8f1eaa833db95fcc38ab6e18
}
public static AttributeSupplier.Builder createAttributes() {
-@@ -221,7 +310,7 @@ public class Dolphin extends WaterAnimal {
+@@ -214,7 +303,7 @@ public class Dolphin extends WaterAnimal {
@Override
protected boolean canRide(Entity entity) {
@@ -4837,7 +4592,7 @@ index 45646c69ea73936a8916756fde37dd3f39db0d04..61bb29de8f1eaa833db95fcc38ab6e18
}
@Override
-@@ -256,6 +345,11 @@ public class Dolphin extends WaterAnimal {
+@@ -249,6 +338,11 @@ public class Dolphin extends WaterAnimal {
@Override
public void tick() {
super.tick();
@@ -4849,7 +4604,7 @@ index 45646c69ea73936a8916756fde37dd3f39db0d04..61bb29de8f1eaa833db95fcc38ab6e18
if (this.isNoAi()) {
this.setAirSupply(this.getMaxAirSupply());
} else {
-@@ -401,6 +495,7 @@ public class Dolphin extends WaterAnimal {
+@@ -391,6 +485,7 @@ public class Dolphin extends WaterAnimal {
@Override
public boolean canUse() {
@@ -4858,10 +4613,10 @@ index 45646c69ea73936a8916756fde37dd3f39db0d04..61bb29de8f1eaa833db95fcc38ab6e18
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/Fox.java b/src/main/java/net/minecraft/world/entity/animal/Fox.java
-index f7a7810fdc2f74b79fa14470493485e4b74539ab..445c1993a18da93e89792b7953e5eb71777c7874 100644
+index e705449496b1a06270ecbc13f4dce5357479845b..124839f22ed0499ca395a648e858469d81d31f93 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Fox.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Fox.java
-@@ -36,6 +36,7 @@ import net.minecraft.util.RandomSource;
+@@ -37,6 +37,7 @@ import net.minecraft.util.RandomSource;
import net.minecraft.util.StringRepresentable;
import net.minecraft.world.DifficultyInstance;
import net.minecraft.world.InteractionHand;
@@ -4869,7 +4624,7 @@ index f7a7810fdc2f74b79fa14470493485e4b74539ab..445c1993a18da93e89792b7953e5eb71
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.AgeableMob;
import net.minecraft.world.entity.Entity;
-@@ -148,6 +149,64 @@ public class Fox extends Animal implements VariantHolder {
+@@ -145,6 +146,64 @@ public class Fox extends Animal implements VariantHolder {
this.setCanPickUpLoot(true);
}
@@ -4932,9 +4687,9 @@ index f7a7810fdc2f74b79fa14470493485e4b74539ab..445c1993a18da93e89792b7953e5eb71
+ }
+
@Override
- protected void defineSynchedData() {
- super.defineSynchedData();
-@@ -167,6 +226,7 @@ public class Fox extends Animal implements VariantHolder {
+ protected void defineSynchedData(SynchedEntityData.Builder builder) {
+ super.defineSynchedData(builder);
+@@ -164,6 +223,7 @@ public class Fox extends Animal implements VariantHolder {
return entityliving instanceof AbstractSchoolingFish;
});
this.goalSelector.addGoal(0, new Fox.FoxFloatGoal());
@@ -4942,7 +4697,7 @@ index f7a7810fdc2f74b79fa14470493485e4b74539ab..445c1993a18da93e89792b7953e5eb71
this.goalSelector.addGoal(0, new ClimbOnTopOfPowderSnowGoal(this, this.level()));
this.goalSelector.addGoal(1, new Fox.FaceplantGoal());
this.goalSelector.addGoal(2, new Fox.FoxPanicGoal(2.2D));
-@@ -193,6 +253,7 @@ public class Fox extends Animal implements VariantHolder {
+@@ -190,6 +250,7 @@ public class Fox extends Animal implements VariantHolder {
this.goalSelector.addGoal(11, new Fox.FoxSearchForItemsGoal());
this.goalSelector.addGoal(12, new Fox.FoxLookAtPlayerGoal(this, Player.class, 24.0F));
this.goalSelector.addGoal(13, new Fox.PerchAndSearchGoal());
@@ -4950,7 +4705,7 @@ index f7a7810fdc2f74b79fa14470493485e4b74539ab..445c1993a18da93e89792b7953e5eb71
this.targetSelector.addGoal(3, new Fox.DefendTrustedTargetGoal(LivingEntity.class, false, false, (entityliving) -> {
return Fox.TRUSTED_TARGET_SELECTOR.test(entityliving) && !this.trusts(entityliving.getUUID());
}));
-@@ -349,6 +410,11 @@ public class Fox extends Animal implements VariantHolder {
+@@ -344,6 +405,11 @@ public class Fox extends Animal implements VariantHolder {
}
private void setTargetGoals() {
@@ -4962,7 +4717,7 @@ index f7a7810fdc2f74b79fa14470493485e4b74539ab..445c1993a18da93e89792b7953e5eb71
if (this.getVariant() == Fox.Type.RED) {
this.targetSelector.addGoal(4, this.landTargetGoal);
this.targetSelector.addGoal(4, this.turtleEggTargetGoal);
-@@ -382,6 +448,7 @@ public class Fox extends Animal implements VariantHolder {
+@@ -377,6 +443,7 @@ public class Fox extends Animal implements VariantHolder {
public void setVariant(Fox.Type variant) {
this.entityData.set(Fox.DATA_TYPE_ID, variant.getId());
@@ -4970,7 +4725,7 @@ index f7a7810fdc2f74b79fa14470493485e4b74539ab..445c1993a18da93e89792b7953e5eb71
}
List getTrustedUUIDs() {
-@@ -728,6 +795,29 @@ public class Fox extends Animal implements VariantHolder {
+@@ -717,6 +784,29 @@ public class Fox extends Animal implements VariantHolder {
}
// Paper end
@@ -5000,7 +4755,7 @@ index f7a7810fdc2f74b79fa14470493485e4b74539ab..445c1993a18da93e89792b7953e5eb71
@Override
// Paper start - Cancellable death event
protected org.bukkit.event.entity.EntityDeathEvent dropAllDeathLoot(DamageSource source) {
-@@ -785,16 +875,16 @@ public class Fox extends Animal implements VariantHolder {
+@@ -769,16 +859,16 @@ public class Fox extends Animal implements VariantHolder {
return new Vec3(0.0D, (double) (0.55F * this.getEyeHeight()), (double) (this.getBbWidth() * 0.4F));
}
@@ -5020,7 +4775,7 @@ index f7a7810fdc2f74b79fa14470493485e4b74539ab..445c1993a18da93e89792b7953e5eb71
}
}
-@@ -805,16 +895,16 @@ public class Fox extends Animal implements VariantHolder {
+@@ -789,16 +879,16 @@ public class Fox extends Animal implements VariantHolder {
}
}
@@ -5040,7 +4795,7 @@ index f7a7810fdc2f74b79fa14470493485e4b74539ab..445c1993a18da93e89792b7953e5eb71
}
}
-@@ -932,8 +1022,10 @@ public class Fox extends Animal implements VariantHolder {
+@@ -916,8 +1006,10 @@ public class Fox extends Animal implements VariantHolder {
CriteriaTriggers.BRED_ANIMALS.trigger(entityplayer2, this.animal, this.partner, entityfox);
}
@@ -5053,7 +4808,7 @@ index f7a7810fdc2f74b79fa14470493485e4b74539ab..445c1993a18da93e89792b7953e5eb71
this.animal.resetLove();
this.partner.resetLove();
worldserver.addFreshEntityWithPassengers(entityfox, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); // CraftBukkit - added SpawnReason
-@@ -1319,7 +1411,7 @@ public class Fox extends Animal implements VariantHolder {
+@@ -1303,7 +1395,7 @@ public class Fox extends Animal implements VariantHolder {
}
protected void onReachedTarget() {
@@ -5063,10 +4818,10 @@ index f7a7810fdc2f74b79fa14470493485e4b74539ab..445c1993a18da93e89792b7953e5eb71
if (iblockdata.is(Blocks.SWEET_BERRY_BUSH)) {
diff --git a/src/main/java/net/minecraft/world/entity/animal/IronGolem.java b/src/main/java/net/minecraft/world/entity/animal/IronGolem.java
-index 6cfe0d6c46caa122db107c607d27a2bdcd82f7a8..442eb602f5c82550a87e218e2013171b718abd62 100644
+index 932fae98c551052cadba4c6fc6e575fc30a25d58..12bc57d36d76f49596df0004fda31a6a678be60c 100644
--- a/src/main/java/net/minecraft/world/entity/animal/IronGolem.java
+++ b/src/main/java/net/minecraft/world/entity/animal/IronGolem.java
-@@ -60,14 +60,59 @@ public class IronGolem extends AbstractGolem implements NeutralMob {
+@@ -56,13 +56,58 @@ public class IronGolem extends AbstractGolem implements NeutralMob {
private int remainingPersistentAngerTime;
@Nullable
private UUID persistentAngerTarget;
@@ -5074,7 +4829,6 @@ index 6cfe0d6c46caa122db107c607d27a2bdcd82f7a8..442eb602f5c82550a87e218e2013171b
public IronGolem(EntityType extends IronGolem> type, Level world) {
super(type, world);
- this.setMaxUpStep(1.0F);
}
+ // Purpur start
@@ -5126,7 +4880,7 @@ index 6cfe0d6c46caa122db107c607d27a2bdcd82f7a8..442eb602f5c82550a87e218e2013171b
this.goalSelector.addGoal(1, new MeleeAttackGoal(this, 1.0D, true));
this.goalSelector.addGoal(2, new MoveTowardsTargetGoal(this, 0.9D, 32.0F));
this.goalSelector.addGoal(2, new MoveBackToVillageGoal(this, 0.6D, false));
-@@ -75,6 +120,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob {
+@@ -70,6 +115,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob {
this.goalSelector.addGoal(5, new OfferFlowerGoal(this));
this.goalSelector.addGoal(7, new LookAtPlayerGoal(this, Player.class, 6.0F));
this.goalSelector.addGoal(8, new RandomLookAroundGoal(this));
@@ -5134,7 +4888,7 @@ index 6cfe0d6c46caa122db107c607d27a2bdcd82f7a8..442eb602f5c82550a87e218e2013171b
this.targetSelector.addGoal(1, new DefendVillageTargetGoal(this));
this.targetSelector.addGoal(2, new HurtByTargetGoal(this, new Class[0]));
this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, this::isAngryAt));
-@@ -139,6 +185,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob {
+@@ -134,6 +180,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob {
public void addAdditionalSaveData(CompoundTag nbt) {
super.addAdditionalSaveData(nbt);
nbt.putBoolean("PlayerCreated", this.isPlayerCreated());
@@ -5142,7 +4896,7 @@ index 6cfe0d6c46caa122db107c607d27a2bdcd82f7a8..442eb602f5c82550a87e218e2013171b
this.addPersistentAngerSaveData(nbt);
}
-@@ -146,6 +193,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob {
+@@ -141,6 +188,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob {
public void readAdditionalSaveData(CompoundTag nbt) {
super.readAdditionalSaveData(nbt);
this.setPlayerCreated(nbt.getBoolean("PlayerCreated"));
@@ -5150,7 +4904,7 @@ index 6cfe0d6c46caa122db107c607d27a2bdcd82f7a8..442eb602f5c82550a87e218e2013171b
this.readPersistentAngerSaveData(this.level(), nbt);
}
-@@ -270,13 +318,13 @@ public class IronGolem extends AbstractGolem implements NeutralMob {
+@@ -265,18 +313,19 @@ public class IronGolem extends AbstractGolem implements NeutralMob {
ItemStack itemstack = player.getItemInHand(hand);
if (!itemstack.is(Items.IRON_INGOT)) {
@@ -5166,16 +4920,14 @@ index 6cfe0d6c46caa122db107c607d27a2bdcd82f7a8..442eb602f5c82550a87e218e2013171b
} else {
float f1 = 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F;
-@@ -285,6 +333,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob {
- itemstack.shrink(1);
- }
-
+ this.playSound(SoundEvents.IRON_GOLEM_REPAIR, 1.0F, f1);
+ itemstack.consume(1, player);
+ if (this.level().purpurConfig.ironGolemHealCalm && isAngry() && getHealth() == getMaxHealth()) stopBeingAngry(); // Purpur
return InteractionResult.sidedSuccess(this.level().isClientSide);
}
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java
-index 6659abb4ab8a13a48c154d2e3f273eb13b202e7f..560981601c6a43fee99372eafd7bd746798845a6 100644
+index 5707c6287a691030841fa973e8f7f34a816103e4..8299ed1f8632f94592f274b543b234c46fd83886 100644
--- a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java
+++ b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java
@@ -64,6 +64,43 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder drops = this.generateDefaultDrops();
-+ List drops = this.generateDefaultDrops(net.minecraft.world.item.enchantment.EnchantmentHelper.getMobLooting(player)); // Purpur
+- java.util.List drops = this.generateDefaultDrops();
++ java.util.List drops = this.generateDefaultDrops(net.minecraft.world.item.enchantment.EnchantmentHelper.getMobLooting(player)); // Purpur
org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops);
if (event != null) {
if (event.isCancelled()) {
@@ -5236,16 +4988,16 @@ index 6659abb4ab8a13a48c154d2e3f273eb13b202e7f..560981601c6a43fee99372eafd7bd746
}
drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops());
}
-@@ -152,7 +189,7 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder> optional = this.getEffectsFromItemStack(itemstack);
+@@ -150,7 +187,7 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder optional = this.getEffectsFromItemStack(itemstack);
if (optional.isEmpty()) {
- return InteractionResult.PASS;
+ return tryRide(player, hand); // Purpur
}
- if (!player.getAbilities().instabuild) {
-@@ -176,13 +213,13 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder generateDefaultDrops() {
-+ public List generateDefaultDrops(int looting) { // Purpur
- List dropEntities = new java.util.ArrayList<>(5);
+- public java.util.List generateDefaultDrops() {
++ public java.util.List generateDefaultDrops(int looting) { // Purpur
+ java.util.List dropEntities = new java.util.ArrayList<>(5);
- for (int i = 0; i < 5; ++i) {
+ for (int i = 0; i < 5 + (org.purpurmc.purpur.PurpurConfig.allowShearsLooting ? looting : 0); ++i) { // Purpur
dropEntities.add(new ItemStack(this.getVariant().getBlockState().getBlock()));
}
return dropEntities;
diff --git a/src/main/java/net/minecraft/world/entity/animal/Ocelot.java b/src/main/java/net/minecraft/world/entity/animal/Ocelot.java
-index 4300fab61765dd224fab084d118aae7294fc9de6..3c5f25300d1c7800144a459cc8bf598352a62a35 100644
+index 2c7491edbb60e7ec6a208ea7292cd28a3f8f9e31..07dc8a43f4e8c54a94696b84896d32f66a207ad3 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Ocelot.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Ocelot.java
-@@ -70,6 +70,43 @@ public class Ocelot extends Animal {
+@@ -66,6 +66,43 @@ public class Ocelot extends Animal {
this.reassessTrustingGoals();
}
@@ -5310,9 +5062,9 @@ index 4300fab61765dd224fab084d118aae7294fc9de6..3c5f25300d1c7800144a459cc8bf5983
public boolean isTrusting() {
return (Boolean) this.entityData.get(Ocelot.DATA_TRUSTING);
}
-@@ -101,12 +138,14 @@ public class Ocelot extends Animal {
- protected void registerGoals() {
- this.temptGoal = new Ocelot.OcelotTemptGoal(this, 0.6D, Ocelot.TEMPT_INGREDIENT, true);
+@@ -99,12 +136,14 @@ public class Ocelot extends Animal {
+ return itemstack.is(ItemTags.OCELOT_FOOD);
+ }, true);
this.goalSelector.addGoal(1, new FloatGoal(this));
+ this.goalSelector.addGoal(1, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur
this.goalSelector.addGoal(3, this.temptGoal);
@@ -5325,7 +5077,7 @@ index 4300fab61765dd224fab084d118aae7294fc9de6..3c5f25300d1c7800144a459cc8bf5983
this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Chicken.class, false));
this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Turtle.class, 10, false, false, Turtle.BABY_ON_LAND_SELECTOR));
}
-@@ -256,7 +295,7 @@ public class Ocelot extends Animal {
+@@ -254,7 +293,7 @@ public class Ocelot extends Animal {
if (world.isUnobstructed(this) && !world.containsAnyLiquid(this.getBoundingBox())) {
BlockPos blockposition = this.blockPosition();
@@ -5335,10 +5087,10 @@ index 4300fab61765dd224fab084d118aae7294fc9de6..3c5f25300d1c7800144a459cc8bf5983
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/Panda.java b/src/main/java/net/minecraft/world/entity/animal/Panda.java
-index d683c49fdf2d1e5b0f2620641f9c241e82f96825..adfa18c941b5070692ed855d1d609993ca49a01d 100644
+index db60b91c2b26ca8cdb66e05deab7742ffe212767..7bd81d073ce4a8d5981f256415d3e99e13da79ba 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Panda.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Panda.java
-@@ -115,6 +115,53 @@ public class Panda extends Animal {
+@@ -120,6 +120,53 @@ public class Panda extends Animal {
}
@@ -5392,7 +5144,7 @@ index d683c49fdf2d1e5b0f2620641f9c241e82f96825..adfa18c941b5070692ed855d1d609993
@Override
public boolean canTakeItem(ItemStack stack) {
EquipmentSlot enumitemslot = Mob.getEquipmentSlotForItem(stack);
-@@ -276,6 +323,7 @@ public class Panda extends Animal {
+@@ -281,6 +328,7 @@ public class Panda extends Animal {
@Override
protected void registerGoals() {
this.goalSelector.addGoal(0, new FloatGoal(this));
@@ -5400,7 +5152,7 @@ index d683c49fdf2d1e5b0f2620641f9c241e82f96825..adfa18c941b5070692ed855d1d609993
this.goalSelector.addGoal(2, new Panda.PandaPanicGoal(this, 2.0D));
this.goalSelector.addGoal(2, new Panda.PandaBreedGoal(this, 1.0D));
this.goalSelector.addGoal(3, new Panda.PandaAttackGoal(this, 1.2000000476837158D, true));
-@@ -291,6 +339,7 @@ public class Panda extends Animal {
+@@ -298,6 +346,7 @@ public class Panda extends Animal {
this.goalSelector.addGoal(12, new Panda.PandaRollGoal(this));
this.goalSelector.addGoal(13, new FollowParentGoal(this, 1.25D));
this.goalSelector.addGoal(14, new WaterAvoidingRandomStrollGoal(this, 1.0D));
@@ -5408,7 +5160,7 @@ index d683c49fdf2d1e5b0f2620641f9c241e82f96825..adfa18c941b5070692ed855d1d609993
this.targetSelector.addGoal(1, (new Panda.PandaHurtByTargetGoal(this, new Class[0])).setAlertOthers(new Class[0]));
}
-@@ -614,7 +663,10 @@ public class Panda extends Animal {
+@@ -632,7 +681,10 @@ public class Panda extends Animal {
public void setAttributes() {
if (this.isWeak()) {
@@ -5420,7 +5172,7 @@ index d683c49fdf2d1e5b0f2620641f9c241e82f96825..adfa18c941b5070692ed855d1d609993
}
if (this.isLazy()) {
-@@ -637,7 +689,7 @@ public class Panda extends Animal {
+@@ -655,7 +707,7 @@ public class Panda extends Animal {
ItemStack itemstack = player.getItemInHand(hand);
if (this.isScared()) {
@@ -5429,7 +5181,7 @@ index d683c49fdf2d1e5b0f2620641f9c241e82f96825..adfa18c941b5070692ed855d1d609993
} else if (this.isOnBack()) {
this.setOnBack(false);
return InteractionResult.sidedSuccess(this.level().isClientSide);
-@@ -655,7 +707,7 @@ public class Panda extends Animal {
+@@ -673,7 +725,7 @@ public class Panda extends Animal {
this.setInLove(player, breedCopy); // Paper - Fix EntityBreedEvent copying
} else {
if (this.level().isClientSide || this.isSitting() || this.isInWater()) {
@@ -5438,7 +5190,7 @@ index d683c49fdf2d1e5b0f2620641f9c241e82f96825..adfa18c941b5070692ed855d1d609993
}
this.tryToSit();
-@@ -674,7 +726,7 @@ public class Panda extends Animal {
+@@ -692,7 +744,7 @@ public class Panda extends Animal {
return InteractionResult.SUCCESS;
} else {
@@ -5447,8 +5199,8 @@ index d683c49fdf2d1e5b0f2620641f9c241e82f96825..adfa18c941b5070692ed855d1d609993
}
}
-@@ -719,7 +771,7 @@ public class Panda extends Animal {
- return new Vector3f(0.0F, dimensions.height - (this.isBaby() ? 0.4375F : 0.0F) * scaleFactor, 0.0F);
+@@ -737,7 +789,7 @@ public class Panda extends Animal {
+ return this.isBaby() ? Panda.BABY_DIMENSIONS : super.getDefaultDimensions(pose);
}
- private static class PandaMoveControl extends MoveControl {
@@ -5456,7 +5208,7 @@ index d683c49fdf2d1e5b0f2620641f9c241e82f96825..adfa18c941b5070692ed855d1d609993
private final Panda panda;
-@@ -729,9 +781,9 @@ public class Panda extends Animal {
+@@ -747,9 +799,9 @@ public class Panda extends Animal {
}
@Override
@@ -5469,10 +5221,10 @@ index d683c49fdf2d1e5b0f2620641f9c241e82f96825..adfa18c941b5070692ed855d1d609993
}
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/Parrot.java b/src/main/java/net/minecraft/world/entity/animal/Parrot.java
-index f3f48225c2a1e4bd3d0091d1b4b7e4e150850ed2..670cf5a74554b0b420706db2fbce3a8e5dca147b 100644
+index 5ca96541abbb754f4d9fbe01f37ebaf19c532bbb..b8c69414b734eecb7412fab8ae6996712307da70 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Parrot.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Parrot.java
-@@ -131,12 +131,88 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder type, Level world) {
super(type, world);
@@ -5500,9 +5252,9 @@ index f3f48225c2a1e4bd3d0091d1b4b7e4e150850ed2..670cf5a74554b0b420706db2fbce3a8e
+ }
+ this.moveControl = new ParrotMoveControl(this, 10, false);
+ // Purpur end
- this.setPathfindingMalus(BlockPathTypes.DANGER_FIRE, -1.0F);
- this.setPathfindingMalus(BlockPathTypes.DAMAGE_FIRE, -1.0F);
- this.setPathfindingMalus(BlockPathTypes.COCOA, -1.0F);
+ this.setPathfindingMalus(PathType.DANGER_FIRE, -1.0F);
+ this.setPathfindingMalus(PathType.DAMAGE_FIRE, -1.0F);
+ this.setPathfindingMalus(PathType.COCOA, -1.0F);
}
+ // Purpur start
@@ -5561,8 +5313,8 @@ index f3f48225c2a1e4bd3d0091d1b4b7e4e150850ed2..670cf5a74554b0b420706db2fbce3a8e
+
@Nullable
@Override
- public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType spawnReason, @Nullable SpawnGroupData entityData, @Nullable CompoundTag entityNbt) {
-@@ -155,8 +231,11 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder type, LevelAccessor world, MobSpawnType spawnReason, BlockPos pos, RandomSource random) {
-@@ -308,13 +388,13 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder {
@@ -155,6 +193,17 @@ public class Pig extends Animal implements ItemSteerable, Saddleable {
public InteractionResult mobInteract(Player player, InteractionHand hand) {
boolean flag = this.isFood(player.getItemInHand(hand));
@@ -5688,7 +5440,7 @@ index 24770540c51fe4831040d6b46b27636d25ebac40..10d6361077a74c5685eca72d12f99e33
if (!this.level().isClientSide) {
player.startRiding(this);
diff --git a/src/main/java/net/minecraft/world/entity/animal/PolarBear.java b/src/main/java/net/minecraft/world/entity/animal/PolarBear.java
-index c9e10d4ce00b711b30de5d346a5ac26e7b441390..2fecdd574b407eeb1d0cd4f1b34ff7931e620540 100644
+index c87a57e8ceac32a6c8a603aa24f8cb053610e47c..9b6e07b0de7328b18c5e526b89cfd48fdbc79753 100644
--- a/src/main/java/net/minecraft/world/entity/animal/PolarBear.java
+++ b/src/main/java/net/minecraft/world/entity/animal/PolarBear.java
@@ -59,11 +59,81 @@ public class PolarBear extends Animal implements NeutralMob {
@@ -5824,10 +5576,10 @@ index c9e10d4ce00b711b30de5d346a5ac26e7b441390..2fecdd574b407eeb1d0cd4f1b34ff793
public float getStandingAnimationScale(float tickDelta) {
diff --git a/src/main/java/net/minecraft/world/entity/animal/Pufferfish.java b/src/main/java/net/minecraft/world/entity/animal/Pufferfish.java
-index a197337f2e09f53cf382022569c8836745d78769..54f5206b686c3cf4d2e5b470c07047a518f5dd00 100644
+index 3f0fad476fe573c3ba946a9436d1b3f7c5260ee2..c758f759ccae81b7651bfcba254f54335f2c7cc8 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Pufferfish.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Pufferfish.java
-@@ -45,6 +45,33 @@ public class Pufferfish extends AbstractFish {
+@@ -51,6 +51,33 @@ public class Pufferfish extends AbstractFish {
this.refreshDimensions();
}
@@ -5859,13 +5611,13 @@ index a197337f2e09f53cf382022569c8836745d78769..54f5206b686c3cf4d2e5b470c07047a5
+ }
+
@Override
- protected void defineSynchedData() {
- super.defineSynchedData();
+ protected void defineSynchedData(SynchedEntityData.Builder builder) {
+ super.defineSynchedData(builder);
diff --git a/src/main/java/net/minecraft/world/entity/animal/Rabbit.java b/src/main/java/net/minecraft/world/entity/animal/Rabbit.java
-index cf4859814a60468f683e3afe285b4934d35e9704..eae2488f2a46e543b496b7a2919aabbb55dcb825 100644
+index b58300e114e2e27ac68d7a9489bc52b127c9bc17..02702390c0b336762ce8c0d38d804e6f24ebbfd4 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Rabbit.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Rabbit.java
-@@ -87,6 +87,7 @@ public class Rabbit extends Animal implements VariantHolder {
+@@ -86,6 +86,7 @@ public class Rabbit extends Animal implements VariantHolder {
private boolean wasOnGround;
private int jumpDelayTicks;
public int moreCarrotTicks;
@@ -5873,7 +5625,7 @@ index cf4859814a60468f683e3afe285b4934d35e9704..eae2488f2a46e543b496b7a2919aabbb
public Rabbit(EntityType extends Rabbit> type, Level world) {
super(type, world);
-@@ -94,9 +95,75 @@ public class Rabbit extends Animal implements VariantHolder {
+@@ -93,9 +94,75 @@ public class Rabbit extends Animal implements VariantHolder {
this.moveControl = new Rabbit.RabbitMoveControl(this);
}
@@ -5949,7 +5701,7 @@ index cf4859814a60468f683e3afe285b4934d35e9704..eae2488f2a46e543b496b7a2919aabbb
this.goalSelector.addGoal(1, new ClimbOnTopOfPowderSnowGoal(this, this.level()));
this.goalSelector.addGoal(1, new Rabbit.RabbitPanicGoal(this, 2.2D));
this.goalSelector.addGoal(2, new BreedGoal(this, 0.8D));
-@@ -111,6 +178,14 @@ public class Rabbit extends Animal implements VariantHolder {
+@@ -112,6 +179,14 @@ public class Rabbit extends Animal implements VariantHolder {
@Override
protected float getJumpPower() {
@@ -5964,7 +5716,7 @@ index cf4859814a60468f683e3afe285b4934d35e9704..eae2488f2a46e543b496b7a2919aabbb
float f = 0.3F;
if (this.horizontalCollision || this.moveControl.hasWanted() && this.moveControl.getWantedY() > this.getY() + 0.5D) {
-@@ -135,7 +210,7 @@ public class Rabbit extends Animal implements VariantHolder {
+@@ -136,7 +211,7 @@ public class Rabbit extends Animal implements VariantHolder {
}
@Override
@@ -5973,7 +5725,7 @@ index cf4859814a60468f683e3afe285b4934d35e9704..eae2488f2a46e543b496b7a2919aabbb
super.jumpFromGround();
double d0 = this.moveControl.getSpeedModifier();
-@@ -185,6 +260,13 @@ public class Rabbit extends Animal implements VariantHolder {
+@@ -186,6 +261,13 @@ public class Rabbit extends Animal implements VariantHolder {
@Override
public void customServerAiStep() {
@@ -5987,7 +5739,7 @@ index cf4859814a60468f683e3afe285b4934d35e9704..eae2488f2a46e543b496b7a2919aabbb
if (this.jumpDelayTicks > 0) {
--this.jumpDelayTicks;
}
-@@ -402,10 +484,23 @@ public class Rabbit extends Animal implements VariantHolder {
+@@ -399,10 +481,23 @@ public class Rabbit extends Animal implements VariantHolder {
}
this.setVariant(entityrabbit_variant);
@@ -5998,7 +5750,7 @@ index cf4859814a60468f683e3afe285b4934d35e9704..eae2488f2a46e543b496b7a2919aabbb
+ }
+ // Purpur end
+
- return super.finalizeSpawn(world, difficulty, spawnReason, (SpawnGroupData) entityData, entityNbt);
+ return super.finalizeSpawn(world, difficulty, spawnReason, (SpawnGroupData) entityData);
}
private static Rabbit.Variant getRandomRabbitVariant(LevelAccessor world, BlockPos pos) {
@@ -6011,7 +5763,7 @@ index cf4859814a60468f683e3afe285b4934d35e9704..eae2488f2a46e543b496b7a2919aabbb
Holder holder = world.getBiome(pos);
int i = world.getRandom().nextInt(100);
-@@ -469,7 +564,7 @@ public class Rabbit extends Animal implements VariantHolder {
+@@ -466,7 +561,7 @@ public class Rabbit extends Animal implements VariantHolder {
}
}
@@ -6020,7 +5772,7 @@ index cf4859814a60468f683e3afe285b4934d35e9704..eae2488f2a46e543b496b7a2919aabbb
private final Rabbit rabbit;
private double nextJumpSpeed;
-@@ -480,14 +575,14 @@ public class Rabbit extends Animal implements VariantHolder {
+@@ -477,14 +572,14 @@ public class Rabbit extends Animal implements VariantHolder {
}
@Override
@@ -6037,7 +5789,7 @@ index cf4859814a60468f683e3afe285b4934d35e9704..eae2488f2a46e543b496b7a2919aabbb
}
@Override
-@@ -549,7 +644,7 @@ public class Rabbit extends Animal implements VariantHolder {
+@@ -546,7 +641,7 @@ public class Rabbit extends Animal implements VariantHolder {
@Override
public boolean canUse() {
if (this.nextStartTick <= 0) {
@@ -6085,10 +5837,10 @@ index 0af79daa357f53a8871e293b57e16c099e5d3f64..382e47f26ee94506cb76463a677351b9
public int getMaxSchoolSize() {
return 5;
diff --git a/src/main/java/net/minecraft/world/entity/animal/Sheep.java b/src/main/java/net/minecraft/world/entity/animal/Sheep.java
-index 865f244de1605303f22d8944174b0fe00115cab0..981429215b01ae1f03735d5ffc584108013b137e 100644
+index 0dfc2ccd8f454d0252542312661f65f41a6209ab..632562e3c27d11b73fdfb6b2f49c31edc761ed8d 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Sheep.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Sheep.java
-@@ -119,10 +119,48 @@ public class Sheep extends Animal implements Shearable {
+@@ -117,10 +117,48 @@ public class Sheep extends Animal implements Shearable {
super(type, world);
}
@@ -6136,8 +5888,8 @@ index 865f244de1605303f22d8944174b0fe00115cab0..981429215b01ae1f03735d5ffc584108
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur
this.goalSelector.addGoal(1, new PanicGoal(this, 1.25D));
this.goalSelector.addGoal(2, new BreedGoal(this, 1.0D));
- this.goalSelector.addGoal(3, new TemptGoal(this, 1.1D, Ingredient.of(Items.WHEAT), false));
-@@ -254,7 +292,7 @@ public class Sheep extends Animal implements Shearable {
+ this.goalSelector.addGoal(3, new TemptGoal(this, 1.1D, (itemstack) -> {
+@@ -259,7 +297,7 @@ public class Sheep extends Animal implements Shearable {
if (!this.level().isClientSide && this.readyForShearing()) {
// CraftBukkit start
// Paper start - custom shear drops
@@ -6146,7 +5898,7 @@ index 865f244de1605303f22d8944174b0fe00115cab0..981429215b01ae1f03735d5ffc584108
org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops);
if (event != null) {
if (event.isCancelled()) {
-@@ -281,12 +319,13 @@ public class Sheep extends Animal implements Shearable {
+@@ -284,12 +322,13 @@ public class Sheep extends Animal implements Shearable {
@Override
public void shear(SoundSource shearedSoundCategory) {
// Paper start - custom shear drops
@@ -6163,13 +5915,13 @@ index 865f244de1605303f22d8944174b0fe00115cab0..981429215b01ae1f03735d5ffc584108
for (int j = 0; j < count; ++j) {
dropEntities.add(new ItemStack(Sheep.ITEM_BY_DYE.get(this.getColor())));
diff --git a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
-index 9eab1170cb123d3b60a02314702516704f959ab7..a4f5e54a04311243bf804f579a7ed028bac22031 100644
+index 5c2ed3c39c8eb850f3be1e2ea5b5a7ea266e16d1..3b74931ae4e3a869d8db38c119e57b44af887859 100644
--- a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
+++ b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
-@@ -49,17 +49,56 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
+@@ -47,17 +47,56 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
+
private static final EntityDataAccessor DATA_PUMPKIN_ID = SynchedEntityData.defineId(SnowGolem.class, EntityDataSerializers.BYTE);
private static final byte PUMPKIN_FLAG = 16;
- private static final float EYE_HEIGHT = 1.7F;
+ @Nullable private java.util.UUID summoner; // Purpur
public SnowGolem(EntityType extends SnowGolem> type, Level world) {
@@ -6224,7 +5976,7 @@ index 9eab1170cb123d3b60a02314702516704f959ab7..a4f5e54a04311243bf804f579a7ed028
this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Mob.class, 10, true, false, (entityliving) -> {
return entityliving instanceof Enemy;
}));
-@@ -79,6 +118,7 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
+@@ -77,6 +116,7 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
public void addAdditionalSaveData(CompoundTag nbt) {
super.addAdditionalSaveData(nbt);
nbt.putBoolean("Pumpkin", this.hasPumpkin());
@@ -6232,7 +5984,7 @@ index 9eab1170cb123d3b60a02314702516704f959ab7..a4f5e54a04311243bf804f579a7ed028
}
@Override
-@@ -87,12 +127,13 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
+@@ -85,12 +125,13 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
if (nbt.contains("Pumpkin")) {
this.setPumpkin(nbt.getBoolean("Pumpkin"));
}
@@ -6247,7 +5999,7 @@ index 9eab1170cb123d3b60a02314702516704f959ab7..a4f5e54a04311243bf804f579a7ed028
}
@Override
-@@ -103,10 +144,11 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
+@@ -101,10 +142,11 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
this.hurt(this.damageSources().melting(), 1.0F); // CraftBukkit - DamageSources.ON_FIRE -> CraftEventFactory.MELTING
}
@@ -6260,7 +6012,7 @@ index 9eab1170cb123d3b60a02314702516704f959ab7..a4f5e54a04311243bf804f579a7ed028
BlockState iblockdata = Blocks.SNOW.defaultBlockState();
for (int i = 0; i < 4; ++i) {
-@@ -154,11 +196,11 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
+@@ -147,11 +189,11 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
if (itemstack.is(Items.SHEARS) && this.readyForShearing()) {
// CraftBukkit start
// Paper start - custom shear drops
@@ -6274,7 +6026,7 @@ index 9eab1170cb123d3b60a02314702516704f959ab7..a4f5e54a04311243bf804f579a7ed028
}
drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops());
}
-@@ -173,19 +215,36 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
+@@ -164,19 +206,36 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
}
return InteractionResult.sidedSuccess(this.level().isClientSide);
@@ -6310,20 +6062,20 @@ index 9eab1170cb123d3b60a02314702516704f959ab7..a4f5e54a04311243bf804f579a7ed028
+ }
+ return java.util.Collections.unmodifiableList(list);
+ }
-+ // Purpur end
++ // Purpur end
return java.util.Collections.singletonList(new ItemStack(Items.CARVED_PUMPKIN));
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/Squid.java b/src/main/java/net/minecraft/world/entity/animal/Squid.java
-index 36506dc4b99f9de19a23a99c1bccdcb4e7102e72..432a5b7e4887a6febee36467d6880c24370f750e 100644
+index 43b4ea96c5c4a6234e5b83d41db9b85c1fe27b8f..cb950ba3ee3bdfe0ff7acdb94c7ee233d73ab22e 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Squid.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Squid.java
-@@ -44,13 +44,66 @@ public class Squid extends WaterAnimal {
+@@ -42,13 +42,66 @@ public class Squid extends WaterAnimal {
public Squid(EntityType extends Squid> type, Level world) {
super(type, world);
- //this.random.setSeed((long)this.getId()); // Paper - Share random for entities to make them more random
-+ if (!world.purpurConfig.entitySharedRandom) this.random.setSeed((long) this.getId()); // Paper - Share random for entities to make them more random // Purpur
++ if (!world.purpurConfig.entitySharedRandom) this.random.setSeed((long)this.getId()); // Paper - Share random for entities to make them more random // Purpur
this.tentacleSpeed = 1.0F / (this.random.nextFloat() + 1.0F) * 0.2F;
}
@@ -6386,7 +6138,7 @@ index 36506dc4b99f9de19a23a99c1bccdcb4e7102e72..432a5b7e4887a6febee36467d6880c24
this.goalSelector.addGoal(1, new Squid.SquidFleeGoal());
}
-@@ -119,6 +172,7 @@ public class Squid extends WaterAnimal {
+@@ -117,6 +170,7 @@ public class Squid extends WaterAnimal {
}
if (this.isInWaterOrBubble()) {
@@ -6394,7 +6146,7 @@ index 36506dc4b99f9de19a23a99c1bccdcb4e7102e72..432a5b7e4887a6febee36467d6880c24
if (this.tentacleMovement < (float) Math.PI) {
float f = this.tentacleMovement / (float) Math.PI;
this.tentacleAngle = Mth.sin(f * f * (float) Math.PI) * (float) Math.PI * 0.25F;
-@@ -292,10 +346,41 @@ public class Squid extends WaterAnimal {
+@@ -290,10 +344,41 @@ public class Squid extends WaterAnimal {
@Override
public void tick() {
@@ -6438,10 +6190,10 @@ index 36506dc4b99f9de19a23a99c1bccdcb4e7102e72..432a5b7e4887a6febee36467d6880c24
float g = Mth.cos(f) * 0.2F;
float h = -0.1F + this.squid.getRandom().nextFloat() * 0.2F;
diff --git a/src/main/java/net/minecraft/world/entity/animal/TropicalFish.java b/src/main/java/net/minecraft/world/entity/animal/TropicalFish.java
-index 6e9e86b6d547d7437c990b65718b95ad0d60f020..98205d89aa0cca82863257abfad46ab834385a20 100644
+index 3d03ffe2e12eca82dfa2f414471d12bb362d4552..2d04addd17d2c358fff598012b323cd7d8bf007e 100644
--- a/src/main/java/net/minecraft/world/entity/animal/TropicalFish.java
+++ b/src/main/java/net/minecraft/world/entity/animal/TropicalFish.java
-@@ -65,6 +65,33 @@ public class TropicalFish extends AbstractSchoolingFish implements VariantHolder
+@@ -67,6 +67,33 @@ public class TropicalFish extends AbstractSchoolingFish implements VariantHolder
super(type, world);
}
@@ -6476,11 +6228,11 @@ index 6e9e86b6d547d7437c990b65718b95ad0d60f020..98205d89aa0cca82863257abfad46ab8
return "entity.minecraft.tropical_fish.predefined." + variant;
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/Turtle.java b/src/main/java/net/minecraft/world/entity/animal/Turtle.java
-index 2eb099957a3d0bae3339ff4edbab103fb348abed..2153dac7c7c83ef3192d2b8370b8924ee67383a8 100644
+index 30b87b5cb18c25cdd04eab64cfbe5acd6c1b6d84..01dc59695f295657b1cd7bb015558bfc2ce73b47 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java
-@@ -86,6 +86,43 @@ public class Turtle extends Animal {
- this.setMaxUpStep(1.0F);
+@@ -87,6 +87,43 @@ public class Turtle extends Animal {
+ this.moveControl = new Turtle.TurtleMoveControl(this);
}
+ // Purpur start
@@ -6523,7 +6275,7 @@ index 2eb099957a3d0bae3339ff4edbab103fb348abed..2153dac7c7c83ef3192d2b8370b8924e
public void setHomePos(BlockPos pos) {
this.entityData.set(Turtle.HOME_POS, pos.immutable()); // Paper - called with mutablepos...
}
-@@ -188,6 +225,7 @@ public class Turtle extends Animal {
+@@ -189,6 +226,7 @@ public class Turtle extends Animal {
@Override
protected void registerGoals() {
@@ -6531,8 +6283,8 @@ index 2eb099957a3d0bae3339ff4edbab103fb348abed..2153dac7c7c83ef3192d2b8370b8924e
this.goalSelector.addGoal(0, new Turtle.TurtlePanicGoal(this, 1.2D));
this.goalSelector.addGoal(1, new Turtle.TurtleBreedGoal(this, 1.0D));
this.goalSelector.addGoal(1, new Turtle.TurtleLayEggGoal(this, 1.0D));
-@@ -344,13 +382,15 @@ public class Turtle extends Animal {
- return new Vector3f(0.0F, dimensions.height + (this.isBaby() ? 0.0F : 0.15625F) * scaleFactor, -0.25F * scaleFactor);
+@@ -342,13 +380,15 @@ public class Turtle extends Animal {
+ return this.isBaby() ? Turtle.BABY_DIMENSIONS : super.getDefaultDimensions(pose);
}
- private static class TurtleMoveControl extends MoveControl {
@@ -6548,7 +6300,7 @@ index 2eb099957a3d0bae3339ff4edbab103fb348abed..2153dac7c7c83ef3192d2b8370b8924e
}
private void updateSpeed() {
-@@ -370,7 +410,7 @@ public class Turtle extends Animal {
+@@ -368,7 +408,7 @@ public class Turtle extends Animal {
}
@Override
@@ -6557,7 +6309,7 @@ index 2eb099957a3d0bae3339ff4edbab103fb348abed..2153dac7c7c83ef3192d2b8370b8924e
this.updateSpeed();
if (this.operation == MoveControl.Operation.MOVE_TO && !this.turtle.getNavigation().isDone()) {
double d0 = this.wantedX - this.turtle.getX();
-@@ -386,7 +426,7 @@ public class Turtle extends Animal {
+@@ -384,7 +424,7 @@ public class Turtle extends Animal {
this.turtle.setYRot(this.rotlerp(this.turtle.getYRot(), f, 90.0F));
this.turtle.yBodyRot = this.turtle.getYRot();
@@ -6567,63 +6319,27 @@ index 2eb099957a3d0bae3339ff4edbab103fb348abed..2153dac7c7c83ef3192d2b8370b8924e
this.turtle.setSpeed(Mth.lerp(0.125F, this.turtle.getSpeed(), f1));
this.turtle.setDeltaMovement(this.turtle.getDeltaMovement().add(0.0D, (double) this.turtle.getSpeed() * d1 * 0.1D, 0.0D));
diff --git a/src/main/java/net/minecraft/world/entity/animal/Wolf.java b/src/main/java/net/minecraft/world/entity/animal/Wolf.java
-index 2d20b2c1f58beb1ad8c9012d8124e476899e6be6..a90055fe8819a32180754b6060a0f88e81d1a3b6 100644
+index b5ee82e5abfecc59e2362628f288b76881855f36..b12544d1280f39b6c365317a0f4965c8d65b6497 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Wolf.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Wolf.java
-@@ -10,6 +10,7 @@ import net.minecraft.network.syncher.EntityDataAccessor;
- import net.minecraft.network.syncher.EntityDataSerializers;
- import net.minecraft.network.syncher.SynchedEntityData;
- import net.minecraft.server.level.ServerLevel;
-+import net.minecraft.server.level.ServerPlayer;
- import net.minecraft.sounds.SoundEvent;
- import net.minecraft.sounds.SoundEvents;
- import net.minecraft.tags.BlockTags;
-@@ -17,9 +18,12 @@ import net.minecraft.util.Mth;
- import net.minecraft.util.RandomSource;
- import net.minecraft.util.TimeUtil;
- import net.minecraft.util.valueproviders.UniformInt;
-+import net.minecraft.world.DifficultyInstance;
+@@ -30,6 +30,8 @@ import net.minecraft.world.DifficultyInstance;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.damagesource.DamageSource;
+import net.minecraft.world.effect.MobEffectInstance;
+import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.AgeableMob;
+ import net.minecraft.world.entity.Crackiness;
import net.minecraft.world.entity.Entity;
- import net.minecraft.world.entity.EntityDimensions;
-@@ -29,6 +33,7 @@ import net.minecraft.world.entity.Mob;
- import net.minecraft.world.entity.MobSpawnType;
- import net.minecraft.world.entity.NeutralMob;
- import net.minecraft.world.entity.Pose;
-+import net.minecraft.world.entity.SpawnGroupData;
- import net.minecraft.world.entity.TamableAnimal;
- import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
- import net.minecraft.world.entity.ai.attributes.Attributes;
-@@ -37,6 +42,7 @@ import net.minecraft.world.entity.ai.goal.BegGoal;
- import net.minecraft.world.entity.ai.goal.BreedGoal;
- import net.minecraft.world.entity.ai.goal.FloatGoal;
- import net.minecraft.world.entity.ai.goal.FollowOwnerGoal;
-+import net.minecraft.world.entity.ai.goal.Goal;
- import net.minecraft.world.entity.ai.goal.LeapAtTargetGoal;
- import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal;
- import net.minecraft.world.entity.ai.goal.MeleeAttackGoal;
-@@ -64,6 +70,7 @@ import net.minecraft.world.item.ItemStack;
- import net.minecraft.world.item.Items;
- import net.minecraft.world.level.Level;
- import net.minecraft.world.level.LevelAccessor;
-+import net.minecraft.world.level.ServerLevelAccessor;
- import net.minecraft.world.level.block.state.BlockState;
- import net.minecraft.world.level.gameevent.GameEvent;
- import net.minecraft.world.level.pathfinder.BlockPathTypes;
-@@ -86,6 +93,37 @@ public class Wolf extends TamableAnimal implements NeutralMob {
+@@ -104,6 +106,37 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder RABID_PREDICATE = entity -> entity instanceof ServerPlayer || entity instanceof Mob;
-+ private final Goal PATHFINDER_VANILLA = new NonTameRandomTargetGoal<>(this, Animal.class, false, PREY_SELECTOR);
-+ private final Goal PATHFINDER_RABID = new NonTameRandomTargetGoal<>(this, LivingEntity.class, false, RABID_PREDICATE);
++ private static final Predicate RABID_PREDICATE = entity -> entity instanceof net.minecraft.server.level.ServerPlayer || entity instanceof Mob;
++ private final net.minecraft.world.entity.ai.goal.Goal PATHFINDER_VANILLA = new NonTameRandomTargetGoal<>(this, Animal.class, false, PREY_SELECTOR);
++ private final net.minecraft.world.entity.ai.goal.Goal PATHFINDER_RABID = new NonTameRandomTargetGoal<>(this, LivingEntity.class, false, RABID_PREDICATE);
+ private static final class AvoidRabidWolfGoal extends AvoidEntityGoal {
+ private final Wolf wolf;
+
@@ -6651,10 +6367,10 @@ index 2d20b2c1f58beb1ad8c9012d8124e476899e6be6..a90055fe8819a32180754b6060a0f88e
+ }
+ // Purpur end
private static final float START_HEALTH = 8.0F;
- private static final float TAME_HEALTH = 20.0F;
- private float interestedAngle;
-@@ -105,12 +143,93 @@ public class Wolf extends TamableAnimal implements NeutralMob {
- this.setPathfindingMalus(BlockPathTypes.DANGER_POWDER_SNOW, -1.0F);
+ private static final float TAME_HEALTH = 40.0F;
+ private static final float ARMOR_REPAIR_UNIT = 0.125F;
+@@ -124,12 +157,86 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder 0.0D && random.nextDouble() <= world.getLevel().purpurConfig.wolfNaturalRabid;
-+ this.updatePathfinders(false);
-+ return super.finalizeSpawn(world, difficulty, type, data, nbt);
-+ }
-+
-+ @Override
+ public void tame(Player player) {
+ setCollarColor(level().purpurConfig.wolfDefaultCollarColor);
+ super.tame(player);
@@ -6740,14 +6449,14 @@ index 2d20b2c1f58beb1ad8c9012d8124e476899e6be6..a90055fe8819a32180754b6060a0f88e
protected void registerGoals() {
this.goalSelector.addGoal(1, new FloatGoal(this));
+ this.goalSelector.addGoal(1, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur
- this.goalSelector.addGoal(1, new Wolf.WolfPanicGoal(1.5D));
+ this.goalSelector.addGoal(1, new Wolf.WolfPanicGoal(this, 1.5D));
this.goalSelector.addGoal(2, new SitWhenOrderedToGoal(this));
this.goalSelector.addGoal(3, new Wolf.WolfAvoidEntityGoal<>(this, Llama.class, 24.0F, 1.5D, 1.5D));
+ this.goalSelector.addGoal(3, new AvoidRabidWolfGoal(this, 24.0F, 1.5D, 1.5D)); // Purpur
this.goalSelector.addGoal(4, new LeapAtTargetGoal(this, 0.4F));
this.goalSelector.addGoal(5, new MeleeAttackGoal(this, 1.0D, true));
this.goalSelector.addGoal(6, new FollowOwnerGoal(this, 1.0D, 10.0F, 2.0F, false));
-@@ -119,11 +238,12 @@ public class Wolf extends TamableAnimal implements NeutralMob {
+@@ -138,11 +245,12 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder(this, Turtle.class, false, Turtle.BABY_ON_LAND_SELECTOR));
this.targetSelector.addGoal(7, new NearestAttackableTargetGoal<>(this, AbstractSkeleton.class, false));
this.targetSelector.addGoal(8, new ResetUniversalAngerTargetGoal<>(this, true));
-@@ -150,6 +270,7 @@ public class Wolf extends TamableAnimal implements NeutralMob {
+@@ -185,6 +293,7 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder 0.0D && random.nextDouble() <= world.getLevel().purpurConfig.wolfNaturalRabid;
++ this.updatePathfinders(false);
++ // Purpur end
++
+ return super.finalizeSpawn(world, difficulty, spawnReason, (SpawnGroupData) entityData);
+ }
+
+@@ -261,6 +380,11 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder brainProvider() {
return Brain.provider(Allay.MEMORY_TYPES, Allay.SENSOR_TYPES);
-@@ -224,7 +259,7 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS
+@@ -218,7 +253,7 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS
private int behaviorTick = 0; // Pufferfish
@Override
protected void customServerAiStep() {
@@ -6888,47 +6610,28 @@ index c521ff04be40bfa892021f67acc1b324551fcd5e..eb60d2d99155aae4a761051175fbbddf
this.getBrain().tick((ServerLevel) this.level(), this);
AllayAi.updateActivity(this);
super.customServerAiStep();
-@@ -367,9 +402,31 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS
-
- @Override
- public boolean wantsToPickUp(ItemStack stack) {
-- ItemStack itemstack1 = this.getItemInHand(InteractionHand.MAIN_HAND);
--
-- return !itemstack1.isEmpty() && this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && this.inventory.canAddItem(stack) && this.allayConsidersItemEqual(itemstack1, stack);
-+ // Purpur start
-+ if (!this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
-+ return false;
-+ }
-+ ItemStack itemStack = this.getItemInHand(InteractionHand.MAIN_HAND);
-+ if (itemStack.isEmpty()) {
-+ return false;
-+ }
-+ if (!allayConsidersItemEqual(itemStack, stack)) {
-+ return false;
-+ }
-+ if (!this.inventory.canAddItem(stack)) {
-+ return false;
-+ }
-+ for (String tag : this.level().purpurConfig.allayRespectNBT) {
-+ if (stack.hasTag() && itemStack.hasTag()) {
-+ Tag tag1 = stack.getTag().get(tag);
-+ Tag tag2 = itemStack.getTag().get(tag);
-+ if (!Objects.equals(tag1, tag2)) {
-+ return false;
-+ }
-+ }
-+ }
-+ return true;
-+ // Purpur end
+diff --git a/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java b/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java
+index 6a3b119bdcac4de1b39216b23ba8dceae062d278..063dde771ade593a29481f14b8f44a0f72f15953 100644
+--- a/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java
++++ b/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java
+@@ -465,4 +465,11 @@ public class Armadillo extends Animal {
+ return this.animationDuration;
+ }
}
-
- private boolean allayConsidersItemEqual(ItemStack stack, ItemStack stack2) {
++
++ // Purpur start
++ @Override
++ public int getPurpurBreedTime() {
++ return 6000;
++ }
++ // Purpur end
+ }
diff --git a/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java b/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java
-index d0c624a6a000c2a41e41d14dd785a7bf9612afe8..bcc49ca8afa9794952883098a586d0e1b89d04d5 100644
+index d339e9c0b81a50d20048375bd8b4141618fc1d2a..3409b0eaf9f09a92846359ca58ecda7deb17c099 100644
--- a/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java
+++ b/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java
-@@ -98,6 +98,43 @@ public class Axolotl extends Animal implements LerpingModel, VariantHolder getModelRotationValues() {
return this.modelRotationValues;
-@@ -278,7 +315,7 @@ public class Axolotl extends Animal implements LerpingModel, VariantHolder {
+@@ -103,6 +103,8 @@ public class Frog extends Animal implements VariantHolder> {
public final AnimationState croakAnimationState = new AnimationState();
public final AnimationState tongueAnimationState = new AnimationState();
public final AnimationState swimIdleAnimationState = new AnimationState();
@@ -7074,10 +6777,10 @@ index 791791fa03c402998fa99b5da9e9f969b256bf4e..44b17f1c6367b729d6e8f7f45c5689a1
public Frog(EntityType extends Animal> type, Level world) {
super(type, world);
- this.lookControl = new Frog.FrogLookControl(this);
- this.setPathfindingMalus(BlockPathTypes.WATER, 4.0F);
- this.setPathfindingMalus(BlockPathTypes.TRAPDOOR, -1.0F);
-- this.moveControl = new SmoothSwimmingMoveControl(this, 85, 10, 0.02F, 0.1F, true);
+@@ -110,6 +112,58 @@ public class Frog extends Animal implements VariantHolder> {
+ this.setPathfindingMalus(PathType.WATER, 4.0F);
+ this.setPathfindingMalus(PathType.TRAPDOOR, -1.0F);
+ this.moveControl = new SmoothSwimmingMoveControl(this, 85, 10, 0.02F, 0.1F, true);
+ // Purpur start
+ this.purpurLandController = new org.purpurmc.purpur.controller.MoveControllerWASD(this, 0.2F);
+ this.purpurWaterController = new org.purpurmc.purpur.controller.WaterMoveControllerWASD(this, 0.5F);
@@ -7098,9 +6801,8 @@ index 791791fa03c402998fa99b5da9e9f969b256bf4e..44b17f1c6367b729d6e8f7f45c5689a1
+ }
+ };
+ // Purpur end
- this.setMaxUpStep(1.0F);
- }
-
++ }
++
+ // Purpur start
+ @Override
+ public boolean isRidable() {
@@ -7131,12 +6833,10 @@ index 791791fa03c402998fa99b5da9e9f969b256bf4e..44b17f1c6367b729d6e8f7f45c5689a1
+
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.frogBreedingTicks;
-+ }
-+
+ }
+
@Override
- protected Brain.Provider brainProvider() {
- return Brain.provider(MEMORY_TYPES, SENSOR_TYPES);
-@@ -186,7 +239,7 @@ public class Frog extends Animal implements VariantHolder {
+@@ -184,7 +238,7 @@ public class Frog extends Animal implements VariantHolder> {
private int behaviorTick = 0; // Pufferfish
@Override
protected void customServerAiStep() {
@@ -7145,20 +6845,20 @@ index 791791fa03c402998fa99b5da9e9f969b256bf4e..44b17f1c6367b729d6e8f7f45c5689a1
this.getBrain().tick((ServerLevel)this.level(), this);
FrogAi.updateActivity(this);
super.customServerAiStep();
-@@ -372,7 +425,7 @@ public class Frog extends Animal implements VariantHolder {
+@@ -369,7 +423,7 @@ public class Frog extends Animal implements VariantHolder> {
return world.getBlockState(pos.below()).is(BlockTags.FROGS_SPAWNABLE_ON) && isBrightEnoughToSpawn(world, pos);
}
- class FrogLookControl extends LookControl {
+ class FrogLookControl extends org.purpurmc.purpur.controller.LookControllerWASD { // Purpur
- FrogLookControl(Mob entity) {
+ FrogLookControl(final Mob entity) {
super(entity);
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java b/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java
-index 257687004b03e17cf3f5c0ea4c4cfeb7f34033e4..93e321a0b8fdce12968f03b3cfe6724ae564b823 100644
+index 40dad395aabb04c21ac26fadce823ce8b4f79b3a..e6861fd5f9817ec54294976f0e93952baa387773 100644
--- a/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java
+++ b/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java
-@@ -48,13 +48,50 @@ public class Tadpole extends AbstractFish {
+@@ -51,13 +51,50 @@ public class Tadpole extends AbstractFish {
protected static final ImmutableList>> SENSOR_TYPES = ImmutableList.of(SensorType.NEAREST_LIVING_ENTITIES, SensorType.NEAREST_PLAYERS, SensorType.HURT_BY, SensorType.FROG_TEMPTATIONS);
protected static final ImmutableList> MEMORY_TYPES = ImmutableList.of(MemoryModuleType.LOOK_TARGET, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.WALK_TARGET, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.PATH, MemoryModuleType.NEAREST_VISIBLE_ADULT, MemoryModuleType.TEMPTATION_COOLDOWN_TICKS, MemoryModuleType.IS_TEMPTED, MemoryModuleType.TEMPTING_PLAYER, MemoryModuleType.BREED_TARGET, MemoryModuleType.IS_PANICKING);
public boolean ageLocked; // Paper
@@ -7210,22 +6910,20 @@ index 257687004b03e17cf3f5c0ea4c4cfeb7f34033e4..93e321a0b8fdce12968f03b3cfe6724a
@Override
protected PathNavigation createNavigation(Level world) {
return new WaterBoundPathNavigation(this, world);
-@@ -83,8 +120,8 @@ public class Tadpole extends AbstractFish {
+@@ -86,7 +123,7 @@ public class Tadpole extends AbstractFish {
private int behaviorTick = 0; // Pufferfish
@Override
protected void customServerAiStep() {
- if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish
-- this.getBrain().tick((ServerLevel) this.level(), this);
+ if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider
-+ //this.getBrain().tick((ServerLevel) this.level(), this); // Dreeam TODO - should remove this?
+ this.getBrain().tick((ServerLevel) this.level(), this);
TadpoleAi.updateActivity(this);
super.customServerAiStep();
- }
diff --git a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
-index d75178611f2c74af45e39c9e37770e2c56773b1d..af81fa69336d21408de3703def803af9e303be4a 100644
+index 1bf1e2714f210188202a97219765428f9cf2c956..65d01a9c1b2d66446eb08a4a2bcdbe8284ce9e43 100644
--- a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
+++ b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
-@@ -92,6 +92,38 @@ public class Goat extends Animal {
+@@ -91,6 +91,38 @@ public class Goat extends Animal {
return InstrumentItem.create(Items.GOAT_HORN, (Holder) holderset.getRandomElement(randomsource).get());
}
@@ -7264,7 +6962,7 @@ index d75178611f2c74af45e39c9e37770e2c56773b1d..af81fa69336d21408de3703def803af9
@Override
protected Brain.Provider brainProvider() {
return Brain.provider(Goat.MEMORY_TYPES, Goat.SENSOR_TYPES);
-@@ -194,7 +226,7 @@ public class Goat extends Animal {
+@@ -193,7 +225,7 @@ public class Goat extends Animal {
private int behaviorTick = 0; // Pufferfish
@Override
protected void customServerAiStep() {
@@ -7273,7 +6971,7 @@ index d75178611f2c74af45e39c9e37770e2c56773b1d..af81fa69336d21408de3703def803af9
this.getBrain().tick((ServerLevel) this.level(), this);
GoatAi.updateActivity(this);
super.customServerAiStep();
-@@ -393,6 +425,7 @@ public class Goat extends Animal {
+@@ -392,6 +424,7 @@ public class Goat extends Animal {
// Paper start - Goat ram API
public void ram(net.minecraft.world.entity.LivingEntity entity) {
@@ -7282,16 +6980,15 @@ index d75178611f2c74af45e39c9e37770e2c56773b1d..af81fa69336d21408de3703def803af9
brain.setMemory(MemoryModuleType.RAM_TARGET, entity.position());
brain.eraseMemory(MemoryModuleType.RAM_COOLDOWN_TICKS);
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
-index 815eb15086976b8f9e03bf8182d9ed50aec14720..3170f9044f18b8c609433ddbd3ef9ac330644a0f 100644
+index 9357cf0179d19fbdfe76413e909a99b924c85780..59829fb7342696d29aa709d392f89bf263257fd3 100644
--- a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
-@@ -149,12 +149,60 @@ public abstract class AbstractHorse extends Animal implements ContainerListener,
+@@ -217,11 +217,59 @@ public abstract class AbstractHorse extends Animal implements ContainerListener,
protected AbstractHorse(EntityType extends AbstractHorse> type, Level world) {
super(type, world);
+ this.moveControl = new net.minecraft.world.entity.ai.control.MoveControl(this); // Purpur - use vanilla controller
+ this.lookControl = new net.minecraft.world.entity.ai.control.LookControl(this); // Purpur - use vanilla controller
- this.setMaxUpStep(1.0F);
this.createInventory();
}
@@ -7346,7 +7043,7 @@ index 815eb15086976b8f9e03bf8182d9ed50aec14720..3170f9044f18b8c609433ddbd3ef9ac3
this.goalSelector.addGoal(1, new PanicGoal(this, 1.2D));
this.goalSelector.addGoal(1, new RunAroundLikeCrazyGoal(this, 1.2D));
this.goalSelector.addGoal(2, new BreedGoal(this, 1.0D, AbstractHorse.class));
-@@ -165,6 +213,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener,
+@@ -232,6 +280,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener,
if (this.canPerformRearing()) {
this.goalSelector.addGoal(9, new RandomStandGoal(this));
}
@@ -7354,26 +7051,17 @@ index 815eb15086976b8f9e03bf8182d9ed50aec14720..3170f9044f18b8c609433ddbd3ef9ac3
this.addBehaviourGoals();
}
-@@ -337,7 +386,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener,
-
- @Override
- protected int calculateFallDamage(float fallDistance, float damageMultiplier) {
-- return Mth.ceil((fallDistance * 0.5F - 3.0F) * damageMultiplier);
-+ return Mth.ceil((fallDistance * 0.5F - this.safeFallDistance) * damageMultiplier);
- }
-
- protected int getInventorySize() {
-@@ -1231,7 +1280,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener,
+@@ -1249,7 +1298,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener,
entityData = new AgeableMob.AgeableMobGroupData(0.2F);
}
- this.randomizeAttributes(world.getRandom());
+ // this.randomizeAttributes(world.getRandom()); // Purpur - replaced by initAttributes()
- return super.finalizeSpawn(world, difficulty, spawnReason, (SpawnGroupData) entityData, entityNbt);
+ return super.finalizeSpawn(world, difficulty, spawnReason, (SpawnGroupData) entityData);
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/Donkey.java b/src/main/java/net/minecraft/world/entity/animal/horse/Donkey.java
-index 8c14f9f2ad383f87c498126f135b460a241da410..42efd14b59a2b7da3409895bdff49e83b6cb2fa5 100644
+index ff02169ba14f5264cea8beaf1779e2890c5d74b8..94021abe521aea4a70f5eaa78fb05f9f71b7c38c 100644
--- a/src/main/java/net/minecraft/world/entity/animal/horse/Donkey.java
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/Donkey.java
@@ -15,6 +15,43 @@ public class Donkey extends AbstractChestedHorse {
@@ -7421,10 +7109,10 @@ index 8c14f9f2ad383f87c498126f135b460a241da410..42efd14b59a2b7da3409895bdff49e83
protected SoundEvent getAmbientSound() {
return SoundEvents.DONKEY_AMBIENT;
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/Horse.java b/src/main/java/net/minecraft/world/entity/animal/horse/Horse.java
-index 2181d74ad955197eb4f1925a64914a6197fa9023..eab6efcae632a393924d7245a71c40b57c6e316d 100644
+index 6e299770fca78699f7e1988db4cdef37b99d74c1..fdf9ec418b0fc567e286ac79dbdbeddac568ad67 100644
--- a/src/main/java/net/minecraft/world/entity/animal/horse/Horse.java
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/Horse.java
-@@ -40,6 +40,43 @@ public class Horse extends AbstractHorse implements VariantHolder {
+@@ -44,6 +44,43 @@ public class Horse extends AbstractHorse implements VariantHolder {
super(type, world);
}
@@ -7469,7 +7157,7 @@ index 2181d74ad955197eb4f1925a64914a6197fa9023..eab6efcae632a393924d7245a71c40b5
protected void randomizeAttributes(RandomSource random) {
this.getAttribute(Attributes.MAX_HEALTH).setBaseValue((double)generateMaxHealth(random::nextInt));
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java b/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java
-index 6623674136b0f865d5b3d7a10d3bf05793b82f87..22abcf70f51a6752ab6d3f421366adb196e50dfc 100644
+index 1dd4290287725898ace29e46b439b55df8fdd1af..7d2a5c806fd0f1228c45b8a8b56d7ba13b899a2d 100644
--- a/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java
@@ -75,9 +75,84 @@ public class Llama extends AbstractChestedHorse implements VariantHolder 0 && this.level().getEntitiesOfClass(EndCrystal.class, getBoundingBox()).size() > this.level().purpurConfig.endCrystalCramming) this.hurt(this.damageSources().cramming(), 6.0F); // Purpur
+ }
+
-+ // Purpur start
++ // Purpur start
+ if (level().purpurConfig.phantomAttackedByCrystalRadius <= 0 || --idleCooldown > 0) {
+ return; // on cooldown
+ }
@@ -7991,12 +7676,11 @@ index 036640d49a5e891e9a0f767abe33f1f51d6d4cde..fcca438db945c1c7327cf3a979de01f0
+ phantomBeamTicks = 0;
+ phantomDamageCooldown = 0;
+ idleCooldown = 60;
- }
+ // Purpur end
+ }
@Override
- protected void addAdditionalSaveData(CompoundTag nbt) {
-@@ -124,16 +190,18 @@ public class EndCrystal extends Entity {
+@@ -121,16 +187,18 @@ public class EndCrystal extends Entity {
}
// CraftBukkit end
if (!source.is(DamageTypeTags.IS_EXPLOSION)) {
@@ -8018,10 +7702,10 @@ index 036640d49a5e891e9a0f767abe33f1f51d6d4cde..fcca438db945c1c7327cf3a979de01f0
this.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause
}
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
-index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a77996018e589807 100644
+index 6f14607a88761171a72e274b3c9b476b20a272f1..3da1f7a6e443954e4976dd59391ea19b9c903cf7 100644
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
-@@ -108,6 +108,7 @@ public class EnderDragon extends Mob implements Enemy {
+@@ -106,6 +106,7 @@ public class EnderDragon extends Mob implements Enemy {
@Nullable
private BlockPos podium;
// Paper end - Allow changing the EnderDragon podium
@@ -8029,7 +7713,7 @@ index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a7799601
public EnderDragon(EntityType extends EnderDragon> entitytypes, Level world) {
super(EntityType.ENDER_DRAGON, world);
-@@ -130,6 +131,37 @@ public class EnderDragon extends Mob implements Enemy {
+@@ -128,6 +129,37 @@ public class EnderDragon extends Mob implements Enemy {
this.noCulling = true;
this.phaseManager = new EnderDragonPhaseManager(this);
this.explosionSource = new Explosion(world, this, null, null, Double.NaN, Double.NaN, Double.NaN, Float.NaN, true, Explosion.BlockInteraction.DESTROY, ParticleTypes.EXPLOSION, ParticleTypes.EXPLOSION_EMITTER, SoundEvents.GENERIC_EXPLODE); // CraftBukkit
@@ -8067,7 +7751,7 @@ index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a7799601
}
public void setDragonFight(EndDragonFight fight) {
-@@ -144,6 +176,27 @@ public class EnderDragon extends Mob implements Enemy {
+@@ -142,6 +174,27 @@ public class EnderDragon extends Mob implements Enemy {
return this.fightOrigin;
}
@@ -8095,7 +7779,7 @@ index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a7799601
public static AttributeSupplier.Builder createAttributes() {
return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 200.0D);
}
-@@ -205,6 +258,37 @@ public class EnderDragon extends Mob implements Enemy {
+@@ -203,6 +256,37 @@ public class EnderDragon extends Mob implements Enemy {
@Override
public void aiStep() {
@@ -8133,7 +7817,7 @@ index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a7799601
this.processFlappingMovement();
if (this.level().isClientSide) {
this.setHealth(this.getHealth());
-@@ -231,6 +315,8 @@ public class EnderDragon extends Mob implements Enemy {
+@@ -229,6 +313,8 @@ public class EnderDragon extends Mob implements Enemy {
float f;
if (this.isDeadOrDying()) {
@@ -8142,7 +7826,7 @@ index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a7799601
float f1 = (this.random.nextFloat() - 0.5F) * 8.0F;
f = (this.random.nextFloat() - 0.5F) * 4.0F;
-@@ -243,9 +329,9 @@ public class EnderDragon extends Mob implements Enemy {
+@@ -241,9 +327,9 @@ public class EnderDragon extends Mob implements Enemy {
f = 0.2F / ((float) vec3d.horizontalDistance() * 10.0F + 1.0F);
f *= (float) Math.pow(2.0D, vec3d.y);
@@ -8154,7 +7838,7 @@ index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a7799601
this.flapTime += f * 0.5F;
} else {
this.flapTime += f;
-@@ -279,7 +365,7 @@ public class EnderDragon extends Mob implements Enemy {
+@@ -277,7 +363,7 @@ public class EnderDragon extends Mob implements Enemy {
}
this.phaseManager.getCurrentPhase().doClientTick();
@@ -8163,7 +7847,7 @@ index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a7799601
DragonPhaseInstance idragoncontroller = this.phaseManager.getCurrentPhase();
idragoncontroller.doServerTick();
-@@ -348,7 +434,7 @@ public class EnderDragon extends Mob implements Enemy {
+@@ -346,7 +432,7 @@ public class EnderDragon extends Mob implements Enemy {
this.tickPart(this.body, (double) (f11 * 0.5F), 0.0D, (double) (-f12 * 0.5F));
this.tickPart(this.wing1, (double) (f12 * 4.5F), 2.0D, (double) (f11 * 4.5F));
this.tickPart(this.wing2, (double) (f12 * -4.5F), 2.0D, (double) (f11 * -4.5F));
@@ -8172,7 +7856,7 @@ index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a7799601
this.knockBack(this.level().getEntities((Entity) this, this.wing1.getBoundingBox().inflate(4.0D, 2.0D, 4.0D).move(0.0D, -2.0D, 0.0D), EntitySelector.NO_CREATIVE_OR_SPECTATOR));
this.knockBack(this.level().getEntities((Entity) this, this.wing2.getBoundingBox().inflate(4.0D, 2.0D, 4.0D).move(0.0D, -2.0D, 0.0D), EntitySelector.NO_CREATIVE_OR_SPECTATOR));
this.hurt(this.level().getEntities((Entity) this, this.head.getBoundingBox().inflate(1.0D), EntitySelector.NO_CREATIVE_OR_SPECTATOR));
-@@ -392,7 +478,7 @@ public class EnderDragon extends Mob implements Enemy {
+@@ -390,7 +476,7 @@ public class EnderDragon extends Mob implements Enemy {
}
if (!this.level().isClientSide) {
@@ -8181,7 +7865,7 @@ index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a7799601
if (this.dragonFight != null) {
this.dragonFight.updateDragon(this);
}
-@@ -524,7 +610,7 @@ public class EnderDragon extends Mob implements Enemy {
+@@ -522,7 +608,7 @@ public class EnderDragon extends Mob implements Enemy {
BlockState iblockdata = this.level().getBlockState(blockposition);
if (!iblockdata.isAir() && !iblockdata.is(BlockTags.DRAGON_TRANSPARENT)) {
@@ -8190,7 +7874,7 @@ index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a7799601
// CraftBukkit start - Add blocks to list rather than destroying them
// flag1 = this.level().removeBlock(blockposition, false) || flag1;
flag1 = true;
-@@ -668,7 +754,7 @@ public class EnderDragon extends Mob implements Enemy {
+@@ -666,7 +752,7 @@ public class EnderDragon extends Mob implements Enemy {
boolean flag = this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT);
short short0 = 500;
@@ -8199,7 +7883,7 @@ index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a7799601
short0 = 12000;
}
-@@ -1104,6 +1190,7 @@ public class EnderDragon extends Mob implements Enemy {
+@@ -1102,6 +1188,7 @@ public class EnderDragon extends Mob implements Enemy {
@Override
protected boolean canRide(Entity entity) {
@@ -8208,11 +7892,11 @@ index 1df13af62af7d0bbd92c84d424a07da66bb8583f..ff4b188084d43af9e8ed60e6a7799601
}
diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
-index 12440ee2dccc0a697fb403765f2e1b987ccc0283..736845ca1f7c184b89ddb418339ec3ad22c3447f 100644
+index 7ddca52f7fe3f289b4b867e134326b1ead1a2aee..4a98027a12c2535d1df3a9f6390eb85146398403 100644
--- a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
+++ b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
-@@ -85,20 +85,59 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
- return entityliving.getMobType() != MobType.UNDEAD && entityliving.attackable();
+@@ -88,20 +88,59 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
+ return !entityliving.getType().is(EntityTypeTags.WITHER_FRIENDS) && entityliving.attackable();
};
private static final TargetingConditions TARGETING_CONDITIONS = TargetingConditions.forCombat().range(20.0D).selector(WitherBoss.LIVING_ENTITY_SELECTOR);
+ @Nullable private java.util.UUID summoner; // Purpur
@@ -8272,7 +7956,7 @@ index 12440ee2dccc0a697fb403765f2e1b987ccc0283..736845ca1f7c184b89ddb418339ec3ad
@Override
protected PathNavigation createNavigation(Level world) {
FlyingPathNavigation navigationflying = new FlyingPathNavigation(this, world);
-@@ -109,13 +148,113 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
+@@ -112,13 +151,113 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
return navigationflying;
}
@@ -8386,7 +8070,7 @@ index 12440ee2dccc0a697fb403765f2e1b987ccc0283..736845ca1f7c184b89ddb418339ec3ad
this.targetSelector.addGoal(1, new HurtByTargetGoal(this, new Class[0]));
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, LivingEntity.class, 0, false, false, WitherBoss.LIVING_ENTITY_SELECTOR));
}
-@@ -133,6 +272,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
+@@ -136,6 +275,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
public void addAdditionalSaveData(CompoundTag nbt) {
super.addAdditionalSaveData(nbt);
nbt.putInt("Invul", this.getInvulnerableTicks());
@@ -8394,7 +8078,7 @@ index 12440ee2dccc0a697fb403765f2e1b987ccc0283..736845ca1f7c184b89ddb418339ec3ad
}
@Override
-@@ -142,6 +282,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
+@@ -145,6 +285,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
if (this.hasCustomName()) {
this.bossEvent.setName(this.getDisplayName());
}
@@ -8402,7 +8086,7 @@ index 12440ee2dccc0a697fb403765f2e1b987ccc0283..736845ca1f7c184b89ddb418339ec3ad
}
-@@ -257,6 +398,16 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
+@@ -263,6 +404,16 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
@Override
protected void customServerAiStep() {
@@ -8419,7 +8103,7 @@ index 12440ee2dccc0a697fb403765f2e1b987ccc0283..736845ca1f7c184b89ddb418339ec3ad
int i;
if (this.getInvulnerableTicks() > 0) {
-@@ -273,7 +424,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
+@@ -279,7 +430,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
}
// CraftBukkit end
@@ -8428,7 +8112,7 @@ index 12440ee2dccc0a697fb403765f2e1b987ccc0283..736845ca1f7c184b89ddb418339ec3ad
// CraftBukkit start - Use relative location for far away sounds
// this.level().globalLevelEvent(1023, new BlockPosition(this), 0);
int viewDistance = ((ServerLevel) this.level()).getCraftServer().getViewDistance() * 16;
-@@ -298,7 +449,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
+@@ -304,7 +455,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
this.setInvulnerableTicks(i);
if (this.tickCount % 10 == 0) {
@@ -8437,15 +8121,15 @@ index 12440ee2dccc0a697fb403765f2e1b987ccc0283..736845ca1f7c184b89ddb418339ec3ad
}
} else {
-@@ -358,7 +509,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
+@@ -364,7 +515,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
if (this.destroyBlocksTick > 0) {
--this.destroyBlocksTick;
- if (this.destroyBlocksTick == 0 && this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ if (this.destroyBlocksTick == 0 && (this.level().purpurConfig.witherBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // Purpur
- i = Mth.floor(this.getY());
- j = Mth.floor(this.getX());
- int i1 = Mth.floor(this.getZ());
+ boolean flag = false;
+
+ j = Mth.floor(this.getBbWidth() / 2.0F + 1.0F);
@@ -391,8 +542,10 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
}
}
@@ -8459,7 +8143,7 @@ index 12440ee2dccc0a697fb403765f2e1b987ccc0283..736845ca1f7c184b89ddb418339ec3ad
}
this.bossEvent.setProgress(this.getHealth() / this.getMaxHealth());
-@@ -578,11 +731,11 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
+@@ -580,11 +733,11 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
}
public int getAlternativeTarget(int headIndex) {
@@ -8473,7 +8157,7 @@ index 12440ee2dccc0a697fb403765f2e1b987ccc0283..736845ca1f7c184b89ddb418339ec3ad
}
@Override
-@@ -597,6 +750,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
+@@ -594,6 +747,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
@Override
protected boolean canRide(Entity entity) {
@@ -8482,10 +8166,10 @@ index 12440ee2dccc0a697fb403765f2e1b987ccc0283..736845ca1f7c184b89ddb418339ec3ad
}
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
-index eadcebd7845ee716e33c0ac0544502da1a6c5941..8e71d4d3874ff154eae423a8fb8f15ae08143f4d 100644
+index c2bd2e303f956d390319f6bbbe9a6492ebec5154..6697cd8a632becd72ee132007a61d1221e817abf 100644
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
-@@ -100,10 +100,12 @@ public class ArmorStand extends LivingEntity {
+@@ -103,10 +103,12 @@ public class ArmorStand extends LivingEntity {
private boolean noTickPoseDirty = false;
private boolean noTickEquipmentDirty = false;
// Paper end - Allow ArmorStands not to tick
@@ -8498,32 +8182,31 @@ index eadcebd7845ee716e33c0ac0544502da1a6c5941..8e71d4d3874ff154eae423a8fb8f15ae
this.handItems = NonNullList.withSize(2, ItemStack.EMPTY);
this.armorItems = NonNullList.withSize(4, ItemStack.EMPTY);
this.headPose = ArmorStand.DEFAULT_HEAD_POSE;
-@@ -113,6 +115,7 @@ public class ArmorStand extends LivingEntity {
+@@ -115,6 +117,7 @@ public class ArmorStand extends LivingEntity {
+ this.rightArmPose = ArmorStand.DEFAULT_RIGHT_ARM_POSE;
this.leftLegPose = ArmorStand.DEFAULT_LEFT_LEG_POSE;
this.rightLegPose = ArmorStand.DEFAULT_RIGHT_LEG_POSE;
- this.setMaxUpStep(0.0F);
+ this.setShowArms(world != null && world.purpurConfig.armorstandPlaceWithArms); // Purpur
}
public ArmorStand(Level world, double x, double y, double z) {
-@@ -607,7 +610,7 @@ public class ArmorStand extends LivingEntity {
+@@ -613,6 +616,7 @@ public class ArmorStand extends LivingEntity {
private org.bukkit.event.entity.EntityDeathEvent brokenByPlayer(DamageSource damageSource) { // Paper
ItemStack itemstack = new ItemStack(Items.ARMOR_STAND);
-- if (this.hasCustomName()) {
-+ if (this.level().purpurConfig.persistentDroppableEntityDisplayNames && this.hasCustomName()) { // Purpur
- itemstack.setHoverName(this.getCustomName());
- }
-
-@@ -678,6 +681,7 @@ public class ArmorStand extends LivingEntity {
++ if (this.level().purpurConfig.persistentDroppableEntityDisplayNames)
+ itemstack.set(DataComponents.CUSTOM_NAME, this.getCustomName());
+ this.drops.add(new DefaultDrop(itemstack, stack -> Block.popResource(this.level(), this.blockPosition(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior
+ return this.brokenByAnything(damageSource); // Paper
+@@ -676,6 +680,7 @@ public class ArmorStand extends LivingEntity {
@Override
public void tick() {
-+ maxUpStep = level().purpurConfig.armorstandStepHeight; // Purpur
++ maxUpStep = level().purpurConfig.armorstandStepHeight;
// Paper start - Allow ArmorStands not to tick
if (!this.canTick) {
if (this.noTickPoseDirty) {
-@@ -1005,4 +1009,18 @@ public class ArmorStand extends LivingEntity {
+@@ -1003,4 +1008,18 @@ public class ArmorStand extends LivingEntity {
}
}
// Paper end
@@ -8543,18 +8226,18 @@ index eadcebd7845ee716e33c0ac0544502da1a6c5941..8e71d4d3874ff154eae423a8fb8f15ae
+ // Purpur end
}
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java
-index c34701f95580e4cf45fe086115563127432a28c5..2363d9eaad655389c7b7d67d545ef8025f550431 100644
+index da0d1c9a1c4ae081bff9ca4230c9a1503885c354..9af8fcf6abb9b768829592bc1b091ebe4599ed2e 100644
--- a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java
+++ b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java
-@@ -268,7 +268,13 @@ public class ItemFrame extends HangingEntity {
+@@ -262,7 +262,13 @@ public class ItemFrame extends HangingEntity {
}
if (alwaysDrop) {
- this.spawnAtLocation(this.getFrameItemStack());
+ // Purpur start
+ final ItemStack itemFrame = this.getFrameItemStack();
-+ if (this.level().purpurConfig.persistentDroppableEntityDisplayNames && this.hasCustomName()) {
-+ itemFrame.setHoverName(this.getCustomName());
++ if (!this.level().purpurConfig.persistentDroppableEntityDisplayNames) {
++ itemFrame.set(DataComponents.CUSTOM_NAME, null);
+ }
+ this.spawnAtLocation(itemFrame);
+ // Purpur end
@@ -8562,27 +8245,18 @@ index c34701f95580e4cf45fe086115563127432a28c5..2363d9eaad655389c7b7d67d545ef802
if (!itemstack.isEmpty()) {
diff --git a/src/main/java/net/minecraft/world/entity/decoration/Painting.java b/src/main/java/net/minecraft/world/entity/decoration/Painting.java
-index fee2269b241cbfb10bbbb76b404aa5ef3997dfe0..af07901daaf6a0e5cd7e4b1e07fb491566807932 100644
+index 40e7112669abb58a0ab6df1846afec3979e95e55..183464f202d4c2774840edfde1dfcab44d05d0d3 100644
--- a/src/main/java/net/minecraft/world/entity/decoration/Painting.java
+++ b/src/main/java/net/minecraft/world/entity/decoration/Painting.java
-@@ -120,7 +120,7 @@ public class Painting extends HangingEntity implements VariantHolder holder = loadVariant(nbt).orElseGet(Painting::getDefaultVariant);
-+ Holder holder = loadVariant(nbt).orElseGet(() -> (Holder.Reference) getDefaultVariant()); // Purpur - decompile error TODO: still needed?
- this.setVariant(holder);
- this.direction = Direction.from2DDataValue(nbt.getByte("facing"));
- super.readAdditionalSaveData(nbt);
-@@ -155,7 +155,13 @@ public class Painting extends HangingEntity implements VariantHolder type, Level world) {
super(type, world);
-@@ -393,7 +399,16 @@ public class ItemEntity extends Entity implements TraceableEntity {
+@@ -399,7 +405,16 @@ public class ItemEntity extends Entity implements TraceableEntity {
@Override
public boolean hurt(DamageSource source, float amount) {
@@ -8624,7 +8298,7 @@ index 293bc6e40fec09a8ec5cac901d52cc3f7e9b9ea3..6a94e28cda9319b3a965f07d758083b5
return false;
} else if (!this.getItem().isEmpty() && this.getItem().is(Items.NETHER_STAR) && source.is(DamageTypeTags.IS_EXPLOSION)) {
return false;
-@@ -596,6 +611,12 @@ public class ItemEntity extends Entity implements TraceableEntity {
+@@ -607,6 +622,12 @@ public class ItemEntity extends Entity implements TraceableEntity {
public void setItem(ItemStack stack) {
this.getEntityData().set(ItemEntity.DATA_ITEM, stack);
this.despawnRate = this.level().paperConfig().entities.spawning.altItemDespawnRate.enabled ? this.level().paperConfig().entities.spawning.altItemDespawnRate.items.getOrDefault(stack.getItem(), this.level().spigotConfig.itemDespawnRate) : this.level().spigotConfig.itemDespawnRate; // Paper - Alternative item-despawn-rate
@@ -8638,10 +8312,10 @@ index 293bc6e40fec09a8ec5cac901d52cc3f7e9b9ea3..6a94e28cda9319b3a965f07d758083b5
@Override
diff --git a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
-index e712bd07ea2946167782473a536e0c72fab4bccd..6d934405cd18d63943171448743cafd5c52026e2 100644
+index f1f352ec0e51f5db59254841a06c176c5a876fc9..dff0e7b08b973a1b29f916e63d3e4778d6c56cdc 100644
--- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
+++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
-@@ -200,4 +200,29 @@ public class PrimedTnt extends Entity implements TraceableEntity {
+@@ -193,4 +193,29 @@ public class PrimedTnt extends Entity implements TraceableEntity {
return !level().paperConfig().fixes.preventTntFromMovingInWater && super.isPushedByFluid();
}
// Paper end - Option to prevent TNT from moving in water
@@ -8658,7 +8332,7 @@ index e712bd07ea2946167782473a536e0c72fab4bccd..6d934405cd18d63943171448743cafd5
+ new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.TNT));
+ tntItem.setPickUpDelay(10);
+
-+ inHand.hurtAndBreak(1, player, entity -> entity.broadcastBreakEvent(hand));
++ inHand.hurtAndBreak(1, player, LivingEntity.getSlotForHand(hand));
+ level().addFreshEntity(tntItem, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.CUSTOM);
+
+ this.playSound(net.minecraft.sounds.SoundEvents.SHEEP_SHEAR);
@@ -8672,10 +8346,10 @@ index e712bd07ea2946167782473a536e0c72fab4bccd..6d934405cd18d63943171448743cafd5
+ // Purpur end - Shears can defuse TNT
}
diff --git a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
-index 586e3e92ccc275446df6dbbff9bf010a37a9aa8f..3a4cd10a3614cd5e29c49ecde490d5e564d9e568 100644
+index 0c5fe46d2da113beff3e220843593d616e37d4ca..7efe410a10d76e0e4c90a303f1ebecf54a8ff96b 100644
--- a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
+++ b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
-@@ -66,16 +66,19 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
+@@ -65,16 +65,19 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
protected AbstractSkeleton(EntityType extends AbstractSkeleton> type, Level world) {
super(type, world);
this.reassessWeaponGoal();
@@ -8695,8 +8369,8 @@ index 586e3e92ccc275446df6dbbff9bf010a37a9aa8f..3a4cd10a3614cd5e29c49ecde490d5e5
this.targetSelector.addGoal(1, new HurtByTargetGoal(this, new Class[0]));
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true));
this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, IronGolem.class, true));
-@@ -99,35 +102,14 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
- }
+@@ -93,35 +96,14 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
+ abstract SoundEvent getStepSound();
// Paper start - shouldBurnInDay API
- private boolean shouldBurnInDay = true;
@@ -8725,7 +8399,7 @@ index 586e3e92ccc275446df6dbbff9bf010a37a9aa8f..3a4cd10a3614cd5e29c49ecde490d5e5
- }
-
- if (flag) {
-- this.setSecondsOnFire(8);
+- this.igniteForSeconds(8);
- }
- }
-
@@ -8761,19 +8435,19 @@ index 586e3e92ccc275446df6dbbff9bf010a37a9aa8f..3a4cd10a3614cd5e29c49ecde490d5e5
// Paper end - shouldBurnInDay API
diff --git a/src/main/java/net/minecraft/world/entity/monster/Blaze.java b/src/main/java/net/minecraft/world/entity/monster/Blaze.java
-index 58c2b8b8bfd5a40259aa6252243884d14c183ef2..5f876ed6523f808f37b9915e3ddbaed750c3b916 100644
+index aee2fa184bc5723dfd3d54f460a173982d874c8b..27db17e19dd95e99f7bd67747eba3c3072b48ed5 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Blaze.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Blaze.java
@@ -32,26 +32,73 @@ public class Blaze extends Monster {
public Blaze(EntityType extends Blaze> type, Level world) {
super(type, world);
-- this.setPathfindingMalus(BlockPathTypes.WATER, -1.0F);
+- this.setPathfindingMalus(PathType.WATER, -1.0F);
+ this.moveControl = new org.purpurmc.purpur.controller.FlyingWithSpacebarMoveControllerWASD(this, 0.3F); // Purpur
-+ if (isSensitiveToWater()) this.setPathfindingMalus(BlockPathTypes.WATER, -1.0F); // Purpur
- this.setPathfindingMalus(BlockPathTypes.LAVA, 8.0F);
- this.setPathfindingMalus(BlockPathTypes.DANGER_FIRE, 0.0F);
- this.setPathfindingMalus(BlockPathTypes.DAMAGE_FIRE, 0.0F);
++ if (isSensitiveToWater()) this.setPathfindingMalus(PathType.WATER, -1.0F); // Purpur
+ this.setPathfindingMalus(PathType.LAVA, 8.0F);
+ this.setPathfindingMalus(PathType.DANGER_FIRE, 0.0F);
+ this.setPathfindingMalus(PathType.DAMAGE_FIRE, 0.0F);
this.xpReward = 10;
}
@@ -8836,11 +8510,11 @@ index 58c2b8b8bfd5a40259aa6252243884d14c183ef2..5f876ed6523f808f37b9915e3ddbaed7
public static AttributeSupplier.Builder createAttributes() {
- return Monster.createMonsterAttributes().add(Attributes.ATTACK_DAMAGE, 6.0).add(Attributes.MOVEMENT_SPEED, 0.23F).add(Attributes.FOLLOW_RANGE, 48.0);
-+ return Monster.createMonsterAttributes().add(Attributes.ATTACK_DAMAGE, 6.0).add(Attributes.MOVEMENT_SPEED, 0.23F).add(Attributes.FOLLOW_RANGE, 48.0).add(Attributes.FLYING_SPEED, 0.6); // Purpur
++ return Monster.createMonsterAttributes().add(Attributes.ATTACK_DAMAGE, 6.0).add(Attributes.MOVEMENT_SPEED, 0.23F).add(Attributes.FOLLOW_RANGE, 48.0).add(Attributes.FLYING_SPEED, 0.6D); // Purpur
}
@Override
-@@ -111,11 +158,19 @@ public class Blaze extends Monster {
+@@ -111,11 +158,18 @@ public class Blaze extends Monster {
@Override
public boolean isSensitiveToWater() {
@@ -8857,15 +8531,27 @@ index 58c2b8b8bfd5a40259aa6252243884d14c183ef2..5f876ed6523f808f37b9915e3ddbaed7
+ return;
+ }
+ // Purpur end
-+
this.nextHeightOffsetChangeTick--;
if (this.nextHeightOffsetChangeTick <= 0) {
this.nextHeightOffsetChangeTick = 100;
+diff --git a/src/main/java/net/minecraft/world/entity/monster/Bogged.java b/src/main/java/net/minecraft/world/entity/monster/Bogged.java
+index 754eb747179d9318bc5a3883e5622cc400c4e06c..4e929539cb093d58f3311d5f6a62bd1aeb71cfb0 100644
+--- a/src/main/java/net/minecraft/world/entity/monster/Bogged.java
++++ b/src/main/java/net/minecraft/world/entity/monster/Bogged.java
+@@ -155,7 +155,7 @@ public class Bogged extends AbstractSkeleton implements Shearable {
+
+ // Paper start - shear drops API
+ @Override
+- public java.util.List generateDefaultDrops() {
++ public java.util.List generateDefaultDrops(int looting) { // Purpur
+ final java.util.List drops = new java.util.ArrayList<>();
+ this.generateShearedMushrooms(drops::add);
+ return drops;
diff --git a/src/main/java/net/minecraft/world/entity/monster/CaveSpider.java b/src/main/java/net/minecraft/world/entity/monster/CaveSpider.java
-index 70d25bb45ad603095a1f5812cc396dfc5f16a1e1..c9bd400473166999479f5eef1edad529d3aafe01 100644
+index 87e4b300ac248f6c13d9b4a8f24fd78b24b565b4..43b5a0e7993ae9daef1c1ea67722347f9851d3a9 100644
--- a/src/main/java/net/minecraft/world/entity/monster/CaveSpider.java
+++ b/src/main/java/net/minecraft/world/entity/monster/CaveSpider.java
-@@ -29,6 +29,38 @@ public class CaveSpider extends Spider {
+@@ -26,6 +26,38 @@ public class CaveSpider extends Spider {
return Spider.createAttributes().add(Attributes.MAX_HEALTH, 12.0D);
}
@@ -8905,13 +8591,13 @@ index 70d25bb45ad603095a1f5812cc396dfc5f16a1e1..c9bd400473166999479f5eef1edad529
public boolean doHurtTarget(Entity target) {
if (super.doHurtTarget(target)) {
diff --git a/src/main/java/net/minecraft/world/entity/monster/Creeper.java b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
-index 9657796d08f4a102d9d5ff7685f2a152d1a87fda..54315fb84e3289f0ad8305c2c2cec980a5b2c627 100644
+index cbcb2bfa8f91099e5c374f590f48885390bdf7a7..1829bedfa8084c4932a0e67c36f48f19993e22b6 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
-@@ -60,21 +60,99 @@ public class Creeper extends Monster implements PowerableMob {
- public int maxSwell = 30;
+@@ -61,21 +61,99 @@ public class Creeper extends Monster implements PowerableMob {
public int explosionRadius = 3;
private int droppedSkulls;
+ private Player entityIgniter; // CraftBukkit
+ // Purpur start
+ private int spacebarCharge = 0;
+ private int prevSpacebarCharge = 0;
@@ -9008,7 +8694,7 @@ index 9657796d08f4a102d9d5ff7685f2a152d1a87fda..54315fb84e3289f0ad8305c2c2cec980
this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Player.class, true));
this.targetSelector.addGoal(2, new HurtByTargetGoal(this, new Class[0]));
}
-@@ -174,6 +252,37 @@ public class Creeper extends Monster implements PowerableMob {
+@@ -175,6 +253,37 @@ public class Creeper extends Monster implements PowerableMob {
}
}
@@ -9017,12 +8703,12 @@ index 9657796d08f4a102d9d5ff7685f2a152d1a87fda..54315fb84e3289f0ad8305c2c2cec980
+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.creeperMaxHealth);
+ }
+
-+ public net.minecraft.world.entity.SpawnGroupData finalizeSpawn(net.minecraft.world.level.ServerLevelAccessor world, net.minecraft.world.DifficultyInstance difficulty, net.minecraft.world.entity.MobSpawnType spawnReason, @Nullable net.minecraft.world.entity.SpawnGroupData entityData, @Nullable CompoundTag entityNbt) {
++ public net.minecraft.world.entity.SpawnGroupData finalizeSpawn(net.minecraft.world.level.ServerLevelAccessor world, net.minecraft.world.DifficultyInstance difficulty, net.minecraft.world.entity.MobSpawnType spawnReason, @Nullable net.minecraft.world.entity.SpawnGroupData entityData) {
+ double chance = world.getLevel().purpurConfig.creeperChargedChance;
+ if (chance > 0D && random.nextDouble() <= chance) {
+ setPowered(true);
+ }
-+ return super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityNbt);
++ return super.finalizeSpawn(world, difficulty, spawnReason, entityData);
+ }
+
+ @Override
@@ -9046,7 +8732,7 @@ index 9657796d08f4a102d9d5ff7685f2a152d1a87fda..54315fb84e3289f0ad8305c2c2cec980
@Override
protected SoundEvent getHurtSound(DamageSource source) {
return SoundEvents.CREEPER_HURT;
-@@ -265,15 +374,17 @@ public class Creeper extends Monster implements PowerableMob {
+@@ -263,15 +372,17 @@ public class Creeper extends Monster implements PowerableMob {
}
public void explodeCreeper() {
@@ -9061,12 +8747,12 @@ index 9657796d08f4a102d9d5ff7685f2a152d1a87fda..54315fb84e3289f0ad8305c2c2cec980
if (!event.isCancelled()) {
// CraftBukkit end
this.dead = true;
-- this.level().explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB); // CraftBukkit
-+ this.level().explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), this.level().getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING) && level().purpurConfig.creeperAllowGriefing ? Level.ExplosionInteraction.MOB : Level.ExplosionInteraction.NONE); // CraftBukkit // Purpur
+- this.level().explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB); // CraftBukkit // Paper - fix DamageSource API
++ this.level().explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), this.level().getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING) && level().purpurConfig.creeperAllowGriefing ? Level.ExplosionInteraction.MOB : Level.ExplosionInteraction.NONE); // CraftBukkit // Paper - fix DamageSource API // Purpur
this.discard(EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause
this.spawnLingeringCloud();
// CraftBukkit start
-@@ -283,7 +394,7 @@ public class Creeper extends Monster implements PowerableMob {
+@@ -281,7 +392,7 @@ public class Creeper extends Monster implements PowerableMob {
}
// CraftBukkit end
}
@@ -9075,7 +8761,7 @@ index 9657796d08f4a102d9d5ff7685f2a152d1a87fda..54315fb84e3289f0ad8305c2c2cec980
}
private void spawnLingeringCloud() {
-@@ -325,6 +436,7 @@ public class Creeper extends Monster implements PowerableMob {
+@@ -323,6 +434,7 @@ public class Creeper extends Monster implements PowerableMob {
com.destroystokyo.paper.event.entity.CreeperIgniteEvent event = new com.destroystokyo.paper.event.entity.CreeperIgniteEvent((org.bukkit.entity.Creeper) getBukkitEntity(), ignited);
if (event.callEvent()) {
this.entityData.set(Creeper.DATA_IS_IGNITED, event.isIgnited());
@@ -9084,7 +8770,7 @@ index 9657796d08f4a102d9d5ff7685f2a152d1a87fda..54315fb84e3289f0ad8305c2c2cec980
}
// Paper end - CreeperIgniteEvent
diff --git a/src/main/java/net/minecraft/world/entity/monster/Drowned.java b/src/main/java/net/minecraft/world/entity/monster/Drowned.java
-index 01897af1e6253b987734a24c052daf2ce1314092..7600e747d91ae888eb801cfafcb09bffb76c8e62 100644
+index cff1b5e0e3fd32d82157d5f13d83d4abdfad7378..15afee3c4f6307557321424560d2340e23cd472b 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Drowned.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Drowned.java
@@ -29,6 +29,7 @@ import net.minecraft.world.entity.ai.goal.MoveToBlockGoal;
@@ -9095,8 +8781,8 @@ index 01897af1e6253b987734a24c052daf2ce1314092..7600e747d91ae888eb801cfafcb09bff
import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal;
import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal;
import net.minecraft.world.entity.ai.navigation.GroundPathNavigation;
-@@ -68,6 +69,58 @@ public class Drowned extends Zombie implements RangedAttackMob {
- this.groundNavigation = new GroundPathNavigation(this, world);
+@@ -71,6 +72,58 @@ public class Drowned extends Zombie implements RangedAttackMob {
+ return Zombie.createAttributes().add(Attributes.STEP_HEIGHT, 1.0D);
}
+ // Purpur start
@@ -9154,7 +8840,7 @@ index 01897af1e6253b987734a24c052daf2ce1314092..7600e747d91ae888eb801cfafcb09bff
@Override
protected void addBehaviourGoals() {
this.goalSelector.addGoal(1, new Drowned.DrownedGoToWaterGoal(this, 1.0D));
-@@ -75,10 +128,23 @@ public class Drowned extends Zombie implements RangedAttackMob {
+@@ -78,10 +131,23 @@ public class Drowned extends Zombie implements RangedAttackMob {
this.goalSelector.addGoal(2, new Drowned.DrownedAttackGoal(this, 1.0D, false));
this.goalSelector.addGoal(5, new Drowned.DrownedGoToBeachGoal(this, 1.0D));
this.goalSelector.addGoal(6, new Drowned.DrownedSwimUpGoal(this, 1.0D, this.level().getSeaLevel()));
@@ -9179,7 +8865,7 @@ index 01897af1e6253b987734a24c052daf2ce1314092..7600e747d91ae888eb801cfafcb09bff
this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, IronGolem.class, true));
this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Axolotl.class, true, false));
this.targetSelector.addGoal(5, new NearestAttackableTargetGoal<>(this, Turtle.class, 10, true, false, Turtle.BABY_ON_LAND_SELECTOR));
-@@ -112,7 +178,7 @@ public class Drowned extends Zombie implements RangedAttackMob {
+@@ -115,7 +181,7 @@ public class Drowned extends Zombie implements RangedAttackMob {
@Override
public boolean supportsBreakDoorGoal() {
@@ -9188,7 +8874,7 @@ index 01897af1e6253b987734a24c052daf2ce1314092..7600e747d91ae888eb801cfafcb09bff
}
@Override
-@@ -259,8 +325,7 @@ public class Drowned extends Zombie implements RangedAttackMob {
+@@ -262,8 +328,7 @@ public class Drowned extends Zombie implements RangedAttackMob {
this.searchingForLand = targetingUnderwater;
}
@@ -9198,7 +8884,7 @@ index 01897af1e6253b987734a24c052daf2ce1314092..7600e747d91ae888eb801cfafcb09bff
private final Drowned drowned;
public DrownedMoveControl(Drowned drowned) {
-@@ -269,7 +334,7 @@ public class Drowned extends Zombie implements RangedAttackMob {
+@@ -272,7 +337,7 @@ public class Drowned extends Zombie implements RangedAttackMob {
}
@Override
@@ -9207,7 +8893,7 @@ index 01897af1e6253b987734a24c052daf2ce1314092..7600e747d91ae888eb801cfafcb09bff
LivingEntity entityliving = this.drowned.getTarget();
if (this.drowned.wantsToSwim() && this.drowned.isInWater()) {
-@@ -292,7 +357,7 @@ public class Drowned extends Zombie implements RangedAttackMob {
+@@ -295,7 +360,7 @@ public class Drowned extends Zombie implements RangedAttackMob {
this.drowned.setYRot(this.rotlerp(this.drowned.getYRot(), f, 90.0F));
this.drowned.yBodyRot = this.drowned.getYRot();
@@ -9216,7 +8902,7 @@ index 01897af1e6253b987734a24c052daf2ce1314092..7600e747d91ae888eb801cfafcb09bff
float f2 = Mth.lerp(0.125F, this.drowned.getSpeed(), f1);
this.drowned.setSpeed(f2);
-@@ -302,7 +367,7 @@ public class Drowned extends Zombie implements RangedAttackMob {
+@@ -305,7 +370,7 @@ public class Drowned extends Zombie implements RangedAttackMob {
this.drowned.setDeltaMovement(this.drowned.getDeltaMovement().add(0.0D, -0.008D, 0.0D));
}
@@ -9226,10 +8912,10 @@ index 01897af1e6253b987734a24c052daf2ce1314092..7600e747d91ae888eb801cfafcb09bff
}
diff --git a/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java b/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java
-index 91ff663b2260d1cdd1388c93068e4cd9d0331aea..cb189457305916f509d624beb303feff35d0c358 100644
+index fd995b1f29c47884e9db2cb92f1dd615d62ae032..7e8603ef5df722f19e85b9c5cdd4ebfdd6481e42 100644
--- a/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java
+++ b/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java
-@@ -36,6 +36,33 @@ public class ElderGuardian extends Guardian {
+@@ -33,6 +33,33 @@ public class ElderGuardian extends Guardian {
}
@@ -9264,15 +8950,15 @@ index 91ff663b2260d1cdd1388c93068e4cd9d0331aea..cb189457305916f509d624beb303feff
return Guardian.createAttributes().add(Attributes.MOVEMENT_SPEED, 0.30000001192092896D).add(Attributes.ATTACK_DAMAGE, 8.0D).add(Attributes.MAX_HEALTH, 80.0D);
}
diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
-index 9898e05682c2d47953c95e355d51c701a3b0cc1b..d945b0d74a4f87e7eea6cc8625c0da47ac53dfe7 100644
+index 15b544bd0794e021ed4a9fde94883bcb5c6a3521..e2518ca9196ae93cd98fcae0781c85d39d7e9622 100644
--- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
+++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
-@@ -95,12 +95,40 @@ public class EnderMan extends Monster implements NeutralMob {
+@@ -90,12 +90,40 @@ public class EnderMan extends Monster implements NeutralMob {
+
public EnderMan(EntityType extends EnderMan> type, Level world) {
super(type, world);
- this.setMaxUpStep(1.0F);
-- this.setPathfindingMalus(BlockPathTypes.WATER, -1.0F);
-+ if (isSensitiveToWater()) this.setPathfindingMalus(BlockPathTypes.WATER, -1.0F); // Purpur
+- this.setPathfindingMalus(PathType.WATER, -1.0F);
++ if (isSensitiveToWater()) this.setPathfindingMalus(PathType.WATER, -1.0F); // Purpur
+ }
+
+ // Purpur start
@@ -9309,7 +8995,7 @@ index 9898e05682c2d47953c95e355d51c701a3b0cc1b..d945b0d74a4f87e7eea6cc8625c0da47
this.goalSelector.addGoal(1, new EnderMan.EndermanFreezeWhenLookedAt(this));
this.goalSelector.addGoal(2, new MeleeAttackGoal(this, 1.0D, false));
this.goalSelector.addGoal(7, new WaterAvoidingRandomStrollGoal(this, 1.0D, 0.0F));
-@@ -108,9 +136,10 @@ public class EnderMan extends Monster implements NeutralMob {
+@@ -103,9 +131,10 @@ public class EnderMan extends Monster implements NeutralMob {
this.goalSelector.addGoal(8, new RandomLookAroundGoal(this));
this.goalSelector.addGoal(10, new EnderMan.EndermanLeaveBlockGoal(this));
this.goalSelector.addGoal(11, new EnderMan.EndermanTakeBlockGoal(this));
@@ -9321,7 +9007,7 @@ index 9898e05682c2d47953c95e355d51c701a3b0cc1b..d945b0d74a4f87e7eea6cc8625c0da47
this.targetSelector.addGoal(4, new ResetUniversalAngerTargetGoal<>(this, false));
}
-@@ -247,7 +276,7 @@ public class EnderMan extends Monster implements NeutralMob {
+@@ -242,7 +271,7 @@ public class EnderMan extends Monster implements NeutralMob {
// Paper end - EndermanAttackPlayerEvent
ItemStack itemstack = (ItemStack) player.getInventory().armor.get(3);
@@ -9330,7 +9016,7 @@ index 9898e05682c2d47953c95e355d51c701a3b0cc1b..d945b0d74a4f87e7eea6cc8625c0da47
return false;
} else {
Vec3 vec3d = player.getViewVector(1.0F).normalize();
-@@ -289,12 +318,12 @@ public class EnderMan extends Monster implements NeutralMob {
+@@ -274,12 +303,12 @@ public class EnderMan extends Monster implements NeutralMob {
@Override
public boolean isSensitiveToWater() {
@@ -9345,7 +9031,7 @@ index 9898e05682c2d47953c95e355d51c701a3b0cc1b..d945b0d74a4f87e7eea6cc8625c0da47
float f = this.getLightLevelDependentMagicValue();
if (f > 0.5F && this.level().canSeeSky(this.blockPosition()) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.RUNAWAY)) { // Paper - EndermanEscapeEvent
-@@ -415,6 +444,8 @@ public class EnderMan extends Monster implements NeutralMob {
+@@ -400,6 +429,8 @@ public class EnderMan extends Monster implements NeutralMob {
public boolean hurt(DamageSource source, float amount) {
if (this.isInvulnerableTo(source)) {
return false;
@@ -9354,7 +9040,7 @@ index 9898e05682c2d47953c95e355d51c701a3b0cc1b..d945b0d74a4f87e7eea6cc8625c0da47
} else {
boolean flag = source.getDirectEntity() instanceof ThrownPotion;
boolean flag1;
-@@ -429,6 +460,7 @@ public class EnderMan extends Monster implements NeutralMob {
+@@ -414,6 +445,7 @@ public class EnderMan extends Monster implements NeutralMob {
} else {
flag1 = flag && this.hurtWithCleanWater(source, (ThrownPotion) source.getDirectEntity(), amount);
@@ -9362,7 +9048,7 @@ index 9898e05682c2d47953c95e355d51c701a3b0cc1b..d945b0d74a4f87e7eea6cc8625c0da47
if (this.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.INDIRECT)) { // Paper - EndermanEscapeEvent
for (int i = 0; i < 64; ++i) {
if (this.teleport()) {
-@@ -475,7 +507,7 @@ public class EnderMan extends Monster implements NeutralMob {
+@@ -458,7 +490,7 @@ public class EnderMan extends Monster implements NeutralMob {
@Override
public boolean requiresCustomPersistence() {
@@ -9371,7 +9057,7 @@ index 9898e05682c2d47953c95e355d51c701a3b0cc1b..d945b0d74a4f87e7eea6cc8625c0da47
}
private static class EndermanFreezeWhenLookedAt extends Goal {
-@@ -522,7 +554,16 @@ public class EnderMan extends Monster implements NeutralMob {
+@@ -505,7 +537,16 @@ public class EnderMan extends Monster implements NeutralMob {
@Override
public boolean canUse() {
@@ -9389,7 +9075,7 @@ index 9898e05682c2d47953c95e355d51c701a3b0cc1b..d945b0d74a4f87e7eea6cc8625c0da47
}
@Override
-@@ -567,7 +608,16 @@ public class EnderMan extends Monster implements NeutralMob {
+@@ -550,7 +591,16 @@ public class EnderMan extends Monster implements NeutralMob {
@Override
public boolean canUse() {
@@ -9408,10 +9094,10 @@ index 9898e05682c2d47953c95e355d51c701a3b0cc1b..d945b0d74a4f87e7eea6cc8625c0da47
@Override
diff --git a/src/main/java/net/minecraft/world/entity/monster/Endermite.java b/src/main/java/net/minecraft/world/entity/monster/Endermite.java
-index b8ce2a9ad151b20f0f4e9e8e34a57069d8d77128..965362c281315c15fb70a83a6949d7825bebf15b 100644
+index 9c78905762d9a484878fa9cf03a2ca3850e7e613..14d6796a124a85b8cbf5f3b719d89d99e0cf8db5 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Endermite.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Endermite.java
-@@ -37,20 +37,63 @@ public class Endermite extends Monster {
+@@ -32,20 +32,63 @@ public class Endermite extends Monster {
private static final int MAX_LIFE = 2400;
public int life;
@@ -9475,7 +9161,7 @@ index b8ce2a9ad151b20f0f4e9e8e34a57069d8d77128..965362c281315c15fb70a83a6949d782
this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, new Class[0])).setAlertOthers());
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true));
}
-@@ -93,12 +136,14 @@ public class Endermite extends Monster {
+@@ -83,12 +126,14 @@ public class Endermite extends Monster {
public void readAdditionalSaveData(CompoundTag nbt) {
super.readAdditionalSaveData(nbt);
this.life = nbt.getInt("Lifetime");
@@ -9491,10 +9177,10 @@ index b8ce2a9ad151b20f0f4e9e8e34a57069d8d77128..965362c281315c15fb70a83a6949d782
@Override
diff --git a/src/main/java/net/minecraft/world/entity/monster/Evoker.java b/src/main/java/net/minecraft/world/entity/monster/Evoker.java
-index e67cb165a0d706d38e4970fb3d63f59a29808a76..daee6c4c0c2d43b65cdfd691bbbdc72465702dfe 100644
+index 38e866571c35ebc4843a8d4fa39691902a5fcc91..f92f93c780f4c176d6c02c4b98ffe3a4ef3993f6 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Evoker.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Evoker.java
-@@ -51,10 +51,43 @@ public class Evoker extends SpellcasterIllager {
+@@ -52,10 +52,43 @@ public class Evoker extends SpellcasterIllager {
this.xpReward = 10;
}
@@ -9538,7 +9224,7 @@ index e67cb165a0d706d38e4970fb3d63f59a29808a76..daee6c4c0c2d43b65cdfd691bbbdc724
this.goalSelector.addGoal(1, new Evoker.EvokerCastingSpellGoal());
this.goalSelector.addGoal(2, new AvoidEntityGoal<>(this, Player.class, 8.0F, 0.6D, 1.0D));
this.goalSelector.addGoal(4, new Evoker.EvokerSummonSpellGoal());
-@@ -63,6 +96,7 @@ public class Evoker extends SpellcasterIllager {
+@@ -64,6 +97,7 @@ public class Evoker extends SpellcasterIllager {
this.goalSelector.addGoal(8, new RandomStrollGoal(this, 0.6D));
this.goalSelector.addGoal(9, new LookAtPlayerGoal(this, Player.class, 3.0F, 1.0F));
this.goalSelector.addGoal(10, new LookAtPlayerGoal(this, Mob.class, 8.0F));
@@ -9546,7 +9232,7 @@ index e67cb165a0d706d38e4970fb3d63f59a29808a76..daee6c4c0c2d43b65cdfd691bbbdc724
this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, new Class[]{Raider.class})).setAlertOthers());
this.targetSelector.addGoal(2, (new NearestAttackableTargetGoal<>(this, Player.class, true)).setUnseenMemoryTicks(300));
this.targetSelector.addGoal(3, (new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false)).setUnseenMemoryTicks(300));
-@@ -327,7 +361,7 @@ public class Evoker extends SpellcasterIllager {
+@@ -340,7 +374,7 @@ public class Evoker extends SpellcasterIllager {
return false;
} else if (Evoker.this.tickCount < this.nextAttackTickCount) {
return false;
@@ -9556,10 +9242,10 @@ index e67cb165a0d706d38e4970fb3d63f59a29808a76..daee6c4c0c2d43b65cdfd691bbbdc724
} else {
List list = Evoker.this.level().getNearbyEntities(Sheep.class, this.wololoTargeting, Evoker.this, Evoker.this.getBoundingBox().inflate(16.0D, 4.0D, 16.0D));
diff --git a/src/main/java/net/minecraft/world/entity/monster/Ghast.java b/src/main/java/net/minecraft/world/entity/monster/Ghast.java
-index c135bc245f59a1af706f98b9d140dee77016b12f..640f0c378a18cf0a820ad544bb3b172b698c6bfc 100644
+index 373a4f036157017b0d95e8f1849780582235a549..a25c82be45e3db5143f6bf617fedc2fa85bd89ca 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Ghast.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Ghast.java
-@@ -45,11 +45,47 @@ public class Ghast extends FlyingMob implements Enemy {
+@@ -43,11 +43,47 @@ public class Ghast extends FlyingMob implements Enemy {
this.moveControl = new Ghast.GhastMoveControl(this);
}
@@ -9607,7 +9293,7 @@ index c135bc245f59a1af706f98b9d140dee77016b12f..640f0c378a18cf0a820ad544bb3b172b
this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, (entityliving) -> {
return Math.abs(entityliving.getY() - this.getY()) <= 4.0D;
}));
-@@ -97,6 +133,21 @@ public class Ghast extends FlyingMob implements Enemy {
+@@ -95,6 +131,21 @@ public class Ghast extends FlyingMob implements Enemy {
}
}
@@ -9627,9 +9313,9 @@ index c135bc245f59a1af706f98b9d140dee77016b12f..640f0c378a18cf0a820ad544bb3b172b
+ }
+
@Override
- protected void defineSynchedData() {
- super.defineSynchedData();
-@@ -104,7 +155,7 @@ public class Ghast extends FlyingMob implements Enemy {
+ protected void defineSynchedData(SynchedEntityData.Builder builder) {
+ super.defineSynchedData(builder);
+@@ -102,7 +153,7 @@ public class Ghast extends FlyingMob implements Enemy {
}
public static AttributeSupplier.Builder createAttributes() {
@@ -9638,8 +9324,8 @@ index c135bc245f59a1af706f98b9d140dee77016b12f..640f0c378a18cf0a820ad544bb3b172b
}
@Override
-@@ -171,7 +222,7 @@ public class Ghast extends FlyingMob implements Enemy {
- return 2.6F;
+@@ -154,7 +205,7 @@ public class Ghast extends FlyingMob implements Enemy {
+
}
- private static class GhastMoveControl extends MoveControl {
@@ -9647,7 +9333,7 @@ index c135bc245f59a1af706f98b9d140dee77016b12f..640f0c378a18cf0a820ad544bb3b172b
private final Ghast ghast;
private int floatDuration;
-@@ -182,7 +233,7 @@ public class Ghast extends FlyingMob implements Enemy {
+@@ -165,7 +216,7 @@ public class Ghast extends FlyingMob implements Enemy {
}
@Override
@@ -9657,22 +9343,19 @@ index c135bc245f59a1af706f98b9d140dee77016b12f..640f0c378a18cf0a820ad544bb3b172b
if (this.floatDuration-- <= 0) {
this.floatDuration += this.ghast.getRandom().nextInt(5) + 2;
diff --git a/src/main/java/net/minecraft/world/entity/monster/Giant.java b/src/main/java/net/minecraft/world/entity/monster/Giant.java
-index a329395dd8ff2d5428de19018111373806fc8796..20d6fd08cc7b5964f74b7dd99ee117ac30273426 100644
+index 118521ae54254b0a73bb7cba7b2871c9c26f89fc..5c2881d0be519c52cbba74d7b7ca3ea9b4536463 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Giant.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Giant.java
-@@ -1,18 +1,123 @@
+@@ -1,23 +1,128 @@
package net.minecraft.world.entity.monster;
import net.minecraft.core.BlockPos;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.world.Difficulty;
+import net.minecraft.world.DifficultyInstance;
- import net.minecraft.world.entity.Entity;
- import net.minecraft.world.entity.EntityDimensions;
import net.minecraft.world.entity.EntityType;
+import net.minecraft.world.entity.EquipmentSlot;
+import net.minecraft.world.entity.MobSpawnType;
- import net.minecraft.world.entity.Pose;
+import net.minecraft.world.entity.SpawnGroupData;
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
import net.minecraft.world.entity.ai.attributes.Attributes;
@@ -9699,9 +9382,8 @@ index a329395dd8ff2d5428de19018111373806fc8796..20d6fd08cc7b5964f74b7dd99ee117ac
public class Giant extends Monster {
public Giant(EntityType extends Giant> type, Level world) {
super(type, world);
-+ this.safeFallDistance = 10.0F; // Purpur
-+ }
-+
+ }
+
+ // Purpur start
+ @Override
+ public boolean isRidable() {
@@ -9748,7 +9430,6 @@ index a329395dd8ff2d5428de19018111373806fc8796..20d6fd08cc7b5964f74b7dd99ee117ac
+ protected boolean isAlwaysExperienceDropper() {
+ return this.level().purpurConfig.giantAlwaysDropExp;
+ }
-+ // Purpur end
+
+ @Override
+ protected void initAttributes() {
@@ -9757,9 +9438,15 @@ index a329395dd8ff2d5428de19018111373806fc8796..20d6fd08cc7b5964f74b7dd99ee117ac
+ this.getAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(this.level().purpurConfig.giantAttackDamage);
+ }
+
++ // Purpur end
++
+ public static AttributeSupplier.Builder createAttributes() {
+ return Monster.createMonsterAttributes().add(Attributes.MAX_HEALTH, 100.0).add(Attributes.MOVEMENT_SPEED, 0.5).add(Attributes.ATTACK_DAMAGE, 50.0);
+ }
+
+ @Override
-+ public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType spawnReason, @Nullable SpawnGroupData entityData, @Nullable CompoundTag entityNbt) {
-+ SpawnGroupData groupData = super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityNbt);
++ public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType spawnReason, @Nullable SpawnGroupData entityData) {
++ SpawnGroupData groupData = super.finalizeSpawn(world, difficulty, spawnReason, entityData);
+ if (groupData == null) {
+ populateDefaultEquipmentSlots(this.random, difficulty);
+ populateDefaultEquipmentEnchantments(this.random, difficulty);
@@ -9781,11 +9468,8 @@ index a329395dd8ff2d5428de19018111373806fc8796..20d6fd08cc7b5964f74b7dd99ee117ac
+ // 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 level().purpurConfig.giantJumpHeight;
- }
-
- @Override
-@@ -31,6 +136,6 @@ public class Giant extends Monster {
-
++ }
++
@Override
public float getWalkTargetValue(BlockPos pos, LevelReader world) {
- return world.getPathfindingCostFromLightLevels(pos);
@@ -9793,12 +9477,12 @@ index a329395dd8ff2d5428de19018111373806fc8796..20d6fd08cc7b5964f74b7dd99ee117ac
}
}
diff --git a/src/main/java/net/minecraft/world/entity/monster/Guardian.java b/src/main/java/net/minecraft/world/entity/monster/Guardian.java
-index fd41ef66e2e12ec3a888bb376ef4363343914fcd..01c558673f0bb5034bca9df0e473375e7b7e724e 100644
+index 6c2e2fd5826a5f8070502e20d1d140c3d70bd0d3..f9496126f75b4c1b89ec33617e577d83042e0290 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Guardian.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Guardian.java
-@@ -70,15 +70,51 @@ public class Guardian extends Monster {
+@@ -66,15 +66,51 @@ public class Guardian extends Monster {
this.xpReward = 10;
- this.setPathfindingMalus(BlockPathTypes.WATER, 0.0F);
+ this.setPathfindingMalus(PathType.WATER, 0.0F);
this.moveControl = new Guardian.GuardianMoveControl(this);
+ // Purpur start
+ this.lookControl = new org.purpurmc.purpur.controller.LookControllerWASD(this) {
@@ -9848,7 +9532,7 @@ index fd41ef66e2e12ec3a888bb376ef4363343914fcd..01c558673f0bb5034bca9df0e473375e
this.goalSelector.addGoal(4, this.guardianAttackGoal = new Guardian.GuardianAttackGoal(this)); // CraftBukkit - assign field
this.goalSelector.addGoal(5, pathfindergoalmovetowardsrestriction);
this.goalSelector.addGoal(7, this.randomStrollGoal);
-@@ -87,6 +123,7 @@ public class Guardian extends Monster {
+@@ -83,6 +119,7 @@ public class Guardian extends Monster {
this.goalSelector.addGoal(9, new RandomLookAroundGoal(this));
this.randomStrollGoal.setFlags(EnumSet.of(Goal.Flag.MOVE, Goal.Flag.LOOK));
pathfindergoalmovetowardsrestriction.setFlags(EnumSet.of(Goal.Flag.MOVE, Goal.Flag.LOOK));
@@ -9856,7 +9540,7 @@ index fd41ef66e2e12ec3a888bb376ef4363343914fcd..01c558673f0bb5034bca9df0e473375e
this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, LivingEntity.class, 10, true, false, new Guardian.GuardianAttackSelector(this)));
}
-@@ -347,7 +384,7 @@ public class Guardian extends Monster {
+@@ -333,7 +370,7 @@ public class Guardian extends Monster {
@Override
public void travel(Vec3 movementInput) {
if (this.isControlledByLocalInstance() && this.isInWater()) {
@@ -9865,8 +9549,8 @@ index fd41ef66e2e12ec3a888bb376ef4363343914fcd..01c558673f0bb5034bca9df0e473375e
this.move(MoverType.SELF, this.getDeltaMovement());
this.setDeltaMovement(this.getDeltaMovement().scale(0.9D));
if (!this.isMoving() && this.getTarget() == null) {
-@@ -364,7 +401,7 @@ public class Guardian extends Monster {
- return new Vector3f(0.0F, dimensions.height + 0.125F * scaleFactor, 0.0F);
+@@ -345,7 +382,7 @@ public class Guardian extends Monster {
+
}
- private static class GuardianMoveControl extends MoveControl {
@@ -9874,7 +9558,7 @@ index fd41ef66e2e12ec3a888bb376ef4363343914fcd..01c558673f0bb5034bca9df0e473375e
private final Guardian guardian;
-@@ -373,8 +410,17 @@ public class Guardian extends Monster {
+@@ -354,8 +391,17 @@ public class Guardian extends Monster {
this.guardian = guardian;
}
@@ -9893,7 +9577,7 @@ index fd41ef66e2e12ec3a888bb376ef4363343914fcd..01c558673f0bb5034bca9df0e473375e
if (this.operation == MoveControl.Operation.MOVE_TO && !this.guardian.getNavigation().isDone()) {
Vec3 vec3d = new Vec3(this.wantedX - this.guardian.getX(), this.wantedY - this.guardian.getY(), this.wantedZ - this.guardian.getZ());
double d0 = vec3d.length();
-@@ -385,7 +431,7 @@ public class Guardian extends Monster {
+@@ -366,7 +412,7 @@ public class Guardian extends Monster {
this.guardian.setYRot(this.rotlerp(this.guardian.getYRot(), f, 90.0F));
this.guardian.yBodyRot = this.guardian.getYRot();
@@ -9903,10 +9587,10 @@ index fd41ef66e2e12ec3a888bb376ef4363343914fcd..01c558673f0bb5034bca9df0e473375e
this.guardian.setSpeed(f2);
diff --git a/src/main/java/net/minecraft/world/entity/monster/Husk.java b/src/main/java/net/minecraft/world/entity/monster/Husk.java
-index 72b8290bebe8ed9bc3c464b30cfe5d2d664310f5..06a5106a94a44c1d21537410d801cdd945503d69 100644
+index c34c8483a026f61fe20935697d321d7ef5d8dfbc..95d3edc6c88d6ed0556c21c2623cdd5cfda35911 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Husk.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Husk.java
-@@ -22,6 +22,59 @@ public class Husk extends Zombie {
+@@ -20,6 +20,59 @@ public class Husk extends Zombie {
public Husk(EntityType extends Husk> type, Level world) {
super(type, world);
@@ -9966,7 +9650,7 @@ index 72b8290bebe8ed9bc3c464b30cfe5d2d664310f5..06a5106a94a44c1d21537410d801cdd9
}
public static boolean checkHuskSpawnRules(EntityType type, ServerLevelAccessor world, MobSpawnType spawnReason, BlockPos pos, RandomSource random) {
-@@ -30,7 +83,7 @@ public class Husk extends Zombie {
+@@ -28,7 +81,7 @@ public class Husk extends Zombie {
@Override
public boolean isSunSensitive() {
@@ -9976,10 +9660,10 @@ index 72b8290bebe8ed9bc3c464b30cfe5d2d664310f5..06a5106a94a44c1d21537410d801cdd9
@Override
diff --git a/src/main/java/net/minecraft/world/entity/monster/Illusioner.java b/src/main/java/net/minecraft/world/entity/monster/Illusioner.java
-index fb84b35e34063075e69e00e430bc00e7c3b9d62c..a8b3431c67442c5440b063426a1adc423f5c0658 100644
+index a7964208c952cb4e34916ae6523850fc3921b07e..ae036a16e3677dfba451f4eb4505036d45e50cf3 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Illusioner.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Illusioner.java
-@@ -59,10 +59,45 @@ public class Illusioner extends SpellcasterIllager implements RangedAttackMob {
+@@ -56,10 +56,45 @@ public class Illusioner extends SpellcasterIllager implements RangedAttackMob {
}
@@ -10025,7 +9709,7 @@ index fb84b35e34063075e69e00e430bc00e7c3b9d62c..a8b3431c67442c5440b063426a1adc42
this.goalSelector.addGoal(1, new SpellcasterIllager.SpellcasterCastingSpellGoal());
this.goalSelector.addGoal(4, new Illusioner.IllusionerMirrorSpellGoal());
this.goalSelector.addGoal(5, new Illusioner.IllusionerBlindnessSpellGoal());
-@@ -70,6 +105,7 @@ public class Illusioner extends SpellcasterIllager implements RangedAttackMob {
+@@ -67,6 +102,7 @@ public class Illusioner extends SpellcasterIllager implements RangedAttackMob {
this.goalSelector.addGoal(8, new RandomStrollGoal(this, 0.6D));
this.goalSelector.addGoal(9, new LookAtPlayerGoal(this, Player.class, 3.0F, 1.0F));
this.goalSelector.addGoal(10, new LookAtPlayerGoal(this, Mob.class, 8.0F));
@@ -10034,10 +9718,10 @@ index fb84b35e34063075e69e00e430bc00e7c3b9d62c..a8b3431c67442c5440b063426a1adc42
this.targetSelector.addGoal(2, (new NearestAttackableTargetGoal<>(this, Player.class, true)).setUnseenMemoryTicks(300));
this.targetSelector.addGoal(3, (new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false)).setUnseenMemoryTicks(300));
diff --git a/src/main/java/net/minecraft/world/entity/monster/MagmaCube.java b/src/main/java/net/minecraft/world/entity/monster/MagmaCube.java
-index c4b4ff79bfdf9e34bf73a7760369e24b28dbbd70..1bfd5ef9ce8a07375ff215d092368c3f5104ab13 100644
+index 7be2393dc3cb79556d9767b09f43be0f81308a12..e7c79e8c72226285eb5a4763dcf8ddd27078539c 100644
--- a/src/main/java/net/minecraft/world/entity/monster/MagmaCube.java
+++ b/src/main/java/net/minecraft/world/entity/monster/MagmaCube.java
-@@ -25,6 +25,58 @@ public class MagmaCube extends Slime {
+@@ -24,6 +24,58 @@ public class MagmaCube extends Slime {
super(type, world);
}
@@ -10096,7 +9780,7 @@ index c4b4ff79bfdf9e34bf73a7760369e24b28dbbd70..1bfd5ef9ce8a07375ff215d092368c3f
public static AttributeSupplier.Builder createAttributes() {
return Monster.createMonsterAttributes().add(Attributes.MOVEMENT_SPEED, 0.2F);
}
-@@ -70,11 +122,12 @@ public class MagmaCube extends Slime {
+@@ -64,11 +116,12 @@ public class MagmaCube extends Slime {
}
@Override
@@ -10130,10 +9814,10 @@ index 759839e912c54598b257ad738481364940f88a18..e60e6b3e5ae5a468cfe649ed2222412f
return false;
} else {
diff --git a/src/main/java/net/minecraft/world/entity/monster/Phantom.java b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
-index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b2498d2bb998 100644
+index 68f8945292753535a3b73acb9f48c1594f0789a4..26077bd6eeedbdae84613188cb0f336abb3563d2 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
-@@ -50,6 +50,8 @@ public class Phantom extends FlyingMob implements Enemy {
+@@ -48,6 +48,8 @@ public class Phantom extends FlyingMob implements Enemy {
Vec3 moveTargetPoint;
public BlockPos anchorPoint;
Phantom.AttackPhase attackPhase;
@@ -10142,10 +9826,10 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249
public Phantom(EntityType extends Phantom> type, Level world) {
super(type, world);
-@@ -59,6 +61,92 @@ public class Phantom extends FlyingMob implements Enemy {
+@@ -57,6 +59,92 @@ public class Phantom extends FlyingMob implements Enemy {
this.xpReward = 5;
this.moveControl = new Phantom.PhantomMoveControl(this);
- this.lookControl = new Phantom.PhantomLookControl(this);
+ this.lookControl = new Phantom.PhantomLookControl(this, this);
+ this.setShouldBurnInDay(true); // Purpur
+ }
+
@@ -10235,7 +9919,7 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249
}
@Override
-@@ -73,9 +161,17 @@ public class Phantom extends FlyingMob implements Enemy {
+@@ -71,9 +159,17 @@ public class Phantom extends FlyingMob implements Enemy {
@Override
protected void registerGoals() {
@@ -10256,7 +9940,7 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249
this.targetSelector.addGoal(1, new Phantom.PhantomAttackPlayerTargetGoal());
}
-@@ -91,7 +187,10 @@ public class Phantom extends FlyingMob implements Enemy {
+@@ -89,7 +185,10 @@ public class Phantom extends FlyingMob implements Enemy {
private void updatePhantomSizeInfo() {
this.refreshDimensions();
@@ -10268,7 +9952,7 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249
}
public int getPhantomSize() {
-@@ -121,6 +220,21 @@ public class Phantom extends FlyingMob implements Enemy {
+@@ -114,6 +213,21 @@ public class Phantom extends FlyingMob implements Enemy {
return true;
}
@@ -10290,8 +9974,8 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249
@Override
public void tick() {
super.tick();
-@@ -141,14 +255,12 @@ public class Phantom extends FlyingMob implements Enemy {
- this.level().addParticle(ParticleTypes.MYCELIUM, this.getX() - (double) f2, this.getY() + (double) f4, this.getZ() - (double) f3, 0.0D, 0.0D, 0.0D);
+@@ -134,14 +248,12 @@ public class Phantom extends FlyingMob implements Enemy {
+ this.level().addParticle(ParticleTypes.MYCELIUM, this.getX() - (double) f3, this.getY() + (double) f5, this.getZ() - (double) f4, 0.0D, 0.0D, 0.0D);
}
+ if (level().purpurConfig.phantomFlamesOnSwoop && attackPhase == AttackPhase.SWOOP) shoot(); // Purpur
@@ -10299,17 +9983,17 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249
@Override
public void aiStep() {
-- if (this.isAlive() && shouldBurnInDay && this.isSunBurnTick()) { // Paper - shouldBurnInDay API
-- this.setSecondsOnFire(8);
+- if (this.isAlive() && this.shouldBurnInDay && this.isSunBurnTick()) { // Paper - shouldBurnInDay API
+- this.igniteForSeconds(8);
- }
-
+ // Purpur - moved down to shouldBurnInDay()
super.aiStep();
}
-@@ -160,7 +272,11 @@ public class Phantom extends FlyingMob implements Enemy {
+@@ -153,7 +265,11 @@ public class Phantom extends FlyingMob implements Enemy {
@Override
- public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType spawnReason, @Nullable SpawnGroupData entityData, @Nullable CompoundTag entityNbt) {
+ public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType spawnReason, @Nullable SpawnGroupData entityData) {
this.anchorPoint = this.blockPosition().above(5);
- this.setPhantomSize(0);
+ // Purpur start
@@ -10317,10 +10001,10 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249
+ int max = world.getLevel().purpurConfig.phantomMaxSize;
+ this.setPhantomSize(min == max ? min : world.getRandom().nextInt(max + 1 - min) + min);
+ // Purpur end
- return super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityNbt);
+ return super.finalizeSpawn(world, difficulty, spawnReason, entityData);
}
-@@ -176,7 +292,7 @@ public class Phantom extends FlyingMob implements Enemy {
+@@ -169,7 +285,7 @@ public class Phantom extends FlyingMob implements Enemy {
if (nbt.hasUUID("Paper.SpawningEntity")) {
this.spawningEntity = nbt.getUUID("Paper.SpawningEntity");
}
@@ -10329,7 +10013,7 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249
this.shouldBurnInDay = nbt.getBoolean("Paper.ShouldBurnInDay");
}
// Paper end
-@@ -193,7 +309,7 @@ public class Phantom extends FlyingMob implements Enemy {
+@@ -186,7 +302,7 @@ public class Phantom extends FlyingMob implements Enemy {
if (this.spawningEntity != null) {
nbt.putUUID("Paper.SpawningEntity", this.spawningEntity);
}
@@ -10338,12 +10022,13 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249
// Paper end
}
-@@ -262,8 +378,14 @@ public class Phantom extends FlyingMob implements Enemy {
- return spawningEntity;
+@@ -242,8 +358,15 @@ public class Phantom extends FlyingMob implements Enemy {
+ return this.spawningEntity;
}
public void setSpawningEntity(java.util.UUID entity) { this.spawningEntity = entity; }
- private boolean shouldBurnInDay = true;
- public boolean shouldBurnInDay() { return shouldBurnInDay; }
++
+ // private boolean shouldBurnInDay = true; // Purpur - moved to LivingEntity - keep methods for ABI compatibility
+ // Purpur start
+ public boolean shouldBurnInDay() {
@@ -10354,8 +10039,8 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249
+ // Purpur End
public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; }
// Paper end
- private static enum AttackPhase {
-@@ -273,7 +395,125 @@ public class Phantom extends FlyingMob implements Enemy {
+
+@@ -254,7 +377,125 @@ public class Phantom extends FlyingMob implements Enemy {
private AttackPhase() {}
}
@@ -10482,7 +10167,7 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249
private float speed = 0.1F;
-@@ -281,8 +521,19 @@ public class Phantom extends FlyingMob implements Enemy {
+@@ -262,8 +503,19 @@ public class Phantom extends FlyingMob implements Enemy {
super(entity);
}
@@ -10503,15 +10188,15 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249
if (Phantom.this.horizontalCollision) {
Phantom.this.setYRot(Phantom.this.getYRot() + 180.0F);
this.speed = 0.1F;
-@@ -328,14 +579,20 @@ public class Phantom extends FlyingMob implements Enemy {
+@@ -309,14 +561,20 @@ public class Phantom extends FlyingMob implements Enemy {
}
}
- private class PhantomLookControl extends LookControl {
+ private class PhantomLookControl extends org.purpurmc.purpur.controller.LookControllerWASD { // Purpur
- public PhantomLookControl(Mob entity) {
- super(entity);
+ public PhantomLookControl(final Phantom entity, final Mob phantom) {
+ super(phantom);
}
+ // Purpur start
@@ -10526,7 +10211,7 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249
}
private class PhantomBodyRotationControl extends BodyRotationControl {
-@@ -422,6 +679,12 @@ public class Phantom extends FlyingMob implements Enemy {
+@@ -403,6 +661,12 @@ public class Phantom extends FlyingMob implements Enemy {
return false;
} else if (!entityliving.isAlive()) {
return false;
@@ -10539,7 +10224,7 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249
} else {
if (entityliving instanceof Player) {
Player entityhuman = (Player) entityliving;
-@@ -567,6 +830,7 @@ public class Phantom extends FlyingMob implements Enemy {
+@@ -548,6 +812,7 @@ public class Phantom extends FlyingMob implements Enemy {
this.nextScanTick = reducedTickDelay(60);
List list = Phantom.this.level().getNearbyPlayers(this.attackTargeting, Phantom.this, Phantom.this.getBoundingBox().inflate(16.0D, 64.0D, 16.0D));
@@ -10548,10 +10233,10 @@ index 187037c43ebb5b245ffa4b50163d443490668744..b70065edff5da1f564aae14b3032b249
list.sort(Comparator.comparing((Entity e) -> { return e.getY(); }).reversed()); // CraftBukkit - decompile error
Iterator iterator = list.iterator();
diff --git a/src/main/java/net/minecraft/world/entity/monster/Pillager.java b/src/main/java/net/minecraft/world/entity/monster/Pillager.java
-index 05ed2f06a41f3b12e0432a37faf98d0b1fea7a8b..d5becd13774f9a2ead77d58e777ffc9aea10cb60 100644
+index ac411202c0029052a962b51b015da191b124de5f..ae3eb87af8d3853be82c2002507141e43ab644de 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Pillager.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Pillager.java
-@@ -66,15 +66,49 @@ public class Pillager extends AbstractIllager implements CrossbowAttackMob, Inve
+@@ -58,15 +58,49 @@ public class Pillager extends AbstractIllager implements CrossbowAttackMob, Inve
super(type, world);
}
@@ -10592,7 +10277,7 @@ index 05ed2f06a41f3b12e0432a37faf98d0b1fea7a8b..d5becd13774f9a2ead77d58e777ffc9a
super.registerGoals();
this.goalSelector.addGoal(0, new FloatGoal(this));
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur
- this.goalSelector.addGoal(2, new Raider.HoldGroundAttackGoal(this, 10.0F));
+ this.goalSelector.addGoal(2, new Raider.HoldGroundAttackGoal(this, 10.0F)); // Paper - decomp fix
this.goalSelector.addGoal(3, new RangedCrossbowAttackGoal<>(this, 1.0D, 8.0F));
this.goalSelector.addGoal(8, new RandomStrollGoal(this, 0.6D));
this.goalSelector.addGoal(9, new LookAtPlayerGoal(this, Player.class, 15.0F, 1.0F));
@@ -10602,11 +10287,11 @@ index 05ed2f06a41f3b12e0432a37faf98d0b1fea7a8b..d5becd13774f9a2ead77d58e777ffc9a
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true));
this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false));
diff --git a/src/main/java/net/minecraft/world/entity/monster/Ravager.java b/src/main/java/net/minecraft/world/entity/monster/Ravager.java
-index 151acc43c96b4545ce92d3d559d8e1591874b4b5..2d834e57253f666f04f8e0b47c8b8a45458c0a75 100644
+index 2d7b7c949faaaaae94c0043132a4a822f55df104..9551bd7c9bed37cf17910e7f71b82ed20fb2d759 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Ravager.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Ravager.java
-@@ -71,14 +71,54 @@ public class Ravager extends Raider {
- this.setPathfindingMalus(BlockPathTypes.LEAVES, 0.0F);
+@@ -68,14 +68,54 @@ public class Ravager extends Raider {
+ this.setPathfindingMalus(PathType.LEAVES, 0.0F);
}
+ // Purpur start
@@ -10660,7 +10345,7 @@ index 151acc43c96b4545ce92d3d559d8e1591874b4b5..2d834e57253f666f04f8e0b47c8b8a45
this.targetSelector.addGoal(2, (new HurtByTargetGoal(this, new Class[]{Raider.class})).setAlertOthers());
this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Player.class, true));
this.targetSelector.addGoal(4, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, true, (entityliving) -> {
-@@ -136,7 +176,7 @@ public class Ravager extends Raider {
+@@ -128,7 +168,7 @@ public class Ravager extends Raider {
@Override
public void aiStep() {
super.aiStep();
@@ -10669,7 +10354,7 @@ index 151acc43c96b4545ce92d3d559d8e1591874b4b5..2d834e57253f666f04f8e0b47c8b8a45
if (this.isImmobile()) {
this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.0D);
} else {
-@@ -146,7 +186,7 @@ public class Ravager extends Raider {
+@@ -138,7 +178,7 @@ public class Ravager extends Raider {
this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(Mth.lerp(0.1D, d1, d0));
}
@@ -10678,7 +10363,7 @@ index 151acc43c96b4545ce92d3d559d8e1591874b4b5..2d834e57253f666f04f8e0b47c8b8a45
boolean flag = false;
AABB axisalignedbb = this.getBoundingBox().inflate(0.2D);
Iterator iterator = BlockPos.betweenClosed(Mth.floor(axisalignedbb.minX), Mth.floor(axisalignedbb.minY), Mth.floor(axisalignedbb.minZ), Mth.floor(axisalignedbb.maxX), Mth.floor(axisalignedbb.maxY), Mth.floor(axisalignedbb.maxZ)).iterator();
-@@ -156,7 +196,7 @@ public class Ravager extends Raider {
+@@ -148,7 +188,7 @@ public class Ravager extends Raider {
BlockState iblockdata = this.level().getBlockState(blockposition);
Block block = iblockdata.getBlock();
@@ -10688,10 +10373,10 @@ index 151acc43c96b4545ce92d3d559d8e1591874b4b5..2d834e57253f666f04f8e0b47c8b8a45
if (!CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, iblockdata.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state
continue;
diff --git a/src/main/java/net/minecraft/world/entity/monster/Shulker.java b/src/main/java/net/minecraft/world/entity/monster/Shulker.java
-index f3c2a2ffb74daa89a516db4c188ce675c79932bf..ab21a44905a4154013cd65acdecbf55b741da086 100644
+index 5215fa54666979ef4da074ddfdb082e7274f2957..1afa6dc4f2a6437cd4cc3e49694e79641fcc13ad 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Shulker.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Shulker.java
-@@ -22,6 +22,8 @@ import net.minecraft.tags.DamageTypeTags;
+@@ -23,6 +23,8 @@ import net.minecraft.tags.DamageTypeTags;
import net.minecraft.util.Mth;
import net.minecraft.world.Difficulty;
import net.minecraft.world.DifficultyInstance;
@@ -10699,8 +10384,8 @@ index f3c2a2ffb74daa89a516db4c188ce675c79932bf..ab21a44905a4154013cd65acdecbf55b
+import net.minecraft.world.InteractionResult;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
- import net.minecraft.world.entity.EntityDimensions;
-@@ -49,6 +51,8 @@ import net.minecraft.world.entity.player.Player;
+ import net.minecraft.world.entity.EntitySelector;
+@@ -48,6 +50,8 @@ import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.AbstractArrow;
import net.minecraft.world.entity.projectile.ShulkerBullet;
import net.minecraft.world.item.DyeColor;
@@ -10769,7 +10454,7 @@ index f3c2a2ffb74daa89a516db4c188ce675c79932bf..ab21a44905a4154013cd65acdecbf55b
this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, new Class[]{this.getClass()})).setAlertOthers());
this.targetSelector.addGoal(2, new Shulker.ShulkerNearestAttackGoal(this));
this.targetSelector.addGoal(3, new Shulker.ShulkerDefenseAttackGoal(this));
-@@ -474,12 +525,21 @@ public class Shulker extends AbstractGolem implements VariantHolder getVariant() {
@@ -10805,20 +10490,20 @@ index f3c2a2ffb74daa89a516db4c188ce675c79932bf..ab21a44905a4154013cd65acdecbf55b
}
@Nullable
-@@ -601,7 +661,7 @@ public class Shulker extends AbstractGolem implements VariantHolder(this, Player.class, true));
}
-@@ -187,7 +221,7 @@ public class Silverfish extends Monster {
+@@ -167,7 +201,7 @@ public class Silverfish extends Monster {
continue;
}
// CraftBukkit end
@@ -10876,7 +10561,7 @@ index fcd5cc3ff8d4b38f4dea08f78723db3dac53ffde..931412a5ab315d4080a9f5209d3e85d7
world.destroyBlock(blockposition1, true, this.silverfish);
} else {
world.setBlock(blockposition1, ((InfestedBlock) block).hostStateByInfested(world.getBlockState(blockposition1)), 3);
-@@ -225,7 +259,7 @@ public class Silverfish extends Monster {
+@@ -205,7 +239,7 @@ public class Silverfish extends Monster {
} else {
RandomSource randomsource = this.mob.getRandom();
@@ -10886,7 +10571,7 @@ index fcd5cc3ff8d4b38f4dea08f78723db3dac53ffde..931412a5ab315d4080a9f5209d3e85d7
BlockPos blockposition = BlockPos.containing(this.mob.getX(), this.mob.getY() + 0.5D, this.mob.getZ()).relative(this.selectedDirection);
BlockState iblockdata = this.mob.level().getBlockState(blockposition);
diff --git a/src/main/java/net/minecraft/world/entity/monster/Skeleton.java b/src/main/java/net/minecraft/world/entity/monster/Skeleton.java
-index 92974452d8f63fde8524cfac305ee2ef5212f840..30ff77f5f137614b5d0d2df6dc90f47c97e8ab13 100644
+index 5642bddc8268d70e5bb5446b65be1d8ce34feb9b..9eb6ed001bfc578311300977dda6f3f156d07190 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Skeleton.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Skeleton.java
@@ -14,6 +14,16 @@ import net.minecraft.world.item.Items;
@@ -10906,7 +10591,7 @@ index 92974452d8f63fde8524cfac305ee2ef5212f840..30ff77f5f137614b5d0d2df6dc90f47c
public class Skeleton extends AbstractSkeleton {
private static final int TOTAL_CONVERSION_TIME = 300;
-@@ -26,6 +36,38 @@ public class Skeleton extends AbstractSkeleton {
+@@ -26,6 +36,40 @@ public class Skeleton extends AbstractSkeleton {
super(type, world);
}
@@ -10932,10 +10617,12 @@ index 92974452d8f63fde8524cfac305ee2ef5212f840..30ff77f5f137614b5d0d2df6dc90f47c
+ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.skeletonMaxHealth);
+ }
+
++ // Purpur start
+ @Override
+ public boolean isSensitiveToWater() {
+ return this.level().purpurConfig.skeletonTakeDamageFromWater;
+ }
++ // Purpur end
+
+ @Override
+ protected boolean isAlwaysExperienceDropper() {
@@ -10943,9 +10630,9 @@ index 92974452d8f63fde8524cfac305ee2ef5212f840..30ff77f5f137614b5d0d2df6dc90f47c
+ }
+
@Override
- protected void defineSynchedData() {
- super.defineSynchedData();
-@@ -142,4 +184,67 @@ public class Skeleton extends AbstractSkeleton {
+ protected void defineSynchedData(SynchedEntityData.Builder builder) {
+ super.defineSynchedData(builder);
+@@ -140,4 +184,67 @@ public class Skeleton extends AbstractSkeleton {
}
}
@@ -11014,10 +10701,10 @@ index 92974452d8f63fde8524cfac305ee2ef5212f840..30ff77f5f137614b5d0d2df6dc90f47c
+ // Purpur end
}
diff --git a/src/main/java/net/minecraft/world/entity/monster/Slime.java b/src/main/java/net/minecraft/world/entity/monster/Slime.java
-index 3d9107d2c19a09215445aa0e0aacc32f9f82a536..0f77f00e9a02d1f982f285617604e7291b70a2a4 100644
+index f223e78eb1204bbf5f2de38a7ce5b663800f7dc4..ccf7fea215d3096e76db294daa5874fec00147ca 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Slime.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java
-@@ -62,6 +62,7 @@ public class Slime extends Mob implements Enemy {
+@@ -61,6 +61,7 @@ public class Slime extends Mob implements Enemy {
public float squish;
public float oSquish;
private boolean wasOnGround;
@@ -11025,7 +10712,7 @@ index 3d9107d2c19a09215445aa0e0aacc32f9f82a536..0f77f00e9a02d1f982f285617604e729
public Slime(EntityType extends Slime> type, Level world) {
super(type, world);
-@@ -69,12 +70,89 @@ public class Slime extends Mob implements Enemy {
+@@ -68,12 +69,89 @@ public class Slime extends Mob implements Enemy {
this.moveControl = new Slime.SlimeMoveControl(this);
}
@@ -11115,7 +10802,7 @@ index 3d9107d2c19a09215445aa0e0aacc32f9f82a536..0f77f00e9a02d1f982f285617604e729
this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, (entityliving) -> {
return Math.abs(entityliving.getY() - this.getY()) <= 4.0D;
}));
-@@ -99,9 +177,9 @@ public class Slime extends Mob implements Enemy {
+@@ -98,9 +176,9 @@ public class Slime extends Mob implements Enemy {
this.entityData.set(Slime.ID_SIZE, j);
this.reapplyPosition();
this.refreshDimensions();
@@ -11127,7 +10814,7 @@ index 3d9107d2c19a09215445aa0e0aacc32f9f82a536..0f77f00e9a02d1f982f285617604e729
if (heal) {
this.setHealth(this.getMaxHealth());
}
-@@ -386,11 +464,12 @@ public class Slime extends Mob implements Enemy {
+@@ -382,11 +460,12 @@ public class Slime extends Mob implements Enemy {
}
@Override
@@ -11141,8 +10828,8 @@ index 3d9107d2c19a09215445aa0e0aacc32f9f82a536..0f77f00e9a02d1f982f285617604e729
}
@Nullable
-@@ -424,7 +503,7 @@ public class Slime extends Mob implements Enemy {
- return super.getDimensions(pose).scale(0.255F * (float) this.getSize());
+@@ -420,7 +499,7 @@ public class Slime extends Mob implements Enemy {
+ return super.getDefaultDimensions(pose).scale((float) this.getSize());
}
- private static class SlimeMoveControl extends MoveControl {
@@ -11150,7 +10837,7 @@ index 3d9107d2c19a09215445aa0e0aacc32f9f82a536..0f77f00e9a02d1f982f285617604e729
private float yRot;
private int jumpDelay;
-@@ -443,21 +522,33 @@ public class Slime extends Mob implements Enemy {
+@@ -439,21 +518,33 @@ public class Slime extends Mob implements Enemy {
}
public void setWantedMovement(double speed) {
@@ -11187,7 +10874,7 @@ index 3d9107d2c19a09215445aa0e0aacc32f9f82a536..0f77f00e9a02d1f982f285617604e729
if (this.jumpDelay-- <= 0) {
this.jumpDelay = this.slime.getJumpDelay();
if (this.isAggressive) {
-@@ -474,7 +565,7 @@ public class Slime extends Mob implements Enemy {
+@@ -470,7 +561,7 @@ public class Slime extends Mob implements Enemy {
this.mob.setSpeed(0.0F);
}
} else {
@@ -11197,10 +10884,10 @@ index 3d9107d2c19a09215445aa0e0aacc32f9f82a536..0f77f00e9a02d1f982f285617604e729
}
diff --git a/src/main/java/net/minecraft/world/entity/monster/Spider.java b/src/main/java/net/minecraft/world/entity/monster/Spider.java
-index 7618364e5373fe17cfe45a5a4ee9ab25e591581c..b44ffeb4cc0ef63fdd25683f60c5a20fcdeb9135 100644
+index fa0316e9d2a4cf213982994dc8bf310299cca984..159740069aba59bffff444d933af32aaf752ba48 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Spider.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Spider.java
-@@ -53,14 +53,48 @@ public class Spider extends Monster {
+@@ -51,9 +51,42 @@ public class Spider extends Monster {
super(type, world);
}
@@ -11240,8 +10927,10 @@ index 7618364e5373fe17cfe45a5a4ee9ab25e591581c..b44ffeb4cc0ef63fdd25683f60c5a20f
protected void registerGoals() {
this.goalSelector.addGoal(1, new FloatGoal(this));
+ this.goalSelector.addGoal(1, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur
- this.goalSelector.addGoal(3, new LeapAtTargetGoal(this, 0.4F));
- this.goalSelector.addGoal(4, new Spider.SpiderAttackGoal(this));
+ this.goalSelector.addGoal(2, new AvoidEntityGoal<>(this, Armadillo.class, 6.0F, 1.0D, 1.2D, (entityliving) -> {
+ return !((Armadillo) entityliving).isScared();
+ }));
+@@ -62,6 +95,7 @@ public class Spider extends Monster {
this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 0.8D));
this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 8.0F));
this.goalSelector.addGoal(6, new RandomLookAroundGoal(this));
@@ -11293,18 +10982,18 @@ index 207a649d737adff440bd3f7cba15b0dbca338a35..18c0cf991c2e8418d7fdd4c8dbd7487a
BlockPos blockPos = pos;
diff --git a/src/main/java/net/minecraft/world/entity/monster/Strider.java b/src/main/java/net/minecraft/world/entity/monster/Strider.java
-index 61162ecd43dc5e6f7898daecdec49f444e6d869b..2f49b528601a1feb7246fe7a9b83ce828c2d78fc 100644
+index fe85900a610afd0b237d8b5a164181c03afbdfc7..5ea5bf9c0e11b0e1f9fe50093899c6e35ee6cf4f 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Strider.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Strider.java
-@@ -94,12 +94,44 @@ public class Strider extends Animal implements ItemSteerable, Saddleable {
+@@ -91,12 +91,44 @@ public class Strider extends Animal implements ItemSteerable, Saddleable {
super(type, world);
this.steering = new ItemBasedSteering(this.entityData, Strider.DATA_BOOST_TIME, Strider.DATA_SADDLE_ID);
this.blocksBuilding = true;
-- this.setPathfindingMalus(BlockPathTypes.WATER, -1.0F);
-+ if (isSensitiveToWater()) this.setPathfindingMalus(BlockPathTypes.WATER, -1.0F); // Purpur
- this.setPathfindingMalus(BlockPathTypes.LAVA, 0.0F);
- this.setPathfindingMalus(BlockPathTypes.DANGER_FIRE, 0.0F);
- this.setPathfindingMalus(BlockPathTypes.DAMAGE_FIRE, 0.0F);
+- this.setPathfindingMalus(PathType.WATER, -1.0F);
++ if (isSensitiveToWater()) this.setPathfindingMalus(PathType.WATER, -1.0F); // Purpur
+ this.setPathfindingMalus(PathType.LAVA, 0.0F);
+ this.setPathfindingMalus(PathType.DANGER_FIRE, 0.0F);
+ this.setPathfindingMalus(PathType.DAMAGE_FIRE, 0.0F);
}
+ // Purpur start
@@ -11342,14 +11031,14 @@ index 61162ecd43dc5e6f7898daecdec49f444e6d869b..2f49b528601a1feb7246fe7a9b83ce82
public static boolean checkStriderSpawnRules(EntityType type, LevelAccessor world, MobSpawnType spawnReason, BlockPos pos, RandomSource random) {
BlockPos.MutableBlockPos blockposition_mutableblockposition = pos.mutable();
-@@ -161,6 +193,7 @@ public class Strider extends Animal implements ItemSteerable, Saddleable {
+@@ -158,6 +190,7 @@ public class Strider extends Animal implements ItemSteerable, Saddleable {
@Override
protected void registerGoals() {
this.goalSelector.addGoal(1, new PanicGoal(this, 1.65D));
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur
this.goalSelector.addGoal(2, new BreedGoal(this, 1.0D));
- this.temptGoal = new TemptGoal(this, 1.4D, Strider.TEMPT_ITEMS, false);
- this.goalSelector.addGoal(3, this.temptGoal);
+ this.temptGoal = new TemptGoal(this, 1.4D, (itemstack) -> {
+ return itemstack.is(ItemTags.STRIDER_TEMPT_ITEMS);
@@ -414,7 +447,7 @@ public class Strider extends Animal implements ItemSteerable, Saddleable {
@Override
@@ -11389,10 +11078,10 @@ index 61162ecd43dc5e6f7898daecdec49f444e6d869b..2f49b528601a1feb7246fe7a9b83ce82
if (flag && !this.isSilent()) {
this.level().playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.STRIDER_EAT, this.getSoundSource(), 1.0F, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F);
diff --git a/src/main/java/net/minecraft/world/entity/monster/Vex.java b/src/main/java/net/minecraft/world/entity/monster/Vex.java
-index f443006c1e32feee97b32312814e2447a50c45e2..834abf1160034543fe3e89fa1c8d4bb55ffc5dc1 100644
+index fd3b37dde54623ba38186efb2a64d364c86b81d2..691f319719280f873140df7d93c821417e32e8f7 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Vex.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Vex.java
-@@ -63,6 +63,65 @@ public class Vex extends Monster implements TraceableEntity {
+@@ -60,6 +60,65 @@ public class Vex extends Monster implements TraceableEntity {
this.xpReward = 3;
}
@@ -11438,7 +11127,6 @@ index f443006c1e32feee97b32312814e2447a50c45e2..834abf1160034543fe3e89fa1c8d4bb5
+ public boolean causeFallDamage(float fallDistance, float damageMultiplier, DamageSource damageSource) {
+ return false; // no fall damage please
+ }
-+ // Purpur end
+
+ @Override
+ public void initAttributes() {
@@ -11454,11 +11142,12 @@ index f443006c1e32feee97b32312814e2447a50c45e2..834abf1160034543fe3e89fa1c8d4bb5
+ protected boolean isAlwaysExperienceDropper() {
+ return this.level().purpurConfig.vexAlwaysDropExp;
+ }
++ // Purpur end
+
@Override
- protected float getStandingEyeHeight(Pose pose, EntityDimensions dimensions) {
- return dimensions.height - 0.28125F;
-@@ -81,7 +140,7 @@ public class Vex extends Monster implements TraceableEntity {
+ public boolean isFlapping() {
+ return this.tickCount % Vex.TICKS_PER_FLAP == 0;
+@@ -73,7 +132,7 @@ public class Vex extends Monster implements TraceableEntity {
@Override
public void tick() {
@@ -11467,7 +11156,7 @@ index f443006c1e32feee97b32312814e2447a50c45e2..834abf1160034543fe3e89fa1c8d4bb5
super.tick();
this.noPhysics = false;
this.setNoGravity(true);
-@@ -96,17 +155,19 @@ public class Vex extends Monster implements TraceableEntity {
+@@ -88,17 +147,19 @@ public class Vex extends Monster implements TraceableEntity {
protected void registerGoals() {
super.registerGoals();
this.goalSelector.addGoal(0, new FloatGoal(this));
@@ -11488,14 +11177,14 @@ index f443006c1e32feee97b32312814e2447a50c45e2..834abf1160034543fe3e89fa1c8d4bb5
}
@Override
-@@ -251,14 +312,14 @@ public class Vex extends Monster implements TraceableEntity {
- return new Vector3f(0.0F, dimensions.height - 0.0625F * scaleFactor, 0.0F);
+@@ -230,14 +291,14 @@ public class Vex extends Monster implements TraceableEntity {
+ this.setDropChance(EquipmentSlot.MAINHAND, 0.0F);
}
- private class VexMoveControl extends MoveControl {
+ private class VexMoveControl extends org.purpurmc.purpur.controller.FlyingMoveControllerWASD { // Purpur
- public VexMoveControl(Vex entityvex) {
+ public VexMoveControl(final Vex entityvex) {
super(entityvex);
}
@@ -11505,7 +11194,7 @@ index f443006c1e32feee97b32312814e2447a50c45e2..834abf1160034543fe3e89fa1c8d4bb5
if (this.operation == MoveControl.Operation.MOVE_TO) {
Vec3 vec3d = new Vec3(this.wantedX - Vex.this.getX(), this.wantedY - Vex.this.getY(), this.wantedZ - Vex.this.getZ());
double d0 = vec3d.length();
-@@ -267,7 +328,7 @@ public class Vex extends Monster implements TraceableEntity {
+@@ -246,7 +307,7 @@ public class Vex extends Monster implements TraceableEntity {
this.operation = MoveControl.Operation.WAIT;
Vex.this.setDeltaMovement(Vex.this.getDeltaMovement().scale(0.5D));
} else {
@@ -11515,10 +11204,10 @@ index f443006c1e32feee97b32312814e2447a50c45e2..834abf1160034543fe3e89fa1c8d4bb5
Vec3 vec3d1 = Vex.this.getDeltaMovement();
diff --git a/src/main/java/net/minecraft/world/entity/monster/Vindicator.java b/src/main/java/net/minecraft/world/entity/monster/Vindicator.java
-index 0ee020848cdfd0c069f1e8d3a9516a339d82467c..960b5e2c290f82501384f79d4653f47bedf926fb 100644
+index b3da310d6fd1d533da805c38c2f449cf06d01492..e7703aa5467e7551bff06fab4c11d76237bda2e0 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Vindicator.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Vindicator.java
-@@ -56,14 +56,48 @@ public class Vindicator extends AbstractIllager {
+@@ -50,14 +50,48 @@ public class Vindicator extends AbstractIllager {
super(type, world);
}
@@ -11567,7 +11256,7 @@ index 0ee020848cdfd0c069f1e8d3a9516a339d82467c..960b5e2c290f82501384f79d4653f47b
this.targetSelector.addGoal(1, new HurtByTargetGoal(this, Raider.class).setAlertOthers());
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true));
this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, true));
-@@ -136,6 +170,12 @@ public class Vindicator extends AbstractIllager {
+@@ -124,6 +158,12 @@ public class Vindicator extends AbstractIllager {
RandomSource randomSource = world.getRandom();
this.populateDefaultEquipmentSlots(randomSource, difficulty);
this.populateDefaultEquipmentEnchantments(randomSource, difficulty);
@@ -11581,10 +11270,10 @@ index 0ee020848cdfd0c069f1e8d3a9516a339d82467c..960b5e2c290f82501384f79d4653f47b
}
diff --git a/src/main/java/net/minecraft/world/entity/monster/Witch.java b/src/main/java/net/minecraft/world/entity/monster/Witch.java
-index f9ffc5f4cbfdcf5c7351a883d2e5c26492175283..4af36f8d0647f881a842e248d02d747115e1cc70 100644
+index 5803c1d36b769f0186baa0665976749765b4cb61..b4aab57b9aaab2ed1322ca41d4bf3c60f155902c 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Witch.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Witch.java
-@@ -59,6 +59,38 @@ public class Witch extends Raider implements RangedAttackMob {
+@@ -55,6 +55,38 @@ public class Witch extends Raider implements RangedAttackMob {
super(type, world);
}
@@ -11623,7 +11312,7 @@ index f9ffc5f4cbfdcf5c7351a883d2e5c26492175283..4af36f8d0647f881a842e248d02d7471
@Override
protected void registerGoals() {
super.registerGoals();
-@@ -67,10 +99,12 @@ public class Witch extends Raider implements RangedAttackMob {
+@@ -63,10 +95,12 @@ public class Witch extends Raider implements RangedAttackMob {
});
this.attackPlayersGoal = new NearestAttackableWitchTargetGoal<>(this, Player.class, 10, true, false, (Predicate) null);
this.goalSelector.addGoal(1, new FloatGoal(this));
@@ -11637,11 +11326,11 @@ index f9ffc5f4cbfdcf5c7351a883d2e5c26492175283..4af36f8d0647f881a842e248d02d7471
this.targetSelector.addGoal(2, this.healRaidersGoal);
this.targetSelector.addGoal(3, this.attackPlayersGoal);
diff --git a/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java b/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java
-index 20a65c11ededcd7170704b70118da6200151fbab..e97cb4e166c2e9ac6d93ed5b15350758326e7e74 100644
+index 3f1191795e58f31b7e2fe34ef2774df13b9a789f..8c62d39c54acf274200667ae30c517cd4416b22f 100644
--- a/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java
+++ b/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java
-@@ -35,6 +35,38 @@ public class WitherSkeleton extends AbstractSkeleton {
- this.setPathfindingMalus(BlockPathTypes.LAVA, 8.0F);
+@@ -32,6 +32,38 @@ public class WitherSkeleton extends AbstractSkeleton {
+ this.setPathfindingMalus(PathType.LAVA, 8.0F);
}
+ // Purpur start
@@ -11680,10 +11369,10 @@ index 20a65c11ededcd7170704b70118da6200151fbab..e97cb4e166c2e9ac6d93ed5b15350758
protected void registerGoals() {
this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractPiglin.class, true));
diff --git a/src/main/java/net/minecraft/world/entity/monster/Zoglin.java b/src/main/java/net/minecraft/world/entity/monster/Zoglin.java
-index 6c1a402e45d7b224c41696bb8bc0e09da076ae4d..ff5839b56ceb59a06ad0de950915a432f7decfb6 100644
+index e650d78e21944579f556f9c9efb38d150cd3a64e..f5feb8b048df713808cda9aff37086a531cfa481 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Zoglin.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Zoglin.java
-@@ -82,6 +82,38 @@ public class Zoglin extends Monster implements Enemy, HoglinBase {
+@@ -80,6 +80,38 @@ public class Zoglin extends Monster implements Enemy, HoglinBase {
this.xpReward = 5;
}
@@ -11722,7 +11411,7 @@ index 6c1a402e45d7b224c41696bb8bc0e09da076ae4d..ff5839b56ceb59a06ad0de950915a432
@Override
protected Brain.Provider brainProvider() {
return Brain.provider(MEMORY_TYPES, SENSOR_TYPES);
-@@ -241,6 +273,7 @@ public class Zoglin extends Monster implements Enemy, HoglinBase {
+@@ -234,6 +266,7 @@ public class Zoglin extends Monster implements Enemy, HoglinBase {
@Override
protected void customServerAiStep() {
@@ -11731,10 +11420,10 @@ index 6c1a402e45d7b224c41696bb8bc0e09da076ae4d..ff5839b56ceb59a06ad0de950915a432
this.updateActivity();
}
diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
-index 5c40e994007dbf46ebc12c1e6a6ca90379471b74..6d69d936a2346f42abe8f867d51040121213b6ff 100644
+index e42dfc62bb179be1ab01b0096c05c6549d38abbc..70263881941efe3b406bbc571932fc8d2c1a78cb 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
-@@ -96,22 +96,69 @@ public class Zombie extends Monster {
+@@ -93,22 +93,69 @@ public class Zombie extends Monster {
private int inWaterTime;
public int conversionTime;
private int lastTick = MinecraftServer.currentTick; // CraftBukkit - add field
@@ -11805,7 +11494,7 @@ index 5c40e994007dbf46ebc12c1e6a6ca90379471b74..6d69d936a2346f42abe8f867d5104012
this.addBehaviourGoals();
}
-@@ -121,7 +168,19 @@ public class Zombie extends Monster {
+@@ -118,7 +165,19 @@ public class Zombie extends Monster {
this.goalSelector.addGoal(7, new WaterAvoidingRandomStrollGoal(this, 1.0D));
this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, new Class[0])).setAlertOthers(ZombifiedPiglin.class));
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true));
@@ -11826,7 +11515,7 @@ index 5c40e994007dbf46ebc12c1e6a6ca90379471b74..6d69d936a2346f42abe8f867d5104012
this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, IronGolem.class, true));
this.targetSelector.addGoal(5, new NearestAttackableTargetGoal<>(this, Turtle.class, 10, true, false, Turtle.BABY_ON_LAND_SELECTOR));
}
-@@ -243,30 +302,7 @@ public class Zombie extends Monster {
+@@ -240,30 +299,7 @@ public class Zombie extends Monster {
@Override
public void aiStep() {
@@ -11849,7 +11538,7 @@ index 5c40e994007dbf46ebc12c1e6a6ca90379471b74..6d69d936a2346f42abe8f867d5104012
- }
-
- if (flag) {
-- this.setSecondsOnFire(8);
+- this.igniteForSeconds(8);
- }
- }
- }
@@ -11858,7 +11547,7 @@ index 5c40e994007dbf46ebc12c1e6a6ca90379471b74..6d69d936a2346f42abe8f867d5104012
super.aiStep();
}
-@@ -304,6 +340,7 @@ public class Zombie extends Monster {
+@@ -301,6 +337,7 @@ public class Zombie extends Monster {
}
@@ -11866,16 +11555,16 @@ index 5c40e994007dbf46ebc12c1e6a6ca90379471b74..6d69d936a2346f42abe8f867d5104012
public boolean isSunSensitive() {
return this.shouldBurnInDay; // Paper - Add more Zombie API
}
-@@ -433,7 +470,7 @@ public class Zombie extends Monster {
+@@ -424,7 +461,7 @@ public class Zombie extends Monster {
nbt.putBoolean("CanBreakDoors", this.canBreakDoors());
nbt.putInt("InWaterTime", this.isInWater() ? this.inWaterTime : -1);
nbt.putInt("DrownedConversionTime", this.isUnderWaterConverting() ? this.conversionTime : -1);
- nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Paper - Add more Zombie API
-+ //nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Paper - Add more Zombie API // Purpur - implemented in LivingEntity
++ // nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Paper - Add more Zombie API // Purpur - implemented in LivingEntity
}
@Override
-@@ -447,7 +484,7 @@ public class Zombie extends Monster {
+@@ -438,7 +475,7 @@ public class Zombie extends Monster {
}
// Paper start - Add more Zombie API
if (nbt.contains("Paper.ShouldBurnInDay")) {
@@ -11884,10 +11573,10 @@ index 5c40e994007dbf46ebc12c1e6a6ca90379471b74..6d69d936a2346f42abe8f867d5104012
}
// Paper end - Add more Zombie API
-@@ -520,19 +557,20 @@ public class Zombie extends Monster {
- if (object instanceof Zombie.ZombieGroupData) {
- Zombie.ZombieGroupData entityzombie_groupdatazombie = (Zombie.ZombieGroupData) object;
+@@ -509,19 +546,20 @@ public class Zombie extends Monster {
+ }
+ if (object instanceof Zombie.ZombieGroupData entityzombie_groupdatazombie) {
- if (entityzombie_groupdatazombie.isBaby) {
- this.setBaby(true);
+ // Purpur start
@@ -11911,7 +11600,7 @@ index 5c40e994007dbf46ebc12c1e6a6ca90379471b74..6d69d936a2346f42abe8f867d5104012
Chicken entitychicken1 = (Chicken) EntityType.CHICKEN.create(this.level());
if (entitychicken1 != null) {
-@@ -542,6 +580,7 @@ public class Zombie extends Monster {
+@@ -531,6 +569,7 @@ public class Zombie extends Monster {
this.startRiding(entitychicken1);
world.addFreshEntity(entitychicken1, CreatureSpawnEvent.SpawnReason.MOUNT); // CraftBukkit
}
@@ -11919,7 +11608,7 @@ index 5c40e994007dbf46ebc12c1e6a6ca90379471b74..6d69d936a2346f42abe8f867d5104012
}
}
}
-@@ -588,7 +627,7 @@ public class Zombie extends Monster {
+@@ -577,7 +616,7 @@ public class Zombie extends Monster {
}
protected void randomizeReinforcementsChance() {
@@ -11929,10 +11618,10 @@ index 5c40e994007dbf46ebc12c1e6a6ca90379471b74..6d69d936a2346f42abe8f867d5104012
@Override
diff --git a/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java b/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java
-index 9274015f58c71f991903bd28434a4832afd074b2..d713afdc687b44595c40690f76e5d6c7ccb501c6 100644
+index 22ec9c1e74450f56cd1e390d59ca28f1577e6139..8ea44416ea728e740af82912017e888a10d78983 100644
--- a/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java
+++ b/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java
-@@ -82,6 +82,58 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder {
+@@ -80,6 +80,58 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder {
});
}
@@ -11989,18 +11678,15 @@ index 9274015f58c71f991903bd28434a4832afd074b2..d713afdc687b44595c40690f76e5d6c7
+ }
+
@Override
- protected void defineSynchedData() {
- super.defineSynchedData();
-@@ -168,13 +220,13 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder {
+ protected void defineSynchedData(SynchedEntityData.Builder builder) {
+ super.defineSynchedData(builder);
+@@ -172,10 +224,10 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder {
ItemStack itemstack = player.getItemInHand(hand);
if (itemstack.is(Items.GOLDEN_APPLE)) {
- if (this.hasEffect(MobEffects.WEAKNESS)) {
+ if (this.hasEffect(MobEffects.WEAKNESS) && level().purpurConfig.zombieVillagerCureEnabled) { // Purpur
- if (!player.getAbilities().instabuild) {
- itemstack.shrink(1);
- }
-
+ itemstack.consume(1, player);
if (!this.level().isClientSide) {
- this.startConverting(player.getUUID(), this.random.nextInt(2401) + 3600);
+ this.startConverting(player.getUUID(), this.random.nextInt(level().purpurConfig.zombieVillagerCuringTimeMax - level().purpurConfig.zombieVillagerCuringTimeMin + 1) + level().purpurConfig.zombieVillagerCuringTimeMin); // Purpur
@@ -12008,11 +11694,11 @@ index 9274015f58c71f991903bd28434a4832afd074b2..d713afdc687b44595c40690f76e5d6c7
return InteractionResult.SUCCESS;
diff --git a/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java b/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java
-index fbabbd0808304f5d0d12f987d00c9e43a89fb1c9..feba8a264bae656244f60296d0511a8046297f73 100644
+index a6def4133f06c41be287e9942643e80a7b8e8218..5bae3215ee0bf222c3bd77b3131f3d01ac6c9c41 100644
--- a/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java
+++ b/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java
-@@ -64,6 +64,53 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob {
- this.setPathfindingMalus(BlockPathTypes.LAVA, 8.0F);
+@@ -62,6 +62,53 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob {
+ this.setPathfindingMalus(PathType.LAVA, 8.0F);
}
+ // Purpur start
@@ -12065,7 +11751,7 @@ index fbabbd0808304f5d0d12f987d00c9e43a89fb1c9..feba8a264bae656244f60296d0511a80
@Override
public void setPersistentAngerTarget(@Nullable UUID angryAt) {
this.persistentAngerTarget = angryAt;
-@@ -111,7 +158,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob {
+@@ -109,7 +156,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob {
this.maybeAlertOthers();
}
@@ -12074,7 +11760,7 @@ index fbabbd0808304f5d0d12f987d00c9e43a89fb1c9..feba8a264bae656244f60296d0511a80
this.lastHurtByPlayerTime = this.tickCount;
}
-@@ -166,7 +213,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob {
+@@ -164,7 +211,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob {
this.ticksUntilNextAlert = ZombifiedPiglin.ALERT_INTERVAL.sample(this.random);
}
@@ -12083,7 +11769,7 @@ index fbabbd0808304f5d0d12f987d00c9e43a89fb1c9..feba8a264bae656244f60296d0511a80
this.setLastHurtByPlayer((Player) entityliving);
}
-@@ -246,7 +293,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob {
+@@ -244,7 +291,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob {
@Override
protected void randomizeReinforcementsChance() {
@@ -12093,10 +11779,10 @@ index fbabbd0808304f5d0d12f987d00c9e43a89fb1c9..feba8a264bae656244f60296d0511a80
@Nullable
diff --git a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java
-index fde1a076d1a490cf7bdea7f89a8714b4661a0d7d..ae1d7f36aa818bf8ee073f062117566f7f8db803 100644
+index 837ae63b1621a4fabba4a44145279d5f95f57f6b..8f89cb4dfa44b04811ddf43d6dc5fdf0b56c3b50 100644
--- a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java
+++ b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java
-@@ -92,6 +92,43 @@ public class Hoglin extends Animal implements Enemy, HoglinBase {
+@@ -90,6 +90,43 @@ public class Hoglin extends Animal implements Enemy, HoglinBase {
this.xpReward = 5;
}
@@ -12140,7 +11826,7 @@ index fde1a076d1a490cf7bdea7f89a8714b4661a0d7d..ae1d7f36aa818bf8ee073f062117566f
@Override
public boolean canBeLeashed(Player player) {
return !this.isLeashed();
-@@ -158,7 +195,7 @@ public class Hoglin extends Animal implements Enemy, HoglinBase {
+@@ -156,7 +193,7 @@ public class Hoglin extends Animal implements Enemy, HoglinBase {
private int behaviorTick; // Pufferfish
@Override
protected void customServerAiStep() {
@@ -12150,10 +11836,10 @@ index fde1a076d1a490cf7bdea7f89a8714b4661a0d7d..ae1d7f36aa818bf8ee073f062117566f
HoglinAi.updateActivity(this);
if (this.isConverting()) {
diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java
-index 2eeb23ce4125b2538e92e19bf73f55398d2dbfc0..0127c4522a7656b7a3bdd967f946f2aa72566442 100644
+index 5ea7cc29c2f9c4e2ee7741b4cead8ea78c296c5d..e2051abbca0b33875e352b0b2821184ada3c57b5 100644
--- a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java
+++ b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java
-@@ -96,6 +96,38 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento
+@@ -94,6 +94,38 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento
this.xpReward = 5;
}
@@ -12192,7 +11878,7 @@ index 2eeb23ce4125b2538e92e19bf73f55398d2dbfc0..0127c4522a7656b7a3bdd967f946f2aa
@Override
public void addAdditionalSaveData(CompoundTag nbt) {
super.addAdditionalSaveData(nbt);
-@@ -303,7 +335,7 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento
+@@ -297,7 +329,7 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento
private int behaviorTick; // Pufferfish
@Override
protected void customServerAiStep() {
@@ -12201,7 +11887,7 @@ index 2eeb23ce4125b2538e92e19bf73f55398d2dbfc0..0127c4522a7656b7a3bdd967f946f2aa
this.getBrain().tick((ServerLevel) this.level(), this);
PiglinAi.updateActivity(this);
super.customServerAiStep();
-@@ -400,7 +432,7 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento
+@@ -389,7 +421,7 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento
@Override
public boolean wantsToPickUp(ItemStack stack) {
@@ -12211,39 +11897,23 @@ index 2eeb23ce4125b2538e92e19bf73f55398d2dbfc0..0127c4522a7656b7a3bdd967f946f2aa
protected boolean canReplaceCurrentItem(ItemStack stack) {
diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java
-index 4f4f557b7f4232ec3b90dda43c6bed30521318ba..dd4313e0507d3adda0ec84c79f1af13ecc2d7ef3 100644
+index e25af9af8f87e6762716749c367658bf6bda9e34..b7d5c0b0e3741fcf04c4bac21a82fc41e2eeed5d 100644
--- a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java
+++ b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java
-@@ -599,20 +599,33 @@ public class PiglinAi {
- Iterator iterator = iterable.iterator();
-
- Item item;
-+ ItemStack itemstack; // Purpur
-
- do {
- if (!iterator.hasNext()) {
- return false;
- }
-
-- ItemStack itemstack = (ItemStack) iterator.next();
-+ itemstack = (ItemStack) iterator.next(); // Purpur
+@@ -606,11 +606,18 @@ public class PiglinAi {
+ ItemStack itemstack = (ItemStack) iterator.next();
item = itemstack.getItem();
-- } while (!(item instanceof ArmorItem) || ((ArmorItem) item).getMaterial() != ArmorMaterials.GOLD);
-+ } while (!(item instanceof ArmorItem) || ((ArmorItem) item).getMaterial() != ArmorMaterials.GOLD && (!entity.level().purpurConfig.piglinIgnoresArmorWithGoldTrim || !isWearingGoldTrim(entity, itemstack))); // Purpur
+- } while (!(item instanceof ArmorItem) || !((ArmorItem) item).getMaterial().is(ArmorMaterials.GOLD));
++ } while (!(item instanceof ArmorItem) || !((ArmorItem) item).getMaterial().is(ArmorMaterials.GOLD) && (!entity.level().purpurConfig.piglinIgnoresArmorWithGoldTrim || !isWearingGoldTrim(item))); // Purpur
return true;
}
+ // Purpur start
-+ private static boolean isWearingGoldTrim(LivingEntity entity, ItemStack itemstack) {
-+ Optional optionalArmorTrim = net.minecraft.world.item.armortrim.ArmorTrim.getTrim(entity.level().registryAccess(), itemstack, true);
-+
-+ if (optionalArmorTrim.isEmpty()) return false;
-+
-+ net.minecraft.world.item.armortrim.ArmorTrim armorTrim = optionalArmorTrim.get();
-+
-+ return armorTrim.material().is(net.minecraft.world.item.armortrim.TrimMaterials.GOLD);
++ private static boolean isWearingGoldTrim(Item itemstack) {
++ net.minecraft.world.item.armortrim.ArmorTrim armorTrim = itemstack.components().get(net.minecraft.core.component.DataComponents.TRIM);
++ return armorTrim != null && armorTrim.material().is(net.minecraft.world.item.armortrim.TrimMaterials.GOLD);
+ }
+ // Purpur end
+
@@ -12251,10 +11921,10 @@ index 4f4f557b7f4232ec3b90dda43c6bed30521318ba..dd4313e0507d3adda0ec84c79f1af13e
piglin.getBrain().eraseMemory(MemoryModuleType.WALK_TARGET);
piglin.getNavigation().stop();
diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinBrute.java b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinBrute.java
-index 76916f1f23c274f615aeccb4dc48649483cdcdb5..44fd639409169838ebc96342fa85d5b2bf8ae9bb 100644
+index 072c28e309d1d18cb3e3e719aec23d77dd966b47..723e4467e202669faeffd4d92a376ca85c199496 100644
--- a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinBrute.java
+++ b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinBrute.java
-@@ -63,6 +63,38 @@ public class PiglinBrute extends AbstractPiglin {
+@@ -62,6 +62,38 @@ public class PiglinBrute extends AbstractPiglin {
this.xpReward = 20;
}
@@ -12293,7 +11963,7 @@ index 76916f1f23c274f615aeccb4dc48649483cdcdb5..44fd639409169838ebc96342fa85d5b2
public static AttributeSupplier.Builder createAttributes() {
return Monster.createMonsterAttributes().add(Attributes.MAX_HEALTH, 50.0).add(Attributes.MOVEMENT_SPEED, 0.35F).add(Attributes.ATTACK_DAMAGE, 7.0);
}
-@@ -113,6 +145,7 @@ public class PiglinBrute extends AbstractPiglin {
+@@ -106,6 +138,7 @@ public class PiglinBrute extends AbstractPiglin {
@Override
protected void customServerAiStep() {
@@ -12302,13 +11972,13 @@ index 76916f1f23c274f615aeccb4dc48649483cdcdb5..44fd639409169838ebc96342fa85d5b2
PiglinBruteAi.updateActivity(this);
PiglinBruteAi.maybePlayActivitySound(this);
diff --git a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java
-index 5cad15c512919ce6b0cae9f45e9011dd66134622..07fa613d75f3659145945245926e9068057e3ed2 100644
+index 7350e339c673c3c59bc36843f03f86ab1ef5e925..664774be9fa4422cc76b0f7e362737426e8e1105 100644
--- a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java
+++ b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java
@@ -123,8 +123,32 @@ public class Warden extends Monster implements VibrationSystem {
- this.setPathfindingMalus(BlockPathTypes.LAVA, 8.0F);
- this.setPathfindingMalus(BlockPathTypes.DAMAGE_FIRE, 0.0F);
- this.setPathfindingMalus(BlockPathTypes.DANGER_FIRE, 0.0F);
+ this.setPathfindingMalus(PathType.LAVA, 8.0F);
+ this.setPathfindingMalus(PathType.DAMAGE_FIRE, 0.0F);
+ this.setPathfindingMalus(PathType.DANGER_FIRE, 0.0F);
+ this.moveControl = new org.purpurmc.purpur.controller.MoveControllerWASD(this, 0.5F); // Purpur
}
@@ -12338,16 +12008,14 @@ index 5cad15c512919ce6b0cae9f45e9011dd66134622..07fa613d75f3659145945245926e9068
@Override
public Packet getAddEntityPacket() {
return new ClientboundAddEntityPacket(this, this.hasPose(Pose.EMERGING) ? 1 : 0);
-@@ -396,19 +420,16 @@ public class Warden extends Monster implements VibrationSystem {
+@@ -392,17 +416,14 @@ public class Warden extends Monster implements VibrationSystem {
@Contract("null->false")
public boolean canTargetEntity(@Nullable Entity entity) {
- boolean flag;
-
+ if (getRider() != null && isControllable()) return false; // Purpur
- if (entity instanceof LivingEntity) {
- LivingEntity entityliving = (LivingEntity) entity;
-
+ if (entity instanceof LivingEntity entityliving) {
if (this.level() == entity.level() && EntitySelector.NO_CREATIVE_OR_SPECTATOR.test(entity) && !this.isAlliedTo(entity) && entityliving.getType() != EntityType.ARMOR_STAND && entityliving.getType() != EntityType.WARDEN && !entityliving.isInvulnerable() && !entityliving.isDeadOrDying() && this.level().getWorldBorder().isWithinBounds(entityliving.getBoundingBox())) {
- flag = true;
- return flag;
@@ -12362,10 +12030,10 @@ index 5cad15c512919ce6b0cae9f45e9011dd66134622..07fa613d75f3659145945245926e9068
public static void applyDarknessAround(ServerLevel world, Vec3 pos, @Nullable Entity entity, int range) {
diff --git a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
-index 4e6c2f6b2e54a4c126e9a026b9cad05ce835ad66..69553b5b3c56998e4ae40876b1458929b335ad5d 100644
+index d323cf157f2a910916baa9ce3f7e5bc81648c47d..6cbbca1db5362fa2dd5c5704c7fbaa612d3cbab1 100644
--- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
+++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
-@@ -42,6 +42,7 @@ import org.bukkit.event.entity.VillagerAcquireTradeEvent;
+@@ -48,6 +48,7 @@ import org.bukkit.event.entity.VillagerAcquireTradeEvent;
// CraftBukkit end
public abstract class AbstractVillager extends AgeableMob implements InventoryCarrier, Npc, Merchant {
@@ -12374,10 +12042,10 @@ index 4e6c2f6b2e54a4c126e9a026b9cad05ce835ad66..69553b5b3c56998e4ae40876b1458929
// CraftBukkit start
private CraftMerchant craftMerchant;
diff --git a/src/main/java/net/minecraft/world/entity/npc/CatSpawner.java b/src/main/java/net/minecraft/world/entity/npc/CatSpawner.java
-index 5d1610eddcaf0cf65c726a5438b42e53bab85332..4c7523a8df9124c30dbb569259c8b66497eff9db 100644
+index e0e5046c84941a8d17e18c177f3daea9cb631940..d503d7a5837dbeb98e58dbe8f7e5de45f6d88990 100644
--- a/src/main/java/net/minecraft/world/entity/npc/CatSpawner.java
+++ b/src/main/java/net/minecraft/world/entity/npc/CatSpawner.java
-@@ -28,7 +28,7 @@ public class CatSpawner implements CustomSpawner {
+@@ -27,7 +27,7 @@ public class CatSpawner implements CustomSpawner {
if (this.nextTick > 0) {
return 0;
} else {
@@ -12386,7 +12054,7 @@ index 5d1610eddcaf0cf65c726a5438b42e53bab85332..4c7523a8df9124c30dbb569259c8b664
Player player = world.getRandomPlayer();
if (player == null) {
return 0;
-@@ -62,8 +62,12 @@ public class CatSpawner implements CustomSpawner {
+@@ -61,8 +61,12 @@ public class CatSpawner implements CustomSpawner {
private int spawnInVillage(ServerLevel world, BlockPos pos) {
int i = 48;
@@ -12397,11 +12065,11 @@ index 5d1610eddcaf0cf65c726a5438b42e53bab85332..4c7523a8df9124c30dbb569259c8b664
+ if (range <= 0) return 0;
+ if (world.getPoiManager().getCountInRange(entry -> entry.is(PoiTypes.HOME), pos, range, PoiManager.Occupancy.IS_OCCUPIED) > 4L) {
+ List list = world.getEntitiesOfClass(Cat.class, new AABB(pos).inflate(range, 8.0, range));
-+ // Purpur end
++ // Purpur end
if (list.size() < 5) {
return this.spawnCat(pos, world);
}
-@@ -74,7 +78,11 @@ public class CatSpawner implements CustomSpawner {
+@@ -73,7 +77,11 @@ public class CatSpawner implements CustomSpawner {
private int spawnInHut(ServerLevel world, BlockPos pos) {
int i = 16;
@@ -12415,19 +12083,20 @@ index 5d1610eddcaf0cf65c726a5438b42e53bab85332..4c7523a8df9124c30dbb569259c8b664
}
diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java
-index 34812d4ab115f31a6ad1cf8cbc345dda4339c075..248ef4e472d569395eda57298298f788bf9db6f7 100644
+index e32c928dc21def1df0f6d334405cff5dc8e999cd..dc2bbb7cbe31abb6ff54d51267d01c5485bbdfdc 100644
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
-@@ -146,6 +146,8 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
- });
+@@ -147,6 +147,9 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
public long nextGolemPanic = -1; // Pufferfish
+
+ private boolean isLobotomized = false; public boolean isLobotomized() { return this.isLobotomized; } // Purpur
+ private int notLobotomizedCount = 0; // Purpur
-
++
public Villager(EntityType extends Villager> entityType, Level world) {
this(entityType, world, VillagerType.PLAINS);
-@@ -158,6 +160,91 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
+ }
+@@ -158,6 +161,91 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
this.getNavigation().setCanFloat(true);
this.setCanPickUpLoot(true);
this.setVillagerData(this.getVillagerData().setType(type).setProfession(VillagerProfession.NONE));
@@ -12519,7 +12188,7 @@ index 34812d4ab115f31a6ad1cf8cbc345dda4339c075..248ef4e472d569395eda57298298f788
}
@Override
-@@ -194,7 +281,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
+@@ -194,7 +282,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
brain.addActivity(Activity.PLAY, VillagerGoalPackages.getPlayPackage(0.5F));
} else {
brain.setSchedule(Schedule.VILLAGER_DEFAULT);
@@ -12528,7 +12197,7 @@ index 34812d4ab115f31a6ad1cf8cbc345dda4339c075..248ef4e472d569395eda57298298f788
}
brain.addActivity(Activity.CORE, VillagerGoalPackages.getCorePackage(villagerprofession, 0.5F));
-@@ -257,13 +344,21 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
+@@ -257,13 +345,22 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
// Paper start
this.customServerAiStep(false);
}
@@ -12542,18 +12211,18 @@ index 34812d4ab115f31a6ad1cf8cbc345dda4339c075..248ef4e472d569395eda57298298f788
+ } else {
+ this.isLobotomized = false;
+ }
++ // Purpur end
// Pufferfish start
- if (!inactive && this.behaviorTick++ % this.activatedPriority == 0) {
-+ if (!inactive && (getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Purpur - only use brain if no rider
++ if (!inactive && (getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) { // Purpur - only use brain if no rider
this.getBrain().tick((ServerLevel) this.level(), this); // Paper
-- }
+ }
// Pufferfish end
-+ else if (this.isLobotomized && shouldRestock()) restock();
-+ // Purpur end
++ else if (this.isLobotomized && shouldRestock()) restock(); // Purpur
if (this.assignProfessionWhenSpawned) {
this.assignProfessionWhenSpawned = false;
}
-@@ -319,7 +414,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
+@@ -319,7 +416,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
if (!itemstack.is(Items.VILLAGER_SPAWN_EGG) && this.isAlive() && !this.isTrading() && !this.isSleeping()) {
if (this.isBaby()) {
this.setUnhappy();
@@ -12562,7 +12231,7 @@ index 34812d4ab115f31a6ad1cf8cbc345dda4339c075..248ef4e472d569395eda57298298f788
} else {
boolean flag = this.getOffers().isEmpty();
-@@ -332,9 +427,10 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
+@@ -332,9 +429,10 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
}
if (flag) {
@@ -12575,7 +12244,7 @@ index 34812d4ab115f31a6ad1cf8cbc345dda4339c075..248ef4e472d569395eda57298298f788
this.startTrading(player);
}
-@@ -503,7 +599,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
+@@ -503,7 +601,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
while (iterator.hasNext()) {
MerchantOffer merchantrecipe = (MerchantOffer) iterator.next();
@@ -12584,7 +12253,7 @@ index 34812d4ab115f31a6ad1cf8cbc345dda4339c075..248ef4e472d569395eda57298298f788
}
}
-@@ -753,7 +849,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
+@@ -745,7 +843,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
@Override
public boolean canBreed() {
@@ -12593,7 +12262,7 @@ index 34812d4ab115f31a6ad1cf8cbc345dda4339c075..248ef4e472d569395eda57298298f788
}
private boolean hungry() {
-@@ -967,6 +1063,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
+@@ -959,6 +1057,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
public boolean hasFarmSeeds() {
return this.getInventory().hasAnyMatching((itemstack) -> {
@@ -12605,7 +12274,7 @@ index 34812d4ab115f31a6ad1cf8cbc345dda4339c075..248ef4e472d569395eda57298298f788
return itemstack.is(ItemTags.VILLAGER_PLANTABLE_SEEDS);
});
}
-@@ -1024,6 +1125,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
+@@ -1016,6 +1119,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
}
public void spawnGolemIfNeeded(ServerLevel world, long time, int requiredCount) {
@@ -12613,7 +12282,7 @@ index 34812d4ab115f31a6ad1cf8cbc345dda4339c075..248ef4e472d569395eda57298298f788
if (this.wantsToSpawnGolem(time)) {
AABB axisalignedbb = this.getBoundingBox().inflate(10.0D, 10.0D, 10.0D);
List list = world.getEntitiesOfClass(Villager.class, axisalignedbb);
-@@ -1088,6 +1190,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
+@@ -1080,6 +1184,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
@Override
public void startSleeping(BlockPos pos) {
@@ -12640,7 +12309,7 @@ index 3821c02187ad04b20cdf1e719a0deeabbf91007d..8f36f113e8eb3236ce53ad9cce320c3d
"farmer",
PoiTypes.FARMER,
diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java
-index 8d1cc1a644415be251f469ab1cb2ebc09fe5c3eb..b133c186d2d1412aa623ba3db68091bc69c282a5 100644
+index 0854e9b7ee2e6b23b6c1ee6a324a5a253c9d4679..c1e573758539a151452b12466339ccf8b39c7d38 100644
--- a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java
+++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java
@@ -71,6 +71,43 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill
@@ -12718,10 +12387,10 @@ index 8d1cc1a644415be251f469ab1cb2ebc09fe5c3eb..b133c186d2d1412aa623ba3db68091bc
this.openTradingScreen(player, this.getDisplayName(), 1);
}
diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java
-index d7bddedb19c10f62fd1f7d3128453ad706ed16be..752b38d45d59d8b3cd492246e5aa4f378a78734d 100644
+index c72b6ea5530e54fc373c701028e1c147cea34b59..96e9fce5f9084737d2fcf4deb83305733b480179 100644
--- a/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java
+++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java
-@@ -159,7 +159,17 @@ public class WanderingTraderSpawner implements CustomSpawner {
+@@ -160,7 +160,17 @@ public class WanderingTraderSpawner implements CustomSpawner {
int k = pos.getX() + this.random.nextInt(range * 2) - range;
int l = pos.getZ() + this.random.nextInt(range * 2) - range;
int i1 = world.getHeight(Heightmap.Types.WORLD_SURFACE, k, l);
@@ -12738,14 +12407,14 @@ index d7bddedb19c10f62fd1f7d3128453ad706ed16be..752b38d45d59d8b3cd492246e5aa4f37
+ }
+ // Purpur end
- if (NaturalSpawner.isSpawnPositionOk(SpawnPlacements.Type.ON_GROUND, world, blockposition2, EntityType.WANDERING_TRADER)) {
+ if (spawnplacementtype.isSpawnPositionOk(world, blockposition2, EntityType.WANDERING_TRADER)) {
blockposition1 = blockposition2;
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
-index c300b272c820786c8c4b9d83e184c5969468e1e0..fc840fff5fe2dc33986f8e5d3a60c3c853fe6151 100644
+index 70b9d7c9f938009274143ea2fb728492f394531e..852acdd290f2c8d7c3de470140e54a150da4dbb6 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
-@@ -186,11 +186,21 @@ public abstract class Player extends LivingEntity {
- public float hurtDir; // Paper - protected -> public
+@@ -198,11 +198,20 @@ public abstract class Player extends LivingEntity {
+ public boolean ignoreFallDamageFromCurrentImpulse;
public boolean affectsSpawning = true; // Paper - Affects Spawning API
public net.kyori.adventure.util.TriState flyingFallDamage = net.kyori.adventure.util.TriState.NOT_SET; // Paper - flying fall damage
+ public int sixRowEnderchestSlotCount = -1; // Purpur
@@ -12756,8 +12425,7 @@ index c300b272c820786c8c4b9d83e184c5969468e1e0..fc840fff5fe2dc33986f8e5d3a60c3c8
public boolean fauxSleeping;
public int oldLevel = -1;
-+ public void setAfk(boolean afk) {
-+ }
++ public void setAfk(boolean afk) {}
+
+ public boolean isAfk() {
+ return false;
@@ -12766,7 +12434,7 @@ index c300b272c820786c8c4b9d83e184c5969468e1e0..fc840fff5fe2dc33986f8e5d3a60c3c8
@Override
public CraftHumanEntity getBukkitEntity() {
return (CraftHumanEntity) super.getBukkitEntity();
-@@ -199,6 +209,19 @@ public abstract class Player extends LivingEntity {
+@@ -211,6 +220,19 @@ public abstract class Player extends LivingEntity {
public final int sendAllPlayerInfoBucketIndex; // Gale - Purpur - spread out sending all player info
@@ -12786,7 +12454,7 @@ index c300b272c820786c8c4b9d83e184c5969468e1e0..fc840fff5fe2dc33986f8e5d3a60c3c8
public Player(Level world, BlockPos pos, float yaw, GameProfile gameProfile) {
super(EntityType.PLAYER, world);
this.lastItemInMainHand = ItemStack.EMPTY;
-@@ -244,6 +267,12 @@ public abstract class Player extends LivingEntity {
+@@ -256,6 +278,12 @@ public abstract class Player extends LivingEntity {
@Override
public void tick() {
@@ -12799,7 +12467,7 @@ index c300b272c820786c8c4b9d83e184c5969468e1e0..fc840fff5fe2dc33986f8e5d3a60c3c8
this.noPhysics = this.isSpectator();
if (this.isSpectator()) {
this.setOnGround(false);
-@@ -358,6 +387,16 @@ public abstract class Player extends LivingEntity {
+@@ -370,6 +398,16 @@ public abstract class Player extends LivingEntity {
this.addEffect(new MobEffectInstance(MobEffects.WATER_BREATHING, 200, 0, false, false, true), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.TURTLE_HELMET); // CraftBukkit
}
@@ -12816,7 +12484,7 @@ index c300b272c820786c8c4b9d83e184c5969468e1e0..fc840fff5fe2dc33986f8e5d3a60c3c8
}
protected ItemCooldowns createItemCooldowns() {
-@@ -448,7 +487,7 @@ public abstract class Player extends LivingEntity {
+@@ -460,7 +498,7 @@ public abstract class Player extends LivingEntity {
@Override
public int getPortalWaitTime() {
@@ -12825,7 +12493,7 @@ index c300b272c820786c8c4b9d83e184c5969468e1e0..fc840fff5fe2dc33986f8e5d3a60c3c8
}
@Override
-@@ -604,7 +643,7 @@ public abstract class Player extends LivingEntity {
+@@ -603,7 +641,7 @@ public abstract class Player extends LivingEntity {
while (iterator.hasNext()) {
Entity entity = (Entity) iterator.next();
@@ -12834,16 +12502,16 @@ index c300b272c820786c8c4b9d83e184c5969468e1e0..fc840fff5fe2dc33986f8e5d3a60c3c8
list1.add(entity);
} else if (!entity.isRemoved()) {
this.touch(entity);
-@@ -1295,7 +1334,7 @@ public abstract class Player extends LivingEntity {
- flag2 = flag2 && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper - Toggleable player crits
- flag2 = flag2 && !this.isSprinting();
- if (flag2) {
-- f *= 1.5F;
-+ f *= this.level().purpurConfig.playerCriticalDamageMultiplier; // Purpur
- }
+@@ -1311,7 +1349,7 @@ public abstract class Player extends LivingEntity {
- f += f1;
-@@ -1938,9 +1977,19 @@ public abstract class Player extends LivingEntity {
+ flag2 = flag2 && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper - Toggleable player crits
+ if (flag2) {
+- f *= 1.5F;
++ f *= this.level().purpurConfig.playerCriticalDamageMultiplier; // Purpur
+ }
+
+ f += f1;
+@@ -1956,9 +1994,19 @@ public abstract class Player extends LivingEntity {
@Override
public int getExperienceReward() {
if (!this.level().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) && !this.isSpectator()) {
@@ -12866,40 +12534,34 @@ index c300b272c820786c8c4b9d83e184c5969468e1e0..fc840fff5fe2dc33986f8e5d3a60c3c8
} else {
return 0;
}
-@@ -2016,6 +2065,11 @@ public abstract class Player extends LivingEntity {
- return this.inventory.armor;
+@@ -2039,6 +2087,13 @@ public abstract class Player extends LivingEntity {
+ return slot != EquipmentSlot.BODY;
}
++ // Purpur start
+ @Override
+ public boolean dismountsUnderwater() {
+ return !level().purpurConfig.playerRidableInWater;
+ }
++ // Purpur end
+
public boolean setEntityOnShoulder(CompoundTag entityNbt) {
if (!this.isPassenger() && this.onGround() && !this.isInWater() && !this.isInPowderSnow) {
if (this.getShoulderEntityLeft().isEmpty()) {
-@@ -2296,7 +2350,7 @@ public abstract class Player extends LivingEntity {
+@@ -2336,7 +2391,7 @@ public abstract class Player extends LivingEntity {
public ItemStack eat(Level world, ItemStack stack) {
- this.getFoodData().eat(stack.getItem(), stack);
+ this.getFoodData().eat(stack);
this.awardStat(Stats.ITEM_USED.get(stack.getItem()));
- world.playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_BURP, SoundSource.PLAYERS, 0.5F, world.random.nextFloat() * 0.1F + 0.9F);
+ // world.playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_BURP, SoundSource.PLAYERS, 0.5F, world.random.nextFloat() * 0.1F + 0.9F); // Purpur - moved to tick()
if (this instanceof ServerPlayer) {
CriteriaTriggers.CONSUME_ITEM.trigger((ServerPlayer) this, stack);
}
-@@ -2390,6 +2444,7 @@ public abstract class Player extends LivingEntity {
- }
-
- public static boolean isValidUsername(String name) {
-+ if (true) return org.purpurmc.purpur.PurpurConfig.usernameValidCharactersPattern.matcher(name).matches(); // Purpur
- // Paper start - username validation overriding
- if (name == null || name.isEmpty() || name.length() > 16) {
- return false;
diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
-index 488a98e20b4f405d1ce4a224d2d2b5151dec369b..609695ef44fa46bd9a0418e9ac5fe3d105daa505 100644
+index 7f99fe3ea54c6b39584a73d1931100193ac09cbd..54483331ce0906c93d109421007ca38833d02e27 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
-@@ -75,6 +75,7 @@ public abstract class AbstractArrow extends Projectile {
+@@ -77,6 +77,7 @@ public abstract class AbstractArrow extends Projectile {
@Nullable
private List piercedAndKilledEntities;
public ItemStack pickupItemStack;
@@ -12907,7 +12569,7 @@ index 488a98e20b4f405d1ce4a224d2d2b5151dec369b..609695ef44fa46bd9a0418e9ac5fe3d1
// Spigot Start
@Override
-@@ -642,6 +643,12 @@ public abstract class AbstractArrow extends Projectile {
+@@ -655,6 +656,12 @@ public abstract class AbstractArrow extends Projectile {
this.knockback = punch;
}
@@ -12949,10 +12611,10 @@ index 9d89872c5958f3e8d6c1ef4fd93f9b8b85296851..6a94c86acce5afbf1e9c8e7d664b3eb2
// CraftBukkit start - fire ExplosionPrimeEvent
ExplosionPrimeEvent event = new ExplosionPrimeEvent((org.bukkit.entity.Explosive) this.getBukkitEntity());
diff --git a/src/main/java/net/minecraft/world/entity/projectile/LlamaSpit.java b/src/main/java/net/minecraft/world/entity/projectile/LlamaSpit.java
-index 8f5376543cca9cbfb2a014f67ec373d984b0df64..3673d1442778331ece25f8faca95b3499cafe46e 100644
+index ffd01d24cbfc90e2a8807757e61b2cf20a944354..a419820d5001079ed839e67c757bc8fa591a20b3 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/LlamaSpit.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/LlamaSpit.java
-@@ -29,6 +29,12 @@ public class LlamaSpit extends Projectile {
+@@ -30,6 +30,12 @@ public class LlamaSpit extends Projectile {
this.setPos(owner.getX() - (double) (owner.getBbWidth() + 1.0F) * 0.5D * (double) Mth.sin(owner.yBodyRot * 0.017453292F), owner.getEyeY() - 0.10000000149011612D, owner.getZ() + (double) (owner.getBbWidth() + 1.0F) * 0.5D * (double) Mth.cos(owner.yBodyRot * 0.017453292F));
}
@@ -12963,22 +12625,13 @@ index 8f5376543cca9cbfb2a014f67ec373d984b0df64..3673d1442778331ece25f8faca95b349
+ // Purpur end
+
@Override
- public void tick() {
- super.tick();
+ protected double getDefaultGravity() {
+ return 0.06D;
diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
-index d3a055e221ec62070f6557d1686febadf1249402..4a3fe54e9b3af58cba9b09478f75ea788f4880f2 100644
+index adb4cd2a926744182952d0702284f7c7b9e5d42c..330d6badfbd096e4aec873dcb419df7975cb60a3 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
-@@ -70,7 +70,7 @@ public abstract class Projectile extends Entity implements TraceableEntity {
- int maxChunkLoadsPerProjectile = maxProjectileChunkLoadsConfig.perProjectile.max;
- if (maxChunkLoadsPerProjectile >= 0 && this.chunksLoadedByProjectile >= maxChunkLoadsPerProjectile) {
- if (maxProjectileChunkLoadsConfig.perProjectile.removeFromWorldAfterReachLimit) {
-- this.discard();
-+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); // Purpur
- } else if (maxProjectileChunkLoadsConfig.perProjectile.resetMovementAfterReachLimit) {
- this.setDeltaMovement(0, this.getDeltaMovement().y, 0);
- }
-@@ -343,7 +343,7 @@ public abstract class Projectile extends Entity implements TraceableEntity {
+@@ -382,7 +382,7 @@ public abstract class Projectile extends Entity implements TraceableEntity {
public boolean mayInteract(Level world, BlockPos pos) {
Entity entity = this.getOwner();
@@ -12988,7 +12641,7 @@ index d3a055e221ec62070f6557d1686febadf1249402..4a3fe54e9b3af58cba9b09478f75ea78
public boolean mayBreak(Level world) {
diff --git a/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java b/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java
-index 6724fe4470aeea338eb4cfd10a7e61fbcac1e5b7..dd38f32ac6a62905c9a79dacf85cf073fa6941b3 100644
+index 3a11ad32d95088a5aca713a1a6a984cc22d4fa9a..c078ccad4aabe469a9611331b415a4cef241973e 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java
@@ -27,7 +27,7 @@ public class SmallFireball extends Fireball {
@@ -13001,7 +12654,7 @@ index 6724fe4470aeea338eb4cfd10a7e61fbcac1e5b7..dd38f32ac6a62905c9a79dacf85cf073
// CraftBukkit end
}
diff --git a/src/main/java/net/minecraft/world/entity/projectile/Snowball.java b/src/main/java/net/minecraft/world/entity/projectile/Snowball.java
-index 5e82549ea2e80b3968b793b7b4b685c4891e9a91..bb61e1132c28274175215a679befdcfa2496b099 100644
+index 2b4d206c0d31ba38d7b2af654bd420e85145d441..1b9d0e28e518c501b4b93ae385ddd64aeade97d5 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/Snowball.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/Snowball.java
@@ -58,11 +58,41 @@ public class Snowball extends ThrowableItemProjectile {
@@ -13074,10 +12727,10 @@ index 1fb1e729d6879568d8b4943071fa940325b2e5b0..d9761d8fe746e925a7a32dfc15eb8045
// CraftBukkit end
this.level().playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_TELEPORT, SoundSource.PLAYERS);
diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java
-index 8ae7d62b72fb72d893e68b02b645d48374595ae6..2bd77524313ae7b32f710e7d197e81a2ddd12965 100644
+index 3ff06cc6ad35567bcb1f29115db63c11a8e79dbb..f7dd785bdb0dbd0706b367b48235215ff1a0e08f 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java
-@@ -63,7 +63,7 @@ public class ThrownTrident extends AbstractArrow {
+@@ -67,7 +67,7 @@ public class ThrownTrident extends AbstractArrow {
Entity entity = this.getOwner();
byte b0 = (Byte) this.entityData.get(ThrownTrident.ID_LOYALTY);
@@ -13087,7 +12740,7 @@ index 8ae7d62b72fb72d893e68b02b645d48374595ae6..2bd77524313ae7b32f710e7d197e81a2
if (!this.level().isClientSide && this.pickup == AbstractArrow.Pickup.ALLOWED) {
this.spawnAtLocation(this.getPickupItem(), 0.1F);
diff --git a/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java b/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java
-index 6f49b9b8707d74330adb973e0db3cd5bccf138b6..b4a38621b58e16b2bf48b3d45d85130e8883b477 100644
+index 55b4b5ad5f084c9a271a716d076672478d6486ba..a60d7f7baab005afc532ecec7aa22c53db4f51e0 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java
@@ -99,7 +99,7 @@ public class WitherSkull extends AbstractHurtingProjectile {
@@ -13099,10 +12752,11 @@ index 6f49b9b8707d74330adb973e0db3cd5bccf138b6..b4a38621b58e16b2bf48b3d45d85130e
this.level().getCraftServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
-@@ -111,6 +111,17 @@ public class WitherSkull extends AbstractHurtingProjectile {
+@@ -111,6 +111,19 @@ public class WitherSkull extends AbstractHurtingProjectile {
}
++ // Purpur start
+ @Override
+ public boolean canHitEntity(Entity target) {
+ // do not hit rider
@@ -13113,15 +12767,16 @@ index 6f49b9b8707d74330adb973e0db3cd5bccf138b6..b4a38621b58e16b2bf48b3d45d85130e
+ public boolean canSaveToDisk() {
+ return false;
+ }
++ // Purpur end
+
@Override
- public boolean isPickable() {
+ public boolean hurt(DamageSource source, float amount) {
return false;
diff --git a/src/main/java/net/minecraft/world/entity/raid/Raider.java b/src/main/java/net/minecraft/world/entity/raid/Raider.java
-index 031355802d86f51489a58561b8806d7d672e4a3b..fb61df507e844a2eed27cbe295ab9378b5f780f5 100644
+index 98e558338b5d9fb03869d2cc21b3e90eb45b95f6..4a8fa7e5844b5cd12ef6b113f988b715c7a3ef64 100644
--- a/src/main/java/net/minecraft/world/entity/raid/Raider.java
+++ b/src/main/java/net/minecraft/world/entity/raid/Raider.java
-@@ -322,7 +322,7 @@ public abstract class Raider extends PatrollingMonster {
+@@ -341,7 +341,7 @@ public abstract class Raider extends PatrollingMonster {
@Override
public boolean canUse() {
@@ -13129,12 +12784,12 @@ index 031355802d86f51489a58561b8806d7d672e4a3b..fb61df507e844a2eed27cbe295ab9378
+ if ((!this.mob.level().purpurConfig.pillagerBypassMobGriefing && !this.mob.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) || !this.mob.canPickUpLoot()) return false; // Paper - respect game and entity rules for picking up items // Purpur
Raid raid = this.mob.getCurrentRaid();
- if (this.mob.hasActiveRaid() && !this.mob.getCurrentRaid().isOver() && this.mob.canBeLeader() && !ItemStack.matches(this.mob.getItemBySlot(EquipmentSlot.HEAD), Raid.LEADER_BANNER)) { // Gale - Lithium - cache ominous banner item
+ if (this.mob.hasActiveRaid() && !this.mob.getCurrentRaid().isOver() && this.mob.canBeLeader() && !ItemStack.matches(this.mob.getItemBySlot(EquipmentSlot.HEAD), Raid.getLeaderBannerInstance(this.mob.registryAccess().lookupOrThrow(Registries.BANNER_PATTERN)))) {
diff --git a/src/main/java/net/minecraft/world/entity/raid/Raids.java b/src/main/java/net/minecraft/world/entity/raid/Raids.java
-index 31831811ce16265e9828fa34d9e67d8ac195d723..a1f74718240da3dfb0fc53f337ec3bf1636def75 100644
+index 8c60f71270d909c10e6617eb64b8fdb42deb73e9..eedce2a3d67d875d5174ee125e2679480d4d412c 100644
--- a/src/main/java/net/minecraft/world/entity/raid/Raids.java
+++ b/src/main/java/net/minecraft/world/entity/raid/Raids.java
-@@ -29,6 +29,7 @@ import net.minecraft.world.phys.Vec3;
+@@ -26,6 +26,7 @@ import net.minecraft.world.phys.Vec3;
public class Raids extends SavedData {
private static final String RAID_FILE_ID = "raids";
@@ -13142,7 +12797,7 @@ index 31831811ce16265e9828fa34d9e67d8ac195d723..a1f74718240da3dfb0fc53f337ec3bf1
public final Map raidMap = Maps.newHashMap();
private final ServerLevel level;
private int nextAvailableID;
-@@ -54,6 +55,17 @@ public class Raids extends SavedData {
+@@ -51,6 +52,17 @@ public class Raids extends SavedData {
public void tick() {
++this.tick;
@@ -13157,28 +12812,28 @@ index 31831811ce16265e9828fa34d9e67d8ac195d723..a1f74718240da3dfb0fc53f337ec3bf1
+ });
+ }
+ // Purpur end
- Iterator iterator = this.raidMap.values().iterator();
+ Iterator iterator = this.raidMap.values().iterator();
while (iterator.hasNext()) {
-@@ -138,11 +150,13 @@ public class Raids extends SavedData {
- }
+@@ -122,11 +134,13 @@ public class Raids extends SavedData {
+ */
- if (flag) {
+ if (!raid.isStarted() || (raid.isInProgress() && raid.getRaidOmenLevel() < raid.getMaxRaidOmenLevel())) { // CraftBukkit - fixed a bug with raid: players could add up Bad Omen level even when the raid had finished
+ if (level.purpurConfig.raidCooldownSeconds != 0 && playerCooldowns.containsKey(player.getUUID())) return null; // Purpur
// CraftBukkit start
if (!org.bukkit.craftbukkit.event.CraftEventFactory.callRaidTriggerEvent(raid, player)) {
- player.removeEffect(MobEffects.BAD_OMEN);
+ player.removeEffect(net.minecraft.world.effect.MobEffects.RAID_OMEN);
return null;
}
+ if (level.purpurConfig.raidCooldownSeconds != 0) playerCooldowns.put(player.getUUID(), level.purpurConfig.raidCooldownSeconds); // Purpur
- if (!this.raidMap.containsKey(raid.getId())) {
+ if (!raid.isStarted() && !this.raidMap.containsKey(raid.getId())) {
this.raidMap.put(raid.getId(), raid);
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
-index d514ec1e4cbdc579c3a61533998437903afdc8b6..eb5bd5cfd131042e366872bf599a315d83dc732b 100644
+index 4d7454e5a64fc18e63793a221daa94617f17c666..e7a1ce585c9e552e6f9ce9acd26fdfe5c43e0b5d 100644
--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
+++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
-@@ -105,12 +105,14 @@ public abstract class AbstractMinecart extends VehicleEntity {
+@@ -102,12 +102,14 @@ public abstract class AbstractMinecart extends VehicleEntity {
private double flyingY = 0.95;
private double flyingZ = 0.95;
public double maxSpeed = 0.4D;
@@ -13193,7 +12848,7 @@ index d514ec1e4cbdc579c3a61533998437903afdc8b6..eb5bd5cfd131042e366872bf599a315d
}
protected AbstractMinecart(EntityType> type, Level world, double x, double y, double z) {
-@@ -294,6 +296,12 @@ public abstract class AbstractMinecart extends VehicleEntity {
+@@ -296,6 +298,12 @@ public abstract class AbstractMinecart extends VehicleEntity {
@Override
public void tick() {
@@ -13206,7 +12861,7 @@ index d514ec1e4cbdc579c3a61533998437903afdc8b6..eb5bd5cfd131042e366872bf599a315d
// CraftBukkit start
double prevX = this.getX();
double prevY = this.getY();
-@@ -451,16 +459,62 @@ public abstract class AbstractMinecart extends VehicleEntity {
+@@ -448,16 +456,62 @@ public abstract class AbstractMinecart extends VehicleEntity {
public void activateMinecart(int x, int y, int z, boolean powered) {}
@@ -13269,7 +12924,7 @@ index d514ec1e4cbdc579c3a61533998437903afdc8b6..eb5bd5cfd131042e366872bf599a315d
this.move(MoverType.SELF, this.getDeltaMovement());
if (!this.onGround()) {
-@@ -622,7 +676,7 @@ public abstract class AbstractMinecart extends VehicleEntity {
+@@ -619,7 +673,7 @@ public abstract class AbstractMinecart extends VehicleEntity {
if (d18 > 0.01D) {
double d20 = 0.06D;
@@ -13279,10 +12934,10 @@ index d514ec1e4cbdc579c3a61533998437903afdc8b6..eb5bd5cfd131042e366872bf599a315d
Vec3 vec3d5 = this.getDeltaMovement();
double d21 = vec3d5.x;
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
-index db6aa75d642f4a7258f197933671907faf79c8f2..81e0930acccd014e977b88d22e10346627f0edb0 100644
+index b068cff9b5aa457d65b679529956e8210296d799..105e2b7d7cd7c64a9164e4114476e44f29433f49 100644
--- a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
+++ b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
-@@ -521,6 +521,7 @@ public class Boat extends VehicleEntity implements VariantHolder {
+@@ -514,6 +514,7 @@ public class Boat extends VehicleEntity implements VariantHolder {
if (f > 0.0F) {
this.landFriction = f;
@@ -13290,15 +12945,15 @@ index db6aa75d642f4a7258f197933671907faf79c8f2..81e0930acccd014e977b88d22e103466
return Boat.Status.ON_LAND;
} else {
return Boat.Status.IN_AIR;
-@@ -967,7 +968,13 @@ public class Boat extends VehicleEntity implements VariantHolder {
+@@ -962,7 +963,13 @@ public class Boat extends VehicleEntity implements VariantHolder {
@Override
public ItemStack getPickResult() {
- return new ItemStack(this.getDropItem());
+ // Purpur start
+ final ItemStack boat = new ItemStack(this.getDropItem());
-+ if (this.level().purpurConfig.persistentDroppableEntityDisplayNames && this.hasCustomName()) {
-+ boat.setHoverName(this.getCustomName());
++ if (!this.level().purpurConfig.persistentDroppableEntityDisplayNames) {
++ boat.set(net.minecraft.core.component.DataComponents.CUSTOM_NAME, null);
+ }
+ return boat;
+ // Purpur end
@@ -13306,21 +12961,20 @@ index db6aa75d642f4a7258f197933671907faf79c8f2..81e0930acccd014e977b88d22e103466
public static enum Type implements StringRepresentable {
diff --git a/src/main/java/net/minecraft/world/food/FoodData.java b/src/main/java/net/minecraft/world/food/FoodData.java
-index c3448707fd8a632b457cc97b35d08a9c6933d5ee..e8079d126e6c0cf0b15c01afb6498922ee05964c 100644
+index b89860d451d92ddda64b7e4144542b7fc5fd86f0..dd72d6a79139ff33f26a32b71283ce0b8d084ecc 100644
--- a/src/main/java/net/minecraft/world/food/FoodData.java
+++ b/src/main/java/net/minecraft/world/food/FoodData.java
-@@ -33,8 +33,10 @@ public class FoodData {
- // CraftBukkit end
+@@ -38,7 +38,9 @@ public class FoodData {
+ }
public void eat(int food, float saturationModifier) {
+ int oldValue = this.foodLevel; // Purpur
- this.foodLevel = Math.min(food + this.foodLevel, 20);
- this.saturationLevel = Math.min(this.saturationLevel + (float) food * saturationModifier * 2.0F, (float) this.foodLevel);
+ this.add(food, FoodConstants.saturationByModifier(food, saturationModifier));
+ if (this.entityhuman.level().purpurConfig.playerBurpWhenFull && this.foodLevel == 20 && oldValue < 20) this.entityhuman.burpDelay = this.entityhuman.level().purpurConfig.playerBurpDelay; // Purpur
}
- public void eat(Item item, ItemStack stack) {
-@@ -100,7 +102,7 @@ public class FoodData {
+ public void eat(ItemStack stack) {
+@@ -105,7 +107,7 @@ public class FoodData {
++this.tickTimer;
if (this.tickTimer >= this.starvationRate) { // CraftBukkit - add regen rate manipulation
if (player.getHealth() > 10.0F || enumdifficulty == Difficulty.HARD || player.getHealth() > 1.0F && enumdifficulty == Difficulty.NORMAL) {
@@ -13329,54 +12983,8 @@ index c3448707fd8a632b457cc97b35d08a9c6933d5ee..e8079d126e6c0cf0b15c01afb6498922
}
this.tickTimer = 0;
-diff --git a/src/main/java/net/minecraft/world/food/FoodProperties.java b/src/main/java/net/minecraft/world/food/FoodProperties.java
-index 9967ba762567631f2bdb1e4f8fe16a13ea927b46..6c945ae8fe8b1517e312c688f829fab41f12d9f4 100644
---- a/src/main/java/net/minecraft/world/food/FoodProperties.java
-+++ b/src/main/java/net/minecraft/world/food/FoodProperties.java
-@@ -2,15 +2,22 @@ package net.minecraft.world.food;
-
- import com.google.common.collect.Lists;
- import com.mojang.datafixers.util.Pair;
-+
-+import java.util.ArrayList;
- import java.util.List;
- import net.minecraft.world.effect.MobEffectInstance;
-
- public class FoodProperties {
-- private final int nutrition;
-- private final float saturationModifier;
-- private final boolean isMeat;
-- private final boolean canAlwaysEat;
-- private final boolean fastFood;
-+ // Purpur start
-+ private int nutrition; public void setNutrition(int nutrition) { this.nutrition = nutrition; }
-+ private float saturationModifier; public void setSaturationModifier(float saturation) { this.saturationModifier = saturation; }
-+ private boolean isMeat; public void setIsMeat(boolean isMeat) { this.isMeat = isMeat; }
-+ private boolean canAlwaysEat; public void setCanAlwaysEat(boolean canAlwaysEat) { this.canAlwaysEat = canAlwaysEat; }
-+ private boolean fastFood; public void setFastFood(boolean isFastFood) { this.fastFood = isFastFood; }
-+ public FoodProperties copy() {
-+ return new FoodProperties(this.nutrition, this.saturationModifier, this.isMeat, this.canAlwaysEat, this.fastFood, new ArrayList<>(this.effects));
-+ }
-+ // Purpur end
- private final List> effects;
-
- FoodProperties(int hunger, float saturationModifier, boolean meat, boolean alwaysEdible, boolean snack, List> statusEffects) {
-diff --git a/src/main/java/net/minecraft/world/food/Foods.java b/src/main/java/net/minecraft/world/food/Foods.java
-index 4569cf30b33167a415256a8542820557ad38f89e..e21efb231ddbd9438139084d5ec5e53ae584e5c8 100644
---- a/src/main/java/net/minecraft/world/food/Foods.java
-+++ b/src/main/java/net/minecraft/world/food/Foods.java
-@@ -4,6 +4,9 @@ import net.minecraft.world.effect.MobEffectInstance;
- import net.minecraft.world.effect.MobEffects;
-
- public class Foods {
-+ public static final java.util.Map ALL_PROPERTIES = new java.util.HashMap<>(); // Purpur
-+ public static final java.util.Map DEFAULT_PROPERTIES = new java.util.HashMap<>(); // Purpur
-+
- public static final FoodProperties APPLE = new FoodProperties.Builder().nutrition(4).saturationMod(0.3F).build();
- public static final FoodProperties BAKED_POTATO = new FoodProperties.Builder().nutrition(5).saturationMod(0.6F).build();
- public static final FoodProperties BEEF = new FoodProperties.Builder().nutrition(3).saturationMod(0.3F).meat().build();
diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
-index 48f634a7521d31c1e9dfd3cfc83139d428dbd37a..fa185a8145843edf44fc0aeedb6c36b2b13263ae 100644
+index 32910f677b0522ac8ec513fa0d00b714b52cfae4..f85eef14b91a0ada1f6f4b13ab3966f051ff92d3 100644
--- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
+++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
@@ -76,6 +76,7 @@ public abstract class AbstractContainerMenu {
@@ -13407,10 +13015,10 @@ index 1af7e1548f0648890a1ef2fc0ff4e4c3a56c947c..decea1697c075e7549ccc7501c8e5935
} else if (this.isFuel(itemstack1)) {
if (!this.moveItemStackTo(itemstack1, 1, 2, false)) {
diff --git a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
-index cab3e0ba471c93764b5949ad68a0f2cce4d00099..2913d69fcff4b6df68586146b7323cea33eba74b 100644
+index 2bd91b48eaa06f85a5b9b1ae052c70e966ae8e4c..2747f04e657154362af55eef1dd50455e02af371 100644
--- a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
+++ b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
-@@ -23,6 +23,13 @@ import org.slf4j.Logger;
+@@ -25,6 +25,13 @@ import org.slf4j.Logger;
import org.bukkit.craftbukkit.inventory.CraftInventoryView;
// CraftBukkit end
@@ -13424,7 +13032,7 @@ index cab3e0ba471c93764b5949ad68a0f2cce4d00099..2913d69fcff4b6df68586146b7323cea
public class AnvilMenu extends ItemCombinerMenu {
public static final int INPUT_SLOT = 0;
-@@ -51,6 +58,8 @@ public class AnvilMenu extends ItemCombinerMenu {
+@@ -53,6 +60,8 @@ public class AnvilMenu extends ItemCombinerMenu {
public int maximumRepairCost = 40;
private CraftInventoryView bukkitEntity;
// CraftBukkit end
@@ -13433,12 +13041,12 @@ index cab3e0ba471c93764b5949ad68a0f2cce4d00099..2913d69fcff4b6df68586146b7323cea
public AnvilMenu(int syncId, Inventory inventory) {
this(syncId, inventory, ContainerLevelAccess.NULL);
-@@ -78,12 +87,15 @@ public class AnvilMenu extends ItemCombinerMenu {
+@@ -80,12 +89,15 @@ public class AnvilMenu extends ItemCombinerMenu {
@Override
protected boolean mayPickup(Player player, boolean present) {
-- return (player.getAbilities().instabuild || player.experienceLevel >= this.cost.get()) && this.cost.get() > AnvilMenu.DEFAULT_DENIED_COST && present; // CraftBukkit - allow cost 0 like a free item
-+ return (player.getAbilities().instabuild || player.experienceLevel >= this.cost.get()) && (bypassCost || this.cost.get() > AnvilMenu.DEFAULT_DENIED_COST) && present; // CraftBukkit - allow cost 0 like a free item // Purpur
+- return (player.hasInfiniteMaterials() || player.experienceLevel >= this.cost.get()) && this.cost.get() > AnvilMenu.DEFAULT_DENIED_COST && present; // CraftBukkit - allow cost 0 like a free item
++ return (player.hasInfiniteMaterials() || player.experienceLevel >= this.cost.get()) && (bypassCost || this.cost.get() > AnvilMenu.DEFAULT_DENIED_COST) && present; // CraftBukkit - allow cost 0 like a free item // Purpur
}
@Override
@@ -13450,7 +13058,7 @@ index cab3e0ba471c93764b5949ad68a0f2cce4d00099..2913d69fcff4b6df68586146b7323cea
player.giveExperienceLevels(-this.cost.get());
}
-@@ -134,6 +146,12 @@ public class AnvilMenu extends ItemCombinerMenu {
+@@ -136,6 +148,12 @@ public class AnvilMenu extends ItemCombinerMenu {
@Override
public void createResult() {
@@ -13463,44 +13071,53 @@ index cab3e0ba471c93764b5949ad68a0f2cce4d00099..2913d69fcff4b6df68586146b7323cea
ItemStack itemstack = this.inputSlots.getItem(0);
this.cost.set(1);
+@@ -143,7 +161,7 @@ public class AnvilMenu extends ItemCombinerMenu {
+ long j = 0L;
+ byte b0 = 0;
+
+- if (!itemstack.isEmpty() && EnchantmentHelper.canStoreEnchantments(itemstack)) {
++ if (!itemstack.isEmpty() && canDoUnsafeEnchants || EnchantmentHelper.canStoreEnchantments(itemstack)) { // Purpur
+ ItemStack itemstack1 = itemstack.copy();
+ ItemStack itemstack2 = this.inputSlots.getItem(1);
+ ItemEnchantments.Mutable itemenchantments_a = new ItemEnchantments.Mutable(EnchantmentHelper.getEnchantmentsForCrafting(itemstack1));
@@ -210,7 +228,8 @@ public class AnvilMenu extends ItemCombinerMenu {
- int i2 = (Integer) map1.get(enchantment);
+ int i2 = entry.getIntValue();
- i2 = l1 == i2 ? i2 + 1 : Math.max(i2, l1);
-- boolean flag3 = enchantment.canEnchant(itemstack);
-+ boolean flag3 = canDoUnsafeEnchants || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchants && org.purpurmc.purpur.PurpurConfig.allowInapplicableEnchants) || enchantment.canEnchant(itemstack); // Purpur
-+ boolean flag4 = true; // Purpur
+ i2 = l1 == i2 ? i2 + 1 : Math.max(i2, l1);
+- boolean flag3 = enchantment.canEnchant(itemstack);
++ boolean flag3 = canDoUnsafeEnchants || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchants && org.purpurmc.purpur.PurpurConfig.allowInapplicableEnchants) || enchantment.canEnchant(itemstack); // Purpur
++ boolean flag4 = true; // Purpur
- if (this.player.getAbilities().instabuild || itemstack.is(Items.ENCHANTED_BOOK)) {
- flag3 = true;
+ if (this.player.getAbilities().instabuild || itemstack.is(Items.ENCHANTED_BOOK)) {
+ flag3 = true;
@@ -222,16 +241,20 @@ public class AnvilMenu extends ItemCombinerMenu {
- Enchantment enchantment1 = (Enchantment) iterator1.next();
+ Holder holder1 = (Holder) iterator1.next();
- if (enchantment1 != enchantment && !enchantment.isCompatibleWith(enchantment1)) {
-- flag3 = false;
-+ flag4 = canDoUnsafeEnchants || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchants && org.purpurmc.purpur.PurpurConfig.allowIncompatibleEnchants); // Purpur flag3 -> flag4
+ if (!holder1.equals(holder) && !enchantment.isCompatibleWith((Enchantment) holder1.value())) {
+- flag3 = false;
++ flag4 = canDoUnsafeEnchants || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchants && org.purpurmc.purpur.PurpurConfig.allowIncompatibleEnchants); // Purpur flag3 -> flag4
+ if (!flag4 && org.purpurmc.purpur.PurpurConfig.replaceIncompatibleEnchants) {
+ iterator1.remove();
+ flag4 = true;
+ }
- ++i;
- }
+ ++i;
+ }
+ }
+
+- if (!flag3) {
++ if (!flag3 || !flag4) { // Purpur
+ flag2 = true;
+ } else {
+ flag1 = true;
+- if (i2 > enchantment.getMaxLevel()) {
++ if ((!org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchants || !org.purpurmc.purpur.PurpurConfig.allowHigherEnchantsLevels) && i2 > enchantment.getMaxLevel()) { // Purpur
+ i2 = enchantment.getMaxLevel();
}
-- if (!flag3) {
-+ if (!flag3 || !flag4) { // Purpur
- flag2 = true;
- } else {
- flag1 = true;
-- if (i2 > enchantment.getMaxLevel()) {
-+ if ((!org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchants || !org.purpurmc.purpur.PurpurConfig.allowHigherEnchantsLevels) && i2 > enchantment.getMaxLevel()) { // Purpur
- i2 = enchantment.getMaxLevel();
- }
-
-@@ -276,6 +299,54 @@ public class AnvilMenu extends ItemCombinerMenu {
+@@ -261,6 +284,54 @@ public class AnvilMenu extends ItemCombinerMenu {
if (!this.itemName.equals(itemstack.getHoverName().getString())) {
- b1 = 1;
- i += b1;
+ b0 = 1;
+ i += b0;
+ // Purpur start
+ if (this.player != null) {
+ org.bukkit.craftbukkit.entity.CraftHumanEntity player = this.player.getBukkitEntity();
@@ -13545,20 +13162,19 @@ index cab3e0ba471c93764b5949ad68a0f2cce4d00099..2913d69fcff4b6df68586146b7323cea
+ if (removeItalics) {
+ component = component.decoration(net.kyori.adventure.text.format.TextDecoration.ITALIC, false);
+ }
-+ itemstack1.setHoverName(io.papermc.paper.adventure.PaperAdventure.asVanilla(component));
++ itemstack1.set(DataComponents.CUSTOM_NAME, io.papermc.paper.adventure.PaperAdventure.asVanilla(component));
+ }
+ else
+ // Purpur end
- itemstack1.setHoverName(Component.literal(this.itemName));
+ itemstack1.set(DataComponents.CUSTOM_NAME, Component.literal(this.itemName));
}
- } else if (itemstack.hasCustomHoverName()) {
-@@ -293,6 +364,13 @@ public class AnvilMenu extends ItemCombinerMenu {
+ } else if (itemstack.has(DataComponents.CUSTOM_NAME)) {
+@@ -280,6 +351,12 @@ public class AnvilMenu extends ItemCombinerMenu {
this.cost.set(this.maximumRepairCost - 1); // CraftBukkit
}
+ // Purpur start
+ if (bypassCost && cost.get() >= maximumRepairCost) {
-+ itemstack.addTagElement("Purpur.realCost", IntTag.valueOf(cost.get()));
+ cost.set(maximumRepairCost - 1);
+ }
+ // Purpur end
@@ -13566,7 +13182,7 @@ index cab3e0ba471c93764b5949ad68a0f2cce4d00099..2913d69fcff4b6df68586146b7323cea
if (this.cost.get() >= this.maximumRepairCost && !this.player.getAbilities().instabuild) { // CraftBukkit
itemstack1 = ItemStack.EMPTY;
}
-@@ -315,11 +393,17 @@ public class AnvilMenu extends ItemCombinerMenu {
+@@ -301,6 +378,12 @@ public class AnvilMenu extends ItemCombinerMenu {
org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareAnvilEvent(this.getBukkitView(), itemstack1); // CraftBukkit
this.sendAllDataToRemote(); // CraftBukkit - SPIGOT-6686: Always send completed inventory to stay in sync with client
this.broadcastChanges();
@@ -13576,12 +13192,15 @@ index cab3e0ba471c93764b5949ad68a0f2cce4d00099..2913d69fcff4b6df68586146b7323cea
+ ((ServerPlayer) player).connection.send(new ClientboundContainerSetDataPacket(containerId, 0, cost.get()));
+ }
+ // Purpur end
- }
+ } else {
+ org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareAnvilEvent(this.getBukkitView(), ItemStack.EMPTY); // CraftBukkit
+ this.cost.set(AnvilMenu.DEFAULT_DENIED_COST); // CraftBukkit - use a variable for set a cost for denied item
+@@ -308,7 +391,7 @@ public class AnvilMenu extends ItemCombinerMenu {
}
public static int calculateIncreasedRepairCost(int cost) {
-- return cost * 2 + 1;
-+ return org.purpurmc.purpur.PurpurConfig.anvilCumulativeCost ? cost * 2 + 1 : 0;
+- return (int) Math.min((long) cost * 2L + 1L, 2147483647L);
++ return org.purpurmc.purpur.PurpurConfig.anvilCumulativeCost ? (int) Math.min((long) cost * 2L + 1L, 2147483647L) : 0;
}
public boolean setItemName(String newItemName) {
@@ -13621,23 +13240,23 @@ index 0dbfd23bbfc6ad203f048142f8c90ef741849fe1..9a80427d2bb470b6b1638e59aba57216
return new ChestMenu(MenuType.GENERIC_9x6, syncId, playerInventory, inventory, 6);
}
diff --git a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java
-index e6935b6632c7a7e07f4da459c95f564356242f98..1a686780e5aadcbdcfceb770ce8e283b38115209 100644
+index 5b3e33807e0e13480e3359c0cf067719e5749237..c3a644b0f8c7c5622acc9e1a496f95d432718806 100644
--- a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java
+++ b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java
-@@ -40,6 +40,12 @@ import org.bukkit.event.enchantment.PrepareItemEnchantEvent;
+@@ -38,6 +38,12 @@ import org.bukkit.event.enchantment.PrepareItemEnchantEvent;
import org.bukkit.entity.Player;
// CraftBukkit end
+// Purpur start
+import net.minecraft.world.level.block.entity.BlockEntity;
-+import net.minecraft.world.level.block.entity.EnchantmentTableBlockEntity;
++import net.minecraft.world.level.block.entity.EnchantingTableBlockEntity;
+import org.bukkit.craftbukkit.entity.CraftHumanEntity;
+// Purpur end
+
public class EnchantmentMenu extends AbstractContainerMenu {
static final ResourceLocation EMPTY_SLOT_LAPIS_LAZULI = new ResourceLocation("item/empty_slot_lapis_lazuli");
-@@ -74,6 +80,22 @@ public class EnchantmentMenu extends AbstractContainerMenu {
+@@ -72,6 +78,22 @@ public class EnchantmentMenu extends AbstractContainerMenu {
return context.getLocation();
}
// CraftBukkit end
@@ -13650,7 +13269,7 @@ index e6935b6632c7a7e07f4da459c95f564356242f98..1a686780e5aadcbdcfceb770ce8e283b
+ if (who.getHandle().level().purpurConfig.enchantmentTableLapisPersists) {
+ access.execute((level, pos) -> {
+ BlockEntity blockEntity = level.getBlockEntity(pos);
-+ if (blockEntity instanceof EnchantmentTableBlockEntity enchantmentTable) {
++ if (blockEntity instanceof EnchantingTableBlockEntity enchantmentTable) {
+ enchantmentTable.setLapis(this.getItem(1).getCount());
+ }
+ });
@@ -13660,7 +13279,7 @@ index e6935b6632c7a7e07f4da459c95f564356242f98..1a686780e5aadcbdcfceb770ce8e283b
};
this.random = RandomSource.create();
this.enchantmentSeed = DataSlot.standalone();
-@@ -99,6 +121,17 @@ public class EnchantmentMenu extends AbstractContainerMenu {
+@@ -97,6 +119,17 @@ public class EnchantmentMenu extends AbstractContainerMenu {
}
});
@@ -13668,7 +13287,7 @@ index e6935b6632c7a7e07f4da459c95f564356242f98..1a686780e5aadcbdcfceb770ce8e283b
+ access.execute((level, pos) -> {
+ if (level.purpurConfig.enchantmentTableLapisPersists) {
+ BlockEntity blockEntity = level.getBlockEntity(pos);
-+ if (blockEntity instanceof EnchantmentTableBlockEntity enchantmentTable) {
++ if (blockEntity instanceof EnchantingTableBlockEntity enchantmentTable) {
+ this.getSlot(1).set(new ItemStack(Items.LAPIS_LAZULI, enchantmentTable.getLapis()));
+ }
+ }
@@ -13678,7 +13297,7 @@ index e6935b6632c7a7e07f4da459c95f564356242f98..1a686780e5aadcbdcfceb770ce8e283b
int j;
for (j = 0; j < 3; ++j) {
-@@ -351,6 +384,7 @@ public class EnchantmentMenu extends AbstractContainerMenu {
+@@ -332,6 +365,7 @@ public class EnchantmentMenu extends AbstractContainerMenu {
public void removed(net.minecraft.world.entity.player.Player player) {
super.removed(player);
this.access.execute((world, blockposition) -> {
@@ -13687,7 +13306,7 @@ index e6935b6632c7a7e07f4da459c95f564356242f98..1a686780e5aadcbdcfceb770ce8e283b
});
}
diff --git a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java
-index 23462de504932bd351b8dfacde514fe361343912..af99ce32872e079beb6ac1caf3a8ac4c3cae4648 100644
+index db9444dda248260372d96ce239a590e88a4c1142..dda890500e360274ce194929560f01b544e4cb4f 100644
--- a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java
+++ b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java
@@ -95,9 +95,11 @@ public class GrindstoneMenu extends AbstractContainerMenu {
@@ -13704,54 +13323,121 @@ index 23462de504932bd351b8dfacde514fe361343912..af99ce32872e079beb6ac1caf3a8ac4c
world.levelEvent(1042, blockposition, 0);
@@ -130,7 +132,7 @@ public class GrindstoneMenu extends AbstractContainerMenu {
- Enchantment enchantment = (Enchantment) entry.getKey();
- Integer integer = (Integer) entry.getValue();
+ Enchantment enchantment = (Enchantment) ((Holder) entry.getKey()).value();
+ int k = entry.getIntValue();
- if (!enchantment.isCurse()) {
+ if (!org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains(enchantment)) { // Purpur
- j += enchantment.getMinCost(integer);
+ j += enchantment.getMinCost(k);
}
}
-@@ -230,7 +232,7 @@ public class GrindstoneMenu extends AbstractContainerMenu {
- Entry entry = (Entry) iterator.next();
- Enchantment enchantment = (Enchantment) entry.getKey();
+@@ -229,7 +231,7 @@ public class GrindstoneMenu extends AbstractContainerMenu {
+ Entry> entry = (Entry) iterator.next();
+ Enchantment enchantment = (Enchantment) ((Holder) entry.getKey()).value();
-- if (!enchantment.isCurse() || EnchantmentHelper.getItemEnchantmentLevel(enchantment, itemstack2) == 0) {
-+ if (!org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains(enchantment) || EnchantmentHelper.getItemEnchantmentLevel(enchantment, itemstack2) == 0) { // Purpur
- itemstack2.enchant(enchantment, (Integer) entry.getValue());
+- if (!enchantment.isCurse() || itemenchantments_a.getLevel(enchantment) == 0) {
++ if (!org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains(enchantment) || itemenchantments_a.getLevel(enchantment) == 0) { // Purpur
+ itemenchantments_a.upgrade(enchantment, entry.getIntValue());
+ }
}
- }
-@@ -250,7 +252,7 @@ public class GrindstoneMenu extends AbstractContainerMenu {
- }
-
- Map map = (Map) EnchantmentHelper.getEnchantments(item).entrySet().stream().filter((entry) -> {
-- return ((Enchantment) entry.getKey()).isCurse();
-+ return org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains((Enchantment) entry.getKey()); // Purpur
- }).collect(Collectors.toMap(Entry::getKey, Entry::getValue));
-
- EnchantmentHelper.setEnchantments(map, itemstack1);
-@@ -266,6 +268,20 @@ public class GrindstoneMenu extends AbstractContainerMenu {
- itemstack1.setRepairCost(AnvilMenu.calculateIncreasedRepairCost(itemstack1.getBaseRepairCost()));
- }
-
-+ // Purpur start
-+ if (org.purpurmc.purpur.PurpurConfig.grindstoneRemoveAttributes && itemstack1.getTag() != null) {
-+ for (String key : itemstack1.getTag().getAllKeys()) {
-+ if (!key.equals("display")) {
-+ itemstack1.getTag().remove(key);
-+ }
-+ }
-+ }
-+
-+ if (org.purpurmc.purpur.PurpurConfig.grindstoneRemoveDisplay && itemstack1.getTag() != null) {
-+ itemstack1.getTag().remove("display");
-+ }
-+ // Purpur end
-+
- return itemstack1;
+@@ -237,10 +239,71 @@ public class GrindstoneMenu extends AbstractContainerMenu {
+ });
}
-@@ -327,7 +343,9 @@ public class GrindstoneMenu extends AbstractContainerMenu {
++ // Purpur start
++ private java.util.List> GRINDSTONE_REMOVE_ATTRIBUTES_REMOVAL_LIST = java.util.List.of(
++ // DataComponents.MAX_STACK_SIZE,
++ // DataComponents.DAMAGE,
++ // DataComponents.BLOCK_STATE,
++ DataComponents.CUSTOM_DATA,
++ // DataComponents.MAX_DAMAGE,
++ // DataComponents.UNBREAKABLE,
++ // DataComponents.CUSTOM_NAME,
++ // DataComponents.ITEM_NAME,
++ // DataComponents.LORE,
++ // DataComponents.RARITY,
++ // DataComponents.ENCHANTMENTS,
++ // DataComponents.CAN_PLACE_ON,
++ // DataComponents.CAN_BREAK,
++ DataComponents.ATTRIBUTE_MODIFIERS,
++ DataComponents.CUSTOM_MODEL_DATA,
++ // DataComponents.HIDE_ADDITIONAL_TOOLTIP,
++ // DataComponents.HIDE_TOOLTIP,
++ // DataComponents.REPAIR_COST,
++ // DataComponents.CREATIVE_SLOT_LOCK,
++ // DataComponents.ENCHANTMENT_GLINT_OVERRIDE,
++ // DataComponents.INTANGIBLE_PROJECTILE,
++ // DataComponents.FOOD,
++ // DataComponents.FIRE_RESISTANT,
++ // DataComponents.TOOL,
++ // DataComponents.STORED_ENCHANTMENTS,
++ DataComponents.DYED_COLOR,
++ // DataComponents.MAP_COLOR,
++ // DataComponents.MAP_ID,
++ // DataComponents.MAP_DECORATIONS,
++ // DataComponents.MAP_POST_PROCESSING,
++ // DataComponents.CHARGED_PROJECTILES,
++ // DataComponents.BUNDLE_CONTENTS,
++ // DataComponents.POTION_CONTENTS,
++ DataComponents.SUSPICIOUS_STEW_EFFECTS
++ // DataComponents.WRITABLE_BOOK_CONTENT,
++ // DataComponents.WRITTEN_BOOK_CONTENT,
++ // DataComponents.TRIM,
++ // DataComponents.DEBUG_STICK_STATE,
++ // DataComponents.ENTITY_DATA,
++ // DataComponents.BUCKET_ENTITY_DATA,
++ // DataComponents.BLOCK_ENTITY_DATA,
++ // DataComponents.INSTRUMENT,
++ // DataComponents.OMINOUS_BOTTLE_AMPLIFIER,
++ // DataComponents.RECIPES,
++ // DataComponents.LODESTONE_TRACKER,
++ // DataComponents.FIREWORK_EXPLOSION,
++ // DataComponents.FIREWORKS,
++ // DataComponents.PROFILE,
++ // DataComponents.NOTE_BLOCK_SOUND,
++ // DataComponents.BANNER_PATTERNS,
++ // DataComponents.BASE_COLOR,
++ // DataComponents.POT_DECORATIONS,
++ // DataComponents.CONTAINER,
++ // DataComponents.BEES,
++ // DataComponents.LOCK,
++ // DataComponents.CONTAINER_LOOT,
++ );
++ // Purpur end
++
+ private ItemStack removeNonCursesFrom(ItemStack item) {
+ ItemEnchantments itemenchantments = EnchantmentHelper.updateEnchantments(item, (itemenchantments_a) -> {
+ itemenchantments_a.removeIf((holder) -> {
+- return !((Enchantment) holder.value()).isCurse();
++ return !org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains(holder.value());
+ });
+ });
+
+@@ -255,6 +318,23 @@ public class GrindstoneMenu extends AbstractContainerMenu {
+ }
+
+ item.set(DataComponents.REPAIR_COST, i);
++
++ // Purpur start
++ net.minecraft.core.component.DataComponentPatch.Builder builder = net.minecraft.core.component.DataComponentPatch.builder();
++ if (org.purpurmc.purpur.PurpurConfig.grindstoneRemoveAttributes) {
++ item.getComponents().forEach(typedDataComponent -> {
++ if (GRINDSTONE_REMOVE_ATTRIBUTES_REMOVAL_LIST.contains(typedDataComponent.type())) {
++ builder.remove(typedDataComponent.type());
++ }
++ });
++ }
++ if (org.purpurmc.purpur.PurpurConfig.grindstoneRemoveDisplay) {
++ builder.remove(DataComponents.CUSTOM_NAME);
++ builder.remove(DataComponents.LORE);
++ }
++ item.applyComponents(builder.build());
++ // Purpur end
++
+ return item;
+ }
+
+@@ -316,7 +396,9 @@ public class GrindstoneMenu extends AbstractContainerMenu {
return ItemStack.EMPTY;
}
@@ -13762,10 +13448,10 @@ index 23462de504932bd351b8dfacde514fe361343912..af99ce32872e079beb6ac1caf3a8ac4c
return itemstack;
diff --git a/src/main/java/net/minecraft/world/inventory/InventoryMenu.java b/src/main/java/net/minecraft/world/inventory/InventoryMenu.java
-index 9af1da3858d6cf79b8bfaf99dde1370ccc50d023..1acb41fab25bdbc4109913b111dbe3b0e106af3f 100644
+index 9992599dbe4f4a430e822a44b03c00505abfbfaf..3fea9339420aa38b303ccf6c154aec246e617b5b 100644
--- a/src/main/java/net/minecraft/world/inventory/InventoryMenu.java
+++ b/src/main/java/net/minecraft/world/inventory/InventoryMenu.java
-@@ -95,7 +95,7 @@ public class InventoryMenu extends RecipeBookMenu {
+@@ -97,7 +97,7 @@ public class InventoryMenu extends RecipeBookMenu {
public boolean mayPickup(Player playerEntity) {
ItemStack itemstack = this.getItem();
@@ -13775,7 +13461,7 @@ index 9af1da3858d6cf79b8bfaf99dde1370ccc50d023..1acb41fab25bdbc4109913b111dbe3b0
@Override
diff --git a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java
-index 62e1b7096fa659778b737b3d520389e73138dc5d..3756de835ea87e3a4fb87cbf77365ffd87957ea9 100644
+index 7de5e47f9a54263734eeef855a2dc07ef64d30ea..7215af6cc91f48b040c23c54536d4aac8d293497 100644
--- a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java
+++ b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java
@@ -178,7 +178,9 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu {
@@ -13789,10 +13475,10 @@ index 62e1b7096fa659778b737b3d520389e73138dc5d..3756de835ea87e3a4fb87cbf77365ffd
return itemstack;
diff --git a/src/main/java/net/minecraft/world/inventory/PlayerEnderChestContainer.java b/src/main/java/net/minecraft/world/inventory/PlayerEnderChestContainer.java
-index 4703f23316f82a1a942907b46d2d6dcb7d70ec37..162798f57a05b78121fa6c4fadf5adee80fbe221 100644
+index a15d5ff872dbd77f3c3145e0328f3d02e431ff8c..1dcf36d502990d32fc4cd3ea69c3ea334baed69a 100644
--- a/src/main/java/net/minecraft/world/inventory/PlayerEnderChestContainer.java
+++ b/src/main/java/net/minecraft/world/inventory/PlayerEnderChestContainer.java
-@@ -30,11 +30,18 @@ public class PlayerEnderChestContainer extends SimpleContainer {
+@@ -31,11 +31,18 @@ public class PlayerEnderChestContainer extends SimpleContainer {
}
public PlayerEnderChestContainer(Player owner) {
@@ -13813,10 +13499,10 @@ index 4703f23316f82a1a942907b46d2d6dcb7d70ec37..162798f57a05b78121fa6c4fadf5adee
this.activeChest = blockEntity;
}
diff --git a/src/main/java/net/minecraft/world/item/ArmorItem.java b/src/main/java/net/minecraft/world/item/ArmorItem.java
-index 6b81be03f87967124b046708557e05d519aa79e4..b47cc957f9e4936b15b80a6f685ddddb5b289298 100644
+index 786e4a8700cb84b16dd9b8892a0d1d5803924d81..b108ca4c7900ccf6a14ebea01c21c103459054f8 100644
--- a/src/main/java/net/minecraft/world/item/ArmorItem.java
+++ b/src/main/java/net/minecraft/world/item/ArmorItem.java
-@@ -67,7 +67,7 @@ public class ArmorItem extends Item implements Equipable {
+@@ -69,7 +69,7 @@ public class ArmorItem extends Item implements Equipable {
return false;
} else {
LivingEntity entityliving = (LivingEntity) list.get(0);
@@ -13826,7 +13512,7 @@ index 6b81be03f87967124b046708557e05d519aa79e4..b47cc957f9e4936b15b80a6f685ddddb
// CraftBukkit start
Level world = pointer.level();
diff --git a/src/main/java/net/minecraft/world/item/ArmorStandItem.java b/src/main/java/net/minecraft/world/item/ArmorStandItem.java
-index 7cffc64573008502bdd14ae4906fe51166b12fb3..1feafdbb48cf760cb6ebf95d5be2c32bdb1ad44f 100644
+index 1634a7d5ff06583408cf2f02f2b5f90931b1e02a..dfe8473a880cbddfc3ac6a9c97f1a500624eeb38 100644
--- a/src/main/java/net/minecraft/world/item/ArmorStandItem.java
+++ b/src/main/java/net/minecraft/world/item/ArmorStandItem.java
@@ -58,6 +58,14 @@ public class ArmorStandItem extends Item {
@@ -13834,21 +13520,21 @@ index 7cffc64573008502bdd14ae4906fe51166b12fb3..1feafdbb48cf760cb6ebf95d5be2c32b
}
// CraftBukkit end
+ // Purpur start
-+ if (world.purpurConfig.persistentDroppableEntityDisplayNames && itemstack.hasCustomHoverName()) {
-+ entityarmorstand.setCustomName(itemstack.getHoverName());
-+ if (world.purpurConfig.armorstandSetNameVisible) {
-+ entityarmorstand.setCustomNameVisible(true);
-+ }
++ if (!world.purpurConfig.persistentDroppableEntityDisplayNames) {
++ entityarmorstand.setCustomName(null);
++ }
++ if (world.purpurConfig.armorstandSetNameVisible) {
++ entityarmorstand.setCustomNameVisible(true);
+ }
+ // Purpur end
worldserver.addFreshEntityWithPassengers(entityarmorstand);
world.playSound((Player) null, entityarmorstand.getX(), entityarmorstand.getY(), entityarmorstand.getZ(), SoundEvents.ARMOR_STAND_PLACE, SoundSource.BLOCKS, 0.75F, 0.8F);
entityarmorstand.gameEvent(GameEvent.ENTITY_PLACE, context.getPlayer());
diff --git a/src/main/java/net/minecraft/world/item/AxeItem.java b/src/main/java/net/minecraft/world/item/AxeItem.java
-index 4f8689e8cbc8b6b9f44168126b95cc864a383c9e..b05bb4caf57965b82d841f52d6ea27985a5efc84 100644
+index 9fd2d97ff0e05578a3e6a0b86dc1974691845c5d..58343722399404530d497648155dbc254d6a865a 100644
--- a/src/main/java/net/minecraft/world/item/AxeItem.java
+++ b/src/main/java/net/minecraft/world/item/AxeItem.java
-@@ -55,13 +55,15 @@ public class AxeItem extends DiggerItem {
+@@ -56,13 +56,15 @@ public class AxeItem extends DiggerItem {
Level level = context.getLevel();
BlockPos blockPos = context.getClickedPos();
Player player = context.getPlayer();
@@ -13866,7 +13552,7 @@ index 4f8689e8cbc8b6b9f44168126b95cc864a383c9e..b05bb4caf57965b82d841f52d6ea2798
return InteractionResult.PASS;
}
// Paper end
-@@ -69,32 +71,41 @@ public class AxeItem extends DiggerItem {
+@@ -70,32 +72,41 @@ public class AxeItem extends DiggerItem {
CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger((ServerPlayer)player, blockPos, itemStack);
}
@@ -13882,7 +13568,7 @@ index 4f8689e8cbc8b6b9f44168126b95cc864a383c9e..b05bb4caf57965b82d841f52d6ea2798
+ level.gameEvent(GameEvent.BLOCK_CHANGE, blockPos, GameEvent.Context.of(player, state));
+ // Purpur end
if (player != null) {
- itemStack.hurtAndBreak(1, player, p -> p.broadcastBreakEvent(context.getHand()));
+ itemStack.hurtAndBreak(1, player, LivingEntity.getSlotForHand(context.getHand()));
}
- return InteractionResult.sidedSuccess(level.isClientSide);
@@ -13920,28 +13606,20 @@ index 4f8689e8cbc8b6b9f44168126b95cc864a383c9e..b05bb4caf57965b82d841f52d6ea2798
return optional3;
} else {
diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java
-index 8d2c0accadaf0c5d28e7db6e62a05f6c619cf02f..f33fcd7bca6f315c4b4cf1f5063f4772790ad20d 100644
+index 96fb69ec6db2e7c8c728435f0c537b076259b2fb..7572c289758001c7417a192f0e6e994ffa8408b3 100644
--- a/src/main/java/net/minecraft/world/item/BlockItem.java
+++ b/src/main/java/net/minecraft/world/item/BlockItem.java
-@@ -152,7 +152,24 @@ public class BlockItem extends Item {
+@@ -157,7 +157,16 @@ public class BlockItem extends Item {
}
protected boolean updateCustomBlockEntityTag(BlockPos pos, Level world, @Nullable Player player, ItemStack stack, BlockState state) {
- return BlockItem.updateCustomBlockEntityTag(world, player, pos, stack);
+ // Purpur start
+ boolean handled = updateCustomBlockEntityTag(world, player, pos, stack);
-+ if (world.purpurConfig.persistentTileEntityDisplayNames && stack.hasTag()) {
-+ CompoundTag display = stack.getTagElement("display");
-+ if (display != null) {
-+ BlockEntity blockEntity = world.getBlockEntity(pos);
-+ if (blockEntity != null) {
-+ if (display.contains("Name", 8)) {
-+ blockEntity.setPersistentDisplayName(display.getString("Name"));
-+ }
-+ if (display.contains("Lore", 9)) {
-+ blockEntity.setPersistentLore(display.getList("Lore", 8));
-+ }
-+ }
++ if (world.purpurConfig.persistentTileEntityLore) {
++ BlockEntity blockEntity1 = world.getBlockEntity(pos);
++ if (blockEntity1 != null) {
++ blockEntity1.setPersistentLore(stack.getOrDefault(DataComponents.LORE, net.minecraft.world.item.component.ItemLore.EMPTY));
+ }
+ }
+ return handled;
@@ -13949,79 +13627,68 @@ index 8d2c0accadaf0c5d28e7db6e62a05f6c619cf02f..f33fcd7bca6f315c4b4cf1f5063f4772
}
@Nullable
-@@ -287,7 +304,7 @@ public class BlockItem extends Item {
+@@ -219,6 +228,7 @@ public class BlockItem extends Item {
- @Override
- public void onDestroyed(ItemEntity entity) {
-- if (this.block instanceof ShulkerBoxBlock) {
-+ if (this.block instanceof ShulkerBoxBlock && entity.level().purpurConfig.shulkerBoxItemDropContentsWhenDestroyed) {
- ItemStack itemstack = entity.getItem();
- CompoundTag nbttagcompound = BlockItem.getBlockEntityData(itemstack);
+ if (tileentity != null) {
+ if (!world.isClientSide && tileentity.onlyOpCanSetNbt() && (player == null || !(player.canUseGameMasterBlocks() || (player.getAbilities().instabuild && player.getBukkitEntity().hasPermission("minecraft.nbt.place"))))) { // Spigot - add permission
++ if (!(!world.isClientSide && world.purpurConfig.silkTouchEnabled && tileentity instanceof net.minecraft.world.level.block.entity.SpawnerBlockEntity && player.getBukkitEntity().hasPermission("purpur.drop.spawners")))
+ return false;
+ }
+
+@@ -259,6 +269,7 @@ public class BlockItem extends Item {
+ ItemContainerContents itemcontainercontents = (ItemContainerContents) entity.getItem().set(DataComponents.CONTAINER, ItemContainerContents.EMPTY);
+
+ if (itemcontainercontents != null) {
++ if (entity.level().purpurConfig.shulkerBoxItemDropContentsWhenDestroyed && entity.getItem().is(Items.SHULKER_BOX)) // Purpur
+ ItemUtils.onContainerDestroyed(entity, itemcontainercontents.nonEmptyItemsCopy());
+ }
diff --git a/src/main/java/net/minecraft/world/item/BoatItem.java b/src/main/java/net/minecraft/world/item/BoatItem.java
-index 67a5a201d0b26ca7b27e6d0c3ffb9f8b6e16bce0..ec3d60b561de45349b705b7f14592be930af4b91 100644
+index eb74d45ad458b80cf8455297c3bc550186adaea3..ef01856c487e4ab982996e01537618233592ac32 100644
--- a/src/main/java/net/minecraft/world/item/BoatItem.java
+++ b/src/main/java/net/minecraft/world/item/BoatItem.java
-@@ -71,6 +71,11 @@ public class BoatItem extends Item {
+@@ -72,6 +72,11 @@ public class BoatItem extends Item {
entityboat.setVariant(this.type);
entityboat.setYRot(user.getYRot());
+ // Purpur start
-+ if (world.purpurConfig.persistentDroppableEntityDisplayNames && itemstack.hasCustomHoverName()) {
-+ entityboat.setCustomName(itemstack.getHoverName());
++ if (!world.purpurConfig.persistentDroppableEntityDisplayNames) {
++ entityboat.setCustomName(null);
+ }
+ // Purpur end
if (!world.noCollision(entityboat, entityboat.getBoundingBox())) {
return InteractionResultHolder.fail(itemstack);
} else {
diff --git a/src/main/java/net/minecraft/world/item/BowItem.java b/src/main/java/net/minecraft/world/item/BowItem.java
-index 08d597db1a5345a343777a01427655e6bf2c926b..d45a2f49c82d00801578c34e5f5277fc5e82be87 100644
+index 5ca843df5b4caa668953e5e36a9b20fabeb35046..ff39d3614f360918d74b54b817bc227f89d34c9c 100644
--- a/src/main/java/net/minecraft/world/item/BowItem.java
+++ b/src/main/java/net/minecraft/world/item/BowItem.java
-@@ -38,13 +38,13 @@ public class BowItem extends ProjectileWeaponItem implements Vanishable {
- float f = BowItem.getPowerForTime(j);
+@@ -29,9 +29,9 @@ public class BowItem extends ProjectileWeaponItem {
+ int i = this.getUseDuration(stack) - remainingUseTicks;
+ float f = getPowerForTime(i);
+ if (!((double)f < 0.1)) {
+- List list = draw(stack, itemStack, player);
++ List list = draw(stack, itemStack, player, !((itemStack.is(Items.ARROW) && world.purpurConfig.infinityWorksWithNormalArrows) || (itemStack.is(Items.TIPPED_ARROW) && world.purpurConfig.infinityWorksWithTippedArrows) || (itemStack.is(Items.SPECTRAL_ARROW) && world.purpurConfig.infinityWorksWithSpectralArrows)));
+ if (!world.isClientSide() && !list.isEmpty()) {
+- this.shoot(world, player, player.getUsedItemHand(), stack, list, f * 3.0F, 1.0F, f == 1.0F, null);
++ this.shoot(world, player, player.getUsedItemHand(), stack, list, f * 3.0F, (float) world.purpurConfig.bowProjectileOffset, f == 1.0F, null); // Purpur
+ }
- if ((double) f >= 0.1D) {
-- boolean flag1 = flag && itemstack1.is(Items.ARROW);
-+ boolean flag1 = flag && ((itemstack1.is(Items.ARROW) && world.purpurConfig.infinityWorksWithNormalArrows) || (itemstack1.is(Items.TIPPED_ARROW) && world.purpurConfig.infinityWorksWithTippedArrows) || (itemstack1.is(Items.SPECTRAL_ARROW) && world.purpurConfig.infinityWorksWithSpectralArrows)); // Purpur if (!world.isClientSide) {
-
- if (!world.isClientSide) {
- ArrowItem itemarrow = (ArrowItem) (itemstack1.getItem() instanceof ArrowItem ? itemstack1.getItem() : Items.ARROW);
- AbstractArrow entityarrow = itemarrow.createArrow(world, itemstack1, entityhuman);
-
-- entityarrow.shootFromRotation(entityhuman, entityhuman.getXRot(), entityhuman.getYRot(), 0.0F, f * 3.0F, 1.0F);
-+ entityarrow.shootFromRotation(entityhuman, entityhuman.getXRot(), entityhuman.getYRot(), 0.0F, f * 3.0F, (float) world.purpurConfig.bowProjectileOffset); // Purpur
- if (f == 1.0F) {
- entityarrow.setCritArrow(true);
- }
-@@ -64,6 +64,13 @@ public class BowItem extends ProjectileWeaponItem implements Vanishable {
- if (EnchantmentHelper.getItemEnchantmentLevel(Enchantments.FLAMING_ARROWS, stack) > 0) {
- entityarrow.setSecondsOnFire(100);
- }
-+ // Purpur start
-+ int lootingLevel = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.MOB_LOOTING, stack);
-+
-+ if (lootingLevel > 0) {
-+ entityarrow.setLootingLevel(lootingLevel);
-+ }
-+ // Purpur end
- // CraftBukkit start
- org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(entityhuman, stack, itemstack1, entityarrow, entityhuman.getUsedItemHand(), f, !flag1);
- if (event.isCancelled()) {
-@@ -132,7 +139,7 @@ public class BowItem extends ProjectileWeaponItem implements Vanishable {
- ItemStack itemstack = user.getItemInHand(hand);
- boolean flag = !user.getProjectile(itemstack).isEmpty();
-
-- if (!user.getAbilities().instabuild && !flag) {
-+ if (!(world.purpurConfig.infinityWorksWithoutArrows && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.INFINITY_ARROWS, itemstack) > 0) && !user.getAbilities().instabuild && !flag) { // Purpur
- return InteractionResultHolder.fail(itemstack);
+ world.playSound(
+@@ -81,7 +81,7 @@ public class BowItem extends ProjectileWeaponItem {
+ public InteractionResultHolder use(Level world, Player user, InteractionHand hand) {
+ ItemStack itemStack = user.getItemInHand(hand);
+ boolean bl = !user.getProjectile(itemStack).isEmpty();
+- if (!user.hasInfiniteMaterials() && !bl) {
++ if (!(world.purpurConfig.infinityWorksWithoutArrows && net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.INFINITY, itemStack) > 0) && !user.hasInfiniteMaterials() && !bl) {
+ return InteractionResultHolder.fail(itemStack);
} else {
user.startUsingItem(hand);
diff --git a/src/main/java/net/minecraft/world/item/BucketItem.java b/src/main/java/net/minecraft/world/item/BucketItem.java
-index 6371f326fc86cfc53e39bf8ed13b646f7705fbbc..3dec0c5fc8dece5341634eaf8e94fe1964bf4038 100644
+index 49557d6f22c5725c663a231deab019d4f6fe95fa..046652e8f9c5dcdf7c90acb9391214cac46bd7d8 100644
--- a/src/main/java/net/minecraft/world/item/BucketItem.java
+++ b/src/main/java/net/minecraft/world/item/BucketItem.java
-@@ -195,7 +195,7 @@ public class BucketItem extends Item implements DispensibleContainerItem {
+@@ -194,7 +194,7 @@ public class BucketItem extends Item implements DispensibleContainerItem {
// CraftBukkit end
if (!flag2) {
return movingobjectpositionblock != null && this.emptyContents(entityhuman, world, movingobjectpositionblock.getBlockPos().relative(movingobjectpositionblock.getDirection()), (BlockHitResult) null, enumdirection, clicked, itemstack, enumhand); // CraftBukkit
@@ -14030,7 +13697,7 @@ index 6371f326fc86cfc53e39bf8ed13b646f7705fbbc..3dec0c5fc8dece5341634eaf8e94fe19
int i = blockposition.getX();
int j = blockposition.getY();
int k = blockposition.getZ();
-@@ -203,7 +203,7 @@ public class BucketItem extends Item implements DispensibleContainerItem {
+@@ -202,7 +202,7 @@ public class BucketItem extends Item implements DispensibleContainerItem {
world.playSound(entityhuman, blockposition, SoundEvents.FIRE_EXTINGUISH, SoundSource.BLOCKS, 0.5F, 2.6F + (world.random.nextFloat() - world.random.nextFloat()) * 0.8F);
for (int l = 0; l < 8; ++l) {
@@ -14040,56 +13707,32 @@ index 6371f326fc86cfc53e39bf8ed13b646f7705fbbc..3dec0c5fc8dece5341634eaf8e94fe19
return true;
diff --git a/src/main/java/net/minecraft/world/item/CrossbowItem.java b/src/main/java/net/minecraft/world/item/CrossbowItem.java
-index f3a428f80c265639250114498b10067b4bf1ada1..211d8e59a9b3460b346e5f8cf581df70b05d1b8f 100644
+index 0f6504a7160bc304b3af554f8740c65e2987cd37..9a8092602c96ddd77c8e6fcfe7a6f5ed733023a2 100644
--- a/src/main/java/net/minecraft/world/item/CrossbowItem.java
+++ b/src/main/java/net/minecraft/world/item/CrossbowItem.java
-@@ -64,7 +64,7 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable {
- ItemStack itemstack = user.getItemInHand(hand);
-
- if (CrossbowItem.isCharged(itemstack)) {
-- CrossbowItem.performShooting(world, user, hand, itemstack, CrossbowItem.getShootingPower(itemstack), 1.0F);
-+ CrossbowItem.performShooting(world, user, hand, itemstack, CrossbowItem.getShootingPower(itemstack), (float) world.purpurConfig.crossbowProjectileOffset); // Purpur
- CrossbowItem.setCharged(itemstack, false);
- return InteractionResultHolder.consume(itemstack);
- } else if (!user.getProjectile(itemstack).isEmpty()) {
-@@ -114,7 +114,7 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable {
- // Paper end - Add EntityLoadCrossbowEvent
- int i = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.MULTISHOT, crossbow);
- int j = i == 0 ? 1 : 3;
-- boolean flag = !consume || shooter instanceof Player && ((Player) shooter).getAbilities().instabuild; // Paper - Add EntityLoadCrossbowEvent
-+ boolean flag = !consume || shooter instanceof Player && ((Player) shooter).getAbilities().instabuild || (org.purpurmc.purpur.PurpurConfig.allowCrossbowInfinity && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.INFINITY_ARROWS, crossbow) > 0); // Paper - Add EntityLoadCrossbowEvent // Purpur
- ItemStack itemstack1 = shooter.getProjectile(crossbow);
- ItemStack itemstack2 = itemstack1.copy();
-
-@@ -291,6 +291,14 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable {
- entityarrow.setPierceLevel((byte) i);
- }
-
-+ // Purpur start
-+ int lootingLevel = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.MOB_LOOTING, crossbow);
-+
-+ if (lootingLevel > 0) {
-+ entityarrow.setLootingLevel(lootingLevel);
-+ }
-+ // Purpur end
-+
- return entityarrow;
+@@ -60,7 +60,7 @@ public class CrossbowItem extends ProjectileWeaponItem {
+ ItemStack itemStack = user.getItemInHand(hand);
+ ChargedProjectiles chargedProjectiles = itemStack.get(DataComponents.CHARGED_PROJECTILES);
+ if (chargedProjectiles != null && !chargedProjectiles.isEmpty()) {
+- this.performShooting(world, user, hand, itemStack, getShootingPower(chargedProjectiles), 1.0F, null);
++ this.performShooting(world, user, hand, itemStack, getShootingPower(chargedProjectiles), (float) world.purpurConfig.crossbowProjectileOffset, null); // Purpur
+ return InteractionResultHolder.consume(itemStack);
+ } else if (!user.getProjectile(itemStack).isEmpty()) {
+ this.startSoundPlayed = false;
+@@ -107,7 +107,7 @@ public class CrossbowItem extends ProjectileWeaponItem {
+ return CrossbowItem.tryLoadProjectiles(shooter, crossbow, true);
}
-
-@@ -300,7 +308,7 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable {
-
- for (int i = 0; i < list.size(); ++i) {
- ItemStack itemstack1 = (ItemStack) list.get(i);
-- boolean flag = entity instanceof Player && ((Player) entity).getAbilities().instabuild;
-+ boolean flag = entity instanceof Player && ((Player) entity).getAbilities().instabuild || (org.purpurmc.purpur.PurpurConfig.allowCrossbowInfinity && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.INFINITY_ARROWS, stack) > 0); // Purpur
-
- if (!itemstack1.isEmpty()) {
- if (i == 0) {
+ private static boolean tryLoadProjectiles(LivingEntity shooter, ItemStack crossbow, boolean consume) {
+- List list = draw(crossbow, shooter.getProjectile(crossbow), shooter, consume);
++ List list = draw(crossbow, shooter.getProjectile(crossbow), shooter, (org.purpurmc.purpur.PurpurConfig.allowCrossbowInfinity && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.INFINITY, crossbow) > 0) || consume);
+ // Paper end - Add EntityLoadCrossbowEvent
+ if (!list.isEmpty()) {
+ crossbow.set(DataComponents.CHARGED_PROJECTILES, ChargedProjectiles.of(list));
diff --git a/src/main/java/net/minecraft/world/item/DyeColor.java b/src/main/java/net/minecraft/world/item/DyeColor.java
-index 52ff8331f2859ee4bf39bf2fa6631bed7eed2f18..848a36a740576a0dd9e4ad50d1dd3ff07bd1d537 100644
+index 2202798612cad53aff28c499b8909a7292a37ad5..5ed2b7d15686fc9aa6dc7c03c337433cb3ee2cbd 100644
--- a/src/main/java/net/minecraft/world/item/DyeColor.java
+++ b/src/main/java/net/minecraft/world/item/DyeColor.java
-@@ -101,4 +101,10 @@ public enum DyeColor implements StringRepresentable {
+@@ -105,4 +105,10 @@ public enum DyeColor implements StringRepresentable {
public String getSerializedName() {
return this.name;
}
@@ -14101,10 +13744,10 @@ index 52ff8331f2859ee4bf39bf2fa6631bed7eed2f18..848a36a740576a0dd9e4ad50d1dd3ff0
+ // Purpur end
}
diff --git a/src/main/java/net/minecraft/world/item/EggItem.java b/src/main/java/net/minecraft/world/item/EggItem.java
-index a3bd507793994e9cc87a956871a8afbb8ca9460d..ef2197a23aef0a4215fae09bd4618e449e14c64e 100644
+index 4ebd634cff286b10868e26eeb3ecf34abdcab22e..7dc811335caa46870d1d895899a1e6c21980382d 100644
--- a/src/main/java/net/minecraft/world/item/EggItem.java
+++ b/src/main/java/net/minecraft/world/item/EggItem.java
-@@ -24,7 +24,7 @@ public class EggItem extends Item {
+@@ -27,7 +27,7 @@ public class EggItem extends Item implements ProjectileItem {
ThrownEgg entityegg = new ThrownEgg(world, user);
entityegg.setItem(itemstack);
@@ -14114,10 +13757,10 @@ index a3bd507793994e9cc87a956871a8afbb8ca9460d..ef2197a23aef0a4215fae09bd4618e44
com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entityegg.getBukkitEntity());
if (event.callEvent() && world.addFreshEntity(entityegg)) {
diff --git a/src/main/java/net/minecraft/world/item/EndCrystalItem.java b/src/main/java/net/minecraft/world/item/EndCrystalItem.java
-index a0bc8bb8d88e96457a2be0befe1fd69ef4973e11..26b0084f0b8c707f6d2b90e4cf6de7e92b4617c0 100644
+index ded33fd166cbb95917f7e321875acc4222caff46..da43fd53a5c44cc0ed7d1fa5297b77c43a894fc5 100644
--- a/src/main/java/net/minecraft/world/item/EndCrystalItem.java
+++ b/src/main/java/net/minecraft/world/item/EndCrystalItem.java
-@@ -26,7 +26,7 @@ public class EndCrystalItem extends Item {
+@@ -27,7 +27,7 @@ public class EndCrystalItem extends Item {
BlockPos blockposition = context.getClickedPos();
BlockState iblockdata = world.getBlockState(blockposition);
@@ -14127,7 +13770,7 @@ index a0bc8bb8d88e96457a2be0befe1fd69ef4973e11..26b0084f0b8c707f6d2b90e4cf6de7e9
} else {
BlockPos blockposition1 = blockposition.above(); final BlockPos aboveBlockPosition = blockposition1; // Paper - OBFHELPER
diff --git a/src/main/java/net/minecraft/world/item/EnderpearlItem.java b/src/main/java/net/minecraft/world/item/EnderpearlItem.java
-index 8c8cf8705107c95d9a4eab28b5845ae13c4ffb3c..8031e38c66468676b3b4a7443d6678eec6b1e8a4 100644
+index 20a91d798d31a71b3c05efa2cc5bda55494e26cc..11b04455f09d8bfdf44499bb8359dc715c2daffd 100644
--- a/src/main/java/net/minecraft/world/item/EnderpearlItem.java
+++ b/src/main/java/net/minecraft/world/item/EnderpearlItem.java
@@ -24,7 +24,7 @@ public class EnderpearlItem extends Item {
@@ -14149,62 +13792,45 @@ index 8c8cf8705107c95d9a4eab28b5845ae13c4ffb3c..8031e38c66468676b3b4a7443d6678ee
// Paper end - PlayerLaunchProjectileEvent
if (user instanceof net.minecraft.server.level.ServerPlayer) {
diff --git a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
-index e1c8b24a92ea63a645406522a3c2fb5efd87f01a..0f6c1716103514dedf46e7068fd79e8b9b94e15d 100644
+index 218f2f085309f04438f8b07bc41cf242583db2dc..ea8e49b42b9dde74784189430be66ed6978015dd 100644
--- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
+++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
-@@ -15,6 +15,7 @@ import net.minecraft.util.ByIdMap;
- import net.minecraft.world.InteractionHand;
- import net.minecraft.world.InteractionResult;
- import net.minecraft.world.InteractionResultHolder;
-+import net.minecraft.world.entity.EquipmentSlot;
- import net.minecraft.world.entity.player.Player;
- import net.minecraft.world.entity.projectile.FireworkRocketEntity;
- import net.minecraft.world.item.context.UseOnContext;
-@@ -76,6 +77,14 @@ public class FireworkRocketItem extends Item {
+@@ -65,6 +65,14 @@ public class FireworkRocketItem extends Item implements ProjectileItem {
com.destroystokyo.paper.event.player.PlayerElytraBoostEvent event = new com.destroystokyo.paper.event.player.PlayerElytraBoostEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Firework) fireworkRocketEntity.getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand));
if (event.callEvent() && world.addFreshEntity(fireworkRocketEntity)) {
user.awardStat(Stats.ITEM_USED.get(this));
+ // Purpur start
+ if (world.purpurConfig.elytraDamagePerFireworkBoost > 0) {
-+ ItemStack chestItem = user.getItemBySlot(EquipmentSlot.CHEST);
++ ItemStack chestItem = user.getItemBySlot(net.minecraft.world.entity.EquipmentSlot.CHEST);
+ if (chestItem.getItem() == Items.ELYTRA) {
-+ chestItem.hurtAndBreak(world.purpurConfig.elytraDamagePerFireworkBoost, user, (entityliving) -> entityliving.broadcastBreakEvent(EquipmentSlot.CHEST));
++ chestItem.hurtAndBreak(world.purpurConfig.elytraDamagePerFireworkBoost, user, net.minecraft.world.entity.EquipmentSlot.CHEST);
+ }
+ }
+ // Purpur end
- if (event.shouldConsume() && !user.getAbilities().instabuild) {
- itemStack.shrink(1);
+ if (event.shouldConsume() && !user.hasInfiniteMaterials()) {
+ itemStack.shrink(1);
} else ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
diff --git a/src/main/java/net/minecraft/world/item/HangingEntityItem.java b/src/main/java/net/minecraft/world/item/HangingEntityItem.java
-index b2ad6d230de2c29f371178bccde1111c7532ee70..6667926519a0f1c151e53f59cce36e7417dfc1cd 100644
+index 530167ce8e5bb72a418f8ec61411e38a5892fd72..35dc7546793dba34bf6debad3f214f61a8fb4f4e 100644
--- a/src/main/java/net/minecraft/world/item/HangingEntityItem.java
+++ b/src/main/java/net/minecraft/world/item/HangingEntityItem.java
-@@ -48,7 +48,7 @@ public class HangingEntityItem extends Item {
- return InteractionResult.FAIL;
- } else {
- Level world = context.getLevel();
-- Object object;
-+ Entity object; // Purpur
+@@ -73,6 +73,11 @@ public class HangingEntityItem extends Item {
- if (this.type == EntityType.PAINTING) {
- Optional optional = Painting.create(world, blockposition1, enumdirection);
-@@ -72,6 +72,11 @@ public class HangingEntityItem extends Item {
-
- if (nbttagcompound != null) {
- EntityType.updateCustomEntityTag(world, entityhuman, (Entity) object, nbttagcompound);
+ if (!customdata.isEmpty()) {
+ EntityType.updateCustomEntityTag(world, entityhuman, (Entity) object, customdata);
+ // Purpur start
-+ if (world.purpurConfig.persistentDroppableEntityDisplayNames && itemstack.hasCustomHoverName()) {
-+ object.setCustomName(itemstack.getHoverName());
++ if (!world.purpurConfig.persistentDroppableEntityDisplayNames) {
++ ((Entity) object).setCustomName(null);
+ }
+ // Purpur end
}
if (((HangingEntity) object).survives()) {
diff --git a/src/main/java/net/minecraft/world/item/HoeItem.java b/src/main/java/net/minecraft/world/item/HoeItem.java
-index 9e5695eabd4c3ea165121b22fff93f09b170bc6b..18cbcfcd331f7b7a112383311e3e2b9984857028 100644
+index 06497b5141e611cc7a1b6030a7b9c54b5c4eda06..28df1b3230762e52b5458ac93a85c9a5d41eb6a6 100644
--- a/src/main/java/net/minecraft/world/item/HoeItem.java
+++ b/src/main/java/net/minecraft/world/item/HoeItem.java
-@@ -45,15 +45,23 @@ public class HoeItem extends DiggerItem {
+@@ -46,15 +46,23 @@ public class HoeItem extends DiggerItem {
public InteractionResult useOn(UseOnContext context) {
Level level = context.getLevel();
BlockPos blockPos = context.getClickedPos();
@@ -14235,7 +13861,7 @@ index 9e5695eabd4c3ea165121b22fff93f09b170bc6b..18cbcfcd331f7b7a112383311e3e2b99
if (!level.isClientSide) {
consumer.accept(context);
if (player != null) {
-@@ -61,7 +69,7 @@ public class HoeItem extends DiggerItem {
+@@ -62,7 +70,7 @@ public class HoeItem extends DiggerItem {
}
}
@@ -14245,10 +13871,10 @@ index 9e5695eabd4c3ea165121b22fff93f09b170bc6b..18cbcfcd331f7b7a112383311e3e2b99
return InteractionResult.PASS;
}
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
-index a39201ea35edb1be068ff7269dcee614d0477050..d997e54428902fda805c3a79d8b112c76e15d363 100644
+index 028d86b7c26724b955e88373c80af5fea7869d67..1545ec1759526ab88838309133e2a16c634ce074 100644
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
-@@ -454,6 +454,7 @@ public final class ItemStack {
+@@ -475,6 +475,7 @@ public final class ItemStack implements DataComponentHolder {
world.preventPoiUpdated = true; // CraftBukkit - SPIGOT-5710
for (BlockState blockstate : blocks) {
blockstate.update(true, false);
@@ -14256,22 +13882,22 @@ index a39201ea35edb1be068ff7269dcee614d0477050..d997e54428902fda805c3a79d8b112c7
}
world.preventPoiUpdated = false;
-@@ -485,6 +486,7 @@ public final class ItemStack {
+@@ -506,6 +507,7 @@ public final class ItemStack implements DataComponentHolder {
if (!(block.getBlock() instanceof BaseEntityBlock)) { // Containers get placed automatically
- block.getBlock().onPlace(block, world, newblockposition, oldBlock, true, context); // Paper - pass context
+ block.onPlace(world, newblockposition, oldBlock, true, context); // Paper - pass context
}
+ block.getBlock().forgetPlacer(); // Purpur
world.notifyAndUpdatePhysics(newblockposition, null, oldBlock, block, world.getBlockState(newblockposition), updateFlag, 512); // send null chunk as chunk.k() returns false by this point
}
-@@ -613,6 +615,16 @@ public final class ItemStack {
+@@ -636,6 +638,16 @@ public final class ItemStack implements DataComponentHolder {
return this.isDamageableItem() && this.getDamageValue() > 0;
}
+ // Purpur start
+ public float getDamagePercent() {
+ if (isDamaged()) {
-+ return (float) getDamageValue() / (float) getItem().getMaxDamage();
++ return (float) getDamageValue() / (float) getMaxDamage();
+ } else {
+ return 0F;
+ }
@@ -14279,9 +13905,9 @@ index a39201ea35edb1be068ff7269dcee614d0477050..d997e54428902fda805c3a79d8b112c7
+ // Purpur end
+
public int getDamageValue() {
- return this.tag == null ? 0 : this.tag.getInt("Damage");
+ return Mth.clamp((Integer) this.getOrDefault(DataComponents.DAMAGE, 0), 0, this.getMaxDamage());
}
-@@ -632,7 +644,7 @@ public final class ItemStack {
+@@ -653,7 +665,7 @@ public final class ItemStack implements DataComponentHolder {
int j;
if (amount > 0) {
@@ -14290,117 +13916,89 @@ index a39201ea35edb1be068ff7269dcee614d0477050..d997e54428902fda805c3a79d8b112c7
int k = 0;
for (int l = 0; j > 0 && l < amount; ++l) {
-@@ -687,6 +699,12 @@ public final class ItemStack {
- if (this.hurt(amount, entity.getRandom(), entity /*instanceof ServerPlayer ? (ServerPlayer) entity : null*/)) { // Paper - Add EntityDamageItemEvent
- breakCallback.accept(entity);
- Item item = this.getItem();
-+ // Purpur start
-+ if (item == Items.ELYTRA) {
-+ setDamageValue(item.getMaxDamage() - 1);
-+ return;
-+ }
-+ // Purpur end
- // CraftBukkit start - Check for item breaking
- if (this.count == 1 && entity instanceof net.minecraft.world.entity.player.Player) {
- org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent((net.minecraft.world.entity.player.Player) entity, this);
-@@ -1217,7 +1235,7 @@ public final class ItemStack {
-
- ListTag nbttaglist = this.tag.getList("Enchantments", 10);
-
-- nbttaglist.add(EnchantmentHelper.storeEnchantment(EnchantmentHelper.getEnchantmentId(enchantment), (byte) level));
-+ nbttaglist.add(EnchantmentHelper.storeEnchantment(EnchantmentHelper.getEnchantmentId(enchantment), (org.purpurmc.purpur.PurpurConfig.clampEnchantLevels) ? (byte) level : (short) level)); // Purpur
- processEnchantOrder(this.tag); // Paper
- }
-
-@@ -1225,6 +1243,12 @@ public final class ItemStack {
- return this.tag != null && this.tag.contains("Enchantments", 9) ? !this.tag.getList("Enchantments", 10).isEmpty() : false;
+@@ -729,6 +741,12 @@ public final class ItemStack implements DataComponentHolder {
+ this.hurtAndBreak(amount, randomsource, entity, () -> { // Paper - Add EntityDamageItemEvent
+ entity.broadcastBreakEvent(slot);
+ Item item = this.getItem();
++ // Purpur start
++ if (item == Items.ELYTRA) {
++ setDamageValue(getMaxDamage() - 1);
++ return;
++ }
++ // Purpur end
+ // CraftBukkit start - Check for item breaking
+ if (this.count == 1 && entity instanceof net.minecraft.world.entity.player.Player) {
+ org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent((net.minecraft.world.entity.player.Player) entity, this);
+@@ -1210,6 +1228,16 @@ public final class ItemStack implements DataComponentHolder {
+ return !((ItemEnchantments) this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY)).isEmpty();
}
+ // Purpur start
+ public boolean hasEnchantment(Enchantment enchantment) {
-+ return isEnchanted() && EnchantmentHelper.deserializeEnchantments(getEnchantmentTags()).containsKey(enchantment);
++ if (isEnchanted()) {
++ ItemEnchantments enchantments = this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY);
++ return new net.minecraft.advancements.critereon.EnchantmentPredicate(enchantment, net.minecraft.advancements.critereon.MinMaxBounds.Ints.atLeast(1)).containedIn(enchantments);
++ }
++ return false;
+ }
+ // Purpur end
+
- public void addTagElement(String key, Tag element) {
- this.getOrCreateTag().put(key, element);
+ public ItemEnchantments getEnchantments() {
+ return (ItemEnchantments) this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY);
}
diff --git a/src/main/java/net/minecraft/world/item/Items.java b/src/main/java/net/minecraft/world/item/Items.java
-index b43598ee4035d9c53a40629dd4021b58c04132c8..c2c58a0788bfda5c1775194cbb9ddb406b882292 100644
+index d00b59efb754594cf532f8598f4b6d3b29693232..42b322879629afb2d2fc64a215f010f5d5ce9e02 100644
--- a/src/main/java/net/minecraft/world/item/Items.java
+++ b/src/main/java/net/minecraft/world/item/Items.java
-@@ -316,7 +316,7 @@ public class Items {
+@@ -338,7 +338,7 @@ public class Items {
public static final Item PURPUR_BLOCK = registerBlock(Blocks.PURPUR_BLOCK);
public static final Item PURPUR_PILLAR = registerBlock(Blocks.PURPUR_PILLAR);
public static final Item PURPUR_STAIRS = registerBlock(Blocks.PURPUR_STAIRS);
- public static final Item SPAWNER = registerBlock(Blocks.SPAWNER);
+ public static final Item SPAWNER = registerBlock(new org.purpurmc.purpur.item.SpawnerItem(Blocks.SPAWNER, new Item.Properties().rarity(Rarity.EPIC))); // Purpur
- public static final Item CHEST = registerBlock(Blocks.CHEST);
+ public static final Item CHEST = registerBlock(Blocks.CHEST, settings -> settings.component(DataComponents.CONTAINER, ItemContainerContents.EMPTY));
public static final Item CRAFTING_TABLE = registerBlock(Blocks.CRAFTING_TABLE);
public static final Item FARMLAND = registerBlock(Blocks.FARMLAND);
-@@ -1535,7 +1535,7 @@ public class Items {
+@@ -1909,7 +1909,7 @@ public class Items {
"sweet_berries", new ItemNameBlockItem(Blocks.SWEET_BERRY_BUSH, new Item.Properties().food(Foods.SWEET_BERRIES))
);
public static final Item GLOW_BERRIES = registerItem(
- "glow_berries", new ItemNameBlockItem(Blocks.CAVE_VINES, new Item.Properties().food(Foods.GLOW_BERRIES))
-+ "glow_berries", new org.purpurmc.purpur.item.GlowBerryItem(Blocks.CAVE_VINES, new Item.Properties().food(Foods.GLOW_BERRIES)) // Purpur
++ "glow_berries", new org.purpurmc.purpur.item.GlowBerryItem(Blocks.CAVE_VINES, new Item.Properties().food(Foods.GLOW_BERRIES)) // Purpur
);
- public static final Item CAMPFIRE = registerBlock(Blocks.CAMPFIRE);
- public static final Item SOUL_CAMPFIRE = registerBlock(Blocks.SOUL_CAMPFIRE);
-@@ -1715,6 +1715,13 @@ public class Items {
- ((BlockItem)item).registerBlocks(Item.BY_BLOCK, item);
- }
-
-+ // Purpur start
-+ if (item.getFoodProperties() != null) {
-+ Foods.ALL_PROPERTIES.put(key.location().getPath(), item.getFoodProperties());
-+ Foods.DEFAULT_PROPERTIES.put(key.location().getPath(), item.getFoodProperties().copy());
-+ }
-+ // Purpur end
-+
- return Registry.register(BuiltInRegistries.ITEM, key, item);
- }
- }
+ public static final Item CAMPFIRE = registerBlock(Blocks.CAMPFIRE, settings -> settings.component(DataComponents.CONTAINER, ItemContainerContents.EMPTY));
+ public static final Item SOUL_CAMPFIRE = registerBlock(
diff --git a/src/main/java/net/minecraft/world/item/MapItem.java b/src/main/java/net/minecraft/world/item/MapItem.java
-index d8dd99ec8bf7444c5a3c426db3a9c13e334dc0ff..8d3c1897044f9a2bbe1911e1a72dc9a00fb246df 100644
+index ce461b1a8d7fab87ae28e30205f6fab67f1808b6..608390ed36710a419de1542b80340dd3fcc7299c 100644
--- a/src/main/java/net/minecraft/world/item/MapItem.java
+++ b/src/main/java/net/minecraft/world/item/MapItem.java
-@@ -235,6 +235,7 @@ public class MapItem extends ComplexItem {
- MapItemSavedData worldmap = MapItem.getSavedData(map, world);
-
- if (worldmap != null) {
-+ worldmap.isExplorerMap = true; // Purpur
- if (world.dimension() == worldmap.dimension) {
- int i = 1 << worldmap.scale;
- int j = worldmap.centerX;
+@@ -195,6 +195,7 @@ public class MapItem extends ComplexItem {
+ public static void renderBiomePreviewMap(ServerLevel world, ItemStack map) {
+ MapItemSavedData mapItemSavedData = getSavedData(map, world);
+ if (mapItemSavedData != null) {
++ mapItemSavedData.isExplorerMap = true; // Purpur
+ if (world.dimension() == mapItemSavedData.dimension) {
+ int i = 1 << mapItemSavedData.scale;
+ int j = mapItemSavedData.centerX;
diff --git a/src/main/java/net/minecraft/world/item/MilkBucketItem.java b/src/main/java/net/minecraft/world/item/MilkBucketItem.java
-index f33977d95b6db473be4f95075ba99caf90ad0220..56dc04d8875971ee9a5d077a695509af74fe2473 100644
+index 0f83ae4b0d5f52ff9ccfff6bbcc31153d45bd619..d0751274e89042715cab8e9e72387042356e3244 100644
--- a/src/main/java/net/minecraft/world/item/MilkBucketItem.java
+++ b/src/main/java/net/minecraft/world/item/MilkBucketItem.java
-@@ -5,6 +5,8 @@ import net.minecraft.server.level.ServerPlayer;
- import net.minecraft.stats.Stats;
- import net.minecraft.world.InteractionHand;
- import net.minecraft.world.InteractionResultHolder;
-+import net.minecraft.world.effect.MobEffectInstance;
-+import net.minecraft.world.effect.MobEffects;
- import net.minecraft.world.entity.LivingEntity;
- import net.minecraft.world.entity.player.Player;
- import net.minecraft.world.level.Level;
-@@ -31,7 +33,9 @@ public class MilkBucketItem extends Item {
- }
+@@ -26,7 +26,9 @@ public class MilkBucketItem extends Item {
+ stack.consume(1, user);
if (!world.isClientSide) {
-+ MobEffectInstance badOmen = user.getEffect(MobEffects.BAD_OMEN);
++ net.minecraft.world.effect.MobEffectInstance badOmen = user.getEffect(net.minecraft.world.effect.MobEffects.BAD_OMEN); // Purpur
user.removeAllEffects(org.bukkit.event.entity.EntityPotionEffectEvent.Cause.MILK); // CraftBukkit
+ if (!world.purpurConfig.milkCuresBadOmen && badOmen != null) user.addEffect(badOmen); // Purpur
}
return stack.isEmpty() ? new ItemStack(Items.BUCKET) : stack;
diff --git a/src/main/java/net/minecraft/world/item/MinecartItem.java b/src/main/java/net/minecraft/world/item/MinecartItem.java
-index 3aa73cd44aa8c86b78c35bc1788e4f83018c49ed..66a8b28275619079e3bcbcc460146976d533d54e 100644
+index 66074445d3908b9bb1c8d70e1e27d057720ec8e5..0fd4f2ab929df479360755a3f1e58a933ae59520 100644
--- a/src/main/java/net/minecraft/world/item/MinecartItem.java
+++ b/src/main/java/net/minecraft/world/item/MinecartItem.java
-@@ -119,8 +119,9 @@ public class MinecartItem extends Item {
+@@ -120,8 +120,9 @@ public class MinecartItem extends Item {
BlockState iblockdata = world.getBlockState(blockposition);
if (!iblockdata.is(BlockTags.RAILS)) {
@@ -14412,7 +14010,7 @@ index 3aa73cd44aa8c86b78c35bc1788e4f83018c49ed..66a8b28275619079e3bcbcc460146976
ItemStack itemstack = context.getItemInHand();
if (world instanceof ServerLevel) {
-@@ -145,6 +146,6 @@ public class MinecartItem extends Item {
+@@ -146,6 +147,6 @@ public class MinecartItem extends Item {
itemstack.shrink(1);
return InteractionResult.sidedSuccess(world.isClientSide);
@@ -14421,22 +14019,41 @@ index 3aa73cd44aa8c86b78c35bc1788e4f83018c49ed..66a8b28275619079e3bcbcc460146976
}
}
diff --git a/src/main/java/net/minecraft/world/item/NameTagItem.java b/src/main/java/net/minecraft/world/item/NameTagItem.java
-index a0b3c2d3b3f86ecd6cb80ff767839d29ca4f4f68..61b4430d6dd73b5406c4879e41ff80a1b6f67f84 100644
+index 774c982f28b4f127fc3f036c19dfb47fb9ae3264..d49b60e7e643498b49c03593dc0da2f8e4459902 100644
--- a/src/main/java/net/minecraft/world/item/NameTagItem.java
+++ b/src/main/java/net/minecraft/world/item/NameTagItem.java
-@@ -20,6 +20,7 @@ public class NameTagItem extends Item {
+@@ -23,6 +23,7 @@ public class NameTagItem extends Item {
if (!event.callEvent()) return InteractionResult.PASS;
LivingEntity newEntity = ((org.bukkit.craftbukkit.entity.CraftLivingEntity) event.getEntity()).getHandle();
newEntity.setCustomName(event.getName() != null ? io.papermc.paper.adventure.PaperAdventure.asVanilla(event.getName()) : null);
+ if (user.level().purpurConfig.armorstandFixNametags && entity instanceof net.minecraft.world.entity.decoration.ArmorStand) entity.setCustomNameVisible(true); // Purpur
- if (event.isPersistent() && newEntity instanceof Mob) {
- ((Mob) newEntity).setPersistenceRequired();
- // Paper end - Add PlayerNameEntityEvent
+ if (event.isPersistent() && newEntity instanceof Mob mob) {
+ // Paper end - Add PlayerNameEntityEvent
+ mob.setPersistenceRequired();
+diff --git a/src/main/java/net/minecraft/world/item/ProjectileWeaponItem.java b/src/main/java/net/minecraft/world/item/ProjectileWeaponItem.java
+index f91ce87491b18f4f4ae6458192d1f320b308102a..aec96d297401b705ca2af97904739afdf1134574 100644
+--- a/src/main/java/net/minecraft/world/item/ProjectileWeaponItem.java
++++ b/src/main/java/net/minecraft/world/item/ProjectileWeaponItem.java
+@@ -131,6 +131,14 @@ public abstract class ProjectileWeaponItem extends Item {
+ entityarrow.setPierceLevel((byte) k);
+ }
+
++ // Purpur start
++ int lootingLevel = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.LOOTING, weaponStack);
++
++ if (lootingLevel > 0) {
++ entityarrow.setLootingLevel(lootingLevel);
++ }
++ // Purpur end
++
+ return entityarrow;
+ }
+
diff --git a/src/main/java/net/minecraft/world/item/ShovelItem.java b/src/main/java/net/minecraft/world/item/ShovelItem.java
-index 9aba0211f37501bbd19b583d22fa83eae32390d9..f44e28bf44b9d39267d21eaf6a025b5f28f3cd72 100644
+index 24f6a158e4759aac3be8da4cf5e0d40bd295355b..6b7dbb570f8a698c87c6bce992d84d87b55176e6 100644
--- a/src/main/java/net/minecraft/world/item/ShovelItem.java
+++ b/src/main/java/net/minecraft/world/item/ShovelItem.java
-@@ -46,9 +46,12 @@ public class ShovelItem extends DiggerItem {
+@@ -47,9 +47,12 @@ public class ShovelItem extends DiggerItem {
BlockState blockState2 = FLATTENABLES.get(blockState.getBlock());
BlockState blockState3 = null;
Runnable afterAction = null; // Paper
@@ -14452,7 +14069,7 @@ index 9aba0211f37501bbd19b583d22fa83eae32390d9..f44e28bf44b9d39267d21eaf6a025b5f
} else if (blockState.getBlock() instanceof CampfireBlock && blockState.getValue(CampfireBlock.LIT)) {
afterAction = () -> { // Paper
if (!level.isClientSide()) {
-@@ -75,7 +78,7 @@ public class ShovelItem extends DiggerItem {
+@@ -76,7 +79,7 @@ public class ShovelItem extends DiggerItem {
}
}
@@ -14462,10 +14079,10 @@ index 9aba0211f37501bbd19b583d22fa83eae32390d9..f44e28bf44b9d39267d21eaf6a025b5f
return InteractionResult.PASS;
}
diff --git a/src/main/java/net/minecraft/world/item/SnowballItem.java b/src/main/java/net/minecraft/world/item/SnowballItem.java
-index bc8186a5bc3a98b35fad570729dd4ba52efab238..caab0c1e2bc5696080750797cbf1c93f57799f7d 100644
+index 32b170551a2f5bdc88d29f4d03750bfe3974e71b..a41fb0dd26af367fc2470a7913a84d864bc505f7 100644
--- a/src/main/java/net/minecraft/world/item/SnowballItem.java
+++ b/src/main/java/net/minecraft/world/item/SnowballItem.java
-@@ -25,7 +25,7 @@ public class SnowballItem extends Item {
+@@ -28,7 +28,7 @@ public class SnowballItem extends Item implements ProjectileItem {
Snowball entitysnowball = new Snowball(world, user);
entitysnowball.setItem(itemstack);
@@ -14475,31 +14092,30 @@ index bc8186a5bc3a98b35fad570729dd4ba52efab238..caab0c1e2bc5696080750797cbf1c93f
com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entitysnowball.getBukkitEntity());
if (event.callEvent() && world.addFreshEntity(entitysnowball)) {
diff --git a/src/main/java/net/minecraft/world/item/SpawnEggItem.java b/src/main/java/net/minecraft/world/item/SpawnEggItem.java
-index 3bfbf7daa190b03f978b9fc72233c18c383b6659..afed52ed201193867f19054c5b379270a6fbe480 100644
+index 9cea8da84f39bb3f687139ef213ccea358724dee..076e6858222b92f8409f1f5cad398582c1fd6bcb 100644
--- a/src/main/java/net/minecraft/world/item/SpawnEggItem.java
+++ b/src/main/java/net/minecraft/world/item/SpawnEggItem.java
-@@ -68,6 +68,16 @@ public class SpawnEggItem extends Item {
+@@ -74,6 +74,15 @@ public class SpawnEggItem extends Item {
Spawner spawner = (Spawner) tileentity;
- entitytypes = this.getType(itemstack.getTag());
+ entitytypes = this.getType(itemstack);
+
+ // Purpur start
+ org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ());
-+ org.purpurmc.purpur.event.PlayerSetSpawnerTypeWithEggEvent event = new org.purpurmc.purpur.event.PlayerSetSpawnerTypeWithEggEvent((org.bukkit.entity.Player) context.getPlayer().getBukkitEntity(), bukkitBlock, (org.bukkit.block.CreatureSpawner) bukkitBlock.getState(), org.bukkit.entity.EntityType.fromName(entitytypes.getName()));
++ org.purpurmc.purpur.event.PlayerSetSpawnerTypeWithEggEvent event = new org.purpurmc.purpur.event.PlayerSetSpawnerTypeWithEggEvent((org.bukkit.entity.Player) context.getPlayer().getBukkitEntity(), bukkitBlock, (org.bukkit.block.CreatureSpawner) bukkitBlock.getState(), org.bukkit.entity.EntityType.fromName(entitytypes.getName()));
+ if (!event.callEvent()) {
+ return InteractionResult.FAIL;
+ }
+ entitytypes = EntityType.getFromBukkitType(event.getEntityType());
+ // Purpur end
-+
spawner.setEntityId(entitytypes, world.getRandom());
world.sendBlockUpdated(blockposition, iblockdata, iblockdata, 3);
- world.gameEvent((Entity) context.getPlayer(), GameEvent.BLOCK_CHANGE, blockposition);
+ world.gameEvent((Entity) context.getPlayer(), (Holder) GameEvent.BLOCK_CHANGE, blockposition);
diff --git a/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java b/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java
-index f47f793c62a919fb65c081ddb82d597a978d3b20..3bbb44ae3da68afbd6012df68dee277a7dbf98c0 100644
+index 369955746f4b51f69fa01103e3771dd74fc6c8f0..e6edd3a0fa2578900cdbe8bd588219dc3fd3af5f 100644
--- a/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java
+++ b/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java
-@@ -18,7 +18,7 @@ public class ThrowablePotionItem extends PotionItem {
+@@ -21,7 +21,7 @@ public class ThrowablePotionItem extends PotionItem implements ProjectileItem {
if (!world.isClientSide) {
ThrownPotion thrownPotion = new ThrownPotion(world, user);
thrownPotion.setItem(itemStack);
@@ -14509,21 +14125,21 @@ index f47f793c62a919fb65c081ddb82d597a978d3b20..3bbb44ae3da68afbd6012df68dee277a
com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) thrownPotion.getBukkitEntity());
if (event.callEvent() && world.addFreshEntity(thrownPotion)) {
diff --git a/src/main/java/net/minecraft/world/item/TridentItem.java b/src/main/java/net/minecraft/world/item/TridentItem.java
-index a792c7b7a6179aa88fc473b27ef0ca13bd91a395..95f9dd3f8fbf593fd6898335454951868c867a06 100644
+index 47de500fddb0716d142f8f5876a82a95afaa06fa..905a020dd7b365d51d5addadbbeb9555d03c5238 100644
--- a/src/main/java/net/minecraft/world/item/TridentItem.java
+++ b/src/main/java/net/minecraft/world/item/TridentItem.java
-@@ -77,11 +77,19 @@ public class TridentItem extends Item implements Vanishable {
+@@ -76,11 +76,19 @@ public class TridentItem extends Item implements ProjectileItem {
if (k == 0) {
ThrownTrident entitythrowntrident = new ThrownTrident(world, entityhuman, stack);
- entitythrowntrident.shootFromRotation(entityhuman, entityhuman.getXRot(), entityhuman.getYRot(), 0.0F, 2.5F + (float) k * 0.5F, 1.0F);
+ entitythrowntrident.shootFromRotation(entityhuman, entityhuman.getXRot(), entityhuman.getYRot(), 0.0F, 2.5F + (float) k * 0.5F, (float) world.purpurConfig.tridentProjectileOffset); // Purpur
- if (entityhuman.getAbilities().instabuild) {
+ if (entityhuman.hasInfiniteMaterials()) {
entitythrowntrident.pickup = AbstractArrow.Pickup.CREATIVE_ONLY;
}
+ // Purpur start
-+ int lootingLevel = EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.MOB_LOOTING, stack);
++ int lootingLevel = EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.LOOTING, stack);
+
+ if (lootingLevel > 0) {
+ entitythrowntrident.setLootingLevel(lootingLevel);
@@ -14533,7 +14149,7 @@ index a792c7b7a6179aa88fc473b27ef0ca13bd91a395..95f9dd3f8fbf593fd689833545495186
// CraftBukkit start
// Paper start - PlayerLaunchProjectileEvent
com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack), (org.bukkit.entity.Projectile) entitythrowntrident.getBukkitEntity());
-@@ -128,6 +136,14 @@ public class TridentItem extends Item implements Vanishable {
+@@ -123,6 +131,14 @@ public class TridentItem extends Item implements ProjectileItem {
f3 *= f6 / f5;
f4 *= f6 / f5;
org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerRiptideEvent(entityhuman, stack, f2, f3, f4); // CraftBukkit
@@ -14541,7 +14157,7 @@ index a792c7b7a6179aa88fc473b27ef0ca13bd91a395..95f9dd3f8fbf593fd689833545495186
+ // Purpur start
+ ItemStack chestItem = entityhuman.getItemBySlot(EquipmentSlot.CHEST);
+ if (chestItem.getItem() == Items.ELYTRA && world.purpurConfig.elytraDamagePerTridentBoost > 0) {
-+ chestItem.hurtAndBreak(world.purpurConfig.elytraDamagePerTridentBoost, entityhuman, (entity) -> entity.broadcastBreakEvent(EquipmentSlot.CHEST));
++ chestItem.hurtAndBreak(world.purpurConfig.elytraDamagePerTridentBoost, entityhuman, EquipmentSlot.CHEST);
+ }
+ // Purpur end
+
@@ -14549,10 +14165,10 @@ index a792c7b7a6179aa88fc473b27ef0ca13bd91a395..95f9dd3f8fbf593fd689833545495186
entityhuman.startAutoSpinAttack(20);
if (entityhuman.onGround()) {
diff --git a/src/main/java/net/minecraft/world/item/crafting/Ingredient.java b/src/main/java/net/minecraft/world/item/crafting/Ingredient.java
-index 7c29750e534eae4266bf7a63c50e3827401d6569..e8e9a3370ba07dc0ca47c8352f6f04a449f2268f 100644
+index e314f36951e9ac15c57137e24fce8c410373130a..21dfb8e91c5427ac12133de2c05d923d87adf5ba 100644
--- a/src/main/java/net/minecraft/world/item/crafting/Ingredient.java
+++ b/src/main/java/net/minecraft/world/item/crafting/Ingredient.java
-@@ -36,6 +36,7 @@ public final class Ingredient implements Predicate {
+@@ -41,6 +41,7 @@ public final class Ingredient implements Predicate {
@Nullable
private IntList stackingIds;
public boolean exact; // CraftBukkit
@@ -14560,7 +14176,7 @@ index 7c29750e534eae4266bf7a63c50e3827401d6569..e8e9a3370ba07dc0ca47c8352f6f04a4
public static final Codec CODEC = Ingredient.codec(true);
public static final Codec CODEC_NONEMPTY = Ingredient.codec(false);
-@@ -67,6 +68,12 @@ public final class Ingredient implements Predicate {
+@@ -72,6 +73,12 @@ public final class Ingredient implements Predicate {
} else if (this.isEmpty()) {
return itemstack.isEmpty();
} else {
@@ -14574,25 +14190,10 @@ index 7c29750e534eae4266bf7a63c50e3827401d6569..e8e9a3370ba07dc0ca47c8352f6f04a4
int i = aitemstack.length;
diff --git a/src/main/java/net/minecraft/world/item/enchantment/ArrowInfiniteEnchantment.java b/src/main/java/net/minecraft/world/item/enchantment/ArrowInfiniteEnchantment.java
-index 04c39359585d909dedbdfd78f6cbdc06b926607a..127950c54ae057b3d0eb62e8f81d5eef6f11a36c 100644
+index 81cc05c929d612898609965d82454b89cd18f9f5..fa73c3d4b58ad8379963a9866d8f09e1d6abd663 100644
--- a/src/main/java/net/minecraft/world/item/enchantment/ArrowInfiniteEnchantment.java
+++ b/src/main/java/net/minecraft/world/item/enchantment/ArrowInfiniteEnchantment.java
-@@ -7,6 +7,14 @@ public class ArrowInfiniteEnchantment extends Enchantment {
- super(weight, EnchantmentCategory.BOW, slotTypes);
- }
-
-+ // Purpur start
-+ @Override
-+ public boolean canEnchant(net.minecraft.world.item.ItemStack stack) {
-+ // we have to cheat the system because this class is loaded before purpur's config is loaded
-+ return (org.purpurmc.purpur.PurpurConfig.allowCrossbowInfinity ? EnchantmentCategory.BOW_AND_CROSSBOW : EnchantmentCategory.BOW).canEnchant(stack.getItem());
-+ }
-+ // Purpur end
-+
- @Override
- public int getMinCost(int level) {
- return 20;
-@@ -19,6 +27,6 @@ public class ArrowInfiniteEnchantment extends Enchantment {
+@@ -7,6 +7,6 @@ public class ArrowInfiniteEnchantment extends Enchantment {
@Override
public boolean checkCompatibility(Enchantment other) {
@@ -14600,45 +14201,11 @@ index 04c39359585d909dedbdfd78f6cbdc06b926607a..127950c54ae057b3d0eb62e8f81d5eef
+ return !(other instanceof MendingEnchantment) && super.checkCompatibility(other) || other instanceof MendingEnchantment && org.purpurmc.purpur.PurpurConfig.allowInfinityMending; // Purpur
}
}
-diff --git a/src/main/java/net/minecraft/world/item/enchantment/EnchantmentCategory.java b/src/main/java/net/minecraft/world/item/enchantment/EnchantmentCategory.java
-index afd74b274aa46b1e2187935ebeb2a8824a133867..4f8d8665cb90b746dc59913ec270839c4e5dba91 100644
---- a/src/main/java/net/minecraft/world/item/enchantment/EnchantmentCategory.java
-+++ b/src/main/java/net/minecraft/world/item/enchantment/EnchantmentCategory.java
-@@ -113,6 +113,20 @@ public enum EnchantmentCategory {
- public boolean canEnchant(Item item) {
- return item instanceof Vanishable || Block.byItem(item) instanceof Vanishable || BREAKABLE.canEnchant(item);
- }
-+ // Purpur start
-+ },
-+ BOW_AND_CROSSBOW {
-+ @Override
-+ public boolean canEnchant(Item item) {
-+ return item instanceof BowItem || item instanceof CrossbowItem;
-+ }
-+ },
-+ WEAPON_AND_SHEARS {
-+ @Override
-+ public boolean canEnchant(Item item) {
-+ return WEAPON.canEnchant(item) || item instanceof net.minecraft.world.item.ShearsItem;
-+ }
-+ // Purpur end
- };
-
- public abstract boolean canEnchant(Item item);
diff --git a/src/main/java/net/minecraft/world/item/enchantment/EnchantmentHelper.java b/src/main/java/net/minecraft/world/item/enchantment/EnchantmentHelper.java
-index 496a9b9b095bd322fba8229a5d47e2a0107aeb96..8ffa04b583da86a9aa6cabe7d978373825b82b32 100644
+index d2f0463b0e74983eb2e3dfca9a268e9502b86257..6d0363cec691996be416ab22ef9d825196399158 100644
--- a/src/main/java/net/minecraft/world/item/enchantment/EnchantmentHelper.java
+++ b/src/main/java/net/minecraft/world/item/enchantment/EnchantmentHelper.java
-@@ -47,7 +47,7 @@ public class EnchantmentHelper {
- }
-
- public static int getEnchantmentLevel(CompoundTag nbt) {
-- return Mth.clamp(nbt.getInt("lvl"), 0, 255);
-+ return Mth.clamp(nbt.getInt("lvl"), 0, (org.purpurmc.purpur.PurpurConfig.clampEnchantLevels) ? 255 : 32767); // Purpur
- }
-
- @Nullable
-@@ -266,6 +266,29 @@ public class EnchantmentHelper {
+@@ -237,6 +237,29 @@ public class EnchantmentHelper {
return getItemEnchantmentLevel(Enchantments.CHANNELING, stack) > 0;
}
@@ -14666,32 +14233,51 @@ index 496a9b9b095bd322fba8229a5d47e2a0107aeb96..8ffa04b583da86a9aa6cabe7d9783738
+ // Purpur end
+
@Nullable
- public static Entry