diff --git a/gradle.properties b/gradle.properties index beff72e79..2e53a5344 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ group=net.pl3x.purpur version=1.17-R0.1-SNAPSHOT packageVersion=1_17_R1 -paperCommit=bc4b23e389a80d3f5228688060cf1f610f58ea43 +paperCommit=ce6610254f61047ec957814426a643138f077979 org.gradle.parallel=true org.gradle.jvmargs=-Xmx3G diff --git a/patches/server-unmapped/0140-Config-migration-climbing-should-not-bypass-cramming.patch b/patches/removed/0140-Config-migration-climbing-should-not-bypass-cramming.patch similarity index 100% rename from patches/server-unmapped/0140-Config-migration-climbing-should-not-bypass-cramming.patch rename to patches/removed/0140-Config-migration-climbing-should-not-bypass-cramming.patch diff --git a/patches/server-unmapped/0137-Snow-Golem-rate-of-fire-config.patch b/patches/server-unmapped/0137-Snow-Golem-rate-of-fire-config.patch deleted file mode 100644 index b1f61e1d3..000000000 --- a/patches/server-unmapped/0137-Snow-Golem-rate-of-fire-config.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Simon Gardling -Date: Tue, 1 Dec 2020 16:50:36 -0500 -Subject: [PATCH] Snow Golem rate of fire config - -The formula used to determine the amount of ticks between shots is: - ((sqrt(distanceToTarget) / snowGolemAttackDistance) / snowGolemSnowBallModifer) * (maxShootIntervalTicks - minShootIntervalTicks) + minShootIntervalTicks - -If min-shoot-interval-ticks and max-shoot-interval-ticks are both set to -0, snow golems won't shoot any snowballs. - -diff --git a/src/main/java/net/minecraft/world/entity/animal/EntitySnowman.java b/src/main/java/net/minecraft/world/entity/animal/EntitySnowman.java -index a692b973717ecc56d808039418599a11aedc2c5a..76fe39cf57384602c7422cb340f15ca7cac65ef9 100644 ---- a/src/main/java/net/minecraft/world/entity/animal/EntitySnowman.java -+++ b/src/main/java/net/minecraft/world/entity/animal/EntitySnowman.java -@@ -66,7 +66,7 @@ public class EntitySnowman extends EntityGolem implements IShearable, IRangedEnt - @Override - protected void initPathfinder() { - this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur -- this.goalSelector.a(1, new PathfinderGoalArrowAttack(this, 1.25D, 20, 10.0F)); -+ this.goalSelector.a(1, new PathfinderGoalArrowAttack(this, world.purpurConfig.snowGolemAttackDistance, world.purpurConfig.snowGolemSnowBallMin, world.purpurConfig.snowGolemSnowBallMax, world.purpurConfig.snowGolemSnowBallModifier)); // Purpur - configurable snow golem snowball throwing - this.goalSelector.a(2, new PathfinderGoalRandomStrollLand(this, 1.0D, 1.0000001E-5F)); - this.goalSelector.a(3, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); - this.goalSelector.a(4, new PathfinderGoalRandomLookaround(this)); -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index c2044a89fd1547092fd3d6be671570fcf2a60f09..ed2b682b3717e58eb18ef12c18f362a75174f069 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -1039,12 +1039,20 @@ public class PurpurWorldConfig { - public boolean snowGolemLeaveTrailWhenRidden = false; - public boolean snowGolemDropsPumpkin = true; - public boolean snowGolemPutPumpkinBack = false; -+ public int snowGolemSnowBallMin = 20; -+ public int snowGolemSnowBallMax = 20; -+ public float snowGolemSnowBallModifier = 10.0F; -+ public double snowGolemAttackDistance = 1.25D; - private void snowGolemSettings() { - snowGolemRidable = getBoolean("mobs.snow_golem.ridable", snowGolemRidable); - snowGolemRidableInWater = getBoolean("mobs.snow_golem.ridable-in-water", snowGolemRidableInWater); - snowGolemLeaveTrailWhenRidden = getBoolean("mobs.snow_golem.leave-trail-when-ridden", snowGolemLeaveTrailWhenRidden); - snowGolemDropsPumpkin = getBoolean("mobs.snow_golem.drop-pumpkin-when-sheared", snowGolemDropsPumpkin); - snowGolemPutPumpkinBack = getBoolean("mobs.snow_golem.pumpkin-can-be-added-back", snowGolemPutPumpkinBack); -+ snowGolemSnowBallMin = getInt("mobs.snow_golem.min-shoot-interval-ticks", snowGolemSnowBallMin); -+ snowGolemSnowBallMax = getInt("mobs.snow_golem.max-shoot-interval-ticks", snowGolemSnowBallMax); -+ snowGolemSnowBallModifier = (float) getDouble("mobs.snow_golem.snow-ball-modifier", snowGolemSnowBallModifier); -+ snowGolemAttackDistance = getDouble("mobs.snow_golem.attack-distance", snowGolemAttackDistance); - } - - public boolean squidRidable = false; diff --git a/patches/server-unmapped/0139-EMC-Configurable-disable-give-dropping.patch b/patches/server-unmapped/0139-EMC-Configurable-disable-give-dropping.patch deleted file mode 100644 index a8fd9d60a..000000000 --- a/patches/server-unmapped/0139-EMC-Configurable-disable-give-dropping.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Thu, 14 Jan 2016 00:49:14 -0500 -Subject: [PATCH] EMC - Configurable disable give dropping - -Modified version of a patch by Aikar from EMC. Adds a config option in -purpur.yml to disable the /give command from dropping items on the -floor when a player's inventory is full. - -diff --git a/src/main/java/net/minecraft/server/commands/CommandGive.java b/src/main/java/net/minecraft/server/commands/CommandGive.java -index a10207f7cb9455e29db7e6906cb2138ad5609a1f..9557fd12f87e7e825501759598eaee75cd3891ac 100644 ---- a/src/main/java/net/minecraft/server/commands/CommandGive.java -+++ b/src/main/java/net/minecraft/server/commands/CommandGive.java -@@ -47,6 +47,7 @@ public class CommandGive { - boolean flag = entityplayer.inventory.pickup(itemstack); - EntityItem entityitem; - -+ if (net.pl3x.purpur.PurpurConfig.disableGiveCommandDrops) continue; // Purpur - add config option for toggling give command dropping - if (flag && itemstack.isEmpty()) { - itemstack.setCount(1); - entityitem = entityplayer.drop(itemstack, false, false, true); // Paper - Fix duplicating /give items on item drop cancel -diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java -index 8a1311eeb2504bc9708403686518ea38bf598c71..f4fab86ed176aea7d5fca3836e76f53e6101575f 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java -@@ -193,6 +193,11 @@ public class PurpurConfig { - useAlternateKeepAlive = getBoolean("settings.use-alternate-keepalive", useAlternateKeepAlive); - } - -+ public static boolean disableGiveCommandDrops = false; -+ private static void disableGiveCommandDrops() { -+ disableGiveCommandDrops = getBoolean("settings.disable-give-dropping", disableGiveCommandDrops); -+ } -+ - public static boolean barrelSixRows = false; - public static boolean enderChestSixRows = false; - public static boolean enderChestPermissionRows = false; diff --git a/patches/server-unmapped/0141-Lobotomize-stuck-villagers.patch b/patches/server-unmapped/0141-Lobotomize-stuck-villagers.patch deleted file mode 100644 index e859261ff..000000000 --- a/patches/server-unmapped/0141-Lobotomize-stuck-villagers.patch +++ /dev/null @@ -1,126 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Thu, 3 Dec 2020 17:56:18 -0600 -Subject: [PATCH] Lobotomize stuck villagers - - -diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 5fd01caa85eedc2e703b76fd230762cc89fceb21..4c427a3950b1418ef6135a288449f5b7f7939701 100644 ---- a/src/main/java/net/minecraft/world/entity/Entity.java -+++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -206,7 +206,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne - public double lastY; - public double lastZ; - private Vec3D loc; -- private BlockPosition locBlock; -+ private BlockPosition locBlock; public BlockPosition getBlockLocation() { return locBlock; } // Purpur - private Vec3D mot; - public float yaw; - public float pitch; -diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/NavigationAbstract.java b/src/main/java/net/minecraft/world/entity/ai/navigation/NavigationAbstract.java -index e6ba9b7fbf08ae0dd083a1ebee8eb7ed8a937751..1df161b817747f9d21733b8e415da11bfacfbfc7 100644 ---- a/src/main/java/net/minecraft/world/entity/ai/navigation/NavigationAbstract.java -+++ b/src/main/java/net/minecraft/world/entity/ai/navigation/NavigationAbstract.java -@@ -116,6 +116,7 @@ public abstract class NavigationAbstract { - } - - @Nullable -+ public PathEntity calculateDestination(BlockPosition blockposition, int i) { return a(blockposition, i); } // Purpur - OBFHELPER - public PathEntity a(BlockPosition blockposition, int i) { - // Paper start - add target parameter - return this.a(blockposition, null, i); -diff --git a/src/main/java/net/minecraft/world/entity/npc/EntityVillager.java b/src/main/java/net/minecraft/world/entity/npc/EntityVillager.java -index 85242947bd115f63f8807e1d4e6784fff537e802..df73d1ff1d5c2e878693aabf50105e315a0152c9 100644 ---- a/src/main/java/net/minecraft/world/entity/npc/EntityVillager.java -+++ b/src/main/java/net/minecraft/world/entity/npc/EntityVillager.java -@@ -89,6 +89,7 @@ import net.minecraft.world.level.IWorldReader; - import net.minecraft.world.level.World; - import net.minecraft.world.level.WorldAccess; - import net.minecraft.world.level.block.state.IBlockData; -+import net.minecraft.world.level.pathfinder.PathEntity; - import net.minecraft.world.phys.AxisAlignedBB; - import org.apache.logging.log4j.Logger; - -@@ -258,15 +259,39 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation - } - // Spigot End - -+ private int behaviorTick = 0; -+ -+ // Purpur start -+ boolean lobotomized = false; -+ -+ private boolean isLobotomized() { -+ if ((world.getTime() + brainTickOffset) % world.purpurConfig.villagerLobotomizeCheck == 0) { -+ this.lobotomized = !canTravelFrom(getBlockLocation().up()); -+ } -+ return this.lobotomized; -+ } -+ -+ private boolean canTravelFrom(BlockPosition pos) { -+ return canTravelTo(pos.east()) || canTravelTo(pos.west()) || canTravelTo(pos.north()) || canTravelTo(pos.south()); -+ } -+ -+ private boolean canTravelTo(BlockPosition pos) { -+ PathEntity to = navigation.calculateDestination(pos, 0); -+ return to != null && to.getPoints().size() > 1; -+ } -+ // Purpur end -+ - @Override - protected void mobTick() { mobTick(false); } - protected void mobTick(boolean inactive) { - this.world.getMethodProfiler().enter("villagerBrain"); - // Purpur start -+ if (world.purpurConfig.villagerLobotomizeEnabled) inactive = inactive || isLobotomized(); - boolean tick = (world.getTime() + brainTickOffset) % world.purpurConfig.villagerBrainTicks == 0; - if (((WorldServer) world).getMinecraftServer().lagging ? tick : world.purpurConfig.villagerUseBrainTicksOnlyWhenLagging || tick) - // Purpur end - if (!inactive) this.getBehaviorController().a((WorldServer) this.world, this); // CraftBukkit - decompile error // Paper -+ else if (shouldRestock()) doRestock(); // Purpur - this.world.getMethodProfiler().exit(); - if (this.bF) { - this.bF = false; -@@ -398,6 +423,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation - return true; - } - -+ public void doRestock() { fb(); } // Purpur - OBFHELPER - public void fb() { - this.fp(); - Iterator iterator = this.getOffers().iterator(); -@@ -432,6 +458,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation - return this.bD == 0 || this.bD < 2 && this.world.getTime() > this.bC + 2400L; - } - -+ public boolean shouldRestock() { return fc(); } // Purpur - OBFHELPER - public boolean fc() { - long i = this.bC + 12000L; - long j = this.world.getTime(); -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 3e2898e3582efc00764885739e1df3a2ab5d5f6e..6f4aab0495e168afe3927b994e9c42ddce59dc20 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -1134,6 +1134,8 @@ public class PurpurWorldConfig { - public int villagerSpawnIronGolemLimit = 0; - public boolean villagerCanBreed = true; - public int villagerBreedingTicks = 6000; -+ public boolean villagerLobotomizeEnabled = false; -+ public int villagerLobotomizeCheck = 60; - private void villagerSettings() { - villagerRidable = getBoolean("mobs.villager.ridable", villagerRidable); - villagerRidableInWater = getBoolean("mobs.villager.ridable-in-water", villagerRidableInWater); -@@ -1146,6 +1148,13 @@ public class PurpurWorldConfig { - villagerSpawnIronGolemLimit = getInt("mobs.villager.spawn-iron-golem.limit", villagerSpawnIronGolemLimit); - villagerCanBreed = getBoolean("mobs.villager.can-breed", villagerCanBreed); - villagerBreedingTicks = getInt("mobs.villager.breeding-delay-ticks", villagerBreedingTicks); -+ if (PurpurConfig.version < 9) { -+ boolean oldValue = getBoolean("mobs.villager.lobotomize-1x1", villagerLobotomizeEnabled); -+ set("mobs.villager.lobotomize.enabled", oldValue); -+ set("mobs.villager.lobotomize-1x1", null); -+ } -+ villagerLobotomizeEnabled = getBoolean("mobs.villager.lobotomize.enabled", villagerLobotomizeEnabled); -+ villagerLobotomizeCheck = getInt("mobs.villager.lobotomize.check-interval", villagerLobotomizeCheck); - } - - public boolean villagerTraderRidable = false; diff --git a/patches/server-unmapped/0142-Option-for-Villager-Clerics-to-farm-Nether-Wart.patch b/patches/server-unmapped/0142-Option-for-Villager-Clerics-to-farm-Nether-Wart.patch deleted file mode 100644 index 2d9289f81..000000000 --- a/patches/server-unmapped/0142-Option-for-Villager-Clerics-to-farm-Nether-Wart.patch +++ /dev/null @@ -1,247 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> -Date: Sat, 5 Dec 2020 01:20:16 -0800 -Subject: [PATCH] Option for Villager Clerics to farm Nether Wart - -Adds an option so that Villagers with the Cleric profession are able to -farm Nether Wart. Reimplemented based on a feature of the carpet-extra -mod. - -diff --git a/src/main/java/net/minecraft/world/IInventory.java b/src/main/java/net/minecraft/world/IInventory.java -index 774ba6a923f7e329f6af5efc17e1c46e87ed2d77..b8c73cd0ba916b7bf166a6d2f6b7ab68cd9c939b 100644 ---- a/src/main/java/net/minecraft/world/IInventory.java -+++ b/src/main/java/net/minecraft/world/IInventory.java -@@ -38,6 +38,7 @@ public interface IInventory extends Clearable { - return true; - } - -+ default int getAmount(Item item) { return this.a(item); } // Purpur - OBFHELPER - default int a(Item item) { - int i = 0; - -@@ -52,6 +53,7 @@ public interface IInventory extends Clearable { - return i; - } - -+ default boolean containsAny(Set itemSet) { return a(itemSet); } // Purpur - OBFHELPER - default boolean a(Set set) { - for (int i = 0; i < this.getSize(); ++i) { - ItemStack itemstack = this.getItem(i); -diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/BehaviorFarm.java b/src/main/java/net/minecraft/world/entity/ai/behavior/BehaviorFarm.java -index 42c70a6c2972ac38e889a6d42fe2d7d4f6017d57..752642c0a15d68fcc1871e1cb02658b12c8978b3 100644 ---- a/src/main/java/net/minecraft/world/entity/ai/behavior/BehaviorFarm.java -+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/BehaviorFarm.java -@@ -32,6 +32,7 @@ public class BehaviorFarm extends Behavior { - private long c; - private int d; - private final List e = Lists.newArrayList(); -+ private boolean clericWartFarmer = false; // Purpur - - public BehaviorFarm() { - super(ImmutableMap.of(MemoryModuleType.LOOK_TARGET, MemoryStatus.VALUE_ABSENT, MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT, MemoryModuleType.SECONDARY_JOB_SITE, MemoryStatus.VALUE_PRESENT)); -@@ -40,9 +41,14 @@ public class BehaviorFarm extends Behavior { - protected boolean a(WorldServer worldserver, EntityVillager entityvillager) { - if (!worldserver.getGameRules().getBoolean(GameRules.MOB_GRIEFING) && !worldserver.purpurConfig.villagerFarmingBypassMobGriefing) { // Purpur - return false; -- } else if (entityvillager.getVillagerData().getProfession() != VillagerProfession.FARMER) { -+ } else if (entityvillager.getVillagerData().getProfession() != VillagerProfession.FARMER && !(worldserver.purpurConfig.villagerClericsFarmWarts && entityvillager.getVillagerData().getProfession() == VillagerProfession.CLERIC)) { // Purpur - return false; - } else { -+ // Purpur start -+ if (!this.clericWartFarmer && entityvillager.getVillagerData().getProfession() == VillagerProfession.CLERIC) { -+ this.clericWartFarmer = true; -+ } -+ // Purpur end - BlockPosition.MutableBlockPosition blockposition_mutableblockposition = entityvillager.getChunkCoordinates().i(); - - this.e.clear(); -@@ -73,6 +79,11 @@ public class BehaviorFarm extends Behavior { - Block block = iblockdata.getBlock(); - Block block1 = worldserver.getType(blockposition.down()).getBlock(); - -+ // Purpur start -+ if (this.clericWartFarmer) { -+ return block == Blocks.NETHER_WART && iblockdata.get(net.minecraft.world.level.block.BlockNetherWart.AGE) == 3 || iblockdata.isAir() && block1 == Blocks.SOUL_SAND; -+ } -+ // Purpur end - return block instanceof BlockCrops && ((BlockCrops) block).isRipe(iblockdata) || iblockdata.isAir() && block1 instanceof BlockSoil; - } - -@@ -98,7 +109,7 @@ public class BehaviorFarm extends Behavior { - Block block = iblockdata.getBlock(); - Block block1 = worldserver.getType(this.farmBlock.down()).getBlock(); - -- if (block instanceof BlockCrops && ((BlockCrops) block).isRipe(iblockdata)) { -+ if (block instanceof BlockCrops && ((BlockCrops) block).isRipe(iblockdata) && !this.clericWartFarmer || this.clericWartFarmer && block == Blocks.NETHER_WART && iblockdata.get(net.minecraft.world.level.block.BlockNetherWart.AGE) == 3) { // Purpur - // CraftBukkit start - if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entityvillager, this.farmBlock, Blocks.AIR.getBlockData()).isCancelled()) { - worldserver.a(this.farmBlock, true, entityvillager); -@@ -106,7 +117,7 @@ public class BehaviorFarm extends Behavior { - // CraftBukkit end - } - -- if (iblockdata.isAir() && block1 instanceof BlockSoil && entityvillager.canPlant()) { -+ if (iblockdata.isAir() && (block1 instanceof BlockSoil && !this.clericWartFarmer || this.clericWartFarmer && block1 == Blocks.SOUL_SAND) && entityvillager.canPlant()) { // Purpur - InventorySubcontainer inventorysubcontainer = entityvillager.getInventory(); - - for (int j = 0; j < inventorysubcontainer.getSize(); ++j) { -@@ -116,6 +127,14 @@ public class BehaviorFarm extends Behavior { - if (!itemstack.isEmpty()) { - // CraftBukkit start - Block planted = null; -+ // Purpur start -+ if (this.clericWartFarmer) { -+ if (itemstack.getItem() == Items.NETHER_WART) { -+ planted = Blocks.NETHER_WART; -+ flag = true; -+ } -+ } else -+ // Purpur end - if (itemstack.getItem() == Items.WHEAT_SEEDS) { - planted = Blocks.WHEAT; - flag = true; -@@ -139,7 +158,7 @@ public class BehaviorFarm extends Behavior { - } - - if (flag) { -- worldserver.playSound((EntityHuman) null, (double) this.farmBlock.getX(), (double) this.farmBlock.getY(), (double) this.farmBlock.getZ(), SoundEffects.ITEM_CROP_PLANT, SoundCategory.BLOCKS, 1.0F, 1.0F); -+ worldserver.playSound((EntityHuman) null, (double) this.farmBlock.getX(), (double) this.farmBlock.getY(), (double) this.farmBlock.getZ(), this.clericWartFarmer ? SoundEffects.ITEM_NETHER_WART_PLANT : SoundEffects.ITEM_CROP_PLANT, SoundCategory.BLOCKS, 1.0F, 1.0F); // Purpur - itemstack.subtract(1); - if (itemstack.isEmpty()) { - inventorysubcontainer.setItem(j, ItemStack.b); -diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/BehaviorTradeVillager.java b/src/main/java/net/minecraft/world/entity/ai/behavior/BehaviorTradeVillager.java -index 71ea6c43d76bf1abe6b08dadb20ea4708b0ecfc7..c73b4475182541fa8261bec44f1eeeef21c22f42 100644 ---- a/src/main/java/net/minecraft/world/entity/ai/behavior/BehaviorTradeVillager.java -+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/BehaviorTradeVillager.java -@@ -53,6 +53,11 @@ public class BehaviorTradeVillager extends Behavior { - if (entityvillager1.getVillagerData().getProfession() == VillagerProfession.FARMER && entityvillager.getInventory().a(Items.WHEAT) > Items.WHEAT.getMaxStackSize() / 2) { - a(entityvillager, ImmutableSet.of(Items.WHEAT), entityvillager1); - } -+ // Purpur start -+ if (worldserver.purpurConfig.villagerClericsFarmWarts && worldserver.purpurConfig.villagerClericFarmersThrowWarts && entityvillager.getVillagerData().getProfession() == VillagerProfession.CLERIC && entityvillager.getInventory().getAmount(Items.NETHER_WART) > Items.NETHER_WART.getMaxStackSize() / 2) { -+ tryThrowingItems(entityvillager, ImmutableSet.of(Items.NETHER_WART), entityvillager1); -+ } -+ // Purpur end - - if (!this.b.isEmpty() && entityvillager.getInventory().a(this.b)) { - a(entityvillager, this.b, entityvillager1); -@@ -74,6 +79,7 @@ public class BehaviorTradeVillager extends Behavior { - }).collect(Collectors.toSet()); - } - -+ private static void tryThrowingItems(EntityVillager entityVillager, Set acceptableItems, EntityLiving targetEntity) { a(entityVillager, acceptableItems, targetEntity); } // Purpur - OBFHELPER - private static void a(EntityVillager entityvillager, Set set, EntityLiving entityliving) { - InventorySubcontainer inventorysubcontainer = entityvillager.getInventory(); - ItemStack itemstack = ItemStack.b; -diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/Behaviors.java b/src/main/java/net/minecraft/world/entity/ai/behavior/Behaviors.java -index df12193e1a2e449193a3feab53fc684a2571ae3a..4a8217862a98488ce71ce577b5fa9d6a0f9c898a 100644 ---- a/src/main/java/net/minecraft/world/entity/ai/behavior/Behaviors.java -+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/Behaviors.java -@@ -21,10 +21,13 @@ public class Behaviors { - return ImmutableList.of(Pair.of(0, new BehaviorSwim(0.8F)), Pair.of(0, new BehaviorInteractDoor()), Pair.of(0, new BehaviorLook(45, 90)), Pair.of(0, new BehaviorPanic()), Pair.of(0, new BehaviorWake()), Pair.of(0, new BehaviorBellAlert()), Pair.of(0, new BehaviorRaid()), Pair.of(0, new BehaviorPositionValidate(villagerprofession.b(), MemoryModuleType.JOB_SITE)), Pair.of(0, new BehaviorPositionValidate(villagerprofession.b(), MemoryModuleType.POTENTIAL_JOB_SITE)), Pair.of(1, new BehavorMove()), Pair.of(2, new BehaviorBetterJob(villagerprofession)), Pair.of(3, new BehaviorInteractPlayer(f)), new Pair[]{Pair.of(5, new BehaviorFindAdmirableItem<>(f, false, 4)), Pair.of(6, new BehaviorFindPosition(villagerprofession.b(), MemoryModuleType.JOB_SITE, MemoryModuleType.POTENTIAL_JOB_SITE, true, Optional.empty())), Pair.of(7, new BehaviorPotentialJobSite(f)), Pair.of(8, new BehaviorLeaveJob(f)), Pair.of(10, new BehaviorFindPosition(VillagePlaceType.r, MemoryModuleType.HOME, false, Optional.of((byte) 14))), Pair.of(10, new BehaviorFindPosition(VillagePlaceType.s, MemoryModuleType.MEETING_POINT, true, Optional.of((byte) 14))), Pair.of(10, new BehaviorCareer()), Pair.of(10, new BehaviorProfession())}); - } - -- public static ImmutableList>> b(VillagerProfession villagerprofession, float f) { -- Object object; -+ // Purpur start - OBFHELPER, add clericsFarmWarts param -+ public static ImmutableList>> b(VillagerProfession villagerprofession, float f) { return createWorkTask(villagerprofession, f, false); } -+ public static ImmutableList>> createWorkTask(VillagerProfession villagerprofession, float f, boolean clericsFarmWarts) { -+ BehaviorWork object; // Purpur - decompile fix - -- if (villagerprofession == VillagerProfession.FARMER) { -+ if (villagerprofession == VillagerProfession.FARMER || (clericsFarmWarts && villagerprofession == VillagerProfession.CLERIC)) { -+ // Purpur end - object = new BehaviorWorkComposter(); - } else { - object = new BehaviorWork(); -diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/SensorSecondaryPlaces.java b/src/main/java/net/minecraft/world/entity/ai/sensing/SensorSecondaryPlaces.java -index 25c10973c74f98224dd1d2ae5e7178b9781374aa..d50b5632f0e53147ea23109f1ed627b44f798b58 100644 ---- a/src/main/java/net/minecraft/world/entity/ai/sensing/SensorSecondaryPlaces.java -+++ b/src/main/java/net/minecraft/world/entity/ai/sensing/SensorSecondaryPlaces.java -@@ -20,6 +20,13 @@ public class SensorSecondaryPlaces extends Sensor { - } - - protected void a(WorldServer worldserver, EntityVillager entityvillager) { -+ // Purpur start - make sure clerics don't wander to soul sand when the option is off -+ BehaviorController behaviorcontroller = entityvillager.getBehaviorController(); -+ if (!worldserver.purpurConfig.villagerClericsFarmWarts && entityvillager.getVillagerData().getProfession() == net.minecraft.world.entity.npc.VillagerProfession.CLERIC) { -+ behaviorcontroller.removeMemory(MemoryModuleType.SECONDARY_JOB_SITE); -+ return; -+ } -+ // Purpur end - ResourceKey resourcekey = worldserver.getDimensionKey(); - BlockPosition blockposition = entityvillager.getChunkCoordinates(); - List list = Lists.newArrayList(); -@@ -37,10 +44,10 @@ public class SensorSecondaryPlaces extends Sensor { - } - } - -- BehaviorController behaviorcontroller = entityvillager.getBehaviorController(); -+ //BehaviorController behaviorcontroller = entityvillager.getBehaviorController(); // Purpur - move up - - if (!list.isEmpty()) { -- behaviorcontroller.setMemory(MemoryModuleType.SECONDARY_JOB_SITE, (Object) list); -+ behaviorcontroller.setMemory(MemoryModuleType.SECONDARY_JOB_SITE, list); // Purpur - decompile fix - } else { - behaviorcontroller.removeMemory(MemoryModuleType.SECONDARY_JOB_SITE); - } -diff --git a/src/main/java/net/minecraft/world/entity/npc/EntityVillager.java b/src/main/java/net/minecraft/world/entity/npc/EntityVillager.java -index df73d1ff1d5c2e878693aabf50105e315a0152c9..d888aa8df65d54a0dce23eaae609aa0d2c3be3d9 100644 ---- a/src/main/java/net/minecraft/world/entity/npc/EntityVillager.java -+++ b/src/main/java/net/minecraft/world/entity/npc/EntityVillager.java -@@ -203,7 +203,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation - behaviorcontroller.a(Activity.PLAY, Behaviors.a(0.5F)); - } else { - behaviorcontroller.setSchedule(Schedule.VILLAGER_DEFAULT); -- behaviorcontroller.a(Activity.WORK, Behaviors.b(villagerprofession, 0.5F), (Set) ImmutableSet.of(Pair.of(MemoryModuleType.JOB_SITE, MemoryStatus.VALUE_PRESENT))); -+ behaviorcontroller.a(Activity.WORK, Behaviors.createWorkTask(villagerprofession, 0.5F, this.world.purpurConfig.villagerClericsFarmWarts), ImmutableSet.of(Pair.of(MemoryModuleType.JOB_SITE, MemoryStatus.VALUE_PRESENT))); // Purpur - } - - behaviorcontroller.a(Activity.CORE, Behaviors.a(villagerprofession, 0.5F)); -@@ -951,6 +951,11 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation - } - - public boolean canPlant() { -+ // Purpur start -+ if (this.world.purpurConfig.villagerClericsFarmWarts && this.getVillagerData().getProfession() == VillagerProfession.CLERIC) { -+ return this.getInventory().containsAny(ImmutableSet.of(Items.NETHER_WART)); -+ } -+ // Purpur end - return this.getInventory().a((Set) ImmutableSet.of(Items.WHEAT_SEEDS, Items.POTATO, Items.CARROT, Items.BEETROOT_SEEDS)); - } - -diff --git a/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java b/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java -index 69de7588eebba7557cdaec129f19ec1fc2c675c5..dd9b678481620856fb7eaaa04c3b812c861e892a 100644 ---- a/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java -+++ b/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java -@@ -18,7 +18,7 @@ public class VillagerProfession { - public static final VillagerProfession ARMORER = a("armorer", VillagePlaceType.d, SoundEffects.ENTITY_VILLAGER_WORK_ARMORER); - public static final VillagerProfession BUTCHER = a("butcher", VillagePlaceType.e, SoundEffects.ENTITY_VILLAGER_WORK_BUTCHER); - public static final VillagerProfession CARTOGRAPHER = a("cartographer", VillagePlaceType.f, SoundEffects.ENTITY_VILLAGER_WORK_CARTOGRAPHER); -- public static final VillagerProfession CLERIC = a("cleric", VillagePlaceType.g, SoundEffects.ENTITY_VILLAGER_WORK_CLERIC); -+ public static final VillagerProfession CLERIC = a("cleric", VillagePlaceType.g, ImmutableSet.of(Items.NETHER_WART), ImmutableSet.of(Blocks.SOUL_SAND), SoundEffects.ENTITY_VILLAGER_WORK_CLERIC); // Purpur - public static final VillagerProfession FARMER = a("farmer", VillagePlaceType.h, ImmutableSet.of(Items.WHEAT, Items.WHEAT_SEEDS, Items.BEETROOT_SEEDS, Items.BONE_MEAL), ImmutableSet.of(Blocks.FARMLAND), SoundEffects.ENTITY_VILLAGER_WORK_FARMER); - public static final VillagerProfession FISHERMAN = a("fisherman", VillagePlaceType.i, SoundEffects.ENTITY_VILLAGER_WORK_FISHERMAN); - public static final VillagerProfession FLETCHER = a("fletcher", VillagePlaceType.j, SoundEffects.ENTITY_VILLAGER_WORK_FLETCHER); -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 6f4aab0495e168afe3927b994e9c42ddce59dc20..efe82464beb6741413b73bbd6adc5c45eba7bcd6 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -1136,6 +1136,8 @@ public class PurpurWorldConfig { - public int villagerBreedingTicks = 6000; - public boolean villagerLobotomizeEnabled = false; - public int villagerLobotomizeCheck = 60; -+ public boolean villagerClericsFarmWarts = false; -+ public boolean villagerClericFarmersThrowWarts = true; - private void villagerSettings() { - villagerRidable = getBoolean("mobs.villager.ridable", villagerRidable); - villagerRidableInWater = getBoolean("mobs.villager.ridable-in-water", villagerRidableInWater); -@@ -1155,6 +1157,8 @@ public class PurpurWorldConfig { - } - villagerLobotomizeEnabled = getBoolean("mobs.villager.lobotomize.enabled", villagerLobotomizeEnabled); - villagerLobotomizeCheck = getInt("mobs.villager.lobotomize.check-interval", villagerLobotomizeCheck); -+ villagerClericsFarmWarts = getBoolean("mobs.villager.clerics-farm-warts", villagerClericsFarmWarts); -+ villagerClericFarmersThrowWarts = getBoolean("mobs.villager.cleric-wart-farmers-throw-warts-at-villagers", villagerClericFarmersThrowWarts); - } - - public boolean villagerTraderRidable = false; diff --git a/patches/server-unmapped/0138-PaperPR-Config-option-for-Piglins-guarding-chests.patch b/patches/server/0133-PaperPR-Config-option-for-Piglins-guarding-chests.patch similarity index 60% rename from patches/server-unmapped/0138-PaperPR-Config-option-for-Piglins-guarding-chests.patch rename to patches/server/0133-PaperPR-Config-option-for-Piglins-guarding-chests.patch index cd95736a4..1f56c9300 100644 --- a/patches/server-unmapped/0138-PaperPR-Config-option-for-Piglins-guarding-chests.patch +++ b/patches/server/0133-PaperPR-Config-option-for-Piglins-guarding-chests.patch @@ -5,10 +5,10 @@ Subject: [PATCH] PaperPR - Config option for Piglins guarding chests diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index fcacc08db8f5a58ddd06be7f9f2cb2cf6b2231c3..03c26e4dfb4775bfd9caa4f155bde58e83865388 100644 +index 26e18a08a7f0bd704ff3055ce3a7814191450c85..197756f89b7d4d0e20e2ba48ab42b0ac59ded47f 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -@@ -719,6 +719,11 @@ public class PaperWorldConfig { +@@ -49,6 +49,11 @@ public class PaperWorldConfig { zombiesTargetTurtleEggs = getBoolean("zombies-target-turtle-eggs", zombiesTargetTurtleEggs); } @@ -20,15 +20,15 @@ index fcacc08db8f5a58ddd06be7f9f2cb2cf6b2231c3..03c26e4dfb4775bfd9caa4f155bde58e public boolean useEigencraftRedstone = false; private void useEigencraftRedstone() { useEigencraftRedstone = this.getBoolean("use-faster-eigencraft-redstone", false); -diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAI.java b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAI.java -index 44ecce39996cc4e7baad543803e1b5cfc22f8cf0..b7213d5a9c3d0f60a8f8f725cef6506d5b22d0ed 100644 ---- a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAI.java -+++ b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAI.java -@@ -437,6 +437,7 @@ public class PiglinAI { +diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java +index 7606254a83975f4052565efbf52d37df31b37bca..c8194aed379d97613b99a7c697110bbc333420ed 100644 +--- a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java ++++ b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java +@@ -468,6 +468,7 @@ public class PiglinAi { } - public static void a(EntityHuman entityhuman, boolean flag) { -+ if (!entityhuman.world.paperConfig.piglinsGuardChests) return; // Paper - List list = entityhuman.world.a(EntityPiglin.class, entityhuman.getBoundingBox().g(16.0D)); // CraftBukkit - decompile error + public static void angerNearbyPiglins(Player player, boolean blockOpen) { ++ if (!player.level.paperConfig.piglinsGuardChests) return; // Paper + List list = (List) player.level.getEntitiesOfClass(Piglin.class, player.getBoundingBox().inflate(16.0D)); // CraftBukkit - decompile error - list.stream().filter(PiglinAI::d).filter((entitypiglin) -> { + list.stream().filter(PiglinAi::isIdle).filter((entitypiglin) -> { diff --git a/patches/server/0134-EMC-Configurable-disable-give-dropping.patch b/patches/server/0134-EMC-Configurable-disable-give-dropping.patch new file mode 100644 index 000000000..252272a46 --- /dev/null +++ b/patches/server/0134-EMC-Configurable-disable-give-dropping.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Thu, 14 Jan 2016 00:49:14 -0500 +Subject: [PATCH] EMC - Configurable disable give dropping + +Modified version of a patch by Aikar from EMC. Adds a config option in +purpur.yml to disable the /give command from dropping items on the +floor when a player's inventory is full. + +diff --git a/src/main/java/net/minecraft/server/commands/GiveCommand.java b/src/main/java/net/minecraft/server/commands/GiveCommand.java +index a0dc380e90415de9068ea408d62a1605c82631df..60fd566f7e1499ecf2ad91216a667f12cb0e05de 100644 +--- a/src/main/java/net/minecraft/server/commands/GiveCommand.java ++++ b/src/main/java/net/minecraft/server/commands/GiveCommand.java +@@ -45,6 +45,7 @@ public class GiveCommand { + k -= l; + ItemStack itemStack = item.createItemStack(l, false); + boolean bl = serverPlayer.getInventory().add(itemStack); ++ if (net.pl3x.purpur.PurpurConfig.disableGiveCommandDrops) continue; // Purpur - add config option for toggling give command dropping + if (bl && itemStack.isEmpty()) { + itemStack.setCount(1); + ItemEntity itemEntity2 = serverPlayer.drop(itemStack, false, false, true); // Paper - Fix duplicating /give items on item drop cancel +diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java +index 7c13409ab49326915830fe860d4f3457e9625c2f..45dd23971204a7a04aca9c271643cada98add9fb 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java +@@ -179,6 +179,11 @@ public class PurpurConfig { + useAlternateKeepAlive = getBoolean("settings.use-alternate-keepalive", useAlternateKeepAlive); + } + ++ public static boolean disableGiveCommandDrops = false; ++ private static void disableGiveCommandDrops() { ++ disableGiveCommandDrops = getBoolean("settings.disable-give-dropping", disableGiveCommandDrops); ++ } ++ + public static boolean barrelSixRows = false; + public static boolean enderChestSixRows = false; + public static boolean enderChestPermissionRows = false; diff --git a/patches/server/0135-Lobotomize-stuck-villagers.patch b/patches/server/0135-Lobotomize-stuck-villagers.patch new file mode 100644 index 000000000..dfc20a51c --- /dev/null +++ b/patches/server/0135-Lobotomize-stuck-villagers.patch @@ -0,0 +1,81 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Thu, 3 Dec 2020 17:56:18 -0600 +Subject: [PATCH] Lobotomize stuck villagers + + +diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java +index 1e05cc98a332e5b115c4670e5331e679117c6629..84142a42111ff03827297c522b7ce164b9a28276 100644 +--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java ++++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java +@@ -142,6 +142,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + return villageplacetype == PoiType.MEETING; + }); + private final int brainTickOffset; // Purpur ++ boolean lobotomized = false; // Purpur + + public Villager(EntityType entityType, Level world) { + this(entityType, world, VillagerType.PLAINS); +@@ -183,6 +184,22 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + public boolean canBeLeashed(Player player) { + return level.purpurConfig.villagerCanBeLeashed && !this.isLeashed(); + } ++ ++ private boolean isLobotomized() { ++ if ((level.getGameTime() + brainTickOffset) % level.purpurConfig.villagerLobotomizeCheck == 0) { ++ this.lobotomized = !canTravelFrom(blockPosition().above()); ++ } ++ return this.lobotomized; ++ } ++ ++ private boolean canTravelFrom(BlockPos pos) { ++ return canTravelTo(pos.east()) || canTravelTo(pos.west()) || canTravelTo(pos.north()) || canTravelTo(pos.south()); ++ } ++ ++ private boolean canTravelTo(BlockPos pos) { ++ net.minecraft.world.level.pathfinder.Path to = navigation.createPath(pos, 0); ++ return to != null && to.nodes.size() > 1; ++ } + // Purpur end + + @Override +@@ -280,10 +297,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + protected void mobTick(boolean inactive) { + this.level.getProfiler().push("villagerBrain"); + // Purpur start ++ if (level.purpurConfig.villagerLobotomizeEnabled) inactive = inactive || isLobotomized(); + boolean tick = (level.getGameTime() + brainTickOffset) % level.purpurConfig.villagerBrainTicks == 0; + if (((ServerLevel) level).getServer().lagging ? tick : level.purpurConfig.villagerUseBrainTicksOnlyWhenLagging || tick) + // Purpur end + if (!inactive) this.getBrain().tick((ServerLevel) this.level, this); // CraftBukkit - decompile error // Paper ++ else if (shouldRestock()) restock(); // Purpur + this.level.getProfiler().pop(); + if (this.assignProfessionWhenSpawned) { + this.assignProfessionWhenSpawned = false; +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index eb4af292087a27b30a8f2898d1847a6cb6025442..071407bd7569eec3a1f8de0158d4099f8551ce6c 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -1615,6 +1615,8 @@ public class PurpurWorldConfig { + public int villagerSpawnIronGolemLimit = 0; + public boolean villagerCanBreed = true; + public int villagerBreedingTicks = 6000; ++ public boolean villagerLobotomizeEnabled = false; ++ public int villagerLobotomizeCheck = 60; + private void villagerSettings() { + villagerRidable = getBoolean("mobs.villager.ridable", villagerRidable); + villagerRidableInWater = getBoolean("mobs.villager.ridable-in-water", villagerRidableInWater); +@@ -1633,6 +1635,13 @@ public class PurpurWorldConfig { + villagerSpawnIronGolemLimit = getInt("mobs.villager.spawn-iron-golem.limit", villagerSpawnIronGolemLimit); + villagerCanBreed = getBoolean("mobs.villager.can-breed", villagerCanBreed); + villagerBreedingTicks = getInt("mobs.villager.breeding-delay-ticks", villagerBreedingTicks); ++ if (PurpurConfig.version < 9) { ++ boolean oldValue = getBoolean("mobs.villager.lobotomize-1x1", villagerLobotomizeEnabled); ++ set("mobs.villager.lobotomize.enabled", oldValue); ++ set("mobs.villager.lobotomize-1x1", null); ++ } ++ villagerLobotomizeEnabled = getBoolean("mobs.villager.lobotomize.enabled", villagerLobotomizeEnabled); ++ villagerLobotomizeCheck = getInt("mobs.villager.lobotomize.check-interval", villagerLobotomizeCheck); + } + + public boolean vindicatorRidable = false; diff --git a/patches/server/0136-Option-for-Villager-Clerics-to-farm-Nether-Wart.patch b/patches/server/0136-Option-for-Villager-Clerics-to-farm-Nether-Wart.patch new file mode 100644 index 000000000..3907ad8ad --- /dev/null +++ b/patches/server/0136-Option-for-Villager-Clerics-to-farm-Nether-Wart.patch @@ -0,0 +1,208 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> +Date: Sat, 5 Dec 2020 01:20:16 -0800 +Subject: [PATCH] Option for Villager Clerics to farm Nether Wart + +Adds an option so that Villagers with the Cleric profession are able to +farm Nether Wart. Reimplemented based on a feature of the carpet-extra +mod. + +diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java b/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java +index 2d83b7252814a3a921db32a62f6bfb711d5b5ac1..cac70a59d86cff9fe5123172c73d62ca5cda35f3 100644 +--- a/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java ++++ b/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java +@@ -34,6 +34,7 @@ public class HarvestFarmland extends Behavior { + private long nextOkStartTime; + private int timeWorkedSoFar; + private final List validFarmlandAroundVillager = Lists.newArrayList(); ++ private boolean clericWartFarmer = false; // Purpur + + public HarvestFarmland() { + super(ImmutableMap.of(MemoryModuleType.LOOK_TARGET, MemoryStatus.VALUE_ABSENT, MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT, MemoryModuleType.SECONDARY_JOB_SITE, MemoryStatus.VALUE_PRESENT)); +@@ -42,9 +43,10 @@ public class HarvestFarmland extends Behavior { + protected boolean checkExtraStartConditions(ServerLevel world, Villager entity) { + if (!world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && !world.purpurConfig.villagerFarmingBypassMobGriefing) { // Purpur + return false; +- } else if (entity.getVillagerData().getProfession() != VillagerProfession.FARMER) { ++ } else if (entity.getVillagerData().getProfession() != VillagerProfession.FARMER && !(world.purpurConfig.villagerClericsFarmWarts && entity.getVillagerData().getProfession() == VillagerProfession.CLERIC)) { // Purpur + return false; + } else { ++ if (!this.clericWartFarmer && entity.getVillagerData().getProfession() == VillagerProfession.CLERIC) this.clericWartFarmer = true; // Purpur + BlockPos.MutableBlockPos blockposition_mutableblockposition = entity.blockPosition().mutable(); + + this.validFarmlandAroundVillager.clear(); +@@ -75,6 +77,7 @@ public class HarvestFarmland extends Behavior { + Block block = iblockdata.getBlock(); + Block block1 = world.getBlockState(pos.below()).getBlock(); + ++ if (this.clericWartFarmer) return block == Blocks.NETHER_WART && iblockdata.getValue(net.minecraft.world.level.block.NetherWartBlock.AGE) == 3 || iblockdata.isAir() && block1 == Blocks.SOUL_SAND; // Purpur + return block instanceof CropBlock && ((CropBlock) block).isMaxAge(iblockdata) || iblockdata.isAir() && block1 instanceof FarmBlock; + } + +@@ -100,7 +103,7 @@ public class HarvestFarmland extends Behavior { + Block block = iblockdata.getBlock(); + Block block1 = worldserver.getBlockState(this.aboveFarmlandPos.below()).getBlock(); + +- if (block instanceof CropBlock && ((CropBlock) block).isMaxAge(iblockdata)) { ++ if (block instanceof CropBlock && ((CropBlock) block).isMaxAge(iblockdata) && !this.clericWartFarmer || this.clericWartFarmer && block == Blocks.NETHER_WART && iblockdata.getValue(net.minecraft.world.level.block.NetherWartBlock.AGE) == 3) { // Purpur + // CraftBukkit start + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entityvillager, this.aboveFarmlandPos, Blocks.AIR.defaultBlockState()).isCancelled()) { + worldserver.destroyBlock(this.aboveFarmlandPos, true, entityvillager); +@@ -108,7 +111,7 @@ public class HarvestFarmland extends Behavior { + // CraftBukkit end + } + +- if (iblockdata.isAir() && block1 instanceof FarmBlock && entityvillager.hasFarmSeeds()) { ++ if (iblockdata.isAir() && (block1 instanceof FarmBlock && !this.clericWartFarmer || this.clericWartFarmer && block1 == Blocks.SOUL_SAND) && entityvillager.hasFarmSeeds()) { // Purpur + SimpleContainer inventorysubcontainer = entityvillager.getInventory(); + + for (int j = 0; j < inventorysubcontainer.getContainerSize(); ++j) { +@@ -118,6 +121,14 @@ public class HarvestFarmland extends Behavior { + if (!itemstack.isEmpty()) { + // CraftBukkit start + Block planted = null; ++ // Purpur start ++ if (this.clericWartFarmer) { ++ if (itemstack.getItem() == Items.NETHER_WART) { ++ planted = Blocks.NETHER_WART; ++ flag = true; ++ } ++ } else ++ // Purpur end + if (itemstack.is(Items.WHEAT_SEEDS)) { + planted = Blocks.WHEAT; + flag = true; +@@ -141,7 +152,7 @@ public class HarvestFarmland extends Behavior { + } + + if (flag) { +- worldserver.playSound((Player) null, (double) this.aboveFarmlandPos.getX(), (double) this.aboveFarmlandPos.getY(), (double) this.aboveFarmlandPos.getZ(), SoundEvents.CROP_PLANTED, SoundSource.BLOCKS, 1.0F, 1.0F); ++ worldserver.playSound((Player) null, (double) this.aboveFarmlandPos.getX(), (double) this.aboveFarmlandPos.getY(), (double) this.aboveFarmlandPos.getZ(), this.clericWartFarmer ? SoundEvents.NETHER_WART_PLANTED : SoundEvents.CROP_PLANTED, SoundSource.BLOCKS, 1.0F, 1.0F); // Purpur + itemstack.shrink(1); + if (itemstack.isEmpty()) { + inventorysubcontainer.setItem(j, ItemStack.EMPTY); +diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java b/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java +index 1150a541a270a3ce5c69895f5385800aa44c22f4..808da0b75fcf492a76c692e312aa33ef6fc90c03 100644 +--- a/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java ++++ b/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java +@@ -56,6 +56,12 @@ public class TradeWithVillager extends Behavior { + throwHalfStack(villager, ImmutableSet.of(Items.WHEAT), villager2); + } + ++ // Purpur start ++ if (serverLevel.purpurConfig.villagerClericsFarmWarts && serverLevel.purpurConfig.villagerClericFarmersThrowWarts && villager.getVillagerData().getProfession() == VillagerProfession.CLERIC && villager.getInventory().countItem(Items.NETHER_WART) > Items.NETHER_WART.getMaxStackSize() / 2) { ++ throwHalfStack(villager, ImmutableSet.of(Items.NETHER_WART), villager2); ++ } ++ // Purpur end ++ + if (!this.trades.isEmpty() && villager.getInventory().hasAnyOf(this.trades)) { + throwHalfStack(villager, this.trades, villager2); + } +diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java b/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java +index 9d6bcbdb79a968f93319e7792c83245383ed0cea..480ca2615ae8bc17b6889a2df2282f81a54c242e 100644 +--- a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java ++++ b/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java +@@ -23,8 +23,13 @@ public class VillagerGoalPackages { + } + + public static ImmutableList>> getWorkPackage(VillagerProfession profession, float speed) { ++ // Purpur start ++ return getWorkPackage(profession, speed, false); ++ } ++ public static ImmutableList>> getWorkPackage(VillagerProfession profession, float speed, boolean clericsFarmWarts) { ++ // Purpur end + WorkAtPoi workAtPoi; +- if (profession == VillagerProfession.FARMER) { ++ if (profession == VillagerProfession.FARMER || (clericsFarmWarts && profession == VillagerProfession.CLERIC)) { // Purpur + workAtPoi = new WorkAtComposter(); + } else { + workAtPoi = new WorkAtPoi(); +diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java +index b615dc2a2127f0874775d1707e96edfb4d95b987..72ae6b3282aac806ae11b87024ee940eec8fbe91 100644 +--- a/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java ++++ b/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java +@@ -22,6 +22,13 @@ public class SecondaryPoiSensor extends Sensor { + + @Override + protected void doTick(ServerLevel world, Villager entity) { ++ // Purpur start - make sure clerics don't wander to soul sand when the option is off ++ Brain brain = entity.getBrain(); ++ if (!world.purpurConfig.villagerClericsFarmWarts && entity.getVillagerData().getProfession() == net.minecraft.world.entity.npc.VillagerProfession.CLERIC) { ++ brain.eraseMemory(MemoryModuleType.SECONDARY_JOB_SITE); ++ return; ++ } ++ // Purpur end + ResourceKey resourceKey = world.dimension(); + BlockPos blockPos = entity.blockPosition(); + List list = Lists.newArrayList(); +@@ -38,7 +45,7 @@ public class SecondaryPoiSensor extends Sensor { + } + } + +- Brain brain = entity.getBrain(); ++ //Brain brain = entity.getBrain(); // Purpur - moved up + if (!list.isEmpty()) { + brain.setMemory(MemoryModuleType.SECONDARY_JOB_SITE, list); + } else { +diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java +index 84142a42111ff03827297c522b7ce164b9a28276..3b404c12ba12d75caaeb2161eb18abaf3c14ae57 100644 +--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java ++++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java +@@ -236,7 +236,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + brain.addActivity(Activity.PLAY, VillagerGoalPackages.getPlayPackage(0.5F)); + } else { + brain.setSchedule(Schedule.VILLAGER_DEFAULT); +- brain.addActivityWithConditions(Activity.WORK, VillagerGoalPackages.getWorkPackage(villagerprofession, 0.5F), ImmutableSet.of(Pair.of(MemoryModuleType.JOB_SITE, MemoryStatus.VALUE_PRESENT))); ++ brain.addActivityWithConditions(Activity.WORK, VillagerGoalPackages.getWorkPackage(villagerprofession, 0.5F, this.level.purpurConfig.villagerClericsFarmWarts), ImmutableSet.of(Pair.of(MemoryModuleType.JOB_SITE, MemoryStatus.VALUE_PRESENT))); // Purpur + } + + brain.addActivity(Activity.CORE, VillagerGoalPackages.getCorePackage(villagerprofession, 0.5F)); +@@ -989,7 +989,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + } + + public boolean hasFarmSeeds() { +- return this.getInventory().hasAnyOf((Set) ImmutableSet.of(Items.WHEAT_SEEDS, Items.POTATO, Items.CARROT, Items.BEETROOT_SEEDS)); ++ // Purpur start ++ if (this.level.purpurConfig.villagerClericsFarmWarts && this.getVillagerData().getProfession() == VillagerProfession.CLERIC) { ++ return this.getInventory().hasAnyOf(ImmutableSet.of(Items.NETHER_WART)); ++ } ++ return this.getInventory().hasAnyOf(ImmutableSet.of(Items.WHEAT_SEEDS, Items.POTATO, Items.CARROT, Items.BEETROOT_SEEDS)); ++ // Purpur end + } + + @Override +diff --git a/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java b/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java +index 901fc6520d58a5fa5f2cf1b4fa78fec6008aa409..9050cd25663c71197c597aac0ab2e6121b76b13b 100644 +--- a/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java ++++ b/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java +@@ -17,7 +17,7 @@ public class VillagerProfession { + public static final VillagerProfession ARMORER = register("armorer", PoiType.ARMORER, SoundEvents.VILLAGER_WORK_ARMORER); + public static final VillagerProfession BUTCHER = register("butcher", PoiType.BUTCHER, SoundEvents.VILLAGER_WORK_BUTCHER); + public static final VillagerProfession CARTOGRAPHER = register("cartographer", PoiType.CARTOGRAPHER, SoundEvents.VILLAGER_WORK_CARTOGRAPHER); +- public static final VillagerProfession CLERIC = register("cleric", PoiType.CLERIC, SoundEvents.VILLAGER_WORK_CLERIC); ++ public static final VillagerProfession CLERIC = register("cleric", PoiType.CLERIC, ImmutableSet.of(Items.NETHER_WART), ImmutableSet.of(Blocks.SOUL_SAND), SoundEvents.VILLAGER_WORK_CLERIC); // Purpur + public static final VillagerProfession FARMER = register("farmer", PoiType.FARMER, ImmutableSet.of(Items.WHEAT, Items.WHEAT_SEEDS, Items.BEETROOT_SEEDS, Items.BONE_MEAL), ImmutableSet.of(Blocks.FARMLAND), SoundEvents.VILLAGER_WORK_FARMER); + public static final VillagerProfession FISHERMAN = register("fisherman", PoiType.FISHERMAN, SoundEvents.VILLAGER_WORK_FISHERMAN); + public static final VillagerProfession FLETCHER = register("fletcher", PoiType.FLETCHER, SoundEvents.VILLAGER_WORK_FLETCHER); +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index 071407bd7569eec3a1f8de0158d4099f8551ce6c..71209e046ecfc5b2578eb8fede37938d9d6677b7 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -1617,6 +1617,8 @@ public class PurpurWorldConfig { + public int villagerBreedingTicks = 6000; + public boolean villagerLobotomizeEnabled = false; + public int villagerLobotomizeCheck = 60; ++ public boolean villagerClericsFarmWarts = false; ++ public boolean villagerClericFarmersThrowWarts = true; + private void villagerSettings() { + villagerRidable = getBoolean("mobs.villager.ridable", villagerRidable); + villagerRidableInWater = getBoolean("mobs.villager.ridable-in-water", villagerRidableInWater); +@@ -1642,6 +1644,8 @@ public class PurpurWorldConfig { + } + villagerLobotomizeEnabled = getBoolean("mobs.villager.lobotomize.enabled", villagerLobotomizeEnabled); + villagerLobotomizeCheck = getInt("mobs.villager.lobotomize.check-interval", villagerLobotomizeCheck); ++ villagerClericsFarmWarts = getBoolean("mobs.villager.clerics-farm-warts", villagerClericsFarmWarts); ++ villagerClericFarmersThrowWarts = getBoolean("mobs.villager.cleric-wart-farmers-throw-warts-at-villagers", villagerClericFarmersThrowWarts); + } + + public boolean vindicatorRidable = false; diff --git a/patches/server-unmapped/0143-Toggle-for-Zombified-Piglin-death-always-counting-as.patch b/patches/server/0137-Toggle-for-Zombified-Piglin-death-always-counting-as.patch similarity index 62% rename from patches/server-unmapped/0143-Toggle-for-Zombified-Piglin-death-always-counting-as.patch rename to patches/server/0137-Toggle-for-Zombified-Piglin-death-always-counting-as.patch index fb011b36d..fa7c28df4 100644 --- a/patches/server-unmapped/0143-Toggle-for-Zombified-Piglin-death-always-counting-as.patch +++ b/patches/server/0137-Toggle-for-Zombified-Piglin-death-always-counting-as.patch @@ -12,33 +12,33 @@ to the Piglin being angry, even though the player never hit them. This patch adds a toggle to disable this behavior. -diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityPigZombie.java b/src/main/java/net/minecraft/world/entity/monster/EntityPigZombie.java -index 9f50054211db48e7fe764434e8d71aab0995e57a..82279ab2f3c1edec14c24c3a7ad24d097d52dea2 100644 ---- a/src/main/java/net/minecraft/world/entity/monster/EntityPigZombie.java -+++ b/src/main/java/net/minecraft/world/entity/monster/EntityPigZombie.java -@@ -130,7 +130,7 @@ public class EntityPigZombie extends EntityZombie implements IEntityAngerable { - this.eY(); +diff --git a/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java b/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java +index 43ef93d2c0c59e0d7021ee9aa2b44345192cc0a9..ce780a2ba7dcbd9c1c9dc24c0738786190545382 100644 +--- a/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java ++++ b/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java +@@ -137,7 +137,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { + this.maybeAlertOthers(); } - if (this.isAngry()) { -+ if (this.isAngry() && this.world.purpurConfig.zombifiedPiglinCountAsPlayerKillWhenAngry) { // Purpur - this.lastDamageByPlayerTime = this.ticksLived; ++ if (this.isAngry() && this.level.purpurConfig.zombifiedPiglinCountAsPlayerKillWhenAngry) { // Purpur + this.lastHurtByPlayerTime = this.tickCount; } -@@ -185,7 +185,7 @@ public class EntityPigZombie extends EntityZombie implements IEntityAngerable { - this.bt = EntityPigZombie.bs.a(this.random); +@@ -192,7 +192,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { + this.ticksUntilNextAlert = ZombifiedPiglin.ALERT_INTERVAL.sample(this.random); } -- if (entityliving instanceof EntityHuman) { -+ if (entityliving instanceof EntityHuman && this.world.purpurConfig.zombifiedPiglinCountAsPlayerKillWhenAngry) { // Purpur - this.e((EntityHuman) entityliving); +- if (entityliving instanceof Player) { ++ if (entityliving instanceof Player && this.level.purpurConfig.zombifiedPiglinCountAsPlayerKillWhenAngry) { // Purpur + this.setLastHurtByPlayer((Player) entityliving); } diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index efe82464beb6741413b73bbd6adc5c45eba7bcd6..7d32788c5e538be6eff9b6ff4655f279ac1e0e6b 100644 +index 71209e046ecfc5b2578eb8fede37938d9d6677b7..9a48046093f3de6f68c5e33adbbe5ea3090315ec 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -1268,12 +1268,14 @@ public class PurpurWorldConfig { +@@ -1852,6 +1852,7 @@ public class PurpurWorldConfig { public boolean zombifiedPiglinJockeyOnlyBaby = true; public double zombifiedPiglinJockeyChance = 0.05D; public boolean zombifiedPiglinJockeyTryExistingChickens = true; @@ -46,10 +46,10 @@ index efe82464beb6741413b73bbd6adc5c45eba7bcd6..7d32788c5e538be6eff9b6ff4655f279 private void zombifiedPiglinSettings() { zombifiedPiglinRidable = getBoolean("mobs.zombified_piglin.ridable", zombifiedPiglinRidable); zombifiedPiglinRidableInWater = getBoolean("mobs.zombified_piglin.ridable-in-water", zombifiedPiglinRidableInWater); +@@ -1865,5 +1866,6 @@ public class PurpurWorldConfig { zombifiedPiglinJockeyOnlyBaby = getBoolean("mobs.zombified_piglin.jockey.only-babies", zombifiedPiglinJockeyOnlyBaby); zombifiedPiglinJockeyChance = getDouble("mobs.zombified_piglin.jockey.chance", zombifiedPiglinJockeyChance); zombifiedPiglinJockeyTryExistingChickens = getBoolean("mobs.zombified_piglin.jockey.try-existing-chickens", zombifiedPiglinJockeyTryExistingChickens); + zombifiedPiglinCountAsPlayerKillWhenAngry = getBoolean("mobs.zombified_piglin.count-as-player-kill-when-angry", zombifiedPiglinCountAsPlayerKillWhenAngry); } - - public boolean zombieVillagerRidable = false; + } diff --git a/settings.gradle.kts b/settings.gradle.kts index a3c6ca1c7..babdf4736 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ pluginManagement { repositories { gradlePluginPortal() - maven("https://repo.pl3x.net/snapshots/") + maven("https://papermc.io/repo/repository/maven-public/") } }