diff --git a/patches/server-unmapped/0057-Add-option-to-allow-loyalty-on-tridents-to-work-in-t.patch b/patches/server-unmapped/0057-Add-option-to-allow-loyalty-on-tridents-to-work-in-t.patch deleted file mode 100644 index edd87500f..000000000 --- a/patches/server-unmapped/0057-Add-option-to-allow-loyalty-on-tridents-to-work-in-t.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Thu, 19 Mar 2020 19:39:34 -0500 -Subject: [PATCH] Add option to allow loyalty on tridents to work in the void - - -diff --git a/src/main/java/net/minecraft/world/entity/projectile/EntityThrownTrident.java b/src/main/java/net/minecraft/world/entity/projectile/EntityThrownTrident.java -index 646043987e1102ae8e9becc9820e6c6d86ef844d..7aadfe6598f0d3d41b94cfc003fcc9d075ee6ae5 100644 ---- a/src/main/java/net/minecraft/world/entity/projectile/EntityThrownTrident.java -+++ b/src/main/java/net/minecraft/world/entity/projectile/EntityThrownTrident.java -@@ -60,7 +60,7 @@ public class EntityThrownTrident extends EntityArrow { - - Entity entity = this.getShooter(); - -- if ((this.ai || this.t()) && entity != null) { -+ if ((this.ai || this.t() || (world.purpurConfig.tridentLoyaltyVoidReturnHeight < 0.0D && locY() < world.purpurConfig.tridentLoyaltyVoidReturnHeight)) && entity != null) { // Purpur - byte b0 = (Byte) this.datawatcher.get(EntityThrownTrident.g); - - if (b0 > 0 && !this.z()) { -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 6b65a81bc54cc7c795885cc860346d4a0ed64125..0a6255422a5d22e84cc1048caf7ca964a168b7fe 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -148,9 +148,11 @@ public class PurpurWorldConfig { - - public boolean disableDropsOnCrammingDeath = false; - public boolean milkCuresBadOmen = true; -+ public double tridentLoyaltyVoidReturnHeight = 0.0D; - private void miscGameplayMechanicsSettings() { - disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath); - milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen); -+ tridentLoyaltyVoidReturnHeight = getDouble("gameplay-mechanics.trident-loyalty-void-return-height", tridentLoyaltyVoidReturnHeight); - } - - public int playerSpawnInvulnerableTicks = 60; diff --git a/patches/server-unmapped/0058-Add-enderman-and-creeper-griefing-controls.patch b/patches/server-unmapped/0058-Add-enderman-and-creeper-griefing-controls.patch deleted file mode 100644 index 6db4dfdf2..000000000 --- a/patches/server-unmapped/0058-Add-enderman-and-creeper-griefing-controls.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sun, 26 Apr 2020 16:28:38 -0500 -Subject: [PATCH] Add enderman and creeper griefing controls - - -diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityCreeper.java b/src/main/java/net/minecraft/world/entity/monster/EntityCreeper.java -index 63a6b1820f60db9eea49a3a589dd50ad25a3c0a2..09df2bd3b523072de0e9858e6e707e3721474422 100644 ---- a/src/main/java/net/minecraft/world/entity/monster/EntityCreeper.java -+++ b/src/main/java/net/minecraft/world/entity/monster/EntityCreeper.java -@@ -255,7 +255,7 @@ public class EntityCreeper extends EntityMonster { - - public void explode() { - if (!this.world.isClientSide) { -- Explosion.Effect explosion_effect = this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) ? Explosion.Effect.DESTROY : Explosion.Effect.NONE; -+ Explosion.Effect explosion_effect = this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) && world.purpurConfig.creeperAllowGriefing ? Explosion.Effect.DESTROY : Explosion.Effect.NONE; // Purpur - float f = this.isPowered() ? 2.0F : 1.0F; - - // CraftBukkit start -diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityEnderman.java b/src/main/java/net/minecraft/world/entity/monster/EntityEnderman.java -index e993b1849beb60515c51ee4f37617faab63ca223..6a5593ff735a9e0486d7ed9b3afb4f44ad156b34 100644 ---- a/src/main/java/net/minecraft/world/entity/monster/EntityEnderman.java -+++ b/src/main/java/net/minecraft/world/entity/monster/EntityEnderman.java -@@ -423,6 +423,7 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable { - - @Override - public boolean a() { -+ if (!enderman.world.purpurConfig.endermanAllowGriefing) return false; // Purpur - return this.enderman.getCarried() != null ? false : (!this.enderman.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) ? false : this.enderman.getRandom().nextInt(20) == 0); - } - -@@ -456,7 +457,7 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable { - - static class PathfinderGoalEndermanPlaceBlock extends PathfinderGoal { - -- private final EntityEnderman a; -+ private final EntityEnderman a; public EntityEnderman getEnderman() { return a; } // Purpur - OBFHELPER - - public PathfinderGoalEndermanPlaceBlock(EntityEnderman entityenderman) { - this.a = entityenderman; -@@ -464,6 +465,7 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable { - - @Override - public boolean a() { -+ if (!getEnderman().world.purpurConfig.endermanAllowGriefing) return false; // Purpur - return this.a.getCarried() == null ? false : (!this.a.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) ? false : this.a.getRandom().nextInt(2000) == 0); - } - -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 0a6255422a5d22e84cc1048caf7ca964a168b7fe..8033348257c0fcc6f3c1c376b6fb343c414618c5 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -225,8 +225,10 @@ public class PurpurWorldConfig { - cowFeedMushrooms = getInt("mobs.cow.feed-mushrooms-for-mooshroom", cowFeedMushrooms); - } - -+ public boolean creeperAllowGriefing = true; - public double creeperChargedChance = 0.0D; - private void creeperSettings() { -+ creeperAllowGriefing = getBoolean("mobs.creeper.allow-griefing", creeperAllowGriefing); - creeperChargedChance = getDouble("mobs.creeper.naturally-charged-chance", creeperChargedChance); - } - -@@ -235,6 +237,11 @@ public class PurpurWorldConfig { - enderDragonAlwaysDropsFullExp = getBoolean("mobs.ender_dragon.always-drop-full-exp", enderDragonAlwaysDropsFullExp); - } - -+ public boolean endermanAllowGriefing = true; -+ private void endermanSettings() { -+ endermanAllowGriefing = getBoolean("mobs.enderman.allow-griefing", endermanAllowGriefing); -+ } -+ - public boolean foxTypeChangesWithTulips = false; - private void foxSettings() { - foxTypeChangesWithTulips = getBoolean("mobs.fox.tulips-change-type", foxTypeChangesWithTulips); diff --git a/patches/server-unmapped/0061-Villagers-follow-emerald-blocks.patch b/patches/server-unmapped/0061-Villagers-follow-emerald-blocks.patch deleted file mode 100644 index 4cb54ce84..000000000 --- a/patches/server-unmapped/0061-Villagers-follow-emerald-blocks.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Fri, 29 Nov 2019 22:10:12 -0600 -Subject: [PATCH] Villagers follow emerald blocks - - -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 c45e6ae3f912ac582c6ba693517e05cd8fbf33e2..284401de0e8f4e4cf6df64a8f2b619c10e937130 100644 ---- a/src/main/java/net/minecraft/world/entity/npc/EntityVillager.java -+++ b/src/main/java/net/minecraft/world/entity/npc/EntityVillager.java -@@ -59,6 +59,7 @@ import net.minecraft.world.entity.ai.BehaviorController; - import net.minecraft.world.entity.ai.attributes.AttributeProvider; - import net.minecraft.world.entity.ai.attributes.GenericAttributes; - import net.minecraft.world.entity.ai.behavior.Behaviors; -+import net.minecraft.world.entity.ai.goal.PathfinderGoalTempt; - import net.minecraft.world.entity.ai.gossip.Reputation; - import net.minecraft.world.entity.ai.gossip.ReputationType; - import net.minecraft.world.entity.ai.memory.MemoryModuleType; -@@ -143,6 +144,13 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation - this.brainTickOffset = getRandom().nextInt(100); // Purpur - } - -+ // Purpur start -+ @Override -+ protected void initPathfinder() { -+ if (world.purpurConfig.villagerFollowEmeraldBlock) this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.0D, false, TEMPT_ITEMS)); -+ } -+ // Purpur end -+ - @Override - public BehaviorController getBehaviorController() { - return (BehaviorController) super.getBehaviorController(); // CraftBukkit - decompile error -diff --git a/src/main/java/net/minecraft/world/entity/npc/EntityVillagerAbstract.java b/src/main/java/net/minecraft/world/entity/npc/EntityVillagerAbstract.java -index 49821f0f26864c35be84a4a4288857a04668fbba..91142526187f96615b5cbd3ed3b68d9175cb9f8b 100644 ---- a/src/main/java/net/minecraft/world/entity/npc/EntityVillagerAbstract.java -+++ b/src/main/java/net/minecraft/world/entity/npc/EntityVillagerAbstract.java -@@ -25,11 +25,13 @@ import net.minecraft.world.entity.EnumMobSpawn; - import net.minecraft.world.entity.GroupDataEntity; - import net.minecraft.world.entity.player.EntityHuman; - import net.minecraft.world.item.ItemStack; -+import net.minecraft.world.item.crafting.RecipeItemStack; - import net.minecraft.world.item.trading.IMerchant; - import net.minecraft.world.item.trading.MerchantRecipe; - import net.minecraft.world.item.trading.MerchantRecipeList; - import net.minecraft.world.level.World; - import net.minecraft.world.level.WorldAccess; -+import net.minecraft.world.level.block.Blocks; - import net.minecraft.world.level.pathfinder.PathType; - - // CraftBukkit start -@@ -45,6 +47,8 @@ import io.papermc.paper.event.player.PlayerTradeEvent; - - public abstract class EntityVillagerAbstract extends EntityAgeable implements NPC, IMerchant { - -+ static final RecipeItemStack TEMPT_ITEMS = RecipeItemStack.a(Blocks.EMERALD_BLOCK.getItem()); // Purpur -+ - // CraftBukkit start - private CraftMerchant craftMerchant; - -diff --git a/src/main/java/net/minecraft/world/entity/npc/EntityVillagerTrader.java b/src/main/java/net/minecraft/world/entity/npc/EntityVillagerTrader.java -index 69044827ed6b34924ffd89a977afa06df0dcefc3..6fab69bf5800ef8a37f29c3b6b2103051f36fedf 100644 ---- a/src/main/java/net/minecraft/world/entity/npc/EntityVillagerTrader.java -+++ b/src/main/java/net/minecraft/world/entity/npc/EntityVillagerTrader.java -@@ -26,6 +26,7 @@ import net.minecraft.world.entity.ai.goal.PathfinderGoalLookAtTradingPlayer; - import net.minecraft.world.entity.ai.goal.PathfinderGoalMoveTowardsRestriction; - import net.minecraft.world.entity.ai.goal.PathfinderGoalPanic; - import net.minecraft.world.entity.ai.goal.PathfinderGoalRandomStrollLand; -+import net.minecraft.world.entity.ai.goal.PathfinderGoalTempt; - import net.minecraft.world.entity.ai.goal.PathfinderGoalTradeWithPlayer; - import net.minecraft.world.entity.ai.goal.PathfinderGoalUseItem; - import net.minecraft.world.entity.monster.EntityEvoker; -@@ -89,6 +90,7 @@ public class EntityVillagerTrader extends EntityVillagerAbstract { - this.goalSelector.a(1, new PathfinderGoalPanic(this, 0.5D)); - this.goalSelector.a(1, new PathfinderGoalLookAtTradingPlayer(this)); - this.goalSelector.a(2, new EntityVillagerTrader.a(this, 2.0D, 0.35D)); -+ if (world.purpurConfig.villagerTraderFollowEmeraldBlock) this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.0D, false, TEMPT_ITEMS)); // Purpur - this.goalSelector.a(4, new PathfinderGoalMoveTowardsRestriction(this, 0.35D)); - this.goalSelector.a(8, new PathfinderGoalRandomStrollLand(this, 0.35D)); - this.goalSelector.a(9, new PathfinderGoalInteract(this, EntityHuman.class, 3.0F, 1.0F)); -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index e82485ee1270ce83ccc93825d795743d4ead23a1..2eaef857f474c05ef1b4aac4870222d2464da949 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -320,10 +320,17 @@ public class PurpurWorldConfig { - public int villagerBrainTicks = 1; - public boolean villagerUseBrainTicksOnlyWhenLagging = true; - public boolean villagerFarmingBypassMobGriefing = false; -+ public boolean villagerFollowEmeraldBlock = false; - private void villagerSettings() { - villagerBrainTicks = getInt("mobs.villager.brain-ticks", villagerBrainTicks); - villagerUseBrainTicksOnlyWhenLagging = getBoolean("mobs.villager.use-brain-ticks-only-when-lagging", villagerUseBrainTicksOnlyWhenLagging); - villagerFarmingBypassMobGriefing = getBoolean("mobs.villager.bypass-mob-griefing", villagerFarmingBypassMobGriefing); -+ villagerFollowEmeraldBlock = getBoolean("mobs.villager.follow-emerald-blocks", villagerFollowEmeraldBlock); -+ } -+ -+ public boolean villagerTraderFollowEmeraldBlock = false; -+ private void villagerTraderSettings() { -+ villagerTraderFollowEmeraldBlock = getBoolean("mobs.wandering_trader.follow-emerald-blocks", villagerTraderFollowEmeraldBlock); - } - - public boolean witherSkeletonTakesWitherDamage = false; diff --git a/patches/server-unmapped/0062-Allow-leashing-villagers.patch b/patches/server-unmapped/0062-Allow-leashing-villagers.patch deleted file mode 100644 index 9a95a2044..000000000 --- a/patches/server-unmapped/0062-Allow-leashing-villagers.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Thu, 3 Oct 2019 18:08:03 -0500 -Subject: [PATCH] Allow leashing villagers - - -diff --git a/src/main/java/net/minecraft/world/entity/EntityInsentient.java b/src/main/java/net/minecraft/world/entity/EntityInsentient.java -index d2841e1528804841532bbfa885a2689669ad5429..f6e868a5cd62e0d997a2538c6b2bead0e3d88178 100644 ---- a/src/main/java/net/minecraft/world/entity/EntityInsentient.java -+++ b/src/main/java/net/minecraft/world/entity/EntityInsentient.java -@@ -49,6 +49,7 @@ import net.minecraft.world.entity.item.EntityItem; - import net.minecraft.world.entity.monster.EntityBlaze; - import net.minecraft.world.entity.monster.EntityEnderman; - import net.minecraft.world.entity.monster.IMonster; -+import net.minecraft.world.entity.npc.EntityVillagerAbstract; - import net.minecraft.world.entity.player.EntityHuman; - import net.minecraft.world.entity.vehicle.EntityBoat; - import net.minecraft.world.item.Item; -@@ -1212,6 +1213,7 @@ public abstract class EntityInsentient extends EntityLiving { - if (!this.isAlive()) { - return EnumInteractionResult.PASS; - } else if (this.getLeashHolder() == entityhuman) { -+ if (enumhand == EnumHand.OFF_HAND && (world.purpurConfig.villagerCanBeLeashed || world.purpurConfig.villagerTraderCanBeLeashed) && this instanceof EntityVillagerAbstract) return EnumInteractionResult.CONSUME; // Purpur - // CraftBukkit start - fire PlayerUnleashEntityEvent - // Paper start - drop leash variable - PlayerUnleashEntityEvent event = CraftEventFactory.callPlayerUnleashEntityEvent(this, entityhuman, !entityhuman.abilities.canInstantlyBuild); -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 284401de0e8f4e4cf6df64a8f2b619c10e937130..007e5c7ef9b5eaf5cbf262197f3d73d2a33741ea 100644 ---- a/src/main/java/net/minecraft/world/entity/npc/EntityVillager.java -+++ b/src/main/java/net/minecraft/world/entity/npc/EntityVillager.java -@@ -149,6 +149,11 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation - protected void initPathfinder() { - if (world.purpurConfig.villagerFollowEmeraldBlock) this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.0D, false, TEMPT_ITEMS)); - } -+ -+ @Override -+ public boolean a(EntityHuman entityhuman) { -+ return world.purpurConfig.villagerCanBeLeashed && !this.isLeashed(); -+ } - // Purpur end - - @Override -diff --git a/src/main/java/net/minecraft/world/entity/npc/EntityVillagerTrader.java b/src/main/java/net/minecraft/world/entity/npc/EntityVillagerTrader.java -index 6fab69bf5800ef8a37f29c3b6b2103051f36fedf..8df4d985e3124ddc1643da8385b15348937bc320 100644 ---- a/src/main/java/net/minecraft/world/entity/npc/EntityVillagerTrader.java -+++ b/src/main/java/net/minecraft/world/entity/npc/EntityVillagerTrader.java -@@ -97,6 +97,13 @@ public class EntityVillagerTrader extends EntityVillagerAbstract { - this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F)); - } - -+ // Purpur - start -+ @Override -+ public boolean a(EntityHuman entityhuman) { -+ return world.purpurConfig.villagerTraderCanBeLeashed && !this.isLeashed(); -+ } -+ // Purpur - end -+ - @Nullable - @Override - public EntityAgeable createChild(WorldServer worldserver, EntityAgeable entityageable) { -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 2eaef857f474c05ef1b4aac4870222d2464da949..9922ca6bd7d856eea182b8dd3c210e5f726ef180 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -319,17 +319,21 @@ public class PurpurWorldConfig { - - public int villagerBrainTicks = 1; - public boolean villagerUseBrainTicksOnlyWhenLagging = true; -+ public boolean villagerCanBeLeashed = false; - public boolean villagerFarmingBypassMobGriefing = false; - public boolean villagerFollowEmeraldBlock = false; - private void villagerSettings() { - villagerBrainTicks = getInt("mobs.villager.brain-ticks", villagerBrainTicks); - villagerUseBrainTicksOnlyWhenLagging = getBoolean("mobs.villager.use-brain-ticks-only-when-lagging", villagerUseBrainTicksOnlyWhenLagging); -+ villagerCanBeLeashed = getBoolean("mobs.villager.can-be-leashed", villagerCanBeLeashed); - villagerFarmingBypassMobGriefing = getBoolean("mobs.villager.bypass-mob-griefing", villagerFarmingBypassMobGriefing); - villagerFollowEmeraldBlock = getBoolean("mobs.villager.follow-emerald-blocks", villagerFollowEmeraldBlock); - } - -+ public boolean villagerTraderCanBeLeashed = false; - public boolean villagerTraderFollowEmeraldBlock = false; - private void villagerTraderSettings() { -+ villagerTraderCanBeLeashed = getBoolean("mobs.wandering_trader.can-be-leashed", villagerTraderCanBeLeashed); - villagerTraderFollowEmeraldBlock = getBoolean("mobs.wandering_trader.follow-emerald-blocks", villagerTraderFollowEmeraldBlock); - } - diff --git a/patches/server/0056-Add-option-to-allow-loyalty-on-tridents-to-work-in-t.patch b/patches/server/0056-Add-option-to-allow-loyalty-on-tridents-to-work-in-t.patch new file mode 100644 index 000000000..d22b54eb7 --- /dev/null +++ b/patches/server/0056-Add-option-to-allow-loyalty-on-tridents-to-work-in-t.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Thu, 19 Mar 2020 19:39:34 -0500 +Subject: [PATCH] Add option to allow loyalty on tridents to work in the void + + +diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java +index c95eef8596fe3e1ca83e620a6c54b164c797cbe1..1e6a5404d767318de29184b3e3a2bc41c1ee2602 100644 +--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java ++++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java +@@ -61,7 +61,7 @@ public class ThrownTrident extends AbstractArrow { + Entity entity = this.getOwner(); + byte b0 = (Byte) this.entityData.get(ThrownTrident.ID_LOYALTY); + +- if (b0 > 0 && (this.dealtDamage || this.isNoPhysics()) && entity != null) { ++ if (b0 > 0 && (this.dealtDamage || this.isNoPhysics() || (level.purpurConfig.tridentLoyaltyVoidReturnHeight < 0.0D && getY() < level.purpurConfig.tridentLoyaltyVoidReturnHeight)) && entity != null) { // Purpur + if (!this.isAcceptibleReturnOwner()) { + if (!this.level.isClientSide && this.pickup == AbstractArrow.Pickup.ALLOWED) { + this.spawnAtLocation(this.getPickupItem(), 0.1F); +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index b22f020c24969cf66445570efc1984acb63f03ce..33bb5a69169251c2424756a1cdcba13c74b3c752 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -148,9 +148,11 @@ public class PurpurWorldConfig { + + public boolean disableDropsOnCrammingDeath = false; + public boolean milkCuresBadOmen = true; ++ public double tridentLoyaltyVoidReturnHeight = 0.0D; + private void miscGameplayMechanicsSettings() { + disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath); + milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen); ++ tridentLoyaltyVoidReturnHeight = getDouble("gameplay-mechanics.trident-loyalty-void-return-height", tridentLoyaltyVoidReturnHeight); + } + + public int playerSpawnInvulnerableTicks = 60; diff --git a/patches/server/0057-Add-enderman-and-creeper-griefing-controls.patch b/patches/server/0057-Add-enderman-and-creeper-griefing-controls.patch new file mode 100644 index 000000000..b203e42ea --- /dev/null +++ b/patches/server/0057-Add-enderman-and-creeper-griefing-controls.patch @@ -0,0 +1,66 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Sun, 26 Apr 2020 16:28:38 -0500 +Subject: [PATCH] Add enderman and creeper griefing controls + + +diff --git a/src/main/java/net/minecraft/world/entity/monster/Creeper.java b/src/main/java/net/minecraft/world/entity/monster/Creeper.java +index 27d8279b71f55ae711b0455bb4c5f1527a0e1ccb..689efb1a80a93d573cb109905105434281eba7d3 100644 +--- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java ++++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java +@@ -270,7 +270,7 @@ public class Creeper extends Monster implements PowerableMob { + + public void explodeCreeper() { + if (!this.level.isClientSide) { +- Explosion.BlockInteraction explosion_effect = this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.NONE; ++ Explosion.BlockInteraction explosion_effect = this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && level.purpurConfig.creeperAllowGriefing ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.NONE; // Purpur + float f = this.isPowered() ? 2.0F : 1.0F; + + // CraftBukkit start +diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java +index a39f4a1585ba888d27588a86130f6dae24f5a71b..b9cc542db0b5b9f7710c2f747cb9a4edc1feb70a 100644 +--- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java ++++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java +@@ -454,6 +454,7 @@ public class EnderMan extends Monster implements NeutralMob { + + @Override + public boolean canUse() { ++ if (!enderman.level.purpurConfig.endermanAllowGriefing) return false; // Purpur + return this.enderman.getCarriedBlock() == null ? false : (!this.enderman.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) ? false : this.enderman.getRandom().nextInt(2000) == 0); + } + +@@ -501,6 +502,7 @@ public class EnderMan extends Monster implements NeutralMob { + + @Override + public boolean canUse() { ++ if (!enderman.level.purpurConfig.endermanAllowGriefing) return false; // Purpur + return this.enderman.getCarriedBlock() != null ? false : (!this.enderman.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) ? false : this.enderman.getRandom().nextInt(20) == 0); + } + +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index 33bb5a69169251c2424756a1cdcba13c74b3c752..8e4c9dab2fa52dbc99473762e10651b89275cd59 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -225,8 +225,10 @@ public class PurpurWorldConfig { + cowFeedMushrooms = getInt("mobs.cow.feed-mushrooms-for-mooshroom", cowFeedMushrooms); + } + ++ public boolean creeperAllowGriefing = true; + public double creeperChargedChance = 0.0D; + private void creeperSettings() { ++ creeperAllowGriefing = getBoolean("mobs.creeper.allow-griefing", creeperAllowGriefing); + creeperChargedChance = getDouble("mobs.creeper.naturally-charged-chance", creeperChargedChance); + } + +@@ -235,6 +237,11 @@ public class PurpurWorldConfig { + enderDragonAlwaysDropsFullExp = getBoolean("mobs.ender_dragon.always-drop-full-exp", enderDragonAlwaysDropsFullExp); + } + ++ public boolean endermanAllowGriefing = true; ++ private void endermanSettings() { ++ endermanAllowGriefing = getBoolean("mobs.enderman.allow-griefing", endermanAllowGriefing); ++ } ++ + public boolean foxTypeChangesWithTulips = false; + private void foxSettings() { + foxTypeChangesWithTulips = getBoolean("mobs.fox.tulips-change-type", foxTypeChangesWithTulips); diff --git a/patches/server-unmapped/0059-Entities-pick-up-loot-bypass-mob-griefing-gamerule.patch b/patches/server/0058-Entities-pick-up-loot-bypass-mob-griefing-gamerule.patch similarity index 52% rename from patches/server-unmapped/0059-Entities-pick-up-loot-bypass-mob-griefing-gamerule.patch rename to patches/server/0058-Entities-pick-up-loot-bypass-mob-griefing-gamerule.patch index 1cca3c660..a7fcfbb8d 100644 --- a/patches/server-unmapped/0059-Entities-pick-up-loot-bypass-mob-griefing-gamerule.patch +++ b/patches/server/0058-Entities-pick-up-loot-bypass-mob-griefing-gamerule.patch @@ -1,24 +1,24 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath +From: William Blake Galbreath Date: Fri, 24 Apr 2020 09:33:11 -0500 Subject: [PATCH] Entities pick up loot bypass mob-griefing gamerule -diff --git a/src/main/java/net/minecraft/world/entity/EntityInsentient.java b/src/main/java/net/minecraft/world/entity/EntityInsentient.java -index 5c047d7f44087adef39bcb56c121f8859748ce42..d2841e1528804841532bbfa885a2689669ad5429 100644 ---- a/src/main/java/net/minecraft/world/entity/EntityInsentient.java -+++ b/src/main/java/net/minecraft/world/entity/EntityInsentient.java -@@ -614,7 +614,7 @@ public abstract class EntityInsentient extends EntityLiving { - public void movementTick() { - super.movementTick(); - this.world.getMethodProfiler().enter("looting"); -- if (!this.world.isClientSide && this.canPickupLoot() && this.isAlive() && !this.killed && this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) { -+ if (!this.world.isClientSide && this.canPickupLoot() && this.isAlive() && !this.killed && (this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) || world.purpurConfig.entitiesPickUpLootBypassMobGriefing)) { // Purpur - List list = this.world.a(EntityItem.class, this.getBoundingBox().grow(1.0D, 0.0D, 1.0D)); +diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java +index ecd6ce01f541a2885384dac47095422b86e194fa..4063bceb87da208db76da2a820e5338ba1b5119b 100644 +--- a/src/main/java/net/minecraft/world/entity/Mob.java ++++ b/src/main/java/net/minecraft/world/entity/Mob.java +@@ -619,7 +619,7 @@ public abstract class Mob extends LivingEntity { + public void aiStep() { + super.aiStep(); + this.level.getProfiler().push("looting"); +- if (!this.level.isClientSide && this.canPickUpLoot() && this.isAlive() && !this.dead && this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ if (!this.level.isClientSide && this.canPickUpLoot() && this.isAlive() && !this.dead && (this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) || level.purpurConfig.entitiesPickUpLootBypassMobGriefing)) { + List list = this.level.getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate(1.0D, 0.0D, 1.0D)); Iterator iterator = list.iterator(); diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 8033348257c0fcc6f3c1c376b6fb343c414618c5..3198f65bff04015babe7e529ad66588ef28e52be 100644 +index 8e4c9dab2fa52dbc99473762e10651b89275cd59..18248e6c7c11357a09cd1d41b62bd2722de58b76 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java @@ -147,10 +147,12 @@ public class PurpurWorldConfig { diff --git a/patches/server-unmapped/0060-Villagers-farming-can-bypass-mob-griefing-gamerule.patch b/patches/server/0059-Villagers-farming-can-bypass-mob-griefing-gamerule.patch similarity index 55% rename from patches/server-unmapped/0060-Villagers-farming-can-bypass-mob-griefing-gamerule.patch rename to patches/server/0059-Villagers-farming-can-bypass-mob-griefing-gamerule.patch index 3019392fc..29e97143c 100644 --- a/patches/server-unmapped/0060-Villagers-farming-can-bypass-mob-griefing-gamerule.patch +++ b/patches/server/0059-Villagers-farming-can-bypass-mob-griefing-gamerule.patch @@ -1,24 +1,24 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath +From: William Blake Galbreath Date: Fri, 24 Apr 2020 09:37:29 -0500 Subject: [PATCH] Villagers farming can bypass mob-griefing gamerule -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 bd998ea93d7e8748b0a938f0a76b4ccf388c7b27..42c70a6c2972ac38e889a6d42fe2d7d4f6017d57 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 -@@ -38,7 +38,7 @@ public class BehaviorFarm extends Behavior { +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 41b5652578e4a703cb6f03e82654b27ea6302b99..2d83b7252814a3a921db32a62f6bfb711d5b5ac1 100644 +--- a/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java ++++ b/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java +@@ -40,7 +40,7 @@ public class HarvestFarmland extends Behavior { } - protected boolean a(WorldServer worldserver, EntityVillager entityvillager) { -- if (!worldserver.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) { -+ if (!worldserver.getGameRules().getBoolean(GameRules.MOB_GRIEFING) && !worldserver.purpurConfig.villagerFarmingBypassMobGriefing) { // Purpur + protected boolean checkExtraStartConditions(ServerLevel world, Villager entity) { +- if (!world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ if (!world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && !world.purpurConfig.villagerFarmingBypassMobGriefing) { // Purpur return false; - } else if (entityvillager.getVillagerData().getProfession() != VillagerProfession.FARMER) { + } else if (entity.getVillagerData().getProfession() != VillagerProfession.FARMER) { return false; diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 3198f65bff04015babe7e529ad66588ef28e52be..e82485ee1270ce83ccc93825d795743d4ead23a1 100644 +index 18248e6c7c11357a09cd1d41b62bd2722de58b76..d69ec4ddb6e0d20546e26765eed9d7d9b3411674 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java @@ -319,9 +319,11 @@ public class PurpurWorldConfig { diff --git a/patches/server/0060-Villagers-follow-emerald-blocks.patch b/patches/server/0060-Villagers-follow-emerald-blocks.patch new file mode 100644 index 000000000..88ba15a90 --- /dev/null +++ b/patches/server/0060-Villagers-follow-emerald-blocks.patch @@ -0,0 +1,101 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Fri, 29 Nov 2019 22:10:12 -0600 +Subject: [PATCH] Villagers follow emerald blocks + + +diff --git a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java +index e59a77c80a1bbe62aaa61bd4792d21b12c895a5c..760546b954c221e1e138891c7684921682d5f24a 100644 +--- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java ++++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java +@@ -28,11 +28,13 @@ import net.minecraft.world.entity.SlotAccess; + import net.minecraft.world.entity.SpawnGroupData; + import net.minecraft.world.entity.player.Player; + import net.minecraft.world.item.ItemStack; ++import net.minecraft.world.item.crafting.Ingredient; + import net.minecraft.world.item.trading.Merchant; + import net.minecraft.world.item.trading.MerchantOffer; + import net.minecraft.world.item.trading.MerchantOffers; + import net.minecraft.world.level.Level; + import net.minecraft.world.level.ServerLevelAccessor; ++import net.minecraft.world.level.block.Blocks; + import net.minecraft.world.level.pathfinder.BlockPathTypes; + import net.minecraft.world.phys.Vec3; + // CraftBukkit start +@@ -44,6 +46,8 @@ import org.bukkit.event.entity.VillagerAcquireTradeEvent; + + public abstract class AbstractVillager extends AgeableMob implements InventoryCarrier, Npc, Merchant { + ++ static final Ingredient TEMPT_ITEMS = Ingredient.of(Blocks.EMERALD_BLOCK.asItem()); // Purpur ++ + // CraftBukkit start + private CraftMerchant craftMerchant; + +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 d9d12330e84f204f96761051e1d92984d8a96330..897dcb4eb6e5530fb612e16551eb9e4f457985f5 100644 +--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java ++++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java +@@ -62,6 +62,7 @@ import net.minecraft.world.entity.ai.Brain; + import net.minecraft.world.entity.ai.attributes.AttributeSupplier; + import net.minecraft.world.entity.ai.attributes.Attributes; + import net.minecraft.world.entity.ai.behavior.VillagerGoalPackages; ++import net.minecraft.world.entity.ai.goal.TemptGoal; + import net.minecraft.world.entity.ai.gossip.GossipContainer; + import net.minecraft.world.entity.ai.gossip.GossipType; + import net.minecraft.world.entity.ai.memory.MemoryModuleType; +@@ -157,6 +158,13 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + this.brainTickOffset = getRandom().nextInt(100); // Purpur + } + ++ // Purpur start ++ @Override ++ protected void registerGoals() { ++ if (level.purpurConfig.villagerFollowEmeraldBlock) this.goalSelector.addGoal(3, new TemptGoal(this, 1.0D, TEMPT_ITEMS, false)); ++ } ++ // Purpur end ++ + @Override + public Brain getBrain() { + return (Brain) super.getBrain(); // CraftBukkit - decompile error +diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java +index c4f7c94255e4631a3c0355f9260132ba28296f50..11576b86368479c319691b58ad47f1f1e1479c68 100644 +--- a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java ++++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java +@@ -25,6 +25,7 @@ import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal; + import net.minecraft.world.entity.ai.goal.LookAtTradingPlayerGoal; + import net.minecraft.world.entity.ai.goal.MoveTowardsRestrictionGoal; + import net.minecraft.world.entity.ai.goal.PanicGoal; ++import net.minecraft.world.entity.ai.goal.TemptGoal; + import net.minecraft.world.entity.ai.goal.TradeWithPlayerGoal; + import net.minecraft.world.entity.ai.goal.UseItemGoal; + import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal; +@@ -87,6 +88,7 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill + this.goalSelector.addGoal(1, new PanicGoal(this, 0.5D)); + this.goalSelector.addGoal(1, new LookAtTradingPlayerGoal(this)); + this.goalSelector.addGoal(2, new WanderingTrader.WanderToPositionGoal(this, 2.0D, 0.35D)); ++ if (level.purpurConfig.villagerTraderFollowEmeraldBlock) this.goalSelector.addGoal(3, new TemptGoal(this, 1.0D, TEMPT_ITEMS, false)); // Purpur + this.goalSelector.addGoal(4, new MoveTowardsRestrictionGoal(this, 0.35D)); + this.goalSelector.addGoal(8, new WaterAvoidingRandomStrollGoal(this, 0.35D)); + this.goalSelector.addGoal(9, new InteractGoal(this, Player.class, 3.0F, 1.0F)); +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index d69ec4ddb6e0d20546e26765eed9d7d9b3411674..3be920c0fd4b406668cc18fbbb2dec6a7f0c2ab2 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -320,10 +320,17 @@ public class PurpurWorldConfig { + public int villagerBrainTicks = 1; + public boolean villagerUseBrainTicksOnlyWhenLagging = true; + public boolean villagerFarmingBypassMobGriefing = false; ++ public boolean villagerFollowEmeraldBlock = false; + private void villagerSettings() { + villagerBrainTicks = getInt("mobs.villager.brain-ticks", villagerBrainTicks); + villagerUseBrainTicksOnlyWhenLagging = getBoolean("mobs.villager.use-brain-ticks-only-when-lagging", villagerUseBrainTicksOnlyWhenLagging); + villagerFarmingBypassMobGriefing = getBoolean("mobs.villager.bypass-mob-griefing", villagerFarmingBypassMobGriefing); ++ villagerFollowEmeraldBlock = getBoolean("mobs.villager.follow-emerald-blocks", villagerFollowEmeraldBlock); ++ } ++ ++ public boolean villagerTraderFollowEmeraldBlock = false; ++ private void villagerTraderSettings() { ++ villagerTraderFollowEmeraldBlock = getBoolean("mobs.wandering_trader.follow-emerald-blocks", villagerTraderFollowEmeraldBlock); + } + + public boolean witherSkeletonTakesWitherDamage = false; diff --git a/patches/server/0061-Allow-leashing-villagers.patch b/patches/server/0061-Allow-leashing-villagers.patch new file mode 100644 index 000000000..cab32d253 --- /dev/null +++ b/patches/server/0061-Allow-leashing-villagers.patch @@ -0,0 +1,94 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Thu, 3 Oct 2019 18:08:03 -0500 +Subject: [PATCH] Allow leashing villagers + + +diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java +index 4063bceb87da208db76da2a820e5338ba1b5119b..f4c9e6184f39dea9ea1fda98333734773858d0f8 100644 +--- a/src/main/java/net/minecraft/world/entity/Mob.java ++++ b/src/main/java/net/minecraft/world/entity/Mob.java +@@ -47,6 +47,7 @@ import net.minecraft.world.entity.decoration.HangingEntity; + import net.minecraft.world.entity.decoration.LeashFenceKnotEntity; + import net.minecraft.world.entity.item.ItemEntity; + import net.minecraft.world.entity.monster.Enemy; ++import net.minecraft.world.entity.npc.AbstractVillager; + import net.minecraft.world.entity.player.Player; + import net.minecraft.world.entity.vehicle.Boat; + import net.minecraft.world.item.ArmorItem; +@@ -1207,6 +1208,7 @@ public abstract class Mob extends LivingEntity { + if (!this.isAlive()) { + return InteractionResult.PASS; + } else if (this.getLeashHolder() == player) { ++ if (hand == InteractionHand.OFF_HAND && (level.purpurConfig.villagerCanBeLeashed || level.purpurConfig.villagerTraderCanBeLeashed) && this instanceof AbstractVillager) return InteractionResult.CONSUME; // Purpur + // CraftBukkit start - fire PlayerUnleashEntityEvent + // Paper start - drop leash variable + org.bukkit.event.player.PlayerUnleashEntityEvent event = CraftEventFactory.callPlayerUnleashEntityEvent(this, player, !player.getAbilities().instabuild); +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 897dcb4eb6e5530fb612e16551eb9e4f457985f5..20cb368076017e6dfc28ef4c2af778c0971e8462 100644 +--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java ++++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java +@@ -76,6 +76,7 @@ import net.minecraft.world.entity.ai.village.poi.PoiManager; + import net.minecraft.world.entity.ai.village.poi.PoiType; + import net.minecraft.world.entity.animal.IronGolem; + import net.minecraft.world.entity.item.ItemEntity; ++import net.minecraft.world.entity.monster.Enemy; + import net.minecraft.world.entity.monster.Witch; + import net.minecraft.world.entity.player.Player; + import net.minecraft.world.entity.raid.Raid; +@@ -163,6 +164,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + protected void registerGoals() { + if (level.purpurConfig.villagerFollowEmeraldBlock) this.goalSelector.addGoal(3, new TemptGoal(this, 1.0D, TEMPT_ITEMS, false)); + } ++ ++ @Override ++ public boolean canBeLeashed(Player player) { ++ return level.purpurConfig.villagerCanBeLeashed && !this.isLeashed(); ++ } + // Purpur end + + @Override +diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java +index 11576b86368479c319691b58ad47f1f1e1479c68..a17f61874a8999973d7368cf729676dfa9da5569 100644 +--- a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java ++++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java +@@ -95,6 +95,13 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill + this.goalSelector.addGoal(10, new LookAtPlayerGoal(this, Mob.class, 8.0F)); + } + ++ // Purpur start ++ @Override ++ public boolean canBeLeashed(Player player) { ++ return level.purpurConfig.villagerTraderCanBeLeashed && !this.isLeashed(); ++ } ++ // Purpur end ++ + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel world, AgeableMob entity) { +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index 3be920c0fd4b406668cc18fbbb2dec6a7f0c2ab2..b6b362befd94e4cca156296058019c8a26c7b2f4 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -319,17 +319,21 @@ public class PurpurWorldConfig { + + public int villagerBrainTicks = 1; + public boolean villagerUseBrainTicksOnlyWhenLagging = true; ++ public boolean villagerCanBeLeashed = false; + public boolean villagerFarmingBypassMobGriefing = false; + public boolean villagerFollowEmeraldBlock = false; + private void villagerSettings() { + villagerBrainTicks = getInt("mobs.villager.brain-ticks", villagerBrainTicks); + villagerUseBrainTicksOnlyWhenLagging = getBoolean("mobs.villager.use-brain-ticks-only-when-lagging", villagerUseBrainTicksOnlyWhenLagging); ++ villagerCanBeLeashed = getBoolean("mobs.villager.can-be-leashed", villagerCanBeLeashed); + villagerFarmingBypassMobGriefing = getBoolean("mobs.villager.bypass-mob-griefing", villagerFarmingBypassMobGriefing); + villagerFollowEmeraldBlock = getBoolean("mobs.villager.follow-emerald-blocks", villagerFollowEmeraldBlock); + } + ++ public boolean villagerTraderCanBeLeashed = false; + public boolean villagerTraderFollowEmeraldBlock = false; + private void villagerTraderSettings() { ++ villagerTraderCanBeLeashed = getBoolean("mobs.wandering_trader.can-be-leashed", villagerTraderCanBeLeashed); + villagerTraderFollowEmeraldBlock = getBoolean("mobs.wandering_trader.follow-emerald-blocks", villagerTraderFollowEmeraldBlock); + } +