From 37621427cf938d4a80a0b1f48867e2848772fd46 Mon Sep 17 00:00:00 2001 From: IPECTER Date: Fri, 1 Sep 2023 02:13:54 +0900 Subject: [PATCH] 1.20.1 --- .github/workflows/build.yml | 4 +- .upstream-data | 4 +- README.md | 8 +- gradle.properties | 4 +- patches/api/0001-Pufferfish-API-Changes.patch | 14 +- patches/api/0002-Purpur-API-Changes.patch | 273 +- patches/api/0003-Plazma-Configurations.patch | 4 +- ...ecord-Chat-API-to-1.19-R0.1-SNAPSHOT.patch | 19 - ...ages.patch => 0004-Publish-Packages.patch} | 12 +- .../0001-Pufferfish-Server-Changes.patch | 517 +- .../server/0002-Purpur-Server-Changes.patch | 7940 +++++++++-------- patches/server/0003-MC-Dev-fixes.patch | 19 +- patches/server/0004-Rebrand.patch | 102 +- .../server/0006-Plazma-Configurations.patch | 93 +- ...0008-Optimize-Default-Configurations.patch | 52 +- .../server/0010-Implement-ChunkSending.patch | 52 +- patches/server/0012-Console-log-tweaks.patch | 2 +- ...14-Add-option-to-allow-any-usernames.patch | 4 +- ...-to-bypass-reducedDebugInfo-gamerule.patch | 28 +- ...missing-purpur-configuration-options.patch | 177 +- patches/server/0019-Misc-configuration.patch | 6 +- .../0020-Reduce-create-random-instance.patch | 61 +- .../server/0022-Various-Optimizations.patch | 23 +- ...n-to-disable-moved-to-quickly-check-.patch | 14 +- patches/server/0024-Apply-faster-random.patch | 18 +- ...5-Do-not-send-useless-entity-packets.patch | 14 +- .../0026-No-Chat-Reports-Configuration.patch | 4 +- .../0027-Implement-No-Chat-Reports.patch | 28 +- .../0028-FixMySpawnR-Configuration.patch | 4 +- .../server/0029-Implement-FixMySpawnR.patch | 6 +- patches/server/0031-Reduce-Sensor-Work.patch | 14 +- .../0032-Configurable-Sensor-Tick.patch | 18 +- patches/server/0033-Optimize-VarInts.patch | 4 +- ...034-Variable-entity-wakeup-duration.patch} | 12 +- ... => 0035-More-optimise-state-lookup.patch} | 6 +- ...-Suppress-Error-From-DirtyAttributes.patch | 8 +- .../server/0037-Implement-FerriteCore.patch | 10 +- .../0038-Let-Me-Despawn-Configuration.patch | 22 - .../0038-Skip-event-if-no-listeners.patch | 31 + .../0039-Implement-Let-Me-Despawn.patch | 74 - ...ns.patch => 0039-Reduce-allocations.patch} | 970 +- 41 files changed, 5560 insertions(+), 5115 deletions(-) delete mode 100644 patches/api/0004-Bump-Bungeecord-Chat-API-to-1.19-R0.1-SNAPSHOT.patch rename patches/api/{0005-Publish-Packages.patch => 0004-Publish-Packages.patch} (72%) rename patches/server/{0034-Variable-Entity-WakeUp-Duration.patch => 0034-Variable-entity-wakeup-duration.patch} (84%) rename patches/server/{0035-More-Optimise-State-Lookup.patch => 0035-More-optimise-state-lookup.patch} (94%) delete mode 100644 patches/server/0038-Let-Me-Despawn-Configuration.patch create mode 100644 patches/server/0038-Skip-event-if-no-listeners.patch delete mode 100644 patches/server/0039-Implement-Let-Me-Despawn.patch rename patches/server/{0040-Reduce-allocations.patch => 0039-Reduce-allocations.patch} (57%) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 18882c4..b8faa36 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,8 +7,8 @@ on: env: ORG_NAME: PlazmaMC - MC_VERSION: 1.19.4 - MAIN_BRANCH: ver/1.19.4 + MC_VERSION: 1.20.1 + MAIN_BRANCH: ver/1.20.1 DEBUG: 'false' jobs: diff --git a/.upstream-data b/.upstream-data index 86b715b..d2dd5b2 100644 --- a/.upstream-data +++ b/.upstream-data @@ -1,2 +1,2 @@ -purpurCommit = 68862729138c74fed22a97b582f399a9c6eb9d79 -pufferfishCommit = cadfa71a2eaef4581e1163ff63d07fc596145fa1 +purpurCommit = 423c2af60ca5e9d18ac0bd955d0313efc693d2a3 +pufferfishCommit = a3c0a4d2f177d80283d03de52617732a7b493665 diff --git a/README.md b/README.md index db446da..fe6442d 100644 --- a/README.md +++ b/README.md @@ -5,14 +5,14 @@ ### A Server Platform for Minecraft: Java Edition based on [Paper](https://github.com/PaperMC/Paper) [![WIP](https://img.shields.io/badge/Work%20In%20Progress-red?style=for-the-badge)](README.md) -[![Build Status](https://img.shields.io/github/actions/workflow/status/PlazmaMC/Plazma/build.yml?branch=ver/1.19.4&logo=GoogleAnalytics&style=for-the-badge&logoColor=ffffff)](https://github.com/PlazmaMC/Plazma/actions/workflows/build.yml?query=branch:ver/1.19.4) +[![Build Status](https://img.shields.io/github/actions/workflow/status/PlazmaMC/Plazma/build.yml?branch=ver/1.20.1&logo=GoogleAnalytics&style=for-the-badge&logoColor=ffffff)](https://github.com/PlazmaMC/Plazma/actions/workflows/build.yml?query=branch:ver/1.20.1) [![Upstream Status](https://img.shields.io/github/actions/workflow/status/PlazmaMC/AlwaysUpToDate/plazma.yml?label=Upstream&logo=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAACXBIWXMAAAsTAAALEwEAmpwYAAAGD0lEQVR4nO2dW4hVVRiAl5OjCFoMlpYx2WXMXjShi5FFTxFhhmFlQxlRU0kEXQiJorKIMoIiIoJegiiK8pKWZBTUg0ZpaHYhslBL8TKVTWWO00x98XP%2BicNhzt5rnb3P2WvtWd%2FjzDl7r%2FX%2F6%2FrfjjGRSCQSiUQikUgkEolEIpGIJwDHAHOA24CngTXA18Bu4BDwN3AUOAh8D3wOrAOeBLqBWUB70f0ICuBE4E7gXaCP7PwBrARuAqYU3T8vAdqB64EPgSGaxz%2F6joUyu8xoBzgOWAbsofXs0ndPNKMNoA24EThA8ezTPWZ0zAjgIt1IfWMbMM%2BUfJ1f3uQ1Po894rnSnZyAU3WEhcInwGmmDMi0BnozCGMA2KT3ADlKXgycAnQAY4HxwAnA6fouWc%2BfBzYCgxne%2BwtwgQkZ4Fq9KLlyBHgDWARMyPD%2BDr2QvamXNlf%2BAuabENGOu47AvcD9wOQmtOck4FG9NbsgfbjBhARwneNm26eCn9CCtk0EHtdZ5qKE%2BSEdM12WndVifiignbKPvOfQzsPA%2BSaA006vw%2Fq6pOD2jgHucRgw0rfpxkeAccBWBzPAHOMJMrIdBs4q4yNqArbhG2Ca8QxgBrDTov0yW8YaD9d9m013O3C88RRgmoUS%2Fm3FYcHVafKVhfB%2FAk42ngOcCfyc0I9txieApZYb7mwTCMBc4M8R%2BiGz%2FHLjC8CxlhebHhMYVDZmcXEO8wOwwPgEcJ%2BF8FebgAGmAp3GU%2FPyjxZLj5%2Fn5tBRH24aDxTdztICfGBhzp1UdDtLiYR3WJz7Hyy6naUFuCNF%2BGJ7n1p0O0uLRp8l8bYpIcAkYAXwKfAl8EzLg700pETCApPoNiUD6KpjppCTYFczXjimzt%2FPThH%2BULVHS00VfhmvGhO%2BeOvqsTc3JWgw7AagXx3i7wBnVf2%2FJ0UBn%2BnnZgLr9RniUfoYOM%2BUT%2Fj5KUGFP5IN5Dexj%2BhnniKZF9WWIt%2BppT8kJWAv%2FHyUoCM%2FyW8rgl2V0oiXU6KaPzLlFH42JejmKiM0CRHsfrIx6HscJo0LP7MSXCIFGkWU3GbKK%2FzGlaAZKM1mnSm%2F8BtTAnBGnc0zL%2BTZM8zoEH7DSpibU2rQiJu48RAqUXPNTBLZ4xT71AQleCt8AXid5vOacSFHJfgu%2FLYWHT4O17MuNFMJXgu%2FKqBMEjOy8Kve%2BNNMNO4mmQxK8F74wwBbEvoxoCmzafGtC1KUsMU0SgNKCEb4AnBZnVkwoIJ9KaW%2FK%2FQ59ZQgz77UZMFBCUEJfxjgSg09qY7iu1D%2FlxbzenPVc%2BapryD%2FcBYLJQQp%2FJoNuVOOpTXu17Q9YnadMMfO3G%2F9CZbO%2Fy2mZQJYYhF80FZE%2FORbmuS8T3OwvLzhZkX9IUmsyfySyMhIMLFF9MfSOl%2BPZAV4zCL6w9tw%2B6ChEnicFnywvuh2lhbgEdJZXHQ7SwkwXW03aXluQUd7eIlmTko0Rxp3G5%2BQ4hZVR9M%2B7cQsExhUyqWlccCrQk%2BaH3ywTr22YC5nwDkWgQnCLcYngFcTGisJbzON51AZRDJ709jqXVCBhTtvp4%2B5wTWVGr%2B1DKnxb0YDOywav8vHmUDFYPYddiw3PgK8YtmBXp9GEHCu5i%2FbsNnbUmZ6bk5Kbq5N9b%2FX2T%2Baf5t7LDdcNBrQv0zJaqS8l2ZF2vJ%2BERmUamCzOecPc8SnWZsIcIVjlax%2B4IlWJPNpoaaH9WhsixjbrjIBOjBcS5X1quUx95OSerQeaqBIrAj%2FahMiOhNclqPqTq%2FUHOTJGUf7Yr2Z267z1ch3FpmQ0T1B3HWNMqT1O18AbtdylV06osdrpn6Hlqu8RG6nwLOSoZOxXOX%2B4MtV1tiHRIihsNn7044rWlzV95LFg5p%2BOs6UFY2X8bF88RfBHDNziru5xqLKSiuQi%2BNdvqdLNQU9pSzT34JpNbu1VKU%2F9vyioJLEvVArr2SNUE5b4zdoRd%2FoRqyjjClaHV3O7r%2FnIHQJGV%2BrNe1i6IjjzGjXn6DqVlPFWq3ftkM9b0f10nZIfQ3bNX9ZkshvlVhN75wmkUgkEolEIpFIJBKJRCIRM5r5D9WH9bFOGhrhAAAAAElFTkSuQmCC&style=for-the-badge)](https://github.com/PlazmaMC/AlwaysUpToDate/actions/workflows/plazma.yml) [![License](https://img.shields.io/github/license/PlazmaMC/Plazma?logo=github&style=for-the-badge&logoColor=ffffff)](LICENSE) [![Discord](https://img.shields.io/discord/1083716853928558652?color=%235865F2&label=Discord&logo=discord&style=for-the-badge&logoColor=ffffff)](https://discord.gg/MmfC52K8A8) -[![MC Version](https://img.shields.io/badge/MC-1.19.4-6047ff?&logo=Webpack&style=for-the-badge&logoColor=ffffff)](https://github.com/PlazmaMC/Plazma/releases/latest-1.19.4) +[![MC Version](https://img.shields.io/badge/MC-1.20.1-6047ff?&logo=Webpack&style=for-the-badge&logoColor=ffffff)](https://github.com/PlazmaMC/Plazma/releases/latest-1.20.1) -[![Downloads](https://img.shields.io/github/downloads/PlazmaMC/Plazma/total?label=Downloads&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAbvSURBVHhe7Z3vixVlFMf3jj9KLC0tqAgJlIoQSjOIIqggwohsCylxrYzU1BfZf7D1IvoLsiIqCwxXqQzCF722N0a+sEKo0BXXosLW1QpX3dvnzHOuuD9m5pm7M/Pc2Xs+cHhmnjnPr/Ode3Zm7o/tqRvNZjMaGxvbgH2L/at2EOuTY+pmlAEBnkug91EmMYDNVnejaAj+my7OqfSru1EkBH8Bdk6DnMYwfvO0WcdTp5y5qtFozNftNBZi97vNzqdOAizS0ofFWnY8tRGAs7+hm5nk8Q2NXbYFxgQIjAkQGBMgMCZAYEyAwJgAgTEBAmMCBMYECIwJEBgTIDAmQGBMgMCYAIExAQJjAgTGBAiMCRAYEyAwJkBgTIDAmACBMQECYwIExgQIjAkQGBMgMCZAYEyAwJgAgTEBAmMCBMYECIwJEJjSBWg2m7PHxsZWYs9gj2AL9FDHIXPDHsV6sRUydz1UT1jEauyX+Nu7CvtnKfqxOermBf5rpb0na7WZF/jPYV5vYP+45g6ZO/aEutULJr4Ou6RrmQTHvqDwFgHfUgTAV37+4EvXbDIcu4g9p+71gHnfxKTlTE8Fn88p5mqzVPArXADGvwpLDP4VDGM3aLNCKeVvAJNd12g0rtHdRPDpxXdAAqFVlcG4Ivwe5rDG1aSyEP8+3S6Usv4I36NlJhqAPSww19+E6SDBx/Z6Br/FCi0LpSMuQyUQBERE8EpH00FebYwzwJhPaVVQyhLgsJbeEJDS05EK7Jt2JvK9loVSlgC7Wew53fZGA1NKOtIzP2/aiaHdMMWnbq9YShEgiqI/KDYx8Uuuxh8JEO0KTUf6qpIzP3faYR4XKV5lTaddTY1g4RuxiywiN7Tbr4GLoaqty1C25Tpf7jlyI3PHXtau6oksAEu8IUuDdnKNHqcjytwCUKbeZKVBOwn+Rumn9rCQV2RBurZc0C6+WcNyCUA7uclq98y/gNX7zJ8IC5puOpKfpfQC3/VY96adJGRhWLvp6JRuZoLvkG7mgnYzJ+0kwQLbTkdlwpxmXtpJQs6yThJB5tI1wW8hC8baSkdFosGf2WknCRYeNB0xdveknSTk7AshgozZ9cFvIYHAKktHGvzOTDvMT94fnUdZ6aNqxqwkHTFG5WmHYeUn9yWmyQ8ZcZBPLuzD/sbkN/mPY2/R6Hp1KR3GKzUdSd8yhg5XOoy1iGHfphzEJKansb3YSnVxUPEiNuXCqZfGS9W1dBirlHSk63tJhykdiRk26EYfD/Wj2IaWo5z5F/TYlHD8MEVln5FhvELTkawPqyztMKQ8BDziRp8ajp/H7hZn+a8TmeD8rPZfCYxXSDqSPqQv7bYSGNb3weGALPQv3UkFv53af2Uw5rTSEW0rTTstJFZuBung96dc6fj+Ln+e3+8vhCiKPqTYwlxzv7NGG3kna3Oj0fjY1VSKb6wWR0zQ67f2ff2KBhE+oMj19qb6blEBKydPTCu91m8XAvkRxWZ51bqaZDT4m0IFPy+1EEDwSUcci9OOClYLaiOAQGAlHa3HzsQV45G6vrqc+S28BeDs6oj/y0KA5SMrS7HXsU+o2kW5g3KZHIudApMrVlwKjdIgE/y+1iZGBsTqgIYtFfzOyytAPvXlw21aGikQVzn7b3d7mQyLACfddibLUKxjv17UKSCAfI9gidvLZEgEOOq20+GSVT4qmOurP13KGmLl+9zsqAjwndv2YgcKz9JtYwIam9fcnheH5A+GfBvQG/y3a2NjAhIbDZMX+C8X1eRrpCdcVTb4yn80vVfHNBTich/2n4tSNvjKt0cb8ixI7h53uW6ywX8+DQ/QwSqt6nok+BQHiM3VrsaL3fg34y0CuoROUt+UmYiojW1j0/tmbqbB2mcRg+0SizgonmjsbtZuHFS8r8dzQbsjmDy3v5HdjrhbLhNZo6wVk3ftUt/1SoJ272l3PZcDRqUocpSXRVvX+vQrqWwQ+5k+4u8IxwdmCKypwZKuZVNuspaw29ZbtPQxQts7sN9lf9wZiwhbOfCO7holgABboyh6V3fHC8DBCNuPCE9qlVEgGtte7HJ2mJSzcboOO4jTXVplFAAx/YHiQc7+EVfjmHQFQ+Dl4dzjNDjmaozpQiyPU6yeGHxhyktIHE8ixMM0/EmrjDbRM/8hiamrGU/iNTwCnMAeoIOvtMrICbHbTyFpJ/GJc+pNFAKcwZ6mI7nhOqvVRgbEakRiRux6p0o7V+J946T3Cf3YC3Sc55a7ayDo5ynksU4/gf8trszAW4AWCHELxTbseYSo7EO7nQyB/5XiM2wngT8VV3qSW4AWDCp3hsvZfAyTB3N3YrdiCxGm9J+dCQHrHaWQq8QhTN7IOoR9w3p/xNq48+/p+R+4L+/7RtGOvAAAAABJRU5ErkJggg==&style=flat-square&color=green)](https://github.com/PlazmaMC/Plazma/releases/tag/latest-1.19.4) +[![Downloads](https://img.shields.io/github/downloads/PlazmaMC/Plazma/total?label=Downloads&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAbvSURBVHhe7Z3vixVlFMf3jj9KLC0tqAgJlIoQSjOIIqggwohsCylxrYzU1BfZf7D1IvoLsiIqCwxXqQzCF722N0a+sEKo0BXXosLW1QpX3dvnzHOuuD9m5pm7M/Pc2Xs+cHhmnjnPr/Ode3Zm7o/tqRvNZjMaGxvbgH2L/at2EOuTY+pmlAEBnkug91EmMYDNVnejaAj+my7OqfSru1EkBH8Bdk6DnMYwfvO0WcdTp5y5qtFozNftNBZi97vNzqdOAizS0ofFWnY8tRGAs7+hm5nk8Q2NXbYFxgQIjAkQGBMgMCZAYEyAwJgAgTEBAmMCBMYECIwJEBgTIDAmQGBMgMCYAIExAQJjAgTGBAiMCRAYEyAwJkBgTIDAmACBMQECYwIExgQIjAkQGBMgMCZAYEyAwJgAgTEBAmMCBMYECIwJEJjSBWg2m7PHxsZWYs9gj2AL9FDHIXPDHsV6sRUydz1UT1jEauyX+Nu7CvtnKfqxOermBf5rpb0na7WZF/jPYV5vYP+45g6ZO/aEutULJr4Ou6RrmQTHvqDwFgHfUgTAV37+4EvXbDIcu4g9p+71gHnfxKTlTE8Fn88p5mqzVPArXADGvwpLDP4VDGM3aLNCKeVvAJNd12g0rtHdRPDpxXdAAqFVlcG4Ivwe5rDG1aSyEP8+3S6Usv4I36NlJhqAPSww19+E6SDBx/Z6Br/FCi0LpSMuQyUQBERE8EpH00FebYwzwJhPaVVQyhLgsJbeEJDS05EK7Jt2JvK9loVSlgC7Wew53fZGA1NKOtIzP2/aiaHdMMWnbq9YShEgiqI/KDYx8Uuuxh8JEO0KTUf6qpIzP3faYR4XKV5lTaddTY1g4RuxiywiN7Tbr4GLoaqty1C25Tpf7jlyI3PHXtau6oksAEu8IUuDdnKNHqcjytwCUKbeZKVBOwn+Rumn9rCQV2RBurZc0C6+WcNyCUA7uclq98y/gNX7zJ8IC5puOpKfpfQC3/VY96adJGRhWLvp6JRuZoLvkG7mgnYzJ+0kwQLbTkdlwpxmXtpJQs6yThJB5tI1wW8hC8baSkdFosGf2WknCRYeNB0xdveknSTk7AshgozZ9cFvIYHAKktHGvzOTDvMT94fnUdZ6aNqxqwkHTFG5WmHYeUn9yWmyQ8ZcZBPLuzD/sbkN/mPY2/R6Hp1KR3GKzUdSd8yhg5XOoy1iGHfphzEJKansb3YSnVxUPEiNuXCqZfGS9W1dBirlHSk63tJhykdiRk26EYfD/Wj2IaWo5z5F/TYlHD8MEVln5FhvELTkawPqyztMKQ8BDziRp8ajp/H7hZn+a8TmeD8rPZfCYxXSDqSPqQv7bYSGNb3weGALPQv3UkFv53af2Uw5rTSEW0rTTstJFZuBung96dc6fj+Ln+e3+8vhCiKPqTYwlxzv7NGG3kna3Oj0fjY1VSKb6wWR0zQ67f2ff2KBhE+oMj19qb6blEBKydPTCu91m8XAvkRxWZ51bqaZDT4m0IFPy+1EEDwSUcci9OOClYLaiOAQGAlHa3HzsQV45G6vrqc+S28BeDs6oj/y0KA5SMrS7HXsU+o2kW5g3KZHIudApMrVlwKjdIgE/y+1iZGBsTqgIYtFfzOyytAPvXlw21aGikQVzn7b3d7mQyLACfddibLUKxjv17UKSCAfI9gidvLZEgEOOq20+GSVT4qmOurP13KGmLl+9zsqAjwndv2YgcKz9JtYwIam9fcnheH5A+GfBvQG/y3a2NjAhIbDZMX+C8X1eRrpCdcVTb4yn80vVfHNBTich/2n4tSNvjKt0cb8ixI7h53uW6ywX8+DQ/QwSqt6nok+BQHiM3VrsaL3fg34y0CuoROUt+UmYiojW1j0/tmbqbB2mcRg+0SizgonmjsbtZuHFS8r8dzQbsjmDy3v5HdjrhbLhNZo6wVk3ftUt/1SoJ272l3PZcDRqUocpSXRVvX+vQrqWwQ+5k+4u8IxwdmCKypwZKuZVNuspaw29ZbtPQxQts7sN9lf9wZiwhbOfCO7holgABboyh6V3fHC8DBCNuPCE9qlVEgGtte7HJ2mJSzcboOO4jTXVplFAAx/YHiQc7+EVfjmHQFQ+Dl4dzjNDjmaozpQiyPU6yeGHxhyktIHE8ixMM0/EmrjDbRM/8hiamrGU/iNTwCnMAeoIOvtMrICbHbTyFpJ/GJc+pNFAKcwZ6mI7nhOqvVRgbEakRiRux6p0o7V+J946T3Cf3YC3Sc55a7ayDo5ynksU4/gf8trszAW4AWCHELxTbseYSo7EO7nQyB/5XiM2wngT8VV3qSW4AWDCp3hsvZfAyTB3N3YrdiCxGm9J+dCQHrHaWQq8QhTN7IOoR9w3p/xNq48+/p+R+4L+/7RtGOvAAAAABJRU5ErkJggg==&style=flat-square&color=green)](https://github.com/PlazmaMC/Plazma/releases/tag/latest-1.20.1) [![Stargazers](https://img.shields.io/github/stars/PlazmaMC/Plazma?label=stars&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABhWlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9bxSIVh1YQcYhQnSyIiuimVShChVArtOpgcukXNGlIUlwcBdeCgx+LVQcXZ10dXAVB8APE0clJ0UVK/F9SaBHjwXE/3t173L0D/PUyU82OMUDVLCOViAuZ7KrQ9YogwujDEGYkZupzopiE5/i6h4+vdzGe5X3uz9Gj5EwG+ATiWaYbFvEG8dSmpXPeJ46woqQQnxOPGnRB4keuyy6/cS447OeZESOdmieOEAuFNpbbmBUNlXiSOKqoGuX7My4rnLc4q+Uqa96TvzCU01aWuU5zEAksYgkiBMioooQyLMRo1UgxkaL9uId/wPGL5JLJVQIjxwIqUCE5fvA/+N2tmZ8Yd5NCcaDzxbY/hoGuXaBRs+3vY9tunACBZ+BKa/krdWD6k/RaS4seAb3bwMV1S5P3gMsdoP9JlwzJkQI0/fk88H5G35QFwrdA95rbW3Mfpw9AmrpK3gAHh8BIgbLXPd4dbO/t3zPN/n4Ax9dyyerighsAAAAGYktHRAAAAAAAAPlDu38AAAAJcEhZcwAADdcAAA3XAUIom3gAAAAHdElNRQfmCBMVNjtc7/hFAAABIElEQVQ4y62SzS5DURSFv6smXkAUCRU0UdKYGNTPyCsYYOYFGGi8Ao9QM0PxCh6CgQ4qfiLpBFEjdKCfySaXtDch1uScs9Ze62TvcyAD6o66zV+gjqpvalsd61XXl5GxBySx3/3t7UPqi1pTD9VXdaRbbZIyDQLTwBSwBqzGGaABnAInwCXQSJLk/tO4orb8jra6nwo/CC6NlrqMOq421Y5aVSfUXJe2cqFVo7b5NdwIuVaf1IWM2cyrD+qdOvlTLERIS53pYi6FdqMWet2wGP1tdNE2Q1vK+gfDsdbDlFfzwV3Ems8KmAXegcd4hSvgVq0Bz6GV0ob+HgF1YAA4Cn4LWA9tLusHnscTHavFFF8MrqOeZQVU1HKGXlYr/Cc+AKuOI2h/Jrf7AAAAAElFTkSuQmCC&style=flat-square&color=green)](https://github.com/PlazmaMC/Plazma/stargazers) [![Forks](https://img.shields.io/github/forks/PlazmaMC/Plazma?label=forks&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABhWlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9bxSIVh1YQcYhQnSyIiuimVShChVArtOpgcukXNGlIUlwcBdeCgx+LVQcXZ10dXAVB8APE0clJ0UVK/F9SaBHjwXE/3t173L0D/PUyU82OMUDVLCOViAuZ7KrQ9YogwujDEGYkZupzopiE5/i6h4+vdzGe5X3uz9Gj5EwG+ATiWaYbFvEG8dSmpXPeJ46woqQQnxOPGnRB4keuyy6/cS447OeZESOdmieOEAuFNpbbmBUNlXiSOKqoGuX7My4rnLc4q+Uqa96TvzCU01aWuU5zEAksYgkiBMioooQyLMRo1UgxkaL9uId/wPGL5JLJVQIjxwIqUCE5fvA/+N2tmZ8Yd5NCcaDzxbY/hoGuXaBRs+3vY9tunACBZ+BKa/krdWD6k/RaS4seAb3bwMV1S5P3gMsdoP9JlwzJkQI0/fk88H5G35QFwrdA95rbW3Mfpw9AmrpK3gAHh8BIgbLXPd4dbO/t3zPN/n4Ax9dyyerighsAAAAGYktHRAAAAAAAAPlDu38AAAAJcEhZcwAADdcAAA3XAUIom3gAAAAHdElNRQfmCBMVNCYN3/YeAAAA/UlEQVQ4y7WTQUoDQRBFf01czlJcxUyOINGjjAvFHMFzZGdygOwDwTtk6UZcqLlAxCAuMigug89FamIzdAIN+qGhq/6v6qrqbumvAJwBj8AHMAQs4DJgBHy65jSW4Bl4AaZsUAbcufumrnmquSzIcSzpTtLA7XbA1fuBa9qxCob8YgUUAdcFqoC/iSXIgLELOhG+49w4nM+2BTP7ljR3M4/MufbNzYxdN1E0Sm2ialZnsVIllZKOJF24eyLpXdKtmS1S3sYMmO3THOwJziUdbrbkZvaVcnILeAh6vweylAQ9D7z2BXCS0sJS0lrSpdtrSW+pn6sPLIFX4Er/hR9C0wl1FTBzNwAAAABJRU5ErkJggg==&style=flat-square&color=green)](https://github.com/PPlazmaMC/Plazma/network/members) [![Watchers](https://img.shields.io/github/watchers/PlazmaMC/Plazma?label=watchers&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABhWlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9bxSIVh1YQcYhQnSyIiuimVShChVArtOpgcukXNGlIUlwcBdeCgx+LVQcXZ10dXAVB8APE0clJ0UVK/F9SaBHjwXE/3t173L0D/PUyU82OMUDVLCOViAuZ7KrQ9YogwujDEGYkZupzopiE5/i6h4+vdzGe5X3uz9Gj5EwG+ATiWaYbFvEG8dSmpXPeJ46woqQQnxOPGnRB4keuyy6/cS447OeZESOdmieOEAuFNpbbmBUNlXiSOKqoGuX7My4rnLc4q+Uqa96TvzCU01aWuU5zEAksYgkiBMioooQyLMRo1UgxkaL9uId/wPGL5JLJVQIjxwIqUCE5fvA/+N2tmZ8Yd5NCcaDzxbY/hoGuXaBRs+3vY9tunACBZ+BKa/krdWD6k/RaS4seAb3bwMV1S5P3gMsdoP9JlwzJkQI0/fk88H5G35QFwrdA95rbW3Mfpw9AmrpK3gAHh8BIgbLXPd4dbO/t3zPN/n4Ax9dyyerighsAAAAGYktHRAAAAAAAAPlDu38AAAAJcEhZcwAADdcAAA3XAUIom3gAAAAHdElNRQfmCBMVNw4TRw0nAAAA3UlEQVQ4y83SP04CURAG8I0lewHOwAFUaiwkdmAlp8CL4FHopfIvtOIJWE3opIBK489mQPKy6xYWOskkL9/MN/PNzMuyf2fIcYkZVuGzwPI68gle8Yl7jMIfAntBp4o8wAeecFgSP8I8cgZp8DwC12j8oLCBCd7R34ItbHCzT8ZZSC7QTYrcYo1WhjGWaCbdCt+2SGLN4IwPfnu07QjrkhG6oWKB0+TMd7sRAuzHYuqWmO8tsVd1xjmOS8htPEfORVWHTmweHnEVPg2sqPxIicxhFFjhLd7D2q/8J/YFHSJt9VSqQ08AAAAASUVORK5CYII=&style=flat-square&color=green)](https://github.com/PlazmaMC/Plazma/watchers) @@ -33,7 +33,7 @@ ## ⬇️ Downloads - You can download the file from [Releases](https://github.com/PlazmaMC/Plazma/releases) -- Direct latest download: [Click here](https://github.com/PlazmaMC/Plazma/releases/download/latest-1.19.4/plazma-paperclip-1.19.4-R0.1-SNAPSHOT-reobf.jar) +- Direct latest download: [Click here](https://github.com/PlazmaMC/Plazma/releases/download/latest-1.20.1/plazma-paperclip-1.20.1-R0.1-SNAPSHOT-reobf.jar) - NOTE: If you don't know about Mojmap or Bundler, download `plazma-paperclip-*-reobf.jar` ## ⚖️ License diff --git a/gradle.properties b/gradle.properties index 8897c61..0dcc876 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ group = org.plazmamc.plazma -version = 1.19.4-R0.1-SNAPSHOT +version = 1.20.1-R0.1-SNAPSHOT -paperCommit = 483368e480eb2ec060d8e68b30e14ec96aba6c4e +paperCommit = b4e3b3d1dd447bac4cbf478595c1ec320bc6dd4b org.gradle.caching = true org.gradle.parallel = true diff --git a/patches/api/0001-Pufferfish-API-Changes.patch b/patches/api/0001-Pufferfish-API-Changes.patch index 75647a4..44ed550 100644 --- a/patches/api/0001-Pufferfish-API-Changes.patch +++ b/patches/api/0001-Pufferfish-API-Changes.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: AlphaKR93 -Date: Sun, 4 Jun 2023 07:49:45 +0000 +From: Kevin Raneri +Date: Tue, 9 Nov 2021 14:01:56 -0500 Subject: [PATCH] Pufferfish API Changes Original: Kevin Raneri @@ -20,18 +20,18 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . diff --git a/build.gradle.kts b/build.gradle.kts -index 279a666e8ea2c07f41ee3f28b768e95dca5f0a10..a93b900889ddb56a2943c54a7fff6f60f42a78f1 100644 +index 8045f92ffdfb4164bcbef99c41359590c45f9006..3676035ba011fb874ad6bb8995940d9bb2a0f0ae 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -42,6 +42,7 @@ dependencies { +@@ -46,6 +46,7 @@ dependencies { apiAndDocs("net.kyori:adventure-text-logger-slf4j") - api("org.apache.logging.log4j:log4j-api:2.17.1") - api("org.slf4j:slf4j-api:1.8.0-beta4") + api("org.apache.logging.log4j:log4j-api:$log4jVersion") + api("org.slf4j:slf4j-api:$slf4jVersion") + api("io.sentry:sentry:5.4.0") // Pufferfish implementation("org.ow2.asm:asm:9.4") implementation("org.ow2.asm:asm-commons:9.4") -@@ -85,6 +86,13 @@ val generateApiVersioningFile by tasks.registering { +@@ -89,6 +90,13 @@ val generateApiVersioningFile by tasks.registering { } } diff --git a/patches/api/0002-Purpur-API-Changes.patch b/patches/api/0002-Purpur-API-Changes.patch index 65b4c3c..ce79c45 100644 --- a/patches/api/0002-Purpur-API-Changes.patch +++ b/patches/api/0002-Purpur-API-Changes.patch @@ -25,10 +25,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/build.gradle.kts b/build.gradle.kts -index a93b900889ddb56a2943c54a7fff6f60f42a78f1..417c4324af22c870de669e338a1eee5d540184a4 100644 +index 3676035ba011fb874ad6bb8995940d9bb2a0f0ae..0c557f34ed438980c6fd9d6a8bce7c1152468735 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -105,6 +105,8 @@ tasks.jar { +@@ -109,6 +109,8 @@ tasks.jar { } tasks.withType { @@ -209,10 +209,10 @@ index a736d7bcdc5861a01b66ba36158db1c716339346..22fc165fd9c95f0f3ae1be7a0857e48c @Override diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index b0bc2df41506770e2854a287813f1c53f003eda1..a2f617537292e3bac52d665a6e51b7d4ce4a227e 100644 +index f78b5fd3c3347d28da58777bff88903d2eb140f6..584e3b08935f43beb27f478cc72229b6a5f40689 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java -@@ -2483,4 +2483,127 @@ public final class Bukkit { +@@ -2756,4 +2756,127 @@ public final class Bukkit { public static Server.Spigot spigot() { return server.spigot(); } @@ -341,7 +341,7 @@ index b0bc2df41506770e2854a287813f1c53f003eda1..a2f617537292e3bac52d665a6e51b7d4 + // Purpur end } diff --git a/src/main/java/org/bukkit/ChatColor.java b/src/main/java/org/bukkit/ChatColor.java -index ea4ceb643239c26851bacbf45fc3f2efef3bb4be..3b8395dcb73e3fb251adf7438cbc7e95c4185a3a 100644 +index 918a045165cdcde264bc24082b7afebb407271de..687d11619379aead7f665d4a5f8f8bcc857cb8e9 100644 --- a/src/main/java/org/bukkit/ChatColor.java +++ b/src/main/java/org/bukkit/ChatColor.java @@ -3,6 +3,7 @@ package org.bukkit; @@ -352,7 +352,7 @@ index ea4ceb643239c26851bacbf45fc3f2efef3bb4be..3b8395dcb73e3fb251adf7438cbc7e95 import java.util.regex.Pattern; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; -@@ -455,4 +456,77 @@ public enum ChatColor { +@@ -456,4 +457,77 @@ public enum ChatColor { BY_CHAR.put(color.code, color); } } @@ -431,10 +431,10 @@ index ea4ceb643239c26851bacbf45fc3f2efef3bb4be..3b8395dcb73e3fb251adf7438cbc7e95 + // Purpur end } diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java -index 9b290969b0e60f20450cd15e3fc6f37276f12ae6..77a885fd17f280649b95df758f1096fa38fe8d69 100644 +index 03b47012447430a350e152920f754d993d4023db..3ad843d519e239430c5f4f5754a8da3026ed0f8e 100644 --- a/src/main/java/org/bukkit/Material.java +++ b/src/main/java/org/bukkit/Material.java -@@ -11166,4 +11166,40 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla +@@ -11047,4 +11047,40 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla public boolean isEnabledByFeature(@NotNull World world) { return Bukkit.getDataPackManager().isEnabledByFeature(this, world); } @@ -476,10 +476,10 @@ index 9b290969b0e60f20450cd15e3fc6f37276f12ae6..77a885fd17f280649b95df758f1096fa + // Purpur end } diff --git a/src/main/java/org/bukkit/OfflinePlayer.java b/src/main/java/org/bukkit/OfflinePlayer.java -index 72175dcae49f75b494ab70958053ed994a8828f4..df642a55003517040be795b44a8bf107dd88810b 100644 +index bce07d84cafca677bb6fad78c21b82097f06430c..4ef0fa4f1ef72bb784674671473c6a322acadecc 100644 --- a/src/main/java/org/bukkit/OfflinePlayer.java +++ b/src/main/java/org/bukkit/OfflinePlayer.java -@@ -460,4 +460,114 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio +@@ -522,4 +522,114 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio */ @Nullable public Location getLastDeathLocation(); @@ -595,10 +595,10 @@ index 72175dcae49f75b494ab70958053ed994a8828f4..df642a55003517040be795b44a8bf107 + // Purpur end - OfflinePlayer API } diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 1d1a1d087dabc9794e0062a064da2cced4062309..96160bced90bb4cd84e48c85c645cad0eb672b85 100644 +index 8d8fe04e6b09d2a5b1cc05002073df5c58cdcb96..aaef58468a3c31f35e5067ed4263e9dd3fbddddd 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -1994,6 +1994,18 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2121,6 +2121,18 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi } // Paper end @@ -617,10 +617,10 @@ index 1d1a1d087dabc9794e0062a064da2cced4062309..96160bced90bb4cd84e48c85c645cad0 /** * Sends the component to the player * -@@ -2162,4 +2174,105 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2404,4 +2416,105 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi */ - @NotNull org.bukkit.potion.PotionBrewer getPotionBrewer(); - // Paper end + boolean isOwnedByCurrentRegion(@NotNull Entity entity); + // Paper end - Folia region threading API + + // Purpur start + /** @@ -724,10 +724,10 @@ index 1d1a1d087dabc9794e0062a064da2cced4062309..96160bced90bb4cd84e48c85c645cad0 + // Purpur end } diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index 72f1576b8ce5b55b50f053f346ce42c52db4b568..adf8169d5baefa7a33c33ef066180a8116617756 100644 +index 6917931966377c51db88a3364997a110dd987970..bf39c6602cfca70a6352519fa26059cd79143cdd 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java -@@ -3974,6 +3974,86 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient +@@ -3992,6 +3992,86 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient @Nullable public DragonBattle getEnderDragonBattle(); @@ -814,6 +814,35 @@ index 72f1576b8ce5b55b50f053f346ce42c52db4b568..adf8169d5baefa7a33c33ef066180a81 /** * Get all {@link FeatureFlag} enabled in this world. * +diff --git a/src/main/java/org/bukkit/block/EntityBlockStorage.java b/src/main/java/org/bukkit/block/EntityBlockStorage.java +index 739911cda33b373f99df627a3a378b37d7d461aa..51e78c22cd021722b963fe31d1d9175d141add1a 100644 +--- a/src/main/java/org/bukkit/block/EntityBlockStorage.java ++++ b/src/main/java/org/bukkit/block/EntityBlockStorage.java +@@ -47,6 +47,24 @@ public interface EntityBlockStorage extends TileState { + @NotNull + List releaseEntities(); + ++ // Purpur start ++ /** ++ * Releases a stored entity, and returns the entity in the world. ++ * ++ * @param entity Entity to release ++ * @return The entity which was released, or null if the stored entity is not in the hive ++ */ ++ @org.jetbrains.annotations.Nullable ++ T releaseEntity(@NotNull org.purpurmc.purpur.entity.StoredEntity entity); ++ ++ /** ++ * Gets all the entities currently stored in the block. ++ * ++ * @return List of all entities which are stored in the block ++ */ ++ @NotNull ++ List> getEntities(); ++ //Purpur end + /** + * 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..5349f16136d9348c374a7dfe5b89a71dfcb0e66d 100644 --- a/src/main/java/org/bukkit/command/SimpleCommandMap.java @@ -853,38 +882,38 @@ index ac9a28922f8a556944a4c3649d74c32c622f0cb0..5349f16136d9348c374a7dfe5b89a71d server.getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerCommandException(ex, target, sender, args))); // Paper //target.timings.stopTiming(); // Spigot // Paper diff --git a/src/main/java/org/bukkit/command/defaults/VersionCommand.java b/src/main/java/org/bukkit/command/defaults/VersionCommand.java -index e40f017f87d6b6b4770501b106c76dc69ec69abb..eac5830986cd0638950bbb1e6f10a30e246e09a7 100644 +index fd5d9881abfd930bb883120f018f76dc78b62b14..d3dadad49df09e85c724c93e8cc88da2c985e9b4 100644 --- a/src/main/java/org/bukkit/command/defaults/VersionCommand.java +++ b/src/main/java/org/bukkit/command/defaults/VersionCommand.java -@@ -198,7 +198,7 @@ public class VersionCommand extends BukkitCommand { +@@ -214,7 +214,7 @@ public class VersionCommand extends BukkitCommand { String version = Bukkit.getVersion(); // Paper start if (version.startsWith("null")) { // running from ide? -- setVersionMessage(net.kyori.adventure.text.Component.text("Unknown version, custom build?", net.kyori.adventure.text.format.NamedTextColor.YELLOW)); -+ setVersionMessage(net.kyori.adventure.text.Component.text("* Unknown version, custom build?", net.kyori.adventure.text.format.NamedTextColor.RED)); // Purpur +- setVersionMessage(Component.text("Unknown version, custom build?", NamedTextColor.YELLOW)); ++ setVersionMessage(Component.text("* Unknown version, custom build?", NamedTextColor.RED)); // Purpur return; } setVersionMessage(getVersionFetcher().getVersionMessage(version)); -@@ -239,9 +239,11 @@ public class VersionCommand extends BukkitCommand { +@@ -255,9 +255,11 @@ public class VersionCommand extends BukkitCommand { // Paper start - private void setVersionMessage(final @NotNull net.kyori.adventure.text.Component msg) { + private void setVersionMessage(final @NotNull Component msg) { lastCheck = System.currentTimeMillis(); -- final net.kyori.adventure.text.Component message = net.kyori.adventure.text.TextComponent.ofChildren( -- net.kyori.adventure.text.Component.text(Bukkit.getVersionMessage(), net.kyori.adventure.text.format.NamedTextColor.WHITE), -- net.kyori.adventure.text.Component.newline(), +- final Component message = Component.textOfChildren( +- Component.text(Bukkit.getVersionMessage(), NamedTextColor.WHITE), +- Component.newline(), + // Purpur start + int distance = getVersionFetcher().distance(); -+ final net.kyori.adventure.text.Component message = net.kyori.adventure.text.Component.join(net.kyori.adventure.text.JoinConfiguration.separator(net.kyori.adventure.text.Component.newline()), ++ final Component message = Component.join(net.kyori.adventure.text.JoinConfiguration.separator(Component.newline()), + ChatColor.parseMM("Current: %s%s*", distance == 0 ? "" : distance > 0 ? "" : "", Bukkit.getVersion()), + // Purpur end msg ); - this.versionMessage = net.kyori.adventure.text.Component.text() + this.versionMessage = Component.text() diff --git a/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java b/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java -index bea786a8be4402f9384984e48390e745f2988dd6..5eb81fcc18b8fdec5a0e4c699525281fa6ad4d78 100644 +index 455ff52d90565838fe7640c3f045b27082a6c2f1..45f5493eebfecf56b7c0ef4659c078dfc62c0612 100644 --- a/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java +++ b/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java -@@ -228,6 +228,28 @@ public enum EnchantmentTarget { +@@ -227,6 +227,28 @@ public enum EnchantmentTarget { public boolean includes(@NotNull Material item) { return BREAKABLE.includes(item) || (WEARABLE.includes(item) && !item.equals(Material.ELYTRA)) || item.equals(Material.COMPASS); } @@ -948,13 +977,13 @@ 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 a2a423d4e4c2702ba5967223cab0432dd7d04732..cc78ce7de88a9a404ed20d5bc61b98d3107f29b3 100644 +index 762cb07861ca8ff058ce8d57ea6c15df1e588bf3..98de85d1382fe84cdc2e2c9db04bf1b4f157291c 100644 --- a/src/main/java/org/bukkit/entity/Entity.java +++ b/src/main/java/org/bukkit/entity/Entity.java -@@ -954,4 +954,55 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent +@@ -1049,4 +1049,55 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent */ - boolean wouldCollideUsing(@NotNull BoundingBox boundingBox); - // Paper End - Collision API + @NotNull String getScoreboardEntryName(); + // Paper end - entity scoreboard name + + // Purpur start + /** @@ -1100,10 +1129,10 @@ index 58017fce436cdbda255f7172fbdadb726d4b113c..05600fc8bf2a61aca8094029bc4c208a + // Purpur end } diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java -index ffca32ae2464ea5a669029079a50585ca259a4f8..654dc0c6d98b29cf45d3826aece374726e3e9802 100644 +index 19e58e62ae442ef9be02ca7fa2f55e370a54afa4..994e026d68fcda9a4c34a8b161a06623f4437dff 100644 --- a/src/main/java/org/bukkit/entity/LivingEntity.java +++ b/src/main/java/org/bukkit/entity/LivingEntity.java -@@ -1150,4 +1150,41 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource +@@ -1192,4 +1192,41 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource */ void setBodyYaw(float bodyYaw); // Paper end @@ -1171,10 +1200,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 88c4885569d2b8b22fce55601d50608ac8e9388c..dc437885404ae147a06cac653e519a4674a9a951 100644 +index f9dd00210c1762a40259f823aeb8d8a5ddc78e3e..9193288438671409cc3cf92033ef7cb60d798b69 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3068,4 +3068,139 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3271,4 +3271,143 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM @Override Spigot spigot(); // Spigot end @@ -1310,8 +1339,12 @@ index 88c4885569d2b8b22fce55601d50608ac8e9388c..dc437885404ae147a06cac653e519a46 + * + * @param message The death message to show the player + * @param killer The entity that killed the player ++ * @deprecated Use {@link #sendDeathScreen(net.kyori.adventure.text.Component)} instead, as 1.20 removed the killer ID from the packet. + */ -+ void sendDeathScreen(@NotNull net.kyori.adventure.text.Component message, @Nullable Entity killer); ++ @Deprecated(since = "1.20") ++ default void sendDeathScreen(@NotNull net.kyori.adventure.text.Component message, @Nullable Entity killer) { ++ sendDeathScreen(message); ++ } + // Purpur end } diff --git a/src/main/java/org/bukkit/entity/Snowman.java b/src/main/java/org/bukkit/entity/Snowman.java @@ -1426,10 +1459,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 a8e631315f2da68895a258cf0ba9875bc88fc48c..d5648ec745e3530aecf18c3e1f3185a5f63f3d11 100644 +index cbce826add9dc2b3187c7bea00c27b785d7517df..3a98de6407d9a6307f89c207be1f09e639385ebe 100644 --- a/src/main/java/org/bukkit/event/inventory/InventoryType.java +++ b/src/main/java/org/bukkit/event/inventory/InventoryType.java -@@ -155,7 +155,7 @@ public enum InventoryType { +@@ -151,7 +151,7 @@ public enum InventoryType { SMITHING_NEW(4, "Upgrade Gear"), ; @@ -2153,6 +2186,23 @@ index 523818cbb0d6c90481ec97123e7fe0e2ff4eea14..bfeb8171a723d84b94bfaacd8aaf7d4d @Override public int hashCode() { int hash = 7; +diff --git a/src/main/java/org/bukkit/map/MapRenderer.java b/src/main/java/org/bukkit/map/MapRenderer.java +index cb7040876a99a5a7e49b81684ef0f3b79584c376..22d8f31b1b8a5dbb5ab3275068642937c097abfe 100644 +--- a/src/main/java/org/bukkit/map/MapRenderer.java ++++ b/src/main/java/org/bukkit/map/MapRenderer.java +@@ -54,4 +54,12 @@ public abstract class MapRenderer { + */ + public abstract void render(@NotNull MapView map, @NotNull MapCanvas canvas, @NotNull Player player); + ++ // Purpur - start ++ /** ++ * Check if this is an explorer (aka treasure) map. ++ * ++ * @return True if explorer map ++ */ ++ public abstract boolean isExplorerMap(); ++ // Purpur - end + } diff --git a/src/main/java/org/bukkit/permissions/PermissibleBase.java b/src/main/java/org/bukkit/permissions/PermissibleBase.java index cd3296fea01648592d2af89b3d80135acb6d0958..45797a6fbae1d8edc4211cb30def24ad4f59bd49 100644 --- a/src/main/java/org/bukkit/permissions/PermissibleBase.java @@ -2585,6 +2635,64 @@ index 0000000000000000000000000000000000000000..baec4c87d7ea4d54934ca22fd1eb7b46 + return purpur; + } +} +diff --git a/src/main/java/org/purpurmc/purpur/entity/StoredEntity.java b/src/main/java/org/purpurmc/purpur/entity/StoredEntity.java +new file mode 100644 +index 0000000000000000000000000000000000000000..29540d55532197d2381a52ea9222b5785d224ef8 +--- /dev/null ++++ b/src/main/java/org/purpurmc/purpur/entity/StoredEntity.java +@@ -0,0 +1,52 @@ ++package org.purpurmc.purpur.entity; ++ ++import org.bukkit.Nameable; ++import org.bukkit.block.EntityBlockStorage; ++import org.bukkit.entity.Entity; ++import org.bukkit.entity.EntityType; ++import org.bukkit.persistence.PersistentDataHolder; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; ++ ++/** ++ * Represents an entity stored in a block ++ * ++ * @see org.bukkit.block.EntityBlockStorage ++ */ ++public interface StoredEntity extends PersistentDataHolder, Nameable { ++ /** ++ * Checks if this entity has been released yet ++ * ++ * @return if this entity has been released ++ */ ++ boolean hasBeenReleased(); ++ ++ /** ++ * Releases the entity from its stored block ++ * ++ * @return the released entity, or null if unsuccessful (including if this entity has already been released) ++ */ ++ @Nullable ++ T release(); ++ ++ /** ++ * Returns the block in which this entity is stored ++ * ++ * @return the EntityBlockStorage in which this entity is stored, or null if it has been released ++ */ ++ @Nullable ++ EntityBlockStorage getBlockStorage(); ++ ++ /** ++ * Gets the entity type of this stored entity ++ * ++ * @return the type of entity this stored entity represents ++ */ ++ @NotNull ++ EntityType getType(); ++ ++ /** ++ * Writes data to the block entity snapshot. {@link EntityBlockStorage#update()} must be run in order to update the block in game. ++ */ ++ void update(); ++} diff --git a/src/main/java/org/purpurmc/purpur/event/ExecuteCommandEvent.java b/src/main/java/org/purpurmc/purpur/event/ExecuteCommandEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..bc590c4d49d32f4365a50ceb5785e798702a8179 @@ -2890,17 +2998,19 @@ 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..b7db0db7f3afbccdb07390d1bcada109e9e6b30b +index 0000000000000000000000000000000000000000..32602b398ede24a35ed8a996faa2b23455615a7b --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/event/PreBlockExplodeEvent.java -@@ -0,0 +1,52 @@ +@@ -0,0 +1,54 @@ +package org.purpurmc.purpur.event; + +import org.bukkit.block.Block; ++import org.bukkit.block.BlockState; +import org.bukkit.event.Cancellable; +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; + +/** @@ -2911,8 +3021,8 @@ index 0000000000000000000000000000000000000000..b7db0db7f3afbccdb07390d1bcada109 + private boolean cancelled; + private final float yield; + -+ public PreBlockExplodeEvent(@NotNull final Block what, final float yield) { -+ super(what, Collections.emptyList(), yield); ++ public PreBlockExplodeEvent(@NotNull final Block what, final float yield, @Nullable BlockState explodedBlockState) { ++ super(what, Collections.emptyList(), yield, explodedBlockState); + this.yield = yield; + this.cancelled = false; + } @@ -3414,79 +3524,6 @@ index 0000000000000000000000000000000000000000..c268c35b541a222d50875c29770c846a + return handlers; + } +} -diff --git a/src/main/java/org/purpurmc/purpur/event/entity/MonsterEggSpawnEvent.java b/src/main/java/org/purpurmc/purpur/event/entity/MonsterEggSpawnEvent.java -new file mode 100644 -index 0000000000000000000000000000000000000000..82f8a0ea22f07954d516935fc9f73f6aa0f65aa6 ---- /dev/null -+++ b/src/main/java/org/purpurmc/purpur/event/entity/MonsterEggSpawnEvent.java -@@ -0,0 +1,67 @@ -+package org.purpurmc.purpur.event.entity; -+ -+import org.bukkit.entity.Entity; -+import org.bukkit.entity.HumanEntity; -+import org.bukkit.entity.Player; -+import org.bukkit.event.Cancellable; -+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; -+ -+public class MonsterEggSpawnEvent extends Event implements Cancellable { -+ private static final HandlerList handlers = new HandlerList(); -+ private boolean canceled; -+ -+ private final Player player; -+ private Entity entity; -+ private final ItemStack item; -+ -+ public MonsterEggSpawnEvent(@Nullable HumanEntity player, @NotNull Entity entity, @NotNull ItemStack item) { -+ this.player = (Player) player; -+ this.entity = entity; -+ this.item = item; -+ } -+ -+ @Nullable -+ public Player getPlayer() { -+ return player; -+ } -+ -+ @NotNull -+ public Entity getEntity() { -+ return entity; -+ } -+ -+ public void setEntity(@Nullable Entity entity) { -+ if (entity == null) { -+ canceled = true; -+ return; -+ } -+ this.entity = entity; -+ } -+ -+ @NotNull -+ public ItemStack getItem() { -+ return item; -+ } -+ -+ public boolean isCancelled() { -+ return canceled; -+ } -+ -+ public void setCancelled(boolean cancel) { -+ canceled = cancel; -+ } -+ -+ @NotNull -+ public HandlerList getHandlers() { -+ return handlers; -+ } -+ -+ @NotNull -+ public static HandlerList getHandlerList() { -+ return handlers; -+ } -+} diff --git a/src/main/java/org/purpurmc/purpur/event/entity/PreEntityExplodeEvent.java b/src/main/java/org/purpurmc/purpur/event/entity/PreEntityExplodeEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..2d4f68228861492baaea0bcc604dfef623b337ba diff --git a/patches/api/0003-Plazma-Configurations.patch b/patches/api/0003-Plazma-Configurations.patch index b7428d0..6717bed 100644 --- a/patches/api/0003-Plazma-Configurations.patch +++ b/patches/api/0003-Plazma-Configurations.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Plazma Configurations diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 96160bced90bb4cd84e48c85c645cad0eb672b85..cd7080c49b769dec6d5d80774bde02e9dd8ecc01 100644 +index 916b9a9f05c0e83109bc9a4eb1692e2ed6e81eaf..ef14d669bc49b7b3694b0743b6085944647e0a29 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -1994,6 +1994,13 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2030,6 +2030,13 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi } // Paper end diff --git a/patches/api/0004-Bump-Bungeecord-Chat-API-to-1.19-R0.1-SNAPSHOT.patch b/patches/api/0004-Bump-Bungeecord-Chat-API-to-1.19-R0.1-SNAPSHOT.patch deleted file mode 100644 index 7bb9da6..0000000 --- a/patches/api/0004-Bump-Bungeecord-Chat-API-to-1.19-R0.1-SNAPSHOT.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: AlphaKR93 -Date: Thu, 22 Dec 2022 20:29:45 +0900 -Subject: [PATCH] Bump Bungeecord Chat API to 1.19-R0.1-SNAPSHOT - - -diff --git a/build.gradle.kts b/build.gradle.kts -index b5835fa536f90b7f88a5ee4df78733cf43e1cb23..42de5c470a2fbb1e0bc9b809c033e3afe30502fa 100644 ---- a/build.gradle.kts -+++ b/build.gradle.kts -@@ -25,7 +25,7 @@ dependencies { - // api dependencies are listed transitively to API consumers - api("com.google.guava:guava:31.1-jre") - api("com.google.code.gson:gson:2.10") -- api("net.md-5:bungeecord-chat:1.16-R0.4-deprecated+build.9") // Paper -+ api("net.md-5:bungeecord-chat:1.19-R0.1-SNAPSHOT") // Paper // Plazma - api("org.yaml:snakeyaml:1.33") - api("org.joml:joml:1.10.5") - // Paper start diff --git a/patches/api/0005-Publish-Packages.patch b/patches/api/0004-Publish-Packages.patch similarity index 72% rename from patches/api/0005-Publish-Packages.patch rename to patches/api/0004-Publish-Packages.patch index 1957cea..8da1fbc 100644 --- a/patches/api/0005-Publish-Packages.patch +++ b/patches/api/0004-Publish-Packages.patch @@ -1,18 +1,17 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: AlphaKR93 -Date: Fri, 6 Jan 2023 17:11:31 +0900 -Subject: [PATCH] Publish Packages +From: IPECTER +Date: Mon, 19 Jun 2023 18:19:50 +0900 +Subject: [PATCH] Publish-Packages diff --git a/build.gradle.kts b/build.gradle.kts -index 7b38042c32295ef7c5ea3c212170cc8fcdf0d7a0..1e300e51fa3413f9846c686545f2b7deb0ac5160 100644 +index 1261dbb7a1c22860922afd0ac8c341aea3569df3..299ce875ee51294d87b31571b624a7991e0fdb1c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -156,3 +156,23 @@ tasks.check { +@@ -163,3 +163,22 @@ tasks.check { dependsOn(scanJar) } // Paper end -+ +// Plazma start +publishing { + repositories { @@ -32,3 +31,4 @@ index 7b38042c32295ef7c5ea3c212170cc8fcdf0d7a0..1e300e51fa3413f9846c686545f2b7de + } +} +// Plazma end +\ No newline at end of file diff --git a/patches/server/0001-Pufferfish-Server-Changes.patch b/patches/server/0001-Pufferfish-Server-Changes.patch index 8d331a7..9af5a13 100644 --- a/patches/server/0001-Pufferfish-Server-Changes.patch +++ b/patches/server/0001-Pufferfish-Server-Changes.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: AlphaKR93 -Date: Sun, 4 Jun 2023 07:49:45 +0000 +From: Kevin Raneri +Date: Wed, 3 Feb 2021 23:02:38 -0600 Subject: [PATCH] Pufferfish Server Changes Original: Kevin Raneri @@ -17,11 +17,11 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/build.gradle.kts b/build.gradle.kts -index 4f2fa65ade89c5703451dad4f80eeef162b277d1..3ee1160c796cc86db9bc9438055b307239e9a8f7 100644 +index fb98936bb8a5488db75d676c5bcb4060597fbbf8..f6cd7b910ce41a254e71bf0fcfe93c38abbb1445 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -7,8 +7,12 @@ plugins { - } +@@ -13,8 +13,12 @@ configurations.named(log4jPlugins.compileClasspathConfigurationName) { + val alsoShade: Configuration by configurations.creating dependencies { - implementation(project(":paper-api")) @@ -35,13 +35,13 @@ index 4f2fa65ade89c5703451dad4f80eeef162b277d1..3ee1160c796cc86db9bc9438055b3072 // Paper start implementation("org.jline:jline-terminal-jansi:3.21.0") implementation("net.minecrell:terminalconsoleappender:1.3.0") -@@ -42,6 +46,13 @@ dependencies { +@@ -52,6 +56,13 @@ dependencies { runtimeOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.7.3") runtimeOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.7.3") + // Pufferfish start + implementation("org.yaml:snakeyaml:1.32") -+ implementation ("me.carleslc.Simple-YAML:Simple-Yaml:1.8.2") { ++ implementation ("com.github.carleslc.Simple-YAML:Simple-Yaml:1.8.4") { + exclude(group="org.yaml", module="snakeyaml") + } + // Pufferfish end @@ -49,10 +49,10 @@ index 4f2fa65ade89c5703451dad4f80eeef162b277d1..3ee1160c796cc86db9bc9438055b3072 testImplementation("io.github.classgraph:classgraph:4.8.47") // Paper - mob goal test testImplementation("junit:junit:4.13.2") testImplementation("org.hamcrest:hamcrest-library:1.3") -@@ -50,6 +61,14 @@ dependencies { +@@ -60,6 +71,14 @@ dependencies { } - val craftbukkitPackageVersion = "1_19_R3" // Paper + val craftbukkitPackageVersion = "1_20_R1" // Paper + +// Pufferfish Start +tasks.withType { @@ -64,7 +64,7 @@ index 4f2fa65ade89c5703451dad4f80eeef162b277d1..3ee1160c796cc86db9bc9438055b3072 tasks.jar { archiveClassifier.set("dev") -@@ -62,7 +81,7 @@ tasks.jar { +@@ -72,7 +91,7 @@ tasks.jar { attributes( "Main-Class" to "org.bukkit.craftbukkit.Main", "Implementation-Title" to "CraftBukkit", @@ -74,7 +74,7 @@ index 4f2fa65ade89c5703451dad4f80eeef162b277d1..3ee1160c796cc86db9bc9438055b3072 "Specification-Title" to "Bukkit", "Specification-Version" to project.version, diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java -index c07eb451a576811a39021f6f97103c77488fd001..5af15c85fab72034b97ac210ff775e0a8fa0be78 100644 +index a2f71a6d1a9e98133dff6cd0f625da9435a8af14..ff940e43ca35094bbcae6c7d471d3c4aeb7c1727 100644 --- a/src/main/java/co/aikar/timings/TimingsExport.java +++ b/src/main/java/co/aikar/timings/TimingsExport.java @@ -242,7 +242,8 @@ public class TimingsExport extends Thread { @@ -613,10 +613,10 @@ index 0000000000000000000000000000000000000000..020368da69b9a492155f6de6297f7473 +} diff --git a/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java b/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java new file mode 100644 -index 0000000000000000000000000000000000000000..0dd3374468e05f7a312ba5856b9cf8a4787dfa59 +index 0000000000000000000000000000000000000000..3d4bb28fe686a9ad2e4c0f75f21e6289c2ea5cf9 --- /dev/null +++ b/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java -@@ -0,0 +1,293 @@ +@@ -0,0 +1,296 @@ +package gg.pufferfish.pufferfish; + +import gg.pufferfish.pufferfish.simd.SIMDDetection; @@ -901,11 +901,14 @@ index 0000000000000000000000000000000000000000..0dd3374468e05f7a312ba5856b9cf8a4 + "the ender dragon whenever a player places an end crystal."); + } + ++ + public static boolean disableMethodProfiler; + public static boolean disableOutOfOrderChat; ++ public static boolean suppressNullIdDisconnections; + private static void miscSettings() { + disableMethodProfiler = getBoolean("misc.disable-method-profiler", true); + disableOutOfOrderChat = getBoolean("misc.disable-out-of-order-chat", false); ++ suppressNullIdDisconnections = getBoolean("misc.suppress-null-id-disconnections", false); + setComment("misc", "Settings for things that don't belong elsewhere"); + } + @@ -934,7 +937,7 @@ index 0000000000000000000000000000000000000000..53f2df00c6809618a9ee3d2ea72e85e8 +} diff --git a/src/main/java/gg/pufferfish/pufferfish/PufferfishVersionFetcher.java b/src/main/java/gg/pufferfish/pufferfish/PufferfishVersionFetcher.java new file mode 100644 -index 0000000000000000000000000000000000000000..e877921370f6009a4bd204d9b17d2d58834b8822 +index 0000000000000000000000000000000000000000..893d8c0946ef71a0561221dd76bffff0dc940d56 --- /dev/null +++ b/src/main/java/gg/pufferfish/pufferfish/PufferfishVersionFetcher.java @@ -0,0 +1,136 @@ @@ -970,8 +973,8 @@ index 0000000000000000000000000000000000000000..e877921370f6009a4bd204d9b17d2d58 + private static final Logger LOGGER = Logger.getLogger("PufferfishVersionFetcher"); + private static final HttpClient client = HttpClient.newHttpClient(); + -+ private static final URI JENKINS_URI = URI.create("https://ci.pufferfish.host/job/Pufferfish-1.19/lastSuccessfulBuild/buildNumber"); -+ private static final String GITHUB_FORMAT = "https://api.github.com/repos/pufferfish-gg/Pufferfish/compare/ver/1.19...%s"; ++ private static final URI JENKINS_URI = URI.create("https://ci.pufferfish.host/job/Pufferfish-1.20/lastSuccessfulBuild/buildNumber"); ++ private static final String GITHUB_FORMAT = "https://api.github.com/repos/pufferfish-gg/Pufferfish/compare/ver/1.20...%s"; + + private static final HttpResponse.BodyHandler JSON_OBJECT_BODY_HANDLER = responseInfo -> HttpResponse.BodySubscribers + .mapping( @@ -1451,10 +1454,10 @@ index 0000000000000000000000000000000000000000..facd55463d44cb7e3d2ca6892982f549 + } +} diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java -index 6efb8b10f17c70b05128039376d254e6beda3841..57e8c6673c7cfe447a75f15506e8000062d813fe 100644 +index c69088a2ec374b2d236fec61e267f42afa2967b1..5dffe28f93925d4c45c9b5c4f7565b00b1aa8dd2 100644 --- a/src/main/java/io/papermc/paper/util/MCUtil.java +++ b/src/main/java/io/papermc/paper/util/MCUtil.java -@@ -210,7 +210,7 @@ public final class MCUtil { +@@ -215,7 +215,7 @@ public final class MCUtil { } public static long getCoordinateKey(final Entity entity) { @@ -1464,10 +1467,10 @@ index 6efb8b10f17c70b05128039376d254e6beda3841..57e8c6673c7cfe447a75f15506e80000 public static long getCoordinateKey(final ChunkPos pair) { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 9f15d9dbdfa74a0640b1a2b4ff695609d4758a4c..a29d92b3f2658b63545b25092bb3a1fea46ca36b 100644 +index 67ee3a4ca8a6cdeb275653d492a1fea8037c51fb..67cba5cf510e4a602121e10c015a491650127752 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -313,6 +313,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); -@@ -1682,7 +1684,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop chunkConsumer) { diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java -index b7fd8e70413c38923d0719aff803449e392383ac..d5cb594f0b17ec9dc1a19cdb99bba553e70171be 100644 +index 196280f54e397c69d32bd4d1f6ae666efdd93773..8ab959dd588b5154b63e133b2e937fa2d0ab8e52 100644 --- a/src/main/java/net/minecraft/server/level/ServerEntity.java +++ b/src/main/java/net/minecraft/server/level/ServerEntity.java -@@ -185,6 +185,7 @@ public class ServerEntity { +@@ -180,7 +180,8 @@ public class ServerEntity { + long i1 = this.positionCodec.encodeZ(vec3d); boolean flag6 = k < -32768L || k > 32767L || l < -32768L || l > 32767L || i1 < -32768L || i1 > 32767L; - if (!flag6 && this.teleportDelay <= 400 && !this.wasRiding && this.wasOnGround == this.entity.isOnGround() && !(io.papermc.paper.configuration.GlobalConfiguration.get().collisions.sendFullPosForHardCollidingEntities && this.entity.hardCollides())) { // Paper - send full pos for hard colliding entities to prevent collision problems due to desync +- if (!flag6 && this.teleportDelay <= 400 && !this.wasRiding && this.wasOnGround == this.entity.onGround()&& !(io.papermc.paper.configuration.GlobalConfiguration.get().collisions.sendFullPosForHardCollidingEntities && this.entity.hardCollides())) { // Paper - send full pos for hard colliding entities to prevent collision problems due to desync ++ if (!flag6 && this.teleportDelay <= 400 && !this.wasRiding && this.wasOnGround == this.entity.onGround() && !(io.papermc.paper.configuration.GlobalConfiguration.get().collisions.sendFullPosForHardCollidingEntities && this.entity.hardCollides())) { // Paper - send full pos for hard colliding entities to prevent collision problems due to desync + if (flag2 || flag3 || this.entity instanceof AbstractArrow) { // Pufferfish if ((!flag2 || !flag3) && !(this.entity instanceof AbstractArrow)) { if (flag2) { - packet1 = new ClientboundMoveEntityPacket.Pos(this.entity.getId(), (short) ((int) k), (short) ((int) l), (short) ((int) i1), this.entity.isOnGround()); -@@ -198,6 +199,7 @@ public class ServerEntity { + packet1 = new ClientboundMoveEntityPacket.Pos(this.entity.getId(), (short) ((int) k), (short) ((int) l), (short) ((int) i1), this.entity.onGround()); +@@ -194,6 +195,7 @@ public class ServerEntity { flag4 = true; flag5 = true; } + } // Pufferfish } else { - this.wasOnGround = this.entity.isOnGround(); + this.wasOnGround = this.entity.onGround(); this.teleportDelay = 0; diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 45804711255f04110e9509df8d60900314aa10b7..3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b 100644 +index 18aac3da3c88f33b1a71a5920a8daa27e9723913..eac31c3fcc9161711328588ac852fcae1116d8ef 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -709,6 +709,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -850,6 +850,7 @@ public class ServerLevel extends Level implements WorldGenLevel { org.spigotmc.ActivationRange.activateEntities(this); // Spigot timings.entityTick.startTiming(); // Spigot this.entityTickList.forEach((entity) -> { @@ -1694,7 +1727,7 @@ index 45804711255f04110e9509df8d60900314aa10b7..3ee5c3c17d450dce54e051dc53c9df44 if (!entity.isRemoved()) { if (false && this.shouldDiscardEntity(entity)) { // CraftBukkit - We prevent spawning in general, so this butchering is not needed entity.discard(); -@@ -728,7 +729,20 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -869,7 +870,20 @@ public class ServerLevel extends Level implements WorldGenLevel { } gameprofilerfiller.push("tick"); @@ -1706,7 +1739,7 @@ index 45804711255f04110e9509df8d60900314aa10b7..3ee5c3c17d450dce54e051dc53c9df44 + } catch (Throwable throwable) { + if (throwable instanceof ThreadDeath) throw throwable; // Paper + // Paper start - Prevent tile entity and entity crashes -+ final String msg = String.format("Entity threw exception at %s:%s,%s,%s", entity.level.getWorld().getName(), entity.getX(), entity.getY(), entity.getZ()); ++ 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(); @@ -1716,7 +1749,7 @@ index 45804711255f04110e9509df8d60900314aa10b7..3ee5c3c17d450dce54e051dc53c9df44 gameprofilerfiller.pop(); } } -@@ -793,9 +807,11 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -934,9 +948,11 @@ public class ServerLevel extends Level implements WorldGenLevel { } // Paper start - optimise random block ticking private final BlockPos.MutableBlockPos chunkTickMutablePosition = new BlockPos.MutableBlockPos(); @@ -1729,7 +1762,7 @@ index 45804711255f04110e9509df8d60900314aa10b7..3ee5c3c17d450dce54e051dc53c9df44 public void tickChunk(LevelChunk chunk, int randomTickSpeed) { ChunkPos chunkcoordintpair = chunk.getPos(); boolean flag = this.isRaining(); -@@ -806,7 +822,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -947,7 +963,7 @@ public class ServerLevel extends Level implements WorldGenLevel { gameprofilerfiller.push("thunder"); final BlockPos.MutableBlockPos blockposition = this.chunkTickMutablePosition; // Paper - use mutable to reduce allocation rate, final to force compile fail on change @@ -1738,9 +1771,9 @@ index 45804711255f04110e9509df8d60900314aa10b7..3ee5c3c17d450dce54e051dc53c9df44 blockposition.set(this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15))); // Paper if (this.isRainingAt(blockposition)) { DifficultyInstance difficultydamagescaler = this.getCurrentDifficultyAt(blockposition); -@@ -836,7 +852,7 @@ public class ServerLevel extends Level implements WorldGenLevel { - gameprofilerfiller.popPush("iceandsnow"); +@@ -978,7 +994,7 @@ public class ServerLevel extends Level implements WorldGenLevel { int l; + int i1; - if (!this.paperConfig().environment.disableIceAndSnow && this.random.nextInt(16) == 0) { // Paper - Disable ice and snow + if (!this.paperConfig().environment.disableIceAndSnow && (this.currentIceAndSnowTick++ & 15) == 0) { // Paper - Disable ice and snow // Paper - optimise random ticking // Pufferfish - optimize further random ticking @@ -1748,10 +1781,10 @@ index 45804711255f04110e9509df8d60900314aa10b7..3ee5c3c17d450dce54e051dc53c9df44 this.getRandomBlockPosition(j, 0, k, 15, blockposition); int normalY = chunk.getHeight(Heightmap.Types.MOTION_BLOCKING, blockposition.getX() & 15, blockposition.getZ() & 15) + 1; diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index aa287d7f37f38d938d195114408cb6dbda59063d..9d2d72fe48b69be2f6ebe74309673a3a4e51eae4 100644 +index 3c0651fa5a5db880202c9a3805a6455269c5f16d..776c7df81d2b71a5610fe90475f4e8044850beab 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1216,6 +1216,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -1233,6 +1233,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic @Override public void handleEditBook(ServerboundEditBookPacket packet) { @@ -1759,7 +1792,7 @@ index aa287d7f37f38d938d195114408cb6dbda59063d..9d2d72fe48b69be2f6ebe74309673a3a // Paper start if (!this.cserver.isPrimaryThread()) { List pageList = packet.getPages(); -@@ -2363,6 +2364,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -2420,6 +2421,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic } private boolean updateChatOrder(Instant timestamp) { @@ -1767,6 +1800,18 @@ index aa287d7f37f38d938d195114408cb6dbda59063d..9d2d72fe48b69be2f6ebe74309673a3a Instant instant1; do { +diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +index 2ff578e4a953ffcf5176815ba8e3f06f73499989..878001928327d92423d5f7f6d5ce8772d6fa477f 100644 +--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java ++++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +@@ -204,6 +204,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, + + @Override + public void onDisconnect(Component reason) { ++ if (gg.pufferfish.pufferfish.PufferfishConfig.suppressNullIdDisconnections && this.gameProfile != null && this.gameProfile.getId() == null && "Disconnected".equals(reason.getString())) return; // Pufferfish + ServerLoginPacketListenerImpl.LOGGER.info("{} lost connection: {}", this.getUserName(), reason.getString()); + } + diff --git a/src/main/java/net/minecraft/world/CompoundContainer.java b/src/main/java/net/minecraft/world/CompoundContainer.java index 241fec02e6869c638d3a160819b32173a081467b..6a8f9e8f5bf108674c47018def28906e2d0a729c 100644 --- a/src/main/java/net/minecraft/world/CompoundContainer.java @@ -1880,10 +1925,10 @@ index 04b1531572e8fff1e46fe1c94e7fc863841e0f66..47ddc42f2b63d9d3fae5ae6ea93d4183 int LARGE_MAX_STACK_SIZE = 64; int DEFAULT_DISTANCE_LIMIT = 8; diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 280ee1838106201f5e3ba7753caced6d030f7e55..b4ab2cfb7a5fa0d2efd1a759d754d5203aaac077 100644 +index e8485fb900b25e911a858678a833852731cb2ace..36795968f4c296f680f79cc5a795391ae13c64e4 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -292,7 +292,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -306,7 +306,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { public double yo; public double zo; private Vec3 position; @@ -1892,7 +1937,7 @@ index 280ee1838106201f5e3ba7753caced6d030f7e55..b4ab2cfb7a5fa0d2efd1a759d754d520 private ChunkPos chunkPosition; private Vec3 deltaMovement; private float yRot; -@@ -417,6 +417,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -434,6 +434,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { return this.originWorld; } // Paper end @@ -1905,7 +1950,7 @@ index 280ee1838106201f5e3ba7753caced6d030f7e55..b4ab2cfb7a5fa0d2efd1a759d754d520 public float getBukkitYaw() { return this.yRot; } -@@ -491,17 +497,36 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -508,17 +514,36 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { this.isLegacyTrackingEntity = isLegacyTrackingEntity; } @@ -1943,7 +1988,7 @@ index 280ee1838106201f5e3ba7753caced6d030f7e55..b4ab2cfb7a5fa0d2efd1a759d754d520 for (Entity passenger : passengers) { org.spigotmc.TrackingRange.TrackingRangeType passengerType = passenger.trackingRangeType; int passengerRange = chunkMap.getEntityTrackerRange(passengerType.ordinal()); -@@ -510,6 +535,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -527,6 +552,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { range = passengerRange; } } @@ -1953,20 +1998,20 @@ index 280ee1838106201f5e3ba7753caced6d030f7e55..b4ab2cfb7a5fa0d2efd1a759d754d520 return chunkMap.playerEntityTrackerTrackMaps[type.ordinal()].getObjectsInRange(MCUtil.getCoordinateKey(this)); } -@@ -791,6 +819,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { - // CraftBukkit end +@@ -798,6 +826,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { + } - public void baseTick() { + public void tick() { + // Pufferfish start - entity TTL + if (type != EntityType.PLAYER && type.ttl >= 0 && this.tickCount >= type.ttl) { -+ remove(RemovalReason.DISCARDED); ++ discard(); + return; + } + // Pufferfish end - entity TTL - this.level.getProfiler().push("entityBaseTick"); - if (firstTick && this instanceof net.minecraft.world.entity.NeutralMob neutralMob) neutralMob.tickInitialPersistentAnger(level); // Paper - Update last hurt when ticking - this.feetBlockState = null; -@@ -4164,16 +4198,18 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { + this.baseTick(); + } + +@@ -4283,16 +4317,18 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } public boolean updateFluidHeightAndDoFluidPushing(TagKey tag, double speed) { @@ -1992,7 +2037,7 @@ index 280ee1838106201f5e3ba7753caced6d030f7e55..b4ab2cfb7a5fa0d2efd1a759d754d520 double d1 = 0.0D; boolean flag = this.isPushedByFluid(); boolean flag1 = false; -@@ -4181,14 +4217,61 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -4300,14 +4336,61 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { int k1 = 0; BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(); @@ -2000,10 +2045,10 @@ index 280ee1838106201f5e3ba7753caced6d030f7e55..b4ab2cfb7a5fa0d2efd1a759d754d520 - for (int i2 = k; i2 < l; ++i2) { - for (int j2 = i1; j2 < j1; ++j2) { - blockposition_mutableblockposition.set(l1, i2, j2); -- FluidState fluid = this.level.getFluidState(blockposition_mutableblockposition); +- FluidState fluid = this.level().getFluidState(blockposition_mutableblockposition); + // Pufferfish start - based off CollisionUtil.getCollisionsForBlocksOrWorldBorder -+ final int minSection = io.papermc.paper.util.WorldUtil.getMinSection(this.level); -+ final int maxSection = io.papermc.paper.util.WorldUtil.getMaxSection(this.level); ++ final int minSection = io.papermc.paper.util.WorldUtil.getMinSection(this.level()); ++ final int maxSection = io.papermc.paper.util.WorldUtil.getMaxSection(this.level()); + final int minBlock = minSection << 4; + final int maxBlock = (maxSection << 4) | 15; + @@ -2030,7 +2075,7 @@ index 280ee1838106201f5e3ba7753caced6d030f7e55..b4ab2cfb7a5fa0d2efd1a759d754d520 + int minX = currChunkX == minChunkX ? minBlockX & 15 : 0; // coordinate in chunk + int maxX = currChunkX == maxChunkX ? maxBlockX & 15 : 16; // coordinate in chunk + -+ net.minecraft.world.level.chunk.ChunkAccess chunk = this.level.getChunkIfLoadedImmediately(currChunkX, currChunkZ); ++ net.minecraft.world.level.chunk.ChunkAccess chunk = this.level().getChunkIfLoadedImmediately(currChunkX, currChunkZ); + if (chunk == null) { + return false; // if we're touching an unloaded chunk then it's false + } @@ -2054,13 +2099,13 @@ index 280ee1838106201f5e3ba7753caced6d030f7e55..b4ab2cfb7a5fa0d2efd1a759d754d520 + FluidState fluid = blocks.get(currX & 15, currY & 15, currZ & 15).getFluidState(); if (fluid.is(tag)) { -- double d2 = (double) ((float) i2 + fluid.getHeight(this.level, blockposition_mutableblockposition)); +- double d2 = (double) ((float) i2 + fluid.getHeight(this.level(), blockposition_mutableblockposition)); + blockposition_mutableblockposition.set((currChunkX << 4) + currX, currY, (currChunkZ << 4) + currZ); -+ double d2 = (double) ((float) currY + fluid.getHeight(this.level, blockposition_mutableblockposition)); ++ double d2 = (double) ((float) currY + fluid.getHeight(this.level(), blockposition_mutableblockposition)); if (d2 >= axisalignedbb.minY) { flag1 = true; -@@ -4210,9 +4293,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -4329,9 +4412,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { // CraftBukkit end } } @@ -2074,7 +2119,7 @@ index 280ee1838106201f5e3ba7753caced6d030f7e55..b4ab2cfb7a5fa0d2efd1a759d754d520 if (vec3d.length() > 0.0D) { if (k1 > 0) { diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index ceacc0d383e2ee674783d3c0a7df0a951595faca..8af0918d3a62de58a4b2af55022c812bb0e46092 100644 +index 9afc81ccb237c3655d64cdbe8a0db9a4d7791043..aa5cec6d56d7a8e80861aa4c9b4a74ca3e64be8c 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java @@ -300,6 +300,8 @@ public class EntityType implements FeatureElement, EntityTypeT @@ -2087,10 +2132,10 @@ index ceacc0d383e2ee674783d3c0a7df0a951595faca..8af0918d3a62de58a4b2af55022c812b private String descriptionId; @Nullable diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 95a27d28f73039693ca64601954af62028413634..f3d96caa83ef4a8083b78e3265282d4723e37d28 100644 +index e11d7283662834047b2ff81a2fd25a4263792deb..e9a31314424d9db911cd9806741222397c3072d7 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -141,7 +141,6 @@ import org.bukkit.event.entity.EntityTeleportEvent; +@@ -142,7 +142,6 @@ import org.bukkit.event.entity.EntityTeleportEvent; import org.bukkit.event.player.PlayerItemConsumeEvent; // CraftBukkit end @@ -2098,16 +2143,16 @@ index 95a27d28f73039693ca64601954af62028413634..f3d96caa83ef4a8083b78e3265282d47 public abstract class LivingEntity extends Entity implements Attackable { -@@ -397,7 +396,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -414,7 +413,7 @@ public abstract class LivingEntity extends Entity implements Attackable { boolean flag = this instanceof net.minecraft.world.entity.player.Player; - if (!this.level.isClientSide) { + if (!this.level().isClientSide) { - if (this.isInWall()) { + if ((!gg.pufferfish.pufferfish.PufferfishConfig.enableSuffocationOptimization || (tickCount % 10 == 0 && couldPossiblyBeHurt(1.0F))) && this.isInWall()) { // Pufferfish - optimize suffocation this.hurt(this.damageSources().inWall(), 1.0F); - } else if (flag && !this.level.getWorldBorder().isWithinBounds(this.getBoundingBox())) { - double d0 = this.level.getWorldBorder().getDistanceToBorder(this) + this.level.getWorldBorder().getDamageSafeZone(); -@@ -1321,6 +1320,15 @@ public abstract class LivingEntity extends Entity implements Attackable { + } else if (flag && !this.level().getWorldBorder().isWithinBounds(this.getBoundingBox())) { + double d0 = this.level().getWorldBorder().getDistanceToBorder(this) + this.level().getWorldBorder().getDamageSafeZone(); +@@ -1369,6 +1368,15 @@ public abstract class LivingEntity extends Entity implements Attackable { return this.getHealth() <= 0.0F; } @@ -2123,7 +2168,7 @@ index 95a27d28f73039693ca64601954af62028413634..f3d96caa83ef4a8083b78e3265282d47 @Override public boolean hurt(DamageSource source, float amount) { if (this.isInvulnerableTo(source)) { -@@ -1929,6 +1937,20 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1965,6 +1973,20 @@ public abstract class LivingEntity extends Entity implements Attackable { return this.lastClimbablePos; } @@ -2144,23 +2189,23 @@ index 95a27d28f73039693ca64601954af62028413634..f3d96caa83ef4a8083b78e3265282d47 public boolean onClimbable() { if (this.isSpectator()) { return false; -@@ -3609,7 +3631,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3651,7 +3673,10 @@ public abstract class LivingEntity extends Entity implements Attackable { Vec3 vec3d1 = new Vec3(entity.getX(), entity.getEyeY(), entity.getZ()); // Paper - diff on change - used in CraftLivingEntity#hasLineOfSight(Location) and CraftWorld#lineOfSightExists -- return vec3d1.distanceToSqr(vec3d) > 128D * 128D ? false : this.level.clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)).getType() == HitResult.Type.MISS; // Paper - use distanceToSqr +- return vec3d1.distanceToSqr(vec3d) > 128D * 128D ? false : this.level().clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)).getType() == HitResult.Type.MISS; + // Pufferfish start -+ //return vec3d1.distanceToSqr(vec3d) > 128D * 128D ? false : this.level.clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)).getType() == HitResult.Type.MISS; // Paper - use distanceToSqr -+ return vec3d1.distanceToSqr(vec3d) > 128D * 128D ? false : this.level.rayTraceDirect(vec3d, vec3d1, net.minecraft.world.phys.shapes.CollisionContext.of(this)) == net.minecraft.world.phys.BlockHitResult.Type.MISS; ++ //return vec3d1.distanceToSqr(vec3d) > 128D * 128D ? false : this.level().clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)).getType() == HitResult.Type.MISS; ++ return vec3d1.distanceToSqr(vec3d) > 128D * 128D ? false : this.level().rayTraceDirect(vec3d, vec3d1, net.minecraft.world.phys.shapes.CollisionContext.of(this)) == net.minecraft.world.phys.BlockHitResult.Type.MISS; + // Pufferfish end } } diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 02cb6b8c1d59855ff4a8aad3024fe12007eca0ee..636e601b004a412d02e5be86e97d489b52c28e1b 100644 +index e2a25c29ec74147b3e66aa0b3deb85a8f6ee53a5..f6eb032897c6d5d16ab5c8c287e49e189c24571c 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -215,14 +215,16 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -218,14 +218,16 @@ public abstract class Mob extends LivingEntity implements Targeting { return this.lookControl; } @@ -2179,26 +2224,26 @@ index 02cb6b8c1d59855ff4a8aad3024fe12007eca0ee..636e601b004a412d02e5be86e97d489b this.targetSelector.tick(); } } -@@ -907,16 +909,20 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -910,16 +912,20 @@ public abstract class Mob extends LivingEntity implements Targeting { if (i % 2 != 0 && this.tickCount > 1) { - this.level.getProfiler().push("targetSelector"); + this.level().getProfiler().push("targetSelector"); + if (this.targetSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking this.targetSelector.tickRunningGoals(false); - this.level.getProfiler().pop(); - this.level.getProfiler().push("goalSelector"); + this.level().getProfiler().pop(); + this.level().getProfiler().push("goalSelector"); + if (this.goalSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking this.goalSelector.tickRunningGoals(false); - this.level.getProfiler().pop(); + this.level().getProfiler().pop(); } else { - this.level.getProfiler().push("targetSelector"); + this.level().getProfiler().push("targetSelector"); + if (this.targetSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking this.targetSelector.tick(); - this.level.getProfiler().pop(); - this.level.getProfiler().push("goalSelector"); + this.level().getProfiler().pop(); + this.level().getProfiler().push("goalSelector"); + if (this.goalSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking this.goalSelector.tick(); - this.level.getProfiler().pop(); + this.level().getProfiler().pop(); } 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 dd1102d5291ef6f18e82400a6d8a0a376cc071e9..e283eb57c25f7de222f9d09dca851169f5f6e488 100644 @@ -2279,19 +2324,19 @@ index b738ee2d3801fadfd09313f05ae24593e56b0ec6..1635818fc4b1788c0d397085239df6dd public boolean hasTasks() { for (WrappedGoal task : this.availableGoals) { diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java -index 26bf383caea68834c654b25653ced9017f1b1b22..615eb55e24d365d994fbfe9d45d2be387fd5d561 100644 +index 34f319ad09276c6f68dde449c79351de0d7d86f5..a719af0b512d9ef243d0d54f3b744b1b1a5f2772 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java @@ -119,6 +119,7 @@ public abstract class MoveToBlockGoal extends Goal { for(int m = 0; m <= l; m = m > 0 ? -m : 1 - m) { for(int n = m < l && m > -l ? l : 0; n <= l; n = n > 0 ? -n : 1 - n) { mutableBlockPos.setWithOffset(blockPos, m, k - 1, n); -+ if (!this.mob.level.hasChunkAt(mutableBlockPos)) continue; // Pufferfish - if this block isn't loaded, continue - if (this.mob.isWithinRestriction(mutableBlockPos) && this.isValidTarget(this.mob.level, mutableBlockPos)) { ++ if (!this.mob.level().hasChunkAt(mutableBlockPos)) continue; // Pufferfish - if this block isn't loaded, continue + if (this.mob.isWithinRestriction(mutableBlockPos) && this.isValidTarget(this.mob.level(), mutableBlockPos)) { this.blockPos = mutableBlockPos; setTargetPosition(mutableBlockPos.immutable()); // Paper diff --git a/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java b/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java -index a7575b5ef56af6f53448d391abb4956e130148ca..e752c83df50fb9b670ecea2abc95426c2a009b6f 100644 +index 58422f00c7d64dbd1cf6d7211c9838875cbe7778..d25307ae8bbdf10ae067ec70fc2cb957b852a0eb 100644 --- a/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java +++ b/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java @@ -75,9 +75,18 @@ public class TargetingConditions { @@ -2316,10 +2361,10 @@ index a7575b5ef56af6f53448d391abb4956e130148ca..e752c83df50fb9b670ecea2abc95426c return false; } 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 f5efdf59617d43de18a2267351fa784c0be3ae83..59338d739b6130f667d151bc27646c4a346886a2 100644 +index 5beaa849a250ea005733250ad3edfa8382224667..2c91fe46355c9a201507de5577f693ed4f5fb974 100644 --- a/src/main/java/net/minecraft/world/entity/ambient/Bat.java +++ b/src/main/java/net/minecraft/world/entity/ambient/Bat.java -@@ -251,13 +251,22 @@ public class Bat extends AmbientCreature { +@@ -237,13 +237,22 @@ public class Bat extends AmbientCreature { } } @@ -2344,23 +2389,23 @@ index f5efdf59617d43de18a2267351fa784c0be3ae83..59338d739b6130f667d151bc27646c4a @Override protected float getStandingEyeHeight(Pose pose, EntityDimensions dimensions) { 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 9b57d2b766f2de2d3fb4a3b5ef4df8d6756a1942..a41d8101c960163803179d3717889aee6182d0bb 100644 +index 339c70f101d026a100a801e66cf514b3329a89d2..1a0eee3b766a5ce5623c32ed9c023a0f80db1d1a 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 -@@ -223,9 +223,11 @@ public class Allay extends PathfinderMob implements InventoryCarrier { +@@ -222,9 +222,11 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS return 0.4F; } + private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { - this.level.getProfiler().push("allayBrain"); + this.level().getProfiler().push("allayBrain"); + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish - this.getBrain().tick((ServerLevel) this.level, this); - this.level.getProfiler().pop(); - this.level.getProfiler().push("allayActivityUpdate"); + this.getBrain().tick((ServerLevel) this.level(), this); + this.level().getProfiler().pop(); + this.level().getProfiler().push("allayActivityUpdate"); 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 a4e98b02175da96472474b8d7ad5975ce4d2fc43..38d21943fb2940f53c2d0ac2c3b94a6f0e46e700 100644 +index 2682a49cd3948e0f80e2d7e58abcd3e6d8f7ac4e..42e22a4b9cb6841de04862cc81454da3232aa65a 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 @@ -285,9 +285,11 @@ public class Axolotl extends Animal implements LerpingModel, VariantHolder { +@@ -162,9 +162,11 @@ public class Frog extends Animal implements VariantHolder { return true; } + private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { - this.level.getProfiler().push("frogBrain"); + this.level().getProfiler().push("frogBrain"); + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish - this.getBrain().tick((ServerLevel)this.level, this); - this.level.getProfiler().pop(); - this.level.getProfiler().push("frogActivityUpdate"); + this.getBrain().tick((ServerLevel)this.level(), this); + this.level().getProfiler().pop(); + this.level().getProfiler().push("frogActivityUpdate"); 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 9058f9f2e561cda9f475f33218bf7a78297de4bc..e591b0a09f5a8475b3ec9cd28bd5d5b69809ed73 100644 +index 4aeab90e778629c355189dfe79c39c4b21f5f5ac..6ed4ac06c76b8d0d6e8db778cade15dbd1e3e5f5 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 @@ -77,9 +77,11 @@ public class Tadpole extends AbstractFish { @@ -2402,74 +2447,74 @@ index 9058f9f2e561cda9f475f33218bf7a78297de4bc..e591b0a09f5a8475b3ec9cd28bd5d5b6 + private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { - this.level.getProfiler().push("tadpoleBrain"); + this.level().getProfiler().push("tadpoleBrain"); + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish - this.getBrain().tick((ServerLevel) this.level, this); - this.level.getProfiler().pop(); - this.level.getProfiler().push("tadpoleActivityUpdate"); + this.getBrain().tick((ServerLevel) this.level(), this); + this.level().getProfiler().pop(); + this.level().getProfiler().push("tadpoleActivityUpdate"); 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 cfa904d42734d0fb0c1ed8b18f4d8bc131027962..4fdc3bd591b6df4c28901e4571aa23baf034d885 100644 +index 247aca0b612f5079a0596350e8311c385df8ab1c..7f21d1d400c8a5615ed1a787dcb0680338f8c28d 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 -@@ -188,9 +188,11 @@ public class Goat extends Animal { +@@ -189,9 +189,11 @@ public class Goat extends Animal { return (Brain) super.getBrain(); // CraftBukkit - decompile error } + private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { - this.level.getProfiler().push("goatBrain"); + this.level().getProfiler().push("goatBrain"); + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish - this.getBrain().tick((ServerLevel) this.level, this); - this.level.getProfiler().pop(); - this.level.getProfiler().push("goatActivityUpdate"); + this.getBrain().tick((ServerLevel) this.level(), this); + this.level().getProfiler().pop(); + this.level().getProfiler().push("goatActivityUpdate"); diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index d47b3ac633e7936d30abfda6fc46c2c7412d76fe..453f0f7042bdf204db73be139aa36f211c5455e7 100644 +index 52196431a6538872755344859a0454a0e50c3b6e..80fc7918cb294b0d88a293bd6a920441cb55c3ad 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -@@ -264,10 +264,16 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -270,10 +270,16 @@ public class ItemEntity extends Entity implements TraceableEntity { if (entityitem.isMergable()) { // Paper Start - Fix items merging through walls - if (this.level.paperConfig().fixes.fixItemsMergingThroughWalls) { + if (this.level().paperConfig().fixes.fixItemsMergingThroughWalls) { + // Pufferfish start - skip the allocations + /* net.minecraft.world.level.ClipContext rayTrace = new net.minecraft.world.level.ClipContext(this.position(), entityitem.position(), net.minecraft.world.level.ClipContext.Block.COLLIDER, net.minecraft.world.level.ClipContext.Fluid.NONE, this); - net.minecraft.world.phys.BlockHitResult rayTraceResult = level.clip(rayTrace); + net.minecraft.world.phys.BlockHitResult rayTraceResult = this.level().clip(rayTrace); if (rayTraceResult.getType() == net.minecraft.world.phys.HitResult.Type.BLOCK) continue; + */ -+ if (level.rayTraceDirect(this.position(), entityitem.position(), net.minecraft.world.phys.shapes.CollisionContext.of(this)) == ++ if (level().rayTraceDirect(this.position(), entityitem.position(), net.minecraft.world.phys.shapes.CollisionContext.of(this)) == + net.minecraft.world.phys.HitResult.Type.BLOCK) continue; + // Pufferfish end } // Paper End this.tryToMerge(entityitem); 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 418d6301f067803e2471e59ac2d52a68cbff249b..c2f5dabb41b172547864decc06aa632d89dff3e1 100644 +index b62457313a1e30aad0c5313d608667b5d3811455..410f10ad93935d1c078447a4596023f367a8e9b7 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java +++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java -@@ -322,11 +322,17 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -326,11 +326,17 @@ public class EnderMan extends Monster implements NeutralMob { private boolean teleport(double x, double y, double z) { BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(x, y, z); -- while (blockposition_mutableblockposition.getY() > this.level.getMinBuildHeight() && !this.level.getBlockState(blockposition_mutableblockposition).getMaterial().blocksMotion()) { +- while (blockposition_mutableblockposition.getY() > this.level().getMinBuildHeight() && !this.level().getBlockState(blockposition_mutableblockposition).blocksMotion()) { + // Pufferfish start - single chunk lookup -+ net.minecraft.world.level.chunk.LevelChunk chunk = this.level.getChunkIfLoaded(blockposition_mutableblockposition); ++ net.minecraft.world.level.chunk.LevelChunk chunk = this.level().getChunkIfLoaded(blockposition_mutableblockposition); + if (chunk == null) { + return false; + } + // Pufferfish end -+ while (blockposition_mutableblockposition.getY() > this.level.getMinBuildHeight() && !chunk.getBlockState(blockposition_mutableblockposition).getMaterial().blocksMotion()) { // Pufferfish ++ while (blockposition_mutableblockposition.getY() > this.level().getMinBuildHeight() && !chunk.getBlockState(blockposition_mutableblockposition).blocksMotion()) { // Pufferfish blockposition_mutableblockposition.move(Direction.DOWN); } -- BlockState iblockdata = this.level.getBlockState(blockposition_mutableblockposition); +- BlockState iblockdata = this.level().getBlockState(blockposition_mutableblockposition); + BlockState iblockdata = chunk.getBlockState(blockposition_mutableblockposition); // Pufferfish - boolean flag = iblockdata.getMaterial().blocksMotion(); + boolean flag = iblockdata.blocksMotion(); boolean flag1 = iblockdata.getFluidState().is(FluidTags.WATER); 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 5d3b3cb3a882eb5d716f678095a65b28d0967476..daa2224b021c966751eb39f269ffbfe6e7f3d426 100644 +index e8f6c34ea789136d63c0aa88aec90203ef6282b5..d6d61b91096d28eea1e5af69ea1c07890820ee7f 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 @@ -126,9 +126,11 @@ public class Hoglin extends Animal implements Enemy, HoglinBase { @@ -2479,50 +2524,50 @@ index 5d3b3cb3a882eb5d716f678095a65b28d0967476..daa2224b021c966751eb39f269ffbfe6 + private int behaviorTick; // Pufferfish @Override protected void customServerAiStep() { - this.level.getProfiler().push("hoglinBrain"); + this.level().getProfiler().push("hoglinBrain"); + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish - this.getBrain().tick((ServerLevel)this.level, this); - this.level.getProfiler().pop(); + this.getBrain().tick((ServerLevel)this.level(), this); + this.level().getProfiler().pop(); HoglinAi.updateActivity(this); 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 afa7ecfa8453da510ec5ccecb1ceeb1d9893d259..b401fb4f276ca81b4bb18426ee56abed8a9f7a7b 100644 +index 27d9145693a772cd1b5d171da303c934101f3be8..e235cc9d1b3ce59ab662ef3cf3ce0267ca78536d 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 -@@ -308,9 +308,11 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento +@@ -305,9 +305,11 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento return !this.cannotHunt; } + private int behaviorTick; // Pufferfish @Override protected void customServerAiStep() { - this.level.getProfiler().push("piglinBrain"); + this.level().getProfiler().push("piglinBrain"); + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish - this.getBrain().tick((ServerLevel) this.level, this); - this.level.getProfiler().pop(); + this.getBrain().tick((ServerLevel) this.level(), this); + this.level().getProfiler().pop(); PiglinAi.updateActivity(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 b2b63d9df3c07696f47281e9be74f1799f50b93e..907d77dd74066c723238155b42028a811365b1f8 100644 +index 97b763431bc5015448ee7a26a340635a932c950b..71db8bd6885377d55cfc571fccc21df6d8a57b54 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 -@@ -270,11 +270,13 @@ public class Warden extends Monster implements VibrationListener.VibrationListen +@@ -271,11 +271,13 @@ public class Warden extends Monster implements VibrationSystem { } + private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { - ServerLevel worldserver = (ServerLevel) this.level; + ServerLevel worldserver = (ServerLevel) this.level(); worldserver.getProfiler().push("wardenBrain"); + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish this.getBrain().tick(worldserver, this); - this.level.getProfiler().pop(); + this.level().getProfiler().pop(); super.customServerAiStep(); 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 6023b9eb3001e1a98ab8b970d853c4e7c7603f4d..5402a084ef5fe0b3cfea897a90cffade1eff5b66 100644 +index e30d5ae3e2900f43d7cafde71b8196f26e872841..c4ddf2661bca728d504918171295e10e307b18b4 100644 --- a/src/main/java/net/minecraft/world/entity/npc/Villager.java +++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java -@@ -140,6 +140,8 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -141,6 +141,8 @@ public class Villager extends AbstractVillager implements ReputationEventHandler return holder.is(PoiTypes.MEETING); }); @@ -2531,30 +2576,32 @@ index 6023b9eb3001e1a98ab8b970d853c4e7c7603f4d..5402a084ef5fe0b3cfea897a90cffade public Villager(EntityType entityType, Level world) { this(entityType, world, VillagerType.PLAINS); } -@@ -243,11 +245,17 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -244,6 +246,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler } // Spigot End + private int behaviorTick = 0; // Pufferfish @Override - protected void customServerAiStep() { mobTick(false); } - protected void mobTick(boolean inactive) { - this.level.getProfiler().push("villagerBrain"); -- if (!inactive) this.getBrain().tick((ServerLevel) this.level, this); // Paper + @Deprecated // Paper + protected void customServerAiStep() { +@@ -253,7 +256,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + protected void customServerAiStep(final boolean inactive) { + // Paper end + this.level().getProfiler().push("villagerBrain"); +- if (!inactive) this.getBrain().tick((ServerLevel) this.level(), this); // Paper + // Pufferfish start -+ if (!inactive) { -+ if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish -+ this.getBrain().tick((ServerLevel) this.level, this); // Paper -+ } ++ if (!inactive && this.behaviorTick++ % this.activatedPriority == 0) { ++ this.getBrain().tick((ServerLevel) this.level(), this); // Paper ++ } + // Pufferfish end - this.level.getProfiler().pop(); + this.level().getProfiler().pop(); if (this.assignProfessionWhenSpawned) { this.assignProfessionWhenSpawned = false; diff --git a/src/main/java/net/minecraft/world/entity/player/Inventory.java b/src/main/java/net/minecraft/world/entity/player/Inventory.java -index 27c028ab6b1edb6e413af3bbaa27bf30f2d85540..302ca7391109c10e81a7745504b3c530bc3be6ad 100644 +index 96d664c28738d6090f7067761c2978dd1aa0fd0e..b1c24a02b87aca7b180a6efbce177f2300db49c1 100644 --- a/src/main/java/net/minecraft/world/entity/player/Inventory.java +++ b/src/main/java/net/minecraft/world/entity/player/Inventory.java -@@ -682,6 +682,8 @@ public class Inventory implements Container, Nameable { +@@ -687,6 +687,8 @@ public class Inventory implements Container, Nameable { } public boolean contains(ItemStack stack) { @@ -2563,7 +2610,7 @@ index 27c028ab6b1edb6e413af3bbaa27bf30f2d85540..302ca7391109c10e81a7745504b3c530 Iterator iterator = this.compartments.iterator(); while (iterator.hasNext()) { -@@ -696,6 +698,18 @@ public class Inventory implements Container, Nameable { +@@ -701,6 +703,18 @@ public class Inventory implements Container, Nameable { } } } @@ -2573,7 +2620,7 @@ index 27c028ab6b1edb6e413af3bbaa27bf30f2d85540..302ca7391109c10e81a7745504b3c530 + for (int j = 0; j < list.size(); j++) { + ItemStack itemstack1 = list.get(j); + -+ if (!itemstack1.isEmpty() && itemstack1.sameItem(stack)) { ++ if (!itemstack1.isEmpty() && ItemStack.isSameItemSameTags(itemstack1, stack)) { + return true; + } + } @@ -2583,7 +2630,7 @@ index 27c028ab6b1edb6e413af3bbaa27bf30f2d85540..302ca7391109c10e81a7745504b3c530 return false; } 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 a211ca048dddc75afce1f83ee1700bad66e457fc..85260fd93ca8d5ffd0ba7a98f1d47093d58f0f87 100644 +index 1b7cf6d06bdf36f146656727511a461f2520762e..459aee61b519a40d9136546c0d9356562f5757c8 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java @@ -44,6 +44,36 @@ public abstract class Projectile extends Entity implements TraceableEntity { @@ -2605,7 +2652,7 @@ index a211ca048dddc75afce1f83ee1700bad66e457fc..85260fd93ca8d5ffd0ba7a98f1d47093 + int previousX = Mth.floor(this.getX()) >> 4, previousZ = Mth.floor(this.getZ()) >> 4; + int newX = Mth.floor(x) >> 4, newZ = Mth.floor(z) >> 4; + if (previousX != newX || previousZ != newZ) { -+ boolean isLoaded = ((net.minecraft.server.level.ServerChunkCache) this.level.getChunkSource()).getChunkAtIfLoadedMainThread(newX, newZ) != null; ++ boolean isLoaded = ((net.minecraft.server.level.ServerChunkCache) this.level().getChunkSource()).getChunkAtIfLoadedMainThread(newX, newZ) != null; + if (!isLoaded) { + if (Projectile.loadedThisTick > gg.pufferfish.pufferfish.PufferfishConfig.maxProjectileLoadsPerTick) { + if (++this.loadedLifetime > gg.pufferfish.pufferfish.PufferfishConfig.maxProjectileLoadsPerProjectile) { @@ -2618,13 +2665,13 @@ index a211ca048dddc75afce1f83ee1700bad66e457fc..85260fd93ca8d5ffd0ba7a98f1d47093 + } + super.setPos(x, y, z); + } -+ // Pufferfish start ++ // Pufferfish end + public void setOwner(@Nullable Entity entity) { if (entity != null) { this.ownerUUID = entity.getUUID(); diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java -index 08f027cdcaeeca7b545483cb8c5eb8d13e4933b9..992ff554643b149d9c6101562a9754a84263ed7e 100644 +index 272095d7a09ab41227d741172735f66fd2798ce1..47692d6db44b58bb724c87128279bd0d3e62a398 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java @@ -27,7 +27,10 @@ import org.bukkit.inventory.InventoryHolder; @@ -2671,23 +2718,23 @@ index 08f027cdcaeeca7b545483cb8c5eb8d13e4933b9..992ff554643b149d9c6101562a9754a8 } diff --git a/src/main/java/net/minecraft/world/item/EndCrystalItem.java b/src/main/java/net/minecraft/world/item/EndCrystalItem.java -index 171ce56ec3b8761f75144b1fca2f100fcbba6800..4202d8df909a6315cce0def93ad5241a519de43e 100644 +index 5a19875cbc603acea95193d969d2e1dc1e0bfd78..3688e9f8c6c6d1239095e3a87060ccca90386d0c 100644 --- a/src/main/java/net/minecraft/world/item/EndCrystalItem.java +++ b/src/main/java/net/minecraft/world/item/EndCrystalItem.java @@ -55,7 +55,7 @@ public class EndCrystalItem extends Item { world.gameEvent((Entity) context.getPlayer(), GameEvent.ENTITY_PLACE, blockposition1); - EndDragonFight enderdragonbattle = ((ServerLevel) world).dragonFight(); + EndDragonFight enderdragonbattle = ((ServerLevel) world).getDragonFight(); - if (enderdragonbattle != null) { + if (enderdragonbattle != null && gg.pufferfish.pufferfish.PufferfishConfig.allowEndCrystalRespawn) { // Pufferfish - enderdragonbattle.tryRespawn(); + enderdragonbattle.tryRespawn(aboveBlockPosition); // Paper - pass placed end crystal position to pre-check proximity to portal } } diff --git a/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java b/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java -index f4f3f3a19d3cadaef1ae1a47daa68251a983dcf2..8da06f8bea0239c5206d5d4f4ff48bdeb0a89f9d 100644 +index 2e60bdc44c33d434bfd9ca5bf8f75de799c6768c..565318c2afaa1661ed9963453a6354dff499f47a 100644 --- a/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java +++ b/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java -@@ -27,8 +27,13 @@ public class ShapelessRecipe implements CraftingRecipe { +@@ -27,8 +27,13 @@ public class ShapelessRecipe extends io.papermc.paper.inventory.recipe.RecipeBoo final CraftingBookCategory category; final ItemStack result; final NonNullList ingredients; @@ -2701,7 +2748,7 @@ index f4f3f3a19d3cadaef1ae1a47daa68251a983dcf2..8da06f8bea0239c5206d5d4f4ff48bde this.id = id; this.group = group; this.category = category; -@@ -82,6 +87,28 @@ public class ShapelessRecipe implements CraftingRecipe { +@@ -83,6 +88,28 @@ public class ShapelessRecipe extends io.papermc.paper.inventory.recipe.RecipeBoo } public boolean matches(CraftingContainer inventory, Level world) { @@ -2728,13 +2775,13 @@ index f4f3f3a19d3cadaef1ae1a47daa68251a983dcf2..8da06f8bea0239c5206d5d4f4ff48bde + // Pufferfish end + StackedContents autorecipestackmanager = new StackedContents(); + autorecipestackmanager.initialize(this); // Paper - better exact choice recipes int i = 0; - diff --git a/src/main/java/net/minecraft/world/level/BlockGetter.java b/src/main/java/net/minecraft/world/level/BlockGetter.java -index 2ee9e8e3c1a28c1823de8e1fe421cc1f3e72f384..cf4a8084158b10bf047d418dda375f8c1fd3216e 100644 +index 0e8746759752b692668886370181aa5db1fd0bb0..58e5ce2afabf480f5dfd9adf43f8fc12666861c6 100644 --- a/src/main/java/net/minecraft/world/level/BlockGetter.java +++ b/src/main/java/net/minecraft/world/level/BlockGetter.java -@@ -73,6 +73,16 @@ public interface BlockGetter extends LevelHeightAccessor { +@@ -68,6 +68,16 @@ public interface BlockGetter extends LevelHeightAccessor { }); } @@ -2752,10 +2799,10 @@ index 2ee9e8e3c1a28c1823de8e1fe421cc1f3e72f384..cf4a8084158b10bf047d418dda375f8c default BlockHitResult clip(ClipContext raytrace1, BlockPos blockposition) { // Paper start - Prevent raytrace from loading chunks diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 973ecd50f9cb6b86c353586e84d15dcb118ccb60..6aec1983a0236d6aa0507a2b3ad1c08b3330f0fc 100644 +index f39ab10c5b0b8d86b579a5b683491204c51db70b..d8d4a1ca2eb062af8b2de4ab44503983587cdd77 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -274,6 +274,17 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -273,6 +273,17 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public abstract ResourceKey getTypeKey(); @@ -2773,7 +2820,7 @@ index 973ecd50f9cb6b86c353586e84d15dcb118ccb60..6aec1983a0236d6aa0507a2b3ad1c08b protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, java.util.concurrent.Executor executor) { // Paper - Async-Anti-Xray - Pass executor this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper -@@ -296,6 +307,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -295,6 +306,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { }); final DimensionType dimensionmanager = (DimensionType) holder.value(); @@ -2787,7 +2834,7 @@ index 973ecd50f9cb6b86c353586e84d15dcb118ccb60..6aec1983a0236d6aa0507a2b3ad1c08b this.dimension = resourcekey; this.isClientSide = flag; if (dimensionmanager.coordinateScale() != 1.0D) { -@@ -413,6 +431,91 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -412,6 +430,91 @@ public abstract class Level implements LevelAccessor, AutoCloseable { return null; } @@ -2879,7 +2926,7 @@ index 973ecd50f9cb6b86c353586e84d15dcb118ccb60..6aec1983a0236d6aa0507a2b3ad1c08b public boolean isInWorldBounds(BlockPos pos) { return pos.isInsideBuildHeightAndWorldBoundsHorizontal(this); // Paper - use better/optimized check } -@@ -925,13 +1028,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -919,13 +1022,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { try { tickConsumer.accept(entity); MinecraftServer.getServer().executeMidTickTasks(); // Paper - execute chunk tasks mid tick @@ -2887,7 +2934,7 @@ index 973ecd50f9cb6b86c353586e84d15dcb118ccb60..6aec1983a0236d6aa0507a2b3ad1c08b + } catch (Throwable throwable) { // Pufferfish - diff on change ServerLevel.tick if (throwable instanceof ThreadDeath) throw throwable; // Paper // Paper start - Prevent tile entity and entity crashes - final String msg = String.format("Entity threw exception at %s:%s,%s,%s", entity.level.getWorld().getName(), entity.getX(), entity.getY(), entity.getZ()); + 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 ServerExceptionEvent(new ServerInternalException(msg, throwable))); - entity.discard(); @@ -2895,7 +2942,7 @@ index 973ecd50f9cb6b86c353586e84d15dcb118ccb60..6aec1983a0236d6aa0507a2b3ad1c08b // Paper end } } -@@ -1454,6 +1557,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1380,6 +1483,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } public ProfilerFiller getProfiler() { @@ -2904,10 +2951,10 @@ index 973ecd50f9cb6b86c353586e84d15dcb118ccb60..6aec1983a0236d6aa0507a2b3ad1c08b } diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 15d266fc97eb73338f4f6fb2cfe25d6861e79810..6180679d922ea61d05d452971ec2d506a724d3c3 100644 +index e85ddf92b4f6f044e2b5834a172f37d78e702ef3..49de1fca183b2c6a0a5399025abfc0e47f314315 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -@@ -417,12 +417,12 @@ public final class NaturalSpawner { +@@ -431,12 +431,12 @@ public final class NaturalSpawner { } } @@ -3052,7 +3099,7 @@ index a71414397bd45ee7bcacfeef0041d80dfa25f114..d66806565770cb03a21794f99e5c4b0f @Override diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java -index aac5572c1d40a10cd1d17f89c9eb836718837577..9b506bd2ec6e7fd1893dc7801592f011680028d7 100644 +index b11f51762ca289d99eaa49e66e31e58595bcea4e..f03608a133338b0f5522a07239e06fd2245db1e5 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java @@ -47,7 +47,10 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen @@ -3115,7 +3162,7 @@ index aac5572c1d40a10cd1d17f89c9eb836718837577..9b506bd2ec6e7fd1893dc7801592f011 flag |= booleansupplier.getAsBoolean(); } -@@ -451,11 +477,18 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen +@@ -452,11 +478,18 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen } private static boolean isFullContainer(Container inventory, Direction direction) { @@ -3136,7 +3183,7 @@ index aac5572c1d40a10cd1d17f89c9eb836718837577..9b506bd2ec6e7fd1893dc7801592f011 } public static boolean suckInItems(Level world, Hopper hopper) { -@@ -636,7 +669,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen +@@ -637,7 +670,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen if (HopperBlockEntity.canPlaceItemInContainer(to, stack, slot, side)) { boolean flag = false; @@ -3145,7 +3192,7 @@ index aac5572c1d40a10cd1d17f89c9eb836718837577..9b506bd2ec6e7fd1893dc7801592f011 if (itemstack1.isEmpty()) { // Spigot start - SPIGOT-6693, InventorySubcontainer#setItem -@@ -813,7 +846,10 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen +@@ -832,7 +865,10 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen @Override protected void setItems(NonNullList list) { @@ -3158,10 +3205,10 @@ index aac5572c1d40a10cd1d17f89c9eb836718837577..9b506bd2ec6e7fd1893dc7801592f011 public static void entityInside(Level world, BlockPos pos, BlockState state, Entity entity, HopperBlockEntity blockEntity) { diff --git a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java -index 79b01e32f89defb6b78f4764600d33d4945af592..6d62cc8fb347ccafd51df05896e616995990f005 100644 +index 081691f9710ff1115e4308f79ed49fbc38941193..765ee7f78532a363813286ef7db2a7e48605cb06 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java -@@ -97,12 +97,7 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc +@@ -96,12 +96,7 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc public boolean isEmpty() { this.unpackLootTable((Player)null); // Paper start @@ -3176,10 +3223,10 @@ index 79b01e32f89defb6b78f4764600d33d4945af592..6d62cc8fb347ccafd51df05896e61699 } diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index d190bad5d287766ed4165ed827d9901a9d878687..13594b96cc8f451723c3598ef302ccee8e01bcac 100644 +index 4ff0d2fc9fd76e92e64abd69f2c9e299aa08ac32..3eeb1f0eac76efe9b7c24f6d5787018c7842d07a 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -88,6 +88,18 @@ public class LevelChunk extends ChunkAccess { +@@ -85,6 +85,18 @@ public class LevelChunk extends ChunkAccess { private final LevelChunkTicks blockTicks; private final LevelChunkTicks fluidTicks; @@ -3198,7 +3245,7 @@ index d190bad5d287766ed4165ed827d9901a9d878687..13594b96cc8f451723c3598ef302ccee public LevelChunk(Level world, ChunkPos pos) { this(world, pos, UpgradeData.EMPTY, new LevelChunkTicks<>(), new LevelChunkTicks<>(), 0L, (LevelChunkSection[]) null, (LevelChunk.PostLoadProcessor) null, (BlendingData) null); } -@@ -116,6 +128,8 @@ public class LevelChunk extends ChunkAccess { +@@ -112,6 +124,8 @@ public class LevelChunk extends ChunkAccess { this.postLoad = entityLoader; this.blockTicks = blockTickScheduler; this.fluidTicks = fluidTickScheduler; @@ -3208,18 +3255,18 @@ index d190bad5d287766ed4165ed827d9901a9d878687..13594b96cc8f451723c3598ef302ccee // CraftBukkit start diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java -index 854865f28bcae0fb0c17717c914687f78e951e21..c6297917e94f5a8b4b1447b2c29c44b806ccaff6 100644 +index d4477b0dda6a1ef7bd8323c0d11b636bd071d18e..5d3dd6a61366ae2c185b62bc9198440ef6227927 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java -@@ -27,6 +27,7 @@ public class LevelChunkSection { +@@ -25,6 +25,7 @@ public class LevelChunkSection { public final PalettedContainer states; // CraftBukkit start - read/write private PalettedContainer> biomes; + public short fluidStateCount; // Pufferfish public final com.destroystokyo.paper.util.maplist.IBlockDataList tickingList = new com.destroystokyo.paper.util.maplist.IBlockDataList(); // Paper - public LevelChunkSection(int i, PalettedContainer datapaletteblock, PalettedContainer> palettedcontainerro) { -@@ -198,6 +199,7 @@ public class LevelChunkSection { + public LevelChunkSection(PalettedContainer datapaletteblock, PalettedContainer> palettedcontainerro) { +@@ -190,6 +191,7 @@ public class LevelChunkSection { if (!fluid.isEmpty()) { --this.tickingFluidCount; @@ -3227,7 +3274,7 @@ index 854865f28bcae0fb0c17717c914687f78e951e21..c6297917e94f5a8b4b1447b2c29c44b8 } if (!state.isAir()) { -@@ -212,6 +214,7 @@ public class LevelChunkSection { +@@ -204,6 +206,7 @@ public class LevelChunkSection { if (!fluid1.isEmpty()) { ++this.tickingFluidCount; @@ -3235,7 +3282,7 @@ index 854865f28bcae0fb0c17717c914687f78e951e21..c6297917e94f5a8b4b1447b2c29c44b8 } this.updateKnownBlockInfo(x | (z << 4) | (y << 8), iblockdata1, state); // Paper -@@ -261,6 +264,7 @@ public class LevelChunkSection { +@@ -249,6 +252,7 @@ public class LevelChunkSection { if (fluid.isRandomlyTicking()) { this.tickingFluidCount = (short) (this.tickingFluidCount + 1); } @@ -3257,10 +3304,10 @@ index 4cdfc433df67afcd455422e9baf56f167dd712ae..57fcf3910f45ce371ac2e237b277b103 private void ensureActiveIsNotIterated() { // Paper - replace with better logic, do not delay removals diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java -index bf4de7b8fd630c596e096a411a8c84c64c13ebf7..6063665b8848a2cd9f0b262eed36a9dd48db6035 100644 +index 5502ad143fd2575f1346334b5b4fe7846628f54e..7d56693102ee558fe784e3a9b9fdcff4b7ad57b9 100644 --- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java +++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java -@@ -43,6 +43,8 @@ public abstract class FlowingFluid extends Fluid { +@@ -44,6 +44,8 @@ public abstract class FlowingFluid extends Fluid { public static final BooleanProperty FALLING = BlockStateProperties.FALLING; public static final IntegerProperty LEVEL = BlockStateProperties.LEVEL_FLOWING; private static final int CACHE_SIZE = 200; @@ -3269,7 +3316,7 @@ index bf4de7b8fd630c596e096a411a8c84c64c13ebf7..6063665b8848a2cd9f0b262eed36a9dd private static final ThreadLocal> OCCLUSION_CACHE = ThreadLocal.withInitial(() -> { Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap = new Object2ByteLinkedOpenHashMap(200) { protected void rehash(int i) {} -@@ -51,6 +53,14 @@ public abstract class FlowingFluid extends Fluid { +@@ -52,6 +54,14 @@ public abstract class FlowingFluid extends Fluid { object2bytelinkedopenhashmap.defaultReturnValue((byte) 127); return object2bytelinkedopenhashmap; }); @@ -3284,7 +3331,7 @@ index bf4de7b8fd630c596e096a411a8c84c64c13ebf7..6063665b8848a2cd9f0b262eed36a9dd private final Map shapes = Maps.newIdentityHashMap(); public FlowingFluid() {} -@@ -239,6 +249,8 @@ public abstract class FlowingFluid extends Fluid { +@@ -240,6 +250,8 @@ public abstract class FlowingFluid extends Fluid { } private boolean canPassThroughWall(Direction face, BlockGetter world, BlockPos pos, BlockState state, BlockPos fromPos, BlockState fromState) { @@ -3293,7 +3340,7 @@ index bf4de7b8fd630c596e096a411a8c84c64c13ebf7..6063665b8848a2cd9f0b262eed36a9dd Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap; if (!state.getBlock().hasDynamicShape() && !fromState.getBlock().hasDynamicShape()) { -@@ -246,9 +258,16 @@ public abstract class FlowingFluid extends Fluid { +@@ -247,9 +259,16 @@ public abstract class FlowingFluid extends Fluid { } else { object2bytelinkedopenhashmap = null; } @@ -3310,7 +3357,7 @@ index bf4de7b8fd630c596e096a411a8c84c64c13ebf7..6063665b8848a2cd9f0b262eed36a9dd if (object2bytelinkedopenhashmap != null) { block_a = new Block.BlockStatePairKey(state, fromState, face); byte b0 = object2bytelinkedopenhashmap.getAndMoveToFirst(block_a); -@@ -259,11 +278,22 @@ public abstract class FlowingFluid extends Fluid { +@@ -260,11 +279,22 @@ public abstract class FlowingFluid extends Fluid { } else { block_a = null; } @@ -3333,7 +3380,7 @@ index bf4de7b8fd630c596e096a411a8c84c64c13ebf7..6063665b8848a2cd9f0b262eed36a9dd if (object2bytelinkedopenhashmap != null) { if (object2bytelinkedopenhashmap.size() == 200) { object2bytelinkedopenhashmap.removeLastByte(); -@@ -271,6 +301,11 @@ public abstract class FlowingFluid extends Fluid { +@@ -272,6 +302,11 @@ public abstract class FlowingFluid extends Fluid { object2bytelinkedopenhashmap.putAndMoveToFirst(block_a, (byte) (flag ? 1 : 0)); } @@ -3345,23 +3392,23 @@ index bf4de7b8fd630c596e096a411a8c84c64c13ebf7..6063665b8848a2cd9f0b262eed36a9dd return flag; } -diff --git a/src/main/java/net/minecraft/world/level/storage/loot/LootContext.java b/src/main/java/net/minecraft/world/level/storage/loot/LootContext.java -index 35f9b11a3a61976c952a2c1c64bb2a932538f54f..9e9ac64764cf0a84e25e75d8d6f516cde6047284 100644 ---- a/src/main/java/net/minecraft/world/level/storage/loot/LootContext.java -+++ b/src/main/java/net/minecraft/world/level/storage/loot/LootContext.java -@@ -41,8 +41,10 @@ public class LootContext { +diff --git a/src/main/java/net/minecraft/world/level/storage/loot/LootParams.java b/src/main/java/net/minecraft/world/level/storage/loot/LootParams.java +index e43d07ccdd36f0c9f5b8e9c74cf0d87e17eec66a..8e441f7c2b2d911a0c0111aaa231fc6adae08730 100644 +--- a/src/main/java/net/minecraft/world/level/storage/loot/LootParams.java ++++ b/src/main/java/net/minecraft/world/level/storage/loot/LootParams.java +@@ -21,8 +21,10 @@ public class LootParams { + + public LootParams(ServerLevel world, Map, Object> parameters, Map dynamicDrops, float luck) { this.level = world; - this.lootTables = tableGetter; - this.conditions = conditionGetter; -- this.params = ImmutableMap.copyOf(parameters); -- this.dynamicDrops = ImmutableMap.copyOf(drops); +- this.params = parameters; +- this.dynamicDrops = dynamicDrops; + // Pufferfish start - use unmodifiable maps instead of immutable ones to skip the copy + this.params = java.util.Collections.unmodifiableMap(parameters); -+ this.dynamicDrops = java.util.Collections.unmodifiableMap(drops); ++ this.dynamicDrops = java.util.Collections.unmodifiableMap(dynamicDrops); + // Pufferfish end + this.luck = luck; } - public boolean hasParam(LootContextParam parameter) { diff --git a/src/main/java/net/minecraft/world/phys/shapes/EntityCollisionContext.java b/src/main/java/net/minecraft/world/phys/shapes/EntityCollisionContext.java index ebe65474a4a05ff1637d7f37ebcfe690af59def5..42142c512b12e5b269c19f1e821c50e7496a5f25 100644 --- a/src/main/java/net/minecraft/world/phys/shapes/EntityCollisionContext.java @@ -3449,10 +3496,10 @@ index ebe65474a4a05ff1637d7f37ebcfe690af59def5..42142c512b12e5b269c19f1e821c50e7 @Nullable diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 9f2536d9a73bdb15b5b3004d4da79ca32cee205b..6ff93df3e870ebc6e52f8b8a719908bfa16a839b 100644 +index ec4b73321205b472f19fa5bd4ad95893020d1340..74c46cea456f4a736325892bb7b4d0f1b35b62cd 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -262,7 +262,7 @@ import javax.annotation.Nullable; // Paper +@@ -265,7 +265,7 @@ import javax.annotation.Nullable; // Paper import javax.annotation.Nonnull; // Paper public final class CraftServer implements Server { @@ -3461,7 +3508,7 @@ index 9f2536d9a73bdb15b5b3004d4da79ca32cee205b..6ff93df3e870ebc6e52f8b8a719908bf private final String serverVersion; private final String bukkitVersion = Versioning.getBukkitVersion(); private final Logger logger = Logger.getLogger("Minecraft"); -@@ -1062,6 +1062,11 @@ public final class CraftServer implements Server { +@@ -1140,6 +1140,11 @@ public final class CraftServer implements Server { plugin.getPluginMeta().getDisplayName(), "This plugin is not properly shutting down its async tasks when it is being shut down. This task may throw errors during the final shutdown logs and might not complete before process dies." )); @@ -3486,10 +3533,10 @@ index f7ea77dd82d978ad307f99c743efacfb34478b3d..009ab06182359862b8f543030ec4fe4e } } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 1179e9fbff93ec8ff82aa3aae477f6bf4ce9b885..1ecf065c5323f65401412cb98d4a0b622f356759 100644 +index 719e7103f7dfdc30f1cefd24a3fa572fa0ac8b1e..2b4581f92543c11f31bcc1417e90d7f90b2aea20 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -472,7 +472,7 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -470,7 +470,7 @@ public final class CraftMagicNumbers implements UnsafeValues { @Override public com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() { @@ -3512,7 +3559,7 @@ index 774556a62eb240da42e84db4502e2ed43495be17..80553face9c70c2a3d897681e7761df8 if (stream != null) { diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index 52780192d6417f8085566e4cdf3a895a83638520..07050c78a2eb6ce0c699101b38961b111d631a41 100644 +index eda7f0bb42f7269676d5d2193e1155912ede9920..68557964e27fa1e5ba218178f9bcc0b28e3a78d9 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -38,6 +38,10 @@ import co.aikar.timings.MinecraftTimings; diff --git a/patches/server/0002-Purpur-Server-Changes.patch b/patches/server/0002-Purpur-Server-Changes.patch index 9cb7cea..b451924 100644 --- a/patches/server/0002-Purpur-Server-Changes.patch +++ b/patches/server/0002-Purpur-Server-Changes.patch @@ -25,36 +25,38 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/build.gradle.kts b/build.gradle.kts -index 3ee1160c796cc86db9bc9438055b307239e9a8f7..9c01005751c0088f560f96401cdfdebbbda4e7ec 100644 +index f6cd7b910ce41a254e71bf0fcfe93c38abbb1445..139e2b17b899da6f0147bb8b4412e2e54e817be4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -7,12 +7,8 @@ plugins { - } +@@ -13,12 +13,12 @@ configurations.named(log4jPlugins.compileClasspathConfigurationName) { + val alsoShade: Configuration by configurations.creating dependencies { - implementation(project(":pufferfish-api")) // Pufferfish // Paper - // Pufferfish start - implementation("io.papermc.paper:paper-mojangapi:1.19.2-R0.1-SNAPSHOT") { -- exclude("io.papermc.paper", "paper-api") -- } ++ // Purpur start ++ implementation(project(":purpur-api")) ++ implementation("io.papermc.paper:paper-mojangapi:${project.version}") { + exclude("io.papermc.paper", "paper-api") + } - // Pufferfish end -+ implementation(project(":purpur-api")) // Purpur -+ implementation("io.papermc.paper:paper-mojangapi:1.19.4-R0.1-SNAPSHOT") // Purpur ++ // Purpur end // Paper start implementation("org.jline:jline-terminal-jansi:3.21.0") implementation("net.minecrell:terminalconsoleappender:1.3.0") -@@ -42,6 +38,10 @@ dependencies { - } - // Paper end +@@ -56,6 +56,10 @@ dependencies { + runtimeOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.7.3") + runtimeOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.7.3") + implementation("org.mozilla:rhino-runtime:1.7.14") // Purpur + implementation("org.mozilla:rhino-engine:1.7.14") // Purpur + implementation("dev.omega24:upnp4j:1.0") // Purpur + - runtimeOnly("org.apache.maven:maven-resolver-provider:3.8.5") - runtimeOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.7.3") - runtimeOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.7.3") -@@ -81,7 +81,7 @@ tasks.jar { + // Pufferfish start + implementation("org.yaml:snakeyaml:1.32") + implementation ("com.github.carleslc.Simple-YAML:Simple-Yaml:1.8.4") { +@@ -91,7 +95,7 @@ tasks.jar { attributes( "Main-Class" to "org.bukkit.craftbukkit.Main", "Implementation-Title" to "CraftBukkit", @@ -63,7 +65,7 @@ index 3ee1160c796cc86db9bc9438055b307239e9a8f7..9c01005751c0088f560f96401cdfdebb "Implementation-Vendor" to date, // Paper "Specification-Title" to "Bukkit", "Specification-Version" to project.version, -@@ -153,7 +153,7 @@ fun TaskContainer.registerRunTask( +@@ -168,7 +172,7 @@ fun TaskContainer.registerRunTask( name: String, block: JavaExec.() -> Unit ): TaskProvider = register(name) { @@ -72,6 +74,97 @@ index 3ee1160c796cc86db9bc9438055b307239e9a8f7..9c01005751c0088f560f96401cdfdebb mainClass.set("org.bukkit.craftbukkit.Main") standardInput = System.`in` workingDir = rootProject.layout.projectDirectory +diff --git a/src/log4jPlugins/java/org/purpurmc/purpur/gui/HighlightErrorConverter.java b/src/log4jPlugins/java/org/purpurmc/purpur/gui/HighlightErrorConverter.java +new file mode 100644 +index 0000000000000000000000000000000000000000..15a226e3854d731f7724025ea3459c8ace07630c +--- /dev/null ++++ b/src/log4jPlugins/java/org/purpurmc/purpur/gui/HighlightErrorConverter.java +@@ -0,0 +1,85 @@ ++package org.purpurmc.purpur.gui.util; ++ ++import org.apache.logging.log4j.Level; ++import org.apache.logging.log4j.core.LogEvent; ++import org.apache.logging.log4j.core.config.Configuration; ++import org.apache.logging.log4j.core.config.plugins.Plugin; ++import org.apache.logging.log4j.core.layout.PatternLayout; ++import org.apache.logging.log4j.core.pattern.ConverterKeys; ++import org.apache.logging.log4j.core.pattern.LogEventPatternConverter; ++import org.apache.logging.log4j.core.pattern.PatternConverter; ++import org.apache.logging.log4j.core.pattern.PatternFormatter; ++import org.apache.logging.log4j.core.pattern.PatternParser; ++import org.apache.logging.log4j.util.PerformanceSensitive; ++ ++import java.util.List; ++ ++@Plugin(name = "highlightGUIError", category = PatternConverter.CATEGORY) ++@ConverterKeys({"highlightGUIError"}) ++@PerformanceSensitive("allocation") ++public final class HighlightErrorConverter extends LogEventPatternConverter { ++ private static final String ERROR = "\u00A74\u00A7l"; // Bold Red ++ private static final String WARN = "\u00A7e\u00A7l"; // Bold Yellow ++ ++ private final List formatters; ++ ++ private HighlightErrorConverter(List formatters) { ++ super("highlightGUIError", null); ++ this.formatters = formatters; ++ } ++ ++ @Override ++ public void format(LogEvent event, StringBuilder toAppendTo) { ++ Level level = event.getLevel(); ++ if (level.isMoreSpecificThan(Level.ERROR)) { ++ format(ERROR, event, toAppendTo); ++ return; ++ } else if (level.isMoreSpecificThan(Level.WARN)) { ++ format(WARN, event, toAppendTo); ++ return; ++ } ++ for (PatternFormatter formatter : formatters) { ++ formatter.format(event, toAppendTo); ++ } ++ } ++ ++ private void format(String style, LogEvent event, StringBuilder toAppendTo) { ++ int start = toAppendTo.length(); ++ toAppendTo.append(style); ++ int end = toAppendTo.length(); ++ ++ for (PatternFormatter formatter : formatters) { ++ formatter.format(event, toAppendTo); ++ } ++ ++ if (toAppendTo.length() == end) { ++ toAppendTo.setLength(start); ++ } ++ } ++ ++ @Override ++ public boolean handlesThrowable() { ++ for (final PatternFormatter formatter : formatters) { ++ if (formatter.handlesThrowable()) { ++ return true; ++ } ++ } ++ return false; ++ } ++ ++ public static HighlightErrorConverter newInstance(Configuration config, String[] options) { ++ if (options.length != 1) { ++ LOGGER.error("Incorrect number of options on highlightGUIError. Expected 1 received " + options.length); ++ return null; ++ } ++ ++ if (options[0] == null) { ++ LOGGER.error("No pattern supplied on highlightGUIError"); ++ return null; ++ } ++ ++ PatternParser parser = PatternLayout.createPatternParser(config); ++ List formatters = parser.parse(options[0]); ++ return new HighlightErrorConverter(formatters); ++ } ++} diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java index 692c962193cf9fcc6801fc93f3220bdc673d527b..8cde30544e14f8fc2dac32966ae3c21f8cf3a551 100644 --- a/src/main/java/com/destroystokyo/paper/Metrics.java @@ -249,7 +342,7 @@ index fa56cd09102a89692b42f1d14257990508c5c720..f9251183df72ddc56662fd3f02acf216 setListData(vector); } diff --git a/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java b/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java -index 0dd3374468e05f7a312ba5856b9cf8a4787dfa59..b4e5fbace85c67e7bd347e6a90514bbc2c132d5e 100644 +index 3d4bb28fe686a9ad2e4c0f75f21e6289c2ea5cf9..bff1b41501c040487583a5a279fc7800fc6aedca 100644 --- a/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java +++ b/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java @@ -28,6 +28,7 @@ public class PufferfishConfig { @@ -288,10 +381,10 @@ index 0dd3374468e05f7a312ba5856b9cf8a4787dfa59..b4e5fbace85c67e7bd347e6a90514bbc "This can improve performance by a few percent, but has minor gameplay implications."); } diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java -index ad3560284ae79b9c6bbc8752be7d9d14b18e226e..37d7d89aac826e5e9c072cc82c64ca9192173e91 100644 +index abd0217cf0bff183c8e262edc173a53403797c1a..2519ad2884b6c09b312432b933c31476b369e599 100644 --- a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java +++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java -@@ -922,9 +922,9 @@ public final class ChunkHolderManager { +@@ -1315,9 +1315,9 @@ public final class ChunkHolderManager { } public boolean processTicketUpdates() { @@ -304,10 +397,10 @@ index ad3560284ae79b9c6bbc8752be7d9d14b18e226e..37d7d89aac826e5e9c072cc82c64ca91 private static final ThreadLocal> CURRENT_TICKET_UPDATE_SCHEDULING = new ThreadLocal<>(); diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java -index 8013dd333e27aa5fd0beb431fa32491eec9f5246..e42eb93fd9f6f51ff5bb4b14a2304d4ffcdd8441 100644 +index 51304c5cf4b0ac7646693ef97ef4a3847d3342b5..535ab99585cd4463d051334681bc80b5d20df7c0 100644 --- a/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java +++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java -@@ -1750,7 +1750,7 @@ public final class NewChunkHolder { +@@ -1779,7 +1779,7 @@ public final class NewChunkHolder { boolean canSavePOI = !(chunk instanceof LevelChunk levelChunk && levelChunk.mustNotSave) && (poi != null && poi.isDirty()); boolean canSaveEntities = entities != null; @@ -316,7 +409,7 @@ index 8013dd333e27aa5fd0beb431fa32491eec9f5246..e42eb93fd9f6f51ff5bb4b14a2304d4f if (canSaveChunk) { canSaveChunk = this.saveChunk(chunk, unloading); } -@@ -1764,7 +1764,7 @@ public final class NewChunkHolder { +@@ -1793,7 +1793,7 @@ public final class NewChunkHolder { this.lastEntityUnload = null; } } @@ -448,63 +541,6 @@ index f0fce4113fb07c64adbec029d177c236cbdcbae8..e94224ed280247ee69dfdff8dc960f2b sender.sendMessage(component); } -diff --git a/src/main/java/io/papermc/paper/console/HexFormattingConverter.java b/src/main/java/io/papermc/paper/console/HexFormattingConverter.java -index b9922b07cb105618390187d98acdf89e728e1f5a..6a1eda942aa33fc0802066416f8bc64f5f15d011 100644 ---- a/src/main/java/io/papermc/paper/console/HexFormattingConverter.java -+++ b/src/main/java/io/papermc/paper/console/HexFormattingConverter.java -@@ -38,6 +38,7 @@ public final class HexFormattingConverter extends LogEventPatternConverter { - private static final String ANSI_RESET = "\u001B[m"; - - private static final char COLOR_CHAR = 0x7f; -+ private static final char LEGACY_CHAR = 0xa7; // Purpur - public static final LegacyComponentSerializer SERIALIZER = LegacyComponentSerializer.builder() - .hexColors() - .flattener(PaperAdventure.FLATTENER) -@@ -49,6 +50,8 @@ public final class HexFormattingConverter extends LogEventPatternConverter { - private static final String RESET_RGB_ANSI = ANSI_RESET + RGB_ANSI; - private static final Pattern NAMED_PATTERN = Pattern.compile(COLOR_CHAR + "[0-9a-fk-orA-FK-OR]"); - private static final Pattern RGB_PATTERN = Pattern.compile(COLOR_CHAR + "#([0-9a-fA-F]){6}"); -+ private static final Pattern LEGACY_RGB_PATTERN = Pattern.compile(LEGACY_CHAR + "x((" + LEGACY_CHAR + "[0-9a-fA-F]){6})"); // Purpur -+ private static final Pattern LEGACY_PATTERN = Pattern.compile(LEGACY_CHAR + "([0-9a-fk-orxA-FK-ORX])"); // Purpur - - private static final String[] RGB_ANSI_CODES = new String[]{ - formatHexAnsi(NamedTextColor.BLACK), // Black §0 -@@ -134,7 +137,21 @@ public final class HexFormattingConverter extends LogEventPatternConverter { - } - - private static String convertRGBColors(final String input) { -- return RGB_PATTERN.matcher(input).replaceAll(result -> { -+ // Purpur start - lets just shove this back in place -+ Matcher matcher = LEGACY_RGB_PATTERN.matcher(input); -+ StringBuilder buffer = new StringBuilder(); -+ while (matcher.find()) { -+ String s = matcher.group().replace(String.valueOf(LEGACY_CHAR), "").replace('x', '#'); -+ int hex = Integer.decode(s); -+ int red = (hex >> 16) & 0xFF; -+ int green = (hex >> 8) & 0xFF; -+ int blue = hex & 0xFF; -+ String replacement = String.format(RGB_ANSI, red, green, blue); -+ matcher.appendReplacement(buffer, replacement); -+ } -+ matcher.appendTail(buffer); -+ return RGB_PATTERN.matcher(buffer.toString()).replaceAll(result -> { -+ // Purpur end - final int hex = Integer.decode(result.group().substring(1)); - return formatHexAnsi(hex); - }); -@@ -152,10 +169,11 @@ public final class HexFormattingConverter extends LogEventPatternConverter { - } - - private static String stripRGBColors(final String input) { -- return RGB_PATTERN.matcher(input).replaceAll(""); -+ return LEGACY_RGB_PATTERN.matcher(RGB_PATTERN.matcher(input).replaceAll("")).replaceAll(""); // Purpur - } - - static void format(String content, StringBuilder result, int start, boolean ansi) { -+ content = LEGACY_PATTERN.matcher(content).replaceAll(COLOR_CHAR + "$1"); // Purpur - int next = content.indexOf(COLOR_CHAR); - int last = content.length() - 1; - if (next == -1 || next == last) { diff --git a/src/main/java/io/papermc/paper/logging/SysoutCatcher.java b/src/main/java/io/papermc/paper/logging/SysoutCatcher.java index a8e813ca89b033f061e695288b3383bdcf128531..1ab65af9359d19530bba7f985a604d2a430ee234 100644 --- a/src/main/java/io/papermc/paper/logging/SysoutCatcher.java @@ -657,10 +693,10 @@ index abe37c7c3c6f5ab73afd738ec78f06d7e4d2ed96..b5b6657e52e4f7a630229bd3ba433438 stringbuilder.append(CrashReport.getErrorComment()); stringbuilder.append("\n\n"); diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java -index 7b6b51392b123d34382233adcf4c3d4867bdaa32..941f3a0d50329658a9380500ef039d7f10a284e2 100644 +index 0de2eae2d448ac9e269a4edf48406d5ea8af8059..873659dcf8c8431f21bd2b23b8d7bdb4ea7e03e8 100644 --- a/src/main/java/net/minecraft/commands/CommandSourceStack.java +++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java -@@ -212,6 +212,21 @@ public class CommandSourceStack implements SharedSuggestionProvider, com.destroy +@@ -227,6 +227,19 @@ public class CommandSourceStack implements SharedSuggestionProvider, com.destroy } // CraftBukkit end @@ -669,11 +705,9 @@ index 7b6b51392b123d34382233adcf4c3d4867bdaa32..941f3a0d50329658a9380500ef039d7f + if (hasPermission(i, bukkitPermission)) { + return true; + } -+ String permissionMessage = getLevel().getServer().server.getPermissionMessage(); -+ if (!permissionMessage.isBlank()) { -+ for (String line : permissionMessage.replace("", bukkitPermission).split("\n")) { -+ sendFailure(Component.literal(line)); -+ } ++ net.kyori.adventure.text.Component permissionMessage = getLevel().getServer().server.permissionMessage(); ++ if (!permissionMessage.equals(net.kyori.adventure.text.Component.empty())) { ++ sendFailure(io.papermc.paper.adventure.PaperAdventure.asVanilla(permissionMessage.replaceText(net.kyori.adventure.text.TextReplacementConfig.builder().matchLiteral("").replacement(bukkitPermission).build()))); + } + return false; + } @@ -682,7 +716,7 @@ index 7b6b51392b123d34382233adcf4c3d4867bdaa32..941f3a0d50329658a9380500ef039d7f public Vec3 getPosition() { return this.worldPosition; } -@@ -317,6 +332,30 @@ public class CommandSourceStack implements SharedSuggestionProvider, com.destroy +@@ -336,6 +349,30 @@ public class CommandSourceStack implements SharedSuggestionProvider, com.destroy } } @@ -706,18 +740,18 @@ index 7b6b51392b123d34382233adcf4c3d4867bdaa32..941f3a0d50329658a9380500ef039d7f + if (message == null) { + return; + } -+ sendSuccess(io.papermc.paper.adventure.PaperAdventure.asVanilla(message), broadcastToOps); ++ sendSuccess(() -> io.papermc.paper.adventure.PaperAdventure.asVanilla(message), broadcastToOps); + } + // Purpur end + - public void sendSuccess(Component message, boolean broadcastToOps) { - if (this.source.acceptsSuccess() && !this.silent) { - this.source.sendSystemMessage(message); + public void sendSuccess(Supplier feedbackSupplier, boolean broadcastToOps) { + boolean flag1 = this.source.acceptsSuccess() && !this.silent; + boolean flag2 = broadcastToOps && this.source.shouldInformAdmins() && !this.silent; diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java -index 87cc7562e4a166d078fe11b7f6980497fc0bd33e..08bed4f01a27162902aa63bb8d35a9159fdcfc4e 100644 +index 80c2c8d565f03ae0ea24fbdecdbe2bc5b9aa4b82..5c0085589b08f199c75ceeab8d0cf25e970a0533 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java -@@ -149,7 +149,7 @@ public class Commands { +@@ -150,7 +150,7 @@ public class Commands { DamageCommand.register(this.dispatcher, commandRegistryAccess); DataCommands.register(this.dispatcher); DataPackCommand.register(this.dispatcher); @@ -726,7 +760,7 @@ index 87cc7562e4a166d078fe11b7f6980497fc0bd33e..08bed4f01a27162902aa63bb8d35a915 DefaultGameModeCommands.register(this.dispatcher); DifficultyCommand.register(this.dispatcher); EffectCommands.register(this.dispatcher, commandRegistryAccess); -@@ -222,6 +222,14 @@ public class Commands { +@@ -224,6 +224,14 @@ public class Commands { SetPlayerIdleTimeoutCommand.register(this.dispatcher); StopCommand.register(this.dispatcher); WhitelistCommand.register(this.dispatcher); @@ -741,7 +775,7 @@ index 87cc7562e4a166d078fe11b7f6980497fc0bd33e..08bed4f01a27162902aa63bb8d35a915 } if (environment.includeIntegrated) { -@@ -309,9 +317,9 @@ public class Commands { +@@ -311,9 +319,9 @@ public class Commands { public int performCommand(ParseResults parseresults, String s, String label) { // CraftBukkit CommandSourceStack commandlistenerwrapper = (CommandSourceStack) parseresults.getContext().getSource(); @@ -753,7 +787,7 @@ index 87cc7562e4a166d078fe11b7f6980497fc0bd33e..08bed4f01a27162902aa63bb8d35a915 byte b0; -@@ -394,7 +402,7 @@ public class Commands { +@@ -396,7 +404,7 @@ public class Commands { b0 = 0; } } finally { @@ -762,7 +796,7 @@ index 87cc7562e4a166d078fe11b7f6980497fc0bd33e..08bed4f01a27162902aa63bb8d35a915 } return b0; -@@ -454,6 +462,7 @@ public class Commands { +@@ -456,6 +464,7 @@ public class Commands { private void runSync(ServerPlayer player, Collection bukkit, RootCommandNode rootcommandnode) { // Paper end - Async command map building new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendCommandsEvent(player.getBukkitEntity(), (RootCommandNode) rootcommandnode, false).callEvent(); // Paper @@ -770,7 +804,7 @@ index 87cc7562e4a166d078fe11b7f6980497fc0bd33e..08bed4f01a27162902aa63bb8d35a915 PlayerCommandSendEvent event = new PlayerCommandSendEvent(player.getBukkitEntity(), new LinkedHashSet<>(bukkit)); event.getPlayer().getServer().getPluginManager().callEvent(event); -@@ -464,6 +473,7 @@ public class Commands { +@@ -466,6 +475,7 @@ public class Commands { } } // CraftBukkit end @@ -833,10 +867,10 @@ index f25b9330e068c7d9e12cb57a7761cfef9ebaf7bc..7e66aaa960ce7b6dda7c064d4c6856cc + // Purpur end } diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java -index b37e0ff164a894d2033fb94bbbc2f630a0e66bcd..ac335ec4f70830c7687ac4e0aa2a6cba9cb04ae1 100644 +index 83cab746d1d6fe25c043c8aee28c39412b90c127..ec6b58dae525c81bbb1c0e2d96fbded6f00a45b5 100644 --- a/src/main/java/net/minecraft/core/BlockPos.java +++ b/src/main/java/net/minecraft/core/BlockPos.java -@@ -41,6 +41,12 @@ public class BlockPos extends Vec3i { +@@ -48,6 +48,12 @@ public class BlockPos extends Vec3i { private static final int X_OFFSET = 38; // Paper end @@ -850,10 +884,10 @@ index b37e0ff164a894d2033fb94bbbc2f630a0e66bcd..ac335ec4f70830c7687ac4e0aa2a6cba super(x, y, z); } diff --git a/src/main/java/net/minecraft/core/Direction.java b/src/main/java/net/minecraft/core/Direction.java -index 82bce6109d59cba30178a446f0ff129da6f3692f..eaa620ad86abfb151b43f697973cbc731e2e5e92 100644 +index d0a8092bf57a29ab7c00ec0ddf52a9fdb2a33267..defe5951938ce3a7b7f83017d4af36bb49ff5be0 100644 --- a/src/main/java/net/minecraft/core/Direction.java +++ b/src/main/java/net/minecraft/core/Direction.java -@@ -248,6 +248,12 @@ public enum Direction implements StringRepresentable { +@@ -238,6 +238,12 @@ public enum Direction implements StringRepresentable { case EAST: var10000 = SOUTH; break; @@ -866,7 +900,7 @@ index 82bce6109d59cba30178a446f0ff129da6f3692f..eaa620ad86abfb151b43f697973cbc73 default: throw new IllegalStateException("Unable to get Y-rotated facing of " + this); } -@@ -360,6 +366,12 @@ public enum Direction implements StringRepresentable { +@@ -350,6 +356,12 @@ public enum Direction implements StringRepresentable { case EAST: var10000 = NORTH; break; @@ -880,18 +914,10 @@ index 82bce6109d59cba30178a446f0ff129da6f3692f..eaa620ad86abfb151b43f697973cbc73 throw new IllegalStateException("Unable to get CCW facing of " + this); } diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -index 88d18d18d69876c98e199acb647c6cca9448d55d..da9cc93f560269a00f0093ad76aba3a05eedb046 100644 +index 70aade6a8d36f8376cc567800258ea6fabb0607f..d44fde7e44cc862253fe577eb0753524ab7a39dc 100644 --- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -@@ -52,6 +52,7 @@ import net.minecraft.world.item.SpawnEggItem; - import net.minecraft.world.item.alchemy.PotionUtils; - import net.minecraft.world.item.alchemy.Potions; - import net.minecraft.world.level.Level; -+import net.minecraft.world.level.block.AnvilBlock; - import net.minecraft.world.level.block.BaseFireBlock; - import net.minecraft.world.level.block.BeehiveBlock; - import net.minecraft.world.level.block.Block; -@@ -1168,6 +1169,23 @@ public interface DispenseItemBehavior { +@@ -1186,6 +1186,23 @@ public interface DispenseItemBehavior { } } }); @@ -905,7 +931,7 @@ index 88d18d18d69876c98e199acb647c6cca9448d55d..da9cc93f560269a00f0093ad76aba3a0 + BlockPos pos = dispenser.getPos().relative(facing); + BlockState state = level.getBlockState(pos); + if (state.isAir()) { -+ level.setBlockAndUpdate(pos, Blocks.ANVIL.defaultBlockState().setValue(AnvilBlock.FACING, facing.getAxis() == Direction.Axis.Y ? Direction.NORTH : facing.getClockWise())); ++ level.setBlockAndUpdate(pos, Blocks.ANVIL.defaultBlockState().setValue(net.minecraft.world.level.block.AnvilBlock.FACING, facing.getAxis() == Direction.Axis.Y ? Direction.NORTH : facing.getClockWise())); + stack.shrink(1); + } + return stack; @@ -916,7 +942,7 @@ index 88d18d18d69876c98e199acb647c6cca9448d55d..da9cc93f560269a00f0093ad76aba3a0 static void setEntityPokingOutOfBlock(BlockSource pointer, Entity entity, 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 d1127d93a85a837933d0d73c24cacac4adc3a5b9..d9a6d273108165f59b995b1fd7748cb5c12b8b1f 100644 +index 9b0049dfeaec9b688bf276f2ac2b18943b5696b2..d7563904232353cbf3b9255cedfb75920e35220c 100644 --- a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java @@ -107,7 +107,7 @@ public class ShearsDispenseItemBehavior extends OptionalDispenseItemBehavior { @@ -929,10 +955,10 @@ index d1127d93a85a837933d0d73c24cacac4adc3a5b9..d9a6d273108165f59b995b1fd7748cb5 return true; } diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java -index f9e10bf048929886db3c414038d2c7e9f84226a6..323416311f14f5ad887f05183ad3b4921981aecd 100644 +index cf20f0983fc25b26cf92b9d3a28746b1909fc56b..89c1b69ddeb420c2fbda5f588e7c9a467a76089d 100644 --- a/src/main/java/net/minecraft/network/Connection.java +++ b/src/main/java/net/minecraft/network/Connection.java -@@ -572,11 +572,20 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -579,11 +579,20 @@ public class Connection extends SimpleChannelInboundHandler> { private static final int MAX_PER_TICK = io.papermc.paper.configuration.GlobalConfiguration.get().misc.maxJoinsPerTick; // Paper private static int joinAttemptsThisTick; // Paper private static int currTick; // Paper @@ -997,31 +1023,6 @@ index d2f0a0755317f5fa9a1ccf7db346aa77fd287d80..03852e7d21d9470a4469676367463fef packet.handle(listener); } catch (Exception exception) { if (listener.shouldPropagateHandlingExceptions()) { -diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerCombatKillPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerCombatKillPacket.java -index 53b75f5737a910ffc5448cd9a85eae57f9c1488f..ea95873dd034779e56a8b924cd27f9375be05daf 100644 ---- a/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerCombatKillPacket.java -+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerCombatKillPacket.java -@@ -9,6 +9,7 @@ public class ClientboundPlayerCombatKillPacket implements Packet processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); public int autosavePeriod; public Commands vanillaCommandDispatcher; -@@ -305,10 +306,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { +@@ -337,13 +340,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0 && this.tickCount % autosavePeriod == 0; try { this.isSaving = true; -@@ -1422,20 +1447,20 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { +@@ -1495,22 +1520,22 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { this.executeBlocking(() -> { this.saveDebugReport(path.resolve("server")); -@@ -2519,40 +2541,40 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { final io.papermc.paper.adventure.ChatDecorationProcessor processor = new io.papermc.paper.adventure.ChatDecorationProcessor(this, sender, commandSourceStack, message); -@@ -2775,7 +2806,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop functions, ResourceLocation label) { @@ -1620,7 +1604,7 @@ index 6483a1d461904a0584b6808b2f86ac7329bba963..8645313e646e6d5278e285f744944776 Iterator iterator = functions.iterator(); while (iterator.hasNext()) { -@@ -69,7 +69,7 @@ public class ServerFunctionManager { +@@ -70,7 +70,7 @@ public class ServerFunctionManager { this.execute(customfunction, this.getGameLoopSender()); } @@ -1629,7 +1613,7 @@ index 6483a1d461904a0584b6808b2f86ac7329bba963..8645313e646e6d5278e285f744944776 } public int execute(CommandFunction function, CommandSourceStack source) { -@@ -88,7 +88,7 @@ public class ServerFunctionManager { +@@ -89,7 +89,7 @@ public class ServerFunctionManager { } else { int i; @@ -1638,22 +1622,22 @@ index 6483a1d461904a0584b6808b2f86ac7329bba963..8645313e646e6d5278e285f744944776 this.context = new ServerFunctionManager.ExecutionContext(tracer); i = this.context.runTopCommand(function, source); } finally { -@@ -177,10 +177,10 @@ public class ServerFunctionManager { +@@ -187,10 +187,10 @@ public class ServerFunctionManager { try { - ServerFunctionManager.QueuedCommand customfunctiondata_b = (ServerFunctionManager.QueuedCommand) this.commandQueue.removeFirst(); + ServerFunctionManager.QueuedCommand customfunctiondata_queuedcommand = (ServerFunctionManager.QueuedCommand) this.commandQueue.removeFirst(); - ProfilerFiller gameprofilerfiller = ServerFunctionManager.this.server.getProfiler(); + //ProfilerFiller gameprofilerfiller = ServerFunctionManager.this.server.getProfiler(); // Purpur - Objects.requireNonNull(customfunctiondata_b); -- gameprofilerfiller.push(customfunctiondata_b::toString); -+ //gameprofilerfiller.push(customfunctiondata_b::toString); // Purpur - this.depth = customfunctiondata_b.depth; - customfunctiondata_b.execute(ServerFunctionManager.this, this.commandQueue, i, this.tracer); - if (!this.nestedCalls.isEmpty()) { -@@ -192,7 +192,7 @@ public class ServerFunctionManager { - this.nestedCalls.clear(); - } + Objects.requireNonNull(customfunctiondata_queuedcommand); +- gameprofilerfiller.push(customfunctiondata_queuedcommand::toString); ++ //gameprofilerfiller.push(customfunctiondata_queuedcommand::toString); // Purpur + this.depth = customfunctiondata_queuedcommand.depth; + customfunctiondata_queuedcommand.execute(ServerFunctionManager.this, this.commandQueue, i, this.tracer); + if (this.abortCurrentDepth) { +@@ -209,7 +209,7 @@ public class ServerFunctionManager { + + this.nestedCalls.clear(); } finally { - ServerFunctionManager.this.server.getProfiler().pop(); + //ServerFunctionManager.this.server.getProfiler().pop(); // Purpur @@ -1661,7 +1645,7 @@ index 6483a1d461904a0584b6808b2f86ac7329bba963..8645313e646e6d5278e285f744944776 ++j; diff --git a/src/main/java/net/minecraft/server/commands/EnchantCommand.java b/src/main/java/net/minecraft/server/commands/EnchantCommand.java -index e639c0ec642910e66b1d68ae0b9208ef58d91fce..24c4ad919eeb9c5e15572ee32b0895c993ac6735 100644 +index 664cbce2e06fcb95d3d3d6c5302fc9119f938925..bc9778c705d23acd84fa1cdeff6b403b4cda3686 100644 --- a/src/main/java/net/minecraft/server/commands/EnchantCommand.java +++ b/src/main/java/net/minecraft/server/commands/EnchantCommand.java @@ -48,7 +48,7 @@ public class EnchantCommand { @@ -1683,10 +1667,10 @@ index e639c0ec642910e66b1d68ae0b9208ef58d91fce..24c4ad919eeb9c5e15572ee32b0895c9 ++i; } else if (targets.size() == 1) { diff --git a/src/main/java/net/minecraft/server/commands/GameModeCommand.java b/src/main/java/net/minecraft/server/commands/GameModeCommand.java -index 27c0aaf123c3e945eb24e8a3892bd8ac42115733..85e1c1d6eb4472baa958b4f482791e8479dfcbf0 100644 +index 5cb15e2209d7b315904a1fc6d650ce1e75584271..7e21db60f3ace2a19686d6ea04b994ec3a793ec8 100644 --- a/src/main/java/net/minecraft/server/commands/GameModeCommand.java +++ b/src/main/java/net/minecraft/server/commands/GameModeCommand.java -@@ -41,6 +41,18 @@ public class GameModeCommand { +@@ -45,6 +45,18 @@ public class GameModeCommand { } private static int setMode(CommandContext context, Collection targets, GameType gameMode) { @@ -1706,19 +1690,19 @@ index 27c0aaf123c3e945eb24e8a3892bd8ac42115733..85e1c1d6eb4472baa958b4f482791e84 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 ee7d29d85c8b024c9b23cba8ecd4192aa7e8aa7b..7a44bac6e66bc5f5fe14a45a5e7c78c940fb1efb 100644 +index d601d287e94a59ff93b8a83a44dac02544d211df..0ff3b06a98b2f4514b2d861b92dd70fe678ae86c 100644 --- a/src/main/java/net/minecraft/server/commands/GiveCommand.java +++ b/src/main/java/net/minecraft/server/commands/GiveCommand.java -@@ -58,6 +58,7 @@ public class GiveCommand { - boolean flag = entityplayer.getInventory().add(itemstack); +@@ -59,6 +59,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 && itemstack.isEmpty()) { - itemstack.setCount(1); - entityitem = entityplayer.drop(itemstack, false, false, false); // SPIGOT-2942: Add boolean to call event + if (flag && itemstack1.isEmpty()) { + itemstack1.setCount(1); + entityitem = entityplayer.drop(itemstack1, false, false, false); // SPIGOT-2942: Add boolean to call event diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index ad4fdbdcf09f30d10e61ccf47f8fb9ce6bd92e73..6ecc75621867390738e804e06ac284524664473d 100644 +index 10501842887c1ffdb6bb667480682b7174fd89c6..2a70abb9e0af502885593df1e732887cd9d2ce4d 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java @@ -99,6 +99,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface @@ -1780,17 +1764,16 @@ index ad4fdbdcf09f30d10e61ccf47f8fb9ce6bd92e73..6ecc75621867390738e804e06ac28452 // CraftBukkit start // this.setPlayerList(new DedicatedPlayerList(this, this.registries(), this.playerDataStorage)); // Spigot - moved up -@@ -342,6 +377,9 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -341,6 +376,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface } if (gg.pufferfish.pufferfish.PufferfishConfig.enableAsyncMobSpawning) mobSpawnExecutor.start(); // Pufferfish + org.purpurmc.purpur.task.BossBarTask.startAll(); // Purpur + org.purpurmc.purpur.task.BeehiveTask.instance().register(); // Purpur -+ return true; } } -@@ -488,7 +526,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -487,7 +524,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface } public void handleConsoleInputs() { @@ -1799,7 +1782,7 @@ index ad4fdbdcf09f30d10e61ccf47f8fb9ce6bd92e73..6ecc75621867390738e804e06ac28452 // Paper start - use proper queue ConsoleInput servercommand; while ((servercommand = this.serverCommandQueue.poll()) != null) { -@@ -505,7 +543,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -504,7 +541,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface // CraftBukkit end } @@ -1821,7 +1804,7 @@ index 818289e831e3dad29345c43265e2efd7689bc500..1ea3012995c738c67b31e997c138f824 public final boolean spawnNpcs = this.get("spawn-npcs", true); public final boolean pvp = this.get("pvp", true); diff --git a/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java b/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java -index c07918aa1ed2469ad7a76a0add60ab648ff7f421..56cf3d5b8e365ce6b1ec88464d9079d774206755 100644 +index dd9f611efc95f7d06fd3011fedd5d0317b1d0a85..be7b3fe2dc84493dcde9e185717b0b7c7c2e9822 100644 --- a/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java +++ b/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java @@ -43,6 +43,11 @@ public class MinecraftServerGui extends JComponent { @@ -1919,7 +1902,7 @@ index c07918aa1ed2469ad7a76a0add60ab648ff7f421..56cf3d5b8e365ce6b1ec88464d9079d7 @@ -176,7 +214,7 @@ public class MinecraftServerGui extends JComponent { } - private static final java.util.regex.Pattern ANSI = java.util.regex.Pattern.compile("\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})*)?[m|K]"); // CraftBukkit + private static final java.util.regex.Pattern ANSI = java.util.regex.Pattern.compile("\\e\\[[\\d;]*[^\\d;]"); // CraftBukkit // Paper - public void print(JTextArea textArea, JScrollPane scrollPane, String message) { + public void print(org.purpurmc.purpur.gui.JColorTextPane textArea, JScrollPane scrollPane, String message) { // Purpur if (!SwingUtilities.isEventDispatchThread()) { @@ -1958,10 +1941,10 @@ index c07918aa1ed2469ad7a76a0add60ab648ff7f421..56cf3d5b8e365ce6b1ec88464d9079d7 + // Purpur end } diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 3ce4dbf4eed442d89d6bbc8e4c6a000172041da5..57fdef8b16e1ed9a4693356144b4685bbcea285c 100644 +index 3770ced0b227f7eea1f04d6afd5c14331f6a1480..319c469c20f3cb4f6d61425bfa6d98b55b55c4d6 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -621,20 +621,20 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -637,20 +637,20 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } protected void tick(BooleanSupplier shouldKeepTicking) { @@ -1990,16 +1973,7 @@ index 3ce4dbf4eed442d89d6bbc8e4c6a000172041da5..57fdef8b16e1ed9a4693356144b4685b } public boolean hasWork() { -@@ -998,7 +998,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - return this.anyPlayerCloseEnoughForSpawning(this.getUpdatingChunkIfPresent(chunkcoordintpair.toLong()), chunkcoordintpair, reducedRange); - } - -- final boolean anyPlayerCloseEnoughForSpawning(ChunkHolder playerchunk, ChunkPos chunkcoordintpair, boolean reducedRange) { -+ public final boolean anyPlayerCloseEnoughForSpawning(ChunkHolder playerchunk, ChunkPos chunkcoordintpair, boolean reducedRange) { // Purpur - package -> public - // this function is so hot that removing the map lookup call can have an order of magnitude impact on its performance - // tested and confirmed via System.nanoTime() - com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet playersInRange = reducedRange ? playerchunk.playersInMobSpawnRange : playerchunk.playersInChunkTickRange; -@@ -1253,24 +1253,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1269,24 +1269,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider // Paper start - optimised tracker private final void processTrackQueue() { @@ -2024,11 +1998,11 @@ index 3ce4dbf4eed442d89d6bbc8e4c6a000172041da5..57fdef8b16e1ed9a4693356144b4685b } } finally { - this.level.timings.tracker2.stopTiming(); -+ //this.level.timings.tracker2.stopTiming(); // Purpur ++ //this.level.timings.tracker2.stopTiming(); Purpur } } // Paper end - optimised tracker -@@ -1285,7 +1285,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1301,7 +1301,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider List list = Lists.newArrayList(); List list1 = this.level.players(); ObjectIterator objectiterator = this.entityMap.values().iterator(); @@ -2037,7 +2011,7 @@ index 3ce4dbf4eed442d89d6bbc8e4c6a000172041da5..57fdef8b16e1ed9a4693356144b4685b ChunkMap.TrackedEntity playerchunkmap_entitytracker; -@@ -1310,17 +1310,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1326,17 +1326,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider playerchunkmap_entitytracker.serverEntity.sendChanges(); } } @@ -2059,10 +2033,10 @@ index 3ce4dbf4eed442d89d6bbc8e4c6a000172041da5..57fdef8b16e1ed9a4693356144b4685b } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index c6f5d6756fa0e068a462d9c0ded12e0771abba37..0ae45cf5a084fd412305e8b2f5dabe608b4eb1c1 100644 +index fe1a9c646b09d11e7fa2186afbeb70b680ad2b57..2d5b0f293bb30243e774bfb62b8100c01e7eb383 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -431,16 +431,16 @@ public class ServerChunkCache extends ChunkSource { +@@ -280,16 +280,16 @@ public class ServerChunkCache extends ChunkSource { return ifLoaded; } // Paper end @@ -2082,7 +2056,7 @@ index c6f5d6756fa0e068a462d9c0ded12e0771abba37..0ae45cf5a084fd412305e8b2f5dabe60 CompletableFuture> completablefuture = this.getChunkFutureMainThread(x, z, leastStatus, create, true); // Paper ServerChunkCache.MainThreadExecutor chunkproviderserver_b = this.mainThreadProcessor; -@@ -450,10 +450,10 @@ public class ServerChunkCache extends ChunkSource { +@@ -299,10 +299,10 @@ public class ServerChunkCache extends ChunkSource { io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.pushChunkWait(this.level, x1, z1); // Paper - rewrite chunk system // Paper end com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.level, x1, z1); // Paper - sync load info @@ -2095,7 +2069,7 @@ index c6f5d6756fa0e068a462d9c0ded12e0771abba37..0ae45cf5a084fd412305e8b2f5dabe60 } // Paper ichunkaccess = (ChunkAccess) ((Either) completablefuture.join()).map((ichunkaccess1) -> { return ichunkaccess1; -@@ -601,17 +601,17 @@ public class ServerChunkCache extends ChunkSource { +@@ -451,17 +451,17 @@ public class ServerChunkCache extends ChunkSource { public void save(boolean flush) { this.runDistanceManagerUpdates(); @@ -2117,7 +2091,7 @@ index c6f5d6756fa0e068a462d9c0ded12e0771abba37..0ae45cf5a084fd412305e8b2f5dabe60 } // Paper end -@@ -628,36 +628,36 @@ public class ServerChunkCache extends ChunkSource { +@@ -478,36 +478,36 @@ public class ServerChunkCache extends ChunkSource { // CraftBukkit start - modelled on below public void purgeUnload() { if (true) return; // Paper - tickets will be removed later, this behavior isn't really well accounted for by the chunk system @@ -2149,7 +2123,7 @@ index c6f5d6756fa0e068a462d9c0ded12e0771abba37..0ae45cf5a084fd412305e8b2f5dabe60 if (tickChunks) { - this.level.timings.chunks.startTiming(); // Paper - timings + //this.level.timings.chunks.startTiming(); // Paper - timings // Purpur - this.chunkMap.playerChunkManager.tick(); // Paper - this is mostly is to account for view distance changes + this.chunkMap.level.playerChunkLoader.tick(); // Paper - replace player chunk loader - this is mostly required to account for view distance changes this.tickChunks(); - this.level.timings.chunks.stopTiming(); // Paper - timings + //this.level.timings.chunks.stopTiming(); // Paper - timings // Purpur @@ -2167,7 +2141,7 @@ index c6f5d6756fa0e068a462d9c0ded12e0771abba37..0ae45cf5a084fd412305e8b2f5dabe60 this.clearCache(); } -@@ -703,15 +703,15 @@ public class ServerChunkCache extends ChunkSource { +@@ -553,15 +553,15 @@ public class ServerChunkCache extends ChunkSource { } // Paper end - optimize isOutisdeRange LevelData worlddata = this.level.getLevelData(); @@ -2187,7 +2161,7 @@ index c6f5d6756fa0e068a462d9c0ded12e0771abba37..0ae45cf5a084fd412305e8b2f5dabe60 int l = this.distanceManager.getNaturalSpawnChunkCount(); // Paper start - per player mob spawning NaturalSpawner.SpawnState spawnercreature_d; // moved down -@@ -732,16 +732,16 @@ public class ServerChunkCache extends ChunkSource { +@@ -592,16 +592,16 @@ public class ServerChunkCache extends ChunkSource { // Pufferfish end } // Paper end @@ -2208,7 +2182,7 @@ index c6f5d6756fa0e068a462d9c0ded12e0771abba37..0ae45cf5a084fd412305e8b2f5dabe60 boolean flag2 = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit // Paper - only shuffle if per-player mob spawning is disabled -@@ -791,17 +791,17 @@ public class ServerChunkCache extends ChunkSource { +@@ -652,17 +652,17 @@ public class ServerChunkCache extends ChunkSource { } } // Paper end - optimise chunk tick iteration @@ -2233,7 +2207,7 @@ index c6f5d6756fa0e068a462d9c0ded12e0771abba37..0ae45cf5a084fd412305e8b2f5dabe60 if (!this.chunkMap.needsChangeBroadcasting.isEmpty()) { ReferenceOpenHashSet copy = this.chunkMap.needsChangeBroadcasting.clone(); this.chunkMap.needsChangeBroadcasting.clear(); -@@ -813,8 +813,8 @@ public class ServerChunkCache extends ChunkSource { +@@ -674,8 +674,8 @@ public class ServerChunkCache extends ChunkSource { } } } @@ -2244,7 +2218,7 @@ index c6f5d6756fa0e068a462d9c0ded12e0771abba37..0ae45cf5a084fd412305e8b2f5dabe60 // Paper end - use set of chunks requiring updates, rather than iterating every single one loaded // Paper start - controlled flush for entity tracker packets List disabledFlushes = new java.util.ArrayList<>(this.level.players.size()); -@@ -1029,7 +1029,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -900,7 +900,7 @@ public class ServerChunkCache extends ChunkSource { @Override protected void doRunTask(Runnable task) { @@ -2254,10 +2228,10 @@ index c6f5d6756fa0e068a462d9c0ded12e0771abba37..0ae45cf5a084fd412305e8b2f5dabe60 } diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java -index d5cb594f0b17ec9dc1a19cdb99bba553e70171be..6afee2a744a3498d4a0eee35f77cde444f73d12c 100644 +index 8ab959dd588b5154b63e133b2e937fa2d0ab8e52..fb11b020d52988360562db23d8568e5ef37e21c8 100644 --- a/src/main/java/net/minecraft/server/level/ServerEntity.java +++ b/src/main/java/net/minecraft/server/level/ServerEntity.java -@@ -72,7 +72,7 @@ public class ServerEntity { +@@ -70,7 +70,7 @@ public class ServerEntity { @Nullable private List> trackedDataValues; // CraftBukkit start @@ -2267,19 +2241,19 @@ index d5cb594f0b17ec9dc1a19cdb99bba553e70171be..6afee2a744a3498d4a0eee35f77cde44 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 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc74459822a48 100644 +index eac31c3fcc9161711328588ac852fcae1116d8ef..221d1d0e1b4b46de6ebca5faac09bbda875fae17 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -212,6 +212,8 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -214,6 +214,8 @@ public class ServerLevel extends Level implements WorldGenLevel { private final StructureManager structureManager; private final StructureCheck structureCheck; private final boolean tickTime; + private double preciseTime; // Purpur + private boolean forceTime; // Purpur + private final RandomSequences randomSequences; public long lastMidTickExecuteFailure; // Paper - execute chunk tasks mid tick - // CraftBukkit start -@@ -220,6 +222,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -223,6 +225,7 @@ public class ServerLevel extends Level implements WorldGenLevel { public boolean hasPhysicsEvent = true; // Paper public boolean hasEntityMoveEvent = false; // Paper private final alternate.current.wire.WireHandler wireHandler = new alternate.current.wire.WireHandler(this); // Paper - optimize redstone (Alternate Current) @@ -2287,7 +2261,7 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 public static Throwable getAddToWorldStackTrace(Entity entity) { final Throwable thr = new Throwable(entity + " Added to world at " + new java.util.Date()); io.papermc.paper.util.StacktraceDeobfuscator.INSTANCE.deobfuscateThrowable(thr); -@@ -542,7 +545,24 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -662,7 +665,24 @@ public class ServerLevel extends Level implements WorldGenLevel { this.dragonParts = new Int2ObjectOpenHashMap(); this.tickTime = flag1; this.server = minecraftserver; @@ -2313,15 +2287,15 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 this.serverLevelData = iworlddataserver; ChunkGenerator chunkgenerator = worlddimension.generator(); // CraftBukkit start -@@ -605,6 +625,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -732,6 +752,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 + this.preciseTime = this.serverLevelData.getDayTime(); // Purpur } - public void setWeatherParameters(int clearDuration, int rainDuration, boolean raining, boolean thundering) { -@@ -633,17 +654,17 @@ public class ServerLevel extends Level implements WorldGenLevel { + // Paper start +@@ -774,17 +795,17 @@ public class ServerLevel extends Level implements WorldGenLevel { } } // Paper end - optimise checkDespawn @@ -2343,7 +2317,7 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 // CraftBukkit start j = this.levelData.getDayTime() + 24000L; TimeSkipEvent event = new TimeSkipEvent(this.getWorld(), TimeSkipEvent.SkipReason.NIGHT_SKIP, (j - j % 24000L) - this.getDayTime()); -@@ -665,32 +686,32 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -806,32 +827,32 @@ public class ServerLevel extends Level implements WorldGenLevel { this.updateSkyBrightness(); this.tickTime(); @@ -2392,7 +2366,7 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 boolean flag = true || !this.players.isEmpty() || !this.getForcedChunks().isEmpty(); // CraftBukkit - this prevents entity cleanup, other issues on servers with no players if (flag) { -@@ -698,25 +719,25 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -839,25 +860,25 @@ public class ServerLevel extends Level implements WorldGenLevel { } if (flag || this.emptyTime++ < 300) { @@ -2425,7 +2399,7 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 if (true || this.chunkSource.chunkMap.getDistanceManager().inEntityTickingRange(entity.chunkPosition().toLong())) { // Paper - now always true if in the ticking list Entity entity1 = entity.getVehicle(); -@@ -728,7 +749,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -869,7 +890,7 @@ public class ServerLevel extends Level implements WorldGenLevel { entity.stopRiding(); } @@ -2434,7 +2408,7 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 // Pufferfish start - copied from this.guardEntityTick try { this.tickNonPassenger(entity); // Pufferfish - changed -@@ -743,20 +764,19 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -884,20 +905,19 @@ public class ServerLevel extends Level implements WorldGenLevel { // Paper end } // Pufferfish end @@ -2460,7 +2434,7 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 } @Override -@@ -774,6 +794,13 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -915,6 +935,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)) { @@ -2474,7 +2448,7 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 this.setDayTime(this.levelData.getDayTime() + 1L); } -@@ -782,7 +809,21 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -923,7 +950,21 @@ public class ServerLevel extends Level implements WorldGenLevel { public void setDayTime(long timeOfDay) { this.serverLevelData.setDayTime(timeOfDay); @@ -2496,7 +2470,7 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 public void tickCustomSpawners(boolean spawnMonsters, boolean spawnAnimals) { Iterator iterator = this.customSpawners.iterator(); -@@ -807,7 +848,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -948,7 +989,7 @@ public class ServerLevel extends Level implements WorldGenLevel { } // Paper start - optimise random block ticking private final BlockPos.MutableBlockPos chunkTickMutablePosition = new BlockPos.MutableBlockPos(); @@ -2505,7 +2479,7 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 // Paper end private int currentIceAndSnowTick = 0; protected void resetIceAndSnowTick() { this.currentIceAndSnowTick = this.randomTickRandom.nextInt(16); } // Pufferfish -@@ -817,9 +858,9 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -958,9 +999,9 @@ public class ServerLevel extends Level implements WorldGenLevel { boolean flag = this.isRaining(); int j = chunkcoordintpair.getMinBlockX(); int k = chunkcoordintpair.getMinBlockZ(); @@ -2517,7 +2491,7 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 final BlockPos.MutableBlockPos blockposition = this.chunkTickMutablePosition; // Paper - use mutable to reduce allocation rate, final to force compile fail on change if (!this.paperConfig().environment.disableThunder && flag && this.isThundering() && this.spigotConfig.thunderChance > 0 && /*this.random.nextInt(this.spigotConfig.thunderChance) == 0 &&*/ chunk.shouldDoLightning(this.random)) { // Spigot // Paper - disable thunder // Pufferfish - replace random with shouldDoLightning -@@ -829,10 +870,18 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -970,10 +1011,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 if (flag1) { @@ -2538,16 +2512,16 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 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 -@@ -849,7 +898,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -990,7 +1039,7 @@ public class ServerLevel extends Level implements WorldGenLevel { } } - gameprofilerfiller.popPush("iceandsnow"); + //gameprofilerfiller.popPush("iceandsnow"); // Purpur int l; + int i1; - if (!this.paperConfig().environment.disableIceAndSnow && (this.currentIceAndSnowTick++ & 15) == 0) { // Paper - Disable ice and snow // Paper - optimise random ticking // Pufferfish - optimize further random ticking -@@ -900,8 +949,8 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1042,8 +1091,8 @@ public class ServerLevel extends Level implements WorldGenLevel { } // Paper start - optimise random block ticking @@ -2558,7 +2532,7 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 if (randomTickSpeed > 0) { LevelChunkSection[] sections = chunk.getSections(); int minSection = io.papermc.paper.util.WorldUtil.getMinSection(this); -@@ -935,8 +984,8 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1077,8 +1126,8 @@ public class ServerLevel extends Level implements WorldGenLevel { } } // Paper end - optimise random block ticking @@ -2569,7 +2543,7 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 } public Optional findLightningRod(BlockPos pos) { -@@ -944,7 +993,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1086,7 +1135,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; @@ -2578,7 +2552,7 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 return optional.map((blockposition1) -> { return blockposition1.above(1); -@@ -993,11 +1042,27 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1135,11 +1184,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); @@ -2607,7 +2581,7 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 ichatmutablecomponent = Component.translatable("sleep.players_sleeping", this.sleepStatus.amountSleeping(), this.sleepStatus.sleepersNeeded(i)); } -@@ -1136,6 +1201,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1278,6 +1343,7 @@ public class ServerLevel extends Level implements WorldGenLevel { private void resetWeatherCycle() { // CraftBukkit start @@ -2615,7 +2589,7 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 this.serverLevelData.setRaining(false, org.bukkit.event.weather.WeatherChangeEvent.Cause.SLEEP); // Paper - when passing the night // 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.... -@@ -1143,6 +1209,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1285,6 +1351,7 @@ public class ServerLevel extends Level implements WorldGenLevel { this.serverLevelData.setRainTime(0); } // CraftBukkit end @@ -2623,7 +2597,7 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 this.serverLevelData.setThundering(false, org.bukkit.event.weather.ThunderChangeEvent.Cause.SLEEP); // Paper - when passing the night // CraftBukkit start // If we stop due to everyone sleeping we should reset the weather duration to some other random value. -@@ -1210,24 +1277,24 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1352,24 +1419,24 @@ public class ServerLevel extends Level implements WorldGenLevel { // Spigot end // Paper start- timings final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(entity); @@ -2656,7 +2630,7 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 Iterator iterator = entity.getPassengers().iterator(); while (iterator.hasNext()) { -@@ -1250,17 +1317,17 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1392,17 +1459,17 @@ public class ServerLevel extends Level implements WorldGenLevel { if (passenger instanceof Player || this.entityTickList.contains(passenger)) { // Paper - EAR 2 final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(passenger); @@ -2680,7 +2654,7 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 // Paper start - EAR 2 if (isActive) { passenger.rideTick(); -@@ -1272,7 +1339,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1414,7 +1481,7 @@ public class ServerLevel extends Level implements WorldGenLevel { vehicle.positionRider(passenger); } // Paper end - EAR 2 @@ -2689,7 +2663,7 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 Iterator iterator = passenger.getPassengers().iterator(); while (iterator.hasNext()) { -@@ -1281,7 +1348,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1423,7 +1490,7 @@ public class ServerLevel extends Level implements WorldGenLevel { this.tickPassenger(passenger, entity2); } @@ -2698,7 +2672,7 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 } } else { passenger.stopRiding(); -@@ -1301,14 +1368,14 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1443,14 +1510,14 @@ public class ServerLevel extends Level implements WorldGenLevel { org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); } @@ -2716,7 +2690,7 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 // Copied from save() // CraftBukkit start - moved from MinecraftServer.saveChunks -@@ -1320,7 +1387,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1462,7 +1529,7 @@ public class ServerLevel extends Level implements WorldGenLevel { this.convertable.saveDataTag(this.server.registryAccess(), this.serverLevelData, this.server.getPlayerList().getSingleplayerData()); } // CraftBukkit end @@ -2725,7 +2699,7 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 } // Paper end -@@ -1334,7 +1401,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1476,7 +1543,7 @@ public class ServerLevel extends Level implements WorldGenLevel { if (!savingDisabled) { org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); // CraftBukkit @@ -2734,7 +2708,7 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 if (progressListener != null) { progressListener.progressStartNoAbort(Component.translatable("menu.savingLevel")); } -@@ -1344,11 +1411,11 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1486,11 +1553,11 @@ public class ServerLevel extends Level implements WorldGenLevel { progressListener.progressStage(Component.translatable("menu.savingChunks")); } @@ -2749,20 +2723,20 @@ index 3ee5c3c17d450dce54e051dc53c9df44d9b3dc1b..86b8485c0fb1dc5cd79c9e24546dc744 // Paper - rewrite chunk system - entity saving moved into ChunkHolder } else if (close) { chunkproviderserver.close(false); } // Paper - rewrite chunk system -@@ -2619,7 +2686,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2769,7 +2836,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 - if (entity.getBukkitEntity() instanceof org.bukkit.inventory.Merchant merchant && merchant.getTrader() != null) { -+ if (!entity.level.purpurConfig.playerVoidTrading && entity.getBukkitEntity() instanceof org.bukkit.inventory.Merchant merchant && merchant.getTrader() != null) { // Purpur ++ if (!entity.level().purpurConfig.playerVoidTrading && entity.getBukkitEntity() instanceof org.bukkit.inventory.Merchant merchant && merchant.getTrader() != null) { // Purpur merchant.getTrader().closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); } // Paper end diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 98df2463bf41fc736aa6a2b6ddf89e5abde6eb39..852266234cf3d63e3b23a71639e40defca91c1b8 100644 +index b382da838acc04a1c5d89064b4fa43bcdd38ae71..0249eeb3937cf48cea13846a7e39b248947e21a4 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -277,6 +277,11 @@ public class ServerPlayer extends Player { +@@ -278,6 +278,11 @@ public class ServerPlayer extends Player { public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet cachedSingleHashSet; // Paper public PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - there are a lot of changes to do if we change all methods leading to the event @@ -2772,9 +2746,9 @@ index 98df2463bf41fc736aa6a2b6ddf89e5abde6eb39..852266234cf3d63e3b23a71639e40def + private boolean tpsBar = false; // Purpur + private boolean compassBar = false; // Purpur - public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile) { - super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile); -@@ -376,6 +381,7 @@ public class ServerPlayer extends Player { + 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)); + public io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader; +@@ -418,6 +423,7 @@ public class ServerPlayer extends Player { this.bukkitPickUpLoot = true; this.maxHealthCache = this.getMaxHealth(); this.cachedSingleMobDistanceMap = new com.destroystokyo.paper.util.PooledHashSets.PooledObjectLinkedOpenHashSet<>(this); // Paper @@ -2782,7 +2756,7 @@ index 98df2463bf41fc736aa6a2b6ddf89e5abde6eb39..852266234cf3d63e3b23a71639e40def } // Yes, this doesn't match Vanilla, but it's the best we can do for now. -@@ -515,6 +521,9 @@ public class ServerPlayer extends Player { +@@ -557,6 +563,9 @@ public class ServerPlayer extends Player { } } @@ -2792,7 +2766,7 @@ index 98df2463bf41fc736aa6a2b6ddf89e5abde6eb39..852266234cf3d63e3b23a71639e40def } @Override -@@ -581,6 +590,9 @@ public class ServerPlayer extends Player { +@@ -623,6 +632,9 @@ public class ServerPlayer extends Player { } this.getBukkitEntity().setExtraData(nbt); // CraftBukkit @@ -2802,13 +2776,13 @@ index 98df2463bf41fc736aa6a2b6ddf89e5abde6eb39..852266234cf3d63e3b23a71639e40def } // CraftBukkit start - World fallback code, either respawn location or global spawn -@@ -709,6 +721,15 @@ public class ServerPlayer extends Player { +@@ -751,6 +763,15 @@ public class ServerPlayer extends Player { this.trackStartFallingPosition(); this.trackEnteredOrExitedLavaOnVehicle(); this.advancements.flushDirty(this); + + // Purpur start -+ if (this.level.purpurConfig.useNightVisionWhenRiding && this.getVehicle() != null && this.getVehicle().getRider() == this && this.level.getGameTime() % 100 == 0) { // 5 seconds ++ if (this.level().purpurConfig.useNightVisionWhenRiding && this.getVehicle() != null && this.getVehicle().getRider() == this && this.level().getGameTime() % 100 == 0) { // 5 seconds + MobEffectInstance nightVision = this.getEffect(MobEffects.NIGHT_VISION); + if (nightVision == null || nightVision.getDuration() <= 300) { // 15 seconds + this.addEffect(new MobEffectInstance(MobEffects.NIGHT_VISION, 400, 0)); // 20 seconds @@ -2818,7 +2792,7 @@ index 98df2463bf41fc736aa6a2b6ddf89e5abde6eb39..852266234cf3d63e3b23a71639e40def } public void doTick() { -@@ -947,6 +968,7 @@ public class ServerPlayer extends Player { +@@ -989,6 +1010,7 @@ public class ServerPlayer extends Player { })); Team scoreboardteambase = this.getTeam(); @@ -2826,7 +2800,7 @@ index 98df2463bf41fc736aa6a2b6ddf89e5abde6eb39..852266234cf3d63e3b23a71639e40def if (scoreboardteambase != null && scoreboardteambase.getDeathMessageVisibility() != Team.Visibility.ALWAYS) { if (scoreboardteambase.getDeathMessageVisibility() == Team.Visibility.HIDE_FOR_OTHER_TEAMS) { this.server.getPlayerList().broadcastSystemToTeam(this, ichatbasecomponent); -@@ -1048,14 +1070,30 @@ public class ServerPlayer extends Player { +@@ -1090,14 +1112,30 @@ public class ServerPlayer extends Player { } @@ -2843,10 +2817,10 @@ index 98df2463bf41fc736aa6a2b6ddf89e5abde6eb39..852266234cf3d63e3b23a71639e40def } else { + // Purpur start + if (source.is(DamageTypeTags.IS_FALL)) { // Purpur -+ if (getRootVehicle() instanceof net.minecraft.world.entity.vehicle.AbstractMinecart && level.purpurConfig.minecartControllable && !level.purpurConfig.minecartControllableFallDamage) { ++ if (getRootVehicle() instanceof net.minecraft.world.entity.vehicle.AbstractMinecart && level().purpurConfig.minecartControllable && !level().purpurConfig.minecartControllableFallDamage) { + return false; + } -+ if (getRootVehicle() instanceof net.minecraft.world.entity.vehicle.Boat && !level.purpurConfig.boatsDoFallDamage) { ++ if (getRootVehicle() instanceof net.minecraft.world.entity.vehicle.Boat && !level().purpurConfig.boatsDoFallDamage) { + return false; + } + } @@ -2858,7 +2832,7 @@ index 98df2463bf41fc736aa6a2b6ddf89e5abde6eb39..852266234cf3d63e3b23a71639e40def return false; } else { Entity entity = source.getEntity(); -@@ -1164,7 +1202,7 @@ public class ServerPlayer extends Player { +@@ -1206,7 +1244,7 @@ public class ServerPlayer extends Player { PortalInfo shapedetectorshape = this.findDimensionEntryPoint(worldserver); if (shapedetectorshape != null) { @@ -2867,7 +2841,7 @@ index 98df2463bf41fc736aa6a2b6ddf89e5abde6eb39..852266234cf3d63e3b23a71639e40def worldserver = shapedetectorshape.world; // CraftBukkit if (worldserver == null) { } else // CraftBukkit - empty to fall through to null to event if (resourcekey == LevelStem.OVERWORLD && worldserver.getTypeKey() == LevelStem.NETHER) { // CraftBukkit -@@ -1187,8 +1225,8 @@ public class ServerPlayer extends Player { +@@ -1229,8 +1267,8 @@ public class ServerPlayer extends Player { worldserver = ((CraftWorld) exit.getWorld()).getHandle(); // CraftBukkit end @@ -2878,15 +2852,14 @@ index 98df2463bf41fc736aa6a2b6ddf89e5abde6eb39..852266234cf3d63e3b23a71639e40def if (true) { // CraftBukkit this.isChangingDimension = true; // CraftBukkit - Set teleport invulnerability only if player changing worlds -@@ -1199,6 +1237,7 @@ public class ServerPlayer extends Player { +@@ -1241,13 +1279,14 @@ public class ServerPlayer extends Player { playerlist.sendPlayerPermissionLevel(this); worldserver1.removePlayerImmediately(this, Entity.RemovalReason.CHANGED_DIMENSION); this.unsetRemoved(); + this.portalPos = io.papermc.paper.util.MCUtil.toBlockPosition(exit); // Purpur // CraftBukkit end - this.setLevel(worldserver); -@@ -1206,7 +1245,7 @@ public class ServerPlayer extends Player { + this.setServerLevel(worldserver); this.connection.teleport(exit); // CraftBukkit - use internal teleport without event this.connection.resetPosition(); worldserver.addDuringPortalTeleport(this); @@ -2895,7 +2868,7 @@ index 98df2463bf41fc736aa6a2b6ddf89e5abde6eb39..852266234cf3d63e3b23a71639e40def this.triggerDimensionChangeTriggers(worldserver1); this.connection.send(new ClientboundPlayerAbilitiesPacket(this.getAbilities())); playerlist.sendLevelInfo(this, worldserver); -@@ -1235,6 +1274,7 @@ public class ServerPlayer extends Player { +@@ -1276,6 +1315,7 @@ public class ServerPlayer extends Player { } // Paper end @@ -2903,24 +2876,45 @@ index 98df2463bf41fc736aa6a2b6ddf89e5abde6eb39..852266234cf3d63e3b23a71639e40def return this; } } -@@ -1356,7 +1396,7 @@ public class ServerPlayer extends Player { +@@ -1397,7 +1437,7 @@ public class ServerPlayer extends Player { return entitymonster.isPreventingPlayerRest(this); }); - if (!list.isEmpty()) { -+ if (!this.level.purpurConfig.playerSleepNearMonsters && !list.isEmpty()) { // Purpur ++ if (!this.level().purpurConfig.playerSleepNearMonsters && !list.isEmpty()) { // Purpur return Either.left(Player.BedSleepingProblem.NOT_SAFE); } } -@@ -1492,6 +1532,7 @@ public class ServerPlayer extends Player { +@@ -1437,7 +1477,19 @@ public class ServerPlayer extends Player { + }); + + if (!this.serverLevel().canSleepThroughNights()) { +- this.displayClientMessage(Component.translatable("sleep.not_possible"), true); ++ // Purpur start ++ Component clientMessage; ++ if (org.purpurmc.purpur.PurpurConfig.sleepNotPossible.isBlank()) { ++ clientMessage = null; ++ } else if (!org.purpurmc.purpur.PurpurConfig.sleepNotPossible.equalsIgnoreCase("default")) { ++ clientMessage = io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.sleepNotPossible)); ++ } else { ++ clientMessage = Component.translatable("sleep.not_possible"); ++ } ++ if (clientMessage != null) { ++ this.displayClientMessage(clientMessage, true); ++ } ++ // Purpur end + } + + ((ServerLevel) this.level()).updateSleepingPlayerList(); +@@ -1534,6 +1586,7 @@ public class ServerPlayer extends Player { @Override - public void openTextEdit(SignBlockEntity sign) { -+ if (level.purpurConfig.signAllowColors) this.connection.send(sign.getTranslatedUpdatePacket(textFilteringEnabled)); // Purpur - sign.setAllowedPlayerEditor(this.getUUID()); - this.connection.send(new ClientboundBlockUpdatePacket(this.level, sign.getBlockPos())); - this.connection.send(new ClientboundOpenSignEditorPacket(sign.getBlockPos())); -@@ -1728,6 +1769,26 @@ public class ServerPlayer extends Player { + 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)); + } +@@ -1779,6 +1832,26 @@ public class ServerPlayer extends Player { this.lastSentExp = -1; // CraftBukkit - Added to reset } @@ -2947,7 +2941,7 @@ index 98df2463bf41fc736aa6a2b6ddf89e5abde6eb39..852266234cf3d63e3b23a71639e40def @Override public void displayClientMessage(Component message, boolean overlay) { this.sendSystemMessage(message, overlay); -@@ -2027,6 +2088,7 @@ public class ServerPlayer extends Player { +@@ -2078,6 +2151,7 @@ public class ServerPlayer extends Player { } public void sendTexturePack(String url, String hash, boolean required, @Nullable Component resourcePackPrompt) { @@ -2955,7 +2949,7 @@ index 98df2463bf41fc736aa6a2b6ddf89e5abde6eb39..852266234cf3d63e3b23a71639e40def this.connection.send(new ClientboundResourcePackPacket(url, hash, required, resourcePackPrompt)); } -@@ -2041,8 +2103,68 @@ public class ServerPlayer extends Player { +@@ -2092,8 +2166,68 @@ public class ServerPlayer extends Player { public void resetLastActionTime() { this.lastActionTime = Util.getMillis(); @@ -2973,7 +2967,7 @@ index 98df2463bf41fc736aa6a2b6ddf89e5abde6eb39..852266234cf3d63e3b23a71639e40def + + String msg = afk ? org.purpurmc.purpur.PurpurConfig.afkBroadcastAway : org.purpurmc.purpur.PurpurConfig.afkBroadcastBack; + -+ org.purpurmc.purpur.event.PlayerAFKEvent event = new org.purpurmc.purpur.event.PlayerAFKEvent(this.getBukkitEntity(), afk, this.level.purpurConfig.idleTimeoutKick, msg, !Bukkit.isPrimaryThread()); ++ org.purpurmc.purpur.event.PlayerAFKEvent event = new org.purpurmc.purpur.event.PlayerAFKEvent(this.getBukkitEntity(), afk, this.level().purpurConfig.idleTimeoutKick, msg, !Bukkit.isPrimaryThread()); + if (!event.callEvent() || event.shouldKick()) { + return; + } @@ -2994,7 +2988,7 @@ index 98df2463bf41fc736aa6a2b6ddf89e5abde6eb39..852266234cf3d63e3b23a71639e40def + server.getPlayerList().broadcastMiniMessage(String.format(msg, playerName), false); + } + -+ if (this.level.purpurConfig.idleTimeoutUpdateTabList) { ++ if (this.level().purpurConfig.idleTimeoutUpdateTabList) { + String scoreboardName = getScoreboardName(); + String playerListName = net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().serialize(getBukkitEntity().playerListName()); + String[] split = playerListName.split(scoreboardName); @@ -3007,7 +3001,7 @@ index 98df2463bf41fc736aa6a2b6ddf89e5abde6eb39..852266234cf3d63e3b23a71639e40def + } + } + -+ ((ServerLevel) this.level).updateSleepingPlayerList(); ++ ((ServerLevel) this.level()).updateSleepingPlayerList(); + } + + @Override @@ -3024,25 +3018,26 @@ index 98df2463bf41fc736aa6a2b6ddf89e5abde6eb39..852266234cf3d63e3b23a71639e40def public ServerStatsCounter getStats() { return this.stats; } -@@ -2514,8 +2636,16 @@ public class ServerPlayer extends Player { +@@ -2605,9 +2739,17 @@ public class ServerPlayer extends Player { @Override public boolean isImmobile() { - return super.isImmobile() || (this.connection != null && this.connection.isDisconnected()); // Paper + return super.isImmobile() || frozen || (this.connection != null && this.connection.isDisconnected()); // Paper // Purpur -+ } -+ + } + + // Purpur start + private boolean frozen = false; + + public void setFrozen(boolean frozen) { + this.frozen = frozen; - } ++ } + // Purpur end - ++ @Override public Scoreboard getScoreboard() { -@@ -2564,4 +2694,50 @@ public class ServerPlayer extends Player { + return this.getBukkitEntity().getScoreboard().getHandle(); +@@ -2655,4 +2797,50 @@ public class ServerPlayer extends Player { return (CraftPlayer) super.getBukkitEntity(); } // CraftBukkit end @@ -3061,7 +3056,7 @@ index 98df2463bf41fc736aa6a2b6ddf89e5abde6eb39..852266234cf3d63e3b23a71639e40def + } + + ServerLevel toLevel = ((CraftWorld) to.getWorld()).getHandle(); -+ if (this.level == toLevel) { ++ if (this.level() == toLevel) { + this.connection.internalTeleport(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch(), java.util.EnumSet.noneOf(net.minecraft.world.entity.RelativeMovement.class)); + } else { + this.server.getPlayerList().respawn(this, toLevel, true, to, !toLevel.paperConfig().environment.disableTeleportationSuffocationCheck, org.bukkit.event.player.PlayerRespawnEvent.RespawnReason.DEATH); @@ -3094,18 +3089,18 @@ index 98df2463bf41fc736aa6a2b6ddf89e5abde6eb39..852266234cf3d63e3b23a71639e40def + // 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 1d33c02088c150189d7f4b0aa27f6a1de96b11cf..75f29f6dddf50ccf7ef43ecfa602ccade3c9004d 100644 +index 618ab9a2903f6d4139acd4aaa2e6db0a26e88ba9..f3bac087856f420aa6c14707e90288f4962967bf 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 { +@@ -398,6 +398,7 @@ public class ServerPlayerGameMode { } else {capturedBlockEntity = true;} // Paper end return false; } -+ if (this.player.level.purpurConfig.slabHalfBreak && this.player.isShiftKeyDown() && iblockdata.getBlock() instanceof net.minecraft.world.level.block.SlabBlock && ((net.minecraft.world.level.block.SlabBlock) iblockdata.getBlock()).halfBreak(iblockdata, pos, this.player)) return true; // Purpur ++ if (this.player.level().purpurConfig.slabHalfBreak && this.player.isShiftKeyDown() && iblockdata.getBlock() instanceof net.minecraft.world.level.block.SlabBlock && ((net.minecraft.world.level.block.SlabBlock) iblockdata.getBlock()).halfBreak(iblockdata, pos, this.player)) return true; // Purpur } // CraftBukkit end -@@ -427,7 +428,7 @@ public class ServerPlayerGameMode { +@@ -428,7 +429,7 @@ public class ServerPlayerGameMode { ItemStack mainHandStack = null; // Paper boolean isCorrectTool = false; // Paper @@ -3114,7 +3109,7 @@ index 1d33c02088c150189d7f4b0aa27f6a1de96b11cf..75f29f6dddf50ccf7ef43ecfa602ccad // return true; // CraftBukkit } else { ItemStack itemstack = this.player.getMainHandItem(); -@@ -516,6 +517,7 @@ public class ServerPlayerGameMode { +@@ -517,6 +518,7 @@ public class ServerPlayerGameMode { public InteractionHand interactHand; public ItemStack interactItemStack; public InteractionResult useItemOn(ServerPlayer player, Level world, ItemStack stack, InteractionHand hand, BlockHitResult hitResult) { @@ -3122,27 +3117,27 @@ index 1d33c02088c150189d7f4b0aa27f6a1de96b11cf..75f29f6dddf50ccf7ef43ecfa602ccad BlockPos blockposition = hitResult.getBlockPos(); BlockState iblockdata = world.getBlockState(blockposition); InteractionResult enuminteractionresult = InteractionResult.PASS; -@@ -576,7 +578,7 @@ public class ServerPlayerGameMode { +@@ -578,7 +580,7 @@ public class ServerPlayerGameMode { boolean flag1 = player.isSecondaryUseActive() && flag; ItemStack itemstack1 = stack.copy(); - if (!flag1) { -+ if (!flag1 || (player.level.purpurConfig.composterBulkProcess && iblockdata.is(Blocks.COMPOSTER))) { // Purpur ++ if (!flag1 || (player.level().purpurConfig.composterBulkProcess && iblockdata.is(Blocks.COMPOSTER))) { // Purpur enuminteractionresult = iblockdata.use(world, player, hand, hitResult); if (enuminteractionresult.consumesAction()) { -@@ -612,4 +614,18 @@ public class ServerPlayerGameMode { +@@ -619,4 +621,18 @@ public class ServerPlayerGameMode { public void setLevel(ServerLevel world) { this.level = world; } + + // Purpur start + public boolean shiftClickMended(ItemStack itemstack) { -+ if (this.player.level.purpurConfig.shiftRightClickRepairsMendingPoints > 0 && this.player.isShiftKeyDown() && this.player.getBukkitEntity().hasPermission("purpur.mending_shift_click")) { -+ int points = Math.min(this.player.totalExperience, this.player.level.purpurConfig.shiftRightClickRepairsMendingPoints); ++ if (this.player.level().purpurConfig.shiftRightClickRepairsMendingPoints > 0 && this.player.isShiftKeyDown() && this.player.getBukkitEntity().hasPermission("purpur.mending_shift_click")) { ++ int points = Math.min(this.player.totalExperience, this.player.level().purpurConfig.shiftRightClickRepairsMendingPoints); + if (points > 0 && itemstack.isDamaged() && net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.MENDING, itemstack) > 0) { + this.player.giveExperiencePoints(-points); -+ this.player.level.addFreshEntity(new net.minecraft.world.entity.ExperienceOrb(this.player.level, this.player.getX(), this.player.getY(), this.player.getZ(), points, org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN, this.player, this.player)); ++ this.player.level().addFreshEntity(new net.minecraft.world.entity.ExperienceOrb(this.player.level(), this.player.getX(), this.player.getY(), this.player.getZ(), points, org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN, this.player, this.player)); + return true; + } + } @@ -3163,10 +3158,10 @@ index 877498729c66de9aa6a27c9148f7494d7895615c..acd7468ee3c86d3456e96e4ec3d7e6a4 Util.logAndPauseIfInIde("Detected setBlock in a far chunk [" + i + ", " + j + "], pos: " + pos + ", status: " + this.generatingStatus + (this.currentlyGenerating == null ? "" : ", currently generating: " + (String) this.currentlyGenerating.get())); hasSetFarWarned = true; diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e4828003133ce766b 100644 +index 776c7df81d2b71a5610fe90475f4e8044850beab..9cc3ab8cd3f7ab7f8fbf4d9d14f25ea0bd757eec 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -263,6 +263,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -265,6 +265,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic private long keepAliveTime = Util.getMillis(); private boolean keepAlivePending; private long keepAliveChallenge; @@ -3174,7 +3169,7 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 // CraftBukkit start - multithreaded fields private final AtomicInteger chatSpamTickCount = new AtomicInteger(); private final java.util.concurrent.atomic.AtomicInteger tabSpamLimiter = new java.util.concurrent.atomic.AtomicInteger(); // Paper - configurable tab spam limits -@@ -340,6 +341,20 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -342,6 +343,20 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic private boolean justTeleported = false; private boolean hasMoved; // Spigot @@ -3195,7 +3190,7 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 public CraftPlayer getCraftPlayer() { return (this.player == null) ? null : (CraftPlayer) this.player.getBukkitEntity(); } -@@ -395,12 +410,27 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -397,12 +412,27 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic this.aboveGroundVehicleTickCount = 0; } @@ -3224,7 +3219,7 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 if (this.keepAlivePending) { if (!this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // check keepalive limit, don't fire if already disconnected ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked due to keepalive timeout!", this.player.getScoreboardName()); // more info -@@ -416,7 +446,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -418,7 +448,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic } // Paper end @@ -3233,20 +3228,20 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 // CraftBukkit start for (int spam; (spam = this.chatSpamTickCount.get()) > 0 && !this.chatSpamTickCount.compareAndSet(spam, spam - 1); ) ; if (tabSpamLimiter.get() > 0) tabSpamLimiter.getAndDecrement(); // Paper - split to seperate variable -@@ -433,6 +463,12 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -435,6 +465,12 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic } - if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) (this.server.getPlayerIdleTimeout() * 1000 * 60) && !this.player.wonGame) { // Paper - Prevent AFK kick while watching end credits. + 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. + // Purpur start + this.player.setAfk(true); -+ if (!this.player.level.purpurConfig.idleTimeoutKick || (!Boolean.parseBoolean(System.getenv("PURPUR_FORCE_IDLE_KICK")) && kickPermissionCache.getUnchecked(this.player.getBukkitEntity()))) { ++ if (!this.player.level().purpurConfig.idleTimeoutKick || (!Boolean.parseBoolean(System.getenv("PURPUR_FORCE_IDLE_KICK")) && kickPermissionCache.getUnchecked(this.player.getBukkitEntity()))) { + return; + } + // Purpur end this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854 this.disconnect(Component.translatable("multiplayer.disconnect.idling"), org.bukkit.event.player.PlayerKickEvent.Cause.IDLING); // Paper - kick event cause } -@@ -744,6 +780,8 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -753,6 +789,8 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic this.lastYaw = to.getYaw(); this.lastPitch = to.getPitch(); @@ -3255,7 +3250,7 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 // Skip the first time we do this if (true) { // Spigot - don't skip any move events Location oldTo = to.clone(); -@@ -820,6 +858,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -829,6 +867,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic 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 @@ -3263,7 +3258,7 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 return; } -@@ -1224,10 +1263,12 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -1241,10 +1280,12 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic 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; @@ -3276,7 +3271,7 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 server.scheduleOnMain(() -> this.disconnect("Book too large!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION)); // Paper - kick event cause return; } -@@ -1251,6 +1292,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -1268,6 +1309,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic 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()); @@ -3284,7 +3279,7 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 server.scheduleOnMain(() -> this.disconnect("Book too large!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION)); // Paper - kick event cause return; } -@@ -1304,13 +1346,16 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -1321,13 +1363,16 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic itemstack1.setTag(nbttagcompound.copy()); } @@ -3304,7 +3299,7 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 this.updateBookPages(pages, (s) -> { return Component.Serializer.toJson(Component.literal(s)); -@@ -1322,10 +1367,13 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -1339,10 +1384,13 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic private void updateBookPages(List list, UnaryOperator unaryoperator, ItemStack itemstack, int slot, ItemStack handItem) { // CraftBukkit ListTag nbttaglist = new ListTag(); @@ -3320,7 +3315,7 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 Objects.requireNonNull(nbttaglist); stream.forEach(nbttaglist::add); -@@ -1335,11 +1383,11 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -1352,11 +1400,11 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic for (int j = list.size(); i < j; ++i) { FilteredText filteredtext = (FilteredText) list.get(i); @@ -3334,7 +3329,7 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 } } -@@ -1352,6 +1400,16 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -1369,6 +1417,16 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic this.player.getInventory().setItem(slot, CraftEventFactory.handleEditBookEvent(player, slot, handItem, itemstack)); // CraftBukkit // Paper - Don't ignore result (see other callsite for handleEditBookEvent) } @@ -3350,11 +3345,11 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 + @Override public void handleEntityTagQuery(ServerboundEntityTagQuery packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.getLevel()); -@@ -1381,8 +1439,16 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); +@@ -1398,8 +1456,16 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic @Override public void handleMovePlayer(ServerboundMovePlayerPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.getLevel()); + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); - if (ServerGamePacketListenerImpl.containsInvalidValues(packet.getX(0.0D), packet.getY(0.0D), packet.getZ(0.0D), packet.getYRot(0.0F), packet.getXRot(0.0F))) { + // Purpur start + boolean invalidX = Double.isNaN(packet.getX(0.0D)); @@ -3367,18 +3362,18 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 + ServerGamePacketListenerImpl.LOGGER.warn(String.format("Disconnected on move player packet. Invalid data: x=%b, y=%b, z=%b, yaw=%b, pitch=%b", invalidX, invalidY, invalidZ, invalidYaw, invalidPitch)); + // Purpur end } else { - ServerLevel worldserver = this.player.getLevel(); + ServerLevel worldserver = this.player.serverLevel(); -@@ -1548,7 +1614,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic - - if (!this.player.isChangingDimension() && d11 > org.spigotmc.SpigotConfig.movedWronglyThreshold && !this.player.isSleeping() && !this.player.gameMode.isCreative() && this.player.gameMode.getGameModeForPlayer() != GameType.SPECTATOR) { // Spigot +@@ -1582,7 +1648,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic + if (!event.isAllowed()) { flag2 = true; // Paper - diff on change, this should be moved wrongly + if (event.getLogWarning()) - ServerGamePacketListenerImpl.LOGGER.warn("{} moved wrongly!", this.player.getName().getString()); -+ ServerGamePacketListenerImpl.LOGGER.warn("{} moved wrongly!, ({})", this.player.getName().getString(), d11); // Purpur ++ ServerGamePacketListenerImpl.LOGGER.warn("{} moved wrongly!, ({})", this.player.getName().getString(), d11); // Purpur + } + // Paper end } - - this.player.absMoveTo(d0, d1, d2, f, f1); -@@ -1599,6 +1665,8 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -1644,6 +1710,8 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic this.lastYaw = to.getYaw(); this.lastPitch = to.getPitch(); @@ -3387,13 +3382,13 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 // Skip the first time we do this if (from.getX() != Double.MAX_VALUE) { Location oldTo = to.clone(); -@@ -1638,6 +1706,13 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -1682,6 +1750,13 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic this.player.resetFallDistance(); } + // Purpur Start -+ if (this.player.level.purpurConfig.dontRunWithScissors && this.player.isSprinting() && !(this.player.level.purpurConfig.ignoreScissorsInWater && this.player.isInWater()) && !(this.player.level.purpurConfig.ignoreScissorsInLava && this.player.isInLava()) && (isScissor(this.player.getItemInHand(InteractionHand.MAIN_HAND)) || isScissor(this.player.getItemInHand(InteractionHand.OFF_HAND))) && (int) (Math.random() * 10) == 0) { -+ this.player.hurt(this.player.damageSources().magic(), (float) this.player.level.purpurConfig.scissorsRunningDamage); ++ if (this.player.level().purpurConfig.dontRunWithScissors && this.player.isSprinting() && !(this.player.level().purpurConfig.ignoreScissorsInWater && this.player.isInWater()) && !(this.player.level().purpurConfig.ignoreScissorsInLava && this.player.isInLava()) && (isScissor(this.player.getItemInHand(InteractionHand.MAIN_HAND)) || isScissor(this.player.getItemInHand(InteractionHand.OFF_HAND))) && (int) (Math.random() * 10) == 0) { ++ this.player.hurt(this.player.damageSources().scissors(), (float) this.player.level().purpurConfig.scissorsRunningDamage); + if (!org.purpurmc.purpur.PurpurConfig.dontRunWithScissors.isBlank()) this.player.sendActionBarMessage(org.purpurmc.purpur.PurpurConfig.dontRunWithScissors); + } + // Purpur End @@ -3401,20 +3396,21 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 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(); -@@ -1671,6 +1746,12 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -1726,6 +1801,13 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic + } } // 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); + } + // Purpur end + - private boolean isPlayerCollidingWithAnythingNew(LevelReader world, AABB box) { - Iterable iterable = world.getCollisions(this.player, this.player.getBoundingBox().deflate(9.999999747378752E-6D)); - VoxelShape voxelshape = Shapes.create(box.deflate(9.999999747378752E-6D)); -@@ -2015,6 +2096,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic + 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)); +@@ -2071,6 +2153,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic boolean cancelled; if (movingobjectposition == null || movingobjectposition.getType() != HitResult.Type.BLOCK) { @@ -3422,12 +3418,12 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.RIGHT_CLICK_AIR, itemstack, enumhand); cancelled = event.useItemInHand() == Event.Result.DENY; } else { -@@ -2068,12 +2150,21 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -2125,12 +2208,21 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic @Override public void handleResourcePackResponse(ServerboundResourcePackPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.getLevel()); + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + // Purpur start -+ if (player.level.purpurConfig.playerInvulnerableWhileAcceptingResourcePack && !this.player.acceptingResourcePack) { ++ if (player.level().purpurConfig.playerInvulnerableWhileAcceptingResourcePack && !this.player.acceptingResourcePack) { + ServerGamePacketListenerImpl.LOGGER.info("Disconnecting {} due to resource pack packet exploitation attempt", this.player.getName()); + this.disconnect(Component.translatable("multiplayer.texturePrompt.failure.line1"), org.bukkit.event.player.PlayerKickEvent.Cause.RESOURCE_PACK_REJECTION); // "Server resource pack couldn't be applied" + return; @@ -3439,12 +3435,12 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 } // Paper start PlayerResourcePackStatusEvent.Status packStatus = PlayerResourcePackStatusEvent.Status.values()[packet.action.ordinal()]; -+ if (player.level.purpurConfig.playerInvulnerableWhileAcceptingResourcePack) player.setFrozen(packStatus == PlayerResourcePackStatusEvent.Status.ACCEPTED); // Purpur ++ if (player.level().purpurConfig.playerInvulnerableWhileAcceptingResourcePack) player.setFrozen(packStatus == PlayerResourcePackStatusEvent.Status.ACCEPTED); // Purpur + this.player.acceptingResourcePack = packStatus == PlayerResourcePackStatusEvent.Status.ACCEPTED; // Purpur player.getBukkitEntity().setResourcePackStatus(packStatus); this.cserver.getPluginManager().callEvent(new PlayerResourcePackStatusEvent(this.getCraftPlayer(), packStatus)); // CraftBukkit // Paper end -@@ -2370,7 +2461,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -2427,7 +2519,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic do { instant1 = (Instant) this.lastChatTimeStamp.get(); if (timestamp.isBefore(instant1)) { @@ -3453,7 +3449,7 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 } } while (!this.lastChatTimeStamp.compareAndSet(instant1, timestamp)); -@@ -2507,7 +2598,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -2558,7 +2650,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic } } // Paper End @@ -3462,7 +3458,7 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 if ( org.spigotmc.SpigotConfig.logCommands ) // Spigot this.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + s); -@@ -2517,7 +2608,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -2568,7 +2660,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic this.cserver.getPluginManager().callEvent(event); if (event.isCancelled()) { @@ -3471,7 +3467,7 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 return; } -@@ -2530,7 +2621,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -2581,7 +2673,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic java.util.logging.Logger.getLogger(ServerGamePacketListenerImpl.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); return; } finally { @@ -3480,7 +3476,7 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 } } // CraftBukkit end -@@ -2796,6 +2887,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -2857,6 +2949,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic AABB axisalignedbb = entity.getBoundingBox(); if (axisalignedbb.distanceToSqr(this.player.getEyePosition()) < ServerGamePacketListenerImpl.MAX_INTERACTION_DISTANCE) { @@ -3488,7 +3484,7 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 packet.dispatch(new ServerboundInteractPacket.Handler() { private void performInteraction(InteractionHand enumhand, ServerGamePacketListenerImpl.EntityInteraction playerconnection_a, PlayerInteractEntityEvent event) { // CraftBukkit ItemStack itemstack = ServerGamePacketListenerImpl.this.player.getItemInHand(enumhand); -@@ -2809,6 +2901,8 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -2870,6 +2963,8 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic ServerGamePacketListenerImpl.this.cserver.getPluginManager().callEvent(event); @@ -3497,7 +3493,7 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 // 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. -@@ -3360,6 +3454,12 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -3450,6 +3545,12 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic } } } @@ -3510,28 +3506,7 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 boolean flag1 = packet.getSlotNum() >= 1 && packet.getSlotNum() <= 45; boolean flag2 = itemstack.isEmpty() || itemstack.getDamageValue() >= 0 && itemstack.getCount() <= 64 && !itemstack.isEmpty(); -@@ -3466,11 +3566,17 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic - for (int i = 0; i < signText.size(); ++i) { - FilteredText filteredtext = (FilteredText) signText.get(i); - -- if (this.player.isTextFilteringEnabled()) { -- lines.add(net.kyori.adventure.text.Component.text(SharedConstants.filterText(filteredtext.filteredOrEmpty()))); // Paper - adventure -+ // Purpur start -+ String line = SharedConstants.filterText(this.player.isTextFilteringEnabled() ? filteredtext.filteredOrEmpty() : filteredtext.raw()); -+ if (worldserver.purpurConfig.signAllowColors) { -+ if (player.hasPermission("purpur.sign.color")) line = line.replaceAll("(?i)&([0-9a-fr])", "\u00a7$1"); -+ if (player.hasPermission("purpur.sign.style")) line = line.replaceAll("(?i)&([l-or])", "\u00a7$1"); -+ if (player.hasPermission("purpur.sign.magic")) line = line.replaceAll("(?i)&([kr])", "\u00a7$1"); -+ lines.add(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(line)); - } else { -- lines.add(net.kyori.adventure.text.Component.text(SharedConstants.filterText(filteredtext.raw()))); // Paper - adventure -+ lines.add(net.kyori.adventure.text.Component.text(line)); - } -+ // Purpur end - } - SignChangeEvent event = new SignChangeEvent((org.bukkit.craftbukkit.block.CraftBlock) player.getWorld().getBlockAt(x, y, z), this.player.getBukkitEntity(), lines); - this.cserver.getPluginManager().callEvent(event); -@@ -3492,6 +3598,16 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -3545,6 +3646,16 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic @Override public void handleKeepAlive(ServerboundKeepAlivePacket packet) { @@ -3545,10 +3520,10 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 + } + } else + // Purpur end - //PacketUtils.ensureRunningOnSameThread(packet, this, this.player.getLevel()); // CraftBukkit // Paper - This shouldn't be on the main thread + //PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // CraftBukkit // Paper - This shouldn't be on the main thread if (this.keepAlivePending && packet.getId() == this.keepAliveChallenge) { int i = (int) (Util.getMillis() - this.keepAliveTime); -@@ -3542,6 +3658,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -3595,6 +3706,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic private static final ResourceLocation CUSTOM_UNREGISTER = new ResourceLocation("unregister"); private static final ResourceLocation MINECRAFT_BRAND = new ResourceLocation("brand"); // Paper - Brand support @@ -3556,7 +3531,7 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 @Override public void handleCustomPayload(ServerboundCustomPayloadPacket packet) { -@@ -3566,6 +3683,13 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -3619,6 +3731,13 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t unregister custom payload", ex); this.disconnect("Invalid payload UNREGISTER!", org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PAYLOAD); // Paper - kick event cause } @@ -3571,10 +3546,10 @@ index 9d2d72fe48b69be2f6ebe74309673a3a4e51eae4..af8cb1f1f0c128923495f51e48280031 try { byte[] data = new byte[packet.data.readableBytes()]; diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index 2ff578e4a953ffcf5176815ba8e3f06f73499989..f719f8aafe7c75e2ef8fcb05f556a8d6bd94b9a0 100644 +index 878001928327d92423d5f7f6d5ce8772d6fa477f..01d5fa265fb2818465b5a71a2e2efeec751a7a05 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -@@ -220,6 +220,8 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, +@@ -221,6 +221,8 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, return false; } @@ -3583,7 +3558,7 @@ index 2ff578e4a953ffcf5176815ba8e3f06f73499989..f719f8aafe7c75e2ef8fcb05f556a8d6 for (int i = 0, len = in.length(); i < len; ++i) { char c = in.charAt(i); -@@ -339,7 +341,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, +@@ -340,7 +342,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, ServerLoginPacketListenerImpl.this.gameProfile = gameprofile; ServerLoginPacketListenerImpl.this.state = ServerLoginPacketListenerImpl.State.READY_TO_ACCEPT; } else { @@ -3625,10 +3600,10 @@ index 9ddbfcf80d9a381dace78a62880f85a4d767e0eb..7383c7d3820dce06108eaafd236a7c6c } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 92e758a286a5db079c32d53cc52c8a422457daef..ff56981a03b55f9ee1ec8ad36adaf9849b2c914b 100644 +index f097ec5b4e3ad6b1a7c464a8cff4f8b2568fcf4f..824f31b68b38f2f8642fb9d59a123cfdaffbb7b2 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -469,6 +469,7 @@ public abstract class PlayerList { +@@ -484,6 +484,7 @@ public abstract class PlayerList { scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam); } // Paper end @@ -3636,16 +3611,15 @@ index 92e758a286a5db079c32d53cc52c8a422457daef..ff56981a03b55f9ee1ec8ad36adaf984 // CraftBukkit - Moved from above, added world PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", player.getName().getString(), s1, player.getId(), worldserver1.serverLevelData.getLevelName(), player.getX(), player.getY(), player.getZ()); } -@@ -578,6 +579,8 @@ public abstract class PlayerList { +@@ -593,6 +594,7 @@ public abstract class PlayerList { } public net.kyori.adventure.text.Component remove(ServerPlayer entityplayer, net.kyori.adventure.text.Component leaveMessage) { // Paper end + org.purpurmc.purpur.task.BossBarTask.removeFromAll(entityplayer.getBukkitEntity()); // Purpur -+ - ServerLevel worldserver = entityplayer.getLevel(); + ServerLevel worldserver = entityplayer.serverLevel(); entityplayer.awardStat(Stats.LEAVE_GAME); -@@ -731,7 +734,7 @@ public abstract class PlayerList { +@@ -747,7 +749,7 @@ public abstract class PlayerList { event.disallow(PlayerLoginEvent.Result.KICK_BANNED, PaperAdventure.asAdventure(ichatmutablecomponent)); // Paper - Adventure } else { // return this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameprofile) ? IChatBaseComponent.translatable("multiplayer.disconnect.server_full") : null; @@ -3654,16 +3628,16 @@ index 92e758a286a5db079c32d53cc52c8a422457daef..ff56981a03b55f9ee1ec8ad36adaf984 event.disallow(PlayerLoginEvent.Result.KICK_FULL, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.serverFullMessage)); // Spigot // Paper - Adventure } } -@@ -969,6 +972,8 @@ public abstract class PlayerList { +@@ -985,6 +987,8 @@ public abstract class PlayerList { } // Paper end -+ entityplayer1.spawnInvulnerableTime = entityplayer1.level.purpurConfig.playerSpawnInvulnerableTicks; // Purpur ++ entityplayer1.spawnInvulnerableTime = entityplayer1.level().purpurConfig.playerSpawnInvulnerableTicks; // Purpur + // CraftBukkit end return entityplayer1; } -@@ -1029,6 +1034,20 @@ public abstract class PlayerList { +@@ -1045,6 +1049,20 @@ public abstract class PlayerList { } // CraftBukkit end @@ -3684,7 +3658,7 @@ index 92e758a286a5db079c32d53cc52c8a422457daef..ff56981a03b55f9ee1ec8ad36adaf984 public void broadcastAll(Packet packet, ResourceKey dimension) { Iterator iterator = this.players.iterator(); -@@ -1132,6 +1151,7 @@ public abstract class PlayerList { +@@ -1148,6 +1166,7 @@ public abstract class PlayerList { } else { b0 = (byte) (24 + permissionLevel); } @@ -3692,7 +3666,7 @@ index 92e758a286a5db079c32d53cc52c8a422457daef..ff56981a03b55f9ee1ec8ad36adaf984 player.connection.send(new ClientboundEntityEventPacket(player, b0)); } -@@ -1140,6 +1160,27 @@ public abstract class PlayerList { +@@ -1156,6 +1175,27 @@ public abstract class PlayerList { player.getBukkitEntity().recalculatePermissions(); // CraftBukkit this.server.getCommands().sendCommands(player); } // Paper @@ -3720,7 +3694,7 @@ index 92e758a286a5db079c32d53cc52c8a422457daef..ff56981a03b55f9ee1ec8ad36adaf984 } public boolean isWhiteListed(GameProfile profile) { -@@ -1201,7 +1242,7 @@ public abstract class PlayerList { +@@ -1217,7 +1257,7 @@ public abstract class PlayerList { public void saveAll(int interval) { io.papermc.paper.util.MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main @@ -3729,7 +3703,7 @@ index 92e758a286a5db079c32d53cc52c8a422457daef..ff56981a03b55f9ee1ec8ad36adaf984 int numSaved = 0; long now = MinecraftServer.currentTick; for (int i = 0; i < this.players.size(); ++i) { -@@ -1212,7 +1253,7 @@ public abstract class PlayerList { +@@ -1228,7 +1268,7 @@ public abstract class PlayerList { } // Paper end } @@ -3739,7 +3713,7 @@ index 92e758a286a5db079c32d53cc52c8a422457daef..ff56981a03b55f9ee1ec8ad36adaf984 } diff --git a/src/main/java/net/minecraft/server/players/SleepStatus.java b/src/main/java/net/minecraft/server/players/SleepStatus.java -index 823efad652d8ff9e96b99375b102fef6f017716e..60f89d7c77a5e792e21e93e35ed1670bd565799a 100644 +index 823efad652d8ff9e96b99375b102fef6f017716e..caa8a69bde0c212c36dd990a67836ac2f95548c0 100644 --- a/src/main/java/net/minecraft/server/players/SleepStatus.java +++ b/src/main/java/net/minecraft/server/players/SleepStatus.java @@ -19,7 +19,7 @@ public class SleepStatus { @@ -3747,7 +3721,7 @@ index 823efad652d8ff9e96b99375b102fef6f017716e..60f89d7c77a5e792e21e93e35ed1670b public boolean areEnoughDeepSleeping(int percentage, List players) { // CraftBukkit start - int j = (int) players.stream().filter((eh) -> { return eh.isSleepingLongEnough() || eh.fauxSleeping; }).count(); -+ int j = (int) players.stream().filter((eh) -> { return eh.isSleepingLongEnough() || eh.fauxSleeping || (eh.level.purpurConfig.idleTimeoutCountAsSleeping && eh.isAfk()); }).count(); // Purpur ++ int j = (int) players.stream().filter((eh) -> { return eh.isSleepingLongEnough() || eh.fauxSleeping || (eh.level().purpurConfig.idleTimeoutCountAsSleeping && eh.isAfk()); }).count(); // Purpur boolean anyDeepSleep = players.stream().anyMatch(Player::isSleepingLongEnough); return anyDeepSleep && j >= this.sleepersNeeded(percentage); @@ -3756,15 +3730,15 @@ index 823efad652d8ff9e96b99375b102fef6f017716e..60f89d7c77a5e792e21e93e35ed1670b if (!entityplayer.isSpectator()) { ++this.activePlayers; - if (entityplayer.isSleeping() || entityplayer.fauxSleeping) { // CraftBukkit -+ if ((entityplayer.isSleeping() || entityplayer.fauxSleeping) || (entityplayer.level.purpurConfig.idleTimeoutCountAsSleeping && entityplayer.isAfk())) { // CraftBukkit // Purpur ++ if ((entityplayer.isSleeping() || entityplayer.fauxSleeping) || (entityplayer.level().purpurConfig.idleTimeoutCountAsSleeping && entityplayer.isAfk())) { // CraftBukkit // Purpur ++this.sleepingPlayers; } // CraftBukkit start diff --git a/src/main/java/net/minecraft/stats/ServerRecipeBook.java b/src/main/java/net/minecraft/stats/ServerRecipeBook.java -index d13ed3069e944d138442ea440ac3eaf8d44c18d3..29ac7f202aa23f7e6fcdc9829af3d59875c92d4e 100644 +index ea29e07a105f3ba6a878bdccf36e7eaf66280280..d5dce6c8d85938d61a57a78f82381d26daf8f87a 100644 --- a/src/main/java/net/minecraft/stats/ServerRecipeBook.java +++ b/src/main/java/net/minecraft/stats/ServerRecipeBook.java -@@ -122,6 +122,7 @@ public class ServerRecipeBook extends RecipeBook { +@@ -125,6 +125,7 @@ public class ServerRecipeBook extends RecipeBook { Optional> optional = recipeManager.byKey(minecraftkey); if (!optional.isPresent()) { @@ -3975,11 +3949,54 @@ index ccbfcef3e83b1bef364447657bfd08a92d615cf6..aa2331c6df4e79d4bb0add071a0b11d2 return damageDealt * (1.0F - f / 25.0F); } } +diff --git a/src/main/java/net/minecraft/world/damagesource/CombatTracker.java b/src/main/java/net/minecraft/world/damagesource/CombatTracker.java +index c12d7bacf2c54f268b1bc5e46250a083ca041415..45a1cbe958c1a626df97022afe22484f2b387233 100644 +--- a/src/main/java/net/minecraft/world/damagesource/CombatTracker.java ++++ b/src/main/java/net/minecraft/world/damagesource/CombatTracker.java +@@ -59,7 +59,7 @@ public class CombatTracker { + } + + ItemStack itemStack = var10000; +- return !itemStack.isEmpty() && itemStack.hasCustomHoverName() ? Component.translatable(itemDeathTranslationKey, this.mob.getDisplayName(), attackerDisplayName, itemStack.getDisplayName()) : Component.translatable(deathTranslationKey, this.mob.getDisplayName(), attackerDisplayName); ++ return !itemStack.isEmpty() && (org.purpurmc.purpur.PurpurConfig.playerDeathsAlwaysShowItem || itemStack.hasCustomHoverName()) ? Component.translatable(itemDeathTranslationKey, this.mob.getDisplayName(), attackerDisplayName, itemStack.getDisplayName()) : Component.translatable(deathTranslationKey, this.mob.getDisplayName(), attackerDisplayName); + } + + private Component getFallMessage(CombatEntry damageRecord, @Nullable Entity attacker) { +@@ -99,6 +99,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 { ++ // Purpur start ++ if (damageSource.isScissors) { ++ return damageSource.getLocalizedDeathMessage(org.purpurmc.purpur.PurpurConfig.deathMsgRunWithScissors, this.mob); ++ } else if (damageSource.isStoneCutter) { ++ return damageSource.getLocalizedDeathMessage(org.purpurmc.purpur.PurpurConfig.deathMsgStonecutter, this.mob); ++ } ++ // Purpur end + return damageSource.getLocalizedDeathMessage(this.mob); + } + } diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSource.java b/src/main/java/net/minecraft/world/damagesource/DamageSource.java -index 93a1e990b0a6caae4143c2f9d09bfb368fa1d6db..615611fe372d6edaef56db058bbf2cf7641e3c26 100644 +index 25a5a3b949a0eb632611355e74ccd4865be108ca..c8860f20956a2819da001e93938249452bf7cb49 100644 --- a/src/main/java/net/minecraft/world/damagesource/DamageSource.java +++ b/src/main/java/net/minecraft/world/damagesource/DamageSource.java -@@ -126,6 +126,15 @@ public class DamageSource { +@@ -54,6 +54,10 @@ public class DamageSource { + // CraftBukkit end + public @Nullable org.bukkit.block.BlockState explodedBlockState; // Paper - add exploded state + ++ public boolean isScissors; // Purpur ++ ++ public boolean isStoneCutter; // Purpur ++ + public String toString() { + return "DamageSource (" + this.type().msgId() + ")"; + } +@@ -122,10 +126,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); } } @@ -3995,41 +4012,63 @@ index 93a1e990b0a6caae4143c2f9d09bfb368fa1d6db..615611fe372d6edaef56db058bbf2cf7 public String getMsgId() { 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 4604f8b38460e9113e966889a679d4547f24aff6..4a5d2e263d2bbee96bde7012d3385fa33860bc1b 100644 +--- a/src/main/java/net/minecraft/world/damagesource/DamageSources.java ++++ b/src/main/java/net/minecraft/world/damagesource/DamageSources.java +@@ -267,4 +267,17 @@ public class DamageSources { + public DamageSource genericKill() { + return this.genericKill; + } ++ // Purpur start ++ public DamageSource scissors() { ++ DamageSource source = new DamageSource(this.damageTypes.getHolderOrThrow(DamageTypes.MAGIC)); ++ source.isScissors = true; ++ return source; ++ } ++ ++ public DamageSource stonecutter() { ++ DamageSource source = new DamageSource(this.damageTypes.getHolderOrThrow(DamageTypes.MAGIC)); ++ source.isStoneCutter = true; ++ return source; ++ } ++ // Purpur end + } diff --git a/src/main/java/net/minecraft/world/effect/MobEffect.java b/src/main/java/net/minecraft/world/effect/MobEffect.java -index 2cc714585fc3790b70a7ad1ab8034543462e2b3b..22d7f04cefafa0115a4504e37380787777091b18 100644 +index 53cc6befb752affcfec65e18365f6d369448d407..01850fc596a85974287ff6750427186d21acac41 100644 --- a/src/main/java/net/minecraft/world/effect/MobEffect.java +++ b/src/main/java/net/minecraft/world/effect/MobEffect.java -@@ -60,16 +60,16 @@ public class MobEffect { +@@ -59,16 +59,16 @@ public class MobEffect { public void applyEffectTick(LivingEntity entity, int amplifier) { if (this == MobEffects.REGENERATION) { if (entity.getHealth() < entity.getMaxHealth()) { - entity.heal(1.0F, RegainReason.MAGIC_REGEN); // CraftBukkit -+ entity.heal(entity.level.purpurConfig.entityHealthRegenAmount, RegainReason.MAGIC_REGEN); // CraftBukkit // Purpur ++ entity.heal(entity.level().purpurConfig.entityHealthRegenAmount, RegainReason.MAGIC_REGEN); // CraftBukkit // Purpur } } else if (this == MobEffects.POISON) { - 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 ++ if (entity.getHealth() > entity.level().purpurConfig.entityMinimalHealthPoison) { // Purpur ++ entity.hurt(entity.damageSources().poison, entity.level().purpurConfig.entityPoisonDegenerationAmount); // CraftBukkit - DamageSource.MAGIC -> CraftEventFactory.POISON // Purpur } } else if (this == MobEffects.WITHER) { - entity.hurt(entity.damageSources().wither(), 1.0F); -+ entity.hurt(entity.damageSources().wither(), entity.level.purpurConfig.entityWitherDegenerationAmount); // Purpur ++ entity.hurt(entity.damageSources().wither(), entity.level().purpurConfig.entityWitherDegenerationAmount); // Purpur } else if (this == MobEffects.HUNGER && entity instanceof Player) { - ((Player) entity).causeFoodExhaustion(0.005F * (float) (amplifier + 1), org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.HUNGER_EFFECT); // CraftBukkit - EntityExhaustionEvent -+ ((Player) entity).causeFoodExhaustion(entity.level.purpurConfig.humanHungerExhaustionAmount * (float) (amplifier + 1), org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.HUNGER_EFFECT); // CraftBukkit - EntityExhaustionEvent // Purpur ++ ((Player) entity).causeFoodExhaustion(entity.level().purpurConfig.humanHungerExhaustionAmount * (float) (amplifier + 1), org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.HUNGER_EFFECT); // CraftBukkit - EntityExhaustionEvent // Purpur } else if (this == MobEffects.SATURATION && entity instanceof Player) { - if (!entity.level.isClientSide) { + if (!entity.level().isClientSide) { // CraftBukkit start -@@ -79,7 +79,7 @@ public class MobEffect { +@@ -76,7 +76,7 @@ public class MobEffect { + int oldFoodLevel = entityhuman.getFoodData().foodLevel; org.bukkit.event.entity.FoodLevelChangeEvent event = CraftEventFactory.callFoodLevelChangeEvent(entityhuman, amplifier + 1 + oldFoodLevel); - if (!event.isCancelled()) { - entityhuman.getFoodData().eat(event.getFoodLevel() - oldFoodLevel, 1.0F); -+ entityhuman.getFoodData().eat(event.getFoodLevel() - oldFoodLevel, entity.level.purpurConfig.humanSaturationRegenAmount); // Purpur ++ entityhuman.getFoodData().eat(event.getFoodLevel() - oldFoodLevel, entity.level().purpurConfig.humanSaturationRegenAmount); // Purpur } - ((ServerPlayer) entityhuman).connection.send(new ClientboundSetHealthPacket(((ServerPlayer) entityhuman).getBukkitEntity().getScaledHealth(), entityhuman.getFoodData().foodLevel, entityhuman.getFoodData().saturationLevel)); + ((CraftPlayer) entityhuman.getBukkitEntity()).sendHealthUpdate(); diff --git a/src/main/java/net/minecraft/world/effect/MobEffectInstance.java b/src/main/java/net/minecraft/world/effect/MobEffectInstance.java index 14fab63346d56c72cd7534a04760efd10eef4295..745e792482f61c571e2efbd4200dd1bdaef6e474 100644 --- a/src/main/java/net/minecraft/world/effect/MobEffectInstance.java @@ -4186,7 +4225,7 @@ index 14fab63346d56c72cd7534a04760efd10eef4295..745e792482f61c571e2efbd4200dd1bd @Override diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index b4ab2cfb7a5fa0d2efd1a759d754d5203aaac077..e71eca3ddbbeb3168dd73433b6d6ffe9f6755f77 100644 +index 36795968f4c296f680f79cc5a795391ae13c64e4..cf0d8da4c4b5f4aa4e4ef15897ca252a2b52ec8d 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -156,7 +156,7 @@ import org.bukkit.plugin.PluginManager; @@ -4198,7 +4237,7 @@ index b4ab2cfb7a5fa0d2efd1a759d754d5203aaac077..e71eca3ddbbeb3168dd73433b6d6ffe9 // CraftBukkit start private static final int CURRENT_LEVEL = 2; public boolean preserveMotion = true; // Paper - keep initial motion on first setPositionRotation -@@ -320,7 +320,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -334,7 +334,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { public double xOld; public double yOld; public double zOld; @@ -4207,7 +4246,7 @@ index b4ab2cfb7a5fa0d2efd1a759d754d5203aaac077..e71eca3ddbbeb3168dd73433b6d6ffe9 public boolean noPhysics; protected final RandomSource random; public int tickCount; -@@ -362,7 +362,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -376,7 +376,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { private final Set tags; private final double[] pistonDeltas; private long pistonDeltasGameTime; @@ -4216,15 +4255,50 @@ index b4ab2cfb7a5fa0d2efd1a759d754d5203aaac077..e71eca3ddbbeb3168dd73433b6d6ffe9 private float eyeHeight; public boolean isInPowderSnow; public boolean wasInPowderSnow; -@@ -401,6 +401,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { - private UUID originWorld; +@@ -418,6 +418,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { public boolean freezeLocked = false; // Paper - Freeze Tick Lock API public boolean collidingWithWorldBorder; // Paper + public boolean fixedPose = false; // Paper + public @Nullable Boolean immuneToFire = null; // Purpur - Fire immune API public void setOrigin(@javax.annotation.Nonnull Location location) { this.origin = location.toVector(); -@@ -580,7 +581,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -439,7 +440,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { + public int activatedPriority = gg.pufferfish.pufferfish.PufferfishConfig.maximumActivationPrio; // golf score + public final BlockPos.MutableBlockPos cachedBlockPos = new BlockPos.MutableBlockPos(); // used where needed + // Pufferfish end +- ++ + public float getBukkitYaw() { + return this.yRot; + } +@@ -493,6 +494,25 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { + return false; + } + ++ public boolean canSaveToDisk() { ++ return true; ++ } ++ ++ // Purpur start - copied from Mob ++ public boolean isSunBurnTick() { ++ if (this.level().isDay() && !this.level().isClientSide) { ++ float f = this.getLightLevelDependentMagicValue(); ++ BlockPos blockposition = BlockPos.containing(this.getX(), this.getEyeY(), this.getZ()); ++ boolean flag = this.isInWaterRainOrBubble() || this.isInPowderSnow || this.wasInPowderSnow; ++ ++ if (f > 0.5F && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && !flag && this.level().canSeeSky(blockposition)) { ++ return true; ++ } ++ } ++ ++ return false; ++ } ++ + public final boolean hardCollides() { + return this.hardCollides; + } +@@ -597,7 +617,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { this.bb = Entity.INITIAL_AABB; this.stuckSpeedMultiplier = Vec3.ZERO; this.nextStep = 1.0F; @@ -4233,47 +4307,47 @@ index b4ab2cfb7a5fa0d2efd1a759d754d5203aaac077..e71eca3ddbbeb3168dd73433b6d6ffe9 this.remainingFireTicks = -this.getFireImmuneTicks(); this.fluidHeight = new Object2DoubleArrayMap(2); this.fluidOnEyes = new HashSet(); -@@ -825,7 +826,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { - return; - } - // Pufferfish end - entity TTL -- this.level.getProfiler().push("entityBaseTick"); -+ //this.level.getProfiler().push("entityBaseTick"); // Purpur +@@ -845,7 +865,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { + // CraftBukkit end + + public void baseTick() { +- this.level().getProfiler().push("entityBaseTick"); ++ //this.level().getProfiler().push("entityBaseTick"); // Purpur if (firstTick && this instanceof net.minecraft.world.entity.NeutralMob neutralMob) neutralMob.tickInitialPersistentAnger(level); // Paper - Update last hurt when ticking this.feetBlockState = null; if (this.isPassenger() && this.getVehicle().isRemoved()) { -@@ -886,7 +887,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -906,7 +926,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } this.firstTick = false; -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur } public void setSharedFlagOnFire(boolean onFire) { -@@ -895,10 +896,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -915,10 +935,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { - public void checkOutOfWorld() { + public void checkBelowWorld() { // Paper start - Configurable nether ceiling damage - if (this.getY() < (double) (this.level.getMinBuildHeight() - 64) || (this.level.getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER -+ if (this.getY() < (double) (this.level.getMinBuildHeight() + level.purpurConfig.voidDamageHeight) || (this.level.getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER // Purpur ++ if (this.getY() < (double) (this.level.getMinBuildHeight() + level().purpurConfig.voidDamageHeight) || (this.level.getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER // Purpur && this.level.paperConfig().environment.netherCeilingVoidDamageHeight.test(v -> this.getY() >= v) && (!(this instanceof Player player) || !player.getAbilities().invulnerable))) { // Paper end -+ if (this.level.purpurConfig.teleportOnNetherCeilingDamage && this.level.getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER && this instanceof ServerPlayer player) player.teleport(MCUtil.toLocation(this.level, this.level.getSharedSpawnPos())); else // Purpur - this.outOfWorld(); ++ if (this.level().purpurConfig.teleportOnNetherCeilingDamage && this.level.getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER && this instanceof ServerPlayer player) player.teleport(io.papermc.paper.util.MCUtil.toLocation(this.level, this.level.getSharedSpawnPos())); else // Purpur + this.onBelowWorld(); } -@@ -1060,7 +1062,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -1125,7 +1146,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } } -- this.level.getProfiler().push("move"); -+ //this.level.getProfiler().push("move"); // Purpur +- this.level().getProfiler().push("move"); ++ //this.level().getProfiler().push("move"); // Purpur if (this.stuckSpeedMultiplier.lengthSqr() > 1.0E-7D) { movement = movement.multiply(this.stuckSpeedMultiplier); this.stuckSpeedMultiplier = Vec3.ZERO; -@@ -1069,7 +1071,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -1134,7 +1155,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { // Paper start - ignore movement changes while inactive. if (isTemporarilyActive && !(this instanceof ItemEntity || this instanceof net.minecraft.world.entity.vehicle.AbstractMinecart) && movement == getDeltaMovement() && movementType == MoverType.SELF) { setDeltaMovement(Vec3.ZERO); @@ -4282,36 +4356,36 @@ index b4ab2cfb7a5fa0d2efd1a759d754d5203aaac077..e71eca3ddbbeb3168dd73433b6d6ffe9 return; } // Paper end -@@ -1090,8 +1092,8 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -1155,8 +1176,8 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { this.setPos(this.getX() + vec3d1.x, this.getY() + vec3d1.y, this.getZ() + vec3d1.z); } -- this.level.getProfiler().pop(); -- this.level.getProfiler().push("rest"); -+ //this.level.getProfiler().pop(); // Purpur -+ //this.level.getProfiler().push("rest"); // Purpur +- this.level().getProfiler().pop(); +- this.level().getProfiler().push("rest"); ++ //this.level().getProfiler().pop(); // Purpur ++ //this.level().getProfiler().push("rest"); // Purpur boolean flag = !Mth.equal(movement.x, vec3d1.x); boolean flag1 = !Mth.equal(movement.z, vec3d1.z); -@@ -1110,7 +1112,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -1175,7 +1196,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { - this.checkFallDamage(vec3d1.y, this.onGround, iblockdata, blockposition); + this.checkFallDamage(vec3d1.y, this.onGround(), iblockdata, blockposition); if (this.isRemoved()) { -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur } else { if (this.horizontalCollision) { Vec3 vec3d2 = this.getDeltaMovement(); -@@ -1251,7 +1253,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -1313,7 +1334,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { this.setRemainingFireTicks(-this.getFireImmuneTicks()); } -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur } } // Paper start - detailed watchdog information -@@ -1678,7 +1680,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -1803,7 +1824,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } public boolean fireImmune() { @@ -4320,7 +4394,7 @@ index b4ab2cfb7a5fa0d2efd1a759d754d5203aaac077..e71eca3ddbbeb3168dd73433b6d6ffe9 } public boolean causeFallDamage(float fallDistance, float damageMultiplier, DamageSource damageSource) { -@@ -1747,7 +1749,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -1872,7 +1893,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { return this.isInWater() || flag; } @@ -4329,7 +4403,7 @@ index b4ab2cfb7a5fa0d2efd1a759d754d5203aaac077..e71eca3ddbbeb3168dd73433b6d6ffe9 Entity entity = this.getVehicle(); if (entity instanceof Boat) { -@@ -2340,6 +2342,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -2473,6 +2494,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { nbt.putBoolean("Paper.FreezeLock", true); } // Paper end @@ -4341,7 +4415,7 @@ index b4ab2cfb7a5fa0d2efd1a759d754d5203aaac077..e71eca3ddbbeb3168dd73433b6d6ffe9 return nbt; } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT"); -@@ -2508,6 +2515,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -2641,6 +2667,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { freezeLocked = nbt.getBoolean("Paper.FreezeLock"); } // Paper end @@ -4353,21 +4427,21 @@ index b4ab2cfb7a5fa0d2efd1a759d754d5203aaac077..e71eca3ddbbeb3168dd73433b6d6ffe9 } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Loading entity NBT"); -@@ -2824,6 +2836,13 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -2942,6 +2973,13 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { this.passengers = ImmutableList.copyOf(list); } + // Purpur start -+ if (isRidable() && this.passengers.get(0) == entity && entity instanceof Player player) { ++ if (isRidable() && this.passengers.get(0) == passenger && passenger instanceof Player player) { + onMount(player); + this.rider = player; + } + // Purpur end + - this.gameEvent(GameEvent.ENTITY_MOUNT, entity); + this.gameEvent(GameEvent.ENTITY_MOUNT, passenger); } - return true; // CraftBukkit -@@ -2865,6 +2884,14 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { + } +@@ -2982,6 +3020,14 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { return false; } // Spigot end @@ -4382,108 +4456,108 @@ index b4ab2cfb7a5fa0d2efd1a759d754d5203aaac077..e71eca3ddbbeb3168dd73433b6d6ffe9 if (this.passengers.size() == 1 && this.passengers.get(0) == entity) { this.passengers = ImmutableList.of(); } else { -@@ -2924,12 +2951,15 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3041,12 +3087,15 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { return Vec3.directionFromRotation(this.getRotationVector()); } + public BlockPos portalPos = BlockPos.ZERO; // Purpur public void handleInsidePortal(BlockPos pos) { if (this.isOnPortalCooldown()) { -+ if (!(level.purpurConfig.playerFixStuckPortal && this instanceof Player && !pos.equals(portalPos))) // Purpur ++ if (!(level().purpurConfig.playerFixStuckPortal && this instanceof Player && !pos.equals(portalPos))) // Purpur this.setPortalCooldown(); - } else { -+ } else if (level.purpurConfig.entitiesCanUsePortals || this instanceof ServerPlayer) { // Purpur - if (!this.level.isClientSide && !pos.equals(this.portalEntrancePos)) { ++ } else if (level().purpurConfig.entitiesCanUsePortals || this instanceof ServerPlayer) { // Purpur + if (!this.level().isClientSide && !pos.equals(this.portalEntrancePos)) { this.portalEntrancePos = pos.immutable(); + portalPos = BlockPos.ZERO; // Purpur } this.isInsidePortal = true; -@@ -2947,7 +2977,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3064,7 +3113,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { ServerLevel worldserver1 = minecraftserver.getLevel(resourcekey); if (true && !this.isPassenger() && this.portalTime++ >= i) { // CraftBukkit -- this.level.getProfiler().push("portal"); -+ //this.level.getProfiler().push("portal"); // Purpur +- this.level().getProfiler().push("portal"); ++ //this.level().getProfiler().push("portal"); // Purpur this.portalTime = i; // Paper start io.papermc.paper.event.entity.EntityPortalReadyEvent event = new io.papermc.paper.event.entity.EntityPortalReadyEvent(this.getBukkitEntity(), worldserver1 == null ? null : worldserver1.getWorld(), org.bukkit.PortalType.NETHER); -@@ -2965,7 +2995,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3082,7 +3131,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } } // Paper // CraftBukkit end -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur } this.isInsidePortal = false; -@@ -2980,7 +3010,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3097,7 +3146,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } this.processPortalCooldown(); - this.tickEndPortal(); // Paper - make end portalling safe -+ if (this.level.purpurConfig.endPortalSafeTeleporting) this.tickEndPortal(); // Paper - make end portalling safe // Purpur ++ if (this.level().purpurConfig.endPortalSafeTeleporting) this.tickEndPortal(); // Paper - make end portalling safe // Purpur } } -@@ -3162,7 +3192,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3283,7 +3332,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } public int getMaxAirSupply() { - return this.maxAirTicks; // CraftBukkit - SPIGOT-6907: re-implement LivingEntity#setMaximumAir() -+ return this.level == null? this.maxAirTicks : this.level.purpurConfig.drowningAirTicks; // CraftBukkit - SPIGOT-6907: re-implement LivingEntity#setMaximumAir() // Purpur ++ return this.level == null? this.maxAirTicks : this.level().purpurConfig.drowningAirTicks; // CraftBukkit - SPIGOT-6907: re-implement LivingEntity#setMaximumAir() // Purpur } public int getAirSupply() { -@@ -3432,14 +3462,14 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3553,14 +3602,14 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } // Paper end - if (this.level instanceof ServerLevel && !this.isRemoved()) { -- this.level.getProfiler().push("changeDimension"); -+ //this.level.getProfiler().push("changeDimension"); // Purpur + if (this.level() instanceof ServerLevel && !this.isRemoved()) { +- this.level().getProfiler().push("changeDimension"); ++ //this.level().getProfiler().push("changeDimension"); // Purpur // CraftBukkit start - // this.decouple(); + // this.unRide(); if (worldserver == null) { return null; } // CraftBukkit end -- this.level.getProfiler().push("reposition"); -+ //this.level.getProfiler().push("reposition"); // Purpur +- this.level().getProfiler().push("reposition"); ++ //this.level().getProfiler().push("reposition"); // Purpur PortalInfo shapedetectorshape = (location == null) ? this.findDimensionEntryPoint(worldserver) : new PortalInfo(new Vec3(location.x(), location.y(), location.z()), Vec3.ZERO, this.yRot, this.xRot, worldserver, null); // CraftBukkit if (shapedetectorshape == null) { -@@ -3473,7 +3503,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3599,7 +3648,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { this.unRide(); // CraftBukkit end -- this.level.getProfiler().popPush("reloading"); -+ //this.level.getProfiler().popPush("reloading"); // Purpur +- this.level().getProfiler().popPush("reloading"); ++ //this.level().getProfiler().popPush("reloading"); // Purpur // Paper start - Change lead drop timing to prevent dupe if (this instanceof Mob) { ((Mob) this).dropLeash(true, true); // Paper drop lead -@@ -3496,10 +3526,10 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3622,10 +3671,10 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } this.removeAfterChangingDimensions(); -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur - ((ServerLevel) this.level).resetEmptyTime(); +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur + ((ServerLevel) this.level()).resetEmptyTime(); worldserver.resetEmptyTime(); -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur return entity; } } else { -@@ -3619,7 +3649,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3745,7 +3794,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } public boolean canChangeDimensions() { - return !this.isPassenger() && !this.isVehicle() && isAlive() && valid; // Paper -+ return !this.isPassenger() && !this.isVehicle() && isAlive() && valid && (level.purpurConfig.entitiesCanUsePortals || this instanceof ServerPlayer); // Paper // Purpur ++ return !this.isPassenger() && !this.isVehicle() && isAlive() && valid && (level().purpurConfig.entitiesCanUsePortals || this instanceof ServerPlayer); // Paper // Purpur } public float getBlockExplosionResistance(Explosion explosion, BlockGetter world, BlockPos pos, BlockState blockState, FluidState fluidState, float max) { -@@ -3916,6 +3946,20 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -4047,6 +4096,20 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { return SlotAccess.NULL; } @@ -4504,7 +4578,7 @@ index b4ab2cfb7a5fa0d2efd1a759d754d5203aaac077..e71eca3ddbbeb3168dd73433b6d6ffe9 @Override public void sendSystemMessage(Component message) {} -@@ -4197,6 +4241,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -4316,6 +4379,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { this.yRotO = this.getYRot(); } @@ -4517,7 +4591,7 @@ index b4ab2cfb7a5fa0d2efd1a759d754d5203aaac077..e71eca3ddbbeb3168dd73433b6d6ffe9 public boolean updateFluidHeightAndDoFluidPushing(TagKey tag, double speed) { if (false && this.touchingUnloadedChunk()) { // Pufferfish - cost of a lookup here is the same cost as below, so skip return false; -@@ -4725,4 +4775,64 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -4869,4 +4938,45 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { return ((net.minecraft.server.level.ServerChunkCache) level.getChunkSource()).isPositionTicking(this); } // Paper end @@ -4561,29 +4635,10 @@ index b4ab2cfb7a5fa0d2efd1a759d754d5203aaac077..e71eca3ddbbeb3168dd73433b6d6ffe9 + public boolean processClick(InteractionHand hand) { + return false; + } -+ -+ public boolean canSaveToDisk() { -+ return true; -+ } -+ -+ // Purpur start - copied from Mob -+ public boolean isSunBurnTick() { -+ if (this.level.isDay() && !this.level.isClientSide) { -+ float f = this.getLightLevelDependentMagicValue(); -+ BlockPos blockposition = BlockPos.containing(this.getX(), this.getEyeY(), this.getZ()); -+ boolean flag = this.isInWaterRainOrBubble() || this.isInPowderSnow || this.wasInPowderSnow; -+ -+ if (f > 0.5F && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && !flag && this.level.canSeeSky(blockposition)) { -+ return true; -+ } -+ } -+ -+ return false; -+ } + // Purpur end } diff --git a/src/main/java/net/minecraft/world/entity/EntitySelector.java b/src/main/java/net/minecraft/world/entity/EntitySelector.java -index 72abebff2018cde2922e97ad6478f93da9aed3ec..412963d7af38a53b6010007278d959a5b11b83c3 100644 +index 3ff999734d14e2b6e7828e117f5ee32a60c26bc1..cfa9607241c3e69777ffc317206996c2f783437a 100644 --- a/src/main/java/net/minecraft/world/entity/EntitySelector.java +++ b/src/main/java/net/minecraft/world/entity/EntitySelector.java @@ -39,6 +39,7 @@ public final class EntitySelector { @@ -4595,7 +4650,7 @@ index 72abebff2018cde2922e97ad6478f93da9aed3ec..412963d7af38a53b6010007278d959a5 private EntitySelector() {} // Paper start diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index 8af0918d3a62de58a4b2af55022c812bb0e46092..3fc26a8976f4bfa28c2c6a862aac997d5f721f51 100644 +index aa5cec6d56d7a8e80861aa4c9b4a74ca3e64be8c..a8ffa403ac48041e17aa4ce057be0539e5468fd4 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java @@ -308,13 +308,24 @@ public class EntityType implements FeatureElement, EntityTypeT @@ -4655,123 +4710,94 @@ index 8af0918d3a62de58a4b2af55022c812bb0e46092..3fc26a8976f4bfa28c2c6a862aac997d } diff --git a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java -index 89699aaccd45a5a928a97d1b3ad06f5de5b9fad1..b3b371ee4850c90a3142c3c96761b032e6de6af0 100644 +index eca634792d2a7cc649675e3394e84dbaf1453905..724bf857bf1b89cb0947b8a82e0ce09a0bec0335 100644 --- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java +++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java -@@ -306,7 +306,7 @@ public class ExperienceOrb extends Entity { +@@ -313,7 +313,7 @@ public class ExperienceOrb extends Entity { public void playerTouch(Player player) { - if (!this.level.isClientSide) { + 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 - player.takeXpDelay = CraftEventFactory.callPlayerXpCooldownEvent(player, 2, PlayerExpCooldownChangeEvent.ChangeReason.PICKUP_ORB).getNewCooldown(); // CraftBukkit - entityhuman.takeXpDelay = 2; -+ player.takeXpDelay = CraftEventFactory.callPlayerXpCooldownEvent(player, this.level.purpurConfig.playerExpPickupDelay, PlayerExpCooldownChangeEvent.ChangeReason.PICKUP_ORB).getNewCooldown(); // CraftBukkit - entityhuman.takeXpDelay = 2; // Purpur ++ player.takeXpDelay = CraftEventFactory.callPlayerXpCooldownEvent(player, this.level().purpurConfig.playerExpPickupDelay, PlayerExpCooldownChangeEvent.ChangeReason.PICKUP_ORB).getNewCooldown(); // CraftBukkit - entityhuman.takeXpDelay = 2; // Purpur player.take(this, 1); int i = this.repairPlayerItems(player, this.value); -@@ -324,7 +324,7 @@ public class ExperienceOrb extends Entity { +@@ -331,7 +331,7 @@ public class ExperienceOrb extends Entity { } private int repairPlayerItems(Player player, int amount) { - Entry entry = EnchantmentHelper.getRandomItemWith(Enchantments.MENDING, player, ItemStack::isDamaged); -+ Entry entry = level.purpurConfig.useBetterMending ? EnchantmentHelper.getMostDamagedEquipment(Enchantments.MENDING, player) : EnchantmentHelper.getRandomItemWith(Enchantments.MENDING, player, ItemStack::isDamaged); // Purpur ++ Entry entry = level().purpurConfig.useBetterMending ? EnchantmentHelper.getMostDamagedEquipment(Enchantments.MENDING, player) : EnchantmentHelper.getRandomItemWith(Enchantments.MENDING, player, ItemStack::isDamaged); // Purpur if (entry != null) { ItemStack itemstack = (ItemStack) entry.getValue(); -@@ -352,13 +352,15 @@ public class ExperienceOrb extends Entity { +@@ -359,13 +359,15 @@ public class ExperienceOrb extends Entity { } } + // Purpur start public int durabilityToXp(int repairAmount) { - return repairAmount / 2; -+ return (int) (repairAmount / (2 * level.purpurConfig.mendingMultiplier)); ++ return (int) (repairAmount / (2 * level().purpurConfig.mendingMultiplier)); } public int xpToDurability(int experienceAmount) { - return experienceAmount * 2; -+ return (int) ((experienceAmount * 2) * level.purpurConfig.mendingMultiplier); ++ return (int) ((experienceAmount * 2) * level().purpurConfig.mendingMultiplier); } + // Purpur end 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 c1e9b40a4a0f9cdc650caa88b5ea132e06ee2496..6f723171fa71d74b351b5cf0cd167bb6f7ca1691 100644 +index 759713f7c646aaf1a918c87a2834a1d405385dad..43cdda0cb26c5d5cc9025199eb71673d71c2abea 100644 --- a/src/main/java/net/minecraft/world/entity/GlowSquid.java +++ b/src/main/java/net/minecraft/world/entity/GlowSquid.java -@@ -18,11 +18,45 @@ import net.minecraft.world.level.block.Blocks; - - public class GlowSquid extends Squid { - private static final EntityDataAccessor DATA_DARK_TICKS_REMAINING = SynchedEntityData.defineId(GlowSquid.class, EntityDataSerializers.INT); -+ private static final net.minecraft.network.syncher.EntityDataAccessor SQUID_COLOR = net.minecraft.network.syncher.SynchedEntityData.defineId(GlowSquid.class, net.minecraft.network.syncher.EntityDataSerializers.STRING); // Purpur - - public GlowSquid(EntityType type, Level world) { +@@ -23,6 +23,39 @@ public class GlowSquid extends Squid { super(type, world); } + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.glowSquidRidable; ++ return level().purpurConfig.glowSquidRidable; + } + + + @Override + public boolean isControllable() { -+ return level.purpurConfig.glowSquidControllable; ++ return level().purpurConfig.glowSquidControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.glowSquidMaxHealth); ++ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.glowSquidMaxHealth); + } + + @Override + public boolean canFly() { -+ return this.level.purpurConfig.glowSquidsCanFly; ++ return this.level().purpurConfig.glowSquidsCanFly; + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.glowSquidTakeDamageFromWater; ++ return this.level().purpurConfig.glowSquidTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.glowSquidAlwaysDropExp; ++ return this.level().purpurConfig.glowSquidAlwaysDropExp; + } -+ // Purpur end + @Override protected ParticleOptions getInkParticle() { return ParticleTypes.GLOW_SQUID_INK; -@@ -32,6 +66,7 @@ public class GlowSquid extends Squid { - protected void defineSynchedData() { - super.defineSynchedData(); - this.entityData.define(DATA_DARK_TICKS_REMAINING, 0); -+ this.entityData.define(SQUID_COLOR, this.level.purpurConfig.glowSquidColorMode.getRandom(this.random).toString()); // Purpur - } - - @Override -@@ -58,12 +93,14 @@ public class GlowSquid extends Squid { - public void addAdditionalSaveData(CompoundTag nbt) { - super.addAdditionalSaveData(nbt); - nbt.putInt("DarkTicksRemaining", this.getDarkTicksRemaining()); -+ nbt.putString("Colour", this.entityData.get(SQUID_COLOR)); // Purpur - key must match rainglow - } - - @Override - public void readAdditionalSaveData(CompoundTag nbt) { - super.readAdditionalSaveData(nbt); - this.setDarkTicks(nbt.getInt("DarkTicksRemaining")); -+ if (nbt.contains("Colour")) this.entityData.set(SQUID_COLOR, nbt.getString("Colour")); // Purpur - key must match rainglow - } - - @Override diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index f3d96caa83ef4a8083b78e3265282d4723e37d28..b67660cda74a4754d1701e746aca99bde868c150 100644 +index e9a31314424d9db911cd9806741222397c3072d7..4cd04661b39a7055f5767a3dff88f9a3e197d810 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -216,9 +216,9 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -218,9 +218,9 @@ public abstract class LivingEntity extends Entity implements Attackable { protected int deathScore; public float lastHurt; public boolean jumping; @@ -4784,7 +4810,7 @@ index f3d96caa83ef4a8083b78e3265282d4723e37d28..b67660cda74a4754d1701e746aca99bd protected int lerpSteps; protected double lerpX; protected double lerpY; -@@ -251,6 +251,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -253,6 +253,7 @@ public abstract class LivingEntity extends Entity implements Attackable { private boolean skipDropExperience; // CraftBukkit start public int expToDrop; @@ -4792,7 +4818,7 @@ index f3d96caa83ef4a8083b78e3265282d4723e37d28..b67660cda74a4754d1701e746aca99bd public boolean forceDrops; public ArrayList drops = new ArrayList(); public final org.bukkit.craftbukkit.attribute.CraftAttributeMap craftAttributes; -@@ -260,6 +261,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -262,6 +263,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 @@ -4800,7 +4826,7 @@ index f3d96caa83ef4a8083b78e3265282d4723e37d28..b67660cda74a4754d1701e746aca99bd @Override public float getBukkitYaw() { -@@ -284,7 +286,8 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -286,7 +288,8 @@ public abstract class LivingEntity extends Entity implements Attackable { this.effectsDirty = true; this.useItem = ItemStack.EMPTY; this.lastClimbablePos = Optional.empty(); @@ -4810,7 +4836,7 @@ index f3d96caa83ef4a8083b78e3265282d4723e37d28..b67660cda74a4754d1701e746aca99bd 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()); -@@ -300,6 +303,8 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -302,6 +305,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())))); } @@ -4819,7 +4845,7 @@ index f3d96caa83ef4a8083b78e3265282d4723e37d28..b67660cda74a4754d1701e746aca99bd public Brain getBrain() { return this.brain; } -@@ -335,6 +340,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -337,6 +342,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); } @@ -4827,62 +4853,78 @@ index f3d96caa83ef4a8083b78e3265282d4723e37d28..b67660cda74a4754d1701e746aca99bd @Override protected void checkFallDamage(double heightDifference, boolean onGround, BlockState state, BlockPos landedPosition) { -@@ -347,8 +353,8 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -349,7 +355,7 @@ public abstract class LivingEntity extends Entity implements Attackable { this.tryAddSoulSpeed(); } -- if (!this.level.isClientSide && this.fallDistance > 3.0F && onGround) { -- float f = (float) Mth.ceil(this.fallDistance - 3.0F); -+ if (!this.level.isClientSide && this.fallDistance > this.safeFallDistance && onGround) { // Purpur -+ float f = (float) Mth.ceil(this.fallDistance - this.safeFallDistance); // Purpur +- 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; + } - if (!state.isAir()) { - double d1 = Math.min((double) (0.2F + f / 15.0F), 2.5D); -@@ -387,7 +393,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +- 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); + +@@ -404,7 +410,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } super.baseTick(); -- this.level.getProfiler().push("livingEntityBaseTick"); -+ //this.level.getProfiler().push("livingEntityBaseTick"); // Purpur - if (this.fireImmune() || this.level.isClientSide) { +- this.level().getProfiler().push("livingEntityBaseTick"); ++ //this.level().getProfiler().push("livingEntityBaseTick"); // Purpur + if (this.fireImmune() || this.level().isClientSide) { this.clearFire(); } -@@ -405,6 +411,7 @@ public abstract class LivingEntity extends Entity implements Attackable { - double d1 = this.level.getWorldBorder().getDamagePerBlock(); +@@ -413,7 +419,7 @@ public abstract class LivingEntity extends Entity implements Attackable { + boolean flag = this instanceof net.minecraft.world.entity.player.Player; + + if (!this.level().isClientSide) { +- if ((!gg.pufferfish.pufferfish.PufferfishConfig.enableSuffocationOptimization || (tickCount % 10 == 0 && couldPossiblyBeHurt(1.0F))) && this.isInWall()) { // Pufferfish - optimize suffocation ++ if (shouldCheckForSuffocation() && this.isInWall()) { // Pufferfish - optimize suffocation // Purpur + this.hurt(this.damageSources().inWall(), 1.0F); + } else if (flag && !this.level().getWorldBorder().isWithinBounds(this.getBoundingBox())) { + double d0 = this.level().getWorldBorder().getDistanceToBorder(this) + this.level().getWorldBorder().getDamageSafeZone(); +@@ -422,6 +428,7 @@ public abstract class LivingEntity extends Entity implements Attackable { + double d1 = this.level().getWorldBorder().getDamagePerBlock(); if (d1 > 0.0D) { -+ if (level.purpurConfig.teleportIfOutsideBorder && this instanceof ServerPlayer) { ((ServerPlayer) this).teleport(io.papermc.paper.util.MCUtil.toLocation(level, ((ServerLevel) level).getSharedSpawnPos())); return; } // Purpur - this.hurt(this.damageSources().inWall(), (float) Math.max(1, Mth.floor(-d0 * d1))); ++ if (level().purpurConfig.teleportIfOutsideBorder && this instanceof ServerPlayer serverPlayer) { serverPlayer.teleport(io.papermc.paper.util.MCUtil.toLocation(level(), ((ServerLevel) level()).getSharedSpawnPos())); return; } // Purpur + this.hurt(this.damageSources().outOfBorder(), (float) Math.max(1, Mth.floor(-d0 * d1))); } } -@@ -416,7 +423,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -433,7 +440,7 @@ public abstract class LivingEntity extends Entity implements Attackable { if (flag1) { this.setAirSupply(this.decreaseAirSupply(this.getAirSupply())); - if (this.getAirSupply() == -20) { -+ if (this.getAirSupply() == -this.level.purpurConfig.drowningDamageInterval) { // Purpur ++ if (this.getAirSupply() == -this.level().purpurConfig.drowningDamageInterval) { // Purpur this.setAirSupply(0); Vec3 vec3d = this.getDeltaMovement(); -@@ -428,7 +435,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); +@@ -445,7 +452,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); } - this.hurt(this.damageSources().drown(), 2.0F); -+ this.hurt(this.damageSources().drown(), (float) this.level.purpurConfig.damageFromDrowning); // Purpur ++ this.hurt(this.damageSources().drown(), (float) this.level().purpurConfig.damageFromDrowning); // Purpur } } -@@ -489,7 +496,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -506,7 +513,7 @@ public abstract class LivingEntity extends Entity implements Attackable { this.yHeadRotO = this.yHeadRot; this.yRotO = this.getYRot(); this.xRotO = this.getXRot(); -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur } public boolean canSpawnSoulSpeedParticle() { -@@ -781,6 +788,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -798,6 +805,7 @@ public abstract class LivingEntity extends Entity implements Attackable { dataresult.resultOrPartial(logger::error).ifPresent((nbtbase) -> { nbt.put("Brain", nbtbase); }); @@ -4890,7 +4932,7 @@ index f3d96caa83ef4a8083b78e3265282d4723e37d28..b67660cda74a4754d1701e746aca99bd } @Override -@@ -865,6 +873,11 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -882,6 +890,11 @@ public abstract class LivingEntity extends Entity implements Attackable { this.brain = this.makeBrain(new Dynamic(NbtOps.INSTANCE, nbt.get("Brain"))); } @@ -4902,7 +4944,7 @@ index f3d96caa83ef4a8083b78e3265282d4723e37d28..b67660cda74a4754d1701e746aca99bd } // CraftBukkit start -@@ -1010,9 +1023,31 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1027,9 +1040,31 @@ public abstract class LivingEntity extends Entity implements Attackable { ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD); EntityType entitytypes = entity.getType(); @@ -4910,16 +4952,16 @@ index f3d96caa83ef4a8083b78e3265282d4723e37d28..b67660cda74a4754d1701e746aca99bd - d0 *= 0.5D; + // Purpur start + if (entitytypes == EntityType.SKELETON && itemstack.is(Items.SKELETON_SKULL)) { -+ d0 *= entity.level.purpurConfig.skeletonHeadVisibilityPercent; ++ d0 *= entity.level().purpurConfig.skeletonHeadVisibilityPercent; + } + else if (entitytypes == EntityType.ZOMBIE && itemstack.is(Items.ZOMBIE_HEAD)) { -+ d0 *= entity.level.purpurConfig.zombieHeadVisibilityPercent; ++ d0 *= entity.level().purpurConfig.zombieHeadVisibilityPercent; + } + else if (entitytypes == EntityType.CREEPER && itemstack.is(Items.CREEPER_HEAD)) { -+ d0 *= entity.level.purpurConfig.creeperHeadVisibilityPercent; ++ d0 *= entity.level().purpurConfig.creeperHeadVisibilityPercent; + } + else if ((entitytypes == EntityType.PIGLIN || entitytypes == EntityType.PIGLIN_BRUTE) && itemstack.is(Items.PIGLIN_HEAD)) { -+ d0 *= entity.level.purpurConfig.piglinHeadVisibilityPercent; ++ d0 *= entity.level().purpurConfig.piglinHeadVisibilityPercent; + } + // Purpur end + @@ -4928,7 +4970,7 @@ index f3d96caa83ef4a8083b78e3265282d4723e37d28..b67660cda74a4754d1701e746aca99bd + if (entityliving.hasEffect(MobEffects.BLINDNESS)) { + int amplifier = entityliving.getEffect(MobEffects.BLINDNESS).getAmplifier(); + for (int i = 0; i < amplifier; i++) { -+ d0 *= this.level.purpurConfig.mobsBlindnessMultiplier; ++ d0 *= this.level().purpurConfig.mobsBlindnessMultiplier; + } + } } @@ -4936,36 +4978,48 @@ index f3d96caa83ef4a8083b78e3265282d4723e37d28..b67660cda74a4754d1701e746aca99bd } return d0; -@@ -1072,6 +1107,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1089,6 +1124,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().isBeneficial()) continue; // Purpur EntityPotionEffectEvent event = CraftEventFactory.callEntityPotionEffectChangeEvent(this, effect, null, cause, EntityPotionEffectEvent.Action.CLEARED); if (event.isCancelled()) { continue; -@@ -1428,13 +1464,13 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1376,6 +1412,11 @@ public abstract class LivingEntity extends Entity implements Attackable { + return true; + } + // Pufferfish end ++ // Purpur start ++ public boolean shouldCheckForSuffocation() { ++ return (!gg.pufferfish.pufferfish.PufferfishConfig.enableSuffocationOptimization || (tickCount % 10 == 0 && couldPossiblyBeHurt(1.0F))); ++ } ++ // Purpur end + + @Override + public boolean hurt(DamageSource source, float amount) { +@@ -1467,13 +1508,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; - this.lastHurtByPlayerTime = 100; -+ this.lastHurtByPlayerTime = this.level.purpurConfig.mobLastHurtByPlayerTime; // Purpur ++ this.lastHurtByPlayerTime = this.level().purpurConfig.mobLastHurtByPlayerTime; // Purpur this.lastHurtByPlayer = entityhuman; } else if (entity1 instanceof Wolf) { Wolf entitywolf = (Wolf) entity1; if (entitywolf.isTame()) { - this.lastHurtByPlayerTime = 100; -+ this.lastHurtByPlayerTime = this.level.purpurConfig.mobLastHurtByPlayerTime; // Purpur ++ this.lastHurtByPlayerTime = this.level().purpurConfig.mobLastHurtByPlayerTime; // Purpur LivingEntity entityliving2 = entitywolf.getOwner(); if (entityliving2 instanceof net.minecraft.world.entity.player.Player) { -@@ -1545,6 +1581,18 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1584,6 +1625,18 @@ public abstract class LivingEntity extends Entity implements Attackable { } } + // Purpur start -+ if (level.purpurConfig.totemOfUndyingWorksInInventory && this instanceof ServerPlayer player && (itemstack == null || itemstack.getItem() != Items.TOTEM_OF_UNDYING) && player.getBukkitEntity().hasPermission("purpur.inventory_totem")) { ++ if (level().purpurConfig.totemOfUndyingWorksInInventory && this instanceof ServerPlayer player && (itemstack == null || itemstack.getItem() != Items.TOTEM_OF_UNDYING) && player.getBukkitEntity().hasPermission("purpur.inventory_totem")) { + for (ItemStack item : player.getInventory().items) { + if (item.getItem() == Items.TOTEM_OF_UNDYING) { + itemstack1 = item; @@ -4979,24 +5033,24 @@ index f3d96caa83ef4a8083b78e3265282d4723e37d28..b67660cda74a4754d1701e746aca99bd 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); -@@ -1705,7 +1753,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1750,7 +1803,7 @@ public abstract class LivingEntity extends Entity implements Attackable { boolean flag = false; if (this.dead && adversary instanceof WitherBoss) { // Paper -- if (this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -+ if (this.level.purpurConfig.witherBypassMobGriefing || this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur +- if (this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ if (this.level().purpurConfig.witherBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur BlockPos blockposition = this.blockPosition(); BlockState iblockdata = Blocks.WITHER_ROSE.defaultBlockState(); -@@ -1751,6 +1799,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1796,6 +1849,7 @@ public abstract class LivingEntity extends Entity implements Attackable { this.dropEquipment(); // CraftBukkit - from below - if (this.shouldDropLoot() && this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { -+ if (!(source.is(net.minecraft.world.damagesource.DamageTypes.CRAMMING) && level.purpurConfig.disableDropsOnCrammingDeath)) { // Purpur + if (this.shouldDropLoot() && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { ++ if (!(source.is(net.minecraft.world.damagesource.DamageTypes.CRAMMING) && level().purpurConfig.disableDropsOnCrammingDeath)) { // Purpur this.dropFromLootTable(source, flag); // Paper start final boolean prev = this.clearEquipmentSlots; -@@ -1759,6 +1808,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1804,6 +1858,7 @@ public abstract class LivingEntity extends Entity implements Attackable { // Paper end this.dropCustomDeathLoot(source, i, flag); this.clearEquipmentSlots = prev; // Paper @@ -5004,7 +5058,7 @@ index f3d96caa83ef4a8083b78e3265282d4723e37d28..b67660cda74a4754d1701e746aca99bd } // 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, () -> { -@@ -2014,7 +2064,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2050,7 +2105,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); @@ -5013,12 +5067,12 @@ index f3d96caa83ef4a8083b78e3265282d4723e37d28..b67660cda74a4754d1701e746aca99bd } } -@@ -2237,6 +2287,20 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2273,6 +2328,20 @@ 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 (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)) { @@ -5034,138 +5088,138 @@ index f3d96caa83ef4a8083b78e3265282d4723e37d28..b67660cda74a4754d1701e746aca99bd if (f > 0 || !human) { if (human) { // PAIL: Be sure to drag all this code from the EntityHuman subclass each update. -@@ -2455,7 +2519,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2489,7 +2558,7 @@ public abstract class LivingEntity extends Entity implements Attackable { @Override - protected void outOfWorld() { -- this.hurt(this.damageSources().outOfWorld(), 4.0F); -+ this.hurt(this.damageSources().outOfWorld(), (float) level.purpurConfig.voidDamageDealt); // Purpur + protected void onBelowWorld() { +- this.hurt(this.damageSources().fellOutOfWorld(), 4.0F); ++ this.hurt(this.damageSources().fellOutOfWorld(), (float) level().purpurConfig.voidDamageDealt); // Purpur } protected void updateSwingTime() { -@@ -2652,7 +2716,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2686,7 +2755,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } protected long lastJumpTime = 0L; // Paper - protected void jumpFromGround() { + public void jumpFromGround() { // Purpur - protected -> public - double d0 = (double) this.getJumpPower() + this.getJumpBoostPower(); Vec3 vec3d = this.getDeltaMovement(); // Paper start -@@ -2806,6 +2870,7 @@ public abstract class LivingEntity extends Entity implements Attackable { + long time = System.nanoTime(); +@@ -2838,6 +2907,7 @@ public abstract class LivingEntity extends Entity implements Attackable { if (f3 > 0.0F) { this.playSound(this.getFallDamageSound((int) f3), 1.0F, 1.0F); -+ if (level.purpurConfig.elytraKineticDamage) // Purpur ++ if (level().purpurConfig.elytraKineticDamage) // Purpur this.hurt(this.damageSources().flyIntoWall(), f3); } } -@@ -3028,10 +3093,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3059,10 +3129,10 @@ public abstract class LivingEntity extends Entity implements Attackable { } this.run += (f3 - this.run) * 0.3F; -- this.level.getProfiler().push("headTurn"); -+ //this.level.getProfiler().push("headTurn"); // Purpur +- this.level().getProfiler().push("headTurn"); ++ //this.level().getProfiler().push("headTurn"); // Purpur f2 = this.tickHeadTurn(f1, f2); -- this.level.getProfiler().pop(); -- this.level.getProfiler().push("rangeChecks"); -+ //this.level.getProfiler().pop(); // Purpur -+ //this.level.getProfiler().push("rangeChecks"); // Purpur +- this.level().getProfiler().pop(); +- this.level().getProfiler().push("rangeChecks"); ++ //this.level().getProfiler().pop(); // Purpur ++ //this.level().getProfiler().push("rangeChecks"); // Purpur // Paper start - stop large pitch and yaw changes from crashing the server this.yRotO += Math.round((this.getYRot() - this.yRotO) / 360.0F) * 360.0F; -@@ -3043,7 +3108,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3074,7 +3144,7 @@ public abstract class LivingEntity extends Entity implements Attackable { this.yHeadRotO += Math.round((this.yHeadRot - this.yHeadRotO) / 360.0F) * 360.0F; // Paper end -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur this.animStep += f2; if (this.isFallFlying()) { ++this.fallFlyTicks; -@@ -3332,19 +3397,19 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3363,19 +3433,19 @@ public abstract class LivingEntity extends Entity implements Attackable { } this.setDeltaMovement(d4, d5, d6); -- this.level.getProfiler().push("ai"); -+ //this.level.getProfiler().push("ai"); // Purpur +- this.level().getProfiler().push("ai"); ++ //this.level().getProfiler().push("ai"); // Purpur if (this.isImmobile()) { this.jumping = false; this.xxa = 0.0F; this.zza = 0.0F; } else if (this.isEffectiveAi()) { -- this.level.getProfiler().push("newAi"); -+ //this.level.getProfiler().push("newAi"); // Purpur +- this.level().getProfiler().push("newAi"); ++ //this.level().getProfiler().push("newAi"); // Purpur this.serverAiStep(); -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur } -- this.level.getProfiler().pop(); -- this.level.getProfiler().push("jump"); -+ //this.level.getProfiler().pop(); // Purpur -+ //this.level.getProfiler().push("jump"); // Purpur +- this.level().getProfiler().pop(); +- this.level().getProfiler().push("jump"); ++ //this.level().getProfiler().pop(); // Purpur ++ //this.level().getProfiler().push("jump"); // Purpur if (this.jumping && this.isAffectedByFluids()) { double d7; -@@ -3371,8 +3436,8 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3402,8 +3472,8 @@ public abstract class LivingEntity extends Entity implements Attackable { this.noJumpDelay = 0; } -- this.level.getProfiler().pop(); -- this.level.getProfiler().push("travel"); -+ //this.level.getProfiler().pop(); // Purpur -+ //this.level.getProfiler().push("travel"); // Purpur +- this.level().getProfiler().pop(); +- this.level().getProfiler().push("travel"); ++ //this.level().getProfiler().pop(); // Purpur ++ //this.level().getProfiler().push("travel"); // Purpur this.xxa *= 0.98F; this.zza *= 0.98F; this.updateFallFlying(); -@@ -3388,8 +3453,8 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3430,8 +3500,8 @@ public abstract class LivingEntity extends Entity implements Attackable { + this.travel(vec3d1); } - //SpigotTimings.timerEntityAIMove.stopTiming(); // Spigot // Paper -- this.level.getProfiler().pop(); -- this.level.getProfiler().push("freezing"); -+ //this.level.getProfiler().pop(); // Purpur -+ //this.level.getProfiler().push("freezing"); // Purpur - if (!this.level.isClientSide && !this.isDeadOrDying() && !freezeLocked) { // Paper - Freeze Tick Lock API +- this.level().getProfiler().pop(); +- this.level().getProfiler().push("freezing"); ++ //this.level().getProfiler().pop(); // Purpur ++ //this.level().getProfiler().push("freezing"); // Purpur + if (!this.level().isClientSide && !this.isDeadOrDying() && !freezeLocked) { // Paper - Freeze Tick Lock API int i = this.getTicksFrozen(); -@@ -3406,18 +3471,20 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3448,18 +3518,20 @@ public abstract class LivingEntity extends Entity implements Attackable { this.hurt(this.damageSources().freeze(), 1.0F); } -- this.level.getProfiler().pop(); -- this.level.getProfiler().push("push"); -+ //this.level.getProfiler().pop(); // Purpur -+ //this.level.getProfiler().push("push"); // Purpur +- this.level().getProfiler().pop(); +- this.level().getProfiler().push("push"); ++ //this.level().getProfiler().pop(); // Purpur ++ //this.level().getProfiler().push("push"); // Purpur if (this.autoSpinAttackTicks > 0) { --this.autoSpinAttackTicks; this.checkAutoSpinAttack(axisalignedbb, this.getBoundingBox()); } this.pushEntities(); -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur // Paper start -- if (((ServerLevel) this.level).hasEntityMoveEvent && !(this instanceof net.minecraft.world.entity.player.Player)) { -- if (this.xo != getX() || this.yo != this.getY() || this.zo != this.getZ() || this.yRotO != this.getYRot() || this.xRotO != this.getXRot()) { +- if (((ServerLevel) this.level()).hasEntityMoveEvent && !(this instanceof net.minecraft.world.entity.player.Player)) { +- if (this.xo != this.getX() || this.yo != this.getY() || this.zo != this.getZ() || this.yRotO != this.getYRot() || this.xRotO != this.getXRot()) { + // Purpur start + if (this.xo != this.getX() || this.yo != this.getY() || this.zo != this.getZ() || this.yRotO != this.getYRot() || this.xRotO != this.getXRot()) { -+ if (((ServerLevel) this.level).hasEntityMoveEvent && !(this instanceof net.minecraft.world.entity.player.Player)) { ++ if (((ServerLevel) this.level()).hasEntityMoveEvent && !(this instanceof net.minecraft.world.entity.player.Player)) { + // Purpur end - 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()); + 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()); -@@ -3427,12 +3494,48 @@ public abstract class LivingEntity extends Entity implements Attackable { - absMoveTo(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ(), event.getTo().getYaw(), event.getTo().getPitch()); +@@ -3469,12 +3541,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()); } } + // Purpur start + if (getRider() != null) { + getRider().resetLastActionTime(); -+ if (((ServerLevel) level).hasRidableMoveEvent && this instanceof Mob) { -+ Location from = new Location(level.getWorld(), xo, yo, zo, this.yRotO, this.xRotO); -+ Location to = new Location(level.getWorld(), getX(), getY(), getZ(), this.getYRot(), this.getXRot()); ++ if (((ServerLevel) level()).hasRidableMoveEvent && this instanceof Mob) { ++ Location from = new Location(level().getWorld(), xo, yo, zo, this.yRotO, this.xRotO); ++ Location to = new Location(level().getWorld(), getX(), getY(), getZ(), this.getYRot(), this.getXRot()); + org.purpurmc.purpur.event.entity.RidableMoveEvent event = new org.purpurmc.purpur.event.entity.RidableMoveEvent((org.bukkit.entity.Mob) getBukkitLivingEntity(), (Player) getRider().getBukkitEntity(), from, to.clone()); + if (!event.callEvent()) { + absMoveTo(from.getX(), from.getY(), from.getZ(), from.getYaw(), from.getPitch()); @@ -5177,7 +5231,7 @@ index f3d96caa83ef4a8083b78e3265282d4723e37d28..b67660cda74a4754d1701e746aca99bd + // Purpur end } // Paper end - if (!this.level.isClientSide && this.isSensitiveToWater() && this.isInWaterRainOrBubble()) { + if (!this.level().isClientSide && this.isSensitiveToWater() && this.isInWaterRainOrBubble()) { this.hurt(this.damageSources().drown(), 1.0F); } @@ -5205,16 +5259,16 @@ index f3d96caa83ef4a8083b78e3265282d4723e37d28..b67660cda74a4754d1701e746aca99bd } public boolean isSensitiveToWater() { -@@ -3453,7 +3556,16 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3495,7 +3603,16 @@ public abstract class LivingEntity extends Entity implements Attackable { int j = i / 10; if (j % 2 == 0) { - itemstack.hurtAndBreak(1, this, (entityliving) -> { + // Purpur start -+ int damage = level.purpurConfig.elytraDamagePerSecond; -+ if (level.purpurConfig.elytraDamageMultiplyBySpeed > 0) { ++ int damage = level().purpurConfig.elytraDamagePerSecond; ++ if (level().purpurConfig.elytraDamageMultiplyBySpeed > 0) { + double speed = getDeltaMovement().lengthSqr(); -+ if (speed > level.purpurConfig.elytraDamageMultiplyBySpeed) { ++ if (speed > level().purpurConfig.elytraDamageMultiplyBySpeed) { + damage *= (int) speed; + } + } @@ -5224,7 +5278,7 @@ index f3d96caa83ef4a8083b78e3265282d4723e37d28..b67660cda74a4754d1701e746aca99bd }); } diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 636e601b004a412d02e5be86e97d489b52c28e1b..8e2274f7dce34e0997356205cf96e46f8d41cca1 100644 +index f6eb032897c6d5d16ab5c8c287e49e189c24571c..19d9d3a9f634631e2ec5a6fa7f2cd9dd18f62f89 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java @@ -65,6 +65,7 @@ import net.minecraft.world.item.ProjectileWeaponItem; @@ -5235,7 +5289,7 @@ index 636e601b004a412d02e5be86e97d489b52c28e1b..8e2274f7dce34e0997356205cf96e46f import net.minecraft.world.level.GameRules; import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.Level; -@@ -133,6 +134,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -132,6 +133,7 @@ public abstract class Mob extends LivingEntity implements Targeting { private BlockPos restrictCenter; private float restrictRadius; @@ -5243,7 +5297,7 @@ index 636e601b004a412d02e5be86e97d489b52c28e1b..8e2274f7dce34e0997356205cf96e46f public boolean aware = true; // CraftBukkit protected Mob(EntityType type, Level world) { -@@ -146,8 +148,8 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -145,8 +147,8 @@ public abstract class Mob extends LivingEntity implements Targeting { this.restrictRadius = -1.0F; this.goalSelector = new GoalSelector(world.getProfilerSupplier()); this.targetSelector = new GoalSelector(world.getProfilerSupplier()); @@ -5254,7 +5308,7 @@ index 636e601b004a412d02e5be86e97d489b52c28e1b..8e2274f7dce34e0997356205cf96e46f this.jumpControl = new JumpControl(this); this.bodyRotationControl = this.createBodyControl(); this.navigation = this.createNavigation(world); -@@ -319,6 +321,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -322,6 +324,7 @@ public abstract class Mob extends LivingEntity implements Targeting { entityliving = null; } } @@ -5262,20 +5316,20 @@ index 636e601b004a412d02e5be86e97d489b52c28e1b..8e2274f7dce34e0997356205cf96e46f this.target = entityliving; return true; // CraftBukkit end -@@ -359,15 +362,35 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -362,15 +365,35 @@ public abstract class Mob extends LivingEntity implements Targeting { @Override public void baseTick() { super.baseTick(); -- this.level.getProfiler().push("mobBaseTick"); -+ //this.level.getProfiler().push("mobBaseTick"); // Purpur +- this.level().getProfiler().push("mobBaseTick"); ++ //this.level().getProfiler().push("mobBaseTick"); // Purpur if (this.isAlive() && this.random.nextInt(1000) < this.ambientSoundTime++) { this.resetAmbientSoundTime(); this.playAmbientSound(); } -- this.level.getProfiler().pop(); +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur + incrementTicksSinceLastInteraction(); // Purpur -+ //this.level.getProfiler().pop(); // Purpur } + // Purpur start @@ -5285,13 +5339,13 @@ index 636e601b004a412d02e5be86e97d489b52c28e1b..8e2274f7dce34e0997356205cf96e46f + this.ticksSinceLastInteraction = 0; + return; + } -+ if (this.level.purpurConfig.entityLifeSpan <= 0) { ++ if (this.level().purpurConfig.entityLifeSpan <= 0) { + return; // feature disabled + } + if (!this.removeWhenFarAway(0) || isPersistenceRequired() || requiresCustomPersistence() || hasCustomName()) { + return; // mob persistent + } -+ if (this.ticksSinceLastInteraction > this.level.purpurConfig.entityLifeSpan) { ++ if (this.ticksSinceLastInteraction > this.level().purpurConfig.entityLifeSpan) { + this.discard(); + } + } @@ -5300,7 +5354,7 @@ index 636e601b004a412d02e5be86e97d489b52c28e1b..8e2274f7dce34e0997356205cf96e46f @Override protected void playHurtSound(DamageSource source) { this.resetAmbientSoundTime(); -@@ -557,6 +580,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -560,6 +583,7 @@ public abstract class Mob extends LivingEntity implements Targeting { } nbt.putBoolean("Bukkit.Aware", this.aware); // CraftBukkit @@ -5308,7 +5362,7 @@ index 636e601b004a412d02e5be86e97d489b52c28e1b..8e2274f7dce34e0997356205cf96e46f } @Override -@@ -627,6 +651,11 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -630,6 +654,11 @@ public abstract class Mob extends LivingEntity implements Targeting { this.aware = nbt.getBoolean("Bukkit.Aware"); } // CraftBukkit end @@ -5320,94 +5374,94 @@ index 636e601b004a412d02e5be86e97d489b52c28e1b..8e2274f7dce34e0997356205cf96e46f } @Override -@@ -670,8 +699,8 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -673,8 +702,8 @@ public abstract class Mob extends LivingEntity implements Targeting { @Override public void aiStep() { super.aiStep(); -- this.level.getProfiler().push("looting"); -- if (!this.level.isClientSide && this.canPickUpLoot() && this.isAlive() && !this.dead && this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -+ //this.level.getProfiler().push("looting"); // Purpur -+ if (!this.level.isClientSide && this.canPickUpLoot() && this.isAlive() && !this.dead && (this.level.purpurConfig.entitiesPickUpLootBypassMobGriefing || this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { +- this.level().getProfiler().push("looting"); +- if (!this.level().isClientSide && this.canPickUpLoot() && this.isAlive() && !this.dead && this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ //this.level().getProfiler().push("looting"); // Purpur ++ if (!this.level().isClientSide && this.canPickUpLoot() && this.isAlive() && !this.dead && (this.level().purpurConfig.entitiesPickUpLootBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { Vec3i baseblockposition = this.getPickupReach(); - List list = this.level.getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate((double) baseblockposition.getX(), (double) baseblockposition.getY(), (double) baseblockposition.getZ())); + List list = this.level().getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate((double) baseblockposition.getX(), (double) baseblockposition.getY(), (double) baseblockposition.getZ())); Iterator iterator = list.iterator(); -@@ -690,7 +719,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -693,7 +722,7 @@ public abstract class Mob extends LivingEntity implements Targeting { } } -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur } protected Vec3i getPickupReach() { -@@ -902,46 +931,46 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -905,46 +934,46 @@ public abstract class Mob extends LivingEntity implements Targeting { return; } // Paper end -- this.level.getProfiler().push("sensing"); -+ //this.level.getProfiler().push("sensing"); // Purpur +- this.level().getProfiler().push("sensing"); ++ //this.level().getProfiler().push("sensing"); // Purpur this.sensing.tick(); -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur - int i = this.level.getServer().getTickCount() + this.getId(); +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur + int i = this.level().getServer().getTickCount() + this.getId(); if (i % 2 != 0 && this.tickCount > 1) { -- this.level.getProfiler().push("targetSelector"); -+ //this.level.getProfiler().push("targetSelector"); // Purpur +- this.level().getProfiler().push("targetSelector"); ++ //this.level().getProfiler().push("targetSelector"); // Purpur if (this.targetSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking this.targetSelector.tickRunningGoals(false); -- this.level.getProfiler().pop(); -- this.level.getProfiler().push("goalSelector"); -+ //this.level.getProfiler().pop(); // Purpur -+ //this.level.getProfiler().push("goalSelector"); // Purpur +- this.level().getProfiler().pop(); +- this.level().getProfiler().push("goalSelector"); ++ //this.level().getProfiler().pop(); // Purpur ++ //this.level().getProfiler().push("goalSelector"); // Purpur if (this.goalSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking this.goalSelector.tickRunningGoals(false); -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur } else { -- this.level.getProfiler().push("targetSelector"); -+ //this.level.getProfiler().push("targetSelector"); // Purpur +- this.level().getProfiler().push("targetSelector"); ++ //this.level().getProfiler().push("targetSelector"); if (this.targetSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking this.targetSelector.tick(); -- this.level.getProfiler().pop(); -- this.level.getProfiler().push("goalSelector"); -+ //this.level.getProfiler().pop(); // Purpur -+ //this.level.getProfiler().push("goalSelector"); // Purpur +- this.level().getProfiler().pop(); +- this.level().getProfiler().push("goalSelector"); ++ //this.level().getProfiler().pop(); // Purpur ++ //this.level().getProfiler().push("goalSelector"); // Purpur if (this.goalSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking this.goalSelector.tick(); -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur } -- this.level.getProfiler().push("navigation"); -+ //this.level.getProfiler().push("navigation"); // Purpur +- this.level().getProfiler().push("navigation"); ++ //this.level().getProfiler().push("navigation"); // Purpur this.navigation.tick(); -- this.level.getProfiler().pop(); -- this.level.getProfiler().push("mob tick"); -+ //this.level.getProfiler().pop(); // Purpur -+ //this.level.getProfiler().push("mob tick"); // Purpur +- this.level().getProfiler().pop(); +- this.level().getProfiler().push("mob tick"); ++ //this.level().getProfiler().pop(); // Purpur ++ //this.level().getProfiler().push("mob tick"); // Purpur this.customServerAiStep(); -- this.level.getProfiler().pop(); -- this.level.getProfiler().push("controls"); -- this.level.getProfiler().push("move"); -+ //this.level.getProfiler().pop(); // Purpur -+ //this.level.getProfiler().push("controls"); // Purpur -+ //this.level.getProfiler().push("move"); // Purpur +- this.level().getProfiler().pop(); +- this.level().getProfiler().push("controls"); +- this.level().getProfiler().push("move"); ++ //this.level().getProfiler().pop(); // Purpur ++ //this.level().getProfiler().push("controls"); // Purpur ++ //this.level().getProfiler().push("move"); // Purpur this.moveControl.tick(); -- this.level.getProfiler().popPush("look"); -+ //this.level.getProfiler().popPush("look"); // Purpur +- this.level().getProfiler().popPush("look"); ++ //this.level().getProfiler().popPush("look"); // Purpur this.lookControl.tick(); -- this.level.getProfiler().popPush("jump"); -+ //this.level.getProfiler().popPush("jump"); // Purpur +- this.level().getProfiler().popPush("jump"); ++ //this.level().getProfiler().popPush("jump"); // Purpur this.jumpControl.tick(); -- this.level.getProfiler().pop(); -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur -+ //this.level.getProfiler().pop(); // Purpur +- this.level().getProfiler().pop(); +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur ++ //this.level().getProfiler().pop(); // Purpur this.sendDebugPackets(); } -@@ -1163,6 +1192,12 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1166,6 +1195,12 @@ public abstract class Mob extends LivingEntity implements Targeting { } @@ -5420,7 +5474,7 @@ index 636e601b004a412d02e5be86e97d489b52c28e1b..8e2274f7dce34e0997356205cf96e46f @Nullable public static Item getEquipmentForSlot(EquipmentSlot equipmentSlot, int equipmentLevel) { switch (equipmentSlot) { -@@ -1257,7 +1292,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1260,7 +1295,7 @@ public abstract class Mob extends LivingEntity implements Targeting { 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)); @@ -5429,15 +5483,15 @@ index 636e601b004a412d02e5be86e97d489b52c28e1b..8e2274f7dce34e0997356205cf96e46f this.setLeftHanded(true); } else { this.setLeftHanded(false); -@@ -1305,6 +1340,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1308,6 +1343,7 @@ public abstract class Mob extends LivingEntity implements Targeting { 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 ++ 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 - drop leash variable org.bukkit.event.player.PlayerUnleashEntityEvent event = CraftEventFactory.callPlayerUnleashEntityEvent(this, player, hand, !player.getAbilities().instabuild); -@@ -1378,7 +1414,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1381,7 +1417,7 @@ public abstract class Mob extends LivingEntity implements Targeting { protected void onOffspringSpawnedFromEgg(Player player, Mob child) {} protected InteractionResult mobInteract(Player player, InteractionHand hand) { @@ -5446,7 +5500,7 @@ index 636e601b004a412d02e5be86e97d489b52c28e1b..8e2274f7dce34e0997356205cf96e46f } public boolean isWithinRestriction() { -@@ -1684,6 +1720,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1686,6 +1722,7 @@ public abstract class Mob extends LivingEntity implements Targeting { this.setLastHurtMob(target); } @@ -5454,33 +5508,33 @@ index 636e601b004a412d02e5be86e97d489b52c28e1b..8e2274f7dce34e0997356205cf96e46f return flag; } -@@ -1700,17 +1737,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1702,17 +1739,7 @@ public abstract class Mob extends LivingEntity implements Targeting { } public boolean isSunBurnTick() { -- if (this.level.isDay() && !this.level.isClientSide) { +- if (this.level().isDay() && !this.level().isClientSide) { - float f = this.getLightLevelDependentMagicValue(); - BlockPos blockposition = BlockPos.containing(this.getX(), this.getEyeY(), this.getZ()); - boolean flag = this.isInWaterRainOrBubble() || this.isInPowderSnow || this.wasInPowderSnow; - -- if (f > 0.5F && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && !flag && this.level.canSeeSky(blockposition)) { +- if (f > 0.5F && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && !flag && this.level().canSeeSky(blockposition)) { - return true; - } - } - - return false; -+ return super.isSunBurnTick(); // Purpur - moved contents to Entity ++ return super.isSunBurnTick(); } @Override -@@ -1754,4 +1781,56 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1759,4 +1786,56 @@ public abstract class Mob extends LivingEntity implements Targeting { return itemmonsteregg == null ? null : new ItemStack(itemmonsteregg); } + + // Purpur start + public double getMaxY() { -+ return level.getHeight(); ++ return level().getHeight(); + } + + public InteractionResult tryRide(Player player, InteractionHand hand) { @@ -5507,12 +5561,12 @@ index 636e601b004a412d02e5be86e97d489b52c28e1b..8e2274f7dce34e0997356205cf96e46f + if (tamable.isTame() && !tamable.isOwnedBy(player)) { + return InteractionResult.PASS; + } -+ if (!tamable.isTame() && !level.purpurConfig.untamedTamablesAreRidable) { ++ if (!tamable.isTame() && !level().purpurConfig.untamedTamablesAreRidable) { + return InteractionResult.PASS; + } + } + if (this instanceof AgeableMob ageable) { -+ if (ageable.isBaby() && !level.purpurConfig.babiesAreRidable) { ++ if (ageable.isBaby() && !level().purpurConfig.babiesAreRidable) { + return InteractionResult.PASS; + } + } @@ -5724,10 +5778,10 @@ index 57ef7fbba3028c28231abf7b7ae78aa019323536..651c156dc8a5aad04d461add02e22147 } 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 7ad71f2c139c2288b49d6b0fde3f8b8013f5e095..2dca8e45b9b1f5451db2734cba4c2b03c9dd303b 100644 +index d3a2a6dee2d83b3df0ddc521c080f7d72b709461..a1acc479c9d6a838e3180da3ac8a3a02d22db5c1 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 -@@ -34,17 +34,19 @@ public class HarvestFarmland extends Behavior { +@@ -40,17 +40,19 @@ public class HarvestFarmland extends Behavior { private long nextOkStartTime; private int timeWorkedSoFar; private final List validFarmlandAroundVillager = Lists.newArrayList(); @@ -5749,7 +5803,7 @@ index 7ad71f2c139c2288b49d6b0fde3f8b8013f5e095..2dca8e45b9b1f5451db2734cba4c2b03 BlockPos.MutableBlockPos blockposition_mutableblockposition = entity.blockPosition().mutable(); this.validFarmlandAroundVillager.clear(); -@@ -75,6 +77,7 @@ public class HarvestFarmland extends Behavior { +@@ -81,6 +83,7 @@ public class HarvestFarmland extends Behavior { Block block = iblockdata.getBlock(); Block block1 = world.getBlockState(pos.below()).getBlock(); @@ -5757,17 +5811,15 @@ index 7ad71f2c139c2288b49d6b0fde3f8b8013f5e095..2dca8e45b9b1f5451db2734cba4c2b03 return block instanceof CropBlock && ((CropBlock) block).isMaxAge(iblockdata) || iblockdata.isAir() && block1 instanceof FarmBlock; } -@@ -100,7 +103,7 @@ public class HarvestFarmland extends Behavior { +@@ -106,20 +109,20 @@ public class HarvestFarmland extends Behavior { Block block = iblockdata.getBlock(); Block block1 = world.getBlockState(this.aboveFarmlandPos.below()).getBlock(); - if (block instanceof CropBlock && ((CropBlock) block).isMaxAge(iblockdata)) { + if (block instanceof CropBlock && ((CropBlock) block).isMaxAge(iblockdata) && !this.clericWartFarmer || this.clericWartFarmer && block == Blocks.NETHER_WART && iblockdata.getValue(net.minecraft.world.level.block.NetherWartBlock.AGE) == 3) { // Purpur - // CraftBukkit start - if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, this.aboveFarmlandPos, Blocks.AIR.defaultBlockState()).isCancelled()) { - world.destroyBlock(this.aboveFarmlandPos, true, entity); -@@ -108,7 +111,7 @@ public class HarvestFarmland extends Behavior { - // CraftBukkit end + if (CraftEventFactory.callEntityChangeBlockEvent(entity, this.aboveFarmlandPos, iblockdata.getFluidState().createLegacyBlock())) { // CraftBukkit // Paper - fix wrong block state + world.destroyBlock(this.aboveFarmlandPos, true, entity); + } // CraftBukkit } - if (iblockdata.isAir() && block1 instanceof FarmBlock && entity.hasFarmSeeds()) { @@ -5775,20 +5827,15 @@ index 7ad71f2c139c2288b49d6b0fde3f8b8013f5e095..2dca8e45b9b1f5451db2734cba4c2b03 SimpleContainer inventorysubcontainer = entity.getInventory(); for (int j = 0; j < inventorysubcontainer.getContainerSize(); ++j) { -@@ -119,6 +122,12 @@ public class HarvestFarmland extends Behavior { - BlockState iblockdata1; + ItemStack itemstack = inventorysubcontainer.getItem(j); + boolean flag = false; - // CraftBukkit start -+ // Purpur start -+ if (this.clericWartFarmer && itemstack.getItem() == Items.NETHER_WART) { -+ iblockdata1 = Blocks.NETHER_WART.defaultBlockState(); -+ flag = true; -+ } else -+ // Purpur end - if (itemstack.is(Items.WHEAT_SEEDS)) { - iblockdata1 = Blocks.WHEAT.defaultBlockState(); - flag = true; -@@ -145,7 +154,7 @@ public class HarvestFarmland extends Behavior { +- if (!itemstack.isEmpty() && itemstack.is(ItemTags.VILLAGER_PLANTABLE_SEEDS)) { ++ if (!itemstack.isEmpty() && (itemstack.is(ItemTags.VILLAGER_PLANTABLE_SEEDS) || this.clericWartFarmer && itemstack.getItem() == net.minecraft.world.item.Items.NETHER_WART)) { + Item item = itemstack.getItem(); + + if (item instanceof BlockItem) { +@@ -135,7 +138,7 @@ public class HarvestFarmland extends Behavior { } if (flag) { @@ -5798,7 +5845,7 @@ index 7ad71f2c139c2288b49d6b0fde3f8b8013f5e095..2dca8e45b9b1f5451db2734cba4c2b03 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 c3fb86dc3d94d3a0d2464f2dbb83cda2fb9f7bbe..fd77dd0c0bfaba57e5bdfd13f7a90241ecdf813a 100644 +index 42ae4d293a420f0b8eb476df6389b2e7a693895f..97c20c5b89e6d7e4ed844eff39ee55dfa8988d37 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 { @@ -5806,7 +5853,7 @@ index c3fb86dc3d94d3a0d2464f2dbb83cda2fb9f7bbe..fd77dd0c0bfaba57e5bdfd13f7a90241 if (iblockdata.is(BlockTags.WOODEN_DOORS, (blockbase_blockdata) -> { return blockbase_blockdata.getBlock() instanceof DoorBlock; - })) { -+ }) && !DoorBlock.requiresRedstone(entityliving.level, iblockdata, blockposition)) { // Purpur ++ }) && !DoorBlock.requiresRedstone(entityliving.level(), iblockdata, blockposition)) { // Purpur DoorBlock blockdoor = (DoorBlock) iblockdata.getBlock(); if (!blockdoor.isOpen(iblockdata)) { @@ -5815,7 +5862,7 @@ index c3fb86dc3d94d3a0d2464f2dbb83cda2fb9f7bbe..fd77dd0c0bfaba57e5bdfd13f7a90241 if (iblockdata1.is(BlockTags.WOODEN_DOORS, (blockbase_blockdata) -> { return blockbase_blockdata.getBlock() instanceof DoorBlock; - })) { -+ }) && !DoorBlock.requiresRedstone(entityliving.level, iblockdata, blockposition1)) { // Purpur ++ }) && !DoorBlock.requiresRedstone(entityliving.level(), iblockdata, blockposition1)) { // Purpur DoorBlock blockdoor1 = (DoorBlock) iblockdata1.getBlock(); if (!blockdoor1.isOpen(iblockdata1)) { @@ -5824,19 +5871,19 @@ index c3fb86dc3d94d3a0d2464f2dbb83cda2fb9f7bbe..fd77dd0c0bfaba57e5bdfd13f7a90241 if (!iblockdata.is(BlockTags.WOODEN_DOORS, (blockbase_blockdata) -> { return blockbase_blockdata.getBlock() instanceof DoorBlock; - })) { -+ }) || DoorBlock.requiresRedstone(entity.level, iblockdata, blockposition)) { // Purpur ++ }) || DoorBlock.requiresRedstone(entity.level(), iblockdata, blockposition)) { // Purpur iterator.remove(); } else { DoorBlock blockdoor = (DoorBlock) iblockdata.getBlock(); diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/ShowTradesToPlayer.java b/src/main/java/net/minecraft/world/entity/ai/behavior/ShowTradesToPlayer.java -index 98373e013748817209b811d4adbb40a8787242a6..567b501f4de7556e55e2418d2f5700b4e4265235 100644 +index 050be72c815010bf3f4b72427e2052b00420e8ee..8a213205f57c8dcd2226d7194d74b1b13dec5a78 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/ShowTradesToPlayer.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/ShowTradesToPlayer.java @@ -42,6 +42,7 @@ public class ShowTradesToPlayer extends Behavior { @Override public boolean canStillUse(ServerLevel world, Villager entity, long time) { -+ if (!entity.level.purpurConfig.villagerDisplayTradeItem) return false; // Purpur ++ if (!entity.level().purpurConfig.villagerDisplayTradeItem) return false; // Purpur return this.checkExtraStartConditions(world, entity) && this.lookTime > 0 && entity.getBrain().getMemory(MemoryModuleType.INTERACTION_TARGET).isPresent(); } @@ -5877,24 +5924,24 @@ index cd7a90ec1073b2b452ca70decefe6a594445003b..47672e48c1cae73cffe532d622b29634 } 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 0951c04533e7c39b969d041271684355770b53c2..02d4ba2ccdce99ca97614baa7c8e49213126af96 100644 +index 645d204fe2c727637a6a547aad7d4db1279628ae..8be2f612c9e8a64b0aad6bb54450cdfb12b3c19e 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 -@@ -123,8 +123,10 @@ public class VillagerMakeLove extends Behavior { +@@ -127,8 +127,10 @@ public class VillagerMakeLove extends Behavior { return Optional.empty(); } - // CraftBukkit end + // Move age setting down - parent.setAge(6000); - partner.setAge(6000); + // Purpur start + parent.setAge(world.purpurConfig.villagerBreedingTicks); + partner.setAge(world.purpurConfig.villagerBreedingTicks); + // Purpur end - world.addFreshEntityWithPassengers(entityvillager2, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); // CraftBukkit - added SpawnReason + world.addFreshEntityWithPassengers(entityvillager2, CreatureSpawnEvent.SpawnReason.BREEDING); + // CraftBukkit end world.broadcastEntityEvent(entityvillager2, (byte) 12); - return Optional.of(entityvillager2); 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 3d7586142aa5116964e4fffc6198f55fc6da324b..b4fb0af5bffffb9f0de3a2452c22b09fe92d7129 100644 +index 03d77c6d4697d4934ca65e3329982f0efe089820..ce7e3e90993b76225dc820a21e04267e488f5f7b 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 { @@ -5919,7 +5966,7 @@ index 3d7586142aa5116964e4fffc6198f55fc6da324b..b4fb0af5bffffb9f0de3a2452c22b09f return this.operation == MoveControl.Operation.MOVE_TO; } diff --git a/src/main/java/net/minecraft/world/entity/ai/control/SmoothSwimmingLookControl.java b/src/main/java/net/minecraft/world/entity/ai/control/SmoothSwimmingLookControl.java -index 7df56705a4a0de2dc4ff7ab133fc26612c219162..60d21d6171b9af20a4c6fcc0d564a31aaa4ecdba 100644 +index 7df56705a4a0de2dc4ff7ab133fc26612c219162..384bed4505b6cabb1ae151cd2c4eb5e56f24563f 100644 --- a/src/main/java/net/minecraft/world/entity/ai/control/SmoothSwimmingLookControl.java +++ b/src/main/java/net/minecraft/world/entity/ai/control/SmoothSwimmingLookControl.java @@ -3,7 +3,7 @@ package net.minecraft.world.entity.ai.control; @@ -5940,63 +5987,38 @@ index 7df56705a4a0de2dc4ff7ab133fc26612c219162..60d21d6171b9af20a4c6fcc0d564a31a if (this.lookAtCooldown > 0) { --this.lookAtCooldown; this.getYRotD().ifPresent((yaw) -> { -@@ -32,9 +32,9 @@ public class SmoothSwimmingLookControl extends LookControl { - } - - float f = Mth.wrapDegrees(this.mob.yHeadRot - this.mob.yBodyRot); -- if (f < (float)(-this.maxYRotFromCenter)) { -+ if (f < (float) (-this.maxYRotFromCenter)) { - this.mob.yBodyRot -= 4.0F; -- } else if (f > (float)this.maxYRotFromCenter) { -+ } else if (f > (float) this.maxYRotFromCenter) { - this.mob.yBodyRot += 4.0F; - } - diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java -index 529435cf648d61f80a37f041cee3c6fc0b74ceb6..6c7195c93b5968845da35450e80022c70839487d 100644 +index a85885ee51df585fa11ae9f8fcd67ff2a71c5a18..d81509e08e70ec5b2f837c9dc66b1254c86854e4 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java @@ -32,7 +32,7 @@ public class BreakDoorGoal extends DoorInteractGoal { @Override public boolean canUse() { -- return !super.canUse() ? false : (!this.mob.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) ? false : this.isValidDifficulty(this.mob.level.getDifficulty()) && !this.isOpen()); -+ return !super.canUse() ? false : ((!this.mob.level.purpurConfig.zombieBypassMobGriefing && !this.mob.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) ? false : this.isValidDifficulty(this.mob.level.getDifficulty()) && !this.isOpen()); // Purpur +- return !super.canUse() ? false : (!this.mob.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) ? false : this.isValidDifficulty(this.mob.level().getDifficulty()) && !this.isOpen()); ++ return !super.canUse() ? false : ((!this.mob.level().purpurConfig.zombieBypassMobGriefing && !this.mob.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) ? false : this.isValidDifficulty(this.mob.level().getDifficulty()) && !this.isOpen()); // Purpur } @Override diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java -index 80aa539f7c6a6ee44338de084cdcdf5fb4ef996a..c55118a4d2237a33039b63dc797ccdb86b63344f 100644 +index 93bbda61f0eb2dd52573602b1f9cc7b031d1fc5a..63f9e5e2490e5b2fec6f2395077e21e601804ca5 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java -@@ -31,6 +31,12 @@ public class EatBlockGoal extends Goal { +@@ -74,7 +74,7 @@ public class EatBlockGoal extends Goal { - @Override - public boolean canUse() { -+ // Purpur start -+ net.minecraft.world.level.chunk.LevelChunk chunk = this.mob.level.getChunkIfLoaded(this.mob.blockPosition()); -+ if (chunk == null || chunk.playerChunk == null || !((net.minecraft.server.level.ServerLevel) this.mob.level).getChunkSource().chunkMap.anyPlayerCloseEnoughForSpawning(chunk.playerChunk, this.mob.chunkPosition(), false)) { -+ return false; -+ } -+ // Purpur end - if (this.mob.getRandom().nextInt(this.mob.isBaby() ? 50 : 1000) != 0) { - return false; - } else { -@@ -69,7 +75,7 @@ public class EatBlockGoal extends Goal { - - if (EatBlockGoal.IS_TALL_GRASS.test(this.level.getBlockState(blockposition))) { - // CraftBukkit -- if (!CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition, Blocks.AIR.defaultBlockState(), !this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)).isCancelled()) { -+ if (!CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition, Blocks.AIR.defaultBlockState(), !this.level.purpurConfig.sheepBypassMobGriefing && !this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)).isCancelled()) { // Purpur + final BlockState blockState = this.level.getBlockState(blockposition); // Paper - fix wrong block state + if (EatBlockGoal.IS_TALL_GRASS.test(blockState)) { // Paper - fix wrong block state +- if (CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition, blockState.getFluidState().createLegacyBlock(), !this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Paper - fix wrong block state ++ if (CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition, blockState.getFluidState().createLegacyBlock(), !this.level.purpurConfig.sheepBypassMobGriefing && !this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Paper - fix wrong block state // Purpur this.level.destroyBlock(blockposition, false); } -@@ -79,7 +85,7 @@ public class EatBlockGoal extends Goal { +@@ -83,7 +83,7 @@ public class EatBlockGoal extends Goal { + BlockPos blockposition1 = blockposition.below(); if (this.level.getBlockState(blockposition1).is(Blocks.GRASS_BLOCK)) { - // CraftBukkit -- if (!CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition1, Blocks.DIRT.defaultBlockState(), !this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)).isCancelled()) { // Paper - Fix wrong block state -+ if (!CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition1, Blocks.DIRT.defaultBlockState(), !this.level.purpurConfig.sheepBypassMobGriefing && !this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)).isCancelled()) { // Paper - Fix wrong block state // Purpur +- if (CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition1, Blocks.DIRT.defaultBlockState(), !this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Paper - Fix wrong block state ++ if (CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition1, Blocks.DIRT.defaultBlockState(), !this.level.purpurConfig.sheepBypassMobGriefing && !this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Paper - Fix wrong block state // Purpur this.level.levelEvent(2001, blockposition1, Block.getId(Blocks.GRASS_BLOCK.defaultBlockState())); this.level.setBlock(blockposition1, Blocks.DIRT.defaultBlockState(), 2); } @@ -6053,16 +6075,16 @@ index 1635818fc4b1788c0d397085239df6dd75b210ab..02978315bc2b828cc603ce7478408f3f public Set getAvailableGoals() { diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/LlamaFollowCaravanGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/LlamaFollowCaravanGoal.java -index 721971f7618751a2e95f1c49fdc48a9c0c672cab..ad30f2d678cfc4b0d693e84e6e152c63b1b3cbb8 100644 +index 21725aee29e9120d1c7e1e19f91c21a73a28844f..3fc9528201fb96d6a0f905afe0b6a82ec88a7235 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/LlamaFollowCaravanGoal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/LlamaFollowCaravanGoal.java @@ -22,6 +22,7 @@ public class LlamaFollowCaravanGoal extends Goal { @Override public boolean canUse() { -+ if (!this.llama.level.purpurConfig.llamaJoinCaravans || !this.llama.shouldJoinCaravan) return false; // Purpur ++ if (!this.llama.level().purpurConfig.llamaJoinCaravans || !this.llama.shouldJoinCaravan) return false; // Purpur if (!this.llama.isLeashed() && !this.llama.inCaravan()) { - List list = this.llama.level.getEntities(this.llama, this.llama.getBoundingBox().inflate(9.0D, 4.0D, 9.0D), (entity) -> { + List list = this.llama.level().getEntities(this.llama, this.llama.getBoundingBox().inflate(9.0D, 4.0D, 9.0D), (entity) -> { EntityType entityType = entity.getType(); @@ -71,6 +72,7 @@ public class LlamaFollowCaravanGoal extends Goal { @@ -6073,12 +6095,12 @@ index 721971f7618751a2e95f1c49fdc48a9c0c672cab..ad30f2d678cfc4b0d693e84e6e152c63 double d = this.llama.distanceToSqr(this.llama.getCaravanHead()); if (d > 676.0D) { diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/RangedBowAttackGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/RangedBowAttackGoal.java -index 6558b0d4bea99948fdc2b51751f3cfdc239d4b67..d85dabebbbbe213e791b8a3be3c6df05b959e40c 100644 +index 87fb10096fc9dade33c663234b1cecc34d3d77bb..874c7b29a261b1b5ad6e86ca219ff935870aecb0 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/RangedBowAttackGoal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/RangedBowAttackGoal.java -@@ -111,9 +111,9 @@ public class RangedBowAttackGoal extends Go +@@ -119,9 +119,9 @@ public class RangedBowAttackGoal extends Go + } - this.mob.getMoveControl().strafe(this.strafingBackwards ? -0.5F : 0.5F, this.strafingClockwise ? 0.5F : -0.5F); this.mob.lookAt(livingEntity, 30.0F, 30.0F); - } else { + } //else { // Purpur - fix MC-121706 @@ -6089,33 +6111,33 @@ index 6558b0d4bea99948fdc2b51751f3cfdc239d4b67..d85dabebbbbe213e791b8a3be3c6df05 if (this.mob.isUsingItem()) { if (!bl && this.seeTime < -60) { 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 d3e91faee8805e88d850740fb5de9e5c8288c48b..fe526ebf395ff9813b94284fc3f0142323d6a303 100644 +index 509317a26c79f453335df1c19dc4c9ec570046af..8e4d673e4f2d7f50ea5ed13794da08b1d20e6665 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 { @Override public boolean canUse() { -- if (!this.removerMob.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -+ if (!this.removerMob.level.purpurConfig.zombieBypassMobGriefing && !this.removerMob.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur +- if (!this.removerMob.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ if (!this.removerMob.level().purpurConfig.zombieBypassMobGriefing && !this.removerMob.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur return false; } 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 5c64905e90ccca6e0b347241ddf9cc3f71058b8e..3bd7521b131b2b40f807bdc7ab95e64cf9bcdadc 100644 +index 7fc5b5d624b61a3de9c71e975b51d20c5800be00..8fb070b1ae11d34b2fa420ded58097d421263cab 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 -@@ -63,7 +63,7 @@ public class RunAroundLikeCrazyGoal extends Goal { +@@ -66,7 +66,7 @@ public class RunAroundLikeCrazyGoal extends Goal { + int i = this.horse.getTemper(); int j = this.horse.getMaxTemper(); - // CraftBukkit - fire EntityTameEvent -- if (j > 0 && this.horse.getRandom().nextInt(j) < i && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this.horse, ((org.bukkit.craftbukkit.entity.CraftHumanEntity) this.horse.getBukkitEntity().getPassenger()).getHandle()).isCancelled()) { -+ if ((this.horse.level.purpurConfig.alwaysTameInCreative && ((Player) entity).getAbilities().instabuild) || (j > 0 && this.horse.getRandom().nextInt(j) < i && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this.horse, ((org.bukkit.craftbukkit.entity.CraftHumanEntity) this.horse.getBukkitEntity().getPassenger()).getHandle()).isCancelled())) { // Purpur +- 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 this.horse.tameWithName((Player) entity); return; } diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/SwellGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/SwellGoal.java -index e241ae250f4f04a17ef2c583d00b065a4ca56a4c..02b567e4e808e1a809d285ef39e1abc54e1e6ad2 100644 +index e241ae250f4f04a17ef2c583d00b065a4ca56a4c..7b99c3446b50939241d3e220d93e05649f72a6df 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/SwellGoal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/SwellGoal.java @@ -54,6 +54,14 @@ public class SwellGoal extends Goal { @@ -6123,7 +6145,7 @@ index e241ae250f4f04a17ef2c583d00b065a4ca56a4c..02b567e4e808e1a809d285ef39e1abc5 } else { this.creeper.setSwellDir(1); + // Purpur start -+ if (this.creeper.getLevel().purpurConfig.creeperEncircleTarget) { ++ if (this.creeper.level().purpurConfig.creeperEncircleTarget) { + net.minecraft.world.phys.Vec3 relative = this.creeper.position().subtract(this.target.position()); + relative = relative.yRot((float) Math.PI / 3).normalize().multiply(2, 2, 2); + net.minecraft.world.phys.Vec3 destination = this.target.position().add(relative); @@ -6134,7 +6156,7 @@ index e241ae250f4f04a17ef2c583d00b065a4ca56a4c..02b567e4e808e1a809d285ef39e1abc5 } } 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 79bb13c5614bab1f0749c5f8f57f762c6216c564..2cbc9adc8e417def48be03d08174a5833068ec65 100644 +index 0d9b194781d152e842c9a4b8d6f23d307b2e4452..00cf59524477ec79d4354cc403fc3e75a63b81a0 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 { @@ -6147,7 +6169,7 @@ index 79bb13c5614bab1f0749c5f8f57f762c6216c564..2cbc9adc8e417def48be03d08174a583 @Override diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java -index 7ffe5bef3778d5971ea4ceadf3102725fd0d08cd..6d127ed3da899851ca95b2be6792e2abca1aca12 100644 +index b376670d11088e524ce246f667e580e90cd119a3..fdb08ecc19bc4a1bc93cf6b18adcea2bc5573965 100644 --- a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java @@ -172,12 +172,12 @@ public abstract class PathNavigation { @@ -6193,18 +6215,18 @@ index cb1d91f9fe98f21c2afbe3894dfd9bca3bdd3ba6..d2703432af207c74ea8d298a784329c3 brain.setMemory(MemoryModuleType.SECONDARY_JOB_SITE, list); } else { diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/Sensing.java b/src/main/java/net/minecraft/world/entity/ai/sensing/Sensing.java -index 288c6627906d07c0d223eacd84ae4eb31a349998..9babe636176da3c40598eb5bdac0919a1704eaa0 100644 +index 51772f03a3469b11e7166ec6f3a1b9c64a606221..02f2f46ccc48bb4d9bd08555818b0489f60d9f13 100644 --- a/src/main/java/net/minecraft/world/entity/ai/sensing/Sensing.java +++ b/src/main/java/net/minecraft/world/entity/ai/sensing/Sensing.java @@ -26,9 +26,9 @@ public class Sensing { } else if (this.unseen.contains(i)) { return false; } else { -- this.mob.level.getProfiler().push("hasLineOfSight"); -+ //this.mob.level.getProfiler().push("hasLineOfSight"); // Purpur +- this.mob.level().getProfiler().push("hasLineOfSight"); ++ //this.mob.level().getProfiler().push("hasLineOfSight"); // Purpur boolean bl = this.mob.hasLineOfSight(entity); -- this.mob.level.getProfiler().pop(); -+ //this.mob.level.getProfiler().pop(); // Purpur +- this.mob.level().getProfiler().pop(); ++ //this.mob.level().getProfiler().pop(); // Purpur if (bl) { this.seen.add(i); } else { @@ -6226,7 +6248,7 @@ index fcdb9bde8e1605e30dde3e580491522d4b62cdc0..7094701d213c73ba47ace806962244c1 } diff --git a/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java b/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java -index e752c83df50fb9b670ecea2abc95426c2a009b6f..baa4f9026d31de92210300ecb8ee8c1b6d575435 100644 +index d25307ae8bbdf10ae067ec70fc2cb957b852a0eb..54bdb81785b617e13e67530752395f2a0c6d703a 100644 --- a/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java +++ b/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java @@ -64,6 +64,10 @@ public class TargetingConditions { @@ -6234,14 +6256,14 @@ index e752c83df50fb9b670ecea2abc95426c2a009b6f..baa4f9026d31de92210300ecb8ee8c1b } else if (this.selector != null && !this.selector.test(targetEntity)) { return false; + // Purpur start -+ } else if (!targetEntity.level.purpurConfig.idleTimeoutTargetPlayer && targetEntity instanceof net.minecraft.server.level.ServerPlayer player && player.isAfk()) { ++ } else if (!targetEntity.level().purpurConfig.idleTimeoutTargetPlayer && targetEntity instanceof net.minecraft.server.level.ServerPlayer player && player.isAfk()) { + return false; + // Purpur end } else { if (baseEntity == null) { - if (this.isCombat && (!targetEntity.canBeSeenAsEnemy() || targetEntity.level.getDifficulty() == Difficulty.PEACEFUL)) { + 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 59338d739b6130f667d151bc27646c4a346886a2..bfa1b84cba0dface99fcd3cf573be49f6f1f7d55 100644 +index 2c91fe46355c9a201507de5577f693ed4f5fb974..1eab1393a2636c4a247f25dae317cea60cc7021c 100644 --- a/src/main/java/net/minecraft/world/entity/ambient/Bat.java +++ b/src/main/java/net/minecraft/world/entity/ambient/Bat.java @@ -18,6 +18,7 @@ import net.minecraft.world.entity.EntityDimensions; @@ -6252,7 +6274,7 @@ index 59338d739b6130f667d151bc27646c4a346886a2..bfa1b84cba0dface99fcd3cf573be49f import net.minecraft.world.entity.Pose; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; -@@ -41,12 +42,81 @@ public class Bat extends AmbientCreature { +@@ -43,12 +44,59 @@ public class Bat extends AmbientCreature { public Bat(EntityType type, Level world) { super(type, world); @@ -6269,22 +6291,22 @@ index 59338d739b6130f667d151bc27646c4a346886a2..bfa1b84cba0dface99fcd3cf573be49f + + @Override + public boolean isRidable() { -+ return level.purpurConfig.batRidable; ++ return level().purpurConfig.batRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.batRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.batRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.batControllable; ++ return level().purpurConfig.batControllable; + } + + @Override + public double getMaxY() { -+ return level.purpurConfig.batMaxY; ++ return level().purpurConfig.batMaxY; + } + + @Override @@ -6292,7 +6314,7 @@ index 59338d739b6130f667d151bc27646c4a346886a2..bfa1b84cba0dface99fcd3cf573be49f + super.onMount(rider); + if (isResting()) { + setResting(false); -+ level.levelEvent(null, 1025, new BlockPos(this).above(), 0); ++ level().levelEvent(null, 1025, new BlockPos(this).above(), 0); + } + } + @@ -6307,34 +6329,12 @@ index 59338d739b6130f667d151bc27646c4a346886a2..bfa1b84cba0dface99fcd3cf573be49f + setDeltaMovement(mot.scale(0.9D)); + } + } -+ -+ @Override -+ public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.batMaxHealth); -+ this.getAttribute(Attributes.FOLLOW_RANGE).setBaseValue(this.level.purpurConfig.batFollowRange); -+ this.getAttribute(Attributes.KNOCKBACK_RESISTANCE).setBaseValue(this.level.purpurConfig.batKnockbackResistance); -+ this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(this.level.purpurConfig.batMovementSpeed); -+ this.getAttribute(Attributes.FLYING_SPEED).setBaseValue(this.level.purpurConfig.batFlyingSpeed); -+ this.getAttribute(Attributes.ARMOR).setBaseValue(this.level.purpurConfig.batArmor); -+ this.getAttribute(Attributes.ARMOR_TOUGHNESS).setBaseValue(this.level.purpurConfig.batArmorToughness); -+ this.getAttribute(Attributes.ATTACK_KNOCKBACK).setBaseValue(this.level.purpurConfig.batAttackKnockback); -+ } -+ -+ @Override -+ public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.batTakeDamageFromWater; -+ } -+ -+ @Override -+ protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.batAlwaysDropExp; -+ } + // Purpur end + @Override public boolean isFlapping() { return !this.isResting() && this.tickCount % Bat.TICKS_PER_FLAP == 0; -@@ -96,7 +166,7 @@ public class Bat extends AmbientCreature { +@@ -98,7 +146,7 @@ public class Bat extends AmbientCreature { protected void pushEntities() {} public static AttributeSupplier.Builder createAttributes() { @@ -6343,7 +6343,7 @@ index 59338d739b6130f667d151bc27646c4a346886a2..bfa1b84cba0dface99fcd3cf573be49f } public boolean isResting() { -@@ -128,6 +198,14 @@ public class Bat extends AmbientCreature { +@@ -130,6 +178,14 @@ public class Bat extends AmbientCreature { @Override protected void customServerAiStep() { @@ -6358,7 +6358,36 @@ index 59338d739b6130f667d151bc27646c4a346886a2..bfa1b84cba0dface99fcd3cf573be49f super.customServerAiStep(); BlockPos blockposition = this.blockPosition(); BlockPos blockposition1 = blockposition.above(); -@@ -241,7 +319,7 @@ public class Bat extends AmbientCreature { +@@ -208,6 +264,28 @@ public class Bat extends AmbientCreature { + } + } + ++ @Override ++ public void initAttributes() { ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.batMaxHealth); ++ this.getAttribute(Attributes.FOLLOW_RANGE).setBaseValue(this.level().purpurConfig.batFollowRange); ++ this.getAttribute(Attributes.KNOCKBACK_RESISTANCE).setBaseValue(this.level().purpurConfig.batKnockbackResistance); ++ this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(this.level().purpurConfig.batMovementSpeed); ++ this.getAttribute(Attributes.FLYING_SPEED).setBaseValue(this.level().purpurConfig.batFlyingSpeed); ++ this.getAttribute(Attributes.ARMOR).setBaseValue(this.level().purpurConfig.batArmor); ++ this.getAttribute(Attributes.ARMOR_TOUGHNESS).setBaseValue(this.level().purpurConfig.batArmorToughness); ++ this.getAttribute(Attributes.ATTACK_KNOCKBACK).setBaseValue(this.level().purpurConfig.batAttackKnockback); ++ } ++ ++ @Override ++ public boolean isSensitiveToWater() { ++ return this.level().purpurConfig.batTakeDamageFromWater; ++ } ++ ++ @Override ++ protected boolean isAlwaysExperienceDropper() { ++ return this.level().purpurConfig.batAlwaysDropExp; ++ } ++ + @Override + public void readAdditionalSaveData(CompoundTag nbt) { + super.readAdditionalSaveData(nbt); +@@ -227,7 +305,7 @@ public class Bat extends AmbientCreature { int i = world.getMaxLocalRawBrightness(pos); byte b0 = 4; @@ -6367,7 +6396,7 @@ index 59338d739b6130f667d151bc27646c4a346886a2..bfa1b84cba0dface99fcd3cf573be49f b0 = 7; } else if (random.nextBoolean()) { return false; -@@ -255,6 +333,7 @@ public class Bat extends AmbientCreature { +@@ -241,6 +319,7 @@ public class Bat extends AmbientCreature { private static boolean isSpookySeason = false; private static final int ONE_HOUR = 20 * 60 * 60; private static int lastSpookyCheck = -ONE_HOUR; @@ -6376,7 +6405,7 @@ index 59338d739b6130f667d151bc27646c4a346886a2..bfa1b84cba0dface99fcd3cf573be49f if (net.minecraft.server.MinecraftServer.currentTick - lastSpookyCheck > ONE_HOUR) { LocalDate localdate = LocalDate.now(); 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 1f85f34c1e50f34fb270d2fac7d307c82a550bfa..324f52edd95b5f9a498e46def8c14435cfd00abb 100644 +index 2249fc6dd98afb8d52623b5864955fdd3b3fc042..2ccfaab0a02cf5ff9779e250fb79a75a9852e10d 100644 --- a/src/main/java/net/minecraft/world/entity/animal/AbstractFish.java +++ b/src/main/java/net/minecraft/world/entity/animal/AbstractFish.java @@ -94,7 +94,7 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable { @@ -6432,10 +6461,10 @@ index 1f85f34c1e50f34fb270d2fac7d307c82a550bfa..324f52edd95b5f9a498e46def8c14435 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 3c4d142e982c34a23bdb5da1f51c8dcacc0532c1..2ac88f06ebb79e515cd9934ac1e3e2c8003d9e3c 100644 +index c2f61ed153260692c96af4f20bc5b7d55cbbc380..8773b1072016a3bbf025959e9ab827704ec17fc6 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Animal.java +++ b/src/main/java/net/minecraft/world/entity/animal/Animal.java -@@ -39,6 +39,7 @@ public abstract class Animal extends AgeableMob { +@@ -42,6 +42,7 @@ public abstract class Animal extends AgeableMob { @Nullable public UUID loveCause; public ItemStack breedItem; // CraftBukkit - Add breedItem variable @@ -6443,45 +6472,54 @@ index 3c4d142e982c34a23bdb5da1f51c8dcacc0532c1..2ac88f06ebb79e515cd9934ac1e3e2c8 protected Animal(EntityType type, Level world) { super(type, world); -@@ -150,7 +151,7 @@ public abstract class Animal extends AgeableMob { +@@ -154,7 +155,7 @@ public abstract class Animal extends AgeableMob { if (this.isFood(itemstack)) { int i = this.getAge(); -- if (!this.level.isClientSide && i == 0 && this.canFallInLove()) { -+ if (!this.level.isClientSide && i == 0 && this.canFallInLove() && (this.level.purpurConfig.animalBreedingCooldownSeconds <= 0 || !this.level.hasBreedingCooldown(player.getUUID(), this.getClass()))) { // Purpur +- if (!this.level().isClientSide && i == 0 && this.canFallInLove()) { ++ if (!this.level().isClientSide && i == 0 && this.canFallInLove() && (this.level().purpurConfig.animalBreedingCooldownSeconds <= 0 || !this.level().hasBreedingCooldown(player.getUUID(), this.getClass()))) { // Purpur this.usePlayerItem(player, hand, itemstack); this.setInLove(player); return InteractionResult.SUCCESS; -@@ -237,6 +238,14 @@ public abstract class Animal extends AgeableMob { - if (entityplayer == null && other.getLoveCause() != null) { - entityplayer = other.getLoveCause(); - } +@@ -236,12 +237,20 @@ public abstract class Animal extends AgeableMob { + AgeableMob entityageable = this.getBreedOffspring(world, other); + + if (entityageable != null) { +- entityageable.setBaby(true); +- entityageable.moveTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F); +- // CraftBukkit start - call EntityBreedEvent + // Purpur start -+ if (entityplayer != null && world.purpurConfig.animalBreedingCooldownSeconds > 0) { -+ if (world.hasBreedingCooldown(entityplayer.getUUID(), this.getClass())) { + ServerPlayer breeder = Optional.ofNullable(this.getLoveCause()).or(() -> { + return Optional.ofNullable(other.getLoveCause()); + }).orElse(null); ++ if (breeder != null && world.purpurConfig.animalBreedingCooldownSeconds > 0) { ++ if (world.hasBreedingCooldown(breeder.getUUID(), this.getClass())) { + return; + } -+ world.addBreedingCooldown(entityplayer.getUUID(), this.getClass()); ++ world.addBreedingCooldown(breeder.getUUID(), this.getClass()); + } ++ entityageable.setBaby(true); ++ entityageable.moveTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F); ++ // CraftBukkit start - call EntityBreedEvent + // Purpur end - // CraftBukkit start - call EntityBreedEvent - entityageable.setBaby(true); - entityageable.moveTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F); -@@ -253,8 +262,10 @@ public abstract class Animal extends AgeableMob { - CriteriaTriggers.BRED_ANIMALS.trigger(entityplayer, this, other, entityageable); - } - -- this.setAge(6000); -- other.setAge(6000); -+ // Purpur start -+ this.setAge(this.getPurpurBreedTime()); -+ other.setAge(other.getPurpurBreedTime()); -+ // Purpur end - this.resetLove(); - other.resetLove(); - world.addFreshEntityWithPassengers(entityageable, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); // CraftBukkit - added SpawnReason + 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()) { +@@ -269,8 +278,10 @@ public abstract class Animal extends AgeableMob { + entityplayer.awardStat(Stats.ANIMALS_BRED); + CriteriaTriggers.BRED_ANIMALS.trigger(entityplayer, this, entityanimal, entityageable); + } // Paper +- this.setAge(6000); +- entityanimal.setAge(6000); ++ // Purpur start ++ this.setAge(this.getPurpurBreedTime()); ++ entityanimal.setAge(entityanimal.getPurpurBreedTime()); ++ // Purpur end + this.resetLove(); + 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 c33e5c51839c8e6ec04c1b302127d2bf0f48664c..d47dc0c3fe8c2b80d7b7eb828a12af6eb32145e4 100644 +index 55026e1731e41b4e3e4c6a8fef5d96a32051a556..6c04c8e7776b2830ac368229da834532e8ce163e 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; @@ -6492,7 +6530,7 @@ index c33e5c51839c8e6ec04c1b302127d2bf0f48664c..d47dc0c3fe8c2b80d7b7eb828a12af6e import net.minecraft.world.entity.NeutralMob; import net.minecraft.world.entity.PathfinderMob; import net.minecraft.world.entity.Pose; -@@ -143,6 +144,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -147,6 +148,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { public Bee(EntityType type, Level world) { super(type, world); this.remainingCooldownBeforeLocatingNewFlower = Mth.nextInt(this.random, 20, 60); @@ -6500,7 +6538,7 @@ index c33e5c51839c8e6ec04c1b302127d2bf0f48664c..d47dc0c3fe8c2b80d7b7eb828a12af6e // Paper start - apply gravity to bees when they get stuck in the void, fixes MC-167279 class BeeFlyingMoveControl extends FlyingMoveControl { public BeeFlyingMoveControl(final Mob entity, final int maxPitchChange, final boolean noGravity) { -@@ -151,22 +153,89 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -155,22 +157,69 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { @Override public void tick() { @@ -6510,7 +6548,7 @@ index c33e5c51839c8e6ec04c1b302127d2bf0f48664c..d47dc0c3fe8c2b80d7b7eb828a12af6e + return; + } + // Purpur end - if (this.mob.getY() <= Bee.this.level.getMinBuildHeight()) { + if (this.mob.getY() <= Bee.this.level().getMinBuildHeight()) { this.mob.setNoGravity(false); } super.tick(); @@ -6537,22 +6575,22 @@ index c33e5c51839c8e6ec04c1b302127d2bf0f48664c..d47dc0c3fe8c2b80d7b7eb828a12af6e + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.beeRidable; ++ return level().purpurConfig.beeRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.beeRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.beeRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.beeControllable; ++ return level().purpurConfig.beeControllable; + } + + @Override + public double getMaxY() { -+ return level.purpurConfig.beeMaxY; ++ return level().purpurConfig.beeMaxY; + } + + @Override @@ -6566,32 +6604,12 @@ index c33e5c51839c8e6ec04c1b302127d2bf0f48664c..d47dc0c3fe8c2b80d7b7eb828a12af6e + setDeltaMovement(mot.scale(0.9D)); + } + } -+ -+ @Override -+ public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.beeMaxHealth); -+ } -+ -+ @Override -+ public int getPurpurBreedTime() { -+ return this.level.purpurConfig.beeBreedingTicks; -+ } -+ -+ @Override -+ public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.beeTakeDamageFromWater; -+ } -+ -+ @Override -+ protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.beeAlwaysDropExp; -+ } + // Purpur end + @Override protected void defineSynchedData() { super.defineSynchedData(); -@@ -181,6 +250,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -185,6 +234,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { @Override protected void registerGoals() { @@ -6599,7 +6617,7 @@ index c33e5c51839c8e6ec04c1b302127d2bf0f48664c..d47dc0c3fe8c2b80d7b7eb828a12af6e 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)); -@@ -196,6 +266,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -200,6 +250,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)); @@ -6607,48 +6625,75 @@ index c33e5c51839c8e6ec04c1b302127d2bf0f48664c..d47dc0c3fe8c2b80d7b7eb828a12af6e 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)); -@@ -344,7 +415,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -348,7 +399,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { boolean wantsToEnterHive() { if (this.stayOutOfHiveCountdown <= 0 && !this.beePollinateGoal.isPollinating() && !this.hasStung() && this.getTarget() == null) { -- boolean flag = this.isTiredOfLookingForNectar() || this.level.isRaining() || this.level.isNight() || this.hasNectar(); -+ boolean flag = this.isTiredOfLookingForNectar() || (this.level.isRaining() && !this.level.purpurConfig.beeCanWorkInRain) || (this.level.isNight() && !this.level.purpurConfig.beeCanWorkAtNight) || this.hasNectar(); // Purpur +- boolean flag = this.isTiredOfLookingForNectar() || this.level().isRaining() || this.level().isNight() || this.hasNectar(); ++ boolean flag = this.isTiredOfLookingForNectar() || (this.level().isRaining() && !this.level().purpurConfig.beeCanWorkInRain) || (this.level().isNight() && !this.level().purpurConfig.beeCanWorkAtNight) || this.hasNectar(); // Purpur return flag && !this.isHiveNearFire(); } else { -@@ -384,6 +455,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -388,6 +439,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { this.hurt(this.damageSources().drown(), 1.0F); } -+ if (flag && !this.level.purpurConfig.beeDiesAfterSting) setHasStung(false); else // Purpur ++ if (flag && !this.level().purpurConfig.beeDiesAfterSting) setHasStung(false); else // Purpur if (flag) { ++this.timeSinceSting; if (this.timeSinceSting % 5 == 0 && this.random.nextInt(Mth.clamp(1200 - this.timeSinceSting, 1, 1200)) == 0) { -@@ -732,6 +804,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -420,6 +472,26 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { + } + } + ++ @Override ++ public void initAttributes() { ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.beeMaxHealth); ++ } ++ ++ @Override ++ public int getPurpurBreedTime() { ++ return this.level().purpurConfig.beeBreedingTicks; ++ } ++ ++ @Override ++ public boolean isSensitiveToWater() { ++ return this.level().purpurConfig.beeTakeDamageFromWater; ++ } ++ ++ @Override ++ protected boolean isAlwaysExperienceDropper() { ++ return this.level().purpurConfig.beeAlwaysDropExp; ++ } ++ + @Override + public int getRemainingPersistentAngerTime() { + return (Integer) this.entityData.get(Bee.DATA_REMAINING_ANGER_TIME); +@@ -735,6 +807,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); -+ new org.purpurmc.purpur.event.entity.BeeFoundFlowerEvent((org.bukkit.entity.Bee) Bee.this.getBukkitEntity(), io.papermc.paper.util.MCUtil.toLocation(Bee.this.level, Bee.this.savedFlowerPos)).callEvent(); // Purpur ++ new org.purpurmc.purpur.event.entity.BeeFoundFlowerEvent((org.bukkit.entity.Bee) Bee.this.getBukkitEntity(), io.papermc.paper.util.MCUtil.toLocation(Bee.this.level(), Bee.this.savedFlowerPos)).callEvent(); // Purpur return true; } else { Bee.this.remainingCooldownBeforeLocatingNewFlower = Mth.nextInt(Bee.this.random, 20, 60); -@@ -788,6 +861,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -791,6 +864,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { this.pollinating = false; Bee.this.navigation.stop(); Bee.this.remainingCooldownBeforeLocatingNewFlower = 200; -+ new org.purpurmc.purpur.event.entity.BeeStopPollinatingEvent((org.bukkit.entity.Bee) Bee.this.getBukkitEntity(), Bee.this.savedFlowerPos == null ? null : io.papermc.paper.util.MCUtil.toLocation(Bee.this.level, Bee.this.savedFlowerPos), Bee.this.hasNectar()).callEvent(); // Purpur ++ new org.purpurmc.purpur.event.entity.BeeStopPollinatingEvent((org.bukkit.entity.Bee) Bee.this.getBukkitEntity(), Bee.this.savedFlowerPos == null ? null : io.papermc.paper.util.MCUtil.toLocation(Bee.this.level(), Bee.this.savedFlowerPos), Bee.this.hasNectar()).callEvent(); // Purpur } @Override -@@ -834,6 +908,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -837,6 +911,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { this.setWantedPos(); } -+ if (this.successfulPollinatingTicks == 0) new org.purpurmc.purpur.event.entity.BeeStartedPollinatingEvent((org.bukkit.entity.Bee) Bee.this.getBukkitEntity(), io.papermc.paper.util.MCUtil.toLocation(Bee.this.level, Bee.this.savedFlowerPos)).callEvent(); // Purpur ++ if (this.successfulPollinatingTicks == 0) new org.purpurmc.purpur.event.entity.BeeStartedPollinatingEvent((org.bukkit.entity.Bee) Bee.this.getBukkitEntity(), io.papermc.paper.util.MCUtil.toLocation(Bee.this.level(), Bee.this.savedFlowerPos)).callEvent(); // Purpur ++this.successfulPollinatingTicks; if (Bee.this.random.nextFloat() < 0.05F && this.successfulPollinatingTicks > this.lastSoundPlayedTick + 60) { this.lastSoundPlayedTick = this.successfulPollinatingTicks; -@@ -878,16 +953,16 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -881,16 +956,16 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { } } @@ -6669,7 +6714,7 @@ index c33e5c51839c8e6ec04c1b302127d2bf0f48664c..d47dc0c3fe8c2b80d7b7eb828a12af6e } 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 72b30a5cdeb8a43702d9ab5f198311929761fad1..fe08d83a49efe5e1648cafc50e9184dbd0db2115 100644 +index 90ce201bc7c47cef9bc59d7b535a7453854bac75..3347b39fa1bc3308aa3b70b4169523885b91a047 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Cat.java +++ b/src/main/java/net/minecraft/world/entity/animal/Cat.java @@ -97,6 +97,51 @@ public class Cat extends TamableAnimal implements VariantHolder { @@ -6679,17 +6724,17 @@ index 72b30a5cdeb8a43702d9ab5f198311929761fad1..fe08d83a49efe5e1648cafc50e9184db + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.catRidable; ++ return level().purpurConfig.catRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.catRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.catRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.catControllable; ++ return level().purpurConfig.catControllable; + } + + @Override @@ -6699,27 +6744,27 @@ index 72b30a5cdeb8a43702d9ab5f198311929761fad1..fe08d83a49efe5e1648cafc50e9184db + setLying(false); + setRelaxStateOne(false); + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.catMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.catMaxHealth); + } + + @Override + public int getPurpurBreedTime() { -+ return this.level.purpurConfig.catBreedingTicks; ++ return this.level().purpurConfig.catBreedingTicks; + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.catTakeDamageFromWater; ++ return this.level().purpurConfig.catTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.catAlwaysDropExp; ++ return this.level().purpurConfig.catAlwaysDropExp; + } -+ // Purpur end + public ResourceLocation getResourceLocation() { return this.getVariant().texture(); @@ -6747,7 +6792,7 @@ index 72b30a5cdeb8a43702d9ab5f198311929761fad1..fe08d83a49efe5e1648cafc50e9184db + // Purpur start + @Override + public void tame(Player player) { -+ setCollarColor(level.purpurConfig.catDefaultCollarColor); ++ setCollarColor(level().purpurConfig.catDefaultCollarColor); + super.tame(player); + } + // Purpur end @@ -6768,12 +6813,12 @@ index 72b30a5cdeb8a43702d9ab5f198311929761fad1..fe08d83a49efe5e1648cafc50e9184db } 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 ++ 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); + 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 b4dc621cb1be7cb4bf1cb31f921d4e9f6cffef88..c5e81244331d76535028f8296d10939933010d09 100644 +index 84cefbc339ca368ac306d521012ce2f826a660b5..00bdb2b75221349cb40da2b5fc1563393fd17ef6 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Chicken.java +++ b/src/main/java/net/minecraft/world/entity/animal/Chicken.java @@ -54,16 +54,65 @@ public class Chicken extends Animal { @@ -6783,42 +6828,42 @@ index b4dc621cb1be7cb4bf1cb31f921d4e9f6cffef88..c5e81244331d76535028f8296d109399 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.chickenRidable; ++ return level().purpurConfig.chickenRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.chickenRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.chickenRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.chickenControllable; ++ return level().purpurConfig.chickenControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.chickenMaxHealth); -+ if (level.purpurConfig.chickenRetaliate) { ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.chickenMaxHealth); ++ if (level().purpurConfig.chickenRetaliate) { + this.getAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(2.0D); + } + } + + @Override + public int getPurpurBreedTime() { -+ return this.level.purpurConfig.chickenBreedingTicks; ++ return this.level().purpurConfig.chickenBreedingTicks; + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.chickenTakeDamageFromWater; ++ return this.level().purpurConfig.chickenTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.chickenAlwaysDropExp; ++ return this.level().purpurConfig.chickenAlwaysDropExp; + } -+ // Purpur end + @Override protected void registerGoals() { @@ -6833,7 +6878,7 @@ index b4dc621cb1be7cb4bf1cb31f921d4e9f6cffef88..c5e81244331d76535028f8296d109399 this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 6.0F)); this.goalSelector.addGoal(7, new RandomLookAroundGoal(this)); + // Purpur start -+ if (level.purpurConfig.chickenRetaliate) { ++ if (level().purpurConfig.chickenRetaliate) { + this.goalSelector.addGoal(1, new net.minecraft.world.entity.ai.goal.MeleeAttackGoal(this, 1.0D, false)); + this.targetSelector.addGoal(1, new net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal(this)); + } else { @@ -6853,7 +6898,7 @@ index b4dc621cb1be7cb4bf1cb31f921d4e9f6cffef88..c5e81244331d76535028f8296d109399 @Override diff --git a/src/main/java/net/minecraft/world/entity/animal/Cod.java b/src/main/java/net/minecraft/world/entity/animal/Cod.java -index 824e5e4fe7619ae46061c3c978c9a044db8c84ab..2a45b487e5305e7c40cc8de4ddbb142af4b041de 100644 +index 824e5e4fe7619ae46061c3c978c9a044db8c84ab..f0b6118a9995bb41836685bbf94d2e7fb15761eb 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Cod.java +++ b/src/main/java/net/minecraft/world/entity/animal/Cod.java @@ -13,6 +13,33 @@ public class Cod extends AbstractSchoolingFish { @@ -6863,35 +6908,35 @@ index 824e5e4fe7619ae46061c3c978c9a044db8c84ab..2a45b487e5305e7c40cc8de4ddbb142a + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.codRidable; ++ return level().purpurConfig.codRidable; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.codControllable; ++ return level().purpurConfig.codControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.codMaxHealth); ++ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.codMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.codTakeDamageFromWater; ++ return this.level().purpurConfig.codTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.codAlwaysDropExp; ++ return this.level().purpurConfig.codAlwaysDropExp; + } -+ // Purpur end + @Override 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 abae850f5babfd75c7547e88fb7637e9775991d3..54d9213d9de26a14a5ca770440d098bf0438373e 100644 +index 0263acf81330ada1bb8ae7d52a3b04e08d0c4dcb..3cee7d5656b2df2997ceaee3489c02ce881e6875 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; @@ -6910,7 +6955,7 @@ index abae850f5babfd75c7547e88fb7637e9775991d3..54d9213d9de26a14a5ca770440d098bf import net.minecraft.world.level.block.state.BlockState; // CraftBukkit start import org.bukkit.craftbukkit.event.CraftEventFactory; -@@ -36,25 +38,74 @@ import org.bukkit.craftbukkit.inventory.CraftItemStack; +@@ -37,25 +39,74 @@ import org.bukkit.event.player.PlayerBucketFillEvent; // CraftBukkit end public class Cow extends Animal { @@ -6923,33 +6968,34 @@ index abae850f5babfd75c7547e88fb7637e9775991d3..54d9213d9de26a14a5ca770440d098bf + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.cowRidable; ++ return level().purpurConfig.cowRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.cowRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.cowRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.cowControllable; ++ return level().purpurConfig.cowControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.cowMaxHealth); -+ this.getAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(this.level.purpurConfig.cowNaturallyAggressiveToPlayersDamage); // Purpur ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.cowMaxHealth); ++ this.getAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(this.level().purpurConfig.cowNaturallyAggressiveToPlayersDamage); // Purpur + } + + @Override + public int getPurpurBreedTime() { -+ return this.level.purpurConfig.cowBreedingTicks; ++ return this.level().purpurConfig.cowBreedingTicks; + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.cowTakeDamageFromWater; ++ return this.level().purpurConfig.cowTakeDamageFromWater; + } + + @Override @@ -6960,9 +7006,8 @@ index abae850f5babfd75c7547e88fb7637e9775991d3..54d9213d9de26a14a5ca770440d098bf + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.cowAlwaysDropExp; ++ return this.level().purpurConfig.cowAlwaysDropExp; + } -+ // Purpur end + @Override protected void registerGoals() { @@ -6971,7 +7016,7 @@ index abae850f5babfd75c7547e88fb7637e9775991d3..54d9213d9de26a14a5ca770440d098bf 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 ++ 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(4, new FollowParentGoal(this, 1.25D)); this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 1.0D)); @@ -6986,7 +7031,7 @@ index abae850f5babfd75c7547e88fb7637e9775991d3..54d9213d9de26a14a5ca770440d098bf } @Override -@@ -84,6 +135,7 @@ public class Cow extends Animal { +@@ -85,6 +136,7 @@ public class Cow extends Animal { @Override public InteractionResult mobInteract(Player player, InteractionHand hand) { @@ -6994,8 +7039,8 @@ index abae850f5babfd75c7547e88fb7637e9775991d3..54d9213d9de26a14a5ca770440d098bf ItemStack itemstack = player.getItemInHand(hand); if (itemstack.is(Items.BUCKET) && !this.isBaby()) { -@@ -91,7 +143,7 @@ public class Cow extends Animal { - org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level, player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET, hand); +@@ -92,7 +144,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()) { - return InteractionResult.PASS; @@ -7003,18 +7048,18 @@ index abae850f5babfd75c7547e88fb7637e9775991d3..54d9213d9de26a14a5ca770440d098bf } // CraftBukkit end -@@ -100,6 +152,10 @@ public class Cow extends Animal { +@@ -101,6 +153,10 @@ public class Cow extends Animal { player.setItemInHand(hand, itemstack1); - return InteractionResult.sidedSuccess(this.level.isClientSide); + return InteractionResult.sidedSuccess(this.level().isClientSide); + // Purpur start - feed mushroom to change to mooshroom -+ } else if (level.purpurConfig.cowFeedMushrooms > 0 && this.getType() != EntityType.MOOSHROOM && isMushroom(itemstack)) { ++ } else if (level().purpurConfig.cowFeedMushrooms > 0 && this.getType() != EntityType.MOOSHROOM && isMushroom(itemstack)) { + return this.feedMushroom(player, itemstack); + // Purpur end } else { return super.mobInteract(player, hand); } -@@ -115,4 +171,69 @@ public class Cow extends Animal { +@@ -116,4 +172,69 @@ public class Cow extends Animal { protected float getStandingEyeHeight(Pose pose, EntityDimensions dimensions) { return this.isBaby() ? dimensions.height * 0.95F : 1.3F; } @@ -7036,15 +7081,15 @@ index abae850f5babfd75c7547e88fb7637e9775991d3..54d9213d9de26a14a5ca770440d098bf + } + + private InteractionResult feedMushroom(Player player, ItemStack stack) { -+ level.broadcastEntityEvent(this, (byte) 18); // hearts ++ level().broadcastEntityEvent(this, (byte) 18); // hearts + playSound(SoundEvents.COW_MILK, 1.0F, 1.0F); -+ if (incrementFeedCount(stack) < level.purpurConfig.cowFeedMushrooms) { ++ if (incrementFeedCount(stack) < level().purpurConfig.cowFeedMushrooms) { + if (!player.getAbilities().instabuild) { + stack.shrink(1); + } + return InteractionResult.CONSUME; // require 5 mushrooms to transform (prevents mushroom duping) + } -+ MushroomCow mooshroom = EntityType.MOOSHROOM.create(level); ++ MushroomCow mooshroom = EntityType.MOOSHROOM.create(level()); + if (mooshroom == null) { + return InteractionResult.PASS; + } @@ -7070,13 +7115,13 @@ index abae850f5babfd75c7547e88fb7637e9775991d3..54d9213d9de26a14a5ca770440d098bf + if (!new com.destroystokyo.paper.event.entity.EntityTransformedEvent(this.getBukkitEntity(), mooshroom.getBukkitEntity(), com.destroystokyo.paper.event.entity.EntityTransformedEvent.TransformedReason.INFECTED).callEvent()) { + return InteractionResult.PASS; + } -+ this.level.addFreshEntity(mooshroom); ++ this.level().addFreshEntity(mooshroom); + this.remove(RemovalReason.DISCARDED); + if (!player.getAbilities().instabuild) { + stack.shrink(1); + } + for (int i = 0; i < 15; ++i) { -+ ((ServerLevel) level).sendParticles(((ServerLevel) level).players(), null, ParticleTypes.HAPPY_VILLAGER, ++ ((ServerLevel) level()).sendParticles(((ServerLevel) level()).players(), null, ParticleTypes.HAPPY_VILLAGER, + getX() + random.nextFloat(), getY() + (random.nextFloat() * 2), getZ() + random.nextFloat(), 1, + random.nextGaussian() * 0.05D, random.nextGaussian() * 0.05D, random.nextGaussian() * 0.05D, 0, true); + } @@ -7085,15 +7130,15 @@ index abae850f5babfd75c7547e88fb7637e9775991d3..54d9213d9de26a14a5ca770440d098bf + // 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 e93abb02744b5cd8db88e01b6ccf145498903b11..a077edbe97ce89e11a26fe3ebeb0bdd996593f78 100644 +index 8448c5d778998390cf2b683f36e4e18ca7ffdc34..4c9c07d470357c35bd5ba3c21437a2c44c52811e 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java +++ b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java -@@ -78,19 +78,104 @@ public class Dolphin extends WaterAnimal { +@@ -82,19 +82,104 @@ public class Dolphin extends WaterAnimal { public static final Predicate ALLOWED_ITEMS = (entityitem) -> { return !entityitem.hasPickUpDelay() && entityitem.isAlive() && entityitem.isInWater(); }; -+ private int spitCooldown; // Purpur + private boolean isNaturallyAggressiveToPlayers; // Purpur ++ private int spitCooldown; // Purpur public Dolphin(EntityType type, Level world) { super(type, world); @@ -7137,18 +7182,18 @@ index e93abb02744b5cd8db88e01b6ccf145498903b11..a077edbe97ce89e11a26fe3ebeb0bdd9 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.dolphinRidable; ++ return level().purpurConfig.dolphinRidable; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.dolphinControllable; ++ return level().purpurConfig.dolphinControllable; + } + + @Override + public boolean onSpacebar() { + if (spitCooldown == 0 && getRider() != null) { -+ spitCooldown = level.purpurConfig.dolphinSpitCooldown; ++ spitCooldown = level().purpurConfig.dolphinSpitCooldown; + + org.bukkit.craftbukkit.entity.CraftPlayer player = (org.bukkit.craftbukkit.entity.CraftPlayer) getRider().getBukkitEntity(); + if (!player.hasPermission("allow.special.dolphin")) { @@ -7159,31 +7204,31 @@ index e93abb02744b5cd8db88e01b6ccf145498903b11..a077edbe97ce89e11a26fe3ebeb0bdd9 + loc.setPitch(loc.getPitch() - 10); + org.bukkit.util.Vector target = loc.getDirection().normalize().multiply(10).add(loc.toVector()); + -+ org.purpurmc.purpur.entity.DolphinSpit spit = new org.purpurmc.purpur.entity.DolphinSpit(level, this); -+ spit.shoot(target.getX() - getX(), target.getY() - getY(), target.getZ() - getZ(), level.purpurConfig.dolphinSpitSpeed, 5.0F); ++ org.purpurmc.purpur.entity.DolphinSpit spit = new org.purpurmc.purpur.entity.DolphinSpit(level(), this); ++ spit.shoot(target.getX() - getX(), target.getY() - getY(), target.getZ() - getZ(), level().purpurConfig.dolphinSpitSpeed, 5.0F); + -+ level.addFreshEntity(spit); ++ level().addFreshEntity(spit); + playSound(SoundEvents.DOLPHIN_ATTACK, 1.0F, 1.0F + (random.nextFloat() - random.nextFloat()) * 0.2F); + return true; + } + return false; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.dolphinMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.dolphinMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.dolphinTakeDamageFromWater; ++ return this.level().purpurConfig.dolphinTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.dolphinAlwaysDropExp; ++ return this.level().purpurConfig.dolphinAlwaysDropExp; + } -+ // Purpur end + @Nullable @Override @@ -7194,12 +7239,12 @@ index e93abb02744b5cd8db88e01b6ccf145498903b11..a077edbe97ce89e11a26fe3ebeb0bdd9 return super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityNbt); } -@@ -160,17 +245,21 @@ public class Dolphin extends WaterAnimal { +@@ -164,17 +249,21 @@ public class Dolphin extends WaterAnimal { protected void registerGoals() { this.goalSelector.addGoal(0, new BreathAirGoal(this)); this.goalSelector.addGoal(0, new TryFindWaterGoal(this)); -+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur + this.goalSelector.addGoal(1, new MeleeAttackGoal(this, 1.2000000476837158D, true)); // Purpur ++ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur this.goalSelector.addGoal(1, new Dolphin.DolphinSwimToTreasureGoal(this)); this.goalSelector.addGoal(2, new Dolphin.DolphinSwimWithPlayerGoal(this, 4.0D)); this.goalSelector.addGoal(4, new RandomSwimmingGoal(this, 1.0D, 10)); @@ -7217,7 +7262,7 @@ index e93abb02744b5cd8db88e01b6ccf145498903b11..a077edbe97ce89e11a26fe3ebeb0bdd9 } public static AttributeSupplier.Builder createAttributes() { -@@ -221,7 +310,7 @@ public class Dolphin extends WaterAnimal { +@@ -225,7 +314,7 @@ public class Dolphin extends WaterAnimal { @Override protected boolean canRide(Entity entity) { @@ -7226,7 +7271,7 @@ index e93abb02744b5cd8db88e01b6ccf145498903b11..a077edbe97ce89e11a26fe3ebeb0bdd9 } @Override -@@ -256,6 +345,11 @@ public class Dolphin extends WaterAnimal { +@@ -260,6 +349,11 @@ public class Dolphin extends WaterAnimal { @Override public void tick() { super.tick(); @@ -7238,16 +7283,16 @@ index e93abb02744b5cd8db88e01b6ccf145498903b11..a077edbe97ce89e11a26fe3ebeb0bdd9 if (this.isNoAi()) { this.setAirSupply(this.getMaxAirSupply()); } else { -@@ -401,6 +495,7 @@ public class Dolphin extends WaterAnimal { +@@ -405,6 +499,7 @@ public class Dolphin extends WaterAnimal { @Override public boolean canUse() { -+ if (this.dolphin.level.purpurConfig.dolphinDisableTreasureSearching) return false; // Purpur - return this.dolphin.gotFish() && this.dolphin.getAirSupply() >= 100 && this.dolphin.level.getWorld().canGenerateStructures(); // MC-151364, SPIGOT-5494: hangs if generate-structures=false ++ if (this.dolphin.level().purpurConfig.dolphinDisableTreasureSearching) return false; // Purpur + return this.dolphin.gotFish() && this.dolphin.getAirSupply() >= 100; } 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 89894bc6a55bc7e456a9d49ac48f6a8192b890ae..f0eb5e0c01923f884b1c7c48e8d67ed5cd429854 100644 +index 62604ed2e82afd3603ccac5d9c6e285c431542b1..ca3096abbd54745af591101c7b306ed87f212954 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Fox.java +++ b/src/main/java/net/minecraft/world/entity/animal/Fox.java @@ -35,6 +35,7 @@ import net.minecraft.util.RandomSource; @@ -7273,17 +7318,17 @@ index 89894bc6a55bc7e456a9d49ac48f6a8192b890ae..f0eb5e0c01923f884b1c7c48e8d67ed5 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.foxRidable; ++ return level().purpurConfig.foxRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.foxRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.foxRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.foxControllable; ++ return level().purpurConfig.foxControllable; + } + + @Override @@ -7306,27 +7351,27 @@ index 89894bc6a55bc7e456a9d49ac48f6a8192b890ae..f0eb5e0c01923f884b1c7c48e8d67ed5 + super.onDismount(rider); + setCanPickUpLoot(true); + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.foxMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.foxMaxHealth); + } + + @Override + public int getPurpurBreedTime() { -+ return this.level.purpurConfig.foxBreedingTicks; ++ return this.level().purpurConfig.foxBreedingTicks; + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.foxTakeDamageFromWater; ++ return this.level().purpurConfig.foxTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.foxAlwaysDropExp; ++ return this.level().purpurConfig.foxAlwaysDropExp; + } -+ // Purpur end + @Override protected void defineSynchedData() { @@ -7336,7 +7381,7 @@ index 89894bc6a55bc7e456a9d49ac48f6a8192b890ae..f0eb5e0c01923f884b1c7c48e8d67ed5 }); this.goalSelector.addGoal(0, new Fox.FoxFloatGoal()); + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - this.goalSelector.addGoal(0, new ClimbOnTopOfPowderSnowGoal(this, this.level)); + 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)); @@ -186,6 +247,7 @@ public class Fox extends Animal implements VariantHolder { @@ -7374,7 +7419,7 @@ index 89894bc6a55bc7e456a9d49ac48f6a8192b890ae..f0eb5e0c01923f884b1c7c48e8d67ed5 + // Purpur start + @Override + public InteractionResult mobInteract(Player player, InteractionHand hand) { -+ if (level.purpurConfig.foxTypeChangesWithTulips) { ++ if (level().purpurConfig.foxTypeChangesWithTulips) { + ItemStack itemstack = player.getItemInHand(hand); + if (getVariant() == Type.RED && itemstack.getItem() == Items.WHITE_TULIP) { + setVariant(Type.SNOW); @@ -7454,16 +7499,16 @@ index 89894bc6a55bc7e456a9d49ac48f6a8192b890ae..f0eb5e0c01923f884b1c7c48e8d67ed5 } protected void onReachedTarget() { -- if (Fox.this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -+ if (Fox.this.level.purpurConfig.foxBypassMobGriefing || Fox.this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur - BlockState iblockdata = Fox.this.level.getBlockState(this.blockPos); +- if (Fox.this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ if (Fox.this.level().purpurConfig.foxBypassMobGriefing || Fox.this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur + BlockState iblockdata = Fox.this.level().getBlockState(this.blockPos); 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 4fbbd74cda7e4f2c623db46c2c94d9697ca5df05..b5f445750a5ccbe7658396bdcc9648dc41f39ced 100644 +index f383928fc5b331ddf128bdcb6a23010d8fe088d3..64aba511e615983988cdb6a0fd45b7d9d4f2f16d 100644 --- a/src/main/java/net/minecraft/world/entity/animal/IronGolem.java +++ b/src/main/java/net/minecraft/world/entity/animal/IronGolem.java -@@ -63,14 +63,59 @@ public class IronGolem extends AbstractGolem implements NeutralMob { +@@ -60,14 +60,59 @@ public class IronGolem extends AbstractGolem implements NeutralMob { private int remainingPersistentAngerTime; @Nullable private UUID persistentAngerTarget; @@ -7477,27 +7522,28 @@ index 4fbbd74cda7e4f2c623db46c2c94d9697ca5df05..b5f445750a5ccbe7658396bdcc9648dc + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.ironGolemRidable; ++ return level().purpurConfig.ironGolemRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.ironGolemRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.ironGolemRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.ironGolemControllable; ++ return level().purpurConfig.ironGolemControllable; + } + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.ironGolemMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.ironGolemMaxHealth); + } ++ // Purpur end + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.ironGolemTakeDamageFromWater; ++ return this.level().purpurConfig.ironGolemTakeDamageFromWater; + } + + @Nullable @@ -7511,19 +7557,18 @@ index 4fbbd74cda7e4f2c623db46c2c94d9697ca5df05..b5f445750a5ccbe7658396bdcc9648dc + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.ironGolemAlwaysDropExp; ++ return this.level().purpurConfig.ironGolemAlwaysDropExp; + } -+ // Purpur end + @Override protected void registerGoals() { -+ if (level.purpurConfig.ironGolemCanSwim) this.goalSelector.addGoal(0, new net.minecraft.world.entity.ai.goal.FloatGoal(this)); // Purpur ++ if (level().purpurConfig.ironGolemCanSwim) this.goalSelector.addGoal(0, new net.minecraft.world.entity.ai.goal.FloatGoal(this)); // Purpur ++ if (this.level().purpurConfig.ironGolemPoppyCalm) this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.ReceiveFlower(this)); // Purpur + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur -+ if (this.level.purpurConfig.ironGolemPoppyCalm) this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.ReceiveFlower(this)); // Purpur 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)); -@@ -78,6 +123,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { +@@ -75,6 +120,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)); @@ -7531,7 +7576,7 @@ index 4fbbd74cda7e4f2c623db46c2c94d9697ca5df05..b5f445750a5ccbe7658396bdcc9648dc 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)); -@@ -148,6 +194,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { +@@ -139,6 +185,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { public void addAdditionalSaveData(CompoundTag nbt) { super.addAdditionalSaveData(nbt); nbt.putBoolean("PlayerCreated", this.isPlayerCreated()); @@ -7539,15 +7584,15 @@ index 4fbbd74cda7e4f2c623db46c2c94d9697ca5df05..b5f445750a5ccbe7658396bdcc9648dc this.addPersistentAngerSaveData(nbt); } -@@ -155,6 +202,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { +@@ -146,6 +193,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { public void readAdditionalSaveData(CompoundTag nbt) { super.readAdditionalSaveData(nbt); this.setPlayerCreated(nbt.getBoolean("PlayerCreated")); + if (nbt.contains("Purpur.Summoner")) setSummoner(nbt.getUUID("Purpur.Summoner")); // Purpur - this.readPersistentAngerSaveData(this.level, nbt); + this.readPersistentAngerSaveData(this.level(), nbt); } -@@ -279,13 +327,13 @@ public class IronGolem extends AbstractGolem implements NeutralMob { +@@ -270,13 +318,13 @@ public class IronGolem extends AbstractGolem implements NeutralMob { ItemStack itemstack = player.getItemInHand(hand); if (!itemstack.is(Items.IRON_INGOT)) { @@ -7563,17 +7608,16 @@ index 4fbbd74cda7e4f2c623db46c2c94d9697ca5df05..b5f445750a5ccbe7658396bdcc9648dc } else { float f1 = 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F; -@@ -294,6 +342,8 @@ public class IronGolem extends AbstractGolem implements NeutralMob { +@@ -285,6 +333,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { itemstack.shrink(1); } -+ if (this.level.purpurConfig.ironGolemHealCalm && isAngry() && getHealth() == getMaxHealth()) stopBeingAngry(); // Purpur -+ - return InteractionResult.sidedSuccess(this.level.isClientSide); ++ 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 68a5ee85e64802e4509ba0d184fc0ceb3cbe2d11..b5d0d3aaa0442b4753aef8fdf8f85f017e1dd811 100644 +index a04374f91f2fbb31219d86b6ae63bcf8fdf7318c..e462b81aa1276a8f1222b74459359f6c6d57f739 100644 --- a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java +++ b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java @@ -63,6 +63,43 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder { @@ -145,7 +182,7 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder> optional = this.getEffectFromItemStack(itemstack); @@ -7648,9 +7692,9 @@ index 68a5ee85e64802e4509ba0d184fc0ceb3cbe2d11..b5d0d3aaa0442b4753aef8fdf8f85f01 @Override - public void shear(SoundSource shearedSoundCategory) { + public void shear(SoundSource shearedSoundCategory, int looting) { // Purpur - this.level.playSound((Player) null, (Entity) this, SoundEvents.MOOSHROOM_SHEAR, shearedSoundCategory, 1.0F, 1.0F); - if (!this.level.isClientSide()) { - Cow entitycow = (Cow) EntityType.COW.create(this.level); + this.level().playSound((Player) null, (Entity) this, SoundEvents.MOOSHROOM_SHEAR, shearedSoundCategory, 1.0F, 1.0F); + if (!this.level().isClientSide()) { + Cow entitycow = (Cow) EntityType.COW.create(this.level()); @@ -180,7 +217,13 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder(this, Chicken.class, false)); this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Turtle.class, 10, false, false, Turtle.BABY_ON_LAND_SELECTOR)); } +@@ -254,7 +293,7 @@ public class Ocelot extends Animal { + if (world.isUnobstructed(this) && !world.containsAnyLiquid(this.getBoundingBox())) { + BlockPos blockposition = this.blockPosition(); + +- if (blockposition.getY() < world.getSeaLevel()) { ++ if (!level().purpurConfig.ocelotSpawnUnderSeaLevel && blockposition.getY() < world.getSeaLevel()) { + return false; + } + 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 9c1e02c3a990cd0f8bba1c84c170b438278c02a7..d1e45052fc96b6f81a331c6c73cb68ff96238359 100644 +index f43c4fed59c4c75540008284ddb197d9a6b5487b..bd7c5f6768a54a3d8ffd585d91414e65936991da 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Panda.java +++ b/src/main/java/net/minecraft/world/entity/animal/Panda.java -@@ -108,6 +108,53 @@ public class Panda extends Animal { +@@ -111,6 +111,53 @@ public class Panda extends Animal { } + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.pandaRidable; ++ return level().purpurConfig.pandaRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.pandaRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.pandaRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.pandaControllable; ++ return level().purpurConfig.pandaControllable; + } + + @Override @@ -7769,33 +7822,33 @@ index 9c1e02c3a990cd0f8bba1c84c170b438278c02a7..d1e45052fc96b6f81a331c6c73cb68ff + eat(false); + setOnBack(false); + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.pandaMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.pandaMaxHealth); + setAttributes(); + } + + @Override + public int getPurpurBreedTime() { -+ return this.level.purpurConfig.pandaBreedingTicks; ++ return this.level().purpurConfig.pandaBreedingTicks; + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.pandaTakeDamageFromWater; ++ return this.level().purpurConfig.pandaTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.pandaAlwaysDropExp; ++ return this.level().purpurConfig.pandaAlwaysDropExp; + } -+ // Purpur end + @Override public boolean canTakeItem(ItemStack stack) { EquipmentSlot enumitemslot = Mob.getEquipmentSlotForItem(stack); -@@ -269,6 +316,7 @@ public class Panda extends Animal { +@@ -272,6 +319,7 @@ public class Panda extends Animal { @Override protected void registerGoals() { this.goalSelector.addGoal(0, new FloatGoal(this)); @@ -7803,7 +7856,7 @@ index 9c1e02c3a990cd0f8bba1c84c170b438278c02a7..d1e45052fc96b6f81a331c6c73cb68ff 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)); -@@ -284,6 +332,7 @@ public class Panda extends Animal { +@@ -287,6 +335,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)); @@ -7811,7 +7864,7 @@ index 9c1e02c3a990cd0f8bba1c84c170b438278c02a7..d1e45052fc96b6f81a331c6c73cb68ff this.targetSelector.addGoal(1, (new Panda.PandaHurtByTargetGoal(this, new Class[0])).setAlertOthers(new Class[0])); } -@@ -607,7 +656,10 @@ public class Panda extends Animal { +@@ -610,7 +659,10 @@ public class Panda extends Animal { public void setAttributes() { if (this.isWeak()) { @@ -7823,7 +7876,7 @@ index 9c1e02c3a990cd0f8bba1c84c170b438278c02a7..d1e45052fc96b6f81a331c6c73cb68ff } if (this.isLazy()) { -@@ -630,7 +682,7 @@ public class Panda extends Animal { +@@ -633,7 +685,7 @@ public class Panda extends Animal { ItemStack itemstack = player.getItemInHand(hand); if (this.isScared()) { @@ -7831,17 +7884,17 @@ index 9c1e02c3a990cd0f8bba1c84c170b438278c02a7..d1e45052fc96b6f81a331c6c73cb68ff + return tryRide(player, hand); // Purpur } else if (this.isOnBack()) { this.setOnBack(false); - return InteractionResult.sidedSuccess(this.level.isClientSide); -@@ -647,7 +699,7 @@ public class Panda extends Animal { + return InteractionResult.sidedSuccess(this.level().isClientSide); +@@ -650,7 +702,7 @@ public class Panda extends Animal { this.setInLove(player); } else { - if (this.level.isClientSide || this.isSitting() || this.isInWater()) { + if (this.level().isClientSide || this.isSitting() || this.isInWater()) { - return InteractionResult.PASS; + return tryRide(player, hand); // Purpur } this.tryToSit(); -@@ -666,7 +718,7 @@ public class Panda extends Animal { +@@ -669,7 +721,7 @@ public class Panda extends Animal { return InteractionResult.SUCCESS; } else { @@ -7850,7 +7903,7 @@ index 9c1e02c3a990cd0f8bba1c84c170b438278c02a7..d1e45052fc96b6f81a331c6c73cb68ff } } -@@ -706,7 +758,7 @@ public class Panda extends Animal { +@@ -709,7 +761,7 @@ public class Panda extends Animal { return !this.isOnBack() && !this.isScared() && !this.isEating() && !this.isRolling() && !this.isSitting(); } @@ -7859,7 +7912,7 @@ index 9c1e02c3a990cd0f8bba1c84c170b438278c02a7..d1e45052fc96b6f81a331c6c73cb68ff private final Panda panda; -@@ -716,9 +768,9 @@ public class Panda extends Animal { +@@ -719,9 +771,9 @@ public class Panda extends Animal { } @Override @@ -7872,7 +7925,7 @@ index 9c1e02c3a990cd0f8bba1c84c170b438278c02a7..d1e45052fc96b6f81a331c6c73cb68ff } } 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 e6e40770acf71b9079e8f6ac07025319dd8e2e4e..8ca75f748ac7dcf872b5677648ba384992242a07 100644 +index e1874aaa0065a6e8e6ae043713c22f08b58b5e21..0e20d9ed5b25f5aaab68dc3a4fa4e63ced280969 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Parrot.java +++ b/src/main/java/net/minecraft/world/entity/animal/Parrot.java @@ -129,12 +129,88 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder type, LevelAccessor world, MobSpawnType spawnReason, BlockPos pos, RandomSource random) { @@ -8021,7 +8074,7 @@ index e6e40770acf71b9079e8f6ac07025319dd8e2e4e..8ca75f748ac7dcf872b5677648ba3849 @Override diff --git a/src/main/java/net/minecraft/world/entity/animal/Pig.java b/src/main/java/net/minecraft/world/entity/animal/Pig.java -index ee2dc361ecae87c9d4e2d038068934717c5a8b16..c6fe90852c88e138492c28296869308de8b8428f 100644 +index 4175767f248b1389c5c2a896edde5dc036eb4345..23baba7cdf010afc1c0a1ed264020949bd622fde 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Pig.java +++ b/src/main/java/net/minecraft/world/entity/animal/Pig.java @@ -64,9 +64,47 @@ public class Pig extends Animal implements ItemSteerable, Saddleable { @@ -8031,39 +8084,39 @@ index ee2dc361ecae87c9d4e2d038068934717c5a8b16..c6fe90852c88e138492c28296869308d + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.pigRidable; ++ return level().purpurConfig.pigRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.pigRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.pigRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.pigControllable; ++ return level().purpurConfig.pigControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.pigMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.pigMaxHealth); + } + + @Override + public int getPurpurBreedTime() { -+ return this.level.purpurConfig.pigBreedingTicks; ++ return this.level().purpurConfig.pigBreedingTicks; + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.pigTakeDamageFromWater; ++ return this.level().purpurConfig.pigTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.pigAlwaysDropExp; ++ return this.level().purpurConfig.pigAlwaysDropExp; + } -+ // Purpur end + @Override protected void registerGoals() { @@ -8076,7 +8129,7 @@ index ee2dc361ecae87c9d4e2d038068934717c5a8b16..c6fe90852c88e138492c28296869308d public InteractionResult mobInteract(Player player, InteractionHand hand) { boolean flag = this.isFood(player.getItemInHand(hand)); -+ if (level.purpurConfig.pigGiveSaddleBack && player.isSecondaryUseActive() && !flag && isSaddled() && !isVehicle()) { ++ if (level().purpurConfig.pigGiveSaddleBack && player.isSecondaryUseActive() && !flag && isSaddled() && !isVehicle()) { + this.steering.setSaddle(false); + if (!player.getAbilities().instabuild) { + ItemStack saddle = new ItemStack(Items.SADDLE); @@ -8088,10 +8141,10 @@ index ee2dc361ecae87c9d4e2d038068934717c5a8b16..c6fe90852c88e138492c28296869308d + } + if (!flag && this.isSaddled() && !this.isVehicle() && !player.isSecondaryUseActive()) { - if (!this.level.isClientSide) { + 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 41123a1ec1b410428d804c6f80fa969c4946608f..92437cd638f01506c09448bcd0d1ec6395c4cb07 100644 +index 04f07ecb74d53b6ecf6a9a6055488d5a3023b535..5dd1fa0824dc153c52bf75e397bfc40422c710d0 100644 --- a/src/main/java/net/minecraft/world/entity/animal/PolarBear.java +++ b/src/main/java/net/minecraft/world/entity/animal/PolarBear.java @@ -60,11 +60,81 @@ public class PolarBear extends Animal implements NeutralMob { @@ -8107,17 +8160,17 @@ index 41123a1ec1b410428d804c6f80fa969c4946608f..92437cd638f01506c09448bcd0d1ec63 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.polarBearRidable; ++ return level().purpurConfig.polarBearRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.polarBearRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.polarBearRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.polarBearControllable; ++ return level().purpurConfig.polarBearControllable; + } + + @Override @@ -8130,10 +8183,11 @@ index 41123a1ec1b410428d804c6f80fa969c4946608f..92437cd638f01506c09448bcd0d1ec63 + } + return false; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.polarBearMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.polarBearMaxHealth); + } + + public boolean canMate(Animal other) { @@ -8159,19 +8213,18 @@ index 41123a1ec1b410428d804c6f80fa969c4946608f..92437cd638f01506c09448bcd0d1ec63 + + @Override + public int getPurpurBreedTime() { -+ return this.level.purpurConfig.polarBearBreedingTicks; ++ return this.level().purpurConfig.polarBearBreedingTicks; + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.polarBearTakeDamageFromWater; ++ return this.level().purpurConfig.polarBearTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.polarBearAlwaysDropExp; ++ return this.level().purpurConfig.polarBearAlwaysDropExp; + } -+ // Purpur end + @Nullable @Override @@ -8181,7 +8234,7 @@ index 41123a1ec1b410428d804c6f80fa969c4946608f..92437cd638f01506c09448bcd0d1ec63 @Override public boolean isFood(ItemStack stack) { - return false; -+ return level.purpurConfig.polarBearBreedableItem != null && stack.getItem() == level.purpurConfig.polarBearBreedableItem; // Purpur ++ return level().purpurConfig.polarBearBreedableItem != null && stack.getItem() == level().purpurConfig.polarBearBreedableItem; // Purpur } @Override @@ -8192,9 +8245,9 @@ index 41123a1ec1b410428d804c6f80fa969c4946608f..92437cd638f01506c09448bcd0d1ec63 this.goalSelector.addGoal(1, new PolarBear.PolarBearMeleeAttackGoal()); this.goalSelector.addGoal(1, new PolarBear.PolarBearPanicGoal()); + // Purpur start -+ if (level.purpurConfig.polarBearBreedableItem != null) { ++ if (level().purpurConfig.polarBearBreedableItem != null) { + this.goalSelector.addGoal(2, new net.minecraft.world.entity.ai.goal.BreedGoal(this, 1.0D)); -+ this.goalSelector.addGoal(3, new net.minecraft.world.entity.ai.goal.TemptGoal(this, 1.0D, net.minecraft.world.item.crafting.Ingredient.of(level.purpurConfig.polarBearBreedableItem), false)); ++ this.goalSelector.addGoal(3, new net.minecraft.world.entity.ai.goal.TemptGoal(this, 1.0D, net.minecraft.world.item.crafting.Ingredient.of(level().purpurConfig.polarBearBreedableItem), false)); + } + // Purpur end this.goalSelector.addGoal(4, new FollowParentGoal(this, 1.25D)); @@ -8206,7 +8259,7 @@ index 41123a1ec1b410428d804c6f80fa969c4946608f..92437cd638f01506c09448bcd0d1ec63 this.targetSelector.addGoal(2, new PolarBear.PolarBearAttackPlayersGoal()); this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, this::isAngryAt)); @@ -202,6 +280,11 @@ public class PolarBear extends Animal implements NeutralMob { - this.updatePersistentAnger((ServerLevel)this.level, true); + this.updatePersistentAnger((ServerLevel)this.level(), true); } + // Purpur start @@ -8226,7 +8279,7 @@ index 41123a1ec1b410428d804c6f80fa969c4946608f..92437cd638f01506c09448bcd0d1ec63 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 9aa5aa0d66257bf1413a904c516293aea30d2ca8..d152c50f17e2ab7a37b0c295c7f62e63889b8b76 100644 +index a197337f2e09f53cf382022569c8836745d78769..54f5206b686c3cf4d2e5b470c07047a518f5dd00 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 { @@ -8236,38 +8289,38 @@ index 9aa5aa0d66257bf1413a904c516293aea30d2ca8..d152c50f17e2ab7a37b0c295c7f62e63 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.pufferfishRidable; ++ return level().purpurConfig.pufferfishRidable; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.pufferfishControllable; ++ return level().purpurConfig.pufferfishControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.pufferfishMaxHealth); ++ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.pufferfishMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.pufferfishTakeDamageFromWater; ++ return this.level().purpurConfig.pufferfishTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.pufferfishAlwaysDropExp; ++ return this.level().purpurConfig.pufferfishAlwaysDropExp; + } -+ // Purpur end + @Override protected void defineSynchedData() { super.defineSynchedData(); 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 2e75066db6cf4903f04428b73c4e868988776920..3395bc1d9140ab5496ad998343a963ae12f630d6 100644 +index 082351bd5f98d8738334b9164375f63fdc890455..81a33954aedffd18fcfa96babeaf6388715ab3f3 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Rabbit.java +++ b/src/main/java/net/minecraft/world/entity/animal/Rabbit.java -@@ -83,6 +83,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; @@ -8275,24 +8328,24 @@ index 2e75066db6cf4903f04428b73c4e868988776920..3395bc1d9140ab5496ad998343a963ae public Rabbit(EntityType type, Level world) { super(type, world); -@@ -91,6 +92,71 @@ public class Rabbit extends Animal implements VariantHolder { - this.initializePathFinderGoals(); // CraftBukkit - moved code +@@ -93,9 +94,75 @@ public class Rabbit extends Animal implements VariantHolder { + this.moveControl = new Rabbit.RabbitMoveControl(this); } + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.rabbitRidable; ++ return level().purpurConfig.rabbitRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.rabbitRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.rabbitRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.rabbitControllable; ++ return level().purpurConfig.rabbitControllable; + } + + @Override @@ -8325,40 +8378,37 @@ index 2e75066db6cf4903f04428b73c4e868988776920..3395bc1d9140ab5496ad998343a963ae + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.rabbitMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.rabbitMaxHealth); + } + + @Override + public int getPurpurBreedTime() { -+ return this.level.purpurConfig.rabbitBreedingTicks; ++ return this.level().purpurConfig.rabbitBreedingTicks; + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.rabbitTakeDamageFromWater; ++ return this.level().purpurConfig.rabbitTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.rabbitAlwaysDropExp; ++ return this.level().purpurConfig.rabbitAlwaysDropExp; + } + // Purpur end + - // CraftBukkit start - code from constructor - public void initializePathFinderGoals(){ - this.setSpeedModifier(0.0D); -@@ -100,6 +166,7 @@ public class Rabbit extends Animal implements VariantHolder { @Override public 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 ClimbOnTopOfPowderSnowGoal(this, this.level)); + 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)); -@@ -114,6 +181,13 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -110,6 +177,14 @@ public class Rabbit extends Animal implements VariantHolder { @Override protected float getJumpPower() { ++ // Purpur start + if (getRider() != null && this.isControllable()) { + if (getForwardMot() < 0) { + setSpeed(getForwardMot() * 2F); @@ -8366,10 +8416,10 @@ index 2e75066db6cf4903f04428b73c4e868988776920..3395bc1d9140ab5496ad998343a963ae + return actualJump ? 0.5F : 0.3F; + } + // Purpur end - if (!this.horizontalCollision && (!this.moveControl.hasWanted() || this.moveControl.getWantedY() <= this.getY() + 0.5D)) { - Path pathentity = this.navigation.getPath(); + float f = 0.3F; -@@ -132,7 +206,7 @@ public class Rabbit extends Animal implements VariantHolder { + if (this.horizontalCollision || this.moveControl.hasWanted() && this.moveControl.getWantedY() > this.getY() + 0.5D) { +@@ -134,7 +209,7 @@ public class Rabbit extends Animal implements VariantHolder { } @Override @@ -8378,7 +8428,7 @@ index 2e75066db6cf4903f04428b73c4e868988776920..3395bc1d9140ab5496ad998343a963ae super.jumpFromGround(); double d0 = this.moveControl.getSpeedModifier(); -@@ -182,6 +256,13 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -184,6 +259,13 @@ public class Rabbit extends Animal implements VariantHolder { @Override public void customServerAiStep() { @@ -8392,7 +8442,7 @@ index 2e75066db6cf4903f04428b73c4e868988776920..3395bc1d9140ab5496ad998343a963ae if (this.jumpDelayTicks > 0) { --this.jumpDelayTicks; } -@@ -399,10 +480,23 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -401,10 +483,23 @@ public class Rabbit extends Animal implements VariantHolder { } this.setVariant(entityrabbit_variant); @@ -8416,7 +8466,7 @@ index 2e75066db6cf4903f04428b73c4e868988776920..3395bc1d9140ab5496ad998343a963ae Holder holder = world.getBiome(pos); int i = world.getRandom().nextInt(100); -@@ -466,7 +560,7 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -468,7 +563,7 @@ public class Rabbit extends Animal implements VariantHolder { } } @@ -8425,13 +8475,13 @@ index 2e75066db6cf4903f04428b73c4e868988776920..3395bc1d9140ab5496ad998343a963ae private final Rabbit rabbit; private double nextJumpSpeed; -@@ -477,14 +571,14 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -479,14 +574,14 @@ public class Rabbit extends Animal implements VariantHolder { } @Override - public void tick() { + public void vanillaTick() { // Purpur - if (this.rabbit.onGround && !this.rabbit.jumping && !((Rabbit.RabbitJumpControl) this.rabbit.jumpControl).wantJump()) { + if (this.rabbit.onGround() && !this.rabbit.jumping && !((Rabbit.RabbitJumpControl) this.rabbit.jumpControl).wantJump()) { this.rabbit.setSpeedModifier(0.0D); } else if (this.hasWanted()) { this.rabbit.setSpeedModifier(this.nextJumpSpeed); @@ -8442,17 +8492,17 @@ index 2e75066db6cf4903f04428b73c4e868988776920..3395bc1d9140ab5496ad998343a963ae } @Override -@@ -546,7 +640,7 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -548,7 +643,7 @@ public class Rabbit extends Animal implements VariantHolder { @Override public boolean canUse() { if (this.nextStartTick <= 0) { -- if (!this.rabbit.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -+ if (!this.rabbit.level.purpurConfig.rabbitBypassMobGriefing && !this.rabbit.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur +- if (!this.rabbit.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ if (!this.rabbit.level().purpurConfig.rabbitBypassMobGriefing && !this.rabbit.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur return false; } diff --git a/src/main/java/net/minecraft/world/entity/animal/Salmon.java b/src/main/java/net/minecraft/world/entity/animal/Salmon.java -index 0af79daa357f53a8871e293b57e16c099e5d3f64..e0da8d1974f88e1426034620f78a29f9bdb5adf4 100644 +index 0af79daa357f53a8871e293b57e16c099e5d3f64..382e47f26ee94506cb76463a677351b9bdcf8040 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Salmon.java +++ b/src/main/java/net/minecraft/world/entity/animal/Salmon.java @@ -13,6 +13,33 @@ public class Salmon extends AbstractSchoolingFish { @@ -8462,77 +8512,77 @@ index 0af79daa357f53a8871e293b57e16c099e5d3f64..e0da8d1974f88e1426034620f78a29f9 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.salmonRidable; ++ return level().purpurConfig.salmonRidable; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.salmonControllable; ++ return level().purpurConfig.salmonControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.salmonMaxHealth); ++ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.salmonMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.salmonTakeDamageFromWater; ++ return this.level().purpurConfig.salmonTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.salmonAlwaysDropExp; ++ return this.level().purpurConfig.salmonAlwaysDropExp; + } -+ // Purpur end + @Override 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 fb3777e158065a6ce306a2a6e66bec053da2aeb4..9399361c8d26a140fa6042988a30a1d3d552e418 100644 +index c0e89262c596fbdd0bb3c3f76baccb17a1bb5fcd..54de1f782e45cb3e3b1442aeb56b6e8547b065c0 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Sheep.java +++ b/src/main/java/net/minecraft/world/entity/animal/Sheep.java -@@ -116,10 +116,48 @@ public class Sheep extends Animal implements Shearable { +@@ -117,10 +117,48 @@ public class Sheep extends Animal implements Shearable { super(type, world); } + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.sheepRidable; ++ return level().purpurConfig.sheepRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.sheepRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.sheepRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.sheepControllable; ++ return level().purpurConfig.sheepControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.sheepMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.sheepMaxHealth); + } + + @Override + public int getPurpurBreedTime() { -+ return this.level.purpurConfig.sheepBreedingTicks; ++ return this.level().purpurConfig.sheepBreedingTicks; + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.sheepTakeDamageFromWater; ++ return this.level().purpurConfig.sheepTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.sheepAlwaysDropExp; ++ return this.level().purpurConfig.sheepAlwaysDropExp; + } -+ // Purpur end + @Override protected void registerGoals() { @@ -8542,7 +8592,7 @@ index fb3777e158065a6ce306a2a6e66bec053da2aeb4..9399361c8d26a140fa6042988a30a1d3 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 { +@@ -255,7 +293,7 @@ public class Sheep extends Animal implements Shearable { return InteractionResult.PASS; } // CraftBukkit end @@ -8551,13 +8601,13 @@ index fb3777e158065a6ce306a2a6e66bec053da2aeb4..9399361c8d26a140fa6042988a30a1d3 this.gameEvent(GameEvent.SHEAR, player); itemstack.hurtAndBreak(1, player, (entityhuman1) -> { entityhuman1.broadcastBreakEvent(hand); -@@ -269,14 +307,15 @@ public class Sheep extends Animal implements Shearable { +@@ -270,14 +308,15 @@ public class Sheep extends Animal implements Shearable { } @Override - public void shear(SoundSource shearedSoundCategory) { + public void shear(SoundSource shearedSoundCategory, int looting) { // Purpur - this.level.playSound((Player) null, (Entity) this, SoundEvents.SHEEP_SHEAR, shearedSoundCategory, 1.0F, 1.0F); + this.level().playSound((Player) null, (Entity) this, SoundEvents.SHEEP_SHEAR, shearedSoundCategory, 1.0F, 1.0F); this.setSheared(true); int i = 1 + this.random.nextInt(3); + if (org.purpurmc.purpur.PurpurConfig.allowShearsLooting) i += looting; // Purpur @@ -8565,12 +8615,12 @@ index fb3777e158065a6ce306a2a6e66bec053da2aeb4..9399361c8d26a140fa6042988a30a1d3 for (int j = 0; j < i; ++j) { this.forceDrops = true; // CraftBukkit - ItemEntity entityitem = this.spawnAtLocation((ItemLike) Sheep.ITEM_BY_DYE.get(this.getColor()), 1); -+ ItemEntity entityitem = this.spawnAtLocation((ItemLike) Sheep.ITEM_BY_DYE.get(this.level.purpurConfig.sheepShearJebRandomColor && hasCustomName() && getCustomName().getString().equals("jeb_") ? DyeColor.random(this.level.random) : this.getColor()), 1); // Purpur ++ ItemEntity entityitem = this.spawnAtLocation((ItemLike) Sheep.ITEM_BY_DYE.get(this.level().purpurConfig.sheepShearJebRandomColor && hasCustomName() && getCustomName().getString().equals("jeb_") ? DyeColor.random(this.level().random) : this.getColor()), 1); // Purpur this.forceDrops = false; // CraftBukkit if (entityitem != null) { 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 5437571ce76c62e9cae841e99127867fffb39f43..34fa428268a863e8e36b6340a482ec67f1199efb 100644 +index 8adcfc8f6772a32b5915e4a07100e8eb735f907a..8b364fe9f3a3d47ae6daa331b8f16941ca17432a 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 @@ -8586,22 +8636,23 @@ index 5437571ce76c62e9cae841e99127867fffb39f43..34fa428268a863e8e36b6340a482ec67 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.snowGolemRidable; ++ return level().purpurConfig.snowGolemRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.snowGolemRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.snowGolemRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.snowGolemControllable; ++ return level().purpurConfig.snowGolemControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.snowGolemMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.snowGolemMaxHealth); + } + + @Nullable @@ -8615,15 +8666,14 @@ index 5437571ce76c62e9cae841e99127867fffb39f43..34fa428268a863e8e36b6340a482ec67 + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.snowGolemAlwaysDropExp; ++ return this.level().purpurConfig.snowGolemAlwaysDropExp; + } -+ // Purpur end + @Override protected void registerGoals() { - this.goalSelector.addGoal(1, new RangedAttackGoal(this, 1.25D, 20, 10.0F)); + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur -+ this.goalSelector.addGoal(1, new RangedAttackGoal(this, level.purpurConfig.snowGolemAttackDistance, level.purpurConfig.snowGolemSnowBallMin, level.purpurConfig.snowGolemSnowBallMax, level.purpurConfig.snowGolemSnowBallModifier)); // Purpur ++ this.goalSelector.addGoal(1, new RangedAttackGoal(this, level().purpurConfig.snowGolemAttackDistance, level().purpurConfig.snowGolemSnowBallMin, level().purpurConfig.snowGolemSnowBallMax, level().purpurConfig.snowGolemSnowBallModifier)); // Purpur this.goalSelector.addGoal(2, new WaterAvoidingRandomStrollGoal(this, 1.0D, 1.0000001E-5F)); this.goalSelector.addGoal(3, new LookAtPlayerGoal(this, Player.class, 6.0F)); this.goalSelector.addGoal(4, new RandomLookAroundGoal(this)); @@ -8650,7 +8700,7 @@ index 5437571ce76c62e9cae841e99127867fffb39f43..34fa428268a863e8e36b6340a482ec67 @Override public boolean isSensitiveToWater() { - return true; -+ return this.level.purpurConfig.snowGolemTakeDamageFromWater; // Purpur ++ return this.level().purpurConfig.snowGolemTakeDamageFromWater; // Purpur } @Override @@ -8658,12 +8708,12 @@ index 5437571ce76c62e9cae841e99127867fffb39f43..34fa428268a863e8e36b6340a482ec67 this.hurt(this.damageSources().melting, 1.0F); // CraftBukkit - DamageSource.BURN -> CraftEventFactory.MELTING } -- if (!this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -+ if (!this.level.purpurConfig.snowGolemBypassMobGriefing && !this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur +- if (!this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ if (!this.level().purpurConfig.snowGolemBypassMobGriefing && !this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur return; } -+ if (getRider() != null && this.isControllable() && !level.purpurConfig.snowGolemLeaveTrailWhenRidden) return; // Purpur - don't leave snow trail when being ridden ++ if (getRider() != null && this.isControllable() && !level().purpurConfig.snowGolemLeaveTrailWhenRidden) return; // Purpur - don't leave snow trail when being ridden BlockState iblockdata = Blocks.SNOW.defaultBlockState(); for (int i = 0; i < 4; ++i) { @@ -8678,20 +8728,20 @@ index 5437571ce76c62e9cae841e99127867fffb39f43..34fa428268a863e8e36b6340a482ec67 - this.shear(SoundSource.PLAYERS); + this.shear(SoundSource.PLAYERS, net.minecraft.world.item.enchantment.EnchantmentHelper.getMobLooting(player)); // Purpur this.gameEvent(GameEvent.SHEAR, player); - if (!this.level.isClientSide) { + if (!this.level().isClientSide) { itemstack.hurtAndBreak(1, player, (entityhuman1) -> { @@ -166,17 +208,27 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM } - return InteractionResult.sidedSuccess(this.level.isClientSide); -+ // Purpur start -+ } else if (level.purpurConfig.snowGolemPutPumpkinBack && !hasPumpkin() && itemstack.getItem() == Blocks.CARVED_PUMPKIN.asItem()) { + return InteractionResult.sidedSuccess(this.level().isClientSide); ++ // Purpur start ++ } else if (level().purpurConfig.snowGolemPutPumpkinBack && !hasPumpkin() && itemstack.getItem() == Blocks.CARVED_PUMPKIN.asItem()) { + setPumpkin(true); + if (!player.getAbilities().instabuild) { + itemstack.shrink(1); + } + return InteractionResult.SUCCESS; -+ // Purpur end ++ // Purpur end } else { - return InteractionResult.PASS; + return tryRide(player, hand); // Purpur @@ -8701,24 +8751,24 @@ index 5437571ce76c62e9cae841e99127867fffb39f43..34fa428268a863e8e36b6340a482ec67 @Override - public void shear(SoundSource shearedSoundCategory) { + public void shear(SoundSource shearedSoundCategory, int looting) { // Purpur - this.level.playSound((Player) null, (Entity) this, SoundEvents.SNOW_GOLEM_SHEAR, shearedSoundCategory, 1.0F, 1.0F); - if (!this.level.isClientSide()) { + this.level().playSound((Player) null, (Entity) this, SoundEvents.SNOW_GOLEM_SHEAR, shearedSoundCategory, 1.0F, 1.0F); + if (!this.level().isClientSide()) { this.setPumpkin(false); this.forceDrops = true; // CraftBukkit -+ if (level.purpurConfig.snowGolemDropsPumpkin) // Purpur ++ if (level().purpurConfig.snowGolemDropsPumpkin) // Purpur + for (int i = 0; i < 1 + (org.purpurmc.purpur.PurpurConfig.allowShearsLooting ? looting : 0); i++) // Purpur this.spawnAtLocation(new ItemStack(Items.CARVED_PUMPKIN), 1.7F); this.forceDrops = false; // CraftBukkit } 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 72eea6e512060fc622ca79ca87437f19a64604cc..31c89a6b8f766e1fd03608723c2d03f7f64e2e9b 100644 +index f60c4cd0543fd5d50fa7e2c1a9e8381227adb540..dd7f2beabf0edad4143ac2365ac04a22edf1f75e 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Squid.java +++ b/src/main/java/net/minecraft/world/entity/animal/Squid.java -@@ -46,13 +46,66 @@ public class Squid extends WaterAnimal { +@@ -44,13 +44,66 @@ public class Squid extends WaterAnimal { public Squid(EntityType type, Level world) { super(type, world); -- //this.random.setSeed((long) this.getId()); // Paper - we set the random to shared, do not clobber the seed +- //this.random.setSeed((long)this.getId()); // Paper - we set the random to shared, do not clobber the seed + if (!world.purpurConfig.entitySharedRandom) this.random.setSeed((long) this.getId()); // Paper - we set the random to shared, do not clobber the seed // Purpur this.tentacleSpeed = 1.0F / (this.random.nextFloat() + 1.0F) * 0.2F; } @@ -8726,12 +8776,12 @@ index 72eea6e512060fc622ca79ca87437f19a64604cc..31c89a6b8f766e1fd03608723c2d03f7 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.squidRidable; ++ return level().purpurConfig.squidRidable; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.squidControllable; ++ return level().purpurConfig.squidControllable; + } + + protected void rotateVectorAroundY(org.bukkit.util.Vector vector, double degrees) { @@ -8743,20 +8793,21 @@ index 72eea6e512060fc622ca79ca87437f19a64604cc..31c89a6b8f766e1fd03608723c2d03f7 + vector.setX(cos * x - sine * z); + vector.setZ(sine * x + cos * z); + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.squidMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.squidMaxHealth); + } + + @Override + public net.minecraft.world.phys.AABB getAxisForFluidCheck() { + // Stops squids from floating just over the water -+ return super.getAxisForFluidCheck().offsetY(level.purpurConfig.squidOffsetWaterCheck); ++ return super.getAxisForFluidCheck().offsetY(level().purpurConfig.squidOffsetWaterCheck); + } + + public boolean canFly() { -+ return this.level.purpurConfig.squidsCanFly; ++ return this.level().purpurConfig.squidsCanFly; + } + + @Override @@ -8766,14 +8817,13 @@ index 72eea6e512060fc622ca79ca87437f19a64604cc..31c89a6b8f766e1fd03608723c2d03f7 + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.squidTakeDamageFromWater; ++ return this.level().purpurConfig.squidTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.squidAlwaysDropExp; ++ return this.level().purpurConfig.squidAlwaysDropExp; + } -+ // Purpur end + @Override protected void registerGoals() { @@ -8782,15 +8832,15 @@ index 72eea6e512060fc622ca79ca87437f19a64604cc..31c89a6b8f766e1fd03608723c2d03f7 this.goalSelector.addGoal(1, new Squid.SquidFleeGoal()); } -@@ -121,6 +174,7 @@ public class Squid extends WaterAnimal { +@@ -119,6 +172,7 @@ public class Squid extends WaterAnimal { } if (this.isInWaterOrBubble()) { + if (canFly()) setNoGravity(!wasTouchingWater); // Purpur - if (this.tentacleMovement < 3.1415927F) { - float f = this.tentacleMovement / 3.1415927F; - -@@ -244,11 +298,43 @@ public class Squid extends WaterAnimal { + 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; +@@ -298,10 +352,41 @@ public class Squid extends WaterAnimal { @Override public void tick() { @@ -8825,18 +8875,16 @@ index 72eea6e512060fc622ca79ca87437f19a64604cc..31c89a6b8f766e1fd03608723c2d03f7 + return; + } + // Purpur end -+ int i = this.squid.getNoActionTime(); - if (i > 100) { this.squid.setMovementVector(0.0F, 0.0F, 0.0F); - } else if (this.squid.getRandom().nextInt(reducedTickDelay(50)) == 0 || !this.squid.wasTouchingWater || !this.squid.hasMovementVector()) { + } else if (this.squid.getRandom().nextInt(reducedTickDelay(50)) == 0 || !this.squid.isInWater() || !this.squid.hasMovementVector()) { // Purpur - float f = this.squid.getRandom().nextFloat() * 6.2831855F; - float f1 = Mth.cos(f) * 0.2F; - float f2 = -0.1F + this.squid.getRandom().nextFloat() * 0.2F; + float f = this.squid.getRandom().nextFloat() * ((float)Math.PI * 2F); + 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 b05b560b7570e97bc234b75f26233909fcf575b3..e4b4bf5ef228c0460fdab966d4c9b5c428f78b9a 100644 +index b05b560b7570e97bc234b75f26233909fcf575b3..87b6f6b10ba6e3d9c6a42298a2019a526a183d90 100644 --- a/src/main/java/net/minecraft/world/entity/animal/TropicalFish.java +++ b/src/main/java/net/minecraft/world/entity/animal/TropicalFish.java @@ -42,6 +42,33 @@ public class TropicalFish extends AbstractSchoolingFish implements VariantHolder @@ -8846,35 +8894,35 @@ index b05b560b7570e97bc234b75f26233909fcf575b3..e4b4bf5ef228c0460fdab966d4c9b5c4 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.tropicalFishRidable; ++ return level().purpurConfig.tropicalFishRidable; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.tropicalFishControllable; ++ return level().purpurConfig.tropicalFishControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.tropicalFishMaxHealth); ++ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.tropicalFishMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.tropicalFishTakeDamageFromWater; ++ return this.level().purpurConfig.tropicalFishTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.tropicalFishAlwaysDropExp; ++ return this.level().purpurConfig.tropicalFishAlwaysDropExp; + } -+ // Purpur end + public static String getPredefinedName(int variant) { 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 81dab77f525ae667614f940c4ff5ec308a9579a2..52eff7a4d3a34a566bc3bc03e6643c494c757156 100644 +index d3c15d029d5f003cba3c89f7ea1f3ed4f943f2bd..1502f13acd0a104efe470e605826213ea92af191 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java +++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java @@ -83,6 +83,43 @@ public class Turtle extends Animal { @@ -8884,39 +8932,39 @@ index 81dab77f525ae667614f940c4ff5ec308a9579a2..52eff7a4d3a34a566bc3bc03e6643c49 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.turtleRidable; ++ return level().purpurConfig.turtleRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.turtleRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.turtleRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.turtleControllable; ++ return level().purpurConfig.turtleControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.turtleMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.turtleMaxHealth); + } + + @Override + public int getPurpurBreedTime() { -+ return this.level.purpurConfig.turtleBreedingTicks; ++ return this.level().purpurConfig.turtleBreedingTicks; + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.turtleTakeDamageFromWater; ++ return this.level().purpurConfig.turtleTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.turtleAlwaysDropExp; ++ return this.level().purpurConfig.turtleAlwaysDropExp; + } -+ // Purpur end + public void setHomePos(BlockPos pos) { this.entityData.set(Turtle.HOME_POS, pos.immutable()); // Paper - called with mutablepos... @@ -8976,7 +9024,7 @@ index 81dab77f525ae667614f940c4ff5ec308a9579a2..52eff7a4d3a34a566bc3bc03e6643c49 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/WaterAnimal.java b/src/main/java/net/minecraft/world/entity/animal/WaterAnimal.java -index 35cfa366baf6747105faa93f1220bb9cc31a5bd5..ff3a6755d04f2280a36bd363ab1722e074e37194 100644 +index cd2ce5bcb8c30e4657cd0e340d80544c7e805905..c8c6fed3f93903bb5c6145930538d415f6f59738 100644 --- a/src/main/java/net/minecraft/world/entity/animal/WaterAnimal.java +++ b/src/main/java/net/minecraft/world/entity/animal/WaterAnimal.java @@ -82,6 +82,6 @@ public abstract class WaterAnimal extends PathfinderMob { @@ -8988,7 +9036,7 @@ index 35cfa366baf6747105faa93f1220bb9cc31a5bd5..ff3a6755d04f2280a36bd363ab1722e0 } } 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 612601b2536dc522356d4dd2c2ea1192f6435f72..e0ca657b0aea52ab6a91c256c1bfad1e5028f6e0 100644 +index 57ceec70bb150afaa66962090b142048d5b50c2f..64bceae4d06b35fcbecb0daca2496ba30e39d995 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; @@ -9036,7 +9084,7 @@ index 612601b2536dc522356d4dd2c2ea1192f6435f72..e0ca657b0aea52ab6a91c256c1bfad1e import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.level.pathfinder.BlockPathTypes; -@@ -83,6 +90,37 @@ public class Wolf extends TamableAnimal implements NeutralMob { +@@ -84,6 +91,37 @@ public class Wolf extends TamableAnimal implements NeutralMob { return entitytypes == EntityType.SHEEP || entitytypes == EntityType.RABBIT || entitytypes == EntityType.FOX; }; @@ -9074,19 +9122,19 @@ index 612601b2536dc522356d4dd2c2ea1192f6435f72..e0ca657b0aea52ab6a91c256c1bfad1e private static final float START_HEALTH = 8.0F; private static final float TAME_HEALTH = 20.0F; private float interestedAngle; -@@ -102,12 +140,93 @@ public class Wolf extends TamableAnimal implements NeutralMob { +@@ -103,12 +141,93 @@ public class Wolf extends TamableAnimal implements NeutralMob { this.setPathfindingMalus(BlockPathTypes.DANGER_POWDER_SNOW, -1.0F); } + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.wolfRidable; ++ return level().purpurConfig.wolfRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.wolfRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.wolfRidableInWater; + } + + public void onMount(Player rider) { @@ -9096,17 +9144,18 @@ index 612601b2536dc522356d4dd2c2ea1192f6435f72..e0ca657b0aea52ab6a91c256c1bfad1e + + @Override + public boolean isControllable() { -+ return level.purpurConfig.wolfControllable; ++ return level().purpurConfig.wolfControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.wolfMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.wolfMaxHealth); + } + + @Override + public int getPurpurBreedTime() { -+ return this.level.purpurConfig.wolfBreedingTicks; ++ return this.level().purpurConfig.wolfBreedingTicks; + } + + public boolean isRabid() { @@ -9142,20 +9191,19 @@ index 612601b2536dc522356d4dd2c2ea1192f6435f72..e0ca657b0aea52ab6a91c256c1bfad1e + + @Override + public void tame(Player player) { -+ setCollarColor(level.purpurConfig.wolfDefaultCollarColor); ++ setCollarColor(level().purpurConfig.wolfDefaultCollarColor); + super.tame(player); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.wolfTakeDamageFromWater; ++ return this.level().purpurConfig.wolfTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.wolfAlwaysDropExp; ++ return this.level().purpurConfig.wolfAlwaysDropExp; + } -+ // Purpur end + @Override protected void registerGoals() { @@ -9168,7 +9216,7 @@ index 612601b2536dc522356d4dd2c2ea1192f6435f72..e0ca657b0aea52ab6a91c256c1bfad1e 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)); -@@ -116,11 +235,12 @@ public class Wolf extends TamableAnimal implements NeutralMob { +@@ -117,11 +236,12 @@ public class Wolf extends TamableAnimal implements NeutralMob { this.goalSelector.addGoal(9, new BegGoal(this, 8.0F)); this.goalSelector.addGoal(10, new LookAtPlayerGoal(this, Player.class, 8.0F)); this.goalSelector.addGoal(10, new RandomLookAroundGoal(this)); @@ -9182,7 +9230,7 @@ index 612601b2536dc522356d4dd2c2ea1192f6435f72..e0ca657b0aea52ab6a91c256c1bfad1e this.targetSelector.addGoal(6, new NonTameRandomTargetGoal<>(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)); -@@ -165,6 +285,7 @@ public class Wolf extends TamableAnimal implements NeutralMob { +@@ -148,6 +268,7 @@ public class Wolf extends TamableAnimal implements NeutralMob { public void addAdditionalSaveData(CompoundTag nbt) { super.addAdditionalSaveData(nbt); nbt.putByte("CollarColor", (byte) this.getCollarColor().getId()); @@ -9190,7 +9238,7 @@ index 612601b2536dc522356d4dd2c2ea1192f6435f72..e0ca657b0aea52ab6a91c256c1bfad1e this.addPersistentAngerSaveData(nbt); } -@@ -174,6 +295,10 @@ public class Wolf extends TamableAnimal implements NeutralMob { +@@ -157,6 +278,10 @@ public class Wolf extends TamableAnimal implements NeutralMob { if (nbt.contains("CollarColor", 99)) { this.setCollarColor(DyeColor.byId(nbt.getInt("CollarColor"))); } @@ -9199,9 +9247,9 @@ index 612601b2536dc522356d4dd2c2ea1192f6435f72..e0ca657b0aea52ab6a91c256c1bfad1e + this.updatePathfinders(false); + // Purpur end - this.readPersistentAngerSaveData(this.level, nbt); + this.readPersistentAngerSaveData(this.level(), nbt); } -@@ -218,6 +343,11 @@ public class Wolf extends TamableAnimal implements NeutralMob { +@@ -201,6 +326,11 @@ public class Wolf extends TamableAnimal implements NeutralMob { public void tick() { super.tick(); if (this.isAlive()) { @@ -9213,41 +9261,40 @@ index 612601b2536dc522356d4dd2c2ea1192f6435f72..e0ca657b0aea52ab6a91c256c1bfad1e this.interestedAngleO = this.interestedAngle; if (this.isInterested()) { this.interestedAngle += (1.0F - this.interestedAngle) * 0.4F; -@@ -412,7 +542,7 @@ public class Wolf extends TamableAnimal implements NeutralMob { - } - - // CraftBukkit - added event call and isCancelled check. -- if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { -+ if ((this.level.purpurConfig.alwaysTameInCreative && player.getAbilities().instabuild) || (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, player).isCancelled())) { // Purpur - this.tame(player); - this.navigation.stop(); - this.setTarget((LivingEntity) null); -@@ -424,6 +554,20 @@ public class Wolf extends TamableAnimal implements NeutralMob { - - return InteractionResult.SUCCESS; +@@ -405,7 +535,7 @@ public class Wolf extends TamableAnimal implements NeutralMob { } -+ // Purpur start -+ else if (this.level.purpurConfig.wolfMilkCuresRabies && itemstack.getItem() == Items.MILK_BUCKET && this.isRabid()) { -+ if (!player.isCreative()) { -+ player.setItemInHand(hand, new ItemStack(Items.BUCKET)); -+ } -+ this.setRabid(false); -+ for (int i = 0; i < 10; ++i) { -+ ((ServerLevel) level).sendParticles(((ServerLevel) level).players(), null, ParticleTypes.HAPPY_VILLAGER, -+ getX() + random.nextFloat(), getY() + (random.nextFloat() * 1.5), getZ() + random.nextFloat(), 1, -+ random.nextGaussian() * 0.05D, random.nextGaussian() * 0.05D, random.nextGaussian() * 0.05D, 0, true); -+ } -+ return InteractionResult.SUCCESS; -+ } -+ // Purpur end + // CraftBukkit - added event call and isCancelled check. +- if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { ++ if ((this.level().purpurConfig.alwaysTameInCreative && player.getAbilities().instabuild) || (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, player).isCancelled())) { // Purpur + this.tame(player); + this.navigation.stop(); + this.setTarget((LivingEntity) null); +@@ -416,6 +546,19 @@ public class Wolf extends TamableAnimal implements NeutralMob { + } + + return InteractionResult.SUCCESS; ++ // Purpur start ++ } else if (this.level().purpurConfig.wolfMilkCuresRabies && itemstack.getItem() == Items.MILK_BUCKET && this.isRabid()) { ++ if (!player.isCreative()) { ++ player.setItemInHand(hand, new ItemStack(Items.BUCKET)); ++ } ++ this.setRabid(false); ++ for (int i = 0; i < 10; ++i) { ++ ((ServerLevel) level()).sendParticles(((ServerLevel) level()).players(), null, ParticleTypes.HAPPY_VILLAGER, ++ getX() + random.nextFloat(), getY() + (random.nextFloat() * 1.5), getZ() + random.nextFloat(), 1, ++ random.nextGaussian() * 0.05D, random.nextGaussian() * 0.05D, random.nextGaussian() * 0.05D, 0, true); ++ } ++ return InteractionResult.SUCCESS; ++ // Purpur end + } else { return super.mobInteract(player, hand); } 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 a41d8101c960163803179d3717889aee6182d0bb..e95540122ae6a486ce12a5f50fb4d2d073239554 100644 +index 1a0eee3b766a5ce5623c32ed9c023a0f80db1d1a..7166f4a39fd615e10d7b1f53c57363832a41f365 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 -@@ -101,10 +101,23 @@ public class Allay extends PathfinderMob implements InventoryCarrier { +@@ -101,10 +101,23 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS private float spinningAnimationTicks; private float spinningAnimationTicks0; public boolean forceDancing = false; // CraftBukkit @@ -9270,26 +9317,26 @@ index a41d8101c960163803179d3717889aee6182d0bb..e95540122ae6a486ce12a5f50fb4d2d0 + }; + // Purpur end this.setCanPickUpLoot(this.canPickUpLoot()); - EntityPositionSource entitypositionsource = new EntityPositionSource(this, this.getEyeHeight()); - -@@ -119,6 +132,28 @@ public class Allay extends PathfinderMob implements InventoryCarrier { + this.vibrationUser = new Allay.VibrationUser(); + this.vibrationData = new VibrationSystem.Data(); +@@ -118,6 +131,28 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS } // CraftBukkit end + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.allayRidable; ++ return level().purpurConfig.allayRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.allayRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.allayRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.allayControllable; ++ return level().purpurConfig.allayControllable; + } + + @Override @@ -9301,33 +9348,34 @@ index a41d8101c960163803179d3717889aee6182d0bb..e95540122ae6a486ce12a5f50fb4d2d0 @Override protected Brain.Provider brainProvider() { return Brain.provider(Allay.MEMORY_TYPES, Allay.SENSOR_TYPES); -@@ -226,13 +261,13 @@ public class Allay extends PathfinderMob implements InventoryCarrier { +@@ -225,13 +260,13 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { -- this.level.getProfiler().push("allayBrain"); -+ //this.level.getProfiler().push("allayBrain"); // Purpur - if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish - this.getBrain().tick((ServerLevel) this.level, this); -- this.level.getProfiler().pop(); -- this.level.getProfiler().push("allayActivityUpdate"); -+ //this.level.getProfiler().pop(); // Purpur -+ //this.level.getProfiler().push("allayActivityUpdate"); // Purpur +- this.level().getProfiler().push("allayBrain"); +- if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish ++ //this.level().getProfiler().push("allayBrain"); // Purpur ++ 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); +- this.level().getProfiler().pop(); +- this.level().getProfiler().push("allayActivityUpdate"); ++ //this.level().getProfiler().pop(); // Purpur ++ //this.level().getProfiler().push("allayActivityUpdate"); // Purpur AllayAi.updateActivity(this); -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur super.customServerAiStep(); } -@@ -374,9 +409,31 @@ public class Allay extends PathfinderMob implements InventoryCarrier { +@@ -372,9 +407,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); +- 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)) { ++ if (!this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { + return false; + } + ItemStack itemStack = this.getItemInHand(InteractionHand.MAIN_HAND); @@ -9340,7 +9388,7 @@ index a41d8101c960163803179d3717889aee6182d0bb..e95540122ae6a486ce12a5f50fb4d2d0 + if (!this.inventory.canAddItem(stack)) { + return false; + } -+ for (String tag : this.level.purpurConfig.allayRespectNBT) { ++ for (String tag : this.level().purpurConfig.allayRespectNBT) { + if (stack.hasTag() && itemStack.hasTag()) { + Tag tag1 = stack.getTag().get(tag); + Tag tag2 = itemStack.getTag().get(tag); @@ -9355,7 +9403,7 @@ index a41d8101c960163803179d3717889aee6182d0bb..e95540122ae6a486ce12a5f50fb4d2d0 private boolean allayConsidersItemEqual(ItemStack stack, ItemStack stack2) { 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 38d21943fb2940f53c2d0ac2c3b94a6f0e46e700..18ce5389040b516a7061d2d8e104f400183fdeec 100644 +index 42e22a4b9cb6841de04862cc81454da3232aa65a..07abf72b7aed98652ac6639b26ade358fcd9135a 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() { @@ -9406,17 +9454,18 @@ index 38d21943fb2940f53c2d0ac2c3b94a6f0e46e700..18ce5389040b516a7061d2d8e104f400 private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { -- this.level.getProfiler().push("axolotlBrain"); -+ //this.level.getProfiler().push("axolotlBrain"); // Purpur - if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish - this.getBrain().tick((ServerLevel) this.level, this); -- this.level.getProfiler().pop(); -- this.level.getProfiler().push("axolotlActivityUpdate"); -+ //this.level.getProfiler().pop(); // Purpur -+ //this.level.getProfiler().push("axolotlActivityUpdate"); // Purpur +- this.level().getProfiler().push("axolotlBrain"); +- if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish ++ //this.level().getProfiler().push("axolotlBrain"); // Purpur ++ 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); +- this.level().getProfiler().pop(); +- this.level().getProfiler().push("axolotlActivityUpdate"); ++ //this.level().getProfiler().pop(); // Purpur ++ //this.level().getProfiler().push("axolotlActivityUpdate"); // Purpur AxolotlAi.updateActivity(this); -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur if (!this.isNoAi()) { Optional optional = this.getBrain().getMemory(MemoryModuleType.PLAY_DEAD_TICKS); @@ -9456,59 +9505,63 @@ index 38d21943fb2940f53c2d0ac2c3b94a6f0e46e700..18ce5389040b516a7061d2d8e104f400 } diff --git a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java -index 05c7680569346bb863b896bcc9515f3e7cfb8114..31922ac1139f34e0da61a719e3645c1aaa188890 100644 +index 4efa7e331cc974008c653a04687a336e97626445..9f19ebfa6392a080672c472e08f755379e9776b4 100644 --- a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java +++ b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java -@@ -83,6 +83,13 @@ public class Camel extends AbstractHorse implements PlayerRideableJumping, Rider +@@ -84,6 +84,17 @@ public class Camel extends AbstractHorse implements PlayerRideableJumping, Rider groundPathNavigation.setCanWalkOverFences(true); } + // Purpur start + @Override ++ public boolean dismountsUnderwater() { ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.camelRidableInWater; ++ } ++ + public int getPurpurBreedTime() { -+ return this.level.purpurConfig.camelBreedingTicks; ++ return this.level().purpurConfig.camelBreedingTicks; + } + // Purpur end + @Override public void addAdditionalSaveData(CompoundTag nbt) { super.addAdditionalSaveData(nbt); -@@ -149,13 +156,13 @@ public class Camel extends AbstractHorse implements PlayerRideableJumping, Rider +@@ -150,13 +161,13 @@ public class Camel extends AbstractHorse implements PlayerRideableJumping, Rider @Override protected void customServerAiStep() { -- this.level.getProfiler().push("camelBrain"); -+ //this.level.getProfiler().push("camelBrain"); // Purpur +- this.level().getProfiler().push("camelBrain"); ++ //this.level().getProfiler().push("camelBrain"); // Purpur Brain brain = (Brain) this.getBrain(); // Paper - decompile fix - brain.tick((ServerLevel)this.level, this); -- this.level.getProfiler().pop(); -- this.level.getProfiler().push("camelActivityUpdate"); -+ //this.level.getProfiler().pop(); // Purpur -+ //this.level.getProfiler().push("camelActivityUpdate"); // Purpur + brain.tick((ServerLevel)this.level(), this); +- this.level().getProfiler().pop(); +- this.level().getProfiler().push("camelActivityUpdate"); ++ //this.level().getProfiler().pop(); // Purpur ++ //this.level().getProfiler().push("camelActivityUpdate"); // Purpur CamelAi.updateActivity(this); -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur super.customServerAiStep(); } -@@ -314,6 +321,23 @@ public class Camel extends AbstractHorse implements PlayerRideableJumping, Rider +@@ -319,6 +330,23 @@ public class Camel extends AbstractHorse implements PlayerRideableJumping, Rider return this.dashCooldown; } + // Purpur start + @Override + public float generateMaxHealth(net.minecraft.util.RandomSource random) { -+ return (float) generateMaxHealth(this.level.purpurConfig.camelMaxHealthMin, this.level.purpurConfig.camelMaxHealthMax); ++ return (float) generateMaxHealth(this.level().purpurConfig.camelMaxHealthMin, this.level().purpurConfig.camelMaxHealthMax); + } + + @Override + public double generateJumpStrength(net.minecraft.util.RandomSource random) { -+ return generateJumpStrength(this.level.purpurConfig.camelJumpStrengthMin, this.level.purpurConfig.camelJumpStrengthMax); ++ return generateJumpStrength(this.level().purpurConfig.camelJumpStrengthMin, this.level().purpurConfig.camelJumpStrengthMax); + } + + @Override + public double generateSpeed(net.minecraft.util.RandomSource random) { -+ return generateSpeed(this.level.purpurConfig.camelMovementSpeedMin, this.level.purpurConfig.camelMovementSpeedMax); ++ return generateSpeed(this.level().purpurConfig.camelMovementSpeedMin, this.level().purpurConfig.camelMovementSpeedMax); + } + // Purpur end + @@ -9516,10 +9569,10 @@ index 05c7680569346bb863b896bcc9515f3e7cfb8114..31922ac1139f34e0da61a719e3645c1a protected SoundEvent getAmbientSound() { return SoundEvents.CAMEL_AMBIENT; diff --git a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java -index be44667b8205cd3bb1cefddf8e0e743535414e14..c355aaed76663d37a5da8b2f49f9808828b4ef9b 100644 +index 80ddb3059d6484c2b90c55ef601043798f1a4b50..dc1e8bcd8049d79c0e383ccd6a5697f79a3a2ebd 100644 --- a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java +++ b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java -@@ -82,16 +82,69 @@ public class Frog extends Animal implements VariantHolder { +@@ -77,16 +77,69 @@ 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(); @@ -9558,17 +9611,17 @@ index be44667b8205cd3bb1cefddf8e0e743535414e14..c355aaed76663d37a5da8b2f49f98088 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.frogRidable; ++ return level().purpurConfig.frogRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.frogRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.frogRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.frogControllable; ++ return level().purpurConfig.frogControllable; + } + + @Override @@ -9579,36 +9632,37 @@ index be44667b8205cd3bb1cefddf8e0e743535414e14..c355aaed76663d37a5da8b2f49f98088 + + @Override + public float getJumpPower() { -+ return (getRider() != null && isControllable()) ? level.purpurConfig.frogRidableJumpHeight * this.getBlockJumpFactor() : super.getJumpPower(); -+ } -+ -+ public int getPurpurBreedTime() { -+ return this.level.purpurConfig.frogBreedingTicks; ++ return (getRider() != null && isControllable()) ? level().purpurConfig.frogRidableJumpHeight * this.getBlockJumpFactor() : super.getJumpPower(); + } + // Purpur end ++ ++ public int getPurpurBreedTime() { ++ return this.level().purpurConfig.frogBreedingTicks; ++ } + @Override protected Brain.Provider brainProvider() { return Brain.provider(MEMORY_TYPES, SENSOR_TYPES); -@@ -170,13 +223,13 @@ public class Frog extends Animal implements VariantHolder { +@@ -165,13 +218,13 @@ public class Frog extends Animal implements VariantHolder { private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { -- this.level.getProfiler().push("frogBrain"); -+ //this.level.getProfiler().push("frogBrain"); // Purpur - if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish - this.getBrain().tick((ServerLevel)this.level, this); -- this.level.getProfiler().pop(); -- this.level.getProfiler().push("frogActivityUpdate"); -+ //this.level.getProfiler().pop(); // Purpur -+ //this.level.getProfiler().push("frogActivityUpdate"); // Purpur +- this.level().getProfiler().push("frogBrain"); +- if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish ++ //this.level().getProfiler().push("frogBrain"); // Purpur ++ 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); +- this.level().getProfiler().pop(); +- this.level().getProfiler().push("frogActivityUpdate"); ++ //this.level().getProfiler().pop(); // Purpur ++ //this.level().getProfiler().push("frogActivityUpdate"); // Purpur FrogAi.updateActivity(this); -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur super.customServerAiStep(); } -@@ -376,7 +429,7 @@ public class Frog extends Animal implements VariantHolder { +@@ -347,7 +400,7 @@ public class Frog extends Animal implements VariantHolder { return world.getBlockState(pos.below()).is(BlockTags.FROGS_SPAWNABLE_ON) && isBrightEnoughToSpawn(world, pos); } @@ -9618,7 +9672,7 @@ index be44667b8205cd3bb1cefddf8e0e743535414e14..c355aaed76663d37a5da8b2f49f98088 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 e591b0a09f5a8475b3ec9cd28bd5d5b69809ed73..aadc6743deb195ac3368548a75be641ffd3da404 100644 +index 6ed4ac06c76b8d0d6e8db778cade15dbd1e3e5f5..6b012bea26e8ef0c04571f43da67f6e108188830 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 @@ -45,13 +45,50 @@ public class Tadpole extends AbstractFish { @@ -9651,17 +9705,17 @@ index e591b0a09f5a8475b3ec9cd28bd5d5b69809ed73..aadc6743deb195ac3368548a75be641f + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.tadpoleRidable; ++ return level().purpurConfig.tadpoleRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.tadpoleRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.tadpoleRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.tadpoleControllable; ++ return level().purpurConfig.tadpoleControllable; + } + + @Override @@ -9677,84 +9731,85 @@ index e591b0a09f5a8475b3ec9cd28bd5d5b69809ed73..aadc6743deb195ac3368548a75be641f private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { -- this.level.getProfiler().push("tadpoleBrain"); -+ //this.level.getProfiler().push("tadpoleBrain"); // Purpur - if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish - this.getBrain().tick((ServerLevel) this.level, this); -- this.level.getProfiler().pop(); -- this.level.getProfiler().push("tadpoleActivityUpdate"); -+ //this.level.getProfiler().pop(); // Purpur -+ //this.level.getProfiler().push("tadpoleActivityUpdate"); // Purpur +- this.level().getProfiler().push("tadpoleBrain"); +- if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish ++ //this.level().getProfiler().push("tadpoleBrain"); // Purpur ++ 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); +- this.level().getProfiler().pop(); +- this.level().getProfiler().push("tadpoleActivityUpdate"); ++ //this.level().getProfiler().pop(); // Purpur ++ //this.level().getProfiler().push("tadpoleActivityUpdate"); // Purpur TadpoleAi.updateActivity(this); -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur 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 4fdc3bd591b6df4c28901e4571aa23baf034d885..f5c0fc9f30bdf7935200b875ada0ff1011fdb034 100644 +index 7f21d1d400c8a5615ed1a787dcb0680338f8c28d..b04af8b72357b455597d80592c8b8b0c9da744cd 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 -@@ -89,6 +89,38 @@ public class Goat extends Animal { +@@ -90,6 +90,38 @@ public class Goat extends Animal { return InstrumentItem.create(Items.GOAT_HORN, (Holder) holderset.getRandomElement(randomsource).get()); } + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.goatRidable; ++ return level().purpurConfig.goatRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.goatRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.goatRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.goatControllable; ++ return level().purpurConfig.goatControllable; + } ++ // Purpur end + + @Override + public int getPurpurBreedTime() { -+ return this.level.purpurConfig.goatBreedingTicks; ++ return this.level().purpurConfig.goatBreedingTicks; + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.goatTakeDamageFromWater; ++ return this.level().purpurConfig.goatTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.goatAlwaysDropExp; ++ return this.level().purpurConfig.goatAlwaysDropExp; + } -+ // Purpur end + @Override protected Brain.Provider brainProvider() { return Brain.provider(Goat.MEMORY_TYPES, Goat.SENSOR_TYPES); -@@ -191,13 +223,14 @@ public class Goat extends Animal { +@@ -192,13 +224,14 @@ public class Goat extends Animal { private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { -- this.level.getProfiler().push("goatBrain"); +- this.level().getProfiler().push("goatBrain"); - if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish -+ //this.level.getProfiler().push("goatBrain"); // Purpur -+ 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); -- this.level.getProfiler().pop(); -- this.level.getProfiler().push("goatActivityUpdate"); -+ //this.level.getProfiler().pop -+ // (); // Purpur -+ //this.level.getProfiler().push("goatActivityUpdate"); // Purpur ++ //this.level().getProfiler().push("goatBrain"); // Purpur ++ if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider // Purpur - TODO: Uncomment when pufferfish patch ++ //if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider // Purpur - TODO: Uncomment when pufferfish patch + this.getBrain().tick((ServerLevel) this.level(), this); +- this.level().getProfiler().pop(); +- this.level().getProfiler().push("goatActivityUpdate"); ++ //this.level().getProfiler().pop(); // Purpur ++ //this.level().getProfiler().push("goatActivityUpdate"); // Purpur GoatAi.updateActivity(this); -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur super.customServerAiStep(); } -@@ -389,6 +422,7 @@ public class Goat extends Animal { +@@ -390,6 +423,7 @@ public class Goat extends Animal { // Paper start - Goat ram API public void ram(net.minecraft.world.entity.LivingEntity entity) { @@ -9763,10 +9818,10 @@ index 4fdc3bd591b6df4c28901e4571aa23baf034d885..f5c0fc9f30bdf7935200b875ada0ff10 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 47cd69f91bbc2e2be9ec970674adc522e21593c8..c044ed3a96f10584fd5aec836624bca1b414182d 100644 +index 49d7109b6ca63c8073db777549a65b2fcb70967e..fdf41f4990923aa4309febb9c0ca8009de8e16f1 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 -@@ -144,12 +144,60 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, +@@ -147,12 +147,60 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, protected AbstractHorse(EntityType type, Level world) { super(type, world); @@ -9781,6 +9836,7 @@ index 47cd69f91bbc2e2be9ec970674adc522e21593c8..c044ed3a96f10584fd5aec836624bca1 + public boolean isRidable() { + return false; // vanilla handles + } ++ // Purpur end + + @Override + public void initAttributes() { @@ -9819,7 +9875,6 @@ index 47cd69f91bbc2e2be9ec970674adc522e21593c8..c044ed3a96f10584fd5aec836624bca1 + protected double generateSpeed(RandomSource random) { + return (0.44999998807907104D + random.nextDouble() * 0.3D + random.nextDouble() * 0.3D + random.nextDouble() * 0.3D) * 0.25D; + } -+ // Purpur end + @Override protected void registerGoals() { @@ -9827,7 +9882,7 @@ index 47cd69f91bbc2e2be9ec970674adc522e21593c8..c044ed3a96f10584fd5aec836624bca1 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)); -@@ -160,6 +208,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, +@@ -163,6 +211,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, if (this.canPerformRearing()) { this.goalSelector.addGoal(9, new RandomStandGoal(this)); } @@ -9835,7 +9890,7 @@ index 47cd69f91bbc2e2be9ec970674adc522e21593c8..c044ed3a96f10584fd5aec836624bca1 this.addBehaviourGoals(); } -@@ -336,7 +385,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, +@@ -335,7 +384,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, @Override protected int calculateFallDamage(float fallDistance, float damageMultiplier) { @@ -9844,7 +9899,7 @@ index 47cd69f91bbc2e2be9ec970674adc522e21593c8..c044ed3a96f10584fd5aec836624bca1 } protected int getInventorySize() { -@@ -1252,7 +1301,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, +@@ -1247,7 +1296,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, entityData = new AgeableMob.AgeableMobGroupData(0.2F); } @@ -9854,7 +9909,7 @@ index 47cd69f91bbc2e2be9ec970674adc522e21593c8..c044ed3a96f10584fd5aec836624bca1 } 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 e0dfee0e0ce091d5ae0ec740e939c2c50915c104..7ad29aacc73ca1cb98b76ad36b92a3edb2256629 100644 +index e0dfee0e0ce091d5ae0ec740e939c2c50915c104..72ad12175325091397459e06743875cce6df8d94 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 { @@ -9864,45 +9919,45 @@ index e0dfee0e0ce091d5ae0ec740e939c2c50915c104..7ad29aacc73ca1cb98b76ad36b92a3ed + // Purpur start + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.donkeyRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.donkeyRidableInWater; + } ++ // Purpur end + + @Override + public float generateMaxHealth(net.minecraft.util.RandomSource random) { -+ return (float) generateMaxHealth(this.level.purpurConfig.donkeyMaxHealthMin, this.level.purpurConfig.donkeyMaxHealthMax); ++ return (float) generateMaxHealth(this.level().purpurConfig.donkeyMaxHealthMin, this.level().purpurConfig.donkeyMaxHealthMax); + } + + @Override + public double generateJumpStrength(net.minecraft.util.RandomSource random) { -+ return generateJumpStrength(this.level.purpurConfig.donkeyJumpStrengthMin, this.level.purpurConfig.donkeyJumpStrengthMax); ++ return generateJumpStrength(this.level().purpurConfig.donkeyJumpStrengthMin, this.level().purpurConfig.donkeyJumpStrengthMax); + } + + @Override + public double generateSpeed(net.minecraft.util.RandomSource random) { -+ return generateSpeed(this.level.purpurConfig.donkeyMovementSpeedMin, this.level.purpurConfig.donkeyMovementSpeedMax); ++ return generateSpeed(this.level().purpurConfig.donkeyMovementSpeedMin, this.level().purpurConfig.donkeyMovementSpeedMax); + } + + @Override + public int getPurpurBreedTime() { -+ return this.level.purpurConfig.donkeyBreedingTicks; ++ return this.level().purpurConfig.donkeyBreedingTicks; + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.donkeyTakeDamageFromWater; ++ return this.level().purpurConfig.donkeyTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.donkeyAlwaysDropExp; ++ return this.level().purpurConfig.donkeyAlwaysDropExp; + } -+ // Purpur end + @Override 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 79a2b3c8df70a9a73ad44560a4a6129f91db8e16..fb433878731b824b4d595b7f28626f25bdfabbeb 100644 +index 5f5dc651d570989ec1294c31a14dcfede466b80a..3b1faa63e46a48e83ea672cf6da444a1d7e13270 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 { @@ -9912,48 +9967,48 @@ index 79a2b3c8df70a9a73ad44560a4a6129f91db8e16..fb433878731b824b4d595b7f28626f25 + // Purpur start + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.horseRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.horseRidableInWater; + } ++ // Purpur end + + @Override + public float generateMaxHealth(RandomSource random) { -+ return (float) generateMaxHealth(this.level.purpurConfig.horseMaxHealthMin, this.level.purpurConfig.horseMaxHealthMax); ++ return (float) generateMaxHealth(this.level().purpurConfig.horseMaxHealthMin, this.level().purpurConfig.horseMaxHealthMax); + } + + @Override + public double generateJumpStrength(RandomSource random) { -+ return generateJumpStrength(this.level.purpurConfig.horseJumpStrengthMin, this.level.purpurConfig.horseJumpStrengthMax); ++ return generateJumpStrength(this.level().purpurConfig.horseJumpStrengthMin, this.level().purpurConfig.horseJumpStrengthMax); + } + + @Override + public double generateSpeed(RandomSource random) { -+ return generateSpeed(this.level.purpurConfig.horseMovementSpeedMin, this.level.purpurConfig.horseMovementSpeedMax); ++ return generateSpeed(this.level().purpurConfig.horseMovementSpeedMin, this.level().purpurConfig.horseMovementSpeedMax); + } + + @Override + public int getPurpurBreedTime() { -+ return this.level.purpurConfig.horseBreedingTicks; ++ return this.level().purpurConfig.horseBreedingTicks; + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.horseTakeDamageFromWater; ++ return this.level().purpurConfig.horseTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.horseAlwaysDropExp; ++ return this.level().purpurConfig.horseAlwaysDropExp; + } -+ // Purpur end + @Override 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 7ae0e4b3aa8e861500ddc7b38aa671258b532fcd..309fd5bccadcc584354d328bd31a6f4591c2d0a0 100644 +index d28089c37707f323f73e60cb0ebed4e3cdf8c0fd..a9f36af3e07f74b3d11697d5fad9f0a469844779 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 -@@ -73,11 +73,86 @@ public class Llama extends AbstractChestedHorse implements VariantHolder type, Level world) { super(type, world); -@@ -77,9 +83,69 @@ public class EndCrystal extends Entity { +@@ -42,6 +48,22 @@ public class EndCrystal extends Entity { + this.setPos(x, y, z); + } + ++ public boolean shouldExplode() { ++ return showsBottom() ? level().purpurConfig.basedEndCrystalExplode : level().purpurConfig.baselessEndCrystalExplode; ++ } ++ ++ public float getExplosionPower() { ++ return (float) (showsBottom() ? level().purpurConfig.basedEndCrystalExplosionPower : level().purpurConfig.baselessEndCrystalExplosionPower); ++ } ++ ++ public boolean hasExplosionFire() { ++ return showsBottom() ? level().purpurConfig.basedEndCrystalExplosionFire : level().purpurConfig.baselessEndCrystalExplosionFire; ++ } ++ ++ public Level.ExplosionInteraction getExplosionEffect() { ++ return showsBottom() ? level().purpurConfig.basedEndCrystalExplosionEffect : level().purpurConfig.baselessEndCrystalExplosionEffect; ++ } ++ + @Override + protected Entity.MovementEmission getMovementEmission() { + return Entity.MovementEmission.NONE; +@@ -77,9 +99,53 @@ public class EndCrystal extends Entity { } } // Paper end -+ if (this.level.purpurConfig.endCrystalCramming > 0 && this.level.getEntitiesOfClass(EndCrystal.class, getBoundingBox()).size() > this.level.purpurConfig.endCrystalCramming) this.hurt(this.damageSources().cramming(), 6.0F); // Purpur ++ if (this.level().purpurConfig.endCrystalCramming > 0 && this.level().getEntitiesOfClass(EndCrystal.class, getBoundingBox()).size() > this.level().purpurConfig.endCrystalCramming) this.hurt(this.damageSources().cramming(), 6.0F); // Purpur } + // Purpur start -+ if (level.purpurConfig.phantomAttackedByCrystalRadius <= 0 || --idleCooldown > 0) { ++ if (level().purpurConfig.phantomAttackedByCrystalRadius <= 0 || --idleCooldown > 0) { + return; // on cooldown + } + + if (targetPhantom == null) { -+ for (net.minecraft.world.entity.monster.Phantom phantom : level.getEntitiesOfClass(net.minecraft.world.entity.monster.Phantom.class, getBoundingBox().inflate(level.purpurConfig.phantomAttackedByCrystalRadius))) { ++ for (net.minecraft.world.entity.monster.Phantom phantom : level().getEntitiesOfClass(net.minecraft.world.entity.monster.Phantom.class, getBoundingBox().inflate(level().purpurConfig.phantomAttackedByCrystalRadius))) { + if (phantom.hasLineOfSight(this)) { + attackPhantom(phantom); + break; @@ -10439,7 +10515,7 @@ index 64f17b4a22454b59968787089253eaba0a04c1f2..e3fe5f18c77e36479eaeb7edfd2a3eb9 + if (targetPhantom.hasLineOfSight(this)) { + if (phantomDamageCooldown <= 0) { + phantomDamageCooldown = 20; -+ targetPhantom.hurt(targetPhantom.damageSources().indirectMagic(this, this), level.purpurConfig.phantomAttackedByCrystalDamage); ++ targetPhantom.hurt(targetPhantom.damageSources().indirectMagic(this, this), level().purpurConfig.phantomAttackedByCrystalDamage); + } + } else { + forgetPhantom(); // no longer in sight @@ -10462,28 +10538,12 @@ index 64f17b4a22454b59968787089253eaba0a04c1f2..e3fe5f18c77e36479eaeb7edfd2a3eb9 + phantomBeamTicks = 0; + phantomDamageCooldown = 0; + idleCooldown = 60; -+ } -+ -+ public boolean shouldExplode() { -+ return showsBottom() ? level.purpurConfig.basedEndCrystalExplode : level.purpurConfig.baselessEndCrystalExplode; -+ } -+ -+ public float getExplosionPower() { -+ return (float) (showsBottom() ? level.purpurConfig.basedEndCrystalExplosionPower : level.purpurConfig.baselessEndCrystalExplosionPower); -+ } -+ -+ public boolean hasExplosionFire() { -+ return showsBottom() ? level.purpurConfig.basedEndCrystalExplosionFire : level.purpurConfig.baselessEndCrystalExplosionFire; -+ } -+ -+ public Level.ExplosionInteraction getExplosionEffect() { -+ return showsBottom() ? level.purpurConfig.basedEndCrystalExplosionEffect : level.purpurConfig.baselessEndCrystalExplosionEffect; } + // Purpur end @Override protected void addAdditionalSaveData(CompoundTag nbt) { -@@ -124,17 +190,19 @@ public class EndCrystal extends Entity { +@@ -124,16 +190,18 @@ public class EndCrystal extends Entity { // CraftBukkit end this.remove(Entity.RemovalReason.KILLED); if (!source.is(DamageTypeTags.IS_EXPLOSION)) { @@ -10491,25 +10551,24 @@ index 64f17b4a22454b59968787089253eaba0a04c1f2..e3fe5f18c77e36479eaeb7edfd2a3eb9 DamageSource damagesource1 = source.getEntity() != null ? this.damageSources().explosion(this, source.getEntity()) : null; // CraftBukkit start -- ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), 6.0F, false); -+ ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), getExplosionPower(), hasExplosionFire()); // Purpur - this.level.getCraftServer().getPluginManager().callEvent(event); +- ExplosionPrimeEvent event = CraftEventFactory.callExplosionPrimeEvent(this, 6.0F, false); ++ ExplosionPrimeEvent event = CraftEventFactory.callExplosionPrimeEvent(this, getExplosionPower(), hasExplosionFire()); // Purpur if (event.isCancelled()) { this.unsetRemoved(); return false; } -- this.level.explode(this, damagesource1, (ExplosionDamageCalculator) null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.BLOCK); -+ this.level.explode(this, damagesource1, (ExplosionDamageCalculator) null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), getExplosionEffect()); // Purpur +- this.level().explode(this, damagesource1, (ExplosionDamageCalculator) null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.BLOCK); ++ this.level().explode(this, damagesource1, (ExplosionDamageCalculator) null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), getExplosionEffect()); // Purpur // CraftBukkit end + } else this.unsetRemoved(); // Purpur } this.onDestroyedBy(source); 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 3f66986948d0b43a75454389b7ec8517e2d50899..b6ac41633e91f6ee2755d1f05aac4c8046a4aa8a 100644 +index a24ae93efcdb2da5782d342c7697a1bb253400c7..ec595b74a6376adb65840035cdaa7502c9a3fe50 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 -@@ -104,9 +104,11 @@ public class EnderDragon extends Mob implements Enemy { +@@ -105,9 +105,11 @@ public class EnderDragon extends Mob implements Enemy { @Nullable private BlockPos podium; // Paper end @@ -10518,12 +10577,12 @@ index 3f66986948d0b43a75454389b7ec8517e2d50899..b6ac41633e91f6ee2755d1f05aac4c80 public EnderDragon(EntityType entitytypes, Level world) { super(EntityType.ENDER_DRAGON, world); + this.explosionSource = new Explosion(world, this, null, null, Double.NaN, Double.NaN, Double.NaN, Float.NaN, true, Explosion.BlockInteraction.DESTROY); // Purpur - moved instantiation from field - this.subEntities = new EnderDragonPart[]{this.head, this.neck, this.body, this.tail1, this.tail2, this.tail3, this.wing1, this.wing2}; - this.setHealth(this.getMaxHealth()); + this.fightOrigin = BlockPos.ZERO; + this.growlTime = 100; + this.nodes = new Node[24]; +@@ -126,7 +128,37 @@ public class EnderDragon extends Mob implements Enemy { this.noPhysics = true; -@@ -118,8 +120,59 @@ 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); // CraftBukkit + @@ -10551,38 +10610,44 @@ index 3f66986948d0b43a75454389b7ec8517e2d50899..b6ac41633e91f6ee2755d1f05aac4c80 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.enderDragonRidable; ++ return level().purpurConfig.enderDragonRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.enderDragonRidableInWater; -+ } -+ ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.enderDragonRidableInWater; + } + + public void setDragonFight(EndDragonFight fight) { +@@ -141,6 +173,27 @@ public class EnderDragon extends Mob implements Enemy { + return this.fightOrigin; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.enderDragonControllable; ++ return level().purpurConfig.enderDragonControllable; + } + + @Override + public double getMaxY() { -+ return level.purpurConfig.enderDragonMaxY; ++ return level().purpurConfig.enderDragonMaxY; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.enderDragonMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.enderDragonMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.enderDragonTakeDamageFromWater; - } -+ // Purpur end - ++ return this.level().purpurConfig.enderDragonTakeDamageFromWater; ++ } ++ public static AttributeSupplier.Builder createAttributes() { return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 200.0D); -@@ -182,6 +235,37 @@ public class EnderDragon extends Mob implements Enemy { + } +@@ -202,6 +255,37 @@ public class EnderDragon extends Mob implements Enemy { @Override public void aiStep() { @@ -10618,9 +10683,9 @@ index 3f66986948d0b43a75454389b7ec8517e2d50899..b6ac41633e91f6ee2755d1f05aac4c80 + // Purpur end + this.processFlappingMovement(); - if (this.level.isClientSide) { + if (this.level().isClientSide) { this.setHealth(this.getHealth()); -@@ -195,6 +279,8 @@ public class EnderDragon extends Mob implements Enemy { +@@ -228,6 +312,8 @@ public class EnderDragon extends Mob implements Enemy { float f; if (this.isDeadOrDying()) { @@ -10629,7 +10694,7 @@ index 3f66986948d0b43a75454389b7ec8517e2d50899..b6ac41633e91f6ee2755d1f05aac4c80 float f1 = (this.random.nextFloat() - 0.5F) * 8.0F; f = (this.random.nextFloat() - 0.5F) * 4.0F; -@@ -207,9 +293,9 @@ public class EnderDragon extends Mob implements Enemy { +@@ -240,9 +326,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); @@ -10641,7 +10706,7 @@ index 3f66986948d0b43a75454389b7ec8517e2d50899..b6ac41633e91f6ee2755d1f05aac4c80 this.flapTime += f * 0.5F; } else { this.flapTime += f; -@@ -254,7 +340,7 @@ public class EnderDragon extends Mob implements Enemy { +@@ -287,7 +373,7 @@ public class EnderDragon extends Mob implements Enemy { } this.phaseManager.getCurrentPhase().doClientTick(); @@ -10650,60 +10715,60 @@ index 3f66986948d0b43a75454389b7ec8517e2d50899..b6ac41633e91f6ee2755d1f05aac4c80 DragonPhaseInstance idragoncontroller = this.phaseManager.getCurrentPhase(); idragoncontroller.doServerTick(); -@@ -323,7 +409,7 @@ public class EnderDragon extends Mob implements Enemy { +@@ -356,7 +442,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)); -- if (!this.level.isClientSide && this.hurtTime == 0) { -+ if (!hasRider && !this.level.isClientSide && this.hurtTime == 0) { // Purpur - 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)); -@@ -367,7 +453,7 @@ public class EnderDragon extends Mob implements Enemy { +- if (!this.level().isClientSide && this.hurtTime == 0) { ++ if (!hasRider && !this.level().isClientSide && this.hurtTime == 0) { // Purpur + 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)); +@@ -400,7 +486,7 @@ public class EnderDragon extends Mob implements Enemy { } - if (!this.level.isClientSide) { + if (!this.level().isClientSide) { - this.inWall = this.checkWalls(this.head.getBoundingBox()) | this.checkWalls(this.neck.getBoundingBox()) | this.checkWalls(this.body.getBoundingBox()); + this.inWall = !hasRider && this.checkWalls(this.head.getBoundingBox()) | this.checkWalls(this.neck.getBoundingBox()) | this.checkWalls(this.body.getBoundingBox()); // Purpur if (this.dragonFight != null) { this.dragonFight.updateDragon(this); } -@@ -499,7 +585,7 @@ public class EnderDragon extends Mob implements Enemy { - BlockState iblockdata = this.level.getBlockState(blockposition); +@@ -532,7 +618,7 @@ public class EnderDragon extends Mob implements Enemy { + BlockState iblockdata = this.level().getBlockState(blockposition); if (!iblockdata.isAir() && !iblockdata.is(BlockTags.DRAGON_TRANSPARENT)) { -- if (this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && !iblockdata.is(BlockTags.DRAGON_IMMUNE)) { -+ if ((this.level.purpurConfig.enderDragonBypassMobGriefing || this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) && !iblockdata.is(BlockTags.DRAGON_IMMUNE)) { // Purpur +- if (this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && !iblockdata.is(BlockTags.DRAGON_IMMUNE)) { ++ if ((this.level().purpurConfig.enderDragonBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) && !iblockdata.is(BlockTags.DRAGON_IMMUNE)) { // Purpur // CraftBukkit start - Add blocks to list rather than destroying them - // flag1 = this.level.removeBlock(blockposition, false) || flag1; + // flag1 = this.level().removeBlock(blockposition, false) || flag1; flag1 = true; -@@ -634,7 +720,7 @@ public class EnderDragon extends Mob implements Enemy { - boolean flag = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT); +@@ -676,7 +762,7 @@ public class EnderDragon extends Mob implements Enemy { + boolean flag = this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT); short short0 = 500; - if (this.dragonFight != null && !this.dragonFight.hasPreviouslyKilledDragon()) { -+ if (this.dragonFight != null && (level.purpurConfig.enderDragonAlwaysDropsFullExp || !this.dragonFight.hasPreviouslyKilledDragon())) { ++ if (this.dragonFight != null && (level().purpurConfig.enderDragonAlwaysDropsFullExp || !this.dragonFight.hasPreviouslyKilledDragon())) { short0 = 12000; } -@@ -1069,6 +1155,7 @@ public class EnderDragon extends Mob implements Enemy { +@@ -1111,6 +1197,7 @@ public class EnderDragon extends Mob implements Enemy { @Override protected boolean canRide(Entity entity) { -+ if (this.level.purpurConfig.enderDragonCanRideVehicles) return this.boardingCooldown <= 0; // Purpur ++ if (this.level().purpurConfig.enderDragonCanRideVehicles) return this.boardingCooldown <= 0; // Purpur return false; } 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 e81e8f050bd9df34b6a64c741428503b434f03a3..4781bdd3b6c7d6b686f2fe6af530e82861385342 100644 +index 1e07febcf7a3dfb281728cc5e3e4f15dd776d7e0..4952a7daa1aad68e3ba53123093cd879e0d544b5 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 -@@ -84,16 +84,31 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -84,20 +84,59 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob return entityliving.getMobType() != MobType.UNDEAD && entityliving.attackable(); }; private static final TargetingConditions TARGETING_CONDITIONS = TargetingConditions.forCombat().range(20.0D).selector(WitherBoss.LIVING_ENTITY_SELECTOR); -+ private int shootCooldown = 0; // Purpur + @Nullable private java.util.UUID summoner; // Purpur ++ private int shootCooldown = 0; // Purpur // Paper start private boolean canPortal = false; @@ -10731,29 +10796,57 @@ index e81e8f050bd9df34b6a64c741428503b434f03a3..4781bdd3b6c7d6b686f2fe6af530e828 this.setHealth(this.getMaxHealth()); this.xpReward = 50; } -@@ -108,13 +123,148 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob + ++ @Override ++ public void initAttributes() { ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.witherMaxHealth); ++ } ++ ++ @Override ++ public boolean isSensitiveToWater() { ++ return this.level().purpurConfig.witherTakeDamageFromWater; ++ } ++ ++ @Nullable ++ public java.util.UUID getSummoner() { ++ return summoner; ++ } ++ ++ public void setSummoner(@Nullable java.util.UUID summoner) { ++ this.summoner = summoner; ++ } ++ ++ @Override ++ protected boolean isAlwaysExperienceDropper() { ++ return this.level().purpurConfig.witherAlwaysDropExp; ++ } ++ + @Override + protected PathNavigation createNavigation(Level world) { + FlyingPathNavigation navigationflying = new FlyingPathNavigation(this, world); +@@ -108,13 +147,113 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob return navigationflying; } + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.witherRidable; ++ return level().purpurConfig.witherRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.witherRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.witherRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.witherControllable; ++ return level().purpurConfig.witherControllable; + } + + @Override + public double getMaxY() { -+ return level.purpurConfig.witherMaxY; ++ return level().purpurConfig.witherMaxY; + } + + @Override @@ -10823,48 +10916,13 @@ index e81e8f050bd9df34b6a64c741428503b434f03a3..4781bdd3b6c7d6b686f2fe6af530e828 + } + + public void shoot(int head, double x, double y, double z, Player rider) { -+ level.levelEvent(null, 1024, blockPosition(), 0); ++ level().levelEvent(null, 1024, blockPosition(), 0); + double headX = getHeadX(head); + double headY = getHeadY(head); + double headZ = getHeadZ(head); -+ WitherSkull skull = new WitherSkull(level, this, x - headX, y - headY, z - headZ) { -+ @Override -+ public boolean canHitEntity(Entity target) { -+ // do not hit rider -+ return target != rider && super.canHitEntity(target); -+ } -+ -+ @Override -+ public boolean canSaveToDisk() { -+ return false; -+ } -+ }; ++ WitherSkull skull = new WitherSkull(level(), this, x - headX, y - headY, z - headZ); + skull.setPosRaw(headX, headY, headZ); -+ level.addFreshEntity(skull); -+ } -+ -+ @Override -+ public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.witherMaxHealth); -+ } -+ -+ @Override -+ public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.witherTakeDamageFromWater; -+ } -+ -+ @Nullable -+ public java.util.UUID getSummoner() { -+ return summoner; -+ } -+ -+ public void setSummoner(@Nullable java.util.UUID summoner) { -+ this.summoner = summoner; -+ } -+ -+ @Override -+ protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.witherAlwaysDropExp; ++ level().addFreshEntity(skull); + } + // Purpur end + @@ -10880,7 +10938,7 @@ index e81e8f050bd9df34b6a64c741428503b434f03a3..4781bdd3b6c7d6b686f2fe6af530e828 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)); } -@@ -132,6 +282,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -132,6 +271,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob public void addAdditionalSaveData(CompoundTag nbt) { super.addAdditionalSaveData(nbt); nbt.putInt("Invul", this.getInvulnerableTicks()); @@ -10888,7 +10946,7 @@ index e81e8f050bd9df34b6a64c741428503b434f03a3..4781bdd3b6c7d6b686f2fe6af530e828 } @Override -@@ -141,6 +292,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -141,6 +281,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob if (this.hasCustomName()) { this.bossEvent.setName(this.getDisplayName()); } @@ -10896,7 +10954,21 @@ index e81e8f050bd9df34b6a64c741428503b434f03a3..4781bdd3b6c7d6b686f2fe6af530e828 } -@@ -256,6 +408,16 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -150,6 +291,13 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob + this.bossEvent.setName(this.getDisplayName()); + } + ++ // Purpur start - optimize suffocation ++ @Override ++ public boolean shouldCheckForSuffocation() { ++ return true; ++ } ++ // Purpur end ++ + @Override + protected SoundEvent getAmbientSound() { + return SoundEvents.WITHER_AMBIENT; +@@ -256,6 +404,16 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob @Override protected void customServerAiStep() { @@ -10913,16 +10985,16 @@ index e81e8f050bd9df34b6a64c741428503b434f03a3..4781bdd3b6c7d6b686f2fe6af530e828 int i; if (this.getInvulnerableTicks() > 0) { -@@ -272,7 +434,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -272,7 +430,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob } // CraftBukkit end - if (!this.isSilent()) { -+ if (!this.isSilent() && level.purpurConfig.witherPlaySpawnSound) { ++ if (!this.isSilent() && level().purpurConfig.witherPlaySpawnSound) { // CraftBukkit start - Use relative location for far away sounds - // this.world.globalLevelEvent(1023, new BlockPosition(this), 0); - int viewDistance = ((ServerLevel) this.level).getCraftServer().getViewDistance() * 16; -@@ -296,7 +458,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob + // this.level().globalLevelEvent(1023, new BlockPosition(this), 0); + int viewDistance = ((ServerLevel) this.level()).getCraftServer().getViewDistance() * 16; +@@ -296,7 +454,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob this.setInvulnerableTicks(i); if (this.tickCount % 10 == 0) { @@ -10931,29 +11003,29 @@ index e81e8f050bd9df34b6a64c741428503b434f03a3..4781bdd3b6c7d6b686f2fe6af530e828 } } else { -@@ -356,7 +518,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -356,7 +514,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 +- 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()); -@@ -389,8 +551,10 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -389,8 +547,10 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob } } - if (this.tickCount % 20 == 0) { - this.heal(1.0F, EntityRegainHealthEvent.RegainReason.REGEN); // CraftBukkit + // Purpur start - customizable heal rate and amount -+ if (this.tickCount % level.purpurConfig.witherHealthRegenDelay == 0) { -+ this.heal(level.purpurConfig.witherHealthRegenAmount, EntityRegainHealthEvent.RegainReason.REGEN); // CraftBukkit ++ if (this.tickCount % level().purpurConfig.witherHealthRegenDelay == 0) { ++ this.heal(level().purpurConfig.witherHealthRegenAmount, EntityRegainHealthEvent.RegainReason.REGEN); // CraftBukkit + // Purpur end } this.bossEvent.setProgress(this.getHealth() / this.getMaxHealth()); -@@ -576,11 +740,11 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -576,11 +736,11 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob } public int getAlternativeTarget(int headIndex) { @@ -10967,16 +11039,16 @@ index e81e8f050bd9df34b6a64c741428503b434f03a3..4781bdd3b6c7d6b686f2fe6af530e828 } @Override -@@ -595,6 +759,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -595,6 +755,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob @Override protected boolean canRide(Entity entity) { -+ if (this.level.purpurConfig.witherCanRideVehicles) return this.boardingCooldown <= 0; // Purpur ++ if (this.level().purpurConfig.witherCanRideVehicles) return this.boardingCooldown <= 0; // Purpur return false; } 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 3677dd991ae73428984e62e4d6fb757317987887..0545a39af0f21210ff1f5e53f6d712ae24ce43e4 100644 +index 5c6e060a54ffb13c37ff5711992e964bdd59643d..4c5f20bafe589fbd4a034408edb721ac79bbc666 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java @@ -99,10 +99,12 @@ public class ArmorStand extends LivingEntity { @@ -11000,24 +11072,24 @@ index 3677dd991ae73428984e62e4d6fb757317987887..0545a39af0f21210ff1f5e53f6d712ae } public ArmorStand(Level world, double x, double y, double z) { -@@ -609,7 +612,7 @@ public class ArmorStand extends LivingEntity { +@@ -606,7 +609,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 ++ if (this.level().purpurConfig.persistentDroppableEntityDisplayNames && this.hasCustomName()) { // Purpur itemstack.setHoverName(this.getCustomName()); } -@@ -685,6 +688,7 @@ public class ArmorStand extends LivingEntity { +@@ -682,6 +685,7 @@ public class ArmorStand extends LivingEntity { @Override public void tick() { -+ maxUpStep = level.purpurConfig.armorstandStepHeight; ++ maxUpStep = level().purpurConfig.armorstandStepHeight; // Paper start if (!this.canTick) { if (this.noTickPoseDirty) { -@@ -1006,4 +1010,18 @@ public class ArmorStand extends LivingEntity { +@@ -1016,4 +1020,18 @@ public class ArmorStand extends LivingEntity { } // Paper end // Paper end @@ -11025,8 +11097,8 @@ index 3677dd991ae73428984e62e4d6fb757317987887..0545a39af0f21210ff1f5e53f6d712ae + // Purpur start + @Override + public void updateInWaterStateAndDoWaterCurrentPushing() { -+ if (this.level.purpurConfig.armorstandWaterMovement && -+ (this.level.purpurConfig.armorstandWaterFence || !(level.getBlockState(blockPosition().below()).getBlock() instanceof net.minecraft.world.level.block.FenceBlock))) ++ if (this.level().purpurConfig.armorstandWaterMovement && ++ (this.level().purpurConfig.armorstandWaterFence || !(level().getBlockState(blockPosition().below()).getBlock() instanceof net.minecraft.world.level.block.FenceBlock))) + super.updateInWaterStateAndDoWaterCurrentPushing(); + } + @@ -11037,17 +11109,17 @@ index 3677dd991ae73428984e62e4d6fb757317987887..0545a39af0f21210ff1f5e53f6d712ae + // 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 30aec9dff249ae629b22318e52902361a9fa4099..25158e04c39146218b21ce5d5c963a24be68b2e2 100644 +index 759ecd79534a7706f7d4a63eb9dacbefcfe54674..182faba889dc15a3500c5919cad8a5483a53033a 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java -@@ -272,7 +272,13 @@ public class ItemFrame extends HangingEntity { +@@ -273,7 +273,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()) { ++ if (this.level().purpurConfig.persistentDroppableEntityDisplayNames && this.hasCustomName()) { + itemFrame.setHoverName(this.getCustomName()); + } + this.spawnAtLocation(itemFrame); @@ -11055,22 +11127,8 @@ index 30aec9dff249ae629b22318e52902361a9fa4099..25158e04c39146218b21ce5d5c963a24 } if (!itemstack.isEmpty()) { -@@ -287,6 +293,13 @@ public class ItemFrame extends HangingEntity { - } - } - -+ // Purpur start -+ @Nullable -+ public net.minecraft.world.entity.item.ItemEntity spawnAtLocation(ItemStack stack) { -+ return this.spawnAtLocation(stack, getDirection().equals(Direction.DOWN) ? -0.6F : 0.0F); -+ } -+ // Purpur end -+ - private void removeFramedMap(ItemStack itemstack) { - // Paper start - fix MC-252817 (green map markers do not disappear) - this.getFramedMapIdFromItem(itemstack).ifPresent((i) -> { 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 ad0df80d1adb1d945f40e1b5f7732bb36b2ca2ff..90cab3586d3e3e290475fe8d59a69d89d3c24add 100644 +index 0f4ef103afcbabc04880c8fc3547b861341c15fc..4b3a8e4a084585d56dd10a08405463b1a677368b 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/Painting.java +++ b/src/main/java/net/minecraft/world/entity/decoration/Painting.java @@ -121,7 +121,7 @@ public class Painting extends HangingEntity implements VariantHolder type, Level world) { super(type, world); -@@ -349,6 +355,15 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -358,6 +364,15 @@ public class ItemEntity extends Entity implements TraceableEntity { return false; } else if (!this.getItem().getItem().canBeHurtBy(source)) { return false; @@ -11149,24 +11207,58 @@ index 453f0f7042bdf204db73be139aa36f211c5455e7..52a14af24e3c51c53b40fdb6594b1664 + ) { + return false; + // Purpur end - } else if (this.level.isClientSide) { + } else if (this.level().isClientSide) { return true; } else { -@@ -547,6 +562,12 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -555,6 +570,12 @@ public class ItemEntity extends Entity implements TraceableEntity { + // com.google.common.base.Preconditions.checkArgument(!stack.isEmpty(), "Cannot drop air"); // CraftBukkit // Paper - Remove check this.getEntityData().set(ItemEntity.DATA_ITEM, stack); - this.getEntityData().markDirty(ItemEntity.DATA_ITEM); // CraftBukkit - SPIGOT-4591, must mark dirty - this.despawnRate = level.paperConfig().entities.spawning.altItemDespawnRate.enabled ? level.paperConfig().entities.spawning.altItemDespawnRate.items.getOrDefault(stack.getItem(), level.spigotConfig.itemDespawnRate) : level.spigotConfig.itemDespawnRate; // Paper + 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 + // Purpur start -+ if (level.purpurConfig.itemImmuneToCactus.contains(stack.getItem())) immuneToCactus = true; -+ if (level.purpurConfig.itemImmuneToExplosion.contains(stack.getItem())) immuneToExplosion = true; -+ if (level.purpurConfig.itemImmuneToFire.contains(stack.getItem())) immuneToFire = true; -+ if (level.purpurConfig.itemImmuneToLightning.contains(stack.getItem())) immuneToLightning = true; ++ if (level().purpurConfig.itemImmuneToCactus.contains(stack.getItem())) immuneToCactus = true; ++ if (level().purpurConfig.itemImmuneToExplosion.contains(stack.getItem())) immuneToExplosion = true; ++ if (level().purpurConfig.itemImmuneToFire.contains(stack.getItem())) immuneToFire = true; ++ if (level().purpurConfig.itemImmuneToLightning.contains(stack.getItem())) immuneToLightning = true; + // level end } @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 4ce3e69970dd9eb251d0538a2d233ca30e9e5e47..afc65b8bb7e7f7f70a25f2d869412ed325b658da 100644 +--- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java ++++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java +@@ -175,4 +175,29 @@ public class PrimedTnt extends Entity implements TraceableEntity { + return !level().paperConfig().fixes.preventTntFromMovingInWater && super.isPushedByFluid(); + } + // Paper end ++ // Purpur start - Shears can defuse TNT ++ @Override ++ public net.minecraft.world.InteractionResult interact(net.minecraft.world.entity.player.Player player, net.minecraft.world.InteractionHand hand) { ++ if (!level().isClientSide && level().purpurConfig.shearsCanDefuseTnt) { ++ final net.minecraft.world.item.ItemStack inHand = player.getItemInHand(hand); ++ ++ if (!inHand.is(net.minecraft.world.item.Items.SHEARS) || !player.getBukkitEntity().hasPermission("purpur.tnt.defuse") || ++ level().random.nextFloat() > level().purpurConfig.shearsCanDefuseTntChance) return net.minecraft.world.InteractionResult.PASS; ++ ++ net.minecraft.world.entity.item.ItemEntity tntItem = new net.minecraft.world.entity.item.ItemEntity(level(), getX(), getY(), getZ(), ++ new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.TNT)); ++ tntItem.setPickUpDelay(10); ++ ++ inHand.hurtAndBreak(1, player, entity -> entity.broadcastBreakEvent(hand)); ++ level().addFreshEntity(tntItem, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.CUSTOM); ++ ++ this.playSound(net.minecraft.sounds.SoundEvents.SHEEP_SHEAR); ++ ++ this.kill(); ++ return net.minecraft.world.InteractionResult.SUCCESS; ++ } ++ ++ return super.interact(player, hand); ++ } ++ // 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 f2094c52196b45adfd51d8aebcc4c46b779b0925..9c8713ef3aeb2ff203bd0328d15d80c2d78d09e9 100644 +index 9ca1e9d95e62929c0015d5ca2c2f9c70e421842e..dd84433a988712da9d799cbda2487a902315fb92 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 @@ -11229,14 +11321,14 @@ index f2094c52196b45adfd51d8aebcc4c46b779b0925..9c8713ef3aeb2ff203bd0328d15d80c2 @@ -161,11 +143,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo this.reassessWeaponGoal(); - this.setCanPickUpLoot(this.level.paperConfig().entities.behavior.mobsCanAlwaysPickUpLoot.skeletons || randomsource.nextFloat() < 0.55F * difficulty.getSpecialMultiplier()); // Paper + this.setCanPickUpLoot(this.level().paperConfig().entities.behavior.mobsCanAlwaysPickUpLoot.skeletons || randomsource.nextFloat() < 0.55F * difficulty.getSpecialMultiplier()); // Paper if (this.getItemBySlot(EquipmentSlot.HEAD).isEmpty()) { - LocalDate localdate = LocalDate.now(); - int i = localdate.get(ChronoField.DAY_OF_MONTH); - int j = localdate.get(ChronoField.MONTH_OF_YEAR); - - if (j == 10 && i == 31 && randomsource.nextFloat() < 0.25F) { -+ if (net.minecraft.world.entity.ambient.Bat.isHalloweenSeason(world.getMinecraftWorld()) && this.random.nextFloat() < this.level.purpurConfig.chanceHeadHalloweenOnEntity) { // Purpur ++ if (net.minecraft.world.entity.ambient.Bat.isHalloweenSeason(world.getMinecraftWorld()) && this.random.nextFloat() < this.level().purpurConfig.chanceHeadHalloweenOnEntity) { // Purpur this.setItemSlot(EquipmentSlot.HEAD, new ItemStack(randomsource.nextFloat() < 0.1F ? Blocks.JACK_O_LANTERN : Blocks.CARVED_PUMPKIN)); this.armorDropChances[EquipmentSlot.HEAD.getIndex()] = 0.0F; } @@ -11252,8 +11344,8 @@ index f2094c52196b45adfd51d8aebcc4c46b779b0925..9c8713ef3aeb2ff203bd0328d15d80c2 double d2 = target.getZ() - this.getZ(); double d3 = Math.sqrt(d0 * d0 + d2 * d2); -- entityarrow.shoot(d0, d1 + d3 * 0.20000000298023224D, d2, 1.6F, (float) (14 - this.level.getDifficulty().getId() * 4)); -+ entityarrow.shoot(d0, d1 + d3 * 0.20000000298023224D, d2, 1.6F, this.level.purpurConfig.skeletonBowAccuracyMap.getOrDefault(this.level.getDifficulty().getId(), (float) (14 - this.level.getDifficulty().getId() * 4))); // Purpur +- entityarrow.shoot(d0, d1 + d3 * 0.20000000298023224D, d2, 1.6F, (float) (14 - this.level().getDifficulty().getId() * 4)); ++ entityarrow.shoot(d0, d1 + d3 * 0.20000000298023224D, d2, 1.6F, this.level().purpurConfig.skeletonBowAccuracyMap.getOrDefault(this.level().getDifficulty().getId(), (float) (14 - this.level().getDifficulty().getId() * 4))); // Purpur // CraftBukkit start org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), entityarrow.getPickupItem(), entityarrow, net.minecraft.world.InteractionHand.MAIN_HAND, 0.8F, true); // Paper if (event.isCancelled()) { @@ -11276,7 +11368,7 @@ index f2094c52196b45adfd51d8aebcc4c46b779b0925..9c8713ef3aeb2ff203bd0328d15d80c2 // Paper end 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 5ae34ded698e501dc5cb97b1d7028863e95742a1..2ad81368f731a937303f17ede20f18c978b6479c 100644 +index 17aa7676ab624440651850bbe5689f8a6c9dbeed..a8b58469fd8a1ed4ec0ce443cf05557903527bd7 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 { @@ -11295,22 +11387,22 @@ index 5ae34ded698e501dc5cb97b1d7028863e95742a1..2ad81368f731a937303f17ede20f18c9 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.blazeRidable; ++ return level().purpurConfig.blazeRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.blazeRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.blazeRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.blazeControllable; ++ return level().purpurConfig.blazeControllable; + } + + @Override + public double getMaxY() { -+ return level.purpurConfig.blazeMaxY; ++ return level().purpurConfig.blazeMaxY; + } + + @Override @@ -11324,17 +11416,17 @@ index 5ae34ded698e501dc5cb97b1d7028863e95742a1..2ad81368f731a937303f17ede20f18c9 + setDeltaMovement(mot.scale(0.9D)); + } + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.blazeMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.blazeMaxHealth); + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.blazeAlwaysDropExp; ++ return this.level().purpurConfig.blazeAlwaysDropExp; + } -+ // Purpur end + @Override protected void registerGoals() { @@ -11360,7 +11452,7 @@ index 5ae34ded698e501dc5cb97b1d7028863e95742a1..2ad81368f731a937303f17ede20f18c9 @Override public boolean isSensitiveToWater() { - return true; -+ return this.level.purpurConfig.blazeTakeDamageFromWater; // Purpur ++ return this.level().purpurConfig.blazeTakeDamageFromWater; // Purpur } @Override @@ -11377,7 +11469,7 @@ index 5ae34ded698e501dc5cb97b1d7028863e95742a1..2ad81368f731a937303f17ede20f18c9 if (this.nextHeightOffsetChangeTick <= 0) { this.nextHeightOffsetChangeTick = 100; 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 d980b906d9206560741576fa4153c57212f307a0..d23141c44a11050de6ffd12d95a0c2820c3f71e3 100644 +index da48bd8e15463be8170262ae90a8e95575959bf2..bf218586a79ea5f4288a64ccf6c245ee8491ce9a 100644 --- a/src/main/java/net/minecraft/world/entity/monster/CaveSpider.java +++ b/src/main/java/net/minecraft/world/entity/monster/CaveSpider.java @@ -28,6 +28,38 @@ public class CaveSpider extends Spider { @@ -11387,43 +11479,43 @@ index d980b906d9206560741576fa4153c57212f307a0..d23141c44a11050de6ffd12d95a0c282 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.caveSpiderRidable; ++ return level().purpurConfig.caveSpiderRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.caveSpiderRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.caveSpiderRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.caveSpiderControllable; ++ return level().purpurConfig.caveSpiderControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.caveSpiderMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.caveSpiderMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.caveSpiderTakeDamageFromWater; ++ return this.level().purpurConfig.caveSpiderTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.caveSpiderAlwaysDropExp; ++ return this.level().purpurConfig.caveSpiderAlwaysDropExp; + } -+ // Purpur end + @Override 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 29c62525241e2e03686d1bceee740d4f54f33c54..c32eda28be3eb2c6a6933463d496ea7b6510f27e 100644 +index fd1b5a1beea7594fa65decfdcccfa15781fc005b..304ea7fdcd410a7c88ec61143364e14de8db0b0c 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java +++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java -@@ -59,21 +59,130 @@ public class Creeper extends Monster implements PowerableMob { +@@ -59,21 +59,99 @@ public class Creeper extends Monster implements PowerableMob { public int maxSwell = 30; public int explosionRadius = 3; private int droppedSkulls; @@ -11441,17 +11533,17 @@ index 29c62525241e2e03686d1bceee740d4f54f33c54..c32eda28be3eb2c6a6933463d496ea7b + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.creeperRidable; ++ return level().purpurConfig.creeperRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.creeperRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.creeperRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.creeperControllable; ++ return level().purpurConfig.creeperControllable; + } + + @Override @@ -11506,37 +11598,6 @@ index 29c62525241e2e03686d1bceee740d4f54f33c54..c32eda28be3eb2c6a6933463d496ea7b + } + return getForwardMot() == 0 && getStrafeMot() == 0; // do not jump if standing still + } -+ -+ @Override -+ public void initAttributes() { -+ 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) { -+ double chance = world.getLevel().purpurConfig.creeperChargedChance; -+ if (chance > 0D && random.nextDouble() <= chance) { -+ setPowered(true); -+ } -+ return super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityNbt); -+ } -+ -+ @Override -+ public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.creeperTakeDamageFromWater; -+ } -+ -+ @Override -+ protected org.bukkit.event.entity.EntityDeathEvent dropAllDeathLoot(DamageSource damagesource) { -+ if (!exploding && this.level.purpurConfig.creeperExplodeWhenKilled && damagesource.getEntity() instanceof net.minecraft.server.level.ServerPlayer) { -+ this.explodeCreeper(); -+ } -+ return super.dropAllDeathLoot(damagesource); -+ } -+ -+ @Override -+ protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.creeperAlwaysDropExp; -+ } + // Purpur end + @Override @@ -11554,27 +11615,65 @@ index 29c62525241e2e03686d1bceee740d4f54f33c54..c32eda28be3eb2c6a6933463d496ea7b this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Player.class, true)); this.targetSelector.addGoal(2, new HurtByTargetGoal(this, new Class[0])); } -@@ -263,15 +372,17 @@ public class Creeper extends Monster implements PowerableMob { +@@ -173,6 +251,37 @@ public class Creeper extends Monster implements PowerableMob { + } + } + ++ @Override ++ public void initAttributes() { ++ 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) { ++ double chance = world.getLevel().purpurConfig.creeperChargedChance; ++ if (chance > 0D && random.nextDouble() <= chance) { ++ setPowered(true); ++ } ++ return super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityNbt); ++ } ++ ++ @Override ++ public boolean isSensitiveToWater() { ++ return this.level().purpurConfig.creeperTakeDamageFromWater; ++ } ++ ++ @Override ++ protected org.bukkit.event.entity.EntityDeathEvent dropAllDeathLoot(DamageSource damagesource) { ++ if (!exploding && this.level().purpurConfig.creeperExplodeWhenKilled && damagesource.getEntity() instanceof net.minecraft.server.level.ServerPlayer) { ++ this.explodeCreeper(); ++ } ++ return super.dropAllDeathLoot(damagesource); ++ } ++ ++ @Override ++ protected boolean isAlwaysExperienceDropper() { ++ return this.level().purpurConfig.creeperAlwaysDropExp; ++ } ++ + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return SoundEvents.CREEPER_HURT; +@@ -264,15 +373,17 @@ public class Creeper extends Monster implements PowerableMob { } public void explodeCreeper() { + this.exploding = true; // Purpur - if (!this.level.isClientSide) { + if (!this.level().isClientSide) { float f = this.isPowered() ? 2.0F : 1.0F; -+ float multiplier = this.level.purpurConfig.creeperHealthRadius ? this.getHealth() / this.getMaxHealth() : 1; // Purpur ++ float multiplier = this.level().purpurConfig.creeperHealthRadius ? this.getHealth() / this.getMaxHealth() : 1; // Purpur // CraftBukkit start -- ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), this.explosionRadius * f, false); -+ ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), (this.explosionRadius * f) * multiplier, false); // Purpur - this.level.getCraftServer().getPluginManager().callEvent(event); +- ExplosionPrimeEvent event = CraftEventFactory.callExplosionPrimeEvent(this, this.explosionRadius * f, false); ++ ExplosionPrimeEvent event = CraftEventFactory.callExplosionPrimeEvent(this, (this.explosionRadius * f) * multiplier, false); // Purpur if (!event.isCancelled()) { - this.dead = true; -- this.level.explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB); -+ 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); // Purpur - this.discard(); - this.spawnLingeringCloud(); - } else { -@@ -280,7 +391,7 @@ public class Creeper extends Monster implements PowerableMob { + // 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.discard(); + this.spawnLingeringCloud(); + // CraftBukkit start +@@ -282,7 +393,7 @@ public class Creeper extends Monster implements PowerableMob { } // CraftBukkit end } @@ -11583,7 +11682,7 @@ index 29c62525241e2e03686d1bceee740d4f54f33c54..c32eda28be3eb2c6a6933463d496ea7b } private void spawnLingeringCloud() { -@@ -322,6 +433,7 @@ public class Creeper extends Monster implements PowerableMob { +@@ -324,6 +435,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()); @@ -11592,7 +11691,7 @@ index 29c62525241e2e03686d1bceee740d4f54f33c54..c32eda28be3eb2c6a6933463d496ea7b } // Paper end 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 f00773e05654bdeb5463f448293aac99d2208813..a6980d85455234d4f89ff423e013f3c479bd3fe8 100644 +index 991d728db2a3b64316fc2102cf3aee470327a62e..63a1cf5604c14025171d7be7434e2d6b64c98107 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; @@ -11610,54 +11709,54 @@ index f00773e05654bdeb5463f448293aac99d2208813..a6980d85455234d4f89ff423e013f3c4 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.drownedRidable; ++ return level().purpurConfig.drownedRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.drownedRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.drownedRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.drownedControllable; ++ return level().purpurConfig.drownedControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.drownedMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.drownedMaxHealth); + } + + @Override + protected void randomizeReinforcementsChance() { -+ this.getAttribute(Attributes.SPAWN_REINFORCEMENTS_CHANCE).setBaseValue(this.random.nextDouble() * this.level.purpurConfig.drownedSpawnReinforcements); -+ } -+ -+ @Override -+ public boolean jockeyOnlyBaby() { -+ return level.purpurConfig.drownedJockeyOnlyBaby; -+ } -+ -+ @Override -+ public double jockeyChance() { -+ return level.purpurConfig.drownedJockeyChance; -+ } -+ -+ @Override -+ public boolean jockeyTryExistingChickens() { -+ return level.purpurConfig.drownedJockeyTryExistingChickens; ++ this.getAttribute(Attributes.SPAWN_REINFORCEMENTS_CHANCE).setBaseValue(this.random.nextDouble() * this.level().purpurConfig.drownedSpawnReinforcements); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.drownedTakeDamageFromWater; ++ return this.level().purpurConfig.drownedTakeDamageFromWater; ++ } ++ ++ @Override ++ public boolean jockeyOnlyBaby() { ++ return level().purpurConfig.drownedJockeyOnlyBaby; ++ } ++ ++ @Override ++ public double jockeyChance() { ++ return level().purpurConfig.drownedJockeyChance; ++ } ++ ++ @Override ++ public boolean jockeyTryExistingChickens() { ++ return level().purpurConfig.drownedJockeyTryExistingChickens; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.drownedAlwaysDropExp; ++ return this.level().purpurConfig.drownedAlwaysDropExp; + } -+ // Purpur end + @Override protected void addBehaviourGoals() { @@ -11665,22 +11764,22 @@ index f00773e05654bdeb5463f448293aac99d2208813..a6980d85455234d4f89ff423e013f3c4 @@ -75,10 +128,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())); -+ if (level.purpurConfig.drownedBreakDoors) this.goalSelector.addGoal(6, new MoveThroughVillageGoal(this, 1.0D, true, 4, this::canBreakDoors)); + this.goalSelector.addGoal(6, new Drowned.DrownedSwimUpGoal(this, 1.0D, this.level().getSeaLevel())); ++ if (level().purpurConfig.drownedBreakDoors) this.goalSelector.addGoal(6, new MoveThroughVillageGoal(this, 1.0D, true, 4, this::canBreakDoors)); this.goalSelector.addGoal(7, new RandomStrollGoal(this, 1.0D)); this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, new Class[]{Drowned.class})).setAlertOthers(ZombifiedPiglin.class)); this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, this::okTarget)); -- if (this.level.spigotConfig.zombieAggressiveTowardsVillager) this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false)); // Paper +- if (this.level().spigotConfig.zombieAggressiveTowardsVillager) this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false)); // Paper + // Purpur start -+ if ( level.spigotConfig.zombieAggressiveTowardsVillager ) this.targetSelector.addGoal(3, new NearestAttackableTargetGoal(this, AbstractVillager.class, false) { // Spigot ++ if (this.level().spigotConfig.zombieAggressiveTowardsVillager) this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false) { // Spigot + @Override + public boolean canUse() { -+ return (level.purpurConfig.zombieAggressiveTowardsVillagerWhenLagging || !level.getServer().server.isLagging()) && super.canUse(); ++ return (level().purpurConfig.zombieAggressiveTowardsVillagerWhenLagging || !level().getServer().server.isLagging()) && super.canUse(); + } + + @Override + public boolean canContinueToUse() { -+ return (level.purpurConfig.zombieAggressiveTowardsVillagerWhenLagging || !level.getServer().server.isLagging()) && super.canContinueToUse(); ++ return (level().purpurConfig.zombieAggressiveTowardsVillagerWhenLagging || !level().getServer().server.isLagging()) && super.canContinueToUse(); + } + }); + // Purpur end @@ -11692,7 +11791,7 @@ index f00773e05654bdeb5463f448293aac99d2208813..a6980d85455234d4f89ff423e013f3c4 @Override public boolean supportsBreakDoorGoal() { - return false; -+ return level.purpurConfig.drownedBreakDoors ? true : false; ++ return level().purpurConfig.drownedBreakDoors ? true : false; } @Override @@ -11734,7 +11833,7 @@ index f00773e05654bdeb5463f448293aac99d2208813..a6980d85455234d4f89ff423e013f3c4 } 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 d02286d553c600fe7e75f48e278e380d21c5b868..916cf5137808003058a787210fc3343d75caf3d9 100644 +index 8f481e11815d7162dd62a2b850b3d2af6d904519..b30f13d2a7198f568bc36c0d974fd6dc6be292c2 100644 --- a/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java +++ b/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java @@ -33,6 +33,33 @@ public class ElderGuardian extends Guardian { @@ -11744,72 +11843,72 @@ index d02286d553c600fe7e75f48e278e380d21c5b868..916cf5137808003058a787210fc3343d + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.elderGuardianRidable; ++ return level().purpurConfig.elderGuardianRidable; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.elderGuardianControllable; ++ return level().purpurConfig.elderGuardianControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.elderGuardianMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.elderGuardianMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.elderGuardianTakeDamageFromWater; ++ return this.level().purpurConfig.elderGuardianTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.elderGuardianAlwaysDropExp; ++ return this.level().purpurConfig.elderGuardianAlwaysDropExp; + } -+ // Purpur end + public static AttributeSupplier.Builder createAttributes() { 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 c2f5dabb41b172547864decc06aa632d89dff3e1..7c26e1979cdae52e2e94d24dd8c3164e815226ab 100644 +index 410f10ad93935d1c078447a4596023f367a8e9b7..44331be61edffd5afadf3e637dd181bff1133d4f 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java +++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java -@@ -89,12 +89,40 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -93,12 +93,40 @@ public class EnderMan extends Monster implements NeutralMob { public EnderMan(EntityType 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 - } - ++ } ++ + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.endermanRidable; ++ return level().purpurConfig.endermanRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.endermanRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.endermanRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.endermanControllable; ++ return level().purpurConfig.endermanControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.endermanMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.endermanMaxHealth); + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.endermanAlwaysDropExp; -+ } -+ // Purpur end -+ ++ return this.level().purpurConfig.endermanAlwaysDropExp; + } + @Override protected void registerGoals() { this.goalSelector.addGoal(0, new FloatGoal(this)); @@ -11817,7 +11916,7 @@ index c2f5dabb41b172547864decc06aa632d89dff3e1..7c26e1979cdae52e2e94d24dd8c3164e 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)); -@@ -102,9 +130,10 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -106,9 +134,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)); @@ -11825,35 +11924,35 @@ index c2f5dabb41b172547864decc06aa632d89dff3e1..7c26e1979cdae52e2e94d24dd8c3164e this.targetSelector.addGoal(1, new EnderMan.EndermanLookForPlayerGoal(this, this::isAngryAt)); this.targetSelector.addGoal(2, new HurtByTargetGoal(this, new Class[0])); - this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Endermite.class, true, false)); -+ this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Endermite.class, 10, true, false, (entityliving) -> entityliving.level.purpurConfig.endermanAggroEndermites && entityliving instanceof Endermite endermite && (!entityliving.level.purpurConfig.endermanAggroEndermitesOnlyIfPlayerSpawned || endermite.isPlayerSpawned()))); // Purpur ++ this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Endermite.class, 10, true, false, (entityliving) -> entityliving.level().purpurConfig.endermanAggroEndermites && entityliving instanceof Endermite endermite && (!entityliving.level().purpurConfig.endermanAggroEndermitesOnlyIfPlayerSpawned || endermite.isPlayerSpawned()))); // Purpur this.targetSelector.addGoal(4, new ResetUniversalAngerTargetGoal<>(this, false)); } -@@ -241,7 +270,7 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -245,7 +274,7 @@ public class EnderMan extends Monster implements NeutralMob { // Paper end ItemStack itemstack = (ItemStack) player.getInventory().armor.get(3); - if (itemstack.is(Blocks.CARVED_PUMPKIN.asItem())) { -+ if (this.level.purpurConfig.endermanDisableStareAggro || itemstack.is(Blocks.CARVED_PUMPKIN.asItem()) || (this.level.purpurConfig.endermanIgnorePlayerDragonHead && itemstack.is(net.minecraft.world.item.Items.DRAGON_HEAD))) { // Purpur ++ if (this.level().purpurConfig.endermanDisableStareAggro || itemstack.is(Blocks.CARVED_PUMPKIN.asItem()) || (this.level().purpurConfig.endermanIgnorePlayerDragonHead && itemstack.is(net.minecraft.world.item.Items.DRAGON_HEAD))) { // Purpur return false; } else { Vec3 vec3d = player.getViewVector(1.0F).normalize(); -@@ -278,12 +307,12 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -282,12 +311,12 @@ public class EnderMan extends Monster implements NeutralMob { @Override public boolean isSensitiveToWater() { - return true; -+ return this.level.purpurConfig.endermanTakeDamageFromWater; // Purpur ++ return this.level().purpurConfig.endermanTakeDamageFromWater; // Purpur } @Override protected void customServerAiStep() { -- if (this.level.isDay() && this.tickCount >= this.targetChangeTime + 600) { -+ if ((getRider() == null || !this.isControllable()) && this.level.isDay() && this.tickCount >= this.targetChangeTime + 600) { // Purpur - no random teleporting +- if (this.level().isDay() && this.tickCount >= this.targetChangeTime + 600) { ++ if ((getRider() == null || !this.isControllable()) && this.level().isDay() && this.tickCount >= this.targetChangeTime + 600) { // Purpur - no random teleporting 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 -@@ -404,6 +433,8 @@ public class EnderMan extends Monster implements NeutralMob { + 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 +@@ -408,6 +437,8 @@ public class EnderMan extends Monster implements NeutralMob { public boolean hurt(DamageSource source, float amount) { if (this.isInvulnerableTo(source)) { return false; @@ -11862,34 +11961,34 @@ index c2f5dabb41b172547864decc06aa632d89dff3e1..7c26e1979cdae52e2e94d24dd8c3164e } else { boolean flag = source.getDirectEntity() instanceof ThrownPotion; boolean flag1; -@@ -418,6 +449,7 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -422,6 +453,7 @@ public class EnderMan extends Monster implements NeutralMob { } else { flag1 = flag && this.hurtWithCleanWater(source, (ThrownPotion) source.getDirectEntity(), amount); -+ if (!flag1 && this.level.purpurConfig.endermanIgnoreProjectiles) return super.hurt(source, amount); // Purpur ++ if (!flag1 && this.level().purpurConfig.endermanIgnoreProjectiles) return super.hurt(source, amount); // Purpur if (this.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.INDIRECT)) { // Paper start for (int i = 0; i < 64; ++i) { if (this.teleport()) { -@@ -464,7 +496,7 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -468,7 +500,7 @@ public class EnderMan extends Monster implements NeutralMob { @Override public boolean requiresCustomPersistence() { - return super.requiresCustomPersistence() || this.getCarriedBlock() != null; -+ return super.requiresCustomPersistence() || (!this.level.purpurConfig.endermanDespawnEvenWithBlock && this.getCarriedBlock() != null); // Purpur ++ return super.requiresCustomPersistence() || (!this.level().purpurConfig.endermanDespawnEvenWithBlock && this.getCarriedBlock() != null); // Purpur } private static class EndermanFreezeWhenLookedAt extends Goal { -@@ -511,7 +543,16 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -515,7 +547,16 @@ public class EnderMan extends Monster implements NeutralMob { @Override public boolean canUse() { -- return this.enderman.getCarriedBlock() == null ? false : (!this.enderman.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) ? false : this.enderman.getRandom().nextInt(reducedTickDelay(2000)) == 0); -+ if (!enderman.level.purpurConfig.endermanAllowGriefing) return false; // Purpur +- return this.enderman.getCarriedBlock() == null ? false : (!this.enderman.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) ? false : this.enderman.getRandom().nextInt(reducedTickDelay(2000)) == 0); ++ if (!enderman.level().purpurConfig.endermanAllowGriefing) return false; // Purpur + // Purpur start + if (this.enderman.getCarriedBlock() == null) { + return false; + } -+ if (!this.enderman.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && !this.enderman.level.purpurConfig.endermanBypassMobGriefing) { ++ if (!this.enderman.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && !this.enderman.level().purpurConfig.endermanBypassMobGriefing) { + return false; + } + return this.enderman.getRandom().nextInt(reducedTickDelay(2000)) == 0; @@ -11897,17 +11996,17 @@ index c2f5dabb41b172547864decc06aa632d89dff3e1..7c26e1979cdae52e2e94d24dd8c3164e } @Override -@@ -558,7 +599,16 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -560,7 +601,16 @@ public class EnderMan extends Monster implements NeutralMob { @Override public boolean canUse() { -- return this.enderman.getCarriedBlock() != null ? false : (!this.enderman.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) ? false : this.enderman.getRandom().nextInt(reducedTickDelay(20)) == 0); -+ if (!enderman.level.purpurConfig.endermanAllowGriefing) return false; // Purpur +- return this.enderman.getCarriedBlock() != null ? false : (!this.enderman.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) ? false : this.enderman.getRandom().nextInt(reducedTickDelay(20)) == 0); ++ if (!enderman.level().purpurConfig.endermanAllowGriefing) return false; // Purpur + // Purpur start + if (this.enderman.getCarriedBlock() != null) { + return false; + } -+ if (!this.enderman.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && !this.enderman.level.purpurConfig.endermanBypassMobGriefing) { ++ if (!this.enderman.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && !this.enderman.level().purpurConfig.endermanBypassMobGriefing) { + return false; + } + return this.enderman.getRandom().nextInt(reducedTickDelay(20)) == 0; @@ -11916,7 +12015,7 @@ index c2f5dabb41b172547864decc06aa632d89dff3e1..7c26e1979cdae52e2e94d24dd8c3164e @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 e8c3972b889fd6b348a5b0d18444d28faa813879..e6ecc47828fea09c80ed3a4c39f0d85f4d820571 100644 +index 29b8771ec85f07fcd9d9ba041c9a25a212009b16..e131949bd6aab4c8ff5cd4ea57280ad945ceef67 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Endermite.java +++ b/src/main/java/net/minecraft/world/entity/monster/Endermite.java @@ -31,20 +31,63 @@ import net.minecraft.world.level.block.state.BlockState; @@ -11933,27 +12032,28 @@ index e8c3972b889fd6b348a5b0d18444d28faa813879..e6ecc47828fea09c80ed3a4c39f0d85f + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.endermiteRidable; ++ return level().purpurConfig.endermiteRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.endermiteRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.endermiteRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.endermiteControllable; ++ return level().purpurConfig.endermiteControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.endermiteMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.endermiteMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.endermiteTakeDamageFromWater; ++ return this.level().purpurConfig.endermiteTakeDamageFromWater; + } + + public boolean isPlayerSpawned() { @@ -11966,15 +12066,14 @@ index e8c3972b889fd6b348a5b0d18444d28faa813879..e6ecc47828fea09c80ed3a4c39f0d85f + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.endermiteAlwaysDropExp; ++ return this.level().purpurConfig.endermiteAlwaysDropExp; + } -+ // Purpur end + @Override 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 ClimbOnTopOfPowderSnowGoal(this, this.level)); + this.goalSelector.addGoal(1, new ClimbOnTopOfPowderSnowGoal(this, this.level())); this.goalSelector.addGoal(2, new MeleeAttackGoal(this, 1.0D, false)); this.goalSelector.addGoal(3, new WaterAvoidingRandomStrollGoal(this, 1.0D)); this.goalSelector.addGoal(7, new LookAtPlayerGoal(this, Player.class, 8.0F)); @@ -11999,7 +12098,7 @@ index e8c3972b889fd6b348a5b0d18444d28faa813879..e6ecc47828fea09c80ed3a4c39f0d85f @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 1935f1eb28724d8f03a9612a9b4ddefbbc557157..892e0c0306a21ea638649c1324b8115f24c01bd2 100644 +index a6dde4e31790eaecff27135a4036627192c85702..4a87b76cc92220f6569b976871a86c8eab3c218d 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Evoker.java +++ b/src/main/java/net/minecraft/world/entity/monster/Evoker.java @@ -48,10 +48,43 @@ public class Evoker extends SpellcasterIllager { @@ -12009,34 +12108,34 @@ index 1935f1eb28724d8f03a9612a9b4ddefbbc557157..892e0c0306a21ea638649c1324b8115f + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.evokerRidable; ++ return level().purpurConfig.evokerRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.evokerRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.evokerRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.evokerControllable; ++ return level().purpurConfig.evokerControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.evokerMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.evokerMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.evokerTakeDamageFromWater; ++ return this.level().purpurConfig.evokerTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.evokerAlwaysDropExp; ++ return this.level().purpurConfig.evokerAlwaysDropExp; + } -+ // Purpur end + @Override protected void registerGoals() { @@ -12058,38 +12157,38 @@ index 1935f1eb28724d8f03a9612a9b4ddefbbc557157..892e0c0306a21ea638649c1324b8115f return false; } else if (Evoker.this.tickCount < this.nextAttackTickCount) { return false; -- } else if (!Evoker.this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -+ } else if (!Evoker.this.level.purpurConfig.evokerBypassMobGriefing && !Evoker.this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur +- } else if (!Evoker.this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ } else if (!Evoker.this.level().purpurConfig.evokerBypassMobGriefing && !Evoker.this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur return false; } else { - List list = Evoker.this.level.getNearbyEntities(Sheep.class, this.wololoTargeting, Evoker.this, Evoker.this.getBoundingBox().inflate(16.0D, 4.0D, 16.0D)); + 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 bb2cb17e4e5ce142eeec18951c8948e3d6b3209c..77dcae6ecd87fade2b529386ba1360836363593a 100644 +index 592b0dae251800552a0771ec46b4b8532b63075d..b0aad5778a12d3f0f2ef806f856064c4da842fb3 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Ghast.java +++ b/src/main/java/net/minecraft/world/entity/monster/Ghast.java -@@ -44,11 +44,62 @@ public class Ghast extends FlyingMob implements Enemy { +@@ -44,11 +44,47 @@ public class Ghast extends FlyingMob implements Enemy { this.moveControl = new Ghast.GhastMoveControl(this); } + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.ghastRidable; ++ return level().purpurConfig.ghastRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.ghastRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.ghastRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.ghastControllable; ++ return level().purpurConfig.ghastControllable; + } + + @Override + public double getMaxY() { -+ return level.purpurConfig.ghastMaxY; ++ return level().purpurConfig.ghastMaxY; + } + + @Override @@ -12103,21 +12202,6 @@ index bb2cb17e4e5ce142eeec18951c8948e3d6b3209c..77dcae6ecd87fade2b529386ba136083 + setDeltaMovement(mot.scale(0.9D)); + } + } -+ -+ @Override -+ public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.ghastMaxHealth); -+ } -+ -+ @Override -+ public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.ghastTakeDamageFromWater; -+ } -+ -+ @Override -+ protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.ghastAlwaysDropExp; -+ } + // Purpur end + @Override @@ -12130,6 +12214,28 @@ index bb2cb17e4e5ce142eeec18951c8948e3d6b3209c..77dcae6ecd87fade2b529386ba136083 this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, (entityliving) -> { return Math.abs(entityliving.getY() - this.getY()) <= 4.0D; })); +@@ -96,6 +132,21 @@ public class Ghast extends FlyingMob implements Enemy { + } + } + ++ @Override ++ public void initAttributes() { ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.ghastMaxHealth); ++ } ++ ++ @Override ++ public boolean isSensitiveToWater() { ++ return this.level().purpurConfig.ghastTakeDamageFromWater; ++ } ++ ++ @Override ++ protected boolean isAlwaysExperienceDropper() { ++ return this.level().purpurConfig.ghastAlwaysDropExp; ++ } ++ + @Override + protected void defineSynchedData() { + super.defineSynchedData(); @@ -103,7 +154,7 @@ public class Ghast extends FlyingMob implements Enemy { } @@ -12158,10 +12264,10 @@ index bb2cb17e4e5ce142eeec18951c8948e3d6b3209c..77dcae6ecd87fade2b529386ba136083 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 41004c28edb748e12c4f868aa07b4672891197c1..4e5b9f772ba587b4e108add3758dffa665c1c3f3 100644 +index 41004c28edb748e12c4f868aa07b4672891197c1..88b0dffe2c2b4da1406f218186d28f018ee879a3 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,17 +1,122 @@ package net.minecraft.world.entity.monster; import net.minecraft.core.BlockPos; @@ -12205,36 +12311,29 @@ index 41004c28edb748e12c4f868aa07b4672891197c1..4e5b9f772ba587b4e108add3758dffa6 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.giantRidable; ++ return level().purpurConfig.giantRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.giantRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.giantRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.giantControllable; -+ } -+ -+ @Override -+ protected void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.giantMaxHealth); -+ this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(this.level.purpurConfig.giantMovementSpeed); -+ this.getAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(this.level.purpurConfig.giantAttackDamage); ++ return level().purpurConfig.giantControllable; + } + + @Override + protected void registerGoals() { -+ if (level.purpurConfig.giantHaveAI) { ++ if (level().purpurConfig.giantHaveAI) { + this.goalSelector.addGoal(0, new FloatGoal(this)); + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); + this.goalSelector.addGoal(7, new WaterAvoidingRandomStrollGoal(this, 1.0D)); + this.goalSelector.addGoal(8, new LookAtPlayerGoal(this, Player.class, 16.0F)); + this.goalSelector.addGoal(8, new RandomLookAroundGoal(this)); + this.goalSelector.addGoal(5, new MoveTowardsRestrictionGoal(this, 1.0D)); -+ if (level.purpurConfig.giantHaveHostileAI) { ++ if (level().purpurConfig.giantHaveHostileAI) { + this.goalSelector.addGoal(2, new MeleeAttackGoal(this, 1.0D, false)); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); + this.targetSelector.addGoal(1, new HurtByTargetGoal(this).setAlertOthers(ZombifiedPiglin.class)); @@ -12247,6 +12346,24 @@ index 41004c28edb748e12c4f868aa07b4672891197c1..4e5b9f772ba587b4e108add3758dffa6 + } + + @Override ++ public boolean isSensitiveToWater() { ++ return this.level().purpurConfig.giantTakeDamageFromWater; ++ } ++ ++ @Override ++ protected boolean isAlwaysExperienceDropper() { ++ return this.level().purpurConfig.giantAlwaysDropExp; ++ } ++ // Purpur end ++ ++ @Override ++ protected void initAttributes() { ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.giantMaxHealth); ++ this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(this.level().purpurConfig.giantMovementSpeed); ++ this.getAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(this.level().purpurConfig.giantAttackDamage); ++ } ++ ++ @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); + if (groupData == null) { @@ -12260,7 +12377,7 @@ index 41004c28edb748e12c4f868aa07b4672891197c1..4e5b9f772ba587b4e108add3758dffa6 + protected void populateDefaultEquipmentSlots(net.minecraft.util.RandomSource random, DifficultyInstance difficulty) { + super.populateDefaultEquipmentSlots(this.random, difficulty); + // TODO make configurable -+ if (random.nextFloat() < (level.getDifficulty() == Difficulty.HARD ? 0.1F : 0.05F)) { ++ if (random.nextFloat() < (level().getDifficulty() == Difficulty.HARD ? 0.1F : 0.05F)) { + this.setItemSlot(EquipmentSlot.MAINHAND, new ItemStack(Items.IRON_SWORD)); + } + } @@ -12269,22 +12386,10 @@ index 41004c28edb748e12c4f868aa07b4672891197c1..4e5b9f772ba587b4e108add3758dffa6 + public float getJumpPower() { + // 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 -+ public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.giantTakeDamageFromWater; -+ } -+ -+ @Override -+ protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.giantAlwaysDropExp; ++ return level().purpurConfig.giantJumpHeight; } -+ // Purpur end @Override - protected float getStandingEyeHeight(Pose pose, EntityDimensions dimensions) { @@ -25,6 +130,6 @@ public class Giant extends Monster { @Override @@ -12294,7 +12399,7 @@ index 41004c28edb748e12c4f868aa07b4672891197c1..4e5b9f772ba587b4e108add3758dffa6 } } 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 cf7e9c1db229f9e2cc05ce3046540db1d4fc4ec4..f10304b38e904528907cb36c342acf9d49935edd 100644 +index 5e9b9e9f124ec6103b2e832ae94bc5b334a2c533..96338ed7952683f56d9a406d0956ce230581f146 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Guardian.java +++ b/src/main/java/net/minecraft/world/entity/monster/Guardian.java @@ -69,15 +69,51 @@ public class Guardian extends Monster { @@ -12316,29 +12421,29 @@ index cf7e9c1db229f9e2cc05ce3046540db1d4fc4ec4..f10304b38e904528907cb36c342acf9d + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.guardianRidable; ++ return level().purpurConfig.guardianRidable; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.guardianControllable; ++ return level().purpurConfig.guardianControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.guardianMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.guardianMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.guardianTakeDamageFromWater; ++ return this.level().purpurConfig.guardianTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.guardianAlwaysDropExp; ++ return this.level().purpurConfig.guardianAlwaysDropExp; + } -+ // Purpur end + @Override protected void registerGoals() { @@ -12404,72 +12509,71 @@ index cf7e9c1db229f9e2cc05ce3046540db1d4fc4ec4..f10304b38e904528907cb36c342acf9d 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 4996347c6dde85a2dc9aa37fdf495160093fac64..a7b690c0730d0b10133f24d7ce2d9f6a0e4a7c04 100644 +index efe8e6b895da1a81e5de42697fda58443cf15a59..cd78fbca21112a2354bc40747531e5202bbd5f20 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Husk.java +++ b/src/main/java/net/minecraft/world/entity/monster/Husk.java -@@ -20,15 +20,68 @@ public class Husk extends Zombie { +@@ -20,6 +20,59 @@ public class Husk extends Zombie { public Husk(EntityType type, Level world) { super(type, world); + this.setShouldBurnInDay(false); // Purpur - } - ++ } ++ + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.huskRidable; ++ return level().purpurConfig.huskRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.huskRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.huskRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.huskControllable; ++ return level().purpurConfig.huskControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.huskMaxHealth); ++ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.huskMaxHealth); + } + + @Override + protected void randomizeReinforcementsChance() { -+ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.SPAWN_REINFORCEMENTS_CHANCE).setBaseValue(this.random.nextDouble() * this.level.purpurConfig.huskSpawnReinforcements); ++ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.SPAWN_REINFORCEMENTS_CHANCE).setBaseValue(this.random.nextDouble() * this.level().purpurConfig.huskSpawnReinforcements); + } + + @Override + public boolean jockeyOnlyBaby() { -+ return level.purpurConfig.huskJockeyOnlyBaby; ++ return level().purpurConfig.huskJockeyOnlyBaby; + } + + @Override + public double jockeyChance() { -+ return level.purpurConfig.huskJockeyChance; ++ return level().purpurConfig.huskJockeyChance; + } + + @Override + public boolean jockeyTryExistingChickens() { -+ return level.purpurConfig.huskJockeyTryExistingChickens; ++ return level().purpurConfig.huskJockeyTryExistingChickens; + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.huskTakeDamageFromWater; ++ return this.level().purpurConfig.huskTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.huskAlwaysDropExp; -+ } -+ // Purpur end -+ - public static boolean checkHuskSpawnRules(EntityType type, ServerLevelAccessor world, MobSpawnType spawnReason, BlockPos pos, RandomSource random) { - return checkMonsterSpawnRules(type, world, spawnReason, pos, random) && (spawnReason == MobSpawnType.SPAWNER || world.canSeeSky(pos)); ++ return this.level().purpurConfig.huskAlwaysDropExp; } + public static boolean checkHuskSpawnRules(EntityType type, ServerLevelAccessor world, MobSpawnType spawnReason, BlockPos pos, RandomSource random) { +@@ -28,7 +81,7 @@ public class Husk extends Zombie { + @Override public boolean isSunSensitive() { - return false; @@ -12478,7 +12582,7 @@ index 4996347c6dde85a2dc9aa37fdf495160093fac64..a7b690c0730d0b10133f24d7ce2d9f6a @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 10573602c9bc73713cbd6989762d3dbb6f6fcf8c..63577d941dbd21cf93bc6f88bb50922618b6b5d5 100644 +index 63fce7e3d9f59f36e29bc827a46396d73143bb8b..f9cddf46d1dbcabc738842ba039daa76bb6f3eb5 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 { @@ -12488,36 +12592,36 @@ index 10573602c9bc73713cbd6989762d3dbb6f6fcf8c..63577d941dbd21cf93bc6f88bb509226 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.illusionerRidable; ++ return level().purpurConfig.illusionerRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.illusionerRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.illusionerRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.illusionerControllable; ++ return level().purpurConfig.illusionerControllable; + } ++ // Purpur end + + @Override + protected void initAttributes() { -+ this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(this.level.purpurConfig.illusionerMovementSpeed); -+ this.getAttribute(Attributes.FOLLOW_RANGE).setBaseValue(this.level.purpurConfig.illusionerFollowRange); -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.illusionerMaxHealth); ++ this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(this.level().purpurConfig.illusionerMovementSpeed); ++ this.getAttribute(Attributes.FOLLOW_RANGE).setBaseValue(this.level().purpurConfig.illusionerFollowRange); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.illusionerMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.illusionerTakeDamageFromWater; ++ return this.level().purpurConfig.illusionerTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.illusionerAlwaysDropExp; ++ return this.level().purpurConfig.illusionerAlwaysDropExp; + } -+ // Purpur end + @Override protected void registerGoals() { @@ -12536,7 +12640,7 @@ index 10573602c9bc73713cbd6989762d3dbb6f6fcf8c..63577d941dbd21cf93bc6f88bb509226 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 f23d8796aec3e02a3bb23f338903f39b6ef9dcf1..11af95207f5aff52427dc216fb9929b0f536f411 100644 +index 2858ea5562d06c11e5c7337a2b123f9be7a3f62e..1ad97267394d3717b1871336193cdc91f3ffb276 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 { @@ -12546,66 +12650,67 @@ index f23d8796aec3e02a3bb23f338903f39b6ef9dcf1..11af95207f5aff52427dc216fb9929b0 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.magmaCubeRidable; ++ return level().purpurConfig.magmaCubeRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.magmaCubeRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.magmaCubeRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.magmaCubeControllable; ++ return level().purpurConfig.magmaCubeControllable; + } + + @Override + public float getJumpPower() { + return 0.42F * this.getBlockJumpFactor(); // from EntityLiving + } ++ // Purpur end + + @Override + protected String getMaxHealthEquation() { -+ return level.purpurConfig.magmaCubeMaxHealth; ++ return level().purpurConfig.magmaCubeMaxHealth; + } + + @Override + protected String getAttackDamageEquation() { -+ return level.purpurConfig.magmaCubeAttackDamage; ++ return level().purpurConfig.magmaCubeAttackDamage; + } + + @Override + protected java.util.Map getMaxHealthCache() { -+ return level.purpurConfig.magmaCubeMaxHealthCache; ++ return level().purpurConfig.magmaCubeMaxHealthCache; + } + + @Override + protected java.util.Map getAttackDamageCache() { -+ return level.purpurConfig.magmaCubeAttackDamageCache; ++ return level().purpurConfig.magmaCubeAttackDamageCache; + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.magmaCubeTakeDamageFromWater; ++ return this.level().purpurConfig.magmaCubeTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.magmaCubeAlwaysDropExp; ++ return this.level().purpurConfig.magmaCubeAlwaysDropExp; + } -+ // Purpur end + public static AttributeSupplier.Builder createAttributes() { return Monster.createMonsterAttributes().add(Attributes.MOVEMENT_SPEED, (double)0.2F); } -@@ -70,10 +122,11 @@ public class MagmaCube extends Slime { +@@ -70,11 +122,12 @@ public class MagmaCube extends Slime { } @Override - protected void jumpFromGround() { + public void jumpFromGround() { // Purpur - protected -> public Vec3 vec3 = this.getDeltaMovement(); - this.setDeltaMovement(vec3.x, (double)(this.getJumpPower() + (float)this.getSize() * 0.1F), vec3.z); + float f = (float)this.getSize() * 0.1F; + this.setDeltaMovement(vec3.x, (double)(this.getJumpPower() + f), vec3.z); this.hasImpulse = true; + this.actualJump = false; // Purpur } @@ -12631,44 +12736,44 @@ index 55c245d0dfa369dc6de2197ae37335fba4fae4ae..c9b40515f4c2ff1eedfc9510930c3bae 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 97fb1d2110a51498f6419841081b500b3f190370..2c00a9fdd3a6ea16ee765339857cf58521c85797 100644 +index 4a132c3eff6978e927bcd4df56b9ce0306af6d19..17638b9d3340c86528a8ae597712c7590b98dba6 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java +++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java @@ -49,6 +49,8 @@ public class Phantom extends FlyingMob implements Enemy { Vec3 moveTargetPoint; public BlockPos anchorPoint; Phantom.AttackPhase attackPhase; -+ Vec3 crystalPosition; // Purpur + private static final net.minecraft.world.item.crafting.Ingredient TORCH = net.minecraft.world.item.crafting.Ingredient.of(net.minecraft.world.item.Items.TORCH, net.minecraft.world.item.Items.SOUL_TORCH); // Purpur ++ Vec3 crystalPosition; // Purpur public Phantom(EntityType type, Level world) { super(type, world); -@@ -58,8 +60,110 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -58,6 +60,92 @@ public class Phantom extends FlyingMob implements Enemy { this.xpReward = 5; this.moveControl = new Phantom.PhantomMoveControl(this); this.lookControl = new Phantom.PhantomLookControl(this); + this.setShouldBurnInDay(true); // Purpur - } - ++ } ++ + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.phantomRidable; ++ return level().purpurConfig.phantomRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.phantomRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.phantomRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.phantomControllable; ++ return level().purpurConfig.phantomControllable; + } + + @Override + public double getMaxY() { -+ return level.purpurConfig.phantomMaxY; ++ return level().purpurConfig.phantomMaxY; + } + + @Override @@ -12700,13 +12805,79 @@ index 97fb1d2110a51498f6419841081b500b3f190370..2c00a9fdd3a6ea16ee765339857cf585 + loc.setPitch(-loc.getPitch()); + org.bukkit.util.Vector target = loc.getDirection().normalize().multiply(100).add(loc.toVector()); + -+ org.purpurmc.purpur.entity.PhantomFlames flames = new org.purpurmc.purpur.entity.PhantomFlames(level, this); -+ flames.canGrief = level.purpurConfig.phantomAllowGriefing; ++ org.purpurmc.purpur.entity.PhantomFlames flames = new org.purpurmc.purpur.entity.PhantomFlames(level(), this); ++ flames.canGrief = level().purpurConfig.phantomAllowGriefing; + flames.shoot(target.getX() - getX(), target.getY() - getY(), target.getZ() - getZ(), 1.0F, 5.0F); -+ level.addFreshEntity(flames); ++ level().addFreshEntity(flames); + return true; + } + ++ @Override ++ protected void dropFromLootTable(DamageSource damageSource, boolean causedByPlayer) { ++ boolean dropped = false; ++ if (lastHurtByPlayer == null && damageSource.getEntity() instanceof net.minecraft.world.entity.boss.enderdragon.EndCrystal) { ++ if (random.nextInt(5) < 1) { ++ dropped = spawnAtLocation(new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.PHANTOM_MEMBRANE)) != null; ++ } ++ } ++ if (!dropped) { ++ super.dropFromLootTable(damageSource, causedByPlayer); ++ } ++ } ++ ++ public boolean isCirclingCrystal() { ++ return crystalPosition != null; ++ } ++ // Purpur end ++ ++ @Override ++ public boolean isSensitiveToWater() { ++ return this.level().purpurConfig.phantomTakeDamageFromWater; ++ } ++ ++ @Override ++ protected boolean isAlwaysExperienceDropper() { ++ return this.level().purpurConfig.phantomAlwaysDropExp; + } + + @Override +@@ -72,9 +160,17 @@ public class Phantom extends FlyingMob implements Enemy { + + @Override + protected void registerGoals() { +- this.goalSelector.addGoal(1, new Phantom.PhantomAttackStrategyGoal()); +- this.goalSelector.addGoal(2, new Phantom.PhantomSweepAttackGoal()); +- this.goalSelector.addGoal(3, new Phantom.PhantomCircleAroundAnchorGoal()); ++ // Purpur start ++ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); ++ if (level().purpurConfig.phantomOrbitCrystalRadius > 0) { ++ this.goalSelector.addGoal(1, new FindCrystalGoal(this)); ++ this.goalSelector.addGoal(2, new OrbitCrystalGoal(this)); ++ } ++ this.goalSelector.addGoal(3, new Phantom.PhantomAttackStrategyGoal()); ++ this.goalSelector.addGoal(4, new Phantom.PhantomSweepAttackGoal()); ++ this.goalSelector.addGoal(5, new Phantom.PhantomCircleAroundAnchorGoal()); ++ this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); ++ // Purpur end + this.targetSelector.addGoal(1, new Phantom.PhantomAttackPlayerTargetGoal()); + } + +@@ -90,7 +186,10 @@ public class Phantom extends FlyingMob implements Enemy { + + private void updatePhantomSizeInfo() { + this.refreshDimensions(); +- this.getAttribute(Attributes.ATTACK_DAMAGE).setBaseValue((double) (6 + this.getPhantomSize())); ++ // Purpur start ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(getFromCache(() -> this.level().purpurConfig.phantomMaxHealth, () -> this.level().purpurConfig.phantomMaxHealthCache, () -> 20.0D)); ++ this.getAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(getFromCache(() -> this.level().purpurConfig.phantomAttackDamage, () -> this.level().purpurConfig.phantomAttackDamageCache, () -> (double) 6 + this.getPhantomSize())); ++ // Purpur end + } + + public int getPhantomSize() { +@@ -120,6 +219,21 @@ public class Phantom extends FlyingMob implements Enemy { + return true; + } + + private double getFromCache(java.util.function.Supplier equation, java.util.function.Supplier> cache, java.util.function.Supplier defaultValue) { + int size = getPhantomSize(); + Double value = cache.get().get(size); @@ -12721,77 +12892,15 @@ index 97fb1d2110a51498f6419841081b500b3f190370..2c00a9fdd3a6ea16ee765339857cf585 + } + return value; + } -+ -+ @Override -+ protected net.minecraft.world.level.storage.loot.LootContext.Builder createLootContext(boolean causedByPlayer, DamageSource source) { -+ boolean dropped = false; -+ if (lastHurtByPlayer == null && source.getEntity() instanceof net.minecraft.world.entity.boss.enderdragon.EndCrystal) { -+ if (random.nextInt(5) < 1) { -+ dropped = spawnAtLocation(new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.PHANTOM_MEMBRANE)) != null; -+ } -+ } -+ if (!dropped) { -+ return super.createLootContext(causedByPlayer, source); -+ } -+ return new net.minecraft.world.level.storage.loot.LootContext.Builder((net.minecraft.server.level.ServerLevel) level); -+ } -+ -+ public boolean isCirclingCrystal() { -+ return crystalPosition != null; -+ } -+ -+ @Override -+ public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.phantomTakeDamageFromWater; -+ } -+ -+ @Override -+ protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.phantomAlwaysDropExp; -+ } -+ // Purpur end + @Override - public boolean isFlapping() { - return (this.getUniqueFlapTickOffset() + this.tickCount) % Phantom.TICKS_PER_FLAP == 0; -@@ -72,9 +176,17 @@ public class Phantom extends FlyingMob implements Enemy { - - @Override - protected void registerGoals() { -- this.goalSelector.addGoal(1, new Phantom.PhantomAttackStrategyGoal()); -- this.goalSelector.addGoal(2, new Phantom.PhantomSweepAttackGoal()); -- this.goalSelector.addGoal(3, new Phantom.PhantomCircleAroundAnchorGoal()); -+ // Purpur start -+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); -+ if (level.purpurConfig.phantomOrbitCrystalRadius > 0) { -+ this.goalSelector.addGoal(1, new FindCrystalGoal(this)); -+ this.goalSelector.addGoal(2, new OrbitCrystalGoal(this)); -+ } -+ this.goalSelector.addGoal(3, new Phantom.PhantomAttackStrategyGoal()); -+ this.goalSelector.addGoal(4, new Phantom.PhantomSweepAttackGoal()); -+ this.goalSelector.addGoal(5, new Phantom.PhantomCircleAroundAnchorGoal()); -+ this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); -+ // Purpur end - this.targetSelector.addGoal(1, new Phantom.PhantomAttackPlayerTargetGoal()); - } - -@@ -90,7 +202,10 @@ public class Phantom extends FlyingMob implements Enemy { - - private void updatePhantomSizeInfo() { - this.refreshDimensions(); -- this.getAttribute(Attributes.ATTACK_DAMAGE).setBaseValue((double) (6 + this.getPhantomSize())); -+ // Purpur start -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(getFromCache(() -> this.level.purpurConfig.phantomMaxHealth, () -> this.level.purpurConfig.phantomMaxHealthCache, () -> 20.0D)); -+ this.getAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(getFromCache(() -> this.level.purpurConfig.phantomAttackDamage, () -> this.level.purpurConfig.phantomAttackDamageCache, () -> (double) 6 + this.getPhantomSize())); -+ // Purpur end - } - - public int getPhantomSize() { -@@ -140,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); + public void tick() { + super.tick(); +@@ -140,14 +254,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); } -+ if (level.purpurConfig.phantomFlamesOnSwoop && attackPhase == AttackPhase.SWOOP) shoot(); // Purpur ++ if (level().purpurConfig.phantomFlamesOnSwoop && attackPhase == AttackPhase.SWOOP) shoot(); // Purpur } @Override @@ -12804,7 +12913,7 @@ index 97fb1d2110a51498f6419841081b500b3f190370..2c00a9fdd3a6ea16ee765339857cf585 super.aiStep(); } -@@ -159,7 +272,11 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -159,7 +271,11 @@ public class Phantom extends FlyingMob implements Enemy { @Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType spawnReason, @Nullable SpawnGroupData entityData, @Nullable CompoundTag entityNbt) { this.anchorPoint = this.blockPosition().above(5); @@ -12817,7 +12926,7 @@ index 97fb1d2110a51498f6419841081b500b3f190370..2c00a9fdd3a6ea16ee765339857cf585 return super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityNbt); } -@@ -175,7 +292,7 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -175,7 +291,7 @@ public class Phantom extends FlyingMob implements Enemy { if (nbt.hasUUID("Paper.SpawningEntity")) { this.spawningEntity = nbt.getUUID("Paper.SpawningEntity"); } @@ -12826,7 +12935,7 @@ index 97fb1d2110a51498f6419841081b500b3f190370..2c00a9fdd3a6ea16ee765339857cf585 this.shouldBurnInDay = nbt.getBoolean("Paper.ShouldBurnInDay"); } // Paper end -@@ -192,7 +309,7 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -192,7 +308,7 @@ public class Phantom extends FlyingMob implements Enemy { if (this.spawningEntity != null) { nbt.putUUID("Paper.SpawningEntity", this.spawningEntity); } @@ -12835,7 +12944,7 @@ index 97fb1d2110a51498f6419841081b500b3f190370..2c00a9fdd3a6ea16ee765339857cf585 // Paper end } -@@ -258,8 +375,14 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -258,8 +374,14 @@ public class Phantom extends FlyingMob implements Enemy { } public void setSpawningEntity(java.util.UUID entity) { this.spawningEntity = entity; } @@ -12844,15 +12953,15 @@ index 97fb1d2110a51498f6419841081b500b3f190370..2c00a9fdd3a6ea16ee765339857cf585 + // private boolean shouldBurnInDay = true; // Purpur - moved to LivingEntity - keep methods for ABI compatibility + // Purpur start + public boolean shouldBurnInDay() { -+ boolean burnFromDaylight = this.shouldBurnInDay && this.level.purpurConfig.phantomBurnInDaylight; -+ boolean burnFromLightSource = this.level.purpurConfig.phantomBurnInLight > 0 && this.level.getMaxLocalRawBrightness(blockPosition()) >= this.level.purpurConfig.phantomBurnInLight; ++ boolean burnFromDaylight = this.shouldBurnInDay && this.level().purpurConfig.phantomBurnInDaylight; ++ boolean burnFromLightSource = this.level().purpurConfig.phantomBurnInLight > 0 && this.level().getMaxLocalRawBrightness(blockPosition()) >= this.level().purpurConfig.phantomBurnInLight; + return burnFromDaylight || burnFromLightSource; + } + // Purpur End public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; } // Paper end private static enum AttackPhase { -@@ -269,7 +392,125 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -269,7 +391,125 @@ public class Phantom extends FlyingMob implements Enemy { private AttackPhase() {} } @@ -12872,7 +12981,7 @@ index 97fb1d2110a51498f6419841081b500b3f190370..2c00a9fdd3a6ea16ee765339857cf585 + @Override + public boolean canUse() { + double range = maxTargetRange(); -+ List crystals = level.getEntitiesOfClass(net.minecraft.world.entity.boss.enderdragon.EndCrystal.class, phantom.getBoundingBox().inflate(range)); ++ List crystals = level().getEntitiesOfClass(net.minecraft.world.entity.boss.enderdragon.EndCrystal.class, phantom.getBoundingBox().inflate(range)); + if (crystals.isEmpty()) { + return false; + } @@ -12907,7 +13016,7 @@ index 97fb1d2110a51498f6419841081b500b3f190370..2c00a9fdd3a6ea16ee765339857cf585 + } + + private double maxTargetRange() { -+ return phantom.level.purpurConfig.phantomOrbitCrystalRadius; ++ return phantom.level().purpurConfig.phantomOrbitCrystalRadius; + } + } + @@ -12955,11 +13064,11 @@ index 97fb1d2110a51498f6419841081b500b3f190370..2c00a9fdd3a6ea16ee765339857cf585 + if (phantom.moveTargetPoint.distanceToSqr(phantom.getX(), phantom.getY(), phantom.getZ()) < 4.0D) { + updateOffset(); + } -+ if (phantom.moveTargetPoint.y < phantom.getY() && !phantom.level.isEmptyBlock(new BlockPos(phantom).below(1))) { ++ if (phantom.moveTargetPoint.y < phantom.getY() && !phantom.level().isEmptyBlock(new BlockPos(phantom).below(1))) { + this.verticalChange = Math.max(1.0F, this.verticalChange); + updateOffset(); + } -+ if (phantom.moveTargetPoint.y > phantom.getY() && !phantom.level.isEmptyBlock(new BlockPos(phantom).above(1))) { ++ if (phantom.moveTargetPoint.y > phantom.getY() && !phantom.level().isEmptyBlock(new BlockPos(phantom).above(1))) { + this.verticalChange = Math.min(-1.0F, this.verticalChange); + updateOffset(); + } @@ -12979,7 +13088,7 @@ index 97fb1d2110a51498f6419841081b500b3f190370..2c00a9fdd3a6ea16ee765339857cf585 private float speed = 0.1F; -@@ -277,8 +518,19 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -277,8 +517,19 @@ public class Phantom extends FlyingMob implements Enemy { super(entity); } @@ -13000,7 +13109,7 @@ index 97fb1d2110a51498f6419841081b500b3f190370..2c00a9fdd3a6ea16ee765339857cf585 if (Phantom.this.horizontalCollision) { Phantom.this.setYRot(Phantom.this.getYRot() + 180.0F); this.speed = 0.1F; -@@ -324,14 +576,20 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -324,14 +575,20 @@ public class Phantom extends FlyingMob implements Enemy { } } @@ -13023,29 +13132,29 @@ index 97fb1d2110a51498f6419841081b500b3f190370..2c00a9fdd3a6ea16ee765339857cf585 } private class PhantomBodyRotationControl extends BodyRotationControl { -@@ -418,6 +676,12 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -418,6 +675,12 @@ public class Phantom extends FlyingMob implements Enemy { return false; } else if (!entityliving.isAlive()) { return false; + // Purpur start -+ } else if (level.purpurConfig.phantomBurnInLight > 0 && level.getLightEmission(new BlockPos(Phantom.this)) >= level.purpurConfig.phantomBurnInLight) { ++ } else if (level().purpurConfig.phantomBurnInLight > 0 && level().getLightEmission(new BlockPos(Phantom.this)) >= level().purpurConfig.phantomBurnInLight) { + return false; -+ } else if (level.purpurConfig.phantomIgnorePlayersWithTorch && (TORCH.test(entityliving.getItemInHand(net.minecraft.world.InteractionHand.MAIN_HAND)) || TORCH.test(entityliving.getItemInHand(net.minecraft.world.InteractionHand.OFF_HAND)))) { ++ } else if (level().purpurConfig.phantomIgnorePlayersWithTorch && (TORCH.test(entityliving.getItemInHand(net.minecraft.world.InteractionHand.MAIN_HAND)) || TORCH.test(entityliving.getItemInHand(net.minecraft.world.InteractionHand.OFF_HAND)))) { + return false; + // Purpur end } else { if (entityliving instanceof Player) { Player entityhuman = (Player) entityliving; -@@ -563,6 +827,7 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -563,6 +826,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)); + List list = Phantom.this.level().getNearbyPlayers(this.attackTargeting, Phantom.this, Phantom.this.getBoundingBox().inflate(16.0D, 64.0D, 16.0D)); -+ if (level.purpurConfig.phantomIgnorePlayersWithTorch) list.removeIf(human -> TORCH.test(human.getItemInHand(net.minecraft.world.InteractionHand.MAIN_HAND)) || TORCH.test(human.getItemInHand(net.minecraft.world.InteractionHand.OFF_HAND)));// Purpur ++ if (level().purpurConfig.phantomIgnorePlayersWithTorch) list.removeIf(human -> TORCH.test(human.getItemInHand(net.minecraft.world.InteractionHand.MAIN_HAND)) || TORCH.test(human.getItemInHand(net.minecraft.world.InteractionHand.OFF_HAND)));// Purpur if (!list.isEmpty()) { 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 cec545c3baa6599d47b9cf1a4b97de8771062a22..06a96eb0ef40462932892c611f308eb31411d099 100644 +index cec545c3baa6599d47b9cf1a4b97de8771062a22..06d52d8b61abc4dbbdc953bfed2e688be377b3cc 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Pillager.java +++ b/src/main/java/net/minecraft/world/entity/monster/Pillager.java @@ -62,15 +62,49 @@ public class Pillager extends AbstractIllager implements CrossbowAttackMob, Inve @@ -13055,34 +13164,34 @@ index cec545c3baa6599d47b9cf1a4b97de8771062a22..06a96eb0ef40462932892c611f308eb3 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.pillagerRidable; ++ return level().purpurConfig.pillagerRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.pillagerRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.pillagerRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.pillagerControllable; ++ return level().purpurConfig.pillagerControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.pillagerMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.pillagerMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.pillagerTakeDamageFromWater; ++ return this.level().purpurConfig.pillagerTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.pillagerAlwaysDropExp; ++ return this.level().purpurConfig.pillagerAlwaysDropExp; + } -+ // Purpur end + @Override protected void registerGoals() { @@ -13099,27 +13208,27 @@ index cec545c3baa6599d47b9cf1a4b97de8771062a22..06a96eb0ef40462932892c611f308eb3 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 9258d0f7c5c27b6d3d8f99db947169d6800d8ea9..0099595a5daa9c0ca9e3fd35933038c1c8ecf009 100644 +index e87c6c8ab585d6b0b38bbb8e42c0082e38f03250..0211b50ce4b48a26698f1ece8b593747d170178e 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Ravager.java +++ b/src/main/java/net/minecraft/world/entity/monster/Ravager.java -@@ -65,14 +65,54 @@ public class Ravager extends Raider { +@@ -68,14 +68,54 @@ public class Ravager extends Raider { this.setPathfindingMalus(BlockPathTypes.LEAVES, 0.0F); } + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.ravagerRidable; ++ return level().purpurConfig.ravagerRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.ravagerRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.ravagerRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.ravagerControllable; ++ return level().purpurConfig.ravagerControllable; + } + + @Override @@ -13127,22 +13236,22 @@ index 9258d0f7c5c27b6d3d8f99db947169d6800d8ea9..0099595a5daa9c0ca9e3fd35933038c1 + super.onMount(rider); + getNavigation().stop(); + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.ravagerMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.ravagerMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.ravagerTakeDamageFromWater; ++ return this.level().purpurConfig.ravagerTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.ravagerAlwaysDropExp; ++ return this.level().purpurConfig.ravagerAlwaysDropExp; + } -+ // Purpur end + @Override protected void registerGoals() { @@ -13157,7 +13266,7 @@ index 9258d0f7c5c27b6d3d8f99db947169d6800d8ea9..0099595a5daa9c0ca9e3fd35933038c1 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) -> { -@@ -150,7 +190,7 @@ public class Ravager extends Raider { +@@ -153,7 +193,7 @@ public class Ravager extends Raider { @Override public void aiStep() { super.aiStep(); @@ -13166,26 +13275,26 @@ index 9258d0f7c5c27b6d3d8f99db947169d6800d8ea9..0099595a5daa9c0ca9e3fd35933038c1 if (this.isImmobile()) { this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.0D); } else { -@@ -160,7 +200,7 @@ public class Ravager extends Raider { +@@ -163,7 +203,7 @@ public class Ravager extends Raider { this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(Mth.lerp(0.1D, d1, d0)); } -- if (this.horizontalCollision && this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -+ if (this.horizontalCollision && (this.level.purpurConfig.ravagerBypassMobGriefing || this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // Purpur +- if (this.horizontalCollision && this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ if (this.horizontalCollision && (this.level().purpurConfig.ravagerBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // Purpur 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(); -@@ -170,7 +210,7 @@ public class Ravager extends Raider { - BlockState iblockdata = this.level.getBlockState(blockposition); +@@ -173,7 +213,7 @@ public class Ravager extends Raider { + BlockState iblockdata = this.level().getBlockState(blockposition); Block block = iblockdata.getBlock(); -- if (block instanceof LeavesBlock && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, iblockdata.getFluidState().createLegacyBlock()).isCancelled()) { // CraftBukkit // Paper -+ if (this.level.purpurConfig.ravagerGriefableBlocks.contains(block) && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, iblockdata.getFluidState().createLegacyBlock()).isCancelled()) { // CraftBukkit // Paper - flag = this.level.destroyBlock(blockposition, true, this) || flag; - } - } +- if (block instanceof LeavesBlock) { ++ if (this.level().purpurConfig.ravagerGriefableBlocks.contains(block)) { // Purpur + // CraftBukkit start + 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 8cb910da17d75a9d9c7dbeb3c9e24b6de657a2f7..8b03a027bff592b2257e065f328da6d86e11db98 100644 +index d2073de07bdad71b20e05046577b16649123967b..3e2c60a301d4c66c85cd8ff812331005a667dc4e 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; @@ -13213,33 +13322,34 @@ index 8cb910da17d75a9d9c7dbeb3c9e24b6de657a2f7..8b03a027bff592b2257e065f328da6d8 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.shulkerRidable; ++ return level().purpurConfig.shulkerRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.shulkerRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.shulkerRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.shulkerControllable; ++ return level().purpurConfig.shulkerControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.shulkerMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.shulkerMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.shulkerTakeDamageFromWater; ++ return this.level().purpurConfig.shulkerTakeDamageFromWater; + } + + @Override + protected InteractionResult mobInteract(Player player, InteractionHand hand) { + ItemStack itemstack = player.getItemInHand(hand); -+ if (player.level.purpurConfig.shulkerChangeColorWithDye && itemstack.getItem() instanceof DyeItem dye && dye.getDyeColor() != this.getColor()) { ++ if (player.level().purpurConfig.shulkerChangeColorWithDye && itemstack.getItem() instanceof DyeItem dye && dye.getDyeColor() != this.getColor()) { + this.setVariant(Optional.of(dye.getDyeColor())); + if (!player.getAbilities().instabuild) { + itemstack.shrink(1); @@ -13251,9 +13361,8 @@ index 8cb910da17d75a9d9c7dbeb3c9e24b6de657a2f7..8b03a027bff592b2257e065f328da6d8 + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.shulkerAlwaysDropExp; ++ return this.level().purpurConfig.shulkerAlwaysDropExp; + } -+ // Purpur end + @Override protected void registerGoals() { @@ -13266,42 +13375,43 @@ index 8cb910da17d75a9d9c7dbeb3c9e24b6de657a2f7..8b03a027bff592b2257e065f328da6d8 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)); -@@ -484,11 +535,20 @@ public class Shulker extends AbstractGolem implements VariantHolder= f) { -+ if ((!this.level.purpurConfig.shulkerSpawnFromBulletRequireOpenLid || !this.isClosed()) && this.teleportSomewhere()) { +- if (this.level().random.nextFloat() >= f) { ++ if ((!this.level().purpurConfig.shulkerSpawnFromBulletRequireOpenLid || !this.isClosed()) && this.teleportSomewhere()) { + // Purpur start -+ float chance = this.level.purpurConfig.shulkerSpawnFromBulletBaseChance; -+ if (!this.level.purpurConfig.shulkerSpawnFromBulletNearbyEquation.isBlank()) { -+ int nearby = this.level.getEntities((EntityTypeTest) EntityType.SHULKER, axisalignedbb.inflate(this.level.purpurConfig.shulkerSpawnFromBulletNearbyRange), Entity::isAlive).size(); ++ float chance = this.level().purpurConfig.shulkerSpawnFromBulletBaseChance; ++ if (!this.level().purpurConfig.shulkerSpawnFromBulletNearbyEquation.isBlank()) { ++ int nearby = this.level().getEntities((EntityTypeTest) EntityType.SHULKER, axisalignedbb.inflate(this.level().purpurConfig.shulkerSpawnFromBulletNearbyRange), Entity::isAlive).size(); + try { -+ chance -= ((Number) scriptEngine.eval("let nearby = " + nearby + "; " + this.level.purpurConfig.shulkerSpawnFromBulletNearbyEquation)).floatValue(); ++ chance -= ((Number) scriptEngine.eval("let nearby = " + nearby + "; " + this.level().purpurConfig.shulkerSpawnFromBulletNearbyEquation)).floatValue(); + } catch (javax.script.ScriptException e) { + e.printStackTrace(); + chance -= (nearby - 1) / 5.0F; + } + } -+ if (this.level.random.nextFloat() <= chance) { ++ if (this.level().random.nextFloat() <= chance) { + Shulker entityshulker = (Shulker) EntityType.SHULKER.create(this.level()); + // Purpur end - Shulker entityshulker = (Shulker) EntityType.SHULKER.create(this.level); if (entityshulker != null) { -@@ -601,7 +661,7 @@ public class Shulker extends AbstractGolem implements VariantHolder getVariant() { - return Optional.ofNullable(this.getColor()); -+ return Optional.ofNullable(this.level.purpurConfig.shulkerSpawnFromBulletRandomColor ? DyeColor.random(this.level.random) : this.getColor()); // Purpur ++ return Optional.ofNullable(this.level().purpurConfig.shulkerSpawnFromBulletRandomColor ? DyeColor.random(this.level().random) : this.getColor()); // Purpur } @Nullable -@@ -611,7 +671,7 @@ public class Shulker extends AbstractGolem implements VariantHolder 0 && this.getType() != EntityType.WITHER_SKELETON && stack.getItem() == Blocks.WITHER_ROSE.asItem()) { ++ if (level().purpurConfig.skeletonFeedWitherRoses > 0 && this.getType() != EntityType.WITHER_SKELETON && stack.getItem() == Blocks.WITHER_ROSE.asItem()) { + return this.feedWitherRose(player, stack); + } + @@ -13461,14 +13571,14 @@ index badde621357a567965f0ef203e402e21bed09059..64a5e000adbfa5de2abc32ea9182847d + } + + private InteractionResult feedWitherRose(Player player, ItemStack stack) { -+ if (++witherRosesFed < level.purpurConfig.skeletonFeedWitherRoses) { ++ if (++witherRosesFed < level().purpurConfig.skeletonFeedWitherRoses) { + if (!player.getAbilities().instabuild) { + stack.shrink(1); + } + return InteractionResult.CONSUME; + } + -+ WitherSkeleton skeleton = EntityType.WITHER_SKELETON.create(level); ++ WitherSkeleton skeleton = EntityType.WITHER_SKELETON.create(level()); + if (skeleton == null) { + return InteractionResult.PASS; + } @@ -13494,14 +13604,14 @@ index badde621357a567965f0ef203e402e21bed09059..64a5e000adbfa5de2abc32ea9182847d + return InteractionResult.PASS; + } + -+ this.level.addFreshEntity(skeleton); ++ this.level().addFreshEntity(skeleton); + this.remove(RemovalReason.DISCARDED); + if (!player.getAbilities().instabuild) { + stack.shrink(1); + } + + for (int i = 0; i < 15; ++i) { -+ ((ServerLevel) level).sendParticles(((ServerLevel) level).players(), null, ParticleTypes.HAPPY_VILLAGER, ++ ((ServerLevel) level()).sendParticles(((ServerLevel) level()).players(), null, ParticleTypes.HAPPY_VILLAGER, + getX() + random.nextFloat(), getY() + (random.nextFloat() * 2), getZ() + random.nextFloat(), 1, + random.nextGaussian() * 0.05D, random.nextGaussian() * 0.05D, random.nextGaussian() * 0.05D, 0, true); + } @@ -13510,7 +13620,7 @@ index badde621357a567965f0ef203e402e21bed09059..64a5e000adbfa5de2abc32ea9182847d + // 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 c41c1c2712920c6b7d822cd0f37a5d8d725e4054..89978fcb14362af2527693f3e6ec57e169080c9f 100644 +index 343433158507451152e5b2fc5e5fd0b0e6b229db..467337542551dedc05d922bb3a37b811aeef4d7b 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Slime.java +++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java @@ -64,6 +64,7 @@ public class Slime extends Mob implements Enemy { @@ -13528,17 +13638,27 @@ index c41c1c2712920c6b7d822cd0f37a5d8d725e4054..89978fcb14362af2527693f3e6ec57e1 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.slimeRidable; ++ return level().purpurConfig.slimeRidable; ++ } ++ ++ @Override ++ public boolean isSensitiveToWater() { ++ return this.level().purpurConfig.slimeTakeDamageFromWater; ++ } ++ ++ @Override ++ protected boolean isAlwaysExperienceDropper() { ++ return this.level().purpurConfig.slimeAlwaysDropExp; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.slimeRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.slimeRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.slimeControllable; ++ return level().purpurConfig.slimeControllable; + } + + @Override @@ -13559,19 +13679,19 @@ index c41c1c2712920c6b7d822cd0f37a5d8d725e4054..89978fcb14362af2527693f3e6ec57e1 + } + + protected String getMaxHealthEquation() { -+ return level.purpurConfig.slimeMaxHealth; ++ return level().purpurConfig.slimeMaxHealth; + } + + protected String getAttackDamageEquation() { -+ return level.purpurConfig.slimeAttackDamage; ++ return level().purpurConfig.slimeAttackDamage; + } + + protected java.util.Map getMaxHealthCache() { -+ return level.purpurConfig.slimeMaxHealthCache; ++ return level().purpurConfig.slimeMaxHealthCache; + } + + protected java.util.Map getAttackDamageCache() { -+ return level.purpurConfig.slimeAttackDamageCache; ++ return level().purpurConfig.slimeAttackDamageCache; + } + + protected double getFromCache(java.util.function.Supplier equation, java.util.function.Supplier> cache, java.util.function.Supplier defaultValue) { @@ -13588,16 +13708,6 @@ index c41c1c2712920c6b7d822cd0f37a5d8d725e4054..89978fcb14362af2527693f3e6ec57e1 + } + return value; + } -+ -+ @Override -+ public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.slimeTakeDamageFromWater; -+ } -+ -+ @Override -+ protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.slimeAlwaysDropExp; -+ } + // Purpur end + @Override @@ -13677,7 +13787,7 @@ index c41c1c2712920c6b7d822cd0f37a5d8d725e4054..89978fcb14362af2527693f3e6ec57e1 this.mob.setZza(0.0F); } else { this.operation = MoveControl.Operation.WAIT; - if (this.mob.isOnGround()) { + if (this.mob.onGround()) { - this.mob.setSpeed((float) (this.speedModifier * this.mob.getAttributeValue(Attributes.MOVEMENT_SPEED))); + this.mob.setSpeed((float) (this.getSpeedModifier() * this.mob.getAttributeValue(Attributes.MOVEMENT_SPEED) * (slime.getRider() != null && slime.isControllable() && (slime.getRider().getForwardMot() != 0 || slime.getRider().getStrafeMot() != 0) ? 2.0D : 1.0D))); // Purpur if (this.jumpDelay-- <= 0) { @@ -13693,7 +13803,7 @@ index c41c1c2712920c6b7d822cd0f37a5d8d725e4054..89978fcb14362af2527693f3e6ec57e1 } 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 0c36bb47bd7040f1544817810e1c87157cdaff96..8e071a0922164970e033029c12058db9e8da261a 100644 +index 05432184077752b1d0cb764a5e39ed875748b2d6..b3ab0f8cdbd678970e39e89c2062772374466b67 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Spider.java +++ b/src/main/java/net/minecraft/world/entity/monster/Spider.java @@ -51,14 +51,48 @@ public class Spider extends Monster { @@ -13703,34 +13813,34 @@ index 0c36bb47bd7040f1544817810e1c87157cdaff96..8e071a0922164970e033029c12058db9 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.spiderRidable; ++ return level().purpurConfig.spiderRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.spiderRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.spiderRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.spiderControllable; ++ return level().purpurConfig.spiderControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.spiderMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.spiderMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.spiderTakeDamageFromWater; ++ return this.level().purpurConfig.spiderTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.spiderAlwaysDropExp; ++ return this.level().purpurConfig.spiderAlwaysDropExp; + } -+ // Purpur end + @Override protected void registerGoals() { @@ -13746,7 +13856,7 @@ index 0c36bb47bd7040f1544817810e1c87157cdaff96..8e071a0922164970e033029c12058db9 this.targetSelector.addGoal(2, new Spider.SpiderTargetGoal<>(this, Player.class)); this.targetSelector.addGoal(3, new Spider.SpiderTargetGoal<>(this, IronGolem.class)); diff --git a/src/main/java/net/minecraft/world/entity/monster/Stray.java b/src/main/java/net/minecraft/world/entity/monster/Stray.java -index 118b636a44e4b062e812e433f603b039276337da..677b304c177a1e2bdaddf3044b44a06395ee6b6e 100644 +index 118b636a44e4b062e812e433f603b039276337da..a95e983032b3d3d125a39a46700b7db9dc69f307 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Stray.java +++ b/src/main/java/net/minecraft/world/entity/monster/Stray.java @@ -21,6 +21,38 @@ public class Stray extends AbstractSkeleton { @@ -13756,40 +13866,40 @@ index 118b636a44e4b062e812e433f603b039276337da..677b304c177a1e2bdaddf3044b44a063 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.strayRidable; ++ return level().purpurConfig.strayRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.strayRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.strayRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.strayControllable; ++ return level().purpurConfig.strayControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.strayMaxHealth); ++ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.strayMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.strayTakeDamageFromWater; ++ return this.level().purpurConfig.strayTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.strayAlwaysDropExp; ++ return this.level().purpurConfig.strayAlwaysDropExp; + } -+ // Purpur end + public static boolean checkStraySpawnRules(EntityType type, ServerLevelAccessor world, MobSpawnType spawnReason, BlockPos pos, RandomSource random) { 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 66755efc54059dfb8625f028bf0548d188a57aa2..0b5d3837536d526c25ba1e12be142bb476d03519 100644 +index ebf54d6e36fdee2833250816fae14195ac45eb67..cfa603c7ccaaf1940aa89fa7cd8fafba29529075 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 { @@ -13806,34 +13916,34 @@ index 66755efc54059dfb8625f028bf0548d188a57aa2..0b5d3837536d526c25ba1e12be142bb4 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.striderRidable; ++ return level().purpurConfig.striderRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.striderRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.striderRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.striderControllable; ++ return level().purpurConfig.striderControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.striderMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.striderMaxHealth); + } + + @Override + public int getPurpurBreedTime() { -+ return this.level.purpurConfig.striderBreedingTicks; ++ return this.level().purpurConfig.striderBreedingTicks; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.striderAlwaysDropExp; ++ return this.level().purpurConfig.striderAlwaysDropExp; + } -+ // Purpur end + public static boolean checkStriderSpawnRules(EntityType type, LevelAccessor world, MobSpawnType spawnReason, BlockPos pos, RandomSource random) { BlockPos.MutableBlockPos blockposition_mutableblockposition = pos.mutable(); @@ -13851,7 +13961,7 @@ index 66755efc54059dfb8625f028bf0548d188a57aa2..0b5d3837536d526c25ba1e12be142bb4 @Override public boolean isSensitiveToWater() { - return true; -+ return this.level.purpurConfig.striderTakeDamageFromWater; // Purpur ++ return this.level().purpurConfig.striderTakeDamageFromWater; // Purpur } @Override @@ -13860,7 +13970,7 @@ index 66755efc54059dfb8625f028bf0548d188a57aa2..0b5d3837536d526c25ba1e12be142bb4 boolean flag = this.isFood(player.getItemInHand(hand)); + // Purpur start -+ if (level.purpurConfig.striderGiveSaddleBack && player.isSecondaryUseActive() && !flag && isSaddled() && !isVehicle()) { ++ if (level().purpurConfig.striderGiveSaddleBack && player.isSecondaryUseActive() && !flag && isSaddled() && !isVehicle()) { + this.steering.setSaddle(false); + if (!player.getAbilities().instabuild) { + ItemStack saddle = new ItemStack(Items.SADDLE); @@ -13873,7 +13983,7 @@ index 66755efc54059dfb8625f028bf0548d188a57aa2..0b5d3837536d526c25ba1e12be142bb4 + // Purpur end + if (!flag && this.isSaddled() && !this.isVehicle() && !player.isSecondaryUseActive()) { - if (!this.level.isClientSide) { + if (!this.level().isClientSide) { player.startRiding(this); @@ -470,7 +516,7 @@ public class Strider extends Animal implements ItemSteerable, Saddleable { if (!enuminteractionresult.consumesAction()) { @@ -13883,9 +13993,9 @@ index 66755efc54059dfb8625f028bf0548d188a57aa2..0b5d3837536d526c25ba1e12be142bb4 + return itemstack.is(Items.SADDLE) ? itemstack.interactLivingEntity(player, this, hand) : tryRide(player, hand); // Purpur } else { 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); + 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 bb5c2f90bef5e3c57ffde996853e122d108b2789..4c4c4d52e2be963024106783b4d28713f125e2e6 100644 +index 65cb385ab294e362d666a6d03c4496cdc3b64890..5db70031c8c9ba901a360c758d51222efe911fcc 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 { @@ -13895,22 +14005,22 @@ index bb5c2f90bef5e3c57ffde996853e122d108b2789..4c4c4d52e2be963024106783b4d28713 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.vexRidable; ++ return level().purpurConfig.vexRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.vexRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.vexRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.vexControllable; ++ return level().purpurConfig.vexControllable; + } + + @Override + public double getMaxY() { -+ return level.purpurConfig.vexMaxY; ++ return level().purpurConfig.vexMaxY; + } + + @Override @@ -13934,22 +14044,22 @@ index bb5c2f90bef5e3c57ffde996853e122d108b2789..4c4c4d52e2be963024106783b4d28713 + public boolean causeFallDamage(float fallDistance, float damageMultiplier, DamageSource damageSource) { + return false; // no fall damage please + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.vexMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.vexMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.vexTakeDamageFromWater; ++ return this.level().purpurConfig.vexTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.vexAlwaysDropExp; ++ return this.level().purpurConfig.vexAlwaysDropExp; + } -+ // Purpur end + @Override protected float getStandingEyeHeight(Pose pose, EntityDimensions dimensions) { @@ -14011,7 +14121,7 @@ index bb5c2f90bef5e3c57ffde996853e122d108b2789..4c4c4d52e2be963024106783b4d28713 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 a9e75a16a7dc0ff5d4f0faa92ebc444559a39325..1a333dce35a13b88cb0afdea192585e0bae38442 100644 +index 2acc531bd9e948251cac77d979f973678f576394..f1e410b602bf0d5520f8e9340f7b8b9e25ca4d39 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Vindicator.java +++ b/src/main/java/net/minecraft/world/entity/monster/Vindicator.java @@ -58,14 +58,48 @@ public class Vindicator extends AbstractIllager { @@ -14021,34 +14131,34 @@ index a9e75a16a7dc0ff5d4f0faa92ebc444559a39325..1a333dce35a13b88cb0afdea192585e0 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.vindicatorRidable; ++ return level().purpurConfig.vindicatorRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.vindicatorRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.vindicatorRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.vindicatorControllable; ++ return level().purpurConfig.vindicatorControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.vindicatorMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.vindicatorMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.vindicatorTakeDamageFromWater; ++ return this.level().purpurConfig.vindicatorTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.vindicatorAlwaysDropExp; ++ return this.level().purpurConfig.vindicatorAlwaysDropExp; + } -+ // Purpur end + @Override protected void registerGoals() { @@ -14069,7 +14179,7 @@ index a9e75a16a7dc0ff5d4f0faa92ebc444559a39325..1a333dce35a13b88cb0afdea192585e0 this.populateDefaultEquipmentEnchantments(randomSource, difficulty); + // Purpur start + Level level = world.getMinecraftWorld(); -+ if (level.purpurConfig.vindicatorJohnnySpawnChance > 0D && random.nextDouble() <= level.purpurConfig.vindicatorJohnnySpawnChance) { ++ if (level().purpurConfig.vindicatorJohnnySpawnChance > 0D && random.nextDouble() <= level().purpurConfig.vindicatorJohnnySpawnChance) { + setCustomName(Component.translatable("Johnny")); + } + // Purpur end @@ -14077,7 +14187,7 @@ index a9e75a16a7dc0ff5d4f0faa92ebc444559a39325..1a333dce35a13b88cb0afdea192585e0 } 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 096546d7a97f031060bda7545aa620d522766719..dcf8cdb8343706b55df206fed70fe3a8373e27a6 100644 +index 701f6bf1d558cf0ec4bc1abb9e1f66d96ea5a6c9..80e90202eae1e12d5261d0bb77ecfadcc9ac4599 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Witch.java +++ b/src/main/java/net/minecraft/world/entity/monster/Witch.java @@ -57,6 +57,38 @@ public class Witch extends Raider implements RangedAttackMob { @@ -14087,34 +14197,34 @@ index 096546d7a97f031060bda7545aa620d522766719..dcf8cdb8343706b55df206fed70fe3a8 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.witchRidable; ++ return level().purpurConfig.witchRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.witchRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.witchRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.witchControllable; ++ return level().purpurConfig.witchControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.witchMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.witchMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.witchTakeDamageFromWater; ++ return this.level().purpurConfig.witchTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.witchAlwaysDropExp; ++ return this.level().purpurConfig.witchAlwaysDropExp; + } -+ // Purpur end + @Override protected void registerGoals() { @@ -14133,7 +14243,7 @@ index 096546d7a97f031060bda7545aa620d522766719..dcf8cdb8343706b55df206fed70fe3a8 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 6449213d717271bcc516e393a78dfe1e5c762d68..9016fb6da9c86ca9906f6beb2f6927cede50c804 100644 +index 9a81cb0c3a5ac40ff50dc7c81f6196a447cd03c6..2b3decb90aeb99bef42b36f3b8df06cb1172b413 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 { @@ -14143,40 +14253,40 @@ index 6449213d717271bcc516e393a78dfe1e5c762d68..9016fb6da9c86ca9906f6beb2f6927ce + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.witherSkeletonRidable; ++ return level().purpurConfig.witherSkeletonRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.witherSkeletonRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.witherSkeletonRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.witherSkeletonControllable; ++ return level().purpurConfig.witherSkeletonControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.witherSkeletonMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.witherSkeletonMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.witherSkeletonTakeDamageFromWater; ++ return this.level().purpurConfig.witherSkeletonTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.witherSkeletonAlwaysDropExp; ++ return this.level().purpurConfig.witherSkeletonAlwaysDropExp; + } -+ // Purpur end + @Override 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 5956a7759964f5e4939f062e93714fba64f53141..052eac2c63ecaa052c9fe6ea3d3d1000da8a33fa 100644 +index c1abeb62f63d2f8fb891efec8f76c6736b8f7f75..399e9baedaf37597c539aa5432a513365df83b5e 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zoglin.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zoglin.java @@ -67,6 +67,38 @@ public class Zoglin extends Monster implements Enemy, HoglinBase { @@ -14186,34 +14296,34 @@ index 5956a7759964f5e4939f062e93714fba64f53141..052eac2c63ecaa052c9fe6ea3d3d1000 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.zoglinRidable; ++ return level().purpurConfig.zoglinRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.zoglinRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.zoglinRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.zoglinControllable; ++ return level().purpurConfig.zoglinControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.zoglinMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.zoglinMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.zoglinTakeDamageFromWater; ++ return this.level().purpurConfig.zoglinTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.zoglinAlwaysDropExp; ++ return this.level().purpurConfig.zoglinAlwaysDropExp; + } -+ // Purpur end + @Override protected Brain.Provider brainProvider() { @@ -14231,17 +14341,17 @@ index 5956a7759964f5e4939f062e93714fba64f53141..052eac2c63ecaa052c9fe6ea3d3d1000 @Override protected void customServerAiStep() { -- this.level.getProfiler().push("zoglinBrain"); -+ //this.level.getProfiler().push("zoglinBrain"); // Purpur +- this.level().getProfiler().push("zoglinBrain"); ++ //this.level().getProfiler().push("zoglinBrain"); // Purpur + if (getRider() == null || !this.isControllable()) // Purpur - only use brain if no rider - this.getBrain().tick((ServerLevel)this.level, this); -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur + this.getBrain().tick((ServerLevel)this.level(), this); +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur 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 9976205537cfe228735687f1e9c52c74ac025690..36d37e544e342e1bc584374580dbb5c883523204 100644 +index 3f8c1d1d3c408fc4f15c4b5680bc22c86f104a9d..7c5efb5582f43d9f333f926ad7dba1ed9920333a 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java @@ -95,22 +95,69 @@ public class Zombie extends Monster { @@ -14264,51 +14374,51 @@ index 9976205537cfe228735687f1e9c52c74ac025690..36d37e544e342e1bc584374580dbb5c8 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.zombieRidable; ++ return level().purpurConfig.zombieRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.zombieRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.zombieRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.zombieControllable; ++ return level().purpurConfig.zombieControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.zombieMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.zombieMaxHealth); + } + + public boolean jockeyOnlyBaby() { -+ return level.purpurConfig.zombieJockeyOnlyBaby; ++ return level().purpurConfig.zombieJockeyOnlyBaby; + } + + public double jockeyChance() { -+ return level.purpurConfig.zombieJockeyChance; ++ return level().purpurConfig.zombieJockeyChance; + } + + public boolean jockeyTryExistingChickens() { -+ return level.purpurConfig.zombieJockeyTryExistingChickens; ++ return level().purpurConfig.zombieJockeyTryExistingChickens; + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.zombieTakeDamageFromWater; ++ return this.level().purpurConfig.zombieTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.zombieAlwaysDropExp; ++ return this.level().purpurConfig.zombieAlwaysDropExp; + } -+ // Purpur end + @Override protected void registerGoals() { + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - if (level.paperConfig().entities.behavior.zombiesTargetTurtleEggs) this.goalSelector.addGoal(4, new Zombie.ZombieAttackTurtleEggGoal(this, 1.0D, 3)); // Paper + if (this.level().paperConfig().entities.behavior.zombiesTargetTurtleEggs) this.goalSelector.addGoal(4, new Zombie.ZombieAttackTurtleEggGoal(this, 1.0D, 3)); // Paper this.goalSelector.addGoal(8, new LookAtPlayerGoal(this, Player.class, 8.0F)); this.goalSelector.addGoal(8, new RandomLookAroundGoal(this)); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur @@ -14319,17 +14429,17 @@ index 9976205537cfe228735687f1e9c52c74ac025690..36d37e544e342e1bc584374580dbb5c8 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)); -- if ( level.spigotConfig.zombieAggressiveTowardsVillager ) this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false)); // Spigot +- if ( this.level().spigotConfig.zombieAggressiveTowardsVillager ) this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false)); // Spigot + // Purpur start -+ if ( level.spigotConfig.zombieAggressiveTowardsVillager ) this.targetSelector.addGoal(3, new NearestAttackableTargetGoal(this, AbstractVillager.class, false) { // Spigot ++ if ( this.level().spigotConfig.zombieAggressiveTowardsVillager ) this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false) { // Spigot + @Override + public boolean canUse() { -+ return (level.purpurConfig.zombieAggressiveTowardsVillagerWhenLagging || !level.getServer().server.isLagging()) && super.canUse(); ++ return (level().purpurConfig.zombieAggressiveTowardsVillagerWhenLagging || !level().getServer().server.isLagging()) && super.canUse(); + } + + @Override + public boolean canContinueToUse() { -+ return (level.purpurConfig.zombieAggressiveTowardsVillagerWhenLagging || !level.getServer().server.isLagging()) && super.canContinueToUse(); ++ return (level().purpurConfig.zombieAggressiveTowardsVillagerWhenLagging || !level().getServer().server.isLagging()) && super.canContinueToUse(); + } + }); + // Purpur end @@ -14418,7 +14528,7 @@ index 9976205537cfe228735687f1e9c52c74ac025690..36d37e544e342e1bc584374580dbb5c8 - } - } else if ((double) randomsource.nextFloat() < 0.05D) { + } else { // Purpur - Chicken entitychicken1 = (Chicken) EntityType.CHICKEN.create(this.level); + Chicken entitychicken1 = (Chicken) EntityType.CHICKEN.create(this.level()); if (entitychicken1 != null) { @@ -549,6 +587,7 @@ public class Zombie extends Monster { @@ -14438,7 +14548,7 @@ index 9976205537cfe228735687f1e9c52c74ac025690..36d37e544e342e1bc584374580dbb5c8 - int j = localdate.get(ChronoField.MONTH_OF_YEAR); - - if (j == 10 && i == 31 && randomsource.nextFloat() < 0.25F) { -+ if (net.minecraft.world.entity.ambient.Bat.isHalloweenSeason(world.getMinecraftWorld()) && this.random.nextFloat() < this.level.purpurConfig.chanceHeadHalloweenOnEntity) { // Purpur ++ if (net.minecraft.world.entity.ambient.Bat.isHalloweenSeason(world.getMinecraftWorld()) && this.random.nextFloat() < this.level().purpurConfig.chanceHeadHalloweenOnEntity) { // Purpur this.setItemSlot(EquipmentSlot.HEAD, new ItemStack(randomsource.nextFloat() < 0.1F ? Blocks.JACK_O_LANTERN : Blocks.CARVED_PUMPKIN)); this.armorDropChances[EquipmentSlot.HEAD.getIndex()] = 0.0F; } @@ -14447,12 +14557,12 @@ index 9976205537cfe228735687f1e9c52c74ac025690..36d37e544e342e1bc584374580dbb5c8 protected void randomizeReinforcementsChance() { - this.getAttribute(Attributes.SPAWN_REINFORCEMENTS_CHANCE).setBaseValue(this.random.nextDouble() * 0.10000000149011612D); -+ this.getAttribute(Attributes.SPAWN_REINFORCEMENTS_CHANCE).setBaseValue(this.random.nextDouble() * this.level.purpurConfig.zombieSpawnReinforcements); // Purpur ++ this.getAttribute(Attributes.SPAWN_REINFORCEMENTS_CHANCE).setBaseValue(this.random.nextDouble() * this.level().purpurConfig.zombieSpawnReinforcements); // Purpur } @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 71a36cf9b976443cca9ab63cd0eb23253f638562..0c6e8e05014125427513e96c32510125ec34ece9 100644 +index 25ed5571b24e590bc95056020d84496492b53298..be2a35f703310f699ee31bd2ec1c938af281a577 100644 --- a/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java +++ b/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java @@ -79,6 +79,58 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder { @@ -14462,54 +14572,54 @@ index 71a36cf9b976443cca9ab63cd0eb23253f638562..0c6e8e05014125427513e96c32510125 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.zombieVillagerRidable; ++ return level().purpurConfig.zombieVillagerRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.zombieVillagerRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.zombieVillagerRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.zombieVillagerControllable; ++ return level().purpurConfig.zombieVillagerControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.zombieVillagerMaxHealth); ++ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.zombieVillagerMaxHealth); + } + + @Override + protected void randomizeReinforcementsChance() { -+ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.SPAWN_REINFORCEMENTS_CHANCE).setBaseValue(this.random.nextDouble() * this.level.purpurConfig.zombieVillagerSpawnReinforcements); -+ } -+ -+ @Override -+ public boolean jockeyOnlyBaby() { -+ return level.purpurConfig.zombieVillagerJockeyOnlyBaby; -+ } -+ -+ @Override -+ public double jockeyChance() { -+ return level.purpurConfig.zombieVillagerJockeyChance; -+ } -+ -+ @Override -+ public boolean jockeyTryExistingChickens() { -+ return level.purpurConfig.zombieVillagerJockeyTryExistingChickens; ++ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.SPAWN_REINFORCEMENTS_CHANCE).setBaseValue(this.random.nextDouble() * this.level().purpurConfig.zombieVillagerSpawnReinforcements); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.zombieVillagerTakeDamageFromWater; ++ return this.level().purpurConfig.zombieVillagerTakeDamageFromWater; ++ } ++ ++ @Override ++ public boolean jockeyOnlyBaby() { ++ return level().purpurConfig.zombieVillagerJockeyOnlyBaby; ++ } ++ ++ @Override ++ public double jockeyChance() { ++ return level().purpurConfig.zombieVillagerJockeyChance; ++ } ++ ++ @Override ++ public boolean jockeyTryExistingChickens() { ++ return level().purpurConfig.zombieVillagerJockeyTryExistingChickens; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.zombieVillagerAlwaysDropExp; ++ return this.level().purpurConfig.zombieVillagerAlwaysDropExp; + } -+ // Purpur end + @Override protected void defineSynchedData() { @@ -14519,19 +14629,19 @@ index 71a36cf9b976443cca9ab63cd0eb23253f638562..0c6e8e05014125427513e96c32510125 if (itemstack.is(Items.GOLDEN_APPLE)) { - if (this.hasEffect(MobEffects.WEAKNESS)) { -+ if (this.hasEffect(MobEffects.WEAKNESS) && level.purpurConfig.zombieVillagerCureEnabled) { // Purpur ++ if (this.hasEffect(MobEffects.WEAKNESS) && level().purpurConfig.zombieVillagerCureEnabled) { // Purpur if (!player.getAbilities().instabuild) { itemstack.shrink(1); } - if (!this.level.isClientSide) { + 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 ++ this.startConverting(player.getUUID(), this.random.nextInt(level().purpurConfig.zombieVillagerCuringTimeMax - level().purpurConfig.zombieVillagerCuringTimeMin + 1) + level().purpurConfig.zombieVillagerCuringTimeMin); // Purpur } 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 b75945807b425609394c343da56c316a769f0a29..d3bcfa017967db0a20c18c65e27c2a0471d2214e 100644 +index aff140cfb2bbdce8b512080cf394c84c5c4ff807..7bb99d7fd8e05805e0cac7bec0b2771990057f58 100644 --- a/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java +++ b/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java @@ -63,6 +63,53 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { @@ -14541,49 +14651,49 @@ index b75945807b425609394c343da56c316a769f0a29..d3bcfa017967db0a20c18c65e27c2a04 + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.zombifiedPiglinRidable; ++ return level().purpurConfig.zombifiedPiglinRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.zombifiedPiglinRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.zombifiedPiglinRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.zombifiedPiglinControllable; ++ return level().purpurConfig.zombifiedPiglinControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.zombifiedPiglinMaxHealth); -+ } -+ -+ @Override -+ public boolean jockeyOnlyBaby() { -+ return level.purpurConfig.zombifiedPiglinJockeyOnlyBaby; -+ } -+ -+ @Override -+ public double jockeyChance() { -+ return level.purpurConfig.zombifiedPiglinJockeyChance; -+ } -+ -+ @Override -+ public boolean jockeyTryExistingChickens() { -+ return level.purpurConfig.zombifiedPiglinJockeyTryExistingChickens; ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.zombifiedPiglinMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.zombifiedPiglinTakeDamageFromWater; ++ return this.level().purpurConfig.zombifiedPiglinTakeDamageFromWater; ++ } ++ ++ @Override ++ public boolean jockeyOnlyBaby() { ++ return level().purpurConfig.zombifiedPiglinJockeyOnlyBaby; ++ } ++ ++ @Override ++ public double jockeyChance() { ++ return level().purpurConfig.zombifiedPiglinJockeyChance; ++ } ++ ++ @Override ++ public boolean jockeyTryExistingChickens() { ++ return level().purpurConfig.zombifiedPiglinJockeyTryExistingChickens; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.zombifiedPiglinAlwaysDropExp; ++ return this.level().purpurConfig.zombifiedPiglinAlwaysDropExp; + } -+ // Purpur end + @Override public void setPersistentAngerTarget(@Nullable UUID angryAt) { @@ -14593,7 +14703,7 @@ index b75945807b425609394c343da56c316a769f0a29..d3bcfa017967db0a20c18c65e27c2a04 } - if (this.isAngry()) { -+ if (this.isAngry() && this.level.purpurConfig.zombifiedPiglinCountAsPlayerKillWhenAngry) { // Purpur ++ if (this.isAngry() && this.level().purpurConfig.zombifiedPiglinCountAsPlayerKillWhenAngry) { // Purpur this.lastHurtByPlayerTime = this.tickCount; } @@ -14602,7 +14712,7 @@ index b75945807b425609394c343da56c316a769f0a29..d3bcfa017967db0a20c18c65e27c2a04 } - if (entityliving instanceof Player) { -+ if (entityliving instanceof Player && this.level.purpurConfig.zombifiedPiglinCountAsPlayerKillWhenAngry) { // Purpur ++ if (entityliving instanceof Player && this.level().purpurConfig.zombifiedPiglinCountAsPlayerKillWhenAngry) { // Purpur this.setLastHurtByPlayer((Player) entityliving); } @@ -14611,12 +14721,12 @@ index b75945807b425609394c343da56c316a769f0a29..d3bcfa017967db0a20c18c65e27c2a04 @Override protected void randomizeReinforcementsChance() { - this.getAttribute(Attributes.SPAWN_REINFORCEMENTS_CHANCE).setBaseValue(0.0D); -+ this.getAttribute(Attributes.SPAWN_REINFORCEMENTS_CHANCE).setBaseValue(this.random.nextDouble() * this.level.purpurConfig.zombifiedPiglinSpawnReinforcements); // Purpur ++ this.getAttribute(Attributes.SPAWN_REINFORCEMENTS_CHANCE).setBaseValue(this.random.nextDouble() * this.level().purpurConfig.zombifiedPiglinSpawnReinforcements); // Purpur } @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 daa2224b021c966751eb39f269ffbfe6e7f3d426..63ffb8c04f1408d028af086ba907551a05b96e72 100644 +index d6d61b91096d28eea1e5af69ea1c07890820ee7f..ecc445bb3cda2d79d64c580b72544567dd304f53 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 @@ -67,6 +67,43 @@ public class Hoglin extends Animal implements Enemy, HoglinBase { @@ -14626,39 +14736,39 @@ index daa2224b021c966751eb39f269ffbfe6e7f3d426..63ffb8c04f1408d028af086ba907551a + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.hoglinRidable; ++ return level().purpurConfig.hoglinRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.hoglinRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.hoglinRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.hoglinControllable; ++ return level().purpurConfig.hoglinControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.hoglinMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.hoglinMaxHealth); + } + + @Override + public int getPurpurBreedTime() { -+ return this.level.purpurConfig.hoglinBreedingTicks; ++ return this.level().purpurConfig.hoglinBreedingTicks; + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.hoglinTakeDamageFromWater; ++ return this.level().purpurConfig.hoglinTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.hoglinAlwaysDropExp; ++ return this.level().purpurConfig.hoglinAlwaysDropExp; + } -+ // Purpur end + @Override public boolean canBeLeashed(Player player) { @@ -14667,84 +14777,124 @@ index daa2224b021c966751eb39f269ffbfe6e7f3d426..63ffb8c04f1408d028af086ba907551a private int behaviorTick; // Pufferfish @Override protected void customServerAiStep() { -- this.level.getProfiler().push("hoglinBrain"); +- this.level().getProfiler().push("hoglinBrain"); - if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish -+ //this.level.getProfiler().push("hoglinBrain"); // Purpur ++ //this.level().getProfiler().push("hoglinBrain"); // Purpur + 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); -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur + this.getBrain().tick((ServerLevel)this.level(), this); +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur HoglinAi.updateActivity(this); if (this.isConverting()) { ++this.timeInOverworld; 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 b401fb4f276ca81b4bb18426ee56abed8a9f7a7b..c8db72dbdaedddb712f20cf0e3a9c731312307a0 100644 +index e235cc9d1b3ce59ab662ef3cf3ce0267ca78536d..79f969ea76fc2073e10c050c2aa64b5b5e473181 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 -@@ -97,6 +97,38 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento +@@ -96,6 +96,38 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento this.xpReward = 5; } + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.piglinRidable; ++ return level().purpurConfig.piglinRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.piglinRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.piglinRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.piglinControllable; ++ return level().purpurConfig.piglinControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.piglinMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.piglinMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.piglinTakeDamageFromWater; ++ return this.level().purpurConfig.piglinTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.piglinAlwaysDropExp; ++ return this.level().purpurConfig.piglinAlwaysDropExp; + } -+ // Purpur end + @Override public void addAdditionalSaveData(CompoundTag nbt) { super.addAdditionalSaveData(nbt); -@@ -311,10 +343,10 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento +@@ -308,10 +340,10 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento private int behaviorTick; // Pufferfish @Override protected void customServerAiStep() { -- this.level.getProfiler().push("piglinBrain"); +- this.level().getProfiler().push("piglinBrain"); - if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish -+ //this.level.getProfiler().push("piglinBrain"); // Purpur ++ //this.level().getProfiler().push("piglinBrain"); // Purpur + 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); -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur + this.getBrain().tick((ServerLevel) this.level(), this); +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur PiglinAi.updateActivity(this); super.customServerAiStep(); } -@@ -410,7 +442,7 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento +@@ -407,7 +439,7 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento @Override public boolean wantsToPickUp(ItemStack stack) { -- return this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && this.canPickUpLoot() && PiglinAi.wantsToPickup(this, stack); -+ return (this.level.purpurConfig.piglinBypassMobGriefing || this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) && this.canPickUpLoot() && PiglinAi.wantsToPickup(this, stack); +- return this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && this.canPickUpLoot() && PiglinAi.wantsToPickup(this, stack); ++ return (this.level().purpurConfig.piglinBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) && this.canPickUpLoot() && PiglinAi.wantsToPickup(this, stack); } 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 d98c526676202741e628d5e317b8cdd3f4d3be0a..edf9208ed49a179dc15308dd72ee47367c0a9ded 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 +@@ -597,20 +597,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 + + 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 + + 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); ++ ++ 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); ++ } ++ // Purpur end ++ + private static void stopWalking(Piglin piglin) { + 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 ac75c54e897565e340b66823caeed92ba1d1641a..df4d1745c4957e564bab11d68a37178fdb398543 100644 +index d02ee11066fc4f07ccb110b09b86d895ff90d4f2..856e6e02c9424a6c06e310262cb4f5bdd34da516 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 @@ -41,6 +41,38 @@ public class PiglinBrute extends AbstractPiglin { @@ -14754,34 +14904,34 @@ index ac75c54e897565e340b66823caeed92ba1d1641a..df4d1745c4957e564bab11d68a37178f + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.piglinBruteRidable; ++ return level().purpurConfig.piglinBruteRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.piglinBruteRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.piglinBruteRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.piglinBruteControllable; ++ return level().purpurConfig.piglinBruteControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.piglinBruteMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.piglinBruteMaxHealth); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.piglinBruteTakeDamageFromWater; ++ return this.level().purpurConfig.piglinBruteTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.piglinBruteAlwaysDropExp; ++ return this.level().purpurConfig.piglinBruteAlwaysDropExp; + } -+ // Purpur end + public static AttributeSupplier.Builder createAttributes() { return Monster.createMonsterAttributes().add(Attributes.MAX_HEALTH, 50.0D).add(Attributes.MOVEMENT_SPEED, (double)0.35F).add(Attributes.ATTACK_DAMAGE, 7.0D); @@ -14799,20 +14949,20 @@ index ac75c54e897565e340b66823caeed92ba1d1641a..df4d1745c4957e564bab11d68a37178f @Override protected void customServerAiStep() { -- this.level.getProfiler().push("piglinBruteBrain"); -+ //this.level.getProfiler().push("piglinBruteBrain"); // Purpur +- this.level().getProfiler().push("piglinBruteBrain"); ++ //this.level().getProfiler().push("piglinBruteBrain"); // Purpur + if (getRider() == null || this.isControllable()) // Purpur - only use brain if no rider - this.getBrain().tick((ServerLevel)this.level, this); -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur + this.getBrain().tick((ServerLevel)this.level(), this); +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur PiglinBruteAi.updateActivity(this); PiglinBruteAi.maybePlayActivitySound(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 907d77dd74066c723238155b42028a811365b1f8..69e5b4b6c8d5725bc2fb7cd819219e4ff9df45bd 100644 +index 71db8bd6885377d55cfc571fccc21df6d8a57b54..3fa46affc4d77d01909cfeaeaba6e06ba9fd5592 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 -@@ -120,8 +120,32 @@ public class Warden extends Monster implements VibrationListener.VibrationListen +@@ -121,8 +121,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); @@ -14822,17 +14972,17 @@ index 907d77dd74066c723238155b42028a811365b1f8..69e5b4b6c8d5725bc2fb7cd819219e4f + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.wardenRidable; ++ return level().purpurConfig.wardenRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.wardenRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.wardenRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.wardenControllable; ++ return level().purpurConfig.wardenControllable; + } + + @Override @@ -14845,20 +14995,20 @@ index 907d77dd74066c723238155b42028a811365b1f8..69e5b4b6c8d5725bc2fb7cd819219e4f @Override public Packet getAddEntityPacket() { return new ClientboundAddEntityPacket(this, this.hasPose(Pose.EMERGING) ? 1 : 0); -@@ -275,10 +299,10 @@ public class Warden extends Monster implements VibrationListener.VibrationListen +@@ -276,10 +300,10 @@ public class Warden extends Monster implements VibrationSystem { protected void customServerAiStep() { - ServerLevel worldserver = (ServerLevel) this.level; + ServerLevel worldserver = (ServerLevel) this.level(); - worldserver.getProfiler().push("wardenBrain"); + //worldserver.getProfiler().push("wardenBrain"); // Purpur if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish this.getBrain().tick(worldserver, this); -- this.level.getProfiler().pop(); -+ //this.level.getProfiler().pop(); // Purpur +- this.level().getProfiler().pop(); ++ //this.level().getProfiler().pop(); // Purpur super.customServerAiStep(); if ((this.tickCount + this.getId()) % 120 == 0) { Warden.applyDarknessAround(worldserver, this.position(), this, 20); -@@ -405,19 +429,16 @@ public class Warden extends Monster implements VibrationListener.VibrationListen +@@ -396,19 +420,16 @@ public class Warden extends Monster implements VibrationSystem { @Contract("null->false") public boolean canTargetEntity(@Nullable Entity entity) { @@ -14868,7 +15018,7 @@ index 907d77dd74066c723238155b42028a811365b1f8..69e5b4b6c8d5725bc2fb7cd819219e4f if (entity instanceof LivingEntity) { LivingEntity entityliving = (LivingEntity) entity; - 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())) { + 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; + return true; // Purpur - wtf @@ -14882,7 +15032,7 @@ index 907d77dd74066c723238155b42028a811365b1f8..69e5b4b6c8d5725bc2fb7cd819219e4f 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 ca96b893e22de3ae7c11d5cded51edf70bdcb6f2..d4ab27de59e9c533789f062e74ceb453483e2e39 100644 +index 564908ce0a560c2190fb624e77d227d3b7031024..f2a4e214744227f1df32e3782e71f8a9d5cea261 100644 --- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java +++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java @@ -43,6 +43,7 @@ import org.bukkit.event.entity.VillagerAcquireTradeEvent; @@ -14940,10 +15090,10 @@ index 5f407535298a31a34cfe114dd863fd6a9b977707..29c7e33fe961020e5a0007287fe9b663 } 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 5402a084ef5fe0b3cfea897a90cffade1eff5b66..73cdb6b1793b264e1ec8ff51c4f8274366a7d4d7 100644 +index c4ddf2661bca728d504918171295e10e307b18b4..2ea19f72dd8e86d5821f734c13ac2dc6f53e9c30 100644 --- a/src/main/java/net/minecraft/world/entity/npc/Villager.java +++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java -@@ -139,6 +139,8 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -140,6 +140,8 @@ public class Villager extends AbstractVillager implements ReputationEventHandler }, MemoryModuleType.MEETING_POINT, (entityvillager, holder) -> { return holder.is(PoiTypes.MEETING); }); @@ -14952,59 +15102,62 @@ index 5402a084ef5fe0b3cfea897a90cffade1eff5b66..73cdb6b1793b264e1ec8ff51c4f82743 public long nextGolemPanic = -1; // Pufferfish -@@ -155,6 +157,90 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -154,6 +156,90 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + this.getNavigation().setCanFloat(true); + this.setCanPickUpLoot(true); this.setVillagerData(this.getVillagerData().setType(type).setProfession(VillagerProfession.NONE)); - } - ++ if (level().purpurConfig.villagerFollowEmeraldBlock) this.goalSelector.addGoal(3, new net.minecraft.world.entity.ai.goal.TemptGoal(this, 1.0D, TEMPT_ITEMS, false)); ++ } ++ + // Purpur start + @Override + public boolean isRidable() { -+ return level.purpurConfig.villagerRidable; ++ return level().purpurConfig.villagerRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.villagerRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.villagerRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.villagerControllable; ++ return level().purpurConfig.villagerControllable; + } + + @Override + protected void registerGoals() { + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); -+ if (level.purpurConfig.villagerFollowEmeraldBlock) this.goalSelector.addGoal(3, new net.minecraft.world.entity.ai.goal.TemptGoal(this, 1.0D, TEMPT_ITEMS, false)); + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.villagerMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.villagerMaxHealth); + } + + @Override + public boolean canBeLeashed(Player player) { -+ return level.purpurConfig.villagerCanBeLeashed && !this.isLeashed(); ++ return level().purpurConfig.villagerCanBeLeashed && !this.isLeashed(); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.villagerTakeDamageFromWater; ++ return this.level().purpurConfig.villagerTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.villagerAlwaysDropExp; ++ return this.level().purpurConfig.villagerAlwaysDropExp; + } + + private boolean checkLobotomized() { -+ int interval = this.level.purpurConfig.villagerLobotomizeCheckInterval; ++ int interval = this.level().purpurConfig.villagerLobotomizeCheckInterval; + if (this.notLobotomizedCount > 3) { + // check half as often if not lobotomized for the last 3+ consecutive checks + interval *= 2; + } -+ if (this.level.getGameTime() % interval == 0) { ++ if (this.level().getGameTime() % interval == 0) { + // offset Y for short blocks like dirt_path/farmland + this.isLobotomized = !canTravelFrom(BlockPos.containing(this.position().x, this.getBoundingBox().minY + 0.0625D, this.position().z)); + @@ -15022,7 +15175,7 @@ index 5402a084ef5fe0b3cfea897a90cffade1eff5b66..73cdb6b1793b264e1ec8ff51c4f82743 + } + + private boolean canTravelTo(BlockPos pos) { -+ net.minecraft.world.level.block.state.BlockState state = this.level.getBlockStateIfLoaded(pos); ++ net.minecraft.world.level.block.state.BlockState state = this.level().getBlockStateIfLoaded(pos); + if (state == null) { + // chunk not loaded + return false; @@ -15034,110 +15187,104 @@ index 5402a084ef5fe0b3cfea897a90cffade1eff5b66..73cdb6b1793b264e1ec8ff51c4f82743 + // bottom block is too tall to get over + return false; + } -+ net.minecraft.world.level.block.Block top = level.getBlockState(pos.above()).getBlock(); ++ net.minecraft.world.level.block.Block top = level().getBlockState(pos.above()).getBlock(); + // only if both blocks have no collision + return !bottom.hasCollision && !top.hasCollision; -+ } -+ // Purpur end -+ + } + @Override - public Brain getBrain() { - return (Brain) super.getBrain(); // CraftBukkit - decompile error -@@ -189,7 +275,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -190,7 +276,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler brain.addActivity(Activity.PLAY, VillagerGoalPackages.getPlayPackage(0.5F)); } else { brain.setSchedule(Schedule.VILLAGER_DEFAULT); - brain.addActivityWithConditions(Activity.WORK, VillagerGoalPackages.getWorkPackage(villagerprofession, 0.5F), ImmutableSet.of(Pair.of(MemoryModuleType.JOB_SITE, MemoryStatus.VALUE_PRESENT))); -+ brain.addActivityWithConditions(Activity.WORK, VillagerGoalPackages.getWorkPackage(villagerprofession, 0.5F, this.level.purpurConfig.villagerClericsFarmWarts), ImmutableSet.of(Pair.of(MemoryModuleType.JOB_SITE, MemoryStatus.VALUE_PRESENT))); // Purpur ++ brain.addActivityWithConditions(Activity.WORK, VillagerGoalPackages.getWorkPackage(villagerprofession, 0.5F, this.level().purpurConfig.villagerClericsFarmWarts), ImmutableSet.of(Pair.of(MemoryModuleType.JOB_SITE, MemoryStatus.VALUE_PRESENT))); // Purpur } brain.addActivity(Activity.CORE, VillagerGoalPackages.getCorePackage(villagerprofession, 0.5F)); -@@ -249,14 +335,29 @@ public class Villager extends AbstractVillager implements ReputationEventHandler - @Override - protected void customServerAiStep() { mobTick(false); } - protected void mobTick(boolean inactive) { -- this.level.getProfiler().push("villagerBrain"); -+ //this.level.getProfiler().push("villagerBrain"); // Purpur +@@ -253,15 +339,22 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + // Paper start + this.customServerAiStep(false); + } +- protected void customServerAiStep(final boolean inactive) { ++ protected void customServerAiStep(boolean inactive) { // Purpur - not final + // Paper end +- this.level().getProfiler().push("villagerBrain"); +- // Pufferfish start +- if (!inactive && this.behaviorTick++ % this.activatedPriority == 0) { +- this.getBrain().tick((ServerLevel) this.level(), this); // Paper ++ //this.level().getProfiler().push("villagerBrain"); // Purpur + // Purpur start -+ if (this.level.purpurConfig.villagerLobotomizeEnabled) { ++ if (this.level().purpurConfig.villagerLobotomizeEnabled) { + // treat as inactive if lobotomized + inactive = inactive || checkLobotomized(); + } else { + // clean up state for API + this.isLobotomized = false; -+ } + } +- // Pufferfish end +- this.level().getProfiler().pop(); ++ 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 ++ else if (this.isLobotomized && shouldRestock()) restock(); + // Purpur end - // Pufferfish start - if (!inactive) { -- if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish -+ 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); // Paper - } - // Pufferfish end -- this.level.getProfiler().pop(); -+ // Purpur start -+ else if (this.isLobotomized && shouldRestock()) { -+ // make sure we restock if needed when lobotomized -+ restock(); -+ } -+ // Purpur end -+ //this.level.getProfiler().pop(); // Purpur ++ //this.level().getProfiler().pop(); // Purpur if (this.assignProfessionWhenSpawned) { this.assignProfessionWhenSpawned = false; } -@@ -312,7 +413,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -317,7 +410,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(); -- return InteractionResult.sidedSuccess(this.level.isClientSide); -+ return tryRide(player, hand, InteractionResult.sidedSuccess(this.level.isClientSide)); // Purpur +- return InteractionResult.sidedSuccess(this.level().isClientSide); ++ return tryRide(player, hand, InteractionResult.sidedSuccess(this.level().isClientSide)); // Purpur } else { boolean flag = this.getOffers().isEmpty(); -@@ -325,9 +426,10 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -330,9 +423,10 @@ public class Villager extends AbstractVillager implements ReputationEventHandler } if (flag) { -- return InteractionResult.sidedSuccess(this.level.isClientSide); -+ return tryRide(player, hand, InteractionResult.sidedSuccess(this.level.isClientSide)); // Purpur +- return InteractionResult.sidedSuccess(this.level().isClientSide); ++ return tryRide(player, hand, InteractionResult.sidedSuccess(this.level().isClientSide)); // Purpur } else { -- if (!this.level.isClientSide && !this.offers.isEmpty()) { -+ if (level.purpurConfig.villagerRidable && itemstack.isEmpty()) return tryRide(player, hand); // Purpur -+ if (this.level.purpurConfig.villagerAllowTrading && !this.offers.isEmpty()) { // Purpur +- if (!this.level().isClientSide && !this.offers.isEmpty()) { ++ if (level().purpurConfig.villagerRidable && itemstack.isEmpty()) return tryRide(player, hand); // Purpur ++ if (this.level().purpurConfig.villagerAllowTrading && !this.offers.isEmpty()) { this.startTrading(player); } -@@ -496,7 +598,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -501,7 +595,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler while (iterator.hasNext()) { MerchantOffer merchantrecipe = (MerchantOffer) iterator.next(); - merchantrecipe.updateDemand(); -+ merchantrecipe.updateDemand(this.level.purpurConfig.villagerMinimumDemand); // Purpur ++ merchantrecipe.updateDemand(this.level().purpurConfig.villagerMinimumDemand); // Purpur } } -@@ -746,7 +848,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -751,7 +845,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @Override public boolean canBreed() { - return this.foodLevel + this.countFoodPointsInInventory() >= 12 && !this.isSleeping() && this.getAge() == 0; -+ return this.level.purpurConfig.villagerCanBreed && this.foodLevel + this.countFoodPointsInInventory() >= 12 && !this.isSleeping() && this.getAge() == 0; // Purpur ++ return this.level().purpurConfig.villagerCanBreed && this.foodLevel + this.countFoodPointsInInventory() >= 12 && !this.isSleeping() && this.getAge() == 0; // Purpur } private boolean hungry() { -@@ -938,6 +1040,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler - } +@@ -944,6 +1038,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler public boolean hasFarmSeeds() { -+ // Purpur start -+ if (this.level.purpurConfig.villagerClericsFarmWarts && this.getVillagerData().getProfession() == VillagerProfession.CLERIC) { -+ return this.getInventory().hasAnyOf(ImmutableSet.of(Items.NETHER_WART)); -+ } -+ // Purpur end - return this.getInventory().hasAnyOf(ImmutableSet.of(Items.WHEAT_SEEDS, Items.POTATO, Items.CARROT, Items.BEETROOT_SEEDS)); + return this.getInventory().hasAnyMatching((itemstack) -> { ++ // Purpur start ++ if (this.level().purpurConfig.villagerClericsFarmWarts && this.getVillagerData().getProfession() == VillagerProfession.CLERIC) { ++ return itemstack.is(Items.NETHER_WART); ++ } ++ // Purpur end + return itemstack.is(ItemTags.VILLAGER_PLANTABLE_SEEDS); + }); } - -@@ -986,6 +1093,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -993,6 +1092,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler } public void spawnGolemIfNeeded(ServerLevel world, long time, int requiredCount) { @@ -15145,18 +15292,18 @@ index 5402a084ef5fe0b3cfea897a90cffade1eff5b66..73cdb6b1793b264e1ec8ff51c4f82743 if (this.wantsToSpawnGolem(time)) { AABB axisalignedbb = this.getBoundingBox().inflate(10.0D, 10.0D, 10.0D); List list = world.getEntitiesOfClass(Villager.class, axisalignedbb); -@@ -1059,6 +1167,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -1066,6 +1166,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @Override public void startSleeping(BlockPos pos) { + // Purpur start -+ if (level.purpurConfig.bedExplodeOnVillagerSleep && this.level.getBlockState(pos).getBlock() instanceof net.minecraft.world.level.block.BedBlock) { -+ this.level.explode(null, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, (float) this.level.purpurConfig.bedExplosionPower, this.level.purpurConfig.bedExplosionFire, this.level.purpurConfig.bedExplosionEffect); ++ if (level().purpurConfig.bedExplodeOnVillagerSleep && this.level().getBlockState(pos).getBlock() instanceof net.minecraft.world.level.block.BedBlock) { ++ this.level().explode(null, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, (float) this.level().purpurConfig.bedExplosionPower, this.level().purpurConfig.bedExplosionFire, this.level().purpurConfig.bedExplosionEffect); + return; + } + // Purpur end super.startSleeping(pos); - this.brain.setMemory(MemoryModuleType.LAST_SLEPT, this.level.getGameTime()); // CraftBukkit - decompile error + this.brain.setMemory(MemoryModuleType.LAST_SLEPT, this.level().getGameTime()); // CraftBukkit - decompile error this.brain.eraseMemory(MemoryModuleType.WALK_TARGET); diff --git a/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java b/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java index ac70c2c03241e73943bd517a8c69dd05e0873634..0318663a824d2a9515f867a075d148c3fcb1a907 100644 @@ -15172,85 +15319,85 @@ index ac70c2c03241e73943bd517a8c69dd05e0873634..0318663a824d2a9515f867a075d148c3 public static final VillagerProfession FISHERMAN = register("fisherman", PoiTypes.FISHERMAN, SoundEvents.VILLAGER_WORK_FISHERMAN); public static final VillagerProfession FLETCHER = register("fletcher", PoiTypes.FLETCHER, SoundEvents.VILLAGER_WORK_FLETCHER); 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 c9fb50c33ac15fe72bc77167e4647f30942fdc5d..a6a4d5203cb5f35306f8225e56681bc25e06beed 100644 +index 0002f3a2f2e096d4b2015baf707707f6cc1a9582..0e5fae26bf89749e446050c92dc7c23d788f5edb 100644 --- a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java +++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java -@@ -69,6 +69,43 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill - this.setDespawnDelay(48000); // CraftBukkit - set default from MobSpawnerTrader +@@ -66,6 +66,43 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill + //this.setDespawnDelay(48000); // CraftBukkit - set default from MobSpawnerTrader // Paper - move back to MobSpawnerTrader - Vanilla behavior is that only traders spawned by it have this value set. } + // Purpur - start + @Override + public boolean isRidable() { -+ return level.purpurConfig.wanderingTraderRidable; ++ return level().purpurConfig.wanderingTraderRidable; + } + + @Override + public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.wanderingTraderRidableInWater; ++ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.wanderingTraderRidableInWater; + } + + @Override + public boolean isControllable() { -+ return level.purpurConfig.wanderingTraderControllable; ++ return level().purpurConfig.wanderingTraderControllable; + } ++ // Purpur end + + @Override + public void initAttributes() { -+ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.wanderingTraderMaxHealth); ++ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.wanderingTraderMaxHealth); + } + + @Override + public boolean canBeLeashed(Player player) { -+ return level.purpurConfig.wanderingTraderCanBeLeashed && !this.isLeashed(); ++ return level().purpurConfig.wanderingTraderCanBeLeashed && !this.isLeashed(); + } + + @Override + public boolean isSensitiveToWater() { -+ return this.level.purpurConfig.wanderingTraderTakeDamageFromWater; ++ return this.level().purpurConfig.wanderingTraderTakeDamageFromWater; + } + + @Override + protected boolean isAlwaysExperienceDropper() { -+ return this.level.purpurConfig.wanderingTraderAlwaysDropExp; ++ return this.level().purpurConfig.wanderingTraderAlwaysDropExp; + } -+ // Purpur end + @Override protected void registerGoals() { this.goalSelector.addGoal(0, new FloatGoal(this)); -@@ -76,7 +113,7 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill - return this.canDrinkPotion && this.level.isNight() && !entityvillagertrader.isInvisible(); // Paper - Add more WanderingTrader API +@@ -73,7 +110,7 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill + return this.canDrinkPotion && this.level().isNight() && !entityvillagertrader.isInvisible(); // Paper - Add more WanderingTrader API })); this.goalSelector.addGoal(0, new UseItemGoal<>(this, new ItemStack(Items.MILK_BUCKET), SoundEvents.WANDERING_TRADER_REAPPEARED, (entityvillagertrader) -> { -- return canDrinkMilk && this.level.isDay() && entityvillagertrader.isInvisible(); // Paper - Add more WanderingTrader API -+ return level.purpurConfig.milkClearsBeneficialEffects && canDrinkMilk && this.level.isDay() && entityvillagertrader.isInvisible(); // Paper - Add more WanderingTrader API // Purpur +- return this.canDrinkMilk && this.level().isDay() && entityvillagertrader.isInvisible(); // Paper - Add more WanderingTrader API ++ return level().purpurConfig.milkClearsBeneficialEffects && this.canDrinkMilk && this.level().isDay() && entityvillagertrader.isInvisible(); // Paper - Add more WanderingTrader API // Purpur })); this.goalSelector.addGoal(1, new TradeWithPlayerGoal(this)); this.goalSelector.addGoal(1, new AvoidEntityGoal<>(this, Zombie.class, 8.0F, 0.5D, 0.5D)); -@@ -89,6 +126,7 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill +@@ -86,6 +123,7 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill this.goalSelector.addGoal(1, new PanicGoal(this, 0.5D)); this.goalSelector.addGoal(1, new LookAtTradingPlayerGoal(this)); this.goalSelector.addGoal(2, new WanderingTrader.WanderToPositionGoal(this, 2.0D, 0.35D)); -+ if (level.purpurConfig.wanderingTraderFollowEmeraldBlock) this.goalSelector.addGoal(3, new net.minecraft.world.entity.ai.goal.TemptGoal(this, 1.0D, TEMPT_ITEMS, false)); // Purpur ++ if (level().purpurConfig.wanderingTraderFollowEmeraldBlock) this.goalSelector.addGoal(3, new net.minecraft.world.entity.ai.goal.TemptGoal(this, 1.0D, TEMPT_ITEMS, false)); // Purpur this.goalSelector.addGoal(4, new MoveTowardsRestrictionGoal(this, 0.35D)); this.goalSelector.addGoal(8, new WaterAvoidingRandomStrollGoal(this, 0.35D)); this.goalSelector.addGoal(9, new InteractGoal(this, Player.class, 3.0F, 1.0F)); -@@ -116,9 +154,10 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill +@@ -113,9 +151,10 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill } if (this.getOffers().isEmpty()) { -- return InteractionResult.sidedSuccess(this.level.isClientSide); -+ return tryRide(player, hand, InteractionResult.sidedSuccess(this.level.isClientSide)); // Purpur +- return InteractionResult.sidedSuccess(this.level().isClientSide); ++ return tryRide(player, hand, InteractionResult.sidedSuccess(this.level().isClientSide)); // Purpur } else { -- if (!this.level.isClientSide) { -+ if (level.purpurConfig.wanderingTraderRidable && itemstack.isEmpty()) return tryRide(player, hand); // Purpur -+ if (this.level.purpurConfig.wanderingTraderAllowTrading) { // Purpur +- if (!this.level().isClientSide) { ++ if (level().purpurConfig.wanderingTraderRidable && itemstack.isEmpty()) return tryRide(player, hand); // Purpur ++ if (this.level().purpurConfig.wanderingTraderAllowTrading) { this.setTradingPlayer(player); 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 5d199fe497bd852827d3d18fb7566a09e70331a3..6cd8a50289a6404441e9e5e08d82d2ebe14a09cc 100644 +index 8385eb1d60f377da94e3178ab506feefb43563fd..a5443f92786427c42092aec8350e7ab37704db7a 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 { @@ -15273,33 +15420,36 @@ index 5d199fe497bd852827d3d18fb7566a09e70331a3..6cd8a50289a6404441e9e5e08d82d2eb if (NaturalSpawner.isSpawnPositionOk(SpawnPlacements.Type.ON_GROUND, 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 0629c471d38a77c44fc1c86ccdfcb0690f61ca17..7edcb5b86f27d05a0526229262e0d3a3e160362b 100644 +index 58152160d609d0e9d105153aeb166a56a7955603..d00035e31cf4773a418d1cc6a6018d08e6b558f0 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -186,6 +186,8 @@ public abstract class Player extends LivingEntity { +@@ -187,17 +187,40 @@ public abstract class Player extends LivingEntity { public boolean affectsSpawning = true; public net.kyori.adventure.util.TriState flyingFallDamage = net.kyori.adventure.util.TriState.NOT_SET; // Paper end + public int sixRowEnderchestSlotCount = -1; // Purpur ++ public int burpDelay = 0; // Purpur + public boolean canPortalInstant = false; // Purpur // CraftBukkit start public boolean fauxSleeping; -@@ -197,6 +199,28 @@ public abstract class Player extends LivingEntity { - } - // CraftBukkit end + public int oldLevel = -1; -+ // Purpur start -+ public int burpDelay = 0; -+ -+ public abstract void resetLastActionTime(); -+ + public void setAfk(boolean afk) { + } + + public boolean isAfk() { + return false; + } ++ + @Override + public CraftHumanEntity getBukkitEntity() { + return (CraftHumanEntity) super.getBukkitEntity(); + } + // CraftBukkit end + ++ // Purpur start ++ public abstract void resetLastActionTime(); + + @Override + public boolean processClick(InteractionHand hand) { @@ -15314,67 +15464,67 @@ index 0629c471d38a77c44fc1c86ccdfcb0690f61ca17..7edcb5b86f27d05a0526229262e0d3a3 public Player(Level world, BlockPos pos, float yaw, GameProfile gameProfile) { super(EntityType.PLAYER, world); this.lastItemInMainHand = ItemStack.EMPTY; -@@ -241,6 +265,12 @@ public abstract class Player extends LivingEntity { +@@ -242,6 +265,12 @@ public abstract class Player extends LivingEntity { @Override public void tick() { + // Purpur start + if (this.burpDelay > 0 && --this.burpDelay == 0) { -+ this.level.playSound(null, getX(), getY(), getZ(), SoundEvents.PLAYER_BURP, SoundSource.PLAYERS, 1.0F, this.level.random.nextFloat() * 0.1F + 0.9F); ++ this.level().playSound(null, getX(), getY(), getZ(), SoundEvents.PLAYER_BURP, SoundSource.PLAYERS, 1.0F, this.level().random.nextFloat() * 0.1F + 0.9F); + } + // Purpur end + this.noPhysics = this.isSpectator(); if (this.isSpectator()) { - this.onGround = false; -@@ -344,6 +374,16 @@ public abstract class Player extends LivingEntity { + this.setOnGround(false); +@@ -345,6 +374,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 } + // Purpur start -+ if (this.level.purpurConfig.playerNetheriteFireResistanceDuration > 0 && this.level.getGameTime() % 20 == 0) { ++ if (this.level().purpurConfig.playerNetheriteFireResistanceDuration > 0 && this.level().getGameTime() % 20 == 0) { + if (itemstack.is(Items.NETHERITE_HELMET) + && this.getItemBySlot(EquipmentSlot.CHEST).is(Items.NETHERITE_CHESTPLATE) + && this.getItemBySlot(EquipmentSlot.LEGS).is(Items.NETHERITE_LEGGINGS) + && this.getItemBySlot(EquipmentSlot.FEET).is(Items.NETHERITE_BOOTS)) { -+ this.addEffect(new MobEffectInstance(MobEffects.FIRE_RESISTANCE, this.level.purpurConfig.playerNetheriteFireResistanceDuration, this.level.purpurConfig.playerNetheriteFireResistanceAmplifier, this.level.purpurConfig.playerNetheriteFireResistanceAmbient, this.level.purpurConfig.playerNetheriteFireResistanceShowParticles, this.level.purpurConfig.playerNetheriteFireResistanceShowIcon), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.NETHERITE_ARMOR); ++ this.addEffect(new MobEffectInstance(MobEffects.FIRE_RESISTANCE, this.level().purpurConfig.playerNetheriteFireResistanceDuration, this.level().purpurConfig.playerNetheriteFireResistanceAmplifier, this.level().purpurConfig.playerNetheriteFireResistanceAmbient, this.level().purpurConfig.playerNetheriteFireResistanceShowParticles, this.level().purpurConfig.playerNetheriteFireResistanceShowIcon), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.NETHERITE_ARMOR); + } + } + // Purpur end } protected ItemCooldowns createItemCooldowns() { -@@ -430,7 +470,7 @@ public abstract class Player extends LivingEntity { +@@ -431,7 +470,7 @@ public abstract class Player extends LivingEntity { @Override public int getPortalWaitTime() { - return this.abilities.invulnerable ? 1 : 80; -+ return canPortalInstant ? 1 : this.abilities.invulnerable ? this.level.purpurConfig.playerCreativePortalWaitTime : this.level.purpurConfig.playerPortalWaitTime; // Purpur ++ return canPortalInstant ? 1 : this.abilities.invulnerable ? this.level().purpurConfig.playerCreativePortalWaitTime : this.level().purpurConfig.playerPortalWaitTime; // Purpur } @Override -@@ -590,7 +630,7 @@ public abstract class Player extends LivingEntity { +@@ -591,7 +630,7 @@ public abstract class Player extends LivingEntity { for (int i = 0; i < list.size(); ++i) { Entity entity = (Entity) list.get(i); - if (entity.getType() == EntityType.EXPERIENCE_ORB) { -+ if (entity.getType() == EntityType.EXPERIENCE_ORB && entity.level.purpurConfig.playerExpPickupDelay >= 0) { // Purpur ++ if (entity.getType() == EntityType.EXPERIENCE_ORB && entity.level().purpurConfig.playerExpPickupDelay >= 0) { // Purpur list1.add(entity); } else if (!entity.isRemoved()) { this.touch(entity); -@@ -1281,7 +1321,7 @@ public abstract class Player extends LivingEntity { - flag2 = flag2 && !level.paperConfig().entities.behavior.disablePlayerCrits; // Paper +@@ -1282,7 +1321,7 @@ public abstract class Player extends LivingEntity { + flag2 = flag2 && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper flag2 = flag2 && !this.isSprinting(); if (flag2) { - f *= 1.5F; -+ f *= this.level.purpurConfig.playerCriticalDamageMultiplier; // Purpur ++ f *= this.level().purpurConfig.playerCriticalDamageMultiplier; // Purpur } f += f1; -@@ -1950,9 +1990,19 @@ public abstract class Player extends LivingEntity { +@@ -1977,9 +2016,19 @@ public abstract class Player extends LivingEntity { @Override public int getExperienceReward() { - if (!this.level.getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) && !this.isSpectator()) { + if (!this.level().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) && !this.isSpectator()) { - int i = this.experienceLevel * 7; - - return i > 100 ? 100 : i; @@ -15384,29 +15534,29 @@ index 0629c471d38a77c44fc1c86ccdfcb0690f61ca17..7edcb5b86f27d05a0526229262e0d3a3 + toDrop = Math.round(((Number) scriptEngine.eval("let expLevel = " + experienceLevel + "; " + + "let expTotal = " + totalExperience + "; " + + "let exp = " + experienceProgress + "; " + -+ level.purpurConfig.playerDeathExpDropEquation)).floatValue()); ++ level().purpurConfig.playerDeathExpDropEquation)).floatValue()); + } catch (javax.script.ScriptException e) { + e.printStackTrace(); + toDrop = experienceLevel * 7; + } -+ return Math.min(toDrop, level.purpurConfig.playerDeathExpDropMax); ++ return Math.min(toDrop, level().purpurConfig.playerDeathExpDropMax); + // Purpur end } else { return 0; } -@@ -2028,6 +2078,11 @@ public abstract class Player extends LivingEntity { +@@ -2055,6 +2104,11 @@ public abstract class Player extends LivingEntity { return this.inventory.armor; } + @Override + public boolean dismountsUnderwater() { -+ return !level.purpurConfig.playerRidableInWater; ++ return !level().purpurConfig.playerRidableInWater; + } + public boolean setEntityOnShoulder(CompoundTag entityNbt) { - if (!this.isPassenger() && this.onGround && !this.isInWater() && !this.isInPowderSnow) { + if (!this.isPassenger() && this.onGround() && !this.isInWater() && !this.isInPowderSnow) { if (this.getShoulderEntityLeft().isEmpty()) { -@@ -2311,7 +2366,7 @@ public abstract class Player extends LivingEntity { +@@ -2339,7 +2393,7 @@ public abstract class Player extends LivingEntity { public ItemStack eat(Level world, ItemStack stack) { this.getFoodData().eat(stack.getItem(), stack); this.awardStat(Stats.ITEM_USED.get(stack.getItem())); @@ -15416,12 +15566,12 @@ index 0629c471d38a77c44fc1c86ccdfcb0690f61ca17..7edcb5b86f27d05a0526229262e0d3a3 CriteriaTriggers.CONSUME_ITEM.trigger((ServerPlayer) this, stack); } diff --git a/src/main/java/net/minecraft/world/entity/player/StackedContents.java b/src/main/java/net/minecraft/world/entity/player/StackedContents.java -index 574ebb3a2fcd0e4e426a8a7ee88d722ed3b9c3f5..842b921799111789b37a34b76644c9217bc85794 100644 +index 68d272e98f9e54c9b150c75c27a9ae545be842f6..63fc6074082b579c3f88316008cbeb2a2d7f5841 100644 --- a/src/main/java/net/minecraft/world/entity/player/StackedContents.java +++ b/src/main/java/net/minecraft/world/entity/player/StackedContents.java -@@ -37,8 +37,62 @@ public class StackedContents { - int i = getStackingIndex(stack); +@@ -40,8 +40,62 @@ public class StackedContents { int j = Math.min(maxCount, stack.getCount()); + if (this.extrasMap != null && stack.hasTag() && this.extrasMap.accountStack(stack, j)) return; // Paper - if an exact ingredient, don't include it this.put(i, j); + // PaperPR start + if (stack.hasTag()) { @@ -15443,7 +15593,7 @@ index 574ebb3a2fcd0e4e426a8a7ee88d722ed3b9c3f5..842b921799111789b37a34b76644c921 + if (a == null || b == null) { + return false; + } -+ return ItemStack.tagMatches(a, b); ++ return ItemStack.matches(a, b); + } + }); + private final it.unimi.dsi.fastutil.ints.Int2ObjectMap idToItemstack = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(); @@ -15482,7 +15632,7 @@ index 574ebb3a2fcd0e4e426a8a7ee88d722ed3b9c3f5..842b921799111789b37a34b76644c921 } public static int getStackingIndex(ItemStack stack) { -@@ -80,6 +134,12 @@ public class StackedContents { +@@ -83,6 +137,12 @@ public class StackedContents { } public static ItemStack fromStackingIndex(int itemId) { @@ -15496,7 +15646,7 @@ index 574ebb3a2fcd0e4e426a8a7ee88d722ed3b9c3f5..842b921799111789b37a34b76644c921 } 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 5d6d26cfe8f0ab68a3145214b3fc126ca7a71a66..c6fddfa199e0c42e0556ed1ad380885a17208e37 100644 +index fa885337085348308604e50049ecc5bb52023884..6b070ad6aa1b62a66fb85d54042af9d64cdcea7f 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java +++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java @@ -72,6 +72,7 @@ public abstract class AbstractArrow extends Projectile { @@ -15512,7 +15662,7 @@ index 5d6d26cfe8f0ab68a3145214b3fc126ca7a71a66..c6fddfa199e0c42e0556ed1ad380885a this.setDeltaMovement(vec3d.multiply((double) (this.random.nextFloat() * 0.2F), (double) (this.random.nextFloat() * 0.2F), (double) (this.random.nextFloat() * 0.2F))); - this.life = 0; -+ if (this.level.purpurConfig.arrowMovementResetsDespawnCounter) this.life = 0; // Purpur - do not reset despawn counter ++ if (this.level().purpurConfig.arrowMovementResetsDespawnCounter) this.life = 0; // Purpur - do not reset despawn counter } @Override @@ -15530,35 +15680,35 @@ index 5d6d26cfe8f0ab68a3145214b3fc126ca7a71a66..c6fddfa199e0c42e0556ed1ad380885a return this.knockback; } diff --git a/src/main/java/net/minecraft/world/entity/projectile/LargeFireball.java b/src/main/java/net/minecraft/world/entity/projectile/LargeFireball.java -index 4daa368881e4fa59a9365d7b3810ae7dc1455fa3..a4041580061b2acd150836a1437df66ebb4a62cb 100644 +index 251e6bc87eb02ec4372062ef22b21249ac5164ff..6b60597a0e837054b0d1891c1e6e5e7cd3af9539 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/LargeFireball.java +++ b/src/main/java/net/minecraft/world/entity/projectile/LargeFireball.java @@ -16,20 +16,20 @@ public class LargeFireball extends Fireball { public LargeFireball(EntityType type, Level world) { super(type, world); -- isIncendiary = this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit -+ isIncendiary = this.level.purpurConfig.fireballsBypassMobGriefing || this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit // Purpur +- isIncendiary = this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit ++ isIncendiary = this.level().purpurConfig.fireballsBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit // Purpur } public LargeFireball(Level world, LivingEntity owner, double velocityX, double velocityY, double velocityZ, int explosionPower) { super(EntityType.FIREBALL, owner, velocityX, velocityY, velocityZ, world); this.explosionPower = explosionPower; -- isIncendiary = this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit -+ isIncendiary = this.level.purpurConfig.fireballsBypassMobGriefing || this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit // Purpur +- isIncendiary = this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit ++ isIncendiary = this.level().purpurConfig.fireballsBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit // Purpur } @Override protected void onHit(HitResult hitResult) { super.onHit(hitResult); - if (!this.level.isClientSide) { -- boolean flag = this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); -+ boolean flag = this.level.purpurConfig.fireballsBypassMobGriefing || this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // Purpur + if (!this.level().isClientSide) { +- boolean flag = this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); ++ boolean flag = this.level().purpurConfig.fireballsBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // Purpur // 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 c4f4a26e016eea744f587461af80461074d48303..10b109de5abc015b61a896d363ad37a006dff554 100644 +index 0bbe853f7df93f9dcd2b21d762939f8b6be069aa..7db9844083703944f59e112c6dc5e1a5e062d31c 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/LlamaSpit.java +++ b/src/main/java/net/minecraft/world/entity/projectile/LlamaSpit.java @@ -26,6 +26,12 @@ public class LlamaSpit extends Projectile { @@ -15575,10 +15725,10 @@ index c4f4a26e016eea744f587461af80461074d48303..10b109de5abc015b61a896d363ad37a0 public void tick() { super.tick(); 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 85260fd93ca8d5ffd0ba7a98f1d47093d58f0f87..505a60605ff2282f2c460c81464d60a433f41eda 100644 +index 459aee61b519a40d9136546c0d9356562f5757c8..134b5758e5c6335a52ffb2703c3fa98dc792948e 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -@@ -318,6 +318,6 @@ public abstract class Projectile extends Entity implements TraceableEntity { +@@ -319,6 +319,6 @@ public abstract class Projectile extends Entity implements TraceableEntity { public boolean mayInteract(Level world, BlockPos pos) { Entity entity = this.getOwner(); @@ -15586,21 +15736,34 @@ index 85260fd93ca8d5ffd0ba7a98f1d47093d58f0f87..505a60605ff2282f2c460c81464d60a4 + return entity instanceof Player ? entity.mayInteract(world, pos) : entity == null || world.purpurConfig.projectilesBypassMobGriefing || world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); } } +diff --git a/src/main/java/net/minecraft/world/entity/projectile/ProjectileUtil.java b/src/main/java/net/minecraft/world/entity/projectile/ProjectileUtil.java +index cc0a3d9794d05b6bc6ab05f4f2ab8d83134b181d..e1f918d0bd2a70db1aba8bda8717149f58766825 100644 +--- a/src/main/java/net/minecraft/world/entity/projectile/ProjectileUtil.java ++++ b/src/main/java/net/minecraft/world/entity/projectile/ProjectileUtil.java +@@ -33,7 +33,7 @@ public final class ProjectileUtil { + return getHitResult(vec32, entity, predicate, vec3, level); + } + +- private static HitResult getHitResult(Vec3 pos, Entity entity, Predicate predicate, Vec3 velocity, Level world) { ++ public static HitResult getHitResult(Vec3 pos, Entity entity, Predicate predicate, Vec3 velocity, Level world) { // Purpur - private -> public + Vec3 vec3 = pos.add(velocity); + HitResult hitResult = world.clip(new ClipContext(pos, vec3, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, entity)); + if (hitResult.getType() != HitResult.Type.MISS) { 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 b9e4955fecabbad8d6762f3d933ea1402e932d9b..895c501f8579799139239701703078ef060cd481 100644 +index 04c2ea1ff44af72ae48e2d6b7b912b1c14285038..7839d856b3f924f0c87b298d9a1e3b15ab0693d6 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java +++ b/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java @@ -24,7 +24,7 @@ public class SmallFireball extends Fireball { super(EntityType.SMALL_FIREBALL, owner, velocityX, velocityY, velocityZ, world); // CraftBukkit start if (this.getOwner() != null && this.getOwner() instanceof Mob) { -- isIncendiary = this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); -+ isIncendiary = this.level.purpurConfig.fireballsBypassMobGriefing || this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // Purpur +- isIncendiary = this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); ++ isIncendiary = this.level().purpurConfig.fireballsBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // Purpur } // 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 6cded52e4627c2b6073fa221fc6d6583f1b2a96d..9a84e8cc1d1b2803a061fe9ef6297c9c4aea34c5 100644 +index 718e120c9768cf716b32d3d652f53f1dda925168..440d3d72d8b2dac14f83a83caa5ae9dbf3e979b6 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Snowball.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Snowball.java @@ -53,10 +53,40 @@ public class Snowball extends ThrowableItemProjectile { @@ -15608,7 +15771,7 @@ index 6cded52e4627c2b6073fa221fc6d6583f1b2a96d..9a84e8cc1d1b2803a061fe9ef6297c9c super.onHitEntity(entityHitResult); Entity entity = entityHitResult.getEntity(); - int i = entity instanceof Blaze ? 3 : 0; -+ int i = entity.level.purpurConfig.snowballDamage >= 0 ? entity.level.purpurConfig.snowballDamage : entity instanceof Blaze ? 3 : 0; // Purpur ++ int i = entity.level().purpurConfig.snowballDamage >= 0 ? entity.level().purpurConfig.snowballDamage : entity instanceof Blaze ? 3 : 0; // Purpur entity.hurt(this.damageSources().thrown(this, this.getOwner()), (float)i); } @@ -15617,25 +15780,25 @@ index 6cded52e4627c2b6073fa221fc6d6583f1b2a96d..9a84e8cc1d1b2803a061fe9ef6297c9c + protected void onHitBlock(net.minecraft.world.phys.BlockHitResult blockHitResult) { + super.onHitBlock(blockHitResult); + -+ if (!this.level.isClientSide) { ++ if (!this.level().isClientSide) { + net.minecraft.core.BlockPos blockposition = blockHitResult.getBlockPos(); + net.minecraft.core.BlockPos blockposition1 = blockposition.relative(blockHitResult.getDirection()); + -+ net.minecraft.world.level.block.state.BlockState iblockdata = this.level.getBlockState(blockposition); ++ net.minecraft.world.level.block.state.BlockState iblockdata = this.level().getBlockState(blockposition); + -+ if (this.level.purpurConfig.snowballExtinguishesFire && this.level.getBlockState(blockposition1).is(net.minecraft.world.level.block.Blocks.FIRE)) { -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, blockposition1, net.minecraft.world.level.block.Blocks.AIR.defaultBlockState()).isCancelled()) { -+ this.level.removeBlock(blockposition1, false); ++ if (this.level().purpurConfig.snowballExtinguishesFire && this.level().getBlockState(blockposition1).is(net.minecraft.world.level.block.Blocks.FIRE)) { ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, blockposition1, net.minecraft.world.level.block.Blocks.AIR.defaultBlockState())) { ++ this.level().removeBlock(blockposition1, false); + } -+ } else if (this.level.purpurConfig.snowballExtinguishesCandles && net.minecraft.world.level.block.AbstractCandleBlock.isLit(iblockdata)) { -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, iblockdata.setValue(net.minecraft.world.level.block.AbstractCandleBlock.LIT, false)).isCancelled()) { -+ net.minecraft.world.level.block.AbstractCandleBlock.extinguish(null, iblockdata, this.level, blockposition); ++ } else if (this.level().purpurConfig.snowballExtinguishesCandles && net.minecraft.world.level.block.AbstractCandleBlock.isLit(iblockdata)) { ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, iblockdata.setValue(net.minecraft.world.level.block.AbstractCandleBlock.LIT, false))) { ++ net.minecraft.world.level.block.AbstractCandleBlock.extinguish(null, iblockdata, this.level(), blockposition); + } -+ } else if (this.level.purpurConfig.snowballExtinguishesCampfires && net.minecraft.world.level.block.CampfireBlock.isLitCampfire(iblockdata)) { -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, iblockdata.setValue(net.minecraft.world.level.block.CampfireBlock.LIT, false)).isCancelled()) { -+ this.level.levelEvent(null, 1009, blockposition, 0); -+ net.minecraft.world.level.block.CampfireBlock.dowse(this.getOwner(), this.level, blockposition, iblockdata); -+ this.level.setBlockAndUpdate(blockposition, iblockdata.setValue(net.minecraft.world.level.block.CampfireBlock.LIT, false)); ++ } else if (this.level().purpurConfig.snowballExtinguishesCampfires && net.minecraft.world.level.block.CampfireBlock.isLitCampfire(iblockdata)) { ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, iblockdata.setValue(net.minecraft.world.level.block.CampfireBlock.LIT, false))) { ++ this.level().levelEvent(null, 1009, blockposition, 0); ++ net.minecraft.world.level.block.CampfireBlock.dowse(this.getOwner(), this.level(), blockposition, iblockdata); ++ this.level().setBlockAndUpdate(blockposition, iblockdata.setValue(net.minecraft.world.level.block.CampfireBlock.LIT, false)); + } + } + } @@ -15646,72 +15809,90 @@ index 6cded52e4627c2b6073fa221fc6d6583f1b2a96d..9a84e8cc1d1b2803a061fe9ef6297c9c protected void onHit(HitResult hitResult) { super.onHit(hitResult); diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java -index 39ab9a283d856ba8d578d1378285758e32a24cf0..f35547c6b5951bc6eb4df74b2a94496fd20d69b5 100644 +index e8114d89a3129e56c0329410a49ded63cc77cb4c..d7359c675707eade00f9b737fd67ef8d066e813f 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java @@ -68,10 +68,11 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { Bukkit.getPluginManager().callEvent(teleEvent); if (!teleEvent.isCancelled() && entityplayer.connection.isAcceptingMessages()) { -- if (this.random.nextFloat() < 0.05F && this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) { -+ if (this.random.nextFloat() < this.level.purpurConfig.enderPearlEndermiteChance && this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) { // Purpur - Endermite entityendermite = (Endermite) EntityType.ENDERMITE.create(this.level); +- if (this.random.nextFloat() < 0.05F && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) { ++ if (this.random.nextFloat() < this.level().purpurConfig.enderPearlEndermiteChance && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) { // Purpur + Endermite entityendermite = (Endermite) EntityType.ENDERMITE.create(this.level()); if (entityendermite != null) { + entityendermite.setPlayerSpawned(true); // Purpur entityendermite.moveTo(entity.getX(), entity.getY(), entity.getZ(), entity.getYRot(), entity.getXRot()); - this.level.addFreshEntity(entityendermite, CreatureSpawnEvent.SpawnReason.ENDER_PEARL); + this.level().addFreshEntity(entityendermite, CreatureSpawnEvent.SpawnReason.ENDER_PEARL); } @@ -84,7 +85,7 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { entityplayer.connection.teleport(teleEvent.getTo()); entity.resetFallDistance(); CraftEventFactory.entityDamage = this; - entity.hurt(this.damageSources().fall(), 5.0F); -+ entity.hurt(this.damageSources().fall(), this.level.purpurConfig.enderPearlDamage); // Purpur ++ entity.hurt(this.damageSources().fall(), this.level().purpurConfig.enderPearlDamage); // Purpur CraftEventFactory.entityDamage = null; } // CraftBukkit end 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 db151bf624095014c99d78b4f6748d2c3792abea..fb10fc5a5aa3b6d6220694041778bfd39ffa1cb8 100644 +index a6bc277b6589dd7104566542733327822d6299a4..dde841cc09ba4a3575a462b03537887551d47ba5 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java -@@ -60,7 +60,7 @@ public class ThrownTrident extends AbstractArrow { +@@ -62,7 +62,7 @@ public class ThrownTrident extends AbstractArrow { Entity entity = this.getOwner(); byte b0 = (Byte) this.entityData.get(ThrownTrident.ID_LOYALTY); - if (b0 > 0 && (this.dealtDamage || this.isNoPhysics()) && entity != null) { -+ if (b0 > 0 && (this.dealtDamage || this.isNoPhysics() || (level.purpurConfig.tridentLoyaltyVoidReturnHeight < 0.0D && getY() < level.purpurConfig.tridentLoyaltyVoidReturnHeight)) && entity != null) { // Purpur ++ if (b0 > 0 && (this.dealtDamage || this.isNoPhysics() || (level().purpurConfig.tridentLoyaltyVoidReturnHeight < 0.0D && getY() < level().purpurConfig.tridentLoyaltyVoidReturnHeight)) && entity != null) { // Purpur if (!this.isAcceptibleReturnOwner()) { - if (!this.level.isClientSide && this.pickup == AbstractArrow.Pickup.ALLOWED) { + 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 093a00e52062868b4fbf358b307513d0f599f69d..ba753735f3cbb2cb3d0a491d1bd94a04f83b123d 100644 +index 06d1bdb9bd124b201c36d284c50d22bf50d3735a..b4687453256ead43cf5288994316c7bf946b86df 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java +++ b/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java -@@ -95,7 +95,7 @@ public class WitherSkull extends AbstractHurtingProjectile { - if (!this.level.isClientSide) { +@@ -97,7 +97,7 @@ public class WitherSkull extends AbstractHurtingProjectile { + if (!this.level().isClientSide) { // CraftBukkit start - // this.level.explode(this, this.getX(), this.getY(), this.getZ(), 1.0F, false, World.a.MOB); + // this.level().explode(this, this.getX(), this.getY(), this.getZ(), 1.0F, false, World.a.MOB); - ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), 1.0F, false); -+ ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), this.level.purpurConfig.witherExplosionRadius, false); // Purpur - this.level.getCraftServer().getPluginManager().callEvent(event); ++ ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), this.level().purpurConfig.witherExplosionRadius, false); // Purpur + this.level().getCraftServer().getPluginManager().callEvent(event); if (!event.isCancelled()) { +@@ -109,6 +109,17 @@ public class WitherSkull extends AbstractHurtingProjectile { + + } + ++ @Override ++ public boolean canHitEntity(Entity target) { ++ // do not hit rider ++ return target != this.getRider() && super.canHitEntity(target); ++ } ++ ++ @Override ++ public boolean canSaveToDisk() { ++ return false; ++ } ++ + @Override + public boolean isPickable() { + 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 99e9d46d42ddd0b451c6aeb847f1b295ebe5c697..f7b03dc1d5316aeb760a52d6f6c50e8aae5f978e 100644 +index 57fdcdaf54fd1c92a6e51a3a81789029096e5abe..822dd4265ce02252afadbc652064450b7dfd7e0d 100644 --- a/src/main/java/net/minecraft/world/entity/raid/Raider.java +++ b/src/main/java/net/minecraft/world/entity/raid/Raider.java @@ -319,7 +319,7 @@ public abstract class Raider extends PatrollingMonster { @Override public boolean canUse() { -- if (!this.mob.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) || !this.mob.canPickUpLoot()) return false; // Paper - respect game and entity rules for picking up items -+ 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 +- if (!this.mob.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) || !this.mob.canPickUpLoot()) return false; // Paper - respect game and entity rules for picking up items ++ 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.getLeaderBannerInstance())) { 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 fabce3bc592b1b172b227395a07febdbb66ec3c9..df48bcc8f329e3855bb7426bdfe0e3c72af53bea 100644 +index 41457c9f27b18fa2734a6cca297ec5186470e82f..94356e0541f8f4da68211fa533347cc97d4f3518 100644 --- a/src/main/java/net/minecraft/world/entity/raid/Raids.java +++ b/src/main/java/net/minecraft/world/entity/raid/Raids.java @@ -28,6 +28,7 @@ import net.minecraft.world.phys.Vec3; @@ -15755,10 +15936,10 @@ index fabce3bc592b1b172b227395a07febdbb66ec3c9..df48bcc8f329e3855bb7426bdfe0e3c7 if (!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 ee4f924afe15c9a4d96af7a55b357076c7b28501..ddcd7ada9f4bf5653bd8bf7c6cdb35d7243367d9 100644 +index 9948a28dae4edba877c13ef0156be5ff58df3fa2..b99b94c6ec4767aba16d82eaca8b2761d779b226 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java -@@ -107,11 +107,13 @@ public abstract class AbstractMinecart extends Entity { +@@ -108,11 +108,13 @@ public abstract class AbstractMinecart extends Entity { private double flyingY = 0.949999988079071D; // Paper - restore vanilla precision private double flyingZ = 0.949999988079071D; // Paper - restore vanilla precision public double maxSpeed = 0.4D; @@ -15772,20 +15953,20 @@ index ee4f924afe15c9a4d96af7a55b357076c7b28501..ddcd7ada9f4bf5653bd8bf7c6cdb35d7 } protected AbstractMinecart(EntityType type, Level world, double x, double y, double z) { -@@ -334,6 +336,12 @@ public abstract class AbstractMinecart extends Entity { +@@ -335,6 +337,12 @@ public abstract class AbstractMinecart extends Entity { @Override public void tick() { + // Purpur start -+ if (storedMaxSpeed != level.purpurConfig.minecartMaxSpeed) { -+ maxSpeed = storedMaxSpeed = level.purpurConfig.minecartMaxSpeed; ++ if (storedMaxSpeed != level().purpurConfig.minecartMaxSpeed) { ++ maxSpeed = storedMaxSpeed = level().purpurConfig.minecartMaxSpeed; + } + // Purpur end + // CraftBukkit start double prevX = this.getX(); double prevY = this.getY(); -@@ -497,16 +505,63 @@ public abstract class AbstractMinecart extends Entity { +@@ -499,16 +507,62 @@ public abstract class AbstractMinecart extends Entity { public void activateMinecart(int x, int y, int z, boolean powered) {} @@ -15793,17 +15974,16 @@ index ee4f924afe15c9a4d96af7a55b357076c7b28501..ddcd7ada9f4bf5653bd8bf7c6cdb35d7 + private Double lastSpeed; + + public double getControllableSpeed() { -+ BlockPos pos = new BlockPos(this); -+ Block block = level.getBlockState(pos).getBlock(); -+ if (!block.material.isSolid()) { -+ block = level.getBlockState(pos.relative(Direction.DOWN)).getBlock(); ++ BlockState blockState = level().getBlockState(this.blockPosition()); ++ if (!blockState.isSolid()) { ++ blockState = level().getBlockState(this.blockPosition().relative(Direction.DOWN)); + } -+ Double speed = level.purpurConfig.minecartControllableBlockSpeeds.get(block); -+ if (!block.material.isSolid()) { ++ Double speed = level().purpurConfig.minecartControllableBlockSpeeds.get(blockState.getBlock()); ++ if (!blockState.isSolid()) { + speed = lastSpeed; + } + if (speed == null) { -+ speed = level.purpurConfig.minecartControllableBaseSpeed; ++ speed = level().purpurConfig.minecartControllableBaseSpeed; + } + return lastSpeed = speed; + } @@ -15816,12 +15996,12 @@ index ee4f924afe15c9a4d96af7a55b357076c7b28501..ddcd7ada9f4bf5653bd8bf7c6cdb35d7 this.setDeltaMovement(Mth.clamp(vec3d.x, -d0, d0), vec3d.y, Mth.clamp(vec3d.z, -d0, d0)); + + // Purpur start -+ if (level.purpurConfig.minecartControllable && !isInWater() && !isInLava() && !passengers.isEmpty()) { ++ if (level().purpurConfig.minecartControllable && !isInWater() && !isInLava() && !passengers.isEmpty()) { + Entity passenger = passengers.get(0); + if (passenger instanceof Player) { + Player player = (Player) passenger; + if (player.jumping && this.onGround) { -+ setDeltaMovement(new Vec3(getDeltaMovement().x, level.purpurConfig.minecartControllableHopBoost, getDeltaMovement().z)); ++ setDeltaMovement(new Vec3(getDeltaMovement().x, level().purpurConfig.minecartControllableHopBoost, getDeltaMovement().z)); + } + if (player.zza != 0.0F) { + Vector velocity = player.getBukkitEntity().getEyeLocation().getDirection().normalize().multiply(getControllableSpeed()); @@ -15831,7 +16011,7 @@ index ee4f924afe15c9a4d96af7a55b357076c7b28501..ddcd7ada9f4bf5653bd8bf7c6cdb35d7 + setDeltaMovement(new Vec3(velocity.getX(), getDeltaMovement().y, velocity.getZ())); + } + this.setYRot(passenger.getYRot() - 90); -+ maxUpStep = level.purpurConfig.minecartControllableStepHeight; ++ maxUpStep = level().purpurConfig.minecartControllableStepHeight; + } else { + maxUpStep = 0.0F; + } @@ -15839,27 +16019,27 @@ index ee4f924afe15c9a4d96af7a55b357076c7b28501..ddcd7ada9f4bf5653bd8bf7c6cdb35d7 + maxUpStep = 0.0F; + } + // Purpur end -+ - if (this.onGround) { ++ + if (this.onGround()) { // CraftBukkit start - replace magic numbers with our variables this.setDeltaMovement(new Vec3(this.getDeltaMovement().x * this.derailedX, this.getDeltaMovement().y * this.derailedY, this.getDeltaMovement().z * this.derailedZ)); // CraftBukkit end } -+ else if (level.purpurConfig.minecartControllable) setDeltaMovement(new Vec3(getDeltaMovement().x * derailedX, getDeltaMovement().y, getDeltaMovement().z * derailedZ)); // Purpur ++ else if (level().purpurConfig.minecartControllable) setDeltaMovement(new Vec3(getDeltaMovement().x * derailedX, getDeltaMovement().y, getDeltaMovement().z * derailedZ)); // Purpur this.move(MoverType.SELF, this.getDeltaMovement()); - if (!this.onGround) { -@@ -668,7 +723,7 @@ public abstract class AbstractMinecart extends Entity { + if (!this.onGround()) { +@@ -670,7 +724,7 @@ public abstract class AbstractMinecart extends Entity { if (d18 > 0.01D) { double d20 = 0.06D; - this.setDeltaMovement(vec3d4.add(vec3d4.x / d18 * 0.06D, 0.0D, vec3d4.z / d18 * 0.06D)); -+ this.setDeltaMovement(vec3d4.add(vec3d4.x / d18 * this.level.purpurConfig.poweredRailBoostModifier, 0.0D, vec3d4.z / d18 * this.level.purpurConfig.poweredRailBoostModifier)); // Purpur ++ this.setDeltaMovement(vec3d4.add(vec3d4.x / d18 * this.level().purpurConfig.poweredRailBoostModifier, 0.0D, vec3d4.z / d18 * this.level().purpurConfig.poweredRailBoostModifier)); // Purpur } else { 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 12e3209c5246ede89daaf8455fe70b4a517e12f6..06421017e3a7a0511c253e2ad4a028b0c156c9a8 100644 +index 2c5658df753ebc08f8531d4bdf22ff8f6ca77e94..a7ab9e2284d4a1ae6f5601adc3dfac534bce26fc 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java @@ -223,7 +223,13 @@ public class Boat extends Entity implements VariantHolder { @@ -15869,7 +16049,7 @@ index 12e3209c5246ede89daaf8455fe70b4a517e12f6..06421017e3a7a0511c253e2ad4a028b0 - this.spawnAtLocation((ItemLike) this.getDropItem()); + // Purpur start + final ItemStack boat = new ItemStack(this.getDropItem()); -+ if (this.level.purpurConfig.persistentDroppableEntityDisplayNames && this.hasCustomName()) { ++ if (this.level().purpurConfig.persistentDroppableEntityDisplayNames && this.hasCustomName()) { + boat.setHoverName(this.getCustomName()); + } + this.spawnAtLocation(boat); @@ -15881,12 +16061,12 @@ index 12e3209c5246ede89daaf8455fe70b4a517e12f6..06421017e3a7a0511c253e2ad4a028b0 if (f > 0.0F) { this.landFriction = f; -+ if (level.purpurConfig.boatEjectPlayersOnLand) ejectPassengers(); // Purpur ++ if (level().purpurConfig.boatEjectPlayersOnLand) ejectPassengers(); // Purpur return Boat.Status.ON_LAND; } else { return Boat.Status.IN_AIR; diff --git a/src/main/java/net/minecraft/world/food/FoodData.java b/src/main/java/net/minecraft/world/food/FoodData.java -index 4a2dcf9bd83dd3fdff43483f887f4f58dc4715cd..3d2e3c7dd3bf5c8f483a933e9f6868586c0d3911 100644 +index 2038df72f8d7d33d4105de8129628daf21de6f0f..e54af9ff2a786e919b8261aa27509be942e70261 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 { @@ -15896,7 +16076,7 @@ index 4a2dcf9bd83dd3fdff43483f887f4f58dc4715cd..3d2e3c7dd3bf5c8f483a933e9f686858 + 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); -+ if (this.entityhuman.level.purpurConfig.playerBurpWhenFull && this.foodLevel == 20 && oldValue < 20) this.entityhuman.burpDelay = this.entityhuman.level.purpurConfig.playerBurpDelay; // Purpur ++ 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) { @@ -15905,7 +16085,7 @@ index 4a2dcf9bd83dd3fdff43483f887f4f58dc4715cd..3d2e3c7dd3bf5c8f483a933e9f686858 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) { - player.hurt(player.damageSources().starve(), 1.0F); -+ player.hurt(player.damageSources().starve(), player.level.purpurConfig.hungerStarvationDamage); // Purpur ++ player.hurt(player.damageSources().starve(), player.level().purpurConfig.hungerStarvationDamage); // Purpur } this.tickTimer = 0; @@ -15956,7 +16136,7 @@ index b16d9e2eaa589f19c563ee70b1a56d67dbcdecb0..71beab673f04cd051c46ea37f8c84731 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 c84908095a93d42826b21bf5f3490410fb0a5708..20b328704981c088597359fe18c1d67c339c1c0f 100644 +index 706b354ac9a1a6a4a1e61b2a109180d1dd22bbbd..9ca261c9f21279558961649cb4849ac379d67573 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 { @@ -15968,7 +16148,7 @@ index c84908095a93d42826b21bf5f3490410fb0a5708..20b328704981c088597359fe18c1d67c // CraftBukkit start public boolean checkReachable = true; diff --git a/src/main/java/net/minecraft/world/inventory/AbstractFurnaceMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractFurnaceMenu.java -index 8ae78ae54d87ea7789df754311fa0e8aade0ce91..35479019fb846573f4e2eb5902f3ebe898c4d61f 100644 +index 35b41bceeba72c3896c91c2605bac3b0bf9c54e9..5c028f957661089ff502109c996692856b12ee27 100644 --- a/src/main/java/net/minecraft/world/inventory/AbstractFurnaceMenu.java +++ b/src/main/java/net/minecraft/world/inventory/AbstractFurnaceMenu.java @@ -145,7 +145,13 @@ public abstract class AbstractFurnaceMenu extends RecipeBookMenu { @@ -15987,10 +16167,10 @@ index 8ae78ae54d87ea7789df754311fa0e8aade0ce91..35479019fb846573f4e2eb5902f3ebe8 } 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 b7a2295290227045e6426ee0f71707185d95b943..7ade5cd93b3d7b7259bf3246a8b74b0b31407817 100644 +index e0c3a4ba27e21c3692e601acd0af60873bcbb84c..531b911c1bcdd3735529ee18f2bb0ccdf4ad6089 100644 --- a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java +++ b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java -@@ -21,6 +21,13 @@ import org.slf4j.Logger; +@@ -23,6 +23,13 @@ import org.slf4j.Logger; import org.bukkit.craftbukkit.inventory.CraftInventoryView; // CraftBukkit end @@ -16004,7 +16184,7 @@ index b7a2295290227045e6426ee0f71707185d95b943..7ade5cd93b3d7b7259bf3246a8b74b0b public class AnvilMenu extends ItemCombinerMenu { public static final int INPUT_SLOT = 0; -@@ -48,6 +55,8 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -51,6 +58,8 @@ public class AnvilMenu extends ItemCombinerMenu { public int maximumRepairCost = 40; private CraftInventoryView bukkitEntity; // CraftBukkit end @@ -16013,7 +16193,7 @@ index b7a2295290227045e6426ee0f71707185d95b943..7ade5cd93b3d7b7259bf3246a8b74b0b public AnvilMenu(int syncId, Inventory inventory) { this(syncId, inventory, ContainerLevelAccess.NULL); -@@ -75,12 +84,15 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -78,12 +87,15 @@ public class AnvilMenu extends ItemCombinerMenu { @Override protected boolean mayPickup(Player player, boolean present) { @@ -16030,7 +16210,7 @@ index b7a2295290227045e6426ee0f71707185d95b943..7ade5cd93b3d7b7259bf3246a8b74b0b player.giveExperienceLevels(-this.cost.get()); } -@@ -131,6 +143,12 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -134,6 +146,12 @@ public class AnvilMenu extends ItemCombinerMenu { @Override public void createResult() { @@ -16043,7 +16223,7 @@ index b7a2295290227045e6426ee0f71707185d95b943..7ade5cd93b3d7b7259bf3246a8b74b0b ItemStack itemstack = this.inputSlots.getItem(0); this.cost.set(1); -@@ -207,7 +225,8 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -210,7 +228,8 @@ public class AnvilMenu extends ItemCombinerMenu { int i2 = (Integer) map1.get(enchantment); i2 = l1 == i2 ? i2 + 1 : Math.max(i2, l1); @@ -16053,12 +16233,16 @@ index b7a2295290227045e6426ee0f71707185d95b943..7ade5cd93b3d7b7259bf3246a8b74b0b if (this.player.getAbilities().instabuild || itemstack.is(Items.ENCHANTED_BOOK)) { flag3 = true; -@@ -219,16 +238,16 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -222,16 +241,20 @@ public class AnvilMenu extends ItemCombinerMenu { Enchantment enchantment1 = (Enchantment) 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 (!flag4 && org.purpurmc.purpur.PurpurConfig.replaceIncompatibleEnchants) { ++ iterator1.remove(); ++ flag4 = true; ++ } ++i; } } @@ -16073,62 +16257,62 @@ index b7a2295290227045e6426ee0f71707185d95b943..7ade5cd93b3d7b7259bf3246a8b74b0b i2 = enchantment.getMaxLevel(); } -@@ -278,6 +297,54 @@ public class AnvilMenu extends ItemCombinerMenu { - } else if (!this.itemName.equals(itemstack.getHoverName().getString())) { - b1 = 1; - i += b1; -+ // Purpur start -+ if (this.player != null) { -+ org.bukkit.craftbukkit.entity.CraftHumanEntity player = this.player.getBukkitEntity(); -+ String name = this.itemName; -+ boolean removeItalics = false; -+ if (player.hasPermission("purpur.anvil.remove_italics")) { -+ if (name.startsWith("&r")) { -+ name = name.substring(2); -+ removeItalics = true; -+ } else if (name.startsWith("")) { -+ name = name.substring(3); -+ removeItalics = true; -+ } else if (name.startsWith("")) { -+ name = name.substring(7); -+ removeItalics = true; -+ } -+ } -+ if (this.player.level.purpurConfig.anvilAllowColors) { -+ if (player.hasPermission("purpur.anvil.color")) { -+ java.util.regex.Matcher matcher = java.util.regex.Pattern.compile("(?i)&([0-9a-fr])").matcher(name); -+ while (matcher.find()) { -+ String match = matcher.group(1); -+ name = name.replace("&" + match, "\u00a7" + match.toLowerCase(java.util.Locale.ROOT)); +@@ -276,6 +299,54 @@ public class AnvilMenu extends ItemCombinerMenu { + if (!this.itemName.equals(itemstack.getHoverName().getString())) { + b1 = 1; + i += b1; ++ // Purpur start ++ if (this.player != null) { ++ org.bukkit.craftbukkit.entity.CraftHumanEntity player = this.player.getBukkitEntity(); ++ String name = this.itemName; ++ boolean removeItalics = false; ++ if (player.hasPermission("purpur.anvil.remove_italics")) { ++ if (name.startsWith("&r")) { ++ name = name.substring(2); ++ removeItalics = true; ++ } else if (name.startsWith("")) { ++ name = name.substring(3); ++ removeItalics = true; ++ } else if (name.startsWith("")) { ++ name = name.substring(7); ++ removeItalics = true; + } -+ //name = name.replaceAll("(?i)&([0-9a-fr])", "\u00a7$1"); + } -+ if (player.hasPermission("purpur.anvil.format")) { -+ java.util.regex.Matcher matcher = java.util.regex.Pattern.compile("(?i)&([k-or])").matcher(name); -+ while (matcher.find()) { -+ String match = matcher.group(1); -+ name = name.replace("&" + match, "\u00a7" + match.toLowerCase(java.util.Locale.ROOT)); ++ if (this.player.level().purpurConfig.anvilAllowColors) { ++ if (player.hasPermission("purpur.anvil.color")) { ++ java.util.regex.Matcher matcher = java.util.regex.Pattern.compile("(?i)&([0-9a-fr])").matcher(name); ++ while (matcher.find()) { ++ String match = matcher.group(1); ++ name = name.replace("&" + match, "\u00a7" + match.toLowerCase(java.util.Locale.ROOT)); ++ } ++ //name = name.replaceAll("(?i)&([0-9a-fr])", "\u00a7$1"); ++ } ++ if (player.hasPermission("purpur.anvil.format")) { ++ java.util.regex.Matcher matcher = java.util.regex.Pattern.compile("(?i)&([k-or])").matcher(name); ++ while (matcher.find()) { ++ String match = matcher.group(1); ++ name = name.replace("&" + match, "\u00a7" + match.toLowerCase(java.util.Locale.ROOT)); ++ } ++ //name = name.replaceAll("(?i)&([l-or])", "\u00a7$1"); + } -+ //name = name.replaceAll("(?i)&([l-or])", "\u00a7$1"); + } ++ net.kyori.adventure.text.Component component; ++ if (this.player.level().purpurConfig.anvilColorsUseMiniMessage && player.hasPermission("purpur.anvil.minimessage")) { ++ component = net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.bukkit.ChatColor.stripColor(name)); ++ } else { ++ component = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(name); ++ } ++ if (removeItalics) { ++ component = component.decoration(net.kyori.adventure.text.format.TextDecoration.ITALIC, false); ++ } ++ itemstack1.setHoverName(io.papermc.paper.adventure.PaperAdventure.asVanilla(component)); + } -+ net.kyori.adventure.text.Component component; -+ if (this.player.level.purpurConfig.anvilColorsUseMiniMessage && player.hasPermission("purpur.anvil.minimessage")) { -+ component = net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.bukkit.ChatColor.stripColor(name)); -+ } else { -+ component = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(name); -+ } -+ if (removeItalics) { -+ component = component.decoration(net.kyori.adventure.text.format.TextDecoration.ITALIC, false); -+ } -+ itemstack1.setHoverName(io.papermc.paper.adventure.PaperAdventure.asVanilla(component)); -+ } -+ else -+ // Purpur end - itemstack1.setHoverName(Component.literal(this.itemName)); - } - -@@ -290,6 +357,13 @@ public class AnvilMenu extends ItemCombinerMenu { ++ else ++ // Purpur end + itemstack1.setHoverName(Component.literal(this.itemName)); + } + } else if (itemstack.hasCustomHoverName()) { +@@ -293,6 +364,13 @@ public class AnvilMenu extends ItemCombinerMenu { this.cost.set(this.maximumRepairCost - 1); // CraftBukkit } @@ -16142,7 +16326,7 @@ index b7a2295290227045e6426ee0f71707185d95b943..7ade5cd93b3d7b7259bf3246a8b74b0b if (this.cost.get() >= this.maximumRepairCost && !this.player.getAbilities().instabuild) { // CraftBukkit itemstack1 = ItemStack.EMPTY; } -@@ -312,11 +386,17 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -315,11 +393,17 @@ public class AnvilMenu extends ItemCombinerMenu { org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareAnvilEvent(this.getBukkitView(), itemstack1); // CraftBukkit sendAllDataToRemote(); // CraftBukkit - SPIGOT-6686: Always send completed inventory to stay in sync with client this.broadcastChanges(); @@ -16160,7 +16344,7 @@ index b7a2295290227045e6426ee0f71707185d95b943..7ade5cd93b3d7b7259bf3246a8b74b0b + return org.purpurmc.purpur.PurpurConfig.anvilCumulativeCost ? cost * 2 + 1 : 0; } - public void setItemName(String newItemName) { + public boolean setItemName(String newItemName) { diff --git a/src/main/java/net/minecraft/world/inventory/ChestMenu.java b/src/main/java/net/minecraft/world/inventory/ChestMenu.java index 0dbfd23bbfc6ad203f048142f8c90ef741849fe1..9a80427d2bb470b6b1638e59aba57216676dcbd2 100644 --- a/src/main/java/net/minecraft/world/inventory/ChestMenu.java @@ -16197,7 +16381,7 @@ 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 c2fc00509bf3690d359928e8d352d4b3c2ca1491..69ae671be07b1928e778399551991777829e432a 100644 +index 93e8316f9d64625dcc4df0644a2187bcc884ef65..1711406996ec4a9cb7b1838bd2446e5cf802e043 100644 --- a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java +++ b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java @@ -38,6 +38,12 @@ import org.bukkit.event.enchantment.PrepareItemEnchantEvent; @@ -16223,7 +16407,7 @@ index c2fc00509bf3690d359928e8d352d4b3c2ca1491..69ae671be07b1928e778399551991777 + public void onClose(CraftHumanEntity who) { + super.onClose(who); + -+ if (who.getHandle().getLevel().purpurConfig.enchantmentTableLapisPersists) { ++ if (who.getHandle().level().purpurConfig.enchantmentTableLapisPersists) { + access.execute((level, pos) -> { + BlockEntity blockEntity = level.getBlockEntity(pos); + if (blockEntity instanceof EnchantmentTableBlockEntity enchantmentTable) { @@ -16254,7 +16438,7 @@ index c2fc00509bf3690d359928e8d352d4b3c2ca1491..69ae671be07b1928e778399551991777 int j; for (j = 0; j < 3; ++j) { -@@ -338,6 +371,7 @@ public class EnchantmentMenu extends AbstractContainerMenu { +@@ -340,6 +373,7 @@ public class EnchantmentMenu extends AbstractContainerMenu { public void removed(net.minecraft.world.entity.player.Player player) { super.removed(player); this.access.execute((world, blockposition) -> { @@ -16263,7 +16447,7 @@ index c2fc00509bf3690d359928e8d352d4b3c2ca1491..69ae671be07b1928e778399551991777 }); } diff --git a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java -index 89838076f3231ff4318ebb2718c9406399b4e4f5..d41987060c2261f1a345752ecc46af1ec23b83ea 100644 +index b56766ff0e61691294b40ea8c2370940c0e8b640..23a8522b80475ad29ffb4afd2f4836acda2538e3 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 { @@ -16297,16 +16481,16 @@ index 89838076f3231ff4318ebb2718c9406399b4e4f5..d41987060c2261f1a345752ecc46af1e itemstack2.enchant(enchantment, (Integer) entry.getValue()); } } -@@ -251,7 +253,7 @@ public class GrindstoneMenu extends AbstractContainerMenu { +@@ -250,7 +252,7 @@ public class GrindstoneMenu extends AbstractContainerMenu { + } - itemstack1.setCount(amount); 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); -@@ -267,6 +269,20 @@ public class GrindstoneMenu extends AbstractContainerMenu { +@@ -266,6 +268,20 @@ public class GrindstoneMenu extends AbstractContainerMenu { itemstack1.setRepairCost(AnvilMenu.calculateIncreasedRepairCost(itemstack1.getBaseRepairCost())); } @@ -16327,7 +16511,7 @@ index 89838076f3231ff4318ebb2718c9406399b4e4f5..d41987060c2261f1a345752ecc46af1e return itemstack1; } -@@ -328,7 +344,9 @@ public class GrindstoneMenu extends AbstractContainerMenu { +@@ -327,7 +343,9 @@ public class GrindstoneMenu extends AbstractContainerMenu { return ItemStack.EMPTY; } @@ -16338,7 +16522,7 @@ index 89838076f3231ff4318ebb2718c9406399b4e4f5..d41987060c2261f1a345752ecc46af1e 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 da0f5c5e6ca7ce7b38792e6da52c5cdcdbae3b78..4136bcd49fe05d916ab65de0e866145185db4204 100644 +index c549618421c5d077c3d977d8d2064eca2acc438a..5972fa434847d24fa98b7895fd8386d20a636885 100644 --- a/src/main/java/net/minecraft/world/inventory/InventoryMenu.java +++ b/src/main/java/net/minecraft/world/inventory/InventoryMenu.java @@ -4,6 +4,7 @@ import com.mojang.datafixers.util.Pair; @@ -16354,7 +16538,7 @@ index da0f5c5e6ca7ce7b38792e6da52c5cdcdbae3b78..4136bcd49fe05d916ab65de0e8661451 ItemStack itemstack = this.getItem(); - return !itemstack.isEmpty() && !playerEntity.isCreative() && EnchantmentHelper.hasBindingCurse(itemstack) ? false : super.mayPickup(playerEntity); -+ return !itemstack.isEmpty() && !playerEntity.isCreative() && EnchantmentHelper.hasBindingCurse(itemstack) ? playerEntity.level.purpurConfig.playerRemoveBindingWithWeakness && playerEntity.hasEffect(MobEffects.WEAKNESS) : super.mayPickup(playerEntity); // Purpur ++ return !itemstack.isEmpty() && !playerEntity.isCreative() && EnchantmentHelper.hasBindingCurse(itemstack) ? playerEntity.level().purpurConfig.playerRemoveBindingWithWeakness && playerEntity.hasEffect(MobEffects.WEAKNESS) : super.mayPickup(playerEntity); // Purpur } @Override @@ -16429,7 +16613,7 @@ index 7cffc64573008502bdd14ae4906fe51166b12fb3..1feafdbb48cf760cb6ebf95d5be2c32b 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 9c7d0b9cc2fa98d5785c914c0183f7d4b5b1c1ea..89a4ab17ca8d2aa1f52b041c610d7de19bf55e66 100644 +index 18898e16ec42f6b694b06e09d9174b60d62450d7..20f33b77b4a9494be227456bc742a029eb0af59b 100644 --- a/src/main/java/net/minecraft/world/item/AxeItem.java +++ b/src/main/java/net/minecraft/world/item/AxeItem.java @@ -33,29 +33,32 @@ public class AxeItem extends DiggerItem { @@ -16467,11 +16651,11 @@ index 9c7d0b9cc2fa98d5785c914c0183f7d4b5b1c1ea..89a4ab17ca8d2aa1f52b041c610d7de1 } if (optional4.isPresent()) { -+ org.purpurmc.purpur.tool.Actionable actionable = optional4.get(); ++ org.purpurmc.purpur.tool.Actionable actionable = optional4.get(); // Purpur + BlockState state = actionable.into().withPropertiesOf(blockState); // Purpur // Paper start - EntityChangeBlockEvent -- if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, blockPos, optional4.get()).isCancelled()) { -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, blockPos, state).isCancelled()) { // Purpur +- if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, blockPos, optional4.get())) { ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, blockPos, state)) { // Purpur return InteractionResult.PASS; } // Paper end @@ -16502,7 +16686,7 @@ index 9c7d0b9cc2fa98d5785c914c0183f7d4b5b1c1ea..89a4ab17ca8d2aa1f52b041c610d7de1 return InteractionResult.PASS; } diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java -index ebee8de2ed831755b6fd154f6cc77ac993839bb9..9060a844cd3bb3b62171872d84516b9195b9b677 100644 +index e483186a5292b3b53bfb1af4d56f55fcc1a6106c..41728bcbd5ca3585da64f7c3289b26977f90c229 100644 --- a/src/main/java/net/minecraft/world/item/BlockItem.java +++ b/src/main/java/net/minecraft/world/item/BlockItem.java @@ -153,7 +153,24 @@ public class BlockItem extends Item { @@ -16536,12 +16720,12 @@ index ebee8de2ed831755b6fd154f6cc77ac993839bb9..9060a844cd3bb3b62171872d84516b91 @Override public void onDestroyed(ItemEntity entity) { - if (this.block instanceof ShulkerBoxBlock) { -+ if (this.block instanceof ShulkerBoxBlock && entity.level.purpurConfig.shulkerBoxItemDropContentsWhenDestroyed) { ++ if (this.block instanceof ShulkerBoxBlock && entity.level().purpurConfig.shulkerBoxItemDropContentsWhenDestroyed) { ItemStack itemstack = entity.getItem(); CompoundTag nbttagcompound = BlockItem.getBlockEntityData(itemstack); diff --git a/src/main/java/net/minecraft/world/item/BoatItem.java b/src/main/java/net/minecraft/world/item/BoatItem.java -index 1a95ac11a2fbc811c89afa3adf38e0fc9eaab09b..91280f8c39ea191b90da2a9ff5c49f43c255bd9a 100644 +index aec7ac31a35b1cc81f40b3fbeb5cf95c0f2c8a6c..cbcd35e60a2c344c83978abf0b94c2120ff53dee 100644 --- a/src/main/java/net/minecraft/world/item/BoatItem.java +++ b/src/main/java/net/minecraft/world/item/BoatItem.java @@ -69,6 +69,11 @@ public class BoatItem extends Item { @@ -16600,10 +16784,10 @@ index 08d597db1a5345a343777a01427655e6bf2c926b..d45a2f49c82d00801578c34e5f5277fc } 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 5c6aa9c464784ad5ee366412d080c72d3d22a76f..c03abc9589bf5f37abc1b0d355ed9784bac31a93 100644 +index 578c3db52dda4c169b5ea615a4ce4a79f15a4cad..0bd98b802f246a3f6061f716d470a4797b28d59d 100644 --- a/src/main/java/net/minecraft/world/item/BucketItem.java +++ b/src/main/java/net/minecraft/world/item/BucketItem.java -@@ -166,7 +166,7 @@ public class BucketItem extends Item implements DispensibleContainerItem { +@@ -164,7 +164,7 @@ public class BucketItem extends Item implements DispensibleContainerItem { // CraftBukkit end if (!flag1) { return movingobjectpositionblock != null && this.emptyContents(entityhuman, world, movingobjectpositionblock.getBlockPos().relative(movingobjectpositionblock.getDirection()), (BlockHitResult) null, enumdirection, clicked, itemstack, enumhand); // CraftBukkit @@ -16612,7 +16796,7 @@ index 5c6aa9c464784ad5ee366412d080c72d3d22a76f..c03abc9589bf5f37abc1b0d355ed9784 int i = blockposition.getX(); int j = blockposition.getY(); int k = blockposition.getZ(); -@@ -174,7 +174,7 @@ public class BucketItem extends Item implements DispensibleContainerItem { +@@ -172,7 +172,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) { @@ -16622,7 +16806,7 @@ index 5c6aa9c464784ad5ee366412d080c72d3d22a76f..c03abc9589bf5f37abc1b0d355ed9784 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 bc4f04c2512191da3c9e1c49f0716bb9128fc754..310e03d8cc07f95927d9806fc80a4215283d2ef5 100644 +index eede02c3f125d230af537bb67bebed9b88f7d1b4..2c51a73ebfd05af21b0f5d731fc9f1df77fed1a1 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 { @@ -16634,16 +16818,16 @@ index bc4f04c2512191da3c9e1c49f0716bb9128fc754..310e03d8cc07f95927d9806fc80a4215 CrossbowItem.setCharged(itemstack, false); return InteractionResultHolder.consume(itemstack); } else if (!user.getProjectile(itemstack).isEmpty()) { -@@ -113,7 +113,7 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable { +@@ -114,7 +114,7 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable { // Paper end - int i = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.MULTISHOT, projectile); + 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 consume -+ boolean flag = !consume || shooter instanceof Player && ((Player) shooter).getAbilities().instabuild || (org.purpurmc.purpur.PurpurConfig.allowCrossbowInfinity && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.INFINITY_ARROWS, projectile) > 0); // Paper - add consume // Purpur - ItemStack itemstack1 = shooter.getProjectile(projectile); ++ boolean flag = !consume || shooter instanceof Player && ((Player) shooter).getAbilities().instabuild || (org.purpurmc.purpur.PurpurConfig.allowCrossbowInfinity && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.INFINITY_ARROWS, crossbow) > 0); // Paper - add consume // Purpur + ItemStack itemstack1 = shooter.getProjectile(crossbow); ItemStack itemstack2 = itemstack1.copy(); -@@ -294,6 +294,14 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable { +@@ -291,6 +291,14 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable { entityarrow.setPierceLevel((byte) i); } @@ -16658,7 +16842,7 @@ index bc4f04c2512191da3c9e1c49f0716bb9128fc754..310e03d8cc07f95927d9806fc80a4215 return entityarrow; } -@@ -303,7 +311,7 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable { +@@ -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); @@ -16668,7 +16852,7 @@ index bc4f04c2512191da3c9e1c49f0716bb9128fc754..310e03d8cc07f95927d9806fc80a4215 if (!itemstack1.isEmpty()) { if (i == 0) { diff --git a/src/main/java/net/minecraft/world/item/DyeColor.java b/src/main/java/net/minecraft/world/item/DyeColor.java -index 2170715ed0e81a3055e4ab546c8b294c5ef7f142..beae4e2b9f61df83215de860d64c4ce2d3482004 100644 +index 88e1c2431d51d8cdc3d555b711e506648225d289..ac8735cc9d127fc1f867b40d4000c033ef73bb83 100644 --- a/src/main/java/net/minecraft/world/item/DyeColor.java +++ b/src/main/java/net/minecraft/world/item/DyeColor.java @@ -103,4 +103,10 @@ public enum DyeColor implements StringRepresentable { @@ -16695,6 +16879,19 @@ index 58cb992c5defec2f092755cbde661ff10f38bf9d..52f48681407d23f0925f4c9c072d5f0a // Paper start 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 3688e9f8c6c6d1239095e3a87060ccca90386d0c..34254eec36d34ae343733fa1abbaaba60be41a3b 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 { + BlockPos blockposition = context.getClickedPos(); + BlockState iblockdata = world.getBlockState(blockposition); + +- if (!iblockdata.is(Blocks.OBSIDIAN) && !iblockdata.is(Blocks.BEDROCK)) { ++ if (!world.purpurConfig.endCrystalPlaceAnywhere && !iblockdata.is(Blocks.OBSIDIAN) && !iblockdata.is(Blocks.BEDROCK)) { + return InteractionResult.FAIL; + } 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 749ab72edc0d2e9c6f1161415ab8d59d3d6ca976..6b27d98d06b163243bb0e1bb979aad03f48d7770 100644 --- a/src/main/java/net/minecraft/world/item/EnderpearlItem.java @@ -16770,7 +16967,7 @@ index b2ad6d230de2c29f371178bccde1111c7532ee70..6667926519a0f1c151e53f59cce36e74 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 180aec596110309aade13d2080f8824d152b07cb..c4aec1e5135a79837918b692e75a7b55d5cffeb0 100644 +index 180aec596110309aade13d2080f8824d152b07cb..552c31c0f3746dd35388395036e70a925bf00bd4 100644 --- a/src/main/java/net/minecraft/world/item/HoeItem.java +++ b/src/main/java/net/minecraft/world/item/HoeItem.java @@ -34,15 +34,23 @@ public class HoeItem extends DiggerItem { @@ -16785,7 +16982,7 @@ index 180aec596110309aade13d2080f8824d152b07cb..c4aec1e5135a79837918b692e75a7b55 - Consumer consumer = pair.getSecond(); + // Purpur start + Block clickedBlock = level.getBlockState(blockPos).getBlock(); -+ var tillable = level.purpurConfig.hoeTillables.get(level.getBlockState(blockPos).getBlock()); ++ var tillable = level.purpurConfig.hoeTillables.get(clickedBlock); + if (tillable == null) { return InteractionResult.PASS; } else { + Predicate predicate = tillable.condition().predicate(); + Consumer consumer = (ctx) -> { @@ -16814,18 +17011,18 @@ index 180aec596110309aade13d2080f8824d152b07cb..c4aec1e5135a79837918b692e75a7b55 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 d81fcbadc5c0b3d4b54dde5d47a0f847d8ec6918..aac8c78cec1c935d24207093a36b70a1ed082703 100644 +index 879cc823d56625867eb73bb621db6a13f40ad81c..7e68596e28db88213e9352f798c5a4ce37cc5656 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -111,6 +111,7 @@ import org.bukkit.event.world.StructureGrowEvent; +@@ -113,6 +113,7 @@ import org.bukkit.event.world.StructureGrowEvent; public final class ItemStack { + public boolean isExactRecipeIngredient = false; // PaperPR public static final Codec CODEC = RecordCodecBuilder.create((instance) -> { - return instance.group(BuiltInRegistries.ITEM.byNameCodec().fieldOf("id").forGetter((itemstack) -> { - return itemstack.item; -@@ -417,6 +418,7 @@ public final class ItemStack { + return instance.group(BuiltInRegistries.ITEM.byNameCodec().fieldOf("id").forGetter(ItemStack::getItem), Codec.INT.fieldOf("Count").forGetter(ItemStack::getCount), CompoundTag.CODEC.optionalFieldOf("tag").forGetter((itemstack) -> { + return Optional.ofNullable(itemstack.getTag()); +@@ -426,6 +427,7 @@ public final class ItemStack { world.preventPoiUpdated = true; // CraftBukkit - SPIGOT-5710 for (BlockState blockstate : blocks) { blockstate.update(true, false); @@ -16833,15 +17030,15 @@ index d81fcbadc5c0b3d4b54dde5d47a0f847d8ec6918..aac8c78cec1c935d24207093a36b70a1 } world.preventPoiUpdated = false; -@@ -446,6 +448,7 @@ public final class ItemStack { +@@ -455,6 +457,7 @@ public final class ItemStack { if (!(block.getBlock() instanceof BaseEntityBlock)) { // Containers get placed automatically - block.getBlock().onPlace(block, world, newblockposition, oldBlock, true, itemactioncontext); // Paper - pass itemactioncontext + block.getBlock().onPlace(block, 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 } -@@ -566,6 +569,16 @@ public final class ItemStack { +@@ -583,6 +586,16 @@ public final class ItemStack { return this.isDamageableItem() && this.getDamageValue() > 0; } @@ -16858,16 +17055,16 @@ index d81fcbadc5c0b3d4b54dde5d47a0f847d8ec6918..aac8c78cec1c935d24207093a36b70a1 public int getDamageValue() { return this.tag == null ? 0 : this.tag.getInt("Damage"); } -@@ -585,7 +598,7 @@ public final class ItemStack { +@@ -602,7 +615,7 @@ public final class ItemStack { int j; if (amount > 0) { - j = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.UNBREAKING, this); -+ j = (getItem() == Items.ELYTRA && player != null && player.level.purpurConfig.elytraIgnoreUnbreaking) ? 0 : EnchantmentHelper.getItemEnchantmentLevel(Enchantments.UNBREAKING, this); ++ j = (getItem() == Items.ELYTRA && player != null && player.level().purpurConfig.elytraIgnoreUnbreaking) ? 0 : EnchantmentHelper.getItemEnchantmentLevel(Enchantments.UNBREAKING, this); int k = 0; for (int l = 0; j > 0 && l < amount; ++l) { -@@ -640,6 +653,12 @@ public final class ItemStack { +@@ -657,6 +670,12 @@ public final class ItemStack { if (this.hurt(amount, entity.getRandom(), entity /*instanceof ServerPlayer ? (ServerPlayer) entity : null*/)) { // Paper - pass LivingEntity for EntityItemDamageEvent breakCallback.accept(entity); Item item = this.getItem(); @@ -16880,7 +17077,7 @@ index d81fcbadc5c0b3d4b54dde5d47a0f847d8ec6918..aac8c78cec1c935d24207093a36b70a1 // 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); -@@ -1172,7 +1191,7 @@ public final class ItemStack { +@@ -1183,7 +1202,7 @@ public final class ItemStack { ListTag nbttaglist = this.tag.getList("Enchantments", 10); @@ -16889,7 +17086,7 @@ index d81fcbadc5c0b3d4b54dde5d47a0f847d8ec6918..aac8c78cec1c935d24207093a36b70a1 processEnchantOrder(this.tag); // Paper } -@@ -1180,6 +1199,12 @@ public final class ItemStack { +@@ -1191,6 +1210,12 @@ public final class ItemStack { return this.tag != null && this.tag.contains("Enchantments", 9) ? !this.tag.getList("Enchantments", 10).isEmpty() : false; } @@ -16903,10 +17100,10 @@ index d81fcbadc5c0b3d4b54dde5d47a0f847d8ec6918..aac8c78cec1c935d24207093a36b70a1 this.getOrCreateTag().put(key, element); } diff --git a/src/main/java/net/minecraft/world/item/Items.java b/src/main/java/net/minecraft/world/item/Items.java -index 775823daa5187804d27e5ee696cd75f703bb067c..bc0915913d3d8fbe145ee7e19133c7de922e0c80 100644 +index 5f20e075c532f0f1d413242949d1738c0c152bf7..5fbb13ebef0ca66419f3e5006d19e4a5918a038a 100644 --- a/src/main/java/net/minecraft/world/item/Items.java +++ b/src/main/java/net/minecraft/world/item/Items.java -@@ -292,7 +292,7 @@ public class Items { +@@ -294,7 +294,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); @@ -16915,7 +17112,7 @@ index 775823daa5187804d27e5ee696cd75f703bb067c..bc0915913d3d8fbe145ee7e19133c7de public static final Item CHEST = registerBlock(Blocks.CHEST); public static final Item CRAFTING_TABLE = registerBlock(Blocks.CRAFTING_TABLE); public static final Item FARMLAND = registerBlock(Blocks.FARMLAND); -@@ -1178,7 +1178,7 @@ public class Items { +@@ -1184,7 +1184,7 @@ public class Items { public static final Item LANTERN = registerBlock(Blocks.LANTERN); public static final Item SOUL_LANTERN = registerBlock(Blocks.SOUL_LANTERN); public static final Item SWEET_BERRIES = registerItem("sweet_berries", new ItemNameBlockItem(Blocks.SWEET_BERRY_BUSH, (new Item.Properties()).food(Foods.SWEET_BERRIES))); @@ -16924,20 +17121,32 @@ index 775823daa5187804d27e5ee696cd75f703bb067c..bc0915913d3d8fbe145ee7e19133c7de public static final Item CAMPFIRE = registerBlock(Blocks.CAMPFIRE); public static final Item SOUL_CAMPFIRE = registerBlock(Blocks.SOUL_CAMPFIRE); public static final Item SHROOMLIGHT = registerBlock(Blocks.SHROOMLIGHT); -@@ -1278,6 +1278,13 @@ public class Items { +@@ -1309,6 +1309,13 @@ public class Items { ((BlockItem)item).registerBlocks(Item.BY_BLOCK, item); } + // Purpur start + if (item.getFoodProperties() != null) { -+ Foods.ALL_PROPERTIES.put(id.getPath(), item.getFoodProperties()); -+ Foods.DEFAULT_PROPERTIES.put(id.getPath(), item.getFoodProperties().copy()); ++ 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, id, item); + return Registry.register(BuiltInRegistries.ITEM, key, item); } } +diff --git a/src/main/java/net/minecraft/world/item/MapItem.java b/src/main/java/net/minecraft/world/item/MapItem.java +index d3c29e6bf8b3c2dd628809177dac50220a7de415..735486b46581bb3b91c85f57490b560ff490787e 100644 +--- a/src/main/java/net/minecraft/world/item/MapItem.java ++++ b/src/main/java/net/minecraft/world/item/MapItem.java +@@ -243,6 +243,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; 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 --- a/src/main/java/net/minecraft/world/item/MilkBucketItem.java @@ -16962,7 +17171,7 @@ index f33977d95b6db473be4f95075ba99caf90ad0220..56dc04d8875971ee9a5d077a695509af 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 c6d2f764efa9b8bec730bbe757d480e365b25ccc..33a30d26da2401535f0a72acb2bbffec1aef151e 100644 +index c6d2f764efa9b8bec730bbe757d480e365b25ccc..cef98413d25dcc2def82775bbae71f92b096d905 100644 --- a/src/main/java/net/minecraft/world/item/MinecartItem.java +++ b/src/main/java/net/minecraft/world/item/MinecartItem.java @@ -120,8 +120,9 @@ public class MinecartItem extends Item { @@ -16972,7 +17181,7 @@ index c6d2f764efa9b8bec730bbe757d480e365b25ccc..33a30d26da2401535f0a72acb2bbffec - return InteractionResult.FAIL; - } else { + if (!world.purpurConfig.minecartPlaceAnywhere) return InteractionResult.FAIL; -+ if (iblockdata.getMaterial().isSolid()) blockposition = blockposition.relative(context.getClickedFace()); ++ if (iblockdata.isSolid()) blockposition = blockposition.relative(context.getClickedFace()); + } // else { // Purpur - place minecarts anywhere ItemStack itemstack = context.getItemInHand(); @@ -16986,30 +17195,46 @@ index c6d2f764efa9b8bec730bbe757d480e365b25ccc..33a30d26da2401535f0a72acb2bbffec } } diff --git a/src/main/java/net/minecraft/world/item/NameTagItem.java b/src/main/java/net/minecraft/world/item/NameTagItem.java -index 623f78c078fb3aa2665d7e8a37672438227bce6b..500c69e555c7247e20ef8cc59d83415578f44427 100644 +index 2941c16ef486345b57ab2dfcd26f0272285d3b5a..7cc6812bf6f2ba015f65fd1fc1eaac02dd0f53e2 100644 --- a/src/main/java/net/minecraft/world/item/NameTagItem.java +++ b/src/main/java/net/minecraft/world/item/NameTagItem.java -@@ -24,6 +24,7 @@ public class NameTagItem extends Item { +@@ -20,6 +20,7 @@ public class NameTagItem extends Item { if (!event.callEvent()) return InteractionResult.PASS; LivingEntity newEntityLiving = ((org.bukkit.craftbukkit.entity.CraftLivingEntity) event.getEntity()).getHandle(); - newEntityLiving.setCustomName(event.getName() != null ? PaperAdventure.asVanilla(event.getName()) : null); -+ if (user.level.purpurConfig.armorstandFixNametags && entity instanceof net.minecraft.world.entity.decoration.ArmorStand) entity.setCustomNameVisible(true); // Purpur + newEntityLiving.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() && newEntityLiving instanceof Mob) { ((Mob) newEntityLiving).setPersistenceRequired(); - // Paper end + // Paper end diff --git a/src/main/java/net/minecraft/world/item/ShovelItem.java b/src/main/java/net/minecraft/world/item/ShovelItem.java -index c7195f2e12bbd6545f7bffcc2b4ba5cc3d48df20..5e730bc9c8ff94b16ac2bf8567dda8aea2ee4b2a 100644 +index 21212462e6b415e96536a27b2c009d1562f18946..193bcb12152347f5f02ce18b01ba918e5e838f30 100644 --- a/src/main/java/net/minecraft/world/item/ShovelItem.java +++ b/src/main/java/net/minecraft/world/item/ShovelItem.java -@@ -34,7 +34,7 @@ public class ShovelItem extends DiggerItem { - return InteractionResult.PASS; - } else { - Player player = context.getPlayer(); -- BlockState blockState2 = FLATTENABLES.get(blockState.getBlock()); -+ BlockState blockState2 = level.purpurConfig.shovelTurnsBlockToGrassPath.contains(blockState.getBlock()) ? Blocks.DIRT_PATH.defaultBlockState() : null; // Purpur +@@ -37,9 +37,12 @@ public class ShovelItem extends DiggerItem { + BlockState blockState2 = FLATTENABLES.get(blockState.getBlock()); BlockState blockState3 = null; Runnable afterAction = null; // Paper - if (blockState2 != null && level.getBlockState(blockPos.above()).isAir()) { +- if (blockState2 != null && level.getBlockState(blockPos.above()).isAir()) { +- afterAction = () -> level.playSound(player, blockPos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F); // Paper +- blockState3 = blockState2; ++ // Purpur start ++ var flattenable = level.purpurConfig.shovelFlattenables.get(blockState.getBlock()); ++ if (flattenable != null && level.getBlockState(blockPos.above()).isAir()) { ++ afterAction = () -> {if (!FLATTENABLES.containsKey(blockState.getBlock())) level.playSound(null, blockPos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F);}; // Paper ++ blockState3 = flattenable.into().defaultBlockState(); ++ // Purpur end + } else if (blockState.getBlock() instanceof CampfireBlock && blockState.getValue(CampfireBlock.LIT)) { + afterAction = () -> { // Paper + if (!level.isClientSide()) { +@@ -68,7 +71,7 @@ public class ShovelItem extends DiggerItem { + } + } + +- return InteractionResult.sidedSuccess(level.isClientSide); ++ return InteractionResult.SUCCESS; // Purpur - force arm swing + } else { + 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 ef3f90a5bcdd7b9815a4053cff166f9d2552f55d..e7e5e1cc92f56e3daba8fa09c59188febec5e8f2 100644 --- a/src/main/java/net/minecraft/world/item/SnowballItem.java @@ -17024,7 +17249,7 @@ index ef3f90a5bcdd7b9815a4053cff166f9d2552f55d..e7e5e1cc92f56e3daba8fa09c59188fe 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 31268e25056f980798ef7db72c4f955a074cc639..955822da142a2463af536dd1ce48037deda41402 100644 +index 741719301e6fc91a598e74342810c4185e6fde26..6fbff9c02fbabf03c9c649a9ea6128021081f9cd 100644 --- a/src/main/java/net/minecraft/world/item/SpawnEggItem.java +++ b/src/main/java/net/minecraft/world/item/SpawnEggItem.java @@ -68,6 +68,15 @@ public class SpawnEggItem extends Item { @@ -17057,7 +17282,7 @@ index de5bdceb4c8578fb972a2fd5ee0dfdae509e46dc..bcf63ccb6e679cb97d658780b2663aaf 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 9365f886a23a71c41091b22d46896ff18a5a0635..d35432087c70ce66b74d1e27df19f462f22b1aa1 100644 +index 8078f127ff4b6e0aafb5804b9c02e237f79445b5..c32cbe6065ecb6810f352b8a3598c21e42e60e1d 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 { @@ -17095,9 +17320,9 @@ index 9365f886a23a71c41091b22d46896ff18a5a0635..d35432087c70ce66b74d1e27df19f462 + entityhuman.push((double) f2, (double) f3, (double) f4); entityhuman.startAutoSpinAttack(20); - if (entityhuman.isOnGround()) { + 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 8d4aca59bd7518179520f4d4fb7137778e232d90..e24034d1ce4bb529de084aab69a531227e0c2f79 100644 +index cd7ea0c16f9ddcb84b5d7e8a2533e6e84f3879c7..f47eab4c31925f51de4a6bc8be730281cb3388fc 100644 --- a/src/main/java/net/minecraft/world/item/crafting/Ingredient.java +++ b/src/main/java/net/minecraft/world/item/crafting/Ingredient.java @@ -39,6 +39,7 @@ public final class Ingredient implements Predicate { @@ -17263,10 +17488,10 @@ index 4007c16550683e23b396dfdff29530a82523fe05..8fe09c13643d99639fb242da4367c42e public int getMinCost(int level) { return 15 + (level - 1) * 9; diff --git a/src/main/java/net/minecraft/world/item/trading/MerchantOffer.java b/src/main/java/net/minecraft/world/item/trading/MerchantOffer.java -index fd50d1c2435b82215bc5b3fdbe5044d426bc342e..68ffea572045634f1ad67a6954d480e6ae7833f5 100644 +index 28bdcb14cb5b458d3c990fcf343ef97f08e4f3c6..48167334162443365bb8a6d082a51b2c626ab3d8 100644 --- a/src/main/java/net/minecraft/world/item/trading/MerchantOffer.java +++ b/src/main/java/net/minecraft/world/item/trading/MerchantOffer.java -@@ -132,7 +132,12 @@ public class MerchantOffer { +@@ -134,7 +134,12 @@ public class MerchantOffer { } public void updateDemand() { @@ -17281,7 +17506,7 @@ index fd50d1c2435b82215bc5b3fdbe5044d426bc342e..68ffea572045634f1ad67a6954d480e6 public ItemStack assemble() { diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java -index 31ac0e5ca26c7bdfa9b710d0bb78d846ddf6863e..feb65fc9ee04141fe6f77400660442ed207547a1 100644 +index 633500aefd515df5dadda3802b94079f75a03fa0..64d911bee1607880514061c75116d8672df8bb8f 100644 --- a/src/main/java/net/minecraft/world/level/BaseSpawner.java +++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java @@ -55,6 +55,7 @@ public abstract class BaseSpawner { @@ -17306,7 +17531,7 @@ index 3b959f42d958bf0f426853aee56753d6c455fcdb..d17abb283ea818244df0379d6b57fc63 if (range < 0.0D || d < range * range) { return true; diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java -index 185f7b1d4df59f5db7b85b529a2de6402630bf35..7a3d9c1f8abdbc25e88ca35da1546725f0013c68 100644 +index 8f97c9df726ac20cfce7bdddd5dd4f8c5aa76c35..4932374ab9a3d8582fb0ef024d817ad896dd23c4 100644 --- a/src/main/java/net/minecraft/world/level/Explosion.java +++ b/src/main/java/net/minecraft/world/level/Explosion.java @@ -86,7 +86,7 @@ public class Explosion { @@ -17337,7 +17562,7 @@ index 185f7b1d4df59f5db7b85b529a2de6402630bf35..7a3d9c1f8abdbc25e88ca35da1546725 + } + }else { + Location location = new Location(this.level.getWorld(), this.x, this.y, this.z); -+ if(!new org.purpurmc.purpur.event.PreBlockExplodeEvent(location.getBlock(), this.blockInteraction == Explosion.BlockInteraction.DESTROY_WITH_DECAY ? 1.0F / this.radius : 1.0F).callEvent()) { ++ if(!new org.purpurmc.purpur.event.PreBlockExplodeEvent(location.getBlock(), this.blockInteraction == Explosion.BlockInteraction.DESTROY_WITH_DECAY ? 1.0F / this.radius : 1.0F, this.damageSource.explodedBlockState).callEvent()) { + this.wasCanceled = true; + return; + } @@ -17366,10 +17591,10 @@ index 185f7b1d4df59f5db7b85b529a2de6402630bf35..7a3d9c1f8abdbc25e88ca35da1546725 } diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 6aec1983a0236d6aa0507a2b3ad1c08b3330f0fc..b8001bca2a33ec1e60566948a651400418a6e9e7 100644 +index d8d4a1ca2eb062af8b2de4ab44503983587cdd77..bdb32964524cb2a4398b8d3bedfb03b0cb805b6d 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -177,6 +177,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -176,6 +176,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Paper end public final com.destroystokyo.paper.antixray.ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray @@ -17377,7 +17602,7 @@ index 6aec1983a0236d6aa0507a2b3ad1c08b3330f0fc..b8001bca2a33ec1e60566948a6514004 public final co.aikar.timings.WorldTimingsHandler timings; // Paper public static BlockPos lastPhysicsProblem; // Spigot private org.spigotmc.TickLimiter entityLimiter; -@@ -194,6 +195,49 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -193,6 +194,49 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } // Paper end - fix and optimise world upgrading @@ -17427,7 +17652,7 @@ index 6aec1983a0236d6aa0507a2b3ad1c08b3330f0fc..b8001bca2a33ec1e60566948a6514004 public CraftWorld getWorld() { return this.world; } -@@ -274,7 +318,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -273,7 +317,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public abstract ResourceKey getTypeKey(); @@ -17436,7 +17661,7 @@ index 6aec1983a0236d6aa0507a2b3ad1c08b3330f0fc..b8001bca2a33ec1e60566948a6514004 // Pufferfish start - ensure these get inlined private final int minBuildHeight, minSection, height, maxBuildHeight, maxSection; -@@ -288,6 +332,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -287,6 +331,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, java.util.concurrent.Executor executor) { // Paper - Async-Anti-Xray - Pass executor this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper @@ -17445,19 +17670,7 @@ index 6aec1983a0236d6aa0507a2b3ad1c08b3330f0fc..b8001bca2a33ec1e60566948a6514004 this.generator = gen; this.world = new CraftWorld((ServerLevel) this, gen, biomeProvider, env); -@@ -672,9 +718,9 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - BlockState iblockdata2 = this.getBlockState(pos); - - if ((flags & 128) == 0 && iblockdata2 != iblockdata1 && (iblockdata2.getLightBlock(this, pos) != iblockdata1.getLightBlock(this, pos) || iblockdata2.getLightEmission() != iblockdata1.getLightEmission() || iblockdata2.useShapeForLightOcclusion() || iblockdata1.useShapeForLightOcclusion())) { -- this.getProfiler().push("queueCheckLight"); -+ //this.getProfiler().push("queueCheckLight"); // Purpur - this.getChunkSource().getLightEngine().checkBlock(pos); -- this.getProfiler().pop(); -+ //this.getProfiler().pop(); // Purpur - } - - /* -@@ -973,18 +1019,18 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -967,18 +1013,18 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } protected void tickBlockEntities() { @@ -17481,7 +17694,7 @@ index 6aec1983a0236d6aa0507a2b3ad1c08b3330f0fc..b8001bca2a33ec1e60566948a6514004 // Spigot start // Iterator iterator = this.blockEntityTickers.iterator(); int tilesThisCycle = 0; -@@ -1017,10 +1063,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1011,10 +1057,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } this.blockEntityTickers.removeAll(toRemove); @@ -17494,7 +17707,7 @@ index 6aec1983a0236d6aa0507a2b3ad1c08b3330f0fc..b8001bca2a33ec1e60566948a6514004 spigotConfig.currentPrimedTnt = 0; // Spigot } -@@ -1213,7 +1259,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1207,7 +1253,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @Override public List getEntities(@Nullable Entity except, AABB box, Predicate predicate) { @@ -17503,7 +17716,7 @@ index 6aec1983a0236d6aa0507a2b3ad1c08b3330f0fc..b8001bca2a33ec1e60566948a6514004 List list = Lists.newArrayList(); ((ServerLevel)this).getEntityLookup().getEntities(except, box, list, predicate); // Paper - optimise this call return list; -@@ -1232,7 +1278,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1226,7 +1272,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } public void getEntities(EntityTypeTest filter, AABB box, Predicate predicate, List result, int limit) { @@ -17512,16 +17725,16 @@ index 6aec1983a0236d6aa0507a2b3ad1c08b3330f0fc..b8001bca2a33ec1e60566948a6514004 // Paper start - optimise this call //TODO use limit if (filter instanceof net.minecraft.world.entity.EntityType entityTypeTest) { -@@ -1557,7 +1603,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1483,7 +1529,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } public ProfilerFiller getProfiler() { - if (gg.pufferfish.pufferfish.PufferfishConfig.disableMethodProfiler) return net.minecraft.util.profiling.InactiveProfiler.INSTANCE; // Pufferfish -+ if (true || gg.pufferfish.pufferfish.PufferfishConfig.disableMethodProfiler) return net.minecraft.util.profiling.InactiveProfiler.INSTANCE; // Pufferfish ++ if (true || gg.pufferfish.pufferfish.PufferfishConfig.disableMethodProfiler) return net.minecraft.util.profiling.InactiveProfiler.INSTANCE; // Pufferfish // Purpur return (ProfilerFiller) this.profiler.get(); } -@@ -1648,4 +1694,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1574,4 +1620,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable { return null; } // Paper end @@ -17537,7 +17750,7 @@ index 6aec1983a0236d6aa0507a2b3ad1c08b3330f0fc..b8001bca2a33ec1e60566948a6514004 + // Purpur end } diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 6180679d922ea61d05d452971ec2d506a724d3c3..132041362b2707946bd386c88bbdf871a317afb7 100644 +index 49de1fca183b2c6a0a5399025abfc0e47f314315..1f9994f4b0b736f64a8676d9431469527c6484df 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java @@ -132,8 +132,8 @@ public final class NaturalSpawner { @@ -17668,10 +17881,10 @@ index 3d2b34c5a7c9b00c1164b4f89c2cbff81fc460eb..b5505e926e5cdb447de68e8eb8e46c97 return true; } else { diff --git a/src/main/java/net/minecraft/world/level/block/BedBlock.java b/src/main/java/net/minecraft/world/level/block/BedBlock.java -index d1d5363ab1742add8ff45507a303106f4d65f52f..19d31064eb271ee02115a75cde383796c899e7f7 100644 +index d40500f9a807cab0b2fb6fa9032f33f4fb74c895..2b66ddafaaca17f64d1e7502dfa4d7576e3e032f 100644 --- a/src/main/java/net/minecraft/world/level/block/BedBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BedBlock.java -@@ -97,7 +97,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock +@@ -96,7 +96,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock Vec3 vec3d = pos.getCenter(); @@ -17680,7 +17893,7 @@ index d1d5363ab1742add8ff45507a303106f4d65f52f..19d31064eb271ee02115a75cde383796 return InteractionResult.SUCCESS; } else if ((Boolean) state.getValue(BedBlock.OCCUPIED)) { if (!BedBlock.canSetSpawn(world)) return this.explodeBed(state, world, pos); // Paper - check explode first -@@ -150,7 +150,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock +@@ -149,7 +149,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock Vec3 vec3d = blockposition.getCenter(); @@ -17689,7 +17902,7 @@ index d1d5363ab1742add8ff45507a303106f4d65f52f..19d31064eb271ee02115a75cde383796 return InteractionResult.SUCCESS; } } -@@ -174,7 +174,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock +@@ -173,7 +173,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock @Override public void fallOn(Level world, BlockState state, BlockPos pos, Entity entity, float fallDistance) { @@ -17699,7 +17912,7 @@ index d1d5363ab1742add8ff45507a303106f4d65f52f..19d31064eb271ee02115a75cde383796 @Override diff --git a/src/main/java/net/minecraft/world/level/block/BigDripleafBlock.java b/src/main/java/net/minecraft/world/level/block/BigDripleafBlock.java -index 8537581e7ca1f4efb492a2e734f46f947f36cffa..5f89229ff68d923c5cdee40e72e379ba7024f961 100644 +index 5921f7ebb56e1d5d3004ae327271873093cff357..c7bb655983d2ee2c6461d23d6fa921def1a9a74c 100644 --- a/src/main/java/net/minecraft/world/level/block/BigDripleafBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BigDripleafBlock.java @@ -236,7 +236,7 @@ public class BigDripleafBlock extends HorizontalDirectionalBlock implements Bone @@ -17712,10 +17925,10 @@ index 8537581e7ca1f4efb492a2e734f46f947f36cffa..5f89229ff68d923c5cdee40e72e379ba if (i != -1) { world.scheduleTick(blockposition, (Block) this, i); diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java -index 4f91e4832a94c3facbc711fcae4cb5ad540a5ca0..773162c3456945605fb664114508622f7d2fcec8 100644 +index fdd9c61b7248e92dbcbec91cd6fe4c6310bba237..dc718efe054aaf36961514287c9cc48e2d28bc4c 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -63,6 +63,13 @@ import net.minecraft.world.phys.shapes.Shapes; +@@ -62,6 +62,13 @@ import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; import org.slf4j.Logger; @@ -17729,7 +17942,7 @@ index 4f91e4832a94c3facbc711fcae4cb5ad540a5ca0..773162c3456945605fb664114508622f public class Block extends BlockBehaviour implements ItemLike { private static final Logger LOGGER = LogUtils.getLogger(); -@@ -89,6 +96,10 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -87,6 +94,10 @@ public class Block extends BlockBehaviour implements ItemLike { public static final int UPDATE_LIMIT = 512; protected final StateDefinition stateDefinition; private BlockState defaultBlockState; @@ -17740,7 +17953,7 @@ index 4f91e4832a94c3facbc711fcae4cb5ad540a5ca0..773162c3456945605fb664114508622f // Paper start public final boolean isDestroyable() { return io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits || -@@ -325,7 +336,7 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -313,7 +324,7 @@ public class Block extends BlockBehaviour implements ItemLike { public static void dropResources(BlockState state, LevelAccessor world, BlockPos pos, @Nullable BlockEntity blockEntity) { if (world instanceof ServerLevel) { Block.getDrops(state, (ServerLevel) world, pos, blockEntity).forEach((itemstack) -> { @@ -17749,7 +17962,7 @@ index 4f91e4832a94c3facbc711fcae4cb5ad540a5ca0..773162c3456945605fb664114508622f }); state.spawnAfterBreak((ServerLevel) world, pos, ItemStack.EMPTY, true); } -@@ -341,7 +352,7 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -329,7 +340,7 @@ public class Block extends BlockBehaviour implements ItemLike { io.papermc.paper.event.block.BlockBreakBlockEvent event = new io.papermc.paper.event.block.BlockBreakBlockEvent(org.bukkit.craftbukkit.block.CraftBlock.at(world, pos), org.bukkit.craftbukkit.block.CraftBlock.at(world, source), items); event.callEvent(); for (var drop : event.getDrops()) { @@ -17758,8 +17971,8 @@ index 4f91e4832a94c3facbc711fcae4cb5ad540a5ca0..773162c3456945605fb664114508622f } state.spawnAfterBreak(world.getMinecraftWorld(), pos, ItemStack.EMPTY, true); } -@@ -352,13 +363,53 @@ public class Block extends BlockBehaviour implements ItemLike { - public static void dropResources(BlockState state, Level world, BlockPos pos, @Nullable BlockEntity blockEntity, Entity entity, ItemStack tool) { +@@ -340,13 +351,53 @@ public class Block extends BlockBehaviour implements ItemLike { + public static void dropResources(BlockState state, Level world, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool) { if (world instanceof ServerLevel) { Block.getDrops(state, (ServerLevel) world, pos, blockEntity, entity, tool).forEach((itemstack1) -> { - Block.popResource(world, pos, itemstack1); @@ -17813,8 +18026,8 @@ index 4f91e4832a94c3facbc711fcae4cb5ad540a5ca0..773162c3456945605fb664114508622f public static void popResource(Level world, BlockPos pos, ItemStack stack) { double d0 = (double) EntityType.ITEM.getHeight() / 2.0D; double d1 = (double) pos.getX() + 0.5D + Mth.nextDouble(world.random, -0.25D, 0.25D); -@@ -434,7 +485,17 @@ public class Block extends BlockBehaviour implements ItemLike { - Block.dropResources(state, world, pos, blockEntity, player, tool); +@@ -430,7 +481,17 @@ public class Block extends BlockBehaviour implements ItemLike { + } // Paper } - public void setPlacedBy(Level world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) {} @@ -17830,9 +18043,9 @@ index 4f91e4832a94c3facbc711fcae4cb5ad540a5ca0..773162c3456945605fb664114508622f + } + // Purpur end - public boolean isPossibleToRespawnInThis() { - return !this.material.isSolid() && !this.material.isLiquid(); -@@ -453,7 +514,7 @@ public class Block extends BlockBehaviour implements ItemLike { + public boolean isPossibleToRespawnInThis(BlockState state) { + return !state.isSolid() && !state.liquid(); +@@ -449,7 +510,7 @@ public class Block extends BlockBehaviour implements ItemLike { } public void fallOn(Level world, BlockState state, BlockPos pos, Entity entity, float fallDistance) { @@ -17842,21 +18055,21 @@ index 4f91e4832a94c3facbc711fcae4cb5ad540a5ca0..773162c3456945605fb664114508622f public void updateEntityAfterFallOn(BlockGetter world, Entity entity) { diff --git a/src/main/java/net/minecraft/world/level/block/Blocks.java b/src/main/java/net/minecraft/world/level/block/Blocks.java -index f148c7d2954cc17377d0da4af03ea2c1c9397a52..4afc4670f9b00a4087410ec366fe45fe2f2734dc 100644 +index 877035b6c6593a28f475b9c5bcd7727e3fcdb802..ed35878fdb9dffcd46c27d26ee8379401207cef5 100644 --- a/src/main/java/net/minecraft/world/level/block/Blocks.java +++ b/src/main/java/net/minecraft/world/level/block/Blocks.java -@@ -1087,8 +1087,8 @@ public class Blocks { - public static final Block CAVE_VINES = register("cave_vines", new CaveVinesBlock(BlockBehaviour.Properties.of(Material.PLANT).randomTicks().noCollission().lightLevel(CaveVines.emission(14)).instabreak().sound(SoundType.CAVE_VINES))); - public static final Block CAVE_VINES_PLANT = register("cave_vines_plant", new CaveVinesPlantBlock(BlockBehaviour.Properties.of(Material.PLANT).noCollission().lightLevel(CaveVines.emission(14)).instabreak().sound(SoundType.CAVE_VINES))); - public static final Block SPORE_BLOSSOM = register("spore_blossom", new SporeBlossomBlock(BlockBehaviour.Properties.of(Material.PLANT).instabreak().noCollission().sound(SoundType.SPORE_BLOSSOM))); -- public static final Block AZALEA = register("azalea", new AzaleaBlock(BlockBehaviour.Properties.of(Material.PLANT).instabreak().sound(SoundType.AZALEA).noOcclusion())); -- public static final Block FLOWERING_AZALEA = register("flowering_azalea", new AzaleaBlock(BlockBehaviour.Properties.of(Material.PLANT).instabreak().sound(SoundType.FLOWERING_AZALEA).noOcclusion())); -+ public static final Block AZALEA = register("azalea", new AzaleaBlock(BlockBehaviour.Properties.of(Material.PLANT).randomTicks().instabreak().sound(SoundType.AZALEA).noOcclusion())); // Purpur -+ public static final Block FLOWERING_AZALEA = register("flowering_azalea", new AzaleaBlock(BlockBehaviour.Properties.of(Material.PLANT).randomTicks().instabreak().sound(SoundType.FLOWERING_AZALEA).noOcclusion())); // Purpur - public static final Block MOSS_CARPET = register("moss_carpet", new CarpetBlock(BlockBehaviour.Properties.of(Material.PLANT, MaterialColor.COLOR_GREEN).strength(0.1F).sound(SoundType.MOSS_CARPET))); - public static final Block PINK_PETALS = register("pink_petals", new PinkPetalsBlock(BlockBehaviour.Properties.of(Material.PLANT).noCollission().sound(SoundType.PINK_PETALS).requiredFeatures(FeatureFlags.UPDATE_1_20))); - public static final Block MOSS_BLOCK = register("moss_block", new MossBlock(BlockBehaviour.Properties.of(Material.MOSS, MaterialColor.COLOR_GREEN).strength(0.1F).sound(SoundType.MOSS))); -@@ -1153,7 +1153,7 @@ public class Blocks { +@@ -1093,8 +1093,8 @@ public class Blocks { + public static final Block CAVE_VINES = register("cave_vines", new CaveVinesBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).randomTicks().noCollission().lightLevel(CaveVines.emission(14)).instabreak().sound(SoundType.CAVE_VINES).pushReaction(PushReaction.DESTROY))); + public static final Block CAVE_VINES_PLANT = register("cave_vines_plant", new CaveVinesPlantBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).noCollission().lightLevel(CaveVines.emission(14)).instabreak().sound(SoundType.CAVE_VINES).pushReaction(PushReaction.DESTROY))); + public static final Block SPORE_BLOSSOM = register("spore_blossom", new SporeBlossomBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).instabreak().noCollission().sound(SoundType.SPORE_BLOSSOM).pushReaction(PushReaction.DESTROY))); +- public static final Block AZALEA = register("azalea", new AzaleaBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).forceSolidOff().instabreak().sound(SoundType.AZALEA).noOcclusion().pushReaction(PushReaction.DESTROY))); +- public static final Block FLOWERING_AZALEA = register("flowering_azalea", new AzaleaBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).forceSolidOff().instabreak().sound(SoundType.FLOWERING_AZALEA).noOcclusion().pushReaction(PushReaction.DESTROY))); ++ public static final Block AZALEA = register("azalea", new AzaleaBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).forceSolidOff().randomTicks().instabreak().sound(SoundType.AZALEA).noOcclusion().pushReaction(PushReaction.DESTROY))); // Purpur ++ public static final Block FLOWERING_AZALEA = register("flowering_azalea", new AzaleaBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).forceSolidOff().randomTicks().instabreak().sound(SoundType.FLOWERING_AZALEA).noOcclusion().pushReaction(PushReaction.DESTROY))); // Purpur + public static final Block MOSS_CARPET = register("moss_carpet", new CarpetBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_GREEN).strength(0.1F).sound(SoundType.MOSS_CARPET).pushReaction(PushReaction.DESTROY))); + public static final Block PINK_PETALS = register("pink_petals", new PinkPetalsBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).noCollission().sound(SoundType.PINK_PETALS).pushReaction(PushReaction.DESTROY))); + public static final Block MOSS_BLOCK = register("moss_block", new MossBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_GREEN).strength(0.1F).sound(SoundType.MOSS).pushReaction(PushReaction.DESTROY))); +@@ -1159,7 +1159,7 @@ public class Blocks { } private static Boolean ocelotOrParrot(BlockState state, BlockGetter world, BlockPos pos, EntityType type) { @@ -17865,25 +18078,6 @@ index f148c7d2954cc17377d0da4af03ea2c1c9397a52..4afc4670f9b00a4087410ec366fe45fe } private static BedBlock bed(DyeColor color) { -diff --git a/src/main/java/net/minecraft/world/level/block/BuddingAmethystBlock.java b/src/main/java/net/minecraft/world/level/block/BuddingAmethystBlock.java -index bedccb8717d08d5a60058445b04ddff149e7d36c..5293ffca3da94c9c485a87d1232b6a902fcafd6a 100644 ---- a/src/main/java/net/minecraft/world/level/block/BuddingAmethystBlock.java -+++ b/src/main/java/net/minecraft/world/level/block/BuddingAmethystBlock.java -@@ -53,4 +53,14 @@ public class BuddingAmethystBlock extends AmethystBlock { - public static boolean canClusterGrowAtState(BlockState state) { - return state.isAir() || state.is(Blocks.WATER) && state.getFluidState().getAmount() == 8; - } -+ -+ // Purpur start -+ @Override -+ public void playerDestroy(net.minecraft.world.level.Level level, net.minecraft.world.entity.player.Player player, BlockPos pos, BlockState state, net.minecraft.world.level.block.entity.BlockEntity blockEntity, net.minecraft.world.item.ItemStack stack) { -+ if (level.purpurConfig.buddingAmethystSilkTouch && net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.SILK_TOUCH, stack) > 0) { -+ popResource(level, pos, net.minecraft.world.item.Items.BUDDING_AMETHYST.getDefaultInstance()); -+ } -+ super.playerDestroy(level, player, pos, state, blockEntity, stack); -+ } -+ // Purpur end - } diff --git a/src/main/java/net/minecraft/world/level/block/BushBlock.java b/src/main/java/net/minecraft/world/level/block/BushBlock.java index 03fde6e47c4a347c62fe9b4a3351769aedf874f6..ca906b0250e5332f7ececf1419ca6d2c1d385adc 100644 --- a/src/main/java/net/minecraft/world/level/block/BushBlock.java @@ -17914,7 +18108,7 @@ index 03fde6e47c4a347c62fe9b4a3351769aedf874f6..ca906b0250e5332f7ececf1419ca6d2c + // Purpur end } diff --git a/src/main/java/net/minecraft/world/level/block/CactusBlock.java b/src/main/java/net/minecraft/world/level/block/CactusBlock.java -index 7579946ce222b6ab3685a7fd9821bcd5a4babe33..ae2ac1c24c1e502a1968a3008273096281d5f1ca 100644 +index 0003fb51ae3a6575575e10b4c86719f3061e2577..0d5f87d24231f6d2b8639825bcd62dd2f8791c8e 100644 --- a/src/main/java/net/minecraft/world/level/block/CactusBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CactusBlock.java @@ -22,7 +22,7 @@ import net.minecraft.world.phys.shapes.CollisionContext; @@ -17926,16 +18120,16 @@ index 7579946ce222b6ab3685a7fd9821bcd5a4babe33..ae2ac1c24c1e502a1968a30082730962 public static final IntegerProperty AGE = BlockStateProperties.AGE_15; public static final int MAX_AGE = 15; -@@ -109,7 +109,7 @@ public class CactusBlock extends Block { - BlockState iblockdata2 = world.getBlockState(pos.relative(enumdirection)); +@@ -107,7 +107,7 @@ public class CactusBlock extends Block { - material = iblockdata2.getMaterial(); -- } while (!material.isSolid() && !world.getFluidState(pos.relative(enumdirection)).is(FluidTags.LAVA)); -+ } while ((!world.getWorldBorder().world.purpurConfig.cactusBreaksFromSolidNeighbors || !material.isSolid()) && !world.getFluidState(pos.relative(enumdirection)).is(FluidTags.LAVA)); // Purpur + enumdirection = (Direction) iterator.next(); + iblockdata1 = world.getBlockState(pos.relative(enumdirection)); +- } while (!iblockdata1.isSolid() && !world.getFluidState(pos.relative(enumdirection)).is(FluidTags.LAVA)); ++ } while ((!world.getWorldBorder().world.purpurConfig.cactusBreaksFromSolidNeighbors || !iblockdata1.isSolid()) && !world.getFluidState(pos.relative(enumdirection)).is(FluidTags.LAVA)); // Purpur return false; } -@@ -131,4 +131,34 @@ public class CactusBlock extends Block { +@@ -129,4 +129,34 @@ public class CactusBlock extends Block { public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type) { return false; } @@ -17984,10 +18178,10 @@ index 219c87dcf065e86512f330fbeec59e55f4675083..f8fd3b320494d1c1e8ee3d170f2feebd @Override diff --git a/src/main/java/net/minecraft/world/level/block/CarvedPumpkinBlock.java b/src/main/java/net/minecraft/world/level/block/CarvedPumpkinBlock.java -index 05112bc416019daba885a3de1b7f96177665135f..32d7ae44dd4e4987b1085f08cb30a92937e57226 100644 +index 23c487e295b3b736d8800f0c884324c9b18a5373..ebeb7caf7fd4f45714bab0856a48b847a544cce7 100644 --- a/src/main/java/net/minecraft/world/level/block/CarvedPumpkinBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CarvedPumpkinBlock.java -@@ -69,7 +69,7 @@ public class CarvedPumpkinBlock extends HorizontalDirectionalBlock implements Eq +@@ -64,7 +64,7 @@ public class CarvedPumpkinBlock extends HorizontalDirectionalBlock { SnowGolem entitysnowman = (SnowGolem) EntityType.SNOW_GOLEM.create(world); if (entitysnowman != null) { @@ -17996,7 +18190,7 @@ index 05112bc416019daba885a3de1b7f96177665135f..32d7ae44dd4e4987b1085f08cb30a929 } } else { BlockPattern.BlockPatternMatch shapedetector_shapedetectorcollection1 = this.getOrCreateIronGolemFull().find(world, pos); -@@ -79,7 +79,7 @@ public class CarvedPumpkinBlock extends HorizontalDirectionalBlock implements Eq +@@ -74,7 +74,7 @@ public class CarvedPumpkinBlock extends HorizontalDirectionalBlock { if (entityirongolem != null) { entityirongolem.setPlayerCreated(true); @@ -18005,7 +18199,7 @@ index 05112bc416019daba885a3de1b7f96177665135f..32d7ae44dd4e4987b1085f08cb30a929 } } } -@@ -87,6 +87,16 @@ public class CarvedPumpkinBlock extends HorizontalDirectionalBlock implements Eq +@@ -82,6 +82,16 @@ public class CarvedPumpkinBlock extends HorizontalDirectionalBlock { } private static void spawnGolemInWorld(Level world, BlockPattern.BlockPatternMatch patternResult, Entity entity, BlockPos pos) { @@ -18063,31 +18257,11 @@ index 5e22d175b1048a58802cdf64ac70a8b56329e915..d81946b400f208c39941128ce823ff77 BlockPos blockposition1 = pos.above(); return world.getBlockState(blockposition1).isRedstoneConductor(world, blockposition1); -diff --git a/src/main/java/net/minecraft/world/level/block/ChorusPlantBlock.java b/src/main/java/net/minecraft/world/level/block/ChorusPlantBlock.java -index a6c25647fb37f59307de0d390f8e8cf55504d7d3..52aae8bd4023b2bb48f12983f54b20fa3c95d403 100644 ---- a/src/main/java/net/minecraft/world/level/block/ChorusPlantBlock.java -+++ b/src/main/java/net/minecraft/world/level/block/ChorusPlantBlock.java -@@ -21,6 +21,7 @@ public class ChorusPlantBlock extends PipeBlock { - - @Override - public BlockState getStateForPlacement(BlockPlaceContext ctx) { -+ if (org.purpurmc.purpur.PurpurConfig.disableChorusPlantUpdates) return this.defaultBlockState(); // Purpur - return this.getStateForPlacement(ctx.getLevel(), ctx.getClickedPos()); - } - -@@ -36,6 +37,7 @@ public class ChorusPlantBlock extends PipeBlock { - - @Override - public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { -+ if (org.purpurmc.purpur.PurpurConfig.disableChorusPlantUpdates) return state; // Purpur - if (!state.canSurvive(world, pos)) { - world.scheduleTick(pos, this, 1); - return super.updateShape(state, direction, neighborState, world, pos, neighborPos); diff --git a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java -index 6fab2b69a0af298bd00b309efcd6aa8399e23d1f..4f7b21caa123ea7896788fd25133d8de3ab1ccaf 100644 +index 10d3912ef043eefdf89105332e29b0d2bf4a5539..596b77306f690a2298835f0f0fea1abee2a7c85d 100644 --- a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java -@@ -228,20 +228,28 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { +@@ -229,20 +229,28 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { ItemStack itemstack = player.getItemInHand(hand); if (i < 8 && ComposterBlock.COMPOSTABLES.containsKey(itemstack.getItem())) { @@ -18128,7 +18302,7 @@ index 6fab2b69a0af298bd00b309efcd6aa8399e23d1f..4f7b21caa123ea7896788fd25133d8de return InteractionResult.sidedSuccess(world.isClientSide); } else if (i == 8) { -@@ -252,6 +260,26 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { +@@ -253,6 +261,26 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { } } @@ -18168,15 +18342,15 @@ index 88faea00be60a519f56f975a5311df5e1eb3e6b8..cbb726ac367be81e27d3a86643baf7c4 int i = aenumdirection.length; diff --git a/src/main/java/net/minecraft/world/level/block/CropBlock.java b/src/main/java/net/minecraft/world/level/block/CropBlock.java -index a140fed067e7e6c1c42e111f47d3678863ef95ce..3415cbb1def0700b5998a8a1db2e48146f4c2c1e 100644 +index decb8caa67bc5f4525e4d92fedf465a17171fceb..26b3f162f25bed3e9d8001e3d9c2f8d7d4b3e08a 100644 --- a/src/main/java/net/minecraft/world/level/block/CropBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CropBlock.java @@ -168,7 +168,7 @@ public class CropBlock extends BushBlock implements BonemealableBlock { @Override public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper -- if (entity instanceof Ravager && !CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)).isCancelled()) { // CraftBukkit -+ if (entity instanceof Ravager && world.purpurConfig.ravagerGriefableBlocks.contains(world.getBlockState(pos).getBlock()) && !CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), (!world.purpurConfig.ravagerBypassMobGriefing && !world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))).isCancelled()) { // CraftBukkit // Purpur +- if (entity instanceof Ravager && CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit ++ if (entity instanceof Ravager && world.purpurConfig.ravagerGriefableBlocks.contains(world.getBlockState(pos).getBlock()) && CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), (!world.purpurConfig.ravagerBypassMobGriefing && !world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)))) { // CraftBukkit // Purpur world.destroyBlock(pos, true, entity); } @@ -18187,30 +18361,30 @@ index a140fed067e7e6c1c42e111f47d3678863ef95ce..3415cbb1def0700b5998a8a1db2e4814 + + // Purpur start + @Override -+ public void playerDestroy(Level world, net.minecraft.world.entity.player.Player player, BlockPos pos, BlockState state, @javax.annotation.Nullable net.minecraft.world.level.block.entity.BlockEntity blockEntity, ItemStack itemInHand) { ++ public void playerDestroy(Level world, net.minecraft.world.entity.player.Player player, BlockPos pos, BlockState state, @javax.annotation.Nullable net.minecraft.world.level.block.entity.BlockEntity blockEntity, ItemStack itemInHand, boolean includeDrops) { + if (world.purpurConfig.hoeReplantsCrops && itemInHand.getItem() instanceof net.minecraft.world.item.HoeItem) { + super.playerDestroyAndReplant(world, player, pos, state, blockEntity, itemInHand, getBaseSeedId()); + } else { -+ super.playerDestroy(world, player, pos, state, blockEntity, itemInHand); ++ super.playerDestroy(world, player, pos, state, blockEntity, itemInHand, includeDrops); + } + } + // Purpur end } diff --git a/src/main/java/net/minecraft/world/level/block/DoorBlock.java b/src/main/java/net/minecraft/world/level/block/DoorBlock.java -index 5ba56ee7d5dd210770e6703be559055d218028d5..b5e90dc00240bccf1a6eca342729a4f4165e22bf 100644 +index c028a7158e41a0754abb8e24dcd647633fbf3fe8..cd65d32f4af016d4937e598c71386a3072f4c490 100644 --- a/src/main/java/net/minecraft/world/level/block/DoorBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DoorBlock.java -@@ -165,6 +165,7 @@ public class DoorBlock extends Block { +@@ -167,6 +167,7 @@ public class DoorBlock extends Block { public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { - if (this.material == Material.METAL) { + if (!this.type.canOpenByHand()) { return InteractionResult.PASS; + } else if (requiresRedstone(world, state, pos)) { return InteractionResult.CONSUME; // Purpur } else { state = (BlockState) state.cycle(DoorBlock.OPEN); world.setBlock(pos, state, 10); -@@ -260,4 +261,18 @@ public class DoorBlock extends Block { - public static boolean isWoodenDoor(BlockState state) { - return state.getBlock() instanceof DoorBlock && (state.getMaterial() == Material.WOOD || state.getMaterial() == Material.NETHER_WOOD); +@@ -270,4 +271,18 @@ public class DoorBlock extends Block { + flag = false; + return flag; } + + // Purpur start @@ -18242,10 +18416,10 @@ index 7e1edcc7b9f170b7c649437c2f0dd78c0bab9be4..5f8ac1fdac2c334951261f2b9702f5e7 BlockPos blockposition1 = pos.offset(world.random.nextInt(16) - world.random.nextInt(16), world.random.nextInt(8) - world.random.nextInt(8), world.random.nextInt(16) - world.random.nextInt(16)); diff --git a/src/main/java/net/minecraft/world/level/block/EnchantmentTableBlock.java b/src/main/java/net/minecraft/world/level/block/EnchantmentTableBlock.java -index f4ee3ce287528337a0f9a3b612c157254f895a58..c4a91d7f1320027ee6a2b364303c01ebbacde584 100644 +index 839b7bc9392906dca384003468746963631fe095..286f34eef22a85be3fe9747dc3c3f9a7d51f437c 100644 --- a/src/main/java/net/minecraft/world/level/block/EnchantmentTableBlock.java +++ b/src/main/java/net/minecraft/world/level/block/EnchantmentTableBlock.java -@@ -28,6 +28,8 @@ import net.minecraft.world.level.pathfinder.PathComputationType; +@@ -29,6 +29,8 @@ import net.minecraft.world.level.pathfinder.PathComputationType; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; @@ -18254,18 +18428,7 @@ index f4ee3ce287528337a0f9a3b612c157254f895a58..c4a91d7f1320027ee6a2b364303c01eb public class EnchantmentTableBlock extends BaseEntityBlock { protected static final VoxelShape SHAPE = Block.box(0.0D, 0.0D, 0.0D, 16.0D, 12.0D, 16.0D); -@@ -40,6 +42,10 @@ public class EnchantmentTableBlock extends BaseEntityBlock { - } - - public static boolean isValidBookShelf(Level world, BlockPos tablePos, BlockPos bookshelfOffset) { -+ // Purpur Start -+ if(org.purpurmc.purpur.PurpurConfig.allowTransparentBlocksInEnchantmentBox){ -+ return world.getBlockState(tablePos.offset(bookshelfOffset)).is(Blocks.BOOKSHELF) && !world.getBlockState(tablePos.offset(bookshelfOffset.getX() / 2, bookshelfOffset.getY(), bookshelfOffset.getZ() / 2)).isSuffocating(world, bookshelfOffset); -+ } // Purpur end - return world.getBlockState(tablePos.offset(bookshelfOffset)).is(Blocks.BOOKSHELF) && world.isEmptyBlock(tablePos.offset(bookshelfOffset.getX() / 2, bookshelfOffset.getY(), bookshelfOffset.getZ() / 2)); - } - -@@ -120,4 +126,18 @@ public class EnchantmentTableBlock extends BaseEntityBlock { +@@ -121,4 +123,18 @@ public class EnchantmentTableBlock extends BaseEntityBlock { public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type) { return false; } @@ -18327,10 +18490,10 @@ index 41d7cff39fc37955877668337689b4b26cd8c7cf..2deddc746e43896584bd65ba8e7971a8 entity.portalWorld = ((ServerLevel)world); entity.portalBlock = pos.immutable(); diff --git a/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java b/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java -index 7385e91f32f070e86a4e0fd3d214f55d832c7979..c3b78dd2d06be7d64920c6bcffcd16c82caa52b4 100644 +index 7385e91f32f070e86a4e0fd3d214f55d832c7979..7b73de87236a60ce7343c29ec147e1866b448ba3 100644 --- a/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java +++ b/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java -@@ -85,6 +85,27 @@ public class EnderChestBlock extends AbstractChestBlock i +@@ -85,6 +85,34 @@ public class EnderChestBlock extends AbstractChestBlock i EnderChestBlockEntity enderChestBlockEntity = (EnderChestBlockEntity)blockEntity; playerEnderChestContainer.setActiveChest(enderChestBlockEntity); player.openMenu(new SimpleMenuProvider((syncId, inventory, playerx) -> { @@ -18339,19 +18502,26 @@ index 7385e91f32f070e86a4e0fd3d214f55d832c7979..c3b78dd2d06be7d64920c6bcffcd16c8 + if (org.purpurmc.purpur.PurpurConfig.enderChestPermissionRows) { + org.bukkit.craftbukkit.entity.CraftHumanEntity bukkitPlayer = player.getBukkitEntity(); + if (bukkitPlayer.hasPermission("purpur.enderchest.rows.six")) { ++ player.sixRowEnderchestSlotCount = 54; + return ChestMenu.sixRows(syncId, inventory, playerEnderChestContainer); + } else if (bukkitPlayer.hasPermission("purpur.enderchest.rows.five")) { ++ player.sixRowEnderchestSlotCount = 45; + return ChestMenu.fiveRows(syncId, inventory, playerEnderChestContainer); + } else if (bukkitPlayer.hasPermission("purpur.enderchest.rows.four")) { ++ player.sixRowEnderchestSlotCount = 36; + return ChestMenu.fourRows(syncId, inventory, playerEnderChestContainer); + } else if (bukkitPlayer.hasPermission("purpur.enderchest.rows.three")) { ++ player.sixRowEnderchestSlotCount = 27; + return ChestMenu.threeRows(syncId, inventory, playerEnderChestContainer); + } else if (bukkitPlayer.hasPermission("purpur.enderchest.rows.two")) { ++ player.sixRowEnderchestSlotCount = 18; + return ChestMenu.twoRows(syncId, inventory, playerEnderChestContainer); + } else if (bukkitPlayer.hasPermission("purpur.enderchest.rows.one")) { ++ player.sixRowEnderchestSlotCount = 9; + return ChestMenu.oneRow(syncId, inventory, playerEnderChestContainer); + } + } ++ player.sixRowEnderchestSlotCount = -1; + return ChestMenu.sixRows(syncId, inventory, playerEnderChestContainer); + } + // Purpur end @@ -18359,10 +18529,10 @@ index 7385e91f32f070e86a4e0fd3d214f55d832c7979..c3b78dd2d06be7d64920c6bcffcd16c8 }, CONTAINER_TITLE)); player.awardStat(Stats.OPEN_ENDERCHEST); diff --git a/src/main/java/net/minecraft/world/level/block/FarmBlock.java b/src/main/java/net/minecraft/world/level/block/FarmBlock.java -index 34d744837e599633a3c2c0b72f253bb0e157f226..69cc276fecd4cac51d38bd3cc7de490ad0ae8ace 100644 +index 5946f06f63b5694034bd027984a4925b0831d439..d566f67f8f6f1748023430de4f191881b79e44a1 100644 --- a/src/main/java/net/minecraft/world/level/block/FarmBlock.java +++ b/src/main/java/net/minecraft/world/level/block/FarmBlock.java -@@ -100,7 +100,7 @@ public class FarmBlock extends Block { +@@ -101,7 +101,7 @@ public class FarmBlock extends Block { @Override public void fallOn(Level world, BlockState state, BlockPos pos, Entity entity, float fallDistance) { super.fallOn(world, state, pos, entity, fallDistance); // CraftBukkit - moved here as game rules / events shouldn't affect fall damage. @@ -18371,7 +18541,7 @@ index 34d744837e599633a3c2c0b72f253bb0e157f226..69cc276fecd4cac51d38bd3cc7de490a // CraftBukkit start - Interact soil org.bukkit.event.Cancellable cancellable; if (entity instanceof Player) { -@@ -114,6 +114,22 @@ public class FarmBlock extends Block { +@@ -115,6 +115,22 @@ public class FarmBlock extends Block { return; } @@ -18391,10 +18561,10 @@ index 34d744837e599633a3c2c0b72f253bb0e157f226..69cc276fecd4cac51d38bd3cc7de490a + } + } + // Purpur end - if (CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.DIRT.defaultBlockState()).isCancelled()) { + if (!CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.DIRT.defaultBlockState())) { return; } -@@ -163,7 +179,7 @@ public class FarmBlock extends Block { +@@ -162,7 +178,7 @@ public class FarmBlock extends Block { } } @@ -18480,85 +18650,11 @@ index cfbe1dae76db76cf54a4f5d72aca72d5e893859e..74cb10230d459ac9f300a9d59af504d2 + super.fallOn(world, state, pos, entity, fallDistance); // Purpur } } -diff --git a/src/main/java/net/minecraft/world/level/block/HugeMushroomBlock.java b/src/main/java/net/minecraft/world/level/block/HugeMushroomBlock.java -index 3c6d97b51c6fec130b80e5965afa2c49d48843c9..b456cb8efd8f0be8a6860c82462ce9bdde3a8383 100644 ---- a/src/main/java/net/minecraft/world/level/block/HugeMushroomBlock.java -+++ b/src/main/java/net/minecraft/world/level/block/HugeMushroomBlock.java -@@ -22,29 +22,65 @@ public class HugeMushroomBlock extends Block { - - public HugeMushroomBlock(BlockBehaviour.Properties settings) { - super(settings); -- this.registerDefaultState(this.stateDefinition.any().setValue(NORTH, Boolean.valueOf(true)).setValue(EAST, Boolean.valueOf(true)).setValue(SOUTH, Boolean.valueOf(true)).setValue(WEST, Boolean.valueOf(true)).setValue(UP, Boolean.valueOf(true)).setValue(DOWN, Boolean.valueOf(true))); -+ // Purpur start -+ this.registerDefaultState(this.stateDefinition.any() -+ .setValue(NORTH, true) -+ .setValue(EAST, true) -+ .setValue(SOUTH, true) -+ .setValue(WEST, true) -+ .setValue(UP, true) -+ .setValue(DOWN, true)); -+ // Purpur end - } - - @Override - public BlockState getStateForPlacement(BlockPlaceContext ctx) { -+ if (org.purpurmc.purpur.PurpurConfig.disableMushroomBlockUpdates) return this.defaultBlockState(); // Purpur - BlockGetter blockGetter = ctx.getLevel(); - BlockPos blockPos = ctx.getClickedPos(); -- return this.defaultBlockState().setValue(DOWN, Boolean.valueOf(!blockGetter.getBlockState(blockPos.below()).is(this))).setValue(UP, Boolean.valueOf(!blockGetter.getBlockState(blockPos.above()).is(this))).setValue(NORTH, Boolean.valueOf(!blockGetter.getBlockState(blockPos.north()).is(this))).setValue(EAST, Boolean.valueOf(!blockGetter.getBlockState(blockPos.east()).is(this))).setValue(SOUTH, Boolean.valueOf(!blockGetter.getBlockState(blockPos.south()).is(this))).setValue(WEST, Boolean.valueOf(!blockGetter.getBlockState(blockPos.west()).is(this))); -+ // Purpur start -+ return this.defaultBlockState() -+ .setValue(DOWN, this != blockGetter.getBlockStateIfLoaded(blockPos.below()).getBlock()) -+ .setValue(UP, this != blockGetter.getBlockStateIfLoaded(blockPos.above()).getBlock()) -+ .setValue(NORTH, this != blockGetter.getBlockStateIfLoaded(blockPos.north()).getBlock()) -+ .setValue(EAST, this != blockGetter.getBlockStateIfLoaded(blockPos.east()).getBlock()) -+ .setValue(SOUTH, this != blockGetter.getBlockStateIfLoaded(blockPos.south()).getBlock()) -+ .setValue(WEST, this != blockGetter.getBlockStateIfLoaded(blockPos.west()).getBlock()); -+ // Purpur end - } - - @Override - public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { -+ if (org.purpurmc.purpur.PurpurConfig.disableMushroomBlockUpdates) return state; // Purpur - return neighborState.is(this) ? state.setValue(PROPERTY_BY_DIRECTION.get(direction), Boolean.valueOf(false)) : super.updateShape(state, direction, neighborState, world, pos, neighborPos); - } - - @Override - public BlockState rotate(BlockState state, Rotation rotation) { -- return state.setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.NORTH)), state.getValue(NORTH)).setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.SOUTH)), state.getValue(SOUTH)).setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.EAST)), state.getValue(EAST)).setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.WEST)), state.getValue(WEST)).setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.UP)), state.getValue(UP)).setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.DOWN)), state.getValue(DOWN)); -+ // Purpur start -+ if (org.purpurmc.purpur.PurpurConfig.disableMushroomBlockUpdates) return state; -+ return state -+ .setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.NORTH)), state.getValue(NORTH)) -+ .setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.SOUTH)), state.getValue(SOUTH)) -+ .setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.EAST)), state.getValue(EAST)) -+ .setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.WEST)), state.getValue(NORTH)) -+ .setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.UP)), state.getValue(UP)) -+ .setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.DOWN)), state.getValue(DOWN)); -+ // Purpur end - } - - @Override - public BlockState mirror(BlockState state, Mirror mirror) { -- return state.setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.NORTH)), state.getValue(NORTH)).setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.SOUTH)), state.getValue(SOUTH)).setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.EAST)), state.getValue(EAST)).setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.WEST)), state.getValue(WEST)).setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.UP)), state.getValue(UP)).setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.DOWN)), state.getValue(DOWN)); -+ // Purpur start -+ if (org.purpurmc.purpur.PurpurConfig.disableMushroomBlockUpdates) return state; -+ return state -+ .setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.NORTH)), state.getValue(NORTH)) -+ .setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.SOUTH)), state.getValue(SOUTH)) -+ .setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.EAST)), state.getValue(EAST)) -+ .setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.WEST)), state.getValue(NORTH)) -+ .setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.UP)), state.getValue(UP)) -+ .setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.DOWN)), state.getValue(DOWN)); -+ // Purpur end - } - - @Override diff --git a/src/main/java/net/minecraft/world/level/block/IceBlock.java b/src/main/java/net/minecraft/world/level/block/IceBlock.java -index 5ecf02ce83b7496c977adfeb203b8eadb05f9da5..bf7f1ac5c691c0c4c30c124970f4b08a8108ad34 100644 +index 04089e6f7d6e3d532b00585870283922b6be5246..61e6d14abd54ecd5e43a5459f8daa7d86adedf44 100644 --- a/src/main/java/net/minecraft/world/level/block/IceBlock.java +++ b/src/main/java/net/minecraft/world/level/block/IceBlock.java -@@ -31,7 +31,7 @@ public class IceBlock extends HalfTransparentBlock { +@@ -33,7 +33,7 @@ public class IceBlock extends HalfTransparentBlock { public void afterDestroy(Level world, BlockPos pos, ItemStack tool) { // Paper end if (EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) == 0) { @@ -18567,7 +18663,7 @@ index 5ecf02ce83b7496c977adfeb203b8eadb05f9da5..bf7f1ac5c691c0c4c30c124970f4b08a world.removeBlock(pos, false); return; } -@@ -59,7 +59,7 @@ public class IceBlock extends HalfTransparentBlock { +@@ -61,7 +61,7 @@ public class IceBlock extends HalfTransparentBlock { return; } // CraftBukkit end @@ -18575,7 +18671,7 @@ index 5ecf02ce83b7496c977adfeb203b8eadb05f9da5..bf7f1ac5c691c0c4c30c124970f4b08a + if (world.isNether() || (world.isTheEnd() && !org.purpurmc.purpur.PurpurConfig.allowWaterPlacementInTheEnd)) { // Purpur world.removeBlock(pos, false); } else { - world.setBlockAndUpdate(pos, Blocks.WATER.defaultBlockState()); + world.setBlockAndUpdate(pos, IceBlock.meltsInto()); diff --git a/src/main/java/net/minecraft/world/level/block/KelpBlock.java b/src/main/java/net/minecraft/world/level/block/KelpBlock.java index bc66fa91ec3e13431d5d9b6e17935cab73066be7..0f16b5ed2e249f3d8f583dc941e32066d354cf95 100644 --- a/src/main/java/net/minecraft/world/level/block/KelpBlock.java @@ -18593,7 +18689,7 @@ index bc66fa91ec3e13431d5d9b6e17935cab73066be7..0f16b5ed2e249f3d8f583dc941e32066 + // Purpur end } diff --git a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java b/src/main/java/net/minecraft/world/level/block/LiquidBlock.java -index 43e8ef1d6a65d4fd3fe53a587639ffb814368217..9c22a730772f71b34c63d1e43d48943f71e9990b 100644 +index bbabe4ad8afcc3a2069f6e9d4a9adcb643266894..55419bd653f7f5391fa13cd15a0b00fbff5e9c39 100644 --- a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java +++ b/src/main/java/net/minecraft/world/level/block/LiquidBlock.java @@ -105,7 +105,7 @@ public class LiquidBlock extends Block implements BucketPickup { @@ -18605,7 +18701,7 @@ index 43e8ef1d6a65d4fd3fe53a587639ffb814368217..9c22a730772f71b34c63d1e43d48943f world.scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper } -@@ -129,7 +129,7 @@ public class LiquidBlock extends Block implements BucketPickup { +@@ -133,7 +133,7 @@ public class LiquidBlock extends Block implements BucketPickup { @Override public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { @@ -18614,7 +18710,7 @@ index 43e8ef1d6a65d4fd3fe53a587639ffb814368217..9c22a730772f71b34c63d1e43d48943f world.scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay(world)); } -@@ -138,7 +138,7 @@ public class LiquidBlock extends Block implements BucketPickup { +@@ -142,7 +142,7 @@ public class LiquidBlock extends Block implements BucketPickup { @Override public void neighborChanged(BlockState state, Level world, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) { @@ -18624,10 +18720,10 @@ index 43e8ef1d6a65d4fd3fe53a587639ffb814368217..9c22a730772f71b34c63d1e43d48943f } diff --git a/src/main/java/net/minecraft/world/level/block/MagmaBlock.java b/src/main/java/net/minecraft/world/level/block/MagmaBlock.java -index 12ffb5714f088f4aeafa1ad6a36f5b64a86c4c96..293aa5c8f91a997045f8d9f2951fe3a7f01f0642 100644 +index 1b766045687e4dcded5cbcc50b746c55b9a34e22..be365914856593bb3c4e1945cc990786072f2953 100644 --- a/src/main/java/net/minecraft/world/level/block/MagmaBlock.java +++ b/src/main/java/net/minecraft/world/level/block/MagmaBlock.java -@@ -27,7 +27,7 @@ public class MagmaBlock extends Block { +@@ -22,7 +22,7 @@ public class MagmaBlock extends Block { @Override public void stepOn(Level world, BlockPos pos, BlockState state, Entity entity) { @@ -18665,7 +18761,7 @@ index a6ab0d0defc05e56a91084c49897059670a1324b..589b437e7c97c846410f293e2f014bdc EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ())); world.getCraftServer().getPluginManager().callEvent(event); diff --git a/src/main/java/net/minecraft/world/level/block/NetherWartBlock.java b/src/main/java/net/minecraft/world/level/block/NetherWartBlock.java -index e55720c4d2fbdf6aae526910e87a67c29cf906fd..bf4485b4cad324d5aace657ebf284c4d97197f53 100644 +index e55720c4d2fbdf6aae526910e87a67c29cf906fd..4310d62c45c776eea81987809309da08c242c7b0 100644 --- a/src/main/java/net/minecraft/world/level/block/NetherWartBlock.java +++ b/src/main/java/net/minecraft/world/level/block/NetherWartBlock.java @@ -14,7 +14,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; @@ -18684,11 +18780,11 @@ index e55720c4d2fbdf6aae526910e87a67c29cf906fd..bf4485b4cad324d5aace657ebf284c4d + + // Purpur start + @Override -+ public void playerDestroy(net.minecraft.world.level.Level world, net.minecraft.world.entity.player.Player player, BlockPos pos, BlockState state, @javax.annotation.Nullable net.minecraft.world.level.block.entity.BlockEntity blockEntity, ItemStack itemInHand) { ++ public void playerDestroy(net.minecraft.world.level.Level world, net.minecraft.world.entity.player.Player player, BlockPos pos, BlockState state, @javax.annotation.Nullable net.minecraft.world.level.block.entity.BlockEntity blockEntity, ItemStack itemInHand, boolean includeDrops) { + if (world.purpurConfig.hoeReplantsNetherWarts && itemInHand.getItem() instanceof net.minecraft.world.item.HoeItem) { + super.playerDestroyAndReplant(world, player, pos, state, blockEntity, itemInHand, Items.NETHER_WART); + } else { -+ super.playerDestroy(world, player, pos, state, blockEntity, itemInHand); ++ super.playerDestroy(world, player, pos, state, blockEntity, itemInHand, includeDrops); + } + } + @@ -18711,36 +18807,15 @@ index e55720c4d2fbdf6aae526910e87a67c29cf906fd..bf4485b4cad324d5aace657ebf284c4d + // Purpur end } diff --git a/src/main/java/net/minecraft/world/level/block/NoteBlock.java b/src/main/java/net/minecraft/world/level/block/NoteBlock.java -index a9c2d254bda5686a35ad2393534b85030dd8b136..c11752564ea48960232844ee735779aa95d82c12 100644 +index e46d84750bdd7c940f400efda226e12a3fdc3848..6343cd0c33cafb30225cfae17ea1cf15859073b1 100644 --- a/src/main/java/net/minecraft/world/level/block/NoteBlock.java +++ b/src/main/java/net/minecraft/world/level/block/NoteBlock.java -@@ -62,11 +62,13 @@ public class NoteBlock extends Block { - - @Override - public BlockState getStateForPlacement(BlockPlaceContext ctx) { -+ if (org.purpurmc.purpur.PurpurConfig.disableNoteBlockUpdates) return this.defaultBlockState(); // Purpur - return this.setInstrument(ctx.getLevel(), ctx.getClickedPos(), this.defaultBlockState()); - } - - @Override - public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { -+ if (org.purpurmc.purpur.PurpurConfig.disableNoteBlockUpdates) return state; // Purpur - boolean flag = NoteBlock.isFeatureFlagEnabled(world) ? direction.getAxis() == Direction.Axis.Y : direction == Direction.DOWN; - - return flag ? this.setInstrument(world, pos, state) : super.updateShape(state, direction, neighborState, world, pos, neighborPos); -@@ -82,13 +84,14 @@ public class NoteBlock extends Block { - state = world.getBlockState(pos); // CraftBukkit - SPIGOT-5617: update in case changed in event - } - -+ if (!org.purpurmc.purpur.PurpurConfig.disableNoteBlockUpdates) // Purpur - world.setBlock(pos, (BlockState) state.setValue(NoteBlock.POWERED, flag1), 3); - } - +@@ -87,7 +87,7 @@ public class NoteBlock extends Block { } private void playNote(@Nullable Entity entity, BlockState state, Level world, BlockPos pos) { -- if (!((NoteBlockInstrument) state.getValue(NoteBlock.INSTRUMENT)).requiresAirAbove() || world.getBlockState(pos.above()).isAir()) { -+ if (world.purpurConfig.noteBlockIgnoreAbove || !((NoteBlockInstrument) state.getValue(NoteBlock.INSTRUMENT)).requiresAirAbove() || world.getBlockState(pos.above()).isAir()) { // Purpur +- if (((NoteBlockInstrument) state.getValue(NoteBlock.INSTRUMENT)).worksAboveNoteBlock() || world.getBlockState(pos.above()).isAir()) { ++ if (world.purpurConfig.noteBlockIgnoreAbove || ((NoteBlockInstrument) state.getValue(NoteBlock.INSTRUMENT)).worksAboveNoteBlock() || world.getBlockState(pos.above()).isAir()) { // Purpur // CraftBukkit start // org.bukkit.event.block.NotePlayEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callNotePlayEvent(world, pos, state.getValue(NoteBlock.INSTRUMENT), state.getValue(NoteBlock.NOTE)); // if (event.isCancelled()) { @@ -18757,10 +18832,10 @@ index 7b45d6b9a005036ca5051d089a7be792eb87012f..8806c97ecc6bdd8a64c2d82bb2f58f46 } diff --git a/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java b/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java -index 6b909d41ccdf6c1ac3ac0c4e673ff52f0d14a238..b8f69063cec4d31c9d9525a04c46ed8904ceff76 100644 +index cd943997f11f5ea5c600fdc6db96043fb0fa713c..4adeda49a2e422e11f885bffb311653d99159bf4 100644 --- a/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java +++ b/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java -@@ -188,7 +188,7 @@ public class PointedDripstoneBlock extends Block implements Fallable, SimpleWate +@@ -186,7 +186,7 @@ public class PointedDripstoneBlock extends Block implements Fallable, SimpleWate @VisibleForTesting public static void maybeTransferFluid(BlockState state, ServerLevel world, BlockPos pos, float dripChance) { @@ -18769,7 +18844,7 @@ index 6b909d41ccdf6c1ac3ac0c4e673ff52f0d14a238..b8f69063cec4d31c9d9525a04c46ed89 if (PointedDripstoneBlock.isStalactiteStartPos(state, world, pos)) { Optional optional = PointedDripstoneBlock.getFluidAboveStalactite(world, pos, state); -@@ -197,13 +197,13 @@ public class PointedDripstoneBlock extends Block implements Fallable, SimpleWate +@@ -195,13 +195,13 @@ public class PointedDripstoneBlock extends Block implements Fallable, SimpleWate float f1; if (fluidtype == Fluids.WATER) { @@ -18786,15 +18861,15 @@ index 6b909d41ccdf6c1ac3ac0c4e673ff52f0d14a238..b8f69063cec4d31c9d9525a04c46ed89 if (dripChance < f1) { diff --git a/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java b/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java -index 518d3832c36c9ecf1ed9267ffc1f926dc84b7989..af5933b886abf3fd17bfdb8c1cb1ea63f6f2a757 100644 +index 7e04ecba2a14be0f0d47c917368abd2a2bd64a05..5c944e39e611201c6ae4dad14511a54c451204f6 100644 --- a/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java +++ b/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java @@ -72,7 +72,7 @@ public class PowderSnowBlock extends Block implements BucketPickup { if (!world.isClientSide) { // CraftBukkit start if (entity.isOnFire() && entity.mayInteract(world, pos)) { -- if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !(world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) || entity instanceof Player)).isCancelled()) { -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !((world.purpurConfig.powderSnowBypassMobGriefing || world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) || entity instanceof Player)).isCancelled()) { +- if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !(world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) || entity instanceof Player))) { ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !((world.purpurConfig.powderSnowBypassMobGriefing || world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) || entity instanceof Player))) { return; } // CraftBukkit end @@ -18825,7 +18900,7 @@ index 2ed78cf83c0ae66a6ddba1ff307da89a24b0d0a8..ae17d6a54fad0bd2d71d306f418b5ced public static boolean canSetSpawn(Level world) { diff --git a/src/main/java/net/minecraft/world/level/block/SculkShriekerBlock.java b/src/main/java/net/minecraft/world/level/block/SculkShriekerBlock.java -index 437b44fb68bcbe81d1c431689431225b6a17a1a6..06d091b7c4df949c4abda16c4f73c194a71a4669 100644 +index 02d01eabb9606ae8c3b76ad9fa4bb9a525e247b1..ce51fec4a874f9466f9966684c535315dbf40b9e 100644 --- a/src/main/java/net/minecraft/world/level/block/SculkShriekerBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SculkShriekerBlock.java @@ -130,7 +130,7 @@ public class SculkShriekerBlock extends BaseEntityBlock implements SimpleWaterlo @@ -18838,10 +18913,10 @@ index 437b44fb68bcbe81d1c431689431225b6a17a1a6..06d091b7c4df949c4abda16c4f73c194 @Override diff --git a/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java b/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java -index c89978ecbc5a13dda6f76ea6d1cc3056efc9a174..39868ad3ee4bb573a4dd562894d93f64be4ee5ac 100644 +index b51155ad12515b2d0dd0f202580b9f455c114d9a..dd6c82a418ee299d7a5614cb0260949c198b4149 100644 --- a/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java -@@ -138,7 +138,7 @@ public class ShulkerBoxBlock extends BaseEntityBlock { +@@ -137,7 +137,7 @@ public class ShulkerBoxBlock extends BaseEntityBlock { public void playerWillDestroy(Level world, BlockPos pos, BlockState state, Player player) { BlockEntity blockEntity = world.getBlockEntity(pos); if (blockEntity instanceof ShulkerBoxBlockEntity shulkerBoxBlockEntity) { @@ -18850,53 +18925,8 @@ index c89978ecbc5a13dda6f76ea6d1cc3056efc9a174..39868ad3ee4bb573a4dd562894d93f64 ItemStack itemStack = getColoredItemStack(this.getColor()); blockEntity.saveToItem(itemStack); if (shulkerBoxBlockEntity.hasCustomName()) { -diff --git a/src/main/java/net/minecraft/world/level/block/SignBlock.java b/src/main/java/net/minecraft/world/level/block/SignBlock.java -index aface9a9697095a29edaf73c9cdabc2c1414b9d7..1a04d0a601b8e481dd6e2592b849b907a5b9f63f 100644 ---- a/src/main/java/net/minecraft/world/level/block/SignBlock.java -+++ b/src/main/java/net/minecraft/world/level/block/SignBlock.java -@@ -14,6 +14,7 @@ import net.minecraft.world.item.DyeItem; - import net.minecraft.world.item.Item; - import net.minecraft.world.item.ItemStack; - import net.minecraft.world.item.Items; -+import net.minecraft.world.item.SignItem; - import net.minecraft.world.level.BlockGetter; - import net.minecraft.world.level.Level; - import net.minecraft.world.level.LevelAccessor; -@@ -76,11 +77,11 @@ public abstract class SignBlock extends BaseEntityBlock implements SimpleWaterlo - if (world.isClientSide) { - return bl4 ? InteractionResult.SUCCESS : InteractionResult.CONSUME; - } else { -- BlockEntity bl5 = world.getBlockEntity(pos); -- if (!(bl5 instanceof SignBlockEntity)) { -+ BlockEntity blockEntity = world.getBlockEntity(pos); // Purpur - decompile fix -+ if (!(blockEntity instanceof SignBlockEntity)) { // Purpur - decompile fix - return InteractionResult.PASS; - } else { -- SignBlockEntity signBlockEntity = (SignBlockEntity)bl5; -+ SignBlockEntity signBlockEntity = (SignBlockEntity)blockEntity; // Purpur - decompile fix - boolean bl5 = signBlockEntity.hasGlowingText(); - if ((!bl2 || !bl5) && (!bl3 || bl5)) { - if (bl4) { -@@ -108,6 +109,17 @@ public abstract class SignBlock extends BaseEntityBlock implements SimpleWaterlo - } - } - -+ // Purpur start - right click to open sign editor -+ if (world.purpurConfig.signRightClickEdit && itemStack.getItem() instanceof SignItem && -+ !player.isCrouching() && player.getAbilities().mayBuild && -+ player.getBukkitEntity().hasPermission("purpur.sign.edit")) { -+ signBlockEntity.setEditable(true); -+ signBlockEntity.setAllowedPlayerEditor(player.getUUID()); -+ player.openTextEdit(signBlockEntity); -+ return InteractionResult.SUCCESS; -+ } -+ // Purpur end -+ - return signBlockEntity.executeClickCommands((ServerPlayer)player) ? InteractionResult.SUCCESS : InteractionResult.PASS; - } else { - return InteractionResult.PASS; diff --git a/src/main/java/net/minecraft/world/level/block/SlabBlock.java b/src/main/java/net/minecraft/world/level/block/SlabBlock.java -index 18b603d646081926343dea108b55d641df1c2c34..03ad3e45fc6d48091ac0c0ba5dc3d014b1d4ddfa 100644 +index 18b603d646081926343dea108b55d641df1c2c34..370772b1297b78bcc7419684015830a87c4d9a17 100644 --- a/src/main/java/net/minecraft/world/level/block/SlabBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SlabBlock.java @@ -130,4 +130,25 @@ public class SlabBlock extends Block implements SimpleWaterloggedBlock { @@ -18915,11 +18945,11 @@ index 18b603d646081926343dea108b55d641df1c2c34..03ad3e45fc6d48091ac0c0ba5dc3d014 + } + double hitY = result.getLocation().y(); + int blockY = org.bukkit.util.NumberConversions.floor(hitY); -+ player.level.setBlock(pos, state.setValue(SlabBlock.TYPE, (hitY - blockY > 0.5 || blockY - pos.getY() == 1) ? SlabType.BOTTOM : SlabType.TOP), 3); ++ player.level().setBlock(pos, state.setValue(SlabBlock.TYPE, (hitY - blockY > 0.5 || blockY - pos.getY() == 1) ? SlabType.BOTTOM : SlabType.TOP), 3); + if (!player.getAbilities().instabuild) { -+ net.minecraft.world.entity.item.ItemEntity item = new net.minecraft.world.entity.item.ItemEntity(player.level, pos.getX(), pos.getY(), pos.getZ(), new ItemStack(asItem())); ++ net.minecraft.world.entity.item.ItemEntity item = new net.minecraft.world.entity.item.ItemEntity(player.level(), pos.getX(), pos.getY(), pos.getZ(), new ItemStack(asItem())); + item.setDefaultPickUpDelay(); -+ player.level.addFreshEntity(item); ++ player.level().addFreshEntity(item); + } + return true; + } @@ -18943,7 +18973,7 @@ index 14e00c7feb1c051d56a3d27cd00dcef072dd771a..4952fb1aaaafb55baa0fddb389f966a1 } diff --git a/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java b/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java -index 936d844a5a246138c9f9ae4ae6e318242b8f1420..d58dc4aa02fe371deaf879df8692dbe93c648f9b 100644 +index 936d844a5a246138c9f9ae4ae6e318242b8f1420..93f5f226cf6fd6110e4daa02b3f5d9ad253814a0 100644 --- a/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java @@ -40,6 +40,58 @@ public class SpawnerBlock extends BaseEntityBlock { @@ -18952,7 +18982,7 @@ index 936d844a5a246138c9f9ae4ae6e318242b8f1420..d58dc4aa02fe371deaf879df8692dbe9 + // Purpur start + @Override -+ public void playerDestroy(Level level, net.minecraft.world.entity.player.Player player, BlockPos pos, BlockState state, BlockEntity blockEntity, ItemStack stack) { ++ public void playerDestroy(Level level, net.minecraft.world.entity.player.Player player, BlockPos pos, BlockState state, BlockEntity blockEntity, ItemStack stack, boolean includeDrops) { + if (level.purpurConfig.silkTouchEnabled && player.getBukkitEntity().hasPermission("purpur.drop.spawners") && isSilkTouch(level, stack)) { + Optional> type = net.minecraft.world.entity.EntityType.by(((SpawnerBlockEntity) blockEntity).getSpawner().nextSpawnData.getEntityToSpawn()); + @@ -18994,7 +19024,7 @@ index 936d844a5a246138c9f9ae4ae6e318242b8f1420..d58dc4aa02fe371deaf879df8692dbe9 + + popResource(level, pos, item); + } -+ super.playerDestroy(level, player, pos, state, blockEntity, stack); ++ super.playerDestroy(level, player, pos, state, blockEntity, stack, includeDrops); + } + + private boolean isSilkTouch(Level level, ItemStack stack) { @@ -19014,48 +19044,40 @@ index 936d844a5a246138c9f9ae4ae6e318242b8f1420..d58dc4aa02fe371deaf879df8692dbe9 int i = 15 + worldserver.random.nextInt(15) + worldserver.random.nextInt(15); diff --git a/src/main/java/net/minecraft/world/level/block/SpongeBlock.java b/src/main/java/net/minecraft/world/level/block/SpongeBlock.java -index 7304b2659eb45bc4bc9fa7c43e6ca07221d0fc73..df04a571ebd3c04bc7b58c1ee5661a1f03c69d2f 100644 +index 4bce895268542531598a01a1bccd8ac1ed703b7d..2276fed1feb4fea59b5bd49b5e4586d49478b3cc 100644 --- a/src/main/java/net/minecraft/world/level/block/SpongeBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SpongeBlock.java -@@ -73,16 +73,16 @@ public class SpongeBlock extends Block { +@@ -48,7 +48,7 @@ public class SpongeBlock extends Block { + + private boolean removeWaterBreadthFirstSearch(Level world, BlockPos pos) { + BlockStateListPopulator blockList = new BlockStateListPopulator(world); // CraftBukkit - Use BlockStateListPopulator +- BlockPos.breadthFirstTraversal(pos, 6, 65, (blockposition1, consumer) -> { ++ BlockPos.breadthFirstTraversal(pos, world.purpurConfig.spongeAbsorptionRadius, world.purpurConfig.spongeAbsorptionArea, (blockposition1, consumer) -> { // Purpur + Direction[] aenumdirection = SpongeBlock.ALL_DIRECTIONS; + int i = aenumdirection.length; + +@@ -67,7 +67,7 @@ public class SpongeBlock extends Block { + FluidState fluid = blockList.getFluidState(blockposition1); // CraftBukkit end - Material material = iblockdata.getMaterial(); -- if (fluid.is(FluidTags.WATER)) { -+ if (fluid.is(FluidTags.WATER) || (world.purpurConfig.spongeAbsorbsLava && fluid.is(FluidTags.LAVA))) { // Purpur - if (iblockdata.getBlock() instanceof BucketPickup && !((BucketPickup) iblockdata.getBlock()).pickupBlock(blockList, blockposition2, iblockdata).isEmpty()) { // CraftBukkit - ++i; -- if (j < 6) { -+ if (j < world.purpurConfig.spongeAbsorptionRadius) { // Purpur - queue.add(new Tuple<>(blockposition2, j + 1)); - } - } else if (iblockdata.getBlock() instanceof LiquidBlock) { - blockList.setBlock(blockposition2, Blocks.AIR.defaultBlockState(), 3); // CraftBukkit - ++i; -- if (j < 6) { -+ if (j < world.purpurConfig.spongeAbsorptionRadius) { // Purpur - queue.add(new Tuple<>(blockposition2, j + 1)); - } - } else if (material == Material.WATER_PLANT || material == Material.REPLACEABLE_WATER_PLANT) { -@@ -93,14 +93,14 @@ public class SpongeBlock extends Block { - blockList.setBlock(blockposition2, Blocks.AIR.defaultBlockState(), 3); - // CraftBukkit end - ++i; -- if (j < 6) { -+ if (j < world.purpurConfig.spongeAbsorptionRadius) { // Purpur - queue.add(new Tuple<>(blockposition2, j + 1)); - } - } - } - } +- if (!fluid.is(FluidTags.WATER)) { ++ if (!fluid.is(FluidTags.WATER) && (!world.purpurConfig.spongeAbsorbsLava || !fluid.is(FluidTags.LAVA)) && (!world.purpurConfig.spongeAbsorbsWaterFromMud || !iblockdata.is(Blocks.MUD))) { // Purpur + return false; + } else { + Block block = iblockdata.getBlock(); +@@ -82,6 +82,10 @@ public class SpongeBlock extends Block { -- if (i > 64) { -+ if (i > world.purpurConfig.spongeAbsorptionArea) { // Purpur - break; - } - } + if (iblockdata.getBlock() instanceof LiquidBlock) { + blockList.setBlock(blockposition1, Blocks.AIR.defaultBlockState(), 3); // CraftBukkit ++ // Purpur start ++ } else if (iblockdata.is(Blocks.MUD)) { ++ blockList.setBlock(blockposition1, Blocks.CLAY.defaultBlockState(), 3); ++ // Purpur end + } else { + if (!iblockdata.is(Blocks.KELP) && !iblockdata.is(Blocks.KELP_PLANT) && !iblockdata.is(Blocks.SEAGRASS) && !iblockdata.is(Blocks.TALL_SEAGRASS)) { + return false; diff --git a/src/main/java/net/minecraft/world/level/block/StonecutterBlock.java b/src/main/java/net/minecraft/world/level/block/StonecutterBlock.java -index 0a95842c53a9d0286c57bcb42db97e468e30fb7d..e2d42e7947a237dd060ec1b9b63ac6ca4f37241a 100644 +index 0a95842c53a9d0286c57bcb42db97e468e30fb7d..0882e67c5cf876e0fc58a4ca4accb4be40418983 100644 --- a/src/main/java/net/minecraft/world/level/block/StonecutterBlock.java +++ b/src/main/java/net/minecraft/world/level/block/StonecutterBlock.java @@ -92,4 +92,16 @@ public class StonecutterBlock extends Block { @@ -19068,7 +19090,7 @@ index 0a95842c53a9d0286c57bcb42db97e468e30fb7d..e2d42e7947a237dd060ec1b9b63ac6ca + public void stepOn(Level level, BlockPos pos, BlockState state, net.minecraft.world.entity.Entity entity) { + if (level.purpurConfig.stonecutterDamage > 0.0F && entity instanceof net.minecraft.world.entity.LivingEntity) { + org.bukkit.craftbukkit.event.CraftEventFactory.blockDamage = level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); -+ entity.hurt(entity.damageSources().magic(), level.purpurConfig.stonecutterDamage); ++ entity.hurt(entity.damageSources().stonecutter(), level.purpurConfig.stonecutterDamage); + org.bukkit.craftbukkit.event.CraftEventFactory.blockDamage = null; + } + super.stepOn(level, pos, state, entity); @@ -19076,7 +19098,7 @@ index 0a95842c53a9d0286c57bcb42db97e468e30fb7d..e2d42e7947a237dd060ec1b9b63ac6ca + // Purpur end } diff --git a/src/main/java/net/minecraft/world/level/block/SugarCaneBlock.java b/src/main/java/net/minecraft/world/level/block/SugarCaneBlock.java -index 6b400a4759c8c8612a3b5c96ca0d87ef9dc71435..992de1ab2c00a2545a857f1b5533926bc895f996 100644 +index c3f500580d257e1397f2eb7c47b063a6fe6bb405..0d5c6bdfd4aeda472804b493315bf21ac3067e9d 100644 --- a/src/main/java/net/minecraft/world/level/block/SugarCaneBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SugarCaneBlock.java @@ -19,7 +19,7 @@ import net.minecraft.world.level.material.FluidState; @@ -19124,7 +19146,7 @@ index 6b400a4759c8c8612a3b5c96ca0d87ef9dc71435..992de1ab2c00a2545a857f1b5533926b + // Purpur end } diff --git a/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java b/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java -index 6c1a0e6f961e46a1a89850746a71e97b32514adf..a8c227e2cb62cfa8225798329cde9078d194c776 100644 +index 181e99e3f29c70568b6f28f8a5d3bb692f7abad8..58facc048840d3ba0a58c92673340e6e0aa4e305 100644 --- a/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java +++ b/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java @@ -160,7 +160,7 @@ public class TurtleEggBlock extends Block { @@ -19202,10 +19224,10 @@ index e5c135ec059746b75fe58516809584221285cdbe..713c7e6e31a3e1097b612c77a4fce147 + // Purpur end } diff --git a/src/main/java/net/minecraft/world/level/block/WitherSkullBlock.java b/src/main/java/net/minecraft/world/level/block/WitherSkullBlock.java -index b91effe91dad2e1aeea0ea31140f7432833b343f..bb628bd3fe8b185f356968697b17e1c4a442a6d2 100644 +index 1aa0e921890d600c9274deb923da04e72b12bcc6..44bd7bee2665a05878fd2df935a700f02cd13a75 100644 --- a/src/main/java/net/minecraft/world/level/block/WitherSkullBlock.java +++ b/src/main/java/net/minecraft/world/level/block/WitherSkullBlock.java -@@ -71,6 +71,7 @@ public class WitherSkullBlock extends SkullBlock { +@@ -69,6 +69,7 @@ public class WitherSkullBlock extends SkullBlock { entitywither.moveTo((double) blockposition1.getX() + 0.5D, (double) blockposition1.getY() + 0.55D, (double) blockposition1.getZ() + 0.5D, shapedetector_shapedetectorcollection.getForwards().getAxis() == Direction.Axis.X ? 0.0F : 90.0F, 0.0F); entitywither.yBodyRot = shapedetector_shapedetectorcollection.getForwards().getAxis() == Direction.Axis.X ? 0.0F : 90.0F; entitywither.makeInvulnerable(); @@ -19214,7 +19236,7 @@ index b91effe91dad2e1aeea0ea31140f7432833b343f..bb628bd3fe8b185f356968697b17e1c4 if (!world.addFreshEntity(entitywither, SpawnReason.BUILD_WITHER)) { return; diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index a3f073066f6e2eea8964461ad2b0409ade202f35..5cd7b4e7065070bf9fcc34b621dba2ccba99a573 100644 +index 448fa4f4f200430d6ce3051763c7ceb697696146..997d0fab71eacc6466ffe3bc8f6349e5813d6d49 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java @@ -44,6 +44,7 @@ import net.minecraft.world.level.Level; @@ -19337,7 +19359,7 @@ index 416aa989ebb18a8741cc9d605a1180ab830f6643..e38a0adf5463c48311ad08b8d2e5b5c2 @Override diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java -index ef740d1ad6352ca4af299001a081b720bc472d2e..8f82b0ce87afc8890c5b3386d5f6e22c48974b16 100644 +index 3b866e2c20ee7bfc981ff09b29065530de993778..2e6220c5a6c871401ce9734adfab710dcf86ad44 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java @@ -84,6 +84,16 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name @@ -19385,7 +19407,7 @@ index ef740d1ad6352ca4af299001a081b720bc472d2e..8f82b0ce87afc8890c5b3386d5f6e22c BeaconBlockEntity.playSound(world, pos, SoundEvents.BEACON_AMBIENT); } diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java -index 41c9f074203915c31c1ae7a160ce509c13383f84..7b82842b97ce795745cf6ee6399f618c55acbbf3 100644 +index 41c9f074203915c31c1ae7a160ce509c13383f84..5344393f62af19c3591f54a6ebc40b2e4c3b6226 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java @@ -43,7 +43,7 @@ public class BeehiveBlockEntity extends BlockEntity { @@ -19397,7 +19419,57 @@ index 41c9f074203915c31c1ae7a160ce509c13383f84..7b82842b97ce795745cf6ee6399f618c public BeehiveBlockEntity(BlockPos pos, BlockState state) { super(BlockEntityType.BEEHIVE, pos, state); -@@ -203,7 +203,7 @@ public class BeehiveBlockEntity extends BlockEntity { +@@ -130,6 +130,36 @@ public class BeehiveBlockEntity extends BlockEntity { + return list; + } + ++ // Purpur start ++ public List releaseBees(BlockState iblockdata, Level level, BeehiveBlockEntity.BeeReleaseStatus tileentitybeehive_releasestatus, boolean force) { ++ List list = Lists.newArrayList(); ++ ++ this.stored.removeIf((tileentitybeehive_hivebee) -> { ++ return BeehiveBlockEntity.releaseBee(level, this.worldPosition, iblockdata, tileentitybeehive_hivebee, list, tileentitybeehive_releasestatus, this.savedFlowerPos, force); ++ }); ++ ++ if (!list.isEmpty()) { ++ super.setChanged(); ++ } ++ ++ return list; ++ } ++ ++ public List releaseBee(BlockState iblockdata, Level level, BeeData data, BeehiveBlockEntity.BeeReleaseStatus tileentitybeehive_releasestatus, boolean force) { ++ List list = Lists.newArrayList(); ++ ++ BeehiveBlockEntity.releaseBee(level, this.worldPosition, iblockdata, data, list, tileentitybeehive_releasestatus, this.savedFlowerPos, force); ++ ++ if (!list.isEmpty()) { ++ stored.remove(data); ++ ++ super.setChanged(); ++ } ++ ++ return list; ++ } ++ // Purpur end ++ + public void addOccupant(Entity entity, boolean hasNectar) { + this.addOccupantWithPresetTicks(entity, hasNectar, 0); + } +@@ -139,6 +169,12 @@ public class BeehiveBlockEntity extends BlockEntity { + return this.stored.size(); + } + ++ // Purpur start ++ public List getStored() { ++ return stored; ++ } ++ // Purpur end ++ + // Paper start - Add EntityBlockStorage clearEntities + public void clearBees() { + this.stored.clear(); +@@ -203,7 +239,7 @@ public class BeehiveBlockEntity extends BlockEntity { } private static boolean releaseBee(Level world, BlockPos blockposition, BlockState iblockdata, BeehiveBlockEntity.BeeData tileentitybeehive_hivebee, @Nullable List list, BeehiveBlockEntity.BeeReleaseStatus tileentitybeehive_releasestatus, @Nullable BlockPos blockposition1, boolean force) { @@ -19406,8 +19478,20 @@ index 41c9f074203915c31c1ae7a160ce509c13383f84..7b82842b97ce795745cf6ee6399f618c // CraftBukkit end return false; } else { +@@ -425,9 +461,9 @@ public class BeehiveBlockEntity extends BlockEntity { + private BeeReleaseStatus() {} + } + +- private static class BeeData { ++ public static class BeeData { // Purpur - change from private to public + +- final CompoundTag entityData; ++ public final CompoundTag entityData; // Purpur - make public + int ticksInHive; + int exitTickCounter; // Paper - separate counter for checking if bee should exit to reduce exit attempts + final int minOccupationTicks; diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -index 1b248db497500aa6bd346b306dcb908af77626f3..e438e7e018f643d82ddf5efbf72779876c516d1a 100644 +index 370a25d2deb54f10a35ee24d9e7e92fbfde60edf..3431f1a00ae2918b91a6b7a449e613e6e12ff6d4 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java @@ -6,6 +6,8 @@ import net.minecraft.CrashReportCategory; @@ -19419,7 +19503,7 @@ index 1b248db497500aa6bd346b306dcb908af77626f3..e438e7e018f643d82ddf5efbf7277987 import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.ClientGamePacketListener; import net.minecraft.resources.ResourceLocation; -@@ -74,10 +76,27 @@ public abstract class BlockEntity { +@@ -73,10 +75,27 @@ public abstract class BlockEntity { if (persistentDataTag instanceof CompoundTag) { this.persistentDataContainer.putAll((CompoundTag) persistentDataTag); } @@ -19448,7 +19532,7 @@ index 1b248db497500aa6bd346b306dcb908af77626f3..e438e7e018f643d82ddf5efbf7277987 public final CompoundTag saveWithFullMetadata() { CompoundTag nbttagcompound = this.saveWithoutMetadata(); -@@ -187,10 +206,24 @@ public abstract class BlockEntity { +@@ -186,10 +205,24 @@ public abstract class BlockEntity { @Nullable public Packet getUpdatePacket() { @@ -19473,7 +19557,7 @@ index 1b248db497500aa6bd346b306dcb908af77626f3..e438e7e018f643d82ddf5efbf7277987 return new CompoundTag(); } -@@ -264,4 +297,24 @@ public abstract class BlockEntity { +@@ -263,4 +296,24 @@ public abstract class BlockEntity { } // Paper end @@ -19614,24 +19698,63 @@ index 65e1381bb2d10bd212463feb602c60f8fdb9ade1..b7370e64fd0d50e8725d7d5afc30af2e + // Purpur } diff --git a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java -index 4da4edae517a0efec6e03a719ec47b700509dab1..9e760a8e8244b15daaf0abdfc5f8a51d5c663e12 100644 +index 38cde466714e5663cd416b6afd5d2558e139ec09..2d625f18f2ba42ee5a1ebeea78ca395ad6f88b37 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java -@@ -203,6 +203,23 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C +@@ -202,16 +202,31 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C + return this.setText((SignText) textChanger.apply(signtext), front); + } + ++ // Purpur start ++ private Component translateColors(org.bukkit.entity.Player player, String line, Style style) { ++ if (level.purpurConfig.signAllowColors) { ++ if (player.hasPermission("purpur.sign.color")) line = line.replaceAll("(?i)&([0-9a-fr])", "\u00a7$1"); ++ if (player.hasPermission("purpur.sign.style")) line = line.replaceAll("(?i)&([l-or])", "\u00a7$1"); ++ if (player.hasPermission("purpur.sign.magic")) line = line.replaceAll("(?i)&([kr])", "\u00a7$1"); ++ ++ return io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(line)); ++ } else { ++ return Component.literal(line).setStyle(style); ++ } ++ } ++ // Purpur end ++ + private SignText setMessages(net.minecraft.world.entity.player.Player entityhuman, List list, SignText signtext, boolean front) { // CraftBukkit + SignText originalText = signtext; // CraftBukkit + for (int i = 0; i < list.size(); ++i) { + FilteredText filteredtext = (FilteredText) list.get(i); + Style chatmodifier = signtext.getMessage(i, entityhuman.isTextFilteringEnabled()).getStyle(); + ++ org.bukkit.entity.Player player = (org.bukkit.craftbukkit.entity.CraftPlayer) entityhuman.getBukkitEntity(); // Purpur + if (entityhuman.isTextFilteringEnabled()) { +- signtext = signtext.setMessage(i, Component.literal(net.minecraft.SharedConstants.filterText(filteredtext.filteredOrEmpty())).setStyle(chatmodifier)); // Paper - filter sign text to chat only ++ signtext = signtext.setMessage(i, translateColors(player, net.minecraft.SharedConstants.filterText(filteredtext.filteredOrEmpty()), chatmodifier)); // Paper - filter sign text to chat only // Purpur + } else { +- signtext = signtext.setMessage(i, Component.literal(net.minecraft.SharedConstants.filterText(filteredtext.raw())).setStyle(chatmodifier), Component.literal(net.minecraft.SharedConstants.filterText(filteredtext.filteredOrEmpty())).setStyle(chatmodifier)); // Paper - filter sign text to chat only ++ signtext = signtext.setMessage(i, translateColors(player, net.minecraft.SharedConstants.filterText(filteredtext.raw()), chatmodifier), translateColors(player, net.minecraft.SharedConstants.filterText(filteredtext.filteredOrEmpty()), chatmodifier)); // Paper - filter sign text to chat only // Purpur + } + } + +@@ -351,6 +366,28 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C return ClientboundBlockEntityDataPacket.create(this); } + // Purpur start -+ public ClientboundBlockEntityDataPacket getTranslatedUpdatePacket(boolean filtered) { ++ public ClientboundBlockEntityDataPacket getTranslatedUpdatePacket(boolean filtered, boolean front) { + final CompoundTag nbt = new CompoundTag(); + this.saveAdditional(nbt); -+ final Component[] lines = getMessages(filtered); ++ final Component[] lines = front ? frontText.getMessages(filtered) : backText.getMessages(filtered); ++ final String side = front ? "front_text" : "back_text"; + for (int i = 0; i < 4; i++) { + final var component = io.papermc.paper.adventure.PaperAdventure.asAdventure(lines[i]); + final String line = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacyAmpersand().serialize(component); + final var text = net.kyori.adventure.text.Component.text(line); + final String json = net.kyori.adventure.text.serializer.gson.GsonComponentSerializer.gson().serialize(text); -+ nbt.putString("Text" + (i + 1), json); ++ if (!nbt.contains(side)) nbt.put(side, new CompoundTag()); ++ final CompoundTag sideNbt = nbt.getCompound(side); ++ if (!sideNbt.contains("messages")) sideNbt.put("messages", new net.minecraft.nbt.ListTag()); ++ final net.minecraft.nbt.ListTag messagesNbt = sideNbt.getList("messages", Tag.TAG_STRING); ++ messagesNbt.set(i, net.minecraft.nbt.StringTag.valueOf(json)); + } + nbt.putString("PurpurEditor", "true"); + return ClientboundBlockEntityDataPacket.create(this, entity -> nbt); @@ -19642,10 +19765,10 @@ index 4da4edae517a0efec6e03a719ec47b700509dab1..9e760a8e8244b15daaf0abdfc5f8a51d public CompoundTag getUpdateTag() { return this.saveWithoutMetadata(); diff --git a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java -index c2bc747e9b9dd02971c13cb88e7aebeca8c0f2aa..a4cd9869988f414ce1bf14d38442f78207e3f048 100644 +index 1ec80f9c901dff1c9f29befa5a8e3c3f6f37aaf7..7291e4056b8e46ab59b71818388ac55fbb12993f 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java -@@ -178,6 +178,15 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity { +@@ -177,6 +177,15 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity { public static void teleportEntity(Level world, BlockPos pos, BlockState state, Entity entity, TheEndGatewayBlockEntity blockEntity) { if (world instanceof ServerLevel && !blockEntity.isCoolingDown()) { @@ -19693,26 +19816,32 @@ index 744d91546d1a810f60a43c15ed74b4158f341a4a..354538daefa603f6df5a139b6bff87db } diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -index 505503a3f59d4b747649275c6f6faa504b7c7b64..bee42ce7c1cb0f5ebd4890c02bc9c5dd727f7fd6 100644 +index de4c1e4701236e7d5ec77339c51ad6a9d8288bb6..942ce713afe27ec75d849877a88721ef6334fafa 100644 --- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java +++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -@@ -78,9 +78,9 @@ import net.minecraft.world.phys.shapes.VoxelShape; - public abstract class BlockBehaviour implements FeatureElement { +@@ -81,7 +81,7 @@ public abstract class BlockBehaviour implements FeatureElement { protected static final Direction[] UPDATE_SHAPE_ORDER = new Direction[]{Direction.WEST, Direction.EAST, Direction.NORTH, Direction.SOUTH, Direction.DOWN, Direction.UP}; -- protected final Material material; -+ public final Material material; // Purpur - protected -> public public final boolean hasCollision; - protected final float explosionResistance; + public float explosionResistance; // Purpur - protected final -> public protected final boolean isRandomlyTicking; protected final SoundType soundType; protected final float friction; +@@ -89,7 +89,7 @@ public abstract class BlockBehaviour implements FeatureElement { + protected final float jumpFactor; + protected final boolean dynamicShape; + protected final FeatureFlagSet requiredFeatures; +- protected final BlockBehaviour.Properties properties; ++ public final BlockBehaviour.Properties properties; // Purpur - protected -> public + @Nullable + protected ResourceLocation drops; + diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index 13594b96cc8f451723c3598ef302ccee8e01bcac..e9d92bf484fb0d2fcb66a7c424eced109bfa031d 100644 +index 3eeb1f0eac76efe9b7c24f6d5787018c7842d07a..c17b04880b4032984b43dd4fbe1c08f96112abac 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -129,7 +129,7 @@ public class LevelChunk extends ChunkAccess { +@@ -125,7 +125,7 @@ public class LevelChunk extends ChunkAccess { this.blockTicks = blockTickScheduler; this.fluidTicks = fluidTickScheduler; @@ -19721,7 +19850,22 @@ index 13594b96cc8f451723c3598ef302ccee8e01bcac..e9d92bf484fb0d2fcb66a7c424eced10 } // CraftBukkit start -@@ -925,7 +925,7 @@ public class LevelChunk extends ChunkAccess { +@@ -552,11 +552,11 @@ public class LevelChunk extends ChunkAccess { + if (LightEngine.hasDifferentLightProperties(this, blockposition, iblockdata1, iblockdata)) { + ProfilerFiller gameprofilerfiller = this.level.getProfiler(); + +- gameprofilerfiller.push("updateSkyLightSources"); ++ //gameprofilerfiller.push("updateSkyLightSources"); // Purpur + this.skyLightSources.update(this, j, i, l); +- gameprofilerfiller.popPush("queueCheckLight"); ++ //gameprofilerfiller.popPush("queueCheckLight"); // Purpur + this.level.getChunkSource().getLightEngine().checkBlock(blockposition); +- gameprofilerfiller.pop(); ++ //gameprofilerfiller.pop(); // Purpur + } + + boolean flag3 = iblockdata1.hasBlockEntity(); +@@ -895,7 +895,7 @@ public class LevelChunk extends ChunkAccess { this.chunkHolder.getEntityChunk().callEntitiesLoadEvent(); // Paper - rewrite chunk system if (this.needsDecoration) { @@ -19730,7 +19874,7 @@ index 13594b96cc8f451723c3598ef302ccee8e01bcac..e9d92bf484fb0d2fcb66a7c424eced10 this.needsDecoration = false; java.util.Random random = new java.util.Random(); random.setSeed(this.level.getSeed()); -@@ -945,7 +945,7 @@ public class LevelChunk extends ChunkAccess { +@@ -915,7 +915,7 @@ public class LevelChunk extends ChunkAccess { } } server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(bukkitChunk)); @@ -19739,7 +19883,7 @@ index 13594b96cc8f451723c3598ef302ccee8e01bcac..e9d92bf484fb0d2fcb66a7c424eced10 } } } -@@ -1315,10 +1315,10 @@ public class LevelChunk extends ChunkAccess { +@@ -1270,10 +1270,10 @@ public class LevelChunk extends ChunkAccess { if (LevelChunk.this.isTicking(blockposition)) { try { @@ -19753,7 +19897,7 @@ index 13594b96cc8f451723c3598ef302ccee8e01bcac..e9d92bf484fb0d2fcb66a7c424eced10 BlockState iblockdata = LevelChunk.this.getBlockState(blockposition); if (this.blockEntity.getType().isValid(iblockdata)) { -@@ -1329,7 +1329,7 @@ public class LevelChunk extends ChunkAccess { +@@ -1284,7 +1284,7 @@ public class LevelChunk extends ChunkAccess { LevelChunk.LOGGER.warn("Block entity {} @ {} state {} invalid for ticking:", new Object[]{LogUtils.defer(this::getType), LogUtils.defer(this::getPos), iblockdata}); } @@ -19762,7 +19906,7 @@ index 13594b96cc8f451723c3598ef302ccee8e01bcac..e9d92bf484fb0d2fcb66a7c424eced10 } catch (Throwable throwable) { if (throwable instanceof ThreadDeath) throw throwable; // Paper // Paper start - Prevent tile entity and entity crashes -@@ -1340,7 +1340,7 @@ public class LevelChunk extends ChunkAccess { +@@ -1295,7 +1295,7 @@ public class LevelChunk extends ChunkAccess { // Paper end // Spigot start } finally { @@ -19784,10 +19928,10 @@ index 060e064625969610539dbf969ce773b877a7c579..32cd9df202704cdfb8fa06aaf0e738d4 final EntityType entityType = entity.getType(); final int saveLimit = level.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1); diff --git a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java -index e8ae4449696d73c8c9b8b27d4d2e20db933a72cc..f55c50f6637a4f930b15565d6ac82bb4f27b9059 100644 +index dfeb3e336e06ef01f5401a362755030db942bb07..f74c5eda91a3d521763ec7bc33f23e0c62458cc2 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java +++ b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java -@@ -51,7 +51,7 @@ public class PhantomSpawner implements CustomSpawner { +@@ -49,7 +49,7 @@ public class PhantomSpawner implements CustomSpawner { int spawnAttemptMaxSeconds = world.paperConfig().entities.behavior.phantomsSpawnAttemptMaxSeconds; this.nextTick += (spawnAttemptMinSeconds + randomsource.nextInt(spawnAttemptMaxSeconds - spawnAttemptMinSeconds + 1)) * 20; // Paper end @@ -19796,9 +19940,9 @@ index e8ae4449696d73c8c9b8b27d4d2e20db933a72cc..f55c50f6637a4f930b15565d6ac82bb4 return 0; } else { int i = 0; -@@ -63,10 +63,10 @@ public class PhantomSpawner implements CustomSpawner { - if (!entityhuman.isSpectator() && (!world.paperConfig().entities.behavior.phantomsDoNotSpawnOnCreativePlayers || !entityhuman.isCreative())) { // Paper - BlockPos blockposition = entityhuman.blockPosition(); +@@ -61,10 +61,10 @@ public class PhantomSpawner implements CustomSpawner { + if (!entityplayer.isSpectator() && (!world.paperConfig().entities.behavior.phantomsDoNotSpawnOnCreativePlayers || !entityplayer.isCreative())) { // Paper + BlockPos blockposition = entityplayer.blockPosition(); - if (!world.dimensionType().hasSkyLight() || blockposition.getY() >= world.getSeaLevel() && world.canSeeSky(blockposition)) { + if (!world.dimensionType().hasSkyLight() || (!world.purpurConfig.phantomSpawnOnlyAboveSeaLevel || blockposition.getY() >= world.getSeaLevel()) && (!world.purpurConfig.phantomSpawnOnlyWithVisibleSky || world.canSeeSky(blockposition))) { // Purpur @@ -19806,10 +19950,10 @@ index e8ae4449696d73c8c9b8b27d4d2e20db933a72cc..f55c50f6637a4f930b15565d6ac82bb4 - if (difficultydamagescaler.isHarderThan(randomsource.nextFloat() * 3.0F)) { + if (difficultydamagescaler.isHarderThan(randomsource.nextFloat() * (float) world.purpurConfig.phantomSpawnLocalDifficultyChance)) { // Purpur - ServerStatsCounter serverstatisticmanager = ((ServerPlayer) entityhuman).getStats(); + ServerStatsCounter serverstatisticmanager = entityplayer.getStats(); int j = Mth.clamp(serverstatisticmanager.getValue(Stats.CUSTOM.get(Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE); boolean flag2 = true; -@@ -78,7 +78,7 @@ public class PhantomSpawner implements CustomSpawner { +@@ -76,7 +76,7 @@ public class PhantomSpawner implements CustomSpawner { if (NaturalSpawner.isValidEmptySpawnBlock(world, blockposition1, iblockdata, fluid, EntityType.PHANTOM)) { SpawnGroupData groupdataentity = null; @@ -19819,10 +19963,10 @@ index e8ae4449696d73c8c9b8b27d4d2e20db933a72cc..f55c50f6637a4f930b15565d6ac82bb4 for (int l = 0; l < k; ++l) { // Paper start diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java -index 6063665b8848a2cd9f0b262eed36a9dd48db6035..5536b9e36b4ea99e2aaa62690b5bf00208291a58 100644 +index 7d56693102ee558fe784e3a9b9fdcff4b7ad57b9..485bbec4b52f126393332d5cad2d97c2a220f91a 100644 --- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java +++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java -@@ -226,7 +226,7 @@ public abstract class FlowingFluid extends Fluid { +@@ -227,7 +227,7 @@ public abstract class FlowingFluid extends Fluid { } } @@ -19831,7 +19975,7 @@ index 6063665b8848a2cd9f0b262eed36a9dd48db6035..5536b9e36b4ea99e2aaa62690b5bf002 BlockState iblockdata2 = world.getBlockState(pos.below()); FluidState fluid1 = iblockdata2.getFluidState(); -@@ -324,6 +324,12 @@ public abstract class FlowingFluid extends Fluid { +@@ -325,6 +325,12 @@ public abstract class FlowingFluid extends Fluid { protected abstract boolean canConvertToSource(Level world); @@ -19845,7 +19989,7 @@ index 6063665b8848a2cd9f0b262eed36a9dd48db6035..5536b9e36b4ea99e2aaa62690b5bf002 if (state.getBlock() instanceof LiquidBlockContainer) { ((LiquidBlockContainer) state.getBlock()).placeLiquid(world, pos, state, fluidState); diff --git a/src/main/java/net/minecraft/world/level/material/LavaFluid.java b/src/main/java/net/minecraft/world/level/material/LavaFluid.java -index 783e315d92227cbcb5cd207b0a06a12e0778d14b..b05b4d3d97bca159c297f150005b5ab5bf6087e0 100644 +index c3f8e1e2dd89c168b8b4a15b589109db486bc8d7..70ddb3b130ee59a6e200ea5af3ac89f3c3fa9e9b 100644 --- a/src/main/java/net/minecraft/world/level/material/LavaFluid.java +++ b/src/main/java/net/minecraft/world/level/material/LavaFluid.java @@ -180,7 +180,7 @@ public abstract class LavaFluid extends FlowingFluid { @@ -19871,17 +20015,8 @@ index 783e315d92227cbcb5cd207b0a06a12e0778d14b..b05b4d3d97bca159c297f150005b5ab5 @Override protected boolean canConvertToSource(Level world) { return world.getGameRules().getBoolean(GameRules.RULE_LAVA_SOURCE_CONVERSION); -@@ -232,7 +239,7 @@ public abstract class LavaFluid extends FlowingFluid { - - @Override - protected float getExplosionResistance() { -- return 100.0F; -+ return Blocks.LAVA.getExplosionResistance(); // Purpur - } - - @Override diff --git a/src/main/java/net/minecraft/world/level/material/WaterFluid.java b/src/main/java/net/minecraft/world/level/material/WaterFluid.java -index 82e85fbbd45244d02df90fa00c9046e7f51275a2..0f16deddd8cbb506ef7886f57ae640a42e841703 100644 +index d280c98aed5262c4ce39526c917de884f25a8584..e7d9f6802520620a1dcf0938256ffe80fc72a6f0 100644 --- a/src/main/java/net/minecraft/world/level/material/WaterFluid.java +++ b/src/main/java/net/minecraft/world/level/material/WaterFluid.java @@ -64,6 +64,13 @@ public abstract class WaterFluid extends FlowingFluid { @@ -19898,15 +20033,6 @@ index 82e85fbbd45244d02df90fa00c9046e7f51275a2..0f16deddd8cbb506ef7886f57ae640a4 // Paper start @Override protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state, BlockPos source) { -@@ -109,7 +116,7 @@ public abstract class WaterFluid extends FlowingFluid { - - @Override - protected float getExplosionResistance() { -- return 100.0F; -+ return Blocks.WATER.getExplosionResistance(); // Purpur - } - - @Override diff --git a/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java b/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java index d23481453717f715124156b5d83f6448f720d049..a8af51a25b0f99c3a64d9150fdfcd6b818aa7581 100644 --- a/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java @@ -19923,19 +20049,19 @@ index d23481453717f715124156b5d83f6448f720d049..a8af51a25b0f99c3a64d9150fdfcd6b8 startNode.g = 0.0F; startNode.h = this.getBestH(startNode, positions); // Paper - optimize collection diff --git a/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java b/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java -index 94a0fde36dda9404e5eb62d323c71dac1929a46b..a7578e112e80ed2585a7eb4fff9542f6068546be 100644 +index 3583fcf5284bc5883308876dbd9886664b391e28..ba57accc272958da4714896baeadb52c99383561 100644 --- a/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java +++ b/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java -@@ -243,7 +243,7 @@ public class WalkNodeEvaluator extends NodeEvaluator { +@@ -241,7 +241,7 @@ public class WalkNodeEvaluator extends NodeEvaluator { } if (blockPathTypes != BlockPathTypes.WALKABLE && (!this.isAmphibious() || blockPathTypes != BlockPathTypes.WATER)) { - if ((node == null || node.costMalus < 0.0F) && maxYStep > 0 && (blockPathTypes != BlockPathTypes.FENCE || this.canWalkOverFences()) && blockPathTypes != BlockPathTypes.UNPASSABLE_RAIL && blockPathTypes != BlockPathTypes.TRAPDOOR && blockPathTypes != BlockPathTypes.POWDER_SNOW) { -+ if ((node == null || node.costMalus < 0.0F) && maxYStep > 0 && (blockPathTypes != BlockPathTypes.FENCE || this.canWalkOverFences()) && (this.mob.level.purpurConfig.mobsIgnoreRails || blockPathTypes != BlockPathTypes.UNPASSABLE_RAIL) && blockPathTypes != BlockPathTypes.TRAPDOOR && blockPathTypes != BlockPathTypes.POWDER_SNOW) { // Purpur ++ if ((node == null || node.costMalus < 0.0F) && maxYStep > 0 && (blockPathTypes != BlockPathTypes.FENCE || this.canWalkOverFences()) && (this.mob.level().purpurConfig.mobsIgnoreRails || blockPathTypes != BlockPathTypes.UNPASSABLE_RAIL) && blockPathTypes != BlockPathTypes.TRAPDOOR && blockPathTypes != BlockPathTypes.POWDER_SNOW) { // Purpur node = this.findAcceptedNode(x, y + 1, z, maxYStep - 1, prevFeetY, direction, nodeType); if (node != null && (node.type == BlockPathTypes.OPEN || node.type == BlockPathTypes.WALKABLE) && this.mob.getBbWidth() < 1.0F) { double g = (double)(x - direction.getStepX()) + 0.5D; -@@ -463,7 +463,7 @@ public class WalkNodeEvaluator extends NodeEvaluator { +@@ -465,7 +465,7 @@ public class WalkNodeEvaluator extends NodeEvaluator { return BlockPathTypes.BLOCKED; } else { // Paper end @@ -19944,7 +20070,7 @@ index 94a0fde36dda9404e5eb62d323c71dac1929a46b..a7578e112e80ed2585a7eb4fff9542f6 return BlockPathTypes.DANGER_OTHER; } -@@ -493,7 +493,7 @@ public class WalkNodeEvaluator extends NodeEvaluator { +@@ -498,7 +498,7 @@ public class WalkNodeEvaluator extends NodeEvaluator { } else if (!blockState.is(BlockTags.TRAPDOORS) && !blockState.is(Blocks.LILY_PAD) && !blockState.is(Blocks.BIG_DRIPLEAF)) { if (blockState.is(Blocks.POWDER_SNOW)) { return BlockPathTypes.POWDER_SNOW; @@ -19966,6 +20092,18 @@ index c461e0d04047db9c0c5ecc04063cebd38bf96ec2..e7554ec800f321e4e34c926c53f2375a }; private static final float SAFE_TRAVEL_MAX_ENTITY_XY = 4.0F; private static final double SAFE_TRAVEL_MAX_VERTICAL_DELTA = 1.0D; +diff --git a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java +index 50713f03c783c63f93710d986d94af544be0615a..e64921f454c88e2ca9e1396fcb1ca7c179ff71a7 100644 +--- a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java ++++ b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java +@@ -66,6 +66,7 @@ public class MapItemSavedData extends SavedData { + private final Map frameMarkers = Maps.newHashMap(); + private int trackedDecorationCount; + private org.bukkit.craftbukkit.map.RenderData vanillaRender = new org.bukkit.craftbukkit.map.RenderData(); // Paper ++ public boolean isExplorerMap; // Purpur + + // CraftBukkit start + public final CraftMapView mapView; diff --git a/src/main/java/net/minecraft/world/level/storage/loot/functions/LootingEnchantFunction.java b/src/main/java/net/minecraft/world/level/storage/loot/functions/LootingEnchantFunction.java index 31918fa2eb38e42a5ea5366e559f25ea9d7d59ae..15d8e9261a89da30529ac347462c520920ca4e7d 100644 --- a/src/main/java/net/minecraft/world/level/storage/loot/functions/LootingEnchantFunction.java @@ -20033,10 +20171,10 @@ index 1d7c663fa0e550bd0cfb9a4b83ccd7e2968666f0..0043c0087896a6df6910b0500da37d84 this.rescheduleLeftoverContainers(); } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java -index 714afc98b5150907b45a00060be4e41582333204..312a6d90c0a09570aef24c205dc2ff277dcd4279 100644 +index c1b874cd6e0498fce3cd53fdbaca30d290e004d7..23087d511b609693f0bb06cbaac8b6cf8d0defe2 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java -@@ -549,4 +549,213 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa +@@ -567,4 +567,213 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa manager.save(); } } @@ -20251,10 +20389,10 @@ index 714afc98b5150907b45a00060be4e41582333204..312a6d90c0a09570aef24c205dc2ff27 + // Purpur end - OfflinePlayer API } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 6ff93df3e870ebc6e52f8b8a719908bfa16a839b..3310828edcabd2c24e3200dcb89d4e8ebd82cf16 100644 +index 74c46cea456f4a736325892bb7b4d0f1b35b62cd..b08d4a2a74392b1d59b1eeeab3108103d83ad96c 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -262,7 +262,7 @@ import javax.annotation.Nullable; // Paper +@@ -265,7 +265,7 @@ import javax.annotation.Nullable; // Paper import javax.annotation.Nonnull; // Paper public final class CraftServer implements Server { @@ -20263,7 +20401,7 @@ index 6ff93df3e870ebc6e52f8b8a719908bfa16a839b..3310828edcabd2c24e3200dcb89d4e8e private final String serverVersion; private final String bukkitVersion = Versioning.getBukkitVersion(); private final Logger logger = Logger.getLogger("Minecraft"); -@@ -324,6 +324,20 @@ public final class CraftServer implements Server { +@@ -397,6 +397,20 @@ public final class CraftServer implements Server { this.dataPackManager = new CraftDataPackManager(this.getServer().getPackRepository()); Bukkit.setServer(this); @@ -20284,7 +20422,7 @@ index 6ff93df3e870ebc6e52f8b8a719908bfa16a839b..3310828edcabd2c24e3200dcb89d4e8e // Register all the Enchantments and PotionTypes now so we can stop new registration immediately after Enchantments.SHARPNESS.getClass(); -@@ -979,6 +993,7 @@ public final class CraftServer implements Server { +@@ -1057,6 +1071,7 @@ public final class CraftServer implements Server { org.spigotmc.SpigotConfig.init((File) console.options.valueOf("spigot-settings")); // Spigot this.console.paperConfigurations.reloadConfigs(this.console); @@ -20292,7 +20430,7 @@ index 6ff93df3e870ebc6e52f8b8a719908bfa16a839b..3310828edcabd2c24e3200dcb89d4e8e for (ServerLevel world : this.console.getAllLevels()) { // world.serverLevelData.setDifficulty(config.difficulty); // Paper - per level difficulty world.setSpawnSettings(world.serverLevelData.getDifficulty() != Difficulty.PEACEFUL && config.spawnMonsters, config.spawnAnimals); // Paper - per level difficulty (from MinecraftServer#setDifficulty(ServerLevel, Difficulty, boolean)) -@@ -994,6 +1009,7 @@ public final class CraftServer implements Server { +@@ -1072,6 +1087,7 @@ public final class CraftServer implements Server { } } world.spigotConfig.init(); // Spigot @@ -20300,7 +20438,7 @@ index 6ff93df3e870ebc6e52f8b8a719908bfa16a839b..3310828edcabd2c24e3200dcb89d4e8e } Plugin[] pluginClone = pluginManager.getPlugins().clone(); // Paper -@@ -1009,6 +1025,7 @@ public final class CraftServer implements Server { +@@ -1087,6 +1103,7 @@ public final class CraftServer implements Server { this.reloadData(); org.spigotmc.SpigotConfig.registerCommands(); // Spigot io.papermc.paper.command.PaperCommands.registerCommands(this.console); // Paper @@ -20308,7 +20446,7 @@ index 6ff93df3e870ebc6e52f8b8a719908bfa16a839b..3310828edcabd2c24e3200dcb89d4e8e this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*"); this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions"); -@@ -1451,6 +1468,55 @@ public final class CraftServer implements Server { +@@ -1552,6 +1569,55 @@ public final class CraftServer implements Server { return true; } @@ -20363,8 +20501,8 @@ index 6ff93df3e870ebc6e52f8b8a719908bfa16a839b..3310828edcabd2c24e3200dcb89d4e8e + @Override public List getRecipesFor(ItemStack result) { - Validate.notNull(result, "Result cannot be null"); -@@ -2722,6 +2788,7 @@ public final class CraftServer implements Server { + Preconditions.checkArgument(result != null, "ItemStack cannot be null"); +@@ -2891,6 +2957,7 @@ public final class CraftServer implements Server { @Override public double[] getTPS() { return new double[] { @@ -20372,7 +20510,7 @@ index 6ff93df3e870ebc6e52f8b8a719908bfa16a839b..3310828edcabd2c24e3200dcb89d4e8e net.minecraft.server.MinecraftServer.getServer().tps1.getAverage(), net.minecraft.server.MinecraftServer.getServer().tps5.getAverage(), net.minecraft.server.MinecraftServer.getServer().tps15.getAverage() -@@ -2768,6 +2835,18 @@ public final class CraftServer implements Server { +@@ -2937,6 +3004,18 @@ public final class CraftServer implements Server { return CraftServer.this.console.paperConfigurations.createLegacyObject(CraftServer.this.console); } @@ -20391,7 +20529,7 @@ index 6ff93df3e870ebc6e52f8b8a719908bfa16a839b..3310828edcabd2c24e3200dcb89d4e8e @Override public void restart() { org.spigotmc.RestartCommand.restart(); -@@ -2981,4 +3060,16 @@ public final class CraftServer implements Server { +@@ -3150,4 +3229,16 @@ public final class CraftServer implements Server { } // Paper end @@ -20409,11 +20547,11 @@ index 6ff93df3e870ebc6e52f8b8a719908bfa16a839b..3310828edcabd2c24e3200dcb89d4e8e + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 8f0234296397ca2d4a607dcea6093c6c606dc7d2..68df53648c9b76cf1b6abcaa90c5e8938e9e0d05 100644 +index f857f490ffba2f25f7c06c5fb1a1905f0b51fbe2..1392e483c363e25d1f16465d876cb7d7c70afa68 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -2284,6 +2284,48 @@ public class CraftWorld extends CraftRegionAccessor implements World { - return (this.getHandle().dragonFight() == null) ? null : new CraftDragonBattle(this.getHandle().dragonFight()); +@@ -2290,6 +2290,48 @@ public class CraftWorld extends CraftRegionAccessor implements World { + return (this.getHandle().getDragonFight() == null) ? null : new CraftDragonBattle(this.getHandle().getDragonFight()); } + // Purpur start @@ -20462,7 +20600,7 @@ index 8f0234296397ca2d4a607dcea6093c6c606dc7d2..68df53648c9b76cf1b6abcaa90c5e893 public PersistentDataContainer getPersistentDataContainer() { return this.persistentDataContainer; diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index bfa091f72d6f477bcaf63d364639a1b4df9b1987..288cf98287c6d3c073b9ab6696c3957c999cad32 100644 +index 776b7fc26fe96b69be260bbd36efae147d988640..9a3374a1236164194ef0df43ed639296cbe1c731 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -173,6 +173,20 @@ public class Main { @@ -20495,6 +20633,97 @@ index bfa091f72d6f477bcaf63d364639a1b4df9b1987..288cf98287c6d3c073b9ab6696c3957c Date buildDate = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z").parse(Main.class.getPackage().getImplementationVendor()); // Paper Calendar deadline = Calendar.getInstance(); +diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java +index 380897c010521f368848a3e6986d307cf47ff319..3c5eae31dc229b8c5f15215be9462410bcb41f07 100644 +--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java ++++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java +@@ -16,8 +16,15 @@ import org.bukkit.entity.Bee; + + public class CraftBeehive extends CraftBlockEntityState implements Beehive { + ++ private final List> storage = new ArrayList<>(); // Purpur ++ + public CraftBeehive(World world, BeehiveBlockEntity tileEntity) { + super(world, tileEntity); ++ // Purpur start - load bees to be able to modify them individually ++ for(BeehiveBlockEntity.BeeData data : getSnapshot().getStored()) { ++ storage.add(new org.purpurmc.purpur.entity.PurpurStoredBee(data, this)); ++ } ++ // Purpur end + } + + @Override +@@ -66,25 +73,67 @@ public class CraftBeehive extends CraftBlockEntityState impl + List bees = new ArrayList<>(); + + if (isPlaced()) { +- BeehiveBlockEntity beehive = ((BeehiveBlockEntity) this.getTileEntityFromWorld()); +- for (Entity bee : beehive.releaseBees(this.getHandle(), BeeReleaseStatus.BEE_RELEASED, true)) { ++ // Purpur start - change which releaseBees method is called, and use beehive snapshot ++ BeehiveBlockEntity beehive = ((BeehiveBlockEntity) this.getSnapshot()); ++ for (Entity bee : beehive.releaseBees(this.getHandle(), getWorldHandle().getMinecraftWorld(), BeeReleaseStatus.BEE_RELEASED, true)) { ++ // Purpur end + bees.add((Bee) bee.getBukkitEntity()); + } + } +- ++ storage.clear(); // Purpur + return bees; + } + ++ // Purpur start ++ @Override ++ public Bee releaseEntity(org.purpurmc.purpur.entity.StoredEntity entity) { ++ ensureNoWorldGeneration(); ++ ++ if(!getEntities().contains(entity)) { ++ return null; ++ } ++ ++ if(isPlaced()) { ++ BeehiveBlockEntity beehive = this.getSnapshot(); ++ BeehiveBlockEntity.BeeData data = ((org.purpurmc.purpur.entity.PurpurStoredBee) entity).getHandle(); ++ ++ List list = beehive.releaseBee(getHandle(), getWorldHandle().getMinecraftWorld(), data, BeeReleaseStatus.BEE_RELEASED, true); ++ ++ if (list.size() == 1) { ++ storage.remove(entity); ++ ++ return (Bee) list.get(0).getBukkitEntity(); ++ } ++ } ++ ++ return null; ++ } ++ ++ @Override ++ public List> getEntities() { ++ return new ArrayList<>(storage); ++ } ++ // Purpur end ++ + @Override + public void addEntity(Bee entity) { + Preconditions.checkArgument(entity != null, "Entity must not be null"); + ++ int length = getSnapshot().getStored().size(); // Purpur + getSnapshot().addOccupant(((CraftBee) entity).getHandle(), false); ++ ++ // Purpur start - check if new bee was added, and if yes, add to stored bees ++ List s = getSnapshot().getStored(); ++ if(length < s.size()) { ++ storage.add(new org.purpurmc.purpur.entity.PurpurStoredBee(s.get(s.size() - 1), this)); ++ } ++ // Purpur end + } + // Paper start - Add EntityBlockStorage clearEntities + @Override + public void clearEntities() { + getSnapshot().clearBees(); ++ storage.clear(); // Purpur + } + // Paper end + } diff --git a/src/main/java/org/bukkit/craftbukkit/command/CraftConsoleCommandSender.java b/src/main/java/org/bukkit/craftbukkit/command/CraftConsoleCommandSender.java index 4e56018b64d11f76c8da43fd8f85c6de72204e36..9607675e6c5bff2183c4420d11fc63eeb5747fb6 100644 --- a/src/main/java/org/bukkit/craftbukkit/command/CraftConsoleCommandSender.java @@ -20535,10 +20764,10 @@ index 3d0ce0803e1da8a2681a3cb41096ac942ece54a1..bcd075a771c7f43c6d1549aeec2ccb20 return null; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEndermite.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEndermite.java -index 75c7645fb5732c43d1da15181cf5c7ee4c3ecd6c..e7f5ea4d8d72672cf03483e720c6389425f28f6d 100644 +index d657fd2c507a5b215aeab0a5f3e9c2ee892a27c8..985e9ec21c60a1f47973bd5fc53b96a6f9b7d04a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEndermite.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEndermite.java -@@ -27,12 +27,12 @@ public class CraftEndermite extends CraftMonster implements Endermite { +@@ -21,12 +21,12 @@ public class CraftEndermite extends CraftMonster implements Endermite { @Override public boolean isPlayerSpawned() { @@ -20554,13 +20783,23 @@ index 75c7645fb5732c43d1da15181cf5c7ee4c3ecd6c..e7f5ea4d8d72672cf03483e720c63894 // Paper start @Override diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 56c75029a94e8812c9e0ce5375aaa7cbcda90b87..97ea9612343e4288decd8daa9327a7e781877a8e 100644 +index 2dbe8b870fd39b4d22e9725912f443757ae70761..8973c8a3bad120e55269bf1b7b810284ad0fe14c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -209,6 +209,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { - this.entity = entity; +@@ -224,6 +224,21 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { + this.entityType = (type != null) ? type : EntityType.UNKNOWN; } ++ @Override ++ public boolean isImmuneToFire() { ++ return getHandle().fireImmune(); ++ } ++ ++ @Override ++ public void setImmuneToFire(Boolean fireImmune) { ++ getHandle().immuneToFire = fireImmune; ++ } ++ + @Override + public boolean isInDaylight() { + return getHandle().isSunBurnTick(); @@ -20569,7 +20808,7 @@ index 56c75029a94e8812c9e0ce5375aaa7cbcda90b87..97ea9612343e4288decd8daa9327a7e7 public static CraftEntity getEntity(CraftServer server, Entity entity) { /* * Order is *EXTREMELY* important -- keep it right! =D -@@ -586,6 +591,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -601,6 +616,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { // Paper end if ((!ignorePassengers && this.entity.isVehicle()) || this.entity.isRemoved()) { // Paper - Teleport passenger API @@ -20580,10 +20819,10 @@ index 56c75029a94e8812c9e0ce5375aaa7cbcda90b87..97ea9612343e4288decd8daa9327a7e7 return false; } -@@ -1442,4 +1451,37 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { - return !this.getHandle().level.noCollision(this.getHandle(), aabb); +@@ -1507,4 +1526,27 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { + return this.getHandle().getScoreboardName(); } - // Paper End - Collision API + // Paper end - entity scoreboard name + + // Purpur start + @Override @@ -20606,20 +20845,10 @@ index 56c75029a94e8812c9e0ce5375aaa7cbcda90b87..97ea9612343e4288decd8daa9327a7e7 + public boolean isRidableInWater() { + return !getHandle().dismountsUnderwater(); + } -+ -+ @Override -+ public boolean isImmuneToFire() { -+ return getHandle().fireImmune(); -+ } -+ -+ @Override -+ public void setImmuneToFire(Boolean fireImmune) { -+ getHandle().immuneToFire = fireImmune; -+ } + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -index 1b008e5217c5bbf566a213abb92e1c7c43a3a7c2..468023414b4a9119a3418b8e8a5e38375bbd2407 100644 +index 7db63d9ef93902872937b69f431137336e4abc3a..05ab5d0ae25f154d16c7bf107e93ed8e31e1f992 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -266,6 +266,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { @@ -20631,12 +20860,12 @@ index 1b008e5217c5bbf566a213abb92e1c7c43a3a7c2..468023414b4a9119a3418b8e8a5e3837 @Override diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftIronGolem.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftIronGolem.java -index 2966d4d466f44751b2f02afda2273a708c12b251..55f19324f92f98e497da49d3022e0edfc2351461 100644 +index 75d10b5322eb0a62bce2855c04a5151eb857d7de..208018981a2a5666c455eb34614b03f617354165 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftIronGolem.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftIronGolem.java -@@ -33,4 +33,17 @@ public class CraftIronGolem extends CraftGolem implements IronGolem { - public EntityType getType() { - return EntityType.IRON_GOLEM; +@@ -27,4 +27,17 @@ public class CraftIronGolem extends CraftGolem implements IronGolem { + public void setPlayerCreated(boolean playerCreated) { + this.getHandle().setPlayerCreated(playerCreated); } + + // Purpur start @@ -20653,12 +20882,12 @@ index 2966d4d466f44751b2f02afda2273a708c12b251..55f19324f92f98e497da49d3022e0edf + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java -index a925b5c490e7129b27370aa57b5fad1cf05530c6..ea15690da167ec5e653da6f5afb55b33c45d1622 100644 +index 5e83fabb20bc2b0668cbf48530053ca1bb9092f3..4ffb4046b63cbc140c76721f51c9a7a09e81844d 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java -@@ -160,4 +160,51 @@ public class CraftItem extends CraftEntity implements Item { - public EntityType getType() { - return EntityType.DROPPED_ITEM; +@@ -154,4 +154,51 @@ public class CraftItem extends CraftEntity implements Item { + public String toString() { + return "CraftItem"; } + + // Purpur start @@ -20709,19 +20938,19 @@ index a925b5c490e7129b27370aa57b5fad1cf05530c6..ea15690da167ec5e653da6f5afb55b33 + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index d43859f8aa7beed82dd3a146bb1086982cd0cda7..7ef5980f7321662aa7034a74c2f6926846425db9 100644 +index f0ce29d21fe9af803ce4e41b8c037b2ec5d1b124..99dd93c066d4acc177de7f03ae45e491b535f4d1 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -444,7 +444,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -453,7 +453,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { net.minecraft.server.level.ServerPlayer entityPlayer = killer == null ? null : ((CraftPlayer) killer).getHandle(); getHandle().lastHurtByPlayer = entityPlayer; getHandle().lastHurtByMob = entityPlayer; - getHandle().lastHurtByPlayerTime = entityPlayer == null ? 0 : 100; // 100 value taken from EntityLiving#damageEntity -+ getHandle().lastHurtByPlayerTime = entityPlayer == null ? 0 : getHandle().level.purpurConfig.mobLastHurtByPlayerTime; // 100 value taken from EntityLiving#damageEntity // Purpur ++ getHandle().lastHurtByPlayerTime = entityPlayer == null ? 0 : getHandle().level().purpurConfig.mobLastHurtByPlayerTime; // 100 value taken from EntityLiving#damageEntity // Purpur } // Paper end -@@ -456,7 +456,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -465,7 +465,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { @Override public boolean addPotionEffect(PotionEffect effect, boolean force) { org.spigotmc.AsyncCatcher.catchOp("effect add"); // Paper @@ -20730,7 +20959,7 @@ index d43859f8aa7beed82dd3a146bb1086982cd0cda7..7ef5980f7321662aa7034a74c2f69268 return true; } -@@ -477,7 +477,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -486,7 +486,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { @Override public PotionEffect getPotionEffect(PotionEffectType type) { MobEffectInstance handle = this.getHandle().getEffect(MobEffect.byId(type.getId())); @@ -20739,7 +20968,7 @@ index d43859f8aa7beed82dd3a146bb1086982cd0cda7..7ef5980f7321662aa7034a74c2f69268 } @Override -@@ -489,7 +489,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -498,7 +498,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { public Collection getActivePotionEffects() { List effects = new ArrayList(); for (MobEffectInstance handle : this.getHandle().activeEffects.values()) { @@ -20748,7 +20977,7 @@ index d43859f8aa7beed82dd3a146bb1086982cd0cda7..7ef5980f7321662aa7034a74c2f69268 } return effects; } -@@ -884,7 +884,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -907,7 +907,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { return EntityCategory.WATER; } @@ -20757,7 +20986,7 @@ index d43859f8aa7beed82dd3a146bb1086982cd0cda7..7ef5980f7321662aa7034a74c2f69268 } @Override -@@ -1071,4 +1071,32 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -1094,4 +1094,32 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { getHandle().knockback(strength, directionX, directionZ); }; // Paper end @@ -20791,10 +21020,10 @@ index d43859f8aa7beed82dd3a146bb1086982cd0cda7..7ef5980f7321662aa7034a74c2f69268 + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java -index 4d7a2c4c1001aefe9fcd4be8dbcb414f721bfff9..2c7716a9d65ebda209a144b82c2126b602aa9182 100644 +index 0ad16ee7b33582d214dab41eeee378d52c8e38ed..16bd1294c219f15ada653ef810bc2d748222d0da 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java -@@ -96,4 +96,16 @@ public class CraftLlama extends CraftChestedHorse implements Llama, com.destroys +@@ -90,4 +90,16 @@ public class CraftLlama extends CraftChestedHorse implements Llama, com.destroys return this.getHandle().caravanTail == null ? null : (Llama) this.getHandle().caravanTail.getBukkitEntity(); } // Paper end @@ -20812,10 +21041,10 @@ index 4d7a2c4c1001aefe9fcd4be8dbcb414f721bfff9..2c7716a9d65ebda209a144b82c2126b6 + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index be64633c8bcee96f2ad5247525cac965b7b031b1..e363891e8ab872ed24c557e3f94110f36c6fb277 100644 +index 4e6fea7cf11b1e29ae7c7098a6f5d06bb5f93cc2..668d825a2469706e4de11629a0b41877de700ca6 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -534,10 +534,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -517,10 +517,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setPlayerListName(String name) { @@ -20832,7 +21061,7 @@ index be64633c8bcee96f2ad5247525cac965b7b031b1..e363891e8ab872ed24c557e3f94110f3 for (ServerPlayer player : (List) server.getHandle().players) { if (player.getBukkitEntity().canSee(this)) { player.connection.send(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME, this.getHandle())); -@@ -1358,6 +1363,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1350,6 +1355,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } if (entity.isVehicle() && !ignorePassengers) { // Paper - Teleport API @@ -20843,7 +21072,7 @@ index be64633c8bcee96f2ad5247525cac965b7b031b1..e363891e8ab872ed24c557e3f94110f3 return false; } -@@ -2405,6 +2414,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2496,6 +2505,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return this.getHandle().getAbilities().walkingSpeed * 2f; } @@ -20870,9 +21099,9 @@ index be64633c8bcee96f2ad5247525cac965b7b031b1..e363891e8ab872ed24c557e3f94110f3 + // Purpur end - OfflinePlayer API + private void validateSpeed(float value) { - if (value < 0) { - if (value < -1f) { -@@ -3180,4 +3211,97 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + Preconditions.checkArgument(value <= 1f && value >= -1f, "Speed value (%s) need to be between -1f and 1f", value); + } +@@ -3267,4 +3298,90 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return this.spigot; } // Spigot end @@ -20958,25 +21187,18 @@ index be64633c8bcee96f2ad5247525cac965b7b031b1..e363891e8ab872ed24c557e3f94110f3 + + @Override + public void sendDeathScreen(net.kyori.adventure.text.Component message) { -+ sendDeathScreen(message, null); -+ } -+ -+ @Override -+ public void sendDeathScreen(net.kyori.adventure.text.Component message, org.bukkit.entity.Entity killer) { + if (this.getHandle().connection == null) return; -+ net.minecraft.network.protocol.game.ClientboundPlayerCombatKillPacket packet = new net.minecraft.network.protocol.game.ClientboundPlayerCombatKillPacket(getEntityId(), killer == null ? -1 : killer.getEntityId(), null); -+ packet.adventure$message = message; -+ this.getHandle().connection.send(packet); ++ this.getHandle().connection.send(new net.minecraft.network.protocol.game.ClientboundPlayerCombatKillPacket(getEntityId(), io.papermc.paper.adventure.PaperAdventure.asVanilla(message))); + } + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java -index 42b7058d93fab8cbee49dba130734e1df9910096..5c6f55527cc0016f09b443528463b3906c433f8b 100644 +index e4a14cdfeb91a3d32e622d27d612605b1bca08e2..898d934aafd6066df45f02fe3406fa83f79b745c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java -@@ -34,4 +34,17 @@ public class CraftSnowman extends CraftGolem implements Snowman, com.destroystok - public EntityType getType() { - return EntityType.SNOWMAN; +@@ -28,4 +28,17 @@ public class CraftSnowman extends CraftGolem implements Snowman, com.destroystok + public String toString() { + return "CraftSnowman"; } + + // Purpur start @@ -20993,10 +21215,10 @@ index 42b7058d93fab8cbee49dba130734e1df9910096..5c6f55527cc0016f09b443528463b390 + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java -index 4e880409b06086568627f3e930159f1abb979984..48fb7302b54f8e7f5c424210b550c03d4d071ea9 100644 +index f29e221e5b850516c169c03bfbd2b0885d1a841b..9e343d6e6393db17748fd13d76354464e128001f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java -@@ -223,4 +223,11 @@ public class CraftVillager extends CraftAbstractVillager implements Villager { +@@ -216,4 +216,11 @@ public class CraftVillager extends CraftAbstractVillager implements Villager { getHandle().getGossips().gossips.clear(); } // Paper end @@ -21009,10 +21231,10 @@ index 4e880409b06086568627f3e930159f1abb979984..48fb7302b54f8e7f5c424210b550c03d + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java -index 1a21d30620f13a48976da5ead7edab201ea68b21..a50a04dc2009515032058562627eba8e4406c5bb 100644 +index 5a97c92f9b044d8ab7bd3346ceb464455a09046e..e30d8b80734f04b1fa89e8a3cef666116fd7366c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java -@@ -105,4 +105,17 @@ public class CraftWither extends CraftMonster implements Wither, com.destroystok +@@ -99,4 +99,17 @@ public class CraftWither extends CraftMonster implements Wither, com.destroystok this.getHandle().makeInvulnerable(); } // Paper end @@ -21031,10 +21253,10 @@ index 1a21d30620f13a48976da5ead7edab201ea68b21..a50a04dc2009515032058562627eba8e + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java -index e43fd3e59fd8c74828ae65965fade27f56beef65..b2f133c8baabba1cffa6e92ea0f854532f4c181b 100644 +index e16459c9cfcac790edd6d912750d32c68387cbbc..890938ad866e2c588f3f819230ba121b0b436401 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java -@@ -63,4 +63,16 @@ public class CraftWolf extends CraftTameableAnimal implements Wolf { +@@ -57,4 +57,16 @@ public class CraftWolf extends CraftTameableAnimal implements Wolf { public void setInterested(boolean flag) { this.getHandle().setIsInterested(flag); } @@ -21052,10 +21274,10 @@ index e43fd3e59fd8c74828ae65965fade27f56beef65..b2f133c8baabba1cffa6e92ea0f85453 + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index a153c134cf26e86d49ef419eca35994539af0db3..e9599e0f3d2122c3843ebde81743bc8d558bfd30 100644 +index 090b1ee57ddef58ca71469ad860960f66da7d5a2..5641df31686d6203a523b04406c2c85eab2240d2 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -563,6 +563,15 @@ public class CraftEventFactory { +@@ -590,6 +590,15 @@ public class CraftEventFactory { // Paper end craftServer.getPluginManager().callEvent(event); @@ -21071,7 +21293,7 @@ index a153c134cf26e86d49ef419eca35994539af0db3..e9599e0f3d2122c3843ebde81743bc8d return event; } -@@ -1000,6 +1009,7 @@ public class CraftEventFactory { +@@ -1031,6 +1040,7 @@ public class CraftEventFactory { damageCause = DamageCause.ENTITY_EXPLOSION; } event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), entity.getBukkitEntity(), damageCause, modifiers, modifierFunctions, source.isCritical()); // Paper - add critical damage API @@ -21079,7 +21301,7 @@ index a153c134cf26e86d49ef419eca35994539af0db3..e9599e0f3d2122c3843ebde81743bc8d } event.setCancelled(cancelled); -@@ -1114,6 +1124,7 @@ public class CraftEventFactory { +@@ -1145,6 +1155,7 @@ public class CraftEventFactory { } else { entity.lastDamageCancelled = true; // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Keep track if the event was canceled } @@ -21087,7 +21309,7 @@ index a153c134cf26e86d49ef419eca35994539af0db3..e9599e0f3d2122c3843ebde81743bc8d return event; } -@@ -1173,6 +1184,7 @@ public class CraftEventFactory { +@@ -1208,6 +1219,7 @@ public class CraftEventFactory { EntityDamageEvent event; if (damager != null) { event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), damagee.getBukkitEntity(), cause, modifiers, modifierFunctions, critical); // Paper - add critical damage API @@ -21096,10 +21318,10 @@ index a153c134cf26e86d49ef419eca35994539af0db3..e9599e0f3d2122c3843ebde81743bc8d event = new EntityDamageEvent(damagee.getBukkitEntity(), cause, modifiers, modifierFunctions); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java -index 04088918e172eecb8d53b0e6de9be0071ccf33b5..eddd6073e0feb7b046db1d169020ca067fdf689c 100644 +index 633e6f4922ccaf59979a22885162f42c65bf628a..15001e7c8eae3a89f9d8669be532d56b70d538ef 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java -@@ -182,8 +182,19 @@ public class CraftContainer extends AbstractContainerMenu { +@@ -181,8 +181,19 @@ public class CraftContainer extends AbstractContainerMenu { case PLAYER: case CHEST: case ENDER_CHEST: @@ -21121,18 +21343,18 @@ index 04088918e172eecb8d53b0e6de9be0071ccf33b5..eddd6073e0feb7b046db1d169020ca06 case DISPENSER: case DROPPER: diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java -index 092f6843e3b43d4c615d2eee344f5966e96ae850..cb0c851ab5fcf676da2397040835a94d4bdb4be1 100644 +index 471ae4458e7ea7c29d7551b32cec98180fbccd4e..23db63c78e9fcf86cd498b3ed36ca50253c2fe97 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java @@ -83,7 +83,7 @@ public class CraftInventory implements Inventory { @Override public void setContents(ItemStack[] items) { -- if (this.getSize() < items.length) { -+ if (false && this.getSize() < items.length) { // Purpur - throw new IllegalArgumentException("Invalid inventory size; expected " + this.getSize() + " or less"); - } +- Preconditions.checkArgument(items.length <= this.getSize(), "Invalid inventory size (%s); expected %s or less", items.length, this.getSize()); ++ // Preconditions.checkArgument(items.length <= this.getSize(), "Invalid inventory size (%s); expected %s or less", items.length, this.getSize()); // Purpur + for (int i = 0; i < this.getSize(); i++) { + if (i >= items.length) { diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java index 88d3ca586ff6905f18a8ab9f0e229f440ed44088..27dd4eb4781a3c75772860c11db886e1038cecd2 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java @@ -21174,11 +21396,11 @@ index 88d3ca586ff6905f18a8ab9f0e229f440ed44088..27dd4eb4781a3c75772860c11db886e1 + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java -index 0d4348ce1c4ec9bb779eaebf8606ea578f17d2cb..486768894f130cd23905cc7a8be16ce705667bbb 100644 +index d94ab2607d1ab657a6b37924ce5ebcbbc3984011..f594596029513426f974ba820ed4702703b667a4 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java -@@ -13,6 +13,7 @@ import net.minecraft.nbt.ListTag; - import org.apache.commons.lang.Validate; +@@ -13,6 +13,7 @@ import net.minecraft.nbt.CompoundTag; + import net.minecraft.nbt.ListTag; import org.bukkit.Color; import org.bukkit.Material; +import org.bukkit.NamespacedKey; @@ -21193,7 +21415,7 @@ index 0d4348ce1c4ec9bb779eaebf8606ea578f17d2cb..486768894f130cd23905cc7a8be16ce7 // Having an initial "state" in ItemMeta seems bit dirty but the UNCRAFTABLE potion type // is treated as the empty form of the meta because it represents an empty potion with no effect -@@ -92,7 +94,13 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { +@@ -91,7 +93,13 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { boolean ambient = effect.getBoolean(AMBIENT.NBT); boolean particles = effect.contains(SHOW_PARTICLES.NBT, CraftMagicNumbers.NBT.TAG_BYTE) ? effect.getBoolean(SHOW_PARTICLES.NBT) : true; boolean icon = effect.contains(SHOW_ICON.NBT, CraftMagicNumbers.NBT.TAG_BYTE) ? effect.getBoolean(SHOW_ICON.NBT) : particles; @@ -21208,7 +21430,7 @@ index 0d4348ce1c4ec9bb779eaebf8606ea578f17d2cb..486768894f130cd23905cc7a8be16ce7 } } } -@@ -141,6 +149,11 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { +@@ -138,6 +146,11 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { effectData.putBoolean(AMBIENT.NBT, effect.isAmbient()); effectData.putBoolean(SHOW_PARTICLES.NBT, effect.hasParticles()); effectData.putBoolean(SHOW_ICON.NBT, effect.hasIcon()); @@ -21220,7 +21442,7 @@ index 0d4348ce1c4ec9bb779eaebf8606ea578f17d2cb..486768894f130cd23905cc7a8be16ce7 effectList.add(effectData); } } -@@ -202,7 +215,7 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { +@@ -199,7 +212,7 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { if (index != -1) { if (overwrite) { PotionEffect old = this.customEffects.get(index); @@ -21230,10 +21452,10 @@ index 0d4348ce1c4ec9bb779eaebf8606ea578f17d2cb..486768894f130cd23905cc7a8be16ce7 } this.customEffects.set(index, effect); diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java -index 8563fcf77eef0e1e354857b9a4256d78a523a8d0..b94c964790433cb7bd88ad16c5d82d1a8e39312d 100644 +index 13d25d118eb4d3ef35a4cdfb9bbde9ed83f6c04b..553ecc9b5631ffc0848a798bb3295f16d1722c1f 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java -@@ -29,6 +29,7 @@ public interface CraftRecipe extends Recipe { +@@ -30,6 +30,7 @@ public interface CraftRecipe extends Recipe { } else if (bukkit instanceof RecipeChoice.ExactChoice) { stack = new Ingredient(((RecipeChoice.ExactChoice) bukkit).getChoices().stream().map((mat) -> new net.minecraft.world.item.crafting.Ingredient.ItemValue(CraftItemStack.asNMSCopy(mat)))); stack.exact = true; @@ -21242,7 +21464,7 @@ index 8563fcf77eef0e1e354857b9a4256d78a523a8d0..b94c964790433cb7bd88ad16c5d82d1a throw new IllegalArgumentException("Unknown recipe stack instance " + bukkit); } diff --git a/src/main/java/org/bukkit/craftbukkit/legacy/CraftLegacy.java b/src/main/java/org/bukkit/craftbukkit/legacy/CraftLegacy.java -index 110503062b3043cffa082a1cda6b8d57152869aa..3e7e06bd5e9e4ed45c9e3452eb04e946fac817d8 100644 +index 2677e21d8239bf0361a3bc5c9a50c328e54d70f6..544a79d5da661aff19e2019f7b83a3a49350bb68 100644 --- a/src/main/java/org/bukkit/craftbukkit/legacy/CraftLegacy.java +++ b/src/main/java/org/bukkit/craftbukkit/legacy/CraftLegacy.java @@ -256,6 +256,7 @@ public final class CraftLegacy { @@ -21253,6 +21475,21 @@ index 110503062b3043cffa082a1cda6b8d57152869aa..3e7e06bd5e9e4ed45c9e3452eb04e946 LOGGER.warn("Initializing Legacy Material Support. Unless you have legacy plugins and/or data this is a bug!"); // Paper - doesn't need to be an error if (MinecraftServer.getServer() != null && MinecraftServer.getServer().isDebugging()) { new Exception().printStackTrace(); +diff --git a/src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java b/src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java +index 9683d7d103af66fffd68c11abc38fb4fd2f99482..18a4de76021ff8b500801ef0121003f8dd62a961 100644 +--- a/src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java ++++ b/src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java +@@ -46,4 +46,10 @@ public class CraftMapRenderer extends MapRenderer { + } + } + ++ // Purpur - start ++ @Override ++ public boolean isExplorerMap() { ++ return this.worldMap.isExplorerMap; ++ } ++ // Purpur - end + } diff --git a/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionUtil.java b/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionUtil.java index acb69821a99aa69bce6d127e10976089c85be223..c5abd73981c5f4b41605eba0d44e6573dfd2a77a 100644 --- a/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionUtil.java @@ -21276,19 +21513,19 @@ index acb69821a99aa69bce6d127e10976089c85be223..c5abd73981c5f4b41605eba0d44e6573 public static boolean equals(MobEffect mobEffect, PotionEffectType type) { diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java -index cdefb2025eedea7e204d70d568adaf1c1ec4c03c..5402098dce0d64d3dceea51f248d7d366850a74f 100644 +index d7ce4971d9271dbeff4adb9d852e4e7bdf60bf03..a4567188e2fe3f922bb6aeb71a2845d1a1be536f 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java -@@ -504,7 +504,7 @@ public class CraftScheduler implements BukkitScheduler { +@@ -501,7 +501,7 @@ public class CraftScheduler implements BukkitScheduler { this.parsePending(); } else { - //this.debugTail = this.debugTail.setNext(new CraftAsyncDebugger(currentTick + CraftScheduler.RECENT_TICKS, task.getOwner(), task.getTaskClass())); // Paper + // this.debugTail = this.debugTail.setNext(new CraftAsyncDebugger(currentTick + CraftScheduler.RECENT_TICKS, task.getOwner(), task.getTaskClass())); // Paper - task.getOwner().getLogger().log(Level.SEVERE, "Unexpected Async Task in the Sync Scheduler. Report this to Paper"); // Paper + task.getOwner().getLogger().log(Level.SEVERE, "Unexpected Async Task in the Sync Scheduler. Report this to Purpur"); // Paper // Purpur // We don't need to parse pending // (async tasks must live with race-conditions if they attempt to cancel between these few lines of code) } -@@ -516,10 +516,10 @@ public class CraftScheduler implements BukkitScheduler { +@@ -513,10 +513,10 @@ public class CraftScheduler implements BukkitScheduler { this.runners.remove(task.getTaskId()); } } @@ -21301,7 +21538,7 @@ index cdefb2025eedea7e204d70d568adaf1c1ec4c03c..5402098dce0d64d3dceea51f248d7d36 //this.debugHead = this.debugHead.getNextHead(currentTick); // Paper } -@@ -563,7 +563,7 @@ public class CraftScheduler implements BukkitScheduler { +@@ -559,7 +559,7 @@ public class CraftScheduler implements BukkitScheduler { } void parsePending() { // Paper @@ -21310,7 +21547,7 @@ index cdefb2025eedea7e204d70d568adaf1c1ec4c03c..5402098dce0d64d3dceea51f248d7d36 CraftTask head = this.head; CraftTask task = head.getNext(); CraftTask lastTask = head; -@@ -582,7 +582,7 @@ public class CraftScheduler implements BukkitScheduler { +@@ -578,7 +578,7 @@ public class CraftScheduler implements BukkitScheduler { task.setNext(null); } this.head = lastTask; @@ -21340,7 +21577,7 @@ index 3f45bab0e9f7b3697e6d9d1092a1e6e579f7066f..4f1cf281c4bf68c37982d390da8779de long getCreatedAt() { diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java -index 138407c2d4b0bc55ddb9aac5d2aa3edadda090fb..a6e9e503a496c18e2501b03ec84f4600c134a50c 100644 +index 500f2eb0df5a07637cd278c263e95592b0037eb6..895431584c476067790f1f131699d49eac3f4b8f 100644 --- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java +++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java @@ -115,7 +115,7 @@ public final class CraftScoreboardManager implements ScoreboardManager { @@ -21362,15 +21599,15 @@ index 138407c2d4b0bc55ddb9aac5d2aa3edadda090fb..a6e9e503a496c18e2501b03ec84f4600 // Paper end - add timings for scoreboard search } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 1ecf065c5323f65401412cb98d4a0b622f356759..1bf9a11abf7884a421374cbca5ccc18480717b79 100644 +index 2b4581f92543c11f31bcc1417e90d7f90b2aea20..ffca5970a6259b024c9aa935e22cf72ed8cd8e9f 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -472,7 +472,7 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -470,7 +470,7 @@ public final class CraftMagicNumbers implements UnsafeValues { @Override public com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() { - return new gg.pufferfish.pufferfish.PufferfishVersionFetcher(); // Pufferfish -+ return new com.destroystokyo.paper.PaperVersionFetcher(); // Purpur ++ return new com.destroystokyo.paper.PaperVersionFetcher(); // Pufferfish // Purpur } @Override @@ -21388,7 +21625,7 @@ index 80553face9c70c2a3d897681e7761df85b22d464..99597258e8e88cd9e2c901c4ac3ff7fa if (stream != null) { diff --git a/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java b/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java -index ec771c480156db393c326fa2fbdc2d432fb76f53..71940bf3a4162d12a422a5b3100ad8def85f95ac 100644 +index 2959f713ce75a1df9c6c7cf5e021690cfcb6e1e7..3fa9539cfb2c35beeba6d44fa05cee971444b7d0 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java +++ b/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java @@ -23,7 +23,15 @@ public final class CommandPermissions { @@ -21405,15 +21642,15 @@ index ec771c480156db393c326fa2fbdc2d432fb76f53..71940bf3a4162d12a422a5b3100ad8de + gamemodeVanilla.addParent(gamemodeSelf, true); + } + // Purpur end - DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "xp", "Allows the user to give themselves or others arbitrary values of experience", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "experience", "Allows the user to give themselves or others arbitrary values of experience", PermissionDefault.OP, commands); // Paper - wrong permission; redirects are de-redirected and the root literal name is used, so xp -> experience DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "defaultgamemode", "Allows the user to change the default gamemode of the server", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "seed", "Allows the user to view the seed of the world", PermissionDefault.OP, commands); diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java new file mode 100644 -index 0000000000000000000000000000000000000000..be8b44daa0141151c973917a774aa07721647ed1 +index 0000000000000000000000000000000000000000..3633574e112f217b412217dd243a631dc4e9c40c --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java -@@ -0,0 +1,638 @@ +@@ -0,0 +1,655 @@ +package org.purpurmc.purpur; + +import com.google.common.base.Throwables; @@ -21491,8 +21728,8 @@ index 0000000000000000000000000000000000000000..be8b44daa0141151c973917a774aa077 + commands = new HashMap<>(); + commands.put("purpur", new PurpurCommand("purpur")); + -+ version = getInt("config-version", 32); -+ set("config-version", 32); ++ version = getInt("config-version", 33); ++ set("config-version", 33); + + readConfig(PurpurConfig.class, null); + @@ -21606,6 +21843,7 @@ index 0000000000000000000000000000000000000000..be8b44daa0141151c973917a774aa077 + public static String unverifiedUsername = "default"; + public static String sleepSkippingNight = "default"; + public static String sleepingPlayersPercent = "default"; ++ public static String sleepNotPossible = "default"; + private static void messages() { + cannotRideMob = getString("settings.messages.cannot-ride-mob", cannotRideMob); + afkBroadcastAway = getString("settings.messages.afk-broadcast-away", afkBroadcastAway); @@ -21624,6 +21862,7 @@ index 0000000000000000000000000000000000000000..be8b44daa0141151c973917a774aa077 + unverifiedUsername = getString("settings.messages.unverified-username", unverifiedUsername); + sleepSkippingNight = getString("settings.messages.sleep-skipping-night", sleepSkippingNight); + sleepingPlayersPercent = getString("settings.messages.sleeping-players-percent", sleepingPlayersPercent); ++ sleepNotPossible = getString("settings.messages.sleep-not-possible", sleepNotPossible); + } + + public static String deathMsgRunWithScissors = " slipped and fell on their shears"; @@ -21831,12 +22070,12 @@ index 0000000000000000000000000000000000000000..be8b44daa0141151c973917a774aa077 + public static boolean allowInfinityMending = false; + public static boolean allowCrossbowInfinity = false; + public static boolean allowShearsLooting = false; -+ public static boolean allowTransparentBlocksInEnchantmentBox = false; + public static boolean allowUnsafeEnchants = false; + public static boolean allowInapplicableEnchants = true; + public static boolean allowIncompatibleEnchants = true; + public static boolean allowHigherEnchantsLevels = true; + public static boolean allowUnsafeEnchantCommand = false; ++ public static boolean replaceIncompatibleEnchants = false; + public static boolean clampEnchantLevels = true; + private static void enchantmentSettings() { + if (version < 5) { @@ -21855,12 +22094,12 @@ index 0000000000000000000000000000000000000000..be8b44daa0141151c973917a774aa077 + allowInfinityMending = getBoolean("settings.enchantment.allow-infinity-and-mending-together", allowInfinityMending); + allowCrossbowInfinity = getBoolean("settings.enchantment.allow-infinity-on-crossbow", allowCrossbowInfinity); + allowShearsLooting = getBoolean("settings.enchantment.allow-looting-on-shears", allowShearsLooting); -+ allowTransparentBlocksInEnchantmentBox = getBoolean("settings.enchantment.allow-transparent-blocks-in-enchantment-box", allowTransparentBlocksInEnchantmentBox); + allowUnsafeEnchants = getBoolean("settings.enchantment.anvil.allow-unsafe-enchants", allowUnsafeEnchants); + allowInapplicableEnchants = getBoolean("settings.enchantment.anvil.allow-inapplicable-enchants", allowInapplicableEnchants); + allowIncompatibleEnchants = getBoolean("settings.enchantment.anvil.allow-incompatible-enchants", allowIncompatibleEnchants); + allowHigherEnchantsLevels = getBoolean("settings.enchantment.anvil.allow-higher-enchants-levels", allowHigherEnchantsLevels); + allowUnsafeEnchantCommand = getBoolean("settings.enchantment.allow-unsafe-enchant-command", allowUnsafeEnchants); // allowUnsafeEnchants as default for backwards compatability ++ replaceIncompatibleEnchants = getBoolean("settings.enchantment.anvil.replace-incompatible-enchants", replaceIncompatibleEnchants); + clampEnchantLevels = getBoolean("settings.enchantment.clamp-levels", clampEnchantLevels); + } + @@ -21875,15 +22114,6 @@ index 0000000000000000000000000000000000000000..be8b44daa0141151c973917a774aa077 + allowWaterPlacementInTheEnd = getBoolean("settings.allow-water-placement-in-the-end", allowWaterPlacementInTheEnd); + } + -+ public static boolean disableMushroomBlockUpdates = false; -+ public static boolean disableNoteBlockUpdates = false; -+ public static boolean disableChorusPlantUpdates = false; -+ private static void blockUpdatesSettings() { -+ disableMushroomBlockUpdates = getBoolean("settings.blocks.disable-mushroom-updates", disableMushroomBlockUpdates); -+ disableNoteBlockUpdates = getBoolean("settings.blocks.disable-note-block-updates", disableNoteBlockUpdates); -+ disableChorusPlantUpdates = getBoolean("settings.blocks.disable-chorus-plant-updates", disableChorusPlantUpdates); -+ } -+ + public static boolean loggerSuppressInitLegacyMaterialError = false; + public static boolean loggerSuppressIgnoredAdvancementWarnings = false; + public static boolean loggerSuppressUnrecognizedRecipeErrors = false; @@ -21925,6 +22155,17 @@ index 0000000000000000000000000000000000000000..be8b44daa0141151c973917a774aa077 + config.addDefault("settings.food-properties", new HashMap<>()); + return; + } ++ ++ Map> effectDefaults = new HashMap<>(); ++ Map EFFECT_DEFAULT = Map.of( ++ "chance", 0.0F, ++ "duration", 0, ++ "amplifier", 0, ++ "ambient", false, ++ "visible", true, ++ "show-icon", true ++ ); ++ + properties.getKeys(false).forEach(foodKey -> { + FoodProperties food = Foods.ALL_PROPERTIES.get(foodKey); + if (food == null) { @@ -21939,15 +22180,17 @@ index 0000000000000000000000000000000000000000..be8b44daa0141151c973917a774aa077 + food.setFastFood(properties.getBoolean(foodKey + ".fast-food", foodDefaults.isFastFood())); + ConfigurationSection effects = properties.getConfigurationSection(foodKey + ".effects"); + if (effects != null) { -+ Map effectDefaults = new HashMap<>(); ++ effectDefaults.clear(); + foodDefaults.getEffects().forEach(pair -> { -+ effectDefaults.put("chance", pair.getSecond()); + MobEffectInstance effect = pair.getFirst(); -+ effectDefaults.put("duration", effect.getDuration()); -+ effectDefaults.put("amplifier", effect.getAmplifier()); -+ effectDefaults.put("ambient", effect.isAmbient()); -+ effectDefaults.put("visible", effect.isVisible()); -+ effectDefaults.put("show-icon", effect.showIcon()); ++ effectDefaults.put(effect.getEffect(), Map.of( ++ "chance", pair.getSecond(), ++ "duration", effect.getDuration(), ++ "amplifier", effect.getAmplifier(), ++ "ambient", effect.isAmbient(), ++ "visible", effect.isVisible(), ++ "show-icon", effect.showIcon() ++ )); + }); + effects.getKeys(false).forEach(effectKey -> { + MobEffect effect = BuiltInRegistries.MOB_EFFECT.get(new ResourceLocation(effectKey)); @@ -21955,16 +22198,22 @@ index 0000000000000000000000000000000000000000..be8b44daa0141151c973917a774aa077 + PurpurConfig.log(Level.SEVERE, "Invalid food property effect for " + foodKey + ": " + effectKey); + return; + } ++ ++ Map effectDefault = effectDefaults.get(effect); ++ if (effectDefault == null) { ++ effectDefault = EFFECT_DEFAULT; ++ } ++ + food.getEffects().removeIf(pair -> pair.getFirst().getEffect() == effect); -+ float chance = (float) effects.getDouble(effectKey + ".chance", ((Float) effectDefaults.get("chance")).doubleValue()); -+ int duration = effects.getInt(effectKey + ".duration", (int) effectDefaults.get("duration")); ++ float chance = (float) effects.getDouble(effectKey + ".chance", ((Float) effectDefault.get("chance")).doubleValue()); ++ int duration = effects.getInt(effectKey + ".duration", (int) effectDefault.get("duration")); + if (chance <= 0.0F || duration < 0) { + return; + } -+ int amplifier = effects.getInt(effectKey + ".amplifier", (int) effectDefaults.get("amplifier")); -+ boolean ambient = effects.getBoolean(effectKey + ".ambient", (boolean) effectDefaults.get("ambient")); -+ boolean visible = effects.getBoolean(effectKey + ".visible", (boolean) effectDefaults.get("visible")); -+ boolean showIcon = effects.getBoolean(effectKey + ".show-icon", (boolean) effectDefaults.get("show-icon")); ++ int amplifier = effects.getInt(effectKey + ".amplifier", (int) effectDefault.get("amplifier")); ++ boolean ambient = effects.getBoolean(effectKey + ".ambient", (boolean) effectDefault.get("ambient")); ++ boolean visible = effects.getBoolean(effectKey + ".visible", (boolean) effectDefault.get("visible")); ++ boolean showIcon = effects.getBoolean(effectKey + ".show-icon", (boolean) effectDefault.get("show-icon")); + food.getEffects().add(Pair.of(new MobEffectInstance(effect, duration, amplifier, ambient, visible, showIcon), chance)); + }); + } @@ -22051,13 +22300,18 @@ index 0000000000000000000000000000000000000000..be8b44daa0141151c973917a774aa077 + block.fallDistanceMultiplier = fallDistanceMultiplier.floatValue(); + }); + } ++ ++ public static boolean playerDeathsAlwaysShowItem = false; ++ private static void playerDeathsAlwaysShowItem() { ++ playerDeathsAlwaysShowItem = getBoolean("settings.player-deaths-always-show-item", playerDeathsAlwaysShowItem); ++ } +} diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java new file mode 100644 -index 0000000000000000000000000000000000000000..397c4afa8da85845f49974832674a6e45ee6edb7 +index 0000000000000000000000000000000000000000..078102e636803f38facc049952813ff2f8b63594 --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -@@ -0,0 +1,3203 @@ +@@ -0,0 +1,3239 @@ +package org.purpurmc.purpur; + +import net.minecraft.core.registries.BuiltInRegistries; @@ -22068,11 +22322,10 @@ index 0000000000000000000000000000000000000000..397c4afa8da85845f49974832674a6e4 +import net.minecraft.world.item.DyeColor; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.Items; -+import net.minecraft.world.level.Explosion; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.properties.Tilt; -+import org.purpurmc.purpur.entity.GlowSquidColor; ++import org.purpurmc.purpur.tool.Flattenable; +import org.purpurmc.purpur.tool.Strippable; +import org.purpurmc.purpur.tool.Tillable; +import org.purpurmc.purpur.tool.Waxable; @@ -22084,7 +22337,6 @@ index 0000000000000000000000000000000000000000..397c4afa8da85845f49974832674a6e4 +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; -+import java.util.Locale; +import java.util.Map; +import java.util.function.Predicate; +import java.util.logging.Level; @@ -22593,21 +22845,6 @@ index 0000000000000000000000000000000000000000..397c4afa8da85845f49974832674a6e4 + snowballDamage = getInt("gameplay-mechanics.projectile-damage.snowball", snowballDamage); + } + -+ public List shovelTurnsBlockToGrassPath = new ArrayList<>(); -+ private void shovelSettings() { -+ getList("gameplay-mechanics.shovel-turns-block-to-grass-path", new ArrayList(){{ -+ add("minecraft:coarse_dirt"); -+ add("minecraft:dirt"); -+ add("minecraft:grass_block"); -+ add("minecraft:mycelium"); -+ add("minecraft:podzol"); -+ add("minecraft:rooted_dirt"); -+ }}).forEach(key -> { -+ Block block = BuiltInRegistries.BLOCK.get(new ResourceLocation(key.toString())); -+ if (block != Blocks.AIR) shovelTurnsBlockToGrassPath.add(block); -+ }); -+ } -+ + public boolean silkTouchEnabled = false; + public String silkTouchSpawnerName = "Monster Spawner"; + public List silkTouchSpawnerLore = new ArrayList<>(); @@ -22630,10 +22867,10 @@ index 0000000000000000000000000000000000000000..397c4afa8da85845f49974832674a6e4 + .forEach(line -> silkTouchSpawnerLore.add(line.toString())); + silkTouchTools.clear(); + getList("gameplay-mechanics.silk-touch.tools", List.of( -+ "minecraft:iron_pickaxe", -+ "minecraft:golden_pickaxe", -+ "minecraft:diamond_pickaxe", -+ "minecraft:netherite_pickaxe" ++ "minecraft:iron_pickaxe", ++ "minecraft:golden_pickaxe", ++ "minecraft:diamond_pickaxe", ++ "minecraft:netherite_pickaxe" + )).forEach(key -> { + Item item = BuiltInRegistries.ITEM.get(new ResourceLocation(key.toString())); + if (item != Items.AIR) silkTouchTools.add(item); @@ -22644,6 +22881,7 @@ index 0000000000000000000000000000000000000000..397c4afa8da85845f49974832674a6e4 + public Map axeWaxables = new HashMap<>(); + public Map axeWeatherables = new HashMap<>(); + public Map hoeTillables = new HashMap<>(); ++ public Map shovelFlattenables = new HashMap<>(); + public boolean hoeReplantsCrops = false; + public boolean hoeReplantsNetherWarts = false; + private void toolSettings() { @@ -22651,6 +22889,7 @@ index 0000000000000000000000000000000000000000..397c4afa8da85845f49974832674a6e4 + axeWaxables.clear(); + axeWeatherables.clear(); + hoeTillables.clear(); ++ shovelFlattenables.clear(); + if (PurpurConfig.version < 18) { + ConfigurationSection section = PurpurConfig.config.getConfigurationSection("world-settings." + worldName + ".tools.hoe.tilling"); + if (section != null) { @@ -22672,6 +22911,19 @@ index 0000000000000000000000000000000000000000..397c4afa8da85845f49974832674a6e4 + PurpurConfig.config.set("world-settings.default.tools.axe.strippables.minecraft:cherry_wood", Map.of("into", "minecraft:stripped_cherry_wood", "drops", new HashMap())); + PurpurConfig.config.set("world-settings.default.tools.axe.strippables.minecraft:bamboo_block", Map.of("into", "minecraft:stripped_bamboo_block", "drops", new HashMap())); + } ++ if (PurpurConfig.version < 33) { ++ getList("gameplay-mechanics.shovel-turns-block-to-grass-path", new ArrayList(){{ ++ add("minecraft:coarse_dirt"); ++ add("minecraft:dirt"); ++ add("minecraft:grass_block"); ++ add("minecraft:mycelium"); ++ add("minecraft:podzol"); ++ add("minecraft:rooted_dirt"); ++ }}).forEach(key -> { ++ PurpurConfig.config.set("world-settings.default.tools.shovel.flattenables." + key.toString(), Map.of("into", "minecraft:dirt_path", "drops", new HashMap())); ++ }); ++ set("gameplay-mechanics.shovel-turns-block-to-grass-path", null); ++ } + getMap("tools.axe.strippables", Map.ofEntries( + Map.entry("minecraft:oak_wood", Map.of("into", "minecraft:stripped_oak_wood", "drops", new HashMap())), + Map.entry("minecraft:oak_log", Map.of("into", "minecraft:stripped_oak_log", "drops", new HashMap())), @@ -22801,6 +23053,30 @@ index 0000000000000000000000000000000000000000..397c4afa8da85845f49974832674a6e4 + }); + hoeTillables.put(block, new Tillable(condition, into, drops)); + }); ++ getMap("tools.shovel.flattenables", Map.ofEntries( ++ Map.entry("minecraft:grass_block", Map.of("into", "minecraft:dirt_path", "drops", new HashMap())), ++ Map.entry("minecraft:dirt", Map.of("into", "minecraft:dirt_path", "drops", new HashMap())), ++ Map.entry("minecraft:podzol", Map.of("into", "minecraft:dirt_path", "drops", new HashMap())), ++ Map.entry("minecraft:coarse_dirt", Map.of("into", "minecraft:dirt_path", "drops", new HashMap())), ++ Map.entry("minecraft:mycelium", Map.of("into", "minecraft:dirt_path", "drops", new HashMap())), ++ Map.entry("minecraft:rooted_dirt", Map.of("into", "minecraft:dirt_path", "drops", new HashMap()))) ++ ).forEach((blockId, obj) -> { ++ Block block = BuiltInRegistries.BLOCK.get(new ResourceLocation(blockId)); ++ if (block == Blocks.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid block for `tools.shovel.flattenables`: " + blockId); return; } ++ if (!(obj instanceof Map map)) { PurpurConfig.log(Level.SEVERE, "Invalid yaml for `tools.shovel.flattenables." + blockId + "`"); return; } ++ String intoId = (String) map.get("into"); ++ Block into = BuiltInRegistries.BLOCK.get(new ResourceLocation(intoId)); ++ if (into == Blocks.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid block for `tools.shovel.flattenables." + blockId + ".into`: " + intoId); return; } ++ Object dropsObj = map.get("drops"); ++ if (!(dropsObj instanceof Map dropsMap)) { PurpurConfig.log(Level.SEVERE, "Invalid yaml for `tools.shovel.flattenables." + blockId + ".drops`"); return; } ++ Map drops = new HashMap<>(); ++ dropsMap.forEach((itemId, chance) -> { ++ Item item = BuiltInRegistries.ITEM.get(new ResourceLocation(itemId.toString())); ++ if (item == Items.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid item for `tools.shovel.flattenables." + blockId + ".drops`: " + itemId); return; } ++ drops.put(item, (double) chance); ++ }); ++ shovelFlattenables.put(block, new Flattenable(into, drops)); ++ }); + hoeReplantsCrops = getBoolean("tools.hoe.replant-crops", hoeReplantsCrops); + hoeReplantsNetherWarts = getBoolean("tools.hoe.replant-nether-warts", hoeReplantsNetherWarts); + } @@ -22873,11 +23149,6 @@ index 0000000000000000000000000000000000000000..397c4afa8da85845f49974832674a6e4 + }); + } + -+ public boolean buddingAmethystSilkTouch = false; -+ private void buddingAmethystSettings() { -+ buddingAmethystSilkTouch = getBoolean("blocks.budding_amethyst.silk-touch", buddingAmethystSilkTouch); -+ } -+ + public boolean cactusBreaksFromSolidNeighbors = true; + public boolean cactusAffectedByBonemeal = false; + private void cactusSettings() { @@ -22946,6 +23217,7 @@ index 0000000000000000000000000000000000000000..397c4afa8da85845f49974832674a6e4 + public boolean basedEndCrystalExplosionFire = false; + public net.minecraft.world.level.Level.ExplosionInteraction basedEndCrystalExplosionEffect = net.minecraft.world.level.Level.ExplosionInteraction.BLOCK; + public int endCrystalCramming = 0; ++ public boolean endCrystalPlaceAnywhere = false; + private void endCrystalSettings() { + if (PurpurConfig.version < 31) { + if ("DESTROY".equals(getString("blocks.end-crystal.baseless.explosion-effect", baselessEndCrystalExplosionEffect.name()))) { @@ -22974,6 +23246,7 @@ index 0000000000000000000000000000000000000000..397c4afa8da85845f49974832674a6e4 + basedEndCrystalExplosionEffect = net.minecraft.world.level.Level.ExplosionInteraction.BLOCK; + } + endCrystalCramming = getInt("blocks.end-crystal.cramming-amount", endCrystalCramming); ++ endCrystalPlaceAnywhere = getBoolean("gameplay-mechanics.item.end-crystal.place-anywhere", endCrystalPlaceAnywhere); + } + + public boolean farmlandBypassMobGriefing = false; @@ -23090,10 +23363,8 @@ index 0000000000000000000000000000000000000000..397c4afa8da85845f49974832674a6e4 + shulkerBoxAllowOversizedStacks = getBoolean("blocks.shulker_box.allow-oversized-stacks", shulkerBoxAllowOversizedStacks); + } + -+ public boolean signRightClickEdit = false; + public boolean signAllowColors = false; + private void signSettings() { -+ signRightClickEdit = getBoolean("blocks.sign.right-click-edit", signRightClickEdit); + signAllowColors = getBoolean("blocks.sign.allow-colors", signAllowColors); + } + @@ -23109,13 +23380,15 @@ index 0000000000000000000000000000000000000000..397c4afa8da85845f49974832674a6e4 + spawnerFixMC238526 = getBoolean("blocks.spawner.fix-mc-238526", spawnerFixMC238526); + } + -+ public int spongeAbsorptionArea = 64; ++ public int spongeAbsorptionArea = 65; + public int spongeAbsorptionRadius = 6; + public boolean spongeAbsorbsLava = false; ++ public boolean spongeAbsorbsWaterFromMud = false; + private void spongeSettings() { + spongeAbsorptionArea = getInt("blocks.sponge.absorption.area", spongeAbsorptionArea); + spongeAbsorptionRadius = getInt("blocks.sponge.absorption.radius", spongeAbsorptionRadius); + spongeAbsorbsLava = getBoolean("blocks.sponge.absorbs-lava", spongeAbsorbsLava); ++ spongeAbsorbsWaterFromMud = getBoolean("blocks.sponge.absorbs-water-from-mud", spongeAbsorbsWaterFromMud); + } + + public float stonecutterDamage = 0.0F; @@ -23206,6 +23479,13 @@ index 0000000000000000000000000000000000000000..397c4afa8da85845f49974832674a6e4 + set("mobs.bat.attributes.max_health", oldValue); + } + batMaxHealth = getDouble("mobs.bat.attributes.max_health", batMaxHealth); ++ batFollowRange = getDouble("mobs.bat.attributes.follow_range", batFollowRange); ++ batKnockbackResistance = getDouble("mobs.bat.attributes.knockback_resistance", batKnockbackResistance); ++ batMovementSpeed = getDouble("mobs.bat.attributes.movement_speed", batMovementSpeed); ++ batFlyingSpeed = getDouble("mobs.bat.attributes.flying_speed", batFlyingSpeed); ++ batArmor = getDouble("mobs.bat.attributes.armor", batArmor); ++ batArmorToughness = getDouble("mobs.bat.attributes.armor_toughness", batArmorToughness); ++ batAttackKnockback = getDouble("mobs.bat.attributes.attack_knockback", batAttackKnockback); + batTakeDamageFromWater = getBoolean("mobs.bat.takes-damage-from-water", batTakeDamageFromWater); + batAlwaysDropExp = getBoolean("mobs.bat.always-drop-exp", batAlwaysDropExp); + } @@ -23262,14 +23542,16 @@ index 0000000000000000000000000000000000000000..397c4afa8da85845f49974832674a6e4 + blazeAlwaysDropExp = getBoolean("mobs.blaze.always-drop-exp", blazeAlwaysDropExp); + } + -+ public int camelBreedingTicks = 6000; ++ public boolean camelRidableInWater = false; + public double camelMaxHealthMin = 32.0D; + public double camelMaxHealthMax = 32.0D; + public double camelJumpStrengthMin = 0.42D; + public double camelJumpStrengthMax = 0.42D; + public double camelMovementSpeedMin = 0.09D; + public double camelMovementSpeedMax = 0.09D; ++ public int camelBreedingTicks = 6000; + private void camelSettings() { ++ camelRidableInWater = getBoolean("mobs.camel.ridable-in-water", camelRidableInWater); + camelMaxHealthMin = getDouble("mobs.camel.attributes.max_health.min", camelMaxHealthMin); + camelMaxHealthMax = getDouble("mobs.camel.attributes.max_health.max", camelMaxHealthMax); + camelJumpStrengthMin = getDouble("mobs.camel.attributes.jump_strength.min", camelJumpStrengthMin); @@ -23305,7 +23587,7 @@ index 0000000000000000000000000000000000000000..397c4afa8da85845f49974832674a6e4 + catSpawnVillageScanRange = getInt("mobs.cat.scan-range-for-other-cats.village", catSpawnVillageScanRange); + catBreedingTicks = getInt("mobs.cat.breeding-delay-ticks", catBreedingTicks); + try { -+ catDefaultCollarColor = DyeColor.valueOf(getString("mobs.cat.default-collar-color", wolfDefaultCollarColor.name())); ++ catDefaultCollarColor = DyeColor.valueOf(getString("mobs.cat.default-collar-color", catDefaultCollarColor.name())); + } catch (IllegalArgumentException ignore) { + catDefaultCollarColor = DyeColor.RED; + } @@ -23768,7 +24050,6 @@ index 0000000000000000000000000000000000000000..397c4afa8da85845f49974832674a6e4 + public boolean glowSquidsCanFly = false; + public boolean glowSquidTakeDamageFromWater = false; + public boolean glowSquidAlwaysDropExp = false; -+ public GlowSquidColor.Mode glowSquidColorMode = GlowSquidColor.Mode.RAINBOW; + private void glowSquidSettings() { + glowSquidRidable = getBoolean("mobs.glow_squid.ridable", glowSquidRidable); + glowSquidControllable = getBoolean("mobs.glow_squid.controllable", glowSquidControllable); @@ -23776,7 +24057,6 @@ index 0000000000000000000000000000000000000000..397c4afa8da85845f49974832674a6e4 + glowSquidsCanFly = getBoolean("mobs.glow_squid.can-fly", glowSquidsCanFly); + glowSquidTakeDamageFromWater = getBoolean("mobs.glow_squid.takes-damage-from-water", glowSquidTakeDamageFromWater); + glowSquidAlwaysDropExp = getBoolean("mobs.glow_squid.always-drop-exp", glowSquidAlwaysDropExp); -+ glowSquidColorMode = GlowSquidColor.Mode.get(getString("mobs.glow_squid.rainglow-mode", glowSquidColorMode.toString())); + } + + public boolean goatRidable = false; @@ -24076,6 +24356,7 @@ index 0000000000000000000000000000000000000000..397c4afa8da85845f49974832674a6e4 + public int ocelotBreedingTicks = 6000; + public boolean ocelotTakeDamageFromWater = false; + public boolean ocelotAlwaysDropExp = false; ++ public boolean ocelotSpawnUnderSeaLevel = false; + private void ocelotSettings() { + ocelotRidable = getBoolean("mobs.ocelot.ridable", ocelotRidable); + ocelotRidableInWater = getBoolean("mobs.ocelot.ridable-in-water", ocelotRidableInWater); @@ -24089,6 +24370,7 @@ index 0000000000000000000000000000000000000000..397c4afa8da85845f49974832674a6e4 + ocelotBreedingTicks = getInt("mobs.ocelot.breeding-delay-ticks", ocelotBreedingTicks); + ocelotTakeDamageFromWater = getBoolean("mobs.ocelot.takes-damage-from-water", ocelotTakeDamageFromWater); + ocelotAlwaysDropExp = getBoolean("mobs.ocelot.always-drop-exp", ocelotAlwaysDropExp); ++ ocelotSpawnUnderSeaLevel = getBoolean("mobs.ocelot.spawn-below-sea-level", ocelotSpawnUnderSeaLevel); + } + + public boolean pandaRidable = false; @@ -24243,6 +24525,7 @@ index 0000000000000000000000000000000000000000..397c4afa8da85845f49974832674a6e4 + public int piglinPortalSpawnModifier = 2000; + public boolean piglinAlwaysDropExp = false; + public double piglinHeadVisibilityPercent = 0.5D; ++ public boolean piglinIgnoresArmorWithGoldTrim = false; + private void piglinSettings() { + piglinRidable = getBoolean("mobs.piglin.ridable", piglinRidable); + piglinRidableInWater = getBoolean("mobs.piglin.ridable-in-water", piglinRidableInWater); @@ -24258,6 +24541,7 @@ index 0000000000000000000000000000000000000000..397c4afa8da85845f49974832674a6e4 + piglinPortalSpawnModifier = getInt("mobs.piglin.portal-spawn-modifier", piglinPortalSpawnModifier); + piglinAlwaysDropExp = getBoolean("mobs.piglin.always-drop-exp", piglinAlwaysDropExp); + piglinHeadVisibilityPercent = getDouble("mobs.piglin.head-visibility-percent", piglinHeadVisibilityPercent); ++ piglinIgnoresArmorWithGoldTrim = getBoolean("mobs.piglin.ignores-armor-with-gold-trim", piglinIgnoresArmorWithGoldTrim); + } + + public boolean piglinBruteRidable = false; @@ -25259,8 +25543,14 @@ index 0000000000000000000000000000000000000000..397c4afa8da85845f49974832674a6e4 + cauldronDripstoneWaterFillChance = (float) getDouble("blocks.cauldron.fill-chances.dripstone-water", cauldronDripstoneWaterFillChance); + cauldronDripstoneLavaFillChance = (float) getDouble("blocks.cauldron.fill-chances.dripstone-lava", cauldronDripstoneLavaFillChance); + } -+} + ++ public float shearsCanDefuseTntChance = 0.00F; ++ public boolean shearsCanDefuseTnt = false; ++ private void shearsCanDefuseTntSettings() { ++ shearsCanDefuseTntChance = (float) getDouble("gameplay-mechanics.item.shears.defuse-tnt-chance", 0.00D); ++ shearsCanDefuseTnt = shearsCanDefuseTntChance > 0.00F; ++ } ++} diff --git a/src/main/java/org/purpurmc/purpur/command/CompassCommand.java b/src/main/java/org/purpurmc/purpur/command/CompassCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..79b8490832d2a0cc7846ddcb091cb6bcac74ea45 @@ -25539,7 +25829,7 @@ index 0000000000000000000000000000000000000000..2852c07adb080c34905f5d1b19efed8e +} diff --git a/src/main/java/org/purpurmc/purpur/command/RamCommand.java b/src/main/java/org/purpurmc/purpur/command/RamCommand.java new file mode 100644 -index 0000000000000000000000000000000000000000..4ea0877f92b6733035d83a186c3d02c101c9b6cd +index 0000000000000000000000000000000000000000..992f8dfc628c7485e335191e1308cdfd4eedfbe8 --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/command/RamCommand.java @@ -0,0 +1,30 @@ @@ -25561,7 +25851,7 @@ index 0000000000000000000000000000000000000000..4ea0877f92b6733035d83a186c3d02c1 + .executes(context -> { + CommandSourceStack sender = context.getSource(); + RamBarTask ramBar = RamBarTask.instance(); -+ sender.sendSuccess(PaperAdventure.asVanilla(MiniMessage.miniMessage().deserialize(PurpurConfig.ramCommandOutput, ++ sender.sendSuccess(() -> PaperAdventure.asVanilla(MiniMessage.miniMessage().deserialize(PurpurConfig.ramCommandOutput, + Placeholder.component("allocated", ramBar.format(ramBar.getAllocated())), + Placeholder.component("used", ramBar.format(ramBar.getUsed())), + Placeholder.component("xmx", ramBar.format(ramBar.getXmx())), @@ -26065,10 +26355,10 @@ index 0000000000000000000000000000000000000000..ba2a37dad43e238e54632975abea8ee6 +} diff --git a/src/main/java/org/purpurmc/purpur/entity/DolphinSpit.java b/src/main/java/org/purpurmc/purpur/entity/DolphinSpit.java new file mode 100644 -index 0000000000000000000000000000000000000000..f0279d6cdc93f524f321c3c40967fdeeb8d2c46b +index 0000000000000000000000000000000000000000..ce614ae6b1fa0b31c1ee8dacb69134bb20c949f4 --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/entity/DolphinSpit.java -@@ -0,0 +1,104 @@ +@@ -0,0 +1,106 @@ +package org.purpurmc.purpur.entity; + +import net.minecraft.core.particles.ParticleTypes; @@ -26106,16 +26396,18 @@ index 0000000000000000000000000000000000000000..f0279d6cdc93f524f321c3c40967fdee + dolphin.getZ() + (double) (dolphin.getBbWidth() + 1.0F) * 0.5D * (double) Mth.cos(dolphin.yBodyRot * 0.017453292F)); + } + ++ // Purpur start + @Override + public boolean canSaveToDisk() { + return false; + } ++ // Purpur end + + public void tick() { + super_tick(); + + Vec3 mot = this.getDeltaMovement(); -+ HitResult hitResult = ProjectileUtil.getHitResult(this, this::canHitEntity); ++ HitResult hitResult = ProjectileUtil.getHitResult(this.position(), this, this::canHitEntity, mot, level()); + + this.preOnHit(hitResult); + @@ -26127,7 +26419,7 @@ index 0000000000000000000000000000000000000000..f0279d6cdc93f524f321c3c40967fdee + + Vec3 motDouble = mot.scale(2.0); + for (int i = 0; i < 5; i++) { -+ ((ServerLevel) level).sendParticles(null, ParticleTypes.BUBBLE, ++ ((ServerLevel) level()).sendParticles(null, ParticleTypes.BUBBLE, + getX() + random.nextFloat() / 2 - 0.25F, + getY() + random.nextFloat() / 2 - 0.25F, + getZ() + random.nextFloat() / 2 - 0.25F, @@ -26159,7 +26451,7 @@ index 0000000000000000000000000000000000000000..f0279d6cdc93f524f321c3c40967fdee + protected void onHitEntity(EntityHitResult entityHitResult) { + Entity shooter = this.getOwner(); + if (shooter instanceof LivingEntity) { -+ entityHitResult.getEntity().hurt(entityHitResult.getEntity().damageSources().mobProjectile(this, (LivingEntity) shooter), level.purpurConfig.dolphinSpitDamage); ++ entityHitResult.getEntity().hurt(entityHitResult.getEntity().damageSources().mobProjectile(this, (LivingEntity) shooter), level().purpurConfig.dolphinSpitDamage); + } + } + @@ -26168,84 +26460,17 @@ index 0000000000000000000000000000000000000000..f0279d6cdc93f524f321c3c40967fdee + if (this.hitCancelled) { + return; + } -+ BlockState state = this.level.getBlockState(blockHitResult.getBlockPos()); -+ state.onProjectileHit(this.level, state, blockHitResult, this); ++ BlockState state = this.level().getBlockState(blockHitResult.getBlockPos()); ++ state.onProjectileHit(this.level(), state, blockHitResult, this); + this.discard(); + } +} -diff --git a/src/main/java/org/purpurmc/purpur/entity/GlowSquidColor.java b/src/main/java/org/purpurmc/purpur/entity/GlowSquidColor.java -new file mode 100644 -index 0000000000000000000000000000000000000000..c90256f4c16ffdb2d8e767e837ea36ac7a6613be ---- /dev/null -+++ b/src/main/java/org/purpurmc/purpur/entity/GlowSquidColor.java -@@ -0,0 +1,61 @@ -+package org.purpurmc.purpur.entity; -+ -+import net.minecraft.util.RandomSource; -+ -+import java.util.ArrayList; -+import java.util.Arrays; -+import java.util.HashMap; -+import java.util.List; -+import java.util.Locale; -+import java.util.Map; -+ -+public enum GlowSquidColor { -+ BLUE, RED, GREEN, PINK, YELLOW, ORANGE, INDIGO, PURPLE, WHITE, GRAY, BLACK; -+ -+ @Override -+ public String toString() { -+ return this.name().toLowerCase(Locale.ROOT); -+ } -+ -+ public enum Mode { -+ RAINBOW(RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, PURPLE), -+ ALL_COLORS(BLUE, RED, GREEN, PINK, YELLOW, ORANGE, INDIGO, PURPLE, WHITE, GRAY, BLACK), -+ TRANS_PRIDE(BLUE, WHITE, PINK), -+ LESBIAN_PRIDE(RED, ORANGE, WHITE, PINK, PURPLE), -+ BI_PRIDE(BLUE, PINK, PURPLE), -+ GAY_PRIDE(BLUE, GREEN, WHITE), -+ PAN_PRIDE(PINK, YELLOW, BLUE), -+ ACE_PRIDE(BLACK, GRAY, WHITE, PURPLE), -+ ARO_PRIDE(BLACK, GRAY, WHITE, GREEN), -+ ENBY_PRIDE(YELLOW, WHITE, BLACK, PURPLE), -+ GENDERFLUID(PURPLE, WHITE, BLACK, PINK, BLUE), -+ MONOCHROME(BLACK, GRAY, WHITE), -+ VANILLA(BLUE); -+ -+ private static final Map BY_NAME = new HashMap<>(); -+ -+ static { -+ Arrays.stream(values()).forEach(mode -> BY_NAME.put(mode.name(), mode)); -+ } -+ -+ private final List colors = new ArrayList<>(); -+ -+ Mode(GlowSquidColor... colors) { -+ this.colors.addAll(Arrays.stream(colors).toList()); -+ } -+ -+ public static Mode get(String string) { -+ Mode mode = BY_NAME.get(string.toUpperCase(Locale.ROOT)); -+ return mode == null ? RAINBOW : mode; -+ } -+ -+ public GlowSquidColor getRandom(RandomSource random) { -+ return this.colors.get(random.nextInt(this.colors.size())); -+ } -+ -+ @Override -+ public String toString() { -+ return this.name().toLowerCase(Locale.ROOT); -+ } -+ } -+} diff --git a/src/main/java/org/purpurmc/purpur/entity/PhantomFlames.java b/src/main/java/org/purpurmc/purpur/entity/PhantomFlames.java new file mode 100644 -index 0000000000000000000000000000000000000000..1542f038621b97a298a0fb31ab3be912e2bcd0d6 +index 0000000000000000000000000000000000000000..ea8b928b6d82689e71bbcc39ab497491072dfba6 --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/entity/PhantomFlames.java -@@ -0,0 +1,119 @@ +@@ -0,0 +1,121 @@ +package org.purpurmc.purpur.entity; + +import net.minecraft.core.particles.ParticleTypes; @@ -26286,16 +26511,18 @@ index 0000000000000000000000000000000000000000..1542f038621b97a298a0fb31ab3be912 + phantom.getZ() + (double) (phantom.getBbWidth() + 1.0F) * 0.5D * (double) Mth.cos(phantom.yBodyRot * 0.017453292F)); + } + ++ // Purpur start + @Override + public boolean canSaveToDisk() { + return false; + } ++ // Purpur end + + public void tick() { + super_tick(); + + Vec3 mot = this.getDeltaMovement(); -+ HitResult hitResult = ProjectileUtil.getHitResult(this, this::canHitEntity); ++ HitResult hitResult = ProjectileUtil.getHitResult(this.position(), this, this::canHitEntity, mot, level()); + + this.preOnHit(hitResult); + @@ -26307,7 +26534,7 @@ index 0000000000000000000000000000000000000000..1542f038621b97a298a0fb31ab3be912 + + Vec3 motDouble = mot.scale(2.0); + for (int i = 0; i < 5; i++) { -+ ((ServerLevel) level).sendParticles(null, ParticleTypes.FLAME, ++ ((ServerLevel) level()).sendParticles(null, ParticleTypes.FLAME, + getX() + random.nextFloat() / 2 - 0.25F, + getY() + random.nextFloat() / 2 - 0.25F, + getZ() + random.nextFloat() / 2 - 0.25F, @@ -26316,7 +26543,7 @@ index 0000000000000000000000000000000000000000..1542f038621b97a298a0fb31ab3be912 + + if (++ticksLived > 20) { + this.discard(); -+ } else if (this.level.getBlockStates(this.getBoundingBox()).noneMatch(BlockBehaviour.BlockStateBase::isAir)) { ++ } else if (this.level().getBlockStates(this.getBoundingBox()).noneMatch(BlockBehaviour.BlockStateBase::isAir)) { + this.discard(); + } else if (this.isInWaterOrBubble()) { + this.discard(); @@ -26345,9 +26572,9 @@ index 0000000000000000000000000000000000000000..1542f038621b97a298a0fb31ab3be912 + if (shooter instanceof LivingEntity) { + Entity target = entityHitResult.getEntity(); + if (canGrief || (target instanceof LivingEntity && !(target instanceof ArmorStand))) { -+ boolean hurt = target.hurt(target.damageSources().mobProjectile(this, (LivingEntity) shooter), level.purpurConfig.phantomFlameDamage); -+ if (hurt && level.purpurConfig.phantomFlameFireTime > 0) { -+ target.setSecondsOnFire(level.purpurConfig.phantomFlameFireTime); ++ boolean hurt = target.hurt(target.damageSources().mobProjectile(this, (LivingEntity) shooter), level().purpurConfig.phantomFlameDamage); ++ if (hurt && level().purpurConfig.phantomFlameFireTime > 0) { ++ target.setSecondsOnFire(level().purpurConfig.phantomFlameFireTime); + } + } + } @@ -26359,12 +26586,120 @@ index 0000000000000000000000000000000000000000..1542f038621b97a298a0fb31ab3be912 + return; + } + if (this.canGrief) { -+ BlockState state = this.level.getBlockState(blockHitResult.getBlockPos()); -+ state.onProjectileHit(this.level, state, blockHitResult, this); ++ BlockState state = this.level().getBlockState(blockHitResult.getBlockPos()); ++ state.onProjectileHit(this.level(), state, blockHitResult, this); + } + this.discard(); + } +} +diff --git a/src/main/java/org/purpurmc/purpur/entity/PurpurStoredBee.java b/src/main/java/org/purpurmc/purpur/entity/PurpurStoredBee.java +new file mode 100644 +index 0000000000000000000000000000000000000000..8efca1d91188ac4db911a8eb0fa9ea2cc3c48e28 +--- /dev/null ++++ b/src/main/java/org/purpurmc/purpur/entity/PurpurStoredBee.java +@@ -0,0 +1,102 @@ ++package org.purpurmc.purpur.entity; ++ ++import io.papermc.paper.adventure.PaperAdventure; ++import net.kyori.adventure.text.Component; ++import net.minecraft.nbt.Tag; ++import net.minecraft.world.level.block.entity.BeehiveBlockEntity; ++import org.bukkit.block.EntityBlockStorage; ++import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer; ++import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry; ++import org.bukkit.entity.Bee; ++import org.bukkit.entity.EntityType; ++import org.bukkit.persistence.PersistentDataContainer; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; ++ ++import java.util.Locale; ++ ++public class PurpurStoredBee implements StoredEntity { ++ private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry(); ++ ++ private final EntityBlockStorage blockStorage; ++ private final BeehiveBlockEntity.BeeData handle; ++ private final CraftPersistentDataContainer persistentDataContainer = new CraftPersistentDataContainer(PurpurStoredBee.DATA_TYPE_REGISTRY); ++ ++ private Component customName; ++ ++ public PurpurStoredBee(BeehiveBlockEntity.BeeData data, EntityBlockStorage blockStorage) { ++ this.handle = data; ++ this.blockStorage = blockStorage; ++ ++ this.customName = handle.entityData.contains("CustomName", Tag.TAG_STRING) ++ ? PaperAdventure.asAdventure(net.minecraft.network.chat.Component.Serializer.fromJson(handle.entityData.getString("CustomName"))) ++ : null; ++ ++ if(handle.entityData.contains("BukkitValues", Tag.TAG_COMPOUND)) { ++ this.persistentDataContainer.putAll(handle.entityData.getCompound("BukkitValues")); ++ } ++ } ++ ++ public BeehiveBlockEntity.BeeData getHandle() { ++ return handle; ++ } ++ ++ @Override ++ public @Nullable Component customName() { ++ return customName; ++ } ++ ++ @Override ++ public void customName(@Nullable Component customName) { ++ this.customName = customName; ++ } ++ ++ @Override ++ public @Nullable String getCustomName() { ++ return PaperAdventure.asPlain(customName, Locale.US); ++ } ++ ++ @Override ++ public void setCustomName(@Nullable String name) { ++ customName(name != null ? Component.text(name) : null); ++ } ++ ++ @Override ++ public @NotNull PersistentDataContainer getPersistentDataContainer() { ++ return persistentDataContainer; ++ } ++ ++ @Override ++ public boolean hasBeenReleased() { ++ return !blockStorage.getEntities().contains(this); ++ } ++ ++ @Override ++ public @Nullable Bee release() { ++ return blockStorage.releaseEntity(this); ++ } ++ ++ @Override ++ public @Nullable EntityBlockStorage getBlockStorage() { ++ if(hasBeenReleased()) { ++ return null; ++ } ++ ++ return blockStorage; ++ } ++ ++ @Override ++ public @NotNull EntityType getType() { ++ return EntityType.BEE; ++ } ++ ++ @Override ++ public void update() { ++ handle.entityData.put("BukkitValues", this.persistentDataContainer.toTagCompound()); ++ if(customName == null) { ++ handle.entityData.remove("CustomName"); ++ } else { ++ handle.entityData.putString("CustomName", net.minecraft.network.chat.Component.Serializer.toJson(PaperAdventure.asVanilla(customName))); ++ } ++ } ++} diff --git a/src/main/java/org/purpurmc/purpur/entity/ai/HasRider.java b/src/main/java/org/purpurmc/purpur/entity/ai/HasRider.java new file mode 100644 index 0000000000000000000000000000000000000000..8babdaddd8b33278aea0369dbbeeb445abe45016 @@ -26439,7 +26774,7 @@ index 0000000000000000000000000000000000000000..18a95e043cbffa65eeaaf65ff7695e5d +} diff --git a/src/main/java/org/purpurmc/purpur/entity/ai/ReceiveFlower.java b/src/main/java/org/purpurmc/purpur/entity/ai/ReceiveFlower.java new file mode 100644 -index 0000000000000000000000000000000000000000..115a3b36cbb7716b28ef940a29ca97ac42a8a521 +index 0000000000000000000000000000000000000000..9660716f4162a4441c6e1b0baddef8f5086566c5 --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/entity/ai/ReceiveFlower.java @@ -0,0 +1,91 @@ @@ -26479,7 +26814,7 @@ index 0000000000000000000000000000000000000000..115a3b36cbb7716b28ef940a29ca97ac + if (uuid == null) { + return false; + } -+ Entity target = ((ServerLevel) this.irongolem.level).getEntity(uuid); ++ Entity target = ((ServerLevel) this.irongolem.level()).getEntity(uuid); + if (!(target instanceof ServerPlayer player)) { + return false; + } @@ -26678,97 +27013,6 @@ index 0000000000000000000000000000000000000000..33e89b4c00fa8318506b36cbe49fe4e4 + } + } +} -diff --git a/src/main/java/org/purpurmc/purpur/gui/util/HighlightErrorConverter.java b/src/main/java/org/purpurmc/purpur/gui/util/HighlightErrorConverter.java -new file mode 100644 -index 0000000000000000000000000000000000000000..15a226e3854d731f7724025ea3459c8ace07630c ---- /dev/null -+++ b/src/main/java/org/purpurmc/purpur/gui/util/HighlightErrorConverter.java -@@ -0,0 +1,85 @@ -+package org.purpurmc.purpur.gui.util; -+ -+import org.apache.logging.log4j.Level; -+import org.apache.logging.log4j.core.LogEvent; -+import org.apache.logging.log4j.core.config.Configuration; -+import org.apache.logging.log4j.core.config.plugins.Plugin; -+import org.apache.logging.log4j.core.layout.PatternLayout; -+import org.apache.logging.log4j.core.pattern.ConverterKeys; -+import org.apache.logging.log4j.core.pattern.LogEventPatternConverter; -+import org.apache.logging.log4j.core.pattern.PatternConverter; -+import org.apache.logging.log4j.core.pattern.PatternFormatter; -+import org.apache.logging.log4j.core.pattern.PatternParser; -+import org.apache.logging.log4j.util.PerformanceSensitive; -+ -+import java.util.List; -+ -+@Plugin(name = "highlightGUIError", category = PatternConverter.CATEGORY) -+@ConverterKeys({"highlightGUIError"}) -+@PerformanceSensitive("allocation") -+public final class HighlightErrorConverter extends LogEventPatternConverter { -+ private static final String ERROR = "\u00A74\u00A7l"; // Bold Red -+ private static final String WARN = "\u00A7e\u00A7l"; // Bold Yellow -+ -+ private final List formatters; -+ -+ private HighlightErrorConverter(List formatters) { -+ super("highlightGUIError", null); -+ this.formatters = formatters; -+ } -+ -+ @Override -+ public void format(LogEvent event, StringBuilder toAppendTo) { -+ Level level = event.getLevel(); -+ if (level.isMoreSpecificThan(Level.ERROR)) { -+ format(ERROR, event, toAppendTo); -+ return; -+ } else if (level.isMoreSpecificThan(Level.WARN)) { -+ format(WARN, event, toAppendTo); -+ return; -+ } -+ for (PatternFormatter formatter : formatters) { -+ formatter.format(event, toAppendTo); -+ } -+ } -+ -+ private void format(String style, LogEvent event, StringBuilder toAppendTo) { -+ int start = toAppendTo.length(); -+ toAppendTo.append(style); -+ int end = toAppendTo.length(); -+ -+ for (PatternFormatter formatter : formatters) { -+ formatter.format(event, toAppendTo); -+ } -+ -+ if (toAppendTo.length() == end) { -+ toAppendTo.setLength(start); -+ } -+ } -+ -+ @Override -+ public boolean handlesThrowable() { -+ for (final PatternFormatter formatter : formatters) { -+ if (formatter.handlesThrowable()) { -+ return true; -+ } -+ } -+ return false; -+ } -+ -+ public static HighlightErrorConverter newInstance(Configuration config, String[] options) { -+ if (options.length != 1) { -+ LOGGER.error("Incorrect number of options on highlightGUIError. Expected 1 received " + options.length); -+ return null; -+ } -+ -+ if (options[0] == null) { -+ LOGGER.error("No pattern supplied on highlightGUIError"); -+ return null; -+ } -+ -+ PatternParser parser = PatternLayout.createPatternParser(config); -+ List formatters = parser.parse(options[0]); -+ return new HighlightErrorConverter(formatters); -+ } -+} diff --git a/src/main/java/org/purpurmc/purpur/item/GlowBerryItem.java b/src/main/java/org/purpurmc/purpur/item/GlowBerryItem.java new file mode 100644 index 0000000000000000000000000000000000000000..7f526883495b3222746de3d0442e9e4fb5107036 @@ -26845,7 +27089,7 @@ index 0000000000000000000000000000000000000000..c038fb2bbb0f0e78380bc24bbd6348b8 +} diff --git a/src/main/java/org/purpurmc/purpur/task/BeehiveTask.java b/src/main/java/org/purpurmc/purpur/task/BeehiveTask.java new file mode 100644 -index 0000000000000000000000000000000000000000..055dd307e9d5ac0d4623c961164c84bab1edd3bd +index 0000000000000000000000000000000000000000..2ebbaf5faa92a88bfb4d61298951e5b74157d1e1 --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/task/BeehiveTask.java @@ -0,0 +1,81 @@ @@ -26906,7 +27150,7 @@ index 0000000000000000000000000000000000000000..055dd307e9d5ac0d4623c961164c84ba + + ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); + -+ BlockEntity blockEntity = serverPlayer.level.getBlockEntity(pos); ++ BlockEntity blockEntity = serverPlayer.level().getBlockEntity(pos); + if (!(blockEntity instanceof BeehiveBlockEntity beehive)) { + return; + } @@ -27432,6 +27676,24 @@ index 0000000000000000000000000000000000000000..e18c37f06730da9d3055d5215e813b14 + return drops; + } +} +diff --git a/src/main/java/org/purpurmc/purpur/tool/Flattenable.java b/src/main/java/org/purpurmc/purpur/tool/Flattenable.java +new file mode 100644 +index 0000000000000000000000000000000000000000..345d4ee4ff0b78bd1050959711a4f5d16a5e8aee +--- /dev/null ++++ b/src/main/java/org/purpurmc/purpur/tool/Flattenable.java +@@ -0,0 +1,12 @@ ++package org.purpurmc.purpur.tool; ++ ++import net.minecraft.world.item.Item; ++import net.minecraft.world.level.block.Block; ++ ++import java.util.Map; ++ ++public class Flattenable extends Actionable { ++ public Flattenable(Block into, Map drops) { ++ super(into, drops); ++ } ++} diff --git a/src/main/java/org/purpurmc/purpur/tool/Strippable.java b/src/main/java/org/purpurmc/purpur/tool/Strippable.java new file mode 100644 index 0000000000000000000000000000000000000000..bf5402214f41af9c09bd6c5c4f45d330516d742e @@ -27543,7 +27805,7 @@ index 0000000000000000000000000000000000000000..b7586f494528f30eb0da82420d3bcf5b + } +} diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index 07050c78a2eb6ce0c699101b38961b111d631a41..ee64ddb0da23ea1e54d0295324aca5b46a438111 100644 +index 68557964e27fa1e5ba218178f9bcc0b28e3a78d9..43d9e7287cf0e498ccbff9b865bb813e7fb567c0 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -15,6 +15,7 @@ import net.minecraft.world.entity.ambient.AmbientCreature; @@ -27567,7 +27829,7 @@ index 07050c78a2eb6ce0c699101b38961b111d631a41..ee64ddb0da23ea1e54d0295324aca5b4 continue; } -+ if (!player.level.purpurConfig.idleTimeoutTickNearbyEntities && player.isAfk()) continue; // Purpur ++ if (!player.level().purpurConfig.idleTimeoutTickNearbyEntities && player.isAfk()) continue; // Purpur // Paper start int worldHeight = world.getHeight(); ActivationRange.maxBB = player.getBoundingBox().inflate( maxRange, worldHeight, maxRange ); @@ -27584,7 +27846,7 @@ index 07050c78a2eb6ce0c699101b38961b111d631a41..ee64ddb0da23ea1e54d0295324aca5b4 */ public static boolean checkIfActive(Entity entity) { -+ if (entity.level.purpurConfig.squidImmuneToEAR && entity instanceof Squid) return true; // Purpur ++ if (entity.level().purpurConfig.squidImmuneToEAR && entity instanceof Squid) return true; // Purpur // Never safe to skip fireworks or entities not yet added to chunk if ( entity instanceof FireworkRocketEntity ) { return true; @@ -27602,7 +27864,7 @@ index bf970bf3356a914459c2d6db93537ce2d32c7e18..08221c7256f41ca511a4a61ffb2b9793 sender.sendMessage(builder.asComponent()); if (args.length > 0 && args[0].equals("mem") && sender.hasPermission("bukkit.command.tpsmemory")) { diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java -index e9fa7faaa4451e36b3908cbcbbe0baf213abde96..a810bfd3b8d6bd4d8f2ef8797e4281ae4fe8a67f 100644 +index 98fba0288be9ed2cb18ffba5cf81148157dd4fcf..0801dea155048ac5383295f4fef9bd597b678535 100644 --- a/src/main/java/org/spigotmc/WatchdogThread.java +++ b/src/main/java/org/spigotmc/WatchdogThread.java @@ -96,7 +96,7 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa @@ -27657,7 +27919,7 @@ index e9fa7faaa4451e36b3908cbcbbe0baf213abde96..a810bfd3b8d6bd4d8f2ef8797e4281ae log.log( Level.SEVERE, "------------------------------" ); diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml -index 74ccc67e3c12dc5182602fb691ef3ddeb5b53280..52af11926a1f7973d70a1dae191d2e8138ec5c94 100644 +index 675cd61221e807aadf28322b46c3daa1370241b5..0769f5c4711a3b7f59489e611ed01ad8367e5db1 100644 --- a/src/main/resources/log4j2.xml +++ b/src/main/resources/log4j2.xml @@ -2,7 +2,16 @@ @@ -27667,11 +27929,11 @@ index 74ccc67e3c12dc5182602fb691ef3ddeb5b53280..52af11926a1f7973d70a1dae191d2e81 - + + -+ ++ + + + ++ pattern="%highlightGUIError{[%d{HH:mm:ss} %level]: %stripAnsi{%msg}%n%xEx{full}}" /> + + + @@ -27679,7 +27941,7 @@ index 74ccc67e3c12dc5182602fb691ef3ddeb5b53280..52af11926a1f7973d70a1dae191d2e81 diff --git a/src/main/resources/logo.png b/src/main/resources/logo.png -index a7d785f60c884ee4ee487cc364402d66c3dc2ecc..518591dd83289e041a16e2c2e7d7e7640d4b2e1b 100644 +index 8b924977b7886df9ab8790b1e4ff9b1c04a2af45..518591dd83289e041a16e2c2e7d7e7640d4b2e1b 100644 GIT binary patch literal 9260 zcmWk!Wmptl7+qlLS~|W3b}1=IK|*5b5@|#_l0AUP @@ -27861,282 +28123,330 @@ zQ849yy&@&j=J^g(>AzQq6uvFcs%W{$71OuAvW8Wpseg+*PVYLv?WMN=C|H@$;E_S5fVp$L;GyupU7jZ$kfvC58X?uLqEZijH!v HqBZh=dic2S -literal 14310 -zcmXY21yoy2uugDycPmm{N^yd_Q`}vP7YOd|PH`>8wLo!q*HRn`6f5rV?*HD)IX5{c -zxpy-=`|Zxo_svGBD$Agwkf4A-AaprdNp;|J21vifLD%hMrT$lZeEex|7Xe0mqFAZArC{!qp)zJmbab@utqA`6 -z61Z~|e!k$IbXNT?PvGuuzT7G514$8e!}lsR>%nURMm+~pde``@(!O=ISt0%B93;Ez -za-qRi4n0Q>zQ2#2^_y08QOl3jT*!Ir5@<8VrFx(6f9sP|H8ttjftN;wrX>jP4BcG1;MfU5x^L`zc09u!bDBt#+ll=7@ -zB;}A$BKgu}V?#qfHvm`~pt%wG2y{MOc%B!8I`p|pc -zO#?sq!Zd&j8UPmvY4RQnfo>!6{a}GFV!}g@qu<3Wu$07X(O`vikNW$~q!ngF23Ls2 -z53p8js<-B_Qd?xX6rtq43Mdz(jOg2QXx#Wng_9^1^^~KqFNq{Kvb@Ap9}bf&xFA-C -z5+#cQ`#v$A=kd0O=agATcleBaxXf_(dnqbQz|cL9R&&Ni1omTs+6~YApmk)MCghxj -z1}mq&IU>1nEiF=q=PI`%jQbyRd=hVI83Sm{E-4uTc#w;NNwEW)C(C`xvWzY_%`_MmO -zD&g-sEaE)}6(&g)y-N&rNy;5@+{M`}!{60Y8wMgF5;HmO#B~hG`W$;7xLG*yF((rq -zxP6I#r#o`B3FppK{v(q1!C+YLFSfySDcHyoW!}EfzuCB1B|C5+oP}dtocnwkcNy1EZ6#5JX4=ePl&cu~0tMnt&79+I4%PaK>VqFx;r!QdNmnxlEqdU-QR%Nmu{aWP -zJxwXvt5fFTCOVgB)Zq -z%H0U=9q7Y0lu&1kc4zYT3*lHA@XJfoK>3WFM&WWf2u6^+wCm8##D$x@Gkw+t^HoO( -z4pxDRqg;$5S=t^k22H5^V3V0Qfy%Ogl8I%LD$52=7)J>Ki9Ej1HyEi_ujELlz8$-+?cdD1Zxi02kW0 -zaY=caFq4~s^R?zxcc3Z0X|az}Aww<{P$>6rk+5Di5J7$kWor0{Q&>+DWSBH^Gf`SP -zT{4}IOFh-hB7xwBdewq%de)q6QvxorV(()2>@j8i!kj)=^hN -zl_N{$9xTHHA;V&Zx#tX&1pOO;v^NiOP#_UK@J;;lp+OOhOOO2mlMdxM;Qv-mWG+^vzox|8t`w| -z=gPlM3)y6G*hfV1WwuMe>bO-vP9g`h5BqgO9x{ROBD;aPl>XDmvt(3PUxt|4RFRpK -z5OEtRz{(Oa_W_!Z4XHf#h;Z-~71XM7wlF*L!-#h_Uy2tGuy-rAZ)4{qE~feNkp}qf -zgvBtLkFPI~I7%C=OHZfPZz$j>L9)rb;l -z@J^dxncy52;wmHg=wC3|Xn6jPYCR7xc}~D0wNjoYxmoRh_zh=6@8coM1UQIa_z*1)cZPw4v40qoZQp-uy#DLv=oP -zX9b3vzFA2r8}|_AO8W1(OMG__0{1AUD&Z%&7-(>s+Z-X6Sv}G5QguIbZ3mYa--?09 -z;wNw?n=yAag4%m#w$$-YZ{(ZJUcwHfzu&!gykNjG)e}!=q8xy2_KS=ULsQwv45NK! -zVqqD8#S{vRjg4(Q6HM_F&tihNIQns<%DVjE$cv33ET>Dvc^#{z&#u&&9RgXO?ZLuebczKv#;! -zCS|2lIa37Bp#3RWj0$V3=I2>o40{(J^LD|EUH?!2;Z&HS*>7*V%{v1)wHaUP85mcX -z%q!K}Ntr*IzJD%++btJ;VQO*OjJL1t{GvR3cy@OC-~pe^bV?N`z0QKCr?Tom)4u%A -z3mi2k&eIgh0^rGI#Di+&3lrsy-r+}zwBkDQtswtPbkj!Y^l`{f!# -zLseC0M;DiifDa!({-G4{W$Wxsgv*(NX%HMyXhArVwY105dUHg?+=@6Sy8n@slS76x -zU7%PI8ToKm#qahfR;7kn#|t@9y(0EkooWBDqA1(mpO)>BBz))giBi8xVHlj#dR9U8 -zRo%`iBdlj8%_tRn^qa%T>{nsLLwTNld&WHLyfbPzv2W62m6q=Nsdxnk -z#{P==5!Lidx3bcr_qlUl%BX!xjywA?jv>FU^mJDa0zQT9Kw8RRHq>7B -zb~DXw0(oqBrOQunsm2ghWV2i1VmN{F?)U;0%*j{FEUxazAJ3)KSWomuhklkDi?5h*MTLDS5ma_Nk1sNZYzZ#$maGRyiXBzjG@(G__fuyBl(^A>s&{jF+J%5| -zv#7nD1XK806#_U_4#N2ANAxznk%;U$Y$z#{K*O07mADqx6LjACqwP<`HFV#C6Q*wx -z8JVP_qGF}V7B?^8)f*2F5AON7v$L~Kr?2}oPai_kG!_6MI(U`LS~+Mo*CSyrw>pPE -zllqxy -z^&rnDn4XA@AUY7~`1lwTCrm8KlVRqX&!kZFH&;i9@=R}UDxNSh*)Iq2U+#9}@ag1t -z%KUOEw0DXT)>hQoLTprY^z=BC=8NAyi3pZWT7A`?;rI<3%65Nqb93%pJ=!+dNtB>W -z7f3O-e-S7ZBgBntcyt~wOG_p$AU2zlGH8=%TEm+z8kLYReEMTkIo#2YiA=iKWrH); -zS%uT3xAyyY=!U)0Evpgx{{38MPR2nN<3913M<0O#YCO=TSt^4IzV3^D%2zC>t_OO} -z_h~AVOk+IIi$Ov;-g93a4j@WaekCC#HFm2_Vu9s)8-GbYtr{LgrxnSIN^PW9)!jYX -z?%-yssA~&R3F)C)wj5i|@!atCx?Qy%P1QEGSZm;iUNai`-F(8a%y+_a>CMzx$XEKx -z>sW|JbN36s+Y{4SZsrspH%UH=+Q6J`c&_-JLGL&5|$XUA1vFOC+rgoc&xT{dFT&pMaEBKwyD;plX0>2nla;jTlQ{!fn2M=Ak*=K*g% -zBm0-$ly1~}CT-5gv){jex9)7&b8u!a+vYHXU>=NF2>g3+_rN{(LUMGwRWKk49sS$v -zazyX8zZ1hwZ|U*5{fK@i@hRl*U%Q2cg+!iIfb)6W%S5F{91qinEZE%~4Gl>rBw9S< -zMP5$exl1jESyt}d~jo?hf`z^32b!}UGtJH+w9(0UrI#~Ei*ii&6z(AVE?(}k_A -zE9Z@mj7HF-ch46I0ipe3gapRj{=zk_J1E^b_JwdrhKi4ytBuwP)m>e$@9v`A{1N{h -zwUN6H=_W+h(a?rGaQ%%LP5C4)XiZ*`1uUwgqWvk`LyDD!Ps#Q5oI($KDJ%8n5kBi- -zghsLx`~mf<>WT)6-cJBbp|htk1NfkZ@e#B4@l?UH7!MDMpO?1NETGk_Eg{z!N3!D< -zWg8gtgS%b(0Bg7dw9u35xq)1vNdnM8iu7Eje*u?#sZ~%^q*HDaZC?5z4ZzhSA%ndS -z4&$M&7(|(9nWY%QShCnuN0 -z`n9&UeypypUgx;R+x;XM#8uDM{p`9~j<49)^dotHJVO*A@HL&g7F={FP#trj@{dzm -zeQUiqRWJ&pkKkA1O-|vOf8O1UQ$$0lIExffio|}F@ROV#MXcPH$ -z?$$kxAF@B#KT}u;R@SVyIO>1sw1!i?C(_013w9@?8$bKaLQi34zC$g*^}F&(%NEO6 -zQzD-^6}HQMnGJ{h$J*)HjSxjblWegsW&rLC8Ov_r_20jLjUS$Ptnm|p9fK%r0j+4; -z57^mjL&lISh8>DC;eB$B69$h4XxE3qU4T&zUpDeV@4g>or%D-x@qhie>6mqD959ck74(h?S0BA0}YQ18d?hr6}%}y{%ZNJ^-(?=Op~; -z#2-UNh)jH9>RXmvPJ(Y!8(uhyW|sFpyvv)AaNeljHj^Fx+RC -z!`@c->W1C^FUKHmG2w_atkdsMnzY+l!CV8havQ8-Gu)<8t{#V*2Pwp4h?ayXsi5Z> -zo!guta>TA~iv#iJpQkN>#)QF%As@2WgU&V_Y^qm#E*O}M_ijJfFWq}ts)-l4>D)kCqJJ@MG2$69ph0jzwI8ry1u8D@CyinC$oT?7S*Z}Eg -zYs}PWLqr4u@)w}#!{cMx;KxO6W2H6~3k$laJjAt+C{0mmCRnfs=OJYbh}HMh&e`#> -zj;jrpjqKCh41OK{FOS`@_sPP$iCm46G^EMNk8(l-1f>!gEV+4vMVRZ#8infUenP+k -zL^tBOHF^=)k&U-Tw{gfijqQ&^ -z-RHHII5yp}2|o8pTsf6x7$teW9Em!~iy2DN?D@|U)g%I6VG%JBO$|~;c~1Q^3|x`1 -z6HRbq1#~Ke)wWpALcc&@P;m+*sGavR0{aOx3=IwUE3YPWAwV45pzD$~02inxi7(6X -z$zk683M=_r#M*+6fQ)&FK0y|lm7JLwS)K=t&ZJk!U_-y%_o@fhr{s37MUEQOF*M)3 -zB$;4>Zx;Xk*(hwFjb>1iJ1f*D#nyWL{=>{2|9*^vCNN!%bF8Oe<`xz#s;jFz?;I}4M3lL;!fy_;J-E96Of+;sG%K=fZdR)99pJ}fM( -zq%(s8UrsEL{NrdF`!#RY+VjFyPpE_vtqPMM!MQ+QnE)+_g9Z^{4^;k&Sa^=w*yuxB_*Z!U%!3{_9Qr)Jfz4IeS#io4oj_Kqhq`HCUub|Ke!v$1-$v=kc+O#rlCej?%dhY -zxxKUTsFPG1nfoFp3%7@gh9S?vM0N27#*fpJyaX;Vy{!pt*}!9_mX9uC#J5RyjknW2Dm3dCvZYU -zSW?0kvI9!o2un}*%`AYhr^CQT1aZF=-Nt^atn@Kt%b2!hT(pK!|MclbBv3-<+6{>_ -z8toMfWc9rpOk(8|KW>Z-k>Fr(xc_+q9ocf`8!_n}XYUrW?Ax|*_|=5m*4F0V+46wJ -z1IGS^Z5t=0Zj86J2MfJc -zUq#WKCfhoB<;P2&&`*_G4^_0uqDR20m!>T8ay_rxSzA&9_v5##g6tzXTkx+KRfz32 -z9vvpp?+YxHTxDthCBu7)&Q052y4s9*$M4_2w-OdPyK?F-EBoUuSsIk@@(!gA*A_!0 -z2eu1y;-Q$Ut(M>8FCOtw?vZR-%*ly^x)<95vK@P0tJoZws@+M*NGhg_NU`!}DZnWBHQz%*@6))$BWN;EM0xAF+B4Mph#S??J?K+&viwPmes*n^HGDL9iBf -zCk|mDu46wwughN!isu&G((DO>Ws`(VLY?^#w=RONxUgFGby--Y=5NJ|(>qXOS`;lZhmXyMEyBdVM@jJh71E-})~`?t4w8^Kwy) -z<+KACjs!F^TS-;FT24_iWF+=l(nR}j7U#;Vd -z)IT3=b&}A}1PUKFa6DKfgHkJci!~7u?a%k9h7Rri^{y`|;;xNDoQbV}+oJ=LdApL}|77o@C= -z;~aed)XpbrMtt1x3gHPWxbliQH4nKBCew{9 -z*-_PTyn~`1VrwKcc4ZrhI^!MsZ{D0O0%O2!SHHi^Dfyr9*x*DGFKwc()b;q6nM*M7 -zvA$x_?$BMJJHN5HIn9Ps{_7-sn79~BZegaa5V;s(BA<5BnU?^AeJHXtd)cIj_UCjA -zW|N@MjV~vrJz{sE0Dzv}tXxUDQAXm)1(kX7C_ZVFX%!TlZ850i(P1A0BxaJu)#LcH -zoxMFRzxoxw$bM=B6gpuMD#vcsa^00?%=D+T9-dQqV*=zD|)W!3BLun2&^n)~$ -z2_^{i9~sGXOAsF_S=k&4mWJ@`mD+G%MiPTlhuomboeFNwHb(< -zVpVR!mwf;JmpO3JL|B%L-!;@7TG}+`HZA;-{VIlQGY|T=f|!9!S=!c?sq5|KeEQ*~ -zm!1xeZcJPbSsfjU9e>K|=Ni<+YgrIG!|5@|Z>4bjx+`1j^O-{QK8XARf -zUG$nLRiTEtt;)9F30rvw>nj)@vCF{$d7>o2n>}~Y2^^C79l@s`uXRZOcuy>^%2@t- -zRGv={pKlDXFUgvG_^DWGR==il1rIzn{$p4r(FVOQxZi!_*Ksfl2hR{Aj>01RbFAM= -zpr0wzMwlOwlkt4|JLK)$>VL+{4nv>^`yMa)T;(9f*B(9;{T+)_=M4dN>M&&hS-#(G -z)-sW(WxVkHR)`x#g)25Lu7qnN;~Q-bvKDZ=;^fyLy@okDpvt&ZU{!U)WVtmnp -zAN-CzM{jPFWep9NAKDDq@=kynkGi_GQ@Z2y_Wn)xc_q3-&+9`qdGy_{PF-2c^$)%x -zd0sonEJhtG*2|P*Q-f_3`Akk96HzBz2 -z!5tnJaCcA2hGQrSw*{F)epvfYX?7toP=O0dN -zizY2w`>O@4Vqff!dBhQ^><#TjMP}loM9ProiD-Og@$V=*zQ|Avg0D!+96lr^u(1fl -z3J52PHoJYDdvdiIW?q?JIC*r?88VruLx#bp0lys39v$(c6uC*j}2IFFh -zViOX|K+DH18cd9%Rgjs$*sXuoW<>p^Fv-7CV|zpgTUnj812pyyX-nhA4TZ^UyYY9; -z?}BOarTT1q;0xSTjV_DPWE11?Y2+wSA*ybzebDoy8JwhznKa6SvYxE$WswX7Z6pG$ -zsA2GgHFFL3^zA@XTYK{a+6$Q8di%@1-|q9U15y+~R-L7Kwx8*xr(FP{g*JDPa`e((jSl#~?Rx=3ne(nLfeP9k0grubJK -zU4euzZqt~$Cl%k^{-!e6YQZi|D3#+MUS}VsYZ)0S>y@)kyqRI?A_esvAu-{`1Uq@! -zC+b`wnMK&<_mitl+k@e*$*{&S>vayX*>D>Q5sw2FZ?l(8ff%(8lo<^mBMrwQXOXe+ -z*7sZdWzBTIwZO$y^F)qZL1XbOMY<@M_a56y{({Vg@YN<_y}toq41V%~w=+4ZQvg)X -zVw~l$z-sId^nKU%dlk7W(mG}eS&KV2BdYqNJnX-p=YrG&&`_m0fzA_|iKD${5?oL* -zdS$heR@%Q+(3!!T&k;tIN|v2j=UI))rgkvyC7MTTrKP3g>Fma@_R0`GE5(tL%sS$7 -zG41ag%(Y(xZ5cjlk=R~(3XC+$25r*Fo=G5OhGgR}i!nDoG?^sult?Eo*x$x6CH-3L@LtZ0dfq!Bbbw-S}RwlN%lpH8c=4l2qH -z1wRszHSPh~=esnWvXD8B{D4<}?}6cA+@Ob1760Is6`g!zl@WL(L&={LA}SxAt0>Tw -z%b7i^&yNKM;(vGcNwuxAK{g|S3Y1&pH_6U1G -z3M4zx5FU=O;=l_?VzQ-~bx~xN1axPgYI0am3d25BjYmfSTX7Q}==Vcryl6@Se0(Jv -zxKW_o%H`jdnC7QXlkFbCsACHN1Dx=0gf<~@PW-&<=`1Hd)@#ypH7%OpalDj-P=ts+3^~yWs~TV}BD20HjkW6zc1L -z0#HzMkn3JV%7N-18_@tgE82*YnmEzxirriDSx#_|<|q1vL{k}7>^mRzO(ueTSN2~H -zG}kxp)Qn!&)><3|e>62+GXSpQKcemfqU!&BHZ5Ca;DT<63bBM&uV1BDS?MM$M;x8w>gShAPMxJM^BbMZn}Unm{OC9^4x3%% -zlmX8!km-u$N4fQXQ>jRe`7)3+RFGjhz -z18zf(Fo2<>YV^7LJO^UTZ2Ivd#mpN}o?7pBV&q=f%ID>haV7M8R3jsF*@a%iwIy>| -zsZ!-y{!%&j7`B?W8TcF4NH-RHH1xZ{;7BsA<#APu!;cND)te)FhoXz$BIU}2&^7WP -zT}TX>ZO58$VNPuh6JV7~s(W$vAj`^%AtUamex3YdVl3~4+pqk?G)qUibNMrj0*M25 -zY>5Ac|Dnv6xBQmV#$3JA?&HTN(lYl~J}@$l{*TY^kORrCB)3dDO}^^v!dcLf^CHty -zanjllIQeSLmpuG+h&ae`r*v!C*0A&W^a&q>93?BAXzG7n -z2*3TGPIcN`-_hY9&oaiv#fiv~>}7`T`4=pInEqWX*3e8+yPm^9h-tr&ts55$l+388 -zW)~F}2JH!}VLbQ>?6~H@&k`MnSsTeVj0TRVP4jGbP*!!CwM6`Z11c)yI2w$+R0zxo -zT|obYS1&&`{>>Z9(jnVU&=yI*%PGe*f78ie*_9oap?sd7fx7{r^WT>=XHF -zl`f{=UJEn2?tRw`Fem?eRE6#*nOes(ebRcmaK3~a3{a3EyE1zXSF0p7I_iDJ&%;3V -zU;AS}e?*mH#Yh2P9E3QBigIqu2iXf=@t)2+I~f*_E^JtEP1@IR{CBfTj%T}E3e#n% -zUa{@vU?D$l4DEANwkkK@ruP4ta)E*e^KLGg%$PizyPmHvKNMWtuJQ6sPXY=(1m#>W -z7V?9E!Vj}>a|KfQx5ESpH+q6$@gAp-P#~lbz`aj1_?xinN>3o8b2-Z3w>UZ3QZ}W0 -zWg-!>p>AADDcU^4;0*L4UFgB0QLlXd^y1E&4>txV!T|!`RwjZGl`;-4ZgFf>luHIy -zZ8d8Rh{I3r!g-ht6mAZxMB6VxRqnA0UY`h|mJZy2 -z17BazT$jMKFL3J6Ue_HL1^)4s%$Jj~Qx~1HG#tS@kwL(KP_ZI3dWz0SH(sqj#-*TNGsIWqPj>cj?!GyWvfdEiNOu4$>MIqL=F&Cc0{g*~L5 -zA1wt)=_zMFUkCT5$l!G{1-Y9QtGQ#qm5E(3fYPms_EP*sSVI)bfXN|uNO`BqVuCvd -zv)z8IGRgtM1<_trndVhQ^xA)wn~*W~#d*X@E=W)jcQWI8+?kdzHe;DZ`%+JE%gE}m -z6H=FO8rJxM{N90S=Gi!Mel)TyanxPa;E}C?hJl@e9UWad->;S|v;axgFjrY$z3(rV{MiJ}3M)t;Q?P5wZy0e3G{dcDO7n}3slDXLMrB$;#*W@Qv)D$=?Xs$F(8eTcyGIQ~IWgD%Gn&E>F9y#o>cR-7spE;Rur<_E~Pu)e0I -z#&y1|@8D~8c55<|KMf;&x;hg!A%VOZ38_+uk`jH4#=b9M&xcpxV-7cMN{jXVRnKSe -zlKJJ%=VBV{$DNeI1QkiA;DfdVT?$;O#22z6v6bTK9)fjrfIh!Hq__l~KzuNqT{&kA -zKs@YV6^1ZLGjTgR%(=NHS-DvWnnP)NM#qbHINqmQdCE5??co$3nuikqgm=s7*#Kd*+j_weKrZjMeLeHEoiJm>zuDRU` -zh~ggr^knneWU!Nn}AQt=0Id6Hk; -z4bJqse|V$H`stT?NS0yreYvaZ9YF!fw+N}{3#yXRU!C7?exl35BDC%+!jDMGT^DN# -zN9FGd#5t#;$h}5UgQ?q-Gr15>C6=nLUszle9<+_!!oi_m@_L^-R>_Qty7_g|C%m|5 -z-7^5X5V_ARi?h9_LW%2vByD3X_IvUktqBv{%SYXO1&;e&O#Ll_cfC`Wv1u+l_#RI< -zQ5Kly0;P`%TXaQN(heOg~>V&L{d+ZDA%eq-UKo#1)$rkjSm=nzAE2r -z5--RyKhxfXoGVU3^ab{5XGlyL1+26foG)4HZvN -zG@&I3h0fnK5lIjcrg*XxPy1(gK3_TN`&VYnxP;C|j$~0rT$0f|*#=OzM^NbE-1T5D -z%Csnt)n!sx3N#b(8G&+G3W~Q_B#StA6jZZ=p#wuu`DrAMXm{T@#S;ku4Dme@{Njmk -zCtrh3z6O>o)~o{&Htx+6kn*)$NNBH-biu^aYtWUq -z(G>4rCEKr#tO>!x8A@%W@6g)Xs%2Hq!y#Mbb@9R2@GDWi&!{jhZvzQ1D9nMuPoOS+ -z+cj{9nx5X{jJOIavbFf)Kz5Jnbe5Bu#(XE-z$j&iaP%c9W59OoT0~|N#D*(N2kz={ -zs(|)nH!_+_g1)#ZH2xk>ZTG#6WN#qa3BxZM{NWxq`*#$H255k6Ky?hw*hSA6`c_fl -zT@Ua%E5Ez3;~`kQFmrC#$Nlvc_Uy3#yzhd-6UYuuIwgIBZZC-`dwOBJbfurL(FfhH -z{YkjE+9OrOveY`{t{sGw&51YO1@{iO4)Ki=!Z5#q=m_Hi)_j0`>?;t2j);vv%BUif -z;wpTZdLQLsGvZ()DCdxYudn^Pt;BZ}Rin$4F8h{R`HxT2z`uc&aMXIQOvwgA5%{&) -zFW52MiN!$!EXgx}Px~e1!EMp;#&kY65oDho95j~!qD%YJr`+aK4jCJ4UJ^;q>w@Lf -zvDfg|M`S^@DGxu+7aR3Cx#;%?advj&1~L-m -zJqCP9&TW3migV*`Z$#)Qa>3>Jf)g9D6Ki28P@iX(uso)hic8Dp1F< -zeF;(n8Po8A*~^T{De(J)Z2nqLl@Vv3yoSlGwq0aeOg4ymI(KIkTeur-=J-yp9z?qe)it6gq-wl@I -z0D-_I{|T<5kwD9uH3yf1GWXp5*8eOgJf*q0IRoK|+r{}Fug&0WpNDKMTC@(Xc)9K8 -zy`lByMn!1fnY)1KYP(0Je1)c~WilUuh<&Q8^OE?L9Q^xK*Y@M$`6D6TDCZ^@l8{|} -zxmmNw)mng$hYBii+&ZqedxWT0dnV#LG4zC%+kzcK+-??vEHT>Q-T8zu|s_1IbA#OV)^+1pg1OmmZn` +literal 16900 +zcmaicV|1Ng^k&Q(Hn!T>_Kj`Zc4OO48rwD-Gw*(Xv_UIGaL4*?7e3`t5-R2lSh^xqd84Cs4}W^FDQn9zijsF13M{zVR~<`0dB +z;hww3Rk_uLO*yyZ^N(arMN#SjFcHEi60E_fZug`IjtJ^LVtno=lKj+Jze{_WszRIN1X*HUTCH>C_wc;+D)6YYT +z*RWmTUi`Puu_Uwkj6-qwu_Ue*kO&$%=o%J?6*rej_Ock3znkGIb6 +zWm&yS2Z9LS7slFgUx+?ilDgQBdj7`ruw|IVzJ@wV{&tD)G@SPTMW@9Wl5lcsuU~6` +z7raw|%Or|@Pnlh`7!!rA1H$`p;zz}+92Tp2bFmKDAL`nrC>)<{qBHso +zvJ6|o^vMxL?frh4XZ`3WdH7s_NI0p@{EElbnX*!yp;Vtx&K&w$&to`sW +z79>enm;xWhu;ZKKIN}-h!eBKZM6j$9~*Q(SlE*i_bHS0o#tPY +z5-j+ww|x>h9%`RLUixM!e%f0qVAe5GH83X6?!#^_j-M@lO@*-aD%NMF2;Hg^Wgh@}elrPA3o_&(- +zeNyws4es~%;K1o+pfG(Z!G-nFWzl7)ejRNxY?M~uI=I&MYuz@4>GLH*ptjlQJ`LYr +z*KIIVzBhKHIDwe`X2hc@gsdjzXxX%b<_#kc$vIHFi2)-XM1=fs(`g?0)M{lcJXwp< +zBgIdDXM&n-=+_%;1a?sE$oeN{r%w=8tFfAlQopAk +z%wrVN=r>)oZ0w7^M~Xi~qp6lEaABgF(ck7V3Un;@cg|ODuD7@fw~OZ;^TQV +z$&4AiUj}-4;o`6JV$Y4C2G +z8hVweUdzl78hWzD|&J_)oRr2JdJP +zA&lca);^P(q@hQb9-kqNXVo9An7Q3NoAtyRQw-@JUDD$oluryjE +z3{zzbZhStP-K;xw@Yxf-B=4h(p=4f`k8p2DH$>qQLPR!szD!2|vJ}J`C6=EoRwG^+ +z;`ZDv1SGVO+?IqSxpxSM^_V~@2E+~dZQdl+oz;TP1MX+XXwugMy?Z5AoZ7#R33Y@T +zM)w4;9L0szO3>6i#4fV3q49@wu&`zcvQ!d8!m*dpn&7pp0Y=;QbiyOzhC7)Ki7tDt +zXaIqysWqx53ZgHlO)|YRDG**$7&F{0a8VEECY`3;yx)F>2;4Xr&gC;Iqiqx;orWkF +z8xk0Ty-mK&z`^~Fbs#S;;Qd@1ZFJh4R`+H>Wx$xgn>^oka;w9~QfR>rS7lYHG?D#o +z6Jo`Qg_-DP +zX@kdURs~L5?afF*73QF!=HQ?vIysP;FNCMBfA*}*&%$eDHh5L|y~D=C^v8(wdtcYZ +z)8Q|56BuZ~3~KpF-oKg|5Uf@Ac15Z>sP<9hpm(E>^cgr8dMxGhn7mnWA+JPK+EGR; +zCfK+V1&Xi1M6CUFIA+oJqr(aF3W_=ph7h;IVlqq&xJ=d(CqczQwL>f*A$gJW_|iZw +z&>!^cGyI)UH(_%jFMta0ci8K;?^D#C4_`@%@wP6R4qvs8y@ecdj|*ia7Exg3*BpG4 +z%Dqav(-_hWolzv04-3Ygs)Z~U$`R?hQq2Is2`RWS%z4?!GF2CryzMjCEFg_Y%K+yz +zG8tm;0X{;XG5?BBT|pMZ296(fGUtoF_$Ryrso&s;Cc!g3a;pYOn-tjPvW+1)iAQ)I +zaPyG(wl0MZUqz_Z!4+oEh$t>QIaiZ+J1|fQdfugliOCAg+6D!~3<-k#gA8N#Rk3@5 +z&u3Yevetsi3m`sm2Ntt>FV(PfME~wR=LFu+2@Noy&wr###hgP3mjy&H03re#97OQ% +zsZ;NtktNoC?s@G44Num-@G1zw*?jMf)dA`SWJHyI-Lp=m +zyv8V97L8$~?>Sf(&Ee27TQvEf=-_%~EL56_n`*ZRVS`=4Ka4&HGjr9P8e3rf;8BK& +z&0s~H!Z|V-mPt9vUj?5&%Sa@;XK~`TS$ylgW4|1h&I!<9c6_zoDdR2)FLErHw%Sow +zwc_2ZKizcAMchMvZ^6OY8)uiUt&RwA(`3@dzgihQ1MSrNi;ruq-C+?oVa@U0x +z(>^4ei3Bedg+!LX52G(u@W4P&3sdv45%OawU(*aQat~OuEf?Hi6Zi>__qCd)nw0_j +zvUwA_6WQ5tnFsl_AZNz8L8L*=L4?0A>inj9l&C`AC71u=H +z?bu{Q_=al@1+|F&El|te2eQB@?#+g(D(LjFx>w=0X;CJ|CQc@tuin_)Rd$KH$Y9P9 +z${MAq+Ns2`>_SLAfKm9~%?U2bK6>hiDEbdUD#NMd$hR*wFx8TxWVY3Za +zM&tRPhR$htT-*KlZT-SGBy4YD;6aZfAz^Jt1`=ABifztn#D_;u)2WTa-Bo^EKL;=o +zDc6Ov2x3ybU1B6gkFjv-UvyFl^(EFkIb4ht2Z(*io4 +zW(6^Rp7OMxVh73mYH?bkbxgXB=+TL>U^8OY>=P$oXPkGAmF?6#80T +z+e?24uzuJC8?nCu`7)ef&Nu8x+`0%wOB9wmZ^(+|&$!T80~3uj?NRH)aNhf~#vN9e +zem1VW#bKd$SZ4ufS0-pzoJ%P7UWdT@8yg`1+kpYLV153t;UJy~P8@7sO+#{ePIXcSgw}v2XayA<>Jxh}D)tMOGRgJY0QEJs` +z{>aB;ssVeqKi-6L#(PnBpPuOu<4Rf*GWVk8BdMCd} +zc^_!LU3n2YWBEk1?0<%f@MkB;t#h0%&cixNCZn@Lft$eDVl6z=l@Ga}k<7cF5n!!o +zXet^Q3;AyG!j)+$=3U>7D5cEf)=YMZ)jSZ?)!6EoSa3kU!3W2Xn`K`PqR|ML`Ju!A)|K2`l1>ErJG>o*qIC72B&jHYe36od@P! +zi)qQ9Y7g*>N;Y4;sSLlPxvM;q-Tzw2m;Zx=x>{mk0;Ed5zA?Hb1FrDGc6-;m+iSFU +zc22aC&R^-iyw5vE$D?GWWo7A5o@@>d3_uD92sGM_-tlsdQ?ZbAnF4LsSxDj&0TFgO +zFbB*@;0<;Y0es>tB&~M12_up)gRS(Ce{seFR$9$~MC8~S%gCTV+2AIiH`gndEW2~H +z`z|RK5KuxIccy|!;Bkm8puw0EcWFE{ij71G*o4( +z0~y!3%z_nq1kdh3x<;XVQS{_v?Q3|H1so1Z#CL|Zm2Z&7-mTO?&1?U-oogOAE4Cm{ +z`d4o(XCnWH-J^hx&?7X^xHns&B`u2*skUy`s~w=0252bVaZy(}U?e5?u>fG!UbYaS +z4Gz$YBX|~|U$??YUR+zxw2g5F_OJB7viI^}qx|ouEswnc0o{D4T~~|912EVr9)4P& +zS=*@uBmgy>GC)sz_8A$Iga2y-R#LKP$zyVe7P=4Vrn@Q)Fp6mG;Nall=^07<{OPT~ +zPDD~5M}Py>^H&ikOMCrXaXjFMyNuyNg$gXaPOE4z3=$o3Jt(guFuvAQbA?*MR;Dx}r~+zsgJ +zzCtQ*$r?UAKNl$E39K|(pdcV17*;zU{VtG7{)QDicnC&XAit07AxkJs2xbNxkEh-l +ztI=-hZ#0{5e0{huHk5pMKFXUdk-_HT=8j~#**>ze%L-Vq--ELbc7OqlEqqgfDL$7| +z^zia3^m~7il#>&4bK{s6W!C%o9eQ_nw_LRXoq&)qk2e`~Carh!_+@C+^?4E@nB?8v +zrP(B~aF_-3_5wx4#3EgX2f|T2iDX6dBot9e+}zxz-+7y;fop?^#LWumnJ%(ER<|F> +z44(0)x_-m7iZI17bV#w5<;|{V>IZ-R+z|XI2d!L0M$z{_~PzI|b} +z_>I9TkwT-USfkDEyuoB7YJe7^SUeW*JCd>d31w)Viag>w +zE)Hcnu_U(A@CEh^w;UM0IVsDf+yNUB)lCpiM=a>2dMSVx95URpuHBLGh>h8fgM&77%eeba~6*@>lA8=;7iEw2QP4d^IvP +z8fpiWc?lq5kxp*C)nS|HY^i2ov(x?A!{1u(mk%xyJ_nmAsx{Zt=LV=Ta0-O}2|y4O +z5yIAhMw5|xp3lvw|Ps$0W*KZd^Wlj=W@{AaG=^es3_){Y~Jis`IYYiWN~ho|DLil1qRD5 +zN6xAlvXG=U-8`VKVHr!k-;5Bi)EfnJRTtvY$;jR$#e%~lxMV?xboY;JA{IT_^y}D0 +zw1mJ8tVoSO-(}absB6M8b$Zqe)Ok0$OkaA#I +z48@e8TAlv;PmB6dbP|{7<%qt@Ea>I;PRL4)=M`_G!A40Y$Xy1Mum)I0#!3<77H4)u +zI6c{)TUsy&o^*@2H9Bp>QJA#S8$`zN?+@z^IIQL|VxYEQfVw~Oc}Wq!FS`G2T=aDu +z-DMYe(1$x=331oN(i#yV%?Q)lcY`}FpGRp*74@@$fX%pE+dAGOh5QRhJ&mcaXOhk4 +zLi_pirw^Zws;d9n^#IE8T1ypZDX|crNABquU?iL2;Ql%4Vg5cNBt}OJdbLKnEi|`g2q%v70%eM&7 +z5gdFefu8Ix3n54MC +zW40SGT11ajrrm5AI24T?-2$|VMsU%VX}AMmt>Pr~B}#An{>%QG>_1FQYV^)CExzx2 +z&7E_9c!fpiCLci|F3H*eM2DQQRtQp4>V2RP=KX3ZVw#OXuFxj$VDmM&HQD{*dc7301976VQyI69%EFvxxn>qC&Lo-`%ImvM +zCv>AXKPcD26Z_;m`1pw)uF6Mp=RnShU^yM81!?jbl!v#-kSa#RLhSOG0?yp1YB6Jr +zW=GrO|0zIRSHiH?DYiO+$EpdMkwz#4I6V(J12-W0+dAo4J*?nDQrFI<*}a92Y%1bU +z`RC_4tyg7>R(8{ +zA8*g?PWv##WoF+p0bJe>whg#+(1_+A+)9HS$|n?k;(r=Le*vR;57rn)2& +zEkD8KBSZm#3Drt?t!*#s#>0+yUNysIKRg=t`KSOcSHieiUP0z8F_$tZ(ciPnq_o~@ +z%-{zhbs{i7 +zt~8q8%WO|MF(FE_ye*bl_-@NcA!S9$IMb6x0`e_oNF!hy5a)H^H)5)t(}ek4a1Nc~FF4@f;5aO%aB&3O%B8NuMWWCzYb`d> +zQ-&3)G|5M|pzcLy>pA(p=?3&XKn+v0^`HNsS?M0eb+60BxF|&Y{?>MI^x``)Vp}1V +z;<0N$BUc(0=p=y>zD3k_I~ +zMC>T|rn!T!wN%lqT@ +z&Afsj|04$m&CH2M?F|6yeqb+e`&JWTP^~~z(;c>5;z6RuFKe)%3j|YzeZB9c)5E08 +zvX9?L9%?PT7Vu(RAIXR}s*=I*@Qp<*vA{&7B2uwdBH$_I`33U5di9weG|3 +zx-Iy`1L`R>G-q<+w-{f5qc<7ls}^cT4Y^Qi+meHXFIDgqkt0wpdBZGY?LB+q9&o`T +zd18L5%R+44Ml^UNbEw58BXP#{+I#J1$;VGO`#6Grd<=RWgP+T+ktE6H^>C;%(}szj +zK;wt^oW!yG4Fz=zm4zKw@$Wdo`VJm=879kp$F&$uMP_qiKSB4L@SV)g55F9Rb=3ocrK>iqIRR9n!X0Do*Ldi{9M&^sg&T_TZz~>`tbXc$p%%BI% +z#MahUA?U0t#2ZA4_41*w&52#TXU^_G4)$#uGOnpIb{Gs?Bge_xP|beH;cUSBec^gk +zu;a`And#3j5LZ)LALL9lQ0{$A?tzx&K6M(;#M))7n&`7KTkT>KvjI7O4?mTa;X`81yn7WAir6 +z^Dv#2{~#3{X=5gyP*2v`3yoLJl)--n2rC2}*3n8(L~4ohHzT6QbyEu{!K3q#&p9Lp +z?3#RrZR0JWoh5V%Au%m2?uSB&RO!i99khjDd#7P;NaxJ<_f>mYXQOtXqBZifoWn1d5WC&hmG;&Gv(>!l)|)selJ-m-pz9Og@*rA +z%Xl~n+gHI_Rjy513U_dEaq-~ZLm%H7RpVbREoW=Zu*D?n%JFyy6(v}{RCOy +z>_wu--o5bv-4rRuWG0oN3a2+(f)C6nR0%>9HdI1mB`d{jE6Q4vSf>>{@~N-bGMc6~ +zn=1MB2?XIjZuOC!s@-pN5{60UUw-L4f1L-3Ohud?4)I$4Y&#w^A*ij(1$$3|Vskv} +z#YKCOBnHKh5QN8fd|k)wI{^HZj_1!`{L&>R(m@P^tYk*J)5>eCrio9{j>kWLDCGrM +z*O<)utCbjQiH>aHzD!~>SNyzV|B?uyizaR*!v`(g6N5ks=aSqWHk#wzbQOx2Ehc(>s +zfl`oSK+EzLOKDeK?n#pu;5qF1g-8bXyN##%K`x2R14CxOh8w&P-kz4U}>3Q=A& +zwAa>sCXe?|fR^Y+S9_jW;=!_GK`1Bc2HY6Y)*s}A##+#}239~LV&Q~wL&4n_6^@vW +z;nGUYJ$5-C#kJr2EtD&Ty$t-H)#GyT->}39LWB1gdo%LwqR8{YbRBL*-FCEc5iY{; +z#TpZ~y8yolNKuWi&enqz%<*)Y)j#ff)9q1ezkI|N7|zr3b=T|b>+m?)d% +zKJ;1@L~w8ZQn0MxZS*{ew-;Ohn^Jl!+U{m|QvgB~tai**t#d>0E=CMjN*SZ+36QnO +z4NrSN!Cd>9SLf?=!Hjh+ek}c}ND_U`vvi9(MS>7nGZ*lPm%4(7(bhfuTHod8y%;N{YO_KMV}N<7D)x5snD;XG +zzCOH#WK2$4mAvQWFCCZW#F8TRInJ+=$6eR`V~dES6+!6-=6lkVCHyCW^Bb-$@=b%3 +zi%hxQwAp^EOp|zR61~UikJsM89qE@P3@X5J>+K)hO6K`Z$80UqhLV&|mVt3wQ#G4H +zi4>T}s*jr9pkN+B@=LbuMW8^kzEFQde*yOdnXiUws9u#OD8dYzm?0F`qCm7pBCNNz +zOJB@PR!5?2&9Zw_Jg~i=TwmStKiYq1_@$ +zZKB*^u}y2o({7rV#Nl+8$2T5 +zthMF3X`+*;4Q-~&-*4NzrU=7>#}h=jB}<^tsAch7Ac~Vq;V7 +ziknpCHOP}_P8F&VE%6e`WG~EVa?$ra`knKZrYWbIZ_w@4vO+{B!(Pb&!YhY8pCfe= +zjxF8x>Zh3;#gw`fu})grVJcf=Ohg_Xc9m?(57$!NXQ#N%;Q{V}EjtmA$m<@Ie2(h2j9T2Xq=0<2R#daW&$ +z85=lCIqjn+?h$SF4u|?#DOOKg9>2c{9GSdlh{<(WR;Mb+bxH>u95roevUiqSmcdG* +zEL`{Qv+mA#hjLxuC*l?ROBgDsPYkDNU%;m09$2^ni=SVA=kS_) +z_h->URCbhQr89T-a-Gg9Dk?P`CT8-=f%@A28AYMmma&Ks#DNDsr^|eI%nHBQ0Nps* +z<{@u^G-9krSD|^{Vm?_nRkW_T!;E*n95To#4sxn;9FH2W%&T043S^Vg_Bk^^&J9*H +z=-^Zd6GYUG(CMkA?hy<&4Tc5fn4$3ys+ZiGw!07qHH1zPDzAJY;{8Oj#B1-LTAZ>D +zKqX)c%j0#o|H%z2zdkxYKaV6<&nEMgP`q%2&v+2dsa++rFeWoOnf$VkCAY6|8|kw{ +zdwe(maC?oeGlx#HVClH?)W&QZ`+=l3PIeQ%9cb~nWxJ9)YD|MPt`v?0-3bMcbZ<2Z +zG7xSnH{QoOr#C@?R{C$168|JMfCxcPAVuEhewgQpYO@AfbP3Fw+|Vi7h~L@$6ydj5 +zyf7_h9Rp$0Gii0mkT9xddqw>hIVCXV203~$D~swIj_)TV=zX)@-tK6Hb66mM;EywH +zsMV;{!i^8fvae3b)iz7_f6$4yU2i-b%Bh|o@eU2$RD^G(AtWlyl0^8dxd<9 +zCi_xU0%&wFugtmc%-uOk=xMY?lR%{7BQRZ~b8}1<=DQI)v2*#3|70VNVV*?SK4O}0 +z-HEICfCoyTwy@{F=Ac>4KISQEgQLDcj|>j}hzn(*RSn +zZw&u6!^Z2~7ae&u`+{IHYm_vxJJ@RRZ!LoCjQ2ecK6E;AqeyJZxfuAC +zaFBgBIQO4DawgA~vN)BCS%`;S38kn@9kWOTMq)$V$+z&4nDQvH*{(1#N58$C)v2#; +zJW|ch#FaXRBNNj6mX)HNV{_ScADWB7#Jn(Th}B15lvrI|-2fj-=SL1AY +zQrI&y#`tyxRIyenc$G7)m}|d;5&h;8q8?ap1~7v{vEXIAhojO|^XI$6=K!f+>;5yx +zJJXiq*Z?mW;Ak{?4<=)9$$a@6Q*=1_%}Nx&bGA3oqS%{I)k3y{#DALAzrPw)h(FU +zj}8a8Xte($dBpT +z_ZLeg50aO#zhmy?M*+dS#c4NyP>CZSyS+OOi>@2;)lr;&A$)(OEO;kV+bz6O57by +zyW>9>Ij2^Du|A83(r~$46%S7?Ancv(6R +zJK?TL+k$9p$KMJgY}hdrTzyS}0it==hvU?8YM**7M}l@-W{&s26~NM6 +z#U8(RCX-=6Lw%{$D&=aKSfE%aJ<__RASP1DaZcJPva<-yi3NH#t$OuNk6wlp&CD~1 +zanJ|7AhF;l{a^)Qhr_9Bo;2ZG8=}0whx#r7zZ6W`Fs5 +zJEbvhZVJVsORu$w4Y1HyT1E4?Vka&kS*mSpBuKM>OAT~3W;g7KLGzfQWF~QJ1)H6S +zFCOXwP_auqzKSygLBPB}EH;Q1gXb@Wm*lZWfM<8NWGZM_*$8Ze)0+^IpqCyco5T+P +z>!edzc-RMsx%H6~4%a*u{&6!V2Xf)f8oOKEEtBAhvI#TkSv+Ago-TMSQ(2q}=S0FP +zL(1v}1vp6Ya1@zfO!}Dq3ke|~@mmFXu2dHEQWpO$6X$;c8V@V*w>NACSkmSKF-THX +zXc85Wu2(uhx0b@}vaeA-YhO(oJ!8ZlugSxzOn{tnI7h@dCB`UVE~EEY_ww_|qDlb| +zQh0>qvDy{uar91x0J$!N&ch{3*B*?y730`NAZJT0IXU?T1Oo1Zc+QnB&!+ZYLh%_v +zV;)6DQs1sEzvoxu0r{lou-yG%CgwotYzFK>vqr!e>KRehvaz@y)fTge`_wgV2*|2H +zVl|vbxEx$3ymn~uGqN65%FYqJ<_)*Uqs49;KY2h*(Xa?Tk7AFfl-xf>irJoUyL*;0 +z19&1GQV*5Ni~#kTnaq0ymCiLjk_=0q&=&|cG{r57n*6NwV6zJl5K*ED&DsZy8iEL_rr +zgsLXr6cN9-S7dCo0TeKI3ByoGNNBIG{4b4m4=LB^FstU0B?!6TBZ1v~zn%e*Xk=B) +z@_rySE6iHcIxSfbe^sRAkjZKFfR!7A5uNa|Q%HSV{);)`X_I$=Rz#g9)RV +zjIuDE+A6IDHt@Noy^%sCnU|?kL3tCMU12QN7688MFeYr;%^{CT)BqX<4rY8gFNo(^2<+x6~@> +z0Y;8%xJK3sk3si!JoTyNPRqf>i>%mkw_b{g-~}-aAljQww_S1L53kdn=uMDZM5$#ndk +z&22o*u=b&^trc3UMGkzzrL*~$;t?gd{w8WCC+z$)6{fY`v4CL%;?|JZtR3}&oLz8* +zT?G#HsX)xAYvWho@h=pJpzsjcWp0%LD4s08onG)Nb4)MY=8K^XfVvcKVvP||0{idF +zr>Wx=dX&);ID@-|u5Y#BAa0c8rW_t)Xfo4c@By|jKCCPsr7DjJ6t;eTIrmF;CpM`~(ysWB=S@seY-cC;IYp7eGp3%$l} +z)oc?3jDrN<0qs>+yfj#>o^%eHp8`K^wUK{qUM_Xl#K;;VHK+>&$DqLQV1~BoxLuBrt&0}DAhEKn_^ER` +zz-29QNvC|8F%an87xNYKcn*LCu89T8nVkc&?~&O83)5GbY)slt*#=)i7s;A_C=2r7N7+fk`X1KngTDCyUEafq@X5m_z1=DeiD@Q38P{+Ou8AdwgrjC5 +zajlbj!7Ae^jZ~9GGnmvF%|dV*Siz7~1$lG}zFHP5%BV8TD09lQN!w79WRZ;`=PM(z +z0;YT`0PcRb5SM~SQ_OKjwTc~?W_G_IPe||U$;Um2U%fe+7X>%Nvy!xcXUbbT1miw0 +z=$X7_W&m0ay!h~`ae>C68mu@al*ia7R0saqO=sn$tE@ww372nWLhU^>%{WE>Eoln8 +zaeH(5Zly+xlW1Z@B{Z2HqS52V*oh`BC}k&quf19RS}N6$l#0qGWzl9DQkZ@85(#UMH4E) +z!&hPrOmR$HRF*}2C{e3A#U3h9d)gN68^|>O9=TO4Ga~u#5kl0}_*QP9IxEl~Ce;Vj +zS3zvyQ+p-TKYiV8z>J$akDBH=i$W7}&)8|aN%_17$7$H|;eKWRKgAtrMwoyE;#kJp +z>iJ{R+d4p$2q2;Y5EBQ7>@E&mk*MzVW>!EDsQ9Pd1Icl|=0d^U2HU!hP6MLe0bwp2 +zA=U!|OQM?{{^8dU?o^&w|I~Y5fw~zw)IT&*mzBRUy1Ljo^-=Z`fvN|N_JgxG~k*Hc%03VftQZkoi*AD{-11-bt2%}_=-R;7ZY`jOzsFyAEWb! +zVJNLPL#@4|8iv-c@m4Lu!^Uc7?VOsDWty>@T6^QN67|~9P?w&boWVpR2)d)gI@s*$ +zT0uPct)H#x^_Y(_q2El&g2<(pF8niAzCde(;c)XAp3awn@Z)3{qMO$l1?#O_cXL+a +zB+yS96Q;w{xIBw9%-h2xp$%a(D0`Noi$$31BbukCM_lu$4sG_+rWsH9U`eD0eY3t3 +z@`vkyB5OW$_NhyNPE(&_JPvYO1XVd%SiaJPVza|ZguGogD*p`OzJ!Odk4wR7o=G7; +zQFEN*_9WQcO`Vliy5G@VCnZ;Qb~fJ44e1$o^Tw=L_lA;Z-8Dw0CC}X_m5Q_J*xP61 +z2tVQGAnU9PA@k;{9QL{c=-~c_joC`W*8qxTI)7}foE-)SU;g6SD;S1P5oGCta0DrC +zGXz?khB$Fn{Ycwuk%t&RTyJ!Mz8mnC0U+AYu}PkaA-t-gE*25%;RVKNKyWz!scpu6 +zZDKFBX5S4#lCQK!Ip%UxMsP%cC4T!8d`;mo#M{(B)h;Ilk3UVA`-O^+JuQDuUnt-K +z=jEH2NuzvVs7mGT0rJ;Nz54;;pVk-{O`o<8h5~yAG9cx)%sJ+#d0-B8j!9{+{>1@9 +zYiz-m^g@6wE8^*umZD0JhIN!|&Ok-?2XhJ@B|oI&FfS^$rs90JhlZBoJW`e5b9j^- +zWO>uD9oB-o4QKEBn$akVeT1MeUX-s%#m~lPXZR!_h7SU~%Y_rx{QlrO`$o+{oUb!PIS+x5N +z+{O+YLa6?IE1#&A?RMZ&J}!O!vj>Os^y>J_BMi^Cu8;>FP)!5eagStg`4k8`f<9)s +zLv>uniXJHc5tD}2a*xO+UycHT8lGykAS#tq7H&?$Q|yXO#aH{77;M;}%#Rn*u_i#Q#=kFoCjB +zxM)O)sW@_wx=K{lJ|iyESH0iv9Nr111eP3eEA!SenTb%U12{RS*7qj0=;%^Kd#QiJ +ziYTEU=jFY{zWsSqmqmw<7L@5T1o7NxWhht`9gu$(b|QZnjVAE)D;lyC=>~hv=8piE3T9#-QVKCSaq-q&xr*zuRbfKtru+;Kkp5Si5+<6{tz}rp +zigZWmiiYYR#xdxCbhhJz=wN$k9zPcR8H;AJErv2><3*Bm51h&CEJlpT9yo5`1`w{pnaAJ%0k=ISmg0E +zo$J6^H1-w0!^WV5w|yx36dtal`WN}DGpD-gqYjDTfjIaLtR}xxCDSo6v=}KHRM^9@ +z&T;nw5x5ee(K3%Z3QQF%sMId_cIRpr&3g$f><9ZoX7X_c7g4f{y)mf(?;`TLI@jLv +z?N)ryzDJ)LsBZU+VnRH0X1E}KJ!}%#n_-hEY9w +z`8(=7Fd9^wGY;{_ggJK@ZR?yW!1!^^d;F^x%}=DG(7K8XMm$L~K*Np|t>vZmA5%Y| +zINrWxnZFq_J7&ksTGEluekfNRCX$8u^xk+?w8Q1iII^7LA8Wc=uh=>E34C14fN(+~ +zjb&LKSzG|ur8^cG=n*d|U)DK;5`-D7c>o{;1qb8{cYdL5^ll*Y29ag^ZWs(}{Dq?& +z7Vt6fu%BVSoqvD;RYW!I!KS^e-kCz_2@FvAByt<`2mpvxlE{aWp)% +z7->KZs4&!M+Z9|_;(QrbPRGNC2zLU&;bq*v@zaDlNR7 +zR!OB(0w7?XvMI3w1tc_A&fY$=RO&K>9q)K{?KeL9#X2nl`k!ouFF)XFC@Tui*%L4~ +zwNvTu3}=K5TH;uDS!^k3d+!l_hx$f?(hkYU(6NBYx@mz*Y6dZ7D@JF^5^p{aiT5zv +z;Xjc--#|sw407DGZz<4^FBXBq5F)zwTQ|65$~FTfyft2wOiY&QG(ydKoz#wa?YKny +z)9C@EX0c#XN}}K5dNFdMNo^+Os>0sS^c;E5Ky4zm)q;>J{J+z3sdUj)7tN@@gZSf7 +zJ|wiD$oI`e{Xe-gDV9P_(x}i7AaPVJn&m~NMi(84-RGbXy6@{lY?h66ze7!6Ee=i! +zInre-6PCHrI9+8v4+)Zge*esLVEy0*)t)o|)801Zf98hgQ=EZH2bpZ=)5NN_2yjw# +zP8Ewr(5WN{8DJpt*e!|G(gvZ5Pxywag$Agdns%%4+IH>|FMw9b +zKb<-v)*Cb*Ao~hb;B*`Ee&trZYBi`{$ru%gmKbuXcPNb3lD3H3Jimki7;BEFp{bxX +zFJ7Rk<~$d5(AGs1%w=$DDrj&3=?C4wX`U{m8^^=Z8R3YTB_A>ZAOkmldWl +zwo0ZyTNCB`dfUZA+chm*()HWtA2!JQ3>g${8%Vr% +zasf==&095e)fG}M%iIsk{PaQ>2|D59ppz^2pExvb9Ou9EI^`kN!0aXr*u3p0ex0b4 +z=AnHH#@v>`#o*LjN-yB0^^l)H2Nm=yD3|>1aNigv$f`s680kxF8B%d>SUG)YF0R~W +z$TI5rvll2~&q4RSwu3})*@1!~z4l}@NsY#MwV(2Y=hbLZh-ce*Eq3<#rZ +zxra}au9h@`-JaCDeW|)St?N40z`g~4rjZ?xu=?#W;cJyHNPXCV2DuxD%N1A2hAlFH +zwTJm(6XPn#dA&{dq>&yd{5Lp=pa<%$*em=~TdQ%rn_v#5`>I!IS>M^uNpl#N|wC@HMBcRTMT#SL;d7 +z<(&BuA6dLkkx|8fWw@PXzCeCBgDx@HJs@)L+j8y~gZ)7)${p-|O7{G? +z&|M6FI|A*^d_U+Of-3`+w(c~-YsQby|NH)g|G7xv|Nek^|Jex)g~z+)I0xPC0460S +LFIp>X81%mY^Bg|U diff --git a/src/test/java/com/destroystokyo/paper/entity/ai/VanillaMobGoalTest.java b/src/test/java/com/destroystokyo/paper/entity/ai/VanillaMobGoalTest.java index b2d510459bcf90a3611f3d91dae4ccc3d29b4079..7a052f6deaa30f8a177a2aaf172f9da6c308a22b 100644 @@ -28152,7 +28462,7 @@ index b2d510459bcf90a3611f3d91dae4ccc3d29b4079..7a052f6deaa30f8a177a2aaf172f9da6 } diff --git a/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java b/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java -index 8665e2740aedcc2895b0e2c44ebaba53d2a40568..b7e2227116ee0a08826674d8681fdaac97efb0ea 100644 +index 4f43882d930ab8816e75b216d9a61a06b79df265..40fc8b6579cc29e68720a99ac12f8adacc1d95be 100644 --- a/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java +++ b/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java @@ -45,6 +45,7 @@ public class MinecraftCommandPermissionsTest extends AbstractTestingBase { diff --git a/patches/server/0003-MC-Dev-fixes.patch b/patches/server/0003-MC-Dev-fixes.patch index 89037ab..d45880a 100644 --- a/patches/server/0003-MC-Dev-fixes.patch +++ b/patches/server/0003-MC-Dev-fixes.patch @@ -1,11 +1,11 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: IPECTER Date: Tue, 30 May 2023 12:12:29 +0900 -Subject: [PATCH] MC-Dev-fixes +Subject: [PATCH] MC Dev fixes diff --git a/src/main/java/net/minecraft/util/datafix/fixes/LeavesFix.java b/src/main/java/net/minecraft/util/datafix/fixes/LeavesFix.java -index 75f1d1f06978d836aab5ebbfe8f7d1e0ca5a95b6..89d70a992e0bcc8e7292c4f736470eafd8747b24 100644 +index 11ae164cce84081843518953bbeaf29904334fa9..131a0bb93c0711cc657c5571f3d8313b4bf154a8 100644 --- a/src/main/java/net/minecraft/util/datafix/fixes/LeavesFix.java +++ b/src/main/java/net/minecraft/util/datafix/fixes/LeavesFix.java @@ -71,14 +71,14 @@ public class LeavesFix extends DataFix { @@ -58,3 +58,18 @@ index 75f1d1f06978d836aab5ebbfe8f7d1e0ca5a95b6..89d70a992e0bcc8e7292c4f736470eaf return Pair.of(References.BLOCK_STATE.typeName(), dynamic); }).collect(Collectors.toList())); } +diff --git a/src/main/java/net/minecraft/world/level/storage/loot/entries/EntryGroup.java b/src/main/java/net/minecraft/world/level/storage/loot/entries/EntryGroup.java +index 6e971a9891e43b971d439c3ca11eff8965f3dae9..da1b5c6b68f14969b85472826d3d36ca673a0e5a 100644 +--- a/src/main/java/net/minecraft/world/level/storage/loot/entries/EntryGroup.java ++++ b/src/main/java/net/minecraft/world/level/storage/loot/entries/EntryGroup.java +@@ -31,8 +31,8 @@ public class EntryGroup extends CompositeEntryBase { + }; + default: + return (context, lootChoiceExpander) -> { +- for(ComposableEntryContainer composableEntryContainer : children) { +- composableEntryContainer.expand(context, lootChoiceExpander); ++ for(ComposableEntryContainer composableEntryContainer3 : children) { // Plazma - decompile fix ++ composableEntryContainer3.expand(context, lootChoiceExpander); + } + + return true; diff --git a/patches/server/0004-Rebrand.patch b/patches/server/0004-Rebrand.patch index 2d1c7d2..4db309f 100644 --- a/patches/server/0004-Rebrand.patch +++ b/patches/server/0004-Rebrand.patch @@ -5,24 +5,24 @@ Subject: [PATCH] Rebrand diff --git a/build.gradle.kts b/build.gradle.kts -index 9c01005751c0088f560f96401cdfdebbbda4e7ec..46fda579a95f9ab92a1ba61cad8218024a722208 100644 +index 139e2b17b899da6f0147bb8b4412e2e54e817be4..d8b27e3f2fa1ede41125ec27e129b1e1ad42caa7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -7,7 +7,7 @@ plugins { - } +@@ -14,7 +14,7 @@ val alsoShade: Configuration by configurations.creating dependencies { -- implementation(project(":purpur-api")) // Purpur -+ implementation(project(":plazma-api")) // Purpur - implementation("io.papermc.paper:paper-mojangapi:1.19.4-R0.1-SNAPSHOT") // Purpur - // Paper start - implementation("org.jline:jline-terminal-jansi:3.21.0") -@@ -81,7 +81,7 @@ tasks.jar { + // Purpur start +- implementation(project(":purpur-api")) ++ implementation(project(":plazma-api")) + implementation("io.papermc.paper:paper-mojangapi:${project.version}") { + exclude("io.papermc.paper", "paper-api") + } +@@ -95,7 +95,7 @@ tasks.jar { attributes( "Main-Class" to "org.bukkit.craftbukkit.Main", "Implementation-Title" to "CraftBukkit", - "Implementation-Version" to "git-Purpur-$implementationVersion", // Pufferfish // Purpur -+ "Implementation-Version" to "git-Plazma-$implementationVersion", // Pufferfish // Purpur // Plazma ++ "Implementation-Version" to "git-Plazma-$implementationVersion", // Pufferfish // Purpur "Implementation-Vendor" to date, // Paper "Specification-Title" to "Bukkit", "Specification-Version" to project.version, @@ -153,32 +153,33 @@ index b5b6657e52e4f7a630229bd3ba433438af293e22..c468733f44ccb3ff4ba3c20921a4ec52 stringbuilder.append("// "); stringbuilder.append(CrashReport.getErrorComment()); diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java -index cdbf10339a8e8846a8c364de483a0ccd95cd225a..5ed7acb332b8982a724e5002e12f18fe32dd4dd4 100644 +index dae36c6452ccd57a436dd918547b64d59957ab0a..903da36aeec8e8c7d1f3101d1e93f87412a7eed5 100644 --- a/src/main/java/net/minecraft/server/Main.java +++ b/src/main/java/net/minecraft/server/Main.java -@@ -81,6 +81,17 @@ public class Main { +@@ -112,6 +112,18 @@ public class Main { - @DontObfuscate - public static void main(final OptionSet optionset) { // CraftBukkit - replaces main(String[] astring) -+ // Plazma start - Branding -+ System.out.println(""" -+ \033[38;2;236;61;151m┏\033[38;2;236;61;157m━\033[38;2;237;62;163m━\033[38;2;237;62;169m━\033[38;2;238;62;175m━\033[38;2;238;63;181m━\033[38;2;239;63;187m┓\033[38;2;239;63;193m \033[38;2;239;64;200m┏\033[38;2;240;64;206m━\033[38;2;240;64;212m┓\033[38;2;241;65;218m \033[38;2;241;65;224m \033[38;2;242;65;230m \033[38;2;242;66;236m \033[38;2;242;66;242m \033[38;2;237;66;243m \033[38;2;232;67;243m┏\033[38;2;227;67;244m━\033[38;2;221;67;244m━\033[38;2;216;68;244m━\033[38;2;211;68;245m━\033[38;2;205;69;245m┓\033[38;2;200;69;246m \033[38;2;195;69;246m┏\033[38;2;189;70;246m━\033[38;2;184;70;247m━\033[38;2;179;70;247m━\033[38;2;173;71;247m━\033[38;2;168;71;248m━\033[38;2;163;72;248m━\033[38;2;157;72;249m┓\033[38;2;152;72;249m┏\033[38;2;147;73;249m━\033[38;2;141;73;250m━\033[38;2;136;74;250m┓\033[38;2;131;74;250m \033[38;2;125;74;251m \033[38;2;120;75;251m \033[38;2;115;75;251m┏\033[38;2;109;76;252m━\033[38;2;104;76;252m━\033[38;2;99;77;252m┓\033[38;2;94;77;253m \033[38;2;88;77;253m┏\033[38;2;83;78;253m━\033[38;2;78;79;254m━\033[38;2;79;85;254m━\033[38;2;79;91;254m━\033[38;2;80;97;255m┓\033[38;2;80;103;255m\s -+ \033[38;2;236;61;151m┃\033[38;2;236;61;157m┏\033[38;2;237;62;163m━\033[38;2;237;62;169m━\033[38;2;238;62;175m━\033[38;2;238;63;181m┓\033[38;2;239;63;187m┗\033[38;2;239;63;193m┓\033[38;2;239;64;200m┃\033[38;2;240;64;206m \033[38;2;240;64;212m┃\033[38;2;241;65;218m \033[38;2;241;65;224m \033[38;2;242;65;230m \033[38;2;242;66;236m \033[38;2;242;66;242m \033[38;2;237;66;243m┏\033[38;2;232;67;243m┛\033[38;2;227;67;244m┏\033[38;2;221;67;244m━\033[38;2;216;68;244m━\033[38;2;211;68;245m┓\033[38;2;205;69;245m┗\033[38;2;200;69;246m┓\033[38;2;195;69;246m┗\033[38;2;189;70;246m━\033[38;2;184;70;247m━\033[38;2;179;70;247m┓\033[38;2;173;71;247m \033[38;2;168;71;248m \033[38;2;163;72;248m┏\033[38;2;157;72;249m┛\033[38;2;152;72;249m┃\033[38;2;147;73;249m \033[38;2;141;73;250m \033[38;2;136;74;250m┗\033[38;2;131;74;250m┓\033[38;2;125;74;251m \033[38;2;120;75;251m┏\033[38;2;115;75;251m┛\033[38;2;109;76;252m \033[38;2;104;76;252m \033[38;2;99;77;252m┃\033[38;2;94;77;253m┏\033[38;2;88;77;253m┛\033[38;2;83;78;253m┏\033[38;2;78;79;254m━\033[38;2;79;85;254m━\033[38;2;79;91;254m┓\033[38;2;80;97;255m┗\033[38;2;80;103;255m┓ -+ \033[38;2;236;61;151m┃\033[38;2;236;61;157m┗\033[38;2;237;62;163m━\033[38;2;237;62;169m━\033[38;2;238;62;175m━\033[38;2;238;63;181m┛\033[38;2;239;63;187m┏\033[38;2;239;63;193m┛\033[38;2;239;64;200m┃\033[38;2;240;64;206m \033[38;2;240;64;212m┃\033[38;2;241;65;218m \033[38;2;241;65;224m \033[38;2;242;65;230m \033[38;2;242;66;236m \033[38;2;242;66;242m \033[38;2;237;66;243m┃\033[38;2;232;67;243m \033[38;2;227;67;244m┗\033[38;2;221;67;244m━\033[38;2;216;68;244m━\033[38;2;211;68;245m┛\033[38;2;205;69;245m \033[38;2;200;69;246m┃\033[38;2;195;69;246m \033[38;2;189;70;246m \033[38;2;184;70;247m┏\033[38;2;179;70;247m┛\033[38;2;173;71;247m \033[38;2;168;71;248m┏\033[38;2;163;72;248m┛\033[38;2;157;72;249m \033[38;2;152;72;249m┃\033[38;2;147;73;249m \033[38;2;141;73;250m┏\033[38;2;136;74;250m┓\033[38;2;131;74;250m┗\033[38;2;125;74;251m━\033[38;2;120;75;251m┛\033[38;2;115;75;251m┏\033[38;2;109;76;252m┓\033[38;2;104;76;252m \033[38;2;99;77;252m┃\033[38;2;94;77;253m┃\033[38;2;88;77;253m \033[38;2;83;78;253m┗\033[38;2;78;79;254m━\033[38;2;79;85;254m━\033[38;2;79;91;254m┛\033[38;2;80;97;255m \033[38;2;80;103;255m┃ -+ \033[38;2;236;61;151m┃\033[38;2;236;61;157m \033[38;2;237;62;163m┏\033[38;2;237;62;169m━\033[38;2;238;62;175m━\033[38;2;238;63;181m━\033[38;2;239;63;187m┛\033[38;2;239;63;193m \033[38;2;239;64;200m┃\033[38;2;240;64;206m \033[38;2;240;64;212m┃\033[38;2;241;65;218m \033[38;2;241;65;224m \033[38;2;242;65;230m \033[38;2;242;66;236m \033[38;2;242;66;242m \033[38;2;237;66;243m┃\033[38;2;232;67;243m \033[38;2;227;67;244m┏\033[38;2;221;67;244m━\033[38;2;216;68;244m━\033[38;2;211;68;245m┓\033[38;2;205;69;245m \033[38;2;200;69;246m┃\033[38;2;195;69;246m \033[38;2;189;70;246m┏\033[38;2;184;70;247m┛\033[38;2;179;70;247m \033[38;2;173;71;247m┏\033[38;2;168;71;248m┛\033[38;2;163;72;248m \033[38;2;157;72;249m \033[38;2;152;72;249m┃\033[38;2;147;73;249m \033[38;2;141;73;250m┃\033[38;2;136;74;250m┗\033[38;2;131;74;250m┓\033[38;2;125;74;251m \033[38;2;120;75;251m┏\033[38;2;115;75;251m┛\033[38;2;109;76;252m┃\033[38;2;104;76;252m \033[38;2;99;77;252m┃\033[38;2;94;77;253m┃\033[38;2;88;77;253m \033[38;2;83;78;253m┏\033[38;2;78;79;254m━\033[38;2;79;85;254m━\033[38;2;79;91;254m┓\033[38;2;80;97;255m \033[38;2;80;103;255m┃ -+ \033[38;2;236;61;151m┃\033[38;2;236;61;157m \033[38;2;237;62;163m┃\033[38;2;237;62;169m \033[38;2;238;62;175m \033[38;2;238;63;181m \033[38;2;239;63;187m \033[38;2;239;63;193m \033[38;2;239;64;200m┃\033[38;2;240;64;206m \033[38;2;240;64;212m┗\033[38;2;241;65;218m━\033[38;2;241;65;224m━\033[38;2;242;65;230m━\033[38;2;242;66;236m━\033[38;2;242;66;242m┓\033[38;2;237;66;243m┃\033[38;2;232;67;243m \033[38;2;227;67;244m┃\033[38;2;221;67;244m \033[38;2;216;68;244m \033[38;2;211;68;245m┃\033[38;2;205;69;245m \033[38;2;200;69;246m┃\033[38;2;195;69;246m┏\033[38;2;189;70;246m┛\033[38;2;184;70;247m \033[38;2;179;70;247m \033[38;2;173;71;247m┗\033[38;2;168;71;248m━\033[38;2;163;72;248m━\033[38;2;157;72;249m┓\033[38;2;152;72;249m┃\033[38;2;147;73;249m \033[38;2;141;73;250m┃\033[38;2;136;74;250m \033[38;2;131;74;250m┗\033[38;2;125;74;251m━\033[38;2;120;75;251m┛\033[38;2;115;75;251m \033[38;2;109;76;252m┃\033[38;2;104;76;252m \033[38;2;99;77;252m┃\033[38;2;94;77;253m┃\033[38;2;88;77;253m \033[38;2;83;78;253m┃\033[38;2;78;79;254m \033[38;2;79;85;254m \033[38;2;79;91;254m┃\033[38;2;80;97;255m \033[38;2;80;103;255m┃ -+ \033[38;2;236;61;151m┗\033[38;2;236;61;157m━\033[38;2;237;62;163m┛\033[38;2;237;62;169m \033[38;2;238;62;175m \033[38;2;238;63;181m \033[38;2;239;63;187m \033[38;2;239;63;193m \033[38;2;239;64;200m┗\033[38;2;240;64;206m━\033[38;2;240;64;212m━\033[38;2;241;65;218m━\033[38;2;241;65;224m━\033[38;2;242;65;230m━\033[38;2;242;66;236m━\033[38;2;242;66;242m┛\033[38;2;237;66;243m┗\033[38;2;232;67;243m━\033[38;2;227;67;244m┛\033[38;2;221;67;244m \033[38;2;216;68;244m \033[38;2;211;68;245m┗\033[38;2;205;69;245m━\033[38;2;200;69;246m┛\033[38;2;195;69;246m┗\033[38;2;189;70;246m━\033[38;2;184;70;247m━\033[38;2;179;70;247m━\033[38;2;173;71;247m━\033[38;2;168;71;248m━\033[38;2;163;72;248m━\033[38;2;157;72;249m┛\033[38;2;152;72;249m┗\033[38;2;147;73;249m━\033[38;2;141;73;250m┛\033[38;2;136;74;250m \033[38;2;131;74;250m \033[38;2;125;74;251m \033[38;2;120;75;251m \033[38;2;115;75;251m \033[38;2;109;76;252m┗\033[38;2;104;76;252m━\033[38;2;99;77;252m┛\033[38;2;94;77;253m┗\033[38;2;88;77;253m━\033[38;2;83;78;253m┛\033[38;2;78;79;254m \033[38;2;79;85;254m \033[38;2;79;91;254m┗\033[38;2;80;97;255m━\033[38;2;80;103;255m┛ -+ """); -+ LOGGER.warn("Warning! Plazma may cause unexpected problems, so DO NOT USE it on a production server!"); -+ // Plazma end - SharedConstants.tryDetectVersion(); - /* CraftBukkit start - Replace everything - OptionParser optionparser = new OptionParser(); + try { + ++ // Plazma start - Branding ++ System.out.println(""" ++ \033[38;2;236;61;151m┏\033[38;2;236;61;157m━\033[38;2;237;62;163m━\033[38;2;237;62;169m━\033[38;2;238;62;175m━\033[38;2;238;63;181m━\033[38;2;239;63;187m┓\033[38;2;239;63;193m \033[38;2;239;64;200m┏\033[38;2;240;64;206m━\033[38;2;240;64;212m┓\033[38;2;241;65;218m \033[38;2;241;65;224m \033[38;2;242;65;230m \033[38;2;242;66;236m \033[38;2;242;66;242m \033[38;2;237;66;243m \033[38;2;232;67;243m┏\033[38;2;227;67;244m━\033[38;2;221;67;244m━\033[38;2;216;68;244m━\033[38;2;211;68;245m━\033[38;2;205;69;245m┓\033[38;2;200;69;246m \033[38;2;195;69;246m┏\033[38;2;189;70;246m━\033[38;2;184;70;247m━\033[38;2;179;70;247m━\033[38;2;173;71;247m━\033[38;2;168;71;248m━\033[38;2;163;72;248m━\033[38;2;157;72;249m┓\033[38;2;152;72;249m┏\033[38;2;147;73;249m━\033[38;2;141;73;250m━\033[38;2;136;74;250m┓\033[38;2;131;74;250m \033[38;2;125;74;251m \033[38;2;120;75;251m \033[38;2;115;75;251m┏\033[38;2;109;76;252m━\033[38;2;104;76;252m━\033[38;2;99;77;252m┓\033[38;2;94;77;253m \033[38;2;88;77;253m┏\033[38;2;83;78;253m━\033[38;2;78;79;254m━\033[38;2;79;85;254m━\033[38;2;79;91;254m━\033[38;2;80;97;255m┓\033[38;2;80;103;255m\s ++ \033[38;2;236;61;151m┃\033[38;2;236;61;157m┏\033[38;2;237;62;163m━\033[38;2;237;62;169m━\033[38;2;238;62;175m━\033[38;2;238;63;181m┓\033[38;2;239;63;187m┗\033[38;2;239;63;193m┓\033[38;2;239;64;200m┃\033[38;2;240;64;206m \033[38;2;240;64;212m┃\033[38;2;241;65;218m \033[38;2;241;65;224m \033[38;2;242;65;230m \033[38;2;242;66;236m \033[38;2;242;66;242m \033[38;2;237;66;243m┏\033[38;2;232;67;243m┛\033[38;2;227;67;244m┏\033[38;2;221;67;244m━\033[38;2;216;68;244m━\033[38;2;211;68;245m┓\033[38;2;205;69;245m┗\033[38;2;200;69;246m┓\033[38;2;195;69;246m┗\033[38;2;189;70;246m━\033[38;2;184;70;247m━\033[38;2;179;70;247m┓\033[38;2;173;71;247m \033[38;2;168;71;248m \033[38;2;163;72;248m┏\033[38;2;157;72;249m┛\033[38;2;152;72;249m┃\033[38;2;147;73;249m \033[38;2;141;73;250m \033[38;2;136;74;250m┗\033[38;2;131;74;250m┓\033[38;2;125;74;251m \033[38;2;120;75;251m┏\033[38;2;115;75;251m┛\033[38;2;109;76;252m \033[38;2;104;76;252m \033[38;2;99;77;252m┃\033[38;2;94;77;253m┏\033[38;2;88;77;253m┛\033[38;2;83;78;253m┏\033[38;2;78;79;254m━\033[38;2;79;85;254m━\033[38;2;79;91;254m┓\033[38;2;80;97;255m┗\033[38;2;80;103;255m┓ ++ \033[38;2;236;61;151m┃\033[38;2;236;61;157m┗\033[38;2;237;62;163m━\033[38;2;237;62;169m━\033[38;2;238;62;175m━\033[38;2;238;63;181m┛\033[38;2;239;63;187m┏\033[38;2;239;63;193m┛\033[38;2;239;64;200m┃\033[38;2;240;64;206m \033[38;2;240;64;212m┃\033[38;2;241;65;218m \033[38;2;241;65;224m \033[38;2;242;65;230m \033[38;2;242;66;236m \033[38;2;242;66;242m \033[38;2;237;66;243m┃\033[38;2;232;67;243m \033[38;2;227;67;244m┗\033[38;2;221;67;244m━\033[38;2;216;68;244m━\033[38;2;211;68;245m┛\033[38;2;205;69;245m \033[38;2;200;69;246m┃\033[38;2;195;69;246m \033[38;2;189;70;246m \033[38;2;184;70;247m┏\033[38;2;179;70;247m┛\033[38;2;173;71;247m \033[38;2;168;71;248m┏\033[38;2;163;72;248m┛\033[38;2;157;72;249m \033[38;2;152;72;249m┃\033[38;2;147;73;249m \033[38;2;141;73;250m┏\033[38;2;136;74;250m┓\033[38;2;131;74;250m┗\033[38;2;125;74;251m━\033[38;2;120;75;251m┛\033[38;2;115;75;251m┏\033[38;2;109;76;252m┓\033[38;2;104;76;252m \033[38;2;99;77;252m┃\033[38;2;94;77;253m┃\033[38;2;88;77;253m \033[38;2;83;78;253m┗\033[38;2;78;79;254m━\033[38;2;79;85;254m━\033[38;2;79;91;254m┛\033[38;2;80;97;255m \033[38;2;80;103;255m┃ ++ \033[38;2;236;61;151m┃\033[38;2;236;61;157m \033[38;2;237;62;163m┏\033[38;2;237;62;169m━\033[38;2;238;62;175m━\033[38;2;238;63;181m━\033[38;2;239;63;187m┛\033[38;2;239;63;193m \033[38;2;239;64;200m┃\033[38;2;240;64;206m \033[38;2;240;64;212m┃\033[38;2;241;65;218m \033[38;2;241;65;224m \033[38;2;242;65;230m \033[38;2;242;66;236m \033[38;2;242;66;242m \033[38;2;237;66;243m┃\033[38;2;232;67;243m \033[38;2;227;67;244m┏\033[38;2;221;67;244m━\033[38;2;216;68;244m━\033[38;2;211;68;245m┓\033[38;2;205;69;245m \033[38;2;200;69;246m┃\033[38;2;195;69;246m \033[38;2;189;70;246m┏\033[38;2;184;70;247m┛\033[38;2;179;70;247m \033[38;2;173;71;247m┏\033[38;2;168;71;248m┛\033[38;2;163;72;248m \033[38;2;157;72;249m \033[38;2;152;72;249m┃\033[38;2;147;73;249m \033[38;2;141;73;250m┃\033[38;2;136;74;250m┗\033[38;2;131;74;250m┓\033[38;2;125;74;251m \033[38;2;120;75;251m┏\033[38;2;115;75;251m┛\033[38;2;109;76;252m┃\033[38;2;104;76;252m \033[38;2;99;77;252m┃\033[38;2;94;77;253m┃\033[38;2;88;77;253m \033[38;2;83;78;253m┏\033[38;2;78;79;254m━\033[38;2;79;85;254m━\033[38;2;79;91;254m┓\033[38;2;80;97;255m \033[38;2;80;103;255m┃ ++ \033[38;2;236;61;151m┃\033[38;2;236;61;157m \033[38;2;237;62;163m┃\033[38;2;237;62;169m \033[38;2;238;62;175m \033[38;2;238;63;181m \033[38;2;239;63;187m \033[38;2;239;63;193m \033[38;2;239;64;200m┃\033[38;2;240;64;206m \033[38;2;240;64;212m┗\033[38;2;241;65;218m━\033[38;2;241;65;224m━\033[38;2;242;65;230m━\033[38;2;242;66;236m━\033[38;2;242;66;242m┓\033[38;2;237;66;243m┃\033[38;2;232;67;243m \033[38;2;227;67;244m┃\033[38;2;221;67;244m \033[38;2;216;68;244m \033[38;2;211;68;245m┃\033[38;2;205;69;245m \033[38;2;200;69;246m┃\033[38;2;195;69;246m┏\033[38;2;189;70;246m┛\033[38;2;184;70;247m \033[38;2;179;70;247m \033[38;2;173;71;247m┗\033[38;2;168;71;248m━\033[38;2;163;72;248m━\033[38;2;157;72;249m┓\033[38;2;152;72;249m┃\033[38;2;147;73;249m \033[38;2;141;73;250m┃\033[38;2;136;74;250m \033[38;2;131;74;250m┗\033[38;2;125;74;251m━\033[38;2;120;75;251m┛\033[38;2;115;75;251m \033[38;2;109;76;252m┃\033[38;2;104;76;252m \033[38;2;99;77;252m┃\033[38;2;94;77;253m┃\033[38;2;88;77;253m \033[38;2;83;78;253m┃\033[38;2;78;79;254m \033[38;2;79;85;254m \033[38;2;79;91;254m┃\033[38;2;80;97;255m \033[38;2;80;103;255m┃ ++ \033[38;2;236;61;151m┗\033[38;2;236;61;157m━\033[38;2;237;62;163m┛\033[38;2;237;62;169m \033[38;2;238;62;175m \033[38;2;238;63;181m \033[38;2;239;63;187m \033[38;2;239;63;193m \033[38;2;239;64;200m┗\033[38;2;240;64;206m━\033[38;2;240;64;212m━\033[38;2;241;65;218m━\033[38;2;241;65;224m━\033[38;2;242;65;230m━\033[38;2;242;66;236m━\033[38;2;242;66;242m┛\033[38;2;237;66;243m┗\033[38;2;232;67;243m━\033[38;2;227;67;244m┛\033[38;2;221;67;244m \033[38;2;216;68;244m \033[38;2;211;68;245m┗\033[38;2;205;69;245m━\033[38;2;200;69;246m┛\033[38;2;195;69;246m┗\033[38;2;189;70;246m━\033[38;2;184;70;247m━\033[38;2;179;70;247m━\033[38;2;173;71;247m━\033[38;2;168;71;248m━\033[38;2;163;72;248m━\033[38;2;157;72;249m┛\033[38;2;152;72;249m┗\033[38;2;147;73;249m━\033[38;2;141;73;250m┛\033[38;2;136;74;250m \033[38;2;131;74;250m \033[38;2;125;74;251m \033[38;2;120;75;251m \033[38;2;115;75;251m \033[38;2;109;76;252m┗\033[38;2;104;76;252m━\033[38;2;99;77;252m┛\033[38;2;94;77;253m┗\033[38;2;88;77;253m━\033[38;2;83;78;253m┛\033[38;2;78;79;254m \033[38;2;79;85;254m \033[38;2;79;91;254m┗\033[38;2;80;97;255m━\033[38;2;80;103;255m┛ ++ """); ++ LOGGER.warn("Warning! Plazma may cause unexpected problems, so DO NOT USE it on a production server!"); ++ // Plazma end ++ + Path path = (Path) optionset.valueOf("pidFile"); // CraftBukkit + + if (path != null) { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index beb05039926e1fb7a656dfcd0c503f82db67fc46..615c456de68a20d0e95b30e124a2bdf46039408f 100644 +index e6ddf69ade7ae51640569150f7db10d1afa63691..77b40f3d7162befe4da29a60b3de2b93b261412c 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -930,7 +930,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop SPIGOT_WORLD_DEFAULTS = Suppliers.memoize(() -> new SpigotWorldConfig(RandomStringUtils.randomAlphabetic(255)) { -+ public static final Supplier SPIGOT_WORLD_DEFAULTS = Suppliers.memoize(() -> new SpigotWorldConfig(RandomStringUtils.randomAlphabetic(255)) { // Plazma - private -> public - @Override // override to ensure "verbose" is false - public void init() { +@@ -135,7 +135,7 @@ public class PaperConfigurations extends Configurations public + + // Plazma start + @Override + public org.plazmamc.plazma.configurations.PlazmaConfigurations plazmaConfigurations() { @@ -217,24 +210,24 @@ index ef6ff78af2ae747e939895b82ee9d11c75012dcd..6e3a1ea75005ba53a72889285597603f + } + // Plazma end + - public static final String USERID_CACHE_FILE = "usercache.json"; // Paper - private -> public - public static Services create(YggdrasilAuthenticationService authenticationService, File rootDirectory, File userCacheFile, joptsimple.OptionSet optionSet) throws Exception { // Paper -@@ -30,7 +38,11 @@ public record Services(MinecraftSessionService sessionService, SignatureValidato + MinecraftSessionService minecraftSessionService = authenticationService.createMinecraftSessionService(); + GameProfileRepository gameProfileRepository = authenticationService.createProfileRepository(); +@@ -32,7 +39,11 @@ public record Services(MinecraftSessionService sessionService, ServicesKeySet se final java.nio.file.Path legacyConfigPath = ((File) optionSet.valueOf("paper-settings")).toPath(); final java.nio.file.Path configDirPath = ((File) optionSet.valueOf("paper-settings-directory")).toPath(); io.papermc.paper.configuration.PaperConfigurations paperConfigurations = io.papermc.paper.configuration.PaperConfigurations.setup(legacyConfigPath, configDirPath, rootDirectory.toPath(), (File) optionSet.valueOf("spigot-settings")); -- return new Services(minecraftSessionService, signatureValidator, gameProfileRepository, gameProfileCache, paperConfigurations); +- return new Services(minecraftSessionService, authenticationService.getServicesKeySet(), gameProfileRepository, gameProfileCache, paperConfigurations); + // Plazma start + final java.nio.file.Path plazmaConfigurationDirPath = ((File) optionSet.valueOf("plazma-configurations-directory")).toPath(); + org.plazmamc.plazma.configurations.PlazmaConfigurations plazmaConfigurations = org.plazmamc.plazma.configurations.PlazmaConfigurations.setup(plazmaConfigurationDirPath); -+ return new Services(minecraftSessionService, signatureValidator, gameProfileRepository, gameProfileCache, paperConfigurations, plazmaConfigurations); ++ return new Services(minecraftSessionService, authenticationService.getServicesKeySet(), gameProfileRepository, gameProfileCache, paperConfigurations, plazmaConfigurations); + // Plazma end // Paper end } - } + diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index 6ecc75621867390738e804e06ac284524664473d..b91910eaac0e9c18722e52d223a4420199d77a7f 100644 +index 2a70abb9e0af502885593df1e732887cd9d2ce4d..e6f14bb0825e3b6987ebb2ec782c8316e3b7c094 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java @@ -209,6 +209,10 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface @@ -252,15 +245,15 @@ index 6ecc75621867390738e804e06ac284524664473d..b91910eaac0e9c18722e52d223a44201 org.spigotmc.WatchdogThread.doStart(org.spigotmc.SpigotConfig.timeoutTime, org.spigotmc.SpigotConfig.restartOnCrash); thread.start(); // Paper - start console thread after MinecraftServer.console & PaperConfig are initialized io.papermc.paper.command.PaperCommands.registerCommands(this); -+ org.plazmamc.plazma.commands.PlazmaCommands.registerCommands(this); ++ org.plazmamc.plazma.commands.PlazmaCommands.registerCommands(this); // Plazma com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Purpur start try { diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 86b8485c0fb1dc5cd79c9e24546dc74459822a48..ebbf462835e5a14fe1413c724d4985635207a897 100644 +index 221d1d0e1b4b46de6ebca5faac09bbda875fae17..e009dba395779e2c89a36fe4524e5d40474a29e6 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -530,7 +530,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -650,7 +650,7 @@ public class ServerLevel extends Level implements WorldGenLevel { // Holder holder = worlddimension.type(); // CraftBukkit - decompile error // Objects.requireNonNull(minecraftserver); // CraftBukkit - decompile error @@ -270,10 +263,10 @@ index 86b8485c0fb1dc5cd79c9e24546dc74459822a48..ebbf462835e5a14fe1413c724d498563 this.convertable = convertable_conversionsession; this.uuid = WorldUUID.getUUID(convertable_conversionsession.levelDirectory.path().toFile()); diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 92b440b24c6b083f81837611d08fbd6773a2a6e6..058449f24eb3260dc230dad2a0b4c552d0b7f40e 100644 +index 9fb140b3b6a0c621466b85a6ec7df765a4e823b0..08f9af1d7aebba943096b59b6452818a1aafc94c 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -175,7 +175,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -174,7 +174,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable { return this.paperConfig; } // Paper end @@ -287,7 +280,7 @@ index 92b440b24c6b083f81837611d08fbd6773a2a6e6..058449f24eb3260dc230dad2a0b4c552 public final com.destroystokyo.paper.antixray.ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray public final org.purpurmc.purpur.PurpurWorldConfig purpurConfig; // Purpur public final co.aikar.timings.WorldTimingsHandler timings; // Paper -@@ -329,9 +334,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -328,9 +333,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @Override public final int getHeight() { return this.height; } // Pufferfish end @@ -300,10 +293,10 @@ index 92b440b24c6b083f81837611d08fbd6773a2a6e6..058449f24eb3260dc230dad2a0b4c552 this.playerBreedingCooldowns = this.getNewBreedingCooldownCache(); // Purpur this.generator = gen; diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 5e6952a9d4c1137dc3d720ee2c944d95d4628065..1367072684078c0e93c275c2159ece799f96428b 100644 +index 8833a66f43e9a4ac486fa67db9e8147007917e15..153fcfc55589691a570080aa4f4e179452bf4f6c 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -993,6 +993,7 @@ public final class CraftServer implements Server { +@@ -1071,6 +1071,7 @@ public final class CraftServer implements Server { org.spigotmc.SpigotConfig.init((File) console.options.valueOf("spigot-settings")); // Spigot this.console.paperConfigurations.reloadConfigs(this.console); @@ -311,7 +304,7 @@ index 5e6952a9d4c1137dc3d720ee2c944d95d4628065..1367072684078c0e93c275c2159ece79 org.purpurmc.purpur.PurpurConfig.init((File) console.options.valueOf("purpur-settings")); // Purpur for (ServerLevel world : this.console.getAllLevels()) { // world.serverLevelData.setDifficulty(config.difficulty); // Paper - per level difficulty -@@ -2835,6 +2836,13 @@ public final class CraftServer implements Server { +@@ -3004,6 +3005,13 @@ public final class CraftServer implements Server { return CraftServer.this.console.paperConfigurations.createLegacyObject(CraftServer.this.console); } @@ -326,7 +319,7 @@ index 5e6952a9d4c1137dc3d720ee2c944d95d4628065..1367072684078c0e93c275c2159ece79 @Override public YamlConfiguration getPurpurConfig() { diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index 288cf98287c6d3c073b9ab6696c3957c999cad32..4970b246356bbd04eb1f9715da3fc7c9494573e2 100644 +index 9a3374a1236164194ef0df43ed639296cbe1c731..affd4c6267f60cbae75b6e6a09990144a1f1e1f0 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -173,6 +173,14 @@ public class Main { @@ -975,7 +968,7 @@ index 0000000000000000000000000000000000000000..469100cd86e6742eeebad22923097782 + +} diff --git a/src/test/java/org/bukkit/support/AbstractTestingBase.java b/src/test/java/org/bukkit/support/AbstractTestingBase.java -index a616624a7beb35239be0fc2bb7fe60db1c673c2d..602ac1b30937a89312be7ba068a595d398e53394 100644 +index d1fd4cf65c31bc00d0bffa3123fc2223f1498a34..0aebabc83eea721e4f373fb00f4ee80b659efe83 100644 --- a/src/test/java/org/bukkit/support/AbstractTestingBase.java +++ b/src/test/java/org/bukkit/support/AbstractTestingBase.java @@ -63,6 +63,7 @@ public abstract class AbstractTestingBase { diff --git a/patches/server/0008-Optimize-Default-Configurations.patch b/patches/server/0008-Optimize-Default-Configurations.patch index 24f5fb5..167fe16 100644 --- a/patches/server/0008-Optimize-Default-Configurations.patch +++ b/patches/server/0008-Optimize-Default-Configurations.patch @@ -7,7 +7,7 @@ Original: YouHaveTrouble/minecraft-optimization, AkiraDevelopment/SimplyMC Copyright (C) 2023 YouHaveTrouble, AkiraDevelopment diff --git a/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java b/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java -index b4e5fbace85c67e7bd347e6a90514bbc2c132d5e..edc8eba38af743167a8b78d34cb426d6929f9605 100644 +index bff1b41501c040487583a5a279fc7800fc6aedca..2d7e1ffa117fa2581ab2a42cd04d062f25559b11 100644 --- a/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java +++ b/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java @@ -211,8 +211,8 @@ public class PufferfishConfig { @@ -43,10 +43,10 @@ index b4e5fbace85c67e7bd347e6a90514bbc2c132d5e..edc8eba38af743167a8b78d34cb426d6 "If you want further away entities to tick less often, use 7.", "If you want further away entities to tick more often, try 9."); diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 8d442c5a498ecf288a0cc0c54889c6e2fda849ce..205ce3456a3f6d28cc2c7cbc131ec0f63a461527 100644 +index 019d3bbd78fb0b06861979d223915fedb6c99442..553127c9a38612005530cffdb25544585e6c8234 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -103,7 +103,7 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -142,7 +142,7 @@ public class GlobalConfiguration extends ConfigurationPart { public class Watchdog extends ConfigurationPart { public int earlyWarningEvery = 5000; @@ -56,10 +56,10 @@ index 8d442c5a498ecf288a0cc0c54889c6e2fda849ce..205ce3456a3f6d28cc2c7cbc131ec0f6 public SpamLimiter spamLimiter; diff --git a/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java -index a33de97340f14219291c4175e9194914cdf441db..f63b4ab2057176d4f1549200eef16e71c6018dc2 100644 +index da7c899fbab162ee197a0593f455ebd9c5286d3c..f2f20730ac4602dea996948e525a40ec6520ed09 100644 --- a/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java -@@ -84,15 +84,15 @@ public class WorldConfiguration extends ConfigurationPart { +@@ -88,15 +88,15 @@ public class WorldConfiguration extends ConfigurationPart { public class AntiXray extends ConfigurationPart { public boolean enabled = false; @@ -80,7 +80,7 @@ index a33de97340f14219291c4175e9194914cdf441db..f63b4ab2057176d4f1549200eef16e71 } } -@@ -139,7 +139,7 @@ public class WorldConfiguration extends ConfigurationPart { +@@ -150,7 +150,7 @@ public class WorldConfiguration extends ConfigurationPart { @MergeMap public Reference2IntMap spawnLimits = Util.make(new Reference2IntOpenHashMap<>(NaturalSpawner.SPAWNING_CATEGORIES.length), map -> Arrays.stream(NaturalSpawner.SPAWNING_CATEGORIES).forEach(mobCategory -> map.put(mobCategory, -1))); @MergeMap @@ -89,7 +89,7 @@ index a33de97340f14219291c4175e9194914cdf441db..f63b4ab2057176d4f1549200eef16e71 @ConfigSerializable public record DespawnRange(@Required int soft, @Required int hard) { -@@ -323,7 +323,7 @@ public class WorldConfiguration extends ConfigurationPart { +@@ -371,7 +371,7 @@ public class WorldConfiguration extends ConfigurationPart { public class Environment extends ConfigurationPart { public boolean disableThunder = false; public boolean disableIceAndSnow = false; @@ -98,7 +98,7 @@ index a33de97340f14219291c4175e9194914cdf441db..f63b4ab2057176d4f1549200eef16e71 public boolean disableExplosionKnockback = false; public boolean generateFlatBedrock = false; public FrostedIce frostedIce; -@@ -403,9 +403,9 @@ public class WorldConfiguration extends ConfigurationPart { +@@ -451,9 +451,9 @@ public class WorldConfiguration extends ConfigurationPart { public class Collisions extends ConfigurationPart { public boolean onlyPlayersCollide = false; public boolean allowVehicleCollisions = true; @@ -110,7 +110,7 @@ index a33de97340f14219291c4175e9194914cdf441db..f63b4ab2057176d4f1549200eef16e71 public boolean allowPlayerCrammingDamage = false; } -@@ -413,18 +413,40 @@ public class WorldConfiguration extends ConfigurationPart { +@@ -461,18 +461,40 @@ public class WorldConfiguration extends ConfigurationPart { public class Chunks extends ConfigurationPart { public AutosavePeriod autoSaveInterval = AutosavePeriod.def(); @@ -160,7 +160,7 @@ index a33de97340f14219291c4175e9194914cdf441db..f63b4ab2057176d4f1549200eef16e71 }); public boolean flushRegionsOnSave = false; } -@@ -439,9 +461,9 @@ public class WorldConfiguration extends ConfigurationPart { +@@ -487,9 +509,9 @@ public class WorldConfiguration extends ConfigurationPart { public TickRates tickRates; public class TickRates extends ConfigurationPart { @@ -172,7 +172,7 @@ index a33de97340f14219291c4175e9194914cdf441db..f63b4ab2057176d4f1549200eef16e71 public Table, String, Integer> sensor = Util.make(HashBasedTable.create(), table -> table.put(EntityType.VILLAGER, "secondarypoisensor", 40)); public Table, String, Integer> behavior = Util.make(HashBasedTable.create(), table -> table.put(EntityType.VILLAGER, "validatenearbypoi", -1)); } -@@ -465,9 +487,9 @@ public class WorldConfiguration extends ConfigurationPart { +@@ -513,9 +535,9 @@ public class WorldConfiguration extends ConfigurationPart { public class Misc extends ConfigurationPart { public int lightQueueSize = 20; @@ -197,10 +197,10 @@ index 24763d3d270c29c95e0b3e85111145234f660a62..18bc271a34ffba8c83743fef7eaf4a2c } diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java -index 5ed7acb332b8982a724e5002e12f18fe32dd4dd4..8a10f9b7b837c4d20eaf4a83827e36f14a180ea7 100644 +index 903da36aeec8e8c7d1f3101d1e93f87412a7eed5..79593800173ad2b837b081e6091e98adfa41fb99 100644 --- a/src/main/java/net/minecraft/server/Main.java +++ b/src/main/java/net/minecraft/server/Main.java -@@ -154,7 +154,7 @@ public class Main { +@@ -155,7 +155,7 @@ public class Main { File configFile = (File) optionset.valueOf("bukkit-settings"); YamlConfiguration configuration = YamlConfiguration.loadConfiguration(configFile); configuration.options().copyDefaults(true); @@ -252,10 +252,10 @@ index 1ea3012995c738c67b31e997c138f824f9e69ba1..8ed00a650b712cbf4bc8796165a539d7 this.enableStatus = this.get("enable-status", true); this.hideOnlinePlayers = this.get("hide-online-players", false); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 1367072684078c0e93c275c2159ece799f96428b..84fb7f6cdad5e7a5389e2469bfd6fb961cd1b299 100644 +index 153fcfc55589691a570080aa4f4e179452bf4f6c..45dabf7fc7531392b4140416f2f0931090f14235 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -354,7 +354,7 @@ public final class CraftServer implements Server { +@@ -427,7 +427,7 @@ public final class CraftServer implements Server { this.configuration = YamlConfiguration.loadConfiguration(this.getConfigFile()); this.configuration.options().copyDefaults(true); @@ -265,7 +265,7 @@ index 1367072684078c0e93c275c2159ece799f96428b..84fb7f6cdad5e7a5389e2469bfd6fb96 if (!this.configuration.isString("aliases")) { legacyAlias = this.configuration.getConfigurationSection("aliases"); diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java -index c93f6d275d0541e0751eefca45d17c4ccd39a62a..38a8f79b0075279389f0b3dc7de4b16d9af05295 100644 +index d0d31002562e728fa1a6c9bc81baa4534f11d365..d0968eeb0f9edeee43394da8a32d3ee8d491737b 100644 --- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java +++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java @@ -49,7 +49,10 @@ public class PurpurConfig { @@ -280,7 +280,7 @@ index c93f6d275d0541e0751eefca45d17c4ccd39a62a..38a8f79b0075279389f0b3dc7de4b16d private static File CONFIG_FILE; public static YamlConfiguration config; -@@ -239,7 +242,7 @@ public class PurpurConfig { +@@ -241,7 +244,7 @@ public class PurpurConfig { laggingThreshold = getDouble("settings.lagging-threshold", laggingThreshold); } @@ -290,10 +290,10 @@ index c93f6d275d0541e0751eefca45d17c4ccd39a62a..38a8f79b0075279389f0b3dc7de4b16d useAlternateKeepAlive = getBoolean("settings.use-alternate-keepalive", useAlternateKeepAlive); } diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -index 397c4afa8da85845f49974832674a6e45ee6edb7..ce702e6b5fff3a54f9f254a61becd12eb5c11dd7 100644 +index 078102e636803f38facc049952813ff2f8b63594..16c3a06df8575a4fecd1967cf18854cb6267a4f7 100644 --- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java +++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -@@ -427,7 +427,7 @@ public class PurpurWorldConfig { +@@ -425,7 +425,7 @@ public class PurpurWorldConfig { public boolean playerInvulnerableWhileAcceptingResourcePack = false; public String playerDeathExpDropEquation = "expLevel * 7"; public int playerDeathExpDropMax = 100; @@ -302,7 +302,7 @@ index 397c4afa8da85845f49974832674a6e45ee6edb7..ce702e6b5fff3a54f9f254a61becd12e public boolean teleportOnNetherCeilingDamage = false; public boolean totemOfUndyingWorksInInventory = false; public boolean playerFixStuckPortal = false; -@@ -3040,7 +3040,7 @@ public class PurpurWorldConfig { +@@ -3070,7 +3070,7 @@ public class PurpurWorldConfig { public boolean zombieJockeyOnlyBaby = true; public double zombieJockeyChance = 0.05D; public boolean zombieJockeyTryExistingChickens = true; @@ -312,10 +312,10 @@ index 397c4afa8da85845f49974832674a6e45ee6edb7..ce702e6b5fff3a54f9f254a61becd12e public boolean zombieTakeDamageFromWater = false; public boolean zombieAlwaysDropExp = false; diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java -index bbfafb1400721251dfd2cac4dd8a31be2d682d4b..f61aca65f9d9bc6888285def1c9016f7a7395919 100644 +index 5b5109e942b18418b3a3a0e2109fe4ef15045fe5..e24106f0d936375f200cb82339dc03f8f6f528e6 100644 --- a/src/main/java/org/spigotmc/SpigotWorldConfig.java +++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java -@@ -148,14 +148,14 @@ public class SpigotWorldConfig +@@ -150,14 +150,14 @@ public class SpigotWorldConfig public double itemMerge; private void itemMerge() { @@ -332,7 +332,7 @@ index bbfafb1400721251dfd2cac4dd8a31be2d682d4b..f61aca65f9d9bc6888285def1c9016f7 this.log( "Experience Merge Radius: " + this.expMerge ); } -@@ -194,7 +194,7 @@ public class SpigotWorldConfig +@@ -196,7 +196,7 @@ public class SpigotWorldConfig public byte mobSpawnRange; private void mobSpawnRange() { @@ -341,7 +341,7 @@ index bbfafb1400721251dfd2cac4dd8a31be2d682d4b..f61aca65f9d9bc6888285def1c9016f7 this.log( "Mob Spawn Range: " + this.mobSpawnRange ); } -@@ -205,26 +205,26 @@ public class SpigotWorldConfig +@@ -207,26 +207,26 @@ public class SpigotWorldConfig this.log( "Item Despawn Rate: " + this.itemDespawnRate ); } @@ -381,7 +381,7 @@ index bbfafb1400721251dfd2cac4dd8a31be2d682d4b..f61aca65f9d9bc6888285def1c9016f7 public int villagersWorkImmunityAfter = 5*20; public int villagersWorkImmunityFor = 20; public boolean villagersActiveForPanic = true; -@@ -297,7 +297,7 @@ public class SpigotWorldConfig +@@ -299,7 +299,7 @@ public class SpigotWorldConfig { this.set( "ticks-per.hopper-check", 1 ); } @@ -390,7 +390,7 @@ index bbfafb1400721251dfd2cac4dd8a31be2d682d4b..f61aca65f9d9bc6888285def1c9016f7 this.hopperAmount = this.getInt( "hopper-amount", 1 ); this.hopperCanLoadChunks = this.getBoolean( "hopper-can-load-chunks", false ); this.log( "Hopper Transfer: " + this.hopperTransfer + " Hopper Check: " + this.hopperCheck + " Hopper Amount: " + this.hopperAmount + " Hopper Can Load Chunks: " + this.hopperCanLoadChunks ); -@@ -307,7 +307,7 @@ public class SpigotWorldConfig +@@ -309,7 +309,7 @@ public class SpigotWorldConfig public int tridentDespawnRate; private void arrowDespawnRate() { diff --git a/patches/server/0010-Implement-ChunkSending.patch b/patches/server/0010-Implement-ChunkSending.patch index a4bde9a..43a4764 100644 --- a/patches/server/0010-Implement-ChunkSending.patch +++ b/patches/server/0010-Implement-ChunkSending.patch @@ -7,41 +7,34 @@ Original: someaddons/chunksending Copyright (C) 2023 someaddons diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java -index 904fcdeb7937d36208cc9a8d5eca9ef3a5b2cd9e..7f749579fe056a8436e6625204ae31f1fcc15f32 100644 +index e2202389a2c4133a183cca59c4e909fc419379ab..ccb7ff8832d3673a46d0a285f09d57d12bc0203a 100644 --- a/src/main/java/net/minecraft/server/level/ChunkHolder.java +++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java -@@ -362,15 +362,14 @@ public class ChunkHolder { - } +@@ -398,9 +398,11 @@ public class ChunkHolder { + // Paper end - rewrite chunk system - Object[] backingSet = players.getBackingSet(); -- for (int i = 0, len = backingSet.length; i < len; ++i) { -- if (!(backingSet[i] instanceof ServerPlayer player)) { -- continue; -- } -- if (!this.chunkMap.playerChunkManager.isChunkSent(player, this.pos.x, this.pos.z, onlyOnWatchDistanceEdge)) { -- continue; -- } -+ // Plazma start - Implement ChunkSending -+ for (Object o : backingSet) { -+ if (!(o instanceof ServerPlayer player) -+ || !this.chunkMap.playerChunkManager.isChunkSent(player, this.pos.x, this.pos.z, onlyOnWatchDistanceEdge) -+ || (this.chunkMap.level.plazmaLevelConfiguration().chunkSending.enabled && player.attachToPending(pos, packet))) continue; - player.connection.send(packet); - } + private void broadcast(List players, Packet packet) { +- players.forEach((entityplayer) -> { +- entityplayer.connection.send(packet); +- }); ++ // Plazma start ++ for (ServerPlayer player : players) ++ if (this.chunkMap.level.plazmaLevelConfiguration().chunkSending.enabled && !player.attachToPending(pos, packet)) ++ player.connection.send(packet); + // Plazma end - // Paper end - per player view distance } + // Paper - rewrite chunk system diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 852266234cf3d63e3b23a71639e40defca91c1b8..4668eebc0776a470a42de94de1752986f76250d3 100644 +index 0249eeb3937cf48cea13846a7e39b248947e21a4..f39b3f1b5b37d1939766952a985684279cb2bf2d 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -730,8 +730,36 @@ public class ServerPlayer extends Player { +@@ -772,7 +772,35 @@ public class ServerPlayer extends Player { } } // Purpur end + // Plazma start - Implement ChunkSending -+ if (this.level.plazmaLevelConfiguration().chunkSending.enabled) { ++ if (this.level().plazmaLevelConfiguration().chunkSending.enabled) { + if (chunksToSend.isEmpty()) return; + + if (disconnected) { @@ -52,7 +45,7 @@ index 852266234cf3d63e3b23a71639e40defca91c1b8..4668eebc0776a470a42de94de1752986 + final List>>> packets = new java.util.ArrayList<>(chunksToSend.entrySet()); + packets.sort(java.util.Comparator.comparingDouble(e -> e.getKey().getMiddleBlockPosition(getBlockY()).distSqr(blockPosition()))); + -+ for (int i = 0; i < packets.size() && i < this.level.plazmaLevelConfiguration().chunkSending.maxChunksPerTick; i++) { ++ for (int i = 0; i < packets.size() && i < this.level().plazmaLevelConfiguration().chunkSending.maxChunksPerTick + packets.size() / 100; i++) { + final java.util.Map.Entry>> entry = packets.get(i); + for (final Packet packet : entry.getValue()) { + connection.send(packet); @@ -60,27 +53,26 @@ index 852266234cf3d63e3b23a71639e40defca91c1b8..4668eebc0776a470a42de94de1752986 + chunksToSend.remove(entry.getKey()); + } + } - } - ++ } ++ + public boolean attachToPending(final ChunkPos pos, final Packet packet) { + final List> packetList = chunksToSend.get(pos); + if (packetList == null) return false; + packetList.add(packet); + return true; -+ } + } + // Plazma end -+ + public void doTick() { try { - if (valid && !this.isSpectator() || !this.touchingUnloadedChunk()) { // Paper - don't tick dead players that are not in the world currently (pending respawn) -@@ -2374,7 +2402,14 @@ public class ServerPlayer extends Player { +@@ -2437,7 +2465,14 @@ public class ServerPlayer extends Player { return true; // Paper } + // Plazma start - Implement ChunkSending + private final java.util.Map>> chunksToSend = java.util.Collections.synchronizedMap(new java.util.HashMap<>()); public void trackChunk(ChunkPos chunkPos, Packet chunkDataPacket) { -+ if (this.level.plazmaLevelConfiguration().chunkSending.enabled) { ++ if (this.level().plazmaLevelConfiguration().chunkSending.enabled) { + List> packetList = chunksToSend.computeIfAbsent(chunkPos, k -> new java.util.ArrayList<>()); + packetList.add(chunkDataPacket); + } diff --git a/patches/server/0012-Console-log-tweaks.patch b/patches/server/0012-Console-log-tweaks.patch index 3314d19..b44a828 100644 --- a/patches/server/0012-Console-log-tweaks.patch +++ b/patches/server/0012-Console-log-tweaks.patch @@ -8,7 +8,7 @@ Original by Irochi Licensed under the GPL 3.0 diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index b91910eaac0e9c18722e52d223a4420199d77a7f..84bb45aef3c2087cb9c03a99184956c484b3d8e9 100644 +index 49601ffa5a1a67e8572078fa9bd7780b096b6e67..5435897c040868e4d3c3c39db2fd42977e747de0 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java @@ -180,16 +180,6 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface diff --git a/patches/server/0014-Add-option-to-allow-any-usernames.patch b/patches/server/0014-Add-option-to-allow-any-usernames.patch index 5990be9..b694fa4 100644 --- a/patches/server/0014-Add-option-to-allow-any-usernames.patch +++ b/patches/server/0014-Add-option-to-allow-any-usernames.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add option to allow any usernames diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index f719f8aafe7c75e2ef8fcb05f556a8d6bd94b9a0..06ff5dd9e39e2be8dd8397a764813111019ceaed 100644 +index 01d5fa265fb2818465b5a71a2e2efeec751a7a05..0f1ebdc20460da22c1ff2fee2ff6428654139969 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -@@ -239,7 +239,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, +@@ -240,7 +240,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, @Override public void handleHello(ServerboundHelloPacket packet) { Validate.validState(this.state == ServerLoginPacketListenerImpl.State.HELLO, "Unexpected hello packet", new Object[0]); diff --git a/patches/server/0015-Add-permission-to-bypass-reducedDebugInfo-gamerule.patch b/patches/server/0015-Add-permission-to-bypass-reducedDebugInfo-gamerule.patch index 81b53aa..bd4ed37 100644 --- a/patches/server/0015-Add-permission-to-bypass-reducedDebugInfo-gamerule.patch +++ b/patches/server/0015-Add-permission-to-bypass-reducedDebugInfo-gamerule.patch @@ -5,24 +5,36 @@ Subject: [PATCH] Add permission to bypass reducedDebugInfo gamerule diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index ff56981a03b55f9ee1ec8ad36adaf9849b2c914b..b22b86d7f226e0e24d6be27ea33ec9d690f8f238 100644 +index 824f31b68b38f2f8642fb9d59a123cfdaffbb7b2..86932974a9101779691de336a8c45c464158fca8 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -275,7 +275,7 @@ public abstract class PlayerList { +@@ -282,7 +282,7 @@ public abstract class PlayerList { ServerGamePacketListenerImpl playerconnection = new ServerGamePacketListenerImpl(this.server, connection, player); GameRules gamerules = worldserver1.getGameRules(); boolean flag = gamerules.getBoolean(GameRules.RULE_DO_IMMEDIATE_RESPAWN); - boolean flag1 = gamerules.getBoolean(GameRules.RULE_REDUCEDDEBUGINFO); -+ boolean flag1 = gamerules.getBoolean(GameRules.RULE_REDUCEDDEBUGINFO) && !player.getBukkitEntity().hasPermission("plazma.bypass-reduced-debug-info-gamerule"); // Plazma ++ boolean flag1 = gamerules.getBoolean(GameRules.RULE_REDUCEDDEBUGINFO) && !(org.plazmamc.plazma.configurations.GlobalConfiguration.get().player.enableBypassReducedDebugInfoPermission && player.getBukkitEntity().hasPermission("plazma.bypass-reduced-debug-info-gamerule")); // Plazma // Spigot - view distance - playerconnection.send(new ClientboundLoginPacket(player.getId(), worlddata.isHardcore(), player.gameMode.getGameModeForPlayer(), player.gameMode.getPreviousGameModeForPlayer(), this.server.levelKeys(), this.synchronizedRegistries, worldserver1.dimensionTypeId(), worldserver1.dimension(), BiomeManager.obfuscateSeed(worldserver1.getSeed()), this.getMaxPlayers(), worldserver1.getChunkSource().chunkMap.playerChunkManager.getTargetSendDistance(), worldserver1.getChunkSource().chunkMap.playerChunkManager.getTargetTickViewDistance(), flag1, !flag, worldserver1.isDebug(), worldserver1.isFlat(), player.getLastDeathLocation())); // Paper - replace old player chunk management -@@ -1300,7 +1300,7 @@ public abstract class PlayerList { + playerconnection.send(new ClientboundLoginPacket(player.getId(), worlddata.isHardcore(), player.gameMode.getGameModeForPlayer(), player.gameMode.getPreviousGameModeForPlayer(), this.server.levelKeys(), this.synchronizedRegistries, worldserver1.dimensionTypeId(), worldserver1.dimension(), BiomeManager.obfuscateSeed(worldserver1.getSeed()), this.getMaxPlayers(), worldserver1.getWorld().getSendViewDistance(), worldserver1.getWorld().getSimulationDistance(), flag1, !flag, worldserver1.isDebug(), worldserver1.isFlat(), player.getLastDeathLocation(), player.getPortalCooldown())); // Paper - replace old player chunk management +@@ -1315,7 +1315,7 @@ public abstract class PlayerList { player.getEntityData().refresh(player); // CraftBukkkit - SPIGOT-7218: sync metadata player.connection.send(new ClientboundSetCarriedItemPacket(player.getInventory().selected)); // CraftBukkit start - from GameRules -- int i = player.level.getGameRules().getBoolean(GameRules.RULE_REDUCEDDEBUGINFO) ? 22 : 23; -+ int i = player.level.getGameRules().getBoolean(GameRules.RULE_REDUCEDDEBUGINFO) && !player.getBukkitEntity().hasPermission("plazma.bypass-reduced-debug-info-gamerule") ? 22 : 23; // Plazma +- int i = player.level().getGameRules().getBoolean(GameRules.RULE_REDUCEDDEBUGINFO) ? 22 : 23; ++ int i = player.level().getGameRules().getBoolean(GameRules.RULE_REDUCEDDEBUGINFO) && !(org.plazmamc.plazma.configurations.GlobalConfiguration.get().player.enableBypassReducedDebugInfoPermission && player.getBukkitEntity().hasPermission("plazma.bypass-reduced-debug-info-gamerule")) ? 22 : 23; player.connection.send(new ClientboundEntityEventPacket(player, (byte) i)); - float immediateRespawn = player.level.getGameRules().getBoolean(GameRules.RULE_DO_IMMEDIATE_RESPAWN) ? 1.0F: 0.0F; + float immediateRespawn = player.level().getGameRules().getBoolean(GameRules.RULE_DO_IMMEDIATE_RESPAWN) ? 1.0F: 0.0F; player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.IMMEDIATE_RESPAWN, immediateRespawn)); +diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java +index a45ff31d08129c0d5f159615d934a4450d54146e..4f54ae58bd20481f02aaec3f8406996a5e01b24f 100644 +--- a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java ++++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java +@@ -33,6 +33,7 @@ public class GlobalConfiguration extends ConfigurationPart { + public class Player extends ConfigurationPart { + + public boolean allowAnyUsername = false; ++ public boolean enableBypassReducedDebugInfoPermission = true; // TODO: Move to Player.Permissions class + + } + } diff --git a/patches/server/0016-Add-missing-purpur-configuration-options.patch b/patches/server/0016-Add-missing-purpur-configuration-options.patch index 2dcbaff..6409360 100644 --- a/patches/server/0016-Add-missing-purpur-configuration-options.patch +++ b/patches/server/0016-Add-missing-purpur-configuration-options.patch @@ -5,170 +5,165 @@ Subject: [PATCH] Add missing purpur configuration options 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 e95540122ae6a486ce12a5f50fb4d2d073239554..86c9b549e3e75adf9bd5562c4c8d303cf2080e45 100644 +index 7166f4a39fd615e10d7b1f53c57363832a41f365..599eeb043bba787b88003ad2ac128e8d7f3e69c6 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 -@@ -154,6 +154,23 @@ public class Allay extends PathfinderMob implements InventoryCarrier { +@@ -151,6 +151,23 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS + protected void registerGoals() { + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur } - // Purpur end - -+ // Plazma start - Add missing purpur config options ++ ++ // Plazma start + @Override + public boolean isSensitiveToWater() { -+ return level.purpurConfig.allayTakeDamageFromWater; ++ return level().purpurConfig.allayTakeDamageFromWater; + } + + @Override + public boolean isAlwaysExperienceDropper() { -+ return level.purpurConfig.allayAlwaysDropExp; ++ return level().purpurConfig.allayAlwaysDropExp; + } + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(level.purpurConfig.allayMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(level().purpurConfig.allayMaxHealth); + } + // Plazma end -+ + // Purpur end + @Override - protected Brain.Provider brainProvider() { - return Brain.provider(Allay.MEMORY_TYPES, Allay.SENSOR_TYPES); diff --git a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java -index 31922ac1139f34e0da61a719e3645c1aaa188890..94536f25980cf642edbfcf0c3d338a0172e0b77f 100644 +index 9f19ebfa6392a080672c472e08f755379e9776b4..e5aa7d1cf2e3178f7117e40f2df444963af43d67 100644 --- a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java +++ b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java -@@ -90,6 +90,23 @@ public class Camel extends AbstractHorse implements PlayerRideableJumping, Rider +@@ -93,6 +93,18 @@ public class Camel extends AbstractHorse implements PlayerRideableJumping, Rider + public int getPurpurBreedTime() { + return this.level().purpurConfig.camelBreedingTicks; } - // Purpur end - -+ // Plazma start - Add missing purpur config options -+ @Override -+ public boolean dismountsUnderwater() { -+ return level.purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level.purpurConfig.camelRidableInWater; -+ } + ++ // Plazma start + @Override + public boolean isSensitiveToWater() { -+ return level.purpurConfig.camelTakeDamageFromWater; ++ return level().purpurConfig.camelTakeDamageFromWater; + } + + @Override + public boolean isAlwaysExperienceDropper() { -+ return level.purpurConfig.camelAlwaysDropExp; ++ return level().purpurConfig.camelAlwaysDropExp; + } + // Plazma end -+ + // Purpur end + @Override - public void addAdditionalSaveData(CompoundTag nbt) { - super.addAdditionalSaveData(nbt); diff --git a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java -index c355aaed76663d37a5da8b2f49f9808828b4ef9b..dcc1b75361fe9eb250e3946e54454253a8f0e788 100644 +index dc1e8bcd8049d79c0e383ccd6a5697f79a3a2ebd..c0fce0582530e24d25368a9600b4f8c06d4f8286 100644 --- a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java +++ b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java -@@ -145,6 +145,23 @@ public class Frog extends Animal implements VariantHolder { +@@ -134,6 +134,23 @@ public class Frog extends Animal implements VariantHolder { + public float getJumpPower() { + return (getRider() != null && isControllable()) ? level().purpurConfig.frogRidableJumpHeight * this.getBlockJumpFactor() : super.getJumpPower(); } - // Purpur end - -+ // Plazma start - Add missing purpur config options ++ ++ // Plazma start + @Override + public boolean isSensitiveToWater() { -+ return level.purpurConfig.frogTakeDamageFromWater; ++ return level().purpurConfig.frogTakeDamageFromWater; + } + + @Override + public boolean isAlwaysExperienceDropper() { -+ return level.purpurConfig.frogAlwaysDropExp; ++ return level().purpurConfig.frogAlwaysDropExp; + } + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(level.purpurConfig.frogMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(level().purpurConfig.frogMaxHealth); + } + // Plazma end -+ - @Override - protected Brain.Provider brainProvider() { - return Brain.provider(MEMORY_TYPES, SENSOR_TYPES); + // Purpur end + + public int getPurpurBreedTime() { 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 aadc6743deb195ac3368548a75be641ffd3da404..90314f86e17ac7756f8211519fc5cde5a411677d 100644 +index 6b012bea26e8ef0c04571f43da67f6e108188830..7c816b879d47a1b8a480f4237d1ff0e11df4c98e 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 -@@ -89,6 +89,23 @@ public class Tadpole extends AbstractFish { +@@ -87,6 +87,23 @@ public class Tadpole extends AbstractFish { + protected void registerGoals() { + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur } - // Purpur end - -+ // Plazma start - Add missing purpur config options ++ ++ // Plazma start + @Override + public boolean isSensitiveToWater() { -+ return level.purpurConfig.tadpoleTakeDamageFromWater; ++ return level().purpurConfig.tadpoleTakeDamageFromWater; + } + + @Override + public boolean isAlwaysExperienceDropper() { -+ return level.purpurConfig.tadpoleAlwaysDropExp; ++ return level().purpurConfig.tadpoleAlwaysDropExp; + } + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(level.purpurConfig.tadpoleMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(level().purpurConfig.tadpoleMaxHealth); + } + // Plazma end -+ + // Purpur end + @Override - protected PathNavigation createNavigation(Level world) { - return new WaterBoundPathNavigation(this, world); diff --git a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java -index adae992ade60e0fce7ca0cc10192720025a574fe..9725389b6dd7643d00803799ce195d2d471cdcb8 100644 +index 552777d7ef6a1190a3b84bdf2f130f735c61d275..87f56c75742d856cdae24f525eac72aa5bce5ce2 100644 --- a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java +++ b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java -@@ -108,6 +108,18 @@ public class Sniffer extends Animal { +@@ -105,6 +105,18 @@ public class Sniffer extends Animal { + public boolean isControllable() { + return level().purpurConfig.snifferControllable; } - // Purpur end - -+ // Plazma start - Add missing purpur config options ++ ++ // Plazma start + @Override + public boolean isSensitiveToWater() { -+ return level.purpurConfig.snifferTakeDamageFromWater; ++ return level().purpurConfig.snifferTakeDamageFromWater; + } + + @Override + public boolean isAlwaysExperienceDropper() { -+ return level.purpurConfig.snifferAlwaysDropExp; ++ return level().purpurConfig.snifferAlwaysDropExp; + } + // Plazma end -+ - // CraftBukkit start - SPIGOT-7295: moved from constructor to appropriate location - @Override - protected void defineSynchedData() { -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 69e5b4b6c8d5725bc2fb7cd819219e4ff9df45bd..41301ad56fbcbe0f13447bd3b515d15bf58554c4 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 -@@ -146,6 +146,23 @@ public class Warden extends Monster implements VibrationListener.VibrationListen - } // Purpur end -+ // Plazma start - Add missing purpur config options + @Override +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 3fa46affc4d77d01909cfeaeaba6e06ba9fd5592..6d3373393e38f0ee530baab0d828e7c2722e9b9b 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 +@@ -145,6 +145,23 @@ public class Warden extends Monster implements VibrationSystem { + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur + } ++ ++ // Plazma start + @Override + public boolean isSensitiveToWater() { -+ return level.purpurConfig.wardenTakeDamageFromWater; ++ return level().purpurConfig.wardenTakeDamageFromWater; + } + + @Override + public boolean isAlwaysExperienceDropper() { -+ return level.purpurConfig.wardenAlwaysDropExp; ++ return level().purpurConfig.wardenAlwaysDropExp; + } + + @Override + public void initAttributes() { -+ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(level.purpurConfig.wardenMaxHealth); ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(level().purpurConfig.wardenMaxHealth); + } + // Plazma end -+ + // Purpur end + @Override - public Packet getAddEntityPacket() { - return new ClientboundAddEntityPacket(this, this.hasPose(Pose.EMERGING) ? 1 : 0); diff --git a/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java b/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java -index 3a720375c3daa961a34363f78c2c51d301c3fa06..90bd114feb0924669e61f92f301cdcf7f69405a4 100644 +index e88c39d405fc7068db64ad34a03dec8d559e749e..bb5d42ca73722f3a02154ed889625ded2ac63e6f 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java @@ -41,7 +41,7 @@ public class ChestBoat extends Boat implements HasCustomInventoryScreen, Contain @@ -176,7 +171,7 @@ index 3a720375c3daa961a34363f78c2c51d301c3fa06..90bd114feb0924669e61f92f301cdcf7 public ChestBoat(EntityType type, Level world) { super(type, world); - this.itemStacks = NonNullList.withSize(27, ItemStack.EMPTY); -+ this.itemStacks = NonNullList.withSize(org.purpurmc.purpur.PurpurConfig.chestBoatRows * 9, ItemStack.EMPTY); // Plazma - Add missing purpur config options ++ this.itemStacks = NonNullList.withSize(org.purpurmc.purpur.PurpurConfig.chestBoatRows * 9, ItemStack.EMPTY); // Plazma } public ChestBoat(Level world, double d0, double d1, double d2) { @@ -185,35 +180,35 @@ index 3a720375c3daa961a34363f78c2c51d301c3fa06..90bd114feb0924669e61f92f301cdcf7 @Override public int getContainerSize() { - return 27; -+ return org.purpurmc.purpur.PurpurConfig.chestBoatRows * 9; // Plazma - Add missing purpur config options ++ return org.purpurmc.purpur.PurpurConfig.chestBoatRows * 9; // Plazma } @Override diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java -index 38a8f79b0075279389f0b3dc7de4b16d9af05295..072cc011abded538ae643b36cfb1f861d564bcec 100644 +index d0968eeb0f9edeee43394da8a32d3ee8d491737b..00e4bea74de63da5dc174febe6d6473729ddf8ac 100644 --- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java +++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java -@@ -329,6 +329,7 @@ public class PurpurConfig { +@@ -331,6 +331,7 @@ public class PurpurConfig { } public static int barrelRows = 3; -+ public static int chestBoatRows = 3; // Plazma - Add missing purpur config options ++ public static int chestBoatRows = 3; // Plazma public static boolean enderChestSixRows = false; public static boolean enderChestPermissionRows = false; public static boolean cryingObsidianValidForPortalFrame = false; -@@ -369,6 +370,7 @@ public class PurpurConfig { +@@ -371,6 +372,7 @@ public class PurpurConfig { case 1 -> 9; default -> 27; }); -+ chestBoatRows = getInt("settings.blocks.chest_boat.rows", chestBoatRows); // Plazma - Add missing purpur config options ++ chestBoatRows = getInt("settings.blocks.chest_boat.rows", chestBoatRows); // Plazma enderChestSixRows = getBoolean("settings.blocks.ender_chest.six-rows", enderChestSixRows); org.bukkit.event.inventory.InventoryType.ENDER_CHEST.setDefaultSize(enderChestSixRows ? 54 : 27); enderChestPermissionRows = getBoolean("settings.blocks.ender_chest.use-permissions-for-rows", enderChestPermissionRows); diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -index ce702e6b5fff3a54f9f254a61becd12eb5c11dd7..7d553b0bb9ae478d54931682501afa9f532db5dd 100644 +index 16c3a06df8575a4fecd1967cf18854cb6267a4f7..9c7fd73a30edbf826c8670ac6141c73fa3d505f3 100644 --- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java +++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -@@ -1098,7 +1098,15 @@ public class PurpurWorldConfig { +@@ -1117,7 +1117,15 @@ public class PurpurWorldConfig { public boolean allayRidableInWater = true; public boolean allayControllable = true; public List allayRespectNBT = new ArrayList<>(); @@ -229,23 +224,23 @@ index ce702e6b5fff3a54f9f254a61becd12eb5c11dd7..7d553b0bb9ae478d54931682501afa9f allayRidable = getBoolean("mobs.allay.ridable", allayRidable); allayRidableInWater = getBoolean("mobs.allay.ridable-in-water", allayRidableInWater); allayControllable = getBoolean("mobs.allay.controllable", allayControllable); -@@ -1209,7 +1217,15 @@ public class PurpurWorldConfig { - public double camelJumpStrengthMax = 0.42D; +@@ -1236,7 +1244,15 @@ public class PurpurWorldConfig { public double camelMovementSpeedMin = 0.09D; public double camelMovementSpeedMax = 0.09D; + public int camelBreedingTicks = 6000; + // Plazma start - Add missing purpur config options -+ public boolean camelRidableInWater = false; ++ //public boolean camelRidableInWater = false; + public boolean camelTakeDamageFromWater = false; + public boolean camelAlwaysDropExp = false; private void camelSettings() { -+ camelRidableInWater = getBoolean("mobs.camel.ridable-in-water", camelRidableInWater); ++ //camelRidableInWater = getBoolean("mobs.camel.ridable-in-water", camelRidableInWater); + camelTakeDamageFromWater = getBoolean("mobs.camel.takes-damage-from-water", camelTakeDamageFromWater); + camelAlwaysDropExp = getBoolean("mobs.camel.always-drop-exp", camelAlwaysDropExp); + // Plazma end + camelRidableInWater = getBoolean("mobs.camel.ridable-in-water", camelRidableInWater); camelMaxHealthMin = getDouble("mobs.camel.attributes.max_health.min", camelMaxHealthMin); camelMaxHealthMax = getDouble("mobs.camel.attributes.max_health.max", camelMaxHealthMax); - camelJumpStrengthMin = getDouble("mobs.camel.attributes.jump_strength.min", camelJumpStrengthMin); -@@ -1636,7 +1652,15 @@ public class PurpurWorldConfig { +@@ -1664,7 +1680,15 @@ public class PurpurWorldConfig { public boolean frogControllable = true; public float frogRidableJumpHeight = 0.65F; public int frogBreedingTicks = 6000; @@ -261,7 +256,7 @@ index ce702e6b5fff3a54f9f254a61becd12eb5c11dd7..7d553b0bb9ae478d54931682501afa9f frogRidable = getBoolean("mobs.frog.ridable", frogRidable); frogRidableInWater = getBoolean("mobs.frog.ridable-in-water", frogRidableInWater); frogControllable = getBoolean("mobs.frog.controllable", frogControllable); -@@ -2587,7 +2611,13 @@ public class PurpurWorldConfig { +@@ -2617,7 +2641,13 @@ public class PurpurWorldConfig { public boolean snifferControllable = true; public double snifferMaxHealth = 14.0D; public int snifferBreedingTicks = 6000; @@ -275,7 +270,7 @@ index ce702e6b5fff3a54f9f254a61becd12eb5c11dd7..7d553b0bb9ae478d54931682501afa9f snifferRidable = getBoolean("mobs.sniffer.ridable", snifferRidable); snifferRidableInWater = getBoolean("mobs.sniffer.ridable-in-water", snifferRidableInWater); snifferControllable = getBoolean("mobs.sniffer.controllable", snifferControllable); -@@ -2686,7 +2716,15 @@ public class PurpurWorldConfig { +@@ -2716,7 +2746,15 @@ public class PurpurWorldConfig { public boolean tadpoleRidable = false; public boolean tadpoleRidableInWater = true; public boolean tadpoleControllable = true; @@ -291,7 +286,7 @@ index ce702e6b5fff3a54f9f254a61becd12eb5c11dd7..7d553b0bb9ae478d54931682501afa9f tadpoleRidable = getBoolean("mobs.tadpole.ridable", tadpoleRidable); tadpoleRidableInWater = getBoolean("mobs.tadpole.ridable-in-water", tadpoleRidableInWater); tadpoleControllable = getBoolean("mobs.tadpole.controllable", tadpoleControllable); -@@ -2896,7 +2934,15 @@ public class PurpurWorldConfig { +@@ -2926,7 +2964,15 @@ public class PurpurWorldConfig { public boolean wardenRidable = false; public boolean wardenRidableInWater = true; public boolean wardenControllable = true; diff --git a/patches/server/0019-Misc-configuration.patch b/patches/server/0019-Misc-configuration.patch index f197505..bcf62d2 100644 --- a/patches/server/0019-Misc-configuration.patch +++ b/patches/server/0019-Misc-configuration.patch @@ -5,12 +5,12 @@ Subject: [PATCH] Misc configuration diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -index a45ff31d08129c0d5f159615d934a4450d54146e..59b9b268467b098e5c21d1d00f599cfb36154179 100644 +index 4f54ae58bd20481f02aaec3f8406996a5e01b24f..61477d98f10ce7d0ec29d51de8c7a3b42026dd2d 100644 --- a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java +++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -@@ -34,5 +34,12 @@ public class GlobalConfiguration extends ConfigurationPart { - +@@ -35,5 +35,12 @@ public class GlobalConfiguration extends ConfigurationPart { public boolean allowAnyUsername = false; + public boolean enableBypassReducedDebugInfoPermission = true; // TODO: Move to Player.Permissions class + } + diff --git a/patches/server/0020-Reduce-create-random-instance.patch b/patches/server/0020-Reduce-create-random-instance.patch index 466d9bc..dd38c1a 100644 --- a/patches/server/0020-Reduce-create-random-instance.patch +++ b/patches/server/0020-Reduce-create-random-instance.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Reduce create random instance diff --git a/src/main/java/net/minecraft/server/commands/SpreadPlayersCommand.java b/src/main/java/net/minecraft/server/commands/SpreadPlayersCommand.java -index 591163d8f8300b084ac734800efee902c4def958..d74401ca3182145d136ad668704f5c043b163317 100644 +index f5bc3497831877e0c2b7dc1cbd8abe3a67d7695b..d157758282cc79d58134c056c52a43a24d443153 100644 --- a/src/main/java/net/minecraft/server/commands/SpreadPlayersCommand.java +++ b/src/main/java/net/minecraft/server/commands/SpreadPlayersCommand.java @@ -65,7 +65,7 @@ public class SpreadPlayersCommand { @@ -18,10 +18,10 @@ index 591163d8f8300b084ac734800efee902c4def958..d74401ca3182145d136ad668704f5c04 double d1 = (double) (center.y - maxRange); double d2 = (double) (center.x + maxRange); diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 40eda117db2e3f578ad9d25522b6aadfe319b5cc..ef624a99c971aa5c4ce3869d10e2435c0bc8e0a4 100644 +index ae04c5f4fd340c6bce0be29d4288dad37f260c7d..4a67650da636da5a6d5b5dfaaa86077d0cc9269c 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -405,7 +405,7 @@ public class ServerPlayer extends Player { +@@ -447,7 +447,7 @@ public class ServerPlayer extends Player { long l = k * k; int i1 = l > 2147483647L ? Integer.MAX_VALUE : (int) l; int j1 = this.getCoprime(i1); @@ -30,12 +30,12 @@ index 40eda117db2e3f578ad9d25522b6aadfe319b5cc..ef624a99c971aa5c4ce3869d10e2435c for (int l1 = 0; l1 < i1; ++l1) { int i2 = (k1 + j1 * l1) % i1; -@@ -442,7 +442,7 @@ public class ServerPlayer extends Player { +@@ -484,7 +484,7 @@ public class ServerPlayer extends Player { long l = k * k; int i1 = l > 2147483647L ? Integer.MAX_VALUE : (int) l; int j1 = this.getCoprime(i1); - int k1 = RandomSource.create().nextInt(i1); -+ int k1 = (world.plazmaLevelConfiguration().misc.reduceCreateRandomInstance ? world.getRandom() : RandomSource.create()).nextInt(i1); ++ int k1 = (world.plazmaLevelConfiguration().misc.reduceCreateRandomInstance ? world.getRandom() : RandomSource.create()).nextInt(i1); // Plazma for (int l1 = 0; l1 < i1; ++l1) { int i2 = (k1 + j1 * l1) % i1; @@ -53,7 +53,7 @@ index 1ef089dbf83de35d875c00efdf468c397be56978..dc111e0d1e7303c56cd12fa83be3ff85 } diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java -index bcb0f3fd09ed064b64dc6495302b40828d906837..c6152b295a2f46e5204f42fe76e6cd10127ce12e 100644 +index b8c238287e0639b578170c6fec0d4db5a1a59fe7..9e5eab45d589db16b4f1ec563e40dc3890581bf4 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java +++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java @@ -86,7 +86,7 @@ public class FishingHook extends Projectile { @@ -66,7 +66,7 @@ index bcb0f3fd09ed064b64dc6495302b40828d906837..c6152b295a2f46e5204f42fe76e6cd10 this.currentState = FishingHook.FishHookState.FLYING; this.noCulling = true; diff --git a/src/main/java/net/minecraft/world/entity/raid/Raid.java b/src/main/java/net/minecraft/world/entity/raid/Raid.java -index 879c3bb661e24b9682b654def57c2800f4f8ca92..4c465466543e51ff1e8343d3af7ee31a8b04b839 100644 +index f7399737548483905f3b5c08a03876b0da54b714..7ff8e19fcee67a33bbc8603f8c089a5b76ed23b6 100644 --- a/src/main/java/net/minecraft/world/entity/raid/Raid.java +++ b/src/main/java/net/minecraft/world/entity/raid/Raid.java @@ -110,7 +110,7 @@ public class Raid { @@ -88,7 +88,7 @@ index 879c3bb661e24b9682b654def57c2800f4f8ca92..4c465466543e51ff1e8343d3af7ee31a this.level = world; this.id = nbt.getInt("Id"); diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java -index 7a3d9c1f8abdbc25e88ca35da1546725f0013c68..79f980cadddbfe234b410f25b5f0bc6edfcbba26 100644 +index 4932374ab9a3d8582fb0ef024d817ad896dd23c4..fd9be520b838346555dee2dc13f54dcf0fe0e9d8 100644 --- a/src/main/java/net/minecraft/world/level/Explosion.java +++ b/src/main/java/net/minecraft/world/level/Explosion.java @@ -81,7 +81,7 @@ public class Explosion { @@ -101,10 +101,10 @@ index 7a3d9c1f8abdbc25e88ca35da1546725f0013c68..79f980cadddbfe234b410f25b5f0bc6e this.hitPlayers = Maps.newHashMap(); this.level = world; diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 058449f24eb3260dc230dad2a0b4c552d0b7f40e..cf0ad841267cac84ed058dee6cdd62a835325feb 100644 +index 08f9af1d7aebba943096b59b6452818a1aafc94c..1d2c3147abfa09233976f4cc1cc417a9dab9ed44 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -125,7 +125,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -124,7 +124,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public final Thread thread; private final boolean isDebug; private int skyDarken; @@ -114,10 +114,10 @@ index 058449f24eb3260dc230dad2a0b4c552d0b7f40e..cf0ad841267cac84ed058dee6cdd62a8 protected float oRainLevel; public float rainLevel; diff --git a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java -index a4cd9869988f414ce1bf14d38442f78207e3f048..f99a7b2da94ef7b413ff10b57fa43e23398aa715 100644 +index 7291e4056b8e46ab59b71818388ac55fbb12993f..5e5efeec92f70060b0d409252ceff65691155367 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java -@@ -369,7 +369,7 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity { +@@ -368,7 +368,7 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity { } private static void spawnGatewayPortal(ServerLevel world, BlockPos pos, EndGatewayConfiguration config) { @@ -127,45 +127,32 @@ index a4cd9869988f414ce1bf14d38442f78207e3f048..f99a7b2da94ef7b413ff10b57fa43e23 @Override diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java -index e9eb32469a5c03f7a3677ef50fd4541c1ed662ad..75665373c291faaea1cbf5f54c3634fdb042556c 100644 +index 5b333bef255d7ef61c99510837536920c6fb6e8c..6331c068aefcdf07d2c880eef8df07add277f856 100644 --- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java +++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java -@@ -411,7 +411,7 @@ public class EndDragonFight { - this.level.registryAccess().registry(Registries.CONFIGURED_FEATURE).flatMap((registry) -> { - return registry.getHolder(EndFeatures.END_GATEWAY_DELAYED); - }).ifPresent((reference) -> { -- reference.value().place(this.level, this.level.getChunkSource().getGenerator(), RandomSource.create(), pos); -+ reference.value().place(this.level, this.level.getChunkSource().getGenerator(), (this.level.plazmaLevelConfiguration().misc.reduceCreateRandomInstance ? this.level.getRandom() : RandomSource.create()), pos); // Plazma +@@ -472,7 +472,7 @@ public class EndDragonFight { + this.level.registryAccess().registry(Registries.CONFIGURED_FEATURE).flatMap((iregistry) -> { + return iregistry.getHolder(EndFeatures.END_GATEWAY_DELAYED); + }).ifPresent((holder_c) -> { +- ((ConfiguredFeature) holder_c.value()).place(this.level, this.level.getChunkSource().getGenerator(), RandomSource.create(), pos); ++ ((ConfiguredFeature) holder_c.value()).place(this.level, this.level.getChunkSource().getGenerator(), (this.level.plazmaLevelConfiguration().misc.reduceCreateRandomInstance ? this.level.getRandom() : RandomSource.create()), pos); }); } -@@ -427,7 +427,7 @@ public class EndDragonFight { +@@ -490,7 +490,7 @@ public class EndDragonFight { this.portalLocation = this.portalLocation.atY(this.level.getMinBuildHeight() + 1); } // Paper end -- endPodiumFeature.place(FeatureConfiguration.NONE, this.level, this.level.getChunkSource().getGenerator(), RandomSource.create(), this.portalLocation); -+ endPodiumFeature.place(FeatureConfiguration.NONE, this.level, this.level.getChunkSource().getGenerator(), (this.level.plazmaLevelConfiguration().misc.reduceCreateRandomInstance ? this.level.getRandom() : RandomSource.create()), this.portalLocation); // Plazma +- worldgenendtrophy.place(FeatureConfiguration.NONE, this.level, this.level.getChunkSource().getGenerator(), RandomSource.create(), this.portalLocation); ++ worldgenendtrophy.place(FeatureConfiguration.NONE, this.level, this.level.getChunkSource().getGenerator(), (this.level.plazmaLevelConfiguration().misc.reduceCreateRandomInstance ? this.level.getRandom() : RandomSource.create()), this.portalLocation); } @Nullable -diff --git a/src/main/java/net/minecraft/world/level/storage/loot/LootContext.java b/src/main/java/net/minecraft/world/level/storage/loot/LootContext.java -index 9e9ac64764cf0a84e25e75d8d6f516cde6047284..2d197a7de77657a19b1b527c0aa53ef9918eb15f 100644 ---- a/src/main/java/net/minecraft/world/level/storage/loot/LootContext.java -+++ b/src/main/java/net/minecraft/world/level/storage/loot/LootContext.java -@@ -202,7 +202,7 @@ public class LootContext { - } else { - RandomSource randomSource = this.random; - if (randomSource == null) { -- randomSource = RandomSource.create(); -+ randomSource = this.level.plazmaLevelConfiguration().misc.reduceCreateRandomInstance ? this.level.getRandom() : RandomSource.create(); - } - - MinecraftServer minecraftServer = this.level.getServer(); diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -index 59b9b268467b098e5c21d1d00f599cfb36154179..fa33fd5a64fadbfe6507ae9f61fdfbfc816686b5 100644 +index 61477d98f10ce7d0ec29d51de8c7a3b42026dd2d..3e0d0d21dc73b2a5d033d8bcd43b08866e0d6923 100644 --- a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java +++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -@@ -39,7 +39,7 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -40,7 +40,7 @@ public class GlobalConfiguration extends ConfigurationPart { public Misc misc; public class Misc extends ConfigurationPart { diff --git a/patches/server/0022-Various-Optimizations.patch b/patches/server/0022-Various-Optimizations.patch index 0134cda..134a58c 100644 --- a/patches/server/0022-Various-Optimizations.patch +++ b/patches/server/0022-Various-Optimizations.patch @@ -10,31 +10,32 @@ Subject: [PATCH] Various Optimizations 0011 - Swaps the predicate order of collision (Akarin) diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index e71eca3ddbbeb3168dd73433b6d6ffe9f6755f77..f8be2d9d454965257de55d2aa572016115d1b346 100644 +index cf0d8da4c4b5f4aa4e4ef15897ca252a2b52ec8d..42c1b7c635cd22125dbb6b4d195976daac0c9ea1 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -1993,8 +1993,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -2145,8 +2145,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { public void playerTouch(Player player) {} public void push(Entity entity) { + if (entity.noPhysics || this.noPhysics) return; // Plazma if (!this.isPassengerOfSameVehicle(entity)) { - if (!entity.noPhysics && !this.noPhysics) { -+ //if (!entity.noPhysics && !this.noPhysics) { // Plazma ++ //if (!entity.noPhysics && !this.noPhysics) { // Plazma - moved up if (this.level.paperConfig().collisions.onlyPlayersCollide && !(entity instanceof ServerPlayer || this instanceof ServerPlayer)) return; // Paper double d0 = entity.getX() - this.getX(); double d1 = entity.getZ() - this.getZ(); -@@ -2023,7 +2024,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -2174,8 +2175,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { + entity.push(d0, 0.0D, d1); } } - +- - } + //} // Plazma } } diff --git a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java -index 6d62cc8fb347ccafd51df05896e616995990f005..c26e4795afd0bd450d304f4528d0b8e4cfa761ce 100644 +index 765ee7f78532a363813286ef7db2a7e48605cb06..47830edd65b7f54a01559c80d28586b91cc07739 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java @@ -70,6 +70,7 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc @@ -43,13 +44,13 @@ index 6d62cc8fb347ccafd51df05896e616995990f005..c26e4795afd0bd450d304f4528d0b8e4 public void unpackLootTable(@Nullable Player player) { + if (org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.doNotTriggerLootTableRefreshForNonPlayerInteraction && player == null) return; // Plazma if (this.lootableData.shouldReplenish(player) && this.level.getServer() != null) { // Paper - LootTable lootTable = this.level.getServer().getLootTables().get(this.lootTable); + LootTable lootTable = this.level.getServer().getLootData().getLootTable(this.lootTable); if (player instanceof ServerPlayer) { diff --git a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java -index f55c50f6637a4f930b15565d6ac82bb4f27b9059..9c4e65a67bda331625a0891be10495eaae5f3f5e 100644 +index f74c5eda91a3d521763ec7bc33f23e0c62458cc2..9f1ee01eb9dcb599d1eb453653c7e7479fb24a4c 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java +++ b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java -@@ -73,6 +73,7 @@ public class PhantomSpawner implements CustomSpawner { +@@ -71,6 +71,7 @@ public class PhantomSpawner implements CustomSpawner { if (randomsource.nextInt(j) >= world.paperConfig().entities.behavior.playerInsomniaStartTicks) { // Paper BlockPos blockposition1 = blockposition.above(20 + randomsource.nextInt(15)).east(-10 + randomsource.nextInt(21)).south(-10 + randomsource.nextInt(21)); @@ -81,10 +82,10 @@ index 36af81f0957d17e170d229059c66f4eb4539dfeb..039c952f0c157cba6e79fa9b976958bd } // Spigot Start diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -index fa33fd5a64fadbfe6507ae9f61fdfbfc816686b5..590afba7c588e7b9f5f9c61e91805e3dc3b62771 100644 +index 3e0d0d21dc73b2a5d033d8bcd43b08866e0d6923..e91b404fca2823748c2ed343cbd83301e55b2f0a 100644 --- a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java +++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -@@ -40,6 +40,7 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -41,6 +41,7 @@ public class GlobalConfiguration extends ConfigurationPart { public class Misc extends ConfigurationPart { public boolean reduceCreateRandomInstance = DO_OPTIMIZE; diff --git a/patches/server/0023-Add-configuration-to-disable-moved-to-quickly-check-.patch b/patches/server/0023-Add-configuration-to-disable-moved-to-quickly-check-.patch index fb1cfc1..ffe6616 100644 --- a/patches/server/0023-Add-configuration-to-disable-moved-to-quickly-check-.patch +++ b/patches/server/0023-Add-configuration-to-disable-moved-to-quickly-check-.patch @@ -6,18 +6,18 @@ Subject: [PATCH] Add configuration to disable moved to quickly check for diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index af8cb1f1f0c128923495f51e4828003133ce766b..8f911f589bf04902e38e2c625d84ba0c47cbd9ee 100644 +index 9cc3ab8cd3f7ab7f8fbf4d9d14f25ea0bd757eec..09183dbac0e8ca2cc2c8da57b105b80eab42d459 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1544,7 +1544,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic - if (!this.player.isChangingDimension() && (!this.player.getLevel().getGameRules().getBoolean(GameRules.RULE_DISABLE_ELYTRA_MOVEMENT_CHECK) || !this.player.isFallFlying())) { +@@ -1566,7 +1566,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic + if (!this.player.isChangingDimension() && (!this.player.level().getGameRules().getBoolean(GameRules.RULE_DISABLE_ELYTRA_MOVEMENT_CHECK) || !this.player.isFallFlying())) { float f2 = this.player.isFallFlying() ? 300.0F : 100.0F; -- if (d11 - d10 > Math.max(f2, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) { -+ if (!(this.player.getLevel().plazmaLevelConfiguration().misc.checkSpectatorMovedToQuickly && this.player.isSpectator()) && d11 - d10 > Math.max(f2, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) { // Plazma +- if (d10 - d9 > Math.max(f2, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) { ++ if (!(this.player.level().plazmaLevelConfiguration().misc.checkSpectatorMovedToQuickly && this.player.isSpectator()) && d10 - d9 > Math.max(f2, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) { // Plazma // CraftBukkit end - ServerGamePacketListenerImpl.LOGGER.warn("{} moved too quickly! {},{},{}", new Object[]{this.player.getName().getString(), d7, d8, d9}); - this.teleport(this.player.getX(), this.player.getY(), this.player.getZ(), this.player.getYRot(), this.player.getXRot()); + // Paper start - Add fail move event + io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_TOO_QUICKLY, diff --git a/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java index 80ee8293d73ecdb1a942ca88f1aa00813d600849..e6c22ab535ab8fecaadbf06d4982440fd5863f17 100644 --- a/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java diff --git a/patches/server/0024-Apply-faster-random.patch b/patches/server/0024-Apply-faster-random.patch index d3734e8..69189d3 100644 --- a/patches/server/0024-Apply-faster-random.patch +++ b/patches/server/0024-Apply-faster-random.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Apply faster random diff --git a/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java -index e5ea9f27a1936ed9e329e74317c91c5df89b9fbd..7e7a4d872983cd2efdc575bc33353f94d73cc641 100644 +index 5408cbc21fc7577a6100b5a1ca0463e899d2df8b..4f264e098e7907c397f09ee23a579ed7da494edc 100644 --- a/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java +++ b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java -@@ -13,7 +13,7 @@ import java.util.UUID; +@@ -16,7 +16,7 @@ import java.util.UUID; public class PaperLootableInventoryData { @@ -18,10 +18,10 @@ index e5ea9f27a1936ed9e329e74317c91c5df89b9fbd..7e7a4d872983cd2efdc575bc33353f94 private long lastFill = -1; private long nextRefill = -1; diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index cc6968a064b30f7250d18c20efb2bb8602bb0cdd..3c80e14392ee7a6bf5040d7cb81b7d894e162eff 100644 +index 0acbaa18a61d1cfdb894c6c756d2b9bdc3599b82..93ff3ef401d4212cede5290990528988c7ca3a0c 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -694,7 +694,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0) { -@@ -281,6 +282,21 @@ public class ServerEntity { - })); +@@ -275,6 +276,21 @@ public class ServerEntity { + }); } + // Plazma start + private boolean isUselessEntityPacket(@Nullable Packet packet) { + if (packet == null) return false; + if (packet instanceof ClientboundMoveEntityPacket p) { -+ if (p instanceof ClientboundMoveEntityPacket.Pos) ++ if (p instanceof ClientboundMoveEntityPacket.Pos) + return p.getXa() == 0 && p.getYa() == 0 && p.getZa() == 0; + else if (p instanceof ClientboundMoveEntityPacket.Rot) + return p.getxRot() == 0 && p.getyRot() == 0; @@ -39,10 +39,10 @@ index 6afee2a744a3498d4a0eee35f77cde444f73d12c..dbb987d5896e199aeae3bcd86c69bf33 this.entity.stopSeenByPlayer(player); player.connection.send(new ClientboundRemoveEntitiesPacket(new int[]{this.entity.getId()})); diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -index 590afba7c588e7b9f5f9c61e91805e3dc3b62771..8ed22e178bd093241592981c06c747524ad24dc3 100644 +index e91b404fca2823748c2ed343cbd83301e55b2f0a..d21be63b98f026fa3ac7dcdc73f9f488a7000643 100644 --- a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java +++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -@@ -41,6 +41,7 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -42,6 +42,7 @@ public class GlobalConfiguration extends ConfigurationPart { public boolean reduceCreateRandomInstance = DO_OPTIMIZE; public boolean doNotTriggerLootTableRefreshForNonPlayerInteraction = DO_OPTIMIZE; diff --git a/patches/server/0026-No-Chat-Reports-Configuration.patch b/patches/server/0026-No-Chat-Reports-Configuration.patch index ed3593d..a91a10c 100644 --- a/patches/server/0026-No-Chat-Reports-Configuration.patch +++ b/patches/server/0026-No-Chat-Reports-Configuration.patch @@ -5,10 +5,10 @@ Subject: [PATCH] No Chat Reports Configuration diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -index 8ed22e178bd093241592981c06c747524ad24dc3..0e8d5b01a673ba826c943fcb33552518022a2ea3 100644 +index d21be63b98f026fa3ac7dcdc73f9f488a7000643..f67ac1a3dddb024af606da14b3929f10d8f22330 100644 --- a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java +++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -@@ -43,5 +43,12 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -44,5 +44,12 @@ public class GlobalConfiguration extends ConfigurationPart { public boolean doNotTriggerLootTableRefreshForNonPlayerInteraction = DO_OPTIMIZE; public boolean doNotSendUselessEntityPackets = DO_OPTIMIZE; diff --git a/patches/server/0027-Implement-No-Chat-Reports.patch b/patches/server/0027-Implement-No-Chat-Reports.patch index 8b2ebc9..025556a 100644 --- a/patches/server/0027-Implement-No-Chat-Reports.patch +++ b/patches/server/0027-Implement-No-Chat-Reports.patch @@ -40,10 +40,10 @@ index 1f4b64a5f812376c499c98cb4be62469bd0b7dbe..c0bd2997fe3ebbfe926de832a36d209c public void writeId(IdMap registry, T value) { diff --git a/src/main/java/net/minecraft/network/protocol/status/ServerStatus.java b/src/main/java/net/minecraft/network/protocol/status/ServerStatus.java -index e6cc2bab1fde2e8c1394772b99201ea8d7eb8057..2ba3291f6c82f633d7ed7b150f2ae3c28d74b21e 100644 +index 98ea56cbc8de5a5694b4f4d9a2f25811fdecba04..9e2a1f04cd9de2b0a7f3c512a4849a572d8fc00c 100644 --- a/src/main/java/net/minecraft/network/protocol/status/ServerStatus.java +++ b/src/main/java/net/minecraft/network/protocol/status/ServerStatus.java -@@ -64,4 +64,21 @@ public record ServerStatus(Component description, Optional +@@ -62,4 +62,21 @@ public record ServerStatus(Component description, Optional return new ServerStatus.Version(worldVersion.getName(), worldVersion.getProtocolVersion()); } } @@ -66,29 +66,29 @@ index e6cc2bab1fde2e8c1394772b99201ea8d7eb8057..2ba3291f6c82f633d7ed7b150f2ae3c2 + // Plazma end } diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index 84bb45aef3c2087cb9c03a99184956c484b3d8e9..778b79ce3530781705f6d6ae11a2631f186e3763 100644 +index 191bebab12c94756e9f98cfacbf06eb9a7c2f2f9..2d47c13f768ac482422e118921d186d3cfd5d765 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java @@ -684,7 +684,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface - - @Override public boolean enforceSecureProfile() { -- return this.getProperties().enforceSecureProfile && this.getProperties().onlineMode; -+ return !org.plazmamc.plazma.configurations.GlobalConfiguration.get().noChatReports.enabled && this.getProperties().enforceSecureProfile && this.getProperties().onlineMode; // Plazma - NCR + DedicatedServerProperties dedicatedserverproperties = this.getProperties(); + +- return dedicatedserverproperties.enforceSecureProfile && dedicatedserverproperties.onlineMode && this.services.profileKeySignatureValidator() != null; ++ return !org.plazmamc.plazma.configurations.GlobalConfiguration.get().noChatReports.enabled && dedicatedserverproperties.enforceSecureProfile && dedicatedserverproperties.onlineMode && this.services.profileKeySignatureValidator() != null; // Plazma - NCR // TODO: Check } protected boolean convertOldUsers() { diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 8f911f589bf04902e38e2c625d84ba0c47cbd9ee..b15de37a06c3efb1c4bc790ccb23ebff3c97d54d 100644 +index 09183dbac0e8ca2cc2c8da57b105b80eab42d459..e4c92730b63204126609a52d286da46ef6495080 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2235,10 +2235,19 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -2293,10 +2293,19 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic @Override public void send(Packet packet) { + // Plazma start - NCR + if (org.plazmamc.plazma.configurations.GlobalConfiguration.get().noChatReports.convertToGameMessage() && packet instanceof ClientboundPlayerChatPacket chat) -+ packet = new ClientboundSystemChatPacket(null, Component.Serializer.toJson(chat.chatType().resolve(this.player.level.registryAccess()).get().decorate(chat.unsignedContent() != null ? chat.unsignedContent() : Component.literal(chat.body().content()))), false); ++ packet = new ClientboundSystemChatPacket(null, Component.Serializer.toJson(chat.chatType().resolve(this.player.level().registryAccess()).get().decorate(chat.unsignedContent() != null ? chat.unsignedContent() : Component.literal(chat.body().content()))), false); this.send(packet, (PacketSendListener) null); } @@ -103,10 +103,10 @@ index 8f911f589bf04902e38e2c625d84ba0c47cbd9ee..b15de37a06c3efb1c4bc790ccb23ebff if (packet == null || this.processedDisconnect) { // Spigot return; diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index b22b86d7f226e0e24d6be27ea33ec9d690f8f238..022da50912d357581b2132cf57e1a767e436022c 100644 +index 86932974a9101779691de336a8c45c464158fca8..b711efca8a834adaf0db902fab34c3c80c9cbad6 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1464,7 +1464,7 @@ public abstract class PlayerList { +@@ -1479,7 +1479,7 @@ public abstract class PlayerList { } public boolean verifyChatTrusted(PlayerChatMessage message) { // Paper - private -> public @@ -116,10 +116,10 @@ index b22b86d7f226e0e24d6be27ea33ec9d690f8f238..022da50912d357581b2132cf57e1a767 // CraftBukkit start diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -index 0e8d5b01a673ba826c943fcb33552518022a2ea3..17454a128f7ef53428920f95e4709180fd8efb32 100644 +index f67ac1a3dddb024af606da14b3929f10d8f22330..2033c7ff519e30f507e6535004687eb49c08c33b 100644 --- a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java +++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -@@ -48,7 +48,17 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -49,7 +49,17 @@ public class GlobalConfiguration extends ConfigurationPart { public NoChatReports noChatReports; public class NoChatReports extends ConfigurationPart { diff --git a/patches/server/0028-FixMySpawnR-Configuration.patch b/patches/server/0028-FixMySpawnR-Configuration.patch index 624a3f5..5170986 100644 --- a/patches/server/0028-FixMySpawnR-Configuration.patch +++ b/patches/server/0028-FixMySpawnR-Configuration.patch @@ -5,10 +5,10 @@ Subject: [PATCH] FixMySpawnR Configuration diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -index 17454a128f7ef53428920f95e4709180fd8efb32..39eca4acefa8f9cf143398cfc6cf157e8489947e 100644 +index 2033c7ff519e30f507e6535004687eb49c08c33b..b2c9ac1947e6c9ad0e693cfeaf6f2f4bfd521aa0 100644 --- a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java +++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -@@ -61,4 +61,12 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -62,4 +62,12 @@ public class GlobalConfiguration extends ConfigurationPart { } } diff --git a/patches/server/0029-Implement-FixMySpawnR.patch b/patches/server/0029-Implement-FixMySpawnR.patch index 59da08e..a27eee1 100644 --- a/patches/server/0029-Implement-FixMySpawnR.patch +++ b/patches/server/0029-Implement-FixMySpawnR.patch @@ -7,7 +7,7 @@ Original: AbsolemJackdaw/FixMySpawnR Copyright (C) 2023 AbsolemJackdaw diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java -index feb65fc9ee04141fe6f77400660442ed207547a1..9c759e71ef1d119d7807886f9e56b7230a334475 100644 +index 64d911bee1607880514061c75116d8672df8bb8f..4dcf2c5e4efa645572c7a646e7233232c49a130c 100644 --- a/src/main/java/net/minecraft/world/level/BaseSpawner.java +++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java @@ -46,6 +46,8 @@ public abstract class BaseSpawner { @@ -38,7 +38,7 @@ index feb65fc9ee04141fe6f77400660442ed207547a1..9c759e71ef1d119d7807886f9e56b723 if (spawnCount <= 0 || maxNearbyEntities <= 0) return; // Paper - Ignore impossible spawn tick // Paper start - Configurable mob spawner tick rate if (spawnDelay > 0 && --tickDelay > 0) return; -@@ -292,6 +306,13 @@ public abstract class BaseSpawner { +@@ -286,6 +300,13 @@ public abstract class BaseSpawner { this.spawnRange = nbt.getShort("SpawnRange"); } @@ -52,7 +52,7 @@ index feb65fc9ee04141fe6f77400660442ed207547a1..9c759e71ef1d119d7807886f9e56b723 this.displayEntity = null; } -@@ -321,6 +342,12 @@ public abstract class BaseSpawner { +@@ -315,6 +336,12 @@ public abstract class BaseSpawner { } nbt.put("SpawnPotentials", (Tag) SpawnData.LIST_CODEC.encodeStart(NbtOps.INSTANCE, this.spawnPotentials).result().orElseThrow()); diff --git a/patches/server/0031-Reduce-Sensor-Work.patch b/patches/server/0031-Reduce-Sensor-Work.patch index 2041e86..21b5023 100644 --- a/patches/server/0031-Reduce-Sensor-Work.patch +++ b/patches/server/0031-Reduce-Sensor-Work.patch @@ -7,32 +7,32 @@ Original: Bloom-host/Petal Copyright (C) 2023 peaches94 diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index b67660cda74a4754d1701e746aca99bde868c150..8dcc8ea2450ee14880e2ffff0f013ccee9b33e2f 100644 +index 0b08cf7b26731ffd6f3909342f4e3a92fe0c813e..5c3df4d7b12bd942780ff74e6353a07d489de74f 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1020,20 +1020,20 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1037,20 +1037,20 @@ public abstract class LivingEntity extends Entity implements Attackable { } if (entity != null) { - ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD); -+ // ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD); // Plazma - check head itemstack only when needed ++ //ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD); // Plazma EntityType entitytypes = entity.getType(); // Purpur start - if (entitytypes == EntityType.SKELETON && itemstack.is(Items.SKELETON_SKULL)) { + if (entitytypes == EntityType.SKELETON && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.SKELETON_SKULL)) { // Plazma - d0 *= entity.level.purpurConfig.skeletonHeadVisibilityPercent; + d0 *= entity.level().purpurConfig.skeletonHeadVisibilityPercent; } - else if (entitytypes == EntityType.ZOMBIE && itemstack.is(Items.ZOMBIE_HEAD)) { + else if (entitytypes == EntityType.ZOMBIE && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.ZOMBIE_HEAD)) { // Plazma - d0 *= entity.level.purpurConfig.zombieHeadVisibilityPercent; + d0 *= entity.level().purpurConfig.zombieHeadVisibilityPercent; } - else if (entitytypes == EntityType.CREEPER && itemstack.is(Items.CREEPER_HEAD)) { + else if (entitytypes == EntityType.CREEPER && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.CREEPER_HEAD)) { // Plazma - d0 *= entity.level.purpurConfig.creeperHeadVisibilityPercent; + d0 *= entity.level().purpurConfig.creeperHeadVisibilityPercent; } - else if ((entitytypes == EntityType.PIGLIN || entitytypes == EntityType.PIGLIN_BRUTE) && itemstack.is(Items.PIGLIN_HEAD)) { + else if ((entitytypes == EntityType.PIGLIN || entitytypes == EntityType.PIGLIN_BRUTE) && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.PIGLIN_HEAD)) { // Plazma - d0 *= entity.level.purpurConfig.piglinHeadVisibilityPercent; + d0 *= entity.level().purpurConfig.piglinHeadVisibilityPercent; } // Purpur end diff --git a/patches/server/0032-Configurable-Sensor-Tick.patch b/patches/server/0032-Configurable-Sensor-Tick.patch index d905013..f380119 100644 --- a/patches/server/0032-Configurable-Sensor-Tick.patch +++ b/patches/server/0032-Configurable-Sensor-Tick.patch @@ -7,21 +7,21 @@ Original: Bloom-host/Petal Copyright (C) 2023 peaches94 diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 8e2274f7dce34e0997356205cf96e46f8d41cca1..3a365d7efd439cb8ddb99381bd714fb48896f4d2 100644 +index 19d9d3a9f634631e2ec5a6fa7f2cd9dd18f62f89..ba20f60588b980f49423307ff20fc24c95f3e7b5 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -932,10 +932,10 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -935,10 +935,11 @@ public abstract class Mob extends LivingEntity implements Targeting { } // Paper end - //this.level.getProfiler().push("sensing"); // Purpur + //this.level().getProfiler().push("sensing"); // Purpur - this.sensing.tick(); -+ // Plazma - Configurable Sensor Tick - //this.level.getProfiler().pop(); // Purpur - int i = this.level.getServer().getTickCount() + this.getId(); -- -+ if (i % this.level.plazmaLevelConfiguration().entity.sensor.tick == 0) this.sensing.tick(); // Plazma - Configurable Sensor Tick ++ //this.sensing.tick(); // Plazma - moved down (configurable sensor tick) + //this.level().getProfiler().pop(); // Purpur + int i = this.level().getServer().getTickCount() + this.getId(); + ++ if (i % this.level().plazmaLevelConfiguration().entity.sensor.tick == 0) this.sensing.tick(); // Plazma - Configurable Sensor Tick if (i % 2 != 0 && this.tickCount > 1) { - //this.level.getProfiler().push("targetSelector"); // Purpur + //this.level().getProfiler().push("targetSelector"); // Purpur if (this.targetSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking diff --git a/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java index e6c22ab535ab8fecaadbf06d4982440fd5863f17..185e2627596314d979188468f838d008442f2d2e 100644 diff --git a/patches/server/0033-Optimize-VarInts.patch b/patches/server/0033-Optimize-VarInts.patch index 3997c2e..fb8db1a 100644 --- a/patches/server/0033-Optimize-VarInts.patch +++ b/patches/server/0033-Optimize-VarInts.patch @@ -57,10 +57,10 @@ index c0bd2997fe3ebbfe926de832a36d209cc875f3e2..6108f3aa438b96e817c3a2e582c2c817 this.writeByte(value & 127 | 128); value >>>= 7; diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -index 39eca4acefa8f9cf143398cfc6cf157e8489947e..754ed13a04631c69e3fb2421a12b17d0a6f732c6 100644 +index b2c9ac1947e6c9ad0e693cfeaf6f2f4bfd521aa0..c1ff5d20dd3b74062837fd30a7b3966e16bdf54c 100644 --- a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java +++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -@@ -42,6 +42,7 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -43,6 +43,7 @@ public class GlobalConfiguration extends ConfigurationPart { public boolean reduceCreateRandomInstance = DO_OPTIMIZE; public boolean doNotTriggerLootTableRefreshForNonPlayerInteraction = DO_OPTIMIZE; public boolean doNotSendUselessEntityPackets = DO_OPTIMIZE; diff --git a/patches/server/0034-Variable-Entity-WakeUp-Duration.patch b/patches/server/0034-Variable-entity-wakeup-duration.patch similarity index 84% rename from patches/server/0034-Variable-Entity-WakeUp-Duration.patch rename to patches/server/0034-Variable-entity-wakeup-duration.patch index f09cdd6..aa01817 100644 --- a/patches/server/0034-Variable-Entity-WakeUp-Duration.patch +++ b/patches/server/0034-Variable-entity-wakeup-duration.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: IPECTER Date: Sat, 6 May 2023 21:09:45 +0900 -Subject: [PATCH] Variable-Entity-WakeUp-Duration +Subject: [PATCH] Variable entity wakeup duration Original: GaleMC/Gale Copyright (C) 2023 Martijn Muijsers @@ -32,7 +32,7 @@ index 185e2627596314d979188468f838d008442f2d2e..238e10a35a9e4b300b11c838cda39b87 } } diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index ee64ddb0da23ea1e54d0295324aca5b46a438111..d5230a360cd8c296303b494d716d33ad1fca6a96 100644 +index 43d9e7287cf0e498ccbff9b865bb813e7fb567c0..21f7c0b235936cedcc4e4bde45bebd5fea2e1275 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -75,28 +75,36 @@ public class ActivationRange @@ -40,25 +40,25 @@ index ee64ddb0da23ea1e54d0295324aca5b46a438111..d5230a360cd8c296303b494d716d33ad if (inactiveFor > config.wakeUpInactiveVillagersEvery && world.wakeupInactiveRemainingVillagers > 0) { world.wakeupInactiveRemainingVillagers--; - return config.wakeUpInactiveVillagersFor; -+ return getWakeUpDurationWithVariance(config.wakeUpInactiveVillagersFor, entity.level.plazmaLevelConfiguration().entity.wakeUp.durationVariance.villager); // Plazma - Variable Entity WakeUp Duration ++ return getWakeUpDurationWithVariance(config.wakeUpInactiveVillagersFor, entity.level().plazmaLevelConfiguration().entity.wakeUp.durationVariance.villager); // Plazma - Variable Entity WakeUp Duration } } else if (entity.activationType == ActivationType.ANIMAL) { if (inactiveFor > config.wakeUpInactiveAnimalsEvery && world.wakeupInactiveRemainingAnimals > 0) { world.wakeupInactiveRemainingAnimals--; - return config.wakeUpInactiveAnimalsFor; -+ return getWakeUpDurationWithVariance(config.wakeUpInactiveAnimalsFor, entity.level.plazmaLevelConfiguration().entity.wakeUp.durationVariance.animal); // Plazma - Variable Entity WakeUp Duration ++ return getWakeUpDurationWithVariance(config.wakeUpInactiveAnimalsFor, entity.level().plazmaLevelConfiguration().entity.wakeUp.durationVariance.animal); // Plazma - Variable Entity WakeUp Duration } } else if (entity.activationType == ActivationType.FLYING_MONSTER) { if (inactiveFor > config.wakeUpInactiveFlyingEvery && world.wakeupInactiveRemainingFlying > 0) { world.wakeupInactiveRemainingFlying--; - return config.wakeUpInactiveFlyingFor; -+ return getWakeUpDurationWithVariance(config.wakeUpInactiveFlyingFor, entity.level.plazmaLevelConfiguration().entity.wakeUp.durationVariance.flyingMonster); // Plazma - Variable Entity WakeUp Duration ++ return getWakeUpDurationWithVariance(config.wakeUpInactiveFlyingFor, entity.level().plazmaLevelConfiguration().entity.wakeUp.durationVariance.flyingMonster); // Plazma - Variable Entity WakeUp Duration } } else if (entity.activationType == ActivationType.MONSTER || entity.activationType == ActivationType.RAIDER) { if (inactiveFor > config.wakeUpInactiveMonstersEvery && world.wakeupInactiveRemainingMonsters > 0) { world.wakeupInactiveRemainingMonsters--; - return config.wakeUpInactiveMonstersFor; -+ return getWakeUpDurationWithVariance(config.wakeUpInactiveMonstersFor, entity.level.plazmaLevelConfiguration().entity.wakeUp.durationVariance.monster); // Plazma - Variable Entity WakeUp Duration ++ return getWakeUpDurationWithVariance(config.wakeUpInactiveMonstersFor, entity.level().plazmaLevelConfiguration().entity.wakeUp.durationVariance.monster); // Plazma - Variable Entity WakeUp Duration } } return -1; diff --git a/patches/server/0035-More-Optimise-State-Lookup.patch b/patches/server/0035-More-optimise-state-lookup.patch similarity index 94% rename from patches/server/0035-More-Optimise-State-Lookup.patch rename to patches/server/0035-More-optimise-state-lookup.patch index 2459cdb..3e76fbf 100644 --- a/patches/server/0035-More-Optimise-State-Lookup.patch +++ b/patches/server/0035-More-optimise-state-lookup.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: IPECTER Date: Wed, 10 May 2023 15:30:03 +0900 -Subject: [PATCH] More-Optimise-State-Lookup +Subject: [PATCH] More optimise state lookup diff --git a/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java b/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java @@ -18,7 +18,7 @@ index 57d0cd3ad6f972e986c72a57f1a6e36003f190c2..5c03e26db0f9da992e9b0487a872e0ec public ZeroCollidingReferenceStateTable(final StateHolder state, final Map, Comparable> this_map) { diff --git a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java -index 170f5cb3f01a57ad76e3bbeacd5b7c7e52f29959..ec42cafb7a9caf710f9ec5cea6130d54092dc5d2 100644 +index 5f285d190186a2ff5a61d05070593e1d633dd79a..62934ef07ef856b917862c6f58ad391984da6327 100644 --- a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java +++ b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java @@ -114,21 +114,17 @@ public abstract class StateHolder { @@ -26,7 +26,7 @@ index 170f5cb3f01a57ad76e3bbeacd5b7c7e52f29959..ec42cafb7a9caf710f9ec5cea6130d54 public , V extends T> S trySetValue(Property property, V value) { - Comparable comparable = this.values.get(property); -- if (comparable != null && comparable != value) { +- if (comparable != null && !comparable.equals(value)) { - S object = this.neighbours.get(property, value); - if (object == null) { - throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner + ", it is not an allowed value"); diff --git a/patches/server/0036-Suppress-Error-From-DirtyAttributes.patch b/patches/server/0036-Suppress-Error-From-DirtyAttributes.patch index 582783e..5db74bf 100644 --- a/patches/server/0036-Suppress-Error-From-DirtyAttributes.patch +++ b/patches/server/0036-Suppress-Error-From-DirtyAttributes.patch @@ -5,21 +5,21 @@ Subject: [PATCH] Suppress-Error-From-DirtyAttributes diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java -index dbb987d5896e199aeae3bcd86c69bf3327af8ada..d6079c9577d65eab51dab8803eab6e46dccc8dd3 100644 +index 80ab684a33876d62186dcf86f555e46db1594b09..21b18d85563ffd5f93234455dca4dc30582b8925 100644 --- a/src/main/java/net/minecraft/server/level/ServerEntity.java +++ b/src/main/java/net/minecraft/server/level/ServerEntity.java -@@ -419,8 +419,8 @@ public class ServerEntity { +@@ -403,8 +403,8 @@ public class ServerEntity { } if (this.entity instanceof LivingEntity) { - Set set = ((LivingEntity) this.entity).getAttributes().getDirtyAttributes(); - + Set attributes = ((LivingEntity) this.entity).getAttributes().getDirtyAttributes(); // Plazma - suppress error from dirty attributes -+ final Set set = this.entity.level.plazmaLevelConfiguration().misc.suppressErrorFromDirtyAttributes ? java.util.Collections.synchronizedSet(attributes) : attributes; // Plazma - suppress error from dirty attributes ++ final Set set = this.entity.level().plazmaLevelConfiguration().misc.suppressErrorFromDirtyAttributes ? java.util.Collections.synchronizedSet(attributes) : attributes; // Plazma - suppress error from dirty attributes if (!set.isEmpty()) { // CraftBukkit start - Send scaled max health if (this.entity instanceof ServerPlayer) { -@@ -430,7 +430,7 @@ public class ServerEntity { +@@ -414,7 +414,7 @@ public class ServerEntity { this.broadcastAndSend(new ClientboundUpdateAttributesPacket(this.entity.getId(), set)); } diff --git a/patches/server/0037-Implement-FerriteCore.patch b/patches/server/0037-Implement-FerriteCore.patch index a450356..12d48fb 100644 --- a/patches/server/0037-Implement-FerriteCore.patch +++ b/patches/server/0037-Implement-FerriteCore.patch @@ -7,10 +7,10 @@ Original: malte0811/FerriteCore Copyright (C) 2023 malte0811 diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -index bee42ce7c1cb0f5ebd4890c02bc9c5dd727f7fd6..22f194956640b88c1d060b732e517f85d9091cf6 100644 +index 942ce713afe27ec75d849877a88721ef6334fafa..595771af13659fcb365fd3f088762dc01964842f 100644 --- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java +++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -@@ -737,6 +737,12 @@ public abstract class BlockBehaviour implements FeatureElement { +@@ -789,6 +789,12 @@ public abstract class BlockBehaviour implements FeatureElement { protected BlockBehaviour.BlockStateBase.Cache cache; private FluidState fluidState; private boolean isRandomlyTicking; @@ -23,7 +23,7 @@ index bee42ce7c1cb0f5ebd4890c02bc9c5dd727f7fd6..22f194956640b88c1d060b732e517f85 protected BlockStateBase(Block block, ImmutableMap, Comparable> propertyMap, MapCodec codec) { super(block, propertyMap, codec); -@@ -795,6 +801,7 @@ public abstract class BlockBehaviour implements FeatureElement { +@@ -871,6 +877,7 @@ public abstract class BlockBehaviour implements FeatureElement { // Paper end public void initCache() { @@ -31,7 +31,7 @@ index bee42ce7c1cb0f5ebd4890c02bc9c5dd727f7fd6..22f194956640b88c1d060b732e517f85 this.fluidState = ((Block) this.owner).getFluidState(this.asState()); this.isRandomlyTicking = ((Block) this.owner).isRandomlyTicking(this.asState()); if (!this.getBlock().hasDynamicShape()) { -@@ -832,7 +839,61 @@ public abstract class BlockBehaviour implements FeatureElement { +@@ -909,7 +916,61 @@ public abstract class BlockBehaviour implements FeatureElement { } } // Paper end @@ -93,7 +93,7 @@ index bee42ce7c1cb0f5ebd4890c02bc9c5dd727f7fd6..22f194956640b88c1d060b732e517f85 public Block getBlock() { return (Block) this.owner; -@@ -1205,10 +1266,10 @@ public abstract class BlockBehaviour implements FeatureElement { +@@ -1305,10 +1366,10 @@ public abstract class BlockBehaviour implements FeatureElement { final boolean propagatesSkylightDown; final int lightBlock; @Nullable diff --git a/patches/server/0038-Let-Me-Despawn-Configuration.patch b/patches/server/0038-Let-Me-Despawn-Configuration.patch deleted file mode 100644 index 74a0b89..0000000 --- a/patches/server/0038-Let-Me-Despawn-Configuration.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: IPECTER -Date: Thu, 18 May 2023 16:21:37 +0900 -Subject: [PATCH] Let Me Despawn Configuration - - -diff --git a/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -index a1b55bb5431d1712fc06da0cf06857a986efeea0..116384c1fe27a868bcbe1d21f0b2723c73b9170c 100644 ---- a/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -+++ b/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -@@ -131,4 +131,11 @@ public class LevelConfigurations extends ConfigurationPart { - } - - } -+ -+ public LetMeDespawn letMeDespawn; -+ public class LetMeDespawn extends ConfigurationPart { -+ -+ public boolean enabled = false; -+ -+ } - } diff --git a/patches/server/0038-Skip-event-if-no-listeners.patch b/patches/server/0038-Skip-event-if-no-listeners.patch new file mode 100644 index 0000000..b91c185 --- /dev/null +++ b/patches/server/0038-Skip-event-if-no-listeners.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: AlphaKR93 +Date: Thu, 29 Jun 2023 05:49:26 +0000 +Subject: [PATCH] Skip event if no listeners + + +diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java +index 7ce9ebba8ce304d1f3f21d4f15ee5f3560d7700b..32305a34bcebd53aa523102a6da59bc2eb765055 100644 +--- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java ++++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java +@@ -36,15 +36,17 @@ class PaperEventManager { + + // SimplePluginManager + public void callEvent(@NotNull Event event) { ++ // Plazma start ++ HandlerList handlers = event.getHandlers(); ++ RegisteredListener[] listeners = handlers.getRegisteredListeners(); ++ if (listeners.length == 0) return; ++ // Plazma end + if (event.isAsynchronous() && this.server.isPrimaryThread()) { + throw new IllegalStateException(event.getEventName() + " may only be triggered asynchronously."); + } else if (!event.isAsynchronous() && !this.server.isPrimaryThread() && !this.server.isStopping()) { + throw new IllegalStateException(event.getEventName() + " may only be triggered synchronously."); + } + +- HandlerList handlers = event.getHandlers(); +- RegisteredListener[] listeners = handlers.getRegisteredListeners(); +- + for (RegisteredListener registration : listeners) { + if (!registration.getPlugin().isEnabled()) { + continue; diff --git a/patches/server/0039-Implement-Let-Me-Despawn.patch b/patches/server/0039-Implement-Let-Me-Despawn.patch deleted file mode 100644 index 801dd17..0000000 --- a/patches/server/0039-Implement-Let-Me-Despawn.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: IPECTER -Date: Thu, 18 May 2023 16:42:40 +0900 -Subject: [PATCH] Implement Let Me Despawn - -Original: frikinjay/let-me-despawn -Copyright (C) 2023 frikinjay - -diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 3a365d7efd439cb8ddb99381bd714fb48896f4d2..b6d27332eb151bdf408909b241c493da54841c8e 100644 ---- a/src/main/java/net/minecraft/world/entity/Mob.java -+++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -885,7 +885,7 @@ public abstract class Mob extends LivingEntity implements Targeting { - public void checkDespawn() { - if (this.level.getDifficulty() == Difficulty.PEACEFUL && this.shouldDespawnInPeaceful()) { - this.discard(); -- } else if (!this.isPersistenceRequired() && !this.requiresCustomPersistence()) { -+ } else if ((this.level.plazmaLevelConfiguration().letMeDespawn.enabled || !this.isPersistenceRequired()) && !this.requiresCustomPersistence()) { - // Paper start - optimise checkDespawn - Player entityhuman = this.level.findNearbyPlayer(this, level.paperConfig().entities.spawning.despawnRanges.get(this.getType().getCategory()).hard() + 1, EntitySelector.PLAYER_AFFECTS_SPAWNING); // Paper - if (entityhuman == null) { -@@ -899,14 +899,14 @@ public abstract class Mob extends LivingEntity implements Targeting { - int j = i * i; - - if (d0 > (double) j && this.removeWhenFarAway(d0)) { -- this.discard(); -+ this.dropEquipmentOnDespawn(); this.discard(); // Plazma - Let Me Despawn - } - - int k = this.level.paperConfig().entities.spawning.despawnRanges.get(this.getType().getCategory()).soft(); // Paper - custom despawn distances - int l = k * k; - - if (this.noActionTime > 600 && this.random.nextInt(800) == 0 && d0 > (double) l && this.removeWhenFarAway(d0)) { -- this.discard(); -+ this.dropEquipmentOnDespawn(); this.discard(); // Plazma - Let Me Despawn - } else if (d0 < (double) l) { - this.noActionTime = 0; - } -@@ -917,6 +917,19 @@ public abstract class Mob extends LivingEntity implements Targeting { - } - } - -+ // Plazma start - Let Me Despawn -+ private void dropEquipmentOnDespawn() { -+ if (!this.level.plazmaLevelConfiguration().letMeDespawn.dropPickedUpItem()) return; -+ for (EquipmentSlot equipmentSlot : EquipmentSlot.values()) { -+ ItemStack itemStack = this.getItemBySlot(equipmentSlot); -+ if (!itemStack.isEmpty() && !EnchantmentHelper.hasVanishingCurse(itemStack)) { -+ this.spawnAtLocation(itemStack); -+ this.setItemSlot(equipmentSlot, ItemStack.EMPTY); -+ } -+ } -+ } -+ // Plazma end -+ - @Override - protected final void serverAiStep() { - ++this.noActionTime; -diff --git a/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -index 116384c1fe27a868bcbe1d21f0b2723c73b9170c..97ffcd1c0e50ab21756404a483fa8d1f4b6579b1 100644 ---- a/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -+++ b/src/main/java/org/plazmamc/plazma/configurations/LevelConfigurations.java -@@ -136,6 +136,11 @@ public class LevelConfigurations extends ConfigurationPart { - public class LetMeDespawn extends ConfigurationPart { - - public boolean enabled = false; -+ boolean dropPickedUpItem = true; -+ -+ public boolean dropPickedUpItem() { -+ return enabled && dropPickedUpItem; -+ } - - } - } diff --git a/patches/server/0040-Reduce-allocations.patch b/patches/server/0039-Reduce-allocations.patch similarity index 57% rename from patches/server/0040-Reduce-allocations.patch rename to patches/server/0039-Reduce-allocations.patch index 808b643..21250d5 100644 --- a/patches/server/0040-Reduce-allocations.patch +++ b/patches/server/0039-Reduce-allocations.patch @@ -1,33 +1,31 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: IPECTER -Date: Tue, 30 May 2023 11:33:01 +0900 -Subject: [PATCH] Reduce-allocations +From: AlphaKR93 +Date: Thu, 6 Jul 2023 23:56:45 +0900 +Subject: [PATCH] Reduce allocations diff --git a/src/main/java/ca/spottedleaf/starlight/common/light/StarLightEngine.java b/src/main/java/ca/spottedleaf/starlight/common/light/StarLightEngine.java -index 1b0d92c68407cdb09ed8aac271b625d92db87017..8b48be5e2ea8815c152d182aa010eba0da84c562 100644 +index ad1eeebe6de219143492b94da309cb54ae9e0a5b..9c5cd176f9e7c525877c9fd219a4b8d3e2e6231d 100644 --- a/src/main/java/ca/spottedleaf/starlight/common/light/StarLightEngine.java +++ b/src/main/java/ca/spottedleaf/starlight/common/light/StarLightEngine.java -@@ -39,7 +39,7 @@ public abstract class StarLightEngine { - AxisDirection.POSITIVE_Z, AxisDirection.NEGATIVE_Z - }; +@@ -1088,13 +1088,14 @@ public abstract class StarLightEngine { -- protected static enum AxisDirection { -+ public static enum AxisDirection { // Plazma - protected -> public - - // Declaration order is important and relied upon. Do not change without modifying propagation code. - POSITIVE_X(1, 0, 0), NEGATIVE_X(-1, 0, 0), -@@ -1094,7 +1094,7 @@ public abstract class StarLightEngine { + protected static final AxisDirection[][] OLD_CHECK_DIRECTIONS = new AxisDirection[1 << 6][]; + protected static final int ALL_DIRECTIONS_BITSET = (1 << 6) - 1; ++ private static final AxisDirection[] EMPTY_DIRECTION = new AxisDirection[0]; // Plazma + static { + for (int i = 0; i < OLD_CHECK_DIRECTIONS.length; ++i) { + final List directions = new ArrayList<>(); for (int bitset = i, len = Integer.bitCount(i), index = 0; index < len; ++index, bitset ^= IntegerUtil.getTrailingBit(bitset)) { directions.add(AXIS_DIRECTIONS[IntegerUtil.trailingZeros(bitset)]); } - OLD_CHECK_DIRECTIONS[i] = directions.toArray(new AxisDirection[0]); -+ OLD_CHECK_DIRECTIONS[i] = directions.toArray(org.plazmamc.plazma.util.Constants.STARLIGHT_AXIS_DIRECTION); ++ OLD_CHECK_DIRECTIONS[i] = directions.toArray(EMPTY_DIRECTION); // Plazma } } diff --git a/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java b/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java -index cab91880a08c6fdc545804911d295e0f24f4d983..ca2ca7f3b5b0ea5862011c6b4beab4b2ab540792 100644 +index 42fdce97d99618a53f2e9c51804ff2205b574f69..20ad001e6418606d0d33f9a1148cbec86f0d4a3a 100644 --- a/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java +++ b/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java @@ -92,8 +92,8 @@ public final class ChunkPacketBlockControllerAntiXray extends ChunkPacketBlockCo @@ -36,78 +34,77 @@ index cab91880a08c6fdc545804911d295e0f24f4d983..ca2ca7f3b5b0ea5862011c6b4beab4b2 presetBlockStateSet.addAll(presetBlockStateList); - presetBlockStates = presetBlockStateSet.isEmpty() ? new BlockState[]{Blocks.DIAMOND_ORE.defaultBlockState()} : presetBlockStateSet.toArray(new BlockState[0]); - presetBlockStatesFull = presetBlockStateSet.isEmpty() ? new BlockState[]{Blocks.DIAMOND_ORE.defaultBlockState()} : presetBlockStateList.toArray(new BlockState[0]); -+ presetBlockStates = presetBlockStateSet.isEmpty() ? new BlockState[]{Blocks.DIAMOND_ORE.defaultBlockState()} : presetBlockStateSet.toArray(org.plazmamc.plazma.util.Constants.BLOCK_STATE); -+ presetBlockStatesFull = presetBlockStateSet.isEmpty() ? new BlockState[]{Blocks.DIAMOND_ORE.defaultBlockState()} : presetBlockStateList.toArray(org.plazmamc.plazma.util.Constants.BLOCK_STATE); ++ presetBlockStates = presetBlockStateSet.isEmpty() ? new BlockState[]{Blocks.DIAMOND_ORE.defaultBlockState()} : presetBlockStateSet.toArray(org.plazmamc.plazma.EmptyConstants.BLOCK_STATE); // Plazma ++ presetBlockStatesFull = presetBlockStateSet.isEmpty() ? new BlockState[]{Blocks.DIAMOND_ORE.defaultBlockState()} : presetBlockStateList.toArray(org.plazmamc.plazma.EmptyConstants.BLOCK_STATE); // Plazma presetBlockStatesStone = null; presetBlockStatesDeepslate = null; presetBlockStatesNetherrack = null; -diff --git a/src/main/java/com/destroystokyo/paper/util/maplist/ChunkList.java b/src/main/java/com/destroystokyo/paper/util/maplist/ChunkList.java -index 554f4d4e63c1431721989e6f502a32ccc53a8807..237cc1927c237fe4e87d5cbf74c6d1faae1d67f2 100644 ---- a/src/main/java/com/destroystokyo/paper/util/maplist/ChunkList.java -+++ b/src/main/java/com/destroystokyo/paper/util/maplist/ChunkList.java -@@ -17,7 +17,7 @@ public final class ChunkList implements Iterable { - this.chunkToIndex.defaultReturnValue(Integer.MIN_VALUE); - } - -- protected static final LevelChunk[] EMPTY_LIST = new LevelChunk[0]; -+ protected static final LevelChunk[] EMPTY_LIST = org.plazmamc.plazma.util.Constants.LEVEL_CHUNK; - - protected LevelChunk[] chunks = EMPTY_LIST; - protected int count; diff --git a/src/main/java/com/destroystokyo/paper/util/maplist/EntityList.java b/src/main/java/com/destroystokyo/paper/util/maplist/EntityList.java -index 0133ea6feb1ab88f021f66855669f58367e7420b..5bf288af5d2855c2287a297abedb2cf9358b8b3c 100644 +index 0133ea6feb1ab88f021f66855669f58367e7420b..628e8e7c982d498b1a8297bebbe35ea1879fe5b8 100644 --- a/src/main/java/com/destroystokyo/paper/util/maplist/EntityList.java +++ b/src/main/java/com/destroystokyo/paper/util/maplist/EntityList.java -@@ -17,7 +17,7 @@ public final class EntityList implements Iterable { +@@ -17,9 +17,9 @@ public final class EntityList implements Iterable { this.entityToIndex.defaultReturnValue(Integer.MIN_VALUE); } - protected static final Entity[] EMPTY_LIST = new Entity[0]; -+ protected static final Entity[] EMPTY_LIST = org.plazmamc.plazma.util.Constants.ENTITY; ++ //protected static final Entity[] EMPTY_LIST = new Entity[0]; // Plazma - protected Entity[] entities = EMPTY_LIST; +- protected Entity[] entities = EMPTY_LIST; ++ protected Entity[] entities = org.plazmamc.plazma.EmptyConstants.ENTITY; // Plazma protected int count; + + public int size() { diff --git a/src/main/java/com/destroystokyo/paper/util/maplist/IBlockDataList.java b/src/main/java/com/destroystokyo/paper/util/maplist/IBlockDataList.java -index 277cfd9d1e8fff5d9b5e534b75c3c5162d58b0b7..d552f9fe1bfb8c9a25f27117cb6896c11b05a0c3 100644 +index 277cfd9d1e8fff5d9b5e534b75c3c5162d58b0b7..8656dfe589cdfc80207f42cef09684ba637f1700 100644 --- a/src/main/java/com/destroystokyo/paper/util/maplist/IBlockDataList.java +++ b/src/main/java/com/destroystokyo/paper/util/maplist/IBlockDataList.java -@@ -20,7 +20,7 @@ public final class IBlockDataList { +@@ -20,9 +20,9 @@ public final class IBlockDataList { this.map.defaultReturnValue(Long.MAX_VALUE); } - private static final long[] EMPTY_LIST = new long[0]; -+ private static final long[] EMPTY_LIST = org.plazmamc.plazma.util.Constants.EMPTY_LONG; ++ //private static final long[] EMPTY_LIST = new long[0]; // Plazma - private long[] byIndex = EMPTY_LIST; +- private long[] byIndex = EMPTY_LIST; ++ private long[] byIndex = org.plazmamc.plazma.EmptyConstants.LONG; // Plazma private int size; + + public static int getLocationKey(final int x, final int y, final int z) { diff --git a/src/main/java/com/destroystokyo/paper/util/maplist/ReferenceList.java b/src/main/java/com/destroystokyo/paper/util/maplist/ReferenceList.java -index 190c5f0b02a3d99054704ae1afbffb3498ddffe1..a5460fc96ebc6f1356e4cec1ee7ef14879ab3b2a 100644 +index 190c5f0b02a3d99054704ae1afbffb3498ddffe1..98a3a2ab266e88f2d21664f4d0f4b33a2247d6f7 100644 --- a/src/main/java/com/destroystokyo/paper/util/maplist/ReferenceList.java +++ b/src/main/java/com/destroystokyo/paper/util/maplist/ReferenceList.java -@@ -15,7 +15,7 @@ public final class ReferenceList implements Iterable { +@@ -15,9 +15,9 @@ public final class ReferenceList implements Iterable { this.referenceToIndex.defaultReturnValue(Integer.MIN_VALUE); } - protected static final Object[] EMPTY_LIST = new Object[0]; -+ protected static final Object[] EMPTY_LIST = org.plazmamc.plazma.util.Constants.EMPTY_OBJECT; ++ //protected static final Object[] EMPTY_LIST = new Object[0]; // Plazma - protected Object[] references = EMPTY_LIST; +- protected Object[] references = EMPTY_LIST; ++ protected Object[] references = org.plazmamc.plazma.EmptyConstants.OBJECT; // Plazma protected int count; + + public int size() { diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkTaskScheduler.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkTaskScheduler.java -index 84cc9397237fa0c17aa1012dfb5683c90eb6d3b8..aec83ebe4038b73a9c69dd86029e466f6d6e52d5 100644 +index f975cb93716e137d973ff2f9011acdbef58859a2..7b0ac438d00de2c7a27ec8aefc1d280e9c2aef8b 100644 --- a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkTaskScheduler.java +++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkTaskScheduler.java -@@ -751,7 +751,7 @@ public final class ChunkTaskScheduler { +@@ -849,9 +849,10 @@ public final class ChunkTaskScheduler { + } + } ++ private static final ChunkInfo[] EMPTY_CHUNK_INFO = new ChunkInfo[0]; // Plazma public static ChunkInfo[] getChunkInfos() { synchronized (WAITING_CHUNKS) { - return WAITING_CHUNKS.toArray(new ChunkInfo[0]); -+ return WAITING_CHUNKS.toArray(org.plazmamc.plazma.util.Constants.CHUNK_INFO); ++ return WAITING_CHUNKS.toArray(EMPTY_CHUNK_INFO); // Plazma } } diff --git a/src/main/java/io/papermc/paper/command/subcommands/VersionCommand.java b/src/main/java/io/papermc/paper/command/subcommands/VersionCommand.java -index ae60bd96b5284d54676d8e7e4dd5d170b526ec1e..e678d1bf61a2238967c3bd999dfba4adbdf315cc 100644 +index ae60bd96b5284d54676d8e7e4dd5d170b526ec1e..e955582b928085af032170467be015a3e857ec28 100644 --- a/src/main/java/io/papermc/paper/command/subcommands/VersionCommand.java +++ b/src/main/java/io/papermc/paper/command/subcommands/VersionCommand.java @@ -14,7 +14,7 @@ public final class VersionCommand implements PaperSubcommand { @@ -115,34 +112,57 @@ index ae60bd96b5284d54676d8e7e4dd5d170b526ec1e..e678d1bf61a2238967c3bd999dfba4ad final @Nullable Command ver = MinecraftServer.getServer().server.getCommandMap().getCommand("version"); if (ver != null) { - ver.execute(sender, "paper", new String[0]); -+ ver.execute(sender, "paper", org.plazmamc.plazma.util.Constants.EMPTY_STRING); ++ ver.execute(sender, "paper", org.plazmamc.plazma.EmptyConstants.STRING); // Plazma } return true; } -diff --git a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java -index f597d65d56964297eeeed6c7e77703764178fee0..15240fe6ca5fd3f9bbbcc4499c0bf26bb35803c0 100644 ---- a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java -+++ b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java -@@ -81,7 +81,7 @@ public final class ChunkEntitySlices { - } - } - -- return ret.toArray(new org.bukkit.entity.Entity[0]); -+ return ret.toArray(org.plazmamc.plazma.util.Constants.BUKKIT_ENTITY); +diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperPluginInstanceManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperPluginInstanceManager.java +index 9c7552968b8c017c71a7a77557a66a03ed89f125..38d31c03db38235a47400c99dbc08b2d03f20532 100644 +--- a/src/main/java/io/papermc/paper/plugin/manager/PaperPluginInstanceManager.java ++++ b/src/main/java/io/papermc/paper/plugin/manager/PaperPluginInstanceManager.java +@@ -67,8 +67,9 @@ class PaperPluginInstanceManager { + return this.lookupNames.get(name.replace(' ', '_').toLowerCase(java.util.Locale.ENGLISH)); // Paper } - public CompoundTag save() { -@@ -298,7 +298,7 @@ public final class ChunkEntitySlices { ++ private static final Plugin[] EMPTY_PLUGIN = new Plugin[0]; // Plazma + public @NotNull Plugin[] getPlugins() { +- return this.plugins.toArray(new Plugin[0]); ++ return this.plugins.toArray(EMPTY_PLUGIN); // Plazma + } + + public boolean isPluginEnabled(@NotNull String name) { +@@ -125,6 +126,7 @@ class PaperPluginInstanceManager { + } + + // The behavior of this is that all errors are logged instead of being thrown ++ private static final JavaPlugin[] EMPTY_JAVA_PLUGIN = new JavaPlugin[0]; // Plazma + public @NotNull Plugin[] loadPlugins(@NotNull Path directory) { + Preconditions.checkArgument(Files.isDirectory(directory), "Directory must be a directory"); // Avoid creating a directory if it doesn't exist + +@@ -137,7 +139,7 @@ class PaperPluginInstanceManager { + this.server.getLogger().log(Level.SEVERE, "Unknown error occurred while loading plugins through PluginManager.", e); + } + +- return runtimePluginEntrypointHandler.getPluginProviderStorage().getLoaded().toArray(new JavaPlugin[0]); ++ return runtimePluginEntrypointHandler.getPluginProviderStorage().getLoaded().toArray(EMPTY_JAVA_PLUGIN); // Plazma + } + + // Plugins are disabled in order like this inorder to "rougly" prevent +diff --git a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java +index 7e8dc9e8f381abfdcce2746edc93122d623622d1..9c2ccf975c476db4bf71298d08ffce2c323d43e0 100644 +--- a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java ++++ b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java +@@ -303,7 +303,7 @@ public final class ChunkEntitySlices { protected static final class BasicEntityList { - protected static final Entity[] EMPTY = new Entity[0]; -+ protected static final Entity[] EMPTY = org.plazmamc.plazma.util.Constants.ENTITY; ++ protected static final Entity[] EMPTY = org.plazmamc.plazma.EmptyConstants.ENTITY; // Plazma protected static final int DEFAULT_CAPACITY = 4; protected E[] storage; diff --git a/src/main/java/net/minecraft/CrashReport.java b/src/main/java/net/minecraft/CrashReport.java -index c468733f44ccb3ff4ba3c20921a4ec52658f0689..7e124979a2843b7f0a365e51d23192731747e6bf 100644 +index c468733f44ccb3ff4ba3c20921a4ec52658f0689..52dd6bf580f22081a530aee1277276e64270c91b 100644 --- a/src/main/java/net/minecraft/CrashReport.java +++ b/src/main/java/net/minecraft/CrashReport.java @@ -28,7 +28,7 @@ public class CrashReport { @@ -150,12 +170,12 @@ index c468733f44ccb3ff4ba3c20921a4ec52658f0689..7e124979a2843b7f0a365e51d2319273 private File saveFile; private boolean trackingStackTrace = true; - private StackTraceElement[] uncategorizedStackTrace = new StackTraceElement[0]; -+ private StackTraceElement[] uncategorizedStackTrace = org.plazmamc.plazma.util.Constants.STACK_TRACE_ELEMENT; ++ private StackTraceElement[] uncategorizedStackTrace = org.plazmamc.plazma.EmptyConstants.STACK_TRACE_ELEMENT; // Plazma private final SystemReport systemReport = new SystemReport(); public CrashReport(String message, Throwable cause) { diff --git a/src/main/java/net/minecraft/CrashReportCategory.java b/src/main/java/net/minecraft/CrashReportCategory.java -index b54ddd0ba0b001fbcb1838a838ca4890df936f1b..61f63791ddda4fd84298d18be3dbb6c44b3462da 100644 +index b54ddd0ba0b001fbcb1838a838ca4890df936f1b..a49ce64ea944f5cab83ba1bee5ab4c749950af9e 100644 --- a/src/main/java/net/minecraft/CrashReportCategory.java +++ b/src/main/java/net/minecraft/CrashReportCategory.java @@ -12,7 +12,7 @@ import net.minecraft.world.level.block.state.BlockState; @@ -163,47 +183,39 @@ index b54ddd0ba0b001fbcb1838a838ca4890df936f1b..61f63791ddda4fd84298d18be3dbb6c4 private final String title; private final List entries = Lists.newArrayList(); - private StackTraceElement[] stackTrace = new StackTraceElement[0]; -+ private StackTraceElement[] stackTrace = org.plazmamc.plazma.util.Constants.STACK_TRACE_ELEMENT; ++ private StackTraceElement[] stackTrace = org.plazmamc.plazma.EmptyConstants.STACK_TRACE_ELEMENT; // Plazma public CrashReportCategory(String title) { this.title = title; diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java -index 4c90a6ee734451fe404b2255d21090b669da1aa1..ae8b26aa9ceff07a79b1dbfd310123ca61a97a3d 100644 +index c60c73d9f998260f3abe6fe445255c6e7c38b0c3..cf0d0b75b3e5833406d84aaa7b432d80314970d4 100644 --- a/src/main/java/net/minecraft/Util.java +++ b/src/main/java/net/minecraft/Util.java -@@ -400,7 +400,7 @@ public class Util { +@@ -401,7 +401,7 @@ public class Util { } else if (futures.size() == 1) { return futures.get(0).thenApply(List::of); } else { - CompletableFuture completableFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); -+ CompletableFuture completableFuture = CompletableFuture.allOf(futures.toArray(org.plazmamc.plazma.util.Constants.COMPLETABLE_FUTURE)); ++ CompletableFuture completableFuture = CompletableFuture.allOf(futures.toArray(org.plazmamc.plazma.EmptyConstants.COMPLETABLE_FUTURES)); // Plazma return completableFuture.thenApply((void_) -> { return futures.stream().map(CompletableFuture::join).toList(); }); diff --git a/src/main/java/net/minecraft/advancements/AdvancementRewards.java b/src/main/java/net/minecraft/advancements/AdvancementRewards.java -index 9e20a870a9c9c295b32cfa591eb52625125a5439..30473930bf3acf0ae74f3ff5e500f6e1374c11da 100644 +index 1cf85f7920023331c325822046edb33f310acd20..1f937dab74d368a0f75687ba696c9a9424163051 100644 --- a/src/main/java/net/minecraft/advancements/AdvancementRewards.java +++ b/src/main/java/net/minecraft/advancements/AdvancementRewards.java -@@ -24,7 +24,7 @@ import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; +@@ -24,7 +24,8 @@ import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; import net.minecraft.world.level.storage.loot.parameters.LootContextParams; public class AdvancementRewards { - public static final AdvancementRewards EMPTY = new AdvancementRewards(0, new ResourceLocation[0], new ResourceLocation[0], CommandFunction.CacheableFunction.NONE); -+ public static final AdvancementRewards EMPTY = new AdvancementRewards(0, org.plazmamc.plazma.util.Constants.RESOURCE_LOCATION, org.plazmamc.plazma.util.Constants.RESOURCE_LOCATION, CommandFunction.CacheableFunction.NONE); ++ private static final ResourceLocation[] EMPTY_LOCATION = new ResourceLocation[0]; // Plazma ++ public static final AdvancementRewards EMPTY = new AdvancementRewards(0, EMPTY_LOCATION, EMPTY_LOCATION, CommandFunction.CacheableFunction.NONE); // Plazma private final int experience; private final ResourceLocation[] loot; private final ResourceLocation[] recipes; -@@ -187,7 +187,7 @@ public class AdvancementRewards { - } - - public AdvancementRewards build() { -- return new AdvancementRewards(this.experience, this.loot.toArray(new ResourceLocation[0]), this.recipes.toArray(new ResourceLocation[0]), this.function == null ? CommandFunction.CacheableFunction.NONE : new CommandFunction.CacheableFunction(this.function)); -+ return new AdvancementRewards(this.experience, this.loot.toArray(org.plazmamc.plazma.util.Constants.RESOURCE_LOCATION), this.recipes.toArray(org.plazmamc.plazma.util.Constants.RESOURCE_LOCATION), this.function == null ? CommandFunction.CacheableFunction.NONE : new CommandFunction.CacheableFunction(this.function)); - } - } - } diff --git a/src/main/java/net/minecraft/advancements/RequirementsStrategy.java b/src/main/java/net/minecraft/advancements/RequirementsStrategy.java -index 051c1fb81d79c40be683edb86579bb975643bcb3..469c34c773e3257d0edfc807cb882b4cbfc3c53f 100644 +index 051c1fb81d79c40be683edb86579bb975643bcb3..f22dec61e0cc1db80ad435d168b8e877bba3695d 100644 --- a/src/main/java/net/minecraft/advancements/RequirementsStrategy.java +++ b/src/main/java/net/minecraft/advancements/RequirementsStrategy.java @@ -14,7 +14,7 @@ public interface RequirementsStrategy { @@ -211,12 +223,77 @@ index 051c1fb81d79c40be683edb86579bb975643bcb3..469c34c773e3257d0edfc807cb882b4c }; RequirementsStrategy OR = (criteriaNames) -> { - return new String[][]{criteriaNames.toArray(new String[0])}; -+ return new String[][]{criteriaNames.toArray(org.plazmamc.plazma.util.Constants.EMPTY_STRING)}; ++ return new String[][]{criteriaNames.toArray(org.plazmamc.plazma.EmptyConstants.STRING)}; // Plazma }; String[][] createRequirements(Collection criteriaNames); +diff --git a/src/main/java/net/minecraft/advancements/critereon/ContextAwarePredicate.java b/src/main/java/net/minecraft/advancements/critereon/ContextAwarePredicate.java +index bb1f97878f1fbf192207576cc515981f696294c3..2a89d13bd21bc549e498ea718cc8c88ab7460885 100644 +--- a/src/main/java/net/minecraft/advancements/critereon/ContextAwarePredicate.java ++++ b/src/main/java/net/minecraft/advancements/critereon/ContextAwarePredicate.java +@@ -11,7 +11,7 @@ import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; + import net.minecraft.world.level.storage.loot.predicates.LootItemConditions; + + public class ContextAwarePredicate { +- public static final ContextAwarePredicate ANY = new ContextAwarePredicate(new LootItemCondition[0]); ++ public static final ContextAwarePredicate ANY = new ContextAwarePredicate(org.plazmamc.plazma.EmptyConstants.LOOT_ITEM_CONDITIONS); // Plazma + private final LootItemCondition[] conditions; + private final Predicate compositePredicates; + +diff --git a/src/main/java/net/minecraft/advancements/critereon/EntityPredicate.java b/src/main/java/net/minecraft/advancements/critereon/EntityPredicate.java +index 9304f85ac41a89b39db59ef4b6e363d0f46cdbec..a2bf13d895456566bc0938b6931fb61a9606f129 100644 +--- a/src/main/java/net/minecraft/advancements/critereon/EntityPredicate.java ++++ b/src/main/java/net/minecraft/advancements/critereon/EntityPredicate.java +@@ -88,7 +88,7 @@ public class EntityPredicate { + + return contextAwarePredicates; + } else { +- return new ContextAwarePredicate[0]; ++ return org.plazmamc.plazma.EmptyConstants.CONTEXT_AWARE_PREDICATES; // Plazma + } + } + +diff --git a/src/main/java/net/minecraft/advancements/critereon/ItemPredicate.java b/src/main/java/net/minecraft/advancements/critereon/ItemPredicate.java +index e6960637aafdcd8ad9fa20991d57f9c9c4998036..79145d941c2750b799c3bf5eff3010a426a58153 100644 +--- a/src/main/java/net/minecraft/advancements/critereon/ItemPredicate.java ++++ b/src/main/java/net/minecraft/advancements/critereon/ItemPredicate.java +@@ -213,7 +213,7 @@ public class ItemPredicate { + + return itemPredicates; + } else { +- return new ItemPredicate[0]; ++ return org.plazmamc.plazma.EmptyConstants.ITEM_PREDICATES; // Plazma + } + } + +diff --git a/src/main/java/net/minecraft/advancements/critereon/KilledByCrossbowTrigger.java b/src/main/java/net/minecraft/advancements/critereon/KilledByCrossbowTrigger.java +index 818fd4b06c804e9640e3efb63f1e1b34dd73c636..318a7a0a161c0f73c4565e593ee1d66fbadab041 100644 +--- a/src/main/java/net/minecraft/advancements/critereon/KilledByCrossbowTrigger.java ++++ b/src/main/java/net/minecraft/advancements/critereon/KilledByCrossbowTrigger.java +@@ -64,7 +64,7 @@ public class KilledByCrossbowTrigger extends SimpleCriterionTrigger { @@ -224,12 +301,12 @@ index 163b1895bcbd16e93d36cd60d03e6b21df51cba7..4d47adb914399de94f725f53b9385880 public void clear() { - this.data = new byte[0]; -+ this.data = org.plazmamc.plazma.util.Constants.EMPTY_BYTE; ++ this.data = org.plazmamc.plazma.EmptyConstants.BYTE; // Plazma } @Override diff --git a/src/main/java/net/minecraft/nbt/CompoundTag.java b/src/main/java/net/minecraft/nbt/CompoundTag.java -index 7e94ebe06fc62293e665d6db19e42d947e7eb30f..6f41b334efc4a540cd8efcc782f5d5c8862b7476 100644 +index 7e94ebe06fc62293e665d6db19e42d947e7eb30f..bfe9fcc1f1ccc663672f6220aeb2d9244164cd8f 100644 --- a/src/main/java/net/minecraft/nbt/CompoundTag.java +++ b/src/main/java/net/minecraft/nbt/CompoundTag.java @@ -379,7 +379,7 @@ public class CompoundTag implements Tag { @@ -237,7 +314,7 @@ index 7e94ebe06fc62293e665d6db19e42d947e7eb30f..6f41b334efc4a540cd8efcc782f5d5c8 } - return new byte[0]; -+ return org.plazmamc.plazma.util.Constants.EMPTY_BYTE; ++ return org.plazmamc.plazma.EmptyConstants.BYTE; // Plazma } public int[] getIntArray(String key) { @@ -246,7 +323,7 @@ index 7e94ebe06fc62293e665d6db19e42d947e7eb30f..6f41b334efc4a540cd8efcc782f5d5c8 } - return new int[0]; -+ return org.plazmamc.plazma.util.Constants.EMPTY_INT; ++ return org.plazmamc.plazma.EmptyConstants.INT; // Plazma } public long[] getLongArray(String key) { @@ -255,12 +332,12 @@ index 7e94ebe06fc62293e665d6db19e42d947e7eb30f..6f41b334efc4a540cd8efcc782f5d5c8 } - return new long[0]; -+ return org.plazmamc.plazma.util.Constants.EMPTY_LONG; ++ return org.plazmamc.plazma.EmptyConstants.LONG; // Plazma } public CompoundTag getCompound(String key) { diff --git a/src/main/java/net/minecraft/nbt/IntArrayTag.java b/src/main/java/net/minecraft/nbt/IntArrayTag.java -index 25ad2c6ff968f4a6b16b4dea3f67341a4261f2a4..4dec198d867b9d95572e6a93b219f6c46357f3cf 100644 +index 25ad2c6ff968f4a6b16b4dea3f67341a4261f2a4..435bdec39b9f744eb8a7ad327c7facf40c08d612 100644 --- a/src/main/java/net/minecraft/nbt/IntArrayTag.java +++ b/src/main/java/net/minecraft/nbt/IntArrayTag.java @@ -189,7 +189,7 @@ public class IntArrayTag extends CollectionTag { @@ -268,12 +345,12 @@ index 25ad2c6ff968f4a6b16b4dea3f67341a4261f2a4..4dec198d867b9d95572e6a93b219f6c4 public void clear() { - this.data = new int[0]; -+ this.data = org.plazmamc.plazma.util.Constants.EMPTY_INT; ++ this.data = org.plazmamc.plazma.EmptyConstants.INT; // Plazma } @Override diff --git a/src/main/java/net/minecraft/nbt/ListTag.java b/src/main/java/net/minecraft/nbt/ListTag.java -index 749d3e67a877d7d1ed47b5fef511a604ee6589b6..0529814353ba82d6083a88531f06e73377ab5aaf 100644 +index b74b77ec2fd45c7a44e4f2696c4f57075c3d4080..f55dd4d1e094b0ccda307d83e9c3b5f180236547 100644 --- a/src/main/java/net/minecraft/nbt/ListTag.java +++ b/src/main/java/net/minecraft/nbt/ListTag.java @@ -230,7 +230,7 @@ public class ListTag extends CollectionTag { @@ -281,7 +358,7 @@ index 749d3e67a877d7d1ed47b5fef511a604ee6589b6..0529814353ba82d6083a88531f06e733 } - return new int[0]; -+ return org.plazmamc.plazma.util.Constants.EMPTY_INT; ++ return org.plazmamc.plazma.EmptyConstants.INT; // Plazma } public long[] getLongArray(int index) { @@ -290,12 +367,12 @@ index 749d3e67a877d7d1ed47b5fef511a604ee6589b6..0529814353ba82d6083a88531f06e733 } - return new long[0]; -+ return org.plazmamc.plazma.util.Constants.EMPTY_LONG; ++ return org.plazmamc.plazma.EmptyConstants.LONG; // Plazma } public double getDouble(int index) { diff --git a/src/main/java/net/minecraft/nbt/LongArrayTag.java b/src/main/java/net/minecraft/nbt/LongArrayTag.java -index bdc0adc652228328ebe8fe2455c73c257a89d3c5..122d4b9391ddaae2631db213230f57a829d1c943 100644 +index bdc0adc652228328ebe8fe2455c73c257a89d3c5..22f5b4ddde241436962aef4abe013541c7184493 100644 --- a/src/main/java/net/minecraft/nbt/LongArrayTag.java +++ b/src/main/java/net/minecraft/nbt/LongArrayTag.java @@ -193,7 +193,7 @@ public class LongArrayTag extends CollectionTag { @@ -303,12 +380,12 @@ index bdc0adc652228328ebe8fe2455c73c257a89d3c5..122d4b9391ddaae2631db213230f57a8 @Override public void clear() { - this.data = new long[0]; -+ this.data = org.plazmamc.plazma.util.Constants.EMPTY_LONG; ++ this.data = org.plazmamc.plazma.EmptyConstants.LONG; // Plazma } @Override diff --git a/src/main/java/net/minecraft/network/CipherBase.java b/src/main/java/net/minecraft/network/CipherBase.java -index a2920b8a9eff77d9c5d1d7f70ad3abdacba8f0fa..c1c97cc8fa5e0d8349655f90392382a0a878c95f 100644 +index a2920b8a9eff77d9c5d1d7f70ad3abdacba8f0fa..50d620fc893ca010b7ecb43b7a4617d67510d03f 100644 --- a/src/main/java/net/minecraft/network/CipherBase.java +++ b/src/main/java/net/minecraft/network/CipherBase.java @@ -7,8 +7,8 @@ import javax.crypto.ShortBufferException; @@ -317,26 +394,26 @@ index a2920b8a9eff77d9c5d1d7f70ad3abdacba8f0fa..c1c97cc8fa5e0d8349655f90392382a0 private final Cipher cipher; - private byte[] heapIn = new byte[0]; - private byte[] heapOut = new byte[0]; -+ private byte[] heapIn = org.plazmamc.plazma.util.Constants.EMPTY_BYTE; -+ private byte[] heapOut = org.plazmamc.plazma.util.Constants.EMPTY_BYTE; ++ private byte[] heapIn = org.plazmamc.plazma.EmptyConstants.BYTE; // Plazma ++ private byte[] heapOut = org.plazmamc.plazma.EmptyConstants.BYTE; // Plazma protected CipherBase(Cipher cipher) { this.cipher = cipher; diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java -index 323416311f14f5ad887f05183ad3b4921981aecd..7ef5055d7d6d7576cefdbc80ede4f4ce28e15c1b 100644 +index 89c1b69ddeb420c2fbda5f588e7c9a467a76089d..ef566dc65a979db5aa67a21fa760d046a7508ac1 100644 --- a/src/main/java/net/minecraft/network/Connection.java +++ b/src/main/java/net/minecraft/network/Connection.java -@@ -318,7 +318,7 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -325,7 +325,7 @@ public class Connection extends SimpleChannelInboundHandler> { } public void setListener(PacketListener listener) { - Validate.notNull(listener, "packetListener", new Object[0]); -+ Validate.notNull(listener, "packetListener", org.plazmamc.plazma.util.Constants.EMPTY_OBJECT); ++ Validate.notNull(listener, "packetListener", org.plazmamc.plazma.EmptyConstants.OBJECT); // Plazma this.packetListener = listener; } // Paper start diff --git a/src/main/java/net/minecraft/network/chat/contents/TranslatableContents.java b/src/main/java/net/minecraft/network/chat/contents/TranslatableContents.java -index 8a68baf6bd46b59cf57c94ffe5651d47a7cae99c..c732299c908622e3b6262cd942a7397b3f34b8e9 100644 +index 8a68baf6bd46b59cf57c94ffe5651d47a7cae99c..6a979d584b1f27d6838332318488814d3db89a47 100644 --- a/src/main/java/net/minecraft/network/chat/contents/TranslatableContents.java +++ b/src/main/java/net/minecraft/network/chat/contents/TranslatableContents.java @@ -21,7 +21,7 @@ import net.minecraft.network.chat.Style; @@ -344,42 +421,42 @@ index 8a68baf6bd46b59cf57c94ffe5651d47a7cae99c..c732299c908622e3b6262cd942a7397b public class TranslatableContents implements ComponentContents { - public static final Object[] NO_ARGS = new Object[0]; -+ public static final Object[] NO_ARGS = org.plazmamc.plazma.util.Constants.EMPTY_OBJECT; ++ public static final Object[] NO_ARGS = org.plazmamc.plazma.EmptyConstants.OBJECT; // Plazma private static final FormattedText TEXT_PERCENT = FormattedText.of("%"); private static final FormattedText TEXT_NULL = FormattedText.of("null"); private final String key; diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java -index 7c6a6693760638a07b7c7c330aaeffd9fa454845..d4a7157d2b2c5f25ed00b706d0adbf195e5e6977 100644 +index e3f355c85eb7cc8c1683e3009502c10a5ed32daa..50bc08280120ceaa321e30482358b3f4dbe8b3bd 100644 --- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java +++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java -@@ -67,7 +67,7 @@ public class ClientboundSectionBlocksUpdatePacket implements Packet blockChanges, boolean suppressLightUpdates) { +@@ -63,7 +63,7 @@ public class ClientboundSectionBlocksUpdatePacket implements Packet blockChanges) { this.sectionPos = sectionPos; this.positions = blockChanges.keySet().toShortArray(); - this.states = blockChanges.values().toArray(new BlockState[0]); -+ this.states = blockChanges.values().toArray(org.plazmamc.plazma.util.Constants.BLOCK_STATE); - this.suppressLightUpdates = suppressLightUpdates; ++ this.states = blockChanges.values().toArray(org.plazmamc.plazma.EmptyConstants.BLOCK_STATE); // Plazma } // Paper end + diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 3c80e14392ee7a6bf5040d7cb81b7d894e162eff..a358a821e2ed71fdb2e85c71b75fda00fdad7f9b 100644 +index 93ff3ef401d4212cede5290990528988c7ca3a0c..6e13d11d685930acad1c3a80571b73258a6f6f9d 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1373,10 +1373,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop loadStatusIcon() { Optional optional = Optional.of(this.getFile("server-icon.png").toPath()).filter((path) -> { - return Files.isRegularFile(path, new LinkOption[0]); -+ return Files.isRegularFile(path, org.plazmamc.plazma.util.Constants.LINK_OPTION); ++ return Files.isRegularFile(path, org.plazmamc.plazma.EmptyConstants.LINK_OPTION); // Plazma }).or(() -> { return this.storageSource.getIconFile().filter((path) -> { - return Files.isRegularFile(path, new LinkOption[0]); -+ return Files.isRegularFile(path, org.plazmamc.plazma.util.Constants.LINK_OPTION); ++ return Files.isRegularFile(path, org.plazmamc.plazma.EmptyConstants.LINK_OPTION); // Plazma }); }); diff --git a/src/main/java/net/minecraft/server/PlayerAdvancements.java b/src/main/java/net/minecraft/server/PlayerAdvancements.java -index 3919d9c193abcfd8b97dfb0ceb38638440f60fbe..31129b7a4e325649830089a5422e3ccf9b5875a5 100644 +index 69d349613f01ab0ac1890734657da52984704f29..1c5ba90fcd291b68fbdf9cecc5c3b1f39e266305 100644 --- a/src/main/java/net/minecraft/server/PlayerAdvancements.java +++ b/src/main/java/net/minecraft/server/PlayerAdvancements.java @@ -124,7 +124,7 @@ public class PlayerAdvancements { @@ -387,12 +464,12 @@ index 3919d9c193abcfd8b97dfb0ceb38638440f60fbe..31129b7a4e325649830089a5422e3ccf private void load(ServerAdvancementManager advancementLoader) { - if (Files.isRegularFile(this.playerSavePath, new LinkOption[0])) { -+ if (Files.isRegularFile(this.playerSavePath, org.plazmamc.plazma.util.Constants.LINK_OPTION)) { ++ if (Files.isRegularFile(this.playerSavePath, org.plazmamc.plazma.EmptyConstants.LINK_OPTION)) { // Plazma try { JsonReader jsonreader = new JsonReader(Files.newBufferedReader(this.playerSavePath, StandardCharsets.UTF_8)); diff --git a/src/main/java/net/minecraft/server/RunningOnDifferentThreadException.java b/src/main/java/net/minecraft/server/RunningOnDifferentThreadException.java -index 0f52e8a61ca7e57e9f52473dceb9cc3464c0c86d..857c3609b3cd965e1c10caa8fc5682baae999820 100644 +index 0f52e8a61ca7e57e9f52473dceb9cc3464c0c86d..9ee75ed89b2034d1654680f32ec05948c0bfac41 100644 --- a/src/main/java/net/minecraft/server/RunningOnDifferentThreadException.java +++ b/src/main/java/net/minecraft/server/RunningOnDifferentThreadException.java @@ -4,12 +4,12 @@ public final class RunningOnDifferentThreadException extends RuntimeException { @@ -400,18 +477,18 @@ index 0f52e8a61ca7e57e9f52473dceb9cc3464c0c86d..857c3609b3cd965e1c10caa8fc5682ba private RunningOnDifferentThreadException() { - this.setStackTrace(new StackTraceElement[0]); -+ this.setStackTrace(org.plazmamc.plazma.util.Constants.STACK_TRACE_ELEMENT); ++ this.setStackTrace(org.plazmamc.plazma.EmptyConstants.STACK_TRACE_ELEMENT); // Plazma } @Override public synchronized Throwable fillInStackTrace() { - this.setStackTrace(new StackTraceElement[0]); -+ this.setStackTrace(org.plazmamc.plazma.util.Constants.STACK_TRACE_ELEMENT); ++ this.setStackTrace(org.plazmamc.plazma.EmptyConstants.STACK_TRACE_ELEMENT); // Plazma return this; } } diff --git a/src/main/java/net/minecraft/server/ServerFunctionLibrary.java b/src/main/java/net/minecraft/server/ServerFunctionLibrary.java -index 975422a57b83a31e63a600bb4ff9c4e2baaf6da7..64d8935c18f3e92ec35b3b160443700e350a72fa 100644 +index 975422a57b83a31e63a600bb4ff9c4e2baaf6da7..b80dff95660314e4dd27e2ada94aa31598883b4e 100644 --- a/src/main/java/net/minecraft/server/ServerFunctionLibrary.java +++ b/src/main/java/net/minecraft/server/ServerFunctionLibrary.java @@ -81,7 +81,7 @@ public class ServerFunctionLibrary implements PreparableReloadListener { @@ -419,126 +496,134 @@ index 975422a57b83a31e63a600bb4ff9c4e2baaf6da7..64d8935c18f3e92ec35b3b160443700e } - CompletableFuture[] completableFutures = map.values().toArray(new CompletableFuture[0]); -+ CompletableFuture[] completableFutures = map.values().toArray(org.plazmamc.plazma.util.Constants.COMPLETABLE_FUTURE); ++ CompletableFuture[] completableFutures = map.values().toArray(org.plazmamc.plazma.EmptyConstants.COMPLETABLE_FUTURES); // Plazma return CompletableFuture.allOf(completableFutures).handle((unused, ex) -> { return map; }); diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 57fdef8b16e1ed9a4693356144b4685bbcea285c..d41086166c39fedf8da29ac9010c501ef5fe3131 100644 +index 319c469c20f3cb4f6d61425bfa6d98b55b55c4d6..d62adc228724ed5576619da70a41a6aaf9966308 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1550,7 +1550,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1451,6 +1451,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + private final int range; + SectionPos lastSectionPos; + public final Set seenBy = new ReferenceOpenHashSet<>(); // Paper - optimise map impl ++ private static final ServerPlayerConnection[] EMPTY_CONNECTION = new ServerPlayerConnection[0]; // Plazma + + public TrackedEntity(Entity entity, int i, int j, boolean flag) { + this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, j, flag, this::broadcast, this.seenBy); // CraftBukkit +@@ -1487,7 +1488,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider // stuff could have been removed, so we need to check the trackedPlayers set // for players that were removed - for (ServerPlayerConnection conn : this.seenBy.toArray(new ServerPlayerConnection[0])) { // avoid CME -+ for (ServerPlayerConnection conn : this.seenBy.toArray(org.plazmamc.plazma.util.Constants.SERVER_PLAYER_CONNECTION)) { // avoid CME ++ for (ServerPlayerConnection conn : this.seenBy.toArray(EMPTY_CONNECTION)) { // avoid CME // Plazma if (newTrackerCandidates == null || !newTrackerCandidates.contains(conn.getPlayer())) { this.updatePlayer(conn.getPlayer()); } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index ebbf462835e5a14fe1413c724d4985635207a897..c2030d2e936fc5582e3fd1c753e1d0a40b905bab 100644 +index e009dba395779e2c89a36fe4524e5d40474a29e6..c4cafcc1fb0f3b6bc17b7907ee7c6c034d4bf005 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1250,7 +1250,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1392,7 +1392,7 @@ public class ServerLevel extends Level implements WorldGenLevel { public static List getCurrentlyTickingEntities() { Entity ticking = currentlyTickingEntity.get(); - List ret = java.util.Arrays.asList(ticking == null ? new Entity[0] : new Entity[] { ticking }); -+ List ret = java.util.Arrays.asList(ticking == null ? org.plazmamc.plazma.util.Constants.ENTITY : new Entity[] { ticking }); ++ List ret = java.util.Arrays.asList(ticking == null ? org.plazmamc.plazma.EmptyConstants.ENTITY : new Entity[] { ticking }); // Plazma return ret; } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index b15de37a06c3efb1c4bc790ccb23ebff3c97d54d..d76bff083c0ecd49dfd82dd8ccffae86820308ce 100644 +index e4c92730b63204126609a52d286da46ef6495080..864783f856e5f7cfcbccb88a07f77a95c402e90d 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -434,7 +434,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -436,7 +436,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic if (this.keepAlivePending) { if (!this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // check keepalive limit, don't fire if already disconnected ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked due to keepalive timeout!", this.player.getScoreboardName()); // more info - this.disconnect(Component.translatable("disconnect.timeout", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT); // Paper - kick event cause -+ this.disconnect(Component.translatable("disconnect.timeout", org.plazmamc.plazma.util.Constants.EMPTY_OBJECT), org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT); // Paper - kick event cause ++ this.disconnect(Component.translatable("disconnect.timeout", org.plazmamc.plazma.EmptyConstants.OBJECT), org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT); // Paper - kick event cause // Plazma } } else { if (elapsedTime >= 15000L) { // 15 seconds -@@ -915,13 +915,13 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic - // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.getLevel()); // Paper - run this async +@@ -924,13 +924,13 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic + // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - run this async // CraftBukkit start if (this.chatSpamTickCount.addAndGet(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamIncrement) > io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamLimit && !this.server.getPlayerList().isOp(this.player.getGameProfile())) { // Paper start - split and make configurable - server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper - kick event cause -+ server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", org.plazmamc.plazma.util.Constants.EMPTY_OBJECT), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper - kick event cause ++ server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", org.plazmamc.plazma.EmptyConstants.OBJECT), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper - kick event cause // Plazma return; } // Paper start String str = packet.getCommand(); int index = -1; if (str.length() > 64 && ((index = str.indexOf(' ')) == -1 || index >= 64)) { -- server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper - kick event cause -+ server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", org.plazmamc.plazma.util.Constants.EMPTY_OBJECT), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper - kick event cause +- server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper ++ server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", org.plazmamc.plazma.EmptyConstants.OBJECT), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper // Plazma return; } // Paper end -@@ -3391,7 +3391,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic +@@ -3455,7 +3455,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic // Paper start if (!org.bukkit.Bukkit.isPrimaryThread()) { - if (recipeSpamPackets.addAndGet(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.recipeSpamIncrement) > io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.recipeSpamLimit) { -- server.scheduleOnMain(() -> this.disconnect(net.minecraft.network.chat.Component.translatable("disconnect.spam", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper - kick event cause -+ server.scheduleOnMain(() -> this.disconnect(net.minecraft.network.chat.Component.translatable("disconnect.spam", org.plazmamc.plazma.util.Constants.EMPTY_OBJECT), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper - kick event cause + if (this.recipeSpamPackets.addAndGet(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.recipeSpamIncrement) > io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.recipeSpamLimit) { +- this.server.scheduleOnMain(() -> this.disconnect(net.minecraft.network.chat.Component.translatable("disconnect.spam", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper - kick event cause ++ this.server.scheduleOnMain(() -> this.disconnect(net.minecraft.network.chat.Component.translatable("disconnect.spam", org.plazmamc.plazma.EmptyConstants.OBJECT), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper - kick event cause // Plazma return; } } diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index 06ff5dd9e39e2be8dd8397a764813111019ceaed..6a17b2b1d2fc75b87b2683ffe033fdc111e5750c 100644 +index 0f1ebdc20460da22c1ff2fee2ff6428654139969..85b8007f0da3b7d77d1caff64000e4fc174f73bf 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -@@ -238,8 +238,8 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, +@@ -239,8 +239,8 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, @Override public void handleHello(ServerboundHelloPacket packet) { - Validate.validState(this.state == ServerLoginPacketListenerImpl.State.HELLO, "Unexpected hello packet", new Object[0]); - if (!org.plazmamc.plazma.configurations.GlobalConfiguration.get().player.allowAnyUsername) Validate.validState(ServerLoginPacketListenerImpl.isValidUsername(packet.name()), "Invalid characters in username", new Object[0]); // Plazma -+ Validate.validState(this.state == ServerLoginPacketListenerImpl.State.HELLO, "Unexpected hello packet", org.plazmamc.plazma.util.Constants.EMPTY_OBJECT); -+ if (!org.plazmamc.plazma.configurations.GlobalConfiguration.get().player.allowAnyUsername) Validate.validState(ServerLoginPacketListenerImpl.isValidUsername(packet.name()), "Invalid characters in username", org.plazmamc.plazma.util.Constants.EMPTY_OBJECT); // Plazma ++ Validate.validState(this.state == ServerLoginPacketListenerImpl.State.HELLO, "Unexpected hello packet", org.plazmamc.plazma.EmptyConstants.OBJECT); // Plazma ++ if (!org.plazmamc.plazma.configurations.GlobalConfiguration.get().player.allowAnyUsername) Validate.validState(ServerLoginPacketListenerImpl.isValidUsername(packet.name()), "Invalid characters in username", org.plazmamc.plazma.EmptyConstants.OBJECT); // Plazma // Plazma - again // Paper start - validate usernames if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode() && io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.performUsernameValidation) { if (!this.iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation && !validateUsername(packet.name())) { -@@ -298,7 +298,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, +@@ -299,7 +299,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, @Override public void handleKey(ServerboundKeyPacket packet) { - Validate.validState(this.state == ServerLoginPacketListenerImpl.State.KEY, "Unexpected key packet", new Object[0]); -+ Validate.validState(this.state == ServerLoginPacketListenerImpl.State.KEY, "Unexpected key packet", org.plazmamc.plazma.util.Constants.EMPTY_OBJECT); ++ Validate.validState(this.state == ServerLoginPacketListenerImpl.State.KEY, "Unexpected key packet", org.plazmamc.plazma.EmptyConstants.OBJECT); // Plazma final String s; diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 022da50912d357581b2132cf57e1a767e436022c..555472cad13c6453090b6f15133bbf2b90014a74 100644 +index b711efca8a834adaf0db902fab34c3c80c9cbad6..4c793f4f7b79e35c4c42d330bb63d29c0ef32124 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -695,7 +695,7 @@ public abstract class PlayerList { +@@ -710,7 +710,7 @@ public abstract class PlayerList { while (iterator.hasNext()) { entityplayer = (ServerPlayer) iterator.next(); this.save(entityplayer); // CraftBukkit - Force the player's inventory to be saved - entityplayer.connection.disconnect(Component.translatable("multiplayer.disconnect.duplicate_login", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.DUPLICATE_LOGIN); // Paper - kick event cause -+ entityplayer.connection.disconnect(Component.translatable("multiplayer.disconnect.duplicate_login", org.plazmamc.plazma.util.Constants.EMPTY_OBJECT), org.bukkit.event.player.PlayerKickEvent.Cause.DUPLICATE_LOGIN); // Paper - kick event cause ++ entityplayer.connection.disconnect(Component.translatable("multiplayer.disconnect.duplicate_login", org.plazmamc.plazma.EmptyConstants.OBJECT), org.bukkit.event.player.PlayerKickEvent.Cause.DUPLICATE_LOGIN); // Paper - kick event cause // Plazma } // Instead of kicking then returning, we need to store the kick reason diff --git a/src/main/java/net/minecraft/server/players/StoredUserList.java b/src/main/java/net/minecraft/server/players/StoredUserList.java -index 4fd709a550bf8da1e996894a1ca6b91206c31e9e..d676116150e5a741b2050e26c76c19bccc8a95dc 100644 +index 9e8112fbc40a1d89c0f73ea4452e0fa1bb459bf4..5a9fc24037c92fb17ba4baec79e4f344e16a4128 100644 --- a/src/main/java/net/minecraft/server/players/StoredUserList.java +++ b/src/main/java/net/minecraft/server/players/StoredUserList.java -@@ -95,7 +95,7 @@ public abstract class StoredUserList> { +@@ -96,7 +96,7 @@ public abstract class StoredUserList> { } public String[] getUserList() { - return (String[]) this.map.keySet().toArray(new String[0]); -+ return (String[]) this.map.keySet().toArray(org.plazmamc.plazma.util.Constants.EMPTY_STRING); ++ return (String[]) this.map.keySet().toArray(org.plazmamc.plazma.EmptyConstants.STRING); // Plazma } - // CraftBukkit start + public boolean isEmpty() { diff --git a/src/main/java/net/minecraft/util/MemoryReserve.java b/src/main/java/net/minecraft/util/MemoryReserve.java -index 0ee04fe6ff6a4d09754f326526ae04fe7226bab2..0efc5682210e6cd3e0ee03a5e4340614869a8575 100644 +index 0ee04fe6ff6a4d09754f326526ae04fe7226bab2..79046f2d1803eb346d1f184004e6cb09d2a91a36 100644 --- a/src/main/java/net/minecraft/util/MemoryReserve.java +++ b/src/main/java/net/minecraft/util/MemoryReserve.java @@ -11,6 +11,6 @@ public class MemoryReserve { @@ -546,11 +631,11 @@ index 0ee04fe6ff6a4d09754f326526ae04fe7226bab2..0efc5682210e6cd3e0ee03a5e4340614 public static void release() { - reserve = new byte[0]; -+ reserve = org.plazmamc.plazma.util.Constants.EMPTY_BYTE; ++ reserve = org.plazmamc.plazma.EmptyConstants.BYTE; // Plazma } } diff --git a/src/main/java/net/minecraft/util/ZeroBitStorage.java b/src/main/java/net/minecraft/util/ZeroBitStorage.java -index 5d8e9bdf5538b19681f21949368d862fab8a89ad..2d5aa26dc700d08caa856b6b287b35ed8b99a390 100644 +index 311625277a26c9c187025a1036978229241b965f..04a1b316cd6d612a0948d845d7851d3622e4c2af 100644 --- a/src/main/java/net/minecraft/util/ZeroBitStorage.java +++ b/src/main/java/net/minecraft/util/ZeroBitStorage.java @@ -5,7 +5,7 @@ import java.util.function.IntConsumer; @@ -558,116 +643,118 @@ index 5d8e9bdf5538b19681f21949368d862fab8a89ad..2d5aa26dc700d08caa856b6b287b35ed public class ZeroBitStorage implements BitStorage { - public static final long[] RAW = new long[0]; -+ public static final long[] RAW = org.plazmamc.plazma.util.Constants.EMPTY_LONG; ++ //public static final long[] RAW = new long[0]; // Plazma private final int size; public ZeroBitStorage(int size) { -diff --git a/src/main/java/net/minecraft/util/datafix/fixes/LeavesFix.java b/src/main/java/net/minecraft/util/datafix/fixes/LeavesFix.java -index 89d70a992e0bcc8e7292c4f736470eafd8747b24..a3f071101fbd10272373f99ebd2c76c0805d0d25 100644 ---- a/src/main/java/net/minecraft/util/datafix/fixes/LeavesFix.java -+++ b/src/main/java/net/minecraft/util/datafix/fixes/LeavesFix.java -@@ -70,7 +70,7 @@ public class LeavesFix extends DataFix { - OpticFinder opticFinder3 = DSL.typeFinder(type3); - return this.fixTypeEverywhereTyped("Leaves fix", type, (typed) -> { - return typed.updateTyped(opticFinder, (typedx) -> { -- int[] is = new int[]{0}; -+ int[] is = org.plazmamc.plazma.util.Constants.ZERO_INT; - Typed typed2 = typedx.updateTyped(opticFinder2, (typed2x) -> { - Int2ObjectMap int2ObjectMap = new Int2ObjectOpenHashMap<>(typed2x.getAllTyped(opticFinder3).stream().map((typedx2) -> { - return new LeavesFix.LeavesSection(typedx2, this.getInputSchema()); +@@ -33,7 +33,7 @@ public class ZeroBitStorage implements BitStorage { + + @Override + public long[] getRaw() { +- return RAW; ++ return org.plazmamc.plazma.EmptyConstants.LONG; // Plazma + } + + @Override +diff --git a/src/main/java/net/minecraft/util/monitoring/jmx/MinecraftServerStatistics.java b/src/main/java/net/minecraft/util/monitoring/jmx/MinecraftServerStatistics.java +index 8d227c8a1e7e8fa21a8d673e8c9acc38104c6fb0..71dc96d2dacde1dc958f8547fc44df8c1a91853c 100644 +--- a/src/main/java/net/minecraft/util/monitoring/jmx/MinecraftServerStatistics.java ++++ b/src/main/java/net/minecraft/util/monitoring/jmx/MinecraftServerStatistics.java +@@ -35,12 +35,13 @@ public final class MinecraftServerStatistics implements DynamicMBean { + return entry.name; + }, Function.identity())); + ++ private static final MBeanNotificationInfo[] EMPTY_INFO = new MBeanNotificationInfo[0]; // Plazma + private MinecraftServerStatistics(MinecraftServer server) { + this.server = server; + MBeanAttributeInfo[] mBeanAttributeInfos = this.attributeDescriptionByName.values().stream().map(MinecraftServerStatistics.AttributeDescription::asMBeanAttributeInfo).toArray((i) -> { + return new MBeanAttributeInfo[i]; + }); +- this.mBeanInfo = new MBeanInfo(MinecraftServerStatistics.class.getSimpleName(), "metrics for dedicated server", mBeanAttributeInfos, (MBeanConstructorInfo[])null, (MBeanOperationInfo[])null, new MBeanNotificationInfo[0]); ++ this.mBeanInfo = new MBeanInfo(MinecraftServerStatistics.class.getSimpleName(), "metrics for dedicated server", mBeanAttributeInfos, (MBeanConstructorInfo[])null, (MBeanOperationInfo[])null, EMPTY_INFO); // Plazma + } + + public static void registerJmxMonitoring(MinecraftServer server) { 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 d47dc0c3fe8c2b80d7b7eb828a12af6eb32145e4..71d2649e4046323250a85f3b071e98f58a161302 100644 +index 6c04c8e7776b2830ac368229da834532e8ce163e..e0200f84270068612e67671cb027cc0c5145bdf9 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Bee.java +++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java -@@ -267,7 +267,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -251,7 +251,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { this.goalSelector.addGoal(8, new Bee.BeeWanderGoal()); this.goalSelector.addGoal(9, new FloatGoal(this)); this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - this.targetSelector.addGoal(1, (new Bee.BeeHurtByOtherGoal(this)).setAlertOthers(new Class[0])); -+ this.targetSelector.addGoal(1, (new Bee.BeeHurtByOtherGoal(this)).setAlertOthers(org.plazmamc.plazma.util.Constants.EMPTY_CLASS)); ++ this.targetSelector.addGoal(1, (new Bee.BeeHurtByOtherGoal(this)).setAlertOthers(org.plazmamc.plazma.EmptyConstants.CLASS)); // Plazma this.targetSelector.addGoal(2, new Bee.BeeBecomeAngryTargetGoal(this)); this.targetSelector.addGoal(3, new ResetUniversalAngerTargetGoal<>(this, true)); } 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 b5f445750a5ccbe7658396bdcc9648dc41f39ced..d8853726b9925c085e10d1e091cf275f708dd080 100644 +index 64aba511e615983988cdb6a0fd45b7d9d4f2f16d..bb6d976bfc942d42b0ebb672246b795c9f6fce98 100644 --- a/src/main/java/net/minecraft/world/entity/animal/IronGolem.java +++ b/src/main/java/net/minecraft/world/entity/animal/IronGolem.java -@@ -125,7 +125,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { +@@ -122,7 +122,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { this.goalSelector.addGoal(8, new RandomLookAroundGoal(this)); this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur this.targetSelector.addGoal(1, new DefendVillageTargetGoal(this)); - this.targetSelector.addGoal(2, new HurtByTargetGoal(this, new Class[0])); -+ this.targetSelector.addGoal(2, new HurtByTargetGoal(this, org.plazmamc.plazma.util.Constants.EMPTY_CLASS)); ++ this.targetSelector.addGoal(2, new HurtByTargetGoal(this, org.plazmamc.plazma.EmptyConstants.CLASS)); // Plazma this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, this::isAngryAt)); this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Mob.class, 5, false, false, (entityliving) -> { return entityliving instanceof Enemy && !(entityliving instanceof Creeper); 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 d1e45052fc96b6f81a331c6c73cb68ff96238359..2bd536243eca0c93c787260848d8b8862de3c996 100644 +index bd7c5f6768a54a3d8ffd585d91414e65936991da..82464cba4f582596252e2b18a09b860e9c3b330c 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Panda.java +++ b/src/main/java/net/minecraft/world/entity/animal/Panda.java -@@ -333,7 +333,7 @@ public class Panda extends Animal { +@@ -336,7 +336,7 @@ public class Panda extends Animal { this.goalSelector.addGoal(13, new FollowParentGoal(this, 1.25D)); this.goalSelector.addGoal(14, new WaterAvoidingRandomStrollGoal(this, 1.0D)); this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - this.targetSelector.addGoal(1, (new Panda.PandaHurtByTargetGoal(this, new Class[0])).setAlertOthers(new Class[0])); -+ this.targetSelector.addGoal(1, (new Panda.PandaHurtByTargetGoal(this, org.plazmamc.plazma.util.Constants.EMPTY_CLASS)).setAlertOthers(org.plazmamc.plazma.util.Constants.EMPTY_CLASS)); ++ this.targetSelector.addGoal(1, (new Panda.PandaHurtByTargetGoal(this, org.plazmamc.plazma.EmptyConstants.CLASS)).setAlertOthers(org.plazmamc.plazma.EmptyConstants.CLASS)); // Plazma } public static AttributeSupplier.Builder createAttributes() { 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 3395bc1d9140ab5496ad998343a963ae12f630d6..5933576c3f6cd8927fafa003fa30163137c25b20 100644 +index 81a33954aedffd18fcfa96babeaf6388715ab3f3..a85da190d9c51303296f4bbf16f26eb2e454e211 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Rabbit.java +++ b/src/main/java/net/minecraft/world/entity/animal/Rabbit.java -@@ -457,7 +457,7 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -460,7 +460,7 @@ public class Rabbit extends Animal implements VariantHolder { if (variant == Rabbit.Variant.EVIL) { this.getAttribute(Attributes.ARMOR).setBaseValue(8.0D); this.goalSelector.addGoal(4, new Rabbit.EvilRabbitAttackGoal(this)); - this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, new Class[0])).setAlertOthers()); -+ this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, org.plazmamc.plazma.util.Constants.EMPTY_CLASS)).setAlertOthers()); ++ this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, org.plazmamc.plazma.EmptyConstants.CLASS)).setAlertOthers()); // Plazma this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true)); this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Wolf.class, true)); if (!this.hasCustomName()) { 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 e0ca657b0aea52ab6a91c256c1bfad1e5028f6e0..92ff2445dafdc5423e9da5941aee2c9d196e8202 100644 +index 64bceae4d06b35fcbecb0daca2496ba30e39d995..805d2027fcb6c06537b3357fe104742a05391224 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Wolf.java +++ b/src/main/java/net/minecraft/world/entity/animal/Wolf.java -@@ -238,7 +238,7 @@ public class Wolf extends TamableAnimal implements NeutralMob { +@@ -239,7 +239,7 @@ public class Wolf extends TamableAnimal implements NeutralMob { this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur this.targetSelector.addGoal(1, new OwnerHurtByTargetGoal(this)); this.targetSelector.addGoal(2, new OwnerHurtTargetGoal(this)); - this.targetSelector.addGoal(3, (new HurtByTargetGoal(this, new Class[0])).setAlertOthers()); -+ this.targetSelector.addGoal(3, (new HurtByTargetGoal(this, org.plazmamc.plazma.util.Constants.EMPTY_CLASS)).setAlertOthers()); ++ this.targetSelector.addGoal(3, (new HurtByTargetGoal(this, org.plazmamc.plazma.EmptyConstants.CLASS)).setAlertOthers()); // Plazma this.targetSelector.addGoal(4, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, this::isAngryAt)); // this.targetSelector.addGoal(5, new NonTameRandomTargetGoal<>(this, Animal.class, false, Wolf.PREY_SELECTOR)); // Purpur - moved to updatePathfinders() this.targetSelector.addGoal(6, new NonTameRandomTargetGoal<>(this, Turtle.class, false, Turtle.BABY_ON_LAND_SELECTOR)); -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 86c9b549e3e75adf9bd5562c4c8d303cf2080e45..d686cee5601280c3970c7c4e9df2aa2a3bb32a6f 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 -@@ -86,7 +86,7 @@ public class Allay extends PathfinderMob implements InventoryCarrier { - private static final EntityDataAccessor DATA_DANCING = SynchedEntityData.defineId(Allay.class, EntityDataSerializers.BOOLEAN); - private static final EntityDataAccessor DATA_CAN_DUPLICATE = SynchedEntityData.defineId(Allay.class, EntityDataSerializers.BOOLEAN); - protected static final ImmutableList>> SENSOR_TYPES = ImmutableList.of(SensorType.NEAREST_LIVING_ENTITIES, SensorType.NEAREST_PLAYERS, SensorType.HURT_BY, SensorType.NEAREST_ITEMS); -- protected static final ImmutableList> MEMORY_TYPES = ImmutableList.of(MemoryModuleType.PATH, MemoryModuleType.LOOK_TARGET, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.WALK_TARGET, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.HURT_BY, MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM, MemoryModuleType.LIKED_PLAYER, MemoryModuleType.LIKED_NOTEBLOCK_POSITION, MemoryModuleType.LIKED_NOTEBLOCK_COOLDOWN_TICKS, MemoryModuleType.ITEM_PICKUP_COOLDOWN_TICKS, MemoryModuleType.IS_PANICKING, new MemoryModuleType[0]); -+ protected static final ImmutableList> MEMORY_TYPES = ImmutableList.of(MemoryModuleType.PATH, MemoryModuleType.LOOK_TARGET, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.WALK_TARGET, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.HURT_BY, MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM, MemoryModuleType.LIKED_PLAYER, MemoryModuleType.LIKED_NOTEBLOCK_POSITION, MemoryModuleType.LIKED_NOTEBLOCK_COOLDOWN_TICKS, MemoryModuleType.ITEM_PICKUP_COOLDOWN_TICKS, MemoryModuleType.IS_PANICKING, org.plazmamc.plazma.util.Constants.MEMORY_MODULE_TYPE); - public static final ImmutableList THROW_SOUND_PITCHES = ImmutableList.of(0.5625F, 0.625F, 0.75F, 0.9375F, 1.0F, 1.0F, 1.125F, 1.25F, 1.5F, 1.875F, 2.0F, 2.25F, new Float[]{2.5F, 3.0F, 3.75F, 4.0F}); - private final DynamicGameEventListener dynamicVibrationListener; - private final VibrationListener.VibrationListenerConfig vibrationListenerConfig; 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 4781bdd3b6c7d6b686f2fe6af530e82861385342..4bdf023ea780cfe6507d26a00332067194140de5 100644 +index 4952a7daa1aad68e3ba53123093cd879e0d544b5..597bebe5d5586d767332512fb1b2450acf6a95af 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 -@@ -265,7 +265,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -254,7 +254,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 8.0F)); this.goalSelector.addGoal(7, new RandomLookAroundGoal(this)); this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - this.targetSelector.addGoal(1, new HurtByTargetGoal(this, new Class[0])); -+ this.targetSelector.addGoal(1, new HurtByTargetGoal(this, org.plazmamc.plazma.util.Constants.EMPTY_CLASS)); ++ this.targetSelector.addGoal(1, new HurtByTargetGoal(this, org.plazmamc.plazma.EmptyConstants.CLASS)); // Plazma this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, LivingEntity.class, 0, false, false, WitherBoss.LIVING_ENTITY_SELECTOR)); } 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 9c8713ef3aeb2ff203bd0328d15d80c2d78d09e9..e6169c6d1608f7765f3383dd6c2c8b40c2b690da 100644 +index dd84433a988712da9d799cbda2487a902315fb92..42b13e2ebf21bfd4228483a7f349e874a9cac382 100644 --- a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java +++ b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java @@ -79,7 +79,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo @@ -675,51 +762,51 @@ index 9c8713ef3aeb2ff203bd0328d15d80c2d78d09e9..e6169c6d1608f7765f3383dd6c2c8b40 this.goalSelector.addGoal(6, new RandomLookAroundGoal(this)); this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - this.targetSelector.addGoal(1, new HurtByTargetGoal(this, new Class[0])); -+ this.targetSelector.addGoal(1, new HurtByTargetGoal(this, org.plazmamc.plazma.util.Constants.EMPTY_CLASS)); ++ this.targetSelector.addGoal(1, new HurtByTargetGoal(this, org.plazmamc.plazma.EmptyConstants.CLASS)); // Plazma this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true)); this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, IronGolem.class, true)); this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Turtle.class, 10, true, false, Turtle.BABY_ON_LAND_SELECTOR)); 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 c32eda28be3eb2c6a6933463d496ea7b6510f27e..75103823a200b242070d2634c2b2dbdc07aa53be 100644 +index 304ea7fdcd410a7c88ec61143364e14de8db0b0c..3eea42997caa1b66ac4d9d8da65e3bfe2f67cd0f 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java +++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java -@@ -184,7 +184,7 @@ public class Creeper extends Monster implements PowerableMob { +@@ -153,7 +153,7 @@ public class Creeper extends Monster implements PowerableMob { this.goalSelector.addGoal(6, new RandomLookAroundGoal(this)); this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Player.class, true)); - this.targetSelector.addGoal(2, new HurtByTargetGoal(this, new Class[0])); -+ this.targetSelector.addGoal(2, new HurtByTargetGoal(this, org.plazmamc.plazma.util.Constants.EMPTY_CLASS)); ++ this.targetSelector.addGoal(2, new HurtByTargetGoal(this, org.plazmamc.plazma.EmptyConstants.CLASS)); // Plazma } public static AttributeSupplier.Builder createAttributes() { 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 7c26e1979cdae52e2e94d24dd8c3164e815226ab..5faf3a1da09417236a65f13637d09de913207437 100644 +index 44331be61edffd5afadf3e637dd181bff1133d4f..ff6d4b73cd84c44908315080714d57fef1b5614c 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java +++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java -@@ -132,7 +132,7 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -136,7 +136,7 @@ public class EnderMan extends Monster implements NeutralMob { this.goalSelector.addGoal(11, new EnderMan.EndermanTakeBlockGoal(this)); this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur this.targetSelector.addGoal(1, new EnderMan.EndermanLookForPlayerGoal(this, this::isAngryAt)); - this.targetSelector.addGoal(2, new HurtByTargetGoal(this, new Class[0])); -+ this.targetSelector.addGoal(2, new HurtByTargetGoal(this, org.plazmamc.plazma.util.Constants.EMPTY_CLASS)); - this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Endermite.class, 10, true, false, (entityliving) -> entityliving.level.purpurConfig.endermanAggroEndermites && entityliving instanceof Endermite endermite && (!entityliving.level.purpurConfig.endermanAggroEndermitesOnlyIfPlayerSpawned || endermite.isPlayerSpawned()))); // Purpur ++ this.targetSelector.addGoal(2, new HurtByTargetGoal(this, org.plazmamc.plazma.EmptyConstants.CLASS)); // Plazma + this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Endermite.class, 10, true, false, (entityliving) -> entityliving.level().purpurConfig.endermanAggroEndermites && entityliving instanceof Endermite endermite && (!entityliving.level().purpurConfig.endermanAggroEndermitesOnlyIfPlayerSpawned || endermite.isPlayerSpawned()))); // Purpur this.targetSelector.addGoal(4, new ResetUniversalAngerTargetGoal<>(this, false)); } diff --git a/src/main/java/net/minecraft/world/entity/monster/Silverfish.java b/src/main/java/net/minecraft/world/entity/monster/Silverfish.java -index 202fe776c9275571138aabd230bec2fa0a985bb1..f95b46f6df814a9eb6b1d920ea9afa5782c2bfaf 100644 +index 83641c7cf51453e98809900e23f44a68018555ff..b03d42939d55607c74b747ce6704d2fbcf780834 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Silverfish.java +++ b/src/main/java/net/minecraft/world/entity/monster/Silverfish.java -@@ -84,7 +84,7 @@ public class Silverfish extends Monster { +@@ -87,7 +87,7 @@ public class Silverfish extends Monster { this.goalSelector.addGoal(4, new MeleeAttackGoal(this, 1.0D, false)); this.goalSelector.addGoal(5, new Silverfish.SilverfishMergeWithStoneGoal(this)); this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, new Class[0])).setAlertOthers()); -+ this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, org.plazmamc.plazma.util.Constants.EMPTY_CLASS)).setAlertOthers()); ++ this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, org.plazmamc.plazma.EmptyConstants.CLASS)).setAlertOthers()); // Plazma this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true)); } 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 8e071a0922164970e033029c12058db9e8da261a..0c7580f5f648713b781ff6288ec0000809c15dbf 100644 +index b3ab0f8cdbd678970e39e89c2062772374466b67..0e7a4ef59b01b5cc6ba89ff4f986604ba9aebe45 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Spider.java +++ b/src/main/java/net/minecraft/world/entity/monster/Spider.java @@ -93,7 +93,7 @@ public class Spider extends Monster { @@ -727,12 +814,12 @@ index 8e071a0922164970e033029c12058db9e8da261a..0c7580f5f648713b781ff6288ec00008 this.goalSelector.addGoal(6, new RandomLookAroundGoal(this)); this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - this.targetSelector.addGoal(1, new HurtByTargetGoal(this, new Class[0])); -+ this.targetSelector.addGoal(1, new HurtByTargetGoal(this, org.plazmamc.plazma.util.Constants.EMPTY_CLASS)); ++ this.targetSelector.addGoal(1, new HurtByTargetGoal(this, org.plazmamc.plazma.EmptyConstants.CLASS)); // Plazma this.targetSelector.addGoal(2, new Spider.SpiderTargetGoal<>(this, Player.class)); this.targetSelector.addGoal(3, new Spider.SpiderTargetGoal<>(this, IronGolem.class)); } 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 36d37e544e342e1bc584374580dbb5c883523204..11a4a8462723b82367afdfd5776286a0896375d1 100644 +index 7c5efb5582f43d9f333f926ad7dba1ed9920333a..3780f752ec2df3a43746dd3f0107ab37cbd226de 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java @@ -165,7 +165,7 @@ public class Zombie extends Monster { @@ -740,12 +827,12 @@ index 36d37e544e342e1bc584374580dbb5c883523204..11a4a8462723b82367afdfd5776286a0 this.goalSelector.addGoal(6, new MoveThroughVillageGoal(this, 1.0D, true, 4, this::canBreakDoors)); 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(1, (new HurtByTargetGoal(this, org.plazmamc.plazma.util.Constants.EMPTY_CLASS)).setAlertOthers(ZombifiedPiglin.class)); ++ this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, org.plazmamc.plazma.EmptyConstants.CLASS)).setAlertOthers(ZombifiedPiglin.class)); // Plazma this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true)); // Purpur start - if ( level.spigotConfig.zombieAggressiveTowardsVillager ) this.targetSelector.addGoal(3, new NearestAttackableTargetGoal(this, AbstractVillager.class, false) { // Spigot + if ( this.level().spigotConfig.zombieAggressiveTowardsVillager ) this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false) { // Spigot 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 d3bcfa017967db0a20c18c65e27c2a0471d2214e..9da90fd6c828fe5fe3a153cd1fda93ce6e54e482 100644 +index 7bb99d7fd8e05805e0cac7bec0b2771990057f58..393de8e7abc323f922bfc968fe3fe7a991a2ecd4 100644 --- a/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java +++ b/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java @@ -124,7 +124,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { @@ -753,108 +840,86 @@ index d3bcfa017967db0a20c18c65e27c2a0471d2214e..9da90fd6c828fe5fe3a153cd1fda93ce this.goalSelector.addGoal(2, new ZombieAttackGoal(this, 1.0D, false)); this.goalSelector.addGoal(7, new WaterAvoidingRandomStrollGoal(this, 1.0D)); - this.targetSelector.addGoal(1, pathfinderGoalHurtByTarget = (new HurtByTargetGoal(this, new Class[0])).setAlertOthers()); // Paper - assign field -+ this.targetSelector.addGoal(1, pathfinderGoalHurtByTarget = (new HurtByTargetGoal(this, org.plazmamc.plazma.util.Constants.EMPTY_CLASS)).setAlertOthers()); // Paper - assign field ++ this.targetSelector.addGoal(1, pathfinderGoalHurtByTarget = (new HurtByTargetGoal(this, org.plazmamc.plazma.EmptyConstants.CLASS)).setAlertOthers()); // Paper - assign field // Plazma this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, this::isAngryAt)); this.targetSelector.addGoal(3, new ResetUniversalAngerTargetGoal<>(this, true)); } diff --git a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java -index 117a376f99b1d26c5ffa64c8551ac1e666b15888..62edc084153bdf0c7e4d43a9ab2bb8069a8a60e9 100644 +index 6693dd51440da3f0fc338c4e2cb67d3222eed182..a7849d3d669929ea9a25d688ea6247a6299b0bdf 100644 --- a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java +++ b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java -@@ -262,7 +262,7 @@ public class ShapedRecipe implements CraftingRecipe { +@@ -263,7 +263,7 @@ public class ShapedRecipe extends io.papermc.paper.inventory.recipe.RecipeBookEx } if (pattern.length == l) { - return new String[0]; -+ return org.plazmamc.plazma.util.Constants.EMPTY_STRING; ++ return org.plazmamc.plazma.EmptyConstants.STRING; // Plazma } else { String[] astring1 = new String[pattern.length - l - k]; diff --git a/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java b/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java -index 8da06f8bea0239c5206d5d4f4ff48bdeb0a89f9d..0f612bb7ed955ee966ec9f779a075bdc8d5fcbc8 100644 +index 565318c2afaa1661ed9963453a6354dff499f47a..abd5df5a47d6cc5de0018ad7207232be5bd01d53 100644 --- a/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java +++ b/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java -@@ -89,7 +89,7 @@ public class ShapelessRecipe implements CraftingRecipe { +@@ -87,10 +87,11 @@ public class ShapelessRecipe extends io.papermc.paper.inventory.recipe.RecipeBoo + return this.ingredients; + } + ++ private static final Ingredient[] EMPTY_INGREDIENT = new Ingredient[0]; // Plazma public boolean matches(CraftingContainer inventory, Level world) { // Pufferfish start if (!this.isBukkit) { - java.util.List ingredients = com.google.common.collect.Lists.newArrayList(this.ingredients.toArray(new Ingredient[0])); -+ java.util.List ingredients = com.google.common.collect.Lists.newArrayList(this.ingredients.toArray(org.plazmamc.plazma.util.Constants.INGREDIENT)); ++ java.util.List ingredients = com.google.common.collect.Lists.newArrayList(this.ingredients.toArray(EMPTY_INGREDIENT)); // Plazma inventory: for (int index = 0; index < inventory.getContainerSize(); index++) { ItemStack itemStack = inventory.getItem(index); -diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index cf0ad841267cac84ed058dee6cdd62a835325feb..24756bb1913eb1f00dc367dd9c9741a3805ef3b4 100644 ---- a/src/main/java/net/minecraft/world/level/Level.java -+++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -1654,7 +1654,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - public org.bukkit.entity.Entity[] getChunkEntities(int chunkX, int chunkZ) { - io.papermc.paper.world.ChunkEntitySlices slices = ((ServerLevel)this).getEntityLookup().getChunk(chunkX, chunkZ); - if (slices == null) { -- return new org.bukkit.entity.Entity[0]; -+ return org.plazmamc.plazma.util.Constants.BUKKIT_ENTITY; - } - return slices.getChunkEntities(); - } diff --git a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java -index 4f7b21caa123ea7896788fd25133d8de3ab1ccaf..3683eb2d249fecdd0df781e4cdfd2df5d09843b0 100644 +index 596b77306f690a2298835f0f0fea1abee2a7c85d..e781b38bd0925f0250a93222c729a1754ee780bc 100644 --- a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java -@@ -442,7 +442,7 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { +@@ -443,7 +443,7 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { @Override public int[] getSlotsForFace(Direction side) { - return side == Direction.DOWN ? new int[]{0} : new int[0]; -+ return side == Direction.DOWN ? org.plazmamc.plazma.util.Constants.ZERO_INT : org.plazmamc.plazma.util.Constants.EMPTY_INT; ++ return side == Direction.DOWN ? org.plazmamc.plazma.EmptyConstants.ZERO_INT : org.plazmamc.plazma.EmptyConstants.INT; // Plazma } @Override -@@ -491,7 +491,7 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { +@@ -492,7 +492,7 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { @Override public int[] getSlotsForFace(Direction side) { - return side == Direction.UP ? new int[]{0} : new int[0]; -+ return side == Direction.UP ? org.plazmamc.plazma.util.Constants.ZERO_INT : org.plazmamc.plazma.util.Constants.EMPTY_INT; ++ return side == Direction.UP ? org.plazmamc.plazma.EmptyConstants.ZERO_INT : org.plazmamc.plazma.EmptyConstants.INT; // Plazma } @Override -@@ -533,7 +533,7 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { +@@ -534,7 +534,7 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { @Override public int[] getSlotsForFace(Direction side) { - return new int[0]; -+ return org.plazmamc.plazma.util.Constants.EMPTY_INT; ++ return org.plazmamc.plazma.EmptyConstants.INT; // Plazma } @Override -diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index 5cd7b4e7065070bf9fcc34b621dba2ccba99a573..082129fc5febd78063f1b6de5f13671b429d5865 100644 ---- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -+++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -@@ -66,7 +66,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit - protected static final int SLOT_FUEL = 1; - protected static final int SLOT_RESULT = 2; - public static final int DATA_LIT_TIME = 0; -- private static final int[] SLOTS_FOR_UP = new int[]{0}; -+ private static final int[] SLOTS_FOR_UP = org.plazmamc.plazma.util.Constants.ZERO_INT; - private static final int[] SLOTS_FOR_DOWN = new int[]{2, 1}; - private static final int[] SLOTS_FOR_SIDES = new int[]{1}; - public static final int DATA_LIT_DURATION = 1; -diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkStatus.java b/src/main/java/net/minecraft/world/level/chunk/ChunkStatus.java -index 71df7c590e31932f2b8fc26a2afaaa54f52674ac..071847225a94697a26eacb34f22aac0dca436af9 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/ChunkStatus.java -+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkStatus.java -@@ -195,7 +195,7 @@ public class ChunkStatus { - }, (chunkstatus, worldserver, structuretemplatemanager, lightenginethreaded, function, ichunkaccess) -> { - return (CompletableFuture) function.apply(ichunkaccess); - }); -- private static final List STATUS_BY_RANGE = ImmutableList.of(ChunkStatus.FULL, ChunkStatus.FEATURES, ChunkStatus.LIQUID_CARVERS, ChunkStatus.BIOMES, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, new ChunkStatus[0]); -+ private static final List STATUS_BY_RANGE = ImmutableList.of(ChunkStatus.FULL, ChunkStatus.FEATURES, ChunkStatus.LIQUID_CARVERS, ChunkStatus.BIOMES, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, org.plazmamc.plazma.util.Constants.CHUNK_STATUS); - private static final IntList RANGE_BY_STATUS = (IntList) Util.make(new IntArrayList(ChunkStatus.getStatusList().size()), (intarraylist) -> { - int i = 0; +diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java +index f03608a133338b0f5522a07239e06fd2245db1e5..31f2f322e7018a264719cc916f70fc8c28e91811 100644 +--- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java ++++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java +@@ -758,7 +758,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen + // Paper start - optimize hopper item suck in + static final AABB HOPPER_ITEM_SUCK_OVERALL = Hopper.SUCK.bounds(); +- static final AABB[] HOPPER_ITEM_SUCK_INDIVIDUAL = Hopper.SUCK.toAabbs().toArray(new AABB[0]); ++ static final AABB[] HOPPER_ITEM_SUCK_INDIVIDUAL = Hopper.SUCK.toAabbs().toArray(new AABB[0]); // Plazma + // Paper end - optimize hopper item suck in + + public static List getItemsAtAndAbove(Level world, Hopper hopper) { diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java -index dcfe090c269d4cbcc2eb1b6f85392848bb34656c..d1b3863df59115899494b9d662ba6beba2f15353 100644 +index 0c5ac12b1f395bba8b7fc50baf8e825ba6488f6c..ea60ec1bfb4f709921b9328d2f4fa21bec1723b3 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java @@ -445,7 +445,7 @@ public class RegionFile implements AutoCloseable { @@ -862,7 +927,7 @@ index dcfe090c269d4cbcc2eb1b6f85392848bb34656c..d1b3863df59115899494b9d662ba6beb this.usedSectors = new RegionBitmap(); this.version = outputChunkStreamVersion; - if (!Files.isDirectory(directory, new LinkOption[0])) { -+ if (!Files.isDirectory(directory, org.plazmamc.plazma.util.Constants.LINK_OPTION)) { ++ if (!Files.isDirectory(directory, org.plazmamc.plazma.EmptyConstants.LINK_OPTION)) { // Plazma throw new IllegalArgumentException("Expected directory, got " + directory.toAbsolutePath()); } else { this.externalFileDir = directory; @@ -871,7 +936,7 @@ index dcfe090c269d4cbcc2eb1b6f85392848bb34656c..d1b3863df59115899494b9d662ba6beb Path path = this.getExternalChunkPath(pos); - if (!Files.isRegularFile(path, new LinkOption[0])) { -+ if (!Files.isRegularFile(path, org.plazmamc.plazma.util.Constants.LINK_OPTION)) { ++ if (!Files.isRegularFile(path, org.plazmamc.plazma.EmptyConstants.LINK_OPTION)) { // Plazma RegionFile.LOGGER.error("External chunk path {} is not file", path); return null; } else { @@ -880,12 +945,12 @@ index dcfe090c269d4cbcc2eb1b6f85392848bb34656c..d1b3863df59115899494b9d662ba6beb } - if (!Files.isRegularFile(this.getExternalChunkPath(pos), new LinkOption[0])) { -+ if (!Files.isRegularFile(this.getExternalChunkPath(pos), org.plazmamc.plazma.util.Constants.LINK_OPTION)) { ++ if (!Files.isRegularFile(this.getExternalChunkPath(pos), org.plazmamc.plazma.EmptyConstants.LINK_OPTION)) { // Plazma return false; } } else { diff --git a/src/main/java/net/minecraft/world/level/levelgen/DebugLevelSource.java b/src/main/java/net/minecraft/world/level/levelgen/DebugLevelSource.java -index c68736b023127c7b395835f4fa82d9062110697b..bd88f27db229d1e34b69bcd9e975bec502d8226b 100644 +index c68736b023127c7b395835f4fa82d9062110697b..bee65f019e35dd44e6754755c99ff113849176da 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/DebugLevelSource.java +++ b/src/main/java/net/minecraft/world/level/levelgen/DebugLevelSource.java @@ -88,7 +88,7 @@ public class DebugLevelSource extends ChunkGenerator { @@ -893,91 +958,106 @@ index c68736b023127c7b395835f4fa82d9062110697b..bd88f27db229d1e34b69bcd9e975bec5 @Override public NoiseColumn getBaseColumn(int x, int z, LevelHeightAccessor world, RandomState noiseConfig) { - return new NoiseColumn(0, new BlockState[0]); -+ return new NoiseColumn(0, org.plazmamc.plazma.util.Constants.BLOCK_STATE); ++ return new NoiseColumn(0, org.plazmamc.plazma.EmptyConstants.BLOCK_STATE); // Plazma } @Override diff --git a/src/main/java/net/minecraft/world/level/pathfinder/Path.java b/src/main/java/net/minecraft/world/level/pathfinder/Path.java -index 2a335f277bd0e4b8ad0f60d8226eb8aaa80a871f..c5597c9b902857ed83b54fd74fcd9463749e3dbc 100644 +index 2a335f277bd0e4b8ad0f60d8226eb8aaa80a871f..c4395df154e8c7066d213316f300d62db9231e5c 100644 --- a/src/main/java/net/minecraft/world/level/pathfinder/Path.java +++ b/src/main/java/net/minecraft/world/level/pathfinder/Path.java -@@ -13,8 +13,8 @@ import net.minecraft.world.phys.Vec3; +@@ -13,8 +13,11 @@ import net.minecraft.world.phys.Vec3; public class Path { public final List nodes; - private Node[] openSet = new Node[0]; - private Node[] closedSet = new Node[0]; -+ private Node[] openSet = org.plazmamc.plazma.util.Constants.EMPTY_NODE; -+ private Node[] closedSet = org.plazmamc.plazma.util.Constants.EMPTY_NODE; ++ // Plazma start ++ private static final Node[] EMPTY_NODE = new Node[0]; ++ private Node[] openSet = EMPTY_NODE; ++ private Node[] closedSet = EMPTY_NODE; ++ // Plazma end @Nullable private Set targetNodes; private int nextNodeIndex; diff --git a/src/main/java/net/minecraft/world/level/storage/LevelStorageSource.java b/src/main/java/net/minecraft/world/level/storage/LevelStorageSource.java -index f212a78d9d32e9b59f16f03e07d2dd4789ad8080..cd894e9ba08efed114efd76126a888cf3c4f9327 100644 +index ef8b794d1a017f02f90368a48cec2ea7bb57f218..52bf65c0ec0651a24fc3ee187d99451ef640f996 100644 --- a/src/main/java/net/minecraft/world/level/storage/LevelStorageSource.java +++ b/src/main/java/net/minecraft/world/level/storage/LevelStorageSource.java -@@ -125,14 +125,14 @@ public class LevelStorageSource { +@@ -101,7 +101,7 @@ public class LevelStorageSource { + } + + public static DirectoryValidator parseValidator(Path allowedSymlinksFile) { +- if (Files.exists(allowedSymlinksFile, new LinkOption[0])) { ++ if (Files.exists(allowedSymlinksFile, org.plazmamc.plazma.EmptyConstants.LINK_OPTION)) { // Plazma + try { + BufferedReader bufferedreader = Files.newBufferedReader(allowedSymlinksFile); + +@@ -171,7 +171,7 @@ public class LevelStorageSource { } public LevelStorageSource.LevelCandidates findLevelCandidates() throws LevelStorageException { - if (!Files.isDirectory(this.baseDir, new LinkOption[0])) { -+ if (!Files.isDirectory(this.baseDir, org.plazmamc.plazma.util.Constants.LINK_OPTION)) { ++ if (!Files.isDirectory(this.baseDir, org.plazmamc.plazma.EmptyConstants.LINK_OPTION)) { // Plazma throw new LevelStorageException(Component.translatable("selectWorld.load_folder_access")); } else { try { - List list = Files.list(this.baseDir).filter((path) -> { -- return Files.isDirectory(path, new LinkOption[0]); -+ return Files.isDirectory(path, org.plazmamc.plazma.util.Constants.LINK_OPTION); - }).map(LevelStorageSource.LevelDirectory::new).filter((convertable_b) -> { -- return Files.isRegularFile(convertable_b.dataFile(), new LinkOption[0]) || Files.isRegularFile(convertable_b.oldDataFile(), new LinkOption[0]); -+ return Files.isRegularFile(convertable_b.dataFile(), org.plazmamc.plazma.util.Constants.LINK_OPTION) || Files.isRegularFile(convertable_b.oldDataFile(), org.plazmamc.plazma.util.Constants.LINK_OPTION); - }).toList(); +@@ -181,9 +181,9 @@ public class LevelStorageSource { - return new LevelStorageSource.LevelCandidates(list); -@@ -187,12 +187,12 @@ public class LevelStorageSource { + try { + List list = stream.filter((path) -> { +- return Files.isDirectory(path, new LinkOption[0]); ++ return Files.isDirectory(path, org.plazmamc.plazma.EmptyConstants.LINK_OPTION); // Plazma + }).map(LevelStorageSource.LevelDirectory::new).filter((convertable_b) -> { +- return Files.isRegularFile(convertable_b.dataFile(), new LinkOption[0]) || Files.isRegularFile(convertable_b.oldDataFile(), new LinkOption[0]); ++ return Files.isRegularFile(convertable_b.dataFile(), org.plazmamc.plazma.EmptyConstants.LINK_OPTION) || Files.isRegularFile(convertable_b.oldDataFile(), org.plazmamc.plazma.EmptyConstants.LINK_OPTION); // Plazma + }).toList(); + + convertable_a = new LevelStorageSource.LevelCandidates(list); +@@ -255,12 +255,12 @@ public class LevelStorageSource { @Nullable T readLevelData(LevelStorageSource.LevelDirectory levelSave, BiFunction levelDataParser) { - if (!Files.exists(levelSave.path(), new LinkOption[0])) { -+ if (!Files.exists(levelSave.path(), org.plazmamc.plazma.util.Constants.LINK_OPTION)) { ++ if (!Files.exists(levelSave.path(), org.plazmamc.plazma.EmptyConstants.LINK_OPTION)) { // Plazma return null; } else { Path path = levelSave.dataFile(); - if (Files.exists(path, new LinkOption[0])) { -+ if (Files.exists(path, org.plazmamc.plazma.util.Constants.LINK_OPTION)) { ++ if (Files.exists(path, org.plazmamc.plazma.EmptyConstants.LINK_OPTION)) { // Plazma T t0 = levelDataParser.apply(path, this.fixerUpper); if (t0 != null) { -@@ -201,7 +201,7 @@ public class LevelStorageSource { +@@ -269,7 +269,7 @@ public class LevelStorageSource { } path = levelSave.oldDataFile(); - return Files.exists(path, new LinkOption[0]) ? levelDataParser.apply(path, this.fixerUpper) : null; -+ return Files.exists(path, org.plazmamc.plazma.util.Constants.LINK_OPTION) ? levelDataParser.apply(path, this.fixerUpper) : null; ++ return Files.exists(path, org.plazmamc.plazma.EmptyConstants.LINK_OPTION) ? levelDataParser.apply(path, this.fixerUpper) : null; // Plazma } } -@@ -322,7 +322,7 @@ public class LevelStorageSource { +@@ -400,7 +400,7 @@ public class LevelStorageSource { } public boolean levelExists(String name) { -- return Files.isDirectory(this.baseDir.resolve(name), new LinkOption[0]); -+ return Files.isDirectory(this.baseDir.resolve(name), org.plazmamc.plazma.util.Constants.LINK_OPTION); +- return Files.isDirectory(this.getLevelPath(name), new LinkOption[0]); ++ return Files.isDirectory(this.getLevelPath(name), org.plazmamc.plazma.EmptyConstants.LINK_OPTION); // Plazma } - public Path getBaseDir() { -@@ -546,7 +546,7 @@ public class LevelStorageSource { + private Path getLevelPath(String name) { +@@ -645,7 +645,7 @@ public class LevelStorageSource { this.checkLock(); Path path = this.levelDirectory.dataFile(); - if (Files.exists(path, new LinkOption[0])) { -+ if (Files.exists(path, org.plazmamc.plazma.util.Constants.LINK_OPTION)) { ++ if (Files.exists(path, org.plazmamc.plazma.EmptyConstants.LINK_OPTION)) { // Plazma CompoundTag nbttagcompound = NbtIo.readCompressed(path.toFile()); CompoundTag nbttagcompound1 = nbttagcompound.getCompound("Data"); diff --git a/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java b/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java -index 039c952f0c157cba6e79fa9b976958bd1763a922..e9db2ee5819f6b81973472ea74bc0708612e30be 100644 +index 039c952f0c157cba6e79fa9b976958bd1763a922..1899e5a1421ef98cc27199490e3c946e03c75f9f 100644 --- a/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java +++ b/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java @@ -120,7 +120,7 @@ public class PlayerDataStorage { @@ -985,12 +1065,12 @@ index 039c952f0c157cba6e79fa9b976958bd1763a922..e9db2ee5819f6b81973472ea74bc0708 if (astring == null) { - astring = new String[0]; -+ astring = org.plazmamc.plazma.util.Constants.EMPTY_STRING; ++ astring = org.plazmamc.plazma.EmptyConstants.STRING; // Plazma } for (int i = 0; i < astring.length; ++i) { diff --git a/src/main/java/net/minecraft/world/level/storage/loot/LootPool.java b/src/main/java/net/minecraft/world/level/storage/loot/LootPool.java -index fad524f8b032174cee0c68da7c68e020ee3cd619..92fe0ca7c16134701f72ea263d9aa933185978d3 100644 +index fad524f8b032174cee0c68da7c68e020ee3cd619..6175eee025d98f4a7ab78042afef32fb45586045 100644 --- a/src/main/java/net/minecraft/world/level/storage/loot/LootPool.java +++ b/src/main/java/net/minecraft/world/level/storage/loot/LootPool.java @@ -160,7 +160,7 @@ public class LootPool { @@ -998,61 +1078,111 @@ index fad524f8b032174cee0c68da7c68e020ee3cd619..92fe0ca7c16134701f72ea263d9aa933 throw new IllegalArgumentException("Rolls not set"); } else { - return new LootPool(this.entries.toArray(new LootPoolEntryContainer[0]), this.conditions.toArray(new LootItemCondition[0]), this.functions.toArray(new LootItemFunction[0]), this.rolls, this.bonusRolls); -+ return new LootPool(this.entries.toArray(new LootPoolEntryContainer[0]), this.conditions.toArray(new LootItemCondition[0]), this.functions.toArray(org.plazmamc.plazma.util.Constants.LOOT_ITEM_FUNCTION), this.rolls, this.bonusRolls); ++ return new LootPool(this.entries.toArray(org.plazmamc.plazma.EmptyConstants.LOOT_POOL_ENTRY_CONTAINERS), this.conditions.toArray(org.plazmamc.plazma.EmptyConstants.LOOT_ITEM_CONDITIONS), this.functions.toArray(org.plazmamc.plazma.EmptyConstants.LOOT_ITEM_FUNCTION), this.rolls, this.bonusRolls); // Plazma } } } -@@ -171,7 +171,7 @@ public class LootPool { +@@ -170,8 +170,8 @@ public class LootPool { + public LootPool deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { JsonObject jsonObject = GsonHelper.convertToJsonObject(jsonElement, "loot pool"); LootPoolEntryContainer[] lootPoolEntryContainers = GsonHelper.getAsObject(jsonObject, "entries", jsonDeserializationContext, LootPoolEntryContainer[].class); - LootItemCondition[] lootItemConditions = GsonHelper.getAsObject(jsonObject, "conditions", new LootItemCondition[0], jsonDeserializationContext, LootItemCondition[].class); +- LootItemCondition[] lootItemConditions = GsonHelper.getAsObject(jsonObject, "conditions", new LootItemCondition[0], jsonDeserializationContext, LootItemCondition[].class); - LootItemFunction[] lootItemFunctions = GsonHelper.getAsObject(jsonObject, "functions", new LootItemFunction[0], jsonDeserializationContext, LootItemFunction[].class); -+ LootItemFunction[] lootItemFunctions = GsonHelper.getAsObject(jsonObject, "functions", org.plazmamc.plazma.util.Constants.LOOT_ITEM_FUNCTION, jsonDeserializationContext, LootItemFunction[].class); ++ LootItemCondition[] lootItemConditions = GsonHelper.getAsObject(jsonObject, "conditions", org.plazmamc.plazma.EmptyConstants.LOOT_ITEM_CONDITIONS, jsonDeserializationContext, LootItemCondition[].class); // Plazma ++ LootItemFunction[] lootItemFunctions = GsonHelper.getAsObject(jsonObject, "functions", org.plazmamc.plazma.EmptyConstants.LOOT_ITEM_FUNCTION, jsonDeserializationContext, LootItemFunction[].class); // Plazma NumberProvider numberProvider = GsonHelper.getAsObject(jsonObject, "rolls", jsonDeserializationContext, NumberProvider.class); NumberProvider numberProvider2 = GsonHelper.getAsObject(jsonObject, "bonus_rolls", ConstantValue.exactly(0.0F), jsonDeserializationContext, NumberProvider.class); return new LootPool(lootPoolEntryContainers, lootItemConditions, lootItemFunctions, numberProvider, numberProvider2); diff --git a/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java b/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java -index 3bc13092873609af9c6f412190dd989d39f1df23..10654d926a60510e7449903e3ab864bc1e289b4c 100644 +index e46a0afa45ee771a0114703acc314d7cf8e8ffed..687a7de03846bceeee4e1db2459d6c9cafb5f3b6 100644 --- a/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java +++ b/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java -@@ -42,7 +42,7 @@ import org.bukkit.event.world.LootGenerateEvent; +@@ -44,7 +44,7 @@ import org.bukkit.event.world.LootGenerateEvent; public class LootTable { static final Logger LOGGER = LogUtils.getLogger(); -- public static final LootTable EMPTY = new LootTable(LootContextParamSets.EMPTY, new LootPool[0], new LootItemFunction[0]); -+ public static final LootTable EMPTY = new LootTable(LootContextParamSets.EMPTY, org.plazmamc.plazma.util.Constants.LOOT_POOL, org.plazmamc.plazma.util.Constants.LOOT_ITEM_FUNCTION); +- public static final LootTable EMPTY = new LootTable(LootContextParamSets.EMPTY, (ResourceLocation) null, new LootPool[0], new LootItemFunction[0]); ++ public static final LootTable EMPTY = new LootTable(LootContextParamSets.EMPTY, (ResourceLocation) null, org.plazmamc.plazma.EmptyConstants.LOOT_POOL, org.plazmamc.plazma.EmptyConstants.LOOT_ITEM_FUNCTION); // Plazma public static final LootContextParamSet DEFAULT_PARAM_SET = LootContextParamSets.ALL_PARAMS; final LootContextParamSet paramSet; - final LootPool[] pools; -@@ -257,7 +257,7 @@ public class LootTable { + @Nullable +@@ -285,7 +285,7 @@ public class LootTable { } public LootTable build() { -- return new LootTable(this.paramSet, (LootPool[]) this.pools.toArray(new LootPool[0]), (LootItemFunction[]) this.functions.toArray(new LootItemFunction[0])); -+ return new LootTable(this.paramSet, (LootPool[]) this.pools.toArray(org.plazmamc.plazma.util.Constants.LOOT_POOL), (LootItemFunction[]) this.functions.toArray(org.plazmamc.plazma.util.Constants.LOOT_ITEM_FUNCTION)); +- return new LootTable(this.paramSet, this.randomSequence, (LootPool[]) this.pools.toArray(new LootPool[0]), (LootItemFunction[]) this.functions.toArray(new LootItemFunction[0])); ++ return new LootTable(this.paramSet, this.randomSequence, (LootPool[]) this.pools.toArray(org.plazmamc.plazma.EmptyConstants.LOOT_POOL), (LootItemFunction[]) this.functions.toArray(org.plazmamc.plazma.EmptyConstants.LOOT_ITEM_FUNCTION)); // Plazma } } -@@ -267,7 +267,7 @@ public class LootTable { +@@ -295,7 +295,7 @@ public class LootTable { public LootTable deserialize(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { JsonObject jsonobject = GsonHelper.convertToJsonObject(jsonelement, "loot table"); - LootPool[] alootselector = (LootPool[]) GsonHelper.getAsObject(jsonobject, "pools", new LootPool[0], jsondeserializationcontext, LootPool[].class); -+ LootPool[] alootselector = (LootPool[]) GsonHelper.getAsObject(jsonobject, "pools", org.plazmamc.plazma.util.Constants.LOOT_POOL, jsondeserializationcontext, LootPool[].class); ++ LootPool[] alootselector = (LootPool[]) GsonHelper.getAsObject(jsonobject, "pools", org.plazmamc.plazma.EmptyConstants.LOOT_POOL, jsondeserializationcontext, LootPool[].class); // Plazma LootContextParamSet lootcontextparameterset = null; if (jsonobject.has("type")) { -@@ -276,7 +276,7 @@ public class LootTable { - lootcontextparameterset = LootContextParamSets.get(new ResourceLocation(s)); +@@ -314,7 +314,7 @@ public class LootTable { + minecraftkey = null; } - LootItemFunction[] alootitemfunction = (LootItemFunction[]) GsonHelper.getAsObject(jsonobject, "functions", new LootItemFunction[0], jsondeserializationcontext, LootItemFunction[].class); -+ LootItemFunction[] alootitemfunction = (LootItemFunction[]) GsonHelper.getAsObject(jsonobject, "functions", org.plazmamc.plazma.util.Constants.LOOT_ITEM_FUNCTION, jsondeserializationcontext, LootItemFunction[].class); ++ LootItemFunction[] alootitemfunction = (LootItemFunction[]) GsonHelper.getAsObject(jsonobject, "functions", org.plazmamc.plazma.EmptyConstants.LOOT_ITEM_FUNCTION, jsondeserializationcontext, LootItemFunction[].class); // Plazma - return new LootTable(lootcontextparameterset != null ? lootcontextparameterset : LootContextParamSets.ALL_PARAMS, alootselector, alootitemfunction); + return new LootTable(lootcontextparameterset != null ? lootcontextparameterset : LootContextParamSets.ALL_PARAMS, minecraftkey, alootselector, alootitemfunction); } +diff --git a/src/main/java/net/minecraft/world/level/storage/loot/entries/AlternativesEntry.java b/src/main/java/net/minecraft/world/level/storage/loot/entries/AlternativesEntry.java +index d63d8323290625bb0246a6965fc06f29a800750c..b0b104de5d378b6618b392dcc032fe1f5083fa9d 100644 +--- a/src/main/java/net/minecraft/world/level/storage/loot/entries/AlternativesEntry.java ++++ b/src/main/java/net/minecraft/world/level/storage/loot/entries/AlternativesEntry.java +@@ -85,7 +85,7 @@ public class AlternativesEntry extends CompositeEntryBase { + + @Override + public LootPoolEntryContainer build() { +- return new AlternativesEntry(this.entries.toArray(new LootPoolEntryContainer[0]), this.getConditions()); ++ return new AlternativesEntry(this.entries.toArray(org.plazmamc.plazma.EmptyConstants.LOOT_POOL_ENTRY_CONTAINERS), this.getConditions()); // Plazma + } + } + } +diff --git a/src/main/java/net/minecraft/world/level/storage/loot/entries/EntryGroup.java b/src/main/java/net/minecraft/world/level/storage/loot/entries/EntryGroup.java +index da1b5c6b68f14969b85472826d3d36ca673a0e5a..0af74b3442ed73ce2157e9003ce9f1eacf4431c0 100644 +--- a/src/main/java/net/minecraft/world/level/storage/loot/entries/EntryGroup.java ++++ b/src/main/java/net/minecraft/world/level/storage/loot/entries/EntryGroup.java +@@ -67,7 +67,7 @@ public class EntryGroup extends CompositeEntryBase { + + @Override + public LootPoolEntryContainer build() { +- return new EntryGroup(this.entries.toArray(new LootPoolEntryContainer[0]), this.getConditions()); ++ return new EntryGroup(this.entries.toArray(org.plazmamc.plazma.EmptyConstants.LOOT_POOL_ENTRY_CONTAINERS), this.getConditions()); // Plazma + } + } + } +diff --git a/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer.java b/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer.java +index 3bea85eab6f0a3b460b060579c73e90b83be7de4..6233448b253f02b1e3f82984960c027bca5ca150 100644 +--- a/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer.java ++++ b/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer.java +@@ -53,7 +53,7 @@ public abstract class LootPoolEntryContainer implements ComposableEntryContainer + } + + protected LootItemCondition[] getConditions() { +- return this.conditions.toArray(new LootItemCondition[0]); ++ return this.conditions.toArray(org.plazmamc.plazma.EmptyConstants.LOOT_ITEM_CONDITIONS); // Plazma + } + + public AlternativesEntry.Builder otherwise(LootPoolEntryContainer.Builder builder) { +@@ -83,7 +83,7 @@ public abstract class LootPoolEntryContainer implements ComposableEntryContainer + + @Override + public final T deserialize(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) { +- LootItemCondition[] lootItemConditions = GsonHelper.getAsObject(jsonObject, "conditions", new LootItemCondition[0], jsonDeserializationContext, LootItemCondition[].class); ++ LootItemCondition[] lootItemConditions = GsonHelper.getAsObject(jsonObject, "conditions", org.plazmamc.plazma.EmptyConstants.LOOT_ITEM_CONDITIONS, jsonDeserializationContext, LootItemCondition[].class); // Plazma + return this.deserializeCustom(jsonObject, jsonDeserializationContext, lootItemConditions); + } + diff --git a/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java b/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java -index d125b5a470be0f4c56c2c1f229fc5c83fc4d2f3b..ebb598eab6ae185b7a4e126cc59637b0cf878fee 100644 +index d125b5a470be0f4c56c2c1f229fc5c83fc4d2f3b..63ae04cbdd556788675d1a0db4c3309b3c84c0fa 100644 --- a/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java +++ b/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java @@ -78,7 +78,7 @@ public abstract class LootPoolSingletonContainer extends LootPoolEntryContainer @@ -1060,7 +1190,7 @@ index d125b5a470be0f4c56c2c1f229fc5c83fc4d2f3b..ebb598eab6ae185b7a4e126cc59637b0 protected LootItemFunction[] getFunctions() { - return this.functions.toArray(new LootItemFunction[0]); -+ return this.functions.toArray(org.plazmamc.plazma.util.Constants.LOOT_ITEM_FUNCTION); ++ return this.functions.toArray(org.plazmamc.plazma.EmptyConstants.LOOT_ITEM_FUNCTION); // Plazma } public T setWeight(int weight) { @@ -1069,12 +1199,68 @@ index d125b5a470be0f4c56c2c1f229fc5c83fc4d2f3b..ebb598eab6ae185b7a4e126cc59637b0 int i = GsonHelper.getAsInt(jsonObject, "weight", 1); int j = GsonHelper.getAsInt(jsonObject, "quality", 0); - LootItemFunction[] lootItemFunctions = GsonHelper.getAsObject(jsonObject, "functions", new LootItemFunction[0], jsonDeserializationContext, LootItemFunction[].class); -+ LootItemFunction[] lootItemFunctions = GsonHelper.getAsObject(jsonObject, "functions", org.plazmamc.plazma.util.Constants.LOOT_ITEM_FUNCTION, jsonDeserializationContext, LootItemFunction[].class); ++ LootItemFunction[] lootItemFunctions = GsonHelper.getAsObject(jsonObject, "functions", org.plazmamc.plazma.EmptyConstants.LOOT_ITEM_FUNCTION, jsonDeserializationContext, LootItemFunction[].class); // Plazma return this.deserialize(jsonObject, jsonDeserializationContext, i, j, lootItemConditions, lootItemFunctions); } +diff --git a/src/main/java/net/minecraft/world/level/storage/loot/entries/SequentialEntry.java b/src/main/java/net/minecraft/world/level/storage/loot/entries/SequentialEntry.java +index 28ee59e7745ef0c98b13ae3e32f52dc7defe0bcd..d43f00901bac86cbb6e210cca223c8663b440847 100644 +--- a/src/main/java/net/minecraft/world/level/storage/loot/entries/SequentialEntry.java ++++ b/src/main/java/net/minecraft/world/level/storage/loot/entries/SequentialEntry.java +@@ -63,7 +63,7 @@ public class SequentialEntry extends CompositeEntryBase { + + @Override + public LootPoolEntryContainer build() { +- return new SequentialEntry(this.entries.toArray(new LootPoolEntryContainer[0]), this.getConditions()); ++ return new SequentialEntry(this.entries.toArray(org.plazmamc.plazma.EmptyConstants.LOOT_POOL_ENTRY_CONTAINERS), this.getConditions()); // Plazma + } + } + } +diff --git a/src/main/java/net/minecraft/world/level/storage/loot/functions/LootItemConditionalFunction.java b/src/main/java/net/minecraft/world/level/storage/loot/functions/LootItemConditionalFunction.java +index 5c67ae93a18f246d2bffd2c0b92f9ad82294b81e..31f365f26f008ef67b0dbe47743163a420c59b91 100644 +--- a/src/main/java/net/minecraft/world/level/storage/loot/functions/LootItemConditionalFunction.java ++++ b/src/main/java/net/minecraft/world/level/storage/loot/functions/LootItemConditionalFunction.java +@@ -63,7 +63,7 @@ public abstract class LootItemConditionalFunction implements LootItemFunction { + protected abstract T getThis(); + + protected LootItemCondition[] getConditions() { +- return this.conditions.toArray(new LootItemCondition[0]); ++ return this.conditions.toArray(org.plazmamc.plazma.EmptyConstants.LOOT_ITEM_CONDITIONS); // Plazma + } + } + +@@ -96,7 +96,7 @@ public abstract class LootItemConditionalFunction implements LootItemFunction { + + @Override + public final T deserialize(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) { +- LootItemCondition[] lootItemConditions = GsonHelper.getAsObject(jsonObject, "conditions", new LootItemCondition[0], jsonDeserializationContext, LootItemCondition[].class); ++ LootItemCondition[] lootItemConditions = GsonHelper.getAsObject(jsonObject, "conditions", org.plazmamc.plazma.EmptyConstants.LOOT_ITEM_CONDITIONS, jsonDeserializationContext, LootItemCondition[].class); // Plazma + return this.deserialize(jsonObject, jsonDeserializationContext, lootItemConditions); + } + +diff --git a/src/main/java/net/minecraft/world/level/storage/loot/functions/SetAttributesFunction.java b/src/main/java/net/minecraft/world/level/storage/loot/functions/SetAttributesFunction.java +index c5e7caf78049d8a6d18676f19dedf0b688802eab..375665a588c19cfa470fb20b5e502eea8ebb55f0 100644 +--- a/src/main/java/net/minecraft/world/level/storage/loot/functions/SetAttributesFunction.java ++++ b/src/main/java/net/minecraft/world/level/storage/loot/functions/SetAttributesFunction.java +@@ -216,6 +216,7 @@ public class SetAttributesFunction extends LootItemConditionalFunction { + @Nullable + private UUID id; + private final Set slots = EnumSet.noneOf(EquipmentSlot.class); ++ private static final EquipmentSlot[] EMPTY_SLOT = new EquipmentSlot[0]; // Plazma + + public ModifierBuilder(String name, Attribute attribute, AttributeModifier.Operation operation, NumberProvider amount) { + this.name = name; +@@ -235,7 +236,7 @@ public class SetAttributesFunction extends LootItemConditionalFunction { + } + + public SetAttributesFunction.Modifier build() { +- return new SetAttributesFunction.Modifier(this.name, this.attribute, this.operation, this.amount, this.slots.toArray(new EquipmentSlot[0]), this.id); ++ return new SetAttributesFunction.Modifier(this.name, this.attribute, this.operation, this.amount, this.slots.toArray(EMPTY_SLOT), this.id); // Plazma + } + } + diff --git a/src/main/java/net/minecraft/world/scores/Team.java b/src/main/java/net/minecraft/world/scores/Team.java -index 16d2aa4556bc9f32a2def7f9ca282aa3fa23fb87..c9b266246a83e3d7f5ce61306f291ceff902079d 100644 +index 16d2aa4556bc9f32a2def7f9ca282aa3fa23fb87..4886624aea43c1af7ed02da336cc0d25d38cdb8d 100644 --- a/src/main/java/net/minecraft/world/scores/Team.java +++ b/src/main/java/net/minecraft/world/scores/Team.java @@ -80,7 +80,7 @@ public abstract class Team { @@ -1082,38 +1268,25 @@ index 16d2aa4556bc9f32a2def7f9ca282aa3fa23fb87..c9b266246a83e3d7f5ce61306f291cef public static String[] getAllNames() { - return BY_NAME.keySet().toArray(new String[0]); -+ return BY_NAME.keySet().toArray(org.plazmamc.plazma.util.Constants.EMPTY_STRING); ++ return BY_NAME.keySet().toArray(org.plazmamc.plazma.EmptyConstants.STRING); // Plazma } @Nullable -diff --git a/src/main/java/org/bukkit/craftbukkit/bootstrap/Main.java b/src/main/java/org/bukkit/craftbukkit/bootstrap/Main.java -index 9a2ec50be757dfa3780a49ec96942fed89ed530c..d5b904a36d7c0a9d0f8787eccc770fd47a03430f 100644 ---- a/src/main/java/org/bukkit/craftbukkit/bootstrap/Main.java -+++ b/src/main/java/org/bukkit/craftbukkit/bootstrap/Main.java -@@ -50,7 +50,7 @@ public class Main { - System.exit(0); - } - -- URLClassLoader classLoader = new URLClassLoader(extractedUrls.toArray(new URL[0])); -+ URLClassLoader classLoader = new URLClassLoader(extractedUrls.toArray(org.plazmamc.plazma.util.Constants.URL)); - - System.out.println("Starting server"); - Thread runThread = new Thread(() -> { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index e363891e8ab872ed24c557e3f94110f36c6fb277..409d2e1d936932177caebdb1e12278bdd58db3b2 100644 +index 668d825a2469706e4de11629a0b41877de700ca6..01659302dce138ed00ef4c55b712572840d2f10e 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -472,7 +472,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -455,7 +455,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { public void sendTitle(Title title) { Preconditions.checkNotNull(title, "Title is null"); setTitleTimes(title.getFadeIn(), title.getStay(), title.getFadeOut()); - setSubtitle(title.getSubtitle() == null ? new BaseComponent[0] : title.getSubtitle()); -+ setSubtitle(title.getSubtitle() == null ? org.plazmamc.plazma.util.Constants.BASE_COMPONENT : title.getSubtitle()); ++ setSubtitle(title.getSubtitle() == null ? org.plazmamc.plazma.EmptyConstants.BASE_COMPONENT : title.getSubtitle()); // Plazma showTitle(title.getTitle()); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java -index a5d7fae348b0b262a0a8a5e8e76f1bc75ca52a16..8b9b267e226ab1645fd8c57e1f8196276008345e 100644 +index 88c899e323eb554febe191ac7df678bbdfde08dc..a7ce24d3fce8490a8cd4e7cf28eb6be6138f4bd8 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java @@ -609,7 +609,7 @@ public class CraftMetaBook extends CraftMetaItem implements BookMeta { @@ -1121,7 +1294,7 @@ index a5d7fae348b0b262a0a8a5e8e76f1bc75ca52a16..8b9b267e226ab1645fd8c57e1f819627 } - BaseComponent[] newText = text == null ? new BaseComponent[0] : text; -+ BaseComponent[] newText = text == null ? org.plazmamc.plazma.util.Constants.BASE_COMPONENT : text; ++ BaseComponent[] newText = text == null ? org.plazmamc.plazma.EmptyConstants.BASE_COMPONENT : text; // Plazma CraftMetaBook.this.pages.set(page - 1, this.componentsToPage(newText)); } @@ -1130,38 +1303,60 @@ index a5d7fae348b0b262a0a8a5e8e76f1bc75ca52a16..8b9b267e226ab1645fd8c57e1f819627 for (BaseComponent[] page : pages) { if (page == null) { - page = new BaseComponent[0]; -+ page = org.plazmamc.plazma.util.Constants.BASE_COMPONENT; ++ page = org.plazmamc.plazma.EmptyConstants.BASE_COMPONENT; // Plazma } CraftMetaBook.this.internalAddPage(this.componentsToPage(page)); -diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -index 936f8babf74b2be6240e5dbc2d0a84f8badada2e..ab9f71a45a4f2a9781ad1a12f8dda4ac9179c72f 100644 ---- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -@@ -880,7 +880,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { - // Paper start - @Override - public net.md_5.bungee.api.chat.BaseComponent[] getDisplayNameComponent() { -- return displayName == null ? new net.md_5.bungee.api.chat.BaseComponent[0] : net.md_5.bungee.chat.ComponentSerializer.parse(displayName); -+ return displayName == null ? org.plazmamc.plazma.util.Constants.BASE_COMPONENT : net.md_5.bungee.chat.ComponentSerializer.parse(displayName); - } - // Paper end - @Override diff --git a/src/main/java/org/bukkit/craftbukkit/util/WeakCollection.java b/src/main/java/org/bukkit/craftbukkit/util/WeakCollection.java -index 049d750d3af991dd14ac8cf644330404e74b2151..c2d41e133bbbaf1b445388829769e898b0ae67da 100644 +index bbacf58740f3faea0d555e4012fe2b15fb46ed50..032ec7a2e8afcbf70c86ced7c591bba555ffa17e 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/WeakCollection.java +++ b/src/main/java/org/bukkit/craftbukkit/util/WeakCollection.java -@@ -166,7 +166,7 @@ public final class WeakCollection implements Collection { +@@ -164,7 +164,7 @@ public final class WeakCollection implements Collection { @Override public Object[] toArray() { - return this.toArray(new Object[0]); -+ return this.toArray(org.plazmamc.plazma.util.Constants.EMPTY_OBJECT); ++ return this.toArray(org.plazmamc.plazma.EmptyConstants.OBJECT); // Plazma } @Override +diff --git a/src/main/java/org/plazmamc/plazma/EmptyConstants.java b/src/main/java/org/plazmamc/plazma/EmptyConstants.java +new file mode 100644 +index 0000000000000000000000000000000000000000..11602bcc9ea39130138bff67bf52b4f01c0b6c88 +--- /dev/null ++++ b/src/main/java/org/plazmamc/plazma/EmptyConstants.java +@@ -0,0 +1,29 @@ ++package org.plazmamc.plazma; ++ ++public class EmptyConstants { ++ ++ public static final byte[] BYTE = new byte[0]; ++ public static final int[] INT = new int[0]; ++ public static final int[] ZERO_INT = new int[]{0}; ++ public static final long[] LONG = new long[0]; ++ ++ public static final Class[] CLASS = new Class[0]; ++ public static final Object[] OBJECT = new Object[0]; ++ public static final StackTraceElement[] STACK_TRACE_ELEMENT = new StackTraceElement[0]; ++ public static final String[] STRING = new String[0]; ++ ++ public static final java.nio.file.LinkOption[] LINK_OPTION = new java.nio.file.LinkOption[0]; ++ public static final java.util.concurrent.CompletableFuture[] COMPLETABLE_FUTURES = new java.util.concurrent.CompletableFuture[0]; ++ ++ public static final net.minecraft.advancements.critereon.ContextAwarePredicate[] CONTEXT_AWARE_PREDICATES = new net.minecraft.advancements.critereon.ContextAwarePredicate[0]; ++ public static final net.minecraft.advancements.critereon.ItemPredicate[] ITEM_PREDICATES = new net.minecraft.advancements.critereon.ItemPredicate[0]; ++ public static final net.minecraft.world.entity.Entity[] ENTITY = new net.minecraft.world.entity.Entity[0]; ++ public static final net.minecraft.world.level.block.state.BlockState[] BLOCK_STATE = new net.minecraft.world.level.block.state.BlockState[0]; ++ public static final net.minecraft.world.level.storage.loot.LootPool[] LOOT_POOL = new net.minecraft.world.level.storage.loot.LootPool[0]; ++ public static final net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer[] LOOT_POOL_ENTRY_CONTAINERS = new net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer[0]; ++ public static final net.minecraft.world.level.storage.loot.functions.LootItemFunction[] LOOT_ITEM_FUNCTION = new net.minecraft.world.level.storage.loot.functions.LootItemFunction[0]; ++ public static final net.minecraft.world.level.storage.loot.predicates.LootItemCondition[] LOOT_ITEM_CONDITIONS = new net.minecraft.world.level.storage.loot.predicates.LootItemCondition[0]; ++ ++ public static final net.md_5.bungee.api.chat.BaseComponent[] BASE_COMPONENT = new net.md_5.bungee.api.chat.BaseComponent[0]; ++ ++} diff --git a/src/main/java/org/plazmamc/plazma/commands/subcommands/VersionCommand.java b/src/main/java/org/plazmamc/plazma/commands/subcommands/VersionCommand.java -index 85002144e0b350c4ae044e1a4a4c1734cc27c059..d4f5a0e49eebd2e02790a10a87166836ee6c3c09 100644 +index 85002144e0b350c4ae044e1a4a4c1734cc27c059..776e5b5676749a05d29138afb070c9243cbe920c 100644 --- a/src/main/java/org/plazmamc/plazma/commands/subcommands/VersionCommand.java +++ b/src/main/java/org/plazmamc/plazma/commands/subcommands/VersionCommand.java @@ -9,7 +9,7 @@ public class VersionCommand implements PlazmaSubCommand { @@ -1169,59 +1364,12 @@ index 85002144e0b350c4ae044e1a4a4c1734cc27c059..d4f5a0e49eebd2e02790a10a87166836 public boolean execute(CommandSender sender, String subCommand, String[] args) { final @Nullable Command ver = MinecraftServer.getServer().server.getCommandMap().getCommand("version"); - if (ver != null) ver.execute(sender, "plazma", new String[0]); -+ if (ver != null) ver.execute(sender, "plazma", org.plazmamc.plazma.util.Constants.EMPTY_STRING); ++ if (ver != null) ver.execute(sender, "plazma", org.plazmamc.plazma.EmptyConstants.STRING); // Plazma return true; } } -diff --git a/src/main/java/org/plazmamc/plazma/util/Constants.java b/src/main/java/org/plazmamc/plazma/util/Constants.java -new file mode 100644 -index 0000000000000000000000000000000000000000..be3d3a62b966b1d09ca417c4339757fb8c2bb710 ---- /dev/null -+++ b/src/main/java/org/plazmamc/plazma/util/Constants.java -@@ -0,0 +1,40 @@ -+package org.plazmamc.plazma.util; -+ -+public final class Constants { -+ -+ public static final Object[] EMPTY_OBJECT = new Object[0]; -+ public static final byte[] EMPTY_BYTE = new byte[0]; -+ public static final int[] EMPTY_INT = new int[0]; -+ public static final int[] ZERO_INT = new int[]{0}; -+ public static final long[] EMPTY_LONG = new long[0]; -+ public static final String[] EMPTY_STRING = new String[0]; -+ public static final StackTraceElement[] STACK_TRACE_ELEMENT = new StackTraceElement[0]; -+ public static final Class[] EMPTY_CLASS = new Class[0]; -+ -+ public static final java.util.concurrent.CompletableFuture[] COMPLETABLE_FUTURE = new java.util.concurrent.CompletableFuture[0]; -+ public static final java.nio.file.LinkOption[] LINK_OPTION = new java.nio.file.LinkOption[0]; -+ public static final java.net.URL[] URL = new java.net.URL[0]; -+ -+ public static final com.mojang.authlib.GameProfile[] GAME_PROFILE = new com.mojang.authlib.GameProfile[0]; -+ -+ public static final net.minecraft.world.entity.Entity[] ENTITY = new net.minecraft.world.entity.Entity[0]; -+ public static final net.minecraft.world.level.block.state.BlockState[] BLOCK_STATE = new net.minecraft.world.level.block.state.BlockState[0]; -+ public static final net.minecraft.world.level.chunk.LevelChunk[] LEVEL_CHUNK = new net.minecraft.world.level.chunk.LevelChunk[0]; -+ public static final net.minecraft.resources.ResourceLocation[] RESOURCE_LOCATION = new net.minecraft.resources.ResourceLocation[0]; -+ public static final net.minecraft.server.network.ServerPlayerConnection[] SERVER_PLAYER_CONNECTION = new net.minecraft.server.network.ServerPlayerConnection[0]; -+ public static final net.minecraft.world.entity.ai.memory.MemoryModuleType[] MEMORY_MODULE_TYPE = new net.minecraft.world.entity.ai.memory.MemoryModuleType[0]; -+ public static final net.minecraft.world.item.crafting.Ingredient[] INGREDIENT = new net.minecraft.world.item.crafting.Ingredient[0]; -+ public static final net.minecraft.world.level.chunk.ChunkStatus[] CHUNK_STATUS = new net.minecraft.world.level.chunk.ChunkStatus[0]; -+ public static final net.minecraft.world.level.pathfinder.Node[] EMPTY_NODE = new net.minecraft.world.level.pathfinder.Node[0]; -+ public static final net.minecraft.world.level.storage.loot.LootPool[] LOOT_POOL = new net.minecraft.world.level.storage.loot.LootPool[0]; -+ public static final net.minecraft.world.level.storage.loot.functions.LootItemFunction[] LOOT_ITEM_FUNCTION = new net.minecraft.world.level.storage.loot.functions.LootItemFunction[0]; -+ -+ public static final net.md_5.bungee.api.chat.BaseComponent[] BASE_COMPONENT = new net.md_5.bungee.api.chat.BaseComponent[0]; -+ -+ public static final io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.ChunkInfo[] CHUNK_INFO = new io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.ChunkInfo[0]; -+ -+ public static final ca.spottedleaf.starlight.common.light.StarLightEngine.AxisDirection[] STARLIGHT_AXIS_DIRECTION = new ca.spottedleaf.starlight.common.light.StarLightEngine.AxisDirection[0]; -+ -+ public static final org.bukkit.entity.Entity[] BUKKIT_ENTITY = new org.bukkit.entity.Entity[0]; -+ -+} -\ No newline at end of file diff --git a/src/main/java/org/purpurmc/purpur/command/PurpurCommand.java b/src/main/java/org/purpurmc/purpur/command/PurpurCommand.java -index 2621e54879e9ab0029a875f1d09eee67878b90d5..6fdb80b1b3cbc0b4f8e50ccbf5f5104496860100 100644 +index 2621e54879e9ab0029a875f1d09eee67878b90d5..5ebcdcec49d5c54a31d8ca516fa16bba7fc574c7 100644 --- a/src/main/java/org/purpurmc/purpur/command/PurpurCommand.java +++ b/src/main/java/org/purpurmc/purpur/command/PurpurCommand.java @@ -57,7 +57,7 @@ public class PurpurCommand extends Command { @@ -1229,7 +1377,7 @@ index 2621e54879e9ab0029a875f1d09eee67878b90d5..6fdb80b1b3cbc0b4f8e50ccbf5f51044 Command verCmd = org.bukkit.Bukkit.getServer().getCommandMap().getCommand("version"); if (verCmd != null) { - return verCmd.execute(sender, commandLabel, new String[0]); -+ return verCmd.execute(sender, commandLabel, org.plazmamc.plazma.util.Constants.EMPTY_STRING); ++ return verCmd.execute(sender, commandLabel, org.plazmamc.plazma.EmptyConstants.STRING); // Plazma } }