From b12c969bc545c78bfe8490b0b2c07e256794c042 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 5 Jan 2025 15:57:26 -0800 Subject: [PATCH] Allow leashing villagers --- .../0048-Allow-leashing-villagers.patch | 88 ------------------- .../features/0001-Ridables.patch | 34 +++---- ...-Configurable-entity-base-attributes.patch | 24 ++--- ...0007-Villagers-follow-emerald-blocks.patch | 14 +-- .../minecraft/world/entity/Entity.java.patch | 8 ++ .../world/entity/npc/Villager.java.patch | 16 ++++ .../entity/npc/WanderingTrader.java.patch | 16 ++++ .../purpurmc/purpur/PurpurWorldConfig.java | 4 + 8 files changed, 80 insertions(+), 124 deletions(-) delete mode 100644 patches/server/0048-Allow-leashing-villagers.patch create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/entity/npc/Villager.java.patch create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/entity/npc/WanderingTrader.java.patch diff --git a/patches/server/0048-Allow-leashing-villagers.patch b/patches/server/0048-Allow-leashing-villagers.patch deleted file mode 100644 index da3e230bf..000000000 --- a/patches/server/0048-Allow-leashing-villagers.patch +++ /dev/null @@ -1,88 +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/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index fe5e8009d16fe9292312e37538b02b92b9fea9ed..7b017806dde98a33b64223f098cc63c286dac02b 100644 ---- a/net/minecraft/world/entity/Entity.java -+++ b/net/minecraft/world/entity/Entity.java -@@ -3115,6 +3115,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - if (this.isAlive() && this instanceof Leashable leashable) { - if (leashable.getLeashHolder() == player) { - if (!this.level().isClientSide()) { -+ if (hand == InteractionHand.OFF_HAND && (level().purpurConfig.villagerCanBeLeashed || level().purpurConfig.wanderingTraderCanBeLeashed) && this instanceof net.minecraft.world.entity.npc.AbstractVillager) return InteractionResult.CONSUME; // Purpur - Allow leashing villagers - // CraftBukkit start - fire PlayerUnleashEntityEvent - // Paper start - Expand EntityUnleashEvent - org.bukkit.event.player.PlayerUnleashEntityEvent event = CraftEventFactory.callPlayerUnleashEntityEvent(this, player, hand, !player.hasInfiniteMaterials()); -diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java -index 129833b7ecd644e4180fadca15015276961725c6..f89c82db6333dc64ac57e225f5522943eb959f46 100644 ---- a/net/minecraft/world/entity/npc/Villager.java -+++ b/net/minecraft/world/entity/npc/Villager.java -@@ -187,6 +187,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler - this.getAttribute(Attributes.TEMPT_RANGE).setBaseValue(this.level().purpurConfig.villagerTemptRange); // Purpur - Villagers follow emerald blocks - } - // Purpur end - Configurable entity base attributes -+ // Purpur start - Allow leashing villagers -+ @Override -+ public boolean canBeLeashed() { -+ return level().purpurConfig.villagerCanBeLeashed; -+ } -+ // Purpur end - Allow leashing villagers - @Override - public Brain getBrain() { - return (Brain) super.getBrain(); // CraftBukkit - decompile error -diff --git a/net/minecraft/world/entity/npc/WanderingTrader.java b/net/minecraft/world/entity/npc/WanderingTrader.java -index c307aa1153d6a17ee8624453fc9303ac5749b6ef..0066e413d1fa92ecd5573c00195aa2f1412e665e 100644 ---- a/net/minecraft/world/entity/npc/WanderingTrader.java -+++ b/net/minecraft/world/entity/npc/WanderingTrader.java -@@ -101,6 +101,12 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill - return Mob.createMobAttributes().add(net.minecraft.world.entity.ai.attributes.Attributes.TEMPT_RANGE, 10.0D); - } - // Purpur end - Villagers follow emerald blocks -+ // Purpur start - Allow leashing villagers -+ @Override -+ public boolean canBeLeashed() { -+ return level().purpurConfig.wanderingTraderCanBeLeashed; -+ } -+ // Purpur end - Allow leashing villagers - @Override - protected void registerGoals() { - this.goalSelector.addGoal(0, new FloatGoal(this)); -diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -index b81790ec5a7e4b73fbef52229844506b072dfa0d..1b96a84a1c81c075aa5f7308b89d396a4578be33 100644 ---- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -@@ -1590,6 +1590,7 @@ public class PurpurWorldConfig { - public double villagerScale = 1.0D; - public boolean villagerFollowEmeraldBlock = false; - public double villagerTemptRange = 10.0D; -+ public boolean villagerCanBeLeashed = false; - private void villagerSettings() { - villagerRidable = getBoolean("mobs.villager.ridable", villagerRidable); - villagerRidableInWater = getBoolean("mobs.villager.ridable-in-water", villagerRidableInWater); -@@ -1603,6 +1604,7 @@ public class PurpurWorldConfig { - villagerScale = Mth.clamp(getDouble("mobs.villager.attributes.scale", villagerScale), 0.0625D, 16.0D); - villagerFollowEmeraldBlock = getBoolean("mobs.villager.follow-emerald-blocks", villagerFollowEmeraldBlock); - villagerTemptRange = getDouble("mobs.villager.attributes.tempt_range", villagerTemptRange); -+ villagerCanBeLeashed = getBoolean("mobs.villager.can-be-leashed", villagerCanBeLeashed); - } - - public boolean vindicatorRidable = false; -@@ -1630,6 +1632,7 @@ public class PurpurWorldConfig { - public double wanderingTraderScale = 1.0D; - public boolean wanderingTraderFollowEmeraldBlock = false; - public double wanderingTraderTemptRange = 10.0D; -+ public boolean wanderingTraderCanBeLeashed = false; - private void wanderingTraderSettings() { - wanderingTraderRidable = getBoolean("mobs.wandering_trader.ridable", wanderingTraderRidable); - wanderingTraderRidableInWater = getBoolean("mobs.wandering_trader.ridable-in-water", wanderingTraderRidableInWater); -@@ -1643,6 +1646,7 @@ public class PurpurWorldConfig { - wanderingTraderScale = Mth.clamp(getDouble("mobs.wandering_trader.attributes.scale", wanderingTraderScale), 0.0625D, 16.0D); - wanderingTraderFollowEmeraldBlock = getBoolean("mobs.wandering_trader.follow-emerald-blocks", wanderingTraderFollowEmeraldBlock); - wanderingTraderTemptRange = getDouble("mobs.wandering_trader.attributes.tempt_range", wanderingTraderTemptRange); -+ wanderingTraderCanBeLeashed = getBoolean("mobs.wandering_trader.can-be-leashed", wanderingTraderCanBeLeashed); - } - - public boolean wardenRidable = false; diff --git a/purpur-server/minecraft-patches/features/0001-Ridables.patch b/purpur-server/minecraft-patches/features/0001-Ridables.patch index 7f26aac9d..4dab66173 100644 --- a/purpur-server/minecraft-patches/features/0001-Ridables.patch +++ b/purpur-server/minecraft-patches/features/0001-Ridables.patch @@ -75,10 +75,10 @@ index b083228bb3dc87794c6f177ad99832daf6925a39..bf863cfae63a50636c3fcc8fcf9761f1 if ((target instanceof Bucketable && target instanceof LivingEntity && origItem != null && origItem.asItem() == Items.WATER_BUCKET) && (event.isCancelled() || ServerGamePacketListenerImpl.this.player.getInventory().getSelected() == null || ServerGamePacketListenerImpl.this.player.getInventory().getSelected().getItem() != origItem)) { target.resendPossiblyDesyncedEntityData(ServerGamePacketListenerImpl.this.player); // Paper - The entire mob gets deleted, so resend it diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 4575ea1d17bf22790d742a9d73aa88ded665809d..7797dd4d87ea29585d93461126a0d781ed7daec5 100644 +index eef36c568050b790908787a2d423db6f7b8cf313..10fd7f0274d1a6a954f01244f6e1e356bd190211 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -3129,6 +3129,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -3130,6 +3130,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.passengers = ImmutableList.copyOf(list); } @@ -92,7 +92,7 @@ index 4575ea1d17bf22790d742a9d73aa88ded665809d..7797dd4d87ea29585d93461126a0d781 this.gameEvent(GameEvent.ENTITY_MOUNT, passenger); } } -@@ -3170,6 +3177,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -3171,6 +3178,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return false; } // CraftBukkit end @@ -107,7 +107,7 @@ index 4575ea1d17bf22790d742a9d73aa88ded665809d..7797dd4d87ea29585d93461126a0d781 if (this.passengers.size() == 1 && this.passengers.get(0) == passenger) { this.passengers = ImmutableList.of(); } else { -@@ -5084,4 +5099,44 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -5085,4 +5100,44 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return ((ServerLevel) this.level).isPositionEntityTicking(this.blockPosition()); } // Paper end - Expose entity id counter @@ -3134,7 +3134,7 @@ index 2e32567fca7a2a4cd87bc078a6eeb30e3ffabfce..4873a3d8dd9c160ecdbda594ee546c35 public boolean doHurtTarget(ServerLevel level, Entity source) { if (super.doHurtTarget(level, source)) { diff --git a/net/minecraft/world/entity/monster/Creeper.java b/net/minecraft/world/entity/monster/Creeper.java -index 2b3e1fcf4ec73f5be1804c77ffd74f27c2dc2eaf..cae4c797cf72920b9fd8e79d95d51367b5f7b87b 100644 +index 177849ae6613b42fbc2ee515b8ae93f1c13c07a6..c4399f1ad3a6c1a35abb28bc76ac0b0508b98209 100644 --- a/net/minecraft/world/entity/monster/Creeper.java +++ b/net/minecraft/world/entity/monster/Creeper.java @@ -50,21 +50,98 @@ public class Creeper extends Monster { @@ -3332,7 +3332,7 @@ index 4585b7c867685f8419c4d2b5b90af5946d337f90..c6eeaf7b460408acfdf89d988b47b08e return Guardian.createAttributes().add(Attributes.MOVEMENT_SPEED, 0.3F).add(Attributes.ATTACK_DAMAGE, 8.0).add(Attributes.MAX_HEALTH, 80.0); } diff --git a/net/minecraft/world/entity/monster/EnderMan.java b/net/minecraft/world/entity/monster/EnderMan.java -index 4b5ffd278e0e9d47100e5452949e8d757bbfece4..7330a73c4ed3065a999a984864087f60d091bd3b 100644 +index 22a078c9b94516c8a5170a1387d7b941b91c3f1d..1f1e86dcdc6ded664a4562c0a3de45162c4fd6ac 100644 --- a/net/minecraft/world/entity/monster/EnderMan.java +++ b/net/minecraft/world/entity/monster/EnderMan.java @@ -90,9 +90,27 @@ public class EnderMan extends Monster implements NeutralMob { @@ -4928,12 +4928,12 @@ index 9f476e587d7df797129e49738f101cccca7e10b7..f968e5c99bdb23b268bc34ea1ba5d54a && this.level() == entity.level() && EntitySelector.NO_CREATIVE_OR_SPECTATOR.test(entity) diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java -index 2b83262e4a13eae86df82913ce4f3121e3631a43..fbb12688470ac4dea129ee171c9fc001bdc8812b 100644 +index 167493ab38bc7ea77335371c2adf9df86aedace5..975680c50e999fe6d4694f04d49baabf88bf8d8d 100644 --- a/net/minecraft/world/entity/npc/Villager.java +++ b/net/minecraft/world/entity/npc/Villager.java -@@ -193,6 +193,28 @@ public class Villager extends AbstractVillager implements ReputationEventHandler - this.setVillagerData(this.getVillagerData().setType(villagerType).setProfession(VillagerProfession.NONE)); +@@ -200,6 +200,28 @@ public class Villager extends AbstractVillager implements ReputationEventHandler } + // Purpur end - Allow leashing villagers + // Purpur start - Ridables + @Override @@ -4960,7 +4960,7 @@ index 2b83262e4a13eae86df82913ce4f3121e3631a43..fbb12688470ac4dea129ee171c9fc001 @Override public Brain getBrain() { return (Brain)super.getBrain(); -@@ -293,7 +315,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -300,7 +322,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler // Paper end - EAR 2 ProfilerFiller profilerFiller = Profiler.get(); profilerFiller.push("villagerBrain"); @@ -4969,7 +4969,7 @@ index 2b83262e4a13eae86df82913ce4f3121e3631a43..fbb12688470ac4dea129ee171c9fc001 profilerFiller.pop(); if (this.assignProfessionWhenSpawned) { this.assignProfessionWhenSpawned = false; -@@ -349,7 +371,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -356,7 +378,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler return super.mobInteract(player, hand); } else if (this.isBaby()) { this.setUnhappy(); @@ -4978,7 +4978,7 @@ index 2b83262e4a13eae86df82913ce4f3121e3631a43..fbb12688470ac4dea129ee171c9fc001 } else { if (!this.level().isClientSide) { boolean isEmpty = this.getOffers().isEmpty(); -@@ -362,9 +384,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -369,9 +391,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler } if (isEmpty) { @@ -4992,14 +4992,14 @@ index 2b83262e4a13eae86df82913ce4f3121e3631a43..fbb12688470ac4dea129ee171c9fc001 } diff --git a/net/minecraft/world/entity/npc/WanderingTrader.java b/net/minecraft/world/entity/npc/WanderingTrader.java -index 6655d06e2011e20e7346dfe57527795269094d8a..6c14537c8376bd392524aefde8dfe76b159c3655 100644 +index 47c1ad2ef30d464abb3c804260f0fd7cde193ba5..c6b3894fe085c2b565651ab3ae2f1acbb6bacea4 100644 --- a/net/minecraft/world/entity/npc/WanderingTrader.java +++ b/net/minecraft/world/entity/npc/WanderingTrader.java -@@ -69,6 +69,23 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill - super(entityType, level); +@@ -76,6 +76,23 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill } + // Purpur end - Allow leashing villagers -+ // Purpur - start ++ // Purpur - start - Ridables + @Override + public boolean isRidable() { + return level().purpurConfig.wanderingTraderRidable; @@ -5019,7 +5019,7 @@ index 6655d06e2011e20e7346dfe57527795269094d8a..6c14537c8376bd392524aefde8dfe76b @Override protected void registerGoals() { this.goalSelector.addGoal(0, new FloatGoal(this)); -@@ -130,9 +147,9 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill +@@ -137,9 +154,9 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill if (!this.level().isClientSide) { if (this.getOffers().isEmpty()) { diff --git a/purpur-server/minecraft-patches/features/0002-Configurable-entity-base-attributes.patch b/purpur-server/minecraft-patches/features/0002-Configurable-entity-base-attributes.patch index 1a62a5e62..6b63e620e 100644 --- a/purpur-server/minecraft-patches/features/0002-Configurable-entity-base-attributes.patch +++ b/purpur-server/minecraft-patches/features/0002-Configurable-entity-base-attributes.patch @@ -23,7 +23,7 @@ index 666455fff2b391b637cf1c07091e88100c5e1308..a53d662e2c78b002320956b9c7e39ccb protected ParticleOptions getInkParticle() { return ParticleTypes.GLOW_SQUID_INK; diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index 67c99e33642964a1756d48e029e00f2676f07fbb..0f866a6d75afbd2238e49e56a2a2fbc6edb0168c 100644 +index b8f38aefd15fda2ff4326c0ea1a06af4189edc60..3a8285490998dc39d6f175b88ad8cb1369b3a7ea 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java @@ -311,6 +311,7 @@ public abstract class LivingEntity extends Entity implements Attackable { @@ -145,7 +145,7 @@ index 6a19086e272363701260801f3c6db9b5c91b8ef5..434e1fabf2e360a8f5f4eefed96e3883 public ItemStack getBucketItemStack() { return new ItemStack(Items.COD_BUCKET); diff --git a/net/minecraft/world/entity/animal/Cow.java b/net/minecraft/world/entity/animal/Cow.java -index b2bf4276952fa1c984bf0571b041be4141fbdf3a..ad59d1f1e505148b88c0d242a5d92f7c4d8f4ce8 100644 +index 656babc0c8810a85eb9f78ced1f3ad9551fdc286..d2a4bfa5334f7361067e4adac36ba5a4a4fa6ad8 100644 --- a/net/minecraft/world/entity/animal/Cow.java +++ b/net/minecraft/world/entity/animal/Cow.java @@ -55,6 +55,14 @@ public class Cow extends Animal { @@ -221,7 +221,7 @@ index 654f5855e1b69f05205e6a132d79ac94b929eeb4..d195e8658fd5a4045c95ff1e921bfeeb protected void registerGoals() { if (level().purpurConfig.ironGolemCanSwim) this.goalSelector.addGoal(0, new net.minecraft.world.entity.ai.goal.FloatGoal(this)); // Purpur - Ridables diff --git a/net/minecraft/world/entity/animal/MushroomCow.java b/net/minecraft/world/entity/animal/MushroomCow.java -index 696b0eb93f8c8fe30f4c2cabadc50de730f93c22..0afc7aefbeb22ead66d59b3fd67630af0bce2df1 100644 +index 1292146341022483f78a9128ef9d7a88089274a0..990723c31aa1040a4e45b9857a18d86287ef91b4 100644 --- a/net/minecraft/world/entity/animal/MushroomCow.java +++ b/net/minecraft/world/entity/animal/MushroomCow.java @@ -72,6 +72,13 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder getBrain() { return (Brain)super.getBrain(); diff --git a/net/minecraft/world/entity/npc/WanderingTrader.java b/net/minecraft/world/entity/npc/WanderingTrader.java -index 6c14537c8376bd392524aefde8dfe76b159c3655..470f8052af13b24d7cf6cfde19557219e32f4324 100644 +index c6b3894fe085c2b565651ab3ae2f1acbb6bacea4..31449094c6395857289dd56482e8b3902bac2b63 100644 --- a/net/minecraft/world/entity/npc/WanderingTrader.java +++ b/net/minecraft/world/entity/npc/WanderingTrader.java -@@ -86,6 +86,13 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill +@@ -93,6 +93,13 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill } // Purpur end - Ridables diff --git a/purpur-server/minecraft-patches/features/0007-Villagers-follow-emerald-blocks.patch b/purpur-server/minecraft-patches/features/0007-Villagers-follow-emerald-blocks.patch index 5cd54bce7..6aa9d100f 100644 --- a/purpur-server/minecraft-patches/features/0007-Villagers-follow-emerald-blocks.patch +++ b/purpur-server/minecraft-patches/features/0007-Villagers-follow-emerald-blocks.patch @@ -44,10 +44,10 @@ index a71d16d968bb90fd7aca6f01a3dd56df4f9a7ce6..b4e79cac5611942240ce85120f7bbee3 @Override public CraftMerchant getCraftMerchant() { diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java -index 85a6a38fb954915c7bf6290a40b0ab48818d08c8..0f4a8845250a0e59611006b8f3fe370c02c87542 100644 +index 557140401074dec60cf862a29570b2f0a5de64a1..c30fc25536277b487030effafecebf43390934cf 100644 --- a/net/minecraft/world/entity/npc/Villager.java +++ b/net/minecraft/world/entity/npc/Villager.java -@@ -212,6 +212,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -219,6 +219,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @Override protected void registerGoals() { this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); @@ -55,7 +55,7 @@ index 85a6a38fb954915c7bf6290a40b0ab48818d08c8..0f4a8845250a0e59611006b8f3fe370c } // Purpur end - Ridables -@@ -220,6 +221,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -227,6 +228,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler public void initAttributes() { this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.villagerMaxHealth); this.getAttribute(Attributes.SCALE).setBaseValue(this.level().purpurConfig.villagerScale); @@ -63,7 +63,7 @@ index 85a6a38fb954915c7bf6290a40b0ab48818d08c8..0f4a8845250a0e59611006b8f3fe370c } // Purpur end - Configurable entity base attributes -@@ -288,7 +290,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -295,7 +297,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler } public static AttributeSupplier.Builder createAttributes() { @@ -73,10 +73,10 @@ index 85a6a38fb954915c7bf6290a40b0ab48818d08c8..0f4a8845250a0e59611006b8f3fe370c public boolean assignProfessionWhenSpawned() { diff --git a/net/minecraft/world/entity/npc/WanderingTrader.java b/net/minecraft/world/entity/npc/WanderingTrader.java -index 470f8052af13b24d7cf6cfde19557219e32f4324..8fb572cd5699021769a994312b5b31392314ab1e 100644 +index 31449094c6395857289dd56482e8b3902bac2b63..cef51ce86dcbc5ec01bfcbcb487325b55779be52 100644 --- a/net/minecraft/world/entity/npc/WanderingTrader.java +++ b/net/minecraft/world/entity/npc/WanderingTrader.java -@@ -90,9 +90,16 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill +@@ -97,9 +97,16 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill @Override public void initAttributes() { this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.wanderingTraderMaxHealth); @@ -93,7 +93,7 @@ index 470f8052af13b24d7cf6cfde19557219e32f4324..8fb572cd5699021769a994312b5b3139 @Override protected void registerGoals() { this.goalSelector.addGoal(0, new FloatGoal(this)); -@@ -127,6 +134,7 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill +@@ -134,6 +141,7 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill this.goalSelector.addGoal(1, new PanicGoal(this, 0.5)); this.goalSelector.addGoal(1, new LookAtTradingPlayerGoal(this)); this.goalSelector.addGoal(2, new WanderingTrader.WanderToPositionGoal(this, 2.0, 0.35)); diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/Entity.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/Entity.java.patch index bf96394f0..c0d26a8a2 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/Entity.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/Entity.java.patch @@ -17,6 +17,14 @@ public boolean noPhysics; private boolean wasOnFire; public final RandomSource random = SHARED_RANDOM; // Paper - Share random for entities to make them more random +@@ -2922,6 +_,7 @@ + if (this.isAlive() && this instanceof Leashable leashable) { + if (leashable.getLeashHolder() == player) { + if (!this.level().isClientSide()) { ++ if (hand == InteractionHand.OFF_HAND && (level().purpurConfig.villagerCanBeLeashed || level().purpurConfig.wanderingTraderCanBeLeashed) && this instanceof net.minecraft.world.entity.npc.AbstractVillager) return InteractionResult.CONSUME; // Purpur - Allow leashing villagers + // CraftBukkit start - fire PlayerUnleashEntityEvent + // Paper start - Expand EntityUnleashEvent + org.bukkit.event.player.PlayerUnleashEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerUnleashEntityEvent(this, player, hand, !player.hasInfiniteMaterials()); @@ -4885,7 +_,7 @@ } diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/npc/Villager.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/npc/Villager.java.patch new file mode 100644 index 000000000..557589ab8 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/npc/Villager.java.patch @@ -0,0 +1,16 @@ +--- a/net/minecraft/world/entity/npc/Villager.java ++++ b/net/minecraft/world/entity/npc/Villager.java +@@ -193,6 +_,13 @@ + this.setVillagerData(this.getVillagerData().setType(villagerType).setProfession(VillagerProfession.NONE)); + } + ++ // Purpur start - Allow leashing villagers ++ @Override ++ public boolean canBeLeashed() { ++ return level().purpurConfig.villagerCanBeLeashed; ++ } ++ // Purpur end - Allow leashing villagers ++ + @Override + public Brain getBrain() { + return (Brain)super.getBrain(); diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/npc/WanderingTrader.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/npc/WanderingTrader.java.patch new file mode 100644 index 000000000..92828b6c4 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/npc/WanderingTrader.java.patch @@ -0,0 +1,16 @@ +--- a/net/minecraft/world/entity/npc/WanderingTrader.java ++++ b/net/minecraft/world/entity/npc/WanderingTrader.java +@@ -69,6 +_,13 @@ + super(entityType, level); + } + ++ // Purpur start - Allow leashing villagers ++ @Override ++ public boolean canBeLeashed() { ++ return level().purpurConfig.wanderingTraderCanBeLeashed; ++ } ++ // Purpur end - Allow leashing villagers ++ + @Override + protected void registerGoals() { + this.goalSelector.addGoal(0, new FloatGoal(this)); diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java index f41490bae..53b506649 100644 --- a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java +++ b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java @@ -1578,6 +1578,7 @@ public class PurpurWorldConfig { public double villagerScale = 1.0D; public boolean villagerFollowEmeraldBlock = false; public double villagerTemptRange = 10.0D; + public boolean villagerCanBeLeashed = false; private void villagerSettings() { villagerRidable = getBoolean("mobs.villager.ridable", villagerRidable); villagerRidableInWater = getBoolean("mobs.villager.ridable-in-water", villagerRidableInWater); @@ -1591,6 +1592,7 @@ public class PurpurWorldConfig { villagerScale = Mth.clamp(getDouble("mobs.villager.attributes.scale", villagerScale), 0.0625D, 16.0D); villagerFollowEmeraldBlock = getBoolean("mobs.villager.follow-emerald-blocks", villagerFollowEmeraldBlock); villagerTemptRange = getDouble("mobs.villager.attributes.tempt_range", villagerTemptRange); + villagerCanBeLeashed = getBoolean("mobs.villager.can-be-leashed", villagerCanBeLeashed); } public boolean vindicatorRidable = false; @@ -1620,6 +1622,7 @@ public class PurpurWorldConfig { public double wanderingTraderScale = 1.0D; public boolean wanderingTraderFollowEmeraldBlock = false; public double wanderingTraderTemptRange = 10.0D; + public boolean wanderingTraderCanBeLeashed = false; private void wanderingTraderSettings() { wanderingTraderRidable = getBoolean("mobs.wandering_trader.ridable", wanderingTraderRidable); wanderingTraderRidableInWater = getBoolean("mobs.wandering_trader.ridable-in-water", wanderingTraderRidableInWater); @@ -1633,6 +1636,7 @@ public class PurpurWorldConfig { wanderingTraderScale = Mth.clamp(getDouble("mobs.wandering_trader.attributes.scale", wanderingTraderScale), 0.0625D, 16.0D); wanderingTraderFollowEmeraldBlock = getBoolean("mobs.wandering_trader.follow-emerald-blocks", wanderingTraderFollowEmeraldBlock); wanderingTraderTemptRange = getDouble("mobs.wandering_trader.attributes.tempt_range", wanderingTraderTemptRange); + wanderingTraderCanBeLeashed = getBoolean("mobs.wandering_trader.can-be-leashed", wanderingTraderCanBeLeashed); } public boolean wardenRidable = false;