From 2df686555dc5e55a02bfc63c47fbca2bf85fdc24 Mon Sep 17 00:00:00 2001 From: granny Date: Fri, 13 Mar 2026 17:54:48 -0700 Subject: [PATCH] 99/103 rejected minecraft source files applied --- .../ai/attributes/RangedAttribute.java.patch | 18 -- .../entity/ai/behavior/AcquirePoi.java.patch | 19 --- .../ai/behavior/InteractWithDoor.java.patch | 37 ---- .../ai/behavior/ShowTradesToPlayer.java.patch | 18 -- ...TransportItemsBetweenContainers.java.patch | 62 ------- .../world/entity/ai/goal/SwellGoal.java.patch | 25 --- .../ai/sensing/NearestBedSensor.java.patch | 19 --- .../world/entity/animal/Animal.java.patch | 42 ----- .../entity/animal/feline/Ocelot.java.patch | 19 --- .../entity/animal/fish/WaterAnimal.java.patch | 20 --- .../world/entity/animal/pig/Pig.java.patch | 30 ---- .../entity/animal/rabbit/Rabbit.java.patch | 34 ---- .../boss/enderdragon/EnderDragon.java.patch | 27 --- .../world/entity/item/ItemEntity.java.patch | 54 ------ .../world/entity/monster/Ghast.java.patch | 22 --- .../world/entity/monster/Phantom.java.patch | 23 --- .../world/entity/monster/Shulker.java.patch | 67 -------- .../entity/monster/piglin/PiglinAi.java.patch | 36 ---- .../WanderingTraderSpawner.java.patch | 29 ---- .../inventory/AbstractFurnaceMenu.java.patch | 25 --- .../world/inventory/ArmorSlot.java.patch | 19 --- .../inventory/ItemCombinerMenu.java.patch | 20 --- .../AbstractFurnaceBlockEntity.java.patch | 41 ----- .../block/entity/BeaconBlockEntity.java.patch | 66 -------- .../entity/ConduitBlockEntity.java.patch | 74 -------- .../server/MinecraftServer.java.patch | 47 ++---- .../server/level/ServerLevel.java.patch | 159 +++++++----------- .../world/clock/ServerClockManager.java.patch | 20 +++ .../ai/attributes/RangedAttribute.java.patch | 10 ++ .../entity/ai/behavior/AcquirePoi.java.patch | 11 ++ .../ai/behavior/InteractWithDoor.java.patch | 29 ++++ .../ai/behavior/ShowTradesToPlayer.java.patch | 10 ++ .../entity/ai/behavior/SleepInBed.java.patch | 18 ++ ...TransportItemsBetweenContainers.java.patch | 54 ++++++ .../world/entity/ai/goal/SwellGoal.java.patch | 17 ++ .../ai/sensing/NearestBedSensor.java.patch | 14 ++ .../world/entity/animal/Animal.java.patch | 34 ++++ .../world/entity/animal/bee/Bee.java.patch | 36 ++-- .../entity/animal/cow/AbstractCow.java.patch | 24 +-- .../entity/animal/dolphin/Dolphin.java.patch | 27 ++- .../entity/animal/equine/Llama.java.patch | 26 +-- .../world/entity/animal/feline/Cat.java.patch | 18 +- .../entity/animal/feline/Ocelot.java.patch | 11 ++ .../entity/animal/fish/WaterAnimal.java.patch | 12 ++ .../animal/golem/CopperGolemAi.java.patch | 28 ++- .../entity/animal/golem/IronGolem.java.patch | 28 ++- .../entity/animal/parrot/Parrot.java.patch | 26 +-- .../world/entity/animal/pig/Pig.java.patch | 22 +++ .../animal/polarbear/PolarBear.java.patch | 22 +-- .../entity/animal/rabbit/Rabbit.java.patch | 26 +++ .../entity/animal/squid/Squid.java.patch | 24 +-- .../world/entity/animal/wolf/Wolf.java.patch | 42 ++--- .../boss/enderdragon/EndCrystal.java.patch | 22 +-- .../boss/enderdragon/EnderDragon.java.patch | 19 +++ .../entity/boss/wither/WitherBoss.java.patch | 34 ++-- .../world/entity/item/ItemEntity.java.patch | 46 +++++ .../world/entity/monster/Creeper.java.patch | 36 ++-- .../world/entity/monster/Ghast.java.patch | 14 ++ .../world/entity/monster/Monster.java.patch | 20 +-- .../world/entity/monster/Phantom.java.patch | 15 ++ .../world/entity/monster/Ravager.java.patch | 18 +- .../world/entity/monster/Shulker.java.patch | 57 +++++++ .../world/entity/monster/Strider.java.patch | 16 +- .../monster/illager/Vindicator.java.patch | 12 +- .../entity/monster/piglin/PiglinAi.java.patch | 29 ++++ .../skeleton/AbstractSkeleton.java.patch | 18 +- .../entity/monster/zombie/Drowned.java.patch | 12 +- .../monster/zombie/ZombieVillager.java.patch | 18 +- .../entity/npc/villager/Villager.java.patch | 70 +++----- .../WanderingTraderSpawner.java.patch | 21 +++ .../inventory/AbstractFurnaceMenu.java.patch | 17 ++ .../world/inventory/AnvilMenu.java.patch | 120 ++++++------- .../world/inventory/ArmorSlot.java.patch | 11 ++ .../inventory/EnchantmentMenu.java.patch | 18 +- .../world/inventory/GrindstoneMenu.java.patch | 62 +++---- .../inventory/ItemCombinerMenu.java.patch | 12 ++ .../level/block/FarmlandBlock.java.patch} | 34 ++-- .../AbstractFurnaceBlockEntity.java.patch | 33 ++++ .../block/entity/BeaconBlockEntity.java.patch | 58 +++++++ .../entity/BeehiveBlockEntity.java.patch | 20 +-- .../level/block/entity/BlockEntity.java.patch | 20 +-- .../entity/ConduitBlockEntity.java.patch | 66 ++++++++ .../block/entity/SignBlockEntity.java.patch | 38 ++--- 83 files changed, 1079 insertions(+), 1548 deletions(-) delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/attributes/RangedAttribute.java.patch delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/behavior/AcquirePoi.java.patch delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java.patch delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/behavior/ShowTradesToPlayer.java.patch delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/behavior/TransportItemsBetweenContainers.java.patch delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/goal/SwellGoal.java.patch delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java.patch delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/Animal.java.patch delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/feline/Ocelot.java.patch delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/fish/WaterAnimal.java.patch delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/pig/Pig.java.patch delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/rabbit/Rabbit.java.patch delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/item/ItemEntity.java.patch delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/Ghast.java.patch delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/Phantom.java.patch delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/Shulker.java.patch delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/piglin/PiglinAi.java.patch delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/npc/wanderingtrader/WanderingTraderSpawner.java.patch delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/inventory/AbstractFurnaceMenu.java.patch delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/inventory/ArmorSlot.java.patch delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/inventory/ItemCombinerMenu.java.patch delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/entity/BeaconBlockEntity.java.patch delete mode 100644 purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/entity/ConduitBlockEntity.java.patch rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/server/MinecraftServer.java.patch (69%) rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/server/level/ServerLevel.java.patch (54%) create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/clock/ServerClockManager.java.patch create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/attributes/RangedAttribute.java.patch create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/behavior/AcquirePoi.java.patch create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java.patch create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/behavior/ShowTradesToPlayer.java.patch create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/behavior/SleepInBed.java.patch create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/behavior/TransportItemsBetweenContainers.java.patch create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/goal/SwellGoal.java.patch create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java.patch create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/Animal.java.patch rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/entity/animal/bee/Bee.java.patch (74%) rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/entity/animal/cow/AbstractCow.java.patch (78%) rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/entity/animal/dolphin/Dolphin.java.patch (72%) rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/entity/animal/equine/Llama.java.patch (60%) rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/entity/animal/feline/Cat.java.patch (56%) create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/feline/Ocelot.java.patch create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/fish/WaterAnimal.java.patch rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/entity/animal/golem/CopperGolemAi.java.patch (55%) rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/entity/animal/golem/IronGolem.java.patch (65%) rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/entity/animal/parrot/Parrot.java.patch (66%) create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/pig/Pig.java.patch rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/entity/animal/polarbear/PolarBear.java.patch (65%) create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/rabbit/Rabbit.java.patch rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/entity/animal/squid/Squid.java.patch (65%) rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/entity/animal/wolf/Wolf.java.patch (84%) rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java.patch (69%) create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/entity/boss/wither/WitherBoss.java.patch (67%) create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/entity/item/ItemEntity.java.patch rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/entity/monster/Creeper.java.patch (55%) create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Ghast.java.patch rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/entity/monster/Monster.java.patch (60%) create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Phantom.java.patch rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/entity/monster/Ravager.java.patch (59%) rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/entity/monster/Strider.java.patch (51%) rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/entity/monster/illager/Vindicator.java.patch (55%) create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/piglin/PiglinAi.java.patch rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/entity/monster/skeleton/AbstractSkeleton.java.patch (55%) rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/entity/monster/zombie/Drowned.java.patch (80%) rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/entity/monster/zombie/ZombieVillager.java.patch (53%) rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/entity/npc/villager/Villager.java.patch (57%) create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/entity/npc/wanderingtrader/WanderingTraderSpawner.java.patch create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/AbstractFurnaceMenu.java.patch rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/inventory/AnvilMenu.java.patch (66%) create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/ArmorSlot.java.patch rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/inventory/EnchantmentMenu.java.patch (76%) rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/inventory/GrindstoneMenu.java.patch (67%) create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/ItemCombinerMenu.java.patch rename purpur-server/minecraft-patches/{rejected/net/minecraft/world/level/block/FarmBlock.java.patch => sources/net/minecraft/world/level/block/FarmlandBlock.java.patch} (66%) create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/BeaconBlockEntity.java.patch rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java.patch (71%) rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/level/block/entity/BlockEntity.java.patch (62%) create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/ConduitBlockEntity.java.patch rename purpur-server/minecraft-patches/{rejected => sources}/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch (61%) diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/attributes/RangedAttribute.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/attributes/RangedAttribute.java.patch deleted file mode 100644 index 4cc493a53..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/attributes/RangedAttribute.java.patch +++ /dev/null @@ -1,18 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/ai/attributes/RangedAttribute.java b/net/minecraft/world/entity/ai/attributes/RangedAttribute.java -index 0a0e5d9fd64182c1bed4c0aa6a40d8b2cdf8bc9d..353d571b4a2bf18414a08239abe2b079e3750d89 100644 ---- a/net/minecraft/world/entity/ai/attributes/RangedAttribute.java -+++ b/net/minecraft/world/entity/ai/attributes/RangedAttribute.java -@@ -29,6 +29,7 @@ public class RangedAttribute extends Attribute { - - @Override - public double sanitizeValue(double value) { -+ if (!org.purpurmc.purpur.PurpurConfig.clampAttributes) return Double.isNaN(value) ? this.minValue : value; // Purpur - Add attribute clamping and armor limit config - return Double.isNaN(value) ? this.minValue : Mth.clamp(value, this.minValue, this.maxValue); - } - } diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/behavior/AcquirePoi.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/behavior/AcquirePoi.java.patch deleted file mode 100644 index bbc9521be..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/behavior/AcquirePoi.java.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/ai/behavior/AcquirePoi.java b/net/minecraft/world/entity/ai/behavior/AcquirePoi.java -index 278addb7dbe4f57e99fb91ce1cd1bf3559e239a3..3e0fd09a0c0047cfe100e878186471090f8909a0 100644 ---- a/net/minecraft/world/entity/ai/behavior/AcquirePoi.java -+++ b/net/minecraft/world/entity/ai/behavior/AcquirePoi.java -@@ -85,7 +85,7 @@ public class AcquirePoi { - }; - // Paper start - optimise POI access - final java.util.List, BlockPos>> poiposes = new java.util.ArrayList<>(); -- io.papermc.paper.util.PoiAccess.findNearestPoiPositions(poiManager, acquirablePois, predicate1, mob.blockPosition(), 48, 48*48, PoiManager.Occupancy.HAS_SPACE, false, 5, poiposes); -+ io.papermc.paper.util.PoiAccess.findNearestPoiPositions(poiManager, acquirablePois, predicate1, mob.blockPosition(), level.purpurConfig.villagerAcquirePoiSearchRadius, level.purpurConfig.villagerAcquirePoiSearchRadius*level.purpurConfig.villagerAcquirePoiSearchRadius, PoiManager.Occupancy.HAS_SPACE, false, 5, poiposes); // Purpur - Configurable villager search radius - final Set, BlockPos>> set = new java.util.HashSet<>(poiposes.size()); - for (final Pair, BlockPos> poiPose : poiposes) { - if (predicate.test(level, poiPose.getSecond())) { diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java.patch deleted file mode 100644 index d167e7f46..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java b/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java -index df185d375658d765b07648dfb42ea56c84be671e..5c845d78e8baee41809e0678e3d99523368a2882 100644 ---- a/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java -+++ b/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java -@@ -55,7 +55,7 @@ public class InteractWithDoor { - Node nextNode = path.getNextNode(); - BlockPos blockPos = previousNode.asBlockPos(); - BlockState blockState = level.getBlockState(blockPos); -- if (blockState.is(BlockTags.MOB_INTERACTABLE_DOORS, state -> state.getBlock() instanceof DoorBlock)) { -+ if (blockState.is(BlockTags.MOB_INTERACTABLE_DOORS, state -> state.getBlock() instanceof DoorBlock)&& !DoorBlock.requiresRedstone(entity.level(), blockState, blockPos)) { // Purpur - Option to make doors require redstone - DoorBlock doorBlock = (DoorBlock)blockState.getBlock(); - if (!doorBlock.isOpen(blockState)) { - // CraftBukkit start - entities opening doors -@@ -72,7 +72,7 @@ public class InteractWithDoor { - - BlockPos blockPos1 = nextNode.asBlockPos(); - BlockState blockState1 = level.getBlockState(blockPos1); -- if (blockState1.is(BlockTags.MOB_INTERACTABLE_DOORS, state -> state.getBlock() instanceof DoorBlock)) { -+ if (blockState1.is(BlockTags.MOB_INTERACTABLE_DOORS, state -> state.getBlock() instanceof DoorBlock) && !DoorBlock.requiresRedstone(entity.level(), blockState1, blockPos1)) { // Purpur - Option to make doors require redstone - DoorBlock doorBlock1 = (DoorBlock)blockState1.getBlock(); - if (!doorBlock1.isOpen(blockState1)) { - // CraftBukkit start - entities opening doors -@@ -118,7 +118,7 @@ public class InteractWithDoor { - iterator.remove(); - } else { - BlockState blockState = level.getBlockState(blockPos); -- if (!blockState.is(BlockTags.MOB_INTERACTABLE_DOORS, state -> state.getBlock() instanceof DoorBlock)) { -+ if (!blockState.is(BlockTags.MOB_INTERACTABLE_DOORS, state -> state.getBlock() instanceof DoorBlock) || DoorBlock.requiresRedstone(entity.level(), blockState, blockPos)) { // Purpur - Option to make doors require redstone - iterator.remove(); - } else { - DoorBlock doorBlock = (DoorBlock)blockState.getBlock(); diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/behavior/ShowTradesToPlayer.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/behavior/ShowTradesToPlayer.java.patch deleted file mode 100644 index 67b8c7215..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/behavior/ShowTradesToPlayer.java.patch +++ /dev/null @@ -1,18 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/ai/behavior/ShowTradesToPlayer.java b/net/minecraft/world/entity/ai/behavior/ShowTradesToPlayer.java -index 338f9850a9ee968ade1a5554936a10b8a3786fe5..8cac46b6fd025f7f10b17903579f021482ed4b18 100644 ---- a/net/minecraft/world/entity/ai/behavior/ShowTradesToPlayer.java -+++ b/net/minecraft/world/entity/ai/behavior/ShowTradesToPlayer.java -@@ -45,6 +45,7 @@ public class ShowTradesToPlayer extends Behavior { - - @Override - public boolean canStillUse(ServerLevel level, Villager entity, long gameTime) { -+ if (!entity.level().purpurConfig.villagerDisplayTradeItem) return false; // Purpur - Option for villager display trade item - return this.checkExtraStartConditions(level, entity) - && this.lookTime > 0 - && entity.getBrain().getMemory(MemoryModuleType.INTERACTION_TARGET).isPresent(); diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/behavior/TransportItemsBetweenContainers.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/behavior/TransportItemsBetweenContainers.java.patch deleted file mode 100644 index 2fc0b683e..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/behavior/TransportItemsBetweenContainers.java.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/ai/behavior/TransportItemsBetweenContainers.java b/net/minecraft/world/entity/ai/behavior/TransportItemsBetweenContainers.java -index 3741e32fa1aa85e3b5b45c3b05fcb3a0a807a6e7..2a7cda7fbc400a13e7ab71a6a82496068d9c7ae6 100644 ---- a/net/minecraft/world/entity/ai/behavior/TransportItemsBetweenContainers.java -+++ b/net/minecraft/world/entity/ai/behavior/TransportItemsBetweenContainers.java -@@ -285,7 +285,7 @@ public class TransportItemsBetweenContainers extends Behavior { - LevelChunk chunkNow = level.getChunkSource().getChunkNow(chunkPos.x, chunkPos.z); - if (chunkNow != null) { - for (BlockEntity blockEntity : chunkNow.getBlockEntities().values()) { -- if (blockEntity instanceof ChestBlockEntity chestBlockEntity) { -+ if (blockEntity instanceof net.minecraft.world.level.block.entity.BaseContainerBlockEntity chestBlockEntity) { // Purpur - copper golem can place items in barrels or shulkers option - double d1 = chestBlockEntity.getBlockPos().distToCenterSqr(mob.position()); - if (d1 < d) { - TransportItemsBetweenContainers.TransportItemTarget transportItemTarget1 = this.isTargetValidToPick( -@@ -369,7 +369,11 @@ public class TransportItemsBetweenContainers extends Behavior { - } - - private boolean isTargetBlocked(Level level, TransportItemsBetweenContainers.TransportItemTarget target) { -- return ChestBlock.isChestBlockedAt(level, target.pos); -+ // Purpur start - copper golem can place items in barrels or shulkers option -+ boolean isBarrelBlocked = !level.purpurConfig.copperGolemCanOpenBarrel && target.state.is(net.minecraft.world.level.block.Blocks.BARREL); -+ boolean isShulkerBlocked = !level.purpurConfig.copperGolemCanOpenShulker && target.blockEntity instanceof net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity shulkerBoxBlockEntity && !net.minecraft.world.level.block.ShulkerBoxBlock.canOpen(target.state, level, target.pos, shulkerBoxBlockEntity); -+ return target.state.is(net.minecraft.world.level.block.Blocks.BARREL) ? isBarrelBlocked : isShulkerBlocked || net.minecraft.world.level.block.ChestBlock.isChestBlockedAt(level, target.pos); -+ // Purpur end - copper golem can place items in barrels or shulkers option - } - - private boolean targetHasNotChanged(Level level, TransportItemsBetweenContainers.TransportItemTarget target) { -@@ -446,7 +450,7 @@ public class TransportItemsBetweenContainers extends Behavior { - } - - private boolean isWantedBlock(PathfinderMob mob, BlockState state) { -- return isPickingUpItems(mob) ? this.sourceBlockType.test(state) : this.destinationBlockType.test(state); -+ return isPickingUpItems(mob) ? this.sourceBlockType.test(state) : (mob.level().purpurConfig.copperGolemCanOpenBarrel && state.is(net.minecraft.world.level.block.Blocks.BARREL)) || (mob.level().purpurConfig.copperGolemCanOpenShulker && state.is(net.minecraft.tags.BlockTags.SHULKER_BOXES)) || this.destinationBlockType.test(state); // Purpur - copper golem can place items in barrels or shulkers option - } - - private static double getInteractionRange(PathfinderMob mob) { -@@ -488,6 +492,11 @@ public class TransportItemsBetweenContainers extends Behavior { - } - - private static boolean matchesLeavingItemsRequirement(PathfinderMob mob, Container container) { -+ // Purpur start - copper golem can place items in barrels or shulkers option -+ if (mob.level().purpurConfig.copperGolemCanOpenShulker && container instanceof net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity && mob.getMainHandItem().is(net.minecraft.tags.ItemTags.SHULKER_BOXES)) { -+ return false; -+ } -+ // Purpur end - copper golem can place items in barrels or shulkers option - return container.isEmpty() || hasItemMatchingHandItem(mob, container); - } - -@@ -525,7 +534,7 @@ public class TransportItemsBetweenContainers extends Behavior { - int i = 0; - - for (ItemStack itemStack : container) { -- if (!itemStack.isEmpty()) { -+ if (!itemStack.isEmpty() && (!(container instanceof net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity) || !itemStack.is(net.minecraft.tags.ItemTags.SHULKER_BOXES))) { // Purpur - copper golem can place items in barrels or shulkers option - int min = Math.min(itemStack.getCount(), 16); - return container.removeItem(i, min); - } diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/goal/SwellGoal.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/goal/SwellGoal.java.patch deleted file mode 100644 index 7789425e2..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/goal/SwellGoal.java.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/ai/goal/SwellGoal.java b/net/minecraft/world/entity/ai/goal/SwellGoal.java -index 2bc0c7f5973d5d5695ec291f404a836a78e8348e..ccbd344a49a568e97606c364082ab3f74ad5e6ed 100644 ---- a/net/minecraft/world/entity/ai/goal/SwellGoal.java -+++ b/net/minecraft/world/entity/ai/goal/SwellGoal.java -@@ -47,6 +47,14 @@ public class SwellGoal extends Goal { - this.creeper.setSwellDir(-1); - } else { - this.creeper.setSwellDir(1); -+ // Purpur start - option to allow creeper to encircle target when fusing -+ if (this.creeper.level().purpurConfig.creeperEncircleTarget) { -+ net.minecraft.world.phys.Vec3 relative = this.creeper.position().subtract(this.target.position()); -+ relative = relative.yRot((float) Math.PI / 3).normalize().multiply(2, 2, 2); -+ net.minecraft.world.phys.Vec3 destination = this.target.position().add(relative); -+ this.creeper.getNavigation().moveTo(destination.x, destination.y, destination.z, 1); -+ } -+ // Purpur end - option to allow creeper to encircle target when fusing - } - } - } diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java.patch deleted file mode 100644 index b755d3dc8..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java b/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java -index 066faa704338c573472381e1ebd063e0d52aaaa4..1f96fd5085bacb4c584576c7cb9f51e7898e9b03 100644 ---- a/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java -+++ b/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(), level.purpurConfig.villagerNearestBedSensorSearchRadius, PoiManager.Occupancy.ANY, false, Integer.MAX_VALUE, poiposes); // Purpur - Configurable villager search radius - Path path = AcquirePoi.findPathToPois(entity, new java.util.HashSet<>(poiposes)); - // Paper end - optimise POI access - if (path != null && path.canReach()) { diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/Animal.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/Animal.java.patch deleted file mode 100644 index 04d5e34b7..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/Animal.java.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/animal/Animal.java b/net/minecraft/world/entity/animal/Animal.java -index 023b68549e3b185d8ad2f505f34bb59556bbf961..2e7e7c1913f5cbc20ce116c5ae3e185fc83094c0 100644 ---- a/net/minecraft/world/entity/animal/Animal.java -+++ b/net/minecraft/world/entity/animal/Animal.java -@@ -146,7 +146,7 @@ public abstract class Animal extends AgeableMob { - ItemStack itemInHand = player.getItemInHand(hand); - if (this.isFood(itemInHand)) { - int age = this.getAge(); -- if (player instanceof ServerPlayer serverPlayer && age == 0 && this.canFallInLove()) { -+ if (player instanceof ServerPlayer serverPlayer && age == 0 && this.canFallInLove() && (this.level().purpurConfig.animalBreedingCooldownSeconds <= 0 || !this.level().hasBreedingCooldown(player.getUUID(), this.getClass()))) { // Purpur - Add adjustable breeding cooldown to config - final ItemStack breedCopy = itemInHand.copy(); // Paper - Fix EntityBreedEvent copying - this.usePlayerItem(player, hand, itemInHand); - this.setInLove(serverPlayer, breedCopy); // Paper - Fix EntityBreedEvent copying -@@ -227,10 +227,20 @@ public abstract class Animal extends AgeableMob { - public void spawnChildFromBreeding(ServerLevel level, Animal partner) { - AgeableMob breedOffspring = this.getBreedOffspring(level, partner); - if (breedOffspring != null) { -- breedOffspring.setBaby(true); -- breedOffspring.snapTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F); -+ //breedOffspring.setBaby(true); // Purpur - Add adjustable breeding cooldown to config - moved down -+ //breedOffspring.snapTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F); // Purpur - Add adjustable breeding cooldown to config - moved down - // CraftBukkit start - Call EntityBreedEvent - ServerPlayer breeder = Optional.ofNullable(this.getLoveCause()).or(() -> Optional.ofNullable(partner.getLoveCause())).orElse(null); -+ // Purpur start - Add adjustable breeding cooldown to config -+ if (breeder != null && level.purpurConfig.animalBreedingCooldownSeconds > 0) { -+ if (level.hasBreedingCooldown(breeder.getUUID(), this.getClass())) { -+ return; -+ } -+ level.addBreedingCooldown(breeder.getUUID(), this.getClass()); -+ } -+ breedOffspring.setBaby(true); -+ breedOffspring.snapTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F); -+ // Purpur end - Add adjustable breeding cooldown to config - int experience = this.getRandom().nextInt(7) + 1; - org.bukkit.event.entity.EntityBreedEvent entityBreedEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreedEvent(breedOffspring, this, partner, breeder, this.breedItem, experience); - if (entityBreedEvent.isCancelled()) { diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/feline/Ocelot.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/feline/Ocelot.java.patch deleted file mode 100644 index 5e42227e5..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/feline/Ocelot.java.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/animal/feline/Ocelot.java b/net/minecraft/world/entity/animal/feline/Ocelot.java -index cf940de8767df6d07551d7a221a0e87df4e41785..94fdbae92dabf7505a7c7b518d4c07b4f68c8e9c 100644 ---- a/net/minecraft/world/entity/animal/feline/Ocelot.java -+++ b/net/minecraft/world/entity/animal/feline/Ocelot.java -@@ -234,7 +234,7 @@ public class Ocelot extends Animal { - public boolean checkSpawnObstruction(LevelReader level) { - if (level.isUnobstructed(this) && !level.containsAnyLiquid(this.getBoundingBox())) { - BlockPos blockPos = this.blockPosition(); -- if (blockPos.getY() < level.getSeaLevel()) { -+ if (!level().purpurConfig.ocelotSpawnUnderSeaLevel && blockPos.getY() < level.getSeaLevel()) { // Purpur - Option Ocelot Spawn Under Sea Level - return false; - } - diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/fish/WaterAnimal.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/fish/WaterAnimal.java.patch deleted file mode 100644 index 6f19ad71b..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/fish/WaterAnimal.java.patch +++ /dev/null @@ -1,20 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/animal/fish/WaterAnimal.java b/net/minecraft/world/entity/animal/fish/WaterAnimal.java -index 3965cb8ae6fdd8d9d0135e6695463e6bef624fe2..9ff11eb96bc8d0c9bd611c8d45d8799c67f1fb61 100644 ---- a/net/minecraft/world/entity/animal/fish/WaterAnimal.java -+++ b/net/minecraft/world/entity/animal/fish/WaterAnimal.java -@@ -76,8 +76,7 @@ public abstract class WaterAnimal extends PathfinderMob { - seaLevel = level.getMinecraftWorld().paperConfig().entities.spawning.wateranimalSpawnHeight.maximum.or(seaLevel); - i = level.getMinecraftWorld().paperConfig().entities.spawning.wateranimalSpawnHeight.minimum.or(i); - // Paper end - Make water animal spawn height configurable -- return pos.getY() >= i -- && pos.getY() <= seaLevel -+ return ((spawnReason == EntitySpawnReason.SPAWNER && level.getMinecraftWorld().purpurConfig.spawnerFixMC238526) || (pos.getY() >= i && pos.getY() <= seaLevel)) // Purpur - MC-238526 - Fix spawner not spawning water animals correctly - && level.getFluidState(pos.below()).is(FluidTags.WATER) - && level.getBlockState(pos.above()).is(Blocks.WATER); - } diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/pig/Pig.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/pig/Pig.java.patch deleted file mode 100644 index c2fe78a8e..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/pig/Pig.java.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/animal/pig/Pig.java b/net/minecraft/world/entity/animal/pig/Pig.java -index 8f5d1e2d98472e8e313fad285bd1629aea4173a9..943bd459554e9f3374978e595ba369a479d44941 100644 ---- a/net/minecraft/world/entity/animal/pig/Pig.java -+++ b/net/minecraft/world/entity/animal/pig/Pig.java -@@ -138,6 +138,19 @@ public class Pig extends Animal implements ItemSteerable { - @Override - public InteractionResult mobInteract(Player player, InteractionHand hand) { - boolean isFood = this.isFood(player.getItemInHand(hand)); -+ // Purpur start - Pigs give saddle back -+ if (level().purpurConfig.pigGiveSaddleBack && player.isSecondaryUseActive() && !isFood && isSaddled() && !isVehicle()) { -+ this.setItemSlot(EquipmentSlot.SADDLE, ItemStack.EMPTY); -+ if (!player.getAbilities().instabuild) { -+ ItemStack saddle = new ItemStack(Items.SADDLE); -+ if (!player.getInventory().add(saddle)) { -+ player.drop(saddle, false); -+ } -+ } -+ return InteractionResult.SUCCESS; -+ } -+ // Purpur end - Pigs give saddle back -+ - if (!isFood && this.isSaddled() && !this.isVehicle() && !player.isSecondaryUseActive()) { - if (!this.level().isClientSide()) { - player.startRiding(this); diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/rabbit/Rabbit.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/rabbit/Rabbit.java.patch deleted file mode 100644 index b237b32c4..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/rabbit/Rabbit.java.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/animal/rabbit/Rabbit.java b/net/minecraft/world/entity/animal/rabbit/Rabbit.java -index 17e58836d18afc7cfcc1cf7a8ac5b9e66ceb5f0d..d5e7599c23405eb5a4519e2dfd93ddbe2853fa3b 100644 ---- a/net/minecraft/world/entity/animal/rabbit/Rabbit.java -+++ b/net/minecraft/world/entity/animal/rabbit/Rabbit.java -@@ -404,10 +404,23 @@ public class Rabbit extends Animal { - } - - this.setVariant(randomRabbitVariant); -+ -+ // Purpur start - Special mobs naturally spawn -+ if (randomRabbitVariant != Variant.EVIL && level.getLevel().purpurConfig.rabbitNaturalToast > 0D && random.nextDouble() <= level.getLevel().purpurConfig.rabbitNaturalToast) { -+ setCustomName(Component.translatable("Toast")); -+ } -+ // Purpur end - Special mobs naturally spawn -+ - return super.finalizeSpawn(level, difficulty, spawnReason, spawnGroupData); - } - - private static Rabbit.Variant getRandomRabbitVariant(LevelAccessor level, BlockPos pos) { -+ // Purpur start - Special mobs naturally spawn -+ Level world = level.getMinecraftWorld(); -+ if (world.purpurConfig.rabbitNaturalKiller > 0D && world.getRandom().nextDouble() <= world.purpurConfig.rabbitNaturalKiller) { -+ return Rabbit.Variant.EVIL; -+ } -+ // Purpur end - Special mobs naturally spawn - Holder biome = level.getBiome(pos); - int randomInt = level.getRandom().nextInt(100); - if (biome.is(BiomeTags.SPAWNS_WHITE_RABBITS)) { diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch deleted file mode 100644 index 73fd0feef..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java -index 1daf8f52148043339f723aaebdf6135763dd805b..9c38e3b8c09caa2701a207b91761f344c5e53385 100644 ---- a/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java -+++ b/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java -@@ -957,6 +957,7 @@ public class EnderDragon extends Mob implements Enemy { - - @Override - protected boolean canRide(Entity entity) { -+ if (this.level().purpurConfig.enderDragonCanRideVehicles) return this.boardingCooldown <= 0; // Purpur - Configs for if Wither/Ender Dragon can ride vehicles - return false; - } - -@@ -992,7 +993,7 @@ public class EnderDragon extends Mob implements Enemy { - boolean flag = level.getGameRules().get(GameRules.MOB_DROPS); - int i = 500; - -- if (this.dragonFight != null && !this.dragonFight.hasPreviouslyKilledDragon()) { -+ if (this.dragonFight != null && (level().purpurConfig.enderDragonAlwaysDropsFullExp || !this.dragonFight.hasPreviouslyKilledDragon())) { // Purpur - Ender dragon always drop full exp - i = 12000; - } - diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/item/ItemEntity.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/item/ItemEntity.java.patch deleted file mode 100644 index 4b055ac11..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/item/ItemEntity.java.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java -index e82bb8f2d2b0e771dc371fd7e709116e1f5f204f..ddf7fa8e67440beb102b6bf91b30f2b340b52a8e 100644 ---- a/net/minecraft/world/entity/item/ItemEntity.java -+++ b/net/minecraft/world/entity/item/ItemEntity.java -@@ -54,6 +54,12 @@ public class ItemEntity extends Entity implements TraceableEntity { - public boolean canMobPickup = true; // Paper - Item#canEntityPickup - private int despawnRate = -1; // Paper - Alternative item-despawn-rate - public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Friction API -+ // Purpur start - Item entity immunities -+ public boolean immuneToCactus = false; -+ public boolean immuneToExplosion = false; -+ public boolean immuneToFire = false; -+ public boolean immuneToLightning = false; -+ // Purpur end - Item entity immunities - - public ItemEntity(EntityType type, Level level) { - super(type, level); -@@ -330,7 +336,16 @@ public class ItemEntity extends Entity implements TraceableEntity { - - @Override - public final boolean hurtServer(ServerLevel level, DamageSource damageSource, float amount) { -- if (this.isInvulnerableToBase(damageSource)) { -+ // Purpur start - Item entity immunities -+ if ( -+ (immuneToCactus && damageSource.is(net.minecraft.world.damagesource.DamageTypes.CACTUS)) || -+ (immuneToFire && (damageSource.is(net.minecraft.tags.DamageTypeTags.IS_FIRE) || damageSource.is(net.minecraft.world.damagesource.DamageTypes.ON_FIRE) || damageSource.is(net.minecraft.world.damagesource.DamageTypes.IN_FIRE))) || -+ (immuneToLightning && damageSource.is(net.minecraft.world.damagesource.DamageTypes.LIGHTNING_BOLT)) || -+ (immuneToExplosion && damageSource.is(net.minecraft.tags.DamageTypeTags.IS_EXPLOSION)) -+ ) { -+ return false; -+ } else if (this.isInvulnerableToBase(damageSource)) { -+ // Purpur end - Item entity immunities - return false; - } else if (!level.getGameRules().get(GameRules.MOB_GRIEFING) && damageSource.getEntity() instanceof Mob) { - return false; -@@ -508,6 +523,12 @@ public class ItemEntity extends Entity implements TraceableEntity { - public void setItem(ItemStack stack) { - this.getEntityData().set(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 -+ // Purpur start - Item entity immunities -+ if (level().purpurConfig.itemImmuneToCactus.contains(stack.getItem())) immuneToCactus = true; -+ if (level().purpurConfig.itemImmuneToExplosion.contains(stack.getItem())) immuneToExplosion = true; -+ if (level().purpurConfig.itemImmuneToFire.contains(stack.getItem())) immuneToFire = true; -+ if (level().purpurConfig.itemImmuneToLightning.contains(stack.getItem())) immuneToLightning = true; -+ // level end - Item entity immunities - } - - @Override diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/Ghast.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/Ghast.java.patch deleted file mode 100644 index 10d4b8c5a..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/Ghast.java.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/monster/Ghast.java b/net/minecraft/world/entity/monster/Ghast.java -index 605c47f3bd5c4e72389587d50e70fcd57f2a2b27..b8774eb91d21e9f154cc70c5d3bd26de25be41c4 100644 ---- a/net/minecraft/world/entity/monster/Ghast.java -+++ b/net/minecraft/world/entity/monster/Ghast.java -@@ -156,6 +156,11 @@ public class Ghast extends Mob implements Enemy { - public static boolean checkGhastSpawnRules( - EntityType entityType, LevelAccessor level, EntitySpawnReason spawnReason, BlockPos pos, RandomSource random - ) { -+ // Purpur start - Config to disable hostile mob spawn on ice -+ if (net.minecraft.world.entity.monster.Monster.canSpawnInBlueAndPackedIce(level, pos)) { -+ return false; -+ } -+ // Purpur end - Config to disable hostile mob spawn on ice - return level.getDifficulty() != Difficulty.PEACEFUL && random.nextInt(20) == 0 && checkMobSpawnRules(entityType, level, spawnReason, pos, random); - } - diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/Phantom.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/Phantom.java.patch deleted file mode 100644 index 5f09ce019..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/Phantom.java.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/monster/Phantom.java b/net/minecraft/world/entity/monster/Phantom.java -index 62c40a04a105eff471599c4535239fee9726dbd1..d26b7970490a2a108affee11c3fb74e38509d92b 100644 ---- a/net/minecraft/world/entity/monster/Phantom.java -+++ b/net/minecraft/world/entity/monster/Phantom.java -@@ -166,7 +166,11 @@ public class Phantom extends Mob implements Enemy { - ServerLevelAccessor level, DifficultyInstance difficulty, EntitySpawnReason spawnReason, @Nullable SpawnGroupData spawnGroupData - ) { - this.anchorPoint = this.blockPosition().above(5); -- this.setPhantomSize(0); -+ // Purpur start - Configurable phantom size -+ int min = level.getLevel().purpurConfig.phantomMinSize; -+ int max = level.getLevel().purpurConfig.phantomMaxSize; -+ this.setPhantomSize(min == max ? min : level.getRandom().nextInt(max + 1 - min) + min); -+ // Purpur end - Configurable phantom size - return super.finalizeSpawn(level, difficulty, spawnReason, spawnGroupData); - } - diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/Shulker.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/Shulker.java.patch deleted file mode 100644 index 84f645cc4..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/Shulker.java.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/monster/Shulker.java b/net/minecraft/world/entity/monster/Shulker.java -index 935c608ba0fc2246a3f79bf4865cfeb6fe68b0f4..6e8400c4d523da8799d586c5c9019ae78710fbcb 100644 ---- a/net/minecraft/world/entity/monster/Shulker.java -+++ b/net/minecraft/world/entity/monster/Shulker.java -@@ -93,6 +93,21 @@ public class Shulker extends AbstractGolem implements Enemy { - this.lookControl = new Shulker.ShulkerLookControl(this); - } - -+ // Purpur start - Shulker change color with dye -+ @Override -+ protected net.minecraft.world.InteractionResult mobInteract(Player player, net.minecraft.world.InteractionHand hand) { -+ net.minecraft.world.item.ItemStack itemstack = player.getItemInHand(hand); -+ if (player.level().purpurConfig.shulkerChangeColorWithDye && itemstack.getItem() instanceof net.minecraft.world.item.DyeItem dye && dye.getDyeColor() != this.getColor()) { -+ this.setVariant(Optional.of(dye.getDyeColor())); -+ if (!player.getAbilities().instabuild) { -+ itemstack.shrink(1); -+ } -+ return net.minecraft.world.InteractionResult.SUCCESS; -+ } -+ return super.mobInteract(player, hand); -+ } -+ // Purpur end - Shulker change color with dye -+ - @Override - protected void registerGoals() { - this.goalSelector.addGoal(1, new LookAtPlayerGoal(this, Player.class, 8.0F, 0.02F, true)); -@@ -454,11 +469,21 @@ public class Shulker extends AbstractGolem implements Enemy { - private void hitByShulkerBullet() { - Vec3 vec3 = this.position(); - AABB boundingBox = this.getBoundingBox(); -- if (!this.isClosed() && this.teleportSomewhere()) { -- int size = this.level().getEntities(EntityType.SHULKER, boundingBox.inflate(8.0), Entity::isAlive).size(); -- float f = (size - 1) / 5.0F; -- if (!(this.level().random.nextFloat() < f)) { -+ // Purpur start - Shulker spawn from bullet options -+ if ((!this.level().purpurConfig.shulkerSpawnFromBulletRequireOpenLid || !this.isClosed()) && this.teleportSomewhere()) { -+ float chance = this.level().purpurConfig.shulkerSpawnFromBulletBaseChance; -+ if (!this.level().purpurConfig.shulkerSpawnFromBulletNearbyEquation.isBlank()) { -+ int nearby = this.level().getEntities((net.minecraft.world.level.entity.EntityTypeTest) EntityType.SHULKER, boundingBox.inflate(this.level().purpurConfig.shulkerSpawnFromBulletNearbyRange), Entity::isAlive).size(); -+ try { -+ chance -= ((Number) scriptEngine.eval("let nearby = " + nearby + "; " + this.level().purpurConfig.shulkerSpawnFromBulletNearbyEquation)).floatValue(); -+ } catch (javax.script.ScriptException e) { -+ e.printStackTrace(); -+ chance -= (nearby - 1) / 5.0F; -+ } -+ } -+ if (this.level().random.nextFloat() <= chance) { - Shulker shulker = EntityType.SHULKER.create(this.level(), EntitySpawnReason.BREEDING); -+ // Purpur end - Shulker spawn from bullet options - if (shulker != null) { - shulker.setVariant(this.getVariant()); - shulker.snapTo(vec3); -@@ -565,7 +590,7 @@ public class Shulker extends AbstractGolem implements Enemy { - } - - public Optional getVariant() { -- return Optional.ofNullable(this.getColor()); -+ return Optional.ofNullable(this.level().purpurConfig.shulkerSpawnFromBulletRandomColor ? DyeColor.random(this.level().random) : this.getColor()); // Purpur - Shulker spawn from bullet options - } - - public @Nullable DyeColor getColor() { diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/piglin/PiglinAi.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/piglin/PiglinAi.java.patch deleted file mode 100644 index 02e7afa93..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/piglin/PiglinAi.java.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/monster/piglin/PiglinAi.java b/net/minecraft/world/entity/monster/piglin/PiglinAi.java -index 436b17a709517766fdb9d7198f0ae457facd90a1..49294ccf5c4ac3acf7793c8d7cbc449a0d0f44e6 100644 ---- a/net/minecraft/world/entity/monster/piglin/PiglinAi.java -+++ b/net/minecraft/world/entity/monster/piglin/PiglinAi.java -@@ -660,7 +660,10 @@ public class PiglinAi { - - public static boolean isWearingSafeArmor(LivingEntity entity) { - for (EquipmentSlot equipmentSlot : EquipmentSlotGroup.ARMOR) { -- if (entity.getItemBySlot(equipmentSlot).is(ItemTags.PIGLIN_SAFE_ARMOR)) { -+ // Purpur start - piglins ignore gold-trimmed armor -+ net.minecraft.world.item.ItemStack itemStack = entity.getItemBySlot(equipmentSlot); -+ if (itemStack.is(ItemTags.PIGLIN_SAFE_ARMOR) || (entity.level().purpurConfig.piglinIgnoresArmorWithGoldTrim && isWearingGoldTrim(itemStack))) { -+ // Purpur end - piglins ignore gold-trimmed armor - return true; - } - } -@@ -668,6 +671,13 @@ public class PiglinAi { - return false; - } - -+ // Purpur start - piglins ignore gold-trimmed armor -+ private static boolean isWearingGoldTrim(net.minecraft.world.item.ItemStack itemstack) { -+ net.minecraft.world.item.equipment.trim.ArmorTrim armorTrim = itemstack.getComponents().get(net.minecraft.core.component.DataComponents.TRIM); -+ return armorTrim != null && armorTrim.material().is(net.minecraft.world.item.equipment.trim.TrimMaterials.GOLD); -+ } -+ // Purpur end - piglins ignore gold-trimmed armor -+ - private static void stopWalking(Piglin piglin) { - piglin.getBrain().eraseMemory(MemoryModuleType.WALK_TARGET); - piglin.getNavigation().stop(); diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/npc/wanderingtrader/WanderingTraderSpawner.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/npc/wanderingtrader/WanderingTraderSpawner.java.patch deleted file mode 100644 index 7bda9ec17..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/npc/wanderingtrader/WanderingTraderSpawner.java.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/npc/wanderingtrader/WanderingTraderSpawner.java b/net/minecraft/world/entity/npc/wanderingtrader/WanderingTraderSpawner.java -index 44b43ca9fba989f975133f966cedd582a93d3350..7aef337fc0b6fd52c27ad5ca3f38d74f213d9725 100644 ---- a/net/minecraft/world/entity/npc/wanderingtrader/WanderingTraderSpawner.java -+++ b/net/minecraft/world/entity/npc/wanderingtrader/WanderingTraderSpawner.java -@@ -134,7 +134,17 @@ public class WanderingTraderSpawner implements CustomSpawner { - int i1 = pos.getX() + this.random.nextInt(maxDistance * 2) - maxDistance; - int i2 = pos.getZ() + this.random.nextInt(maxDistance * 2) - maxDistance; - int height = level.getHeight(Heightmap.Types.WORLD_SURFACE, i1, i2); -- BlockPos blockPos1 = new BlockPos(i1, height, i2); -+ // Purpur start - Allow toggling special MobSpawners per world - allow traders to spawn below nether roof -+ BlockPos.MutableBlockPos blockPos1 = new BlockPos.MutableBlockPos(i1, height, i2); -+ if (level.dimensionType().hasCeiling()) { -+ do { -+ blockPos1.relative(net.minecraft.core.Direction.DOWN); -+ } while (!level.getBlockState(blockPos1).isAir()); -+ do { -+ blockPos1.relative(net.minecraft.core.Direction.DOWN); -+ } while (level.getBlockState(blockPos1).isAir() && blockPos1.getY() > 0); -+ } -+ // Purpur end - Allow toggling special MobSpawners per world - if (placementType.isSpawnPositionOk(level, blockPos1, EntityType.WANDERING_TRADER)) { - blockPos = blockPos1; - break; diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/inventory/AbstractFurnaceMenu.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/inventory/AbstractFurnaceMenu.java.patch deleted file mode 100644 index 75bee4c26..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/inventory/AbstractFurnaceMenu.java.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/inventory/AbstractFurnaceMenu.java b/net/minecraft/world/inventory/AbstractFurnaceMenu.java -index 6e13b05ebd924d98066624d9ff6ee7f61e248617..9304bc239ffafbef3b34c5a5a42039c86acd5e80 100644 ---- a/net/minecraft/world/inventory/AbstractFurnaceMenu.java -+++ b/net/minecraft/world/inventory/AbstractFurnaceMenu.java -@@ -121,7 +121,13 @@ public abstract class AbstractFurnaceMenu extends RecipeBookMenu { - } else if (slotIndex != 1 && slotIndex != 0) { - if (this.canSmelt(item)) { - if (!this.moveItemStackTo(item, 0, 1, false)) { -- return ItemStack.EMPTY; -+ // Purpur start - Added the ability to add combustible items -+ if (this.isFuel(item)) { -+ if (!this.moveItemStackTo(item, 1, 2, false)) { -+ return ItemStack.EMPTY; -+ } -+ } -+ // Purpur end - Added the ability to add combustible items - } - } else if (this.isFuel(item)) { - if (!this.moveItemStackTo(item, 1, 2, false)) { diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/inventory/ArmorSlot.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/inventory/ArmorSlot.java.patch deleted file mode 100644 index 1e03bf446..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/inventory/ArmorSlot.java.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/inventory/ArmorSlot.java b/net/minecraft/world/inventory/ArmorSlot.java -index f9fef56709a40e2581170a807a0035b593795b05..cdc95952311e6a2df757c3d8ec1224e3e5ad3069 100644 ---- a/net/minecraft/world/inventory/ArmorSlot.java -+++ b/net/minecraft/world/inventory/ArmorSlot.java -@@ -46,7 +46,7 @@ class ArmorSlot extends Slot { - @Override - public boolean mayPickup(Player player) { - ItemStack item = this.getItem(); -- return (item.isEmpty() || player.isCreative() || !EnchantmentHelper.has(item, EnchantmentEffectComponents.PREVENT_ARMOR_CHANGE)) -+ return (item.isEmpty() || player.isCreative() || (!EnchantmentHelper.has(item, EnchantmentEffectComponents.PREVENT_ARMOR_CHANGE) || player.level().purpurConfig.playerRemoveBindingWithWeakness && player.hasEffect(net.minecraft.world.effect.MobEffects.WEAKNESS))) // Purpur - Config to remove curse of binding with weakness - && super.mayPickup(player); - } - diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/inventory/ItemCombinerMenu.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/inventory/ItemCombinerMenu.java.patch deleted file mode 100644 index d07bedaa8..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/inventory/ItemCombinerMenu.java.patch +++ /dev/null @@ -1,20 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/inventory/ItemCombinerMenu.java b/net/minecraft/world/inventory/ItemCombinerMenu.java -index 1296631fc74e83e6c9d6af0cd46d12d9851a30b1..e6c3a0086963298be31befbbbf8d42e85f379c79 100644 ---- a/net/minecraft/world/inventory/ItemCombinerMenu.java -+++ b/net/minecraft/world/inventory/ItemCombinerMenu.java -@@ -156,7 +156,9 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu { - return ItemStack.EMPTY; - } - -+ this.activeQuickItem = itemStack; // Purpur - Anvil API - slot.onTake(player, item); -+ this.activeQuickItem = null; // Purpur - Anvil API - } - - return itemStack; diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch deleted file mode 100644 index 13b36dfd1..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index 1215ac44fd30dc872f9d319be34e5e08ba880ea2..c0bb687b94f3baa9ffda9c47c69a1d6d244acd4e 100644 ---- a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -+++ b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -@@ -187,6 +187,21 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit - } - - ItemStack itemStack = furnace.items.get(1); -+ // Purpur start - Furnace uses lava from underneath -+ boolean usedLavaFromUnderneath = false; -+ if (level.purpurConfig.furnaceUseLavaFromUnderneath && !furnace.isLit() && itemStack.isEmpty() && !furnace.items.get(0).isEmpty() && level.getGameTime() % 20 == 0) { -+ BlockPos below = furnace.getBlockPos().below(); -+ BlockState belowState = level.getBlockStateIfLoaded(below); -+ if (belowState != null && belowState.is(Blocks.LAVA)) { -+ net.minecraft.world.level.material.FluidState fluidState = belowState.getFluidState(); -+ if (fluidState != null && fluidState.isSource()) { -+ level.setBlock(below, Blocks.AIR.defaultBlockState(), 3); -+ itemStack = Items.LAVA_BUCKET.getDefaultInstance(); -+ usedLavaFromUnderneath = true; -+ } -+ } -+ } -+ // Purpur end - Furnace uses lava from underneath - ItemStack itemStack1 = furnace.items.get(0); - boolean flag1 = !itemStack1.isEmpty(); - boolean flag2 = !itemStack.isEmpty(); -@@ -270,6 +285,8 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit - if (flag) { - setChanged(level, pos, state); - } -+ -+ if (usedLavaFromUnderneath) furnace.items.set(1, ItemStack.EMPTY); // Purpur - Furnace uses lava from underneath - } - - private static boolean canBurn( diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/entity/BeaconBlockEntity.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/entity/BeaconBlockEntity.java.patch deleted file mode 100644 index 2c4971ff4..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/entity/BeaconBlockEntity.java.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/level/block/entity/BeaconBlockEntity.java b/net/minecraft/world/level/block/entity/BeaconBlockEntity.java -index 0db33d7e1227e914326e9eb3b50338b001872938..cc301cff64e1bf604a1432f6e36be8aa17db53e7 100644 ---- a/net/minecraft/world/level/block/entity/BeaconBlockEntity.java -+++ b/net/minecraft/world/level/block/entity/BeaconBlockEntity.java -@@ -138,6 +138,16 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name - - public double getEffectRange() { - if (this.effectRange < 0) { -+ // Purpur start - Beacon Activation Range Configurable -+ if (this.level != null) { -+ switch (this.levels) { -+ case 1: return this.level.purpurConfig.beaconLevelOne; -+ case 2: return this.level.purpurConfig.beaconLevelTwo; -+ case 3: return this.level.purpurConfig.beaconLevelThree; -+ case 4: return this.level.purpurConfig.beaconLevelFour; -+ } -+ } -+ // Purpur end - Beacon Activation Range Configurable - return this.levels * 10 + 10; - } else { - return effectRange; -@@ -166,6 +176,7 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name - int y = pos.getY(); - int z = pos.getZ(); - BlockPos blockPos; -+ boolean isTintedGlass = false; // Purpur - allow beacon effects when covered by tinted glass - if (blockEntity.lastCheckY < y) { - blockPos = pos; - blockEntity.checkingBeamSections = Lists.newArrayList(); -@@ -195,11 +206,15 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name - } - } - } else { -- if (section == null || blockState.getLightBlock() >= 15 && !blockState.is(Blocks.BEDROCK)) { -+ if (level.purpurConfig.beaconAllowEffectsWithTintedGlass && blockState.getBlock().equals(Blocks.TINTED_GLASS)) {isTintedGlass = true;} // Purpur - allow beacon effects when covered by tinted glass -+ // Purpur start - fix effects being applied when tinted glass is covered -+ if (section == null || blockState.getLightBlock() >= 15 && !blockState.is(Blocks.BEDROCK) && !(blockState.getBlock().equals(Blocks.TINTED_GLASS) && level.purpurConfig.beaconAllowEffectsWithTintedGlass)) { - blockEntity.checkingBeamSections.clear(); - blockEntity.lastCheckY = height; -+ isTintedGlass = false; - break; - } -+ // Purpur end - fix effects being applied when tinted glass is covered - - section.increaseHeight(); - } -@@ -210,11 +225,11 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name - - int i = blockEntity.levels; final int originalLevels = i; // Paper - OBFHELPER - if (level.getGameTime() % 80L == 0L) { -- if (!blockEntity.beamSections.isEmpty()) { -+ if (!blockEntity.beamSections.isEmpty() || (level.purpurConfig.beaconAllowEffectsWithTintedGlass && isTintedGlass)) { // Purpur - fix beacon effects persisting with broken base while tinted glass is used - blockEntity.levels = updateBase(level, x, y, z); - } - -- if (blockEntity.levels > 0 && !blockEntity.beamSections.isEmpty()) { -+ if (blockEntity.levels > 0 && (!blockEntity.beamSections.isEmpty() || (level.purpurConfig.beaconAllowEffectsWithTintedGlass && isTintedGlass))) { // Purpur - allow beacon effects when covered by tinted glass - applyEffects(level, pos, blockEntity.levels, blockEntity.primaryPower, blockEntity.secondaryPower, blockEntity); // Paper - Custom beacon ranges - playSound(level, pos, SoundEvents.BEACON_AMBIENT); - } diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/entity/ConduitBlockEntity.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/entity/ConduitBlockEntity.java.patch deleted file mode 100644 index c0897b51a..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/entity/ConduitBlockEntity.java.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/level/block/entity/ConduitBlockEntity.java b/net/minecraft/world/level/block/entity/ConduitBlockEntity.java -index be4b46d56ca67cb5c0fac5e0bbc9456fb5552d78..816d9a0f7f35b95b369ffbfc02e4d1f306b814c5 100644 ---- a/net/minecraft/world/level/block/entity/ConduitBlockEntity.java -+++ b/net/minecraft/world/level/block/entity/ConduitBlockEntity.java -@@ -150,7 +150,7 @@ public class ConduitBlockEntity extends BlockEntity { - BlockPos blockPos1 = pos.offset(i, i1, i2x); - BlockState blockState = level.getBlockState(blockPos1); - -- for (Block block : VALID_BLOCKS) { -+ for (Block block : level.purpurConfig.conduitBlocks) { // Purpur - Conduit behavior configuration - if (blockState.is(block)) { - positions.add(blockPos1); - } -@@ -165,13 +165,13 @@ public class ConduitBlockEntity extends BlockEntity { - - private static void applyEffects(Level level, BlockPos pos, List positions) { - // CraftBukkit start -- ConduitBlockEntity.applyEffects(level, pos, ConduitBlockEntity.getRange(positions)); -+ ConduitBlockEntity.applyEffects(level, pos, ConduitBlockEntity.getRange(positions, level)); // Purpur - Conduit behavior configuration - } - -- public static int getRange(List positions) { -+ public static int getRange(List positions, Level level) { // Purpur - Conduit behavior configuration - // CraftBukkit end - int size = positions.size(); -- int i = size / 7 * 16; -+ int i = size / 7 * level.purpurConfig.conduitDistance; // Purpur - Conduit behavior configuration - // CraftBukkit start - return i; - } -@@ -201,7 +201,7 @@ public class ConduitBlockEntity extends BlockEntity { - EntityReference entityReference = updateDestroyTarget(blockEntity.destroyTarget, level, pos, canDestroy); - LivingEntity livingEntity = EntityReference.getLivingEntity(entityReference, level); - if (damageTarget && livingEntity != null) { // CraftBukkit -- if (livingEntity.hurtServer(level, level.damageSources().magic().eventBlockDamager(level, pos), 4.0F)) // CraftBukkit - move up -+ if (livingEntity.hurtServer(level, level.damageSources().magic().eventBlockDamager(level, pos), level.purpurConfig.conduitDamageAmount)) // CraftBukkit - move up // Purpur - Conduit behavior configuration - level.playSound( - null, livingEntity.getX(), livingEntity.getY(), livingEntity.getZ(), SoundEvents.CONDUIT_ATTACK_TARGET, SoundSource.BLOCKS, 1.0F, 1.0F - ); -@@ -222,19 +222,25 @@ public class ConduitBlockEntity extends BlockEntity { - return selectNewTarget(level, pos); - } else { - LivingEntity livingEntity = EntityReference.getLivingEntity(destroyTarget, level); -- return livingEntity != null && livingEntity.isAlive() && pos.closerThan(livingEntity.blockPosition(), 8.0) ? destroyTarget : null; -+ return livingEntity != null && livingEntity.isAlive() && pos.closerThan(livingEntity.blockPosition(), level.purpurConfig.conduitDamageDistance) ? destroyTarget : null; // Purpur - Conduit behavior configuration - } - } - - private static @Nullable EntityReference selectNewTarget(ServerLevel level, BlockPos pos) { - List entitiesOfClass = level.getEntitiesOfClass( -- LivingEntity.class, getDestroyRangeAABB(pos), livingEntity -> livingEntity instanceof Enemy && livingEntity.isInWaterOrRain() -+ LivingEntity.class, getDestroyRangeAABB(pos, level), livingEntity -> livingEntity instanceof Enemy && livingEntity.isInWaterOrRain() // Purpur - Conduit behavior configuration - ); - return entitiesOfClass.isEmpty() ? null : EntityReference.of(Util.getRandom(entitiesOfClass, level.random)); - } - - public static AABB getDestroyRangeAABB(BlockPos pos) { -- return new AABB(pos).inflate(8.0); -+ // Purpur start - Conduit behavior configuration -+ return getDestroyRangeAABB(pos, null); -+ } -+ -+ private static AABB getDestroyRangeAABB(BlockPos pos, Level level) { -+ // Purpur end - Conduit behavior configuration -+ return new AABB(pos).inflate(level == null ? 8.0 : level.purpurConfig.conduitDamageDistance); // Purpur - Conduit behavior configuration - } - - private static void animationTick(Level level, BlockPos pos, List positions, @Nullable Entity entity, int tickCount) { diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/server/MinecraftServer.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/server/MinecraftServer.java.patch similarity index 69% rename from purpur-server/minecraft-patches/rejected/net/minecraft/server/MinecraftServer.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/server/MinecraftServer.java.patch index c3cf217ef..d07ef3376 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/server/MinecraftServer.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/server/MinecraftServer.java.patch @@ -1,14 +1,6 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index ca2caace6aab0dfcb0ab7a0fd28e66555c62fdc5..7a54f6bc2a364c1d3ac1ed58b33ecf720a305840 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -290,6 +290,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); public int autosavePeriod; // Paper - don't store the vanilla dispatcher -@@ -306,6 +307,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop pluginsBlockingSleep = new java.util.HashSet<>(); // Paper - API to allow/disallow tick sleeping public static final long SERVER_INIT = System.nanoTime(); // Paper - Lag compensation @@ -25,7 +17,7 @@ index ca2caace6aab0dfcb0ab7a0fd28e66555c62fdc5..7a54f6bc2a364c1d3ac1ed58b33ecf72 // Paper start - improve tick loop public final ca.spottedleaf.moonrise.common.time.TickData tickTimes1s = new ca.spottedleaf.moonrise.common.time.TickData(java.util.concurrent.TimeUnit.SECONDS.toNanos(1L)); public final ca.spottedleaf.moonrise.common.time.TickData tickTimes5s = new ca.spottedleaf.moonrise.common.time.TickData(java.util.concurrent.TimeUnit.SECONDS.toNanos(5L)); -@@ -375,6 +378,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop catchup) { final long difference = ticksBehind - catchup; -@@ -1785,7 +1812,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index dc65503a2d785d64d37b76b0303f51cf66d9769a..5130c0067f01eec31c69b9e71d904f932943b922 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -218,6 +218,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -219,6 +_,8 @@ private final StructureManager structureManager; private final StructureCheck structureCheck; private final boolean tickTime; + private double preciseTime; // Purpur - Configurable daylight cycle + private boolean forceTime; // Purpur - Configurable daylight cycle - private final RandomSequences randomSequences; - final LevelDebugSynchronizers debugSynchronizers = new LevelDebugSynchronizers(this); + private final LevelDebugSynchronizers debugSynchronizers = new LevelDebugSynchronizers(this); -@@ -622,8 +624,25 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + // CraftBukkit start +@@ -377,8 +_,25 @@ // CraftBukkit end this.tickTime = tickTime; this.server = server; - this.customSpawners = customSpawners; + this.customSpawners = new ArrayList<>(); // Purpur - Allow toggling special MobSpawners per world - this.serverLevelData = serverLevelData; + this.serverLevelData = levelData; + // Purpur start - Allow toggling special MobSpawners per world + if (purpurConfig.phantomSpawning) { + this.customSpawners.add(new net.minecraft.world.level.levelgen.PhantomSpawner()); @@ -38,69 +30,33 @@ index dc65503a2d785d64d37b76b0303f51cf66d9769a..5130c0067f01eec31c69b9e71d904f93 + this.customSpawners.add(new net.minecraft.world.entity.ai.village.VillageSiege()); + } + if (purpurConfig.villagerTraderSpawning) { -+ this.customSpawners.add(new net.minecraft.world.entity.npc.wanderingtrader.WanderingTraderSpawner(serverLevelData)); ++ this.customSpawners.add(new net.minecraft.world.entity.npc.wanderingtrader.WanderingTraderSpawner(levelData)); + } + // Purpur end - Allow toggling special MobSpawners per world - ChunkGenerator chunkGenerator = levelStem.generator(); + ChunkGenerator generator = levelStem.generator(); // CraftBukkit start this.serverLevelData.setWorld(this); -@@ -709,6 +728,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - this.chunkDataController = new ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller.ChunkDataController((ServerLevel)(Object)this, this.chunkTaskScheduler); - // Paper end - rewrite chunk system +@@ -463,6 +_,7 @@ + this.environmentAttributes = EnvironmentAttributeSystem.builder().addDefaultLayers(this).build(); + this.updateSkyBrightness(); this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit + this.preciseTime = this.serverLevelData.getDayTime(); // Purpur - Configurable daylight cycle } // Paper start -@@ -760,7 +780,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -519,7 +_,7 @@ } - int i = this.getGameRules().get(GameRules.PLAYERS_SLEEPING_PERCENTAGE); -- if (this.sleepStatus.areEnoughSleeping(i) && this.sleepStatus.areEnoughDeepSleeping(i, this.players)) { -+ if (this.purpurConfig.playersSkipNight && this.sleepStatus.areEnoughSleeping(i) && this.sleepStatus.areEnoughDeepSleeping(i, this.players)) { // Purpur - Config for skipping night - // Paper start - create time skip event - move up calculations - final long newDayTime = this.levelData.getDayTime() + 24000L; - org.bukkit.event.world.TimeSkipEvent event = new org.bukkit.event.world.TimeSkipEvent( -@@ -895,6 +915,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - this.serverLevelData.getScheduledEvents().tick(this.server, l); - Profiler.get().pop(); - if (this.getGameRules().get(GameRules.ADVANCE_TIME)) { -+ // Purpur start - Configurable daylight cycle -+ int incrementTicks = isBrightOutside() ? this.purpurConfig.daytimeTicks : this.purpurConfig.nighttimeTicks; -+ if (incrementTicks != 12000) { -+ this.preciseTime += 12000 / (double) incrementTicks; -+ this.setDayTime(this.preciseTime); -+ } else -+ // Purpur end - Configurable daylight cycle - this.setDayTime(this.levelData.getDayTime() + 1L); - } - } -@@ -902,6 +929,20 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - - public void setDayTime(long time) { - this.serverLevelData.setDayTime(time); -+ // Purpur start - Configurable daylight cycle -+ this.preciseTime = time; -+ this.forceTime = false; -+ } -+ public void setDayTime(double i) { -+ this.serverLevelData.setDayTime((long) i); -+ this.forceTime = true; -+ // Purpur end - Configurable daylight cycle -+ } -+ -+ // Purpur start - Configurable daylight cycle -+ public boolean isForceTime() { -+ return this.forceTime; -+ // Purpur end - Configurable daylight cycle - } - - public long getDayCount() { -@@ -1010,9 +1051,17 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - && this.random.nextDouble() < currentDifficultyAt.getEffectiveDifficulty() * this.paperConfig().entities.spawning.skeletonHorseThunderSpawnChance.or(0.01) // Paper - Configurable spawn chances for skeleton horses - && !this.getBlockState(blockPos.below()).is(BlockTags.LIGHTNING_RODS); - if (flag) { -- SkeletonHorse skeletonHorse = EntityType.SKELETON_HORSE.create(this, EntitySpawnReason.EVENT); + int percentage = this.getGameRules().get(GameRules.PLAYERS_SLEEPING_PERCENTAGE); +- if (this.sleepStatus.areEnoughSleeping(percentage) && this.sleepStatus.areEnoughDeepSleeping(percentage, this.players)) { ++ if (this.purpurConfig.playersSkipNight && this.sleepStatus.areEnoughSleeping(percentage) && this.sleepStatus.areEnoughDeepSleeping(percentage, this.players)) { // Purpur - Config for skipping night + Optional> defaultClock = this.dimensionType().defaultClock(); + org.bukkit.event.world.TimeSkipEvent event = null; // Paper - time skip event + if (this.getGameRules().get(GameRules.ADVANCE_TIME) && defaultClock.isPresent()) { +@@ -725,9 +_,18 @@ + && this.random.nextDouble() < difficulty.getEffectiveDifficulty() * this.paperConfig().entities.spawning.skeletonHorseThunderSpawnChance.or(0.01) // Paper - Configurable spawn chances for skeleton horses + && !this.getBlockState(pos.below()).is(BlockTags.LIGHTNING_RODS); + if (isTrap) { + // Purpur start - Special mobs naturally spawn + net.minecraft.world.entity.animal.equine.AbstractHorse skeletonHorse; + if (purpurConfig.zombieHorseSpawnChance > 0D && random.nextDouble() <= purpurConfig.zombieHorseSpawnChance) { @@ -110,16 +66,17 @@ index dc65503a2d785d64d37b76b0303f51cf66d9769a..5130c0067f01eec31c69b9e71d904f93 + if (skeletonHorse != null) ((SkeletonHorse) skeletonHorse).setTrap(true); + } + // Purpur end - Special mobs naturally spawn - if (skeletonHorse != null) { -- skeletonHorse.setTrap(true); -+ //skeletonHorse.setTrap(true); // Purpur - Special mobs naturally spawn - moved up - skeletonHorse.setAge(0); - skeletonHorse.setPos(blockPos.getX(), blockPos.getY(), blockPos.getZ()); - this.addFreshEntity(skeletonHorse, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); // CraftBukkit -@@ -1047,9 +1096,35 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - if (blockState.is(Blocks.SNOW)) { - int layersValue = blockState.getValue(SnowLayerBlock.LAYERS); - if (layersValue < Math.min(i, 8)) { + SkeletonHorse horse = EntityType.SKELETON_HORSE.create(this, EntitySpawnReason.EVENT); + if (horse != null) { +- horse.setTrap(true); ++ //horse.setTrap(true); // Purpur - Special mobs naturally spawn - moved up + horse.setAge(0); + horse.setPos(pos.getX(), pos.getY(), pos.getZ()); + this.addFreshEntity(horse, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); // CraftBukkit +@@ -762,9 +_,35 @@ + if (state.is(Blocks.SNOW)) { + int currentLayers = state.getValue(SnowLayerBlock.LAYERS); + if (currentLayers < Math.min(maxHeight, 8)) { + // Purpur start - Smooth snow accumulation + boolean canSnow = true; + // Ensure snow doesn't get more than N layers taller than its neighbors @@ -145,67 +102,67 @@ index dc65503a2d785d64d37b76b0303f51cf66d9769a..5130c0067f01eec31c69b9e71d904f93 + } + if (canSnow) { + // Purpur end - Smooth snow accumulation - BlockState blockState1 = blockState.setValue(SnowLayerBlock.LAYERS, layersValue + 1); - Block.pushEntitiesUp(blockState, blockState1, this, heightmapPos); - org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, heightmapPos, blockState1, Block.UPDATE_ALL, null); // CraftBukkit + BlockState newState = state.setValue(SnowLayerBlock.LAYERS, currentLayers + 1); + Block.pushEntitiesUp(state, newState, this, topPos); + org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, topPos, newState, Block.UPDATE_ALL, null); // CraftBukkit + } // Purpur - Smooth snow accumulation } } else { - org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, heightmapPos, Blocks.SNOW.defaultBlockState(), Block.UPDATE_ALL, null); // CraftBukkit -@@ -1070,7 +1145,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - poiType -> poiType.is(PoiTypes.LIGHTNING_ROD), - blockPos -> blockPos.getY() == this.getHeight(Heightmap.Types.WORLD_SURFACE, blockPos.getX(), blockPos.getZ()) - 1, - pos, + org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, topPos, Blocks.SNOW.defaultBlockState(), Block.UPDATE_ALL, null); // CraftBukkit +@@ -785,7 +_,7 @@ + p -> p.is(PoiTypes.LIGHTNING_ROD), + lightningRodPos -> lightningRodPos.getY() == this.getHeight(Heightmap.Types.WORLD_SURFACE, lightningRodPos.getX(), lightningRodPos.getZ()) - 1, + center, - 128, + org.purpurmc.purpur.PurpurConfig.lightningRodRange, // Purpur - Make lightning rod range configurable PoiManager.Occupancy.ANY ); - return optional.map(blockPos -> blockPos.above(1)); -@@ -1119,8 +1194,26 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - int i = this.getGameRules().get(GameRules.PLAYERS_SLEEPING_PERCENTAGE); - Component component; - if (this.sleepStatus.areEnoughSleeping(i)) { + return nearbyLightningRod.map(blockPos -> blockPos.above(1)); +@@ -833,8 +_,26 @@ + int percentage = this.getGameRules().get(GameRules.PLAYERS_SLEEPING_PERCENTAGE); + Component message; + if (this.sleepStatus.areEnoughSleeping(percentage)) { + // Purpur start - Customizable sleeping actionbar messages + if (org.purpurmc.purpur.PurpurConfig.sleepSkippingNight.isBlank()) { + return; + } + if (!org.purpurmc.purpur.PurpurConfig.sleepSkippingNight.equalsIgnoreCase("default")) { -+ component = io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.sleepSkippingNight)); ++ message = io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.sleepSkippingNight)); + } else + // Purpur end - Customizable sleeping actionbar messages - component = Component.translatable("sleep.skipping_night"); + message = Component.translatable("sleep.skipping_night"); } else { + // Purpur start - Customizable sleeping actionbar messages + if (org.purpurmc.purpur.PurpurConfig.sleepingPlayersPercent.isBlank()) { + return; + } + if (!org.purpurmc.purpur.PurpurConfig.sleepingPlayersPercent.equalsIgnoreCase("default")) { -+ component = io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.sleepingPlayersPercent, ++ message = io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.sleepingPlayersPercent, + net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.parsed("count", Integer.toString(this.sleepStatus.amountSleeping())), + net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.parsed("total", Integer.toString(this.sleepStatus.sleepersNeeded(i))))); + } else + // Purpur end - Customizable sleeping actionbar messages - component = Component.translatable("sleep.players_sleeping", this.sleepStatus.amountSleeping(), this.sleepStatus.sleepersNeeded(i)); + message = Component.translatable("sleep.players_sleeping", this.sleepStatus.amountSleeping(), this.sleepStatus.sleepersNeeded(percentage)); } -@@ -1275,6 +1368,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - @VisibleForTesting +@@ -1000,6 +_,7 @@ public void resetWeatherCycle() { + WeatherData weatherData = this.getWeatherData(); // CraftBukkit start + if (this.purpurConfig.rainStopsAfterSleep) // Purpur - Option for if rain and thunder should stop on sleep - this.serverLevelData.setRaining(false, org.bukkit.event.weather.WeatherChangeEvent.Cause.SLEEP); // Paper - Add cause to Weather/ThunderChangeEvents + weatherData.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.... -@@ -1282,6 +1376,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - this.serverLevelData.setRainTime(0); +@@ -1007,6 +_,7 @@ + weatherData.setRainTime(0); } // CraftBukkit end + if (this.purpurConfig.thunderStopsAfterSleep) // Purpur - Option for if rain and thunder should stop on sleep - this.serverLevelData.setThundering(false, org.bukkit.event.weather.ThunderChangeEvent.Cause.SLEEP); // Paper - Add cause to Weather/ThunderChangeEvents + weatherData.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. -@@ -1954,7 +2049,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - Explosion.BlockInteraction blockInteraction = switch (explosionInteraction) { +@@ -1640,7 +_,7 @@ + Explosion.BlockInteraction blockInteraction = switch (interactionType) { case NONE -> Explosion.BlockInteraction.KEEP; case BLOCK -> this.getDestroyType(GameRules.BLOCK_EXPLOSION_DROP_DECAY); - case MOB -> this.getGameRules().get(GameRules.MOB_GRIEFING) @@ -213,7 +170,7 @@ index dc65503a2d785d64d37b76b0303f51cf66d9769a..5130c0067f01eec31c69b9e71d904f93 ? this.getDestroyType(GameRules.MOB_EXPLOSION_DROP_DECAY) : Explosion.BlockInteraction.KEEP; case TNT -> this.getDestroyType(GameRules.TNT_EXPLOSION_DROP_DECAY); -@@ -2846,7 +2941,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2539,7 +_,7 @@ // 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 diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/clock/ServerClockManager.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/clock/ServerClockManager.java.patch new file mode 100644 index 000000000..d71da2ca8 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/clock/ServerClockManager.java.patch @@ -0,0 +1,20 @@ +--- a/net/minecraft/world/clock/ServerClockManager.java ++++ b/net/minecraft/world/clock/ServerClockManager.java +@@ -112,7 +_,7 @@ + ServerClockManager.ClockInstance instance = this.getInstance(clock); + action.accept(instance); + Map, ClockState> updates = Map.of(clock, instance.packNetworkState(this.server)); +- this.server.getPlayerList().broadcastAll(new ClientboundSetTimePacket(this.getGameTime(), updates)); // TODO 26.1 per-player time ++ this.server.getPlayerList().broadcastAll(new ClientboundSetTimePacket(this.getGameTime(), updates)); // TODO 26.1 per-player time // Purpur - TODO: Configurable daylight cycle + this.setDirty(); + } + +@@ -128,7 +_,7 @@ + // Paper end + + public ClientboundSetTimePacket createFullSyncPacket() { +- // TODO 26.1 per-player time ++ // TODO 26.1 per-player time // Purpur - TODO: Configurable daylight cycle + return new ClientboundSetTimePacket(this.getGameTime(), Util.mapValues(this.clocks, clock -> clock.packNetworkState(this.server))); + } + diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/attributes/RangedAttribute.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/attributes/RangedAttribute.java.patch new file mode 100644 index 000000000..905af06f3 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/attributes/RangedAttribute.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/world/entity/ai/attributes/RangedAttribute.java ++++ b/net/minecraft/world/entity/ai/attributes/RangedAttribute.java +@@ -29,6 +_,7 @@ + + @Override + public double sanitizeValue(final double value) { ++ if (!org.purpurmc.purpur.PurpurConfig.clampAttributes) return Double.isNaN(value) ? this.minValue : value; // Purpur - Add attribute clamping and armor limit config + return Double.isNaN(value) ? this.minValue : Mth.clamp(value, this.minValue, this.maxValue); + } + } diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/behavior/AcquirePoi.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/behavior/AcquirePoi.java.patch new file mode 100644 index 000000000..646d1d51c --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/behavior/AcquirePoi.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/entity/ai/behavior/AcquirePoi.java ++++ b/net/minecraft/world/entity/ai/behavior/AcquirePoi.java +@@ -89,7 +_,7 @@ + } + }; + Set, BlockPos>> poiPositions = poiManager.findAllClosestFirstWithType( +- poiType, cacheTest, body.blockPosition(), 48, PoiManager.Occupancy.HAS_SPACE ++ poiType, cacheTest, body.blockPosition(), level.purpurConfig.villagerAcquirePoiSearchRadius, PoiManager.Occupancy.HAS_SPACE // Purpur - Configurable villager search radius + ) + .limit(5L) + .filter(px -> validPoi.test(level, (BlockPos)px.getSecond())) diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java.patch new file mode 100644 index 000000000..0d20faa0b --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java.patch @@ -0,0 +1,29 @@ +--- a/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java ++++ b/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java +@@ -53,7 +_,7 @@ + Node toNode = path.getNextNode(); + BlockPos fromPos = fromNode.asBlockPos(); + BlockState fromState = level.getBlockState(fromPos); +- if (fromState.is(BlockTags.MOB_INTERACTABLE_DOORS, s -> s.getBlock() instanceof DoorBlock)) { ++ if (fromState.is(BlockTags.MOB_INTERACTABLE_DOORS, s -> s.getBlock() instanceof DoorBlock)&& !DoorBlock.requiresRedstone(entity.level(), blockState, blockPos)) { // Purpur - Option to make doors require redstone + DoorBlock fromBlock = (DoorBlock)fromState.getBlock(); + if (!fromBlock.isOpen(fromState)) { + // CraftBukkit start - entities opening doors +@@ -70,7 +_,7 @@ + + BlockPos toPos = toNode.asBlockPos(); + BlockState toState = level.getBlockState(toPos); +- if (toState.is(BlockTags.MOB_INTERACTABLE_DOORS, s -> s.getBlock() instanceof DoorBlock)) { ++ if (toState.is(BlockTags.MOB_INTERACTABLE_DOORS, s -> s.getBlock() instanceof DoorBlock) && !DoorBlock.requiresRedstone(entity.level(), blockState1, blockPos1)) { // Purpur - Option to make doors require redstone + DoorBlock door = (DoorBlock)toState.getBlock(); + if (!door.isOpen(toState)) { + // CraftBukkit start - entities opening doors +@@ -117,7 +_,7 @@ + iterator.remove(); + } else { + BlockState state = level.getBlockState(doorPos); +- if (!state.is(BlockTags.MOB_INTERACTABLE_DOORS, s -> s.getBlock() instanceof DoorBlock)) { ++ if (!state.is(BlockTags.MOB_INTERACTABLE_DOORS, s -> s.getBlock() instanceof DoorBlock) || DoorBlock.requiresRedstone(entity.level(), blockState, blockPos)) { // Purpur - Option to make doors require redstone + iterator.remove(); + } else { + DoorBlock block = (DoorBlock)state.getBlock(); diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/behavior/ShowTradesToPlayer.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/behavior/ShowTradesToPlayer.java.patch new file mode 100644 index 000000000..f116d14a1 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/behavior/ShowTradesToPlayer.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/world/entity/ai/behavior/ShowTradesToPlayer.java ++++ b/net/minecraft/world/entity/ai/behavior/ShowTradesToPlayer.java +@@ -41,6 +_,7 @@ + + @Override + public boolean canStillUse(final ServerLevel level, final Villager body, final long timestamp) { ++ if (!body.level().purpurConfig.villagerDisplayTradeItem) return false; // Purpur - Option for villager display trade item + return this.checkExtraStartConditions(level, body) && this.lookTime > 0 && body.getBrain().getMemory(MemoryModuleType.INTERACTION_TARGET).isPresent(); + } + diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/behavior/SleepInBed.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/behavior/SleepInBed.java.patch new file mode 100644 index 000000000..69a608ace --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/behavior/SleepInBed.java.patch @@ -0,0 +1,18 @@ +--- a/net/minecraft/world/entity/ai/behavior/SleepInBed.java ++++ b/net/minecraft/world/entity/ai/behavior/SleepInBed.java +@@ -89,7 +_,14 @@ + InteractWithDoor.closeDoorsThatIHaveOpenedOrPassedThrough(level, body, null, null, doors, nearestEntities); + } + +- body.startSleeping(body.getBrain().getMemory(MemoryModuleType.HOME).get().pos()); ++ // Purpur start - Option for beds to explode on villager sleep ++ net.minecraft.core.BlockPos bedPosition = body.getBrain().getMemory(net.minecraft.world.entity.ai.memory.MemoryModuleType.HOME).get().pos(); ++ if (level.purpurConfig.bedExplodeOnVillagerSleep && body.is(net.minecraft.world.entity.EntityType.VILLAGER) && level.getBlockState(bedPosition).getBlock() instanceof net.minecraft.world.level.block.BedBlock) { ++ level.explode(null, (double) bedPosition.getX() + 0.5D, (double) bedPosition.getY() + 0.5D, (double) bedPosition.getZ() + 0.5D, (float) level.purpurConfig.bedExplosionPower, level.purpurConfig.bedExplosionFire, level.purpurConfig.bedExplosionEffect); ++ return; ++ } ++ body.startSleeping(bedPosition); ++ // Purpur end - Option for beds to explode on villager sleep + brain.setMemory(MemoryModuleType.LAST_SLEPT, timestamp); + brain.eraseMemory(MemoryModuleType.WALK_TARGET); + brain.eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE); diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/behavior/TransportItemsBetweenContainers.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/behavior/TransportItemsBetweenContainers.java.patch new file mode 100644 index 000000000..1e19ff5a0 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/behavior/TransportItemsBetweenContainers.java.patch @@ -0,0 +1,54 @@ +--- a/net/minecraft/world/entity/ai/behavior/TransportItemsBetweenContainers.java ++++ b/net/minecraft/world/entity/ai/behavior/TransportItemsBetweenContainers.java +@@ -286,7 +_,7 @@ + LevelChunk levelChunk = level.getChunkSource().getChunkNow(chunkPos.x(), chunkPos.z()); + if (levelChunk != null) { + for (BlockEntity potentialTarget : levelChunk.getBlockEntities().values()) { +- if (potentialTarget instanceof ChestBlockEntity chestBlockEntity) { ++ if (potentialTarget instanceof net.minecraft.world.level.block.entity.BaseContainerBlockEntity chestBlockEntity) { // Purpur - copper golem can place items in barrels or shulkers option + double distance = chestBlockEntity.getBlockPos().distToCenterSqr(body.position()); + if (distance < closestDistance) { + TransportItemsBetweenContainers.TransportItemTarget targetValidToPick = this.isTargetValidToPick( +@@ -375,7 +_,11 @@ + } + + private boolean isTargetBlocked(final Level level, final TransportItemsBetweenContainers.TransportItemTarget target) { +- return ChestBlock.isChestBlockedAt(level, target.pos); ++ // Purpur start - copper golem can place items in barrels or shulkers option ++ boolean isBarrelBlocked = !level.purpurConfig.copperGolemCanOpenBarrel && target.state.is(net.minecraft.world.level.block.Blocks.BARREL); ++ boolean isShulkerBlocked = !level.purpurConfig.copperGolemCanOpenShulker && target.blockEntity instanceof net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity shulkerBoxBlockEntity && !net.minecraft.world.level.block.ShulkerBoxBlock.canOpen(target.state, level, target.pos, shulkerBoxBlockEntity); ++ return target.state.is(net.minecraft.world.level.block.Blocks.BARREL) ? isBarrelBlocked : isShulkerBlocked || net.minecraft.world.level.block.ChestBlock.isChestBlockedAt(level, target.pos); ++ // Purpur end - copper golem can place items in barrels or shulkers option + } + + private boolean targetHasNotChanged(final Level level, final TransportItemsBetweenContainers.TransportItemTarget target) { +@@ -455,7 +_,7 @@ + } + + private boolean isWantedBlock(final PathfinderMob mob, final BlockState block) { +- return isPickingUpItems(mob) ? this.sourceBlockType.test(block) : this.destinationBlockType.test(block); ++ return isPickingUpItems(mob) ? this.sourceBlockType.test(block) : (mob.level().purpurConfig.copperGolemCanOpenBarrel && state.is(net.minecraft.world.level.block.Blocks.BARREL)) || (mob.level().purpurConfig.copperGolemCanOpenShulker && state.is(net.minecraft.tags.BlockTags.SHULKER_BOXES)) || this.destinationBlockType.test(block); // Purpur - copper golem can place items in barrels or shulkers option + } + + private static double getInteractionRange(final PathfinderMob body) { +@@ -507,6 +_,11 @@ + } + + private static boolean matchesLeavingItemsRequirement(final PathfinderMob body, final Container container) { ++ // Purpur start - copper golem can place items in barrels or shulkers option ++ if (body.level().purpurConfig.copperGolemCanOpenShulker && container instanceof net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity && body.getMainHandItem().is(net.minecraft.tags.ItemTags.SHULKER_BOXES)) { ++ return false; ++ } ++ // Purpur end - copper golem can place items in barrels or shulkers option + return container.isEmpty() || hasItemMatchingHandItem(body, container); + } + +@@ -544,7 +_,7 @@ + int slot = 0; + + for (ItemStack itemStack : container) { +- if (!itemStack.isEmpty()) { ++ if (!itemStack.isEmpty() && (!(container instanceof net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity) || !itemStack.is(net.minecraft.tags.ItemTags.SHULKER_BOXES))) { // Purpur - copper golem can place items in barrels or shulkers option + int itemCount = Math.min(itemStack.getCount(), 16); + return container.removeItem(slot, itemCount); + } diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/goal/SwellGoal.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/goal/SwellGoal.java.patch new file mode 100644 index 000000000..7575c7af4 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/goal/SwellGoal.java.patch @@ -0,0 +1,17 @@ +--- a/net/minecraft/world/entity/ai/goal/SwellGoal.java ++++ b/net/minecraft/world/entity/ai/goal/SwellGoal.java +@@ -46,6 +_,14 @@ + this.creeper.setSwellDir(-1); + } else { + this.creeper.setSwellDir(1); ++ // Purpur start - option to allow creeper to encircle target when fusing ++ if (this.creeper.level().purpurConfig.creeperEncircleTarget) { ++ net.minecraft.world.phys.Vec3 relative = this.creeper.position().subtract(this.target.position()); ++ relative = relative.yRot((float) Math.PI / 3).normalize().multiply(2, 2, 2); ++ net.minecraft.world.phys.Vec3 destination = this.target.position().add(relative); ++ this.creeper.getNavigation().moveTo(destination.x, destination.y, destination.z, 1); ++ } ++ // Purpur end - option to allow creeper to encircle target when fusing + } + } else { + this.creeper.setSwellDir(-1); diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java.patch new file mode 100644 index 000000000..4dc439e34 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java.patch @@ -0,0 +1,14 @@ +--- a/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java ++++ b/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java +@@ -54,9 +_,9 @@ + } + }; + Set, BlockPos>> pois = poiManager.findAllWithType( +- e -> e.is(PoiTypes.HOME), cacheTest, body.blockPosition(), 48, PoiManager.Occupancy.ANY ++ e -> e.is(PoiTypes.HOME), cacheTest, body.blockPosition(), level.purpurConfig.villagerNearestBedSensorSearchRadius, PoiManager.Occupancy.ANY + ) +- .collect(Collectors.toSet()); ++ .collect(Collectors.toSet()); // Purpur - Configurable villager search radius + Path path = AcquirePoi.findPathToPois(body, pois); + if (path != null && path.canReach()) { + BlockPos targetPos = path.getTarget(); diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/Animal.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/Animal.java.patch new file mode 100644 index 000000000..be714ae2a --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/Animal.java.patch @@ -0,0 +1,34 @@ +--- a/net/minecraft/world/entity/animal/Animal.java ++++ b/net/minecraft/world/entity/animal/Animal.java +@@ -146,7 +_,7 @@ + ItemStack itemStack = player.getItemInHand(hand); + if (this.isFood(itemStack)) { + int age = this.getAge(); +- if (player instanceof ServerPlayer serverPlayer && age == 0 && this.canFallInLove()) { ++ if (player instanceof ServerPlayer serverPlayer && age == 0 && this.canFallInLove() && (this.level().purpurConfig.animalBreedingCooldownSeconds <= 0 || !this.level().hasBreedingCooldown(player.getUUID(), this.getClass()))) { // Purpur - Add adjustable breeding cooldown to config + final ItemStack breedCopy = itemStack.copy(); // Paper - Fix EntityBreedEvent copying + this.usePlayerItem(player, hand, itemStack); + this.setInLove(serverPlayer, breedCopy); // Paper - Fix EntityBreedEvent copying +@@ -227,10 +_,20 @@ + public void spawnChildFromBreeding(final ServerLevel level, final Animal partner) { + AgeableMob offspring = this.getBreedOffspring(level, partner); + if (offspring != null) { +- offspring.setBaby(true); +- offspring.snapTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F); ++ //offspring.setBaby(true); // Purpur - Add adjustable breeding cooldown to config - moved down ++ //offspring.snapTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F); // Purpur - Add adjustable breeding cooldown to config - moved down + // CraftBukkit start - Call EntityBreedEvent + ServerPlayer breeder = Optional.ofNullable(this.getLoveCause()).or(() -> Optional.ofNullable(partner.getLoveCause())).orElse(null); ++ // Purpur start - Add adjustable breeding cooldown to config ++ if (breeder != null && level.purpurConfig.animalBreedingCooldownSeconds > 0) { ++ if (level.hasBreedingCooldown(breeder.getUUID(), this.getClass())) { ++ return; ++ } ++ level.addBreedingCooldown(breeder.getUUID(), this.getClass()); ++ } ++ offspring.setBaby(true); ++ offspring.snapTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F); ++ // Purpur end - Add adjustable breeding cooldown to config + int experience = this.getRandom().nextInt(7) + 1; + org.bukkit.event.entity.EntityBreedEvent entityBreedEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreedEvent(offspring, this, partner, breeder, this.breedItem, experience); + if (entityBreedEvent.isCancelled()) { diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/bee/Bee.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/bee/Bee.java.patch similarity index 74% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/bee/Bee.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/bee/Bee.java.patch index ee922d9a1..3ff4d75be 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/bee/Bee.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/bee/Bee.java.patch @@ -1,29 +1,21 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/animal/bee/Bee.java b/net/minecraft/world/entity/animal/bee/Bee.java -index 0cbcf23b6edba2305dfbbc95abb06a90a6edd42b..7b9280526af353c3ab1f32e5195499e773731352 100644 --- a/net/minecraft/world/entity/animal/bee/Bee.java +++ b/net/minecraft/world/entity/animal/bee/Bee.java -@@ -171,7 +171,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -172,7 +_,7 @@ // Paper end - Fix MC-167279 this.lookControl = new Bee.BeeLookControl(this); - this.setPathfindingMalus(PathType.DANGER_FIRE, -1.0F); + this.setPathfindingMalus(PathType.FIRE_IN_NEIGHBOR, -1.0F); - this.setPathfindingMalus(PathType.WATER, -1.0F); + if (this.level().purpurConfig.beeCanInstantlyStartDrowning) this.setPathfindingMalus(PathType.WATER, -1.0F); // Purpur - bee can instantly start drowning in water option this.setPathfindingMalus(PathType.WATER_BORDER, 16.0F); this.setPathfindingMalus(PathType.COCOA, -1.0F); this.setPathfindingMalus(PathType.FENCE, -1.0F); -@@ -360,13 +360,19 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -363,13 +_,19 @@ if (this.stayOutOfHiveCountdown <= 0 && !this.beePollinateGoal.isPollinating() && !this.hasStung() && this.getTarget() == null) { - boolean flag = this.hasNectar() + boolean wantsToEnterHive = this.hasNectar() || this.isTiredOfLookingForNectar() - || this.level().environmentAttributes().getValue(EnvironmentAttributes.BEES_STAY_IN_HIVE, this.position()); + || this.level().environmentAttributes().getValue(EnvironmentAttributes.BEES_STAY_IN_HIVE, this.position()) || isNightOrRaining(this.level()); // Purpur - Bee can work when raining or at night - return flag && !this.isHiveNearFire(); + return wantsToEnterHive && !this.isHiveNearFire(); } else { return false; } @@ -35,19 +27,19 @@ index 0cbcf23b6edba2305dfbbc95abb06a90a6edd42b..7b9280526af353c3ab1f32e5195499e7 + } + // Purpur end - Bee can work when raining or at night + - public void setStayOutOfHiveCountdown(int stayOutOfHiveCountdown) { - this.stayOutOfHiveCountdown = stayOutOfHiveCountdown; + public void setStayOutOfHiveCountdown(final int ticks) { + this.stayOutOfHiveCountdown = ticks; } -@@ -387,7 +393,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -390,7 +_,7 @@ @Override - protected void customServerAiStep(ServerLevel level) { + protected void customServerAiStep(final ServerLevel level) { boolean hasStung = this.hasStung(); - if (this.isInWater()) { + if (this.level().purpurConfig.beeCanInstantlyStartDrowning && this.isInWater()) { // Purpur - bee can instantly start drowning in water option this.underWaterTicks++; } else { this.underWaterTicks = 0; -@@ -397,6 +403,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -400,6 +_,7 @@ this.hurtServer(level, this.damageSources().drown(), 1.0F); } @@ -55,15 +47,15 @@ index 0cbcf23b6edba2305dfbbc95abb06a90a6edd42b..7b9280526af353c3ab1f32e5195499e7 if (hasStung) { this.timeSinceSting++; if (this.timeSinceSting % 5 == 0 && this.random.nextInt(Mth.clamp(1200 - this.timeSinceSting, 1, 1200)) == 0) { -@@ -1130,6 +1137,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { - Bee.this.savedFlowerPos = optional.get(); +@@ -1168,6 +_,7 @@ + Bee.this.savedFlowerPos = nearbyPos.get(); Bee.this.navigation .moveTo(Bee.this.savedFlowerPos.getX() + 0.5, Bee.this.savedFlowerPos.getY() + 0.5, Bee.this.savedFlowerPos.getZ() + 0.5, 1.2F); + new org.purpurmc.purpur.event.entity.BeeFoundFlowerEvent((org.bukkit.entity.Bee) Bee.this.getBukkitEntity(), org.bukkit.craftbukkit.util.CraftLocation.toBukkit(Bee.this.savedFlowerPos, Bee.this.level())).callEvent(); // Purpur - Bee API return true; } else { Bee.this.remainingCooldownBeforeLocatingNewFlower = Mth.nextInt(Bee.this.random, 20, 60); -@@ -1176,6 +1184,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -1214,6 +_,7 @@ this.pollinating = false; Bee.this.navigation.stop(); Bee.this.remainingCooldownBeforeLocatingNewFlower = 200; @@ -71,7 +63,7 @@ index 0cbcf23b6edba2305dfbbc95abb06a90a6edd42b..7b9280526af353c3ab1f32e5195499e7 } @Override -@@ -1222,6 +1231,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -1260,6 +_,7 @@ this.setWantedPos(); } diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/cow/AbstractCow.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/cow/AbstractCow.java.patch similarity index 78% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/cow/AbstractCow.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/cow/AbstractCow.java.patch index 3c73cf266..e5163fe45 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/cow/AbstractCow.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/cow/AbstractCow.java.patch @@ -1,25 +1,17 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/animal/cow/AbstractCow.java b/net/minecraft/world/entity/animal/cow/AbstractCow.java -index e10f7d1b264a85798de063b4387bab62621bf54b..f6f251227db315b58bee45f8011624a347eb8fea 100644 --- a/net/minecraft/world/entity/animal/cow/AbstractCow.java +++ b/net/minecraft/world/entity/animal/cow/AbstractCow.java -@@ -40,7 +40,7 @@ public abstract class AbstractCow extends Animal { +@@ -40,7 +_,7 @@ this.goalSelector.addGoal(0, new FloatGoal(this)); this.goalSelector.addGoal(1, new PanicGoal(this, 2.0)); this.goalSelector.addGoal(2, new BreedGoal(this, 1.0)); -- this.goalSelector.addGoal(3, new TemptGoal(this, 1.25, itemStack -> itemStack.is(ItemTags.COW_FOOD), false)); -+ this.goalSelector.addGoal(3, new TemptGoal(this, 1.25, itemStack -> level().purpurConfig.cowFeedMushrooms > 0 && (itemStack.is(net.minecraft.world.level.block.Blocks.RED_MUSHROOM.asItem()) || itemStack.is(net.minecraft.world.level.block.Blocks.BROWN_MUSHROOM.asItem())) || itemStack.is(ItemTags.COW_FOOD), false)); // Purpur - Cows eat mushrooms +- this.goalSelector.addGoal(3, new TemptGoal(this, 1.25, i -> i.is(ItemTags.COW_FOOD), false)); ++ this.goalSelector.addGoal(3, new TemptGoal(this, 1.25, i -> level().purpurConfig.cowFeedMushrooms > 0 && (i.is(net.minecraft.world.level.block.Blocks.RED_MUSHROOM.asItem()) || i.is(net.minecraft.world.level.block.Blocks.BROWN_MUSHROOM.asItem())) || i.is(ItemTags.COW_FOOD), false)); // Purpur - Cows eat mushrooms this.goalSelector.addGoal(4, new FollowParentGoal(this, 1.25)); this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 1.0)); this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 6.0F)); -@@ -96,6 +96,10 @@ public abstract class AbstractCow extends Animal { - ItemStack itemStack = ItemUtils.createFilledResult(itemInHand, player, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItemStack())); // CraftBukkit - player.setItemInHand(hand, itemStack); +@@ -100,6 +_,10 @@ + ItemStack bucketOrMilkBucket = ItemUtils.createFilledResult(itemStack, player, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItemStack())); // CraftBukkit + player.setItemInHand(hand, bucketOrMilkBucket); return InteractionResult.SUCCESS; + // Purpur start - Cows eat mushrooms - feed mushroom to change to mooshroom + } else if (level().purpurConfig.cowFeedMushrooms > 0 && this.getType() != EntityType.MOOSHROOM && isMushroom(itemInHand)) { @@ -28,8 +20,8 @@ index e10f7d1b264a85798de063b4387bab62621bf54b..f6f251227db315b58bee45f8011624a3 } else { return super.mobInteract(player, hand); } -@@ -105,4 +109,67 @@ public abstract class AbstractCow extends Animal { - public EntityDimensions getDefaultDimensions(Pose pose) { +@@ -109,4 +_,67 @@ + public EntityDimensions getDefaultDimensions(final Pose pose) { return this.isBaby() ? BABY_DIMENSIONS : super.getDefaultDimensions(pose); } + diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/dolphin/Dolphin.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/dolphin/Dolphin.java.patch similarity index 72% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/dolphin/Dolphin.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/dolphin/Dolphin.java.patch index ebe6db930..5072bb8b2 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/dolphin/Dolphin.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/dolphin/Dolphin.java.patch @@ -1,30 +1,22 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/animal/dolphin/Dolphin.java b/net/minecraft/world/entity/animal/dolphin/Dolphin.java -index 3a3c9694d3a704aaaa241bd8601c7fd2439436cc..50b8abff1e20855ba8c8acb225c251a1223b8b58 100644 --- a/net/minecraft/world/entity/animal/dolphin/Dolphin.java +++ b/net/minecraft/world/entity/animal/dolphin/Dolphin.java -@@ -75,6 +75,7 @@ public class Dolphin extends AgeableWaterCreature { +@@ -77,6 +_,7 @@ public static final float BABY_SCALE = 0.65F; private static final boolean DEFAULT_GOT_FISH = false; - @Nullable public BlockPos treasurePos; + public @Nullable BlockPos treasurePos; + private boolean isNaturallyAggressiveToPlayers; // Purpur - Dolphins naturally aggressive to players chance - public Dolphin(EntityType type, Level level) { + public Dolphin(final EntityType type, final Level level) { super(type, level); -@@ -90,6 +91,7 @@ public class Dolphin extends AgeableWaterCreature { +@@ -92,6 +_,7 @@ this.setAirSupply(this.getMaxAirSupply()); this.setXRot(0.0F); - SpawnGroupData spawnGroupData1 = Objects.requireNonNullElseGet(spawnGroupData, () -> new AgeableMob.AgeableMobGroupData(0.1F)); + SpawnGroupData spawnGroupData = Objects.requireNonNullElseGet(groupData, () -> new AgeableMob.AgeableMobGroupData(0.1F)); + this.isNaturallyAggressiveToPlayers = level.getLevel().purpurConfig.dolphinNaturallyAggressiveToPlayersChance > 0.0D && random.nextDouble() <= level.getLevel().purpurConfig.dolphinNaturallyAggressiveToPlayersChance; // Purpur - Dolphins naturally aggressive to players chance - return super.finalizeSpawn(level, difficulty, spawnReason, spawnGroupData1); + return super.finalizeSpawn(level, difficulty, spawnReason, spawnGroupData); } -@@ -155,17 +157,19 @@ public class Dolphin extends AgeableWaterCreature { +@@ -157,18 +_,20 @@ protected void registerGoals() { this.goalSelector.addGoal(0, new BreathAirGoal(this)); this.goalSelector.addGoal(0, new TryFindWaterGoal(this)); @@ -38,14 +30,15 @@ index 3a3c9694d3a704aaaa241bd8601c7fd2439436cc..50b8abff1e20855ba8c8acb225c251a1 - this.goalSelector.addGoal(6, new MeleeAttackGoal(this, 1.2F, true)); + //this.goalSelector.addGoal(6, new MeleeAttackGoal(this, 1.2F, true)); // Purpur - moved up - Dolphins naturally aggressive to players chance this.goalSelector.addGoal(8, new Dolphin.PlayWithItemsGoal()); - this.goalSelector.addGoal(8, new FollowBoatGoal(this)); + this.goalSelector.addGoal(8, new FollowPlayerRiddenEntityGoal(this, AbstractBoat.class)); + this.goalSelector.addGoal(8, new FollowPlayerRiddenEntityGoal(this, AbstractNautilus.class)); this.goalSelector.addGoal(9, new AvoidEntityGoal<>(this, Guardian.class, 8.0F, 1.0, 1.0)); this.targetSelector.addGoal(1, new HurtByTargetGoal(this, Guardian.class).setAlertOthers()); + this.targetSelector.addGoal(2, new net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, (ignored, ignored2) -> isNaturallyAggressiveToPlayers)); // Purpur - Dolphins naturally aggressive to players chance } public static AttributeSupplier.Builder createAttributes() { -@@ -392,6 +396,7 @@ public class Dolphin extends AgeableWaterCreature { +@@ -395,6 +_,7 @@ @Override public boolean canUse() { diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/equine/Llama.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/equine/Llama.java.patch similarity index 60% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/equine/Llama.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/equine/Llama.java.patch index e03a0eda8..bc16ff91b 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/equine/Llama.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/equine/Llama.java.patch @@ -1,22 +1,14 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/animal/equine/Llama.java b/net/minecraft/world/entity/animal/equine/Llama.java -index 1522efc1e6937bc8a24a2df77d5421ae04a6642b..cceb66525a4d017b2db21bd301e63670c639223f 100644 --- a/net/minecraft/world/entity/animal/equine/Llama.java +++ b/net/minecraft/world/entity/animal/equine/Llama.java -@@ -76,6 +76,7 @@ public class Llama extends AbstractChestedHorse implements RangedAttackMob { - boolean didSpit; +@@ -75,6 +_,7 @@ + private boolean didSpit; private @Nullable Llama caravanHead; public @Nullable Llama caravanTail; // Paper - public + public boolean shouldJoinCaravan = true; // Purpur - Llama API - public Llama(EntityType type, Level level) { + public Llama(final EntityType type, final Level level) { super(type, level); -@@ -105,6 +106,7 @@ public class Llama extends AbstractChestedHorse implements RangedAttackMob { +@@ -104,6 +_,7 @@ super.addAdditionalSaveData(output); output.store("Variant", Llama.Variant.LEGACY_CODEC, this.getVariant()); output.putInt("Strength", this.getStrength()); @@ -24,7 +16,7 @@ index 1522efc1e6937bc8a24a2df77d5421ae04a6642b..cceb66525a4d017b2db21bd301e63670 } @Override -@@ -112,6 +114,7 @@ public class Llama extends AbstractChestedHorse implements RangedAttackMob { +@@ -111,6 +_,7 @@ this.setStrength(input.getIntOr("Strength", 0)); super.readAdditionalSaveData(input); this.setVariant(input.read("Variant", Llama.Variant.LEGACY_CODEC).orElse(Llama.Variant.DEFAULT)); @@ -32,7 +24,7 @@ index 1522efc1e6937bc8a24a2df77d5421ae04a6642b..cceb66525a4d017b2db21bd301e63670 } @Override -@@ -388,6 +391,7 @@ public class Llama extends AbstractChestedHorse implements RangedAttackMob { +@@ -387,6 +_,7 @@ public void leaveCaravan() { if (this.caravanHead != null) { @@ -40,11 +32,11 @@ index 1522efc1e6937bc8a24a2df77d5421ae04a6642b..cceb66525a4d017b2db21bd301e63670 this.caravanHead.caravanTail = null; } -@@ -395,6 +399,7 @@ public class Llama extends AbstractChestedHorse implements RangedAttackMob { +@@ -394,6 +_,7 @@ } - public void joinCaravan(Llama caravanHead) { + public void joinCaravan(final Llama tail) { + if (!this.level().purpurConfig.llamaJoinCaravans || !shouldJoinCaravan || !new org.purpurmc.purpur.event.entity.LlamaJoinCaravanEvent((org.bukkit.entity.Llama) getBukkitEntity(), (org.bukkit.entity.Llama) caravanHead.getBukkitEntity()).callEvent()) return; // Purpur - Llama API // Purpur - Config to disable Llama caravans - this.caravanHead = caravanHead; + this.caravanHead = tail; this.caravanHead.caravanTail = this; } diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/feline/Cat.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/feline/Cat.java.patch similarity index 56% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/feline/Cat.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/feline/Cat.java.patch index 325da12ca..ac135b32d 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/feline/Cat.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/feline/Cat.java.patch @@ -1,15 +1,7 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/animal/feline/Cat.java b/net/minecraft/world/entity/animal/feline/Cat.java -index f17d7a4ef7061d6ede9a755b5a77324a28c3eeaa..6acd39413ab4fed1eaf251d3b6d9b9e184060e5c 100644 --- a/net/minecraft/world/entity/animal/feline/Cat.java +++ b/net/minecraft/world/entity/animal/feline/Cat.java -@@ -354,6 +354,14 @@ public class Cat extends TamableAnimal { - return this.isTame() && otherAnimal instanceof Cat cat && cat.isTame() && super.canMate(otherAnimal); +@@ -382,6 +_,14 @@ + return this.isTame() && partner instanceof Cat cat && cat.isTame() && super.canMate(partner); } + // Purpur start - Configurable default collar color @@ -22,11 +14,11 @@ index f17d7a4ef7061d6ede9a755b5a77324a28c3eeaa..6acd39413ab4fed1eaf251d3b6d9b9e1 + @Override public @Nullable SpawnGroupData finalizeSpawn( - ServerLevelAccessor level, DifficultyInstance difficulty, EntitySpawnReason spawnReason, @Nullable SpawnGroupData spawnGroupData -@@ -451,7 +459,7 @@ public class Cat extends TamableAnimal { + final ServerLevelAccessor level, final DifficultyInstance difficulty, final EntitySpawnReason spawnReason, @Nullable SpawnGroupData groupData +@@ -476,7 +_,7 @@ } - private void tryToTame(Player player) { + private void tryToTame(final Player player) { - if (this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit + if (((this.level().purpurConfig.alwaysTameInCreative && player.hasInfiniteMaterials()) || this.random.nextInt(3) == 0) && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit // Purpur - Config to always tame in Creative this.tame(player); diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/feline/Ocelot.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/feline/Ocelot.java.patch new file mode 100644 index 000000000..22b5567e9 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/feline/Ocelot.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/entity/animal/feline/Ocelot.java ++++ b/net/minecraft/world/entity/animal/feline/Ocelot.java +@@ -234,7 +_,7 @@ + public boolean checkSpawnObstruction(final LevelReader level) { + if (level.isUnobstructed(this) && !level.containsAnyLiquid(this.getBoundingBox())) { + BlockPos pos = this.blockPosition(); +- if (pos.getY() < level.getSeaLevel()) { ++ if (!level().purpurConfig.ocelotSpawnUnderSeaLevel && pos.getY() < level.getSeaLevel()) { // Purpur - Option Ocelot Spawn Under Sea Level + return false; + } + diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/fish/WaterAnimal.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/fish/WaterAnimal.java.patch new file mode 100644 index 000000000..35a1f6362 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/fish/WaterAnimal.java.patch @@ -0,0 +1,12 @@ +--- a/net/minecraft/world/entity/animal/fish/WaterAnimal.java ++++ b/net/minecraft/world/entity/animal/fish/WaterAnimal.java +@@ -80,8 +_,7 @@ + seaLevel = level.getMinecraftWorld().paperConfig().entities.spawning.wateranimalSpawnHeight.maximum.or(seaLevel); + minSpawnLevel = level.getMinecraftWorld().paperConfig().entities.spawning.wateranimalSpawnHeight.minimum.or(minSpawnLevel); + // Paper end - Make water animal spawn height configurable +- return pos.getY() >= minSpawnLevel +- && pos.getY() <= seaLevel ++ return ((spawnReason == EntitySpawnReason.SPAWNER && level.getMinecraftWorld().purpurConfig.spawnerFixMC238526) || (pos.getY() >= minSpawnLevel && pos.getY() <= seaLevel)) // Purpur - MC-238526 - Fix spawner not spawning water animals correctly + && level.getFluidState(pos.below()).is(FluidTags.WATER) + && level.getBlockState(pos.above()).is(Blocks.WATER); + } diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/golem/CopperGolemAi.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/golem/CopperGolemAi.java.patch similarity index 55% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/golem/CopperGolemAi.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/golem/CopperGolemAi.java.patch index bc8ef01e8..7f9eca8e6 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/golem/CopperGolemAi.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/golem/CopperGolemAi.java.patch @@ -1,31 +1,23 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/animal/golem/CopperGolemAi.java b/net/minecraft/world/entity/animal/golem/CopperGolemAi.java -index 56872b4674ae4ce0ebcb6c28ae606265384777cd..fd556e10ff87eac5e965a5eef31cfe0c0f8fbd66 100644 --- a/net/minecraft/world/entity/animal/golem/CopperGolemAi.java +++ b/net/minecraft/world/entity/animal/golem/CopperGolemAi.java -@@ -43,7 +43,7 @@ public class CopperGolemAi { +@@ -41,7 +_,7 @@ private static final int TICK_TO_START_ON_REACHED_INTERACTION = 1; private static final int TICK_TO_PLAY_ON_REACHED_SOUND = 9; - private static final Predicate TRANSPORT_ITEM_SOURCE_BLOCK = state -> state.is(BlockTags.COPPER_CHESTS); -- private static final Predicate TRANSPORT_ITEM_DESTINATION_BLOCK = state -> state.is(Blocks.CHEST) || state.is(Blocks.TRAPPED_CHEST); -+ private static final Predicate TRANSPORT_ITEM_DESTINATION_BLOCK = state -> state.is(Blocks.CHEST) || state.is(Blocks.TRAPPED_CHEST); // Purpur - copper golem can place items in barrels or shulkers option - diff on change - private static final ImmutableList>> SENSOR_TYPES = ImmutableList.of( - SensorType.NEAREST_LIVING_ENTITIES, SensorType.HURT_BY - ); -@@ -158,6 +158,11 @@ public class CopperGolemAi { + private static final Predicate TRANSPORT_ITEM_SOURCE_BLOCK = block -> block.is(BlockTags.COPPER_CHESTS); +- private static final Predicate TRANSPORT_ITEM_DESTINATION_BLOCK = block -> block.is(Blocks.CHEST) || block.is(Blocks.TRAPPED_CHEST); ++ private static final Predicate TRANSPORT_ITEM_DESTINATION_BLOCK = block -> block.is(Blocks.CHEST) || block.is(Blocks.TRAPPED_CHEST); // Purpur - copper golem can place items in barrels or shulkers option - diff on change + + protected static List> getActivities() { + return List.of(initCoreActivity(), initIdleActivity()); +@@ -130,6 +_,11 @@ } - if (integer == 60) { + if (ticksSinceReachingTarget == 60) { + // Purpur start - copper golem can place items in barrels or shulkers option + if (container instanceof net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity shulkerBoxBlockEntity && shulkerBoxBlockEntity.openCount > 0) { + container.stopOpen(copperGolem); + } + // Purpur end - copper golem can place items in barrels or shulkers option - if (container.getEntitiesWithContainerOpen().contains(pathfinderMob)) { + if (container.getEntitiesWithContainerOpen().contains(body)) { container.stopOpen(copperGolem); } diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/golem/IronGolem.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/golem/IronGolem.java.patch similarity index 65% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/golem/IronGolem.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/golem/IronGolem.java.patch index e5ab418df..a2fa06c68 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/golem/IronGolem.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/golem/IronGolem.java.patch @@ -1,20 +1,12 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/animal/golem/IronGolem.java b/net/minecraft/world/entity/animal/golem/IronGolem.java -index b2c4e93f6063ded665b18ba3b4eaa0eb4cd98732..32425f0aaa748c7f80f2e5cf95ef27238fe50489 100644 --- a/net/minecraft/world/entity/animal/golem/IronGolem.java +++ b/net/minecraft/world/entity/animal/golem/IronGolem.java -@@ -58,13 +58,25 @@ public class IronGolem extends AbstractGolem implements NeutralMob { +@@ -58,13 +_,25 @@ private static final UniformInt PERSISTENT_ANGER_TIME = TimeUtil.rangeOfSeconds(20, 39); private long persistentAngerEndTime; private @Nullable EntityReference persistentAngerTarget; + private java.util.@Nullable UUID summoner; // Purpur - Summoner API - public IronGolem(EntityType type, Level level) { + public IronGolem(final EntityType type, final Level level) { super(type, level); } @@ -34,26 +26,26 @@ index b2c4e93f6063ded665b18ba3b4eaa0eb4cd98732..32425f0aaa748c7f80f2e5cf95ef2723 this.goalSelector.addGoal(1, new MeleeAttackGoal(this, 1.0, true)); this.goalSelector.addGoal(2, new MoveTowardsTargetGoal(this, 0.9, 32.0F)); this.goalSelector.addGoal(2, new MoveBackToVillageGoal(this, 0.6, false)); -@@ -142,6 +154,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { - protected void addAdditionalSaveData(ValueOutput output) { +@@ -142,6 +_,7 @@ + protected void addAdditionalSaveData(final ValueOutput output) { super.addAdditionalSaveData(output); output.putBoolean("PlayerCreated", this.isPlayerCreated()); + output.storeNullable("Purpur.Summoner", net.minecraft.core.UUIDUtil.CODEC, getSummoner()); // Purpur - Summoner API this.addPersistentAngerSaveData(output); } -@@ -149,6 +162,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { - protected void readAdditionalSaveData(ValueInput input) { +@@ -149,6 +_,7 @@ + protected void readAdditionalSaveData(final ValueInput input) { super.readAdditionalSaveData(input); this.setPlayerCreated(input.getBooleanOr("PlayerCreated", false)); + this.setSummoner(input.read("Purpur.Summoner", net.minecraft.core.UUIDUtil.CODEC).orElse(null)); // Purpur - Summoner API this.readPersistentAngerSaveData(this.level(), input); } -@@ -267,6 +281,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { - float f = 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F; - this.playSound(SoundEvents.IRON_GOLEM_REPAIR, 1.0F, f); - itemInHand.consume(1, player); +@@ -267,6 +_,7 @@ + float pitch = 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F; + this.playSound(SoundEvents.IRON_GOLEM_REPAIR, 1.0F, pitch); + itemStack.consume(1, player); + if (this.level().purpurConfig.ironGolemHealCalm && isAngry() && getHealth() == getMaxHealth()) stopBeingAngry(); // Purpur - Iron golem calm anger options return InteractionResult.SUCCESS; } diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/parrot/Parrot.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/parrot/Parrot.java.patch similarity index 66% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/parrot/Parrot.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/parrot/Parrot.java.patch index 2e49ca844..9f03ed4c6 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/parrot/Parrot.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/parrot/Parrot.java.patch @@ -1,14 +1,6 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/animal/parrot/Parrot.java b/net/minecraft/world/entity/animal/parrot/Parrot.java -index 62a26395ee0c3ee450ad3b1ac88bc85523dd27b4..0337ddcd664cd0329d98286214d1aa4daf83e1ea 100644 --- a/net/minecraft/world/entity/animal/parrot/Parrot.java +++ b/net/minecraft/world/entity/animal/parrot/Parrot.java -@@ -164,6 +164,7 @@ public class Parrot extends ShoulderRidingEntity implements FlyingAnimal { +@@ -164,6 +_,7 @@ protected void registerGoals() { this.goalSelector.addGoal(0, new TamableAnimal.TamableAnimalPanicGoal(1.25)); this.goalSelector.addGoal(0, new FloatGoal(this)); @@ -16,7 +8,7 @@ index 62a26395ee0c3ee450ad3b1ac88bc85523dd27b4..0337ddcd664cd0329d98286214d1aa4d this.goalSelector.addGoal(1, new LookAtPlayerGoal(this, Player.class, 8.0F)); this.goalSelector.addGoal(2, new SitWhenOrderedToGoal(this)); this.goalSelector.addGoal(2, new FollowOwnerGoal(this, 1.0, 5.0F, 1.0F)); -@@ -269,7 +270,7 @@ public class Parrot extends ShoulderRidingEntity implements FlyingAnimal { +@@ -270,7 +_,7 @@ } if (!this.level().isClientSide()) { @@ -25,33 +17,33 @@ index 62a26395ee0c3ee450ad3b1ac88bc85523dd27b4..0337ddcd664cd0329d98286214d1aa4d this.tame(player); this.level().broadcastEntityEvent(this, EntityEvent.TAMING_SUCCEEDED); } else { -@@ -277,6 +278,7 @@ public class Parrot extends ShoulderRidingEntity implements FlyingAnimal { +@@ -278,6 +_,7 @@ } } + if (this.level().purpurConfig.parrotBreedable) return super.mobInteract(player, hand); // Purpur - Breedable parrots return InteractionResult.SUCCESS; - } else if (!itemInHand.is(ItemTags.PARROT_POISONOUS_FOOD)) { + } else if (!itemStack.is(ItemTags.PARROT_POISONOUS_FOOD)) { if (!this.isFlying() && this.isTame() && this.isOwnedBy(player)) { -@@ -301,7 +303,7 @@ public class Parrot extends ShoulderRidingEntity implements FlyingAnimal { +@@ -302,7 +_,7 @@ @Override - public boolean isFood(ItemStack stack) { + public boolean isFood(final ItemStack itemStack) { - return false; + return this.level().purpurConfig.parrotBreedable && stack.is(ItemTags.PARROT_FOOD); // Purpur - Breedable parrots } public static boolean checkParrotSpawnRules( -@@ -316,12 +318,12 @@ public class Parrot extends ShoulderRidingEntity implements FlyingAnimal { +@@ -317,12 +_,12 @@ @Override - public boolean canMate(Animal otherAnimal) { + public boolean canMate(final Animal partner) { - return false; + return super.canMate(otherAnimal); // Purpur - Breedable parrots } @Override - public @Nullable AgeableMob getBreedOffspring(ServerLevel level, AgeableMob partner) { + public @Nullable AgeableMob getBreedOffspring(final ServerLevel level, final AgeableMob partner) { - return null; + return level.purpurConfig.parrotBreedable ? EntityType.PARROT.create(level, EntitySpawnReason.BREEDING) : null; // Purpur - Breedable parrots } diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/pig/Pig.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/pig/Pig.java.patch new file mode 100644 index 000000000..01e1e7375 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/pig/Pig.java.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/world/entity/animal/pig/Pig.java ++++ b/net/minecraft/world/entity/animal/pig/Pig.java +@@ -158,6 +_,19 @@ + @Override + public InteractionResult mobInteract(final Player player, final InteractionHand hand) { + boolean hasFood = this.isFood(player.getItemInHand(hand)); ++ // Purpur start - Pigs give saddle back ++ if (level().purpurConfig.pigGiveSaddleBack && player.isSecondaryUseActive() && !hasFood && isSaddled() && !isVehicle()) { ++ this.setItemSlot(EquipmentSlot.SADDLE, ItemStack.EMPTY); ++ if (!player.getAbilities().instabuild) { ++ ItemStack saddle = new ItemStack(Items.SADDLE); ++ if (!player.getInventory().add(saddle)) { ++ player.drop(saddle, false); ++ } ++ } ++ return InteractionResult.SUCCESS; ++ } ++ // Purpur end - Pigs give saddle back ++ + if (!hasFood && this.isSaddled() && !this.isVehicle() && !player.isSecondaryUseActive()) { + if (!this.level().isClientSide()) { + player.startRiding(this); diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/polarbear/PolarBear.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/polarbear/PolarBear.java.patch similarity index 65% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/polarbear/PolarBear.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/polarbear/PolarBear.java.patch index 26e620f67..6b704cb1f 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/polarbear/PolarBear.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/polarbear/PolarBear.java.patch @@ -1,14 +1,6 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/animal/polarbear/PolarBear.java b/net/minecraft/world/entity/animal/polarbear/PolarBear.java -index 8fd0d632e7c6fc7fcb7e9cf141638b5171800799..df4b4a4d32019ef3a667841a0ce4485a8325e897 100644 --- a/net/minecraft/world/entity/animal/polarbear/PolarBear.java +++ b/net/minecraft/world/entity/animal/polarbear/PolarBear.java -@@ -66,6 +66,29 @@ public class PolarBear extends Animal implements NeutralMob { +@@ -67,6 +_,29 @@ super(type, level); } @@ -36,21 +28,21 @@ index 8fd0d632e7c6fc7fcb7e9cf141638b5171800799..df4b4a4d32019ef3a667841a0ce4485a + // Purpur end - Breedable Polar Bears + @Override - public @Nullable AgeableMob getBreedOffspring(ServerLevel level, AgeableMob partner) { + public @Nullable AgeableMob getBreedOffspring(final ServerLevel level, final AgeableMob partner) { return EntityType.POLAR_BEAR.create(level, EntitySpawnReason.BREEDING); -@@ -73,7 +96,7 @@ public class PolarBear extends Animal implements NeutralMob { +@@ -74,7 +_,7 @@ @Override - public boolean isFood(ItemStack stack) { + public boolean isFood(final ItemStack itemStack) { - return false; -+ return level().purpurConfig.polarBearBreedableItem != null && stack.getItem() == level().purpurConfig.polarBearBreedableItem; // Purpur - Breedable Polar Bears ++ return level().purpurConfig.polarBearBreedableItem != null && itemStack.getItem() == level().purpurConfig.polarBearBreedableItem; // Purpur - Breedable Polar Bears } @Override -@@ -82,6 +105,12 @@ public class PolarBear extends Animal implements NeutralMob { +@@ -83,6 +_,12 @@ this.goalSelector.addGoal(0, new FloatGoal(this)); this.goalSelector.addGoal(1, new PolarBear.PolarBearMeleeAttackGoal()); - this.goalSelector.addGoal(1, new PanicGoal(this, 2.0, mob -> mob.isBaby() ? DamageTypeTags.PANIC_CAUSES : DamageTypeTags.PANIC_ENVIRONMENTAL_CAUSES)); + this.goalSelector.addGoal(1, new PanicGoal(this, 2.0, bear -> bear.isBaby() ? DamageTypeTags.PANIC_CAUSES : DamageTypeTags.PANIC_ENVIRONMENTAL_CAUSES)); + // Purpur start - Breedable Polar Bears + if (level().purpurConfig.polarBearBreedableItem != null) { + this.goalSelector.addGoal(2, new net.minecraft.world.entity.ai.goal.BreedGoal(this, 1.0D)); diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/rabbit/Rabbit.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/rabbit/Rabbit.java.patch new file mode 100644 index 000000000..0258be4fe --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/rabbit/Rabbit.java.patch @@ -0,0 +1,26 @@ +--- a/net/minecraft/world/entity/animal/rabbit/Rabbit.java ++++ b/net/minecraft/world/entity/animal/rabbit/Rabbit.java +@@ -419,10 +_,23 @@ + } + + this.setVariant(variant); ++ ++ // Purpur start - Special mobs naturally spawn ++ if (variant != Variant.EVIL && level.getLevel().purpurConfig.rabbitNaturalToast > 0D && random.nextDouble() <= level.getLevel().purpurConfig.rabbitNaturalToast) { ++ setCustomName(Component.translatable("Toast")); ++ } ++ // Purpur end - Special mobs naturally spawn ++ + return super.finalizeSpawn(level, difficulty, spawnReason, groupData); + } + + private static Rabbit.Variant getRandomRabbitVariant(final LevelAccessor level, final BlockPos pos) { ++ // Purpur start - Special mobs naturally spawn ++ Level world = level.getMinecraftWorld(); ++ if (world.purpurConfig.rabbitNaturalKiller > 0D && world.getRandom().nextDouble() <= world.purpurConfig.rabbitNaturalKiller) { ++ return Rabbit.Variant.EVIL; ++ } ++ // Purpur end - Special mobs naturally spawn + Holder biome = level.getBiome(pos); + int randomVal = level.getRandom().nextInt(100); + if (biome.is(BiomeTags.SPAWNS_WHITE_RABBITS)) { diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/squid/Squid.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/squid/Squid.java.patch similarity index 65% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/squid/Squid.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/squid/Squid.java.patch index f9821ce42..85d8e2541 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/squid/Squid.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/squid/Squid.java.patch @@ -1,16 +1,8 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/animal/squid/Squid.java b/net/minecraft/world/entity/animal/squid/Squid.java -index 0e13879ce2802ff8ef0ee9b745a23396727c3e30..504573bf4cbdf1debfa9f9bd071fa40d443b860d 100644 --- a/net/minecraft/world/entity/animal/squid/Squid.java +++ b/net/minecraft/world/entity/animal/squid/Squid.java -@@ -48,10 +48,29 @@ public class Squid extends AgeableWaterCreature { +@@ -51,10 +_,29 @@ - public Squid(EntityType type, Level level) { + public Squid(final EntityType type, final Level level) { super(type, level); - // this.random.setSeed(this.getId()); // Paper - Share random for entities to make them more random + if (!level.purpurConfig.entitySharedRandom) this.random.setSeed(this.getId()); // Paper - Share random for entities to make them more random // Purpur - Add toggle for RNG manipulation @@ -39,20 +31,20 @@ index 0e13879ce2802ff8ef0ee9b745a23396727c3e30..504573bf4cbdf1debfa9f9bd071fa40d @Override protected void registerGoals() { this.goalSelector.addGoal(0, new Squid.SquidRandomMovementGoal(this)); -@@ -128,6 +147,7 @@ public class Squid extends AgeableWaterCreature { +@@ -131,6 +_,7 @@ } if (this.isInWater()) { + if (canFly()) setNoGravity(!wasTouchingWater); // Purpur - Flying squids! Oh my! 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; -@@ -308,7 +328,7 @@ public class Squid extends AgeableWaterCreature { + float tentacleScale = this.tentacleMovement / (float) Math.PI; + this.tentacleAngle = Mth.sin(tentacleScale * tentacleScale * (float) Math.PI) * (float) Math.PI * 0.25F; +@@ -321,7 +_,7 @@ int noActionTime = this.squid.getNoActionTime(); if (noActionTime > 100) { this.squid.movementVector = Vec3.ZERO; - } else if (this.squid.getRandom().nextInt(reducedTickDelay(50)) == 0 || !this.squid.wasTouchingWater || !this.squid.hasMovementVector()) { + } else if (this.squid.getRandom().nextInt(reducedTickDelay(50)) == 0 || !this.squid.isInWater() || !this.squid.hasMovementVector()) { // Purpur - Flying squids! Oh my! - float f = this.squid.getRandom().nextFloat() * (float) (Math.PI * 2); - this.squid.movementVector = new Vec3(Mth.cos(f) * 0.2F, -0.1F + this.squid.getRandom().nextFloat() * 0.2F, Mth.sin(f) * 0.2F); + float angle = this.squid.getRandom().nextFloat() * (float) (Math.PI * 2); + this.squid.movementVector = new Vec3(Mth.cos(angle) * 0.2F, -0.1F + this.squid.getRandom().nextFloat() * 0.2F, Mth.sin(angle) * 0.2F); } diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/wolf/Wolf.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/wolf/Wolf.java.patch similarity index 84% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/wolf/Wolf.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/wolf/Wolf.java.patch index f99dcc366..12eddbc58 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/animal/wolf/Wolf.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/wolf/Wolf.java.patch @@ -1,17 +1,9 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/animal/wolf/Wolf.java b/net/minecraft/world/entity/animal/wolf/Wolf.java -index ffad6072280fb4d02f0a37a97d8c83fba85d3bc2..725624f63a2fbf0bd489a92e2c5862c82d72556c 100644 --- a/net/minecraft/world/entity/animal/wolf/Wolf.java +++ b/net/minecraft/world/entity/animal/wolf/Wolf.java -@@ -100,6 +100,37 @@ public class Wolf extends TamableAnimal implements NeutralMob { - EntityType type = entity.getType(); - return type == EntityType.SHEEP || type == EntityType.RABBIT || type == EntityType.FOX; - }; +@@ -97,6 +_,37 @@ + public static final TargetingConditions.Selector PREY_SELECTOR = (target, level) -> target.is(EntityType.SHEEP) + || target.is(EntityType.RABBIT) + || target.is(EntityType.FOX); + // Purpur start - Configurable chance for wolves to spawn rabid + private boolean isRabid = false; + private static final TargetingConditions.Selector RABID_PREDICATE = (entity, ignored) -> entity instanceof net.minecraft.server.level.ServerPlayer || entity instanceof net.minecraft.world.entity.Mob; @@ -46,8 +38,8 @@ index ffad6072280fb4d02f0a37a97d8c83fba85d3bc2..725624f63a2fbf0bd489a92e2c5862c8 private static final float START_HEALTH = 8.0F; private static final float TAME_HEALTH = 40.0F; private static final float ARMOR_REPAIR_UNIT = 0.125F; -@@ -121,12 +152,47 @@ public class Wolf extends TamableAnimal implements NeutralMob { - this.setPathfindingMalus(PathType.DANGER_POWDER_SNOW, -1.0F); +@@ -118,12 +_,47 @@ + this.setPathfindingMalus(PathType.ON_TOP_OF_POWDER_SNOW, -1.0F); } + // Purpur start - Configurable chance for wolves to spawn rabid @@ -94,7 +86,7 @@ index ffad6072280fb4d02f0a37a97d8c83fba85d3bc2..725624f63a2fbf0bd489a92e2c5862c8 this.goalSelector.addGoal(4, new LeapAtTargetGoal(this, 0.4F)); this.goalSelector.addGoal(5, new MeleeAttackGoal(this, 1.0, true)); this.goalSelector.addGoal(6, new FollowOwnerGoal(this, 1.0, 10.0F, 2.0F)); -@@ -139,7 +205,7 @@ public class Wolf extends TamableAnimal implements NeutralMob { +@@ -136,7 +_,7 @@ this.targetSelector.addGoal(2, new OwnerHurtTargetGoal(this)); this.targetSelector.addGoal(3, new HurtByTargetGoal(this).setAlertOthers()); this.targetSelector.addGoal(4, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, this::isAngryAt)); @@ -103,15 +95,15 @@ index ffad6072280fb4d02f0a37a97d8c83fba85d3bc2..725624f63a2fbf0bd489a92e2c5862c8 this.targetSelector.addGoal(6, new NonTameRandomTargetGoal<>(this, Turtle.class, false, Turtle.BABY_ON_LAND_SELECTOR)); this.targetSelector.addGoal(7, new NearestAttackableTargetGoal<>(this, AbstractSkeleton.class, false)); this.targetSelector.addGoal(8, new ResetUniversalAngerTargetGoal<>(this, true)); -@@ -229,6 +295,7 @@ public class Wolf extends TamableAnimal implements NeutralMob { - protected void addAdditionalSaveData(ValueOutput output) { +@@ -231,6 +_,7 @@ + protected void addAdditionalSaveData(final ValueOutput output) { super.addAdditionalSaveData(output); output.store("CollarColor", DyeColor.LEGACY_ID_CODEC, this.getCollarColor()); + output.putBoolean("Purpur.IsRabid", this.isRabid); // Purpur - Configurable chance for wolves to spawn rabid VariantUtils.writeVariant(output, this.getVariant()); this.addPersistentAngerSaveData(output); this.getSoundVariant() -@@ -243,6 +310,10 @@ public class Wolf extends TamableAnimal implements NeutralMob { +@@ -245,6 +_,10 @@ super.readAdditionalSaveData(input); VariantUtils.readVariant(input, Registries.WOLF_VARIANT).ifPresent(this::setVariant); this.setCollarColor(input.read("CollarColor", DyeColor.LEGACY_ID_CODEC).orElse(DEFAULT_COLLAR_COLOR)); @@ -121,8 +113,8 @@ index ffad6072280fb4d02f0a37a97d8c83fba85d3bc2..725624f63a2fbf0bd489a92e2c5862c8 + // Purpur end - Configurable chance for wolves to spawn rabid this.readPersistentAngerSaveData(this.level(), input); input.read("sound_variant", ResourceKey.codec(Registries.WOLF_SOUND_VARIANT)) - .flatMap(resourceKey -> this.registryAccess().lookupOrThrow(Registries.WOLF_SOUND_VARIANT).get((ResourceKey)resourceKey)) -@@ -266,6 +337,10 @@ public class Wolf extends TamableAnimal implements NeutralMob { + .flatMap(soundVariant -> this.registryAccess().lookupOrThrow(Registries.WOLF_SOUND_VARIANT).get((ResourceKey)soundVariant)) +@@ -268,6 +_,10 @@ } this.setSoundVariant(WolfSoundVariants.pickRandomSoundVariant(this.registryAccess(), level.getRandom())); @@ -130,10 +122,10 @@ index ffad6072280fb4d02f0a37a97d8c83fba85d3bc2..725624f63a2fbf0bd489a92e2c5862c8 + this.isRabid = level.getLevel().purpurConfig.wolfNaturalRabid > 0.0D && random.nextDouble() <= level.getLevel().purpurConfig.wolfNaturalRabid; + this.updatePathfinders(false); + // Purpur end - Configurable chance for wolves to spawn rabid - return super.finalizeSpawn(level, difficulty, spawnReason, spawnGroupData); + return super.finalizeSpawn(level, difficulty, spawnReason, groupData); } -@@ -316,6 +391,11 @@ public class Wolf extends TamableAnimal implements NeutralMob { +@@ -316,6 +_,11 @@ public void tick() { super.tick(); if (this.isAlive()) { @@ -145,8 +137,8 @@ index ffad6072280fb4d02f0a37a97d8c83fba85d3bc2..725624f63a2fbf0bd489a92e2c5862c8 this.interestedAngleO = this.interestedAngle; if (this.isInterested()) { this.interestedAngle = this.interestedAngle + (1.0F - this.interestedAngle) * 0.4F; -@@ -517,13 +597,27 @@ public class Wolf extends TamableAnimal implements NeutralMob { - itemInHand.consume(1, player); +@@ -504,13 +_,27 @@ + itemStack.consume(1, player); this.tryToTame(player); return InteractionResult.SUCCESS_SERVER; + // Purpur start - Configurable chance for wolves to spawn rabid @@ -168,7 +160,7 @@ index ffad6072280fb4d02f0a37a97d8c83fba85d3bc2..725624f63a2fbf0bd489a92e2c5862c8 return super.mobInteract(player, hand); } - private void tryToTame(Player player) { + private void tryToTame(final Player player) { - if (this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit - added event call + if (((this.level().purpurConfig.alwaysTameInCreative && player.hasInfiniteMaterials()) || this.random.nextInt(3) == 0) && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit - added event call // Purpur - Config to always tame in Creative this.tame(player); diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java.patch similarity index 69% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java.patch index 95cab977a..2094309f6 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java.patch @@ -1,14 +1,6 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java b/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java -index c095f42aa103b7874fb5d8dcece1b1484c2e2968..d1c593ccfab7bee4366ee7c56606a230964e3fb7 100644 --- a/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java +++ b/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java -@@ -39,6 +39,24 @@ public class EndCrystal extends Entity { +@@ -39,6 +_,24 @@ this.setPos(x, y, z); } @@ -33,7 +25,7 @@ index c095f42aa103b7874fb5d8dcece1b1484c2e2968..d1c593ccfab7bee4366ee7c56606a230 @Override protected Entity.MovementEmission getMovementEmission() { return Entity.MovementEmission.NONE; -@@ -75,6 +93,8 @@ public class EndCrystal extends Entity { +@@ -75,6 +_,8 @@ } } // Paper end - Fix invulnerable end crystals @@ -42,12 +34,12 @@ index c095f42aa103b7874fb5d8dcece1b1484c2e2968..d1c593ccfab7bee4366ee7c56606a230 } @Override -@@ -115,15 +135,17 @@ public class EndCrystal extends Entity { +@@ -115,15 +_,17 @@ } // CraftBukkit end - if (!damageSource.is(DamageTypeTags.IS_EXPLOSION)) { + if (!source.is(DamageTypeTags.IS_EXPLOSION)) { + if (shouldExplode()) {// Purpur - End crystal explosion options - DamageSource damageSource1 = damageSource.getEntity() != null ? this.damageSources().explosion(this, damageSource.getEntity()) : null; + DamageSource damageSource = source.getEntity() != null ? this.damageSources().explosion(this, source.getEntity()) : null; // CraftBukkit start - org.bukkit.event.entity.ExplosionPrimeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callExplosionPrimeEvent(this, 6.0F, false); + org.bukkit.event.entity.ExplosionPrimeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callExplosionPrimeEvent(this, getExplosionPower(), hasExplosionFire()); // Purpur - End crystal explosion options @@ -56,8 +48,8 @@ index c095f42aa103b7874fb5d8dcece1b1484c2e2968..d1c593ccfab7bee4366ee7c56606a230 } this.remove(Entity.RemovalReason.KILLED, org.bukkit.event.entity.EntityRemoveEvent.Cause.EXPLODE); // Paper - add Bukkit remove cause -- level.explode(this, damageSource1, null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.BLOCK); -+ level.explode(this, damageSource1, null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), getExplosionEffect()); // Purpur - End crystal explosion options +- level.explode(this, damageSource, null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.BLOCK); ++ level.explode(this, damageSource, null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), getExplosionEffect()); // Purpur - End crystal explosion options + } else this.unsetRemoved(); // Purpur - End crystal explosion options } else { this.remove(Entity.RemovalReason.KILLED, org.bukkit.event.entity.EntityRemoveEvent.Cause.DEATH); // Paper - add Bukkit remove cause diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch new file mode 100644 index 000000000..f55ea27b2 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch @@ -0,0 +1,19 @@ +--- a/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java ++++ b/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java +@@ -964,6 +_,7 @@ + + @Override + protected boolean canRide(final Entity vehicle) { ++ if (this.level().purpurConfig.enderDragonCanRideVehicles) return this.boardingCooldown <= 0; // Purpur - Configs for if Wither/Ender Dragon can ride vehicles + return false; + } + +@@ -999,7 +_,7 @@ + boolean shouldDrop = level.getGameRules().get(GameRules.MOB_DROPS); + int xpCount = 500; + +- if (this.dragonFight != null && !this.dragonFight.hasPreviouslyKilledDragon()) { ++ if (this.dragonFight != null && (level().purpurConfig.enderDragonAlwaysDropsFullExp || !this.dragonFight.hasPreviouslyKilledDragon())) { // Purpur - Ender dragon always drop full exp + xpCount = 12000; + } + diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/boss/wither/WitherBoss.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/boss/wither/WitherBoss.java.patch similarity index 67% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/boss/wither/WitherBoss.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/boss/wither/WitherBoss.java.patch index 9f97ef257..625f86b7d 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/boss/wither/WitherBoss.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/boss/wither/WitherBoss.java.patch @@ -1,22 +1,14 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/boss/wither/WitherBoss.java b/net/minecraft/world/entity/boss/wither/WitherBoss.java -index 86b6b94c3e63bb52917fe0f708d24aa813f433c7..be74b2f6e21e9adb1e5c96414854a5c4f07655fc 100644 --- a/net/minecraft/world/entity/boss/wither/WitherBoss.java +++ b/net/minecraft/world/entity/boss/wither/WitherBoss.java -@@ -80,6 +80,7 @@ public class WitherBoss extends Monster implements RangedAttackMob { - private static final TargetingConditions.Selector LIVING_ENTITY_SELECTOR = (entity, level) -> !entity.getType().is(EntityTypeTags.WITHER_FRIENDS) - && entity.attackable(); +@@ -82,6 +_,7 @@ + private static final TargetingConditions.Selector LIVING_ENTITY_SELECTOR = (target, level) -> !target.is(EntityTypeTags.WITHER_FRIENDS) + && target.attackable(); private static final TargetingConditions TARGETING_CONDITIONS = TargetingConditions.forCombat().range(20.0).selector(LIVING_ENTITY_SELECTOR); + private java.util.@Nullable UUID summoner; // Purpur - Summoner API - public WitherBoss(EntityType type, Level level) { + public WitherBoss(final EntityType type, final Level level) { super(type, level); -@@ -88,6 +89,16 @@ public class WitherBoss extends Monster implements RangedAttackMob { +@@ -90,6 +_,16 @@ this.xpReward = 50; } @@ -31,17 +23,17 @@ index 86b6b94c3e63bb52917fe0f708d24aa813f433c7..be74b2f6e21e9adb1e5c96414854a5c4 + // Purpur end - Summoner API + @Override - protected PathNavigation createNavigation(Level level) { + protected PathNavigation createNavigation(final Level level) { FlyingPathNavigation flyingPathNavigation = new FlyingPathNavigation(this, level); -@@ -120,6 +131,7 @@ public class WitherBoss extends Monster implements RangedAttackMob { - protected void addAdditionalSaveData(ValueOutput output) { +@@ -122,6 +_,7 @@ + protected void addAdditionalSaveData(final ValueOutput output) { super.addAdditionalSaveData(output); output.putInt("Invul", this.getInvulnerableTicks()); + output.storeNullable("Purpur.Summoner", net.minecraft.core.UUIDUtil.CODEC, getSummoner()); // Purpur - Summoner API } @Override -@@ -129,6 +141,7 @@ public class WitherBoss extends Monster implements RangedAttackMob { +@@ -131,6 +_,7 @@ if (this.hasCustomName()) { this.bossEvent.setName(this.getDisplayName()); } @@ -49,7 +41,7 @@ index 86b6b94c3e63bb52917fe0f708d24aa813f433c7..be74b2f6e21e9adb1e5c96414854a5c4 } @Override -@@ -272,7 +285,7 @@ public class WitherBoss extends Monster implements RangedAttackMob { +@@ -274,7 +_,7 @@ level.explode(this, this.getX(), this.getEyeY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB); } // CraftBukkit end @@ -58,7 +50,7 @@ index 86b6b94c3e63bb52917fe0f708d24aa813f433c7..be74b2f6e21e9adb1e5c96414854a5c4 // CraftBukkit start - Use relative location for far away sounds // level.globalLevelEvent(LevelEvent.SOUND_WITHER_BOSS_SPAWN, this.blockPosition(), 0); int viewDistance = level.getCraftServer().getViewDistance() * 16; -@@ -379,8 +392,10 @@ public class WitherBoss extends Monster implements RangedAttackMob { +@@ -378,8 +_,10 @@ } } @@ -71,10 +63,10 @@ index 86b6b94c3e63bb52917fe0f708d24aa813f433c7..be74b2f6e21e9adb1e5c96414854a5c4 } this.bossEvent.setProgress(this.getHealth() / this.getMaxHealth()); -@@ -577,6 +592,7 @@ public class WitherBoss extends Monster implements RangedAttackMob { +@@ -576,6 +_,7 @@ @Override - protected boolean canRide(Entity entity) { + protected boolean canRide(final Entity vehicle) { + if (this.level().purpurConfig.witherCanRideVehicles) return this.boardingCooldown <= 0; // Purpur - Configs for if Wither/Ender Dragon can ride vehicles return false; } diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/item/ItemEntity.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/item/ItemEntity.java.patch new file mode 100644 index 000000000..2b79ba108 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/item/ItemEntity.java.patch @@ -0,0 +1,46 @@ +--- a/net/minecraft/world/entity/item/ItemEntity.java ++++ b/net/minecraft/world/entity/item/ItemEntity.java +@@ -54,6 +_,12 @@ + public boolean canMobPickup = true; // Paper - Item#canEntityPickup + private int despawnRate = -1; // Paper - Alternative item-despawn-rate + public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Friction API ++ // Purpur start - Item entity immunities ++ public boolean immuneToCactus = false; ++ public boolean immuneToExplosion = false; ++ public boolean immuneToFire = false; ++ public boolean immuneToLightning = false; ++ // Purpur end - Item entity immunities + + public ItemEntity(final EntityType type, final Level level) { + super(type, level); +@@ -314,7 +_,16 @@ + + @Override + public final boolean hurtServer(final ServerLevel level, final DamageSource source, final float damage) { +- if (this.isInvulnerableToBase(source)) { ++ // Purpur start - Item entity immunities ++ if ( ++ (immuneToCactus && source.is(net.minecraft.world.damagesource.DamageTypes.CACTUS)) || ++ (immuneToFire && (source.is(net.minecraft.tags.DamageTypeTags.IS_FIRE) || source.is(net.minecraft.world.damagesource.DamageTypes.ON_FIRE) || source.is(net.minecraft.world.damagesource.DamageTypes.IN_FIRE))) || ++ (immuneToLightning && source.is(net.minecraft.world.damagesource.DamageTypes.LIGHTNING_BOLT)) || ++ (immuneToExplosion && source.is(net.minecraft.tags.DamageTypeTags.IS_EXPLOSION)) ++ ) { ++ return false; ++ } else if (this.isInvulnerableToBase(source)) { ++ // Purpur end - Item entity immunities + return false; + } else if (!level.getGameRules().get(GameRules.MOB_GRIEFING) && source.getEntity() instanceof Mob) { + return false; +@@ -492,6 +_,12 @@ + public void setItem(final ItemStack itemStack) { + this.getEntityData().set(DATA_ITEM, itemStack); + this.despawnRate = this.level().paperConfig().entities.spawning.altItemDespawnRate.enabled ? this.level().paperConfig().entities.spawning.altItemDespawnRate.items.getOrDefault(itemStack.getItem(), this.level().spigotConfig.itemDespawnRate) : this.level().spigotConfig.itemDespawnRate; // Paper - Alternative item-despawn-rate ++ // Purpur start - Item entity immunities ++ if (level().purpurConfig.itemImmuneToCactus.contains(itemStack.getItem())) immuneToCactus = true; ++ if (level().purpurConfig.itemImmuneToExplosion.contains(itemStack.getItem())) immuneToExplosion = true; ++ if (level().purpurConfig.itemImmuneToFire.contains(itemStack.getItem())) immuneToFire = true; ++ if (level().purpurConfig.itemImmuneToLightning.contains(itemStack.getItem())) immuneToLightning = true; ++ // level end - Item entity immunities + } + + public void setTarget(final @Nullable UUID target) { diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/Creeper.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Creeper.java.patch similarity index 55% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/Creeper.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Creeper.java.patch index 9249e4fdc..56740ff90 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/Creeper.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Creeper.java.patch @@ -1,22 +1,14 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/monster/Creeper.java b/net/minecraft/world/entity/monster/Creeper.java -index e6d93c7a339f06c40b78f554f4e7070fb7fcad02..168003b7159b5e9ea3e3ca19d0b939ed1cfd2311 100644 --- a/net/minecraft/world/entity/monster/Creeper.java +++ b/net/minecraft/world/entity/monster/Creeper.java -@@ -56,6 +56,7 @@ public class Creeper extends Monster { +@@ -56,6 +_,7 @@ public int explosionRadius = 3; public boolean droppedSkulls; public @Nullable Entity entityIgniter; // CraftBukkit + private boolean exploding = false; // Purpur - Config to make Creepers explode on death - public Creeper(EntityType type, Level level) { + public Creeper(final EntityType type, final Level level) { super(type, level); -@@ -159,6 +160,27 @@ public class Creeper extends Monster { +@@ -159,6 +_,27 @@ return false; // CraftBukkit } @@ -42,28 +34,28 @@ index e6d93c7a339f06c40b78f554f4e7070fb7fcad02..168003b7159b5e9ea3e3ca19d0b939ed + // Purpur end - Config to make Creepers explode on death + @Override - public SoundEvent getHurtSound(DamageSource damageSource) { + public SoundEvent getHurtSound(final DamageSource source) { return SoundEvents.CREEPER_HURT; -@@ -243,14 +265,16 @@ public class Creeper extends Monster { +@@ -243,14 +_,16 @@ } public void explodeCreeper() { + this.exploding = true; // Purpur - Config to make Creepers explode on death - if (this.level() instanceof ServerLevel serverLevel) { - float f = this.isPowered() ? 2.0F : 1.0F; -+ float multiplier = serverLevel.purpurConfig.creeperHealthRadius ? this.getHealth() / this.getMaxHealth() : 1; // Purpur - Config for health to impact Creeper explosion radius + if (this.level() instanceof ServerLevel level) { + float explosionMultiplier = this.isPowered() ? 2.0F : 1.0F; ++ float multiplier = level.purpurConfig.creeperHealthRadius ? this.getHealth() / this.getMaxHealth() : 1; // Purpur - Config for health to impact Creeper explosion radius // CraftBukkit start -- org.bukkit.event.entity.ExplosionPrimeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callExplosionPrimeEvent(this, this.explosionRadius * f, false); -+ org.bukkit.event.entity.ExplosionPrimeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callExplosionPrimeEvent(this, (this.explosionRadius * f) * multiplier, false); // Purpur - Config for health to impact Creeper explosion radius +- org.bukkit.event.entity.ExplosionPrimeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callExplosionPrimeEvent(this, this.explosionRadius * explosionMultiplier, false); ++ org.bukkit.event.entity.ExplosionPrimeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callExplosionPrimeEvent(this, (this.explosionRadius * explosionMultiplier) * multiplier, false); // Purpur - Config for health to impact Creeper explosion radius if (!event.isCancelled()) { // CraftBukkit end this.dead = true; -- serverLevel.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) -+ serverLevel.explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), serverLevel.getGameRules().get(net.minecraft.world.level.gamerules.GameRules.MOB_GRIEFING) && 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 - Add enderman and creeper griefing controls +- 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) ++ level.explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), level.getGameRules().get(net.minecraft.world.level.gamerules.GameRules.MOB_GRIEFING) && 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 - Add enderman and creeper griefing controls this.spawnLingeringCloud(); - this.triggerOnDeathMobEffects(serverLevel, Entity.RemovalReason.KILLED); + this.triggerOnDeathMobEffects(level, Entity.RemovalReason.KILLED); this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause -@@ -261,6 +285,7 @@ public class Creeper extends Monster { +@@ -261,6 +_,7 @@ } // CraftBukkit end } diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Ghast.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Ghast.java.patch new file mode 100644 index 000000000..a39da72bf --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Ghast.java.patch @@ -0,0 +1,14 @@ +--- a/net/minecraft/world/entity/monster/Ghast.java ++++ b/net/minecraft/world/entity/monster/Ghast.java +@@ -156,6 +_,11 @@ + public static boolean checkGhastSpawnRules( + final EntityType type, final LevelAccessor level, final EntitySpawnReason spawnReason, final BlockPos pos, final RandomSource random + ) { ++ // Purpur start - Config to disable hostile mob spawn on ice ++ if (net.minecraft.world.entity.monster.Monster.canSpawnInBlueAndPackedIce(level, pos)) { ++ return false; ++ } ++ // Purpur end - Config to disable hostile mob spawn on ice + return level.getDifficulty() != Difficulty.PEACEFUL && random.nextInt(20) == 0 && checkMobSpawnRules(type, level, spawnReason, pos, random); + } + diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/Monster.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Monster.java.patch similarity index 60% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/Monster.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Monster.java.patch index 2b6e7838f..9ac988100 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/Monster.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Monster.java.patch @@ -1,17 +1,9 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/monster/Monster.java b/net/minecraft/world/entity/monster/Monster.java -index 07293a33c45a0834f3b623a47a1bd25f3e059f54..54033572e325f8486a438e31dde34f8407f9180a 100644 --- a/net/minecraft/world/entity/monster/Monster.java +++ b/net/minecraft/world/entity/monster/Monster.java -@@ -84,6 +84,11 @@ public abstract class Monster extends PathfinderMob implements Enemy { +@@ -84,6 +_,11 @@ } - public static boolean isDarkEnoughToSpawn(ServerLevelAccessor level, BlockPos pos, RandomSource random) { + public static boolean isDarkEnoughToSpawn(final ServerLevelAccessor level, final BlockPos pos, final RandomSource random) { + // Purpur start - Config to disable hostile mob spawn on ice + if (canSpawnInBlueAndPackedIce(level, pos)) { + return false; @@ -20,19 +12,19 @@ index 07293a33c45a0834f3b623a47a1bd25f3e059f54..54033572e325f8486a438e31dde34f84 if (level.getBrightness(LightLayer.SKY, pos) > random.nextInt(32)) { return false; } else { -@@ -109,6 +114,11 @@ public abstract class Monster extends PathfinderMob implements Enemy { +@@ -113,6 +_,11 @@ public static boolean checkAnyLightMonsterSpawnRules( - EntityType entityType, LevelAccessor level, EntitySpawnReason spawnReason, BlockPos pos, RandomSource random + final EntityType type, final LevelAccessor level, final EntitySpawnReason spawnReason, final BlockPos pos, final RandomSource random ) { + // Purpur start - Config to disable hostile mob spawn on ice + if (canSpawnInBlueAndPackedIce(level, pos)) { + return false; + } + // Purpur end - Config to disable hostile mob spawn on ice - return level.getDifficulty() != Difficulty.PEACEFUL && checkMobSpawnRules(entityType, level, spawnReason, pos, random); + return level.getDifficulty() != Difficulty.PEACEFUL && checkMobSpawnRules(type, level, spawnReason, pos, random); } -@@ -146,4 +156,12 @@ public abstract class Monster extends PathfinderMob implements Enemy { +@@ -154,4 +_,12 @@ return ItemStack.EMPTY; } } diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Phantom.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Phantom.java.patch new file mode 100644 index 000000000..15607559a --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Phantom.java.patch @@ -0,0 +1,15 @@ +--- a/net/minecraft/world/entity/monster/Phantom.java ++++ b/net/minecraft/world/entity/monster/Phantom.java +@@ -167,7 +_,11 @@ + final ServerLevelAccessor level, final DifficultyInstance difficulty, final EntitySpawnReason spawnReason, final @Nullable SpawnGroupData groupData + ) { + this.anchorPoint = this.blockPosition().above(5); +- this.setPhantomSize(0); ++ // Purpur start - Configurable phantom size ++ int min = level.getLevel().purpurConfig.phantomMinSize; ++ int max = level.getLevel().purpurConfig.phantomMaxSize; ++ this.setPhantomSize(min == max ? min : level.getRandom().nextInt(max + 1 - min) + min); ++ // Purpur end - Configurable phantom size + return super.finalizeSpawn(level, difficulty, spawnReason, groupData); + } + diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/Ravager.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Ravager.java.patch similarity index 59% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/Ravager.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Ravager.java.patch index d1febed45..1d4cd02c4 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/Ravager.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Ravager.java.patch @@ -1,14 +1,6 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/monster/Ravager.java b/net/minecraft/world/entity/monster/Ravager.java -index 631092f088355be45f598bb91bd5d38a39a55d5b..a10c693a8948d1b7c4bd06b957a08a9cea9170ad 100644 --- a/net/minecraft/world/entity/monster/Ravager.java +++ b/net/minecraft/world/entity/monster/Ravager.java -@@ -76,6 +76,7 @@ public class Ravager extends Raider { +@@ -74,6 +_,7 @@ protected void registerGoals() { super.registerGoals(); this.goalSelector.addGoal(0, new FloatGoal(this)); @@ -16,12 +8,12 @@ index 631092f088355be45f598bb91bd5d38a39a55d5b..a10c693a8948d1b7c4bd06b957a08a9c this.goalSelector.addGoal(4, new MeleeAttackGoal(this, 1.0, true)); this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 0.4)); this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 6.0F)); -@@ -154,7 +155,7 @@ public class Ravager extends Raider { +@@ -152,7 +_,7 @@ )) { - BlockState blockState = serverLevel.getBlockState(blockPos); - Block block = blockState.getBlock(); + BlockState state = serverLevel.getBlockState(pos); + Block block = state.getBlock(); - if (block instanceof LeavesBlock) { + if (this.level().purpurConfig.ravagerGriefableBlocks.contains(block)) { // Purpur - Configurable ravager griefable blocks list // CraftBukkit start - if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, blockPos, blockState.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, state.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state continue; diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Shulker.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Shulker.java.patch index bf0da031b..cd03fdd20 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Shulker.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Shulker.java.patch @@ -9,3 +9,60 @@ private float currentPeekAmountO; private float currentPeekAmount; private @Nullable BlockPos clientOldAttachPosition; +@@ -94,6 +_,21 @@ + this.lookControl = new Shulker.ShulkerLookControl(this); + } + ++ // Purpur start - Shulker change color with dye ++ @Override ++ protected net.minecraft.world.InteractionResult mobInteract(Player player, net.minecraft.world.InteractionHand hand) { ++ net.minecraft.world.item.ItemStack itemstack = player.getItemInHand(hand); ++ if (player.level().purpurConfig.shulkerChangeColorWithDye && itemstack.getItem() instanceof net.minecraft.world.item.DyeItem dye && dye.getDyeColor() != this.getColor()) { ++ this.setVariant(Optional.of(dye.getDyeColor())); ++ if (!player.getAbilities().instabuild) { ++ itemstack.shrink(1); ++ } ++ return net.minecraft.world.InteractionResult.SUCCESS; ++ } ++ return super.mobInteract(player, hand); ++ } ++ // Purpur end - Shulker change color with dye ++ + @Override + protected void registerGoals() { + this.goalSelector.addGoal(1, new LookAtPlayerGoal(this, Player.class, 8.0F, 0.02F, true)); +@@ -455,11 +_,21 @@ + private void hitByShulkerBullet() { + Vec3 oldPosition = this.position(); + AABB oldAabb = this.getBoundingBox(); +- if (!this.isClosed() && this.teleportSomewhere()) { +- int shulkerCount = this.level().getEntities(EntityType.SHULKER, oldAabb.inflate(8.0), Entity::isAlive).size(); +- float failureChance = (shulkerCount - 1) / 5.0F; +- if (!(this.level().getRandom().nextFloat() < failureChance)) { ++ // Purpur start - Shulker spawn from bullet options ++ if ((!this.level().purpurConfig.shulkerSpawnFromBulletRequireOpenLid || !this.isClosed()) && this.teleportSomewhere()) { ++ float failureChance = this.level().purpurConfig.shulkerSpawnFromBulletBaseChance; ++ if (!this.level().purpurConfig.shulkerSpawnFromBulletNearbyEquation.isBlank()) { ++ int shulkerCount = this.level().getEntities((net.minecraft.world.level.entity.EntityTypeTest) EntityType.SHULKER, oldAabb.inflate(this.level().purpurConfig.shulkerSpawnFromBulletNearbyRange), Entity::isAlive).size(); ++ try { ++ failureChance -= ((Number) scriptEngine.eval("let shulkerCount = " + shulkerCount + "; " + this.level().purpurConfig.shulkerSpawnFromBulletNearbyEquation)).floatValue(); ++ } catch (javax.script.ScriptException e) { ++ e.printStackTrace(); ++ failureChance -= (shulkerCount - 1) / 5.0F; ++ } ++ } ++ if (this.level().getRandom().nextFloat() <= failureChance) { + Shulker baby = EntityType.SHULKER.create(this.level(), EntitySpawnReason.BREEDING); ++ // Purpur end - Shulker spawn from bullet options + if (baby != null) { + baby.setVariant(this.getVariant()); + baby.snapTo(oldPosition); +@@ -566,7 +_,7 @@ + } + + public Optional getVariant() { +- return Optional.ofNullable(this.getColor()); ++ return Optional.ofNullable(this.level().purpurConfig.shulkerSpawnFromBulletRandomColor ? DyeColor.random(this.level().random) : this.getColor()); // Purpur - Shulker spawn from bullet options + } + + public @Nullable DyeColor getColor() { diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/Strider.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Strider.java.patch similarity index 51% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/Strider.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Strider.java.patch index 9eceb0b9e..683babafd 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/Strider.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Strider.java.patch @@ -1,17 +1,9 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/monster/Strider.java b/net/minecraft/world/entity/monster/Strider.java -index b451566378401e471a98db63df502b7c4cd20f42..beaffb771e6c8d4b992437997ab27be218425c5a 100644 --- a/net/minecraft/world/entity/monster/Strider.java +++ b/net/minecraft/world/entity/monster/Strider.java -@@ -390,6 +390,18 @@ public class Strider extends Animal implements ItemSteerable { +@@ -400,6 +_,18 @@ @Override - public InteractionResult mobInteract(Player player, InteractionHand hand) { - boolean isFood = this.isFood(player.getItemInHand(hand)); + public InteractionResult mobInteract(final Player player, final InteractionHand hand) { + boolean hasFood = this.isFood(player.getItemInHand(hand)); + // Purpur start + if (level().purpurConfig.striderGiveSaddleBack && player.isSecondaryUseActive() && !isFood && isSaddled() && !isVehicle()) { + this.setItemSlot(EquipmentSlot.SADDLE, ItemStack.EMPTY); @@ -24,6 +16,6 @@ index b451566378401e471a98db63df502b7c4cd20f42..beaffb771e6c8d4b992437997ab27be2 + return InteractionResult.SUCCESS; + } + // Purpur end - if (!isFood && this.isSaddled() && !this.isVehicle() && !player.isSecondaryUseActive()) { + if (!hasFood && this.isSaddled() && !this.isVehicle() && !player.isSecondaryUseActive()) { if (!this.level().isClientSide()) { player.startRiding(this); diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/illager/Vindicator.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/illager/Vindicator.java.patch similarity index 55% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/illager/Vindicator.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/illager/Vindicator.java.patch index 432518518..b3aa090f1 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/illager/Vindicator.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/illager/Vindicator.java.patch @@ -1,14 +1,6 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/monster/illager/Vindicator.java b/net/minecraft/world/entity/monster/illager/Vindicator.java -index bfad794ff21e2f97654fbb1207b14fd088aec721..0cdc52cf3b1bb9c00e6ca8c8e564de60e195d6fc 100644 --- a/net/minecraft/world/entity/monster/illager/Vindicator.java +++ b/net/minecraft/world/entity/monster/illager/Vindicator.java -@@ -131,6 +131,11 @@ public class Vindicator extends AbstractIllager { +@@ -131,6 +_,11 @@ RandomSource random = level.getRandom(); this.populateDefaultEquipmentSlots(random, difficulty); this.populateDefaultEquipmentEnchantments(level, random, difficulty); @@ -17,6 +9,6 @@ index bfad794ff21e2f97654fbb1207b14fd088aec721..0cdc52cf3b1bb9c00e6ca8c8e564de60 + setCustomName(Component.translatable("Johnny")); + } + // Purpur end - Special mobs naturally spawn - return spawnGroupData1; + return spawnGroupData; } diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/piglin/PiglinAi.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/piglin/PiglinAi.java.patch new file mode 100644 index 000000000..a49366916 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/piglin/PiglinAi.java.patch @@ -0,0 +1,29 @@ +--- a/net/minecraft/world/entity/monster/piglin/PiglinAi.java ++++ b/net/minecraft/world/entity/monster/piglin/PiglinAi.java +@@ -669,14 +_,24 @@ + } + + public static boolean isWearingSafeArmor(final LivingEntity livingEntity) { +- for (EquipmentSlot slot : EquipmentSlotGroup.ARMOR) { +- if (livingEntity.getItemBySlot(slot).is(ItemTags.PIGLIN_SAFE_ARMOR)) { ++ for (EquipmentSlot equipmentSlot : EquipmentSlotGroup.ARMOR) { ++ // Purpur start - piglins ignore gold-trimmed armor ++ net.minecraft.world.item.ItemStack itemStack = livingEntity.getItemBySlot(equipmentSlot); ++ if (itemStack.is(ItemTags.PIGLIN_SAFE_ARMOR) || (livingEntity.level().purpurConfig.piglinIgnoresArmorWithGoldTrim && isWearingGoldTrim(itemStack))) { ++ // Purpur end - piglins ignore gold-trimmed armor + return true; + } + } + + return false; + } ++ ++ // Purpur start - piglins ignore gold-trimmed armor ++ private static boolean isWearingGoldTrim(net.minecraft.world.item.ItemStack itemstack) { ++ net.minecraft.world.item.equipment.trim.ArmorTrim armorTrim = itemstack.getComponents().get(net.minecraft.core.component.DataComponents.TRIM); ++ return armorTrim != null && armorTrim.material().is(net.minecraft.world.item.equipment.trim.TrimMaterials.GOLD); ++ } ++ // Purpur end - piglins ignore gold-trimmed armor + + private static void stopWalking(final Piglin body) { + body.getBrain().eraseMemory(MemoryModuleType.WALK_TARGET); diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/skeleton/AbstractSkeleton.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/skeleton/AbstractSkeleton.java.patch similarity index 55% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/skeleton/AbstractSkeleton.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/skeleton/AbstractSkeleton.java.patch index 33f4d2890..ded5d1741 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/skeleton/AbstractSkeleton.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/skeleton/AbstractSkeleton.java.patch @@ -1,14 +1,6 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/monster/skeleton/AbstractSkeleton.java b/net/minecraft/world/entity/monster/skeleton/AbstractSkeleton.java -index 0f5bfbfc97c2826de72985c4e2e1dec1d94337f2..1ba7777164c7fd8516c97e1bd964183df37c029f 100644 --- a/net/minecraft/world/entity/monster/skeleton/AbstractSkeleton.java +++ b/net/minecraft/world/entity/monster/skeleton/AbstractSkeleton.java -@@ -137,7 +137,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo +@@ -142,7 +_,7 @@ this.populateDefaultEquipmentEnchantments(level, random, difficulty); this.reassessWeaponGoal(); this.setCanPickUpLoot(level.getLevel().paperConfig().entities.behavior.mobsCanAlwaysPickUpLoot.skeletons || random.nextFloat() < 0.55F * difficulty.getSpecialMultiplier()); // Paper - Add world settings for mobs picking up loot @@ -17,12 +9,12 @@ index 0f5bfbfc97c2826de72985c4e2e1dec1d94337f2..1ba7777164c7fd8516c97e1bd964183d this.setItemSlot(EquipmentSlot.HEAD, new ItemStack(random.nextFloat() < 0.1F ? Blocks.JACK_O_LANTERN : Blocks.CARVED_PUMPKIN)); this.setDropChance(EquipmentSlot.HEAD, 0.0F); } -@@ -184,7 +184,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo - double squareRoot = Math.sqrt(d * d + d2 * d2); +@@ -189,7 +_,7 @@ + double distanceToTarget = Math.sqrt(xd * xd + zd * zd); if (this.level() instanceof ServerLevel serverLevel) { Projectile.Delayed delayedEntity = Projectile.spawnProjectileUsingShootDelayed( // Paper - delayed -- arrow, serverLevel, projectile, d, d1 + squareRoot * 0.2F, d2, 1.6F, 14 - serverLevel.getDifficulty().getId() * 4 -+ arrow, serverLevel, projectile, d, d1 + squareRoot * 0.2F, d2, 1.6F, serverLevel.purpurConfig.skeletonBowAccuracyMap.getOrDefault(serverLevel.getDifficulty().getId(), (float) (14 - serverLevel.getDifficulty().getId() * 4)) // Purpur - skeleton bow accuracy option +- arrow, serverLevel, projectile, xd, yd + distanceToTarget * 0.2F, zd, 1.6F, 14 - serverLevel.getDifficulty().getId() * 4 ++ arrow, serverLevel, projectile, xd, yd + distanceToTarget * 0.2F, zd, 1.6F, serverLevel.purpurConfig.skeletonBowAccuracyMap.getOrDefault(serverLevel.getDifficulty().getId(), (float) (14 - serverLevel.getDifficulty().getId() * 4)) // Purpur - skeleton bow accuracy option ); // Paper start - call EntityShootBowEvent diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/zombie/Drowned.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/zombie/Drowned.java.patch similarity index 80% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/zombie/Drowned.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/zombie/Drowned.java.patch index 0a2199404..cbe6f8b9a 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/zombie/Drowned.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/zombie/Drowned.java.patch @@ -1,21 +1,13 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/monster/zombie/Drowned.java b/net/minecraft/world/entity/monster/zombie/Drowned.java -index db164101d440c503e2e88b1f31af7f0638faaec5..604d5e6a4962de61fb97988a2f3de2965908bada 100644 --- a/net/minecraft/world/entity/monster/zombie/Drowned.java +++ b/net/minecraft/world/entity/monster/zombie/Drowned.java -@@ -86,10 +86,23 @@ public class Drowned extends Zombie implements RangedAttackMob { +@@ -93,10 +_,23 @@ this.goalSelector.addGoal(2, new Drowned.DrownedAttackGoal(this, 1.0, false)); this.goalSelector.addGoal(5, new Drowned.DrownedGoToBeachGoal(this, 1.0)); this.goalSelector.addGoal(6, new Drowned.DrownedSwimUpGoal(this, 1.0, this.level().getSeaLevel())); + if (level().purpurConfig.drownedBreakDoors) this.goalSelector.addGoal(6, new net.minecraft.world.entity.ai.goal.MoveThroughVillageGoal(this, 1.0D, true, 4, this::canBreakDoors)); // Purpur - Option to make drowned break doors this.goalSelector.addGoal(7, new RandomStrollGoal(this, 1.0)); this.targetSelector.addGoal(1, new HurtByTargetGoal(this, Drowned.class).setAlertOthers(ZombifiedPiglin.class)); - this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, (entity, level) -> this.okTarget(entity))); + this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, (target, level) -> this.okTarget(target))); - if (this.level().spigotConfig.zombieAggressiveTowardsVillager) this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false)); // Paper - Check drowned for villager aggression config + // Purpur start - Add option to disable zombie aggressiveness towards villagers + if (this.level().spigotConfig.zombieAggressiveTowardsVillager) this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false) { // Paper - Check drowned for villager aggression config diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/zombie/ZombieVillager.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/zombie/ZombieVillager.java.patch similarity index 53% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/zombie/ZombieVillager.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/zombie/ZombieVillager.java.patch index d585cae13..eca220352 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/monster/zombie/ZombieVillager.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/zombie/ZombieVillager.java.patch @@ -1,20 +1,12 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/monster/zombie/ZombieVillager.java b/net/minecraft/world/entity/monster/zombie/ZombieVillager.java -index 8af935a11a0988f10a2908f6337504f7f6e13d1b..c6f271a921fde124df1a7c5d175cb83b420cd2e3 100644 --- a/net/minecraft/world/entity/monster/zombie/ZombieVillager.java +++ b/net/minecraft/world/entity/monster/zombie/ZombieVillager.java -@@ -159,10 +159,10 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder { - public InteractionResult mobInteract(Player player, InteractionHand hand) { - ItemStack itemInHand = player.getItemInHand(hand); - if (itemInHand.is(Items.GOLDEN_APPLE)) { +@@ -170,10 +_,10 @@ + public InteractionResult mobInteract(final Player player, final InteractionHand hand) { + ItemStack itemStack = player.getItemInHand(hand); + if (itemStack.is(Items.GOLDEN_APPLE)) { - if (this.hasEffect(MobEffects.WEAKNESS)) { + if (this.hasEffect(MobEffects.WEAKNESS) && level().purpurConfig.zombieVillagerCureEnabled) { // Purpur - Add option to disable zombie villagers cure - itemInHand.consume(1, player); + itemStack.consume(1, player); if (!this.level().isClientSide()) { - this.startConverting(player.getUUID(), this.random.nextInt(2401) + 3600); + this.startConverting(player.getUUID(), this.random.nextInt(level().purpurConfig.zombieVillagerCuringTimeMax - level().purpurConfig.zombieVillagerCuringTimeMin + 1) + level().purpurConfig.zombieVillagerCuringTimeMin); // Purpur - Customizable Zombie Villager curing times diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/npc/villager/Villager.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/npc/villager/Villager.java.patch similarity index 57% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/npc/villager/Villager.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/npc/villager/Villager.java.patch index cec4deb94..a75095bf8 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/npc/villager/Villager.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/npc/villager/Villager.java.patch @@ -1,24 +1,16 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/npc/villager/Villager.java b/net/minecraft/world/entity/npc/villager/Villager.java -index 89844d7e804cc8a2110b694e448bc5993991bea7..e117ae1b114c7e2ca314a00335473efc41137f7f 100644 --- a/net/minecraft/world/entity/npc/villager/Villager.java +++ b/net/minecraft/world/entity/npc/villager/Villager.java -@@ -179,6 +179,8 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -181,6 +_,8 @@ MemoryModuleType.MEETING_POINT, (villager, poiType) -> poiType.is(PoiTypes.MEETING) ); + private boolean isLobotomized = false; public boolean isLobotomized() { return this.isLobotomized; } // Purpur - Lobotomize stuck villagers + private int notLobotomizedCount = 0; // Purpur - Lobotomize stuck villagers - public Villager(EntityType type, Level level) { + public Villager(final EntityType type, final Level level) { this(type, level, VillagerType.PLAINS); -@@ -197,6 +199,57 @@ public class Villager extends AbstractVillager implements ReputationEventHandler - this.setVillagerData(this.getVillagerData().withType(villagerType).withProfession(level.registryAccess(), VillagerProfession.NONE)); +@@ -199,6 +_,57 @@ + this.setVillagerData(this.getVillagerData().withType(type).withProfession(level.registryAccess(), VillagerProfession.NONE)); } + // Purpur start - Allow leashing villagers @@ -74,17 +66,12 @@ index 89844d7e804cc8a2110b694e448bc5993991bea7..e117ae1b114c7e2ca314a00335473efc + @Override public Brain getBrain() { - return (Brain)super.getBrain(); -@@ -293,11 +346,22 @@ public class Villager extends AbstractVillager implements ReputationEventHandler - // Paper start - EAR 2 - this.customServerAiStep(level, false); - } -- protected void customServerAiStep(ServerLevel level, final boolean inactive) { -+ protected void customServerAiStep(ServerLevel level, boolean inactive) { // Purpur - Lobotomize stuck villagers - not final - // Paper end - EAR 2 - ProfilerFiller profilerFiller = Profiler.get(); - profilerFiller.push("villagerBrain"); -- if (!inactive) this.getBrain().tick(level, this); // Paper - EAR 2 + return (Brain) super.getBrain(); +@@ -248,7 +_,18 @@ + protected void customServerAiStep(final ServerLevel level) { + ProfilerFiller profiler = Profiler.get(); + profiler.push("villagerBrain"); +- this.getBrain().tick(level, this); + // Purpur start - Lobotomize stuck villagers + if (this.level().purpurConfig.villagerLobotomizeEnabled) { + // treat as inactive if lobotomized @@ -97,10 +84,10 @@ index 89844d7e804cc8a2110b694e448bc5993991bea7..e117ae1b114c7e2ca314a00335473efc + } + else if (this.isLobotomized && shouldRestock(level)) restock(); + // Purpur end - Lobotomize stuck villagers - profilerFiller.pop(); + profiler.pop(); if (this.assignProfessionWhenSpawned) { this.assignProfessionWhenSpawned = false; -@@ -369,6 +433,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -319,6 +_,7 @@ return InteractionResult.CONSUME; } @@ -108,16 +95,16 @@ index 89844d7e804cc8a2110b694e448bc5993991bea7..e117ae1b114c7e2ca314a00335473efc this.startTrading(player); } -@@ -500,7 +565,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -460,7 +_,7 @@ public void updateDemand() { - for (MerchantOffer merchantOffer : this.getOffers()) { -- merchantOffer.updateDemand(); -+ merchantOffer.updateDemand(this.level().purpurConfig.villagerMinimumDemand); // Purpur - Configurable minimum demand for trades + for (MerchantOffer offer : this.getOffers()) { +- offer.updateDemand(); ++ offer.updateDemand(this.level().purpurConfig.villagerMinimumDemand); // Purpur - Configurable minimum demand for trades } } -@@ -692,7 +757,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -660,7 +_,7 @@ @Override public boolean canBreed() { @@ -126,24 +113,11 @@ index 89844d7e804cc8a2110b694e448bc5993991bea7..e117ae1b114c7e2ca314a00335473efc } private boolean hungry() { -@@ -915,6 +980,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -867,6 +_,7 @@ } - public void spawnGolemIfNeeded(ServerLevel level, long gameTime, int minVillagerAmount) { + public void spawnGolemIfNeeded(final ServerLevel level, final long timestamp, final int villagersNeededToAgree) { + if (level.purpurConfig.villagerSpawnIronGolemRadius > 0 && level.getEntitiesOfClass(net.minecraft.world.entity.animal.golem.IronGolem.class, getBoundingBox().inflate(level.purpurConfig.villagerSpawnIronGolemRadius)).size() > level.purpurConfig.villagerSpawnIronGolemLimit) return; // Purpur - Implement configurable search radius for villagers to spawn iron golems - if (this.wantsToSpawnGolem(gameTime)) { - AABB aabb = this.getBoundingBox().inflate(10.0, 10.0, 10.0); - List entitiesOfClass = level.getEntitiesOfClass(Villager.class, aabb); -@@ -982,6 +1048,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler - - @Override - public void startSleeping(BlockPos pos) { -+ // Purpur start - Option for beds to explode on villager sleep -+ if (level().purpurConfig.bedExplodeOnVillagerSleep && this.level().getBlockState(pos).getBlock() instanceof net.minecraft.world.level.block.BedBlock) { -+ this.level().explode(null, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, (float) this.level().purpurConfig.bedExplosionPower, this.level().purpurConfig.bedExplosionFire, this.level().purpurConfig.bedExplosionEffect); -+ return; -+ } -+ // Purpur end - Option for beds to explode on villager sleep - super.startSleeping(pos); - this.brain.setMemory(MemoryModuleType.LAST_SLEPT, this.level().getGameTime()); - this.brain.eraseMemory(MemoryModuleType.WALK_TARGET); + if (this.wantsToSpawnGolem(timestamp)) { + AABB villagerSearchBox = this.getBoundingBox().inflate(10.0, 10.0, 10.0); + List nearbyVillagers = level.getEntitiesOfClass(Villager.class, villagerSearchBox); diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/npc/wanderingtrader/WanderingTraderSpawner.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/npc/wanderingtrader/WanderingTraderSpawner.java.patch new file mode 100644 index 000000000..ab4cfc3a4 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/npc/wanderingtrader/WanderingTraderSpawner.java.patch @@ -0,0 +1,21 @@ +--- a/net/minecraft/world/entity/npc/wanderingtrader/WanderingTraderSpawner.java ++++ b/net/minecraft/world/entity/npc/wanderingtrader/WanderingTraderSpawner.java +@@ -133,7 +_,17 @@ + int xPosition = referencePosition.getX() + this.random.nextInt(radius * 2) - radius; + int zPosition = referencePosition.getZ() + this.random.nextInt(radius * 2) - radius; + int yPosition = level.getHeight(SpawnPlacements.getHeightmapType(EntityType.WANDERING_TRADER), xPosition, zPosition); +- BlockPos spawnPos = new BlockPos(xPosition, yPosition, zPosition); ++ // Purpur start - Allow toggling special MobSpawners per world - allow traders to spawn below nether roof ++ BlockPos.MutableBlockPos spawnPos = new BlockPos.MutableBlockPos(xPosition, yPosition, zPosition); ++ if (level.dimensionType().hasCeiling()) { ++ do { ++ spawnPos.relative(net.minecraft.core.Direction.DOWN); ++ } while (!level.getBlockState(spawnPos).isAir()); ++ do { ++ spawnPos.relative(net.minecraft.core.Direction.DOWN); ++ } while (level.getBlockState(spawnPos).isAir() && spawnPos.getY() > 0); ++ } ++ // Purpur end - Allow toggling special MobSpawners per world + if (wanderingTraderSpawnType.isSpawnPositionOk(level, spawnPos, EntityType.WANDERING_TRADER)) { + spawnPosition = spawnPos; + break; diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/AbstractFurnaceMenu.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/AbstractFurnaceMenu.java.patch new file mode 100644 index 000000000..7677df476 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/AbstractFurnaceMenu.java.patch @@ -0,0 +1,17 @@ +--- a/net/minecraft/world/inventory/AbstractFurnaceMenu.java ++++ b/net/minecraft/world/inventory/AbstractFurnaceMenu.java +@@ -122,7 +_,13 @@ + } else if (slotIndex != 1 && slotIndex != 0) { + if (this.canSmelt(stack)) { + if (!this.moveItemStackTo(stack, 0, 1, false)) { +- return ItemStack.EMPTY; ++ // Purpur start - Added the ability to add combustible items ++ if (this.isFuel(item)) { ++ if (!this.moveItemStackTo(item, 1, 2, false)) { ++ return ItemStack.EMPTY; ++ } ++ } ++ // Purpur end - Added the ability to add combustible items + } + } else if (this.isFuel(stack)) { + if (!this.moveItemStackTo(stack, 1, 2, false)) { diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/inventory/AnvilMenu.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/AnvilMenu.java.patch similarity index 66% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/inventory/AnvilMenu.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/AnvilMenu.java.patch index 07d7e1011..2f73af268 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/inventory/AnvilMenu.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/AnvilMenu.java.patch @@ -1,14 +1,6 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/inventory/AnvilMenu.java b/net/minecraft/world/inventory/AnvilMenu.java -index 7939f19b87364a32a40e58e001cea14e06348f86..b790b9476ec0a0569470d5de4067caa5373b2f6b 100644 --- a/net/minecraft/world/inventory/AnvilMenu.java +++ b/net/minecraft/world/inventory/AnvilMenu.java -@@ -23,6 +23,12 @@ import net.minecraft.world.level.block.state.BlockState; +@@ -23,6 +_,12 @@ import org.jspecify.annotations.Nullable; import org.slf4j.Logger; @@ -21,7 +13,7 @@ index 7939f19b87364a32a40e58e001cea14e06348f86..b790b9476ec0a0569470d5de4067caa5 public class AnvilMenu extends ItemCombinerMenu { public static final int INPUT_SLOT = 0; public static final int ADDITIONAL_SLOT = 1; -@@ -51,6 +57,10 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -51,6 +_,10 @@ private org.bukkit.craftbukkit.inventory.view.CraftAnvilView bukkitEntity; // CraftBukkit end public boolean bypassEnchantmentLevelRestriction = false; // Paper - bypass anvil level restrictions @@ -30,20 +22,20 @@ index 7939f19b87364a32a40e58e001cea14e06348f86..b790b9476ec0a0569470d5de4067caa5 + public boolean canDoUnsafeEnchants = false; + // Purpur end - Anvil API - public AnvilMenu(int containerId, Inventory playerInventory) { - this(containerId, playerInventory, ContainerLevelAccess.NULL); -@@ -76,12 +86,17 @@ public class AnvilMenu extends ItemCombinerMenu { + public AnvilMenu(final int containerId, final Inventory inventory) { + this(containerId, inventory, ContainerLevelAccess.NULL); +@@ -76,12 +_,17 @@ @Override - protected boolean mayPickup(Player player, boolean hasStack) { -- return (player.hasInfiniteMaterials() || player.experienceLevel >= this.cost.get()) && this.cost.get() > AnvilMenu.DEFAULT_DENIED_COST && hasStack; // CraftBukkit - allow cost 0 like a free item -+ return (player.hasInfiniteMaterials() || player.experienceLevel >= this.cost.get()) && (this.bypassCost || this.cost.get() > AnvilMenu.DEFAULT_DENIED_COST) && hasStack; // CraftBukkit - allow cost 0 like a free item // Purpur - Anvil API + protected boolean mayPickup(final Player player, final boolean hasItem) { +- return (player.hasInfiniteMaterials() || player.experienceLevel >= this.cost.get()) && this.cost.get() > AnvilMenu.DEFAULT_DENIED_COST && hasItem; // CraftBukkit - allow cost 0 like a free item ++ return (player.hasInfiniteMaterials() || player.experienceLevel >= this.cost.get()) && (this.bypassCost || this.cost.get() > AnvilMenu.DEFAULT_DENIED_COST) && hasItem; // CraftBukkit - allow cost 0 like a free item // Purpur - Anvil API } @Override - protected void onTake(Player player, ItemStack stack) { + protected void onTake(final Player player, final ItemStack carried) { + // Purpur start - Anvil API -+ ItemStack itemstack = this.activeQuickItem != null ? this.activeQuickItem : stack; ++ ItemStack itemstack = this.activeQuickItem != null ? this.activeQuickItem : carried; + 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.hasInfiniteMaterials()) { @@ -51,7 +43,7 @@ index 7939f19b87364a32a40e58e001cea14e06348f86..b790b9476ec0a0569470d5de4067caa5 player.giveExperienceLevels(-this.cost.get()); } -@@ -134,13 +149,19 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -134,13 +_,19 @@ @Override public void createResult() { @@ -61,60 +53,60 @@ index 7939f19b87364a32a40e58e001cea14e06348f86..b790b9476ec0a0569470d5de4067caa5 + if (org.purpurmc.purpur.event.inventory.AnvilUpdateResultEvent.getHandlerList().getRegisteredListeners().length > 0) new org.purpurmc.purpur.event.inventory.AnvilUpdateResultEvent(getBukkitView()).callEvent(); + // Purpur end - Anvil API + - ItemStack item = this.inputSlots.getItem(0); + ItemStack input = this.inputSlots.getItem(0); this.onlyRenaming = false; this.cost.set(1); - int i = 0; - long l = 0L; - int i1 = 0; -- if (!item.isEmpty() && EnchantmentHelper.canStoreEnchantments(item)) { -+ if (!item.isEmpty() && this.canDoUnsafeEnchants || EnchantmentHelper.canStoreEnchantments(item)) { // Purpur - Anvil API - ItemStack itemStack = item.copy(); - ItemStack item1 = this.inputSlots.getItem(1); - ItemEnchantments.Mutable mutable = new ItemEnchantments.Mutable(EnchantmentHelper.getEnchantmentsForCrafting(itemStack)); -@@ -198,23 +219,34 @@ public class AnvilMenu extends ItemCombinerMenu { - int intValue = entry.getIntValue(); - intValue = level == intValue ? intValue + 1 : Math.max(intValue, level); - Enchantment enchantment = holder.value(); -- boolean canEnchant = enchantment.canEnchant(item); + int price = 0; + long tax = 0L; + int namingCost = 0; +- if (!input.isEmpty() && EnchantmentHelper.canStoreEnchantments(input)) { ++ if (!input.isEmpty() && this.canDoUnsafeEnchants || EnchantmentHelper.canStoreEnchantments(input)) { // Purpur - Anvil API + ItemStack result = input.copy(); + ItemStack addition = this.inputSlots.getItem(1); + ItemEnchantments.Mutable enchantments = new ItemEnchantments.Mutable(EnchantmentHelper.getEnchantmentsForCrafting(result)); +@@ -198,23 +_,34 @@ + int level = entry.getIntValue(); + level = current == level ? level + 1 : Math.max(level, current); + Enchantment enchantment = enchantmentHolder.value(); +- boolean compatible = enchantment.canEnchant(input); + // Purpur start - Config to allow unsafe enchants -+ boolean canEnchant = this.canDoUnsafeEnchants || org.purpurmc.purpur.PurpurConfig.allowInapplicableEnchants || enchantment.canEnchant(item); // whether the enchantment can be applied on specific item type ++ boolean compatible = this.canDoUnsafeEnchants || org.purpurmc.purpur.PurpurConfig.allowInapplicableEnchants || enchantment.canEnchant(input); // whether the enchantment can be applied on specific item type + boolean canEnchant1 = true; // whether two incompatible enchantments can be applied on a single item + // Purpur end - Config to allow unsafe enchants - if (this.player.hasInfiniteMaterials() || item.is(Items.ENCHANTED_BOOK)) { - canEnchant = true; + if (this.player.hasInfiniteMaterials() || input.is(Items.ENCHANTED_BOOK)) { + compatible = true; } + java.util.Set> removedEnchantments = new java.util.HashSet<>(); // Purpur - Config to allow unsafe enchants - for (Holder holder1 : mutable.keySet()) { - if (!holder1.equals(holder) && !Enchantment.areCompatible(holder, holder1)) { -- canEnchant = false; + for (Holder other : enchantments.keySet()) { + if (!other.equals(enchantmentHolder) && !Enchantment.areCompatible(enchantmentHolder, other)) { +- compatible = false; + canEnchant1 = this.canDoUnsafeEnchants || org.purpurmc.purpur.PurpurConfig.allowIncompatibleEnchants; // Purpur - Anvil API // Purpur - canEnchant -> canEnchant1 - Config to allow unsafe enchants + // Purpur start - Config to allow unsafe enchants + if (!canEnchant1 && org.purpurmc.purpur.PurpurConfig.replaceIncompatibleEnchants) { -+ removedEnchantments.add(holder1); ++ removedEnchantments.add(other); + canEnchant1 = true; + } + // Purpur end - Config to allow unsafe enchants - i++; + price++; } } + mutable.removeIf(removedEnchantments::contains); // Purpur - Config to allow unsafe enchants -- if (!canEnchant) { -+ if (!canEnchant || !canEnchant1) { // Purpur - Config to allow unsafe enchants - flag1 = true; +- if (!compatible) { ++ if (!compatible || !canEnchant1) { // Purpur - Config to allow unsafe enchants + isAnyEnchantmentNotCompatible = true; } else { - flag = true; -- if (intValue > enchantment.getMaxLevel() && !this.bypassEnchantmentLevelRestriction) { // Paper - bypass anvil level restrictions -+ if (!org.purpurmc.purpur.PurpurConfig.allowHigherEnchantsLevels && intValue > enchantment.getMaxLevel() && !this.bypassEnchantmentLevelRestriction) { // Paper - bypass anvil level restrictions // Purpur - Config to allow unsafe enchants - intValue = enchantment.getMaxLevel(); + isAnyEnchantmentCompatible = true; +- if (level > enchantment.getMaxLevel() && !this.bypassEnchantmentLevelRestriction) { // Paper - bypass anvil level restrictions ++ if (!org.purpurmc.purpur.PurpurConfig.allowHigherEnchantsLevels && level > enchantment.getMaxLevel() && !this.bypassEnchantmentLevelRestriction) { // Paper - bypass anvil level restrictions // Purpur - Config to allow unsafe enchants + level = enchantment.getMaxLevel(); } -@@ -243,6 +275,54 @@ public class AnvilMenu extends ItemCombinerMenu { - if (!this.itemName.equals(item.getHoverName().getString())) { - i1 = 1; - i += i1; +@@ -243,6 +_,54 @@ + if (!this.itemName.equals(input.getHoverName().getString())) { + namingCost = 1; + price += namingCost; + // Purpur start - Allow anvil colors + if (this.player != null) { + org.bukkit.craftbukkit.entity.CraftHumanEntity player = this.player.getBukkitEntity(); @@ -159,14 +151,14 @@ index 7939f19b87364a32a40e58e001cea14e06348f86..b790b9476ec0a0569470d5de4067caa5 + if (removeItalics) { + component = component.decoration(net.kyori.adventure.text.format.TextDecoration.ITALIC, false); + } -+ itemStack.set(DataComponents.CUSTOM_NAME, io.papermc.paper.adventure.PaperAdventure.asVanilla(component)); ++ result.set(DataComponents.CUSTOM_NAME, io.papermc.paper.adventure.PaperAdventure.asVanilla(component)); + } + else + // Purpur end - Allow anvil colors - itemStack.set(DataComponents.CUSTOM_NAME, Component.literal(this.itemName)); + result.set(DataComponents.CUSTOM_NAME, Component.literal(this.itemName)); } - } else if (item.has(DataComponents.CUSTOM_NAME)) { -@@ -267,6 +347,12 @@ public class AnvilMenu extends ItemCombinerMenu { + } else if (input.has(DataComponents.CUSTOM_NAME)) { +@@ -267,6 +_,12 @@ this.onlyRenaming = true; } @@ -177,11 +169,11 @@ index 7939f19b87364a32a40e58e001cea14e06348f86..b790b9476ec0a0569470d5de4067caa5 + // Purpur end - Anvil API + if (this.cost.get() >= this.maximumRepairCost && !this.player.hasInfiniteMaterials()) { // CraftBukkit - itemStack = ItemStack.EMPTY; + result = ItemStack.EMPTY; } -@@ -287,6 +373,13 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -287,6 +_,13 @@ - org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareAnvilEvent(this.getBukkitView(), itemStack); // CraftBukkit + org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareAnvilEvent(this.getBukkitView(), result); // CraftBukkit this.broadcastChanges(); + + // Purpur start - Anvil API @@ -193,12 +185,12 @@ index 7939f19b87364a32a40e58e001cea14e06348f86..b790b9476ec0a0569470d5de4067caa5 } 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 -@@ -295,7 +388,7 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -295,7 +_,7 @@ } - public static int calculateIncreasedRepairCost(int oldRepairCost) { -- return (int)Math.min(oldRepairCost * 2L + 1L, 2147483647L); -+ return org.purpurmc.purpur.PurpurConfig.anvilCumulativeCost ? (int)Math.min(oldRepairCost * 2L + 1L, 2147483647L) : 0; // Purpur - Make anvil cumulative cost configurable + public static int calculateIncreasedRepairCost(final int baseCost) { +- return (int)Math.min(baseCost * 2L + 1L, 2147483647L); ++ return org.purpurmc.purpur.PurpurConfig.anvilCumulativeCost ? (int)Math.min(baseCost * 2L + 1L, 2147483647L) : 0; // Purpur - Make anvil cumulative cost configurable } - public boolean setItemName(String itemName) { + public boolean setItemName(final String name) { diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/ArmorSlot.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/ArmorSlot.java.patch new file mode 100644 index 000000000..ffb1fdbd9 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/ArmorSlot.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/inventory/ArmorSlot.java ++++ b/net/minecraft/world/inventory/ArmorSlot.java +@@ -54,7 +_,7 @@ + @Override + public boolean mayPickup(final Player player) { + ItemStack itemStack = this.getItem(); +- return (itemStack.isEmpty() || player.isCreative() || !EnchantmentHelper.has(itemStack, EnchantmentEffectComponents.PREVENT_ARMOR_CHANGE)) ++ return (itemStack.isEmpty() || player.isCreative() || (!EnchantmentHelper.has(itemStack, EnchantmentEffectComponents.PREVENT_ARMOR_CHANGE) || player.level().purpurConfig.playerRemoveBindingWithWeakness && player.hasEffect(net.minecraft.world.effect.MobEffects.WEAKNESS))) // Purpur - Config to remove curse of binding with weakness + && super.mayPickup(player); + } + diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/inventory/EnchantmentMenu.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/EnchantmentMenu.java.patch similarity index 76% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/inventory/EnchantmentMenu.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/EnchantmentMenu.java.patch index 506f82809..2e0248273 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/inventory/EnchantmentMenu.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/EnchantmentMenu.java.patch @@ -1,14 +1,6 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/inventory/EnchantmentMenu.java b/net/minecraft/world/inventory/EnchantmentMenu.java -index 385eecd0c59d3c9510e39f96aa9614a7a57fb65a..40860d2facd6720300793dcc2cf99cb3367e61f7 100644 --- a/net/minecraft/world/inventory/EnchantmentMenu.java +++ b/net/minecraft/world/inventory/EnchantmentMenu.java -@@ -63,6 +63,22 @@ public class EnchantmentMenu extends AbstractContainerMenu { +@@ -64,6 +_,22 @@ return access.getLocation(); } // CraftBukkit end @@ -31,7 +23,7 @@ index 385eecd0c59d3c9510e39f96aa9614a7a57fb65a..40860d2facd6720300793dcc2cf99cb3 }; // Paper end - Add missing InventoryHolders this.access = access; -@@ -83,6 +99,16 @@ public class EnchantmentMenu extends AbstractContainerMenu { +@@ -92,6 +_,16 @@ return EnchantmentMenu.EMPTY_SLOT_LAPIS_LAZULI; } }); @@ -45,12 +37,12 @@ index 385eecd0c59d3c9510e39f96aa9614a7a57fb65a..40860d2facd6720300793dcc2cf99cb3 + } + }); + // Purpur end - Enchantment Table Persists Lapis - this.addStandardInventorySlots(playerInventory, 8, 84); + this.addStandardInventorySlots(inventory, 8, 84); this.addDataSlot(DataSlot.shared(this.costs, 0)); this.addDataSlot(DataSlot.shared(this.costs, 1)); -@@ -299,7 +325,7 @@ public class EnchantmentMenu extends AbstractContainerMenu { +@@ -308,7 +_,7 @@ @Override - public void removed(Player player) { + public void removed(final Player player) { super.removed(player); - this.access.execute((level, pos) -> this.clearContainer(player, this.enchantSlots)); + this.access.execute((level, pos) -> {if (level.purpurConfig.enchantmentTableLapisPersists) this.getSlot(1).set(ItemStack.EMPTY);this.clearContainer(player, this.enchantSlots);}); // Purpur - Enchantment Table Persists Lapis diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/inventory/GrindstoneMenu.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/GrindstoneMenu.java.patch similarity index 67% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/inventory/GrindstoneMenu.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/GrindstoneMenu.java.patch index 19de35bb3..2929403ce 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/inventory/GrindstoneMenu.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/GrindstoneMenu.java.patch @@ -1,44 +1,36 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/inventory/GrindstoneMenu.java b/net/minecraft/world/inventory/GrindstoneMenu.java -index ad70a0f7debee27d9f3b2ff39cb0429b39485190..e991ca16d069fddc3e4eb6d8c78c0dbffeb75a54 100644 --- a/net/minecraft/world/inventory/GrindstoneMenu.java +++ b/net/minecraft/world/inventory/GrindstoneMenu.java -@@ -92,11 +92,13 @@ public class GrindstoneMenu extends AbstractContainerMenu { +@@ -105,11 +_,13 @@ @Override - public void onTake(Player player, ItemStack stack) { - access.execute((level, blockPos) -> { + public void onTake(final Player player, final ItemStack carried) { + access.execute((level, pos) -> { + ItemStack itemstack = activeQuickItem == null ? stack : activeQuickItem; // Purpur - Grindstone API if (level instanceof ServerLevel) { // Paper start - Fire BlockExpEvent on grindstone use - org.bukkit.event.block.BlockExpEvent event = new org.bukkit.event.block.BlockExpEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, blockPos), this.getExperienceAmount(level)); + org.bukkit.event.block.BlockExpEvent event = new org.bukkit.event.block.BlockExpEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), this.getExperienceAmount(level)); event.callEvent(); -- ExperienceOrb.awardWithDirection((ServerLevel) level, Vec3.atCenterOf(blockPos), Vec3.ZERO, event.getExpToDrop(), org.bukkit.entity.ExperienceOrb.SpawnReason.GRINDSTONE, player, null); +- ExperienceOrb.awardWithDirection((ServerLevel) level, Vec3.atCenterOf(pos), Vec3.ZERO, event.getExpToDrop(), org.bukkit.entity.ExperienceOrb.SpawnReason.GRINDSTONE, player, null); + org.purpurmc.purpur.event.inventory.GrindstoneTakeResultEvent grindstoneTakeResultEvent = new org.purpurmc.purpur.event.inventory.GrindstoneTakeResultEvent(player.getBukkitEntity(), getBukkitView(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), event.getExpToDrop()); grindstoneTakeResultEvent.callEvent(); // Purpur - Grindstone API -+ ExperienceOrb.awardWithDirection((ServerLevel) level, Vec3.atCenterOf(blockPos), Vec3.ZERO, grindstoneTakeResultEvent.getExperienceAmount(), org.bukkit.entity.ExperienceOrb.SpawnReason.GRINDSTONE, player, null); // Purpur - Grindstone API ++ ExperienceOrb.awardWithDirection((ServerLevel) level, Vec3.atCenterOf(pos), Vec3.ZERO, grindstoneTakeResultEvent.getExperienceAmount(), org.bukkit.entity.ExperienceOrb.SpawnReason.GRINDSTONE, player, null); // Purpur - Grindstone API // Paper end - Fire BlockExpEvent on grindstone use } -@@ -125,7 +127,7 @@ public class GrindstoneMenu extends AbstractContainerMenu { - for (Entry> entry : enchantmentsForCrafting.entrySet()) { - Holder holder = entry.getKey(); - int intValue = entry.getIntValue(); -- if (!holder.is(EnchantmentTags.CURSE)) { +@@ -138,7 +_,7 @@ + for (Entry> entry : enchantments.entrySet()) { + Holder enchant = entry.getKey(); + int lvl = entry.getIntValue(); +- if (!enchant.is(EnchantmentTags.CURSE)) { + if (!org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains(holder.value())) { // Purpur - Config for grindstones - i += holder.value().getMinCost(intValue); + amount += enchant.value().getMinCost(lvl); } } -@@ -203,15 +205,75 @@ public class GrindstoneMenu extends AbstractContainerMenu { +@@ -216,16 +_,76 @@ - for (Entry> entry : enchantmentsForCrafting.entrySet()) { - Holder holder = entry.getKey(); -- if (!holder.is(EnchantmentTags.CURSE) || mutable.getLevel(holder) == 0) { -+ if (!org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains(holder.value()) || mutable.getLevel(holder) == 0) { // Purpur - Config for grindstones - mutable.upgrade(holder, entry.getIntValue()); + for (Entry> entry : enchantments.entrySet()) { + Holder enchant = entry.getKey(); +- if (!enchant.is(EnchantmentTags.CURSE) || newEnchantments.getLevel(enchant) == 0) { ++ if (!org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains(enchant.value()) || newEnchantments.getLevel(enchant) == 0) { // Purpur - Config for grindstones + newEnchantments.upgrade(enchant, entry.getIntValue()); } } }); @@ -105,15 +97,16 @@ index ad70a0f7debee27d9f3b2ff39cb0429b39485190..e991ca16d069fddc3e4eb6d8c78c0dbf + ); + // Purpur end - Config for grindstones private ItemStack removeNonCursesFrom(ItemStack item) { -- ItemEnchantments itemEnchantments = EnchantmentHelper.updateEnchantments(item, mutable -> mutable.removeIf(holder -> !holder.is(EnchantmentTags.CURSE))); -+ ItemEnchantments itemEnchantments = EnchantmentHelper.updateEnchantments(item, mutable -> mutable.removeIf(holder -> !org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains(holder.value()))); // Purpur - Config for grindstones - if (item.is(Items.ENCHANTED_BOOK) && itemEnchantments.isEmpty()) { + ItemEnchantments newEnchantments = EnchantmentHelper.updateEnchantments( +- item, enchantments -> enchantments.removeIf(enchantment -> !enchantment.is(EnchantmentTags.CURSE)) ++ item, enchantments -> enchantments.removeIf(enchantment -> !org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains(enchantment.value())) // Purpur - Config for grindstones + ); + if (item.is(Items.ENCHANTED_BOOK) && newEnchantments.isEmpty()) { item = item.transmuteCopy(Items.BOOK); - } -@@ -223,6 +285,23 @@ public class GrindstoneMenu extends AbstractContainerMenu { +@@ -238,6 +_,22 @@ } - item.set(DataComponents.REPAIR_COST, i); + item.set(DataComponents.REPAIR_COST, repairCost); + + // Purpur start - Config for grindstones + net.minecraft.core.component.DataComponentPatch.Builder builder = net.minecraft.core.component.DataComponentPatch.builder(); @@ -130,11 +123,10 @@ index ad70a0f7debee27d9f3b2ff39cb0429b39485190..e991ca16d069fddc3e4eb6d8c78c0dbf + } + item.applyComponents(builder.build()); + // Purpur end - Config for grindstones -+ return item; } -@@ -279,7 +358,9 @@ public class GrindstoneMenu extends AbstractContainerMenu { +@@ -294,7 +_,9 @@ return ItemStack.EMPTY; } @@ -143,4 +135,4 @@ index ad70a0f7debee27d9f3b2ff39cb0429b39485190..e991ca16d069fddc3e4eb6d8c78c0dbf + this.activeQuickItem = null; // Purpur - Grindstone API } - return itemStack; + return clicked; diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/ItemCombinerMenu.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/ItemCombinerMenu.java.patch new file mode 100644 index 000000000..1676339c1 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/ItemCombinerMenu.java.patch @@ -0,0 +1,12 @@ +--- a/net/minecraft/world/inventory/ItemCombinerMenu.java ++++ b/net/minecraft/world/inventory/ItemCombinerMenu.java +@@ -177,7 +_,9 @@ + return ItemStack.EMPTY; + } + ++ this.activeQuickItem = clicked; // Purpur - Anvil API + slot.onTake(player, stack); ++ this.activeQuickItem = null; // Purpur - Anvil API + } + + return clicked; diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/FarmBlock.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/FarmlandBlock.java.patch similarity index 66% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/FarmBlock.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/FarmlandBlock.java.patch index 53771adbc..0a72539f2 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/FarmBlock.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/FarmlandBlock.java.patch @@ -1,25 +1,17 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/level/block/FarmBlock.java b/net/minecraft/world/level/block/FarmBlock.java -index da822a89e134e98696308315799d872944e7712f..75b38812b538e0938bbbde62427fa9fd23d372a1 100644 ---- a/net/minecraft/world/level/block/FarmBlock.java -+++ b/net/minecraft/world/level/block/FarmBlock.java -@@ -112,7 +112,7 @@ public class FarmBlock extends Block { - public void fallOn(Level level, BlockState state, BlockPos pos, Entity entity, double fallDistance) { +--- a/net/minecraft/world/level/block/FarmlandBlock.java ++++ b/net/minecraft/world/level/block/FarmlandBlock.java +@@ -111,7 +_,7 @@ + public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { super.fallOn(level, state, pos, entity, fallDistance); // CraftBukkit - moved here as game rules / events shouldn't affect fall damage. if (level instanceof ServerLevel serverLevel -- && level.random.nextFloat() < fallDistance - 0.5 -+ && (serverLevel.purpurConfig.farmlandTrampleHeight >= 0D ? fallDistance >= serverLevel.purpurConfig.farmlandTrampleHeight : level.random.nextFloat() < fallDistance - 0.5) // Purpur - Configurable farmland trample height +- && level.getRandom().nextFloat() < fallDistance - 0.5 ++ && (serverLevel.purpurConfig.farmlandTrampleHeight >= 0D ? fallDistance >= serverLevel.purpurConfig.farmlandTrampleHeight : level.getRandom().nextFloat() < fallDistance - 0.5) // Purpur - Configurable farmland trample height && entity instanceof LivingEntity && (entity instanceof Player || serverLevel.getGameRules().get(GameRules.MOB_GRIEFING)) && entity.getBbWidth() * entity.getBbWidth() * entity.getBbHeight() > 0.512F) { -@@ -129,6 +129,28 @@ public class FarmBlock extends Block { - return; - } +@@ -128,6 +_,28 @@ + return; + } + if (level.purpurConfig.farmlandTramplingDisabled) return; // Purpur - Farmland trampling changes + if (level.purpurConfig.farmlandTramplingOnlyPlayers && !(entity instanceof Player)) return; // Purpur - Farmland trampling changes @@ -43,10 +35,10 @@ index da822a89e134e98696308315799d872944e7712f..75b38812b538e0938bbbde62427fa9fd + } + // Purpur end - Farmland trampling changes + - if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.DIRT.defaultBlockState())) { - return; - } -@@ -177,7 +199,7 @@ public class FarmBlock extends Block { + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.DIRT.defaultBlockState())) { + return; + } +@@ -176,7 +_,7 @@ } } diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch new file mode 100644 index 000000000..f6692a796 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch @@ -0,0 +1,33 @@ +--- a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java ++++ b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +@@ -195,6 +_,21 @@ + } + + ItemStack fuel = entity.items.get(1); ++ // Purpur start - Furnace uses lava from underneath ++ boolean usedLavaFromUnderneath = false; ++ if (level.purpurConfig.furnaceUseLavaFromUnderneath && !entity.isLit() && fuel.isEmpty() && !entity.items.get(0).isEmpty() && level.getGameTime() % 20 == 0) { ++ BlockPos below = entity.getBlockPos().below(); ++ BlockState belowState = level.getBlockStateIfLoaded(below); ++ if (belowState != null && belowState.is(net.minecraft.world.level.block.Blocks.LAVA)) { ++ net.minecraft.world.level.material.FluidState fluidState = belowState.getFluidState(); ++ if (fluidState != null && fluidState.isSource()) { ++ level.setBlock(below, net.minecraft.world.level.block.Blocks.AIR.defaultBlockState(), 3); ++ fuel = Items.LAVA_BUCKET.getDefaultInstance(); ++ usedLavaFromUnderneath = true; ++ } ++ } ++ } ++ // Purpur end - Furnace uses lava from underneath + ItemStack ingredient = entity.items.get(0); + boolean hasIngredient = !ingredient.isEmpty(); + boolean hasFuel = !fuel.isEmpty(); +@@ -273,6 +_,8 @@ + if (changed) { + setChanged(level, pos, state); + } ++ ++ if (usedLavaFromUnderneath) furnace.items.set(1, ItemStack.EMPTY); // Purpur - Furnace uses lava from underneath + } + + private static void consumeFuel(final NonNullList items, final ItemStack fuel) { diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/BeaconBlockEntity.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/BeaconBlockEntity.java.patch new file mode 100644 index 000000000..5d4d0fcb5 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/BeaconBlockEntity.java.patch @@ -0,0 +1,58 @@ +--- a/net/minecraft/world/level/block/entity/BeaconBlockEntity.java ++++ b/net/minecraft/world/level/block/entity/BeaconBlockEntity.java +@@ -142,6 +_,16 @@ + + public double getEffectRange() { + if (this.effectRange < 0) { ++ // Purpur start - Beacon Activation Range Configurable ++ if (this.level != null) { ++ switch (this.levels) { ++ case 1: return this.level.purpurConfig.beaconLevelOne; ++ case 2: return this.level.purpurConfig.beaconLevelTwo; ++ case 3: return this.level.purpurConfig.beaconLevelThree; ++ case 4: return this.level.purpurConfig.beaconLevelFour; ++ } ++ } ++ // Purpur end - Beacon Activation Range Configurable + return this.levels * 10 + 10; + } else { + return effectRange; +@@ -170,6 +_,7 @@ + int y = pos.getY(); + int z = pos.getZ(); + BlockPos checkPos; ++ boolean isTintedGlass = false; // Purpur - allow beacon effects when covered by tinted glass + if (entity.lastCheckY < y) { + checkPos = pos; + entity.checkingBeamSections = Lists.newArrayList(); +@@ -199,11 +_,15 @@ + } + } + } else { +- if (lastBeamSection == null || state.getLightDampening() >= 15 && !state.is(Blocks.BEDROCK)) { ++ if (level.purpurConfig.beaconAllowEffectsWithTintedGlass && blockState.getBlock().equals(Blocks.TINTED_GLASS)) {isTintedGlass = true;} // Purpur - allow beacon effects when covered by tinted glass ++ // Purpur start - fix effects being applied when tinted glass is covered ++ if (lastBeamSection == null || state.getLightDampening() >= 15 && !state.is(Blocks.BEDROCK) && !(blockState.getBlock().equals(Blocks.TINTED_GLASS) && level.purpurConfig.beaconAllowEffectsWithTintedGlass)) { + entity.checkingBeamSections.clear(); + entity.lastCheckY = lastSetBlock; ++ isTintedGlass = false; + break; + } ++ // Purpur end - fix effects being applied when tinted glass is covered + + lastBeamSection.increaseHeight(); + } +@@ -214,11 +_,11 @@ + + int previousLevels = entity.levels; + if (level.getGameTime() % 80L == 0L) { +- if (!entity.beamSections.isEmpty()) { ++ if (!entity.beamSections.isEmpty() || (level.purpurConfig.beaconAllowEffectsWithTintedGlass && isTintedGlass)) { // Purpur - fix beacon effects persisting with broken base while tinted glass is used + entity.levels = updateBase(level, x, y, z); + } + +- if (entity.levels > 0 && !entity.beamSections.isEmpty()) { ++ if (entity.levels > 0 && (!entity.beamSections.isEmpty() || (level.purpurConfig.beaconAllowEffectsWithTintedGlass && isTintedGlass))) { // Purpur - allow beacon effects when covered by tinted glass + applyEffects(level, pos, entity.levels, entity.primaryPower, entity.secondaryPower, entity); // Paper - Custom beacon ranges + playSound(level, pos, SoundEvents.BEACON_AMBIENT); + } diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java.patch similarity index 71% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java.patch index 564459f69..088ee7197 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java.patch @@ -1,14 +1,6 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java b/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java -index c989b7d52e16d93e65afb0f921d514c68b814921..9261bc38258ee80aa6ec2f4bcb27a48c01f84b8f 100644 --- a/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java +++ b/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java -@@ -79,7 +79,7 @@ public class BeehiveBlockEntity extends BlockEntity { +@@ -80,7 +_,7 @@ "leash", "UUID" ); @@ -17,8 +9,8 @@ index c989b7d52e16d93e65afb0f921d514c68b814921..9261bc38258ee80aa6ec2f4bcb27a48c private static final int MIN_TICKS_BEFORE_REENTERING_HIVE = 400; private static final int MIN_OCCUPATION_TICKS_NECTAR = 2400; public static final int MIN_OCCUPATION_TICKS_NECTARLESS = 600; -@@ -153,11 +153,33 @@ public class BeehiveBlockEntity extends BlockEntity { - return list; +@@ -156,11 +_,33 @@ + return spawned; } + // Purpur start - Stored Bee API @@ -51,11 +43,11 @@ index c989b7d52e16d93e65afb0f921d514c68b814921..9261bc38258ee80aa6ec2f4bcb27a48c // Paper start - Add EntityBlockStorage clearEntities public void clearBees() { this.stored.clear(); -@@ -398,8 +420,8 @@ public class BeehiveBlockEntity extends BlockEntity { - registrar.register(DebugSubscriptions.BEE_HIVES, () -> DebugHiveInfo.pack(this)); +@@ -399,8 +_,8 @@ + registration.register(DebugSubscriptions.BEE_HIVES, () -> DebugHiveInfo.pack(this)); } -- static class BeeData { +- private static class BeeData { - private final BeehiveBlockEntity.Occupant occupant; + public static class BeeData { // Purpur - make public - Stored Bee API + public final BeehiveBlockEntity.Occupant occupant; // Purpur - make public - Stored Bee API diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/entity/BlockEntity.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/BlockEntity.java.patch similarity index 62% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/entity/BlockEntity.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/BlockEntity.java.patch index 8ee543992..138d8b6a7 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/entity/BlockEntity.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/BlockEntity.java.patch @@ -1,14 +1,6 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/level/block/entity/BlockEntity.java b/net/minecraft/world/level/block/entity/BlockEntity.java -index fb22ebe9758014ebf2aebcda21155f1c4c83fafe..7cbb92c23f0b3d49b8ea6cd66ed4f377dd22ee98 100644 --- a/net/minecraft/world/level/block/entity/BlockEntity.java +++ b/net/minecraft/world/level/block/entity/BlockEntity.java -@@ -105,6 +105,10 @@ public abstract class BlockEntity implements DebugValueSource { +@@ -107,6 +_,10 @@ input.read("PublicBukkitValues", CompoundTag.CODEC) .ifPresent(this.persistentDataContainer::putAll); // Paper end - read persistent data container @@ -18,11 +10,11 @@ index fb22ebe9758014ebf2aebcda21155f1c4c83fafe..7cbb92c23f0b3d49b8ea6cd66ed4f377 + } - public final void loadWithComponents(ValueInput input) { -@@ -117,6 +121,11 @@ public abstract class BlockEntity implements DebugValueSource { + public final void loadWithComponents(final ValueInput input) { +@@ -119,6 +_,11 @@ } - protected void saveAdditional(ValueOutput output) { + protected void saveAdditional(final ValueOutput output) { + // Purpur start - Persistent BlockEntity Lore and DisplayName + if (this.persistentLore != null) { + output.store("Purpur.persistentLore", net.minecraft.world.item.component.ItemLore.CODEC, this.persistentLore); @@ -30,8 +22,8 @@ index fb22ebe9758014ebf2aebcda21155f1c4c83fafe..7cbb92c23f0b3d49b8ea6cd66ed4f377 + // Purpur end - Persistent BlockEntity Lore and DisplayName } - public final CompoundTag saveWithFullMetadata(HolderLookup.Provider registries) { -@@ -402,4 +411,16 @@ public abstract class BlockEntity implements DebugValueSource { + public final CompoundTag saveWithFullMetadata(final HolderLookup.Provider registries) { +@@ -412,4 +_,16 @@ return this.blockEntity.getNameForReporting() + "@" + this.blockEntity.getBlockPos(); } } diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/ConduitBlockEntity.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/ConduitBlockEntity.java.patch new file mode 100644 index 000000000..406f8e273 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/ConduitBlockEntity.java.patch @@ -0,0 +1,66 @@ +--- a/net/minecraft/world/level/block/entity/ConduitBlockEntity.java ++++ b/net/minecraft/world/level/block/entity/ConduitBlockEntity.java +@@ -150,7 +_,7 @@ + BlockPos testPos = worldPosition.offset(ox, oy, ozx); + BlockState testBlock = level.getBlockState(testPos); + +- for (Block type : VALID_BLOCKS) { ++ for (Block type : level.purpurConfig.conduitBlocks) { // Purpur - Conduit behavior configuration + if (testBlock.is(type)) { + effectBlocks.add(testPos); + } +@@ -165,13 +_,13 @@ + + private static void applyEffects(final Level level, final BlockPos worldPosition, final List effectBlocks) { + // CraftBukkit start +- ConduitBlockEntity.applyEffects(level, worldPosition, ConduitBlockEntity.getRange(effectBlocks)); ++ ConduitBlockEntity.applyEffects(level, worldPosition, ConduitBlockEntity.getRange(effectBlocks, level)); // Purpur - Conduit behavior configuration + } + +- public static int getRange(List effectBlocks) { ++ public static int getRange(List effectBlocks, Level level) { // Purpur - Conduit behavior configuration + // CraftBukkit end + int activeSize = effectBlocks.size(); +- int effectRange = activeSize / 7 * 16; ++ int effectRange = activeSize / 7 * level.purpurConfig.conduitDistance; // Purpur - Conduit behavior configuration + // CraftBukkit start + return effectRange; + } +@@ -204,7 +_,7 @@ + EntityReference newDestroyTarget = updateDestroyTarget(entity.destroyTarget, level, worldPosition, isActive); + LivingEntity targetEntity = EntityReference.getLivingEntity(newDestroyTarget, level); + if (damageTarget && targetEntity != null) { // CraftBukkit +- if (targetEntity.hurtServer(level, level.damageSources().magic().eventBlockDamager(level, worldPosition), 4.0F)) // CraftBukkit - move up ++ if (targetEntity.hurtServer(level, level.damageSources().magic().eventBlockDamager(level, worldPosition), level.purpurConfig.conduitDamageAmount)) // CraftBukkit - move up // Purpur - Conduit behavior configuration + level.playSound( + null, targetEntity.getX(), targetEntity.getY(), targetEntity.getZ(), SoundEvents.CONDUIT_ATTACK_TARGET, SoundSource.BLOCKS, 1.0F, 1.0F + ); +@@ -225,19 +_,25 @@ + return selectNewTarget(level, pos); + } else { + LivingEntity targetEntity = EntityReference.getLivingEntity(target, level); +- return targetEntity != null && targetEntity.isAlive() && pos.closerThan(targetEntity.blockPosition(), 8.0) ? target : null; ++ return targetEntity != null && targetEntity.isAlive() && pos.closerThan(targetEntity.blockPosition(), level.purpurConfig.conduitDamageDistance) ? target : null; // Purpur - Conduit behavior configuration + } + } + + private static @Nullable EntityReference selectNewTarget(final ServerLevel level, final BlockPos pos) { + List candidates = level.getEntitiesOfClass( +- LivingEntity.class, getDestroyRangeAABB(pos), input -> input instanceof Enemy && input.isInWaterOrRain() ++ LivingEntity.class, getDestroyRangeAABB(pos, level), input -> input instanceof Enemy && input.isInWaterOrRain() // Purpur - Conduit behavior configuration + ); + return candidates.isEmpty() ? null : EntityReference.of(Util.getRandom(candidates, level.getRandom())); + } + + public static AABB getDestroyRangeAABB(final BlockPos worldPosition) { +- return new AABB(worldPosition).inflate(8.0); ++ // Purpur start - Conduit behavior configuration ++ return getDestroyRangeAABB(worldPosition, null); ++ } ++ ++ private static AABB getDestroyRangeAABB(final BlockPos worldPosition, final Level level) { ++ // Purpur end - Conduit behavior configuration ++ return new AABB(worldPosition).inflate(level == null ? 8.0 : level.purpurConfig.conduitDamageDistance); // Purpur - Conduit behavior configuration + } + + private static void animationTick( diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch similarity index 61% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch index 41877360d..76219d6af 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch @@ -1,15 +1,7 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/level/block/entity/SignBlockEntity.java b/net/minecraft/world/level/block/entity/SignBlockEntity.java -index ce6108ea608463a28f9349010e912f23a7a1cb0c..e93f399c02aa3c47b08e33b8cf2f8b474273c33b 100644 --- a/net/minecraft/world/level/block/entity/SignBlockEntity.java +++ b/net/minecraft/world/level/block/entity/SignBlockEntity.java -@@ -149,16 +149,32 @@ public class SignBlockEntity extends BlockEntity { - return this.setText(updater.apply(text), isFrontText); +@@ -149,16 +_,32 @@ + return this.setText(function.apply(text), isFrontText); } + // Purpur start - Signs allow color codes @@ -26,27 +18,28 @@ index ce6108ea608463a28f9349010e912f23a7a1cb0c..e93f399c02aa3c47b08e33b8cf2f8b47 + } + // Purpur end - Signs allow color codes + - private SignText setMessages(Player player, List filteredText, SignText text, boolean front) { // CraftBukkit + private SignText setMessages(final Player player, final List lines, SignText text, final boolean front) { // CraftBukkit SignText originalText = text; // CraftBukkit - for (int i = 0; i < filteredText.size(); i++) { - FilteredText filteredText1 = filteredText.get(i); - Style style = text.getMessage(i, player.isTextFilteringEnabled()).getStyle(); + for (int i = 0; i < lines.size(); i++) { + FilteredText line = lines.get(i); + Style currentTextStyle = text.getMessage(i, player.isTextFilteringEnabled()).getStyle(); + + org.bukkit.entity.Player craftPlayer = (org.bukkit.craftbukkit.entity.CraftPlayer) player.getBukkitEntity(); // Purpur - Signs allow color codes if (player.isTextFilteringEnabled()) { -- text = text.setMessage(i, Component.literal(net.minecraft.util.StringUtil.filterText(filteredText1.filteredOrEmpty())).setStyle(style)); // Paper - filter sign text to chat only -+ text = text.setMessage(i, translateColors(craftPlayer, net.minecraft.util.StringUtil.filterText(filteredText1.filteredOrEmpty()), style)); // Paper - filter sign text to chat only // Purpur - Signs allow color codes +- text = text.setMessage(i, Component.literal(net.minecraft.util.StringUtil.filterText(line.filteredOrEmpty())).setStyle(currentTextStyle)); // Paper - filter sign text to chat only ++ text = text.setMessage(i, translateColors(craftPlayer, net.minecraft.util.StringUtil.filterText(line.filteredOrEmpty()), currentTextStyle)); // Paper - filter sign text to chat only // Purpur - Signs allow color codes } else { text = text.setMessage( -- i, Component.literal(filteredText1.raw()).setStyle(style), Component.literal(net.minecraft.util.StringUtil.filterText(filteredText1.filteredOrEmpty())).setStyle(style) // Paper - filter sign text to chat only -+ i, translateColors(craftPlayer, net.minecraft.util.StringUtil.filterText(filteredText1.raw()), style), translateColors(craftPlayer, net.minecraft.util.StringUtil.filterText(filteredText1.filteredOrEmpty()), style) // Paper - filter sign text to chat only // Purpur - Signs allow color codes +- i, Component.literal(line.raw()).setStyle(currentTextStyle), Component.literal(net.minecraft.util.StringUtil.filterText(line.filteredOrEmpty())).setStyle(currentTextStyle) // Paper - filter sign text to chat only ++ i, translateColors(craftPlayer, net.minecraft.util.StringUtil.filterText(line.raw()), currentTextStyle), translateColors(craftPlayer, net.minecraft.util.StringUtil.filterText(line.filteredOrEmpty()), currentTextStyle) // Paper - filter sign text to chat only // Purpur - Signs allow color codes ); } } -@@ -308,6 +324,27 @@ public class SignBlockEntity extends BlockEntity { - return new CommandSourceStack(commandSource, Vec3.atCenterOf(pos), Vec2.ZERO, level, LevelBasedPermissionSet.GAMEMASTER, string, component, level.getServer(), player); // Paper - Fix commands from signs not firing command events +@@ -308,6 +_,27 @@ + commandSource, Vec3.atCenterOf(pos), Vec2.ZERO, level, LevelBasedPermissionSet.GAMEMASTER, textName, displayName, level.getServer(), player // Paper - Fix commands from signs not firing command events + ); } - ++ + // Purpur start - Signs allow color codes + public ClientboundBlockEntityDataPacket getTranslatedUpdatePacket(boolean filtered, boolean front) { + try (net.minecraft.util.ProblemReporter.ScopedCollector scopedCollector = new net.minecraft.util.ProblemReporter.ScopedCollector(this.problemPath(), LOGGER)) { @@ -67,7 +60,6 @@ index ce6108ea608463a28f9349010e912f23a7a1cb0c..e93f399c02aa3c47b08e33b8cf2f8b47 + } + } + // Purpur end - Signs allow color codes -+ + @Override public ClientboundBlockEntityDataPacket getUpdatePacket() { - return ClientboundBlockEntityDataPacket.create(this);