diff --git a/patches/generated-api/0001-Purpur-generated-api-Changes.patch b/patches/generated-api/0001-Purpur-generated-api-Changes.patch index 026e0e0a..9713c3b9 100644 --- a/patches/generated-api/0001-Purpur-generated-api-Changes.patch +++ b/patches/generated-api/0001-Purpur-generated-api-Changes.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Github Actions -Date: Sun, 21 Jan 2024 08:34:10 -0500 +Date: Fri, 21 Jun 2024 03:34:00 +0000 Subject: [PATCH] Purpur generated-api Changes Original license: MIT diff --git a/patches/server/0001-Rebrand.patch b/patches/server/0001-Rebrand.patch index ab48d509..4a5ff32c 100644 --- a/patches/server/0001-Rebrand.patch +++ b/patches/server/0001-Rebrand.patch @@ -120,23 +120,37 @@ index 2596e0ee4df5b96f181e28a742ef345981fc97e3..023016de1732f0b299428ec0544128cc @Override diff --git a/src/main/java/net/minecraft/CrashReport.java b/src/main/java/net/minecraft/CrashReport.java -index b24265573fdef5d9a964bcd76146f34542c420cf..ae219897f0085b758dcc1b0ad4893336336e6a49 100644 +index b24265573fdef5d9a964bcd76146f34542c420cf..aa25fd3ee043003f359b2c67a6d0f6700a0ef893 100644 --- a/src/main/java/net/minecraft/CrashReport.java +++ b/src/main/java/net/minecraft/CrashReport.java -@@ -125,6 +125,11 @@ public class CrashReport { - StringBuilder stringbuilder = new StringBuilder(); +@@ -32,6 +32,7 @@ public class CrashReport { + private boolean trackingStackTrace = true; + private StackTraceElement[] uncategorizedStackTrace = new StackTraceElement[0]; + private final SystemReport systemReport = new SystemReport(); ++ private List extraInfo = List.of("", "DO NOT REPORT THIS TO PAPER OR GALE! REPORT TO LEAF INSTEAD!", ""); // Leaf - Purpur - type.appendHeader(stringbuilder, extraInfo); -+ // Leaf start - Purpur -+ stringbuilder.append("// "); -+ stringbuilder.append("// DO NOT REPORT THIS TO PAPER OR GALE! REPORT TO LEAF INSTEAD!"); -+ // Leaf end - Purpur -+ stringbuilder.append("// "); - stringbuilder.append("Time: "); - stringbuilder.append(CrashReport.DATE_TIME_FORMATTER.format(ZonedDateTime.now())); - stringbuilder.append("\n"); + public CrashReport(String message, Throwable cause) { + io.papermc.paper.util.StacktraceDeobfuscator.INSTANCE.deobfuscateThrowable(cause); // Paper +@@ -144,7 +145,7 @@ public class CrashReport { + } + + public String getFriendlyReport(ReportType type) { +- return this.getFriendlyReport(type, List.of()); ++ return this.getFriendlyReport(type, extraInfo); // Leaf - Purpur + } + + @Nullable +@@ -191,7 +192,7 @@ public class CrashReport { + } + + public boolean saveToFile(Path path, ReportType type) { +- return this.saveToFile(path, type, List.of()); ++ return this.saveToFile(path, type, extraInfo); // Leaf - Purpur + } + + public SystemReport getSystemReport() { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 25d1b4512f81802c658a5e0a03c8212ad69ac04e..f583b65fcb3f93e701bf1af0da9a1f975a216750 100644 +index 25d1b4512f81802c658a5e0a03c8212ad69ac04e..44a9ed9f06818f8bcf4caf673c4e6b02f6ed924e 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -956,7 +956,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop -Date: Mon, 29 Apr 2024 09:05:40 +0000 +Date: Fri, 21 Jun 2024 03:34:00 +0000 Subject: [PATCH] Purpur Server Changes TODO - Dreeam: Check TODOs in ServerGamePacketListenerImpl & Fix-pufferfish-issues.patch @@ -8,19 +8,19 @@ TODO - Dreeam: Check TODOs in ServerGamePacketListenerImpl & Fix-pufferfish-issu Original license: MIT Original project: https://github.com/PurpurMC/Purpur -Commit: f1c87e4fee9a8e7d513f9e284d402a21fd73ec3a +Commit: b5f1c487e796a8e55f4441237d9ca830b4423573 Patches below are removed in this patch: -Metrics changes in Purpur-config-files.patch Brand changes in Rebrand.patch +Metrics changes in Purpur-config-files.patch Fix-pufferfish-issues.patch Fix-decompile-errors.patch +Configurable-server-mod-name.patch Alternative-Keepalive-Handling.patch Logger-settings-suppressing-pointless-logs.patch Add-log-suppression-for-LibraryLoader.patch Fix-outdated-server-showing-in-ping-before-server-fu.patch Fix-cow-rotation-when-shearing-mooshroom.patch -End-gateway-should-check-if-entity-can-use-portal.patch Skip-events-if-there-s-no-listeners.patch Add-5-second-tps-average-in-tps.patch Arrows-should-not-reset-despawn-counter.patch @@ -30,32 +30,6 @@ Remove-Timings.patch Remove-Mojang-Profiler.patch MC-121706-Fix-mobs-not-looking-up-and-down-when-stra.patch -diff --git a/build.gradle.kts b/build.gradle.kts -index 63c6997be675696b47ec168374e93bd240d11ad8..59b84e4c4566e0185c6f7b002374e51c8415cad9 100644 ---- a/build.gradle.kts -+++ b/build.gradle.kts -@@ -57,6 +57,12 @@ dependencies { - runtimeOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.18") - runtimeOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.9.18") - -+ // Purpur start -+ implementation("org.mozilla:rhino-runtime:1.7.15") -+ implementation("org.mozilla:rhino-engine:1.7.15") -+ implementation("dev.omega24:upnp4j:1.0") -+ // Purpur end -+ - testImplementation("io.github.classgraph:classgraph:4.8.47") // Paper - mob goal test - testImplementation("org.junit.jupiter:junit-jupiter:5.10.2") - testImplementation("org.hamcrest:hamcrest:2.2") -@@ -164,7 +170,7 @@ fun TaskContainer.registerRunTask( - name: String, - block: JavaExec.() -> Unit - ): TaskProvider = register(name) { -- group = "paper" -+ group = "paperweight" // Purpur - 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 @@ -147,24 +121,6 @@ index 0000000000000000000000000000000000000000..15a226e3854d731f7724025ea3459c8a + return new HighlightErrorConverter(formatters); + } +} -diff --git a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java -index 6fca13221ef3e0bbcad2ebbe74d6aadf8ed2c539..2d655cfddb6e7d6528b928c9270960bc0c6148f9 100644 ---- a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java -+++ b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java -@@ -46,11 +46,8 @@ public class PaperVersionFetcher extends AbstractPaperVersionFetcher { - Charsets.UTF_8 - ).openBufferedStream()) { - final JsonObject json = new Gson().fromJson(reader, JsonObject.class); -- final JsonArray builds = json.getAsJsonArray("builds"); -- final int latest = StreamSupport.stream(builds.spliterator(), false) -- .mapToInt(JsonElement::getAsInt) -- .max() -- .orElseThrow(); -+ //final JsonArray builds = json.getAsJsonArray("builds"); // Purpur -+ final int latest = json.getAsJsonObject("builds").getAsJsonPrimitive("latest").getAsInt(); // Purpur - return latest - jenkinsBuild; - } catch (final JsonSyntaxException ex) { - LOGGER.error("Error parsing json from Paper's downloads API", ex); diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java b/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java index 06455d65c4605ce092bf5300d432087f24186741..750fd2809f6d5d5896904cad0f65029b03bda849 100644 --- a/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java @@ -180,18 +136,6 @@ index 06455d65c4605ce092bf5300d432087f24186741..750fd2809f6d5d5896904cad0f65029b ignored.add("goal_selector_1"); ignored.add("goal_selector_2"); -diff --git a/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java b/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java -index 023016de1732f0b299428ec0544128cc17407333..9d003c2ae45a057c0274a34fe5012cf17d1a2681 100644 ---- a/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java -+++ b/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java -@@ -32,6 +32,7 @@ public record ServerBuildInfoImpl( - - private static final String BRAND_PAPER_NAME = "Paper"; - private static final String BRAND_GALE_NAME = "Gale"; // Gale - branding changes -+ private static final String BRAND_PURPUR_NAME = "Purpur"; // Purpur - private static final String BRAND_LEAF_NAME = "Leaf"; // Leaf - - private static final String BUILD_DEV = "DEV"; diff --git a/src/main/java/io/papermc/paper/command/PaperPluginsCommand.java b/src/main/java/io/papermc/paper/command/PaperPluginsCommand.java index f0fce4113fb07c64adbec029d177c236cbdcbae8..e94224ed280247ee69dfdff8dc960f2b8729be33 100644 --- a/src/main/java/io/papermc/paper/command/PaperPluginsCommand.java @@ -465,7 +409,7 @@ index 0000000000000000000000000000000000000000..cb78dac8e072b5cb3c6e52e17c9ecdf7 + } +} diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java -index 59d7e8a3d83d3ab7aa28606401bb129ccaeff240..684536f600cca94ea346129a139ec4aac4d9f979 100644 +index 2d344df35d47b4b1ecddf32ccaa4dae41e5f58cb..08e783882d0b2ef3ebf88e664f1a3d8bf65f49f2 100644 --- a/src/main/java/net/minecraft/commands/CommandSourceStack.java +++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java @@ -209,6 +209,19 @@ public class CommandSourceStack implements ExecutionCommandSource predicate = this.getPredicate(vec3d); -@@ -215,7 +215,7 @@ public class EntitySelector { + AABB axisalignedbb = this.getAbsoluteAabb(vec3d); +@@ -214,7 +214,7 @@ public class EntitySelector { ServerPlayer entityplayer1 = (ServerPlayer) entity; if (predicate.test(entityplayer1)) { -- return Lists.newArrayList(new ServerPlayer[]{entityplayer1}); -+ return !canSee(source, entityplayer1) ? Collections.emptyList() : Lists.newArrayList(entityplayer1); // Purpur +- return List.of(entityplayer1); ++ return !canSee(source, entityplayer1) ? List.of() : List.of(entityplayer1); // Purpur } } -@@ -226,6 +226,7 @@ public class EntitySelector { +@@ -225,6 +225,7 @@ public class EntitySelector { if (this.isWorldLimited()) { object = source.getLevel().getPlayers(predicate, i); + ((List) object).removeIf(entityplayer3 -> !canSee(source, (ServerPlayer) entityplayer3)); // Purpur } else { - object = Lists.newArrayList(); + object = new ObjectArrayList(); Iterator iterator = source.getServer().getPlayerList().getPlayers().iterator(); -@@ -233,7 +234,7 @@ public class EntitySelector { +@@ -232,7 +233,7 @@ public class EntitySelector { while (iterator.hasNext()) { ServerPlayer entityplayer2 = (ServerPlayer) iterator.next(); @@ -592,7 +536,7 @@ index d78ad5eccd18d89050a486a0c40090a09683bd16..2a0d54f06de7b959055459349365c85c ((List) object).add(entityplayer2); if (((List) object).size() >= i) { return (List) object; -@@ -278,4 +279,10 @@ public class EntitySelector { +@@ -299,4 +300,10 @@ public class EntitySelector { public static Component joinNames(List entities) { return ComponentUtils.formatList(entities, Entity::getDisplayName); } @@ -604,7 +548,7 @@ index d78ad5eccd18d89050a486a0c40090a09683bd16..2a0d54f06de7b959055459349365c85c + // Purpur end } diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java -index 665e88b2dedf9d5bb50914d5f3d377f2d19f40b0..f70a80b496bd1498778e82fc221c3b1b39308b75 100644 +index 2767d6f97e8b314d23a8e62f22dfd396f5660d31..a64e5997b94cc8173f0512d1e282355f14f098ec 100644 --- a/src/main/java/net/minecraft/core/BlockPos.java +++ b/src/main/java/net/minecraft/core/BlockPos.java @@ -61,6 +61,12 @@ public class BlockPos extends Vec3i { @@ -621,10 +565,10 @@ index 665e88b2dedf9d5bb50914d5f3d377f2d19f40b0..f70a80b496bd1498778e82fc221c3b1b super(x, y, z); } diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -index 5dab1e10303177e5a4d97a91ee46ede66f30ae35..68236139e3571791b891dbbef6e3ee20031e16d9 100644 +index 7bf250bba4179a506c0a39b7866a9389552d2905..6548e595ab5c06044be438bc7eac181f413c261a 100644 --- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -@@ -1048,5 +1048,22 @@ public interface DispenseItemBehavior { +@@ -1015,5 +1015,22 @@ public interface DispenseItemBehavior { } } }); @@ -648,10 +592,10 @@ index 5dab1e10303177e5a4d97a91ee46ede66f30ae35..68236139e3571791b891dbbef6e3ee20 } } diff --git a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java -index a024c697a65bbab27408da1d6a75e531d9719b47..e4fab82b369f2c2ea0d8c8acd814d06140d551fc 100644 +index 44b79a7c2f8b95a484d1999fa2167ce588f7985b..68632372c8704058f35f12e0ae6cdd98ebd55937 100644 --- a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java -@@ -105,7 +105,7 @@ public class ShearsDispenseItemBehavior extends OptionalDispenseItemBehavior { +@@ -104,7 +104,7 @@ public class ShearsDispenseItemBehavior extends OptionalDispenseItemBehavior { if (ishearable.readyForShearing()) { // CraftBukkit start // Paper start - Add drops to shear events @@ -661,10 +605,10 @@ index a024c697a65bbab27408da1d6a75e531d9719b47..e4fab82b369f2c2ea0d8c8acd814d061 // Paper end - Add drops to shear events continue; diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java -index f306daa7b9ebb62992ce1db2f062485bc08cfa1e..2ec87b01dc579e2c429d5ceebfa3a3adddd32bdd 100644 +index 90a2c61c42cba7e38f167eccdd7a951a947963c4..f37857eb3973a0cf1a02041effd5491d711c2eb7 100644 --- a/src/main/java/net/minecraft/network/Connection.java +++ b/src/main/java/net/minecraft/network/Connection.java -@@ -610,11 +610,20 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -617,11 +617,20 @@ public class Connection extends SimpleChannelInboundHandler> { private static final int MAX_PER_TICK = io.papermc.paper.configuration.GlobalConfiguration.get().misc.maxJoinsPerTick; // Paper - Buffer joins to world private static int joinAttemptsThisTick; // Paper - Buffer joins to world private static int currTick; // Paper - Buffer joins to world @@ -699,7 +643,7 @@ index 76ef195a5074006b009acd9cc1744667c6aecbb9..659577549e132754281df76a7a1bfd88 public ClientboundSetTimePacket(long time, long timeOfDay, boolean doDaylightCycle) { this.gameTime = time; diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java -index 8841f0376a7676922362b6d06c2af752d1319737..207f8f864f0cf5874f8cad9bd15fa5e9ffa3fc12 100644 +index 96337cdc6737f0a7d1a621cbe87011d4d6d60d19..7320c4bf3215b47700f6fad40866e4da94e9eab1 100644 --- a/src/main/java/net/minecraft/server/Main.java +++ b/src/main/java/net/minecraft/server/Main.java @@ -119,6 +119,12 @@ public class Main { @@ -716,10 +660,10 @@ index 8841f0376a7676922362b6d06c2af752d1319737..207f8f864f0cf5874f8cad9bd15fa5e9 Bootstrap.bootStrap(); Bootstrap.validate(); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index ae808fcaea0710c137188417a7b929057cd242bc..7bba8f957d7b4cbe80000bdd39793ce600201496 100644 +index 44a9ed9f06818f8bcf4caf673c4e6b02f6ed924e..b5fd90764d954acd0381cf42c38d5015c200b886 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -282,6 +282,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); public int autosavePeriod; // Paper - don't store the vanilla dispatcher -@@ -298,6 +299,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - BlockPhysicsEvent worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - Perf: Optimize Hoppers - worldserver.updateLagCompensationTick(); // Paper - lag compensation + worldserver.hasRidableMoveEvent = org.purpurmc.purpur.event.entity.RidableMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Purpur /* Drop global time updates if (this.tickCount % 20 == 0) { diff --git a/src/main/java/net/minecraft/server/PlayerAdvancements.java b/src/main/java/net/minecraft/server/PlayerAdvancements.java -index e3c6e5cf297d32c62bc6bb9f8682a665e98470a1..2d3f733c70ff63f7d0d272b205496ad1e0811e3d 100644 +index 749dbb091af02c2e5922de14fc2743b7649f2928..ffea0dc3acc91b9d65ad0dc5482fee7115dec03a 100644 --- a/src/main/java/net/minecraft/server/PlayerAdvancements.java +++ b/src/main/java/net/minecraft/server/PlayerAdvancements.java @@ -250,6 +250,7 @@ public class PlayerAdvancements { @@ -828,7 +772,7 @@ index e3c6e5cf297d32c62bc6bb9f8682a665e98470a1..2d3f733c70ff63f7d0d272b205496ad1 // Paper end } diff --git a/src/main/java/net/minecraft/server/commands/EnchantCommand.java b/src/main/java/net/minecraft/server/commands/EnchantCommand.java -index 84f1ba6275f04624f46ccd772924b5e075e7b205..5178d120e6bb5774e073fdabad0b4668b0de36c0 100644 +index 99695e38b6a10c3cffda6e453f9f0619c7406cc0..2283f69607cb769545c85bcae940ac956779e80b 100644 --- a/src/main/java/net/minecraft/server/commands/EnchantCommand.java +++ b/src/main/java/net/minecraft/server/commands/EnchantCommand.java @@ -70,7 +70,7 @@ public class EnchantCommand { @@ -836,7 +780,7 @@ index 84f1ba6275f04624f46ccd772924b5e075e7b205..5178d120e6bb5774e073fdabad0b4668 private static int enchant(CommandSourceStack source, Collection targets, Holder enchantment, int level) throws CommandSyntaxException { Enchantment enchantment2 = enchantment.value(); - if (level > enchantment2.getMaxLevel()) { -+ if (!org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchantCommand && level > enchantment2.getMaxLevel()) { // Purpur ++ if (!org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchantCommand && level > enchantment2.getMaxLevel()) { // Purpur - Config to allow unsafe enchants throw ERROR_LEVEL_TOO_HIGH.create(level, enchantment2.getMaxLevel()); } else { int i = 0; @@ -844,9 +788,9 @@ index 84f1ba6275f04624f46ccd772924b5e075e7b205..5178d120e6bb5774e073fdabad0b4668 ItemStack itemStack = livingEntity.getMainHandItem(); if (!itemStack.isEmpty()) { if (enchantment2.canEnchant(itemStack) -- && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(itemStack).keySet(), enchantment2)) { -+ && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(itemStack).keySet(), enchantment2) || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchantCommand && !itemStack.hasEnchantment(enchantment2))) { // Purpur - itemStack.enchant(enchantment2, level); +- && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(itemStack).keySet(), enchantment)) { ++ && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(itemStack).keySet(), enchantment) || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchantCommand && !itemStack.hasEnchantment(enchantment))) { // Purpur - Config to allow unsafe enchants + itemStack.enchant(enchantment, level); 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 @@ -873,10 +817,10 @@ index d1da3600dc07107309b20ebe6e7c0c4da0e8de76..244b4719c689f153fa36381a60acc280 for (ServerPlayer serverPlayer : targets) { diff --git a/src/main/java/net/minecraft/server/commands/GiveCommand.java b/src/main/java/net/minecraft/server/commands/GiveCommand.java -index 47355158e5e762540a10dc67b23092a0fc53bce3..9f1c8a62bda242781a0966fa2fc01534261423c7 100644 +index 0d9de4c61c7b26a6ff37c12fde629161fd0c3d5a..2f7897744f4aea718170698881773e9031a58a51 100644 --- a/src/main/java/net/minecraft/server/commands/GiveCommand.java +++ b/src/main/java/net/minecraft/server/commands/GiveCommand.java -@@ -92,6 +92,7 @@ public class GiveCommand { +@@ -60,6 +60,7 @@ public class GiveCommand { boolean flag = entityplayer.getInventory().add(itemstack1); ItemEntity entityitem; @@ -885,10 +829,10 @@ index 47355158e5e762540a10dc67b23092a0fc53bce3..9f1c8a62bda242781a0966fa2fc01534 entityitem = entityplayer.drop(itemstack, false, false, false); // CraftBukkit - SPIGOT-2942: Add boolean to call event if (entityitem != null) { diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index 74e362dff5ef35d7f725d983a1c29591ff4b5daf..62379ebae3e6972f88742ff29f607a99879f567d 100644 +index 42ac2efb4c84c5f15c10934f928183962f179626..ca31ceb08099324df560bfc4f7888a509ad75307 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -109,6 +109,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -118,6 +118,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface return; } // Paper start - Use TerminalConsoleAppender @@ -896,7 +840,7 @@ index 74e362dff5ef35d7f725d983a1c29591ff4b5daf..62379ebae3e6972f88742ff29f607a99 new com.destroystokyo.paper.console.PaperConsole(DedicatedServer.this).start(); /* jline.console.ConsoleReader bufferedreader = DedicatedServer.this.reader; -@@ -236,6 +237,15 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -245,6 +246,15 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command GaleCommands.registerCommands(this); // Gale - Gale commands - register commands com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Paper - start metrics @@ -912,7 +856,7 @@ index 74e362dff5ef35d7f725d983a1c29591ff4b5daf..62379ebae3e6972f88742ff29f607a99 com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - load version history now // Gale start - Pufferfish - SIMD support -@@ -291,6 +301,30 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -300,6 +310,30 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface if (true) throw new IllegalStateException("Failed to bind to port", ioexception); // Paper - Propagate failed to bind to port error return false; } @@ -943,17 +887,17 @@ index 74e362dff5ef35d7f725d983a1c29591ff4b5daf..62379ebae3e6972f88742ff29f607a99 // CraftBukkit start // this.setPlayerList(new DedicatedPlayerList(this, this.registries(), this.playerDataStorage)); // Spigot - moved up -@@ -365,6 +399,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -373,6 +407,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface + DedicatedServer.LOGGER.info("JMX monitoring enabled"); } - if (org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled) mobSpawnExecutor.start(); // Pufferfish + org.purpurmc.purpur.task.BossBarTask.startAll(); // Purpur + if (org.purpurmc.purpur.PurpurConfig.beeCountPayload) org.purpurmc.purpur.task.BeehiveTask.instance().register(); // Purpur return true; } } diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java -index 4323ffee716380bd67eb04a4a7bb62bc4ba2f7df..307a7596024528ad194eb01d6468aff1f5fe02cf 100644 +index bfe9be2e329c2ea2c8c44458e88d22bc75520ed4..f41853c5195cea0293766a79ae95c59afa281fdb 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java @@ -56,6 +56,7 @@ public class DedicatedServerProperties extends Settings> 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 e3fdd0677b3029be0ddc5f59489f66e28f5c2853..b9d9ef327753272a537bebccc54d9fbc16ed3bdc 100644 +index 7e9bfd51a33c9b39cbec99decc49179e421e1a57..188030bc6f8d243c2b834a18fa154d50803743e8 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -219,6 +219,8 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -220,6 +220,8 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. 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 -@@ -228,6 +230,7 @@ public class ServerLevel extends Level implements WorldGenLevel { + // CraftBukkit start +@@ -228,6 +230,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. public boolean hasPhysicsEvent = true; // Paper - BlockPhysicsEvent public boolean hasEntityMoveEvent; // Paper - Add EntityMoveEvent private final alternate.current.wire.WireHandler wireHandler = new alternate.current.wire.WireHandler(this); // Paper - optimize redstone (Alternate Current) @@ -1135,7 +1079,7 @@ index e3fdd0677b3029be0ddc5f59489f66e28f5c2853..b9d9ef327753272a537bebccc54d9fbc public LevelChunk getChunkIfLoaded(int x, int z) { return this.chunkSource.getChunkAtIfLoadedImmediately(x, z); // Paper - Use getChunkIfLoadedImmediately -@@ -714,7 +717,24 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -519,7 +522,24 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. this.dragonParts = new Int2ObjectOpenHashMap(); this.tickTime = flag1; this.server = minecraftserver; @@ -1161,15 +1105,15 @@ index e3fdd0677b3029be0ddc5f59489f66e28f5c2853..b9d9ef327753272a537bebccc54d9fbc this.serverLevelData = iworlddataserver; ChunkGenerator chunkgenerator = worlddimension.generator(); // CraftBukkit start -@@ -776,6 +796,7 @@ public class ServerLevel extends Level implements WorldGenLevel { - - this.chunkTaskScheduler = new io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler(this, io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.workerThreads); // Paper - rewrite chunk system - this.entityLookup = new io.papermc.paper.chunk.system.entity.EntityLookup(this, new EntityCallbacks()); // Paper - rewrite chunk system +@@ -590,6 +610,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. + this.chunkTaskScheduler = new ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler((ServerLevel)(Object)this, ca.spottedleaf.moonrise.common.util.MoonriseCommon.WORKER_POOL); + // Paper end - rewrite chunk system + this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit + this.preciseTime = this.serverLevelData.getDayTime(); // Purpur } // Paper start -@@ -822,7 +843,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -636,7 +657,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. int i = this.getGameRules().getInt(GameRules.RULE_PLAYERS_SLEEPING_PERCENTAGE); long j; @@ -1178,7 +1122,7 @@ index e3fdd0677b3029be0ddc5f59489f66e28f5c2853..b9d9ef327753272a537bebccc54d9fbc // CraftBukkit start j = this.levelData.getDayTime() + 24000L; TimeSkipEvent event = new TimeSkipEvent(this.getWorld(), TimeSkipEvent.SkipReason.NIGHT_SKIP, (j - j % 24000L) - this.getDayTime()); -@@ -944,6 +965,13 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -745,6 +766,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. this.serverLevelData.setGameTime(i); this.serverLevelData.getScheduledEvents().tick(this.server, i); if (this.levelData.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)) { @@ -1192,7 +1136,7 @@ index e3fdd0677b3029be0ddc5f59489f66e28f5c2853..b9d9ef327753272a537bebccc54d9fbc this.setDayTime(this.levelData.getDayTime() + 1L); } -@@ -952,8 +980,22 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -753,8 +781,22 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. public void setDayTime(long timeOfDay) { this.serverLevelData.setDayTime(timeOfDay); @@ -1215,7 +1159,7 @@ index e3fdd0677b3029be0ddc5f59489f66e28f5c2853..b9d9ef327753272a537bebccc54d9fbc public void tickCustomSpawners(boolean spawnMonsters, boolean spawnAnimals) { Iterator iterator = this.customSpawners.iterator(); -@@ -996,10 +1038,18 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -791,10 +833,18 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. boolean flag1 = this.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && this.random.nextDouble() < (double) difficultydamagescaler.getEffectiveDifficulty() * this.paperConfig().entities.spawning.skeletonHorseThunderSpawnChance.or(0.01D) && !this.getBlockState(blockposition.below()).is(Blocks.LIGHTNING_ROD); // Paper - Configurable spawn chances for skeleton horses if (flag1) { @@ -1236,7 +1180,7 @@ index e3fdd0677b3029be0ddc5f59489f66e28f5c2853..b9d9ef327753272a537bebccc54d9fbc 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 -@@ -1119,7 +1169,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -899,7 +949,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. return holder.is(PoiTypes.LIGHTNING_ROD); }, (blockposition1) -> { return blockposition1.getY() == this.getHeight(Heightmap.Types.WORLD_SURFACE, blockposition1.getX(), blockposition1.getZ()) - 1; @@ -1245,7 +1189,7 @@ index e3fdd0677b3029be0ddc5f59489f66e28f5c2853..b9d9ef327753272a537bebccc54d9fbc return optional.map((blockposition1) -> { return blockposition1.above(1); -@@ -1168,11 +1218,27 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -948,11 +998,27 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. if (this.canSleepThroughNights()) { if (!this.getServer().isSingleplayer() || this.getServer().isPublished()) { int i = this.getGameRules().getInt(GameRules.RULE_PLAYERS_SLEEPING_PERCENTAGE); @@ -1274,7 +1218,7 @@ index e3fdd0677b3029be0ddc5f59489f66e28f5c2853..b9d9ef327753272a537bebccc54d9fbc ichatmutablecomponent = Component.translatable("sleep.players_sleeping", this.sleepStatus.amountSleeping(), this.sleepStatus.sleepersNeeded(i)); } -@@ -1312,6 +1378,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1092,6 +1158,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. @VisibleForTesting public void resetWeatherCycle() { // CraftBukkit start @@ -1282,7 +1226,7 @@ index e3fdd0677b3029be0ddc5f59489f66e28f5c2853..b9d9ef327753272a537bebccc54d9fbc this.serverLevelData.setRaining(false, org.bukkit.event.weather.WeatherChangeEvent.Cause.SLEEP); // Paper - Add cause to Weather/ThunderChangeEvents // If we stop due to everyone sleeping we should reset the weather duration to some other random value. // Not that everyone ever manages to get the whole server to sleep at the same time.... -@@ -1319,6 +1386,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1099,6 +1166,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. this.serverLevelData.setRainTime(0); } // CraftBukkit end @@ -1290,7 +1234,7 @@ index e3fdd0677b3029be0ddc5f59489f66e28f5c2853..b9d9ef327753272a537bebccc54d9fbc this.serverLevelData.setThundering(false, org.bukkit.event.weather.ThunderChangeEvent.Cause.SLEEP); // Paper - Add cause to Weather/ThunderChangeEvents // CraftBukkit start // If we stop due to everyone sleeping we should reset the weather duration to some other random value. -@@ -2771,7 +2839,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2473,7 +2541,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. // Spigot Start if (entity.getBukkitEntity() instanceof org.bukkit.inventory.InventoryHolder && (!(entity instanceof ServerPlayer) || entity.getRemovalReason() != Entity.RemovalReason.KILLED)) { // SPIGOT-6876: closeInventory clears death message // Paper start - Fix merchant inventory not closing on entity removal @@ -1300,10 +1244,10 @@ index e3fdd0677b3029be0ddc5f59489f66e28f5c2853..b9d9ef327753272a537bebccc54d9fbc } // Paper end - Fix merchant inventory not closing on entity removal diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 9be1ba758cc3cac54501c39c05ea057dedeae610..fd3f177012d82fe774069b4c53f7efef3e9b991f 100644 +index 96cedc5d9fb7b88f2807e3db227940ea5ab57925..d573ae3fee994614bcc6c699bcbe8210874ca414 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -299,6 +299,10 @@ public class ServerPlayer extends Player { +@@ -302,6 +302,10 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent public @Nullable String clientBrandName = null; // Paper - Brand support public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event @@ -1312,9 +1256,9 @@ index 9be1ba758cc3cac54501c39c05ea057dedeae610..fd3f177012d82fe774069b4c53f7efef + private boolean compassBar = false; // Purpur + private boolean ramBar = false; // Purpur - // Paper start - replace player chunk loader - private final java.util.concurrent.atomic.AtomicReference viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1)); -@@ -610,6 +614,9 @@ public class ServerPlayer extends Player { + // Paper start - rewrite chunk system + private ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader; +@@ -601,6 +605,9 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple }); } @@ -1324,7 +1268,7 @@ index 9be1ba758cc3cac54501c39c05ea057dedeae610..fd3f177012d82fe774069b4c53f7efef } @Override -@@ -686,6 +693,9 @@ public class ServerPlayer extends Player { +@@ -677,6 +684,9 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple }); } @@ -1334,7 +1278,7 @@ index 9be1ba758cc3cac54501c39c05ea057dedeae610..fd3f177012d82fe774069b4c53f7efef } // CraftBukkit start - World fallback code, either respawn location or global spawn -@@ -815,6 +825,15 @@ public class ServerPlayer extends Player { +@@ -806,6 +816,15 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple this.trackEnteredOrExitedLavaOnVehicle(); this.updatePlayerAttributes(); this.advancements.flushDirty(this); @@ -1350,7 +1294,7 @@ index 9be1ba758cc3cac54501c39c05ea057dedeae610..fd3f177012d82fe774069b4c53f7efef } private void updatePlayerAttributes() { -@@ -1078,6 +1097,7 @@ public class ServerPlayer extends Player { +@@ -1069,6 +1088,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple })); PlayerTeam scoreboardteam = this.getTeam(); @@ -1358,7 +1302,7 @@ index 9be1ba758cc3cac54501c39c05ea057dedeae610..fd3f177012d82fe774069b4c53f7efef if (scoreboardteam != null && scoreboardteam.getDeathMessageVisibility() != Team.Visibility.ALWAYS) { if (scoreboardteam.getDeathMessageVisibility() == Team.Visibility.HIDE_FOR_OTHER_TEAMS) { this.server.getPlayerList().broadcastSystemToTeam(this, ichatbasecomponent); -@@ -1181,6 +1201,16 @@ public class ServerPlayer extends Player { +@@ -1172,6 +1192,16 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple if (this.isInvulnerableTo(source)) { return false; } else { @@ -1375,24 +1319,24 @@ index 9be1ba758cc3cac54501c39c05ea057dedeae610..fd3f177012d82fe774069b4c53f7efef boolean flag = this.server.isDedicatedServer() && this.isPvpAllowed() && source.is(DamageTypeTags.IS_FALL); if (!flag && this.spawnInvulnerableTime > 0 && !source.is(DamageTypeTags.BYPASSES_INVULNERABILITY)) { -@@ -1324,6 +1354,7 @@ public class ServerPlayer extends Player { - playerlist.sendPlayerPermissionLevel(this); +@@ -1399,6 +1429,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple worldserver1.removePlayerImmediately(this, Entity.RemovalReason.CHANGED_DIMENSION); this.unsetRemoved(); -+ this.portalPos = io.papermc.paper.util.MCUtil.toBlockPosition(exit); // Purpur - // CraftBukkit end ++ this.portalPos = io.papermc.paper.util.MCUtil.toBlockPosition(exit); // Purpur this.setServerLevel(worldserver); -@@ -1479,7 +1510,7 @@ public class ServerPlayer extends Player { + this.connection.teleport(exit); // CraftBukkit - use internal teleport without event + this.connection.resetPosition(); +@@ -1502,7 +1533,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple return entitymonster.isPreventingPlayerRest(this); }); - if (!list.isEmpty()) { + if (!this.level().purpurConfig.playerSleepNearMonsters && !list.isEmpty()) { // Purpur - return Either.left(Player.BedSleepingProblem.NOT_SAFE); + return Either.left(net.minecraft.world.entity.player.Player.BedSleepingProblem.NOT_SAFE); } } -@@ -1519,7 +1550,19 @@ public class ServerPlayer extends Player { +@@ -1542,7 +1573,19 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple }); if (!this.serverLevel().canSleepThroughNights()) { @@ -1413,7 +1357,7 @@ index 9be1ba758cc3cac54501c39c05ea057dedeae610..fd3f177012d82fe774069b4c53f7efef } ((ServerLevel) this.level()).updateSleepingPlayerList(); -@@ -1641,6 +1684,7 @@ public class ServerPlayer extends Player { +@@ -1664,6 +1707,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple @Override public void openTextEdit(SignBlockEntity sign, boolean front) { @@ -1421,7 +1365,7 @@ index 9be1ba758cc3cac54501c39c05ea057dedeae610..fd3f177012d82fe774069b4c53f7efef this.connection.send(new ClientboundBlockUpdatePacket(this.level(), sign.getBlockPos())); this.connection.send(new ClientboundOpenSignEditorPacket(sign.getBlockPos(), front)); } -@@ -1975,6 +2019,26 @@ public class ServerPlayer extends Player { +@@ -2000,6 +2044,26 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple this.lastSentExp = -1; // CraftBukkit - Added to reset } @@ -1448,7 +1392,7 @@ index 9be1ba758cc3cac54501c39c05ea057dedeae610..fd3f177012d82fe774069b4c53f7efef @Override public void displayClientMessage(Component message, boolean overlay) { this.sendSystemMessage(message, overlay); -@@ -2300,8 +2364,68 @@ public class ServerPlayer extends Player { +@@ -2340,8 +2404,68 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple public void resetLastActionTime() { this.lastActionTime = Util.getMillis(); @@ -1517,7 +1461,7 @@ index 9be1ba758cc3cac54501c39c05ea057dedeae610..fd3f177012d82fe774069b4c53f7efef public ServerStatsCounter getStats() { return this.stats; } -@@ -2875,4 +2999,50 @@ public class ServerPlayer extends Player { +@@ -2938,4 +3062,50 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple return (CraftPlayer) super.getBukkitEntity(); } // CraftBukkit end @@ -1539,7 +1483,7 @@ index 9be1ba758cc3cac54501c39c05ea057dedeae610..fd3f177012d82fe774069b4c53f7efef + 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); ++ this.server.getPlayerList().respawn(this, true, RemovalReason.KILLED, org.bukkit.event.player.PlayerRespawnEvent.RespawnReason.DEATH, to); + } + } + @@ -1569,10 +1513,10 @@ index 9be1ba758cc3cac54501c39c05ea057dedeae610..fd3f177012d82fe774069b4c53f7efef + // 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 1047027610624c9ba4bb5afd5d7f0714a062b198..7424246750d6ceca1acd5d9ebfd48f0d66504c5d 100644 +index 24b1715397ba8e6f5e9841a030d0e3d964356f89..89eef5b3c964668e3be53cce6551a6faa8f1cca9 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -@@ -400,6 +400,7 @@ public class ServerPlayerGameMode { +@@ -405,6 +405,7 @@ public class ServerPlayerGameMode { } else {capturedBlockEntity = true;} // Paper - Send block entities after destroy prediction return false; } @@ -1580,7 +1524,7 @@ index 1047027610624c9ba4bb5afd5d7f0714a062b198..7424246750d6ceca1acd5d9ebfd48f0d } // CraftBukkit end -@@ -512,6 +513,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) { @@ -1588,7 +1532,7 @@ index 1047027610624c9ba4bb5afd5d7f0714a062b198..7424246750d6ceca1acd5d9ebfd48f0d BlockPos blockposition = hitResult.getBlockPos(); BlockState iblockdata = world.getBlockState(blockposition); boolean cancelledBlock = false; -@@ -573,7 +575,7 @@ public class ServerPlayerGameMode { +@@ -578,7 +580,7 @@ public class ServerPlayerGameMode { ItemStack itemstack1 = stack.copy(); InteractionResult enuminteractionresult; @@ -1597,7 +1541,7 @@ index 1047027610624c9ba4bb5afd5d7f0714a062b198..7424246750d6ceca1acd5d9ebfd48f0d ItemInteractionResult iteminteractionresult = iblockdata.useItemOn(player.getItemInHand(hand), world, player, hand, hitResult); if (iteminteractionresult.consumesAction()) { -@@ -621,4 +623,18 @@ public class ServerPlayerGameMode { +@@ -626,4 +628,18 @@ public class ServerPlayerGameMode { public void setLevel(ServerLevel world) { this.level = world; } @@ -1617,20 +1561,20 @@ index 1047027610624c9ba4bb5afd5d7f0714a062b198..7424246750d6ceca1acd5d9ebfd48f0d + // Purpur end } diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -index 2a7de95242c80e2df86ef11538a315664617d3f0..0805eae5d770a5cc9c0b96ec11de6d9c9faf2d1d 100644 +index a720a05c47b2137a07515461960603cc5c939d16..b66fdb789fcb460d63fd81540112d655c9a0c3f2 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -@@ -86,6 +86,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -87,6 +87,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack private static final long KEEPALIVE_LIMIT = KEEPALIVE_LIMIT_IN_SECONDS * 1000; // Gale end - Purpur - send multiple keep-alive packets - protected static final ResourceLocation MINECRAFT_BRAND = new ResourceLocation("brand"); // Paper - Brand support -+ protected static final ResourceLocation PURPUR_CLIENT = new ResourceLocation("purpur", "client"); // Purpur + protected static final ResourceLocation MINECRAFT_BRAND = ResourceLocation.withDefaultNamespace("brand"); // Paper - Brand support ++ protected static final ResourceLocation PURPUR_CLIENT = ResourceLocation.fromNamespaceAndPath("purpur", "client"); // Purpur public ServerCommonPacketListenerImpl(MinecraftServer minecraftserver, Connection networkmanager, CommonListenerCookie commonlistenercookie, ServerPlayer player) { // CraftBukkit this.server = minecraftserver; -@@ -189,6 +190,13 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -190,6 +191,13 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t register custom payload", ex); - this.disconnect("Invalid payload REGISTER!", org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PAYLOAD); // Paper - kick event cause + this.disconnect(Component.literal("Invalid payload REGISTER!"), PlayerKickEvent.Cause.INVALID_PAYLOAD); // Paper - kick event cause } + // Purpur start + } else if (identifier.equals(PURPUR_CLIENT)) { @@ -1643,31 +1587,31 @@ index 2a7de95242c80e2df86ef11538a315664617d3f0..0805eae5d770a5cc9c0b96ec11de6d9c try { String channels = payload.toString(com.google.common.base.Charsets.UTF_8); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 31cd9c04b06fa691305c078e3c428a9e0d717ecf..fab3ce46529e2619e598c73421c0676831fb16ff 100644 +index deb4282880aa5f28100a202c73514c892f487be0..dc4a4d7de838d8756b0f5cbbc149b1d5cd2b4dd6 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -336,6 +336,20 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -337,6 +337,20 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private boolean justTeleported = false; // CraftBukkit end -+ // Purpur start ++ // Purpur start + private final com.google.common.cache.LoadingCache kickPermissionCache = com.google.common.cache.CacheBuilder.newBuilder() -+ .maximumSize(1000) -+ .expireAfterWrite(1, java.util.concurrent.TimeUnit.MINUTES) -+ .build( -+ new com.google.common.cache.CacheLoader<>() { -+ @Override -+ public Boolean load(CraftPlayer player) { -+ return player.hasPermission("purpur.bypassIdleKick"); -+ } -+ } -+ ); ++ .maximumSize(1000) ++ .expireAfterWrite(1, java.util.concurrent.TimeUnit.MINUTES) ++ .build( ++ new com.google.common.cache.CacheLoader<>() { ++ @Override ++ public Boolean load(CraftPlayer player) { ++ return player.hasPermission("purpur.bypassIdleKick"); ++ } ++ } ++ ); + // Purpur end + @Override public void tick() { if (this.ackBlockChangesUpTo > -1) { -@@ -403,6 +417,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -404,6 +418,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) this.server.getPlayerIdleTimeout() * 1000L * 60L && !this.player.wonGame) { // Paper - Prevent AFK kick while watching end credits @@ -1678,9 +1622,9 @@ index 31cd9c04b06fa691305c078e3c428a9e0d717ecf..fab3ce46529e2619e598c73421c06768 + } + // 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 + this.disconnect((Component) Component.translatable("multiplayer.disconnect.idling"), org.bukkit.event.player.PlayerKickEvent.Cause.IDLING); // Paper - kick event cause } -@@ -662,6 +682,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -654,6 +674,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.lastYaw = to.getYaw(); this.lastPitch = to.getPitch(); @@ -1689,15 +1633,15 @@ index 31cd9c04b06fa691305c078e3c428a9e0d717ecf..fab3ce46529e2619e598c73421c06768 Location oldTo = to.clone(); PlayerMoveEvent event = new PlayerMoveEvent(player, from, to); this.cserver.getPluginManager().callEvent(event); -@@ -735,6 +757,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -704,6 +726,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); 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 + ServerGamePacketListenerImpl.LOGGER.warn("Disconnected on accept teleport packet. Was not expecting position data from client at this time"); // Purpur + this.disconnect((Component) Component.translatable("multiplayer.disconnect.invalid_player_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PLAYER_MOVEMENT); // Paper - kick event cause return; } - -@@ -1170,10 +1193,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1140,10 +1163,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl int maxBookPageSize = io.papermc.paper.configuration.GlobalConfiguration.get().itemValidation.bookSize.pageMax; double multiplier = Math.max(0.3D, Math.min(1D, io.papermc.paper.configuration.GlobalConfiguration.get().itemValidation.bookSize.totalMultiplier)); long byteAllowed = maxBookPageSize; @@ -1710,18 +1654,18 @@ index 31cd9c04b06fa691305c078e3c428a9e0d717ecf..fab3ce46529e2619e598c73421c06768 if (byteLength > 256 * 4) { ServerGamePacketListenerImpl.LOGGER.warn(this.player.getScoreboardName() + " tried to send a book with with a page too large!"); + org.purpurmc.purpur.event.player.PlayerBookTooLargeEvent event = new org.purpurmc.purpur.event.player.PlayerBookTooLargeEvent(player.getBukkitEntity(), itemstack.asBukkitCopy()); if (event.shouldKickPlayer()) // Purpur - server.scheduleOnMain(() -> this.disconnect("Book too large!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION)); // Paper - kick event cause + this.disconnect(Component.literal("Book too large!"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper - kick event cause return; } -@@ -1197,6 +1225,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1167,6 +1195,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (byteTotal > byteAllowed) { ServerGamePacketListenerImpl.LOGGER.warn(this.player.getScoreboardName() + " tried to send too large of a book. Book Size: " + byteTotal + " - Allowed: "+ byteAllowed + " - Pages: " + pageList.size()); + org.purpurmc.purpur.event.player.PlayerBookTooLargeEvent event = new org.purpurmc.purpur.event.player.PlayerBookTooLargeEvent(player.getBukkitEntity(), itemstack.asBukkitCopy()); if (event.shouldKickPlayer()) // Purpur - server.scheduleOnMain(() -> this.disconnect("Book too large!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION)); // Paper - kick event cause + this.disconnect(Component.literal("Book too large!"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper - kick event cause return; } -@@ -1221,10 +1250,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1191,10 +1220,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl Objects.requireNonNull(list); stream.forEach(list::add); @@ -1738,7 +1682,7 @@ index 31cd9c04b06fa691305c078e3c428a9e0d717ecf..fab3ce46529e2619e598c73421c06768 }; this.filterTextPacket((List) list).thenAcceptAsync(consumer, this.server); -@@ -1232,13 +1265,18 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1202,13 +1235,18 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } private void updateBookContents(List pages, int slotId) { @@ -1758,7 +1702,7 @@ index 31cd9c04b06fa691305c078e3c428a9e0d717ecf..fab3ce46529e2619e598c73421c06768 itemstack.set(DataComponents.WRITABLE_BOOK_CONTENT, new WritableBookContent(list1)); this.player.getInventory().setItem(slotId, CraftEventFactory.handleEditBookEvent(this.player, slotId, handItem, itemstack)); // CraftBukkit // Paper - Don't ignore result (see other callsite for handleEditBookEvent) -@@ -1246,6 +1284,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1216,6 +1254,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } private void signBook(FilteredText title, List pages, int slotId) { @@ -1770,7 +1714,7 @@ index 31cd9c04b06fa691305c078e3c428a9e0d717ecf..fab3ce46529e2619e598c73421c06768 ItemStack itemstack = this.player.getInventory().getItem(slotId); if (itemstack.is(Items.WRITABLE_BOOK)) { -@@ -1253,10 +1296,10 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1223,10 +1266,10 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl itemstack1.remove(DataComponents.WRITABLE_BOOK_CONTENT); List> list1 = (List>) (List) pages.stream().map((filteredtext1) -> { // CraftBukkit - decompile error @@ -1783,7 +1727,7 @@ index 31cd9c04b06fa691305c078e3c428a9e0d717ecf..fab3ce46529e2619e598c73421c06768 CraftEventFactory.handleEditBookEvent(this.player, slotId, itemstack, itemstack1); // CraftBukkit this.player.getInventory().setItem(slotId, itemstack); // CraftBukkit - event factory updates the hand book } -@@ -1266,6 +1309,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1236,6 +1279,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl return this.player.isTextFilteringEnabled() ? Filterable.passThrough(message.filteredOrEmpty()) : Filterable.from(message); } @@ -1800,7 +1744,7 @@ index 31cd9c04b06fa691305c078e3c428a9e0d717ecf..fab3ce46529e2619e598c73421c06768 @Override public void handleEntityTagQuery(ServerboundEntityTagQueryPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); -@@ -1315,8 +1368,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1285,7 +1338,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handleMovePlayer(ServerboundMovePlayerPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); @@ -1812,13 +1756,12 @@ index 31cd9c04b06fa691305c078e3c428a9e0d717ecf..fab3ce46529e2619e598c73421c06768 + boolean invalidYaw = !Floats.isFinite(packet.getYRot(0.0F)); + boolean invalidPitch = !Floats.isFinite(packet.getXRot(0.0F)); + if (invalidX || invalidY || invalidZ || invalidYaw || invalidPitch) { - this.disconnect(Component.translatable("multiplayer.disconnect.invalid_player_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PLAYER_MOVEMENT); // Paper - kick event cause -+ 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 ++ 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 ++ // Purpur end + this.disconnect((Component) Component.translatable("multiplayer.disconnect.invalid_player_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PLAYER_MOVEMENT); // Paper - kick event cause } else { ServerLevel worldserver = this.player.serverLevel(); - -@@ -1503,7 +1564,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1464,7 +1525,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl movedWrongly = true; if (event.getLogWarning()) // Paper end @@ -1827,7 +1770,7 @@ index 31cd9c04b06fa691305c078e3c428a9e0d717ecf..fab3ce46529e2619e598c73421c06768 } // Paper } -@@ -1571,6 +1632,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1522,6 +1583,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.lastYaw = to.getYaw(); this.lastPitch = to.getPitch(); @@ -1836,8 +1779,8 @@ index 31cd9c04b06fa691305c078e3c428a9e0d717ecf..fab3ce46529e2619e598c73421c06768 Location oldTo = to.clone(); PlayerMoveEvent event = new PlayerMoveEvent(player, from, to); this.cserver.getPluginManager().callEvent(event); -@@ -1612,6 +1675,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - this.player.resetCurrentImpulseContext(); +@@ -1566,6 +1629,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + this.player.tryResetCurrentImpulseContext(); } + // Purpur Start @@ -1850,11 +1793,10 @@ index 31cd9c04b06fa691305c078e3c428a9e0d717ecf..fab3ce46529e2619e598c73421c06768 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(); -@@ -1651,6 +1721,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - return false; +@@ -1593,6 +1663,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + } } - // Paper end - optimise out extra getCubes -+ + + // Purpur start + public boolean isScissor(ItemStack stack) { + if (!stack.is(Items.SHEARS)) return false; @@ -1866,7 +1808,7 @@ index 31cd9c04b06fa691305c078e3c428a9e0d717ecf..fab3ce46529e2619e598c73421c06768 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)); -@@ -1661,7 +1740,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1603,7 +1681,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl do { if (!iterator.hasNext()) { @@ -1875,7 +1817,7 @@ index 31cd9c04b06fa691305c078e3c428a9e0d717ecf..fab3ce46529e2619e598c73421c06768 } voxelshape1 = (VoxelShape) iterator.next(); -@@ -1999,6 +2078,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1945,6 +2023,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl boolean cancelled; if (movingobjectposition == null || movingobjectposition.getType() != HitResult.Type.BLOCK) { @@ -1883,7 +1825,7 @@ index 31cd9c04b06fa691305c078e3c428a9e0d717ecf..fab3ce46529e2619e598c73421c06768 org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.RIGHT_CLICK_AIR, itemstack, enumhand); cancelled = event.useItemInHand() == Event.Result.DENY; } else { -@@ -2768,6 +2848,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2714,6 +2793,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl AABB axisalignedbb = entity.getBoundingBox(); if (this.player.canInteractWithEntity(axisalignedbb, 1.0D)) { @@ -1891,7 +1833,7 @@ index 31cd9c04b06fa691305c078e3c428a9e0d717ecf..fab3ce46529e2619e598c73421c06768 packet.dispatch(new ServerboundInteractPacket.Handler() { private void performInteraction(InteractionHand enumhand, ServerGamePacketListenerImpl.EntityInteraction playerconnection_a, PlayerInteractEntityEvent event) { // CraftBukkit ItemStack itemstack = ServerGamePacketListenerImpl.this.player.getItemInHand(enumhand); -@@ -2781,6 +2862,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2727,6 +2807,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl ServerGamePacketListenerImpl.this.cserver.getPluginManager().callEvent(event); @@ -1899,12 +1841,12 @@ index 31cd9c04b06fa691305c078e3c428a9e0d717ecf..fab3ce46529e2619e598c73421c06768 + // 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.resendPossiblyDesyncedEntityData(ServerGamePacketListenerImpl.this.player); // Paper - The entire mob gets deleted, so resend it. + entity.resendPossiblyDesyncedEntityData(ServerGamePacketListenerImpl.this.player); // Paper - The entire mob gets deleted, so resend it diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index a2c9ca5bab0b78fdddcfb110aed9718f9ac99c06..52c5ce7339029d7cc3bb1164131a9f96598760c0 100644 +index 00920e9124336908d17d6725f90e18407e43cdba..80fdfc08e57ff3d524956aa9651bfe3cba3efc7b 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -@@ -330,7 +330,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, +@@ -329,7 +329,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, ServerLoginPacketListenerImpl.LOGGER.warn("Failed to verify username but will let them in anyway!"); ServerLoginPacketListenerImpl.this.startClientVerification(ServerLoginPacketListenerImpl.this.createOfflineProfile(s1)); // Spigot } else { @@ -1914,10 +1856,10 @@ index a2c9ca5bab0b78fdddcfb110aed9718f9ac99c06..52c5ce7339029d7cc3bb1164131a9f96 } } catch (AuthenticationUnavailableException authenticationunavailableexception) { diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index d297f558045f13a3c64776de8250bff23d3fe50e..ce4763458258bd5685d3ec02278b6ed829ebf705 100644 +index b74f809138d657bcfcaa68fc30984e591b1e908b..d2153c3e909e7e75529ce6e41d649bf54b48752b 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -502,6 +502,7 @@ public abstract class PlayerList { +@@ -494,6 +494,7 @@ public abstract class PlayerList { scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam); } // Paper end - Configurable player collision @@ -1925,7 +1867,7 @@ index d297f558045f13a3c64776de8250bff23d3fe50e..ce4763458258bd5685d3ec02278b6ed8 if (GaleGlobalConfiguration.get().logToConsole.playerLoginLocations) { // Gale - JettPack - make logging login location configurable PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", player.getName().getString(), s1, player.getId(), worldserver1.serverLevelData.getLevelName(), player.getX(), player.getY(), player.getZ()); // Gale start - JettPack - make logging login location configurable -@@ -619,6 +620,7 @@ public abstract class PlayerList { +@@ -610,6 +611,7 @@ public abstract class PlayerList { } public net.kyori.adventure.text.Component remove(ServerPlayer entityplayer, net.kyori.adventure.text.Component leaveMessage) { // Paper end - Fix kick event leave message not being sent @@ -1933,7 +1875,7 @@ index d297f558045f13a3c64776de8250bff23d3fe50e..ce4763458258bd5685d3ec02278b6ed8 ServerLevel worldserver = entityplayer.serverLevel(); entityplayer.awardStat(Stats.LEAVE_GAME); -@@ -775,7 +777,7 @@ public abstract class PlayerList { +@@ -766,7 +768,7 @@ public abstract class PlayerList { event.disallow(PlayerLoginEvent.Result.KICK_BANNED, io.papermc.paper.adventure.PaperAdventure.asAdventure(ichatmutablecomponent)); // Paper - Adventure } else { // return this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameprofile) ? IChatBaseComponent.translatable("multiplayer.disconnect.server_full") : null; @@ -1942,7 +1884,7 @@ index d297f558045f13a3c64776de8250bff23d3fe50e..ce4763458258bd5685d3ec02278b6ed8 event.disallow(PlayerLoginEvent.Result.KICK_FULL, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.serverFullMessage)); // Spigot // Paper - Adventure } } -@@ -1127,6 +1129,20 @@ public abstract class PlayerList { +@@ -1077,6 +1079,20 @@ public abstract class PlayerList { } // CraftBukkit end @@ -1963,7 +1905,7 @@ index d297f558045f13a3c64776de8250bff23d3fe50e..ce4763458258bd5685d3ec02278b6ed8 public void broadcastAll(Packet packet, ResourceKey dimension) { Iterator iterator = this.players.iterator(); -@@ -1230,6 +1246,7 @@ public abstract class PlayerList { +@@ -1180,6 +1196,7 @@ public abstract class PlayerList { } else { b0 = (byte) (24 + permissionLevel); } @@ -1971,7 +1913,7 @@ index d297f558045f13a3c64776de8250bff23d3fe50e..ce4763458258bd5685d3ec02278b6ed8 player.connection.send(new ClientboundEntityEventPacket(player, b0)); } -@@ -1238,6 +1255,27 @@ public abstract class PlayerList { +@@ -1188,6 +1205,27 @@ public abstract class PlayerList { player.getBukkitEntity().recalculatePermissions(); // CraftBukkit this.server.getCommands().sendCommands(player); } // Paper - Add sendOpLevel API @@ -2034,19 +1976,19 @@ index 0bd191acb9596d3aa21c337230d26f09d26f6888..20211f40aeeade9217ece087688974bd return false; } diff --git a/src/main/java/net/minecraft/world/damagesource/CombatRules.java b/src/main/java/net/minecraft/world/damagesource/CombatRules.java -index ddc880ac0c8378bc1132be5deba746c1484c941c..7a8e4b9a9f2e1e5a9c38ad330c75df1f880d3e8b 100644 +index 064c1e33f3feee77837bb57887877ae1ca39548d..ffd009bca3fdbfd0b14df78072ef8d472a57cd65 100644 --- a/src/main/java/net/minecraft/world/damagesource/CombatRules.java +++ b/src/main/java/net/minecraft/world/damagesource/CombatRules.java -@@ -12,7 +12,7 @@ public class CombatRules { +@@ -15,7 +15,7 @@ public class CombatRules { - public static float getDamageAfterAbsorb(float damage, DamageSource source, float armor, float armorToughnesss) { - float f = 2.0F + armorToughnesss / 4.0F; -- float g = Mth.clamp(armor - damage / f, armor * 0.2F, 20.0F); -+ float g = Mth.clamp(armor - damage / f, armor * 0.2F, org.purpurmc.purpur.PurpurConfig.limitArmor ? 20F : Float.MAX_VALUE); // Purpur + public static float getDamageAfterAbsorb(LivingEntity armorWearer, float damageAmount, DamageSource damageSource, float armor, float armorToughness) { + float f = 2.0F + armorToughness / 4.0F; +- float g = Mth.clamp(armor - damageAmount / f, armor * 0.2F, 20.0F); ++ float g = Mth.clamp(armor - damageAmount / f, armor * 0.2F, org.purpurmc.purpur.PurpurConfig.limitArmor ? 20F : Float.MAX_VALUE); // Purpur float h = g / 25.0F; - float i = EnchantmentHelper.calculateArmorBreach(source.getEntity(), h); - float j = 1.0F - i; -@@ -20,7 +20,7 @@ public class CombatRules { + ItemStack itemStack = damageSource.getWeaponItem(); + float i; +@@ -30,7 +30,7 @@ public class CombatRules { } public static float getDamageAfterMagicAbsorb(float damageDealt, float protection) { @@ -2083,7 +2025,7 @@ index 99a7e9eb75231c15bd8bb24fbb4e296bc9fdedff..4fb025a63628eb60509d90b680922a02 } } diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSource.java b/src/main/java/net/minecraft/world/damagesource/DamageSource.java -index dd9638bdb228a53e72820e0e7cf6fe6fcc08fe4b..1ce1235cbbf23fe975c85a0f713280b433459951 100644 +index 379b36944ddb149e2f48221aa39ad090bbd2faeb..91a5be2eaedb0fa94580de60a9625f94ae724235 100644 --- a/src/main/java/net/minecraft/world/damagesource/DamageSource.java +++ b/src/main/java/net/minecraft/world/damagesource/DamageSource.java @@ -29,6 +29,8 @@ public class DamageSource { @@ -2131,7 +2073,7 @@ index dd9638bdb228a53e72820e0e7cf6fe6fcc08fe4b..1ce1235cbbf23fe975c85a0f713280b4 return damageSource; } // CraftBukkit end -@@ -189,10 +213,19 @@ public class DamageSource { +@@ -194,10 +218,19 @@ public class DamageSource { ItemStack itemstack1 = itemstack; @@ -2153,10 +2095,10 @@ index dd9638bdb228a53e72820e0e7cf6fe6fcc08fe4b..1ce1235cbbf23fe975c85a0f713280b4 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 5ec8cbd07a1830876f58e1fd33de6df4466d7e95..b1fb94380b7d6bd2a3be31a4e8fe95367e948fe2 100644 +index e34584e4780f343d6c946af5377088d53818e88e..d143bba490bfb677361ab82c44f0f31a4a2a43d6 100644 --- a/src/main/java/net/minecraft/world/damagesource/DamageSources.java +++ b/src/main/java/net/minecraft/world/damagesource/DamageSources.java -@@ -44,11 +44,15 @@ public class DamageSources { +@@ -45,11 +45,15 @@ public class DamageSources { // CraftBukkit start private final DamageSource melting; private final DamageSource poison; @@ -2171,8 +2113,8 @@ index 5ec8cbd07a1830876f58e1fd33de6df4466d7e95..b1fb94380b7d6bd2a3be31a4e8fe9536 + this.stonecutter = this.source(DamageTypes.MAGIC).stonecutter(); // Purpur // CraftBukkit end this.inFire = this.source(DamageTypes.IN_FIRE); - this.lightningBolt = this.source(DamageTypes.LIGHTNING_BOLT); -@@ -97,6 +101,15 @@ public class DamageSources { + this.campfire = this.source(DamageTypes.CAMPFIRE); +@@ -99,6 +103,15 @@ public class DamageSources { } // CraftBukkit end @@ -2256,19 +2198,19 @@ index f43bf280999ff3860cc702def50cc62b131eb1bd..66d9e99a351f5fc6cf58be3bee4397d9 } diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index a89689464d0692491d242489a4b806cde1e37bb9..2afa65c3c8ee8e502fa473bf0b485a02b32989f7 100644 +index 55f544a7a7253cd6619ef43d26f17b38ccb375ea..d05aa2a4a88d6c160abf1f10eeb8f1485070a9d4 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -163,7 +163,7 @@ import org.bukkit.plugin.PluginManager; +@@ -168,7 +168,7 @@ import org.bukkit.plugin.PluginManager; // CraftBukkit end - public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, CommandSource, ScoreHolder { + public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, CommandSource, ScoreHolder, ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity { // Paper - rewrite chunk system - + public static javax.script.ScriptEngine scriptEngine = new javax.script.ScriptEngineManager().getEngineByName("rhino"); // Purpur // CraftBukkit start private static final int CURRENT_LEVEL = 2; public boolean preserveMotion = true; // Paper - Fix Entity Teleportation and cancel velocity if teleported; keep initial motion on first setPositionRotation -@@ -340,6 +340,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -344,6 +344,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public double xOld; public double yOld; public double zOld; @@ -2276,7 +2218,7 @@ index a89689464d0692491d242489a4b806cde1e37bb9..2afa65c3c8ee8e502fa473bf0b485a02 public boolean noPhysics; public final RandomSource random; public int tickCount; -@@ -381,7 +382,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -384,7 +385,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess private final Set tags; private final double[] pistonDeltas; private long pistonDeltasGameTime; @@ -2285,7 +2227,7 @@ index a89689464d0692491d242489a4b806cde1e37bb9..2afa65c3c8ee8e502fa473bf0b485a02 private float eyeHeight; public boolean isInPowderSnow; public boolean wasInPowderSnow; -@@ -428,6 +429,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -432,6 +433,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public boolean fixedPose = false; // Paper - Expand Pose API public boolean activatedPriorityReset = false; // Pufferfish - DAB public int activatedPriority = org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.maximumActivationPrio; // Pufferfish - DAB (golf score) @@ -2293,15 +2235,17 @@ index a89689464d0692491d242489a4b806cde1e37bb9..2afa65c3c8ee8e502fa473bf0b485a02 public void setOrigin(@javax.annotation.Nonnull Location location) { this.origin = location.toVector(); -@@ -560,6 +562,25 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - return false; +@@ -533,6 +535,27 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + return this.getIndirectPassengersStream().anyMatch((entity) -> entity instanceof Player); } - + // Paper end - rewrite chunk system ++ // Purpur start + public boolean canSaveToDisk() { + return true; + } ++ // Purpur end + -+ // Purpur start - copied from Mob ++ // Purpur start - copied from Mob - API for any mob to burn daylight + public boolean isSunBurnTick() { + if (this.level().isDay() && !this.level().isClientSide) { + float f = this.getLightLevelDependentMagicValue(); @@ -2315,11 +2259,11 @@ index a89689464d0692491d242489a4b806cde1e37bb9..2afa65c3c8ee8e502fa473bf0b485a02 + + return false; + } -+ - public final boolean hardCollides() { - return this.hardCollides; - } -@@ -580,7 +601,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess ++ // Purpur end - copied from Mob - API for any mob to burn daylight + + public Entity(EntityType type, Level world) { + this.id = Entity.ENTITY_COUNTER.incrementAndGet(); +@@ -541,7 +564,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.bb = Entity.INITIAL_AABB; this.stuckSpeedMultiplier = Vec3.ZERO; this.nextStep = 1.0F; @@ -2328,7 +2272,7 @@ index a89689464d0692491d242489a4b806cde1e37bb9..2afa65c3c8ee8e502fa473bf0b485a02 this.remainingFireTicks = -this.getFireImmuneTicks(); this.fluidHeight = new Object2DoubleArrayMap(2); this.fluidOnEyes = new HashSet(); -@@ -960,10 +981,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -924,10 +947,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public void checkBelowWorld() { // Paper start - Configurable nether ceiling damage @@ -2341,7 +2285,7 @@ index a89689464d0692491d242489a4b806cde1e37bb9..2afa65c3c8ee8e502fa473bf0b485a02 this.onBelowWorld(); } -@@ -1878,7 +1900,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1763,7 +1787,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public boolean fireImmune() { @@ -2350,7 +2294,7 @@ index a89689464d0692491d242489a4b806cde1e37bb9..2afa65c3c8ee8e502fa473bf0b485a02 } public boolean causeFallDamage(float fallDistance, float damageMultiplier, DamageSource damageSource) { -@@ -1951,7 +1973,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1836,7 +1860,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return this.isInWater() || flag; } @@ -2359,7 +2303,7 @@ index a89689464d0692491d242489a4b806cde1e37bb9..2afa65c3c8ee8e502fa473bf0b485a02 Entity entity = this.getVehicle(); if (entity instanceof Boat entityboat) { -@@ -2583,6 +2605,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2483,6 +2507,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess nbttagcompound.putBoolean("Paper.FreezeLock", true); } // Paper end @@ -2371,7 +2315,7 @@ index a89689464d0692491d242489a4b806cde1e37bb9..2afa65c3c8ee8e502fa473bf0b485a02 return nbttagcompound; } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT"); -@@ -2730,6 +2757,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2630,6 +2659,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess freezeLocked = nbt.getBoolean("Paper.FreezeLock"); } // Paper end @@ -2383,7 +2327,15 @@ index a89689464d0692491d242489a4b806cde1e37bb9..2afa65c3c8ee8e502fa473bf0b485a02 } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Loading entity NBT"); -@@ -3114,6 +3146,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2791,6 +2825,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + if (this.isAlive() && this instanceof Leashable leashable) { + if (leashable.getLeashHolder() == player) { + if (!this.level().isClientSide()) { ++ if (hand == InteractionHand.OFF_HAND && (level().purpurConfig.villagerCanBeLeashed || level().purpurConfig.wanderingTraderCanBeLeashed) && this instanceof net.minecraft.world.entity.npc.AbstractVillager) return InteractionResult.CONSUME; // Purpur + // CraftBukkit start - fire PlayerUnleashEntityEvent + // Paper start - Expand EntityUnleashEvent + org.bukkit.event.player.PlayerUnleashEntityEvent event = CraftEventFactory.callPlayerUnleashEntityEvent(this, player, hand, !player.hasInfiniteMaterials()); +@@ -2994,6 +3029,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.passengers = ImmutableList.copyOf(list); } @@ -2397,7 +2349,7 @@ index a89689464d0692491d242489a4b806cde1e37bb9..2afa65c3c8ee8e502fa473bf0b485a02 this.gameEvent(GameEvent.ENTITY_MOUNT, passenger); } } -@@ -3153,6 +3192,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -3033,6 +3075,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return false; } // CraftBukkit end @@ -2412,24 +2364,24 @@ index a89689464d0692491d242489a4b806cde1e37bb9..2afa65c3c8ee8e502fa473bf0b485a02 if (this.passengers.size() == 1 && this.passengers.get(0) == entity) { this.passengers = ImmutableList.of(); } else { -@@ -3231,12 +3278,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -3111,13 +3161,16 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return Vec3.directionFromRotation(this.getRotationVector()); } + public BlockPos portalPos = BlockPos.ZERO; // Purpur - public void handleInsidePortal(BlockPos pos) { + public void setAsInsidePortal(Portal portal, BlockPos pos) { if (this.isOnPortalCooldown()) { + 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)) { - this.portalEntrancePos = pos.immutable(); + } else { + if (this.portalProcess != null && this.portalProcess.isSamePortal(portal)) { + this.portalProcess.updateEntryPosition(pos.immutable()); + this.portalProcess.setAsInsidePortalThisTick(true); + portalPos = BlockPos.ZERO; // Purpur + } else { + this.portalProcess = new PortalProcessor(portal, pos.immutable()); } - - this.isInsidePortal = true; -@@ -3461,7 +3511,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -3325,7 +3378,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public int getMaxAirSupply() { @@ -2438,16 +2390,7 @@ index a89689464d0692491d242489a4b806cde1e37bb9..2afa65c3c8ee8e502fa473bf0b485a02 } public int getAirSupply() { -@@ -3928,7 +3978,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - } - - public boolean canChangeDimensions() { -- return !this.isPassenger() && !this.isVehicle() && isAlive() && valid; // Paper - Fix item duplication and teleport issues -+ return !this.isPassenger() && !this.isVehicle() && isAlive() && valid && (level().purpurConfig.entitiesCanUsePortals || this instanceof ServerPlayer); // Paper - Fix item duplication and teleport issues // Purpur - } - - public float getBlockExplosionResistance(Explosion explosion, BlockGetter world, BlockPos pos, BlockState blockState, FluidState fluidState, float max) { -@@ -4229,6 +4279,20 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4054,6 +4107,20 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return SlotAccess.NULL; } @@ -2468,8 +2411,8 @@ index a89689464d0692491d242489a4b806cde1e37bb9..2afa65c3c8ee8e502fa473bf0b485a02 @Override public void sendSystemMessage(Component message) {} -@@ -4516,6 +4580,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - this.yRotO = this.getYRot(); +@@ -4322,6 +4389,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + return Mth.lerp(delta, this.yRotO, this.yRot); } + // Purpur start @@ -2481,7 +2424,7 @@ index a89689464d0692491d242489a4b806cde1e37bb9..2afa65c3c8ee8e502fa473bf0b485a02 public boolean updateFluidHeightAndDoFluidPushing(TagKey tag, double speed) { if (false && this.touchingUnloadedChunk()) { // Gale - Airplane - reduce entity fluid lookups if no fluids - cost of a lookup here is the same cost as below, so skip return false; -@@ -4924,7 +4994,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4729,7 +4802,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public float maxUpStep() { @@ -2490,7 +2433,7 @@ index a89689464d0692491d242489a4b806cde1e37bb9..2afa65c3c8ee8e502fa473bf0b485a02 } public void onExplosionHit(@Nullable Entity entity) {} -@@ -5096,4 +5166,44 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4921,4 +4994,44 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return ((net.minecraft.server.level.ServerChunkCache) level.getChunkSource()).isPositionTicking(this); } // Paper end - Expose entity id counter @@ -2548,7 +2491,7 @@ index d8cc5614502db7025349e085381b6b32ad32296a..f1b9e83206cc67e6ef29ebe088351b0a private EntitySelector() {} // Paper start - Affects Spawning API diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index e6edbe6177b168d85759bd9c414dc87ea8a394fe..32a1b5a1d01fd4dc603a76fde259f3a0d4749fad 100644 +index f9440014ab2fe753c16b9383f5fffbb8adb76e79..d3de0362dd1ef3954d05c4d8fa56a25edfe1bb2b 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java @@ -324,7 +324,8 @@ public class EntityType implements FeatureElement, EntityTypeT @@ -2567,7 +2510,7 @@ index e6edbe6177b168d85759bd9c414dc87ea8a394fe..32a1b5a1d01fd4dc603a76fde259f3a0 + // Purpur start + public static EntityType getFromBukkitType(org.bukkit.entity.EntityType bukkitType) { -+ return getFromKey(new ResourceLocation(bukkitType.getKey().toString())); ++ return getFromKey(ResourceLocation.parse(bukkitType.getKey().toString())); + } + + public static EntityType getFromKey(ResourceLocation location) { @@ -2609,50 +2552,32 @@ index e6edbe6177b168d85759bd9c414dc87ea8a394fe..32a1b5a1d01fd4dc603a76fde259f3a0 } diff --git a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java -index 46d8bcad1545953757659870901cbbdf3340bc15..40d168d225932717b8ac8bdd27dfe2a202bc2808 100644 +index 15844971ce2cca8c679ad3aaa2dfe160e6d0b564..3003f2ab38008b761bee49823b49edae67cd5292 100644 --- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java +++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java -@@ -326,7 +326,7 @@ public class ExperienceOrb extends Entity { +@@ -329,7 +329,7 @@ public class ExperienceOrb extends Entity { public void playerTouch(Player player) { - if (!this.level().isClientSide) { - if (player.takeXpDelay == 0 && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) { // Paper - PlayerPickupExperienceEvent + if (player instanceof ServerPlayer entityplayer) { + if (player.takeXpDelay == 0 && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(entityplayer.getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) { // Paper - PlayerPickupExperienceEvent - 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.take(this, 1); - int i = this.repairPlayerItems(player, this.value); + int i = this.repairPlayerItems(entityplayer, this.value); -@@ -344,7 +344,7 @@ public class ExperienceOrb extends Entity { +@@ -347,7 +347,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 + private int repairPlayerItems(ServerPlayer player, int amount) { +- Optional optional = EnchantmentHelper.getRandomItemWith(EnchantmentEffectComponents.REPAIR_WITH_XP, player, ItemStack::isDamaged); ++ Optional optional = level().purpurConfig.useBetterMending ? EnchantmentHelper.getMostDamagedItemWith(EnchantmentEffectComponents.REPAIR_WITH_XP, player) : EnchantmentHelper.getRandomItemWith(EnchantmentEffectComponents.REPAIR_WITH_XP, player, ItemStack::isDamaged); // Purpur - Add option to mend the most damaged equipment first - if (entry != null) { - ItemStack itemstack = (ItemStack) entry.getValue(); -@@ -372,13 +372,15 @@ public class ExperienceOrb extends Entity { - } - } - -+ // Purpur start - public int durabilityToXp(int repairAmount) { -- return repairAmount / 2; -+ return (int) (repairAmount / (2 * level().purpurConfig.mendingMultiplier)); - } - - public int xpToDurability(int experienceAmount) { -- return experienceAmount * 2; -+ return (int) ((experienceAmount * 2) * level().purpurConfig.mendingMultiplier); - } -+ // Purpur end - - public int getValue() { - return this.value; + if (optional.isPresent()) { + ItemStack itemstack = ((EnchantedItemInUse) optional.get()).itemStack(); diff --git a/src/main/java/net/minecraft/world/entity/GlowSquid.java b/src/main/java/net/minecraft/world/entity/GlowSquid.java -index 09fdea983772612ef3fff6b2da3cf469a34e4ec0..b69d924fa8034eabbf4aab8d3434f4f4e2529373 100644 +index 09fdea983772612ef3fff6b2da3cf469a34e4ec0..3e2ea26c23e88c395856b65001f2895db6a52bd4 100644 --- a/src/main/java/net/minecraft/world/entity/GlowSquid.java +++ b/src/main/java/net/minecraft/world/entity/GlowSquid.java -@@ -23,6 +23,38 @@ public class GlowSquid extends Squid { +@@ -23,6 +23,39 @@ public class GlowSquid extends Squid { super(type, world); } @@ -2662,6 +2587,7 @@ index 09fdea983772612ef3fff6b2da3cf469a34e4ec0..b69d924fa8034eabbf4aab8d3434f4f4 + return level().purpurConfig.glowSquidRidable; + } + ++ + @Override + public boolean isControllable() { + return level().purpurConfig.glowSquidControllable; @@ -2692,10 +2618,10 @@ index 09fdea983772612ef3fff6b2da3cf469a34e4ec0..b69d924fa8034eabbf4aab8d3434f4f4 protected ParticleOptions getInkParticle() { return ParticleTypes.GLOW_SQUID_INK; diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 546ec288ae19597aa9a1ca25430339109a19df81..3fa3191d98f51b447961ac584bebac5ef2c5fbbc 100644 +index 620f59c9563d7215ee04176eaa74872918f011d6..a0609bce7035188b48a0f84ebf79ebc5682c94d8 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -228,9 +228,9 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -236,9 +236,9 @@ public abstract class LivingEntity extends Entity implements Attackable { protected int deathScore; public float lastHurt; public boolean jumping; @@ -2708,17 +2634,17 @@ index 546ec288ae19597aa9a1ca25430339109a19df81..3fa3191d98f51b447961ac584bebac5e protected int lerpSteps; protected double lerpX; protected double lerpY; -@@ -273,6 +273,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -285,6 +285,7 @@ public abstract class LivingEntity extends Entity implements Attackable { public org.bukkit.craftbukkit.entity.CraftLivingEntity getBukkitLivingEntity() { return (org.bukkit.craftbukkit.entity.CraftLivingEntity) super.getBukkitEntity(); } // Paper public boolean silentDeath = false; // Paper - mark entity as dying silently for cancellable death event public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Friction API -+ protected boolean shouldBurnInDay = false; public boolean shouldBurnInDay() { return this.shouldBurnInDay; } public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; } // Purpur ++ protected boolean shouldBurnInDay = false; public boolean shouldBurnInDay() { return this.shouldBurnInDay; } public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; } // Purpur - API for any mob to burn daylight @Override public float getBukkitYaw() { -@@ -299,7 +300,8 @@ public abstract class LivingEntity extends Entity implements Attackable { - this.useItem = ItemStack.EMPTY; +@@ -312,7 +313,8 @@ public abstract class LivingEntity extends Entity implements Attackable { this.lastClimbablePos = Optional.empty(); + this.activeLocationDependentEnchantments = new Reference2ObjectArrayMap(); this.appliedScale = 1.0F; - this.attributes = new AttributeMap(DefaultAttributes.getSupplier(type)); + this.attributes = new AttributeMap(DefaultAttributes.getSupplier(type), this); // Purpur @@ -2726,7 +2652,7 @@ index 546ec288ae19597aa9a1ca25430339109a19df81..3fa3191d98f51b447961ac584bebac5e 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()); -@@ -314,6 +316,8 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -327,6 +329,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())))); } @@ -2735,15 +2661,15 @@ index 546ec288ae19597aa9a1ca25430339109a19df81..3fa3191d98f51b447961ac584bebac5e public Brain getBrain() { return this.brain; } -@@ -349,6 +353,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -362,6 +366,7 @@ public abstract class LivingEntity extends Entity implements Attackable { public static AttributeSupplier.Builder createLivingAttributes() { - return AttributeSupplier.builder().add(Attributes.MAX_HEALTH).add(Attributes.KNOCKBACK_RESISTANCE).add(Attributes.MOVEMENT_SPEED).add(Attributes.ARMOR).add(Attributes.ARMOR_TOUGHNESS).add(Attributes.MAX_ABSORPTION).add(Attributes.STEP_HEIGHT).add(Attributes.SCALE).add(Attributes.GRAVITY).add(Attributes.SAFE_FALL_DISTANCE).add(Attributes.FALL_DAMAGE_MULTIPLIER).add(Attributes.JUMP_STRENGTH); + return AttributeSupplier.builder().add(Attributes.MAX_HEALTH).add(Attributes.KNOCKBACK_RESISTANCE).add(Attributes.MOVEMENT_SPEED).add(Attributes.ARMOR).add(Attributes.ARMOR_TOUGHNESS).add(Attributes.MAX_ABSORPTION).add(Attributes.STEP_HEIGHT).add(Attributes.SCALE).add(Attributes.GRAVITY).add(Attributes.SAFE_FALL_DISTANCE).add(Attributes.FALL_DAMAGE_MULTIPLIER).add(Attributes.JUMP_STRENGTH).add(Attributes.OXYGEN_BONUS).add(Attributes.BURNING_TIME).add(Attributes.EXPLOSION_KNOCKBACK_RESISTANCE).add(Attributes.WATER_MOVEMENT_EFFICIENCY).add(Attributes.MOVEMENT_EFFICIENCY).add(Attributes.ATTACK_KNOCKBACK); } + public boolean shouldSendAttribute(Attribute attribute) { return true; } // Purpur @Override protected void checkFallDamage(double heightDifference, boolean onGround, BlockState state, BlockPos landedPosition) { -@@ -437,6 +442,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -459,6 +464,7 @@ public abstract class LivingEntity extends Entity implements Attackable { double d1 = this.level().getWorldBorder().getDamagePerBlock(); if (d1 > 0.0D) { @@ -2751,7 +2677,7 @@ index 546ec288ae19597aa9a1ca25430339109a19df81..3fa3191d98f51b447961ac584bebac5e this.hurt(this.damageSources().outOfBorder(), (float) Math.max(1, Mth.floor(-d0 * d1))); } } -@@ -448,7 +454,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -470,7 +476,7 @@ public abstract class LivingEntity extends Entity implements Attackable { if (flag1) { this.setAirSupply(this.decreaseAirSupply(this.getAirSupply())); @@ -2760,7 +2686,7 @@ index 546ec288ae19597aa9a1ca25430339109a19df81..3fa3191d98f51b447961ac584bebac5e this.setAirSupply(0); Vec3 vec3d = this.getDeltaMovement(); -@@ -460,7 +466,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -482,7 +488,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); } @@ -2769,27 +2695,27 @@ index 546ec288ae19597aa9a1ca25430339109a19df81..3fa3191d98f51b447961ac584bebac5e } } -@@ -835,6 +841,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -809,6 +815,7 @@ public abstract class LivingEntity extends Entity implements Attackable { dataresult.resultOrPartial(logger::error).ifPresent((nbtbase) -> { nbt.put("Brain", nbtbase); }); -+ nbt.putBoolean("Purpur.ShouldBurnInDay", shouldBurnInDay); // Purpur ++ nbt.putBoolean("Purpur.ShouldBurnInDay", this.shouldBurnInDay); // Purpur - API for any mob to burn daylight } @Override -@@ -922,6 +929,11 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -897,6 +904,11 @@ public abstract class LivingEntity extends Entity implements Attackable { this.brain = this.makeBrain(new Dynamic(NbtOps.INSTANCE, nbt.get("Brain"))); } -+ // Purpur start ++ // Purpur start - API for any mob to burn daylight + if (nbt.contains("Purpur.ShouldBurnInDay")) { -+ shouldBurnInDay = nbt.getBoolean("Purpur.ShouldBurnInDay"); ++ this.shouldBurnInDay = nbt.getBoolean("Purpur.ShouldBurnInDay"); + } -+ // Purpur end ++ // Purpur end - API for any mob to burn daylight } // CraftBukkit start -@@ -1056,9 +1068,28 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1031,9 +1043,28 @@ public abstract class LivingEntity extends Entity implements Attackable { if (entity != null) { EntityType entitytypes = entity.getType(); @@ -2820,7 +2746,7 @@ index 546ec288ae19597aa9a1ca25430339109a19df81..3fa3191d98f51b447961ac584bebac5e } return d0; -@@ -1117,6 +1148,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1092,6 +1123,7 @@ public abstract class LivingEntity extends Entity implements Attackable { for (flag = false; iterator.hasNext(); flag = true) { // CraftBukkit start MobEffectInstance effect = (MobEffectInstance) iterator.next(); @@ -2828,7 +2754,7 @@ index 546ec288ae19597aa9a1ca25430339109a19df81..3fa3191d98f51b447961ac584bebac5e EntityPotionEffectEvent event = CraftEventFactory.callEntityPotionEffectChangeEvent(this, effect, null, cause, EntityPotionEffectEvent.Action.CLEARED); if (event.isCancelled()) { continue; -@@ -1452,6 +1484,24 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1429,6 +1461,24 @@ public abstract class LivingEntity extends Entity implements Attackable { this.stopSleeping(); } @@ -2853,7 +2779,7 @@ index 546ec288ae19597aa9a1ca25430339109a19df81..3fa3191d98f51b447961ac584bebac5e this.noActionTime = 0; float f1 = amount; boolean flag = amount > 0.0F && this.isDamageSourceBlocked(source); // Copied from below -@@ -1527,13 +1577,13 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1504,13 +1554,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; @@ -2869,7 +2795,7 @@ index 546ec288ae19597aa9a1ca25430339109a19df81..3fa3191d98f51b447961ac584bebac5e LivingEntity entityliving2 = entitywolf.getOwner(); if (entityliving2 instanceof net.minecraft.world.entity.player.Player) { -@@ -1648,6 +1698,18 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1631,6 +1681,18 @@ public abstract class LivingEntity extends Entity implements Attackable { } } @@ -2888,7 +2814,7 @@ index 546ec288ae19597aa9a1ca25430339109a19df81..3fa3191d98f51b447961ac584bebac5e 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); -@@ -1814,7 +1876,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1797,7 +1859,7 @@ public abstract class LivingEntity extends Entity implements Attackable { boolean flag = false; if (this.dead && adversary instanceof WitherBoss) { // Paper @@ -2897,22 +2823,24 @@ index 546ec288ae19597aa9a1ca25430339109a19df81..3fa3191d98f51b447961ac584bebac5e BlockPos blockposition = this.blockPosition(); BlockState iblockdata = Blocks.WITHER_ROSE.defaultBlockState(); -@@ -1860,6 +1922,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1833,7 +1895,8 @@ public abstract class LivingEntity extends Entity implements Attackable { + boolean flag = this.lastHurtByPlayerTime > 0; 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 - this.dropFromLootTable(source, flag); +- if (this.shouldDropLoot() && world.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { ++ if (this.shouldDropLoot() && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { ++ if (!(damageSource.is(net.minecraft.world.damagesource.DamageTypes.CRAMMING) && level().purpurConfig.disableDropsOnCrammingDeath)) { // Purpur + this.dropFromLootTable(damageSource, flag); // Paper start final boolean prev = this.clearEquipmentSlots; -@@ -1868,6 +1931,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1842,6 +1905,7 @@ public abstract class LivingEntity extends Entity implements Attackable { // Paper end - this.dropCustomDeathLoot(source, i, flag); + this.dropCustomDeathLoot(world, damageSource, flag); this.clearEquipmentSlots = prev; // Paper + } // Purpur } // CraftBukkit start - Call death event // Paper start - call advancement triggers with correct entity equipment - org.bukkit.event.entity.EntityDeathEvent deathEvent = CraftEventFactory.callEntityDeathEvent(this, source, this.drops, () -> { + org.bukkit.event.entity.EntityDeathEvent deathEvent = CraftEventFactory.callEntityDeathEvent(this, damageSource, this.drops, () -> { @@ -2614,7 +2678,7 @@ public abstract class LivingEntity extends Entity implements Attackable { @Override @@ -2922,16 +2850,7 @@ index 546ec288ae19597aa9a1ca25430339109a19df81..3fa3191d98f51b447961ac584bebac5e } protected void updateSwingTime() { -@@ -2809,7 +2873,7 @@ public abstract class LivingEntity extends Entity implements Attackable { - } - - protected long lastJumpTime = 0L; // Paper - Prevent excessive velocity through repeated crits -- protected void jumpFromGround() { -+ public void jumpFromGround() { // Purpur - protected -> public - float f = this.getJumpPower(); - - if (f > 1.0E-5F) { -@@ -2969,6 +3033,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2972,6 +3036,7 @@ public abstract class LivingEntity extends Entity implements Attackable { if (f3 > 0.0F) { this.playSound(this.getFallDamageSound((int) f3), 1.0F, 1.0F); @@ -2939,7 +2858,7 @@ index 546ec288ae19597aa9a1ca25430339109a19df81..3fa3191d98f51b447961ac584bebac5e this.hurt(this.damageSources().flyIntoWall(), f3); } } -@@ -3506,8 +3571,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3526,8 +3591,10 @@ public abstract class LivingEntity extends Entity implements Attackable { this.pushEntities(); // Paper start - Add EntityMoveEvent @@ -2952,7 +2871,7 @@ index 546ec288ae19597aa9a1ca25430339109a19df81..3fa3191d98f51b447961ac584bebac5e 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()); -@@ -3517,12 +3584,48 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3537,12 +3604,55 @@ 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()); } } @@ -2977,31 +2896,38 @@ index 546ec288ae19597aa9a1ca25430339109a19df81..3fa3191d98f51b447961ac584bebac5e this.hurt(this.damageSources().drown(), 1.0F); } -+ // Purpur start - copied from Zombie ++ // Purpur start - copied from Zombie - API for any mob to burn daylight + if (this.isAlive()) { -+ boolean flag = this.shouldBurnInDay() && this.isSunBurnTick(); ++ boolean flag = this.shouldBurnInDay() && this.isSunBurnTick(); // Paper - shouldBurnInDay API // Purpur - use shouldBurnInDay() method to handle Phantoms properly - API for any mob to burn daylight ++ + if (flag) { + ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD); ++ + if (!itemstack.isEmpty()) { + if (itemstack.isDamageableItem()) { ++ Item item = itemstack.getItem(); ++ + itemstack.setDamageValue(itemstack.getDamageValue() + this.random.nextInt(2)); + if (itemstack.getDamageValue() >= itemstack.getMaxDamage()) { -+ this.broadcastBreakEvent(EquipmentSlot.HEAD); ++ this.onEquippedItemBroken(item, EquipmentSlot.HEAD); + this.setItemSlot(EquipmentSlot.HEAD, ItemStack.EMPTY); + } + } ++ + flag = false; + } ++ + if (flag) { -+ this.igniteForSeconds(8); ++ if (getRider() == null || !this.isControllable()) // Purpur - ignore mobs which are uncontrollable or without rider - API for any mob to burn daylight ++ this.igniteForSeconds(8.0F); + } + } + } -+ // Purpur end ++ // Purpur end - copied from Zombie - API for any mob to burn daylight } public boolean isSensitiveToWater() { -@@ -3543,7 +3646,16 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3563,7 +3673,16 @@ public abstract class LivingEntity extends Entity implements Attackable { int j = i / 10; if (j % 2 == 0) { @@ -3019,11 +2945,24 @@ index 546ec288ae19597aa9a1ca25430339109a19df81..3fa3191d98f51b447961ac584bebac5e } this.gameEvent(GameEvent.ELYTRA_GLIDE); +@@ -4502,6 +4621,12 @@ public abstract class LivingEntity extends Entity implements Attackable { + return EquipmentSlot.MAINHAND; + } + ++ // Purpur start - Dispenser curse of binding protection ++ public @Nullable EquipmentSlot getEquipmentSlotForDispenserItem(ItemStack itemstack) { ++ return EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.BINDING_CURSE, itemstack) > 0 ? null : this.getEquipmentSlotForItem(itemstack); ++ } ++ // Purpur end - Dispenser curse of binding protection ++ + private static SlotAccess createEquipmentSlotAccess(LivingEntity entity, EquipmentSlot slot) { + return slot != EquipmentSlot.HEAD && slot != EquipmentSlot.MAINHAND && slot != EquipmentSlot.OFFHAND ? SlotAccess.forEquipmentSlot(entity, slot, (itemstack) -> { + return itemstack.isEmpty() || entity.getEquipmentSlotForItem(itemstack) == slot; diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 0bc60e8a40b4c66e9199d91ad61250d1f0fa93bb..42ba2c7b037aaea4ae16dec8bc1413a15fbb8317 100644 +index 460cd5faf391414bff32c92fc295e29352c7d596..2b4e65eee6fd2ce620238beca649a7f39ca3b2f1 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -150,6 +150,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti +@@ -145,6 +145,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab private BlockPos restrictCenter; private float restrictRadius; @@ -3031,7 +2970,7 @@ index 0bc60e8a40b4c66e9199d91ad61250d1f0fa93bb..42ba2c7b037aaea4ae16dec8bc1413a1 public boolean aware = true; // CraftBukkit protected Mob(EntityType type, Level world) { -@@ -166,8 +167,8 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti +@@ -161,8 +162,8 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab this.goalSelector = new GoalSelector(); this.targetSelector = new GoalSelector(); // Gale end - Purpur - remove vanilla profiler @@ -3042,18 +2981,19 @@ index 0bc60e8a40b4c66e9199d91ad61250d1f0fa93bb..42ba2c7b037aaea4ae16dec8bc1413a1 this.jumpControl = new JumpControl(this); this.bodyRotationControl = this.createBodyControl(); this.navigation = this.createNavigation(world); -@@ -341,6 +342,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti +@@ -336,6 +337,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab entityliving = null; } } -+ if (entityliving instanceof ServerPlayer) this.ticksSinceLastInteraction = 0; // Purpur ++ if (entityliving instanceof net.minecraft.server.level.ServerPlayer) this.ticksSinceLastInteraction = 0; // Purpur this.target = entityliving; return true; // CraftBukkit end -@@ -380,8 +382,28 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti +@@ -375,8 +377,29 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab this.resetAmbientSoundTime(); this.playAmbientSound(); } ++ + incrementTicksSinceLastInteraction(); // Purpur } @@ -3079,7 +3019,7 @@ index 0bc60e8a40b4c66e9199d91ad61250d1f0fa93bb..42ba2c7b037aaea4ae16dec8bc1413a1 @Override protected void playHurtSound(DamageSource damageSource) { this.resetAmbientSoundTime(); -@@ -584,6 +606,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti +@@ -551,6 +574,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab } nbt.putBoolean("Bukkit.Aware", this.aware); // CraftBukkit @@ -3087,7 +3027,7 @@ index 0bc60e8a40b4c66e9199d91ad61250d1f0fa93bb..42ba2c7b037aaea4ae16dec8bc1413a1 } @Override -@@ -668,6 +691,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti +@@ -628,6 +652,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab this.aware = nbt.getBoolean("Bukkit.Aware"); } // CraftBukkit end @@ -3099,7 +3039,7 @@ index 0bc60e8a40b4c66e9199d91ad61250d1f0fa93bb..42ba2c7b037aaea4ae16dec8bc1413a1 } @Override -@@ -718,7 +746,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti +@@ -678,7 +707,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab @Override public void aiStep() { super.aiStep(); @@ -3108,37 +3048,16 @@ index 0bc60e8a40b4c66e9199d91ad61250d1f0fa93bb..42ba2c7b037aaea4ae16dec8bc1413a1 Vec3i baseblockposition = this.getPickupReach(); List list = this.level().getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate((double) baseblockposition.getX(), (double) baseblockposition.getY(), (double) baseblockposition.getZ())); Iterator iterator = list.iterator(); -@@ -1289,6 +1317,12 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti +@@ -1385,7 +1414,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab + attributemodifiable.addPermanentModifier(new AttributeModifier(Mob.RANDOM_SPAWN_BONUS_ID, randomsource.triangle(0.0D, 0.11485000000000001D), AttributeModifier.Operation.ADD_MULTIPLIED_BASE)); + } - } - -+ // Purpur start -+ public static @Nullable EquipmentSlot getSlotForDispenser(ItemStack itemstack) { -+ return EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.BINDING_CURSE, itemstack) > 0 ? null : getEquipmentSlotForItem(itemstack); -+ } -+ // Purpur end -+ - @Nullable - public static Item getEquipmentForSlot(EquipmentSlot equipmentSlot, int equipmentLevel) { - switch (equipmentSlot) { -@@ -1383,7 +1417,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti - RandomSource randomsource = world.getRandom(); - - this.getAttribute(Attributes.FOLLOW_RANGE).addPermanentModifier(new AttributeModifier("Random spawn bonus", randomsource.triangle(0.0D, 0.11485000000000001D), AttributeModifier.Operation.ADD_MULTIPLIED_BASE)); - this.setLeftHanded(randomsource.nextFloat() < 0.05F); + this.setLeftHanded(randomsource.nextFloat() < world.getLevel().purpurConfig.entityLeftHandedChance); // Purpur return entityData; } -@@ -1430,6 +1464,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti - if (!this.isAlive()) { - return InteractionResult.PASS; - } else if (this.getLeashHolder() == player) { -+ if (hand == InteractionHand.OFF_HAND && (level().purpurConfig.villagerCanBeLeashed || level().purpurConfig.wanderingTraderCanBeLeashed) && this instanceof net.minecraft.world.entity.npc.AbstractVillager) return InteractionResult.CONSUME; // Purpur - // CraftBukkit start - fire PlayerUnleashEntityEvent - // Paper start - Expand EntityUnleashEvent - org.bukkit.event.player.PlayerUnleashEntityEvent event = CraftEventFactory.callPlayerUnleashEntityEvent(this, player, hand, !player.hasInfiniteMaterials()); -@@ -1505,7 +1540,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti +@@ -1486,7 +1515,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab protected void onOffspringSpawnedFromEgg(Player player, Mob child) {} protected InteractionResult mobInteract(Player player, InteractionHand hand) { @@ -3147,15 +3066,15 @@ index 0bc60e8a40b4c66e9199d91ad61250d1f0fa93bb..42ba2c7b037aaea4ae16dec8bc1413a1 } public boolean isWithinRestriction() { -@@ -1820,6 +1855,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti - this.setLastHurtMob(target); +@@ -1725,6 +1754,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab + this.playAttackSound(); } -+ if (target instanceof ServerPlayer) this.ticksSinceLastInteraction = 0; // Purpur ++ if (target instanceof net.minecraft.server.level.ServerPlayer) this.ticksSinceLastInteraction = 0; // Purpur return flag; } -@@ -1829,28 +1865,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti +@@ -1736,28 +1766,8 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab // Gale end - JettPack - optimize sun burn tick - cache eye blockpos public boolean isSunBurnTick() { @@ -3181,11 +3100,12 @@ index 0bc60e8a40b4c66e9199d91ad61250d1f0fa93bb..42ba2c7b037aaea4ae16dec8bc1413a1 - } - - return false; ++ // Purpur - implemented in Entity - API for any mob to burn daylight + return super.isSunBurnTick(); } @Override -@@ -1898,4 +1913,56 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti +@@ -1800,4 +1810,56 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab return itemmonsteregg == null ? null : new ItemStack(itemmonsteregg); } @@ -3256,11 +3176,11 @@ index 2ee48ac3b665db2b02bcb1a30ec972d43a3725b0..59e8f5431ce5026209e1428b5fa5b548 } // Paper end - custom shear drops diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java -index 665fbe3362dcd9de4bd290b71a1b1f2fed218eeb..894082d9a8e2aa05f86948bfd335090f37a4ba07 100644 +index f9f6745d45aaba4a7106f80d403dcf9ae40e1d6c..80a8125dda7048cb37fbd4b8f56b59fcb4915b1d 100644 --- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java +++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java -@@ -23,14 +23,22 @@ public class AttributeMap { - private final Set dirtyAttributes = new ObjectOpenHashSet<>(); +@@ -24,15 +24,23 @@ public class AttributeMap { + private final Set attributesToUpdate = new ObjectOpenHashSet<>(); private final AttributeSupplier supplier; private final java.util.function.Function, AttributeInstance> createInstance; // Gale - Airplane - reduce entity allocations + private final net.minecraft.world.entity.LivingEntity entity; // Purpur @@ -3278,12 +3198,13 @@ index 665fbe3362dcd9de4bd290b71a1b1f2fed218eeb..894082d9a8e2aa05f86948bfd335090f } private void onAttributeModified(AttributeInstance instance) { + this.attributesToUpdate.add(instance); - if (instance.getAttribute().value().isClientSyncable()) { + if (instance.getAttribute().value().isClientSyncable() && (entity == null || entity.shouldSendAttribute(instance.getAttribute().value()))) { // Purpur - this.dirtyAttributes.add(instance); + this.attributesToSync.add(instance); } } -@@ -40,7 +48,7 @@ public class AttributeMap { +@@ -46,7 +54,7 @@ public class AttributeMap { } public Collection getSyncableAttributes() { @@ -3318,18 +3239,18 @@ index f0703302e7dbbda88de8c648d20d87c55ed9b1e0..a913ebabaa5f443afa987b972355a8f8 } } diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java b/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java -index b5242f2d450f863a3eb774d8a14bb00cbe699a16..c72ce539f3e339c6e87138e744f033d2143abc7a 100644 +index f053ee19875e6c1586ffe4ebb0284172af5fbb23..848452ba2068c9b0ec6e253da0d0ef10fdec48b0 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java -@@ -82,7 +82,7 @@ public class AcquirePoi { +@@ -81,7 +81,7 @@ public class AcquirePoi { + } }; - // Paper start - optimise POI access - java.util.List, BlockPos>> poiposes = new java.util.ArrayList<>(); -- io.papermc.paper.util.PoiAccess.findNearestPoiPositions(poiManager, poiPredicate, predicate2, entity.blockPosition(), 48, 48*48, PoiManager.Occupancy.HAS_SPACE, false, 5, poiposes); -+ io.papermc.paper.util.PoiAccess.findNearestPoiPositions(poiManager, poiPredicate, predicate2, entity.blockPosition(), world.purpurConfig.villagerAcquirePoiSearchRadius, world.purpurConfig.villagerAcquirePoiSearchRadius*world.purpurConfig.villagerAcquirePoiSearchRadius, PoiManager.Occupancy.HAS_SPACE, false, 5, poiposes); // Purpur - Set, BlockPos>> set = new java.util.HashSet<>(poiposes); - // Paper end - optimise POI access - Path path = findPathToPois(entity, set); + Set, BlockPos>> set = poiManager.findAllClosestFirstWithType( +- poiPredicate, predicate2, entity.blockPosition(), 48, PoiManager.Occupancy.HAS_SPACE ++ poiPredicate, predicate2, entity.blockPosition(), world.purpurConfig.villagerAcquirePoiSearchRadius, PoiManager.Occupancy.HAS_SPACE // Purpur + ) + .limit(5L) + .collect(Collectors.toSet()); 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 2ade08d1466660ee1787fa97908002ef56389712..8d4e206aa05b95b7bfec5d23496085cf55a3e1de 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java @@ -3398,12 +3319,12 @@ index 2ade08d1466660ee1787fa97908002ef56389712..8d4e206aa05b95b7bfec5d23496085cf 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 736f46d552d558bf0edd9a86601b5fbb6940815b..cf039181dfe0ddb3ccda44064a5d8a2f6c5c432c 100644 +index 3513b15f6622bfc134ecfcd9129f81a8acc2c601..6e70579a58a1bf906b176b81713e55318199cef6 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 { - if (iblockdata.is(BlockTags.WOODEN_DOORS, (blockbase_blockdata) -> { + if (iblockdata.is(BlockTags.MOB_INTERACTABLE_DOORS, (blockbase_blockdata) -> { return blockbase_blockdata.getBlock() instanceof DoorBlock; - })) { + }) && !DoorBlock.requiresRedstone(entityliving.level(), iblockdata, blockposition)) { // Purpur @@ -3412,7 +3333,7 @@ index 736f46d552d558bf0edd9a86601b5fbb6940815b..cf039181dfe0ddb3ccda44064a5d8a2f if (!blockdoor.isOpen(iblockdata)) { @@ -79,7 +79,7 @@ public class InteractWithDoor { - if (iblockdata1.is(BlockTags.WOODEN_DOORS, (blockbase_blockdata) -> { + if (iblockdata1.is(BlockTags.MOB_INTERACTABLE_DOORS, (blockbase_blockdata) -> { return blockbase_blockdata.getBlock() instanceof DoorBlock; - })) { + }) && !DoorBlock.requiresRedstone(entityliving.level(), iblockdata, blockposition1)) { // Purpur @@ -3421,7 +3342,7 @@ index 736f46d552d558bf0edd9a86601b5fbb6940815b..cf039181dfe0ddb3ccda44064a5d8a2f if (!blockdoor1.isOpen(iblockdata1)) { @@ -122,7 +122,7 @@ public class InteractWithDoor { - if (!iblockdata.is(BlockTags.WOODEN_DOORS, (blockbase_blockdata) -> { + if (!iblockdata.is(BlockTags.MOB_INTERACTABLE_DOORS, (blockbase_blockdata) -> { return blockbase_blockdata.getBlock() instanceof DoorBlock; - })) { + }) || DoorBlock.requiresRedstone(entity.level(), iblockdata, blockposition)) { // Purpur @@ -3441,11 +3362,11 @@ index 18dad0825616c4167a0a7555689ee64910a87e09..6945992491027d43eca4f1ca697ad45c && this.lookTime > 0 && entity.getBrain().getMemory(MemoryModuleType.INTERACTION_TARGET).isPresent(); diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java b/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java -index 3232f40ef11f59091cec469f0dd40c60ee2a16e9..7db823e9edd70808c5629f0a7efd84fe40f42dd9 100644 +index 8508ac7de8cda3127b73e11ff4aee62502e65ead..b1544e028d5a9b84b944e1fb5a12bb163067fb54 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java -@@ -63,6 +63,12 @@ public class TradeWithVillager extends Behavior { - throwHalfStack(entity, Villager.FOOD_POINTS_KEY_ARRAY, villager); // Gale - optimize villager data storage +@@ -59,6 +59,12 @@ public class TradeWithVillager extends Behavior { + throwHalfStack(entity, ImmutableSet.of(Items.WHEAT), villager); } + // Purpur start @@ -3454,9 +3375,9 @@ index 3232f40ef11f59091cec469f0dd40c60ee2a16e9..7db823e9edd70808c5629f0a7efd84fe + } + // Purpur end + - // Gale start - optimize villager data storage - if (this.trades != null && entity.getInventory().hasAnyOf(this.trades)) { + if (!this.trades.isEmpty() && entity.getInventory().hasAnyOf(this.trades)) { throwHalfStack(entity, this.trades, villager); + } diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java b/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java index f000a6c1e61198e6dd06ae5f084d12fdf309f50a..3091d985ba9c55d404332576320718840538722e 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java @@ -3654,23 +3575,23 @@ index 13f8c2cb42334ba3b573ca44ace1d3df76e41ff7..baca552e52c728867fcb0527b6c3eb39 @Override diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java -index 92731b6b593289e9f583c9b705b219e81fcd8e73..9104d7010bda6f9f73b478c11490ef9c53f76da2 100644 +index d5a549f08b98c80a5cf0eef02cb8a389c32dfecb..222c87e80cb089867ce9a7d2dceebe21b4bfe0de 100644 --- a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java +++ b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java -@@ -56,7 +56,7 @@ public class NearestBedSensor extends Sensor { - // Paper start - optimise POI access - java.util.List, BlockPos>> poiposes = new java.util.ArrayList<>(); - // don't ask me why it's unbounded. ask mojang. -- io.papermc.paper.util.PoiAccess.findAnyPoiPositions(poiManager, type -> type.is(PoiTypes.HOME), predicate, entity.blockPosition(), 48, PoiManager.Occupancy.ANY, false, Integer.MAX_VALUE, poiposes); -+ io.papermc.paper.util.PoiAccess.findAnyPoiPositions(poiManager, type -> type.is(PoiTypes.HOME), predicate, entity.blockPosition(), world.purpurConfig.villagerNearestBedSensorSearchRadius, PoiManager.Occupancy.ANY, false, Integer.MAX_VALUE, poiposes); // Purpur - Path path = AcquirePoi.findPathToPois(entity, new java.util.HashSet<>(poiposes)); - // Paper end - optimise POI access - if (path != null && path.canReach()) { +@@ -54,7 +54,7 @@ public class NearestBedSensor extends Sensor { + } + }; + Set, BlockPos>> set = poiManager.findAllWithType( +- holder -> holder.is(PoiTypes.HOME), predicate, entity.blockPosition(), 48, PoiManager.Occupancy.ANY ++ holder -> holder.is(PoiTypes.HOME), predicate, entity.blockPosition(), world.purpurConfig.villagerNearestBedSensorSearchRadius, PoiManager.Occupancy.ANY + ) + .collect(Collectors.toSet()); + Path path = AcquirePoi.findPathToPois(entity, set); diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java -index ce8851c2cacfd3145b1e2c11443140a0759a1b07..9419f230910d0338fc4ac6e2e7b749ee7d5ee362 100644 +index 1595568f3140a62b0f2236644ac2da11db12af05..d548d1b2686667d809f363cd0ae4444bc3918bf2 100644 --- a/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java +++ b/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java -@@ -31,6 +31,13 @@ public class SecondaryPoiSensor extends Sensor { +@@ -29,6 +29,13 @@ public class SecondaryPoiSensor extends Sensor { return; } // Gale end - Lithium - skip secondary POI sensor if absent @@ -3683,18 +3604,18 @@ index ce8851c2cacfd3145b1e2c11443140a0759a1b07..9419f230910d0338fc4ac6e2e7b749ee + // Purpur end ResourceKey resourceKey = world.dimension(); BlockPos blockPos = entity.blockPosition(); - @Nullable ArrayList list = null; // Gale - optimize villager data storage -@@ -52,7 +59,7 @@ public class SecondaryPoiSensor extends Sensor { + List list = Lists.newArrayList(); +@@ -45,7 +52,7 @@ public class SecondaryPoiSensor extends Sensor { } } - Brain brain = entity.getBrain(); + //Brain brain = entity.getBrain(); // Purpur - moved up - // Gale start - optimize villager data storage - if (list != null) { - list.trimToSize(); + if (!list.isEmpty()) { + brain.setMemory(MemoryModuleType.SECONDARY_JOB_SITE, list); + } else { 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 68bc8699a9389d118411ea7134ea0e0588adf8dc..1731147abd53ca2149683ea593e96523dccc7d7e 100644 +index 4addcfe248dd4705be7e67551b258ce86c57e194..82d3e442f6d31211701878fc5ae7a346247ef124 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 { @@ -3881,7 +3802,7 @@ index 3231eaa6af2ddfe4095ff2d650f580ebd4d43aea..e8cb124d232f7316cc8c35dd8bd12f79 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 5193cf1d3c922d750a11e492b7636215e23ad0d6..7f90a0d8f65c96844df06b7c4fa3da28a6f51dd1 100644 +index e96fca314bebea5fcdb684d3478af1b6dc5f13cf..27250278968233b3de05c365ae304a4121887160 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Animal.java +++ b/src/main/java/net/minecraft/world/entity/animal/Animal.java @@ -42,6 +42,7 @@ public abstract class Animal extends AgeableMob { @@ -3939,10 +3860,10 @@ index 5193cf1d3c922d750a11e492b7636215e23ad0d6..7f90a0d8f65c96844df06b7c4fa3da28 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 0dfb8109fd8c022b079da00f6a0e3fc85b57bf7a..539170813921de2dfcd7ef84dd7512d73cd27e68 100644 +index 1b3978f4ea7e8491e0c0cb6de23c141f44fab414..0422c4184c4823b8572afd398ef96fc6054e8485 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Bee.java +++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java -@@ -143,6 +143,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -144,6 +144,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); @@ -3950,7 +3871,7 @@ index 0dfb8109fd8c022b079da00f6a0e3fc85b57bf7a..539170813921de2dfcd7ef84dd7512d7 // Paper start - Fix MC-167279 class BeeFlyingMoveControl extends FlyingMoveControl { public BeeFlyingMoveControl(final Mob entity, final int maxPitchChange, final boolean noGravity) { -@@ -151,22 +152,69 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -152,22 +153,69 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { @Override public void tick() { @@ -4021,7 +3942,7 @@ index 0dfb8109fd8c022b079da00f6a0e3fc85b57bf7a..539170813921de2dfcd7ef84dd7512d7 @Override protected void defineSynchedData(SynchedEntityData.Builder builder) { super.defineSynchedData(builder); -@@ -181,6 +229,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -182,6 +230,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { @Override protected void registerGoals() { @@ -4029,7 +3950,7 @@ index 0dfb8109fd8c022b079da00f6a0e3fc85b57bf7a..539170813921de2dfcd7ef84dd7512d7 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)); -@@ -198,6 +247,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -199,6 +248,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)); @@ -4037,7 +3958,7 @@ index 0dfb8109fd8c022b079da00f6a0e3fc85b57bf7a..539170813921de2dfcd7ef84dd7512d7 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)); -@@ -345,7 +395,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -356,7 +406,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { boolean wantsToEnterHive() { if (this.stayOutOfHiveCountdown <= 0 && !this.beePollinateGoal.isPollinating() && !this.hasStung() && this.getTarget() == null) { @@ -4046,7 +3967,7 @@ index 0dfb8109fd8c022b079da00f6a0e3fc85b57bf7a..539170813921de2dfcd7ef84dd7512d7 return flag && !this.isHiveNearFire(); } else { -@@ -385,6 +435,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -396,6 +446,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { this.hurt(this.damageSources().drown(), 1.0F); } @@ -4054,7 +3975,7 @@ index 0dfb8109fd8c022b079da00f6a0e3fc85b57bf7a..539170813921de2dfcd7ef84dd7512d7 if (flag) { ++this.timeSinceSting; if (this.timeSinceSting % 5 == 0 && this.random.nextInt(Mth.clamp(1200 - this.timeSinceSting, 1, 1200)) == 0) { -@@ -417,6 +468,26 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -428,6 +479,26 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { } } @@ -4081,7 +4002,7 @@ index 0dfb8109fd8c022b079da00f6a0e3fc85b57bf7a..539170813921de2dfcd7ef84dd7512d7 @Override public int getRemainingPersistentAngerTime() { return (Integer) this.entityData.get(Bee.DATA_REMAINING_ANGER_TIME); -@@ -726,6 +797,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -737,6 +808,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); @@ -4089,7 +4010,7 @@ index 0dfb8109fd8c022b079da00f6a0e3fc85b57bf7a..539170813921de2dfcd7ef84dd7512d7 return true; } else { Bee.this.remainingCooldownBeforeLocatingNewFlower = Mth.nextInt(Bee.this.random, 20, 60); -@@ -782,6 +854,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -793,6 +865,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { this.pollinating = false; Bee.this.navigation.stop(); Bee.this.remainingCooldownBeforeLocatingNewFlower = 200; @@ -4097,7 +4018,7 @@ index 0dfb8109fd8c022b079da00f6a0e3fc85b57bf7a..539170813921de2dfcd7ef84dd7512d7 } @Override -@@ -828,6 +901,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -839,6 +912,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { this.setWantedPos(); } @@ -4105,7 +4026,7 @@ index 0dfb8109fd8c022b079da00f6a0e3fc85b57bf7a..539170813921de2dfcd7ef84dd7512d7 ++this.successfulPollinatingTicks; if (Bee.this.random.nextFloat() < 0.05F && this.successfulPollinatingTicks > this.lastSoundPlayedTick + 60) { this.lastSoundPlayedTick = this.successfulPollinatingTicks; -@@ -872,16 +946,16 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -883,16 +957,16 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { } } @@ -4126,10 +4047,10 @@ index 0dfb8109fd8c022b079da00f6a0e3fc85b57bf7a..539170813921de2dfcd7ef84dd7512d7 } 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 07559b9629d4ecb40b511256f400a781e39820e0..3e1345f1c534320e07820d573f5c8dba49746425 100644 +index 23d4dcc82115fd1a0a77565a0472304042d5f12d..80c67e2eb79f47fec6cd9456f691ea03fec361dd 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Cat.java +++ b/src/main/java/net/minecraft/world/entity/animal/Cat.java -@@ -104,6 +104,53 @@ public class Cat extends TamableAnimal implements VariantHolder(this, Rabbit.class, false, (Predicate) null)); this.targetSelector.addGoal(1, new NonTameRandomTargetGoal<>(this, Turtle.class, false, Turtle.BABY_ON_LAND_SELECTOR)); } -@@ -318,6 +367,14 @@ public class Cat extends TamableAnimal implements VariantHolder { @@ -4832,7 +4750,7 @@ index e705449496b1a06270ecbc13f4dce5357479845b..80f897007a60eb0cb9d300207b50387e + @Override // Paper start - Cancellable death event - protected org.bukkit.event.entity.EntityDeathEvent dropAllDeathLoot(DamageSource source) { + protected org.bukkit.event.entity.EntityDeathEvent dropAllDeathLoot(ServerLevel world, DamageSource damageSource) { @@ -769,16 +858,16 @@ public class Fox extends Animal implements VariantHolder { return new Vec3(0.0D, (double) (0.55F * this.getEyeHeight()), (double) (this.getBbWidth() * 0.4F)); } @@ -4896,10 +4814,10 @@ index e705449496b1a06270ecbc13f4dce5357479845b..80f897007a60eb0cb9d300207b50387e 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 932fae98c551052cadba4c6fc6e575fc30a25d58..12bc57d36d76f49596df0004fda31a6a678be60c 100644 +index 1807da10d07d1f6e4ddbc0fa1b8da34a688d67c3..ec6d5dd532968b02a7f12c832eb896600b3ff2aa 100644 --- a/src/main/java/net/minecraft/world/entity/animal/IronGolem.java +++ b/src/main/java/net/minecraft/world/entity/animal/IronGolem.java -@@ -56,13 +56,58 @@ public class IronGolem extends AbstractGolem implements NeutralMob { +@@ -57,13 +57,58 @@ public class IronGolem extends AbstractGolem implements NeutralMob { private int remainingPersistentAngerTime; @Nullable private UUID persistentAngerTarget; @@ -4958,7 +4876,7 @@ index 932fae98c551052cadba4c6fc6e575fc30a25d58..12bc57d36d76f49596df0004fda31a6a 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)); -@@ -70,6 +115,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { +@@ -71,6 +116,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)); @@ -4966,7 +4884,7 @@ index 932fae98c551052cadba4c6fc6e575fc30a25d58..12bc57d36d76f49596df0004fda31a6a 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)); -@@ -134,6 +180,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { +@@ -135,6 +181,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { public void addAdditionalSaveData(CompoundTag nbt) { super.addAdditionalSaveData(nbt); nbt.putBoolean("PlayerCreated", this.isPlayerCreated()); @@ -4974,7 +4892,7 @@ index 932fae98c551052cadba4c6fc6e575fc30a25d58..12bc57d36d76f49596df0004fda31a6a this.addPersistentAngerSaveData(nbt); } -@@ -141,6 +188,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { +@@ -142,6 +189,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { public void readAdditionalSaveData(CompoundTag nbt) { super.readAdditionalSaveData(nbt); this.setPlayerCreated(nbt.getBoolean("PlayerCreated")); @@ -4982,7 +4900,7 @@ index 932fae98c551052cadba4c6fc6e575fc30a25d58..12bc57d36d76f49596df0004fda31a6a this.readPersistentAngerSaveData(this.level(), nbt); } -@@ -265,18 +313,19 @@ public class IronGolem extends AbstractGolem implements NeutralMob { +@@ -273,18 +321,19 @@ public class IronGolem extends AbstractGolem implements NeutralMob { ItemStack itemstack = player.getItemInHand(hand); if (!itemstack.is(Items.IRON_INGOT)) { @@ -5005,7 +4923,7 @@ index 932fae98c551052cadba4c6fc6e575fc30a25d58..12bc57d36d76f49596df0004fda31a6a } } 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 5707c6287a691030841fa973e8f7f34a816103e4..8299ed1f8632f94592f274b543b234c46fd83886 100644 +index 5707c6287a691030841fa973e8f7f34a816103e4..4829e7178c3e8a4c8bbc2c70f2d5fb5e919b03c0 100644 --- a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java +++ b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java @@ -64,6 +64,43 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder drops = this.generateDefaultDrops(); -+ java.util.List drops = this.generateDefaultDrops(net.minecraft.world.item.enchantment.EnchantmentHelper.getMobLooting(player)); // Purpur ++ java.util.List drops = this.generateDefaultDrops(net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.LOOTING, itemstack)); // Purpur org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops); if (event != null) { if (event.isCancelled()) { @@ -5093,7 +5011,7 @@ index 5707c6287a691030841fa973e8f7f34a816103e4..8299ed1f8632f94592f274b543b234c4 } return dropEntities; diff --git a/src/main/java/net/minecraft/world/entity/animal/Ocelot.java b/src/main/java/net/minecraft/world/entity/animal/Ocelot.java -index 2c7491edbb60e7ec6a208ea7292cd28a3f8f9e31..07dc8a43f4e8c54a94696b84896d32f66a207ad3 100644 +index 97f4cc522706ec5914672aa4fdfbc35edc94aeb6..6e866ec44a83ec9064ac3228bd96eb251f3b28b0 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Ocelot.java +++ b/src/main/java/net/minecraft/world/entity/animal/Ocelot.java @@ -66,6 +66,43 @@ public class Ocelot extends Animal { @@ -5155,7 +5073,7 @@ index 2c7491edbb60e7ec6a208ea7292cd28a3f8f9e31..07dc8a43f4e8c54a94696b84896d32f6 this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Chicken.class, false)); this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Turtle.class, 10, false, false, Turtle.BABY_ON_LAND_SELECTOR)); } -@@ -254,7 +293,7 @@ public class Ocelot extends Animal { +@@ -245,7 +284,7 @@ public class Ocelot extends Animal { if (world.isUnobstructed(this) && !world.containsAnyLiquid(this.getBoundingBox())) { BlockPos blockposition = this.blockPosition(); @@ -5165,10 +5083,10 @@ index 2c7491edbb60e7ec6a208ea7292cd28a3f8f9e31..07dc8a43f4e8c54a94696b84896d32f6 } 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 db60b91c2b26ca8cdb66e05deab7742ffe212767..7bd81d073ce4a8d5981f256415d3e99e13da79ba 100644 +index e108f876d3f129c6287f13d68427aed2a6f0c5b1..a27f33b7bbf7f7d5cfb3dbb0bf5b93a66551d493 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Panda.java +++ b/src/main/java/net/minecraft/world/entity/animal/Panda.java -@@ -120,6 +120,53 @@ public class Panda extends Animal { +@@ -121,6 +121,53 @@ public class Panda extends Animal { } @@ -5221,8 +5139,8 @@ index db60b91c2b26ca8cdb66e05deab7742ffe212767..7bd81d073ce4a8d5981f256415d3e99e + @Override public boolean canTakeItem(ItemStack stack) { - EquipmentSlot enumitemslot = Mob.getEquipmentSlotForItem(stack); -@@ -281,6 +328,7 @@ public class Panda extends Animal { + EquipmentSlot enumitemslot = this.getEquipmentSlotForItem(stack); +@@ -282,6 +329,7 @@ public class Panda extends Animal { @Override protected void registerGoals() { this.goalSelector.addGoal(0, new FloatGoal(this)); @@ -5230,7 +5148,7 @@ index db60b91c2b26ca8cdb66e05deab7742ffe212767..7bd81d073ce4a8d5981f256415d3e99e 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)); -@@ -298,6 +346,7 @@ public class Panda extends Animal { +@@ -299,6 +347,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)); @@ -5238,7 +5156,7 @@ index db60b91c2b26ca8cdb66e05deab7742ffe212767..7bd81d073ce4a8d5981f256415d3e99e this.targetSelector.addGoal(1, (new Panda.PandaHurtByTargetGoal(this, new Class[0])).setAlertOthers(new Class[0])); } -@@ -632,7 +681,10 @@ public class Panda extends Animal { +@@ -637,7 +686,10 @@ public class Panda extends Animal { public void setAttributes() { if (this.isWeak()) { @@ -5250,7 +5168,7 @@ index db60b91c2b26ca8cdb66e05deab7742ffe212767..7bd81d073ce4a8d5981f256415d3e99e } if (this.isLazy()) { -@@ -655,7 +707,7 @@ public class Panda extends Animal { +@@ -660,7 +712,7 @@ public class Panda extends Animal { ItemStack itemstack = player.getItemInHand(hand); if (this.isScared()) { @@ -5259,7 +5177,7 @@ index db60b91c2b26ca8cdb66e05deab7742ffe212767..7bd81d073ce4a8d5981f256415d3e99e } else if (this.isOnBack()) { this.setOnBack(false); return InteractionResult.sidedSuccess(this.level().isClientSide); -@@ -673,7 +725,7 @@ public class Panda extends Animal { +@@ -678,7 +730,7 @@ public class Panda extends Animal { this.setInLove(player, breedCopy); // Paper - Fix EntityBreedEvent copying } else { if (this.level().isClientSide || this.isSitting() || this.isInWater()) { @@ -5268,7 +5186,7 @@ index db60b91c2b26ca8cdb66e05deab7742ffe212767..7bd81d073ce4a8d5981f256415d3e99e } this.tryToSit(); -@@ -692,7 +744,7 @@ public class Panda extends Animal { +@@ -697,7 +749,7 @@ public class Panda extends Animal { return InteractionResult.SUCCESS; } else { @@ -5277,7 +5195,7 @@ index db60b91c2b26ca8cdb66e05deab7742ffe212767..7bd81d073ce4a8d5981f256415d3e99e } } -@@ -737,7 +789,7 @@ public class Panda extends Animal { +@@ -742,7 +794,7 @@ public class Panda extends Animal { return this.isBaby() ? Panda.BABY_DIMENSIONS : super.getDefaultDimensions(pose); } @@ -5286,7 +5204,7 @@ index db60b91c2b26ca8cdb66e05deab7742ffe212767..7bd81d073ce4a8d5981f256415d3e99e private final Panda panda; -@@ -747,9 +799,9 @@ public class Panda extends Animal { +@@ -752,9 +804,9 @@ public class Panda extends Animal { } @Override @@ -5299,7 +5217,7 @@ index db60b91c2b26ca8cdb66e05deab7742ffe212767..7bd81d073ce4a8d5981f256415d3e99e } } 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 5ca96541abbb754f4d9fbe01f37ebaf19c532bbb..b8c69414b734eecb7412fab8ae6996712307da70 100644 +index 97931bfd360725945ab9606ff698b518ae101076..eac0c3f8ee77099af65e823fc687e4236b3d2746 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Parrot.java +++ b/src/main/java/net/minecraft/world/entity/animal/Parrot.java @@ -124,12 +124,88 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder polarBear.isBaby() ? DamageTypeTags.PANIC_CAUSES : DamageTypeTags.PANIC_ENVIRONMENTAL_CAUSES)); + // Purpur start + if (level().purpurConfig.polarBearBreedableItem != null) { + this.goalSelector.addGoal(2, new net.minecraft.world.entity.ai.goal.BreedGoal(this, 1.0D)); @@ -5632,7 +5551,7 @@ index c87a57e8ceac32a6c8a603aa24f8cb053610e47c..9b6e07b0de7328b18c5e526b89cfd48f this.targetSelector.addGoal(1, new PolarBear.PolarBearHurtByTargetGoal()); this.targetSelector.addGoal(2, new PolarBear.PolarBearAttackPlayersGoal()); this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, this::isAngryAt)); -@@ -201,6 +279,12 @@ public class PolarBear extends Animal implements NeutralMob { +@@ -202,6 +280,12 @@ public class PolarBear extends Animal implements NeutralMob { if (!this.level().isClientSide) { this.updatePersistentAnger((ServerLevel)this.level(), true); } @@ -5645,7 +5564,7 @@ index c87a57e8ceac32a6c8a603aa24f8cb053610e47c..9b6e07b0de7328b18c5e526b89cfd48f } @Override -@@ -230,6 +314,7 @@ public class PolarBear extends Animal implements NeutralMob { +@@ -221,6 +305,7 @@ public class PolarBear extends Animal implements NeutralMob { public void setStanding(boolean warning) { this.entityData.set(DATA_STANDING_ID, warning); @@ -5692,10 +5611,10 @@ index 3f0fad476fe573c3ba946a9436d1b3f7c5260ee2..c758f759ccae81b7651bfcba254f5433 protected void defineSynchedData(SynchedEntityData.Builder builder) { super.defineSynchedData(builder); diff --git a/src/main/java/net/minecraft/world/entity/animal/Rabbit.java b/src/main/java/net/minecraft/world/entity/animal/Rabbit.java -index b58300e114e2e27ac68d7a9489bc52b127c9bc17..02702390c0b336762ce8c0d38d804e6f24ebbfd4 100644 +index 0109c8ed8bf6a053674456fa4473934e028ca418..8741651193bb1aabc3c09024189eb1e5c1e5eda9 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Rabbit.java +++ b/src/main/java/net/minecraft/world/entity/animal/Rabbit.java -@@ -86,6 +86,7 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -89,6 +89,7 @@ public class Rabbit extends Animal implements VariantHolder { private boolean wasOnGround; private int jumpDelayTicks; public int moreCarrotTicks; @@ -5703,7 +5622,7 @@ index b58300e114e2e27ac68d7a9489bc52b127c9bc17..02702390c0b336762ce8c0d38d804e6f public Rabbit(EntityType type, Level world) { super(type, world); -@@ -93,9 +94,75 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -96,9 +97,75 @@ public class Rabbit extends Animal implements VariantHolder { this.moveControl = new Rabbit.RabbitMoveControl(this); } @@ -5779,7 +5698,7 @@ index b58300e114e2e27ac68d7a9489bc52b127c9bc17..02702390c0b336762ce8c0d38d804e6f 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)); -@@ -112,6 +179,14 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -115,6 +182,14 @@ public class Rabbit extends Animal implements VariantHolder { @Override protected float getJumpPower() { @@ -5794,16 +5713,7 @@ index b58300e114e2e27ac68d7a9489bc52b127c9bc17..02702390c0b336762ce8c0d38d804e6f float f = 0.3F; if (this.horizontalCollision || this.moveControl.hasWanted() && this.moveControl.getWantedY() > this.getY() + 0.5D) { -@@ -136,7 +211,7 @@ public class Rabbit extends Animal implements VariantHolder { - } - - @Override -- protected void jumpFromGround() { -+ public void jumpFromGround() { // Purpur - protected -> public - super.jumpFromGround(); - double d0 = this.moveControl.getSpeedModifier(); - -@@ -186,6 +261,13 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -189,6 +264,13 @@ public class Rabbit extends Animal implements VariantHolder { @Override public void customServerAiStep() { @@ -5817,7 +5727,7 @@ index b58300e114e2e27ac68d7a9489bc52b127c9bc17..02702390c0b336762ce8c0d38d804e6f if (this.jumpDelayTicks > 0) { --this.jumpDelayTicks; } -@@ -399,10 +481,23 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -403,10 +485,23 @@ public class Rabbit extends Animal implements VariantHolder { } this.setVariant(entityrabbit_variant); @@ -5841,7 +5751,7 @@ index b58300e114e2e27ac68d7a9489bc52b127c9bc17..02702390c0b336762ce8c0d38d804e6f Holder holder = world.getBiome(pos); int i = world.getRandom().nextInt(100); -@@ -466,7 +561,7 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -470,7 +565,7 @@ public class Rabbit extends Animal implements VariantHolder { } } @@ -5850,7 +5760,7 @@ index b58300e114e2e27ac68d7a9489bc52b127c9bc17..02702390c0b336762ce8c0d38d804e6f private final Rabbit rabbit; private double nextJumpSpeed; -@@ -477,14 +572,14 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -481,14 +576,14 @@ public class Rabbit extends Animal implements VariantHolder { } @Override @@ -5867,7 +5777,7 @@ index b58300e114e2e27ac68d7a9489bc52b127c9bc17..02702390c0b336762ce8c0d38d804e6f } @Override -@@ -546,7 +641,7 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -550,7 +645,7 @@ public class Rabbit extends Animal implements VariantHolder { @Override public boolean canUse() { if (this.nextStartTick <= 0) { @@ -5915,10 +5825,10 @@ index 0af79daa357f53a8871e293b57e16c099e5d3f64..382e47f26ee94506cb76463a677351b9 public int getMaxSchoolSize() { return 5; diff --git a/src/main/java/net/minecraft/world/entity/animal/Sheep.java b/src/main/java/net/minecraft/world/entity/animal/Sheep.java -index 0dfc2ccd8f454d0252542312661f65f41a6209ab..632562e3c27d11b73fdfb6b2f49c31edc761ed8d 100644 +index eccb524111cec32ed55722817529e6ab992d381d..2b851c572a3a7e4f74aab094f9cba6703547732f 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Sheep.java +++ b/src/main/java/net/minecraft/world/entity/animal/Sheep.java -@@ -117,10 +117,48 @@ public class Sheep extends Animal implements Shearable { +@@ -115,10 +115,48 @@ public class Sheep extends Animal implements Shearable { super(type, world); } @@ -5967,16 +5877,16 @@ index 0dfc2ccd8f454d0252542312661f65f41a6209ab..632562e3c27d11b73fdfb6b2f49c31ed 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, (itemstack) -> { -@@ -259,7 +297,7 @@ public class Sheep extends Animal implements Shearable { +@@ -257,7 +295,7 @@ public class Sheep extends Animal implements Shearable { if (!this.level().isClientSide && this.readyForShearing()) { // CraftBukkit start // Paper start - custom shear drops - java.util.List drops = this.generateDefaultDrops(); -+ java.util.List drops = this.generateDefaultDrops(net.minecraft.world.item.enchantment.EnchantmentHelper.getMobLooting(player)); // Purpur ++ java.util.List drops = this.generateDefaultDrops(net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.LOOTING, itemstack)); // Purpur org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops); if (event != null) { if (event.isCancelled()) { -@@ -284,12 +322,13 @@ public class Sheep extends Animal implements Shearable { +@@ -282,12 +320,13 @@ public class Sheep extends Animal implements Shearable { @Override public void shear(SoundSource shearedSoundCategory) { // Paper start - custom shear drops @@ -5993,7 +5903,7 @@ index 0dfc2ccd8f454d0252542312661f65f41a6209ab..632562e3c27d11b73fdfb6b2f49c31ed for (int j = 0; j < count; ++j) { dropEntities.add(new ItemStack(Sheep.ITEM_BY_DYE.get(this.getColor()))); diff --git a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java -index 5c2ed3c39c8eb850f3be1e2ea5b5a7ea266e16d1..3b74931ae4e3a869d8db38c119e57b44af887859 100644 +index 5c2ed3c39c8eb850f3be1e2ea5b5a7ea266e16d1..0a301d09b59130d741ea9549ac9d967c8f78366d 100644 --- a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java +++ b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java @@ -47,17 +47,56 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM @@ -6095,7 +6005,7 @@ index 5c2ed3c39c8eb850f3be1e2ea5b5a7ea266e16d1..3b74931ae4e3a869d8db38c119e57b44 // CraftBukkit start // Paper start - custom shear drops - java.util.List drops = this.generateDefaultDrops(); -+ java.util.List drops = this.generateDefaultDrops(net.minecraft.world.item.enchantment.EnchantmentHelper.getMobLooting(player)); // Purpur ++ java.util.List drops = this.generateDefaultDrops(net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.LOOTING, itemstack)); // Purpur org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops); if (event != null) { if (event.isCancelled()) { @@ -6145,10 +6055,10 @@ index 5c2ed3c39c8eb850f3be1e2ea5b5a7ea266e16d1..3b74931ae4e3a869d8db38c119e57b44 } 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 43b4ea96c5c4a6234e5b83d41db9b85c1fe27b8f..cb950ba3ee3bdfe0ff7acdb94c7ee233d73ab22e 100644 +index 42f4e544fe7fbc342f15eacb5e38d40849e3c419..e6244d8c7745570099638d96fafa6b4971c4beb8 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Squid.java +++ b/src/main/java/net/minecraft/world/entity/animal/Squid.java -@@ -42,13 +42,66 @@ public class Squid extends WaterAnimal { +@@ -41,13 +41,66 @@ public class Squid extends WaterAnimal { public Squid(EntityType type, Level world) { super(type, world); @@ -6216,7 +6126,7 @@ index 43b4ea96c5c4a6234e5b83d41db9b85c1fe27b8f..cb950ba3ee3bdfe0ff7acdb94c7ee233 this.goalSelector.addGoal(1, new Squid.SquidFleeGoal()); } -@@ -117,6 +170,7 @@ public class Squid extends WaterAnimal { +@@ -116,6 +169,7 @@ public class Squid extends WaterAnimal { } if (this.isInWaterOrBubble()) { @@ -6224,12 +6134,12 @@ index 43b4ea96c5c4a6234e5b83d41db9b85c1fe27b8f..cb950ba3ee3bdfe0ff7acdb94c7ee233 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; -@@ -290,10 +344,41 @@ public class Squid extends WaterAnimal { +@@ -289,10 +343,41 @@ public class Squid extends WaterAnimal { @Override public void tick() { + // Purpur start -+ Player rider = squid.getRider(); ++ net.minecraft.world.entity.player.Player rider = squid.getRider(); + if (rider != null && squid.isControllable()) { + if (rider.jumping) { + squid.onSpacebar(); @@ -6306,7 +6216,7 @@ index 3d03ffe2e12eca82dfa2f414471d12bb362d4552..2d04addd17d2c358fff598012b323cd7 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 30b87b5cb18c25cdd04eab64cfbe5acd6c1b6d84..01dc59695f295657b1cd7bb015558bfc2ce73b47 100644 +index 4bfa947531c4a67989e18032754dabf4c69e989c..edd1114604c089a8b3a85e530e0254d4695dc9c4 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java +++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java @@ -87,6 +87,43 @@ public class Turtle extends Animal { @@ -6351,7 +6261,7 @@ index 30b87b5cb18c25cdd04eab64cfbe5acd6c1b6d84..01dc59695f295657b1cd7bb015558bfc + } + public void setHomePos(BlockPos pos) { - this.entityData.set(Turtle.HOME_POS, pos.immutable()); // Paper - called with mutablepos... + this.entityData.set(Turtle.HOME_POS, pos); } @@ -189,6 +226,7 @@ public class Turtle extends Animal { @@ -6397,10 +6307,10 @@ index 30b87b5cb18c25cdd04eab64cfbe5acd6c1b6d84..01dc59695f295657b1cd7bb015558bfc this.turtle.setSpeed(Mth.lerp(0.125F, this.turtle.getSpeed(), f1)); this.turtle.setDeltaMovement(this.turtle.getDeltaMovement().add(0.0D, (double) this.turtle.getSpeed() * d1 * 0.1D, 0.0D)); diff --git a/src/main/java/net/minecraft/world/entity/animal/Wolf.java b/src/main/java/net/minecraft/world/entity/animal/Wolf.java -index cebbb7341f86b13dcbfc3a41cbe264e9d4b68d60..a8193ef23763a11016b9ac8c7dd55b9e240d6039 100644 +index c382a8f95f612db881b9cdbd07316d1ca1cd9c4b..865640831c988192adc937cb0cad4c7e241b1540 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Wolf.java +++ b/src/main/java/net/minecraft/world/entity/animal/Wolf.java -@@ -104,6 +104,37 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder(this, Llama.class, 24.0F, 1.5D, 1.5D)); + this.goalSelector.addGoal(3, new AvoidRabidWolfGoal(this, 24.0F, 1.5D, 1.5D)); // Purpur this.goalSelector.addGoal(4, new LeapAtTargetGoal(this, 0.4F)); this.goalSelector.addGoal(5, new MeleeAttackGoal(this, 1.0D, true)); - this.goalSelector.addGoal(6, new FollowOwnerGoal(this, 1.0D, 10.0F, 2.0F, false)); -@@ -138,11 +243,12 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder(this, Turtle.class, false, Turtle.BABY_ON_LAND_SELECTOR)); this.targetSelector.addGoal(7, new NearestAttackableTargetGoal<>(this, AbstractSkeleton.class, false)); this.targetSelector.addGoal(8, new ResetUniversalAngerTargetGoal<>(this, true)); -@@ -185,6 +291,7 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder { + nbt.putString("variant", resourcekey.location().toString()); + }); +@@ -210,6 +317,10 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder brainProvider() { return Brain.provider(Allay.MEMORY_TYPES, Allay.SENSOR_TYPES); -@@ -218,7 +253,7 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS +@@ -220,7 +255,7 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { @@ -6680,10 +6590,10 @@ index 34c1df5bd7655bfbcba3ae872a8eec621ace5835..3755ed3c550f9553f147fd442a01958e AllayAi.updateActivity(this); super.customServerAiStep(); diff --git a/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java b/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java -index 6a3b119bdcac4de1b39216b23ba8dceae062d278..2dcabb97ad84d1622619f2f08595a52ec9819ca5 100644 +index a70077521a13d0fbdc987b39a89345442c8e8cc3..7c7b063b0b563716757294792653a705fe7436f9 100644 --- a/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java +++ b/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java -@@ -77,6 +77,33 @@ public class Armadillo extends Animal { +@@ -78,6 +78,33 @@ public class Armadillo extends Animal { return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 12.0D).add(Attributes.MOVEMENT_SPEED, 0.14D); } @@ -6718,10 +6628,10 @@ index 6a3b119bdcac4de1b39216b23ba8dceae062d278..2dcabb97ad84d1622619f2f08595a52e protected void defineSynchedData(SynchedEntityData.Builder builder) { super.defineSynchedData(builder); 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 d339e9c0b81a50d20048375bd8b4141618fc1d2a..3409b0eaf9f09a92846359ca58ecda7deb17c099 100644 +index c75dccb977e0d620e3834ca0197e8fd51bf3bfd4..2b98303d3be00469d9cd84d11cbb824ac0ba9c86 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 -@@ -96,6 +96,43 @@ public class Axolotl extends Animal implements LerpingModel, VariantHolder getModelRotationValues() { return this.modelRotationValues; -@@ -271,7 +308,7 @@ public class Axolotl extends Animal implements LerpingModel, VariantHolder type, Level world) { super(type, world); @@ -7134,7 +7044,7 @@ index 9357cf0179d19fbdfe76413e909a99b924c85780..59829fb7342696d29aa709d392f89bf2 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)); -@@ -232,6 +280,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, +@@ -234,6 +282,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, if (this.canPerformRearing()) { this.goalSelector.addGoal(9, new RandomStandGoal(this)); } @@ -7142,7 +7052,7 @@ index 9357cf0179d19fbdfe76413e909a99b924c85780..59829fb7342696d29aa709d392f89bf2 this.addBehaviourGoals(); } -@@ -1249,7 +1298,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, +@@ -1250,7 +1299,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, entityData = new AgeableMob.AgeableMobGroupData(0.2F); } @@ -7200,10 +7110,10 @@ index ff02169ba14f5264cea8beaf1779e2890c5d74b8..94021abe521aea4a70f5eaa78fb05f9f 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 6e299770fca78699f7e1988db4cdef37b99d74c1..fdf9ec418b0fc567e286ac79dbdbeddac568ad67 100644 +index b1188d05700cafc3a6956171bacde4962d6659be..d51d5fa03232c674fa4b4ed6b8e15ce3a40d2732 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 -@@ -44,6 +44,43 @@ public class Horse extends AbstractHorse implements VariantHolder { +@@ -45,6 +45,43 @@ public class Horse extends AbstractHorse implements VariantHolder { super(type, world); } @@ -7248,7 +7158,7 @@ index 6e299770fca78699f7e1988db4cdef37b99d74c1..fdf9ec418b0fc567e286ac79dbdbedda 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 36d654073ab4058db54830d9447d7d959a0b25f1..f452e18829e2b05cf742a4239cba293263b3a88a 100644 +index cf6a3a63b6f2b96943c0f399e8c82d293fee31ba..7714d7f74836e5a765867fa0339c41fdce703863 100644 --- a/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java +++ b/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java @@ -75,10 +75,85 @@ public class Llama extends AbstractChestedHorse implements VariantHolder public - super.jumpFromGround(); - double d0 = this.moveControl.getSpeedModifier(); - diff --git a/src/main/java/net/minecraft/world/entity/boss/EnderDragonPart.java b/src/main/java/net/minecraft/world/entity/boss/EnderDragonPart.java -index 6725013c608e9321ce0d088059672af4412cf6db..1c8ac6b9603a6e282c5bbe8cdcc61046c9efe41e 100644 +index ca4486844a3125626e949d26fa03c325ef33343f..677ef269bb1206254d000cdbe621bfd926bddd4f 100644 --- a/src/main/java/net/minecraft/world/entity/boss/EnderDragonPart.java +++ b/src/main/java/net/minecraft/world/entity/boss/EnderDragonPart.java -@@ -25,6 +25,13 @@ public class EnderDragonPart extends Entity { +@@ -26,6 +26,13 @@ public class EnderDragonPart extends Entity { this.name = name; } @@ -7680,7 +7581,7 @@ index 6725013c608e9321ce0d088059672af4412cf6db..1c8ac6b9603a6e282c5bbe8cdcc61046 protected void defineSynchedData(SynchedEntityData.Builder builder) { } diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java -index d8e440e14b72dc48ae97244f1bed2c06abd997ab..15ca426701f1fc821da94a4dee577fdbc4f8ff8d 100644 +index a33d89fe9ca9e343edab8bb1cc88c54130ddb4a7..c0275197cc9aab2a49d88476e072a94f8e17e9ee 100644 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java @@ -31,6 +31,12 @@ public class EndCrystal extends Entity { @@ -7719,7 +7620,7 @@ index d8e440e14b72dc48ae97244f1bed2c06abd997ab..15ca426701f1fc821da94a4dee577fdb @Override protected Entity.MovementEmission getMovementEmission() { return Entity.MovementEmission.NONE; -@@ -78,8 +100,52 @@ public class EndCrystal extends Entity { +@@ -80,8 +102,52 @@ public class EndCrystal extends Entity { } } // Paper end - Fix invulnerable end crystals @@ -7772,7 +7673,7 @@ index d8e440e14b72dc48ae97244f1bed2c06abd997ab..15ca426701f1fc821da94a4dee577fdb } @Override -@@ -121,16 +187,18 @@ public class EndCrystal extends Entity { +@@ -123,16 +189,18 @@ public class EndCrystal extends Entity { } // CraftBukkit end if (!source.is(DamageTypeTags.IS_EXPLOSION)) { @@ -7794,10 +7695,10 @@ index d8e440e14b72dc48ae97244f1bed2c06abd997ab..15ca426701f1fc821da94a4dee577fdb this.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause } diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java -index 0e797e2714a2fd103cbd51548764577fd9b6412d..52e1dd6e064dc03312e18ca515a24e7d3e9be957 100644 +index 4d2fbade3a01ca26ff107f1323ae23db6dad8ef8..6d928144987fa8c5d14b3e53a91c33627d13531c 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 -@@ -106,6 +106,7 @@ public class EnderDragon extends Mob implements Enemy { +@@ -107,6 +107,7 @@ public class EnderDragon extends Mob implements Enemy { @Nullable private BlockPos podium; // Paper end - Allow changing the EnderDragon podium @@ -7805,7 +7706,7 @@ index 0e797e2714a2fd103cbd51548764577fd9b6412d..52e1dd6e064dc03312e18ca515a24e7d public EnderDragon(EntityType entitytypes, Level world) { super(EntityType.ENDER_DRAGON, world); -@@ -128,6 +129,37 @@ public class EnderDragon extends Mob implements Enemy { +@@ -129,6 +130,37 @@ public class EnderDragon extends Mob implements Enemy { this.noCulling = true; this.phaseManager = new EnderDragonPhaseManager(this); this.explosionSource = new Explosion(world, this, null, null, Double.NaN, Double.NaN, Double.NaN, Float.NaN, true, Explosion.BlockInteraction.DESTROY, ParticleTypes.EXPLOSION, ParticleTypes.EXPLOSION_EMITTER, SoundEvents.GENERIC_EXPLODE); // CraftBukkit @@ -7843,7 +7744,7 @@ index 0e797e2714a2fd103cbd51548764577fd9b6412d..52e1dd6e064dc03312e18ca515a24e7d } public void setDragonFight(EndDragonFight fight) { -@@ -142,6 +174,27 @@ public class EnderDragon extends Mob implements Enemy { +@@ -143,6 +175,27 @@ public class EnderDragon extends Mob implements Enemy { return this.fightOrigin; } @@ -7871,7 +7772,7 @@ index 0e797e2714a2fd103cbd51548764577fd9b6412d..52e1dd6e064dc03312e18ca515a24e7d public static AttributeSupplier.Builder createAttributes() { return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 200.0D); } -@@ -203,6 +256,37 @@ public class EnderDragon extends Mob implements Enemy { +@@ -204,6 +257,37 @@ public class EnderDragon extends Mob implements Enemy { @Override public void aiStep() { @@ -7909,7 +7810,7 @@ index 0e797e2714a2fd103cbd51548764577fd9b6412d..52e1dd6e064dc03312e18ca515a24e7d this.processFlappingMovement(); if (this.level().isClientSide) { this.setHealth(this.getHealth()); -@@ -229,6 +313,8 @@ public class EnderDragon extends Mob implements Enemy { +@@ -230,6 +314,8 @@ public class EnderDragon extends Mob implements Enemy { float f; if (this.isDeadOrDying()) { @@ -7918,7 +7819,7 @@ index 0e797e2714a2fd103cbd51548764577fd9b6412d..52e1dd6e064dc03312e18ca515a24e7d float f1 = (this.random.nextFloat() - 0.5F) * 8.0F; f = (this.random.nextFloat() - 0.5F) * 4.0F; -@@ -241,9 +327,9 @@ public class EnderDragon extends Mob implements Enemy { +@@ -242,9 +328,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); @@ -7930,7 +7831,7 @@ index 0e797e2714a2fd103cbd51548764577fd9b6412d..52e1dd6e064dc03312e18ca515a24e7d this.flapTime += f * 0.5F; } else { this.flapTime += f; -@@ -277,7 +363,7 @@ public class EnderDragon extends Mob implements Enemy { +@@ -278,7 +364,7 @@ public class EnderDragon extends Mob implements Enemy { } this.phaseManager.getCurrentPhase().doClientTick(); @@ -7939,16 +7840,16 @@ index 0e797e2714a2fd103cbd51548764577fd9b6412d..52e1dd6e064dc03312e18ca515a24e7d DragonPhaseInstance idragoncontroller = this.phaseManager.getCurrentPhase(); idragoncontroller.doServerTick(); -@@ -346,7 +432,7 @@ public class EnderDragon extends Mob implements Enemy { - this.tickPart(this.body, (double) (f11 * 0.5F), 0.0D, (double) (-f12 * 0.5F)); - this.tickPart(this.wing1, (double) (f12 * 4.5F), 2.0D, (double) (f11 * 4.5F)); - this.tickPart(this.wing2, (double) (f12 * -4.5F), 2.0D, (double) (f11 * -4.5F)); -- 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)); -@@ -390,7 +476,7 @@ public class EnderDragon extends Mob implements Enemy { +@@ -352,7 +438,7 @@ public class EnderDragon extends Mob implements Enemy { + if (world1 instanceof ServerLevel) { + ServerLevel worldserver1 = (ServerLevel) world1; + +- if (this.hurtTime == 0) { ++ if (!hasRider && this.hurtTime == 0) { // Purpur + this.knockBack(worldserver1, worldserver1.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(worldserver1, worldserver1.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(worldserver1.getEntities((Entity) this, this.head.getBoundingBox().inflate(1.0D), EntitySelector.NO_CREATIVE_OR_SPECTATOR)); +@@ -397,7 +483,7 @@ public class EnderDragon extends Mob implements Enemy { } if (!this.level().isClientSide) { @@ -7957,7 +7858,7 @@ index 0e797e2714a2fd103cbd51548764577fd9b6412d..52e1dd6e064dc03312e18ca515a24e7d if (this.dragonFight != null) { this.dragonFight.updateDragon(this); } -@@ -522,7 +608,7 @@ public class EnderDragon extends Mob implements Enemy { +@@ -539,7 +625,7 @@ public class EnderDragon extends Mob implements Enemy { BlockState iblockdata = this.level().getBlockState(blockposition); if (!iblockdata.isAir() && !iblockdata.is(BlockTags.DRAGON_TRANSPARENT)) { @@ -7966,7 +7867,7 @@ index 0e797e2714a2fd103cbd51548764577fd9b6412d..52e1dd6e064dc03312e18ca515a24e7d // CraftBukkit start - Add blocks to list rather than destroying them // flag1 = this.level().removeBlock(blockposition, false) || flag1; flag1 = true; -@@ -666,7 +752,7 @@ public class EnderDragon extends Mob implements Enemy { +@@ -683,7 +769,7 @@ public class EnderDragon extends Mob implements Enemy { boolean flag = this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT); short short0 = 500; @@ -7975,7 +7876,7 @@ index 0e797e2714a2fd103cbd51548764577fd9b6412d..52e1dd6e064dc03312e18ca515a24e7d short0 = 12000; } -@@ -1102,6 +1188,7 @@ public class EnderDragon extends Mob implements Enemy { +@@ -1119,6 +1205,7 @@ public class EnderDragon extends Mob implements Enemy { @Override protected boolean canRide(Entity entity) { @@ -7984,7 +7885,7 @@ index 0e797e2714a2fd103cbd51548764577fd9b6412d..52e1dd6e064dc03312e18ca515a24e7d } 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 7ddca52f7fe3f289b4b867e134326b1ead1a2aee..4a98027a12c2535d1df3a9f6390eb85146398403 100644 +index d3b4d492aee380dc17f4232d90eaae4f07bb9f86..49c48268431b06ea0e9dd680f7ed782f989175e8 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 @@ -88,20 +88,59 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob @@ -8048,7 +7949,7 @@ index 7ddca52f7fe3f289b4b867e134326b1ead1a2aee..4a98027a12c2535d1df3a9f6390eb851 @Override protected PathNavigation createNavigation(Level world) { FlyingPathNavigation navigationflying = new FlyingPathNavigation(this, world); -@@ -112,13 +151,113 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -112,13 +151,114 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob return navigationflying; } @@ -8144,7 +8045,8 @@ index 7ddca52f7fe3f289b4b867e134326b1ead1a2aee..4a98027a12c2535d1df3a9f6390eb851 + double headX = getHeadX(head); + double headY = getHeadY(head); + double headZ = getHeadZ(head); -+ WitherSkull skull = new WitherSkull(level(), this, x - headX, y - headY, z - headZ); ++ Vec3 vec3d = new Vec3(x - headX, y - headY, z - headZ); ++ WitherSkull skull = new WitherSkull(level(), this, vec3d.normalize()); + skull.setPosRaw(headX, headY, headZ); + level().addFreshEntity(skull); + } @@ -8162,7 +8064,7 @@ index 7ddca52f7fe3f289b4b867e134326b1ead1a2aee..4a98027a12c2535d1df3a9f6390eb851 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)); } -@@ -136,6 +275,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -136,6 +276,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob public void addAdditionalSaveData(CompoundTag nbt) { super.addAdditionalSaveData(nbt); nbt.putInt("Invul", this.getInvulnerableTicks()); @@ -8170,7 +8072,7 @@ index 7ddca52f7fe3f289b4b867e134326b1ead1a2aee..4a98027a12c2535d1df3a9f6390eb851 } @Override -@@ -145,6 +285,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -145,6 +286,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob if (this.hasCustomName()) { this.bossEvent.setName(this.getDisplayName()); } @@ -8178,7 +8080,7 @@ index 7ddca52f7fe3f289b4b867e134326b1ead1a2aee..4a98027a12c2535d1df3a9f6390eb851 } -@@ -263,6 +404,16 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -263,6 +405,16 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob @Override protected void customServerAiStep() { @@ -8195,7 +8097,7 @@ index 7ddca52f7fe3f289b4b867e134326b1ead1a2aee..4a98027a12c2535d1df3a9f6390eb851 int i; if (this.getInvulnerableTicks() > 0) { -@@ -279,7 +430,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -279,7 +431,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob } // CraftBukkit end @@ -8204,7 +8106,7 @@ index 7ddca52f7fe3f289b4b867e134326b1ead1a2aee..4a98027a12c2535d1df3a9f6390eb851 // CraftBukkit start - Use relative location for far away sounds // this.level().globalLevelEvent(1023, new BlockPosition(this), 0); int viewDistance = ((ServerLevel) this.level()).getCraftServer().getViewDistance() * 16; -@@ -304,7 +455,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -304,7 +456,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob this.setInvulnerableTicks(i); if (this.tickCount % 10 == 0) { @@ -8213,7 +8115,7 @@ index 7ddca52f7fe3f289b4b867e134326b1ead1a2aee..4a98027a12c2535d1df3a9f6390eb851 } } else { -@@ -364,7 +515,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -364,7 +516,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob if (this.destroyBlocksTick > 0) { --this.destroyBlocksTick; @@ -8222,7 +8124,7 @@ index 7ddca52f7fe3f289b4b867e134326b1ead1a2aee..4a98027a12c2535d1df3a9f6390eb851 boolean flag = false; j = Mth.floor(this.getBbWidth() / 2.0F + 1.0F); -@@ -391,8 +542,10 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -391,8 +543,10 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob } } @@ -8235,7 +8137,7 @@ index 7ddca52f7fe3f289b4b867e134326b1ead1a2aee..4a98027a12c2535d1df3a9f6390eb851 } this.bossEvent.setProgress(this.getHealth() / this.getMaxHealth()); -@@ -580,11 +733,11 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -580,11 +734,11 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob } public int getAlternativeTarget(int headIndex) { @@ -8249,7 +8151,7 @@ index 7ddca52f7fe3f289b4b867e134326b1ead1a2aee..4a98027a12c2535d1df3a9f6390eb851 } @Override -@@ -594,6 +747,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -594,6 +748,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob @Override protected boolean canRide(Entity entity) { @@ -8258,10 +8160,10 @@ index 7ddca52f7fe3f289b4b867e134326b1ead1a2aee..4a98027a12c2535d1df3a9f6390eb851 } 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 a02ca704e98ef42f32c3c50b111ee3537f60bf7b..92521cbedcf89a855f10a3401933acaf84bc3f98 100644 +index 2f398750bfee5758ad8b1367b6fc14364e4de776..ad1ec2578fa428baa6b172c44b6c17e52daa5792 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -@@ -103,10 +103,12 @@ public class ArmorStand extends LivingEntity { +@@ -102,10 +102,12 @@ public class ArmorStand extends LivingEntity { private boolean noTickPoseDirty = false; private boolean noTickEquipmentDirty = false; // Paper end - Allow ArmorStands not to tick @@ -8274,7 +8176,7 @@ index a02ca704e98ef42f32c3c50b111ee3537f60bf7b..92521cbedcf89a855f10a3401933acaf this.handItems = NonNullList.withSize(2, ItemStack.EMPTY); this.armorItems = NonNullList.withSize(4, ItemStack.EMPTY); this.headPose = ArmorStand.DEFAULT_HEAD_POSE; -@@ -115,6 +117,7 @@ public class ArmorStand extends LivingEntity { +@@ -114,6 +116,7 @@ public class ArmorStand extends LivingEntity { this.rightArmPose = ArmorStand.DEFAULT_RIGHT_ARM_POSE; this.leftLegPose = ArmorStand.DEFAULT_LEFT_LEG_POSE; this.rightLegPose = ArmorStand.DEFAULT_RIGHT_LEG_POSE; @@ -8282,15 +8184,15 @@ index a02ca704e98ef42f32c3c50b111ee3537f60bf7b..92521cbedcf89a855f10a3401933acaf } public ArmorStand(Level world, double x, double y, double z) { -@@ -613,6 +616,7 @@ public class ArmorStand extends LivingEntity { - private org.bukkit.event.entity.EntityDeathEvent brokenByPlayer(DamageSource damageSource) { // Paper +@@ -620,6 +623,7 @@ public class ArmorStand extends LivingEntity { + private org.bukkit.event.entity.EntityDeathEvent brokenByPlayer(ServerLevel world, DamageSource damageSource) { // Paper ItemStack itemstack = new ItemStack(Items.ARMOR_STAND); + if (this.level().purpurConfig.persistentDroppableEntityDisplayNames) itemstack.set(DataComponents.CUSTOM_NAME, this.getCustomName()); this.drops.add(new DefaultDrop(itemstack, stack -> Block.popResource(this.level(), this.blockPosition(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior - return this.brokenByAnything(damageSource); // Paper -@@ -676,6 +680,7 @@ public class ArmorStand extends LivingEntity { + return this.brokenByAnything(world, damageSource); // Paper +@@ -683,6 +687,7 @@ public class ArmorStand extends LivingEntity { @Override public void tick() { @@ -8298,7 +8200,7 @@ index a02ca704e98ef42f32c3c50b111ee3537f60bf7b..92521cbedcf89a855f10a3401933acaf // Paper start - Allow ArmorStands not to tick if (!this.canTick) { if (this.noTickPoseDirty) { -@@ -1008,4 +1013,18 @@ public class ArmorStand extends LivingEntity { +@@ -1015,4 +1020,18 @@ public class ArmorStand extends LivingEntity { } } // Paper end @@ -8318,10 +8220,10 @@ index a02ca704e98ef42f32c3c50b111ee3537f60bf7b..92521cbedcf89a855f10a3401933acaf + // 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 da0d1c9a1c4ae081bff9ca4230c9a1503885c354..9af8fcf6abb9b768829592bc1b091ebe4599ed2e 100644 +index 5b7245cd99593ee90e17c97e0104f3aba9ae05ea..cf78531b193ba56991ccb0c4f62844208e4a5706 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java -@@ -262,7 +262,13 @@ public class ItemFrame extends HangingEntity { +@@ -227,7 +227,13 @@ public class ItemFrame extends HangingEntity { } if (alwaysDrop) { @@ -8337,14 +8239,14 @@ index da0d1c9a1c4ae081bff9ca4230c9a1503885c354..9af8fcf6abb9b768829592bc1b091ebe if (!itemstack.isEmpty()) { diff --git a/src/main/java/net/minecraft/world/entity/decoration/Painting.java b/src/main/java/net/minecraft/world/entity/decoration/Painting.java -index 40e7112669abb58a0ab6df1846afec3979e95e55..183464f202d4c2774840edfde1dfcab44d05d0d3 100644 +index e86fdf5d6853b7bddfe19d6e5d41d3dec0c25f23..f45567aa7695da68f92809a6c208eb515c2f838a 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/Painting.java +++ b/src/main/java/net/minecraft/world/entity/decoration/Painting.java -@@ -151,7 +151,13 @@ public class Painting extends HangingEntity implements VariantHolder type, Level world) { super(type, world); -@@ -399,7 +405,16 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -400,7 +406,16 @@ public class ItemEntity extends Entity implements TraceableEntity { @Override public boolean hurt(DamageSource source, float amount) { @@ -8390,7 +8292,7 @@ index 8a5cbe95022a3ae41283f4f884d8b2f7eae0cd34..e380d1ea5b3dd6e91e79f6d7bd5d980a return false; } else if (!this.getItem().isEmpty() && this.getItem().is(Items.NETHER_STAR) && source.is(DamageTypeTags.IS_EXPLOSION)) { return false; -@@ -607,6 +622,12 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -608,6 +623,12 @@ public class ItemEntity extends Entity implements TraceableEntity { public void setItem(ItemStack stack) { this.getEntityData().set(ItemEntity.DATA_ITEM, stack); this.despawnRate = this.level().paperConfig().entities.spawning.altItemDespawnRate.enabled ? this.level().paperConfig().entities.spawning.altItemDespawnRate.items.getOrDefault(stack.getItem(), this.level().spigotConfig.itemDespawnRate) : this.level().spigotConfig.itemDespawnRate; // Paper - Alternative item-despawn-rate @@ -8404,10 +8306,10 @@ index 8a5cbe95022a3ae41283f4f884d8b2f7eae0cd34..e380d1ea5b3dd6e91e79f6d7bd5d980a @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 f1f352ec0e51f5db59254841a06c176c5a876fc9..dff0e7b08b973a1b29f916e63d3e4778d6c56cdc 100644 +index 42bd2d9a1528b6210e4dfb56233062fd97c9743b..2a4425d04917b32c7ae5af3e7422c0bafc2aa1c2 100644 --- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java +++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java -@@ -193,4 +193,29 @@ public class PrimedTnt extends Entity implements TraceableEntity { +@@ -230,4 +230,29 @@ public class PrimedTnt extends Entity implements TraceableEntity { return !level().paperConfig().fixes.preventTntFromMovingInWater && super.isPushedByFluid(); } // Paper end - Option to prevent TNT from moving in water @@ -8438,14 +8340,14 @@ index f1f352ec0e51f5db59254841a06c176c5a876fc9..dff0e7b08b973a1b29f916e63d3e4778 + // 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 0c5fe46d2da113beff3e220843593d616e37d4ca..7efe410a10d76e0e4c90a303f1ebecf54a8ff96b 100644 +index 3b5cf6ffb74d11bea5eb21bd66d679734ff5000c..e64a2a551a2190cf2edff3630f662f4a97605832 100644 --- a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java +++ b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java -@@ -65,16 +65,19 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo +@@ -66,16 +66,19 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo protected AbstractSkeleton(EntityType type, Level world) { super(type, world); this.reassessWeaponGoal(); -+ this.setShouldBurnInDay(true); // Purpur ++ this.setShouldBurnInDay(true); // Purpur - API for any mob to burn daylight } @Override @@ -8461,12 +8363,12 @@ index 0c5fe46d2da113beff3e220843593d616e37d4ca..7efe410a10d76e0e4c90a303f1ebecf5 this.targetSelector.addGoal(1, new HurtByTargetGoal(this, new Class[0])); this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true)); this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, IronGolem.class, true)); -@@ -93,35 +96,14 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo +@@ -94,37 +97,14 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo abstract SoundEvent getStepSound(); // Paper start - shouldBurnInDay API - private boolean shouldBurnInDay = true; -+ // private boolean shouldBurnInDay = true; // Purpur - moved to LivingEntity - keep methods for ABI compatibility ++ //private boolean shouldBurnInDay = true; // Purpur - moved to LivingEntity; keep methods for ABI compatibility - API for any mob to burn daylight public boolean shouldBurnInDay() { return shouldBurnInDay; } public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; } // Paper end - shouldBurnInDay API @@ -8480,9 +8382,11 @@ index 0c5fe46d2da113beff3e220843593d616e37d4ca..7efe410a10d76e0e4c90a303f1ebecf5 - - if (!itemstack.isEmpty()) { - if (itemstack.isDamageableItem()) { +- Item item = itemstack.getItem(); +- - itemstack.setDamageValue(itemstack.getDamageValue() + this.random.nextInt(2)); - if (itemstack.getDamageValue() >= itemstack.getMaxDamage()) { -- this.broadcastBreakEvent(EquipmentSlot.HEAD); +- this.onEquippedItemBroken(item, EquipmentSlot.HEAD); - this.setItemSlot(EquipmentSlot.HEAD, ItemStack.EMPTY); - } - } @@ -8491,15 +8395,15 @@ index 0c5fe46d2da113beff3e220843593d616e37d4ca..7efe410a10d76e0e4c90a303f1ebecf5 - } - - if (flag) { -- this.igniteForSeconds(8); +- this.igniteForSeconds(8.0F); - } - } - -+ // Purpur start - implemented in LivingEntity ++ // Purpur - implemented in LivingEntity - API for any mob to burn daylight super.aiStep(); } -@@ -205,7 +187,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo +@@ -209,7 +189,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo double d2 = target.getZ() - this.getZ(); double d3 = Math.sqrt(d0 * d0 + d2 * d2); @@ -8508,26 +8412,26 @@ index 0c5fe46d2da113beff3e220843593d616e37d4ca..7efe410a10d76e0e4c90a303f1ebecf5 // 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()) { -@@ -236,7 +218,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo +@@ -239,7 +219,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo + super.readAdditionalSaveData(nbt); this.reassessWeaponGoal(); // Paper start - shouldBurnInDay API - if (nbt.contains("Paper.ShouldBurnInDay")) { -- this.shouldBurnInDay = nbt.getBoolean("Paper.ShouldBurnInDay"); -+ // this.shouldBurnInDay = nbt.getBoolean("Paper.ShouldBurnInDay"); // Purpur - implemented in LivingEntity +- if (nbt.contains("Paper.ShouldBurnInDay")) { ++ if (false && nbt.contains("Paper.ShouldBurnInDay")) { // Purpur - implemented in LivingEntity - API for any mob to burn daylight + this.shouldBurnInDay = nbt.getBoolean("Paper.ShouldBurnInDay"); } // Paper end - shouldBurnInDay API - } -@@ -245,7 +227,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo +@@ -249,7 +229,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo @Override public void addAdditionalSaveData(CompoundTag nbt) { super.addAdditionalSaveData(nbt); - nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); -+ // nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Purpur - implemented in LivingEntity ++ //nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Purpur - implemented in LivingEntity - API for any mob to burn daylight } // Paper end - shouldBurnInDay API diff --git a/src/main/java/net/minecraft/world/entity/monster/Blaze.java b/src/main/java/net/minecraft/world/entity/monster/Blaze.java -index aee2fa184bc5723dfd3d54f460a173982d874c8b..27db17e19dd95e99f7bd67747eba3c3072b48ed5 100644 +index 61004bb35b0edcc4578b8a9c1b280096466ba279..1e1824eb80696452951cdbbdacad952ae0a7482b 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 { @@ -8627,7 +8531,7 @@ index aee2fa184bc5723dfd3d54f460a173982d874c8b..27db17e19dd95e99f7bd67747eba3c30 if (this.nextHeightOffsetChangeTick <= 0) { this.nextHeightOffsetChangeTick = 100; diff --git a/src/main/java/net/minecraft/world/entity/monster/Bogged.java b/src/main/java/net/minecraft/world/entity/monster/Bogged.java -index e9f9b041ae7195e9d23bd446454b1d8c47a1ace1..fed6e686c29ad0117731a80294e6725f41d8bf77 100644 +index 6e290d67b00c88ecd2cf2ce5f612f52ebda9e280..a39ea8cf75adbf84388b74222b3417a4c45acef5 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Bogged.java +++ b/src/main/java/net/minecraft/world/entity/monster/Bogged.java @@ -45,6 +45,28 @@ public class Bogged extends AbstractSkeleton implements Shearable { @@ -8712,7 +8616,7 @@ index 87e4b300ac248f6c13d9b4a8f24fd78b24b565b4..43b5a0e7993ae9daef1c1ea67722347f 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 0ae4ba060b2ce2c79e1235c939f3c1926eb6e33e..76a0bc9bd6033f1c66e940392f5bed360e7db43c 100644 +index cb1b19e2e0d8f0744b2355b8f4da0206b196b19c..8da09124158ce679ce1e34fa1e3c5a049f2595fb 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java +++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java @@ -61,21 +61,99 @@ public class Creeper extends Monster implements PowerableMob { @@ -8723,8 +8627,8 @@ index 0ae4ba060b2ce2c79e1235c939f3c1926eb6e33e..76a0bc9bd6033f1c66e940392f5bed36 + private int spacebarCharge = 0; + private int prevSpacebarCharge = 0; + private int powerToggleDelay = 0; -+ private boolean exploding = false; + // Purpur end ++ private boolean exploding = false; // Purpur - Config to make Creepers explode on death public Creeper(EntityType type, Level world) { super(type, world); @@ -8815,7 +8719,7 @@ index 0ae4ba060b2ce2c79e1235c939f3c1926eb6e33e..76a0bc9bd6033f1c66e940392f5bed36 this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Player.class, true)); this.targetSelector.addGoal(2, new HurtByTargetGoal(this, new Class[0])); } -@@ -175,6 +253,37 @@ public class Creeper extends Monster implements PowerableMob { +@@ -175,6 +253,39 @@ public class Creeper extends Monster implements PowerableMob { } } @@ -8837,13 +8741,15 @@ index 0ae4ba060b2ce2c79e1235c939f3c1926eb6e33e..76a0bc9bd6033f1c66e940392f5bed36 + return this.level().purpurConfig.creeperTakeDamageFromWater; + } + ++ // Purpur start - Config to make Creepers explode on death + @Override -+ protected org.bukkit.event.entity.EntityDeathEvent dropAllDeathLoot(DamageSource damagesource) { -+ if (!exploding && this.level().purpurConfig.creeperExplodeWhenKilled && damagesource.getEntity() instanceof net.minecraft.server.level.ServerPlayer) { ++ protected org.bukkit.event.entity.EntityDeathEvent dropAllDeathLoot(ServerLevel world, DamageSource damageSource) { ++ if (!this.exploding && this.level().purpurConfig.creeperExplodeWhenKilled && damageSource.getEntity() instanceof net.minecraft.server.level.ServerPlayer) { + this.explodeCreeper(); + } -+ return super.dropAllDeathLoot(damagesource); ++ return super.dropAllDeathLoot(world, damageSource); + } ++ // Purpur end - Config to make Creepers explode on death + + @Override + protected boolean isAlwaysExperienceDropper() { @@ -8853,11 +8759,12 @@ index 0ae4ba060b2ce2c79e1235c939f3c1926eb6e33e..76a0bc9bd6033f1c66e940392f5bed36 @Override protected SoundEvent getHurtSound(DamageSource source) { return SoundEvents.CREEPER_HURT; -@@ -263,15 +372,17 @@ public class Creeper extends Monster implements PowerableMob { +@@ -263,15 +374,18 @@ public class Creeper extends Monster implements PowerableMob { } public void explodeCreeper() { -+ this.exploding = true; // Purpur ++ this.exploding = true; // Purpur - Config to make Creepers explode on death ++ if (!this.level().isClientSide) { float f = this.isPowered() ? 2.0F : 1.0F; + float multiplier = this.level().purpurConfig.creeperHealthRadius ? this.getHealth() / this.getMaxHealth() : 1; // Purpur @@ -8870,19 +8777,18 @@ index 0ae4ba060b2ce2c79e1235c939f3c1926eb6e33e..76a0bc9bd6033f1c66e940392f5bed36 this.dead = true; - this.level().explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB); // CraftBukkit // Paper - fix DamageSource API (revert to vanilla, no, just no, don't change this) + this.level().explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), this.level().getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING) && level().purpurConfig.creeperAllowGriefing ? Level.ExplosionInteraction.MOB : Level.ExplosionInteraction.NONE); // CraftBukkit // Paper - fix DamageSource API (revert to vanilla, no, just no, don't change this) // Purpur - this.discard(EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause this.spawnLingeringCloud(); - // CraftBukkit start -@@ -281,7 +392,7 @@ public class Creeper extends Monster implements PowerableMob { - } + this.triggerOnDeathMobEffects(Entity.RemovalReason.KILLED); + this.discard(EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause +@@ -283,6 +397,7 @@ public class Creeper extends Monster implements PowerableMob { // CraftBukkit end } -- -+ this.exploding = false; // Purpur + ++ this.exploding = false; // Purpur - Config to make Creepers explode on death } private void spawnLingeringCloud() { -@@ -323,6 +434,7 @@ public class Creeper extends Monster implements PowerableMob { +@@ -324,6 +439,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()); @@ -9063,10 +8969,10 @@ index fd995b1f29c47884e9db2cb92f1dd615d62ae032..7e8603ef5df722f19e85b9c5cdd4ebfd 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 15b544bd0794e021ed4a9fde94883bcb5c6a3521..e2518ca9196ae93cd98fcae0781c85d39d7e9622 100644 +index 7b05ef99702af0e8a7d2a652984c4f8c15eefed8..1a4de372061158253cc070c94d55ad8a0721989e 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java +++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java -@@ -90,12 +90,40 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -92,12 +92,40 @@ public class EnderMan extends Monster implements NeutralMob { public EnderMan(EntityType type, Level world) { super(type, world); @@ -9108,7 +9014,7 @@ index 15b544bd0794e021ed4a9fde94883bcb5c6a3521..e2518ca9196ae93cd98fcae0781c85d3 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)); -@@ -103,9 +131,10 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -105,9 +133,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)); @@ -9120,7 +9026,7 @@ index 15b544bd0794e021ed4a9fde94883bcb5c6a3521..e2518ca9196ae93cd98fcae0781c85d3 this.targetSelector.addGoal(4, new ResetUniversalAngerTargetGoal<>(this, false)); } -@@ -242,7 +271,7 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -244,7 +273,7 @@ public class EnderMan extends Monster implements NeutralMob { // Paper end - EndermanAttackPlayerEvent ItemStack itemstack = (ItemStack) player.getInventory().armor.get(3); @@ -9129,7 +9035,7 @@ index 15b544bd0794e021ed4a9fde94883bcb5c6a3521..e2518ca9196ae93cd98fcae0781c85d3 return false; } else { Vec3 vec3d = player.getViewVector(1.0F).normalize(); -@@ -274,12 +303,12 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -276,12 +305,12 @@ public class EnderMan extends Monster implements NeutralMob { @Override public boolean isSensitiveToWater() { @@ -9144,7 +9050,7 @@ index 15b544bd0794e021ed4a9fde94883bcb5c6a3521..e2518ca9196ae93cd98fcae0781c85d3 float f = this.getLightLevelDependentMagicValue(); if (f > 0.5F && this.level().canSeeSky(this.blockPosition()) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.RUNAWAY)) { // Paper - EndermanEscapeEvent -@@ -400,6 +429,8 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -402,6 +431,8 @@ public class EnderMan extends Monster implements NeutralMob { public boolean hurt(DamageSource source, float amount) { if (this.isInvulnerableTo(source)) { return false; @@ -9153,7 +9059,7 @@ index 15b544bd0794e021ed4a9fde94883bcb5c6a3521..e2518ca9196ae93cd98fcae0781c85d3 } else { boolean flag = source.getDirectEntity() instanceof ThrownPotion; boolean flag1; -@@ -414,6 +445,7 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -416,6 +447,7 @@ public class EnderMan extends Monster implements NeutralMob { } else { flag1 = flag && this.hurtWithCleanWater(source, (ThrownPotion) source.getDirectEntity(), amount); @@ -9161,7 +9067,7 @@ index 15b544bd0794e021ed4a9fde94883bcb5c6a3521..e2518ca9196ae93cd98fcae0781c85d3 if (this.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.INDIRECT)) { // Paper - EndermanEscapeEvent for (int i = 0; i < 64; ++i) { if (this.teleport()) { -@@ -458,7 +490,7 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -460,7 +492,7 @@ public class EnderMan extends Monster implements NeutralMob { @Override public boolean requiresCustomPersistence() { @@ -9170,7 +9076,7 @@ index 15b544bd0794e021ed4a9fde94883bcb5c6a3521..e2518ca9196ae93cd98fcae0781c85d3 } private static class EndermanFreezeWhenLookedAt extends Goal { -@@ -505,7 +537,16 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -507,7 +539,16 @@ public class EnderMan extends Monster implements NeutralMob { @Override public boolean canUse() { @@ -9188,7 +9094,7 @@ index 15b544bd0794e021ed4a9fde94883bcb5c6a3521..e2518ca9196ae93cd98fcae0781c85d3 } @Override -@@ -550,7 +591,16 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -552,7 +593,16 @@ public class EnderMan extends Monster implements NeutralMob { @Override public boolean canUse() { @@ -9290,7 +9196,7 @@ index 9c78905762d9a484878fa9cf03a2ca3850e7e613..14d6796a124a85b8cbf5f3b719d89d99 @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 38e866571c35ebc4843a8d4fa39691902a5fcc91..f92f93c780f4c176d6c02c4b98ffe3a4ef3993f6 100644 +index 627cf7ba8f512285228121e46208fff51f22b563..781434438353d00f71f65af760fa4fb19ef6c3bb 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Evoker.java +++ b/src/main/java/net/minecraft/world/entity/monster/Evoker.java @@ -52,10 +52,43 @@ public class Evoker extends SpellcasterIllager { @@ -9355,7 +9261,7 @@ index 38e866571c35ebc4843a8d4fa39691902a5fcc91..f92f93c780f4c176d6c02c4b98ffe3a4 } else { List list = Evoker.this.level().getNearbyEntities(Sheep.class, this.wololoTargeting, Evoker.this, Evoker.this.getBoundingBox().inflate(16.0D, 4.0D, 16.0D)); diff --git a/src/main/java/net/minecraft/world/entity/monster/Ghast.java b/src/main/java/net/minecraft/world/entity/monster/Ghast.java -index 373a4f036157017b0d95e8f1849780582235a549..a25c82be45e3db5143f6bf617fedc2fa85bd89ca 100644 +index a836a902bebf318ceabaed4e98fab1141b46a28b..802d2e0eb9c007a1d087333a797ab9025edd24b7 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Ghast.java +++ b/src/main/java/net/minecraft/world/entity/monster/Ghast.java @@ -43,11 +43,47 @@ public class Ghast extends FlyingMob implements Enemy { @@ -9456,7 +9362,7 @@ index 373a4f036157017b0d95e8f1849780582235a549..a25c82be45e3db5143f6bf617fedc2fa 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 118521ae54254b0a73bb7cba7b2871c9c26f89fc..eab74acdcc644aa844d3daceee2d568e4f247428 100644 +index 118521ae54254b0a73bb7cba7b2871c9c26f89fc..262f0a9146d37ebdb600b8d304cea3d9bcfc8398 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Giant.java +++ b/src/main/java/net/minecraft/world/entity/monster/Giant.java @@ -12,12 +12,94 @@ public class Giant extends Monster { @@ -9528,7 +9434,7 @@ index 118521ae54254b0a73bb7cba7b2871c9c26f89fc..eab74acdcc644aa844d3daceee2d568e + net.minecraft.world.entity.SpawnGroupData groupData = super.finalizeSpawn(world, difficulty, spawnReason, entityData); + if (groupData == null) { + populateDefaultEquipmentSlots(this.random, difficulty); -+ populateDefaultEquipmentEnchantments(this.random, difficulty); ++ populateDefaultEquipmentEnchantments(world, this.random, difficulty); + } + return groupData; + } @@ -9556,7 +9462,7 @@ index 118521ae54254b0a73bb7cba7b2871c9c26f89fc..eab74acdcc644aa844d3daceee2d568e } } 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 6c2e2fd5826a5f8070502e20d1d140c3d70bd0d3..f9496126f75b4c1b89ec33617e577d83042e0290 100644 +index 5df07b59ff6e39687e361d89d7764381ca3ce9ca..5923c800f6b510eb6f17540867607bd64f8e70f5 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Guardian.java +++ b/src/main/java/net/minecraft/world/entity/monster/Guardian.java @@ -66,15 +66,51 @@ public class Guardian extends Monster { @@ -9666,14 +9572,14 @@ index 6c2e2fd5826a5f8070502e20d1d140c3d70bd0d3..f9496126f75b4c1b89ec33617e577d83 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 c34c8483a026f61fe20935697d321d7ef5d8dfbc..95d3edc6c88d6ed0556c21c2623cdd5cfda35911 100644 +index c34c8483a026f61fe20935697d321d7ef5d8dfbc..a9285aac811067313c5609d2d5708783736e6cb5 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Husk.java +++ b/src/main/java/net/minecraft/world/entity/monster/Husk.java @@ -20,6 +20,59 @@ public class Husk extends Zombie { public Husk(EntityType type, Level world) { super(type, world); -+ this.setShouldBurnInDay(false); // Purpur ++ this.setShouldBurnInDay(false); // Purpur - API for any mob to burn daylight + } + + // Purpur start @@ -9734,15 +9640,15 @@ index c34c8483a026f61fe20935697d321d7ef5d8dfbc..95d3edc6c88d6ed0556c21c2623cdd5c @Override public boolean isSunSensitive() { - return false; -+ return this.shouldBurnInDay; // Purpur - moved to LivingEntity - keep methods for ABI compatibility ++ return this.shouldBurnInDay; // Purpur - moved to LivingEntity; keep methods for ABI compatibility - API for any mob to burn daylight } @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 a7964208c952cb4e34916ae6523850fc3921b07e..ae036a16e3677dfba451f4eb4505036d45e50cf3 100644 +index c858556ea457931aa14e338e20672cb50cb19f0e..c21595b6b4eac187eb9f57c6aa4c6074da929162 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Illusioner.java +++ b/src/main/java/net/minecraft/world/entity/monster/Illusioner.java -@@ -56,10 +56,45 @@ public class Illusioner extends SpellcasterIllager implements RangedAttackMob { +@@ -57,10 +57,45 @@ public class Illusioner extends SpellcasterIllager implements RangedAttackMob { } @@ -9788,7 +9694,7 @@ index a7964208c952cb4e34916ae6523850fc3921b07e..ae036a16e3677dfba451f4eb4505036d this.goalSelector.addGoal(1, new SpellcasterIllager.SpellcasterCastingSpellGoal()); this.goalSelector.addGoal(4, new Illusioner.IllusionerMirrorSpellGoal()); this.goalSelector.addGoal(5, new Illusioner.IllusionerBlindnessSpellGoal()); -@@ -67,6 +102,7 @@ public class Illusioner extends SpellcasterIllager implements RangedAttackMob { +@@ -68,6 +103,7 @@ public class Illusioner extends SpellcasterIllager implements RangedAttackMob { this.goalSelector.addGoal(8, new RandomStrollGoal(this, 0.6D)); this.goalSelector.addGoal(9, new LookAtPlayerGoal(this, Player.class, 3.0F, 1.0F)); this.goalSelector.addGoal(10, new LookAtPlayerGoal(this, Mob.class, 8.0F)); @@ -9797,7 +9703,7 @@ index a7964208c952cb4e34916ae6523850fc3921b07e..ae036a16e3677dfba451f4eb4505036d 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 7be2393dc3cb79556d9767b09f43be0f81308a12..e7c79e8c72226285eb5a4763dcf8ddd27078539c 100644 +index d85a1587a11e735b97107c53ac540cdbe2923ed0..e749050be1e2e7b0e5babb86bbcf88db9c47603c 100644 --- a/src/main/java/net/minecraft/world/entity/monster/MagmaCube.java +++ b/src/main/java/net/minecraft/world/entity/monster/MagmaCube.java @@ -24,6 +24,58 @@ public class MagmaCube extends Slime { @@ -9859,13 +9765,7 @@ index 7be2393dc3cb79556d9767b09f43be0f81308a12..e7c79e8c72226285eb5a4763dcf8ddd2 public static AttributeSupplier.Builder createAttributes() { return Monster.createMonsterAttributes().add(Attributes.MOVEMENT_SPEED, 0.2F); } -@@ -64,11 +116,12 @@ public class MagmaCube extends Slime { - } - - @Override -- protected void jumpFromGround() { -+ public void jumpFromGround() { // Purpur - protected -> public - Vec3 vec3 = this.getDeltaMovement(); +@@ -69,6 +121,7 @@ public class MagmaCube extends Slime { float f = (float)this.getSize() * 0.1F; this.setDeltaMovement(vec3.x, (double)(this.getJumpPower() + f), vec3.z); this.hasImpulse = true; @@ -9893,7 +9793,7 @@ index 759839e912c54598b257ad738481364940f88a18..e60e6b3e5ae5a468cfe649ed2222412f return false; } else { diff --git a/src/main/java/net/minecraft/world/entity/monster/Phantom.java b/src/main/java/net/minecraft/world/entity/monster/Phantom.java -index 68f8945292753535a3b73acb9f48c1594f0789a4..26077bd6eeedbdae84613188cb0f336abb3563d2 100644 +index c277dac448a64809e93dd7a447ee3dc2a86c860e..493e9ee0585ae419caffaa163f4975ab6408fad8 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java +++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java @@ -48,6 +48,8 @@ public class Phantom extends FlyingMob implements Enemy { @@ -9909,7 +9809,7 @@ index 68f8945292753535a3b73acb9f48c1594f0789a4..26077bd6eeedbdae84613188cb0f336a this.xpReward = 5; this.moveControl = new Phantom.PhantomMoveControl(this); this.lookControl = new Phantom.PhantomLookControl(this, this); -+ this.setShouldBurnInDay(true); // Purpur ++ this.setShouldBurnInDay(true); // Purpur - API for any mob to burn daylight + } + + // Purpur start @@ -10063,10 +9963,10 @@ index 68f8945292753535a3b73acb9f48c1594f0789a4..26077bd6eeedbdae84613188cb0f336a @Override public void aiStep() { - if (this.isAlive() && this.shouldBurnInDay && this.isSunBurnTick()) { // Paper - shouldBurnInDay API -- this.igniteForSeconds(8); +- this.igniteForSeconds(8.0F); - } - -+ // Purpur - moved down to shouldBurnInDay() ++ // Purpur - implemented in LivingEntity; moved down to shouldBurnInDay() - API for any mob to burn daylight super.aiStep(); } @@ -10088,7 +9988,7 @@ index 68f8945292753535a3b73acb9f48c1594f0789a4..26077bd6eeedbdae84613188cb0f336a this.spawningEntity = nbt.getUUID("Paper.SpawningEntity"); } - if (nbt.contains("Paper.ShouldBurnInDay")) { -+ if (false && nbt.contains("Paper.ShouldBurnInDay")) { // Purpur - implemented in LivingEntity ++ if (false && nbt.contains("Paper.ShouldBurnInDay")) { // Purpur - implemented in LivingEntity - API for any mob to burn daylight this.shouldBurnInDay = nbt.getBoolean("Paper.ShouldBurnInDay"); } // Paper end @@ -10097,29 +9997,28 @@ index 68f8945292753535a3b73acb9f48c1594f0789a4..26077bd6eeedbdae84613188cb0f336a nbt.putUUID("Paper.SpawningEntity", this.spawningEntity); } - nbt.putBoolean("Paper.ShouldBurnInDay", shouldBurnInDay); -+ // nbt.putBoolean("Paper.ShouldBurnInDay", shouldBurnInDay); // Purpur - implemented in LivingEntity ++ //nbt.putBoolean("Paper.ShouldBurnInDay", shouldBurnInDay); // Purpur - implemented in LivingEntity - API for any mob to burn daylight // Paper end } -@@ -242,8 +358,15 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -242,8 +358,14 @@ public class Phantom extends FlyingMob implements Enemy { return this.spawningEntity; } public void setSpawningEntity(java.util.UUID entity) { this.spawningEntity = entity; } - private boolean shouldBurnInDay = true; - public boolean shouldBurnInDay() { return shouldBurnInDay; } -+ -+ // private boolean shouldBurnInDay = true; // Purpur - moved to LivingEntity - keep methods for ABI compatibility -+ // Purpur start ++ //private boolean shouldBurnInDay = true; // Purpur - moved to LivingEntity; keep methods for ABI compatibility - API for any mob to burn daylight ++ // Purpur start - API for any mob to burn daylight + 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; + return burnFromDaylight || burnFromLightSource; + } -+ // Purpur End ++ // Purpur end - API for any mob to burn daylight public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; } // Paper end -@@ -254,7 +377,125 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -254,7 +376,125 @@ public class Phantom extends FlyingMob implements Enemy { private AttackPhase() {} } @@ -10246,7 +10145,7 @@ index 68f8945292753535a3b73acb9f48c1594f0789a4..26077bd6eeedbdae84613188cb0f336a private float speed = 0.1F; -@@ -262,8 +503,19 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -262,8 +502,19 @@ public class Phantom extends FlyingMob implements Enemy { super(entity); } @@ -10267,7 +10166,7 @@ index 68f8945292753535a3b73acb9f48c1594f0789a4..26077bd6eeedbdae84613188cb0f336a if (Phantom.this.horizontalCollision) { Phantom.this.setYRot(Phantom.this.getYRot() + 180.0F); this.speed = 0.1F; -@@ -309,14 +561,20 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -309,14 +560,20 @@ public class Phantom extends FlyingMob implements Enemy { } } @@ -10290,7 +10189,7 @@ index 68f8945292753535a3b73acb9f48c1594f0789a4..26077bd6eeedbdae84613188cb0f336a } private class PhantomBodyRotationControl extends BodyRotationControl { -@@ -403,6 +661,12 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -403,6 +660,12 @@ public class Phantom extends FlyingMob implements Enemy { return false; } else if (!entityliving.isAlive()) { return false; @@ -10303,7 +10202,7 @@ index 68f8945292753535a3b73acb9f48c1594f0789a4..26077bd6eeedbdae84613188cb0f336a } else { if (entityliving instanceof Player) { Player entityhuman = (Player) entityliving; -@@ -548,6 +812,7 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -548,6 +811,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)); @@ -10312,10 +10211,10 @@ index 68f8945292753535a3b73acb9f48c1594f0789a4..26077bd6eeedbdae84613188cb0f336a 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 ac411202c0029052a962b51b015da191b124de5f..ae3eb87af8d3853be82c2002507141e43ab644de 100644 +index 4b4dcee6abe7a6db43638d04665125eec560496e..a43dbeaad8d8fda02a07680969eefdfd1e7fbae0 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Pillager.java +++ b/src/main/java/net/minecraft/world/entity/monster/Pillager.java -@@ -58,15 +58,49 @@ public class Pillager extends AbstractIllager implements CrossbowAttackMob, Inve +@@ -62,15 +62,49 @@ public class Pillager extends AbstractIllager implements CrossbowAttackMob, Inve super(type, world); } @@ -10366,10 +10265,10 @@ index ac411202c0029052a962b51b015da191b124de5f..ae3eb87af8d3853be82c2002507141e4 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 2d7b7c949faaaaae94c0043132a4a822f55df104..dbfcca8adb7afa7a3101f22c2bc48aff6abae4a2 100644 +index 212d341425c0f93bba0376de69bea61ffcf4dbd6..0c494a8c71e316307af2c0e256ccfd23685f8219 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Ravager.java +++ b/src/main/java/net/minecraft/world/entity/monster/Ravager.java -@@ -68,14 +68,55 @@ public class Ravager extends Raider { +@@ -69,14 +69,55 @@ public class Ravager extends Raider { this.setPathfindingMalus(PathType.LEAVES, 0.0F); } @@ -10425,7 +10324,7 @@ index 2d7b7c949faaaaae94c0043132a4a822f55df104..dbfcca8adb7afa7a3101f22c2bc48aff 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) -> { -@@ -128,7 +169,7 @@ public class Ravager extends Raider { +@@ -129,7 +170,7 @@ public class Ravager extends Raider { @Override public void aiStep() { super.aiStep(); @@ -10434,7 +10333,7 @@ index 2d7b7c949faaaaae94c0043132a4a822f55df104..dbfcca8adb7afa7a3101f22c2bc48aff if (this.isImmobile()) { this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.0D); } else { -@@ -138,7 +179,7 @@ public class Ravager extends Raider { +@@ -139,7 +180,7 @@ public class Ravager extends Raider { this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(Mth.lerp(0.1D, d1, d0)); } @@ -10443,7 +10342,7 @@ index 2d7b7c949faaaaae94c0043132a4a822f55df104..dbfcca8adb7afa7a3101f22c2bc48aff 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(); -@@ -148,7 +189,7 @@ public class Ravager extends Raider { +@@ -149,7 +190,7 @@ public class Ravager extends Raider { BlockState iblockdata = this.level().getBlockState(blockposition); Block block = iblockdata.getBlock(); @@ -10453,7 +10352,7 @@ index 2d7b7c949faaaaae94c0043132a4a822f55df104..dbfcca8adb7afa7a3101f22c2bc48aff 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 e03119f88719c8d6d44793a6b3706ae97b2da307..eb2ccb04494b8079185d649ecf1aef6356ee73f6 100644 +index 920c7a92643e83598f39bf984cca430d9deed2cd..18fb2fd83a6b8234cca5d51e931582c391f60207 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Shulker.java +++ b/src/main/java/net/minecraft/world/entity/monster/Shulker.java @@ -97,12 +97,59 @@ public class Shulker extends AbstractGolem implements VariantHolder type, Level world) { super(type, world); -@@ -68,12 +69,89 @@ public class Slime extends Mob implements Enemy { +@@ -70,12 +71,89 @@ public class Slime extends Mob implements Enemy { this.moveControl = new Slime.SlimeMoveControl(this); } @@ -10864,7 +10759,7 @@ index f223e78eb1204bbf5f2de38a7ce5b663800f7dc4..ccf7fea215d3096e76db294daa5874fe this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, (entityliving) -> { return Math.abs(entityliving.getY() - this.getY()) <= 4.0D; })); -@@ -98,9 +176,9 @@ public class Slime extends Mob implements Enemy { +@@ -100,9 +178,9 @@ public class Slime extends Mob implements Enemy { this.entityData.set(Slime.ID_SIZE, j); this.reapplyPosition(); this.refreshDimensions(); @@ -10876,13 +10771,7 @@ index f223e78eb1204bbf5f2de38a7ce5b663800f7dc4..ccf7fea215d3096e76db294daa5874fe if (heal) { this.setHealth(this.getMaxHealth()); } -@@ -382,11 +460,12 @@ public class Slime extends Mob implements Enemy { - } - - @Override -- protected void jumpFromGround() { -+ public void jumpFromGround() { // Purpur - protected -> public - Vec3 vec3d = this.getDeltaMovement(); +@@ -395,6 +473,7 @@ public class Slime extends Mob implements Enemy { this.setDeltaMovement(vec3d.x, (double) this.getJumpPower(), vec3d.z); this.hasImpulse = true; @@ -10890,7 +10779,7 @@ index f223e78eb1204bbf5f2de38a7ce5b663800f7dc4..ccf7fea215d3096e76db294daa5874fe } @Nullable -@@ -420,7 +499,7 @@ public class Slime extends Mob implements Enemy { +@@ -428,7 +507,7 @@ public class Slime extends Mob implements Enemy { return super.getDefaultDimensions(pose).scale((float) this.getSize()); } @@ -10899,7 +10788,7 @@ index f223e78eb1204bbf5f2de38a7ce5b663800f7dc4..ccf7fea215d3096e76db294daa5874fe private float yRot; private int jumpDelay; -@@ -439,21 +518,33 @@ public class Slime extends Mob implements Enemy { +@@ -447,21 +526,33 @@ public class Slime extends Mob implements Enemy { } public void setWantedMovement(double speed) { @@ -10936,7 +10825,7 @@ index f223e78eb1204bbf5f2de38a7ce5b663800f7dc4..ccf7fea215d3096e76db294daa5874fe if (this.jumpDelay-- <= 0) { this.jumpDelay = this.slime.getJumpDelay(); if (this.isAggressive) { -@@ -470,7 +561,7 @@ public class Slime extends Mob implements Enemy { +@@ -478,7 +569,7 @@ public class Slime extends Mob implements Enemy { this.mob.setSpeed(0.0F); } } else { @@ -10946,7 +10835,7 @@ index f223e78eb1204bbf5f2de38a7ce5b663800f7dc4..ccf7fea215d3096e76db294daa5874fe } 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 fa0316e9d2a4cf213982994dc8bf310299cca984..159740069aba59bffff444d933af32aaf752ba48 100644 +index e675f1e3e5b6f9e1aa0d928ebb9abe76458edb38..834889f568c9b89d8b609d959adf8c6179c43417 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Spider.java +++ b/src/main/java/net/minecraft/world/entity/monster/Spider.java @@ -51,9 +51,42 @@ public class Spider extends Monster { @@ -11001,10 +10890,10 @@ index fa0316e9d2a4cf213982994dc8bf310299cca984..159740069aba59bffff444d933af32aa 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 207a649d737adff440bd3f7cba15b0dbca338a35..18c0cf991c2e8418d7fdd4c8dbd7487a301e890d 100644 +index 1b8ab3f1090ea78bdba97265e05576c9a3e2deb3..588c8cefefde335cc9c02f77d0d050ee13bbb8d2 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 { +@@ -22,6 +22,38 @@ public class Stray extends AbstractSkeleton { super(type, world); } @@ -11044,7 +10933,7 @@ index 207a649d737adff440bd3f7cba15b0dbca338a35..18c0cf991c2e8418d7fdd4c8dbd7487a BlockPos blockPos = pos; diff --git a/src/main/java/net/minecraft/world/entity/monster/Strider.java b/src/main/java/net/minecraft/world/entity/monster/Strider.java -index fe85900a610afd0b237d8b5a164181c03afbdfc7..5ea5bf9c0e11b0e1f9fe50093899c6e35ee6cf4f 100644 +index 2c5bfad3c1ae9a19b4762831a3abdd5e89ba24b3..346237b266f3044101d45c69b857f57c701411b3 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Strider.java +++ b/src/main/java/net/minecraft/world/entity/monster/Strider.java @@ -91,12 +91,44 @@ public class Strider extends Animal implements ItemSteerable, Saddleable { @@ -11140,7 +11029,7 @@ index fe85900a610afd0b237d8b5a164181c03afbdfc7..5ea5bf9c0e11b0e1f9fe50093899c6e3 if (flag && !this.isSilent()) { this.level().playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.STRIDER_EAT, this.getSoundSource(), 1.0F, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F); diff --git a/src/main/java/net/minecraft/world/entity/monster/Vex.java b/src/main/java/net/minecraft/world/entity/monster/Vex.java -index fd3b37dde54623ba38186efb2a64d364c86b81d2..691f319719280f873140df7d93c821417e32e8f7 100644 +index 2985296a9a034e535157f55e322fc8c107827752..3f2c335b895754695aa3e5fa1f021a39c4a604c7 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Vex.java +++ b/src/main/java/net/minecraft/world/entity/monster/Vex.java @@ -60,6 +60,65 @@ public class Vex extends Monster implements TraceableEntity { @@ -11266,10 +11155,10 @@ index fd3b37dde54623ba38186efb2a64d364c86b81d2..691f319719280f873140df7d93c82141 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 b3da310d6fd1d533da805c38c2f449cf06d01492..e7703aa5467e7551bff06fab4c11d76237bda2e0 100644 +index 0615bb305d70f660a6baa7f78078990d6db227d3..a03eeb0cb4615a9f730fb0cc1b747f5f9341a855 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Vindicator.java +++ b/src/main/java/net/minecraft/world/entity/monster/Vindicator.java -@@ -50,14 +50,48 @@ public class Vindicator extends AbstractIllager { +@@ -53,14 +53,48 @@ public class Vindicator extends AbstractIllager { super(type, world); } @@ -11318,12 +11207,11 @@ index b3da310d6fd1d533da805c38c2f449cf06d01492..e7703aa5467e7551bff06fab4c11d762 this.targetSelector.addGoal(1, new HurtByTargetGoal(this, Raider.class).setAlertOthers()); this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true)); this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, true)); -@@ -124,6 +158,12 @@ public class Vindicator extends AbstractIllager { +@@ -127,6 +161,11 @@ public class Vindicator extends AbstractIllager { RandomSource randomSource = world.getRandom(); this.populateDefaultEquipmentSlots(randomSource, difficulty); - this.populateDefaultEquipmentEnchantments(randomSource, difficulty); + this.populateDefaultEquipmentEnchantments(world, randomSource, difficulty); + // Purpur start -+ Level level = world.getMinecraftWorld(); + if (level().purpurConfig.vindicatorJohnnySpawnChance > 0D && random.nextDouble() <= level().purpurConfig.vindicatorJohnnySpawnChance) { + setCustomName(Component.translatable("Johnny")); + } @@ -11332,10 +11220,10 @@ index b3da310d6fd1d533da805c38c2f449cf06d01492..e7703aa5467e7551bff06fab4c11d762 } 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 5803c1d36b769f0186baa0665976749765b4cb61..b4aab57b9aaab2ed1322ca41d4bf3c60f155902c 100644 +index b8ff1e3d280171378fe383bcc7c6a855d20ae5d1..2dd74108232af7e957f5924b3ee810c60e8edd77 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Witch.java +++ b/src/main/java/net/minecraft/world/entity/monster/Witch.java -@@ -55,6 +55,38 @@ public class Witch extends Raider implements RangedAttackMob { +@@ -56,6 +56,38 @@ public class Witch extends Raider implements RangedAttackMob { super(type, world); } @@ -11374,7 +11262,7 @@ index 5803c1d36b769f0186baa0665976749765b4cb61..b4aab57b9aaab2ed1322ca41d4bf3c60 @Override protected void registerGoals() { super.registerGoals(); -@@ -63,10 +95,12 @@ public class Witch extends Raider implements RangedAttackMob { +@@ -64,10 +96,12 @@ public class Witch extends Raider implements RangedAttackMob { }); this.attackPlayersGoal = new NearestAttackableWitchTargetGoal<>(this, Player.class, 10, true, false, (Predicate) null); this.goalSelector.addGoal(1, new FloatGoal(this)); @@ -11388,10 +11276,10 @@ index 5803c1d36b769f0186baa0665976749765b4cb61..b4aab57b9aaab2ed1322ca41d4bf3c60 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 3f1191795e58f31b7e2fe34ef2774df13b9a789f..8c62d39c54acf274200667ae30c517cd4416b22f 100644 +index bb2e7cee612dc1fafa042674a0b0d07d7165b54c..fdec9ed0993fd3a670883901e8e451999e211f30 100644 --- a/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java +++ b/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java -@@ -32,6 +32,38 @@ public class WitherSkeleton extends AbstractSkeleton { +@@ -33,6 +33,38 @@ public class WitherSkeleton extends AbstractSkeleton { this.setPathfindingMalus(PathType.LAVA, 8.0F); } @@ -11431,10 +11319,10 @@ index 3f1191795e58f31b7e2fe34ef2774df13b9a789f..8c62d39c54acf274200667ae30c517cd 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 e650d78e21944579f556f9c9efb38d150cd3a64e..f5feb8b048df713808cda9aff37086a531cfa481 100644 +index 0d447c8a141a7d7fcaf9218571bf0513dd28269e..5b87ff7f33054261107e4ab1b3afac1da8f0abc2 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zoglin.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zoglin.java -@@ -80,6 +80,38 @@ public class Zoglin extends Monster implements Enemy, HoglinBase { +@@ -79,6 +79,38 @@ public class Zoglin extends Monster implements Enemy, HoglinBase { this.xpReward = 5; } @@ -11473,7 +11361,7 @@ index e650d78e21944579f556f9c9efb38d150cd3a64e..f5feb8b048df713808cda9aff37086a5 @Override protected Brain.Provider brainProvider() { return Brain.provider(MEMORY_TYPES, SENSOR_TYPES); -@@ -234,6 +266,7 @@ public class Zoglin extends Monster implements Enemy, HoglinBase { +@@ -233,6 +265,7 @@ public class Zoglin extends Monster implements Enemy, HoglinBase { @Override protected void customServerAiStep() { @@ -11482,20 +11370,20 @@ index e650d78e21944579f556f9c9efb38d150cd3a64e..f5feb8b048df713808cda9aff37086a5 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 e42dfc62bb179be1ab01b0096c05c6549d38abbc..70263881941efe3b406bbc571932fc8d2c1a78cb 100644 +index 2280004638fd19ed018cb3e77d53a018b34ec516..e8fb47996c804c1d273d5bada11c70ce924cab51 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -@@ -93,22 +93,69 @@ public class Zombie extends Monster { +@@ -97,22 +97,69 @@ public class Zombie extends Monster { private int inWaterTime; public int conversionTime; private int lastTick = MinecraftServer.currentTick; // CraftBukkit - add field - private boolean shouldBurnInDay = true; // Paper - Add more Zombie API -+ // private boolean shouldBurnInDay = true; // Paper - Add more Zombie API // Purpur - implemented in LivingEntity ++ //private boolean shouldBurnInDay = true; // Paper - Add more Zombie API // Purpur - implemented in LivingEntity - API for any mob to burn daylight public Zombie(EntityType type, Level world) { super(type, world); this.breakDoorGoal = new BreakDoorGoal(this, com.google.common.base.Predicates.in(world.paperConfig().entities.behavior.doorBreakingDifficulty.getOrDefault(type, world.paperConfig().entities.behavior.doorBreakingDifficulty.get(EntityType.ZOMBIE)))); // Paper - Configurable door breaking difficulty -+ this.setShouldBurnInDay(true); // Purpur ++ this.setShouldBurnInDay(true); // Purpur - API for any mob to burn daylight } public Zombie(Level world) { @@ -11556,7 +11444,7 @@ index e42dfc62bb179be1ab01b0096c05c6549d38abbc..70263881941efe3b406bbc571932fc8d this.addBehaviourGoals(); } -@@ -118,7 +165,19 @@ public class Zombie extends Monster { +@@ -122,7 +169,19 @@ public class Zombie extends Monster { this.goalSelector.addGoal(7, new WaterAvoidingRandomStrollGoal(this, 1.0D)); this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, new Class[0])).setAlertOthers(ZombifiedPiglin.class)); this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true)); @@ -11577,7 +11465,7 @@ index e42dfc62bb179be1ab01b0096c05c6549d38abbc..70263881941efe3b406bbc571932fc8d this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, IronGolem.class, true)); this.targetSelector.addGoal(5, new NearestAttackableTargetGoal<>(this, Turtle.class, 10, true, false, Turtle.BABY_ON_LAND_SELECTOR)); } -@@ -240,30 +299,7 @@ public class Zombie extends Monster { +@@ -244,32 +303,7 @@ public class Zombie extends Monster { @Override public void aiStep() { @@ -11589,9 +11477,11 @@ index e42dfc62bb179be1ab01b0096c05c6549d38abbc..70263881941efe3b406bbc571932fc8d - - if (!itemstack.isEmpty()) { - if (itemstack.isDamageableItem()) { +- Item item = itemstack.getItem(); +- - itemstack.setDamageValue(itemstack.getDamageValue() + this.random.nextInt(2)); - if (itemstack.getDamageValue() >= itemstack.getMaxDamage()) { -- this.broadcastBreakEvent(EquipmentSlot.HEAD); +- this.onEquippedItemBroken(item, EquipmentSlot.HEAD); - this.setItemSlot(EquipmentSlot.HEAD, ItemStack.EMPTY); - } - } @@ -11600,42 +11490,42 @@ index e42dfc62bb179be1ab01b0096c05c6549d38abbc..70263881941efe3b406bbc571932fc8d - } - - if (flag) { -- this.igniteForSeconds(8); +- this.igniteForSeconds(8.0F); - } - } - } - -+ // Purpur - implemented in LivingEntity ++ // Purpur - implemented in LivingEntity - API for any mob to burn daylight super.aiStep(); } -@@ -301,6 +337,7 @@ public class Zombie extends Monster { +@@ -307,6 +341,7 @@ public class Zombie extends Monster { } -+ public boolean shouldBurnInDay() { return isSunSensitive(); } // Purpur - for ABI compatibility ++ public boolean shouldBurnInDay() { return this.isSunSensitive(); } // Purpur - for ABI compatibility - API for any mob to burn daylight public boolean isSunSensitive() { return this.shouldBurnInDay; // Paper - Add more Zombie API } -@@ -424,7 +461,7 @@ public class Zombie extends Monster { +@@ -435,7 +470,7 @@ public class Zombie extends Monster { nbt.putBoolean("CanBreakDoors", this.canBreakDoors()); nbt.putInt("InWaterTime", this.isInWater() ? this.inWaterTime : -1); nbt.putInt("DrownedConversionTime", this.isUnderWaterConverting() ? this.conversionTime : -1); - nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Paper - Add more Zombie API -+ // nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Paper - Add more Zombie API // Purpur - implemented in LivingEntity ++ //nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Paper - Add more Zombie API // Purpur - implemented in LivingEntity - API for any mob to burn daylight } @Override -@@ -438,7 +475,7 @@ public class Zombie extends Monster { +@@ -448,7 +483,7 @@ public class Zombie extends Monster { + this.startUnderWaterConversion(nbt.getInt("DrownedConversionTime")); } // Paper start - Add more Zombie API - if (nbt.contains("Paper.ShouldBurnInDay")) { -- this.shouldBurnInDay = nbt.getBoolean("Paper.ShouldBurnInDay"); -+ // this.shouldBurnInDay = nbt.getBoolean("Paper.ShouldBurnInDay"); // Purpur - implemented in LivingEntity +- if (nbt.contains("Paper.ShouldBurnInDay")) { ++ if (false && nbt.contains("Paper.ShouldBurnInDay")) { // Purpur - implemented in LivingEntity - API for any mob to burn daylight + this.shouldBurnInDay = nbt.getBoolean("Paper.ShouldBurnInDay"); } // Paper end - Add more Zombie API - -@@ -509,19 +546,20 @@ public class Zombie extends Monster { +@@ -520,19 +555,20 @@ public class Zombie extends Monster { } if (object instanceof Zombie.ZombieGroupData entityzombie_groupdatazombie) { @@ -11662,7 +11552,7 @@ index e42dfc62bb179be1ab01b0096c05c6549d38abbc..70263881941efe3b406bbc571932fc8d Chicken entitychicken1 = (Chicken) EntityType.CHICKEN.create(this.level()); if (entitychicken1 != null) { -@@ -531,6 +569,7 @@ public class Zombie extends Monster { +@@ -542,6 +578,7 @@ public class Zombie extends Monster { this.startRiding(entitychicken1); world.addFreshEntity(entitychicken1, CreatureSpawnEvent.SpawnReason.MOUNT); // CraftBukkit } @@ -11670,7 +11560,7 @@ index e42dfc62bb179be1ab01b0096c05c6549d38abbc..70263881941efe3b406bbc571932fc8d } } } -@@ -577,7 +616,7 @@ public class Zombie extends Monster { +@@ -588,7 +625,7 @@ public class Zombie extends Monster { } protected void randomizeReinforcementsChance() { @@ -11680,10 +11570,10 @@ index e42dfc62bb179be1ab01b0096c05c6549d38abbc..70263881941efe3b406bbc571932fc8d @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 22ec9c1e74450f56cd1e390d59ca28f1577e6139..8ea44416ea728e740af82912017e888a10d78983 100644 +index e0dabbf6d7a87b8722769c78ef0d2ba4353ed2cb..5ead916772c21d8db98e389984d531aae7f59700 100644 --- a/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java +++ b/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java -@@ -80,6 +80,58 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder { +@@ -83,6 +83,58 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder { }); } @@ -11742,7 +11632,7 @@ index 22ec9c1e74450f56cd1e390d59ca28f1577e6139..8ea44416ea728e740af82912017e888a @Override protected void defineSynchedData(SynchedEntityData.Builder builder) { super.defineSynchedData(builder); -@@ -172,10 +224,10 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder { +@@ -175,10 +227,10 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder { ItemStack itemstack = player.getItemInHand(hand); if (itemstack.is(Items.GOLDEN_APPLE)) { @@ -11756,10 +11646,10 @@ index 22ec9c1e74450f56cd1e390d59ca28f1577e6139..8ea44416ea728e740af82912017e888a 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 a6def4133f06c41be287e9942643e80a7b8e8218..5bae3215ee0bf222c3bd77b3131f3d01ac6c9c41 100644 +index 10388cf33f6f33070aa84b3b2d7bd14fc50ceea8..727ee00adf344e17118d8d61161202664afa4dc2 100644 --- a/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java +++ b/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java -@@ -62,6 +62,53 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { +@@ -63,6 +63,53 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { this.setPathfindingMalus(PathType.LAVA, 8.0F); } @@ -11813,7 +11703,7 @@ index a6def4133f06c41be287e9942643e80a7b8e8218..5bae3215ee0bf222c3bd77b3131f3d01 @Override public void setPersistentAngerTarget(@Nullable UUID angryAt) { this.persistentAngerTarget = angryAt; -@@ -109,7 +156,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { +@@ -110,7 +157,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { this.maybeAlertOthers(); } @@ -11822,7 +11712,7 @@ index a6def4133f06c41be287e9942643e80a7b8e8218..5bae3215ee0bf222c3bd77b3131f3d01 this.lastHurtByPlayerTime = this.tickCount; } -@@ -164,7 +211,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { +@@ -165,7 +212,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { this.ticksUntilNextAlert = ZombifiedPiglin.ALERT_INTERVAL.sample(this.random); } @@ -11831,7 +11721,7 @@ index a6def4133f06c41be287e9942643e80a7b8e8218..5bae3215ee0bf222c3bd77b3131f3d01 this.setLastHurtByPlayer((Player) entityliving); } -@@ -244,7 +291,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { +@@ -245,7 +292,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { @Override protected void randomizeReinforcementsChance() { @@ -11841,7 +11731,7 @@ index a6def4133f06c41be287e9942643e80a7b8e8218..5bae3215ee0bf222c3bd77b3131f3d01 @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 837ae63b1621a4fabba4a44145279d5f95f57f6b..8f89cb4dfa44b04811ddf43d6dc5fdf0b56c3b50 100644 +index 14878f825cc80296ffa09b5b2c0d8ed9a134491b..5596689f3850a0cf94c5791e3a23cf46358ab05f 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 @@ -90,6 +90,43 @@ public class Hoglin extends Animal implements Enemy, HoglinBase { @@ -11863,12 +11753,12 @@ index 837ae63b1621a4fabba4a44145279d5f95f57f6b..8f89cb4dfa44b04811ddf43d6dc5fdf0 + public boolean isControllable() { + return level().purpurConfig.hoglinControllable; + } -+ // Purpur end + + @Override + public void initAttributes() { + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.hoglinMaxHealth); + } ++ // Purpur end + + @Override + public int getPurpurBreedTime() { @@ -11886,8 +11776,8 @@ index 837ae63b1621a4fabba4a44145279d5f95f57f6b..8f89cb4dfa44b04811ddf43d6dc5fdf0 + } + @Override - public boolean canBeLeashed(Player player) { - return !this.isLeashed(); + public boolean canBeLeashed() { + return true; @@ -156,7 +193,7 @@ public class Hoglin extends Animal implements Enemy, HoglinBase { private int behaviorTick; // Pufferfish @Override @@ -11898,10 +11788,10 @@ index 837ae63b1621a4fabba4a44145279d5f95f57f6b..8f89cb4dfa44b04811ddf43d6dc5fdf0 HoglinAi.updateActivity(this); if (this.isConverting()) { diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java -index 5ea7cc29c2f9c4e2ee7741b4cead8ea78c296c5d..e2051abbca0b33875e352b0b2821184ada3c57b5 100644 +index 6da1335186a6d31d8e78542f8b3bd11d214ef13c..4747896ee0d25cda0780458de75bfef2b3b24ac7 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 -@@ -94,6 +94,38 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento +@@ -93,6 +93,38 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento this.xpReward = 5; } @@ -11940,7 +11830,7 @@ index 5ea7cc29c2f9c4e2ee7741b4cead8ea78c296c5d..e2051abbca0b33875e352b0b2821184a @Override public void addAdditionalSaveData(CompoundTag nbt) { super.addAdditionalSaveData(nbt); -@@ -297,7 +329,7 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento +@@ -296,7 +328,7 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento private int behaviorTick; // Pufferfish @Override protected void customServerAiStep() { @@ -11949,7 +11839,7 @@ index 5ea7cc29c2f9c4e2ee7741b4cead8ea78c296c5d..e2051abbca0b33875e352b0b2821184a this.getBrain().tick((ServerLevel) this.level(), this); PiglinAi.updateActivity(this); super.customServerAiStep(); -@@ -389,7 +421,7 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento +@@ -388,7 +420,7 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento @Override public boolean wantsToPickUp(ItemStack stack) { @@ -11959,7 +11849,7 @@ index 5ea7cc29c2f9c4e2ee7741b4cead8ea78c296c5d..e2051abbca0b33875e352b0b2821184a 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 e25af9af8f87e6762716749c367658bf6bda9e34..b7d5c0b0e3741fcf04c4bac21a82fc41e2eeed5d 100644 +index 0192b62fd66621a72fcf2f20896647e5950ba993..d079d5492b6ed709b1e0a7d84fb5f8f6896fc2fe 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 @@ -606,11 +606,18 @@ public class PiglinAi { @@ -12034,10 +11924,10 @@ index 072c28e309d1d18cb3e3e719aec23d77dd966b47..723e4467e202669faeffd4d92a376ca8 PiglinBruteAi.updateActivity(this); PiglinBruteAi.maybePlayActivitySound(this); diff --git a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java -index 7350e339c673c3c59bc36843f03f86ab1ef5e925..664774be9fa4422cc76b0f7e362737426e8e1105 100644 +index 37e682452ecc30646faf1ae8da47f91779619d42..f929b9e623eaea0e949a7af1828b9eb198fc66b8 100644 --- a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java +++ b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java -@@ -123,8 +123,32 @@ public class Warden extends Monster implements VibrationSystem { +@@ -124,8 +124,32 @@ public class Warden extends Monster implements VibrationSystem { this.setPathfindingMalus(PathType.LAVA, 8.0F); this.setPathfindingMalus(PathType.DAMAGE_FIRE, 0.0F); this.setPathfindingMalus(PathType.DANGER_FIRE, 0.0F); @@ -12068,9 +11958,9 @@ index 7350e339c673c3c59bc36843f03f86ab1ef5e925..664774be9fa4422cc76b0f7e36273742 + // Purpur end + @Override - public Packet getAddEntityPacket() { - return new ClientboundAddEntityPacket(this, this.hasPose(Pose.EMERGING) ? 1 : 0); -@@ -392,17 +416,14 @@ public class Warden extends Monster implements VibrationSystem { + public Packet getAddEntityPacket(ServerEntity entityTrackerEntry) { + return new ClientboundAddEntityPacket(this, entityTrackerEntry, this.hasPose(Pose.EMERGING) ? 1 : 0); +@@ -393,17 +417,14 @@ public class Warden extends Monster implements VibrationSystem { @Contract("null->false") public boolean canTargetEntity(@Nullable Entity entity) { @@ -12092,7 +11982,7 @@ index 7350e339c673c3c59bc36843f03f86ab1ef5e925..664774be9fa4422cc76b0f7e36273742 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 d323cf157f2a910916baa9ce3f7e5bc81648c47d..6cbbca1db5362fa2dd5c5704c7fbaa612d3cbab1 100644 +index 49b35fab8ee98a384ee12d36bbe2ac813342f1d6..142bcf71448e2c54991fd144269f74c7a2e94d14 100644 --- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java +++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java @@ -48,6 +48,7 @@ import org.bukkit.event.entity.VillagerAcquireTradeEvent; @@ -12145,20 +12035,19 @@ index e0e5046c84941a8d17e18c177f3daea9cb631940..d503d7a5837dbeb98e58dbe8f7e5de45 } 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 e32c928dc21def1df0f6d334405cff5dc8e999cd..dc2bbb7cbe31abb6ff54d51267d01c5485bbdfdc 100644 +index c96d612f0b3efc96f3f60f35449811cacc93123c..6740a06855f38f961fd741e4aee699314048fba6 100644 --- a/src/main/java/net/minecraft/world/entity/npc/Villager.java +++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java -@@ -147,6 +147,9 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -144,6 +144,8 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + }); public long nextGolemPanic = -1; // Pufferfish - + private boolean isLobotomized = false; public boolean isLobotomized() { return this.isLobotomized; } // Purpur + private int notLobotomizedCount = 0; // Purpur -+ + public Villager(EntityType entityType, Level world) { this(entityType, world, VillagerType.PLAINS); - } -@@ -158,6 +161,91 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -156,6 +158,91 @@ public class Villager extends AbstractVillager implements ReputationEventHandler this.getNavigation().setCanFloat(true); this.setCanPickUpLoot(true); this.setVillagerData(this.getVillagerData().setType(type).setProfession(VillagerProfession.NONE)); @@ -12185,6 +12074,11 @@ index e32c928dc21def1df0f6d334405cff5dc8e999cd..dc2bbb7cbe31abb6ff54d51267d01c54 + protected void registerGoals() { + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); + } ++ ++ @Override ++ public boolean canBeLeashed() { ++ return level().purpurConfig.villagerCanBeLeashed; ++ } + // Purpur end + + @Override @@ -12193,11 +12087,6 @@ index e32c928dc21def1df0f6d334405cff5dc8e999cd..dc2bbb7cbe31abb6ff54d51267d01c54 + } + + @Override -+ public boolean canBeLeashed(Player player) { -+ return level().purpurConfig.villagerCanBeLeashed && !this.isLeashed(); -+ } -+ -+ @Override + public boolean isSensitiveToWater() { + return this.level().purpurConfig.villagerTakeDamageFromWater; + } @@ -12250,7 +12139,7 @@ index e32c928dc21def1df0f6d334405cff5dc8e999cd..dc2bbb7cbe31abb6ff54d51267d01c54 } @Override -@@ -194,7 +282,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -192,7 +279,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler brain.addActivity(Activity.PLAY, VillagerGoalPackages.getPlayPackage(0.5F)); } else { brain.setSchedule(Schedule.VILLAGER_DEFAULT); @@ -12259,7 +12148,7 @@ index e32c928dc21def1df0f6d334405cff5dc8e999cd..dc2bbb7cbe31abb6ff54d51267d01c54 } brain.addActivity(Activity.CORE, VillagerGoalPackages.getCorePackage(villagerprofession, 0.5F)); -@@ -257,13 +345,22 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -255,12 +342,20 @@ public class Villager extends AbstractVillager implements ReputationEventHandler // Paper start this.customServerAiStep(false); } @@ -12278,35 +12167,34 @@ index e32c928dc21def1df0f6d334405cff5dc8e999cd..dc2bbb7cbe31abb6ff54d51267d01c54 - if (!inactive && this.behaviorTick++ % this.activatedPriority == 0) { + if (!inactive && (getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) { // Purpur - only use brain if no rider this.getBrain().tick((ServerLevel) this.level(), this); // Paper - } +- } ++ } else if (this.isLobotomized && shouldRestock()) restock(); // Purpur // Pufferfish end -+ else if (this.isLobotomized && shouldRestock()) restock(); // Purpur if (this.assignProfessionWhenSpawned) { this.assignProfessionWhenSpawned = false; - } -@@ -319,7 +416,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -317,7 +412,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 } else { - boolean flag = this.getOffers().isEmpty(); - -@@ -332,9 +429,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 - } 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()) { - this.startTrading(player); + if (!this.level().isClientSide) { + boolean flag = this.getOffers().isEmpty(); +@@ -331,9 +426,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler } -@@ -503,7 +601,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + if (flag) { +- return InteractionResult.CONSUME; ++ return tryRide(player, hand, InteractionResult.CONSUME); // Purpur + } + ++ if (level().purpurConfig.villagerRidable && itemstack.isEmpty()) return tryRide(player, hand); // Purpur ++ if (this.level().purpurConfig.villagerAllowTrading) // Purpur + this.startTrading(player); + } + +@@ -503,7 +600,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler while (iterator.hasNext()) { MerchantOffer merchantrecipe = (MerchantOffer) iterator.next(); @@ -12315,7 +12203,7 @@ index e32c928dc21def1df0f6d334405cff5dc8e999cd..dc2bbb7cbe31abb6ff54d51267d01c54 } } -@@ -745,7 +843,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -745,7 +842,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @Override public boolean canBreed() { @@ -12324,7 +12212,7 @@ index e32c928dc21def1df0f6d334405cff5dc8e999cd..dc2bbb7cbe31abb6ff54d51267d01c54 } private boolean hungry() { -@@ -959,6 +1057,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -938,6 +1035,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler public boolean hasFarmSeeds() { return this.getInventory().hasAnyMatching((itemstack) -> { @@ -12336,7 +12224,7 @@ index e32c928dc21def1df0f6d334405cff5dc8e999cd..dc2bbb7cbe31abb6ff54d51267d01c54 return itemstack.is(ItemTags.VILLAGER_PLANTABLE_SEEDS); }); } -@@ -1016,6 +1119,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -995,6 +1097,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler } public void spawnGolemIfNeeded(ServerLevel world, long time, int requiredCount) { @@ -12344,7 +12232,7 @@ index e32c928dc21def1df0f6d334405cff5dc8e999cd..dc2bbb7cbe31abb6ff54d51267d01c54 if (this.wantsToSpawnGolem(time)) { AABB axisalignedbb = this.getBoundingBox().inflate(10.0D, 10.0D, 10.0D); List list = world.getEntitiesOfClass(Villager.class, axisalignedbb); -@@ -1080,6 +1184,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -1059,6 +1162,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @Override public void startSleeping(BlockPos pos) { @@ -12358,7 +12246,7 @@ index e32c928dc21def1df0f6d334405cff5dc8e999cd..dc2bbb7cbe31abb6ff54d51267d01c54 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 3821c02187ad04b20cdf1e719a0deeabbf91007d..8f36f113e8eb3236ce53ad9cce320c3d6253d248 100644 +index 8734ab1bd8299bbf43906d81a349c2a13e0981a7..3ca83269311cbc18c9ef3ce62cff6a2d4dc0a683 100644 --- a/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java +++ b/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java @@ -31,7 +31,7 @@ public record VillagerProfession( @@ -12371,7 +12259,7 @@ index 3821c02187ad04b20cdf1e719a0deeabbf91007d..8f36f113e8eb3236ce53ad9cce320c3d "farmer", PoiTypes.FARMER, diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java -index 0854e9b7ee2e6b23b6c1ee6a324a5a253c9d4679..c1e573758539a151452b12466339ccf8b39c7d38 100644 +index 0af34e0f9c9696fbcb11b12fb27472ef17ad532a..360514d5afcafcf6dd83335938bfa09bb02e41d0 100644 --- a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java +++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java @@ -71,6 +71,43 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill @@ -12393,6 +12281,11 @@ index 0854e9b7ee2e6b23b6c1ee6a324a5a253c9d4679..c1e573758539a151452b12466339ccf8 + public boolean isControllable() { + return level().purpurConfig.wanderingTraderControllable; + } ++ ++ @Override ++ public boolean canBeLeashed() { ++ return level().purpurConfig.wanderingTraderCanBeLeashed; ++ } + // Purpur end + + @Override @@ -12401,11 +12294,6 @@ index 0854e9b7ee2e6b23b6c1ee6a324a5a253c9d4679..c1e573758539a151452b12466339ccf8 + } + + @Override -+ public boolean canBeLeashed(Player player) { -+ return level().purpurConfig.wanderingTraderCanBeLeashed && !this.isLeashed(); -+ } -+ -+ @Override + public boolean isSensitiveToWater() { + return this.level().purpurConfig.wanderingTraderTakeDamageFromWater; + } @@ -12435,19 +12323,24 @@ index 0854e9b7ee2e6b23b6c1ee6a324a5a253c9d4679..c1e573758539a151452b12466339ccf8 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)); -@@ -118,9 +156,10 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill +@@ -119,11 +157,13 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill + + if (!this.level().isClientSide) { + if (this.getOffers().isEmpty()) { +- return InteractionResult.CONSUME; ++ return tryRide(player, hand, InteractionResult.CONSUME); // Purpur + } +- +- this.setTradingPlayer(player); +- this.openTradingScreen(player, this.getDisplayName(), 1); ++ if (level().purpurConfig.wanderingTraderRidable && itemstack.isEmpty()) return tryRide(player, hand); // Purpur ++ if (this.level().purpurConfig.wanderingTraderAllowTrading) { // Purpur ++ this.setTradingPlayer(player); ++ this.openTradingScreen(player, this.getDisplayName(), 1); ++ } // Purpur } - if (this.getOffers().isEmpty()) { -- 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) { - this.setTradingPlayer(player); - this.openTradingScreen(player, this.getDisplayName(), 1); - } + return InteractionResult.sidedSuccess(this.level().isClientSide); 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 c72b6ea5530e54fc373c701028e1c147cea34b59..96e9fce5f9084737d2fcf4deb83305733b480179 100644 --- a/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java @@ -12472,11 +12365,11 @@ index c72b6ea5530e54fc373c701028e1c147cea34b59..96e9fce5f9084737d2fcf4deb8330573 if (spawnplacementtype.isSpawnPositionOk(world, blockposition2, EntityType.WANDERING_TRADER)) { blockposition1 = blockposition2; diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index f5203ef461b3fdb9a63a722fb32cd533e6b46e92..e1300b80a8119844ab572c988061a5d51241d630 100644 +index b5659a5cc87859c93f8c837d9f5090f7024a3d84..f1697fe1a102c070eb58d326491e58543111e5e9 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -198,11 +198,20 @@ public abstract class Player extends LivingEntity { - public boolean ignoreFallDamageFromCurrentImpulse; +@@ -199,11 +199,21 @@ public abstract class Player extends LivingEntity { + private int currentImpulseContextResetGraceTime; public boolean affectsSpawning = true; // Paper - Affects Spawning API public net.kyori.adventure.util.TriState flyingFallDamage = net.kyori.adventure.util.TriState.NOT_SET; // Paper - flying fall damage + public int sixRowEnderchestSlotCount = -1; // Purpur @@ -12487,7 +12380,8 @@ index f5203ef461b3fdb9a63a722fb32cd533e6b46e92..e1300b80a8119844ab572c988061a5d5 public boolean fauxSleeping; public int oldLevel = -1; -+ public void setAfk(boolean afk) {} ++ public void setAfk(boolean afk) { ++ } + + public boolean isAfk() { + return false; @@ -12496,7 +12390,7 @@ index f5203ef461b3fdb9a63a722fb32cd533e6b46e92..e1300b80a8119844ab572c988061a5d5 @Override public CraftHumanEntity getBukkitEntity() { return (CraftHumanEntity) super.getBukkitEntity(); -@@ -211,6 +220,19 @@ public abstract class Player extends LivingEntity { +@@ -212,6 +222,19 @@ public abstract class Player extends LivingEntity { public final int sendAllPlayerInfoBucketIndex; // Gale - Purpur - spread out sending all player info @@ -12516,7 +12410,7 @@ index f5203ef461b3fdb9a63a722fb32cd533e6b46e92..e1300b80a8119844ab572c988061a5d5 public Player(Level world, BlockPos pos, float yaw, GameProfile gameProfile) { super(EntityType.PLAYER, world); this.lastItemInMainHand = ItemStack.EMPTY; -@@ -256,6 +278,12 @@ public abstract class Player extends LivingEntity { +@@ -257,6 +280,12 @@ public abstract class Player extends LivingEntity { @Override public void tick() { @@ -12529,7 +12423,7 @@ index f5203ef461b3fdb9a63a722fb32cd533e6b46e92..e1300b80a8119844ab572c988061a5d5 this.noPhysics = this.isSpectator(); if (this.isSpectator()) { this.setOnGround(false); -@@ -370,6 +398,16 @@ public abstract class Player extends LivingEntity { +@@ -375,6 +404,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 } @@ -12546,16 +12440,7 @@ index f5203ef461b3fdb9a63a722fb32cd533e6b46e92..e1300b80a8119844ab572c988061a5d5 } protected ItemCooldowns createItemCooldowns() { -@@ -460,7 +498,7 @@ public abstract class Player extends LivingEntity { - - @Override - public int getPortalWaitTime() { -- return Math.max(1, this.level().getGameRules().getInt(this.abilities.invulnerable ? GameRules.RULE_PLAYERS_NETHER_PORTAL_CREATIVE_DELAY : GameRules.RULE_PLAYERS_NETHER_PORTAL_DEFAULT_DELAY)); -+ return Math.max(1, canPortalInstant ? 1 : this.level().getGameRules().getInt(this.abilities.invulnerable ? GameRules.RULE_PLAYERS_NETHER_PORTAL_CREATIVE_DELAY : GameRules.RULE_PLAYERS_NETHER_PORTAL_DEFAULT_DELAY)); - } - - @Override -@@ -603,7 +641,7 @@ public abstract class Player extends LivingEntity { +@@ -607,7 +646,7 @@ public abstract class Player extends LivingEntity { while (iterator.hasNext()) { Entity entity = (Entity) iterator.next(); @@ -12564,18 +12449,18 @@ index f5203ef461b3fdb9a63a722fb32cd533e6b46e92..e1300b80a8119844ab572c988061a5d5 list1.add(entity); } else if (!entity.isRemoved()) { this.touch(entity); -@@ -1311,7 +1349,7 @@ public abstract class Player extends LivingEntity { +@@ -1326,7 +1365,7 @@ public abstract class Player extends LivingEntity { + flag2 = flag2 && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper - Toggleable player crits + if (flag2) { + damagesource = damagesource.critical(true); // Paper start - critical damage API +- f *= 1.5F; ++ f *= this.level().purpurConfig.playerCriticalDamageMultiplier; // Purpur + } - flag2 = flag2 && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper - Toggleable player crits - if (flag2) { -- f *= 1.5F; -+ f *= this.level().purpurConfig.playerCriticalDamageMultiplier; // Purpur - } - - f += f1; -@@ -1956,9 +1994,19 @@ public abstract class Player extends LivingEntity { + float f3 = f + f1; +@@ -1970,9 +2009,19 @@ public abstract class Player extends LivingEntity { @Override - public int getExperienceReward() { + protected int getBaseExperienceReward() { if (!this.level().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) && !this.isSpectator()) { - int i = this.experienceLevel * 7; - @@ -12596,7 +12481,7 @@ index f5203ef461b3fdb9a63a722fb32cd533e6b46e92..e1300b80a8119844ab572c988061a5d5 } else { return 0; } -@@ -2039,6 +2087,13 @@ public abstract class Player extends LivingEntity { +@@ -2053,6 +2102,13 @@ public abstract class Player extends LivingEntity { return slot != EquipmentSlot.BODY; } @@ -12610,18 +12495,9 @@ index f5203ef461b3fdb9a63a722fb32cd533e6b46e92..e1300b80a8119844ab572c988061a5d5 public boolean setEntityOnShoulder(CompoundTag entityNbt) { if (!this.isPassenger() && this.onGround() && !this.isInWater() && !this.isInPowderSnow) { if (this.getShoulderEntityLeft().isEmpty()) { -@@ -2327,7 +2382,7 @@ public abstract class Player extends LivingEntity { - } - } - -- return this.abilities.instabuild ? new ItemStack(Items.ARROW) : ItemStack.EMPTY; -+ return this.abilities.instabuild || (level().purpurConfig.infinityWorksWithoutArrows && net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.INFINITY, stack) > 0) ? new ItemStack(Items.ARROW) : ItemStack.EMPTY; // Purpur - } - } - } -@@ -2336,7 +2391,7 @@ public abstract class Player extends LivingEntity { - public ItemStack eat(Level world, ItemStack stack) { - this.getFoodData().eat(stack); +@@ -2350,7 +2406,7 @@ public abstract class Player extends LivingEntity { + public ItemStack eat(Level world, ItemStack stack, FoodProperties foodComponent) { + this.getFoodData().eat(stack, foodComponent); // CraftBukkit this.awardStat(Stats.ITEM_USED.get(stack.getItem())); - world.playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_BURP, SoundSource.PLAYERS, 0.5F, world.random.nextFloat() * 0.1F + 0.9F); + // world.playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_BURP, SoundSource.PLAYERS, 0.5F, world.random.nextFloat() * 0.1F + 0.9F); // Purpur - moved to tick() @@ -12629,35 +12505,35 @@ index f5203ef461b3fdb9a63a722fb32cd533e6b46e92..e1300b80a8119844ab572c988061a5d5 CriteriaTriggers.CONSUME_ITEM.trigger((ServerPlayer) this, stack); } 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 7925eee8f8ed40966af91d2e88991271f56f51db..708085bb13a994e65d7c8ef7ea10aa41951c8ffe 100644 +index 95ac8f4af849523e25b95b624d59f9f5ae5877b4..6b570b96570ce515dc150610886587e8f0398331 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java +++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java -@@ -77,6 +77,7 @@ public abstract class AbstractArrow extends Projectile { - @Nullable - private List piercedAndKilledEntities; +@@ -80,6 +80,7 @@ public abstract class AbstractArrow extends Projectile { public ItemStack pickupItemStack; -+ public int lootingLevel; // Purpur + @Nullable + public ItemStack firedFromWeapon; ++ public net.minecraft.world.item.enchantment.ItemEnchantments actualEnchantments = net.minecraft.world.item.enchantment.ItemEnchantments.EMPTY; // Purpur - Add an option to fix MC-3304 projectile looting // Spigot Start @Override -@@ -655,6 +656,12 @@ public abstract class AbstractArrow extends Projectile { - this.knockback = punch; +@@ -589,6 +590,12 @@ public abstract class AbstractArrow extends Projectile { + return this.firedFromWeapon; } -+ // Purpur start -+ public void setLootingLevel(int looting) { -+ this.lootingLevel = looting; ++ // Purpur start - Add an option to fix MC-3304 projectile looting ++ public void setActualEnchantments(net.minecraft.world.item.enchantment.ItemEnchantments actualEnchantments) { ++ this.actualEnchantments = actualEnchantments; + } -+ // Purpur end ++ // Purpur end - Add an option to fix MC-3304 projectile looting + - public int getKnockback() { - return this.knockback; + protected SoundEvent getDefaultHitGroundSoundEvent() { + return SoundEvents.ARROW_HIT; } 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 9d89872c5958f3e8d6c1ef4fd93f9b8b85296851..6a94c86acce5afbf1e9c8e7d664b3eb2d79ab5ab 100644 +index 28a65f2a9ef441ae96a7a635e0695b14ce2ee367..7b6c58a31d37896daccb5f570d3cb9247cea2cd6 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/LargeFireball.java +++ b/src/main/java/net/minecraft/world/entity/projectile/LargeFireball.java -@@ -19,20 +19,20 @@ public class LargeFireball extends Fireball { +@@ -23,20 +23,20 @@ public class LargeFireball extends Fireball { public LargeFireball(EntityType type, Level world) { super(type, world); @@ -12665,8 +12541,8 @@ index 9d89872c5958f3e8d6c1ef4fd93f9b8b85296851..6a94c86acce5afbf1e9c8e7d664b3eb2 + this.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); + public LargeFireball(Level world, LivingEntity owner, Vec3 velocity, int explosionPower) { + super(EntityType.FIREBALL, owner, velocity, world); this.explosionPower = explosionPower; - this.isIncendiary = this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit + this.isIncendiary = this.level().purpurConfig.fireballsBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit // Purpur @@ -12682,10 +12558,10 @@ index 9d89872c5958f3e8d6c1ef4fd93f9b8b85296851..6a94c86acce5afbf1e9c8e7d664b3eb2 // CraftBukkit start - fire ExplosionPrimeEvent ExplosionPrimeEvent event = new ExplosionPrimeEvent((org.bukkit.entity.Explosive) this.getBukkitEntity()); diff --git a/src/main/java/net/minecraft/world/entity/projectile/LlamaSpit.java b/src/main/java/net/minecraft/world/entity/projectile/LlamaSpit.java -index ffd01d24cbfc90e2a8807757e61b2cf20a944354..a419820d5001079ed839e67c757bc8fa591a20b3 100644 +index 8575941fd238750c5d56843989a48bcbde2d8a88..b4ed2df8d0795409808df0205edce6da682c3981 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/LlamaSpit.java +++ b/src/main/java/net/minecraft/world/entity/projectile/LlamaSpit.java -@@ -30,6 +30,12 @@ public class LlamaSpit extends Projectile { +@@ -33,6 +33,12 @@ public class LlamaSpit extends Projectile { this.setPos(owner.getX() - (double) (owner.getBbWidth() + 1.0F) * 0.5D * (double) Mth.sin(owner.yBodyRot * 0.017453292F), owner.getEyeY() - 0.10000000149011612D, owner.getZ() + (double) (owner.getBbWidth() + 1.0F) * 0.5D * (double) Mth.cos(owner.yBodyRot * 0.017453292F)); } @@ -12699,10 +12575,10 @@ index ffd01d24cbfc90e2a8807757e61b2cf20a944354..a419820d5001079ed839e67c757bc8fa protected double getDefaultGravity() { return 0.06D; diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index adb4cd2a926744182952d0702284f7c7b9e5d42c..330d6badfbd096e4aec873dcb419df7975cb60a3 100644 +index bf1e1e7561b674ace6bfd601a5c1ddfcd203ac04..4275eb588114522d337f39c6f3503cd9d4be92e9 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -@@ -382,7 +382,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { +@@ -394,7 +394,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { public boolean mayInteract(Level world, BlockPos pos) { Entity entity = this.getOwner(); @@ -12712,11 +12588,11 @@ index adb4cd2a926744182952d0702284f7c7b9e5d42c..330d6badfbd096e4aec873dcb419df79 public boolean mayBreak(Level world) { diff --git a/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java b/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java -index 3a11ad32d95088a5aca713a1a6a984cc22d4fa9a..c078ccad4aabe469a9611331b415a4cef241973e 100644 +index 1711ad457e7d1233fd32edc3e9e3b9f1e3be9980..554d3c4db6ed07e3d12af23a9a18c28480bf77c0 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java +++ b/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java -@@ -27,7 +27,7 @@ public class SmallFireball extends Fireball { - super(EntityType.SMALL_FIREBALL, owner, velocityX, velocityY, velocityZ, world); +@@ -30,7 +30,7 @@ public class SmallFireball extends Fireball { + super(EntityType.SMALL_FIREBALL, owner, velocity, world); // CraftBukkit start if (this.getOwner() != null && this.getOwner() instanceof Mob) { - this.isIncendiary = this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); @@ -12772,36 +12648,36 @@ index 2b4d206c0d31ba38d7b2af654bd420e85145d441..1b9d0e28e518c501b4b93ae385ddd64a 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 519755b7f8bc7e8bb9fab135fc5bf7de3a9419f9..61bd2459f2b9164dce90134103abaddce42b0621 100644 +index 1aa5e57a4e6a4be60514d8808a2e6c973d93e798..334fa781e94d195c13dd78cdbe8f43b4b126ebd0 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java -@@ -70,10 +70,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 (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); +@@ -77,10 +77,11 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { + return; } -@@ -85,7 +86,7 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { + // CraftBukkit end +- if (this.random.nextFloat() < 0.05F && worldserver.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) { ++ if (this.random.nextFloat() < this.level().purpurConfig.enderPearlEndermiteChance && worldserver.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) { // Purpur + Endermite entityendermite = (Endermite) EntityType.ENDERMITE.create(worldserver); - entityplayer.connection.teleport(teleEvent.getTo()); - entity.resetFallDistance(); -- entity.hurt(this.damageSources().fall().customEventDamager(this), 5.0F); // CraftBukkit // Paper - fix DamageSource API -+ entity.hurt(this.damageSources().fall().customEventDamager(this), this.level().purpurConfig.enderPearlDamage); // CraftBukkit // Paper - fix DamageSource API // Purpur - } - // CraftBukkit end - this.level().playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_TELEPORT, SoundSource.PLAYERS); + if (entityendermite != null) { ++ entityendermite.setPlayerSpawned(true); // Purpur + entityendermite.moveTo(entity.getX(), entity.getY(), entity.getZ(), entity.getYRot(), entity.getXRot()); + worldserver.addFreshEntity(entityendermite, CreatureSpawnEvent.SpawnReason.ENDER_PEARL); + } +@@ -89,7 +90,7 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { + // entity.changeDimension(new DimensionTransition(worldserver, this.position(), entity.getDeltaMovement(), entity.getYRot(), entity.getXRot(), DimensionTransition.DO_NOTHING)); // CraftBukkit - moved up + entity.resetFallDistance(); + entityplayer.resetCurrentImpulseContext(); +- entity.hurt(this.damageSources().fall().customEventDamager(this), 5.0F); // CraftBukkit // Paper - fix DamageSource API ++ entity.hurt(this.damageSources().fall().customEventDamager(this), this.level().purpurConfig.enderPearlDamage); // CraftBukkit // Paper - fix DamageSource API // Purpur + this.playSound(worldserver, this.position()); + } + } else { 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 3ff06cc6ad35567bcb1f29115db63c11a8e79dbb..f7dd785bdb0dbd0706b367b48235215ff1a0e08f 100644 +index cb71f468e90f076caf2c0dcc5f2ba2745c737c22..c8dbca9573060f7d9c2a0a96a532f06d3c17728f 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java -@@ -67,7 +67,7 @@ public class ThrownTrident extends AbstractArrow { +@@ -68,7 +68,7 @@ public class ThrownTrident extends AbstractArrow { Entity entity = this.getOwner(); byte b0 = (Byte) this.entityData.get(ThrownTrident.ID_LOYALTY); @@ -12811,10 +12687,10 @@ index 3ff06cc6ad35567bcb1f29115db63c11a8e79dbb..f7dd785bdb0dbd0706b367b48235215f 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 55b4b5ad5f084c9a271a716d076672478d6486ba..a60d7f7baab005afc532ecec7aa22c53db4f51e0 100644 +index 55fd997a4e894eeab24de269d59e486196ffbe8d..999453409c19abf7f5b5c2dc399699856e57329e 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java +++ b/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java -@@ -99,7 +99,7 @@ public class WitherSkull extends AbstractHurtingProjectile { +@@ -103,7 +103,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); @@ -12823,7 +12699,7 @@ index 55b4b5ad5f084c9a271a716d076672478d6486ba..a60d7f7baab005afc532ecec7aa22c53 this.level().getCraftServer().getPluginManager().callEvent(event); if (!event.isCancelled()) { -@@ -111,6 +111,19 @@ public class WitherSkull extends AbstractHurtingProjectile { +@@ -115,6 +115,19 @@ public class WitherSkull extends AbstractHurtingProjectile { } @@ -12844,15 +12720,15 @@ index 55b4b5ad5f084c9a271a716d076672478d6486ba..a60d7f7baab005afc532ecec7aa22c53 public boolean hurt(DamageSource source, float amount) { return false; diff --git a/src/main/java/net/minecraft/world/entity/raid/Raider.java b/src/main/java/net/minecraft/world/entity/raid/Raider.java -index 98e558338b5d9fb03869d2cc21b3e90eb45b95f6..4a8fa7e5844b5cd12ef6b113f988b715c7a3ef64 100644 +index bbf21ea433f9e3963aac0ede597ed8d3c8e50ed8..06487fc9ea416d8256e0c2cd1969d4e0283ffb05 100644 --- a/src/main/java/net/minecraft/world/entity/raid/Raider.java +++ b/src/main/java/net/minecraft/world/entity/raid/Raider.java -@@ -341,7 +341,7 @@ public abstract class Raider extends PatrollingMonster { +@@ -299,7 +299,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(net.minecraft.world.level.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(net.minecraft.world.level.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(this.mob.registryAccess().lookupOrThrow(Registries.BANNER_PATTERN)))) { @@ -12901,7 +12777,7 @@ index 8c60f71270d909c10e6617eb64b8fdb42deb73e9..eedce2a3d67d875d5174ee125e267948 if (!raid.isStarted() && !this.raidMap.containsKey(raid.getId())) { this.raidMap.put(raid.getId(), raid); diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java -index 4d7454e5a64fc18e63793a221daa94617f17c666..e7a1ce585c9e552e6f9ce9acd26fdfe5c43e0b5d 100644 +index f403fc311a974558233028663dbe14c27b27d3f9..337bd2011c471361653c317004f8380c9fddfc47 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java @@ -102,12 +102,14 @@ public abstract class AbstractMinecart extends VehicleEntity { @@ -13005,10 +12881,10 @@ index 4d7454e5a64fc18e63793a221daa94617f17c666..e7a1ce585c9e552e6f9ce9acd26fdfe5 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 b068cff9b5aa457d65b679529956e8210296d799..105e2b7d7cd7c64a9164e4114476e44f29433f49 100644 +index 907f751c859855484151fb5d607acee2f2a35076..c45bb20e5355b0e0f87447572b6f60e8e2ee47be 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java -@@ -514,6 +514,7 @@ public class Boat extends VehicleEntity implements VariantHolder { +@@ -543,6 +543,7 @@ public class Boat extends VehicleEntity implements Leashable, VariantHolder 0.0F) { this.landFriction = f; @@ -13016,7 +12892,7 @@ index b068cff9b5aa457d65b679529956e8210296d799..105e2b7d7cd7c64a9164e4114476e44f return Boat.Status.ON_LAND; } else { return Boat.Status.IN_AIR; -@@ -962,7 +963,13 @@ public class Boat extends VehicleEntity implements VariantHolder { +@@ -1016,7 +1017,13 @@ public class Boat extends VehicleEntity implements Leashable, VariantHolder= this.starvationRate) { // CraftBukkit - add regen rate manipulation @@ -13055,22 +12931,22 @@ index b89860d451d92ddda64b7e4144542b7fc5fd86f0..dd72d6a79139ff33f26a32b71283ce0b this.tickTimer = 0; diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java -index 32910f677b0522ac8ec513fa0d00b714b52cfae4..f85eef14b91a0ada1f6f4b13ab3966f051ff92d3 100644 +index 32910f677b0522ac8ec513fa0d00b714b52cfae4..c491291b522aebf34c7d990d2b485d1a0d19cdcd 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 { @Nullable private ContainerSynchronizer synchronizer; private boolean suppressRemoteUpdates; -+ @javax.annotation.Nullable protected ItemStack activeQuickItem = null; // Purpur ++ @Nullable protected ItemStack activeQuickItem = null; // Purpur - Anvil API // 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 1af7e1548f0648890a1ef2fc0ff4e4c3a56c947c..decea1697c075e7549ccc7501c8e59357d198a60 100644 +index 6474b6063992d2c643c21187663de499f37b32d6..c374962128a37307093218a9ec46386cc860c376 100644 --- a/src/main/java/net/minecraft/world/inventory/AbstractFurnaceMenu.java +++ b/src/main/java/net/minecraft/world/inventory/AbstractFurnaceMenu.java -@@ -147,7 +147,13 @@ public abstract class AbstractFurnaceMenu extends RecipeBookMenu { +@@ -147,7 +147,13 @@ public abstract class AbstractFurnaceMenu extends RecipeBookMenu= this.cost.get()) && this.cost.get() > AnvilMenu.DEFAULT_DENIED_COST && present; // CraftBukkit - allow cost 0 like a free item -+ return (player.hasInfiniteMaterials() || player.experienceLevel >= this.cost.get()) && (bypassCost || this.cost.get() > AnvilMenu.DEFAULT_DENIED_COST) && present; // CraftBukkit - allow cost 0 like a free item // Purpur ++ return (player.hasInfiniteMaterials() || player.experienceLevel >= this.cost.get()) && (this.bypassCost || this.cost.get() > AnvilMenu.DEFAULT_DENIED_COST) && present; // CraftBukkit - allow cost 0 like a free item // Purpur - Anvil API } @Override protected void onTake(Player player, ItemStack stack) { -+ ItemStack itemstack = activeQuickItem == null ? stack : activeQuickItem; // Purpur -+ if (org.purpurmc.purpur.event.inventory.AnvilTakeResultEvent.getHandlerList().getRegisteredListeners().length > 0) new org.purpurmc.purpur.event.inventory.AnvilTakeResultEvent(player.getBukkitEntity(), getBukkitView(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)).callEvent(); // Purpur ++ // Purpur start - Anvil API ++ ItemStack itemstack = this.activeQuickItem != null ? this.activeQuickItem : stack; ++ if (org.purpurmc.purpur.event.inventory.AnvilTakeResultEvent.getHandlerList().getRegisteredListeners().length > 0) new org.purpurmc.purpur.event.inventory.AnvilTakeResultEvent(player.getBukkitEntity(), getBukkitView(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)).callEvent(); ++ // Purpur end - Anvil API if (!player.getAbilities().instabuild) { -+ if (bypassCost) ((ServerPlayer) player).lastSentExp = -1; else // Purpur ++ if (this.bypassCost) ((ServerPlayer) player).lastSentExp = -1; else // Purpur - Anvil API player.giveExperienceLevels(-this.cost.get()); } -@@ -136,6 +148,12 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -136,6 +151,12 @@ public class AnvilMenu extends ItemCombinerMenu { @Override public void createResult() { -+ // Purpur start -+ bypassCost = false; -+ canDoUnsafeEnchants = false; ++ // Purpur start - Anvil API ++ this.bypassCost = false; ++ this.canDoUnsafeEnchants = false; + if (org.purpurmc.purpur.event.inventory.AnvilUpdateResultEvent.getHandlerList().getRegisteredListeners().length > 0) new org.purpurmc.purpur.event.inventory.AnvilUpdateResultEvent(getBukkitView()).callEvent(); -+ // Purpur end ++ // Purpur end - Anvil API + ItemStack itemstack = this.inputSlots.getItem(0); this.cost.set(1); -@@ -143,7 +161,7 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -143,7 +164,7 @@ public class AnvilMenu extends ItemCombinerMenu { long j = 0L; byte b0 = 0; - if (!itemstack.isEmpty() && EnchantmentHelper.canStoreEnchantments(itemstack)) { -+ if (!itemstack.isEmpty() && canDoUnsafeEnchants || EnchantmentHelper.canStoreEnchantments(itemstack)) { // Purpur ++ if (!itemstack.isEmpty() && this.canDoUnsafeEnchants || EnchantmentHelper.canStoreEnchantments(itemstack)) { // Purpur - Anvil API ItemStack itemstack1 = itemstack.copy(); ItemStack itemstack2 = this.inputSlots.getItem(1); ItemEnchantments.Mutable itemenchantments_a = new ItemEnchantments.Mutable(EnchantmentHelper.getEnchantmentsForCrafting(itemstack1)); -@@ -210,7 +228,8 @@ public class AnvilMenu extends ItemCombinerMenu { - int i2 = entry.getIntValue(); +@@ -210,7 +231,10 @@ public class AnvilMenu extends ItemCombinerMenu { i2 = l1 == i2 ? i2 + 1 : Math.max(i2, l1); + Enchantment enchantment = (Enchantment) holder.value(); - boolean flag3 = enchantment.canEnchant(itemstack); -+ boolean flag3 = canDoUnsafeEnchants || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchants && org.purpurmc.purpur.PurpurConfig.allowInapplicableEnchants) || enchantment.canEnchant(itemstack); // Purpur -+ boolean flag4 = true; // Purpur ++ // Purpur start - Config to allow unsafe enchants ++ boolean flag3 = this.canDoUnsafeEnchants || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchants && org.purpurmc.purpur.PurpurConfig.allowInapplicableEnchants) || enchantment.canEnchant(itemstack); // whether the enchantment can be applied on specific item type ++ boolean flag4 = true; // whether two incompatible enchantments can be applied on a single item ++ // Purpur end - Config to allow unsafe enchants if (this.player.getAbilities().instabuild || itemstack.is(Items.ENCHANTED_BOOK)) { flag3 = true; -@@ -222,16 +241,20 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -222,16 +246,22 @@ public class AnvilMenu extends ItemCombinerMenu { Holder holder1 = (Holder) iterator1.next(); - if (!holder1.equals(holder) && !enchantment.isCompatibleWith((Enchantment) holder1.value())) { + if (!holder1.equals(holder) && !Enchantment.areCompatible(holder, holder1)) { - 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; -+ } ++ flag4 = this.canDoUnsafeEnchants || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchants && org.purpurmc.purpur.PurpurConfig.allowIncompatibleEnchants); // Purpur - Anvil API // Purpur - flag3 -> flag4 - Config to allow unsafe enchants ++ // Purpur start - Config to allow unsafe enchants ++ if (!flag4 && org.purpurmc.purpur.PurpurConfig.replaceIncompatibleEnchants) { ++ iterator1.remove(); // replace current enchant with the incompatible one trying to be applied ++ flag4 = true; ++ } ++ // Purpur end - Config to allow unsafe enchants ++i; } } - if (!flag3) { -+ if (!flag3 || !flag4) { // Purpur ++ if (!flag3 || !flag4) { // Purpur - Config to allow unsafe enchants flag2 = true; } else { flag1 = true; - if (i2 > enchantment.getMaxLevel()) { -+ if ((!org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchants || !org.purpurmc.purpur.PurpurConfig.allowHigherEnchantsLevels) && i2 > enchantment.getMaxLevel()) { // Purpur ++ if ((!org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchants || !org.purpurmc.purpur.PurpurConfig.allowHigherEnchantsLevels) && i2 > enchantment.getMaxLevel()) { // Purpur - Config to allow unsafe enchants i2 = enchantment.getMaxLevel(); } -@@ -261,6 +284,54 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -261,6 +291,54 @@ public class AnvilMenu extends ItemCombinerMenu { if (!this.itemName.equals(itemstack.getHoverName().getString())) { b0 = 1; i += b0; @@ -13240,41 +13123,55 @@ index 2bd91b48eaa06f85a5b9b1ae052c70e966ae8e4c..2747f04e657154362af55eef1dd50455 itemstack1.set(DataComponents.CUSTOM_NAME, Component.literal(this.itemName)); } } else if (itemstack.has(DataComponents.CUSTOM_NAME)) { -@@ -280,6 +351,12 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -280,6 +358,12 @@ public class AnvilMenu extends ItemCombinerMenu { this.cost.set(this.maximumRepairCost - 1); // CraftBukkit } -+ // Purpur start -+ if (bypassCost && cost.get() >= maximumRepairCost) { -+ cost.set(maximumRepairCost - 1); ++ // Purpur start - Anvil API ++ if (this.bypassCost && this.cost.get() >= this.maximumRepairCost) { ++ this.cost.set(this.maximumRepairCost - 1); + } -+ // Purpur end ++ // Purpur end - Anvil API + if (this.cost.get() >= this.maximumRepairCost && !this.player.getAbilities().instabuild) { // CraftBukkit itemstack1 = ItemStack.EMPTY; } -@@ -301,6 +378,12 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -301,6 +385,13 @@ public class AnvilMenu extends ItemCombinerMenu { org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareAnvilEvent(this.getBukkitView(), itemstack1); // CraftBukkit this.sendAllDataToRemote(); // CraftBukkit - SPIGOT-6686: Always send completed inventory to stay in sync with client this.broadcastChanges(); -+ // Purpur start -+ if ((canDoUnsafeEnchants || org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchants) && itemstack1 != ItemStack.EMPTY) { -+ ((ServerPlayer) player).connection.send(new ClientboundContainerSetSlotPacket(containerId, incrementStateId(), 2, itemstack1)); -+ ((ServerPlayer) player).connection.send(new ClientboundContainerSetDataPacket(containerId, 0, cost.get())); ++ ++ // Purpur start - Anvil API ++ if ((this.canDoUnsafeEnchants || org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchants) && itemstack1 != ItemStack.EMPTY) { // Purpur - Config to allow unsafe enchants ++ ((ServerPlayer) this.player).connection.send(new ClientboundContainerSetSlotPacket(this.containerId, this.incrementStateId(), 2, itemstack1)); ++ ((ServerPlayer) this.player).connection.send(new ClientboundContainerSetDataPacket(this.containerId, 0, this.cost.get())); + } -+ // Purpur end ++ // Purpur end - Anvil API } else { org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareAnvilEvent(this.getBukkitView(), ItemStack.EMPTY); // CraftBukkit this.cost.set(AnvilMenu.DEFAULT_DENIED_COST); // CraftBukkit - use a variable for set a cost for denied item -@@ -308,7 +391,7 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -308,7 +399,7 @@ public class AnvilMenu extends ItemCombinerMenu { } public static int calculateIncreasedRepairCost(int cost) { - return (int) Math.min((long) cost * 2L + 1L, 2147483647L); -+ return org.purpurmc.purpur.PurpurConfig.anvilCumulativeCost ? (int) Math.min((long) cost * 2L + 1L, 2147483647L) : 0; ++ return org.purpurmc.purpur.PurpurConfig.anvilCumulativeCost ? (int) Math.min((long) cost * 2L + 1L, 2147483647L) : 0; // Purpur - Make anvil cumulative cost configurable } public boolean setItemName(String newItemName) { +diff --git a/src/main/java/net/minecraft/world/inventory/ArmorSlot.java b/src/main/java/net/minecraft/world/inventory/ArmorSlot.java +index 6c0b6abb1698fac9bb902f695b725d4ab783ee90..091e3c3514fcb378b68098114106d09f04d8fb0d 100644 +--- a/src/main/java/net/minecraft/world/inventory/ArmorSlot.java ++++ b/src/main/java/net/minecraft/world/inventory/ArmorSlot.java +@@ -45,7 +45,7 @@ class ArmorSlot extends Slot { + @Override + public boolean mayPickup(Player playerEntity) { + ItemStack itemStack = this.getItem(); +- return (itemStack.isEmpty() || playerEntity.isCreative() || !EnchantmentHelper.has(itemStack, EnchantmentEffectComponents.PREVENT_ARMOR_CHANGE)) ++ return (itemStack.isEmpty() || playerEntity.isCreative() || (!EnchantmentHelper.has(itemStack, EnchantmentEffectComponents.PREVENT_ARMOR_CHANGE) || playerEntity.level().purpurConfig.playerRemoveBindingWithWeakness && playerEntity.hasEffect(net.minecraft.world.effect.MobEffects.WEAKNESS))) + && super.mayPickup(playerEntity); + } + 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 @@ -13311,10 +13208,10 @@ 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 480d093105073edfd3acdd7b079b4ca5aa5fdc6d..6d28f1097caa3e37c2917eb401018ebf48c13a39 100644 +index 07223046761cb2186d75de8edc03a91d2e8e8b2f..4e5d497b966a04d42b988d26039cbbcc3da7121c 100644 --- a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java +++ b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java -@@ -39,6 +39,12 @@ import org.bukkit.event.enchantment.PrepareItemEnchantEvent; +@@ -45,6 +45,12 @@ import org.bukkit.event.enchantment.PrepareItemEnchantEvent; import org.bukkit.entity.Player; // CraftBukkit end @@ -13326,8 +13223,8 @@ index 480d093105073edfd3acdd7b079b4ca5aa5fdc6d..6d28f1097caa3e37c2917eb401018ebf + public class EnchantmentMenu extends AbstractContainerMenu { - static final ResourceLocation EMPTY_SLOT_LAPIS_LAZULI = new ResourceLocation("item/empty_slot_lapis_lazuli"); -@@ -73,6 +79,22 @@ public class EnchantmentMenu extends AbstractContainerMenu { + static final ResourceLocation EMPTY_SLOT_LAPIS_LAZULI = ResourceLocation.withDefaultNamespace("item/empty_slot_lapis_lazuli"); +@@ -79,6 +85,22 @@ public class EnchantmentMenu extends AbstractContainerMenu { return context.getLocation(); } // CraftBukkit end @@ -13350,7 +13247,7 @@ index 480d093105073edfd3acdd7b079b4ca5aa5fdc6d..6d28f1097caa3e37c2917eb401018ebf }; this.random = RandomSource.create(); this.enchantmentSeed = DataSlot.standalone(); -@@ -98,6 +120,17 @@ public class EnchantmentMenu extends AbstractContainerMenu { +@@ -104,6 +126,17 @@ public class EnchantmentMenu extends AbstractContainerMenu { } }); @@ -13368,7 +13265,7 @@ index 480d093105073edfd3acdd7b079b4ca5aa5fdc6d..6d28f1097caa3e37c2917eb401018ebf int j; for (j = 0; j < 3; ++j) { -@@ -333,6 +366,7 @@ public class EnchantmentMenu extends AbstractContainerMenu { +@@ -344,6 +377,7 @@ public class EnchantmentMenu extends AbstractContainerMenu { public void removed(net.minecraft.world.entity.player.Player player) { super.removed(player); this.access.execute((world, blockposition) -> { @@ -13377,10 +13274,10 @@ index 480d093105073edfd3acdd7b079b4ca5aa5fdc6d..6d28f1097caa3e37c2917eb401018ebf }); } diff --git a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java -index db9444dda248260372d96ce239a590e88a4c1142..dda890500e360274ce194929560f01b544e4cb4f 100644 +index 1678f6c8b2c7db761783e53043169bf12bc2cb29..cf373c763749161d0371bd243b8d77bb750a7d38 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 { +@@ -96,9 +96,11 @@ public class GrindstoneMenu extends AbstractContainerMenu { @Override public void onTake(net.minecraft.world.entity.player.Player player, ItemStack stack) { @@ -13393,98 +13290,97 @@ index db9444dda248260372d96ce239a590e88a4c1142..dda890500e360274ce194929560f01b5 } world.levelEvent(1042, blockposition, 0); -@@ -130,7 +132,7 @@ public class GrindstoneMenu extends AbstractContainerMenu { - Enchantment enchantment = (Enchantment) ((Holder) entry.getKey()).value(); +@@ -131,7 +133,7 @@ public class GrindstoneMenu extends AbstractContainerMenu { + Holder holder = (Holder) entry.getKey(); int k = entry.getIntValue(); -- if (!enchantment.isCurse()) { -+ if (!org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains(enchantment)) { // Purpur - j += enchantment.getMinCost(k); +- if (!holder.is(EnchantmentTags.CURSE)) { ++ if (!org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains(holder.value())) { // Purpur + j += ((Enchantment) holder.value()).getMinCost(k); } } -@@ -229,7 +231,7 @@ public class GrindstoneMenu extends AbstractContainerMenu { +@@ -230,7 +232,7 @@ public class GrindstoneMenu extends AbstractContainerMenu { Entry> entry = (Entry) iterator.next(); - Enchantment enchantment = (Enchantment) ((Holder) entry.getKey()).value(); + Holder holder = (Holder) entry.getKey(); -- if (!enchantment.isCurse() || itemenchantments_a.getLevel(enchantment) == 0) { -+ if (!org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains(enchantment) || itemenchantments_a.getLevel(enchantment) == 0) { // Purpur - itemenchantments_a.upgrade(enchantment, entry.getIntValue()); +- if (!holder.is(EnchantmentTags.CURSE) || itemenchantments_a.getLevel(holder) == 0) { ++ if (!org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains(holder.value()) || itemenchantments_a.getLevel(holder) == 0) { // Purpur + itemenchantments_a.upgrade(holder, entry.getIntValue()); } } -@@ -237,10 +239,71 @@ public class GrindstoneMenu extends AbstractContainerMenu { +@@ -238,10 +240,70 @@ public class GrindstoneMenu extends AbstractContainerMenu { }); } + // Purpur start + private java.util.List> GRINDSTONE_REMOVE_ATTRIBUTES_REMOVAL_LIST = java.util.List.of( -+ // DataComponents.MAX_STACK_SIZE, -+ // DataComponents.DAMAGE, -+ // DataComponents.BLOCK_STATE, -+ DataComponents.CUSTOM_DATA, -+ // DataComponents.MAX_DAMAGE, -+ // DataComponents.UNBREAKABLE, -+ // DataComponents.CUSTOM_NAME, -+ // DataComponents.ITEM_NAME, -+ // DataComponents.LORE, -+ // DataComponents.RARITY, -+ // DataComponents.ENCHANTMENTS, -+ // DataComponents.CAN_PLACE_ON, -+ // DataComponents.CAN_BREAK, -+ DataComponents.ATTRIBUTE_MODIFIERS, -+ DataComponents.CUSTOM_MODEL_DATA, -+ // DataComponents.HIDE_ADDITIONAL_TOOLTIP, -+ // DataComponents.HIDE_TOOLTIP, -+ // DataComponents.REPAIR_COST, -+ // DataComponents.CREATIVE_SLOT_LOCK, -+ // DataComponents.ENCHANTMENT_GLINT_OVERRIDE, -+ // DataComponents.INTANGIBLE_PROJECTILE, -+ // DataComponents.FOOD, -+ // DataComponents.FIRE_RESISTANT, -+ // DataComponents.TOOL, -+ // DataComponents.STORED_ENCHANTMENTS, -+ DataComponents.DYED_COLOR, -+ // DataComponents.MAP_COLOR, -+ // DataComponents.MAP_ID, -+ // DataComponents.MAP_DECORATIONS, -+ // DataComponents.MAP_POST_PROCESSING, -+ // DataComponents.CHARGED_PROJECTILES, -+ // DataComponents.BUNDLE_CONTENTS, -+ // DataComponents.POTION_CONTENTS, -+ DataComponents.SUSPICIOUS_STEW_EFFECTS -+ // DataComponents.WRITABLE_BOOK_CONTENT, -+ // DataComponents.WRITTEN_BOOK_CONTENT, -+ // DataComponents.TRIM, -+ // DataComponents.DEBUG_STICK_STATE, -+ // DataComponents.ENTITY_DATA, -+ // DataComponents.BUCKET_ENTITY_DATA, -+ // DataComponents.BLOCK_ENTITY_DATA, -+ // DataComponents.INSTRUMENT, -+ // DataComponents.OMINOUS_BOTTLE_AMPLIFIER, -+ // DataComponents.RECIPES, -+ // DataComponents.LODESTONE_TRACKER, -+ // DataComponents.FIREWORK_EXPLOSION, -+ // DataComponents.FIREWORKS, -+ // DataComponents.PROFILE, -+ // DataComponents.NOTE_BLOCK_SOUND, -+ // DataComponents.BANNER_PATTERNS, -+ // DataComponents.BASE_COLOR, -+ // DataComponents.POT_DECORATIONS, -+ // DataComponents.CONTAINER, -+ // DataComponents.BEES, -+ // DataComponents.LOCK, -+ // DataComponents.CONTAINER_LOOT, ++ // DataComponents.MAX_STACK_SIZE, ++ // DataComponents.DAMAGE, ++ // DataComponents.BLOCK_STATE, ++ DataComponents.CUSTOM_DATA, ++ // DataComponents.MAX_DAMAGE, ++ // DataComponents.UNBREAKABLE, ++ // DataComponents.CUSTOM_NAME, ++ // DataComponents.ITEM_NAME, ++ // DataComponents.LORE, ++ // DataComponents.RARITY, ++ // DataComponents.ENCHANTMENTS, ++ // DataComponents.CAN_PLACE_ON, ++ // DataComponents.CAN_BREAK, ++ DataComponents.ATTRIBUTE_MODIFIERS, ++ DataComponents.CUSTOM_MODEL_DATA, ++ // DataComponents.HIDE_ADDITIONAL_TOOLTIP, ++ // DataComponents.HIDE_TOOLTIP, ++ // DataComponents.REPAIR_COST, ++ // DataComponents.CREATIVE_SLOT_LOCK, ++ // DataComponents.ENCHANTMENT_GLINT_OVERRIDE, ++ // DataComponents.INTANGIBLE_PROJECTILE, ++ // DataComponents.FOOD, ++ // DataComponents.FIRE_RESISTANT, ++ // DataComponents.TOOL, ++ // DataComponents.STORED_ENCHANTMENTS, ++ DataComponents.DYED_COLOR, ++ // DataComponents.MAP_COLOR, ++ // DataComponents.MAP_ID, ++ // DataComponents.MAP_DECORATIONS, ++ // DataComponents.MAP_POST_PROCESSING, ++ // DataComponents.CHARGED_PROJECTILES, ++ // DataComponents.BUNDLE_CONTENTS, ++ // DataComponents.POTION_CONTENTS, ++ DataComponents.SUSPICIOUS_STEW_EFFECTS ++ // DataComponents.WRITABLE_BOOK_CONTENT, ++ // DataComponents.WRITTEN_BOOK_CONTENT, ++ // DataComponents.TRIM, ++ // DataComponents.DEBUG_STICK_STATE, ++ // DataComponents.ENTITY_DATA, ++ // DataComponents.BUCKET_ENTITY_DATA, ++ // DataComponents.BLOCK_ENTITY_DATA, ++ // DataComponents.INSTRUMENT, ++ // DataComponents.OMINOUS_BOTTLE_AMPLIFIER, ++ // DataComponents.RECIPES, ++ // DataComponents.LODESTONE_TRACKER, ++ // DataComponents.FIREWORK_EXPLOSION, ++ // DataComponents.FIREWORKS, ++ // DataComponents.PROFILE, ++ // DataComponents.NOTE_BLOCK_SOUND, ++ // DataComponents.BANNER_PATTERNS, ++ // DataComponents.BASE_COLOR, ++ // DataComponents.POT_DECORATIONS, ++ // DataComponents.CONTAINER, ++ // DataComponents.BEES, ++ // DataComponents.LOCK, ++ // DataComponents.CONTAINER_LOOT, + ); + // Purpur end -+ private ItemStack removeNonCursesFrom(ItemStack item) { ItemEnchantments itemenchantments = EnchantmentHelper.updateEnchantments(item, (itemenchantments_a) -> { itemenchantments_a.removeIf((holder) -> { -- return !((Enchantment) holder.value()).isCurse(); -+ return !org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains(holder.value()); +- return !holder.is(EnchantmentTags.CURSE); ++ return !org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains(holder.value()); // Purpur }); }); -@@ -255,6 +318,23 @@ public class GrindstoneMenu extends AbstractContainerMenu { +@@ -256,6 +318,23 @@ public class GrindstoneMenu extends AbstractContainerMenu { } item.set(DataComponents.REPAIR_COST, i); @@ -13508,7 +13404,7 @@ index db9444dda248260372d96ce239a590e88a4c1142..dda890500e360274ce194929560f01b5 return item; } -@@ -316,7 +396,9 @@ public class GrindstoneMenu extends AbstractContainerMenu { +@@ -317,7 +396,9 @@ public class GrindstoneMenu extends AbstractContainerMenu { return ItemStack.EMPTY; } @@ -13518,30 +13414,17 @@ index db9444dda248260372d96ce239a590e88a4c1142..dda890500e360274ce194929560f01b5 } 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 9992599dbe4f4a430e822a44b03c00505abfbfaf..3fea9339420aa38b303ccf6c154aec246e617b5b 100644 ---- a/src/main/java/net/minecraft/world/inventory/InventoryMenu.java -+++ b/src/main/java/net/minecraft/world/inventory/InventoryMenu.java -@@ -97,7 +97,7 @@ public class InventoryMenu extends RecipeBookMenu { - public boolean mayPickup(Player playerEntity) { - 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(net.minecraft.world.effect.MobEffects.WEAKNESS) : super.mayPickup(playerEntity); // Purpur - } - - @Override diff --git a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java -index 7de5e47f9a54263734eeef855a2dc07ef64d30ea..7215af6cc91f48b040c23c54536d4aac8d293497 100644 +index 7de5e47f9a54263734eeef855a2dc07ef64d30ea..b3bd9bbd96efc4784b86c2be6bb857da4db919b8 100644 --- a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java +++ b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java @@ -178,7 +178,9 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu { return ItemStack.EMPTY; } -+ this.activeQuickItem = itemstack; // Purpur ++ this.activeQuickItem = itemstack; // Purpur - Anvil API slot1.onTake(player, itemstack1); -+ this.activeQuickItem = null; // Purpur ++ this.activeQuickItem = null; // Purpur - Anvil API } return itemstack; @@ -13570,15 +13453,15 @@ index a15d5ff872dbd77f3c3145e0328f3d02e431ff8c..1dcf36d502990d32fc4cd3ea69c3ea33 this.activeChest = blockEntity; } diff --git a/src/main/java/net/minecraft/world/item/ArmorItem.java b/src/main/java/net/minecraft/world/item/ArmorItem.java -index 786e4a8700cb84b16dd9b8892a0d1d5803924d81..b108ca4c7900ccf6a14ebea01c21c103459054f8 100644 +index 647a4601deace52f8d855f512a73671f82b4762a..d05b1e129eee07434d162e1b949fd5633418ef66 100644 --- a/src/main/java/net/minecraft/world/item/ArmorItem.java +++ b/src/main/java/net/minecraft/world/item/ArmorItem.java -@@ -69,7 +69,7 @@ public class ArmorItem extends Item implements Equipable { +@@ -60,7 +60,7 @@ public class ArmorItem extends Item implements Equipable { return false; } else { LivingEntity entityliving = (LivingEntity) list.get(0); -- EquipmentSlot enumitemslot = Mob.getEquipmentSlotForItem(armor); -+ EquipmentSlot enumitemslot = pointer.level().purpurConfig.dispenserApplyCursedArmor ? Mob.getEquipmentSlotForItem(armor) : Mob.getSlotForDispenser(armor); if (enumitemslot == null) return false; // Purpur +- EquipmentSlot enumitemslot = entityliving.getEquipmentSlotForItem(armor); ++ EquipmentSlot enumitemslot = pointer.level().purpurConfig.dispenserApplyCursedArmor ? entityliving.getEquipmentSlotForItem(armor) : entityliving.getEquipmentSlotForDispenserItem(armor); if (enumitemslot == null) return false; // Purpur - Dispenser curse of binding protection ItemStack itemstack1 = armor.copyWithCount(1); // Paper - shrink below and single item in event // CraftBukkit start Level world = pointer.level(); @@ -13602,50 +13485,54 @@ index 066a6e5ed2632a55324ec0d10f2f8a6bf3f30a0f..1921ecf2c0a9f18c93d207692fb9c2db 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 9fd2d97ff0e05578a3e6a0b86dc1974691845c5d..58343722399404530d497648155dbc254d6a865a 100644 +index f005ea92449cf5e249ff64f4791c3bc6b8635528..ade1a0dac14bb3adc26bb103fc0ce9629fe973c6 100644 --- a/src/main/java/net/minecraft/world/item/AxeItem.java +++ b/src/main/java/net/minecraft/world/item/AxeItem.java -@@ -56,13 +56,15 @@ public class AxeItem extends DiggerItem { - Level level = context.getLevel(); - BlockPos blockPos = context.getClickedPos(); - Player player = context.getPlayer(); -- Optional optional = this.evaluateNewBlockState(level, blockPos, player, level.getBlockState(blockPos)); -+ Optional optional = this.evaluateActionable(level, blockPos, player, level.getBlockState(blockPos)); // Purpur - if (optional.isEmpty()) { +@@ -60,13 +60,15 @@ public class AxeItem extends DiggerItem { + if (playerHasShieldUseIntent(context)) { return InteractionResult.PASS; } else { -+ org.purpurmc.purpur.tool.Actionable actionable = optional.get(); // Purpur -+ BlockState state = actionable.into().withPropertiesOf(level.getBlockState(blockPos)); // Purpur - ItemStack itemStack = context.getItemInHand(); - // Paper start - EntityChangeBlockEvent -- if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, blockPos, optional.get())) { -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, blockPos, state)) { // Purpur +- Optional optional = this.evaluateNewBlockState(level, blockPos, player, level.getBlockState(blockPos)); ++ Optional optional = this.evaluateActionable(level, blockPos, player, level.getBlockState(blockPos)); // Purpur + if (optional.isEmpty()) { return InteractionResult.PASS; - } - // Paper end -@@ -70,32 +72,41 @@ public class AxeItem extends DiggerItem { - CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger((ServerPlayer)player, blockPos, itemStack); - } + } else { ++ org.purpurmc.purpur.tool.Actionable actionable = optional.get(); // Purpur ++ BlockState state = actionable.into().withPropertiesOf(level.getBlockState(blockPos)); // Purpur + ItemStack itemStack = context.getItemInHand(); + // Paper start - EntityChangeBlockEvent +- if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, blockPos, optional.get())) { ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, blockPos, state)) { // Purpur + return InteractionResult.PASS; + } + // Paper end +@@ -74,13 +76,20 @@ public class AxeItem extends DiggerItem { + CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger((ServerPlayer)player, blockPos, itemStack); + } -- level.setBlock(blockPos, optional.get(), 11); -- level.gameEvent(GameEvent.BLOCK_CHANGE, blockPos, GameEvent.Context.of(player, optional.get())); -+ // Purpur start -+ level.setBlock(blockPos, state, 11); -+ actionable.drops().forEach((drop, chance) -> { -+ if (level.random.nextDouble() < chance) { -+ Block.popResourceFromFace(level, blockPos, context.getClickedFace(), new ItemStack(drop)); -+ } -+ }); -+ level.gameEvent(GameEvent.BLOCK_CHANGE, blockPos, GameEvent.Context.of(player, state)); -+ // Purpur end - if (player != null) { - itemStack.hurtAndBreak(1, player, LivingEntity.getSlotForHand(context.getHand())); - } +- level.setBlock(blockPos, optional.get(), 11); +- level.gameEvent(GameEvent.BLOCK_CHANGE, blockPos, GameEvent.Context.of(player, optional.get())); ++ // Purpur start ++ level.setBlock(blockPos, state, 11); ++ actionable.drops().forEach((drop, chance) -> { ++ if (level.random.nextDouble() < chance) { ++ Block.popResourceFromFace(level, blockPos, context.getClickedFace(), new ItemStack(drop)); ++ } ++ }); ++ level.gameEvent(GameEvent.BLOCK_CHANGE, blockPos, GameEvent.Context.of(player, state)); ++ // Purpur end + if (player != null) { + itemStack.hurtAndBreak(1, player, LivingEntity.getSlotForHand(context.getHand())); + } -- return InteractionResult.sidedSuccess(level.isClientSide); -+ return InteractionResult.SUCCESS; // Purpur - force arm swing +- return InteractionResult.sidedSuccess(level.isClientSide); ++ return InteractionResult.SUCCESS; // Purpur - force arm swing + } } } +@@ -90,22 +99,24 @@ public class AxeItem extends DiggerItem { + return context.getHand().equals(InteractionHand.MAIN_HAND) && player.getOffhandItem().is(Items.SHIELD) && !player.isSecondaryUseActive(); + } - private Optional evaluateNewBlockState(Level world, BlockPos pos, @Nullable Player player, BlockState state) { - Optional optional = this.getStripped(state); @@ -13731,23 +13618,23 @@ index eb74d45ad458b80cf8455297c3bc550186adaea3..ef01856c487e4ab982996e0153761823 return InteractionResultHolder.fail(itemstack); } else { diff --git a/src/main/java/net/minecraft/world/item/BowItem.java b/src/main/java/net/minecraft/world/item/BowItem.java -index 5ca843df5b4caa668953e5e36a9b20fabeb35046..ec21d3d00deac4ad51f0a4beec2894675a461618 100644 +index 6eb5c0f23d9dc61e69ad5ad493c89602a9dcd4b5..a00181da8417445705d181fe62933c48a0b1170a 100644 --- a/src/main/java/net/minecraft/world/item/BowItem.java +++ b/src/main/java/net/minecraft/world/item/BowItem.java -@@ -31,7 +31,7 @@ public class BowItem extends ProjectileWeaponItem { +@@ -32,7 +32,7 @@ public class BowItem extends ProjectileWeaponItem { if (!((double)f < 0.1)) { List list = draw(stack, itemStack, player); - if (!world.isClientSide() && !list.isEmpty()) { -- this.shoot(world, player, player.getUsedItemHand(), stack, list, f * 3.0F, 1.0F, f == 1.0F, null); -+ this.shoot(world, player, player.getUsedItemHand(), stack, list, f * 3.0F, (float) world.purpurConfig.bowProjectileOffset, f == 1.0F, null); // Purpur + if (world instanceof ServerLevel serverLevel && !list.isEmpty()) { +- this.shoot(serverLevel, player, player.getUsedItemHand(), stack, list, f * 3.0F, 1.0F, f == 1.0F, null); ++ this.shoot(serverLevel, player, player.getUsedItemHand(), stack, list, f * 3.0F, (float) world.purpurConfig.bowProjectileOffset, f == 1.0F, null); // Purpur } world.playSound( diff --git a/src/main/java/net/minecraft/world/item/BucketItem.java b/src/main/java/net/minecraft/world/item/BucketItem.java -index 49557d6f22c5725c663a231deab019d4f6fe95fa..046652e8f9c5dcdf7c90acb9391214cac46bd7d8 100644 +index 321188173918d0d60858a258400dfd682ccdb21c..af47074f3a61a8518697d7851e43d5436fec5d57 100644 --- a/src/main/java/net/minecraft/world/item/BucketItem.java +++ b/src/main/java/net/minecraft/world/item/BucketItem.java -@@ -194,7 +194,7 @@ public class BucketItem extends Item implements DispensibleContainerItem { +@@ -196,7 +196,7 @@ public class BucketItem extends Item implements DispensibleContainerItem { // CraftBukkit end if (!flag2) { return movingobjectpositionblock != null && this.emptyContents(entityhuman, world, movingobjectpositionblock.getBlockPos().relative(movingobjectpositionblock.getDirection()), (BlockHitResult) null, enumdirection, clicked, itemstack, enumhand); // CraftBukkit @@ -13756,7 +13643,7 @@ index 49557d6f22c5725c663a231deab019d4f6fe95fa..046652e8f9c5dcdf7c90acb9391214ca int i = blockposition.getX(); int j = blockposition.getY(); int k = blockposition.getZ(); -@@ -202,7 +202,7 @@ public class BucketItem extends Item implements DispensibleContainerItem { +@@ -204,7 +204,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) { @@ -13766,10 +13653,10 @@ index 49557d6f22c5725c663a231deab019d4f6fe95fa..046652e8f9c5dcdf7c90acb9391214ca 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 1f52feb5684ee1bab710e1557cf69b43b4d4dfd4..78f124f5204e4af9318ca3eeced6b1e3353b210f 100644 +index c39fa953accd6cf35672f452052cca42fe6f29d0..dbdd1cd9486d91142e1c6b8a34aafba46c3988d3 100644 --- a/src/main/java/net/minecraft/world/item/CrossbowItem.java +++ b/src/main/java/net/minecraft/world/item/CrossbowItem.java -@@ -60,7 +60,7 @@ public class CrossbowItem extends ProjectileWeaponItem { +@@ -69,7 +69,7 @@ public class CrossbowItem extends ProjectileWeaponItem { ItemStack itemStack = user.getItemInHand(hand); ChargedProjectiles chargedProjectiles = itemStack.get(DataComponents.CHARGED_PROJECTILES); if (chargedProjectiles != null && !chargedProjectiles.isEmpty()) { @@ -13778,20 +13665,11 @@ index 1f52feb5684ee1bab710e1557cf69b43b4d4dfd4..78f124f5204e4af9318ca3eeced6b1e3 return InteractionResultHolder.consume(itemStack); } else if (!user.getProjectile(itemStack).isEmpty()) { this.startSoundPlayed = false; -@@ -107,7 +107,7 @@ public class CrossbowItem extends ProjectileWeaponItem { - return CrossbowItem.tryLoadProjectiles(shooter, crossbow, true); - } - private static boolean tryLoadProjectiles(LivingEntity shooter, ItemStack crossbow, boolean consume) { -- List list = draw(crossbow, shooter.getProjectile(crossbow), shooter, consume); -+ List list = draw(crossbow, shooter.getProjectile(crossbow), shooter, (org.purpurmc.purpur.PurpurConfig.allowCrossbowInfinity && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.INFINITY, crossbow) > 0) || consume); - // Paper end - Add EntityLoadCrossbowEvent - if (!list.isEmpty()) { - crossbow.set(DataComponents.CHARGED_PROJECTILES, ChargedProjectiles.of(list)); diff --git a/src/main/java/net/minecraft/world/item/DyeColor.java b/src/main/java/net/minecraft/world/item/DyeColor.java -index 2202798612cad53aff28c499b8909a7292a37ad5..5ed2b7d15686fc9aa6dc7c03c337433cb3ee2cbd 100644 +index 0d04a0107bd1a8a2b9aeb4be55025cd554e8fb79..a050d76233e179a1456b83ccc02bb9a55d1cec84 100644 --- a/src/main/java/net/minecraft/world/item/DyeColor.java +++ b/src/main/java/net/minecraft/world/item/DyeColor.java -@@ -105,4 +105,10 @@ public enum DyeColor implements StringRepresentable { +@@ -103,4 +103,10 @@ public enum DyeColor implements StringRepresentable { public String getSerializedName() { return this.name; } @@ -13870,10 +13748,10 @@ index 218f2f085309f04438f8b07bc41cf242583db2dc..ea8e49b42b9dde74784189430be66ed6 itemStack.shrink(1); } else ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); diff --git a/src/main/java/net/minecraft/world/item/HangingEntityItem.java b/src/main/java/net/minecraft/world/item/HangingEntityItem.java -index 530167ce8e5bb72a418f8ec61411e38a5892fd72..35dc7546793dba34bf6debad3f214f61a8fb4f4e 100644 +index d8a63ac5444eff8e3decb2f4addc2decb8a5d648..41cc9229108aa8e4f5655dfe590ff414a16b1444 100644 --- a/src/main/java/net/minecraft/world/item/HangingEntityItem.java +++ b/src/main/java/net/minecraft/world/item/HangingEntityItem.java -@@ -73,6 +73,11 @@ public class HangingEntityItem extends Item { +@@ -74,6 +74,11 @@ public class HangingEntityItem extends Item { if (!customdata.isEmpty()) { EntityType.updateCustomEntityTag(world, entityhuman, (Entity) object, customdata); @@ -13886,23 +13764,23 @@ index 530167ce8e5bb72a418f8ec61411e38a5892fd72..35dc7546793dba34bf6debad3f214f61 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 06497b5141e611cc7a1b6030a7b9c54b5c4eda06..6251c6226c59763b27b79e541b7e7089ea804ff8 100644 +index 06497b5141e611cc7a1b6030a7b9c54b5c4eda06..28df1b3230762e52b5458ac93a85c9a5d41eb6a6 100644 --- a/src/main/java/net/minecraft/world/item/HoeItem.java +++ b/src/main/java/net/minecraft/world/item/HoeItem.java -@@ -46,15 +46,25 @@ public class HoeItem extends DiggerItem { +@@ -46,15 +46,23 @@ public class HoeItem extends DiggerItem { public InteractionResult useOn(UseOnContext context) { Level level = context.getLevel(); BlockPos blockPos = context.getClickedPos(); - Pair, Consumer> pair = TILLABLES.get(level.getBlockState(blockPos).getBlock()); - if (pair == null) { +- return InteractionResult.PASS; +- } else { +- Predicate predicate = pair.getFirst(); +- Consumer consumer = pair.getSecond(); + // Purpur start + Block clickedBlock = level.getBlockState(blockPos).getBlock(); + var tillable = level.purpurConfig.hoeTillables.get(clickedBlock); -+ if (tillable == null) { - return InteractionResult.PASS; - } else { -- Predicate predicate = pair.getFirst(); -- Consumer consumer = pair.getSecond(); ++ if (tillable == null) { return InteractionResult.PASS; } else { + Predicate predicate = tillable.condition().predicate(); + Consumer consumer = (ctx) -> { + level.setBlock(blockPos, tillable.into().defaultBlockState(), 11); @@ -13920,7 +13798,7 @@ index 06497b5141e611cc7a1b6030a7b9c54b5c4eda06..6251c6226c59763b27b79e541b7e7089 if (!level.isClientSide) { consumer.accept(context); if (player != null) { -@@ -62,7 +72,7 @@ public class HoeItem extends DiggerItem { +@@ -62,7 +70,7 @@ public class HoeItem extends DiggerItem { } } @@ -13930,10 +13808,10 @@ index 06497b5141e611cc7a1b6030a7b9c54b5c4eda06..6251c6226c59763b27b79e541b7e7089 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 2f0b817dd11bc9a043e4ea60268135b3aff18e44..a3f44d5cfcbfcd0c1ece7e23f9e1e0d149b6c572 100644 +index 39368883e050a3bcecd0e2ded22f6c36e7dde0a6..7c57e51a3b929f6a56d11193a589c9936f559405 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -476,6 +476,7 @@ public final class ItemStack implements DataComponentHolder { +@@ -497,6 +497,7 @@ public final class ItemStack implements DataComponentHolder { world.isBlockPlaceCancelled = true; // Paper - prevent calling cleanup logic when undoing a block place upon a cancelled BlockPlaceEvent for (BlockState blockstate : blocks) { blockstate.update(true, false); @@ -13941,7 +13819,7 @@ index 2f0b817dd11bc9a043e4ea60268135b3aff18e44..a3f44d5cfcbfcd0c1ece7e23f9e1e0d1 } world.isBlockPlaceCancelled = false; // Paper - prevent calling cleanup logic when undoing a block place upon a cancelled BlockPlaceEvent world.preventPoiUpdated = false; -@@ -508,6 +509,7 @@ public final class ItemStack implements DataComponentHolder { +@@ -529,6 +530,7 @@ public final class ItemStack implements DataComponentHolder { if (!(block.getBlock() instanceof BaseEntityBlock)) { // Containers get placed automatically block.onPlace(world, newblockposition, oldBlock, true, context); // Paper - pass context } @@ -13949,67 +13827,51 @@ index 2f0b817dd11bc9a043e4ea60268135b3aff18e44..a3f44d5cfcbfcd0c1ece7e23f9e1e0d1 world.notifyAndUpdatePhysics(newblockposition, null, oldBlock, block, world.getBlockState(newblockposition), updateFlag, 512); // send null chunk as chunk.k() returns false by this point } -@@ -638,6 +640,16 @@ public final class ItemStack implements DataComponentHolder { +@@ -643,6 +645,26 @@ public final class ItemStack implements DataComponentHolder { return this.isDamageableItem() && this.getDamageValue() > 0; } -+ // Purpur start ++ // Purpur start - Add option to mend the most damaged equipment first + public float getDamagePercent() { -+ if (isDamaged()) { -+ return (float) getDamageValue() / (float) getMaxDamage(); -+ } else { -+ return 0F; ++ if (this.has(DataComponents.UNBREAKABLE)) { ++ return 0.0F; + } ++ ++ final int maxDamage = this.getOrDefault(DataComponents.MAX_DAMAGE, 0); ++ if (maxDamage == 0) { ++ return 0.0F; ++ } ++ ++ final int damage = this.getOrDefault(DataComponents.DAMAGE, 0); ++ if (damage == 0) { ++ return 0.0F; ++ } ++ ++ return (float) damage / maxDamage; + } -+ // Purpur end ++ // Purpur end - Add option to mend the most damaged equipment first + public int getDamageValue() { return Mth.clamp((Integer) this.getOrDefault(DataComponents.DAMAGE, 0), 0, this.getMaxDamage()); } -@@ -655,7 +667,7 @@ public final class ItemStack implements DataComponentHolder { - 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); - int k = 0; - - for (int l = 0; j > 0 && l < amount; ++l) { -@@ -738,6 +750,12 @@ public final class ItemStack implements DataComponentHolder { - this.hurtAndBreak(amount, randomsource, entity, () -> { // Paper - Add EntityDamageItemEvent - if (slot != null) entity.broadcastBreakEvent(slot); // Paper - ItemStack damage API - slot is nullable - Item item = this.getItem(); -+ // Purpur start -+ if (item == Items.ELYTRA) { -+ setDamageValue(getMaxDamage() - 1); -+ return; -+ } -+ // Purpur end - // CraftBukkit start - Check for item breaking - if (this.count == 1 && entity instanceof net.minecraft.world.entity.player.Player) { - org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent((net.minecraft.world.entity.player.Player) entity, this); -@@ -1219,6 +1237,16 @@ public final class ItemStack implements DataComponentHolder { +@@ -1229,6 +1251,12 @@ public final class ItemStack implements DataComponentHolder { return !((ItemEnchantments) this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY)).isEmpty(); } -+ // Purpur start -+ public boolean hasEnchantment(Enchantment enchantment) { -+ if (isEnchanted()) { -+ ItemEnchantments enchantments = this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY); -+ return new net.minecraft.advancements.critereon.EnchantmentPredicate(enchantment, net.minecraft.advancements.critereon.MinMaxBounds.Ints.atLeast(1)).containedIn(enchantments); -+ } -+ return false; ++ // Purpur start - Config to allow unsafe enchants ++ public boolean hasEnchantment(Holder enchantment) { ++ return this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY).getLevel(enchantment) > 0; + } -+ // Purpur end ++ // Purpur end - Config to allow unsafe enchants + public ItemEnchantments getEnchantments() { return (ItemEnchantments) this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY); } diff --git a/src/main/java/net/minecraft/world/item/Items.java b/src/main/java/net/minecraft/world/item/Items.java -index d00b59efb754594cf532f8598f4b6d3b29693232..55f753668ccb769e2f7af50bda69c41b09238130 100644 +index 07315232192f6e09910a028c4643d7f0544c62e3..6b2235281dca67a80cb651e9f8e9bf2556979276 100644 --- a/src/main/java/net/minecraft/world/item/Items.java +++ b/src/main/java/net/minecraft/world/item/Items.java -@@ -338,7 +338,7 @@ public class Items { +@@ -337,7 +337,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); @@ -14018,12 +13880,12 @@ index d00b59efb754594cf532f8598f4b6d3b29693232..55f753668ccb769e2f7af50bda69c41b public static final Item CHEST = registerBlock(Blocks.CHEST, settings -> settings.component(DataComponents.CONTAINER, ItemContainerContents.EMPTY)); public static final Item CRAFTING_TABLE = registerBlock(Blocks.CRAFTING_TABLE); public static final Item FARMLAND = registerBlock(Blocks.FARMLAND); -@@ -1909,7 +1909,7 @@ public class Items { +@@ -1919,7 +1919,7 @@ public class Items { "sweet_berries", new ItemNameBlockItem(Blocks.SWEET_BERRY_BUSH, new Item.Properties().food(Foods.SWEET_BERRIES)) ); public static final Item GLOW_BERRIES = registerItem( - "glow_berries", new ItemNameBlockItem(Blocks.CAVE_VINES, new Item.Properties().food(Foods.GLOW_BERRIES)) -+ "glow_berries", new org.purpurmc.purpur.item.GlowBerryItem(Blocks.CAVE_VINES, new Item.Properties().food(Foods.GLOW_BERRIES)) // Purpur ++ "glow_berries", new org.purpurmc.purpur.item.GlowBerryItem(Blocks.CAVE_VINES, new Item.Properties().food(Foods.GLOW_BERRIES)) // Purpur ); public static final Item CAMPFIRE = registerBlock(Blocks.CAMPFIRE, settings -> settings.component(DataComponents.CONTAINER, ItemContainerContents.EMPTY)); public static final Item SOUL_CAMPFIRE = registerBlock( @@ -14040,19 +13902,19 @@ index ce461b1a8d7fab87ae28e30205f6fab67f1808b6..608390ed36710a419de1542b80340dd3 int i = 1 << mapItemSavedData.scale; int j = mapItemSavedData.centerX; diff --git a/src/main/java/net/minecraft/world/item/MilkBucketItem.java b/src/main/java/net/minecraft/world/item/MilkBucketItem.java -index 0f83ae4b0d5f52ff9ccfff6bbcc31153d45bd619..d0751274e89042715cab8e9e72387042356e3244 100644 +index 43c9dea6b0db7f8d6070dedcb472883ab46d9eaf..15a1f9ffbf640bffadca97e28f72b6a5d43c65d7 100644 --- a/src/main/java/net/minecraft/world/item/MilkBucketItem.java +++ b/src/main/java/net/minecraft/world/item/MilkBucketItem.java -@@ -26,7 +26,9 @@ public class MilkBucketItem extends Item { +@@ -25,7 +25,9 @@ public class MilkBucketItem extends Item { + } - stack.consume(1, user); if (!world.isClientSide) { + net.minecraft.world.effect.MobEffectInstance badOmen = user.getEffect(net.minecraft.world.effect.MobEffects.BAD_OMEN); // Purpur user.removeAllEffects(org.bukkit.event.entity.EntityPotionEffectEvent.Cause.MILK); // CraftBukkit + if (!world.purpurConfig.milkCuresBadOmen && badOmen != null) user.addEffect(badOmen); // Purpur } - return stack.isEmpty() ? new ItemStack(Items.BUCKET) : stack; + if (user instanceof Player entityhuman) { diff --git a/src/main/java/net/minecraft/world/item/MinecartItem.java b/src/main/java/net/minecraft/world/item/MinecartItem.java index d524fcc191cb95d6ec7f12ae7fceeb8077bb08fc..4b8cebb321eddc852b4ec7def7f51d781f67927b 100644 --- a/src/main/java/net/minecraft/world/item/MinecartItem.java @@ -14090,46 +13952,27 @@ index 774c982f28b4f127fc3f036c19dfb47fb9ae3264..d49b60e7e643498b49c03593dc0da2f8 // Paper end - Add PlayerNameEntityEvent mob.setPersistenceRequired(); diff --git a/src/main/java/net/minecraft/world/item/ProjectileWeaponItem.java b/src/main/java/net/minecraft/world/item/ProjectileWeaponItem.java -index d27e83c08c45b8514207f26e48ceb1a91ded94be..4f352c48007107e1306147310eec53ae17b2d9f0 100644 +index 32dd0b13a0819f597d8a93c6bc3a155781067544..ffbc56290eb8e36339e29f6084bb207366506c39 100644 --- a/src/main/java/net/minecraft/world/item/ProjectileWeaponItem.java +++ b/src/main/java/net/minecraft/world/item/ProjectileWeaponItem.java -@@ -131,11 +131,26 @@ public abstract class ProjectileWeaponItem extends Item { - entityarrow.setPierceLevel((byte) k); +@@ -110,6 +110,8 @@ public abstract class ProjectileWeaponItem extends Item { + entityarrow.setCritArrow(true); } -+ // Purpur start -+ int lootingLevel = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.LOOTING, weaponStack); -+ -+ if (lootingLevel > 0) { -+ entityarrow.setLootingLevel(lootingLevel); -+ } -+ // Purpur end ++ entityarrow.setActualEnchantments(weaponStack.getEnchantments()); // Purpur - Add an option to fix MC-3304 projectile looting + return entityarrow; } - protected static boolean hasInfiniteArrows(ItemStack weaponStack, ItemStack projectileStack, boolean creative) { -- return creative || projectileStack.is(Items.ARROW) && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.INFINITY, weaponStack) > 0; -+ // Purpur start -+ return hasInfiniteArrows(weaponStack, projectileStack, creative, null); -+ } -+ -+ protected static boolean hasInfiniteArrows(ItemStack weaponStack, ItemStack projectileStack, boolean creative, @javax.annotation.Nullable Level level) { -+ boolean canBeInfinity = level == null ? projectileStack.is(Items.ARROW) : ((projectileStack.is(Items.ARROW) && level.purpurConfig.infinityWorksWithNormalArrows) || (projectileStack.is(Items.TIPPED_ARROW) && level.purpurConfig.infinityWorksWithTippedArrows) || (projectileStack.is(Items.SPECTRAL_ARROW) && level.purpurConfig.infinityWorksWithSpectralArrows)); -+ return creative || canBeInfinity && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.INFINITY, weaponStack) > 0; -+ // Purpur end - } +@@ -153,7 +155,7 @@ public abstract class ProjectileWeaponItem extends Item { + int i; + label28: + { +- if (!multishot && !shooter.hasInfiniteMaterials()) { ++ if (!multishot && !shooter.hasInfiniteMaterials() && !shooter.level().purpurConfig.infinityWorksWithoutArrows) { + Level world = shooter.level(); - protected static List draw(ItemStack weaponStack, ItemStack projectileStack, LivingEntity shooter) { -@@ -161,7 +176,7 @@ public abstract class ProjectileWeaponItem extends Item { - } - - protected static ItemStack useAmmo(ItemStack weaponStack, ItemStack projectileStack, LivingEntity shooter, boolean multishot) { -- boolean flag1 = !multishot && !ProjectileWeaponItem.hasInfiniteArrows(weaponStack, projectileStack, shooter.hasInfiniteMaterials()); -+ boolean flag1 = !multishot && !ProjectileWeaponItem.hasInfiniteArrows(weaponStack, projectileStack, shooter.hasInfiniteMaterials(), shooter.level()); // Purpur - ItemStack itemstack2; - - if (!flag1) { + if (world instanceof ServerLevel) { diff --git a/src/main/java/net/minecraft/world/item/ShovelItem.java b/src/main/java/net/minecraft/world/item/ShovelItem.java index 24f6a158e4759aac3be8da4cf5e0d40bd295355b..6b7dbb570f8a698c87c6bce992d84d87b55176e6 100644 --- a/src/main/java/net/minecraft/world/item/ShovelItem.java @@ -14173,7 +14016,7 @@ index 32b170551a2f5bdc88d29f4d03750bfe3974e71b..a41fb0dd26af367fc2470a7913a84d86 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 9cea8da84f39bb3f687139ef213ccea358724dee..076e6858222b92f8409f1f5cad398582c1fd6bcb 100644 +index 9cea8da84f39bb3f687139ef213ccea358724dee..d43be19fdb4ca917d08f84cda5a67667960f28fe 100644 --- a/src/main/java/net/minecraft/world/item/SpawnEggItem.java +++ b/src/main/java/net/minecraft/world/item/SpawnEggItem.java @@ -74,6 +74,15 @@ public class SpawnEggItem extends Item { @@ -14183,7 +14026,7 @@ index 9cea8da84f39bb3f687139ef213ccea358724dee..076e6858222b92f8409f1f5cad398582 + + // Purpur start + org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); -+ org.purpurmc.purpur.event.PlayerSetSpawnerTypeWithEggEvent event = new org.purpurmc.purpur.event.PlayerSetSpawnerTypeWithEggEvent((org.bukkit.entity.Player) context.getPlayer().getBukkitEntity(), bukkitBlock, (org.bukkit.block.CreatureSpawner) bukkitBlock.getState(), org.bukkit.entity.EntityType.fromName(entitytypes.getName())); ++ org.purpurmc.purpur.event.PlayerSetSpawnerTypeWithEggEvent event = new org.purpurmc.purpur.event.PlayerSetSpawnerTypeWithEggEvent((org.bukkit.entity.Player) context.getPlayer().getBukkitEntity(), bukkitBlock, (org.bukkit.block.CreatureSpawner) bukkitBlock.getState(), org.bukkit.entity.EntityType.fromName(entitytypes.getName())); + if (!event.callEvent()) { + return InteractionResult.FAIL; + } @@ -14206,45 +14049,39 @@ index 369955746f4b51f69fa01103e3771dd74fc6c8f0..e6edd3a0fa2578900cdbe8bd588219dc 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 47de500fddb0716d142f8f5876a82a95afaa06fa..905a020dd7b365d51d5addadbbeb9555d03c5238 100644 +index f1b2d388a1a40a1d909a2e726f32d6c15e1eb0eb..8cf0b69fee110af05b89afa8e3236575aa6850e2 100644 --- a/src/main/java/net/minecraft/world/item/TridentItem.java +++ b/src/main/java/net/minecraft/world/item/TridentItem.java -@@ -76,11 +76,19 @@ public class TridentItem extends Item implements ProjectileItem { - if (k == 0) { - ThrownTrident entitythrowntrident = new ThrownTrident(world, entityhuman, stack); +@@ -81,11 +81,13 @@ public class TridentItem extends Item implements ProjectileItem { + if (f == 0.0F) { + ThrownTrident entitythrowntrident = new ThrownTrident(world, entityhuman, stack); -- entitythrowntrident.shootFromRotation(entityhuman, entityhuman.getXRot(), entityhuman.getYRot(), 0.0F, 2.5F + (float) k * 0.5F, 1.0F); -+ entitythrowntrident.shootFromRotation(entityhuman, entityhuman.getXRot(), entityhuman.getYRot(), 0.0F, 2.5F + (float) k * 0.5F, (float) world.purpurConfig.tridentProjectileOffset); // Purpur - if (entityhuman.hasInfiniteMaterials()) { - entitythrowntrident.pickup = AbstractArrow.Pickup.CREATIVE_ONLY; - } +- entitythrowntrident.shootFromRotation(entityhuman, entityhuman.getXRot(), entityhuman.getYRot(), 0.0F, 2.5F, 1.0F); ++ entitythrowntrident.shootFromRotation(entityhuman, entityhuman.getXRot(), entityhuman.getYRot(), 0.0F, 2.5F, (float) world.purpurConfig.tridentProjectileOffset); // Purpur + if (entityhuman.hasInfiniteMaterials()) { + entitythrowntrident.pickup = AbstractArrow.Pickup.CREATIVE_ONLY; + } -+ // Purpur start -+ int lootingLevel = EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.LOOTING, stack); ++ entitythrowntrident.setActualEnchantments(stack.getEnchantments()); // Purpur - Add an option to fix MC-3304 projectile looting + -+ if (lootingLevel > 0) { -+ entitythrowntrident.setLootingLevel(lootingLevel); + // CraftBukkit start + // Paper start - PlayerLaunchProjectileEvent + com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack), (org.bukkit.entity.Projectile) entitythrowntrident.getBukkitEntity()); +@@ -127,6 +129,14 @@ public class TridentItem extends Item implements ProjectileItem { + f4 *= f / f6; + f5 *= f / f6; + org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerRiptideEvent(entityhuman, stack, f3, f4, f5); // CraftBukkit ++ ++ // Purpur start ++ ItemStack chestItem = entityhuman.getItemBySlot(EquipmentSlot.CHEST); ++ if (chestItem.getItem() == Items.ELYTRA && world.purpurConfig.elytraDamagePerTridentBoost > 0) { ++ chestItem.hurtAndBreak(world.purpurConfig.elytraDamagePerTridentBoost, entityhuman, EquipmentSlot.CHEST); + } + // Purpur end + - // CraftBukkit start - // Paper start - PlayerLaunchProjectileEvent - com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack), (org.bukkit.entity.Projectile) entitythrowntrident.getBukkitEntity()); -@@ -123,6 +131,14 @@ public class TridentItem extends Item implements ProjectileItem { - f3 *= f6 / f5; - f4 *= f6 / f5; - org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerRiptideEvent(entityhuman, stack, f2, f3, f4); // CraftBukkit -+ -+ // Purpur start -+ ItemStack chestItem = entityhuman.getItemBySlot(EquipmentSlot.CHEST); -+ if (chestItem.getItem() == Items.ELYTRA && world.purpurConfig.elytraDamagePerTridentBoost > 0) { -+ chestItem.hurtAndBreak(world.purpurConfig.elytraDamagePerTridentBoost, entityhuman, EquipmentSlot.CHEST); -+ } -+ // Purpur end -+ - entityhuman.push((double) f2, (double) f3, (double) f4); - entityhuman.startAutoSpinAttack(20); - if (entityhuman.onGround()) { + entityhuman.push((double) f3, (double) f4, (double) f5); + entityhuman.startAutoSpinAttack(20, 8.0F, stack); + 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 e314f36951e9ac15c57137e24fce8c410373130a..21dfb8e91c5427ac12133de2c05d923d87adf5ba 100644 --- a/src/main/java/net/minecraft/world/item/crafting/Ingredient.java @@ -14270,66 +14107,91 @@ index e314f36951e9ac15c57137e24fce8c410373130a..21dfb8e91c5427ac12133de2c05d923d ItemStack[] aitemstack = this.getItems(); int i = aitemstack.length; -diff --git a/src/main/java/net/minecraft/world/item/enchantment/ArrowInfiniteEnchantment.java b/src/main/java/net/minecraft/world/item/enchantment/ArrowInfiniteEnchantment.java -index 81cc05c929d612898609965d82454b89cd18f9f5..fa73c3d4b58ad8379963a9866d8f09e1d6abd663 100644 ---- a/src/main/java/net/minecraft/world/item/enchantment/ArrowInfiniteEnchantment.java -+++ b/src/main/java/net/minecraft/world/item/enchantment/ArrowInfiniteEnchantment.java -@@ -7,6 +7,6 @@ public class ArrowInfiniteEnchantment extends Enchantment { - - @Override - public boolean checkCompatibility(Enchantment other) { -- return !(other instanceof MendingEnchantment) && super.checkCompatibility(other); -+ return !(other instanceof MendingEnchantment) && super.checkCompatibility(other) || other instanceof MendingEnchantment && org.purpurmc.purpur.PurpurConfig.allowInfinityMending; // Purpur - } - } diff --git a/src/main/java/net/minecraft/world/item/enchantment/EnchantmentHelper.java b/src/main/java/net/minecraft/world/item/enchantment/EnchantmentHelper.java -index d2f0463b0e74983eb2e3dfca9a268e9502b86257..6d0363cec691996be416ab22ef9d825196399158 100644 +index fce49b17905ab97e691aa8499a5dfed67adf0c40..1abf54eeaad1b062f1465ee1a847bbfcba295665 100644 --- a/src/main/java/net/minecraft/world/item/enchantment/EnchantmentHelper.java +++ b/src/main/java/net/minecraft/world/item/enchantment/EnchantmentHelper.java -@@ -237,6 +237,29 @@ public class EnchantmentHelper { - return getItemEnchantmentLevel(Enchantments.CHANNELING, stack) > 0; +@@ -6,6 +6,7 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap.Entry; + import java.util.ArrayList; + import java.util.Collection; + import java.util.List; ++import java.util.Map; + import java.util.Optional; + import java.util.function.BiConsumer; + import java.util.function.Consumer; +@@ -559,4 +560,58 @@ public class EnchantmentHelper { + interface EnchantmentVisitor { + void accept(Holder enchantment, int level); } - -+ // Purpur start -+ @Nullable -+ public static Map.Entry getMostDamagedEquipment(Enchantment enchantment, LivingEntity entity) { -+ Map map = enchantment.getSlotItems(entity); -+ if (map.isEmpty()) { -+ return null; -+ } -+ Map.Entry item = null; -+ float maxPercent = 0F; -+ for (Map.Entry entry : map.entrySet()) { -+ ItemStack itemstack = entry.getValue(); -+ if (!itemstack.isEmpty() && itemstack.isDamaged() && getItemEnchantmentLevel(enchantment, itemstack) > 0) { -+ float percent = itemstack.getDamagePercent(); -+ if (item == null || percent > maxPercent) { -+ item = entry; ++ ++ // Purpur start - Enchantment convenience methods ++ public static Holder.Reference getEnchantmentHolder(ResourceKey enchantment) { ++ return net.minecraft.server.MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.ENCHANTMENT).getOrThrow(enchantment); ++ } ++ ++ public static int getItemEnchantmentLevel(ResourceKey enchantment, ItemStack stack) { ++ return getItemEnchantmentLevel(getEnchantmentHolder(enchantment), stack); ++ } ++ // Purpur end - Enchantment convenience methods ++ ++ // Purpur start - Add option to mend the most damaged equipment first ++ public static Optional getMostDamagedItemWith(DataComponentType componentType, LivingEntity entity) { ++ ItemStack maxStack = null; ++ EquipmentSlot maxSlot = null; ++ float maxPercent = 0.0F; ++ ++ equipmentSlotLoop: ++ for (EquipmentSlot equipmentSlot : EquipmentSlot.values()) { ++ ItemStack stack = entity.getItemBySlot(equipmentSlot); ++ ++ // do not even check enchantments for item with lower or equal damage percent ++ float percent = stack.getDamagePercent(); ++ if (percent <= maxPercent) { ++ continue; ++ } ++ ++ ItemEnchantments itemEnchantments = stack.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY); ++ ++ for (Entry> entry : itemEnchantments.entrySet()) { ++ Enchantment enchantment = entry.getKey().value(); ++ ++ net.minecraft.core.component.DataComponentMap effects = enchantment.effects(); ++ if (!effects.has(componentType)) { ++ // try with another enchantment ++ continue; ++ } ++ ++ if (enchantment.matchingSlot(equipmentSlot)) { ++ maxStack = stack; ++ maxSlot = equipmentSlot; + maxPercent = percent; ++ ++ // check another slot now ++ continue equipmentSlotLoop; + } + } + } -+ return item; -+ } -+ // Purpur end + - @Nullable - public static java.util.Map.Entry getRandomItemWith(Enchantment enchantment, LivingEntity entity) { - return getRandomItemWith(enchantment, entity, stack -> true); ++ return maxStack != null ++ ? Optional.of(new EnchantedItemInUse(maxStack, maxSlot, entity)) ++ : Optional.empty(); ++ } ++ // Purpur end - Add option to mend the most damaged equipment first + } diff --git a/src/main/java/net/minecraft/world/item/enchantment/ItemEnchantments.java b/src/main/java/net/minecraft/world/item/enchantment/ItemEnchantments.java -index af18de11dd55938b6091f5ab183bd3fe4e8df152..2c741860afa1fa4d5798c68b84ec3fe13157ff09 100644 +index 8ac485d82c2d2b32f4d54e02c18c2cb2c3df4fa4..9ebe6a5f31ceacd33d9c111966ad941b535b4e67 100644 --- a/src/main/java/net/minecraft/world/item/enchantment/ItemEnchantments.java +++ b/src/main/java/net/minecraft/world/item/enchantment/ItemEnchantments.java -@@ -37,7 +37,7 @@ public class ItemEnchantments implements TooltipProvider { +@@ -35,7 +35,7 @@ public class ItemEnchantments implements TooltipProvider { + private static final java.util.Comparator> ENCHANTMENT_ORDER = java.util.Comparator.comparing(Holder::getRegisteredName); public static final ItemEnchantments EMPTY = new ItemEnchantments(new Object2IntAVLTreeMap<>(ENCHANTMENT_ORDER), true); // Paper end - public static final int MAX_LEVEL = 255; - private static final Codec LEVEL_CODEC = Codec.intRange(0, 255); + private static final Codec LEVEL_CODEC = Codec.intRange(0, (org.purpurmc.purpur.PurpurConfig.clampEnchantLevels ? 255 : 32767)); // Purpur - private static final Codec>> LEVELS_CODEC = Codec.unboundedMap( // Paper - BuiltInRegistries.ENCHANTMENT.holderByNameCodec(), LEVEL_CODEC - ) -@@ -72,7 +72,7 @@ public class ItemEnchantments implements TooltipProvider { + private static final Codec>> LEVELS_CODEC = Codec.unboundedMap( + Enchantment.CODEC, LEVEL_CODEC + )// Paper start - sort enchantments +@@ -69,7 +69,7 @@ public class ItemEnchantments implements TooltipProvider { for (Entry> entry : enchantments.object2IntEntrySet()) { int i = entry.getIntValue(); @@ -14338,19 +14200,19 @@ index af18de11dd55938b6091f5ab183bd3fe4e8df152..2c741860afa1fa4d5798c68b84ec3fe1 throw new IllegalArgumentException("Enchantment " + entry.getKey() + " has invalid level " + i); } } -@@ -169,13 +169,13 @@ public class ItemEnchantments implements TooltipProvider { +@@ -166,13 +166,13 @@ public class ItemEnchantments implements TooltipProvider { if (level <= 0) { - this.enchantments.removeInt(enchantment.builtInRegistryHolder()); + this.enchantments.removeInt(enchantment); } else { -- this.enchantments.put(enchantment.builtInRegistryHolder(), Math.min(level, 255)); -+ this.enchantments.put(enchantment.builtInRegistryHolder(), Math.min(level, (org.purpurmc.purpur.PurpurConfig.clampEnchantLevels ? 255 : 32767))); +- this.enchantments.put(enchantment, Math.min(level, 255)); ++ this.enchantments.put(enchantment, Math.min(level, (org.purpurmc.purpur.PurpurConfig.clampEnchantLevels ? 255 : 32767))); // Purpur } } - public void upgrade(Enchantment enchantment, int level) { + public void upgrade(Holder enchantment, int level) { if (level > 0) { -- this.enchantments.merge(enchantment.builtInRegistryHolder(), Math.min(level, 255), Integer::max); -+ this.enchantments.merge(enchantment.builtInRegistryHolder(), Math.min(level, (org.purpurmc.purpur.PurpurConfig.clampEnchantLevels ? 255 : 32767)), Integer::max); +- this.enchantments.merge(enchantment, Math.min(level, 255), Integer::max); ++ this.enchantments.merge(enchantment, Math.min(level, (org.purpurmc.purpur.PurpurConfig.clampEnchantLevels ? 255 : 32767)), Integer::max); // Purpur } } @@ -14385,10 +14247,10 @@ index f57e1b78204dff661ad5d3ee93a88a00330af2dc..967af8771ff8564c715d89f4b4b69b16 } diff --git a/src/main/java/net/minecraft/world/level/EntityGetter.java b/src/main/java/net/minecraft/world/level/EntityGetter.java -index ea0aee88c7d901034427db201c1b2430f8a1d522..1f28bfb435c1e4d97da713f96c452abab3fda91a 100644 +index 70c2017400168d4fef3c14462798edcfed58d4bf..3c84722c1075290b5301aa5122936d5e4dac3c43 100644 --- a/src/main/java/net/minecraft/world/level/EntityGetter.java +++ b/src/main/java/net/minecraft/world/level/EntityGetter.java -@@ -192,7 +192,7 @@ public interface EntityGetter { +@@ -153,7 +153,7 @@ public interface EntityGetter extends ca.spottedleaf.moonrise.patches.chunk_syst default boolean hasNearbyAlivePlayer(double x, double y, double z, double range) { for (Player player : this.players()) { @@ -14398,10 +14260,10 @@ index ea0aee88c7d901034427db201c1b2430f8a1d522..1f28bfb435c1e4d97da713f96c452aba if (range < 0.0 || 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 f717213f28eddf2908b6cc1bdb0f71644a16c93a..e5d53f7b16f37032bf75e9af276cdb098f343563 100644 +index 26d5440007db5c820405e4184ededb1ffabf2934..3e2d1f0429a44e1d87319454194be182dea88768 100644 --- a/src/main/java/net/minecraft/world/level/Explosion.java +++ b/src/main/java/net/minecraft/world/level/Explosion.java -@@ -98,7 +98,7 @@ public class Explosion { +@@ -99,7 +99,7 @@ public class Explosion { this.hitPlayers = Maps.newHashMap(); this.level = world; this.source = entity; @@ -14410,7 +14272,7 @@ index f717213f28eddf2908b6cc1bdb0f71644a16c93a..e5d53f7b16f37032bf75e9af276cdb09 this.x = x; this.y = y; this.z = z; -@@ -426,10 +426,29 @@ public class Explosion { +@@ -162,10 +162,29 @@ public class Explosion { public void explode() { // CraftBukkit start @@ -14431,7 +14293,7 @@ index f717213f28eddf2908b6cc1bdb0f71644a16c93a..e5d53f7b16f37032bf75e9af276cdb09 + Location location = new Location(this.level.getWorld(), this.x, this.y, this.z); + org.bukkit.block.Block block = location.getBlock(); + org.bukkit.block.BlockState blockState = (this.damageSource.getDirectBlockState() != null) ? this.damageSource.getDirectBlockState() : block.getState(); -+ if (!new org.purpurmc.purpur.event.PreBlockExplodeEvent(location.getBlock(), this.blockInteraction == Explosion.BlockInteraction.DESTROY_WITH_DECAY ? 1.0F / this.radius : 1.0F, blockState).callEvent()) { ++ if(!new org.purpurmc.purpur.event.PreBlockExplodeEvent(location.getBlock(), this.blockInteraction == Explosion.BlockInteraction.DESTROY_WITH_DECAY ? 1.0F / this.radius : 1.0F, blockState).callEvent()) { + this.wasCanceled = true; + return; + } @@ -14442,10 +14304,10 @@ index f717213f28eddf2908b6cc1bdb0f71644a16c93a..e5d53f7b16f37032bf75e9af276cdb09 Set set = Sets.newHashSet(); boolean flag = true; diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index c97b031c6beca995599642b26dcb888f4977ed5f..8be636ef55f8f2cb0ed1edad42156b742281b044 100644 +index 7de579a46300b94a4bf29f13e074cc365e384b99..e86c8972de653252ae14a8d483941bda69913884 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -176,6 +176,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -175,6 +175,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl // Gale end - Gale configuration public final com.destroystokyo.paper.antixray.ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray @@ -14453,9 +14315,9 @@ index c97b031c6beca995599642b26dcb888f4977ed5f..8be636ef55f8f2cb0ed1edad42156b74 public final co.aikar.timings.WorldTimingsHandler timings; // Paper public static BlockPos lastPhysicsProblem; // Spigot private org.spigotmc.TickLimiter entityLimiter; -@@ -186,6 +187,49 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - - public final io.papermc.paper.util.math.ThreadUnsafeRandom randomTickRandom = new io.papermc.paper.util.math.ThreadUnsafeRandom(this.random.nextLong()); // Gale - Pufferfish - move random tick random +@@ -183,6 +184,49 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl + public final Map explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions + public java.util.ArrayDeque redstoneUpdateInfos; // Paper - Faster redstone torch rapid clock removal; Move from Map in BlockRedstoneTorch to here + // Purpur start + private com.google.common.cache.Cache playerBreedingCooldowns; @@ -14503,7 +14365,7 @@ index c97b031c6beca995599642b26dcb888f4977ed5f..8be636ef55f8f2cb0ed1edad42156b74 public CraftWorld getWorld() { return this.world; } -@@ -225,6 +269,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -272,6 +316,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config this.galeConfig = galeWorldConfigCreator.apply(this.spigotConfig); // Gale - Gale configuration @@ -14512,7 +14374,7 @@ index c97b031c6beca995599642b26dcb888f4977ed5f..8be636ef55f8f2cb0ed1edad42156b74 this.generator = gen; this.world = new CraftWorld((ServerLevel) this, gen, biomeProvider, env); -@@ -1909,4 +1955,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1589,4 +1635,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl return null; } // Paper end - optimize redstone (Alternate Current) @@ -14527,7 +14389,7 @@ index c97b031c6beca995599642b26dcb888f4977ed5f..8be636ef55f8f2cb0ed1edad42156b74 + // 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 d0383cef6e204cc806903666d296287e1c530ed3..27fccd091535f7587aaaa1621361dc1835381b89 100644 +index 7e707fe1d800debf1eef8800fe98eb4e1dbd800b..d490429ddbb8cd82aeda5e03540075c9167b095e 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java @@ -251,7 +251,7 @@ public final class NaturalSpawner { @@ -14679,10 +14541,10 @@ index 8240c32d676a88aa23dcd052ee0136767e54fb0d..372c4ab9d390d5afd98947f21c79aae0 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 d195687595d021423478d8e339659b2c0ec9c7e0..14aaabb6b9595847358f65ff01c81b179d9548ea 100644 +index dbfee1647c564e833eb23a3b90ad0f1cb78edfb5..dcfe68a51067b35057ef14813f57e7d91a0f84b6 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -89,6 +89,10 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -88,6 +88,10 @@ public class Block extends BlockBehaviour implements ItemLike { public static final int UPDATE_LIMIT = 512; protected final StateDefinition stateDefinition; private BlockState defaultBlockState; @@ -14693,7 +14555,7 @@ index d195687595d021423478d8e339659b2c0ec9c7e0..14aaabb6b9595847358f65ff01c81b17 // Paper start public final boolean isDestroyable() { return io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits || -@@ -312,7 +316,7 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -311,7 +315,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) -> { @@ -14702,7 +14564,7 @@ index d195687595d021423478d8e339659b2c0ec9c7e0..14aaabb6b9595847358f65ff01c81b17 }); state.spawnAfterBreak((ServerLevel) world, pos, ItemStack.EMPTY, true); } -@@ -331,7 +335,7 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -330,7 +334,7 @@ public class Block extends BlockBehaviour implements ItemLike { event.setExpToDrop(block.getExpDrop(state, serverLevel, pos, net.minecraft.world.item.ItemStack.EMPTY, true)); // Paper - Properly handle xp dropping event.callEvent(); for (org.bukkit.inventory.ItemStack drop : event.getDrops()) { @@ -14711,7 +14573,7 @@ index d195687595d021423478d8e339659b2c0ec9c7e0..14aaabb6b9595847358f65ff01c81b17 } state.spawnAfterBreak(serverLevel, pos, ItemStack.EMPTY, false); // Paper - Properly handle xp dropping block.popExperience(serverLevel, pos, event.getExpToDrop()); // Paper - Properly handle xp dropping -@@ -348,13 +352,32 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -347,13 +351,32 @@ public class Block extends BlockBehaviour implements ItemLike { // Paper end - Properly handle xp dropping if (world instanceof ServerLevel) { Block.getDrops(state, (ServerLevel) world, pos, blockEntity, entity, tool).forEach((itemstack1) -> { @@ -14745,7 +14607,7 @@ index d195687595d021423478d8e339659b2c0ec9c7e0..14aaabb6b9595847358f65ff01c81b17 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); -@@ -438,7 +461,17 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -437,7 +460,17 @@ public class Block extends BlockBehaviour implements ItemLike { } // Paper - fix drops not preventing stats/food exhaustion } @@ -14764,7 +14626,7 @@ index d195687595d021423478d8e339659b2c0ec9c7e0..14aaabb6b9595847358f65ff01c81b17 public boolean isPossibleToRespawnInThis(BlockState state) { return !state.isSolid() && !state.liquid(); -@@ -457,7 +490,7 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -456,7 +489,7 @@ public class Block extends BlockBehaviour implements ItemLike { } public void fallOn(Level world, BlockState state, BlockPos pos, Entity entity, float fallDistance) { @@ -14774,10 +14636,10 @@ index d195687595d021423478d8e339659b2c0ec9c7e0..14aaabb6b9595847358f65ff01c81b17 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 260906f493416d98ab574a7262fce5e9b7e40c64..ce639e4a2d87202a10ef4fc73274c4b2c4e95720 100644 +index 223259e7a09ada681b6181c898f6857888594f85..7d58a95f7ae8983b466b275f4f82597d38762af0 100644 --- a/src/main/java/net/minecraft/world/level/block/Blocks.java +++ b/src/main/java/net/minecraft/world/level/block/Blocks.java -@@ -7389,6 +7389,7 @@ public class Blocks { +@@ -7361,6 +7361,7 @@ public class Blocks { BlockBehaviour.Properties.of() .mapColor(MapColor.PLANT) .forceSolidOff() @@ -14785,7 +14647,7 @@ index 260906f493416d98ab574a7262fce5e9b7e40c64..ce639e4a2d87202a10ef4fc73274c4b2 .instabreak() .sound(SoundType.AZALEA) .noOcclusion() -@@ -7401,6 +7402,7 @@ public class Blocks { +@@ -7373,6 +7374,7 @@ public class Blocks { BlockBehaviour.Properties.of() .mapColor(MapColor.PLANT) .forceSolidOff() @@ -14897,10 +14759,10 @@ index ff4dda48116a2969704b355ff96407ba869b466e..066181ed274a492762baebf05bf51ac7 + // Purpur end } diff --git a/src/main/java/net/minecraft/world/level/block/CampfireBlock.java b/src/main/java/net/minecraft/world/level/block/CampfireBlock.java -index d6fffb0953494e8667cc456137cac0f5deebfbb6..f7a2244b998aebe354d38eec7aa22fd94ce404c9 100644 +index 7f6058f4def83867971121751acd51c398583651..5a49daf7b6bf9e0ec3d50494287a620d41f8d85d 100644 --- a/src/main/java/net/minecraft/world/level/block/CampfireBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CampfireBlock.java -@@ -133,7 +133,7 @@ public class CampfireBlock extends BaseEntityBlock implements SimpleWaterloggedB +@@ -132,7 +132,7 @@ public class CampfireBlock extends BaseEntityBlock implements SimpleWaterloggedB BlockPos blockposition = ctx.getClickedPos(); boolean flag = world.getFluidState(blockposition).getType() == Fluids.WATER; @@ -14991,22 +14853,22 @@ index daae7fd6e0148cfba8e359d990748a0c83a3376e..0e06b1bcd906e92c083dc74d56d6d0a2 return random.nextFloat() < f1 ? this.getNext(state) : Optional.empty(); } diff --git a/src/main/java/net/minecraft/world/level/block/ChestBlock.java b/src/main/java/net/minecraft/world/level/block/ChestBlock.java -index 8fbfd18b3caeed769396b3ffb1b1778b2f38edc0..4cdfd2d181089e0e198d7f2690d1598b54d0ac4b 100644 +index 8fbfd18b3caeed769396b3ffb1b1778b2f38edc0..dbfe8f5d4df244cb694b73ea8763628c5f2507a3 100644 --- a/src/main/java/net/minecraft/world/level/block/ChestBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ChestBlock.java @@ -343,6 +343,7 @@ public class ChestBlock extends AbstractChestBlock implements } public static boolean isBlockedChestByBlock(BlockGetter world, BlockPos pos) { -+ if(world instanceof Level && ((Level) world).purpurConfig.chestOpenWithBlockOnTop) return false; // Purpur ++ if (world instanceof Level && ((Level) world).purpurConfig.chestOpenWithBlockOnTop) return false; // Purpur BlockPos blockposition1 = pos.above(); return world.getBlockState(blockposition1).isRedstoneConductor(world, blockposition1); 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 e467b96c028d0da3b1fe7c57fdf3220c63c1c6fa..9d07ed11c30bc3e7c68ecc1a8ccf5fe0af458f49 100644 +index d3d12f9114173f4971f95d7ef895a4374705bd3f..f34159f8d6c51af2341bf49db0d6d6f0417919cf 100644 --- a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java -@@ -239,18 +239,27 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { +@@ -237,18 +237,27 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { int i = (Integer) state.getValue(ComposterBlock.LEVEL); if (i < 8 && ComposterBlock.COMPOSTABLES.containsKey(stack.getItem())) { @@ -15045,7 +14907,7 @@ index e467b96c028d0da3b1fe7c57fdf3220c63c1c6fa..9d07ed11c30bc3e7c68ecc1a8ccf5fe0 return ItemInteractionResult.sidedSuccess(world.isClientSide); } else { -@@ -258,6 +267,25 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { +@@ -256,6 +265,25 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { } } @@ -15113,7 +14975,7 @@ index 112d2feba5f75a2a873b595617780515945c10e4..5a190834baef60c7b61074393f8856a9 + // 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 42d43b7a7e3b7c53cc80b8706c130e660f2c72da..96199441202ad929ad0274574704635c538a93c7 100644 +index 6dd75bc722f9c20b4869e6353115c3b02dd79f99..dfaf82f5b0180cf08c4125347867d37a2557fd24 100644 --- a/src/main/java/net/minecraft/world/level/block/DoorBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DoorBlock.java @@ -198,6 +198,7 @@ public class DoorBlock extends Block { @@ -15180,25 +15042,42 @@ index 151e856dda3aa262c846ce8793650ee582bfb749..be0ed8a14e5726d5fcea1864302b18fb + } + // Purpur end } +diff --git a/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java b/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java +index 11486419dd98a013c7387d3d73f322a95a18c574..b1444e8605282a05c3d030330b92213ad8341fda 100644 +--- a/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java ++++ b/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java +@@ -98,6 +98,13 @@ public class EndGatewayBlock extends BaseEntityBlock implements Portal { + TheEndGatewayBlockEntity tileentityendgateway = (TheEndGatewayBlockEntity) tileentity; + + if (!tileentityendgateway.isCoolingDown()) { ++ // Purpur start ++ if (world.purpurConfig.imposeTeleportRestrictionsOnGateways && (entity.isVehicle() || entity.isPassenger())) { ++ if (!new org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent(entity.getBukkitEntity(), entity.isPassenger() ? org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_PASSENGER : org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_VEHICLE, PlayerTeleportEvent.TeleportCause.END_GATEWAY).callEvent()) { ++ return; ++ } ++ } ++ // Purpur end + entity.setAsInsidePortal(this, pos); + TheEndGatewayBlockEntity.triggerCooldown(world, pos, state, tileentityendgateway); + } diff --git a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java -index 7272d70c672b54dcf595beafd7a2ed33c96e35cb..d7f33c676bba279661583d908d3a58c86d853545 100644 +index cff3e9869340f1ffb7093431cbe1ac5e67792a4e..dfe27fc9b2cbc824e8d2a5fd759409d939bd9c71 100644 --- a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java +++ b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java -@@ -54,6 +54,14 @@ public class EndPortalBlock extends BaseEntityBlock { +@@ -65,6 +65,13 @@ public class EndPortalBlock extends BaseEntityBlock implements Portal { protected 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 - Add EntityInsideBlockEvent - if (world instanceof ServerLevel && entity.canChangeDimensions() && Shapes.joinIsNotEmpty(Shapes.create(entity.getBoundingBox().move((double) (-pos.getX()), (double) (-pos.getY()), (double) (-pos.getZ()))), state.getShape(world, pos), BooleanOp.AND)) { + if (entity.canUsePortal(false) && Shapes.joinIsNotEmpty(Shapes.create(entity.getBoundingBox().move((double) (-pos.getX()), (double) (-pos.getY()), (double) (-pos.getZ()))), state.getShape(world, pos), BooleanOp.AND)) { + // Purpur start + if (entity.isPassenger() || entity.isVehicle()) { -+ if (new org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent(entity.getBukkitEntity(), entity.isPassenger() ? org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_PASSENGER : org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_VEHICLE, PlayerTeleportEvent.TeleportCause.END_PORTAL).callEvent()) { -+ this.entityInside(state, world, pos, entity); ++ if (!new org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent(entity.getBukkitEntity(), entity.isPassenger() ? org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_PASSENGER : org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_VEHICLE, PlayerTeleportEvent.TeleportCause.END_PORTAL).callEvent()) { ++ return; + } -+ return; + } + // Purpur end - ResourceKey resourcekey = world.getTypeKey() == LevelStem.END ? Level.OVERWORLD : Level.END; // CraftBukkit - SPIGOT-6152: send back to main overworld in custom ends - ServerLevel worldserver = ((ServerLevel) world).getServer().getLevel(resourcekey); - + // CraftBukkit start - Entity in portal + 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/EnderChestBlock.java b/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java index ca92d49ef2010ba00c623491671dcde8ebe697c1..bd65df4588584b8bb001e9dc3656a14e381a0b6d 100644 --- a/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java @@ -15371,13 +15250,13 @@ index ef364aa171a48482a45bc18cfe730ec20c3f7be6..74971d90506aa253d5ee821b5390fb25 } } 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 013302623d3ca3ff88f242d740af935dcf4844a6..13dd8bc7d2f6b71a5f1779dde53c5c84d83538ce 100644 +index ac775afb265430ac202cfa3900a036d11a308b1e..87ce003dfeca975d8e6af26fd341f3abe66dc185 100644 --- a/src/main/java/net/minecraft/world/level/block/IceBlock.java +++ b/src/main/java/net/minecraft/world/level/block/IceBlock.java @@ -41,7 +41,7 @@ public class IceBlock extends HalfTransparentBlock { public void afterDestroy(Level world, BlockPos pos, ItemStack tool) { // Paper end - Improve Block#breakNaturally API - if (EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) == 0) { + if (!EnchantmentHelper.hasTag(tool, EnchantmentTags.PREVENTS_ICE_MELTING)) { - if (world.dimensionType().ultraWarm()) { + if (world.isNether() || (world.isTheEnd() && !org.purpurmc.purpur.PurpurConfig.allowWaterPlacementInTheEnd)) { // Purpur world.removeBlock(pos, false); @@ -15440,23 +15319,23 @@ index 84623c632d8c2f0fa7ec939c711316d757117d23..1851035b9fdcc076442d0699567a3b02 } 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 77bbdc15472d656fd40e841a70e34d3d31580819..55ae530fac54236ea5614f8e92c30febc744f179 100644 +index 02d59789c09f58045fea302ea6f2ee3856114de3..8072713da7ed8b7a44b63c241050c3a9c16d7b27 100644 --- a/src/main/java/net/minecraft/world/level/block/MagmaBlock.java +++ b/src/main/java/net/minecraft/world/level/block/MagmaBlock.java -@@ -29,7 +29,7 @@ public class MagmaBlock extends Block { +@@ -28,7 +28,7 @@ public class MagmaBlock extends Block { @Override public void stepOn(Level world, BlockPos pos, BlockState state, Entity entity) { -- if (!entity.isSteppingCarefully() && entity instanceof LivingEntity && !EnchantmentHelper.hasFrostWalker((LivingEntity) entity)) { -+ if ((!entity.isSteppingCarefully() || world.purpurConfig.magmaBlockDamageWhenSneaking) && entity instanceof LivingEntity && (world.purpurConfig.magmaBlockDamageWithFrostWalker || !EnchantmentHelper.hasFrostWalker((LivingEntity) entity))) { // Purpur +- if (!entity.isSteppingCarefully() && entity instanceof LivingEntity) { ++ if ((!entity.isSteppingCarefully() || world.purpurConfig.magmaBlockDamageWhenSneaking) && entity instanceof LivingEntity) { // Purpur entity.hurt(world.damageSources().hotFloor().directBlock(world, pos), 1.0F); // CraftBukkit } diff --git a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java -index a9e3078cefcae8cc4672d514a7add162590d48df..8d5e841d8cc69bf09a9f1b6248633a72ce5fe1d7 100644 +index a530276b0123dee5680d7e09ad3d2f0414909c91..b3179c9537ba528379c2b0f6e166f850332e18c3 100644 --- a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java +++ b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java -@@ -60,7 +60,7 @@ public class NetherPortalBlock extends Block { +@@ -77,7 +77,7 @@ public class NetherPortalBlock extends Block implements Portal { @Override protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { @@ -15465,21 +15344,29 @@ index a9e3078cefcae8cc4672d514a7add162590d48df..8d5e841d8cc69bf09a9f1b6248633a72 while (world.getBlockState(pos).is((Block) this)) { pos = pos.below(); } -@@ -92,6 +92,14 @@ public class NetherPortalBlock extends Block { +@@ -109,6 +109,13 @@ public class NetherPortalBlock extends Block implements Portal { protected 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 - Add EntityInsideBlockEvent - if (entity.canChangeDimensions()) { + if (entity.canUsePortal(false)) { + // Purpur start + if (entity.isPassenger() || entity.isVehicle()) { -+ if (new org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent(entity.getBukkitEntity(), entity.isPassenger() ? org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_PASSENGER : org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_VEHICLE, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.NETHER_PORTAL).callEvent()) { -+ this.entityInside(state, world, pos, entity); ++ if (!new org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent(entity.getBukkitEntity(), entity.isPassenger() ? org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_PASSENGER : org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_VEHICLE, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.NETHER_PORTAL).callEvent()) { ++ return; + } -+ return; + } + // Purpur end // CraftBukkit start - Entity in portal EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ())); world.getCraftServer().getPluginManager().callEvent(event); +@@ -121,7 +128,7 @@ public class NetherPortalBlock extends Block implements Portal { + @Override + public int getPortalTransitionTime(ServerLevel world, Entity entity) { + if (entity instanceof Player entityhuman) { +- return Math.max(1, world.getGameRules().getInt(entityhuman.getAbilities().invulnerable ? GameRules.RULE_PLAYERS_NETHER_PORTAL_CREATIVE_DELAY : GameRules.RULE_PLAYERS_NETHER_PORTAL_DEFAULT_DELAY)); ++ return Math.max(1, entityhuman.canPortalInstant ? 1 : world.getGameRules().getInt(entityhuman.getAbilities().invulnerable ? GameRules.RULE_PLAYERS_NETHER_PORTAL_CREATIVE_DELAY : GameRules.RULE_PLAYERS_NETHER_PORTAL_DEFAULT_DELAY)); // Purpur + } else { + return 0; + } 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 acbd60a2f162fe0e254e36d0e8e7face3fc8a7b3..b8355ea1de26c4b6905f477fb4e110f1762447b4 100644 --- a/src/main/java/net/minecraft/world/level/block/NetherWartBlock.java @@ -15940,10 +15827,10 @@ index bbf59b2577812e74ffd45f694b83a42e043273c0..5cb06959aeaceeb98cfee34b1df804e6 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 360f96689b2b0015b56d3a9954b8454193a3316f..90b01d987d16d71f0d69a755f430ffc2170fba7d 100644 +index 730aca233f6e7564d4cb85b5b628d23c4f01d2f4..d12469a1bbd37026012bfd6bce30d7a2593779da 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 -@@ -215,6 +215,22 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit +@@ -213,6 +213,22 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit } } @@ -15966,7 +15853,7 @@ index 360f96689b2b0015b56d3a9954b8454193a3316f..90b01d987d16d71f0d69a755f430ffc2 // CraftBukkit start - add fields and methods private int maxStack = MAX_STACK; public List transaction = new java.util.ArrayList(); -@@ -337,6 +353,21 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit +@@ -335,6 +351,21 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit } ItemStack itemstack = (ItemStack) blockEntity.items.get(1); @@ -15985,10 +15872,10 @@ index 360f96689b2b0015b56d3a9954b8454193a3316f..90b01d987d16d71f0d69a755f430ffc2 + } + } + // Purpur end - boolean flag2 = !((ItemStack) blockEntity.items.get(0)).isEmpty(); + ItemStack itemstack1 = (ItemStack) blockEntity.items.get(0); + boolean flag2 = !itemstack1.isEmpty(); boolean flag3 = !itemstack.isEmpty(); - -@@ -422,6 +453,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit +@@ -421,6 +452,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit setChanged(world, pos, state); } @@ -16055,7 +15942,7 @@ index 6186e55014bbb9d5bedaa0e9d196879c55339d42..f4f11292d6d00f4a7c65e3e2a157bba5 @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 a6ffbbc1b5021564864e42c0756342352c2b8290..5ad48d2003fbd83e60f6faa68532496131935828 100644 +index 814e70f558d7a6186233da0ff86c94c95d390e09..df02a78855f1d0c32d1f744c20803fc97a8085c0 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 @@ -92,6 +92,16 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name @@ -16409,25 +16296,6 @@ index a28be7a332659be655f419d969e0c64e659b6c21..8cd812a25b1cc05ea14675658bf9c150 @Override public ClientboundBlockEntityDataPacket getUpdatePacket() { return ClientboundBlockEntityDataPacket.create(this); -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 3a3182544ca338e81edfa64fd116092775ca0c6c..0e58011d22536051a18388c2d45fd1a30c2f5ffd 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 -@@ -168,6 +168,14 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity { - public static void teleportEntity(Level world, BlockPos pos, BlockState state, Entity entity, TheEndGatewayBlockEntity blockEntity) { - if (world instanceof ServerLevel worldserver && !blockEntity.isCoolingDown()) { - if (entity.level().galeConfig().gameplayMechanics.fixes.checkCanChangeDimensionsBeforeUseEndGateway && world.galeConfig().gameplayMechanics.fixes.checkCanChangeDimensionsBeforeUseEndGateway && !entity.canChangeDimensions()) return; // Gale - Purpur - end gateway should check if entity can use portal -+ // Purpur start -+ if (world.purpurConfig.imposeTeleportRestrictionsOnGateways && (entity.isVehicle() || entity.isPassenger())) { -+ if (new org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent(entity.getBukkitEntity(), entity.isPassenger() ? org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_PASSENGER : org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_VEHICLE, PlayerTeleportEvent.TeleportCause.END_GATEWAY).callEvent()) { -+ teleportEntity(world, pos, state, entity, blockEntity); -+ } -+ return; -+ } -+ // Purpur end - blockEntity.teleportCooldown = 100; - BlockPos blockposition1; - diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonStructureResolver.java b/src/main/java/net/minecraft/world/level/block/piston/PistonStructureResolver.java index 205e223c356634bd6bc6bd58c6f0b7fda61a6f5f..bea05cb928d540a2f19b51bb7352d032b2dd69cd 100644 --- a/src/main/java/net/minecraft/world/level/block/piston/PistonStructureResolver.java @@ -16460,10 +16328,10 @@ index 205e223c356634bd6bc6bd58c6f0b7fda61a6f5f..bea05cb928d540a2f19b51bb7352d032 } 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 2034ca2edd3aff61d94416266e75402babd3e741..031fc626d2075cbe0941fecc188406712ab9953f 100644 +index a768b07dae4bf75b68e3bc1d3de4b68fc7d23842..155a099eb9b0196385947f5765fad4e5c5b74b44 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 -@@ -86,7 +86,7 @@ public abstract class BlockBehaviour implements FeatureElement { +@@ -85,7 +85,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}; public final boolean hasCollision; @@ -16472,7 +16340,7 @@ index 2034ca2edd3aff61d94416266e75402babd3e741..031fc626d2075cbe0941fecc18840671 protected final boolean isRandomlyTicking; protected final SoundType soundType; protected final float friction; -@@ -94,7 +94,7 @@ public abstract class BlockBehaviour implements FeatureElement { +@@ -93,7 +93,7 @@ public abstract class BlockBehaviour implements FeatureElement { protected final float jumpFactor; protected final boolean dynamicShape; protected final FeatureFlagSet requiredFeatures; @@ -16482,17 +16350,17 @@ index 2034ca2edd3aff61d94416266e75402babd3e741..031fc626d2075cbe0941fecc18840671 protected ResourceKey drops; diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java -index bee39dee1b96023c907407877aedf3aafaf5e1b8..5b6bc200381a486c99061f9f5b7121c2c355b477 100644 +index d4a505ef4af9ded02aeb1a817bcbe5b1a912a5b3..97a310f042db1a838a744d2909d261aaf253ea17 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java -@@ -107,6 +107,7 @@ public class EntityStorage implements EntityPersistentStorage { - ListTag listTag = new ListTag(); - final java.util.Map, Integer> savedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk - entities.forEach((entity) -> { // diff here: use entities parameter -+ if (!entity.canSaveToDisk()) return; // Purpur - // Paper start - Entity load/save limit per chunk - final EntityType entityType = entity.getType(); - final int saveLimit = level.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1); +@@ -105,6 +105,7 @@ public class EntityStorage implements EntityPersistentStorage { + } + // Paper end - Entity load/save limit per chunk + CompoundTag compoundTagx = new CompoundTag(); ++ if (!entity.canSaveToDisk()) return; // Purpur + if (entity.save(compoundTagx)) { + listTag.add(compoundTagx); + } 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 ae1e164285f5675371bf036c8a564d9f5c1dd395..976ac286b4a6b8a843d275583dacb4ca2b0c4cb2 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java @@ -16529,7 +16397,7 @@ index ae1e164285f5675371bf036c8a564d9f5c1dd395..976ac286b4a6b8a843d275583dacb4ca for (int l = 0; l < k; ++l) { // Paper start - PhantomPreSpawnEvent 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 761c7a4a12990043bd5f4a3b970d02acdb0843a8..9707422821747c0051e2444a2ddc67fd4c70ec08 100644 +index 0eac7bc0c56ac17c900737271a965cfc1ccd03d2..cd45bfb51294e3510792320e2a159f1c6d554ce1 100644 --- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java +++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java @@ -227,7 +227,7 @@ public abstract class FlowingFluid extends Fluid { @@ -16541,7 +16409,7 @@ index 761c7a4a12990043bd5f4a3b970d02acdb0843a8..9707422821747c0051e2444a2ddc67fd BlockState iblockdata2 = world.getBlockState(pos.below()); FluidState fluid1 = iblockdata2.getFluidState(); -@@ -336,6 +336,12 @@ public abstract class FlowingFluid extends Fluid { +@@ -325,6 +325,12 @@ public abstract class FlowingFluid extends Fluid { protected abstract boolean canConvertToSource(Level world); @@ -16622,10 +16490,10 @@ index d5004290e40a1ff5e0fcfe75f8da34ae15962359..f26383cf896785333dbd6f86348d5a5f } else if (blockState.is(Blocks.HONEY_BLOCK)) { return PathType.STICKY_HONEY; diff --git a/src/main/java/net/minecraft/world/level/portal/PortalShape.java b/src/main/java/net/minecraft/world/level/portal/PortalShape.java -index af24467ee37cfc06f692b3b02e68f6cfbaaa8d59..afe6b2170846273b41b694aa53dca4c31bf78b3f 100644 +index 57139a0b8adcd1ea25cd100be78402681856ee75..e8793e11e94eea41ea9be615f0d46c7add836919 100644 --- a/src/main/java/net/minecraft/world/level/portal/PortalShape.java +++ b/src/main/java/net/minecraft/world/level/portal/PortalShape.java -@@ -33,7 +33,7 @@ public class PortalShape { +@@ -32,7 +32,7 @@ public class PortalShape { private static final int MIN_HEIGHT = 3; public static final int MAX_HEIGHT = 21; private static final BlockBehaviour.StatePredicate FRAME = (iblockdata, iblockaccess, blockposition) -> { @@ -16635,10 +16503,10 @@ index af24467ee37cfc06f692b3b02e68f6cfbaaa8d59..afe6b2170846273b41b694aa53dca4c3 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 973f1d2c1db383eed5fccb7ccbad8f9a6b81d824..ac3341ea02985fdbafa405a4a3bc232439ff2e62 100644 +index 73e546cc828850365dae0131bf8d997f58473823..d6c704d8e933d689c3a946d7ef0e8396ac024841 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 -@@ -79,6 +79,7 @@ public class MapItemSavedData extends SavedData { +@@ -80,6 +80,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 @@ -16646,29 +16514,27 @@ index 973f1d2c1db383eed5fccb7ccbad8f9a6b81d824..ac3341ea02985fdbafa405a4a3bc2324 // 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 cfe953bc924f46b570e37395ac0f05ebcb82eb39..5500e7ada2dd783cc1317968a3e54696bdd73bf8 100644 ---- 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 -@@ -57,6 +57,13 @@ public class LootingEnchantFunction extends LootItemConditionalFunction { - - if (entity instanceof LivingEntity) { - int i = EnchantmentHelper.getMobLooting((LivingEntity) entity); -+ // Purpur start -+ if (org.purpurmc.purpur.PurpurConfig.fixProjectileLootingTransfer && -+ context.getParamOrNull(LootContextParams.DIRECT_KILLER_ENTITY) -+ instanceof net.minecraft.world.entity.projectile.AbstractArrow arrow) { -+ i = arrow.lootingLevel; +diff --git a/src/main/java/net/minecraft/world/level/storage/loot/functions/EnchantedCountIncreaseFunction.java b/src/main/java/net/minecraft/world/level/storage/loot/functions/EnchantedCountIncreaseFunction.java +index d86189bd446c7cd7215cfbcef72b2125a064e3d1..53608b9dbb81c58819b9ae6bc676ffb3ed01ce70 100644 +--- a/src/main/java/net/minecraft/world/level/storage/loot/functions/EnchantedCountIncreaseFunction.java ++++ b/src/main/java/net/minecraft/world/level/storage/loot/functions/EnchantedCountIncreaseFunction.java +@@ -66,6 +66,11 @@ public class EnchantedCountIncreaseFunction extends LootItemConditionalFunction + Entity entity = context.getParamOrNull(LootContextParams.ATTACKING_ENTITY); + if (entity instanceof LivingEntity livingEntity) { + int i = EnchantmentHelper.getEnchantmentLevel(this.enchantment, livingEntity); ++ // Purpur start - Add an option to fix MC-3304 projectile looting ++ if (org.purpurmc.purpur.PurpurConfig.fixProjectileLootingTransfer && context.getParamOrNull(LootContextParams.DIRECT_ATTACKING_ENTITY) instanceof net.minecraft.world.entity.projectile.AbstractArrow arrow) { ++ i = arrow.actualEnchantments.getLevel(this.enchantment); + } -+ // Purpur end - // CraftBukkit start - use lootingModifier if set by plugin - if (context.hasParam(LootContextParams.LOOTING_MOD)) { - i = context.getParamOrNull(LootContextParams.LOOTING_MOD); ++ // Purpur end - Add an option to fix MC-3304 projectile looting + if (i == 0) { + return stack; + } diff --git a/src/main/java/net/minecraft/world/phys/AABB.java b/src/main/java/net/minecraft/world/phys/AABB.java -index 92394960fc76886f393cba02ac33c57739a4b383..494808b7bc2fb296b78e229ce138a937b7ac2c59 100644 +index c8f7c43134e7c51ce8af5b3c1a28c11db67715a2..5b98889715bf62eb4f15c0b45ada2c701491d324 100644 --- a/src/main/java/net/minecraft/world/phys/AABB.java +++ b/src/main/java/net/minecraft/world/phys/AABB.java -@@ -502,4 +502,10 @@ public class AABB { +@@ -508,4 +508,10 @@ public class AABB { public static AABB ofSize(Vec3 center, double dx, double dy, double dz) { return new AABB(center.x - dx / 2.0, center.y - dy / 2.0, center.z - dz / 2.0, center.x + dx / 2.0, center.y + dy / 2.0, center.z + dz / 2.0); } @@ -16918,10 +16784,10 @@ index 9d93130f23addb18b97d7f5ec013faef17a74529..29d2fb87a65778926aea2cfc7a5b486c + // 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 4c3cf9b5643547ba04247882a7467161b8af501b..0523fef009b23eb801acfb6bcc45c02dfbef1833 100644 +index 25cccb9796004891df59c15970b3e1ba391d4073..d10c10907cefc06afff7e0f4c4cbbca352410c25 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -411,6 +411,20 @@ public final class CraftServer implements Server { +@@ -414,6 +414,20 @@ public final class CraftServer implements Server { this.paperPluginManager = new io.papermc.paper.plugin.manager.PaperPluginManagerImpl(this, this.commandMap, pluginManager); this.pluginManager.paperPluginManager = this.paperPluginManager; // Paper end @@ -16942,7 +16808,7 @@ index 4c3cf9b5643547ba04247882a7467161b8af501b..0523fef009b23eb801acfb6bcc45c02d CraftRegistry.setMinecraftRegistry(console.registryAccess()); -@@ -1061,6 +1075,7 @@ public final class CraftServer implements Server { +@@ -1064,6 +1078,7 @@ public final class CraftServer implements Server { org.spigotmc.SpigotConfig.init((File) this.console.options.valueOf("spigot-settings")); // Spigot this.console.paperConfigurations.reloadConfigs(this.console); this.console.galeConfigurations.reloadConfigs(this.console); // Gale - Gale configuration @@ -16950,7 +16816,7 @@ index 4c3cf9b5643547ba04247882a7467161b8af501b..0523fef009b23eb801acfb6bcc45c02d 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)) -@@ -1076,6 +1091,7 @@ public final class CraftServer implements Server { +@@ -1079,6 +1094,7 @@ public final class CraftServer implements Server { } } world.spigotConfig.init(); // Spigot @@ -16958,7 +16824,7 @@ index 4c3cf9b5643547ba04247882a7467161b8af501b..0523fef009b23eb801acfb6bcc45c02d } Plugin[] pluginClone = pluginManager.getPlugins().clone(); // Paper -@@ -1092,6 +1108,7 @@ public final class CraftServer implements Server { +@@ -1095,6 +1111,7 @@ public final class CraftServer implements Server { this.reloadData(); org.spigotmc.SpigotConfig.registerCommands(); // Spigot io.papermc.paper.command.PaperCommands.registerCommands(this.console); // Paper @@ -16966,7 +16832,7 @@ index 4c3cf9b5643547ba04247882a7467161b8af501b..0523fef009b23eb801acfb6bcc45c02d this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*"); this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions"); -@@ -1600,6 +1617,55 @@ public final class CraftServer implements Server { +@@ -1604,6 +1621,55 @@ public final class CraftServer implements Server { return true; } @@ -17022,7 +16888,7 @@ index 4c3cf9b5643547ba04247882a7467161b8af501b..0523fef009b23eb801acfb6bcc45c02d @Override public List getRecipesFor(ItemStack result) { Preconditions.checkArgument(result != null, "ItemStack cannot be null"); -@@ -3070,6 +3136,18 @@ public final class CraftServer implements Server { +@@ -2995,6 +3061,18 @@ public final class CraftServer implements Server { } // Gale end - Gale configuration - API @@ -17041,7 +16907,7 @@ index 4c3cf9b5643547ba04247882a7467161b8af501b..0523fef009b23eb801acfb6bcc45c02d @Override public void restart() { org.spigotmc.RestartCommand.restart(); -@@ -3352,4 +3430,15 @@ public final class CraftServer implements Server { +@@ -3277,4 +3355,15 @@ public final class CraftServer implements Server { } // Gale end - YAPFA - last tick time - API @@ -17058,10 +16924,10 @@ index 4c3cf9b5643547ba04247882a7467161b8af501b..0523fef009b23eb801acfb6bcc45c02d + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 93f9c6d3904ccebafa4d15718e040f651f38af4e..91043fb82cb07163a9bcd05069f9dc8b7b9bff94 100644 +index 8045d6c9398d1c88595da6e41aa1ed27fb6fbad0..0056843aabf3a46251eda8667ddb43da59c9d0ab 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -2449,6 +2449,48 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2338,6 +2338,48 @@ public class CraftWorld extends CraftRegionAccessor implements World { return (this.getHandle().getDragonFight() == null) ? null : new CraftDragonBattle(this.getHandle().getDragonFight()); } @@ -17111,7 +16977,7 @@ index 93f9c6d3904ccebafa4d15718e040f651f38af4e..91043fb82cb07163a9bcd05069f9dc8b public Collection getStructures(int x, int z) { return this.getStructures(x, z, struct -> true); diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index 8332f81a79f969252f506e3ac43c96a36db22684..9f873c07bec896b6c91b306efa51e0f07da1c6a8 100644 +index 51ae7262189a1b7d0170d7887361c3468bc2391c..bbe8cd960f9f1e65bc3304ca27befae420bb5677 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -197,6 +197,14 @@ public class Main { @@ -17129,7 +16995,7 @@ index 8332f81a79f969252f506e3ac43c96a36db22684..9f873c07bec896b6c91b306efa51e0f0 // Paper start acceptsAll(asList("server-name"), "Name of the server") .withRequiredArg() -@@ -316,7 +324,7 @@ public class Main { +@@ -286,7 +294,7 @@ public class Main { System.setProperty(net.minecrell.terminalconsole.TerminalConsoleAppender.JLINE_OVERRIDE_PROPERTY, "false"); // Paper } @@ -17283,13 +17149,14 @@ index d657fd2c507a5b215aeab0a5f3e9c2ee892a27c8..985e9ec21c60a1f47973bd5fc53b96a6 // 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 a2d336ceb52b63db5c03432ee7bc94dc6a742b82..0ed18542fd8e2a992dc56a5f421eaa840e0af193 100644 +index 2cde808bfa797256409879505ba205a71f381981..4b7d38a5ac6247c6e9d71ac7f3b65765ed3cf3ee 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -84,6 +84,21 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -86,6 +86,23 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { this.entityType = CraftEntityType.minecraftToBukkit(entity.getType()); } ++ // Purpur start - API for any mob to burn daylight + @Override + public boolean isImmuneToFire() { + return getHandle().fireImmune(); @@ -17304,22 +17171,20 @@ index a2d336ceb52b63db5c03432ee7bc94dc6a742b82..0ed18542fd8e2a992dc56a5f421eaa84 + public boolean isInDaylight() { + return getHandle().isSunBurnTick(); + } ++ // Purpur end - API for any mob to burn daylight + public static CraftEntity getEntity(CraftServer server, T entity) { Preconditions.checkArgument(entity != null, "Unknown entity"); -@@ -253,6 +268,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { - // Paper end - - if ((!ignorePassengers && this.entity.isVehicle()) || this.entity.isRemoved()) { // Paper - Teleport passenger API -+ // Purpur start -+ if (!entity.isRemoved() && new org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent(entity.getBukkitEntity(), org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_VEHICLE, cause).callEvent()) -+ return teleport(location, cause); -+ // Purpur end +@@ -245,6 +262,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { + boolean ignorePassengers = flagSet.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_PASSENGERS); + // Don't allow teleporting between worlds while keeping passengers + if (flagSet.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_PASSENGERS) && this.entity.isVehicle() && location.getWorld() != this.getWorld()) { ++ if (!new org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent(entity.getBukkitEntity(), org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_VEHICLE, cause).callEvent()) // Purpur return false; } -@@ -1280,4 +1299,27 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1297,4 +1315,27 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return this.getHandle().getScoreboardName(); } // Paper end - entity scoreboard name @@ -17438,10 +17303,10 @@ index 30d62ee4d5cd2ddacb8783b5bbbf475d592b3e02..5c1cda88080850314dac196dbe71ff12 + // 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 0196a49a5822e257b0e065e2383ec92b1bc27bba..3ed19f30f1cab9df3b1bfdf0b0caf7882a77c5f7 100644 +index a1e715629313346f670bce92483996122b0f1d7b..db9962ef89829bb14d84cc8495117ff4509c01cf 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -512,7 +512,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -513,7 +513,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; @@ -17450,28 +17315,22 @@ index 0196a49a5822e257b0e065e2383ec92b1bc27bba..3ed19f30f1cab9df3b1bfdf0b0caf788 } // Paper end -@@ -1180,4 +1180,22 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -1181,4 +1181,16 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { this.getHandle().setYBodyRot(bodyYaw); } // Paper end - body yaw API + -+ // Purpur start -+ @Override -+ public void broadcastItemBreak(org.bukkit.inventory.EquipmentSlot slot) { -+ if (slot == null) return; -+ getHandle().broadcastBreakEvent(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot)); -+ } -+ ++ // Purpur start - API for any mob to burn daylight + @Override + public boolean shouldBurnInDay() { -+ return getHandle().shouldBurnInDay(); ++ return this.getHandle().shouldBurnInDay(); + } + + @Override -+ public void setShouldBurnInDay(boolean shouldBurnInDay) { -+ getHandle().setShouldBurnInDay(shouldBurnInDay); ++ public void setShouldBurnInDay(final boolean shouldBurnInDay) { ++ this.getHandle().setShouldBurnInDay(shouldBurnInDay); + } -+ // Purpur end ++ // Purpur end - API for any mob to burn daylight } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java index 351f42842b780d053cd2e5bad9ae299449141b10..4860574e7fad7a9527dda599703c573c5b4b234b 100644 @@ -17495,10 +17354,10 @@ index 351f42842b780d053cd2e5bad9ae299449141b10..4860574e7fad7a9527dda599703c573c + // 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 32c3c2c6b2eaa90b149d9b425341e75b85bd9764..aac21ff5418f76b0d06b6a49a4021bde194cf1da 100644 +index 7eea190ce8a62960ecc42ff56a4ef71b754184fb..41863584c3a85068b807a5aeb93c3da70f133b47 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -574,10 +574,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -576,10 +576,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setPlayerListName(String name) { @@ -17515,18 +17374,15 @@ index 32c3c2c6b2eaa90b149d9b425341e75b85bd9764..aac21ff5418f76b0d06b6a49a4021bde if (this.getHandle().connection == null) return; // Paper - Updates are possible before the player has fully joined for (ServerPlayer player : (List) this.server.getHandle().players) { if (player.getBukkitEntity().canSee(this)) { -@@ -1439,6 +1444,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player { - } - - if (entity.isVehicle() && !ignorePassengers) { // Paper - Teleport API -+ // Purpur start -+ if (new org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent(entity.getBukkitEntity(), org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_VEHICLE, cause).callEvent()) -+ return teleport(location, cause); -+ // Purpur end +@@ -1431,6 +1436,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + // Paper start - Teleport passenger API + // Don't allow teleporting between worlds while keeping passengers + if (ignorePassengers && entity.isVehicle() && location.getWorld() != this.getWorld()) { ++ if (!new org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent(entity.getBukkitEntity(), org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_VEHICLE, cause).callEvent()) // Purpur start return false; } -@@ -2734,6 +2743,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2752,6 +2758,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return this.getHandle().getAbilities().walkingSpeed * 2f; } @@ -17555,9 +17411,9 @@ index 32c3c2c6b2eaa90b149d9b425341e75b85bd9764..aac21ff5418f76b0d06b6a49a4021bde private void validateSpeed(float value) { Preconditions.checkArgument(value <= 1f && value >= -1f, "Speed value (%s) need to be between -1f and 1f", value); } -@@ -3529,4 +3560,70 @@ public class CraftPlayer extends CraftHumanEntity implements Player { - public void setSendViewDistance(final int viewDistance) { - this.getHandle().setSendViewDistance(viewDistance); +@@ -3553,4 +3581,70 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + ((ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer)this.getHandle()) + .moonrise$getViewDistanceHolder().setSendViewDistance(viewDistance); } + + // Purpur start @@ -17665,7 +17521,7 @@ index 6c15d40979fd3e3d246a447c432b321fbf29ada3..6ace76a829c88e2e747dbbcce0a6582c + // 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 7a8ce6956db56061af93ba9761f5d1057a90bc49..6d286b23806666f7b00ac88c5922144649f8a041 100644 +index 7881c6253c1d652c0c0d54a9a8accdf0a1ff0f3e..da6ccb2a38df76770821a1a2203e54e722f541ca 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java @@ -99,4 +99,17 @@ public class CraftWither extends CraftMonster implements Wither, com.destroystok @@ -17708,10 +17564,10 @@ index 86574da257731de7646a712ed73384955fe35aa3..e223234dd64b0e41441c3b9f649f0b64 + // 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 dfbe0914ab2771ac632fd064719878ac47559e9f..5308dc55bcc334ad6bef927de6c2d9b9364d99ff 100644 +index bd6fee3e3ad9116802ff8bb57bfa741b881c4057..f6dfc393cc444a794dca891bf5a73c461d6ae4bc 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -592,6 +592,15 @@ public class CraftEventFactory { +@@ -593,6 +593,15 @@ public class CraftEventFactory { // Paper end craftServer.getPluginManager().callEvent(event); @@ -17727,7 +17583,7 @@ index dfbe0914ab2771ac632fd064719878ac47559e9f..5308dc55bcc334ad6bef927de6c2d9b9 return event; } -@@ -1123,7 +1132,7 @@ public class CraftEventFactory { +@@ -1124,7 +1133,7 @@ public class CraftEventFactory { return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), source.getDirectBlockState(), entity, DamageCause.LAVA, bukkitDamageSource, modifiers, modifierFunctions, cancelled); } else if (source.getDirectBlock() != null) { DamageCause cause; @@ -17736,7 +17592,7 @@ index dfbe0914ab2771ac632fd064719878ac47559e9f..5308dc55bcc334ad6bef927de6c2d9b9 cause = DamageCause.CONTACT; } else if (source.is(DamageTypes.HOT_FLOOR)) { cause = DamageCause.HOT_FLOOR; -@@ -1181,6 +1190,7 @@ public class CraftEventFactory { +@@ -1184,6 +1193,7 @@ public class CraftEventFactory { EntityDamageEvent event; if (damager != null) { event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), damagee.getBukkitEntity(), cause, bukkitDamageSource, modifiers, modifierFunctions, critical); @@ -17745,10 +17601,10 @@ index dfbe0914ab2771ac632fd064719878ac47559e9f..5308dc55bcc334ad6bef927de6c2d9b9 event = new EntityDamageEvent(damagee.getBukkitEntity(), cause, bukkitDamageSource, 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 977b77547f7ba62cef3640cf8d4f1c8e7cded53a..beae43e9b6fe447e7515d878ac175f461968768a 100644 +index 10a5b1853d3984427209c87bdec1d471dddb1244..5e693a93b9d968f1628f86e46a86161f82a5f4c3 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java -@@ -184,8 +184,19 @@ public class CraftContainer extends AbstractContainerMenu { +@@ -183,8 +183,19 @@ public class CraftContainer extends AbstractContainerMenu { case PLAYER: case CHEST: case ENDER_CHEST: @@ -17783,7 +17639,7 @@ index af1ae3dacb628da23f7d2988c6e76d3fb2d64103..4ee2d501f882279b48edb4b8bf082458 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 9ee14589d63bbfc0880f2eee5e924fe946ee0035..0a5841fa26698e60bdeadbb58b9343fe1ff08a28 100644 +index 9ee14589d63bbfc0880f2eee5e924fe946ee0035..062783f30f41761c34d7679844e443e9a55c6011 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java @@ -9,7 +9,7 @@ import org.bukkit.inventory.AnvilInventory; @@ -17791,7 +17647,7 @@ index 9ee14589d63bbfc0880f2eee5e924fe946ee0035..0a5841fa26698e60bdeadbb58b9343fe private final Location location; - private final AnvilMenu container; -+ public final AnvilMenu container; // Purpur - private -> public ++ public final AnvilMenu container; // Purpur - private -> public - Anvil API public CraftInventoryAnvil(Location location, Container inventory, Container resultInventory, AnvilMenu container) { super(inventory, resultInventory); @@ -17800,27 +17656,27 @@ index 9ee14589d63bbfc0880f2eee5e924fe946ee0035..0a5841fa26698e60bdeadbb58b9343fe this.container.maximumRepairCost = levels; } + -+ // Purpur start ++ // Purpur start - Anvil API + @Override + public boolean canBypassCost() { -+ return container.bypassCost; ++ return this.container.bypassCost; + } + + @Override + public void setBypassCost(boolean bypassCost) { -+ container.bypassCost = bypassCost; ++ this.container.bypassCost = bypassCost; + } + + @Override + public boolean canDoUnsafeEnchants() { -+ return container.canDoUnsafeEnchants; ++ return this.container.canDoUnsafeEnchants; + } + + @Override + public void setDoUnsafeEnchants(boolean canDoUnsafeEnchants) { -+ container.canDoUnsafeEnchants = canDoUnsafeEnchants; ++ this.container.canDoUnsafeEnchants = canDoUnsafeEnchants; + } -+ // Purpur end ++ // Purpur end - Anvil API } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java index c76c78bb7757d407102271463e14716a1b012deb..458b91582a22fb1e6deb1551c38d2a10e33e24f1 100644 @@ -17835,13 +17691,13 @@ index c76c78bb7757d407102271463e14716a1b012deb..458b91582a22fb1e6deb1551c38d2a10 } else if (bukkit == RecipeChoice.empty()) { stack = Ingredient.EMPTY; diff --git a/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java b/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java -index 9c004e7cb46841d874ab997bf2e3b63ae763aec7..36003e5c7c61d964f11e81fa56845a52a8785468 100644 +index d7c8f26b21276d9ff1d5c7c9738cc1126ce7d4b9..f0471f92044612e3a2fd12a575b8b1f844790d3a 100644 --- a/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java +++ b/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java -@@ -678,4 +678,32 @@ public class MaterialRerouting { - return itemStack.withType(material); +@@ -690,4 +690,32 @@ public class MaterialRerouting { + return ItemStack.of(material, amount); } - // Paper end - register paper API specific material consumers in rerouting + // Paper end + // Purpur start + // Method added post 1.13, no-op (https://github.com/PurpurMC/Purpur/pull/570) + public static void addFuel(Server server, Material material, int burnTime) { @@ -17909,10 +17765,10 @@ index 52649f82351ab4f675c3cc3cd6640956b0f76b91..eb51c88c7a0658190d3a8bfd5d18dca7 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..d3a8f712b48b66f8452332668819967cb268f984 +index 0000000000000000000000000000000000000000..71787e9efaa8a711f4c41849793f01f3087add1a --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java -@@ -0,0 +1,586 @@ +@@ -0,0 +1,576 @@ +package org.purpurmc.purpur; + +import com.google.common.base.Throwables; @@ -17920,7 +17776,9 @@ index 0000000000000000000000000000000000000000..d3a8f712b48b66f8452332668819967c +import com.mojang.datafixers.util.Pair; +import net.kyori.adventure.bossbar.BossBar; +import net.kyori.adventure.text.minimessage.MiniMessage; ++import net.minecraft.core.Registry; +import net.minecraft.core.registries.BuiltInRegistries; ++import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.effect.MobEffect; @@ -18146,11 +18004,6 @@ index 0000000000000000000000000000000000000000..d3a8f712b48b66f8452332668819967c + deathMessageOnlyBroadcastToAffectedPlayer = getBoolean("settings.broadcasts.death.only-broadcast-to-affected-player", deathMessageOnlyBroadcastToAffectedPlayer); + } + -+ public static String serverModName = "Purpur"; -+ private static void serverModName() { -+ serverModName = getString("settings.server-mod-name", serverModName); -+ } -+ + public static double laggingThreshold = 19.0D; + private static void tickLoopSettings() { + laggingThreshold = getDouble("settings.lagging-threshold", laggingThreshold); @@ -18287,7 +18140,7 @@ index 0000000000000000000000000000000000000000..d3a8f712b48b66f8452332668819967c + beeInsideBeeHive = getInt("settings.blocks.beehive.max-bees-inside", beeInsideBeeHive); + anvilCumulativeCost = getBoolean("settings.blocks.anvil.cumulative-cost", anvilCumulativeCost); + lightningRodRange = getInt("settings.blocks.lightning_rod.range", lightningRodRange); -+ ArrayList defaultCurses = new ArrayList<>() {{ ++ ArrayList defaultCurses = new ArrayList<>(){{ + add("minecraft:binding_curse"); + add("minecraft:vanishing_curse"); + }}; @@ -18295,7 +18148,9 @@ index 0000000000000000000000000000000000000000..d3a8f712b48b66f8452332668819967c + defaultCurses.clear(); + } + getList("settings.blocks.grindstone.ignored-enchants", defaultCurses).forEach(key -> { -+ Enchantment enchantment = BuiltInRegistries.ENCHANTMENT.get(new ResourceLocation(key.toString())); ++ Registry registry = MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.ENCHANTMENT); ++ Enchantment enchantment = registry.get(ResourceLocation.parse(key.toString())); ++ if (enchantment == null) return; + grindstoneIgnoredEnchants.add(enchantment); + }); + grindstoneRemoveAttributes = getBoolean("settings.blocks.grindstone.remove-attributes", grindstoneRemoveAttributes); @@ -18328,8 +18183,6 @@ index 0000000000000000000000000000000000000000..d3a8f712b48b66f8452332668819967c + soulSandBlockReverseBubbleColumnFlow = getBoolean("settings.blocks.soul-sand.reverse-bubble-column-flow", soulSandBlockReverseBubbleColumnFlow); + } + -+ public static boolean allowInfinityMending = false; -+ public static boolean allowCrossbowInfinity = true; + public static boolean allowShearsLooting = false; + public static boolean allowUnsafeEnchants = false; + public static boolean allowInapplicableEnchants = true; @@ -18339,11 +18192,6 @@ index 0000000000000000000000000000000000000000..d3a8f712b48b66f8452332668819967c + public static boolean replaceIncompatibleEnchants = false; + public static boolean clampEnchantLevels = true; + private static void enchantmentSettings() { -+ if (version < 5) { -+ boolean oldValue = getBoolean("settings.enchantment.allow-infinite-and-mending-together", false); -+ set("settings.enchantment.allow-infinity-and-mending-together", oldValue); -+ set("settings.enchantment.allow-infinite-and-mending-together", null); -+ } + if (version < 30) { + boolean oldValue = getBoolean("settings.enchantment.allow-unsafe-enchants", false); + set("settings.enchantment.anvil.allow-unsafe-enchants", oldValue); @@ -18352,8 +18200,6 @@ index 0000000000000000000000000000000000000000..d3a8f712b48b66f8452332668819967c + set("settings.enchantment.anvil.allow-higher-enchants-levels", true); + set("settings.enchantment.allow-unsafe-enchants", null); + } -+ 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); + allowUnsafeEnchants = getBoolean("settings.enchantment.anvil.allow-unsafe-enchants", allowUnsafeEnchants); + allowInapplicableEnchants = getBoolean("settings.enchantment.anvil.allow-inapplicable-enchants", allowInapplicableEnchants); @@ -18418,7 +18264,7 @@ index 0000000000000000000000000000000000000000..d3a8f712b48b66f8452332668819967c + + private static void blastResistanceSettings() { + getMap("settings.blast-resistance-overrides", Collections.emptyMap()).forEach((blockId, value) -> { -+ Block block = BuiltInRegistries.BLOCK.get(new ResourceLocation(blockId)); ++ Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.withDefaultNamespace(blockId)); + if (block == Blocks.AIR) { + log(Level.SEVERE, "Invalid block for `settings.blast-resistance-overrides`: " + blockId); + return; @@ -18450,7 +18296,7 @@ index 0000000000000000000000000000000000000000..d3a8f712b48b66f8452332668819967c + Map.entry("minecraft:purple_bed", Map.of("distance", 0.5F)), + Map.entry("minecraft:magenta_bed", Map.of("distance", 0.5F)) + )).forEach((blockId, value) -> { -+ Block block = BuiltInRegistries.BLOCK.get(new ResourceLocation(blockId)); ++ Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(blockId)); + if (block == Blocks.AIR) { + log(Level.SEVERE, "Invalid block for `settings.block-fall-multipliers`: " + blockId); + return; @@ -18501,10 +18347,10 @@ index 0000000000000000000000000000000000000000..d3a8f712b48b66f8452332668819967c +} 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..c7f19ef62554bf1ccbec0444305ccb233916602c +index 0000000000000000000000000000000000000000..015bab487cf8a1905285a7bf7fcc2b3512549a87 --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -@@ -0,0 +1,3315 @@ +@@ -0,0 +1,3302 @@ +package org.purpurmc.purpur; + +import net.minecraft.core.registries.BuiltInRegistries; @@ -18621,12 +18467,10 @@ index 0000000000000000000000000000000000000000..c7f19ef62554bf1ccbec0444305ccb23 + } + + public boolean useBetterMending = false; -+ public double mendingMultiplier = 1.0; + public boolean alwaysTameInCreative = false; + public boolean boatEjectPlayersOnLand = false; + public boolean boatsDoFallDamage = false; + public boolean disableDropsOnCrammingDeath = false; -+ public boolean entitiesCanUsePortals = true; + public boolean entitiesPickUpLootBypassMobGriefing = false; + public boolean fireballsBypassMobGriefing = false; + public boolean imposeTeleportRestrictionsOnGateways = false; @@ -18651,12 +18495,10 @@ index 0000000000000000000000000000000000000000..c7f19ef62554bf1ccbec0444305ccb23 + public boolean disableOxidationProximityPenalty = false; + private void miscGameplayMechanicsSettings() { + useBetterMending = getBoolean("gameplay-mechanics.use-better-mending", useBetterMending); -+ mendingMultiplier = getDouble("gameplay-mechanics.mending-multiplier", mendingMultiplier); + alwaysTameInCreative = getBoolean("gameplay-mechanics.always-tame-in-creative", alwaysTameInCreative); + boatEjectPlayersOnLand = getBoolean("gameplay-mechanics.boat.eject-players-on-land", boatEjectPlayersOnLand); + boatsDoFallDamage = getBoolean("gameplay-mechanics.boat.do-fall-damage", boatsDoFallDamage); + disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath); -+ entitiesCanUsePortals = getBoolean("gameplay-mechanics.entities-can-use-portals", entitiesCanUsePortals); + entitiesPickUpLootBypassMobGriefing = getBoolean("gameplay-mechanics.entities-pick-up-loot-bypass-mob-griefing", entitiesPickUpLootBypassMobGriefing); + fireballsBypassMobGriefing = getBoolean("gameplay-mechanics.fireballs-bypass-mob-griefing", fireballsBypassMobGriefing); + imposeTeleportRestrictionsOnGateways = getBoolean("gameplay-mechanics.impose-teleport-restrictions-on-gateways", imposeTeleportRestrictionsOnGateways); @@ -18705,14 +18547,12 @@ index 0000000000000000000000000000000000000000..c7f19ef62554bf1ccbec0444305ccb23 + + public int elytraDamagePerSecond = 1; + public double elytraDamageMultiplyBySpeed = 0; -+ public boolean elytraIgnoreUnbreaking = false; + public int elytraDamagePerFireworkBoost = 0; + public int elytraDamagePerTridentBoost = 0; + public boolean elytraKineticDamage = true; + private void elytraSettings() { + elytraDamagePerSecond = getInt("gameplay-mechanics.elytra.damage-per-second", elytraDamagePerSecond); + elytraDamageMultiplyBySpeed = getDouble("gameplay-mechanics.elytra.damage-multiplied-by-speed", elytraDamageMultiplyBySpeed); -+ elytraIgnoreUnbreaking = getBoolean("gameplay-mechanics.elytra.ignore-unbreaking", elytraIgnoreUnbreaking); + elytraDamagePerFireworkBoost = getInt("gameplay-mechanics.elytra.damage-per-boost.firework", elytraDamagePerFireworkBoost); + elytraDamagePerTridentBoost = getInt("gameplay-mechanics.elytra.damage-per-boost.trident", elytraDamagePerTridentBoost); + elytraKineticDamage = getBoolean("gameplay-mechanics.elytra.kinetic-damage", elytraKineticDamage); @@ -18727,22 +18567,16 @@ index 0000000000000000000000000000000000000000..c7f19ef62554bf1ccbec0444305ccb23 + entitySharedRandom = getBoolean("settings.entity.shared-random", entitySharedRandom); + } + ++ public boolean infinityWorksWithoutArrows = false; ++ private void infinityArrowsSettings() { ++ infinityWorksWithoutArrows = getBoolean("gameplay-mechanics.infinity-bow.works-without-arrows", infinityWorksWithoutArrows); ++ } ++ + public boolean explosionClampRadius = true; + private void explosionSettings() { + explosionClampRadius = getBoolean("gameplay-mechanics.clamp-explosion-radius", explosionClampRadius); + } + -+ public boolean infinityWorksWithoutArrows = false; -+ public boolean infinityWorksWithNormalArrows = true; -+ public boolean infinityWorksWithSpectralArrows = false; -+ public boolean infinityWorksWithTippedArrows = false; -+ private void infinityArrowsSettings() { -+ infinityWorksWithoutArrows = getBoolean("gameplay-mechanics.infinity-bow.works-without-arrows", infinityWorksWithoutArrows); -+ infinityWorksWithNormalArrows = getBoolean("gameplay-mechanics.infinity-bow.normal-arrows", infinityWorksWithNormalArrows); -+ infinityWorksWithSpectralArrows = getBoolean("gameplay-mechanics.infinity-bow.spectral-arrows", infinityWorksWithSpectralArrows); -+ infinityWorksWithTippedArrows = getBoolean("gameplay-mechanics.infinity-bow.tipped-arrows", infinityWorksWithTippedArrows); -+ } -+ + public List itemImmuneToCactus = new ArrayList<>(); + public List itemImmuneToExplosion = new ArrayList<>(); + public List itemImmuneToFire = new ArrayList<>(); @@ -18768,7 +18602,7 @@ index 0000000000000000000000000000000000000000..c7f19ef62554bf1ccbec0444305ccb23 + BuiltInRegistries.ITEM.stream().filter(item -> item != Items.AIR).forEach((item) -> itemImmuneToCactus.add(item)); + return; + } -+ Item item = BuiltInRegistries.ITEM.get(new ResourceLocation(key.toString())); ++ Item item = BuiltInRegistries.ITEM.get(ResourceLocation.parse(key.toString())); + if (item != Items.AIR) itemImmuneToCactus.add(item); + }); + itemImmuneToExplosion.clear(); @@ -18777,7 +18611,7 @@ index 0000000000000000000000000000000000000000..c7f19ef62554bf1ccbec0444305ccb23 + BuiltInRegistries.ITEM.stream().filter(item -> item != Items.AIR).forEach((item) -> itemImmuneToExplosion.add(item)); + return; + } -+ Item item = BuiltInRegistries.ITEM.get(new ResourceLocation(key.toString())); ++ Item item = BuiltInRegistries.ITEM.get(ResourceLocation.parse(key.toString())); + if (item != Items.AIR) itemImmuneToExplosion.add(item); + }); + itemImmuneToFire.clear(); @@ -18786,7 +18620,7 @@ index 0000000000000000000000000000000000000000..c7f19ef62554bf1ccbec0444305ccb23 + BuiltInRegistries.ITEM.stream().filter(item -> item != Items.AIR).forEach((item) -> itemImmuneToFire.add(item)); + return; + } -+ Item item = BuiltInRegistries.ITEM.get(new ResourceLocation(key.toString())); ++ Item item = BuiltInRegistries.ITEM.get(ResourceLocation.parse(key.toString())); + if (item != Items.AIR) itemImmuneToFire.add(item); + }); + itemImmuneToLightning.clear(); @@ -18795,7 +18629,7 @@ index 0000000000000000000000000000000000000000..c7f19ef62554bf1ccbec0444305ccb23 + BuiltInRegistries.ITEM.stream().filter(item -> item != Items.AIR).forEach((item) -> itemImmuneToLightning.add(item)); + return; + } -+ Item item = BuiltInRegistries.ITEM.get(new ResourceLocation(key.toString())); ++ Item item = BuiltInRegistries.ITEM.get(ResourceLocation.parse(key.toString())); + if (item != Items.AIR) itemImmuneToLightning.add(item); + }); + dontRunWithScissors = getBoolean("gameplay-mechanics.item.shears.damage-if-sprinting", dontRunWithScissors); @@ -18866,7 +18700,7 @@ index 0000000000000000000000000000000000000000..c7f19ef62554bf1ccbec0444305ccb23 + ConfigurationSection section = getConfigurationSection("gameplay-mechanics.minecart.controllable.block-speed"); + if (section != null) { + for (String key : section.getKeys(false)) { -+ Block block = BuiltInRegistries.BLOCK.get(new ResourceLocation(key)); ++ Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(key)); + if (block != Blocks.AIR) { + minecartControllableBlockSpeeds.put(block, section.getDouble(key, minecartControllableBaseSpeed)); + } @@ -19007,7 +18841,7 @@ index 0000000000000000000000000000000000000000..c7f19ef62554bf1ccbec0444305ccb23 + "minecraft:diamond_pickaxe", + "minecraft:netherite_pickaxe" + )).forEach(key -> { -+ Item item = BuiltInRegistries.ITEM.get(new ResourceLocation(key.toString())); ++ Item item = BuiltInRegistries.ITEM.get(ResourceLocation.parse(key.toString())); + if (item != Items.AIR) silkTouchTools.add(item); + }); + } @@ -19028,7 +18862,7 @@ index 0000000000000000000000000000000000000000..c7f19ef62554bf1ccbec0444305ccb23 + migrateProjectileDespawnRateSettings(EntityType.SMALL_FIREBALL); + migrateProjectileDespawnRateSettings(EntityType.SNOWBALL); + migrateProjectileDespawnRateSettings(EntityType.WITHER_SKULL); -+ //PufferfishConfig.save(); ++ //PufferfishConfig.save(); // TODO: Pufferfish + set("gameplay-mechanics.projectile-despawn-rates", null); + // pufferfish's entity_timeout is a global config + // we only want to migrate values from the @@ -19037,6 +18871,7 @@ index 0000000000000000000000000000000000000000..c7f19ef62554bf1ccbec0444305ccb23 + } + } + private void migrateProjectileDespawnRateSettings(EntityType type) { ++ // TODO: Pufferfish + //String pufferName = "entity_timeouts." + type.id.toUpperCase(Locale.ROOT); + //int value = getInt("gameplay-mechanics.projectile-despawn-rates." + type.id, -1); + //if (value != -1 && PufferfishConfig.getRawInt(pufferName, -1) == -1) { @@ -19176,17 +19011,17 @@ index 0000000000000000000000000000000000000000..c7f19ef62554bf1ccbec0444305ccb23 + Map.entry("minecraft:crimson_stem", Map.of("into", "minecraft:stripped_crimson_stem", "drops", new HashMap())), + Map.entry("minecraft:crimson_hyphae", Map.of("into", "minecraft:stripped_crimson_hyphae", "drops", new HashMap()))) + ).forEach((blockId, obj) -> { -+ Block block = BuiltInRegistries.BLOCK.get(new ResourceLocation(blockId)); ++ Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(blockId)); + if (block == Blocks.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid block for `tools.axe.strippables`: " + blockId); return; } + if (!(obj instanceof Map map)) { PurpurConfig.log(Level.SEVERE, "Invalid yaml for `tools.axe.strippables." + blockId + "`"); return; } + String intoId = (String) map.get("into"); -+ Block into = BuiltInRegistries.BLOCK.get(new ResourceLocation(intoId)); ++ Block into = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(intoId)); + if (into == Blocks.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid block for `tools.axe.strippables." + blockId + ".into`: " + intoId); return; } + Object dropsObj = map.get("drops"); + if (!(dropsObj instanceof Map dropsMap)) { PurpurConfig.log(Level.SEVERE, "Invalid yaml for `tools.axe.strippables." + blockId + ".drops`"); return; } + Map drops = new HashMap<>(); + dropsMap.forEach((itemId, chance) -> { -+ Item item = BuiltInRegistries.ITEM.get(new ResourceLocation(itemId.toString())); ++ Item item = BuiltInRegistries.ITEM.get(ResourceLocation.parse(itemId.toString())); + if (item == Items.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid item for `tools.axe.strippables." + blockId + ".drops`: " + itemId); return; } + drops.put(item, (double) chance); + }); @@ -19230,17 +19065,17 @@ index 0000000000000000000000000000000000000000..c7f19ef62554bf1ccbec0444305ccb23 + Map.entry("minecraft:waxed_weathered_copper_bulb", Map.of("into", "minecraft:weathered_copper_bulb", "drops", new HashMap())), + Map.entry("minecraft:waxed_oxidized_copper_bulb", Map.of("into", "minecraft:oxidized_copper_bulb", "drops", new HashMap()))) + ).forEach((blockId, obj) -> { -+ Block block = BuiltInRegistries.BLOCK.get(new ResourceLocation(blockId)); ++ Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(blockId)); + if (block == Blocks.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid block for `tools.axe.waxables`: " + blockId); return; } + if (!(obj instanceof Map map)) { PurpurConfig.log(Level.SEVERE, "Invalid yaml for `tools.axe.waxables." + blockId + "`"); return; } + String intoId = (String) map.get("into"); -+ Block into = BuiltInRegistries.BLOCK.get(new ResourceLocation(intoId)); ++ Block into = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(intoId)); + if (into == Blocks.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid block for `tools.axe.waxables." + blockId + ".into`: " + intoId); return; } + Object dropsObj = map.get("drops"); + if (!(dropsObj instanceof Map dropsMap)) { PurpurConfig.log(Level.SEVERE, "Invalid yaml for `tools.axe.waxables." + blockId + ".drops`"); return; } + Map drops = new HashMap<>(); + dropsMap.forEach((itemId, chance) -> { -+ Item item = BuiltInRegistries.ITEM.get(new ResourceLocation(itemId.toString())); ++ Item item = BuiltInRegistries.ITEM.get(ResourceLocation.parse(itemId.toString())); + if (item == Items.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid item for `tools.axe.waxables." + blockId + ".drops`: " + itemId); return; } + drops.put(item, (double) chance); + }); @@ -19275,17 +19110,17 @@ index 0000000000000000000000000000000000000000..c7f19ef62554bf1ccbec0444305ccb23 + Map.entry("minecraft:weathered_copper_bulb", Map.of("into", "minecraft:exposed_copper_bulb", "drops", new HashMap())), + Map.entry("minecraft:oxidized_copper_bulb", Map.of("into", "minecraft:weathered_copper_bulb", "drops", new HashMap()))) + ).forEach((blockId, obj) -> { -+ Block block = BuiltInRegistries.BLOCK.get(new ResourceLocation(blockId)); ++ Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(blockId)); + if (block == Blocks.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid block for `tools.axe.weatherables`: " + blockId); return; } + if (!(obj instanceof Map map)) { PurpurConfig.log(Level.SEVERE, "Invalid yaml for `tools.axe.weatherables." + blockId + "`"); return; } + String intoId = (String) map.get("into"); -+ Block into = BuiltInRegistries.BLOCK.get(new ResourceLocation(intoId)); ++ Block into = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(intoId)); + if (into == Blocks.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid block for `tools.axe.weatherables." + blockId + ".into`: " + intoId); return; } + Object dropsObj = map.get("drops"); + if (!(dropsObj instanceof Map dropsMap)) { PurpurConfig.log(Level.SEVERE, "Invalid yaml for `tools.axe.weatherables." + blockId + ".drops`"); return; } + Map drops = new HashMap<>(); + dropsMap.forEach((itemId, chance) -> { -+ Item item = BuiltInRegistries.ITEM.get(new ResourceLocation(itemId.toString())); ++ Item item = BuiltInRegistries.ITEM.get(ResourceLocation.parse(itemId.toString())); + if (item == Items.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid item for `tools.axe.weatherables." + blockId + ".drops`: " + itemId); return; } + drops.put(item, (double) chance); + }); @@ -19298,20 +19133,20 @@ index 0000000000000000000000000000000000000000..c7f19ef62554bf1ccbec0444305ccb23 + Map.entry("minecraft:coarse_dirt", Map.of("condition", "air_above", "into", "minecraft:dirt", "drops", new HashMap())), + Map.entry("minecraft:rooted_dirt", Map.of("condition", "always", "into", "minecraft:dirt", "drops", Map.of("minecraft:hanging_roots", 1.0D)))) + ).forEach((blockId, obj) -> { -+ Block block = BuiltInRegistries.BLOCK.get(new ResourceLocation(blockId)); ++ Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(blockId)); + if (block == Blocks.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid block for `tools.hoe.tillables`: " + blockId); return; } + if (!(obj instanceof Map map)) { PurpurConfig.log(Level.SEVERE, "Invalid yaml for `tools.hoe.tillables." + blockId + "`"); return; } + String conditionId = (String) map.get("condition"); + Tillable.Condition condition = Tillable.Condition.get(conditionId); + if (condition == null) { PurpurConfig.log(Level.SEVERE, "Invalid condition for `tools.hoe.tillables." + blockId + ".condition`: " + conditionId); return; } + String intoId = (String) map.get("into"); -+ Block into = BuiltInRegistries.BLOCK.get(new ResourceLocation(intoId)); ++ Block into = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(intoId)); + if (into == Blocks.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid block for `tools.hoe.tillables." + blockId + ".into`: " + intoId); return; } + Object dropsObj = map.get("drops"); + if (!(dropsObj instanceof Map dropsMap)) { PurpurConfig.log(Level.SEVERE, "Invalid yaml for `tools.hoe.tillables." + blockId + ".drops`"); return; } + Map drops = new HashMap<>(); + dropsMap.forEach((itemId, chance) -> { -+ Item item = BuiltInRegistries.ITEM.get(new ResourceLocation(itemId.toString())); ++ Item item = BuiltInRegistries.ITEM.get(ResourceLocation.parse(itemId.toString())); + if (item == Items.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid item for `tools.hoe.tillables." + blockId + ".drops`: " + itemId); return; } + drops.put(item, (double) chance); + }); @@ -19325,17 +19160,17 @@ index 0000000000000000000000000000000000000000..c7f19ef62554bf1ccbec0444305ccb23 + 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)); ++ Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(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)); ++ Block into = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(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())); ++ Item item = BuiltInRegistries.ITEM.get(ResourceLocation.parse(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); + }); @@ -19460,7 +19295,7 @@ index 0000000000000000000000000000000000000000..c7f19ef62554bf1ccbec0444305ccb23 + public List doorRequiresRedstone = new ArrayList<>(); + private void doorSettings() { + getList("blocks.door.requires-redstone", new ArrayList()).forEach(key -> { -+ Block block = BuiltInRegistries.BLOCK.get(new ResourceLocation(key.toString())); ++ Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(key.toString())); + if (!block.defaultBlockState().isAir()) { + doorRequiresRedstone.add(block); + } @@ -19570,10 +19405,8 @@ index 0000000000000000000000000000000000000000..c7f19ef62554bf1ccbec0444305ccb23 + } + + public boolean magmaBlockDamageWhenSneaking = false; -+ public boolean magmaBlockDamageWithFrostWalker = false; + private void magmaBlockSettings() { + magmaBlockDamageWhenSneaking = getBoolean("blocks.magma-block.damage-when-sneaking", magmaBlockDamageWhenSneaking); -+ magmaBlockDamageWithFrostWalker = getBoolean("blocks.magma-block.damage-with-frost-walker", magmaBlockDamageWithFrostWalker); + } + + public boolean powderSnowBypassMobGriefing = false; @@ -20867,7 +20700,7 @@ index 0000000000000000000000000000000000000000..c7f19ef62554bf1ccbec0444305ccb23 + } + polarBearMaxHealth = getDouble("mobs.polar_bear.attributes.max_health", polarBearMaxHealth); + polarBearBreedableItemString = getString("mobs.polar_bear.breedable-item", polarBearBreedableItemString); -+ Item item = BuiltInRegistries.ITEM.get(new ResourceLocation(polarBearBreedableItemString)); ++ Item item = BuiltInRegistries.ITEM.get(ResourceLocation.parse(polarBearBreedableItemString)); + if (item != Items.AIR) polarBearBreedableItem = item; + polarBearBreedingTicks = getInt("mobs.polar_bear.breeding-delay-ticks", polarBearBreedingTicks); + polarBearTakeDamageFromWater = getBoolean("mobs.polar_bear.takes-damage-from-water", polarBearTakeDamageFromWater); @@ -20953,7 +20786,7 @@ index 0000000000000000000000000000000000000000..c7f19ef62554bf1ccbec0444305ccb23 + add("minecraft:potatoes"); + add("minecraft:wheat"); + }}).forEach(key -> { -+ Block block = BuiltInRegistries.BLOCK.get(new ResourceLocation(key.toString())); ++ Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(key.toString())); + if (!block.defaultBlockState().isAir()) { + ravagerGriefableBlocks.add(block); + } @@ -21794,7 +21627,7 @@ index 0000000000000000000000000000000000000000..c7f19ef62554bf1ccbec0444305ccb23 + add("minecraft:sea_lantern"); + add("minecraft:dark_prismarine"); + }}).forEach(key -> { -+ Block block = BuiltInRegistries.BLOCK.get(new ResourceLocation(key.toString())); ++ Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(key.toString())); + if (!block.defaultBlockState().isAir()) { + conduitBlockList.add(block); + } @@ -22864,10 +22697,10 @@ index 0000000000000000000000000000000000000000..75e31aee6e706f042398444f272888f9 +} 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..9464bca8af6e8e34a5f13aae6ad14051ee325424 +index 0000000000000000000000000000000000000000..7608bf0981fa0d37031e51e57e4086cb5ec4c88b --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/entity/PurpurStoredBee.java -@@ -0,0 +1,105 @@ +@@ -0,0 +1,106 @@ +package org.purpurmc.purpur.entity; + +import io.papermc.paper.adventure.PaperAdventure; @@ -22875,6 +22708,7 @@ index 0000000000000000000000000000000000000000..9464bca8af6e8e34a5f13aae6ad14051 +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; +import net.minecraft.server.MinecraftServer; ++import net.minecraft.world.item.component.CustomData; +import net.minecraft.world.level.block.entity.BeehiveBlockEntity; +import org.bukkit.block.EntityBlockStorage; +import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer; @@ -22905,7 +22739,7 @@ index 0000000000000000000000000000000000000000..9464bca8af6e8e34a5f13aae6ad14051 + ? PaperAdventure.asAdventure(net.minecraft.network.chat.Component.Serializer.fromJson(customData.getString("CustomName"), MinecraftServer.getDefaultRegistryAccess())) + : null; + -+ if (customData.contains("BukkitValues", Tag.TAG_COMPOUND)) { ++ if(customData.contains("BukkitValues", Tag.TAG_COMPOUND)) { + this.persistentDataContainer.putAll(customData.getCompound("BukkitValues")); + } + } @@ -23329,7 +23163,7 @@ index 0000000000000000000000000000000000000000..7f526883495b3222746de3d0442e9e4f +} diff --git a/src/main/java/org/purpurmc/purpur/item/SpawnerItem.java b/src/main/java/org/purpurmc/purpur/item/SpawnerItem.java new file mode 100644 -index 0000000000000000000000000000000000000000..94104908f46df09b1c4f75296ff5b8e7735e8435 +index 0000000000000000000000000000000000000000..ed50cb2115401c9039df4136caf5a087a5f5991c --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/item/SpawnerItem.java @@ -0,0 +1,40 @@ @@ -23366,7 +23200,7 @@ index 0000000000000000000000000000000000000000..94104908f46df09b1c4f75296ff5b8e7 + EntityType.byString(customData.getString("Purpur.mob_type")).ifPresent(type -> spawner.getSpawner().setEntityId(type, level, level.random, pos)); + } else if (customData.contains("Purpur.SpawnData")) { + net.minecraft.world.level.SpawnData.CODEC.parse(net.minecraft.nbt.NbtOps.INSTANCE, customData.getCompound("Purpur.SpawnData")).result() -+ .ifPresent(spawnData -> spawner.getSpawner().nextSpawnData = spawnData); ++ .ifPresent(spawnData -> spawner.getSpawner().nextSpawnData = spawnData); + } + } + } @@ -23375,7 +23209,7 @@ index 0000000000000000000000000000000000000000..94104908f46df09b1c4f75296ff5b8e7 +} diff --git a/src/main/java/org/purpurmc/purpur/network/ClientboundBeehivePayload.java b/src/main/java/org/purpurmc/purpur/network/ClientboundBeehivePayload.java new file mode 100644 -index 0000000000000000000000000000000000000000..57e195fd2d457295cda6c366684be5577aeef071 +index 0000000000000000000000000000000000000000..793a3ea45fe04e84725926f17615c26e008b0ce4 --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/network/ClientboundBeehivePayload.java @@ -0,0 +1,27 @@ @@ -23390,7 +23224,7 @@ index 0000000000000000000000000000000000000000..57e195fd2d457295cda6c366684be557 + +public record ClientboundBeehivePayload(BlockPos pos, int numOfBees) implements CustomPacketPayload { + public static final StreamCodec STREAM_CODEC = CustomPacketPayload.codec(ClientboundBeehivePayload::write, ClientboundBeehivePayload::new); -+ public static final Type TYPE = new Type<>(new ResourceLocation("purpur", "beehive_s2c")); ++ public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath("purpur", "beehive_s2c")); + + public ClientboundBeehivePayload(FriendlyByteBuf friendlyByteBuf) { + this(friendlyByteBuf.readBlockPos(), friendlyByteBuf.readInt()); @@ -23408,7 +23242,7 @@ index 0000000000000000000000000000000000000000..57e195fd2d457295cda6c366684be557 +} diff --git a/src/main/java/org/purpurmc/purpur/network/ServerboundBeehivePayload.java b/src/main/java/org/purpurmc/purpur/network/ServerboundBeehivePayload.java new file mode 100644 -index 0000000000000000000000000000000000000000..27689754565bf048d1206d540913495d7194a54d +index 0000000000000000000000000000000000000000..fa72769e06061609e1e658a0250e99c8cb026c0e --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/network/ServerboundBeehivePayload.java @@ -0,0 +1,26 @@ @@ -23423,7 +23257,7 @@ index 0000000000000000000000000000000000000000..27689754565bf048d1206d540913495d + +public record ServerboundBeehivePayload(BlockPos pos) implements CustomPacketPayload { + public static final StreamCodec STREAM_CODEC = CustomPacketPayload.codec(ServerboundBeehivePayload::write, ServerboundBeehivePayload::new); -+ public static final Type TYPE = new Type<>(new ResourceLocation("purpur", "beehive_c2s")); ++ public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath("purpur", "beehive_c2s")); + + public ServerboundBeehivePayload(FriendlyByteBuf friendlyByteBuf) { + this(friendlyByteBuf.readBlockPos()); @@ -24142,18 +23976,19 @@ index 0000000000000000000000000000000000000000..b7586f494528f30eb0da82420d3bcf5b + } +} diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index df50c32482067368b11d2928bd353f4fbe595afe..638bed116e4c36974b6096524f3f878a1ecb89c5 100644 +index 4956e37d0cfeb73135966e76723bb4a0da219704..bfd1999476debbd9798d51b2931dfa7e770a6e1f 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java -@@ -219,6 +219,7 @@ public class ActivationRange +@@ -215,6 +215,8 @@ public class ActivationRange continue; } + if (!player.level().purpurConfig.idleTimeoutTickNearbyEntities && player.isAfk()) continue; // Purpur ++ // Paper start int worldHeight = world.getHeight(); ActivationRange.maxBB = player.getBoundingBox().inflate( maxRange, worldHeight, maxRange ); -@@ -416,6 +417,7 @@ public class ActivationRange +@@ -412,6 +414,7 @@ public class ActivationRange */ public static boolean checkIfActive(Entity entity) { @@ -24184,18 +24019,18 @@ index d2a75850af9c6ad2aca66a5f994f1b587d73eac4..a056aa167887abef9e6d531a9edd2cda diff --git a/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java b/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java -index 2f3ff50bf3f70b6b404d02d5ffcc079162a63bc1..4e57fdf21d4b7789cd7c3d3a18ddc6227bc77792 100644 +index ca71c688b37ce2c8b712a4f9216cf872c8edf78e..83f2c04d083eced64bc67661eed0ddfdddc497cc 100644 --- a/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java +++ b/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java -@@ -48,6 +48,7 @@ public class MinecraftCommandPermissionsTest extends AbstractTestingBase { - if ("bukkit.command.paper.pgive".equals(vanillaPerm)) { // skip our custom give command - continue; - } +@@ -45,6 +45,7 @@ public class MinecraftCommandPermissionsTest extends AbstractTestingBase { + Set foundPerms = new HashSet<>(); + for (CommandNode child : root.getChildren()) { + final String vanillaPerm = VanillaCommandWrapper.getPermission(child); + if (TO_SKIP.contains(vanillaPerm)) continue; // Purpur if (!perms.contains(vanillaPerm)) { missing.add("Missing permission for " + child.getName() + " (" + vanillaPerm + ") command"); } else { -@@ -60,6 +61,25 @@ public class MinecraftCommandPermissionsTest extends AbstractTestingBase { +@@ -57,6 +58,25 @@ public class MinecraftCommandPermissionsTest extends AbstractTestingBase { } private static final List TO_SKIP = List.of( diff --git a/patches/server/0012-Fix-Pufferfish-and-Purpur-patches.patch b/patches/server/0011-Fix-Pufferfish-and-Purpur-patches.patch similarity index 80% rename from patches/server/0012-Fix-Pufferfish-and-Purpur-patches.patch rename to patches/server/0011-Fix-Pufferfish-and-Purpur-patches.patch index 0a2c66d0..e21211fd 100644 --- a/patches/server/0012-Fix-Pufferfish-and-Purpur-patches.patch +++ b/patches/server/0011-Fix-Pufferfish-and-Purpur-patches.patch @@ -27,10 +27,10 @@ index e94224ed280247ee69dfdff8dc960f2b8729be33..5b9725a9a81c0850dc2809c150529e5f for (Component component : formatProviders(spigotPlugins, sender)) { // Purpur diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 7bba8f957d7b4cbe80000bdd39793ce600201496..1f166b48af314ee85239ae39358a47fb0e6d423c 100644 +index b5fd90764d954acd0381cf42c38d5015c200b886..6a652ed876128addfef881903272fc9a891b13b6 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -293,7 +293,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); -@@ -974,6 +974,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { // Paper - rewrite chunk system +@@ -982,6 +984,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop= (f - 0.4F) * 2.0F) return false; -+ // Gale end - JettPack - optimize sun burn tick - optimizations and cache eye blockpos ++ // Gale end - JettPack - optimize sun burn tick - optimizations and cache eye blockpos - copied from Mob#isSunBurnTick 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 (!flag && this.level().canSeeSky(this.cached_eye_blockpos)) { // Gale - JettPack - optimize sun burn tick - optimizations and cache eye blockpos ++ if (!flag && this.level().canSeeSky(this.cached_eye_blockpos)) { // Gale - JettPack - optimize sun burn tick - optimizations and cache eye blockpos - copied from Mob#isSunBurnTick return true; } } -@@ -890,7 +906,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -853,7 +869,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public void tick() { // Pufferfish start - entity TTL if (type != EntityType.PLAYER && type.ttl >= 0 && this.tickCount >= type.ttl) { @@ -158,10 +158,10 @@ index 2afa65c3c8ee8e502fa473bf0b485a02b32989f7..0fafe65e9f0ee85469d80a1033078b20 } // Pufferfish end - entity TTL diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 1b092cdccba089684301266a90fe715a55a6f4f8..fa773a29ec77f277546e418aab9b06ccd9567a8f 100644 +index a0609bce7035188b48a0f84ebf79ebc5682c94d8..a9c2e9d9b3bb63e8cbbe66994c960aca7303066b 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1068,17 +1068,19 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1043,17 +1043,19 @@ public abstract class LivingEntity extends Entity implements Attackable { if (entity != null) { EntityType entitytypes = entity.getType(); @@ -186,10 +186,10 @@ index 1b092cdccba089684301266a90fe715a55a6f4f8..fa773a29ec77f277546e418aab9b06cc // Purpur start if (entity instanceof LivingEntity entityliving) { diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 42ba2c7b037aaea4ae16dec8bc1413a15fbb8317..2e030baabb57de26dcc7340430f0ae0a3a5c1f9f 100644 +index 2b4e65eee6fd2ce620238beca649a7f39ca3b2f1..4e5dbee1f43b4114a07adab3c3ddc2b9be53ca9c 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -746,7 +746,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti +@@ -707,7 +707,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab @Override public void aiStep() { super.aiStep(); @@ -198,9 +198,9 @@ index 42ba2c7b037aaea4ae16dec8bc1413a15fbb8317..2e030baabb57de26dcc7340430f0ae0a Vec3i baseblockposition = this.getPickupReach(); List list = this.level().getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate((double) baseblockposition.getX(), (double) baseblockposition.getY(), (double) baseblockposition.getZ())); Iterator iterator = list.iterator(); -@@ -1859,11 +1859,6 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti - return flag; - } +@@ -1760,11 +1760,6 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab + + protected void playAttackSound() {} - // Gale start - JettPack - optimize sun burn tick - cache eye blockpos - private BlockPos cached_eye_blockpos; @@ -208,50 +208,50 @@ index 42ba2c7b037aaea4ae16dec8bc1413a15fbb8317..2e030baabb57de26dcc7340430f0ae0a - // Gale end - JettPack - optimize sun burn tick - cache eye blockpos - public boolean isSunBurnTick() { + // Purpur - implemented in Entity - API for any mob to burn daylight return super.isSunBurnTick(); - } diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java b/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java -index 7db823e9edd70808c5629f0a7efd84fe40f42dd9..833858eacaf5ba788cb9f08a939379f0ff04b2cb 100644 +index b1544e028d5a9b84b944e1fb5a12bb163067fb54..5bbbfc414762c4c3b867bba099f06c76131f6984 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java -@@ -20,6 +20,7 @@ import org.jetbrains.annotations.Nullable; - public class TradeWithVillager extends Behavior { - // Gale start - optimize villager data storage - private static final Item[] WHEAT_SINGLETON_ARRAY = {Items.WHEAT}; -+ private static final Item[] NETHER_WART_SINGLETON_ARRAY = {Items.NETHER_WART}; // Leaf - sync with Gale's Optimize-villager-data-storage.patch - private @NotNull Item @Nullable [] trades = null; - // Gale end - optimize villager data storage +@@ -18,6 +18,7 @@ import net.minecraft.world.item.Items; -@@ -65,7 +66,7 @@ public class TradeWithVillager extends Behavior { + public class TradeWithVillager extends Behavior { + private Set trades = ImmutableSet.of(); ++ //private static final Item[] NETHER_WART_SINGLETON_ARRAY = {Items.NETHER_WART}; // Leaf - sync with Gale's Optimize-villager-data-storage.patch // TODO + + public TradeWithVillager() { + super( +@@ -61,7 +62,8 @@ public class TradeWithVillager extends Behavior { // Purpur start if (world.purpurConfig.villagerClericsFarmWarts && world.purpurConfig.villagerClericFarmersThrowWarts && entity.getVillagerData().getProfession() == VillagerProfession.CLERIC && entity.getInventory().countItem(Items.NETHER_WART) > Items.NETHER_WART.getDefaultMaxStackSize() / 2) { - throwHalfStack(entity, ImmutableSet.of(Items.NETHER_WART), villager); -+ throwHalfStack(entity, NETHER_WART_SINGLETON_ARRAY, villager); // Leaf - sync with Gale's Optimize-villager-data-storage.patch ++ throwHalfStack(entity, ImmutableSet.of(Items.NETHER_WART), villager); // TODO ++ //throwHalfStack(entity, NETHER_WART_SINGLETON_ARRAY, villager); // Leaf - sync with Gale's Optimize-villager-data-storage.patch // TODO } // Purpur end diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java -index 9419f230910d0338fc4ac6e2e7b749ee7d5ee362..2fe25397526c77c3b6b5e96d71d3681c6e26a54e 100644 +index d548d1b2686667d809f363cd0ae4444bc3918bf2..c3519eb6b28d180c9a5bf673037f1c4324ba5685 100644 --- a/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java +++ b/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java -@@ -24,19 +24,15 @@ public class SecondaryPoiSensor extends Sensor { +@@ -22,19 +22,15 @@ public class SecondaryPoiSensor extends Sensor { @Override protected void doTick(ServerLevel world, Villager entity) { -- // Gale start - Lithium - skip secondary POI sensor if absent -- var secondaryPoi = entity.getVillagerData().getProfession().secondaryPoi(); -- if (secondaryPoi == null) { // Gale - optimize villager data storage ++ // Purpur start - make sure clerics don't wander to soul sand when the option is off + // Gale start - Lithium - skip secondary POI sensor if absent + var secondaryPoi = entity.getVillagerData().getProfession().secondaryPoi(); +- if (secondaryPoi.isEmpty()) { - entity.getBrain().eraseMemory(MemoryModuleType.SECONDARY_JOB_SITE); - return; - } - // Gale end - Lithium - skip secondary POI sensor if absent - // Purpur start - make sure clerics don't wander to soul sand when the option is off +- // Purpur start - make sure clerics don't wander to soul sand when the option is off Brain brain = entity.getBrain(); - if (!world.purpurConfig.villagerClericsFarmWarts && entity.getVillagerData().getProfession() == net.minecraft.world.entity.npc.VillagerProfession.CLERIC) { -+ // Gale start - Lithium - skip secondary POI sensor if absent -+ var secondaryPoi = entity.getVillagerData().getProfession().secondaryPoi(); -+ if (secondaryPoi == null || (!world.purpurConfig.villagerClericsFarmWarts && entity.getVillagerData().getProfession() == net.minecraft.world.entity.npc.VillagerProfession.CLERIC)) { // Gale - optimize villager data storage ++ if (secondaryPoi.isEmpty() || (!world.purpurConfig.villagerClericsFarmWarts && entity.getVillagerData().getProfession() == net.minecraft.world.entity.npc.VillagerProfession.CLERIC)) { brain.eraseMemory(MemoryModuleType.SECONDARY_JOB_SITE); return; } @@ -260,10 +260,10 @@ index 9419f230910d0338fc4ac6e2e7b749ee7d5ee362..2fe25397526c77c3b6b5e96d71d3681c ResourceKey resourceKey = world.dimension(); BlockPos blockPos = entity.blockPosition(); 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 92521cbedcf89a855f10a3401933acaf84bc3f98..0bd72f76a65b6248f4e700877b2bda702f9590df 100644 +index ad1ec2578fa428baa6b172c44b6c17e52daa5792..e2ac7e911eb2f46479a9666135894acad0649103 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -@@ -680,7 +680,7 @@ public class ArmorStand extends LivingEntity { +@@ -687,7 +687,7 @@ public class ArmorStand extends LivingEntity { @Override public void tick() { @@ -273,7 +273,7 @@ index 92521cbedcf89a855f10a3401933acaf84bc3f98..0bd72f76a65b6248f4e700877b2bda70 if (!this.canTick) { if (this.noTickPoseDirty) { 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 27db17e19dd95e99f7bd67747eba3c3072b48ed5..4c87fa47a97a75a270a0f1332ee6aea69f9cf9c5 100644 +index 1e1824eb80696452951cdbbdacad952ae0a7482b..b38110d4f01cae6746ccd38b5ae047cff8763d65 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Blaze.java +++ b/src/main/java/net/minecraft/world/entity/monster/Blaze.java @@ -72,7 +72,6 @@ public class Blaze extends Monster { @@ -293,7 +293,7 @@ index 27db17e19dd95e99f7bd67747eba3c3072b48ed5..4c87fa47a97a75a270a0f1332ee6aea6 @Override protected void registerGoals() { 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 8f36f113e8eb3236ce53ad9cce320c3d6253d248..ebe79d9ad2934b53085c8a720fdfca0a6eda05ca 100644 +index 3ca83269311cbc18c9ef3ce62cff6a2d4dc0a683..a636ab87d21c67b152b40b77e62fa8043ca4211e 100644 --- a/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java +++ b/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java @@ -31,7 +31,7 @@ public record VillagerProfession( @@ -306,10 +306,10 @@ index 8f36f113e8eb3236ce53ad9cce320c3d6253d248..ebe79d9ad2934b53085c8a720fdfca0a "farmer", PoiTypes.FARMER, 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 330d6badfbd096e4aec873dcb419df7975cb60a3..abb950417bf5db30f37e50605e897150bba67352 100644 +index 4275eb588114522d337f39c6f3503cd9d4be92e9..7a9757689e7e32e8e07802aad73af2bc7b840b0a 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -@@ -71,7 +71,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { +@@ -77,7 +77,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { int maxChunkLoadsPerProjectile = maxProjectileChunkLoadsConfig.perProjectile.max; if (maxChunkLoadsPerProjectile >= 0 && this.chunksLoadedByProjectile >= maxChunkLoadsPerProjectile) { if (maxProjectileChunkLoadsConfig.perProjectile.removeFromWorldAfterReachLimit) { @@ -319,7 +319,7 @@ index 330d6badfbd096e4aec873dcb419df7975cb60a3..abb950417bf5db30f37e50605e897150 this.setDeltaMovement(0, this.getDeltaMovement().y, 0); } diff --git a/src/main/java/org/galemc/gale/version/AbstractPaperVersionFetcher.java b/src/main/java/org/galemc/gale/version/AbstractPaperVersionFetcher.java -index 75af21644eaf78abdebd722b671f3c47aa083a25..21d71db5ef632ae685c0a852fda54b8d6be183ee 100644 +index 75af21644eaf78abdebd722b671f3c47aa083a25..c55757f0a24a0b5c06333070f5875e7d8a0f7777 100644 --- a/src/main/java/org/galemc/gale/version/AbstractPaperVersionFetcher.java +++ b/src/main/java/org/galemc/gale/version/AbstractPaperVersionFetcher.java @@ -101,10 +101,10 @@ public abstract class AbstractPaperVersionFetcher implements VersionFetcher { @@ -337,3 +337,11 @@ index 75af21644eaf78abdebd722b671f3c47aa083a25..21d71db5ef632ae685c0a852fda54b8d .append(Component.newline()) .append(text("Download the new version at: ") .append(text(this.downloadPage, NamedTextColor.GOLD) // Gale - branding changes - version fetcher +@@ -149,6 +149,6 @@ public abstract class AbstractPaperVersionFetcher implements VersionFetcher { + return null; + } + +- return text("Previous version: " + oldVersion, NamedTextColor.GRAY, TextDecoration.ITALIC); ++ return text("Previous: " + oldVersion, NamedTextColor.GRAY, TextDecoration.ITALIC); // Purpur + } + } diff --git a/patches/server/0013-Purpur-Configurable-server-mod-name.patch b/patches/server/0012-Purpur-Configurable-server-mod-name.patch similarity index 92% rename from patches/server/0013-Purpur-Configurable-server-mod-name.patch rename to patches/server/0012-Purpur-Configurable-server-mod-name.patch index a2483750..22347024 100644 --- a/patches/server/0013-Purpur-Configurable-server-mod-name.patch +++ b/patches/server/0012-Purpur-Configurable-server-mod-name.patch @@ -7,10 +7,10 @@ Original license: MIT Original project: https://github.com/PurpurMC/Purpur diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index ede6cd55688e573e003a6568100b18d5e620f878..9b18c076cabdbfc4b266fa605f38e2ad375e8271 100644 +index 6a652ed876128addfef881903272fc9a891b13b6..12f41f1bc9ea5f5be7e32236aae380f633abee0e 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1919,7 +1919,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop, String> taskNameCache = new MapMaker().weakKeys().makeMap(); - @@ -650,10 +647,10 @@ index 429cff43a9f0c74161fdab857f5d45771f774ac2..00000000000000000000000000000000 -} diff --git a/src/main/java/co/aikar/timings/WorldTimingsHandler.java b/src/main/java/co/aikar/timings/WorldTimingsHandler.java deleted file mode 100644 -index 22687667ec69a954261e55e59261286ac1b8b8cd..0000000000000000000000000000000000000000 +index 2f0d9b953802dee821cfde82d22b0567cce8ee91..0000000000000000000000000000000000000000 --- a/src/main/java/co/aikar/timings/WorldTimingsHandler.java +++ /dev/null -@@ -1,140 +0,0 @@ +@@ -1,120 +0,0 @@ -package co.aikar.timings; - -import net.minecraft.server.level.ServerLevel; @@ -715,16 +712,6 @@ index 22687667ec69a954261e55e59261286ac1b8b8cd..00000000000000000000000000000000 - - public final Timing miscMobSpawning; - -- public final Timing poiUnload; -- public final Timing chunkUnload; -- public final Timing poiSaveDataSerialization; -- public final Timing chunkSave; -- public final Timing chunkSaveDataSerialization; -- public final Timing chunkSaveIOWait; -- public final Timing chunkUnloadPrepareSave; -- public final Timing chunkUnloadPOISerialization; -- public final Timing chunkUnloadDataSave; -- - public WorldTimingsHandler(Level server) { - String name = ((PrimaryLevelData) server.getLevelData()).getLevelName() + " - "; - @@ -778,56 +765,12 @@ index 22687667ec69a954261e55e59261286ac1b8b8cd..00000000000000000000000000000000 - - - miscMobSpawning = Timings.ofSafe(name + "Mob spawning - Misc"); -- -- poiUnload = Timings.ofSafe(name + "Chunk unload - POI"); -- chunkUnload = Timings.ofSafe(name + "Chunk unload - Chunk"); -- poiSaveDataSerialization = Timings.ofSafe(name + "Chunk save - POI Data serialization"); -- chunkSave = Timings.ofSafe(name + "Chunk save - Chunk"); -- chunkSaveDataSerialization = Timings.ofSafe(name + "Chunk save - Chunk Data serialization"); -- chunkSaveIOWait = Timings.ofSafe(name + "Chunk save - Chunk IO Wait"); -- chunkUnloadPrepareSave = Timings.ofSafe(name + "Chunk unload - Async Save Prepare"); -- chunkUnloadPOISerialization = Timings.ofSafe(name + "Chunk unload - POI Data Serialization"); -- chunkUnloadDataSave = Timings.ofSafe(name + "Chunk unload - Data Serialization"); - } - - public static Timing getTickList(ServerLevel worldserver, String timingsType) { - return Timings.ofSafe(((PrimaryLevelData) worldserver.getLevelData()).getLevelName() + " - Scheduled " + timingsType); - } -} -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 6bc7c6f16a1649fc9e24e7cf90fca401e5bd4875..5b446e6ac151f99f64f0c442d0b40b5e251bc4c4 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 -@@ -1316,9 +1316,7 @@ public final class ChunkHolderManager { - } - - public boolean processTicketUpdates() { -- co.aikar.timings.MinecraftTimings.distanceManagerTick.startTiming(); try { // Paper - add timings for distance manager - return this.processTicketUpdates(true, true, null); -- } finally { co.aikar.timings.MinecraftTimings.distanceManagerTick.stopTiming(); } // Paper - add timings for distance manager - } - - 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 56b07a3306e5735816c8d89601b519cb0db6379a..524d9f0e2cc9a840fdf74bfa98537b5c8d572961 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 -@@ -1779,7 +1779,6 @@ public final class NewChunkHolder { - boolean canSavePOI = !(chunk instanceof LevelChunk levelChunk && levelChunk.mustNotSave) && (poi != null && poi.isDirty()); - boolean canSaveEntities = entities != null; - -- try (co.aikar.timings.Timing ignored = this.world.timings.chunkSave.startTiming()) { // Paper - if (canSaveChunk) { - canSaveChunk = this.saveChunk(chunk, unloading); - } -@@ -1793,7 +1792,6 @@ public final class NewChunkHolder { - this.lastEntityUnload = null; - } - } -- } - - return executedUnloadTask | canSaveChunk | canSaveEntities | canSavePOI ? new SaveStat(executedUnloadTask || canSaveChunk, canSaveEntities, canSavePOI): null; - } diff --git a/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitCommandNode.java b/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitCommandNode.java index 0c3c82b28e581286b798ee58ca4193efc2faff4a..5a2a4f69995f23e799370c05f28f9353aa1a1d39 100644 --- a/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitCommandNode.java @@ -858,7 +801,7 @@ index 0c3c82b28e581286b798ee58ca4193efc2faff4a..5a2a4f69995f23e799370c05f28f9353 // return true as command was handled return 1; diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index e246171b3eb3b8d8caab2c2535f305e8af2f3701..f6dd905176605228cbd6673ca2f77431a48248ad 100644 +index 4a215cec69f8fe81d55b497c0b5ff98d03f235ae..726d5cc3422368e7a2bbdb8fce7484da30e24174 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java @@ -1,6 +1,5 @@ @@ -950,11 +893,11 @@ index 097500a59336db1bbfffcd1aa4cff7a8586e46ec..f06076864582ed153c6154fd7f3e9101 @Override diff --git a/src/main/java/net/minecraft/network/protocol/PacketUtils.java b/src/main/java/net/minecraft/network/protocol/PacketUtils.java -index 57e76b53e5e314c3e6b8856010f7a84188121582..d6daa27a8d7aca00b181e90d789f4249e8437d29 100644 +index d0d36a57ec4896bcb74970f8fb24d8f3e17db133..f7197f1347251a37dd0f6d9ffa2f09bc3a4e1233 100644 --- a/src/main/java/net/minecraft/network/protocol/PacketUtils.java +++ b/src/main/java/net/minecraft/network/protocol/PacketUtils.java -@@ -50,8 +50,7 @@ public class PacketUtils { - try { // Paper - detailed watchdog information +@@ -31,8 +31,7 @@ public class PacketUtils { + engine.executeIfPossible(() -> { if (listener instanceof ServerCommonPacketListenerImpl serverCommonPacketListener && serverCommonPacketListener.processedDisconnect) return; // CraftBukkit - Don't handle sync packets for kicked players if (listener.shouldHandleMessage(packet)) { - co.aikar.timings.Timing timing = co.aikar.timings.MinecraftTimings.getPacketTiming(packet); // Paper - timings @@ -964,19 +907,19 @@ index 57e76b53e5e314c3e6b8856010f7a84188121582..d6daa27a8d7aca00b181e90d789f4249 } catch (Exception exception) { if (exception instanceof ReportedException) { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 5bf2d1cca0661ff35533c41e84e4f387f1a18af8..03a787c9bafee3a6b300703cf05a6a65bd4e9c03 100644 +index 12f41f1bc9ea5f5be7e32236aae380f633abee0e..0eac388d53d65d6dbd6900040be4d661cc799765 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -181,8 +181,6 @@ import org.bukkit.craftbukkit.CraftRegistry; +@@ -187,8 +187,6 @@ import org.bukkit.craftbukkit.CraftRegistry; import org.bukkit.event.server.ServerLoadEvent; // CraftBukkit end -import co.aikar.timings.MinecraftTimings; // Paper - - public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements ServerInfo, CommandSource, AutoCloseable { + public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements ServerInfo, ChunkIOErrorReporter, CommandSource, AutoCloseable, ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer { // Paper - rewrite chunk system public static final int SERVER_THREAD_PRIORITY = Integer.getInteger("gale.thread.priority.server", -1); // Gale - server thread priority environment variable -@@ -965,7 +963,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { return !this.canSleepForTickNoOversleep(); // Paper - move oversleep into full server tick -@@ -1477,8 +1473,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { entityplayer.connection.suspendFlushing(); }); @@ -1060,7 +984,7 @@ index 5bf2d1cca0661ff35533c41e84e4f387f1a18af8..03a787c9bafee3a6b300703cf05a6a65 // Paper start - Folia scheduler API ((io.papermc.paper.threadedregions.scheduler.FoliaGlobalRegionScheduler) Bukkit.getGlobalRegionScheduler()).tick(); getAllLevels().forEach(level -> { -@@ -1733,20 +1716,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop list = Lists.newArrayList(); List list1 = this.level.players(); ObjectIterator objectiterator = this.entityMap.values().iterator(); @@ -1238,7 +1117,7 @@ index 54c3e32c7ae869d55408d77ea2aa1635f980a39b..1dc4ccbd999964eee18a420c8166e1a8 ChunkMap.TrackedEntity playerchunkmap_entitytracker; -@@ -1208,17 +1191,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -975,17 +973,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider playerchunkmap_entitytracker.serverEntity.sendChanges(); } } @@ -1257,39 +1136,37 @@ index 54c3e32c7ae869d55408d77ea2aa1635f980a39b..1dc4ccbd999964eee18a420c8166e1a8 } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 360e1df4574c8257ff52b4a38a26314c0ec1a05e..9115054c05d261dd959e1f1f091c9b96c6a01a79 100644 +index e1d2c90295580e130c7f317fa1164c395caea85f..121db0c3b0416e43a7cac8e33d498bbe6765602f 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -272,10 +272,8 @@ public class ServerChunkCache extends ChunkSource { - if (!completablefuture.isDone()) { // Paper - io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.pushChunkWait(this.level, x1, z1); // Paper - rewrite chunk system - com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.level, x, z); // Paper - Add debug for sync chunk loads -- this.level.timings.syncChunkLoad.startTiming(); // Paper - chunkproviderserver_b.managedBlock(completablefuture::isDone); - io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.popChunkWait(); // Paper - rewrite chunk system -- this.level.timings.syncChunkLoad.stopTiming(); // Paper - } // Paper - ChunkResult chunkresult = (ChunkResult) completablefuture.join(); - ChunkAccess ichunkaccess1 = (ChunkAccess) chunkresult.orElse(null); // CraftBukkit - decompile error -@@ -423,17 +421,13 @@ public class ServerChunkCache extends ChunkSource { +@@ -355,12 +355,25 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + } public void save(boolean flush) { - this.runDistanceManagerUpdates(); -- try (co.aikar.timings.Timing timed = level.timings.chunkSaveData.startTiming()) { // Paper - Timings ++<<<<<<< HEAD + // Paper - rewrite chunk system + try (co.aikar.timings.Timing timed = level.timings.chunkSaveData.startTiming()) { // Paper - Timings ++======= ++ this.runDistanceManagerUpdates(); ++>>>>>>> Remove Timings this.chunkMap.saveAllChunks(flush); - } // Paper - Timings } - // Paper start - Incremental chunk and player saving; duplicate save, but call incremental - public void saveIncrementally() { - this.runDistanceManagerUpdates(); -- try (co.aikar.timings.Timing timed = level.timings.chunkSaveData.startTiming()) { // Paper - Timings - this.chunkMap.saveIncrementally(); -- } // Paper - Timings - } - // Paper end - Incremental chunk and player saving - -@@ -466,24 +460,18 @@ public class ServerChunkCache extends ChunkSource { ++<<<<<<< HEAD ++======= ++ // Paper start - Incremental chunk and player saving; duplicate save, but call incremental ++ public void saveIncrementally() { ++ this.runDistanceManagerUpdates(); ++ this.chunkMap.saveIncrementally(); ++ } ++ // Paper end - Incremental chunk and player saving ++ ++>>>>>>> Remove Timings + @Override + public void close() throws IOException { + // CraftBukkit start +@@ -382,24 +395,23 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon @Override public void tick(BooleanSupplier shouldKeepTicking, boolean tickChunks) { @@ -1301,8 +1178,12 @@ index 360e1df4574c8257ff52b4a38a26314c0ec1a05e..9115054c05d261dd959e1f1f091c9b96 this.runDistanceManagerUpdates(); - this.level.timings.doChunkMap.stopTiming(); // Spigot if (tickChunks) { -- this.level.timings.chunks.startTiming(); // Paper - timings - this.chunkMap.level.playerChunkLoader.tick(); // Paper - replace player chunk loader - this is mostly required to account for view distance changes ++<<<<<<< HEAD + this.level.timings.chunks.startTiming(); // Paper - timings + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getPlayerChunkLoader().tick(); // Paper - rewrite chunk system ++======= ++ this.chunkMap.level.playerChunkLoader.tick(); // Paper - replace player chunk loader - this is mostly required to account for view distance changes ++>>>>>>> Remove Timings this.tickChunks(); - this.level.timings.chunks.stopTiming(); // Paper - timings this.chunkMap.tick(); @@ -1314,16 +1195,20 @@ index 360e1df4574c8257ff52b4a38a26314c0ec1a05e..9115054c05d261dd959e1f1f091c9b96 this.clearCache(); } -@@ -493,8 +481,6 @@ public class ServerChunkCache extends ChunkSource { +@@ -409,9 +421,12 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon this.lastInhabitedUpdate = i; if (!this.level.isDebug()) { -- // Paper - optimise chunk tick iteration -- if (this.level.getServer().tickRateManager().runsNormally()) this.level.timings.chunkTicks.startTiming(); // Paper ++<<<<<<< HEAD + List list = Lists.newArrayListWithCapacity(this.chunkMap.size()); + Iterator iterator = this.chunkMap.getChunks().iterator(); + if (this.level.getServer().tickRateManager().runsNormally()) this.level.timings.chunkTicks.startTiming(); // Paper ++======= ++>>>>>>> Remove Timings - // Paper - optimise chunk tick iteration - -@@ -506,7 +492,6 @@ public class ServerChunkCache extends ChunkSource { + while (iterator.hasNext()) { + ChunkHolder playerchunk = (ChunkHolder) iterator.next(); +@@ -429,7 +444,6 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon boolean flagAndHasNaturalSpawn = flag && this.anySpawnCategoryIsSpawnedThisTick(); if (flagAndHasNaturalSpawn) { // Gale end - MultiPaper - skip unnecessary mob spawning computations @@ -1331,19 +1216,29 @@ index 360e1df4574c8257ff52b4a38a26314c0ec1a05e..9115054c05d261dd959e1f1f091c9b96 int k = this.distanceManager.getNaturalSpawnChunkCount(); // Paper start - Optional per player mob spawns int naturalSpawnChunkCount = k; -@@ -535,7 +520,6 @@ public class ServerChunkCache extends ChunkSource { - // Pufferfish end +@@ -453,7 +467,6 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + spawnercreature_d = NaturalSpawner.createState(naturalSpawnChunkCount, this.level.getAllEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false); } // Paper end - Optional per player mob spawns - this.level.timings.countNaturalMobs.stopTiming(); // Paper - timings - //this.lastSpawnState = spawnercreature_d; // Pufferfish - this is managed asynchronously + this.lastSpawnState = spawnercreature_d; // Gale start - MultiPaper - skip unnecessary mob spawning computations -@@ -647,17 +631,13 @@ public class ServerChunkCache extends ChunkSource { +@@ -492,20 +505,79 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + } } } - // Paper end - optimise chunk tick iteration -- this.level.timings.chunkTicks.stopTiming(); // Paper ++<<<<<<< HEAD + this.level.timings.chunkTicks.stopTiming(); // Paper ++======= ++ // Paper start - optimise chunk tick iteration ++ } finally { ++ if (chunkIterator instanceof io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet.Iterator safeIterator) { ++ safeIterator.finishedIterating(); ++ } ++ } ++ // Paper end - optimise chunk tick iteration ++>>>>>>> Remove Timings if (flag) { - try (co.aikar.timings.Timing ignored = this.level.timings.miscMobSpawning.startTiming()) { // Paper - timings @@ -1352,21 +1247,67 @@ index 360e1df4574c8257ff52b4a38a26314c0ec1a05e..9115054c05d261dd959e1f1f091c9b96 } } - // Paper - optimise chunk tick iteration -- this.level.timings.broadcastChunkUpdates.startTiming(); // Paper - timing - // Paper start - optimise chunk tick iteration - if (!this.chunkMap.needsChangeBroadcasting.isEmpty()) { - it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet copy = this.chunkMap.needsChangeBroadcasting.clone(); -@@ -671,7 +651,6 @@ public class ServerChunkCache extends ChunkSource { - } - } - // Paper end - optimise chunk tick iteration -- this.level.timings.broadcastChunkUpdates.stopTiming(); // Paper - timing - // Paper - optimise chunk tick iteration ++<<<<<<< HEAD + list.forEach((chunkproviderserver_a1) -> { + this.level.timings.broadcastChunkUpdates.startTiming(); // Paper - timing + chunkproviderserver_a1.holder.broadcastChanges(chunkproviderserver_a1.chunk); + this.level.timings.broadcastChunkUpdates.stopTiming(); // Paper - timing + }); ++======= ++ // Paper - optimise chunk tick iteration ++ // Paper start - optimise chunk tick iteration ++ if (!this.chunkMap.needsChangeBroadcasting.isEmpty()) { ++ it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet copy = this.chunkMap.needsChangeBroadcasting.clone(); ++ this.chunkMap.needsChangeBroadcasting.clear(); ++ for (ChunkHolder holder : copy) { ++ holder.broadcastChanges(holder.getFullChunkNowUnchecked()); // LevelChunks are NEVER unloaded ++ if (holder.needsBroadcastChanges()) { ++ // I DON'T want to KNOW what DUMB plugins might be doing. ++ this.chunkMap.needsChangeBroadcasting.add(holder); ++ } ++ } ++ } ++ // Paper end - optimise chunk tick iteration ++ // Paper - optimise chunk tick iteration ++ } ++ ++ // Pufferfish start - optimize mob spawning ++ if (org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled) { ++ for (ServerPlayer player : this.level.players) { ++ // Paper start - per player mob spawning backoff ++ for (int ii = 0; ii < ServerPlayer.MOBCATEGORY_TOTAL_ENUMS; ii++) { ++ player.mobCounts[ii] = 0; ++ ++ int newBackoff = player.mobBackoffCounts[ii] - 1; // TODO make configurable bleed // TODO use nonlinear algorithm? ++ if (newBackoff < 0) { ++ newBackoff = 0; ++ } ++ player.mobBackoffCounts[ii] = newBackoff; ++ } ++ // Paper end - per player mob spawning backoff ++ } ++ if (firstRunSpawnCounts) { ++ firstRunSpawnCounts = false; ++ _pufferfish_spawnCountsReady.set(true); ++ } ++ if (_pufferfish_spawnCountsReady.getAndSet(false)) { ++ net.minecraft.server.MinecraftServer.getServer().mobSpawnExecutor.submit(() -> { ++ int mapped = distanceManager.getNaturalSpawnChunkCount(); ++ io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet.Iterator objectiterator = ++ level.entityTickList.entities.iterator(io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet.ITERATOR_FLAG_SEE_ADDITIONS); ++ gg.pufferfish.pufferfish.util.IterableWrapper wrappedIterator = ++ new gg.pufferfish.pufferfish.util.IterableWrapper<>(objectiterator); ++ lastSpawnState = NaturalSpawner.createState(mapped, wrappedIterator, this::getFullChunk, null, true); ++ objectiterator.finishedIterating(); ++ _pufferfish_spawnCountsReady.set(true); ++ }); ++ } ++>>>>>>> Remove Timings } + } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index f8d11853af6bfc08d1bd8a0f537fd5760bfc04be..e354a9c72ec61896d9752d804517e57a412daea5 100644 +index 528e6e37b5552fe8179b472ec5fbbb90fa1b7b5b..4fea04aaf08c8a8e7bbb2add980f28fca08dd97f 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1,7 +1,6 @@ @@ -1377,7 +1318,7 @@ index f8d11853af6bfc08d1bd8a0f537fd5760bfc04be..e354a9c72ec61896d9752d804517e57a import com.google.common.collect.Lists; import com.mojang.datafixers.DataFixer; import com.mojang.datafixers.util.Pair; -@@ -868,27 +867,19 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -682,27 +681,19 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. this.tickTime(); } @@ -1405,7 +1346,7 @@ index f8d11853af6bfc08d1bd8a0f537fd5760bfc04be..e354a9c72ec61896d9752d804517e57a } this.handlingTick = false; -@@ -899,13 +890,11 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -713,13 +704,11 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. } if (flag1 || this.emptyTime++ < 300) { @@ -1419,7 +1360,7 @@ index f8d11853af6bfc08d1bd8a0f537fd5760bfc04be..e354a9c72ec61896d9752d804517e57a this.entityTickList.forEach((entity) -> { entity.activatedPriorityReset = false; // Pufferfish - DAB if (!entity.isRemoved()) { -@@ -942,8 +931,6 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -743,8 +732,6 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. } } }); @@ -1428,27 +1369,27 @@ index f8d11853af6bfc08d1bd8a0f537fd5760bfc04be..e354a9c72ec61896d9752d804517e57a this.tickBlockEntities(); } -@@ -1077,7 +1064,6 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -869,7 +856,6 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. } } // Paper - Option to disable ice and snow - timings.chunkTicksBlocks.startTiming(); // Paper if (randomTickSpeed > 0) { - // Paper start - optimize random block ticking - LevelChunkSection[] sections = chunk.getSections(); -@@ -1110,8 +1096,6 @@ public class ServerLevel extends Level implements WorldGenLevel { + LevelChunkSection[] achunksection = chunk.getSections(); + +@@ -899,8 +885,6 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. + } } } - // Paper end - optimise random block ticking - - timings.chunkTicksBlocks.stopTiming(); // Paper } @VisibleForTesting -@@ -1441,31 +1425,21 @@ public class ServerLevel extends Level implements WorldGenLevel { - currentlyTickingEntity.lazySet(entity); - } - // Paper end - log detailed entity tick information +@@ -1200,31 +1184,21 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. + } + + public void tickNonPassenger(Entity entity) { - ++TimingHistory.entityTicks; // Paper - timings // Spigot start - co.aikar.timings.Timing timer; // Paper @@ -1477,15 +1418,16 @@ index f8d11853af6bfc08d1bd8a0f537fd5760bfc04be..e354a9c72ec61896d9752d804517e57a Iterator iterator = entity.getPassengers().iterator(); while (iterator.hasNext()) { -@@ -1473,7 +1447,6 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1232,8 +1206,6 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. this.tickPassenger(entity, entity1); } - // } finally { timer.stopTiming(); } // Paper - timings - move up - // Paper start - log detailed entity tick information - } finally { - if (currentlyTickingEntity.get() == entity) { -@@ -1488,9 +1461,6 @@ public class ServerLevel extends Level implements WorldGenLevel { +- + } + + private void tickPassenger(Entity vehicle, Entity passenger) { +@@ -1241,9 +1213,6 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. if (passenger instanceof Player || this.entityTickList.contains(passenger)) { // Paper - EAR 2 final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(passenger); @@ -1494,8 +1436,8 @@ index f8d11853af6bfc08d1bd8a0f537fd5760bfc04be..e354a9c72ec61896d9752d804517e57a - // Paper end passenger.setOldPosAndRot(); ++passenger.tickCount; - // Paper start - EAR 2 -@@ -1511,8 +1481,6 @@ public class ServerLevel extends Level implements WorldGenLevel { + +@@ -1265,8 +1234,6 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. this.tickPassenger(passenger, entity2); } @@ -1504,30 +1446,7 @@ index f8d11853af6bfc08d1bd8a0f537fd5760bfc04be..e354a9c72ec61896d9752d804517e57a } } else { passenger.stopRiding(); -@@ -1532,14 +1500,11 @@ public class ServerLevel extends Level implements WorldGenLevel { - org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); - } - -- try (co.aikar.timings.Timing ignored = this.timings.worldSave.startTiming()) { - if (doFull) { - this.saveLevelData(true); // Paper - Write SavedData IO async - } - -- this.timings.worldSaveChunks.startTiming(); // Paper - if (!this.noSave()) chunkproviderserver.saveIncrementally(); -- this.timings.worldSaveChunks.stopTiming(); // Paper - - // Copied from save() - // CraftBukkit start - moved from MinecraftServer.saveChunks -@@ -1551,7 +1516,6 @@ public class ServerLevel extends Level implements WorldGenLevel { - this.convertable.saveDataTag(this.server.registryAccess(), this.serverLevelData, this.server.getPlayerList().getSingleplayerData()); - } - // CraftBukkit end -- } - } - // Paper end - Incremental chunk and player saving - -@@ -1565,7 +1529,6 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1288,7 +1255,6 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. if (!savingDisabled) { org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(this.getWorld())); // CraftBukkit @@ -1535,20 +1454,18 @@ index f8d11853af6bfc08d1bd8a0f537fd5760bfc04be..e354a9c72ec61896d9752d804517e57a if (progressListener != null) { progressListener.progressStartNoAbort(Component.translatable("menu.savingLevel")); } -@@ -1575,11 +1538,8 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1298,9 +1264,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. progressListener.progressStage(Component.translatable("menu.savingChunks")); } - timings.worldSaveChunks.startTiming(); // Paper - if (!close) chunkproviderserver.save(flush); // Paper - rewrite chunk system - if (close) chunkproviderserver.close(true); // Paper - rewrite chunk system + if (!close) { chunkproviderserver.save(flush); } // Paper - add close param - timings.worldSaveChunks.stopTiming(); // Paper -- }// Paper - // Paper - rewrite chunk system - entity saving moved into ChunkHolder + }// Paper + // Paper - rewrite chunk system - } else if (close) { chunkproviderserver.close(false); } // Paper - rewrite chunk system diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index ce4763458258bd5685d3ec02278b6ed829ebf705..9250db41e26d2ffa96146782e898165591f9e819 100644 +index d2153c3e909e7e75529ce6e41d649bf54b48752b..33fd3c88f84a5d6f7f7c0212f364a83870c88fc7 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -1,6 +1,5 @@ @@ -1558,24 +1475,20 @@ index ce4763458258bd5685d3ec02278b6ed829ebf705..9250db41e26d2ffa96146782e8981655 import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -@@ -1337,7 +1336,6 @@ public abstract class PlayerList { +@@ -1282,11 +1281,9 @@ public abstract class PlayerList { - public void saveAll(int interval) { + public void saveAll() { io.papermc.paper.util.MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main - MinecraftTimings.savePlayers.startTiming(); // Paper - int numSaved = 0; - long now = MinecraftServer.currentTick; for (int i = 0; i < this.players.size(); ++i) { -@@ -1348,7 +1346,6 @@ public abstract class PlayerList { - } - // Paper end - Incremental chunk and player saving + this.save(this.players.get(i)); } - MinecraftTimings.savePlayers.stopTiming(); // Paper return null; }); // Paper - ensure main } diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index 32a1b5a1d01fd4dc603a76fde259f3a0d4749fad..4714cbf21f4edb41ee07c7eac180a6806afb7e9e 100644 +index d3de0362dd1ef3954d05c4d8fa56a25edfe1bb2b..6ac3dfab99cfb0b51c81cc20e71da1261a8c567c 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java @@ -356,10 +356,6 @@ public class EntityType implements FeatureElement, EntityTypeT @@ -1715,10 +1628,10 @@ index 85b4b24361e785acf75571ff98f924c00ae80748..ac67dd7a30616fe70f73426e332972b7 } diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 8be636ef55f8f2cb0ed1edad42156b742281b044..e77db67592e13a06133cafb364f227686fcc336b 100644 +index e86c8972de653252ae14a8d483941bda69913884..395ccbe442e9c57d11f3f7dc4381b8f6458ad392 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -177,7 +177,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -176,7 +176,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl public final com.destroystokyo.paper.antixray.ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray public final org.purpurmc.purpur.PurpurWorldConfig purpurConfig; // Purpur @@ -1726,15 +1639,15 @@ index 8be636ef55f8f2cb0ed1edad42156b742281b044..e77db67592e13a06133cafb364f22768 public static BlockPos lastPhysicsProblem; // Spigot private org.spigotmc.TickLimiter entityLimiter; private org.spigotmc.TickLimiter tileLimiter; -@@ -353,7 +352,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -400,7 +399,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl public void onBorderSetDamageSafeZOne(WorldBorder border, double safeZoneRadius) {} }); // CraftBukkit end - this.timings = new co.aikar.timings.WorldTimingsHandler(this); // Paper - code below can generate new world and access timings this.entityLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.entityMaxTickTime); this.tileLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.tileMaxTickTime); - this.chunkPacketBlockController = this.paperConfig().anticheat.antiXray.enabled ? new com.destroystokyo.paper.antixray.ChunkPacketBlockControllerAntiXray(this, executor) : com.destroystokyo.paper.antixray.ChunkPacketBlockController.NO_OPERATION_INSTANCE; // Paper - Anti-Xray -@@ -1318,15 +1316,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + this.entityLookup = new ca.spottedleaf.moonrise.patches.chunk_system.level.entity.dfl.DefaultEntityLookup(this); // Paper - rewrite chunk system +@@ -999,15 +997,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl } protected void tickBlockEntities() { @@ -1750,7 +1663,7 @@ index 8be636ef55f8f2cb0ed1edad42156b742281b044..e77db67592e13a06133cafb364f22768 // Spigot start // Iterator iterator = this.blockEntityTickers.iterator(); boolean flag = this.tickRateManager().runsNormally(); -@@ -1355,9 +1350,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1031,9 +1026,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl } this.blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075 @@ -1761,7 +1674,7 @@ index 8be636ef55f8f2cb0ed1edad42156b742281b044..e77db67592e13a06133cafb364f22768 } diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 27fccd091535f7587aaaa1621361dc1835381b89..885d7c9ef96dd3c7576c28606e5ab83d2a75de71 100644 +index d490429ddbb8cd82aeda5e03540075c9167b095e..d556089907bb695a9d87df1961ef0b0ae4382cad 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java @@ -127,7 +127,6 @@ public final class NaturalSpawner { @@ -1782,10 +1695,10 @@ index 27fccd091535f7587aaaa1621361dc1835381b89..885d7c9ef96dd3c7576c28606e5ab83d // Paper start - Add mobcaps commands 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 14aaabb6b9595847358f65ff01c81b179d9548ea..3dc9f10f00dd982ca28a66b364e5088c3413d5ef 100644 +index dcfe68a51067b35057ef14813f57e7d91a0f84b6..78c3dabea3dd08ed1f4212375e8ef20e904a9d3a 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -107,13 +107,6 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -106,13 +106,6 @@ public class Block extends BlockBehaviour implements ItemLike { this != Blocks.STRUCTURE_BLOCK && this != Blocks.JIGSAW; } @@ -1819,18 +1732,18 @@ index cd0e43f4c53a746dd6183a8406269f9b11ad3571..54657ac895fb2fa9c58910d5421f0082 private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry(); public CraftPersistentDataContainer persistentDataContainer; 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 f2a1787ba10bcb67ad5a2a36165bac55ea7f0a3e..184b69dc39749734f8176d3f3c2bf9f690a099f0 100644 +index 5752576087e5ff411ff8c89fde7a761083945c23..95f306d6d896e6aa4ada7ee20880ed862e0e48d8 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -792,7 +792,6 @@ public class LevelChunk extends ChunkAccess { - this.chunkHolder.getEntityChunk().callEntitiesLoadEvent(); // Paper - rewrite chunk system +@@ -622,7 +622,6 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(this.locX, this.locZ).getEntityChunk().callEntitiesLoadEvent(); // Paper - rewrite chunk system if (this.needsDecoration) { - try (co.aikar.timings.Timing ignored = this.level.timings.chunkLoadPopulate.startTiming()) { // Paper this.needsDecoration = false; java.util.Random random = new java.util.Random(); random.setSeed(this.level.getSeed()); -@@ -812,7 +811,6 @@ public class LevelChunk extends ChunkAccess { +@@ -642,7 +641,6 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p } } server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(bukkitChunk)); @@ -1838,7 +1751,7 @@ index f2a1787ba10bcb67ad5a2a36165bac55ea7f0a3e..184b69dc39749734f8176d3f3c2bf9f6 } } } -@@ -1165,7 +1163,6 @@ public class LevelChunk extends ChunkAccess { +@@ -979,7 +977,6 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p if (LevelChunk.this.isTicking(blockposition)) { try { @@ -1846,8 +1759,8 @@ index f2a1787ba10bcb67ad5a2a36165bac55ea7f0a3e..184b69dc39749734f8176d3f3c2bf9f6 BlockState iblockdata = LevelChunk.this.getBlockState(blockposition); if (this.blockEntity.getType().isValid(iblockdata)) { -@@ -1188,14 +1185,9 @@ public class LevelChunk extends ChunkAccess { - net.minecraft.world.level.chunk.LevelChunk.this.level.getCraftServer().getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new ServerInternalException(msg, throwable))); // Paper - ServerExceptionEvent +@@ -1002,14 +999,9 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p + net.minecraft.world.level.chunk.LevelChunk.this.level.getCraftServer().getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerInternalException(msg, throwable))); // Paper - ServerExceptionEvent LevelChunk.this.removeBlockEntity(this.getPos()); // Paper end - Prevent block entity and entity crashes - // Spigot start @@ -1862,10 +1775,10 @@ index f2a1787ba10bcb67ad5a2a36165bac55ea7f0a3e..184b69dc39749734f8176d3f3c2bf9f6 @Override diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 0523fef009b23eb801acfb6bcc45c02dfbef1833..c8e424d6646f782c8fbd97c1e699115304983533 100644 +index d10c10907cefc06afff7e0f4c4cbbca352410c25..ec341e053e8eb539d4401161245039c90609138c 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -474,7 +474,6 @@ public final class CraftServer implements Server { +@@ -477,7 +477,6 @@ public final class CraftServer implements Server { this.saveCommandsConfig(); this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*"); this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions"); @@ -1873,19 +1786,6 @@ index 0523fef009b23eb801acfb6bcc45c02dfbef1833..c8e424d6646f782c8fbd97c1e6991153 this.overrideSpawnLimits(); console.autosavePeriod = this.configuration.getInt("ticks-per.autosave"); this.warningState = WarningState.value(this.configuration.getString("settings.deprecated-verbose")); -diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index 9f873c07bec896b6c91b306efa51e0f07da1c6a8..ce3572f8044d7a4732d9411a622be79c48da1346 100644 ---- a/src/main/java/org/bukkit/craftbukkit/Main.java -+++ b/src/main/java/org/bukkit/craftbukkit/Main.java -@@ -375,8 +375,6 @@ public class Main { - tryPreloadClass("org.jline.terminal.impl.MouseSupport"); - tryPreloadClass("org.jline.terminal.impl.MouseSupport$1"); - tryPreloadClass("org.jline.terminal.Terminal$MouseTracking"); -- tryPreloadClass("co.aikar.timings.TimingHistory"); -- tryPreloadClass("co.aikar.timings.TimingHistory$MinuteReport"); - tryPreloadClass("io.netty.channel.AbstractChannelHandlerContext"); - tryPreloadClass("io.netty.channel.AbstractChannelHandlerContext$11"); - tryPreloadClass("io.netty.channel.AbstractChannelHandlerContext$12"); diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java index 006adb2adb27c497ede69f87e78bc3e34499cbf8..4ee1c3461d21feab3a54e76a7c2ab80b6ea2ab38 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java @@ -2027,7 +1927,7 @@ index b3e1adeb932da9b3bed16acd94e2f16da48a7c72..e9798517b9211c50a20ea5c69603aab3 } } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 2918b61675e16a0dd023d3ca10f232c4675bf4b0..c8dc6333cddbf25c8211be6d24ce39f5ee64b70a 100644 +index 4250752a95301271f09590f0140f821a0090811a..cbb510df86d7470520a007cba3b915bf0f8b6c67 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -219,9 +219,7 @@ public final class CraftMagicNumbers implements UnsafeValues { @@ -2051,10 +1951,10 @@ index 2918b61675e16a0dd023d3ca10f232c4675bf4b0..c8dc6333cddbf25c8211be6d24ce39f5 @Override diff --git a/src/main/java/org/galemc/gale/configuration/GaleGlobalConfiguration.java b/src/main/java/org/galemc/gale/configuration/GaleGlobalConfiguration.java -index b4cca06a583fbb7918237de256f43ee61fd8ec6c..dd4a5f610e6e84a73051a8ed46e1961804356ca3 100644 +index 9b82eb1cc56e3151ecbd526bb1064ab7ef32186b..f34d71d9e7fccb4b661475101b2c79144c65517d 100644 --- a/src/main/java/org/galemc/gale/configuration/GaleGlobalConfiguration.java +++ b/src/main/java/org/galemc/gale/configuration/GaleGlobalConfiguration.java -@@ -80,41 +80,6 @@ public class GaleGlobalConfiguration extends ConfigurationPart { +@@ -66,41 +66,6 @@ public class GaleGlobalConfiguration extends ConfigurationPart { public int premiumAccountSlowLoginTimeout = -1; // Gale - make slow login timeout configurable public boolean ignoreNullLegacyStructureData = false; // Gale - MultiPaper - ignore null legacy structure data @@ -2257,7 +2157,7 @@ index 139d946346594d2a59a8b2930c4eae794c880dbc..00000000000000000000000000000000 - -} diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index 638bed116e4c36974b6096524f3f878a1ecb89c5..37e35606e3f47325db4da5deeff02aad9d541e87 100644 +index bfd1999476debbd9798d51b2931dfa7e770a6e1f..87a815a942d15f2c1faf1f986bba864f9eea1351 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -34,7 +34,6 @@ import net.minecraft.world.entity.projectile.FireworkRocketEntity; @@ -2268,7 +2168,7 @@ index 638bed116e4c36974b6096524f3f878a1ecb89c5..37e35606e3f47325db4da5deeff02aad import net.minecraft.world.entity.schedule.Activity; import net.minecraft.world.level.Level; import net.minecraft.world.phys.AABB; -@@ -185,7 +184,6 @@ public class ActivationRange +@@ -181,7 +180,6 @@ public class ActivationRange */ public static void activateEntities(Level world) { @@ -2276,7 +2176,7 @@ index 638bed116e4c36974b6096524f3f878a1ecb89c5..37e35606e3f47325db4da5deeff02aad final int miscActivationRange = world.spigotConfig.miscActivationRange; final int raiderActivationRange = world.spigotConfig.raiderActivationRange; final int animalActivationRange = world.spigotConfig.animalActivationRange; -@@ -264,7 +262,6 @@ public class ActivationRange +@@ -261,7 +259,6 @@ public class ActivationRange } // Paper end } diff --git a/patches/server/0016-Bump-Dependencies.patch b/patches/server/0015-Bump-Dependencies.patch similarity index 88% rename from patches/server/0016-Bump-Dependencies.patch rename to patches/server/0015-Bump-Dependencies.patch index 9cbd06ed..08dccadf 100644 --- a/patches/server/0016-Bump-Dependencies.patch +++ b/patches/server/0015-Bump-Dependencies.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Bump Dependencies diff --git a/build.gradle.kts b/build.gradle.kts -index 59b84e4c4566e0185c6f7b002374e51c8415cad9..1d520295a7da79c6952ed950765647e2caf4315b 100644 +index 397d93b63e412abb96cc8366c51c3927d760afb8..d6a307d6f949348559d3dc3e9bc6a8f98c8ac4f4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -25,7 +25,7 @@ dependencies { @@ -17,7 +17,7 @@ index 59b84e4c4566e0185c6f7b002374e51c8415cad9..1d520295a7da79c6952ed950765647e2 implementation("net.minecrell:terminalconsoleappender:1.3.0") implementation("net.kyori:adventure-text-serializer-ansi:4.17.0") // Keep in sync with adventureVersion from Paper-API build file /* -@@ -34,28 +34,32 @@ dependencies { +@@ -34,33 +34,43 @@ dependencies { all its classes to check if they are plugins. Scanning takes about 1-2 seconds so adding this speeds up the server start. */ @@ -37,10 +37,9 @@ index 59b84e4c4566e0185c6f7b002374e51c8415cad9..1d520295a7da79c6952ed950765647e2 implementation("org.ow2.asm:asm-commons:9.7") implementation("org.spongepowered:configurate-yaml:4.2.0-SNAPSHOT") // Paper - config files implementation("commons-lang:commons-lang:2.6") - runtimeOnly("org.xerial:sqlite-jdbc:3.45.3.0") -- runtimeOnly("com.mysql:mysql-connector-j:8.3.0") + runtimeOnly("org.xerial:sqlite-jdbc:3.46.0.0") + runtimeOnly("com.mysql:mysql-connector-j:8.4.0") - runtimeOnly("com.lmax:disruptor:3.4.4") // Paper -+ runtimeOnly("com.mysql:mysql-connector-j:8.4.0") // Leaf - Bump Dependencies + runtimeOnly("com.lmax:disruptor:3.4.4") // Paper // Leaf - Bump Dependencies - Waiting Log4j 3.x to support disruptor 4.0.0 // Paper start - Use Velocity cipher - implementation("com.velocitypowered:velocity-native:3.1.2-SNAPSHOT") { @@ -58,14 +57,14 @@ index 59b84e4c4566e0185c6f7b002374e51c8415cad9..1d520295a7da79c6952ed950765647e2 + runtimeOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.9.20") + // Leaf end - // Purpur start - implementation("org.mozilla:rhino-runtime:1.7.15") -@@ -63,10 +67,10 @@ dependencies { - implementation("dev.omega24:upnp4j:1.0") - // Purpur end - - testImplementation("io.github.classgraph:classgraph:4.8.47") // Paper - mob goal test - testImplementation("org.junit.jupiter:junit-jupiter:5.10.2") ++ // Purpur start ++ implementation("org.mozilla:rhino-runtime:1.7.15") ++ implementation("org.mozilla:rhino-engine:1.7.15") ++ implementation("dev.omega24:upnp4j:1.0") ++ // Purpur end ++ + testImplementation("io.github.classgraph:classgraph:4.8.173") // Paper - mob goal test // Leaf - Bump Dependencies + testImplementation("org.junit.jupiter:junit-jupiter:5.11.0-M2") // Leaf - Bump Dependencies testImplementation("org.hamcrest:hamcrest:2.2") @@ -74,7 +73,7 @@ index 59b84e4c4566e0185c6f7b002374e51c8415cad9..1d520295a7da79c6952ed950765647e2 testImplementation("org.ow2.asm:asm-tree:9.7") testImplementation("org.junit-pioneer:junit-pioneer:2.2.0") // Paper - CartesianTest implementation("net.neoforged:srgutils:1.0.9") // Paper - mappings handling -@@ -77,6 +81,8 @@ dependencies { +@@ -71,6 +81,8 @@ dependencies { implementation("io.papermc:reflection-rewriter-runtime:$reflectionRewriterVersion") implementation("io.papermc:reflection-rewriter-proxy-generator:$reflectionRewriterVersion") // Paper end - Remap reflection @@ -83,7 +82,7 @@ index 59b84e4c4566e0185c6f7b002374e51c8415cad9..1d520295a7da79c6952ed950765647e2 } paperweight { -@@ -270,3 +276,8 @@ sourceSets { +@@ -264,3 +276,8 @@ sourceSets { } } // Gale end - package license into jar diff --git a/patches/server/0017-Remove-vanilla-username-check.patch b/patches/server/0016-Remove-vanilla-username-check.patch similarity index 89% rename from patches/server/0017-Remove-vanilla-username-check.patch rename to patches/server/0016-Remove-vanilla-username-check.patch index 4915bc89..a299b6af 100644 --- a/patches/server/0017-Remove-vanilla-username-check.patch +++ b/patches/server/0016-Remove-vanilla-username-check.patch @@ -5,19 +5,19 @@ Subject: [PATCH] Remove vanilla username check diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index 52c5ce7339029d7cc3bb1164131a9f96598760c0..1d496b2efc44065e91b4d612e17f38382489e876 100644 +index 80fdfc08e57ff3d524956aa9651bfe3cba3efc7b..00d8b8d4d2d1c73c4eeeaa9483cca2999df65a54 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java @@ -181,7 +181,8 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, - // Gale start - JettPack - reduce array allocations - Validate.validState(this.state == ServerLoginPacketListenerImpl.State.HELLO, "Unexpected hello packet", ArrayConstants.emptyObjectArray); + public void handleHello(ServerboundHelloPacket packet) { + Validate.validState(this.state == ServerLoginPacketListenerImpl.State.HELLO, "Unexpected hello packet", new Object[0]); // Paper start - Validate usernames - if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode() + if (!org.dreeam.leaf.config.modules.misc.RemoveVanillaUsernameCheck.enabled // Leaf - Remove Vanilla username check + && io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode() && io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.performUsernameValidation && !this.iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation) { - Validate.validState(StringUtil.isReasonablePlayerName(packet.name()), "Invalid characters in username", ArrayConstants.emptyObjectArray); + Validate.validState(StringUtil.isReasonablePlayerName(packet.name()), "Invalid characters in username", new Object[0]); diff --git a/src/main/java/org/dreeam/leaf/config/modules/misc/RemoveVanillaUsernameCheck.java b/src/main/java/org/dreeam/leaf/config/modules/misc/RemoveVanillaUsernameCheck.java new file mode 100644 index 0000000000000000000000000000000000000000..2dcdf5adff80f63499e6d160ff24313653cfb315 diff --git a/patches/server/0018-Remove-Spigot-Check-for-Broken-BungeeCord-Configurat.patch b/patches/server/0017-Remove-Spigot-Check-for-Broken-BungeeCord-Configurat.patch similarity index 94% rename from patches/server/0018-Remove-Spigot-Check-for-Broken-BungeeCord-Configurat.patch rename to patches/server/0017-Remove-Spigot-Check-for-Broken-BungeeCord-Configurat.patch index 1af9bc9f..587eecfe 100644 --- a/patches/server/0018-Remove-Spigot-Check-for-Broken-BungeeCord-Configurat.patch +++ b/patches/server/0017-Remove-Spigot-Check-for-Broken-BungeeCord-Configurat.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Remove Spigot Check for Broken BungeeCord Configurations diff --git a/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java -index 8e90f35218e66690359dac35828a1485a77f34c1..a544a93deccdff9c7fe6b8cca9650ce8c2a69a7d 100644 +index a1e39d4476e932da3d4e0c363ce22eb5be2b8e6c..e4911a420c81a371142f556584cc05a4f76334e1 100644 --- a/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java -@@ -181,7 +181,7 @@ public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketL +@@ -179,7 +179,7 @@ public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketL { this.connection.spoofedProfile = ServerHandshakePacketListenerImpl.gson.fromJson(split[3], com.mojang.authlib.properties.Property[].class); } diff --git a/patches/server/0019-Remove-UseItemOnPacket-Too-Far-Check.patch b/patches/server/0018-Remove-UseItemOnPacket-Too-Far-Check.patch similarity index 95% rename from patches/server/0019-Remove-UseItemOnPacket-Too-Far-Check.patch rename to patches/server/0018-Remove-UseItemOnPacket-Too-Far-Check.patch index 9dc23859..409b5afd 100644 --- a/patches/server/0019-Remove-UseItemOnPacket-Too-Far-Check.patch +++ b/patches/server/0018-Remove-UseItemOnPacket-Too-Far-Check.patch @@ -7,10 +7,10 @@ This Check is added in 1.17.x -> 1.18.x that updated by Mojang. By removing this check, it gives ability for hackers to use some modules of hack clients. diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index c53e01260b4ca6f637b3d55798cda4cab822b5fe..d107cd93a6d43f060a7bcfc4a3ee0c82c51bc9b9 100644 +index dc4a4d7de838d8756b0f5cbbc149b1d5cd2b4dd6..e26963501b7608097fc1be8f2c9530b082f2c0ec 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2008,7 +2008,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1948,7 +1948,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl Vec3 vec3d1 = vec3d.subtract(Vec3.atCenterOf(blockposition)); double d0 = 1.0000001D; diff --git a/patches/server/0020-KTP-Allow-unknown-event-thread-execution.patch b/patches/server/0019-KTP-Allow-unknown-event-thread-execution.patch similarity index 100% rename from patches/server/0020-KTP-Allow-unknown-event-thread-execution.patch rename to patches/server/0019-KTP-Allow-unknown-event-thread-execution.patch diff --git a/patches/server/0021-KeYi-Player-Skull-API.patch b/patches/server/0020-KeYi-Player-Skull-API.patch similarity index 90% rename from patches/server/0021-KeYi-Player-Skull-API.patch rename to patches/server/0020-KeYi-Player-Skull-API.patch index 0dbc0acf..07b2e3b1 100644 --- a/patches/server/0021-KeYi-Player-Skull-API.patch +++ b/patches/server/0020-KeYi-Player-Skull-API.patch @@ -7,10 +7,10 @@ Original license: MIT Original project: https://github.com/KeYiMC/KeYi diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index aac21ff5418f76b0d06b6a49a4021bde194cf1da..20cf62169210ba0a5de45ed68e3453cc63a07102 100644 +index 41863584c3a85068b807a5aeb93c3da70f133b47..7a7a2acca5980ab3d79346f47e4153dd6c98939b 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3626,4 +3626,27 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3647,4 +3647,27 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().connection.send(new net.minecraft.network.protocol.game.ClientboundPlayerCombatKillPacket(getEntityId(), io.papermc.paper.adventure.PaperAdventure.asVanilla(message))); } // Purpur end diff --git a/patches/server/0022-KeYi-Disable-arrow-despawn-counter-by-default.patch b/patches/server/0021-KeYi-Disable-arrow-despawn-counter-by-default.patch similarity index 90% rename from patches/server/0022-KeYi-Disable-arrow-despawn-counter-by-default.patch rename to patches/server/0021-KeYi-Disable-arrow-despawn-counter-by-default.patch index c41842a4..a323d0a5 100644 --- a/patches/server/0022-KeYi-Disable-arrow-despawn-counter-by-default.patch +++ b/patches/server/0021-KeYi-Disable-arrow-despawn-counter-by-default.patch @@ -7,10 +7,10 @@ Original license: MIT Original project: https://github.com/KeYiMC/KeYi diff --git a/src/main/java/org/galemc/gale/configuration/GaleWorldConfiguration.java b/src/main/java/org/galemc/gale/configuration/GaleWorldConfiguration.java -index 758cc7862121e7c27db5e087f816aab566320162..c3c9fc0d126e3f258fa8f06901fb3cac0d0ab289 100644 +index 76718d966a326ba82a92217a9f0fdf5b17f9d643..46254b2f500ad9bec248cd057c87bc729c592ee0 100644 --- a/src/main/java/org/galemc/gale/configuration/GaleWorldConfiguration.java +++ b/src/main/java/org/galemc/gale/configuration/GaleWorldConfiguration.java -@@ -137,7 +137,7 @@ public class GaleWorldConfiguration extends ConfigurationPart { +@@ -136,7 +136,7 @@ public class GaleWorldConfiguration extends ConfigurationPart { public boolean loadPortalDestinationChunkBeforeEntityTeleport = false; // Gale - MultiPaper - load portal destination chunk before entity teleport } diff --git a/patches/server/0023-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch b/patches/server/0022-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch similarity index 93% rename from patches/server/0023-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch rename to patches/server/0022-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch index 97e753a4..13c4f11b 100644 --- a/patches/server/0023-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch +++ b/patches/server/0022-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch @@ -7,10 +7,10 @@ Original license: MIT Original project: https://github.com/KeYiMC/KeYi 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 e380d1ea5b3dd6e91e79f6d7bd5d980a2c32315a..18d1be51ca12c3ccac5a5130667c47c1f1235935 100644 +index f096a9023fe0b54160e957dd5c6baa489ed0c410..7db0a4b53f27622ad2fd85a451613fc83ea87052 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -@@ -356,7 +356,7 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -357,7 +357,7 @@ public class ItemEntity extends Entity implements TraceableEntity { ItemStack itemstack1 = other.getItem(); if (Objects.equals(this.target, other.target) && ItemEntity.areMergable(itemstack, itemstack1)) { diff --git a/patches/server/0024-Carpet-Fixes-Optimized-getBiome-method.patch b/patches/server/0023-Carpet-Fixes-Optimized-getBiome-method.patch similarity index 100% rename from patches/server/0024-Carpet-Fixes-Optimized-getBiome-method.patch rename to patches/server/0023-Carpet-Fixes-Optimized-getBiome-method.patch diff --git a/patches/server/0025-Carpet-Fixes-Use-optimized-RecipeManager.patch b/patches/server/0024-Carpet-Fixes-Use-optimized-RecipeManager.patch similarity index 72% rename from patches/server/0025-Carpet-Fixes-Use-optimized-RecipeManager.patch rename to patches/server/0024-Carpet-Fixes-Use-optimized-RecipeManager.patch index 92343aee..9426d87f 100644 --- a/patches/server/0025-Carpet-Fixes-Use-optimized-RecipeManager.patch +++ b/patches/server/0024-Carpet-Fixes-Use-optimized-RecipeManager.patch @@ -11,15 +11,15 @@ This is a fully vanilla optimization. Improves: [Blast]Furnace/Campfire/Smoker/S This was mostly made for the auto crafting table, since the performance boost is much more visible while using that mod diff --git a/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java b/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java -index a31326e24cb68472c81cd781c5e3041772712862..0662e7afca15cab700dc61fe7de1d62eed27405d 100644 +index de7c77c1b25680ecc65f0f43f2391aff269a974f..fa0eccdb5f0b6a7bc1426d32a245095e7846b175 100644 --- a/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java +++ b/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java -@@ -132,7 +132,7 @@ public class RecipeManager extends SimpleJsonResourceReloadListener { +@@ -128,7 +128,7 @@ public class RecipeManager extends SimpleJsonResourceReloadListener { } - public > List> getAllRecipesFor(RecipeType type) { + public > List> getAllRecipesFor(RecipeType type) { - return List.copyOf(this.byType(type)); + return new java.util.ArrayList<>(this.byType(type)); // Leaf - Carpet-Fixes } - public > List> getRecipesFor(RecipeType type, C inventory, Level world) { + public > List> getRecipesFor(RecipeType type, I input, Level world) { diff --git a/patches/server/0026-Rail-Optimization-optimized-PoweredRailBlock-logic.patch b/patches/server/0025-Rail-Optimization-optimized-PoweredRailBlock-logic.patch similarity index 100% rename from patches/server/0026-Rail-Optimization-optimized-PoweredRailBlock-logic.patch rename to patches/server/0025-Rail-Optimization-optimized-PoweredRailBlock-logic.patch diff --git a/patches/server/0027-Akarin-Save-Json-list-asynchronously.patch b/patches/server/0026-Akarin-Save-Json-list-asynchronously.patch similarity index 85% rename from patches/server/0027-Akarin-Save-Json-list-asynchronously.patch rename to patches/server/0026-Akarin-Save-Json-list-asynchronously.patch index ff3a14d0..924a7d3a 100644 --- a/patches/server/0027-Akarin-Save-Json-list-asynchronously.patch +++ b/patches/server/0026-Akarin-Save-Json-list-asynchronously.patch @@ -8,10 +8,10 @@ Original license: GPL v3 Original project: https://github.com/Akarin-project/Akarin diff --git a/src/main/java/net/minecraft/server/players/StoredUserList.java b/src/main/java/net/minecraft/server/players/StoredUserList.java -index 1516232f116f1d48fe383d8c05c7dcc63b38f96a..523255345df9f4d84c5fa514de42620c4605d446 100644 +index c038da20b76c0b7b1c18471b20be01e849d29f3a..44b9c8a7c3cd22c0c0e148744e4096d7330f4f34 100644 --- a/src/main/java/net/minecraft/server/players/StoredUserList.java +++ b/src/main/java/net/minecraft/server/players/StoredUserList.java -@@ -104,6 +104,7 @@ public abstract class StoredUserList> { +@@ -103,6 +103,7 @@ public abstract class StoredUserList> { } public void save() throws IOException { @@ -19,7 +19,7 @@ index 1516232f116f1d48fe383d8c05c7dcc63b38f96a..523255345df9f4d84c5fa514de42620c this.removeExpired(); // Paper - remove expired values before saving JsonArray jsonarray = new JsonArray(); Stream stream = this.map.values().stream().map((jsonlistentry) -> { // CraftBukkit - decompile error -@@ -115,6 +116,8 @@ public abstract class StoredUserList> { +@@ -114,6 +115,8 @@ public abstract class StoredUserList> { Objects.requireNonNull(jsonarray); stream.forEach(jsonarray::add); @@ -28,7 +28,7 @@ index 1516232f116f1d48fe383d8c05c7dcc63b38f96a..523255345df9f4d84c5fa514de42620c BufferedWriter bufferedwriter = Files.newWriter(this.file, StandardCharsets.UTF_8); try { -@@ -135,6 +138,13 @@ public abstract class StoredUserList> { +@@ -134,6 +137,13 @@ public abstract class StoredUserList> { bufferedwriter.close(); } diff --git a/patches/server/0028-Slice-Smooth-Teleports.patch b/patches/server/0027-Slice-Smooth-Teleports.patch similarity index 64% rename from patches/server/0028-Slice-Smooth-Teleports.patch rename to patches/server/0027-Slice-Smooth-Teleports.patch index ff45dba1..3e1cdf02 100644 --- a/patches/server/0028-Slice-Smooth-Teleports.patch +++ b/patches/server/0027-Slice-Smooth-Teleports.patch @@ -7,39 +7,39 @@ Original license: MIT Original project: https://github.com/Cryptite/Slice diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index fd3f177012d82fe774069b4c53f7efef3e9b991f..9b97d5ca67c0e53f318a54465708e21ae906e994 100644 +index d573ae3fee994614bcc6c699bcbe8210874ca414..30f984553e823b3c928b0e2181baf5d2058c2d84 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -303,6 +303,7 @@ public class ServerPlayer extends Player { +@@ -306,6 +306,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple private boolean tpsBar = false; // Purpur private boolean compassBar = false; // Purpur private boolean ramBar = false; // Purpur + public boolean smoothWorldTeleport; // Slice - // Paper start - replace player chunk loader - private final java.util.concurrent.atomic.AtomicReference viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1)); + // Paper start - rewrite chunk system + private ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader; diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 9250db41e26d2ffa96146782e898165591f9e819..2e98c6598e589b498991c745058db3c0efb9cbf6 100644 +index 33fd3c88f84a5d6f7f7c0212f364a83870c88fc7..360b52002fe8bc9dd27a4fe3831ed6f5dfe8d6c6 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -969,10 +969,10 @@ public abstract class PlayerList { - ServerLevel worldserver2 = entityplayer1.serverLevel(); - LevelData worlddata = worldserver2.getLevelData(); +@@ -898,10 +898,10 @@ public abstract class PlayerList { + ServerLevel worldserver1 = entityplayer1.serverLevel(); + LevelData worlddata = worldserver1.getLevelData(); -- entityplayer1.connection.send(new ClientboundRespawnPacket(entityplayer1.createCommonSpawnInfo(worldserver2), (byte) i)); -+ if (!entityplayer.smoothWorldTeleport) entityplayer1.connection.send(new ClientboundRespawnPacket(entityplayer1.createCommonSpawnInfo(worldserver2), (byte) i)); // Slice - entityplayer1.connection.send(new ClientboundSetChunkCacheRadiusPacket(worldserver1.getWorld().getSendViewDistance())); // Spigot // Paper - replace old player chunk management - entityplayer1.connection.send(new ClientboundSetSimulationDistancePacket(worldserver1.getWorld().getSimulationDistance())); // Spigot // Paper - replace old player chunk management -- entityplayer1.connection.teleport(CraftLocation.toBukkit(entityplayer1.position(), worldserver2.getWorld(), entityplayer1.getYRot(), entityplayer1.getXRot())); // CraftBukkit -+ if (!entityplayer.smoothWorldTeleport) entityplayer1.connection.teleport(CraftLocation.toBukkit(entityplayer1.position(), worldserver2.getWorld(), entityplayer1.getYRot(), entityplayer1.getXRot())); // CraftBukkit // Slice - entityplayer1.connection.send(new ClientboundSetDefaultSpawnPositionPacket(worldserver1.getSharedSpawnPos(), worldserver1.getSharedSpawnAngle())); +- entityplayer1.connection.send(new ClientboundRespawnPacket(entityplayer1.createCommonSpawnInfo(worldserver1), (byte) i)); ++ if (!entityplayer.smoothWorldTeleport) entityplayer1.connection.send(new ClientboundRespawnPacket(entityplayer1.createCommonSpawnInfo(worldserver1), (byte) i)); // Slice + entityplayer1.connection.send(new ClientboundSetChunkCacheRadiusPacket(worldserver1.spigotConfig.viewDistance)); // Spigot + entityplayer1.connection.send(new ClientboundSetSimulationDistancePacket(worldserver1.spigotConfig.simulationDistance)); // Spigot +- entityplayer1.connection.teleport(CraftLocation.toBukkit(entityplayer1.position(), worldserver1.getWorld(), entityplayer1.getYRot(), entityplayer1.getXRot())); // CraftBukkit ++ if (!entityplayer.smoothWorldTeleport) entityplayer1.connection.teleport(CraftLocation.toBukkit(entityplayer1.position(), worldserver1.getWorld(), entityplayer1.getYRot(), entityplayer1.getXRot())); // CraftBukkit // Slice + entityplayer1.connection.send(new ClientboundSetDefaultSpawnPositionPacket(worldserver.getSharedSpawnPos(), worldserver.getSharedSpawnAngle())); entityplayer1.connection.send(new ClientboundChangeDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); entityplayer1.connection.send(new ClientboundSetExperiencePacket(entityplayer1.experienceProgress, entityplayer1.totalExperience, entityplayer1.experienceLevel)); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 20cf62169210ba0a5de45ed68e3453cc63a07102..581ef3deffeb66d5d06951e6eadffb05b26a50c4 100644 +index 7a7a2acca5980ab3d79346f47e4153dd6c98939b..cf85b3af38258fa34e8f67d1f002a521cc59c81b 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1348,6 +1348,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1361,6 +1361,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { // Paper end } diff --git a/patches/server/0029-Parchment-Make-FixLight-use-action-bar.patch b/patches/server/0028-Parchment-Make-FixLight-use-action-bar.patch similarity index 68% rename from patches/server/0029-Parchment-Make-FixLight-use-action-bar.patch rename to patches/server/0028-Parchment-Make-FixLight-use-action-bar.patch index c2271356..d395d8f2 100644 --- a/patches/server/0029-Parchment-Make-FixLight-use-action-bar.patch +++ b/patches/server/0028-Parchment-Make-FixLight-use-action-bar.patch @@ -7,34 +7,33 @@ Original license: GPLv3 Original project: https://github.com/ProjectEdenGG/Parchment diff --git a/src/main/java/io/papermc/paper/command/subcommands/FixLightCommand.java b/src/main/java/io/papermc/paper/command/subcommands/FixLightCommand.java -index 56524cbe4303901007e1e7fb3703a19efbf79ae7..e461c736e9f386fd7b6c96757f827bec361b78d8 100644 +index 85950a1aa732ab8c01ad28bec9e0de140e1a172e..8e8d1a38290c2dc3f88deda64d050e89273a5b89 100644 --- a/src/main/java/io/papermc/paper/command/subcommands/FixLightCommand.java +++ b/src/main/java/io/papermc/paper/command/subcommands/FixLightCommand.java -@@ -87,18 +87,21 @@ public final class FixLightCommand implements PaperSubcommand { - lightengine.relight(chunks, +@@ -95,17 +95,20 @@ public final class FixLightCommand implements PaperSubcommand { + ((StarLightLightingProvider)lightengine).starlight$serverRelightChunks(chunks, (final ChunkPos chunkPos) -> { ++relitChunks[0]; - sender.getBukkitEntity().sendMessage(text().color(DARK_AQUA).append( - text("Relit chunk ", BLUE), text(chunkPos.toString()), -- text(", progress: ", BLUE), text((int) (Math.round(100.0 * (double) (relitChunks[0]) / (double) pending[0])) + "%") +- text(", progress: ", BLUE), text(ONE_DECIMAL_PLACES.get().format(100.0 * (double) (relitChunks[0]) / (double) pending[0]) + "%") - )); + sender.getBukkitEntity().sendActionBar(text().color(DARK_AQUA).append( + text("Relighting Chunks: ", DARK_AQUA), text(chunkPos.toString()), + text(" " + relitChunks[0], net.kyori.adventure.text.format.NamedTextColor.YELLOW), + text("/", DARK_AQUA), + text(pending[0] + " ", net.kyori.adventure.text.format.NamedTextColor.YELLOW), -+ text("(" + (int) (Math.round(100.0 * (double) (relitChunks[0]) / (double) pending[0])) + "%)", net.kyori.adventure.text.format.NamedTextColor.YELLOW) ++ text("(" + ONE_DECIMAL_PLACES.get().format(100.0 * (double) (relitChunks[0]) / (double) pending[0]) + "%)", net.kyori.adventure.text.format.NamedTextColor.YELLOW) + )); // Leaf - Parchment - Make FixLight use action bar }, (final int totalRelit) -> { final long end = System.nanoTime(); - final long diff = Math.round(1.0e-6 * (end - start)); sender.getBukkitEntity().sendMessage(text().color(DARK_AQUA).append( - text("Relit ", BLUE), text(totalRelit), -- text(" chunks. Took ", BLUE), text(diff + "ms") +- text(" chunks. Took ", BLUE), text(ONE_DECIMAL_PLACES.get().format(1.0e-6 * (end - start)) + "ms") - )); + text("Relit ", DARK_AQUA), text(totalRelit, net.kyori.adventure.text.format.NamedTextColor.YELLOW), -+ text(" chunks. Took ", DARK_AQUA), text(diff + "ms", net.kyori.adventure.text.format.NamedTextColor.YELLOW) ++ text(" chunks. Took ", DARK_AQUA), text(ONE_DECIMAL_PLACES.get().format(1.0e-6 * (end - start)) + "ms", net.kyori.adventure.text.format.NamedTextColor.YELLOW) + )); // Leaf - Parchment - Make FixLight use action bar if (done != null) { done.run();