--- a/net/minecraft/world/entity/monster/piglin/Piglin.java
+++ b/net/minecraft/world/entity/monster/piglin/Piglin.java
@@ -125,6 +_,12 @@
         MemoryModuleType.ATE_RECENTLY,
         MemoryModuleType.NEAREST_REPELLENT
     );
+    // CraftBukkit start - Custom bartering and interest list
+    public java.util.Set<Item> allowedBarterItems = new java.util.HashSet<>();
+    public java.util.Set<Item> interestItems = new java.util.HashSet<>();
+    private static final com.mojang.serialization.Codec<java.util.Set<net.minecraft.world.item.Item>> ITEM_SET_CODEC = net.minecraft.core.registries.BuiltInRegistries.ITEM
+        .byNameCodec().listOf().xmap(java.util.HashSet::new, List::copyOf);
+    // CraftBukkit end
 
     public Piglin(EntityType<? extends AbstractPiglin> entityType, Level level) {
         super(entityType, level);
@@ -137,6 +_,10 @@
         output.putBoolean("IsBaby", this.isBaby());
         output.putBoolean("CannotHunt", this.cannotHunt);
         this.writeInventoryToTag(output);
+        // CraftBukkit start
+        output.store("Bukkit.BarterList", ITEM_SET_CODEC, this.allowedBarterItems);
+        output.store("Bukkit.InterestList", ITEM_SET_CODEC, this.interestItems);
+        // CraftBukkit end
     }
 
     @Override
@@ -145,6 +_,10 @@
         this.setBaby(input.getBooleanOr("IsBaby", false));
         this.setCannotHunt(input.getBooleanOr("CannotHunt", false));
         this.readInventoryFromTag(input);
+        // CraftBukkit start
+        this.allowedBarterItems = input.read("Bukkit.BarterList", ITEM_SET_CODEC).orElseGet(java.util.HashSet::new);
+        this.interestItems = input.read("Bukkit.InterestList", ITEM_SET_CODEC).orElseGet(java.util.HashSet::new);
+        // CraftBukkit end
     }
 
     @VisibleForDebug
@@ -322,7 +_,9 @@
     @Override
     protected void finishConversion(ServerLevel serverLevel) {
         PiglinAi.cancelAdmiring(serverLevel, this);
+        this.forceDrops = true; // Paper - Add missing forceDrop toggles
         this.inventory.removeAllItems().forEach(itemStack -> this.spawnAtLocation(serverLevel, itemStack));
+        this.forceDrops = false; // Paper - Add missing forceDrop toggles
         super.finishConversion(serverLevel);
     }
 
@@ -398,7 +_,7 @@
     }
 
     protected void holdInOffHand(ItemStack stack) {
-        if (stack.is(PiglinAi.BARTERING_ITEM)) {
+        if (stack.is(PiglinAi.BARTERING_ITEM) || this.allowedBarterItems.contains(stack.getItem())) { // CraftBukkit - Changes to accept custom payment items
             this.setItemSlot(EquipmentSlot.OFFHAND, stack);
             this.setGuaranteedDrop(EquipmentSlot.OFFHAND);
         } else {
@@ -423,15 +_,15 @@
             return false;
         } else {
             TagKey<Item> preferredWeaponType = this.getPreferredWeaponType();
-            boolean flag = PiglinAi.isLovedItem(newItem) || preferredWeaponType != null && newItem.is(preferredWeaponType);
-            boolean flag1 = PiglinAi.isLovedItem(currentItem) || preferredWeaponType != null && currentItem.is(preferredWeaponType);
+            boolean flag = PiglinAi.isLovedItem(newItem, this) || preferredWeaponType != null && newItem.is(preferredWeaponType); // CraftBukkit
+            boolean flag1 = PiglinAi.isLovedItem(currentItem, this) || preferredWeaponType != null && currentItem.is(preferredWeaponType); // CraftBukkit
             return flag && !flag1 || (flag || !flag1) && super.canReplaceCurrentItem(newItem, currentItem, slot);
         }
     }
 
     @Override
     protected void pickUpItem(ServerLevel level, ItemEntity entity) {
-        this.onItemPickup(entity);
+        // this.onItemPickup(entity); // Paper - EntityPickupItemEvent fixes; call in PiglinAi#pickUpItem after EntityPickupItemEvent is fired
         PiglinAi.pickUpItem(level, this, entity);
     }
 
