More mobs

This commit is contained in:
Nassim Jahnke 2024-12-13 19:25:16 +01:00
parent 7d42b87010
commit 3ef3394311
No known key found for this signature in database
GPG key ID: EF6771C01F6EF02F
9 changed files with 349 additions and 432 deletions

View file

@ -0,0 +1,36 @@
--- a/net/minecraft/world/entity/animal/axolotl/Axolotl.java
+++ b/net/minecraft/world/entity/animal/axolotl/Axolotl.java
@@ -226,7 +_,7 @@
@Override
public int getMaxAirSupply() {
- return 6000;
+ return this.maxAirTicks; // CraftBukkit - SPIGOT-6907: re-implement LivingEntity#setMaximumAir()
}
@Override
@@ -426,10 +_,10 @@
if (effect == null || effect.endsWithin(2399)) {
int i = effect != null ? effect.getDuration() : 0;
int min = Math.min(2400, 100 + i);
- player.addEffect(new MobEffectInstance(MobEffects.REGENERATION, min, 0), this);
+ player.addEffect(new MobEffectInstance(MobEffects.REGENERATION, min, 0), this, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.AXOLOTL); // CraftBukkit
}
- player.removeEffect(MobEffects.DIG_SLOWDOWN);
+ player.removeEffect(MobEffects.DIG_SLOWDOWN, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.AXOLOTL); // Paper - Add missing effect cause
}
@Override
@@ -620,4 +_,11 @@
return Util.getRandom(variants, random);
}
}
+
+ // CraftBukkit start - SPIGOT-6907: re-implement LivingEntity#setMaximumAir()
+ @Override
+ public int getDefaultMaxAirSupply() {
+ return Axolotl.AXOLOTL_TOTAL_AIR_SUPPLY;
+ }
+ // CraftBukkit end
}

View file

@ -1,15 +1,6 @@
--- a/net/minecraft/world/entity/monster/breeze/Breeze.java
+++ b/net/minecraft/world/entity/monster/breeze/Breeze.java
@@ -77,7 +77,7 @@
@Override
public Brain<Breeze> getBrain() {
- return super.getBrain();
+ return (Brain<Breeze>) super.getBrain(); // CraftBukkit - decompile error
}
@Override
@@ -252,6 +252,7 @@
@@ -250,6 +_,7 @@
@Override
public boolean canAttackType(EntityType<?> type) {

View file

@ -0,0 +1,19 @@
--- a/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java
+++ b/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java
@@ -99,9 +_,14 @@
}
protected void finishConversion(ServerLevel serverLevel) {
- this.convertTo(
- EntityType.ZOMBIFIED_PIGLIN, ConversionParams.single(this, true, true), mob -> mob.addEffect(new MobEffectInstance(MobEffects.CONFUSION, 200, 0))
+ net.minecraft.world.entity.Entity converted = this.convertTo( // Paper - Fix issues with mob conversion; reset to prevent event spam
+ EntityType.ZOMBIFIED_PIGLIN, ConversionParams.single(this, true, true), mob -> {mob.addEffect(new MobEffectInstance(MobEffects.CONFUSION, 200, 0));}, org.bukkit.event.entity.EntityTransformEvent.TransformReason.PIGLIN_ZOMBIFIED, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.PIGLIN_ZOMBIFIED // CraftBukkit - add spawn and transform reasons
);
+ // Paper start - Fix issues with mob conversion; reset to prevent event spam
+ if (converted == null) {
+ this.timeInOverworld = 0;
+ }
+ // Paper end - Fix issues with mob conversion
}
public boolean isAdult() {

View file

@ -0,0 +1,119 @@
--- a/net/minecraft/world/entity/monster/piglin/Piglin.java
+++ b/net/minecraft/world/entity/monster/piglin/Piglin.java
@@ -4,15 +_,6 @@
import com.mojang.serialization.Dynamic;
import java.util.List;
import javax.annotation.Nullable;
-import net.minecraft.core.BlockPos;
-import net.minecraft.nbt.CompoundTag;
-import net.minecraft.network.syncher.EntityDataAccessor;
-import net.minecraft.network.syncher.EntityDataSerializers;
-import net.minecraft.network.syncher.SynchedEntityData;
-import net.minecraft.resources.ResourceLocation;
-import net.minecraft.server.level.ServerLevel;
-import net.minecraft.sounds.SoundEvent;
-import net.minecraft.sounds.SoundEvents;
import net.minecraft.tags.ItemTags;
import net.minecraft.tags.TagKey;
import net.minecraft.util.RandomSource;
@@ -59,6 +_,25 @@
import net.minecraft.world.level.ServerLevelAccessor;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
+// CraftBukkit start
+import java.util.stream.Collectors;
+import java.util.HashSet;
+import java.util.Set;
+import net.minecraft.core.BlockPos;
+import net.minecraft.core.registries.BuiltInRegistries;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.nbt.ListTag;
+import net.minecraft.nbt.StringTag;
+import net.minecraft.nbt.Tag;
+import net.minecraft.network.syncher.EntityDataAccessor;
+import net.minecraft.network.syncher.EntityDataSerializers;
+import net.minecraft.network.syncher.SynchedEntityData;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.sounds.SoundEvent;
+import net.minecraft.sounds.SoundEvents;
+import net.minecraft.world.item.Item;
+// CraftBukkit end
public class Piglin extends AbstractPiglin implements CrossbowAttackMob, InventoryCarrier {
private static final EntityDataAccessor<Boolean> DATA_BABY_ID = SynchedEntityData.defineId(Piglin.class, EntityDataSerializers.BOOLEAN);
@@ -122,6 +_,10 @@
MemoryModuleType.ATE_RECENTLY,
MemoryModuleType.NEAREST_REPELLENT
);
+ // CraftBukkit start - Custom bartering and interest list
+ public Set<Item> allowedBarterItems = new HashSet<>();
+ public Set<Item> interestItems = new HashSet<>();
+ // CraftBukkit end
public Piglin(EntityType<? extends AbstractPiglin> entityType, Level level) {
super(entityType, level);
@@ -140,6 +_,14 @@
}
this.writeInventoryToTag(compound, this.registryAccess());
+ // CraftBukkit start
+ ListTag barterList = new ListTag();
+ this.allowedBarterItems.stream().map(BuiltInRegistries.ITEM::getKey).map(ResourceLocation::toString).map(StringTag::valueOf).forEach(barterList::add);
+ compound.put("Bukkit.BarterList", barterList);
+ ListTag interestList = new ListTag();
+ this.interestItems.stream().map(BuiltInRegistries.ITEM::getKey).map(ResourceLocation::toString).map(StringTag::valueOf).forEach(interestList::add);
+ compound.put("Bukkit.InterestList", interestList);
+ // CraftBukkit end
}
@Override
@@ -148,6 +_,10 @@
this.setBaby(compound.getBoolean("IsBaby"));
this.setCannotHunt(compound.getBoolean("CannotHunt"));
this.readInventoryFromTag(compound, this.registryAccess());
+ // CraftBukkit start
+ this.allowedBarterItems = compound.getList("Bukkit.BarterList", 8).stream().map(Tag::getAsString).map(ResourceLocation::tryParse).map(BuiltInRegistries.ITEM::getValue).collect(Collectors.toCollection(HashSet::new));
+ this.interestItems = compound.getList("Bukkit.InterestList", 8).stream().map(Tag::getAsString).map(ResourceLocation::tryParse).map(BuiltInRegistries.ITEM::getValue).collect(Collectors.toCollection(HashSet::new));
+ // CraftBukkit end
}
@VisibleForDebug
@@ -325,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);
}
@@ -400,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 {
@@ -425,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);
}

View file

@ -0,0 +1,174 @@
--- a/net/minecraft/world/entity/monster/piglin/PiglinAi.java
+++ b/net/minecraft/world/entity/monster/piglin/PiglinAi.java
@@ -70,6 +_,13 @@
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.phys.Vec3;
+// CraftBukkit start
+import java.util.stream.Collectors;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
+import org.bukkit.event.entity.EntityRemoveEvent;
+import org.bukkit.event.entity.PiglinBarterEvent;
+// CraftBukkit end
public class PiglinAi {
public static final int REPELLENT_DETECTION_RANGE_HORIZONTAL = 8;
@@ -328,23 +_,32 @@
protected static void pickUpItem(ServerLevel level, Piglin piglin, ItemEntity itemEntity) {
stopWalking(piglin);
ItemStack item;
- if (itemEntity.getItem().is(Items.GOLD_NUGGET)) {
+ // CraftBukkit start
+ // Paper start - EntityPickupItemEvent fixes; fix event firing twice
+ if (itemEntity.getItem().is(Items.GOLD_NUGGET)/* && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(piglin, itemEntity, 0, false).isCancelled()*/) { // Paper
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(piglin, itemEntity, 0, false).isCancelled()) return;
+ piglin.onItemPickup(itemEntity); // Paper - moved from Piglin#pickUpItem - call prior to item entity modification
+ // Paper end
piglin.take(itemEntity, itemEntity.getItem().getCount());
item = itemEntity.getItem();
- itemEntity.discard();
- } else {
+ itemEntity.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause
+ } else if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(piglin, itemEntity, itemEntity.getItem().getCount() - 1, false).isCancelled()) {
+ piglin.onItemPickup(itemEntity); // Paper - EntityPickupItemEvent fixes; moved from Piglin#pickUpItem - call prior to item entity modification
piglin.take(itemEntity, 1);
item = removeOneItemFromItemEntity(itemEntity);
+ } else {
+ return;
+ // CraftBukkit end
}
- if (isLovedItem(item)) {
+ if (isLovedItem(item, piglin)) { // CraftBukkit - Changes to allow for custom payment in bartering
piglin.getBrain().eraseMemory(MemoryModuleType.TIME_TRYING_TO_REACH_ADMIRE_ITEM);
holdInOffhand(level, piglin, item);
admireGoldItem(piglin);
} else if (isFood(item) && !hasEatenRecently(piglin)) {
eat(piglin);
} else {
- boolean flag = !piglin.equipItemIfPossible(level, item).equals(ItemStack.EMPTY);
+ boolean flag = !piglin.equipItemIfPossible(level, item, null).equals(ItemStack.EMPTY); // CraftBukkit // Paper - pass null item entity to prevent duplicate pickup item event call - called above.
if (!flag) {
putInInventory(piglin, item);
}
@@ -353,7 +_,9 @@
private static void holdInOffhand(ServerLevel level, Piglin piglin, ItemStack stack) {
if (isHoldingItemInOffHand(piglin)) {
+ piglin.forceDrops = true; // Paper - Add missing forceDrop toggles
piglin.spawnAtLocation(level, piglin.getItemInHand(InteractionHand.OFF_HAND));
+ piglin.forceDrops = false; // Paper - Add missing forceDrop toggles
}
piglin.holdInOffHand(stack);
@@ -363,7 +_,7 @@
ItemStack item = itemEntity.getItem();
ItemStack itemStack = item.split(1);
if (item.isEmpty()) {
- itemEntity.discard();
+ itemEntity.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause
} else {
itemEntity.setItem(item);
}
@@ -375,9 +_,14 @@
ItemStack itemInHand = piglin.getItemInHand(InteractionHand.OFF_HAND);
piglin.setItemInHand(InteractionHand.OFF_HAND, ItemStack.EMPTY);
if (piglin.isAdult()) {
- boolean isBarterCurrency = isBarterCurrency(itemInHand);
+ boolean isBarterCurrency = isBarterCurrency(itemInHand, piglin); // CraftBukkit - Changes to allow custom payment for bartering
if (barter && isBarterCurrency) {
- throwItems(piglin, getBarterResponseItems(piglin));
+ // CraftBukkit start
+ PiglinBarterEvent event = CraftEventFactory.callPiglinBarterEvent(piglin, getBarterResponseItems(piglin), itemInHand);
+ if (!event.isCancelled()) {
+ throwItems(piglin, event.getOutcome().stream().map(CraftItemStack::asNMSCopy).collect(Collectors.toList()));
+ }
+ // CraftBukkit end
} else if (!isBarterCurrency) {
boolean flag = !piglin.equipItemIfPossible(level, itemInHand).isEmpty();
if (!flag) {
@@ -388,7 +_,7 @@
boolean isBarterCurrency = !piglin.equipItemIfPossible(level, itemInHand).isEmpty();
if (!isBarterCurrency) {
ItemStack mainHandItem = piglin.getMainHandItem();
- if (isLovedItem(mainHandItem)) {
+ if (isLovedItem(mainHandItem, piglin)) { // CraftBukkit - Changes to allow for custom payment in bartering
putInInventory(piglin, mainHandItem);
} else {
throwItems(piglin, Collections.singletonList(mainHandItem));
@@ -401,7 +_,9 @@
protected static void cancelAdmiring(ServerLevel level, Piglin piglin) {
if (isAdmiringItem(piglin) && !piglin.getOffhandItem().isEmpty()) {
+ piglin.forceDrops = true; // Paper - Add missing forceDrop toggles
piglin.spawnAtLocation(level, piglin.getOffhandItem());
+ piglin.forceDrops = false; // Paper - Add missing forceDrop toggles
piglin.setItemInHand(InteractionHand.OFF_HAND, ItemStack.EMPTY);
}
}
@@ -457,7 +_,7 @@
return false;
} else if (isAdmiringDisabled(piglin) && piglin.getBrain().hasMemoryValue(MemoryModuleType.ATTACK_TARGET)) {
return false;
- } else if (isBarterCurrency(stack)) {
+ } else if (isBarterCurrency(stack, piglin)) { // CraftBukkit
return isNotHoldingLovedItemInOffHand(piglin);
} else {
boolean canAddToInventory = piglin.canAddToInventory(stack);
@@ -466,11 +_,16 @@
} else if (isFood(stack)) {
return !hasEatenRecently(piglin) && canAddToInventory;
} else {
- return !isLovedItem(stack) ? piglin.canReplaceCurrentItem(stack) : isNotHoldingLovedItemInOffHand(piglin) && canAddToInventory;
+ return !isLovedItem(stack, piglin) ? piglin.canReplaceCurrentItem(stack) : isNotHoldingLovedItemInOffHand(piglin) && canAddToInventory; // Paper - upstream missed isLovedItem check
}
}
}
+ // CraftBukkit start - Added method to allow checking for custom payment items
+ protected static boolean isLovedItem(ItemStack item, Piglin piglin) {
+ return PiglinAi.isLovedItem(item) || (piglin.interestItems.contains(item.getItem()) || piglin.allowedBarterItems.contains(item.getItem()));
+ }
+ // CraftBukkit end
protected static boolean isLovedItem(ItemStack item) {
return item.is(ItemTags.PIGLIN_LOVED);
}
@@ -522,6 +_,7 @@
}
public static void angerNearbyPiglins(ServerLevel level, Player player, boolean requireLineOfSight) {
+ if (!player.level().paperConfig().entities.behavior.piglinsGuardChests) return; // Paper - Config option for Piglins guarding chests
List<Piglin> entitiesOfClass = player.level().getEntitiesOfClass(Piglin.class, player.getBoundingBox().inflate(16.0));
entitiesOfClass.stream().filter(PiglinAi::isIdle).filter(piglin -> !requireLineOfSight || BehaviorUtils.canSee(piglin, player)).forEach(piglin -> {
if (level.getGameRules().getBoolean(GameRules.RULE_UNIVERSAL_ANGER)) {
@@ -546,7 +_,7 @@
}
protected static boolean canAdmire(Piglin piglin, ItemStack stack) {
- return !isAdmiringDisabled(piglin) && !isAdmiringItem(piglin) && piglin.isAdult() && isBarterCurrency(stack);
+ return !isAdmiringDisabled(piglin) && !isAdmiringItem(piglin) && piglin.isAdult() && isBarterCurrency(stack, piglin); // CraftBukkit
}
protected static void wasHurtBy(ServerLevel level, Piglin piglin, LivingEntity entity) {
@@ -794,6 +_,11 @@
return piglin.getBrain().hasMemoryValue(MemoryModuleType.ADMIRING_ITEM);
}
+ // CraftBukkit start - Changes to allow custom payment for bartering
+ private static boolean isBarterCurrency(ItemStack item, Piglin piglin) {
+ return PiglinAi.isBarterCurrency(item) || piglin.allowedBarterItems.contains(item.getItem());
+ }
+ // CraftBukkit end
private static boolean isBarterCurrency(ItemStack stack) {
return stack.is(BARTERING_ITEM);
}
@@ -831,7 +_,7 @@
}
private static boolean isNotHoldingLovedItemInOffHand(Piglin piglin) {
- return piglin.getOffhandItem().isEmpty() || !isLovedItem(piglin.getOffhandItem());
+ return piglin.getOffhandItem().isEmpty() || !isLovedItem(piglin.getOffhandItem(), piglin); // CraftBukkit - Changes to allow custom payment for bartering
}
public static boolean isZombified(EntityType<?> entityType) {

View file

@ -1,52 +0,0 @@
--- a/net/minecraft/world/entity/animal/axolotl/Axolotl.java
+++ b/net/minecraft/world/entity/animal/axolotl/Axolotl.java
@@ -67,10 +67,17 @@
public class Axolotl extends Animal implements VariantHolder<Axolotl.Variant>, Bucketable {
+ // CraftBukkit start - SPIGOT-6907: re-implement LivingEntity#setMaximumAir()
+ @Override
+ public int getDefaultMaxAirSupply() {
+ return Axolotl.AXOLOTL_TOTAL_AIR_SUPPLY;
+ }
+ // CraftBukkit end
public static final int TOTAL_PLAYDEAD_TIME = 200;
private static final int POSE_ANIMATION_TICKS = 10;
protected static final ImmutableList<? extends SensorType<? extends Sensor<? super Axolotl>>> SENSOR_TYPES = ImmutableList.of(SensorType.NEAREST_LIVING_ENTITIES, SensorType.NEAREST_ADULT, SensorType.HURT_BY, SensorType.AXOLOTL_ATTACKABLES, SensorType.AXOLOTL_TEMPTATIONS);
- protected static final ImmutableList<? extends MemoryModuleType<?>> MEMORY_TYPES = ImmutableList.of(MemoryModuleType.BREED_TARGET, MemoryModuleType.NEAREST_LIVING_ENTITIES, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.NEAREST_VISIBLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER, MemoryModuleType.LOOK_TARGET, MemoryModuleType.WALK_TARGET, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.PATH, MemoryModuleType.ATTACK_TARGET, MemoryModuleType.ATTACK_COOLING_DOWN, MemoryModuleType.NEAREST_VISIBLE_ADULT, new MemoryModuleType[]{MemoryModuleType.HURT_BY_ENTITY, MemoryModuleType.PLAY_DEAD_TICKS, MemoryModuleType.NEAREST_ATTACKABLE, MemoryModuleType.TEMPTING_PLAYER, MemoryModuleType.TEMPTATION_COOLDOWN_TICKS, MemoryModuleType.IS_TEMPTED, MemoryModuleType.HAS_HUNTING_COOLDOWN, MemoryModuleType.IS_PANICKING});
+ // CraftBukkit - decompile error
+ protected static final ImmutableList<? extends MemoryModuleType<?>> MEMORY_TYPES = ImmutableList.<MemoryModuleType<?>>of(MemoryModuleType.BREED_TARGET, MemoryModuleType.NEAREST_LIVING_ENTITIES, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.NEAREST_VISIBLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER, MemoryModuleType.LOOK_TARGET, MemoryModuleType.WALK_TARGET, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.PATH, MemoryModuleType.ATTACK_TARGET, MemoryModuleType.ATTACK_COOLING_DOWN, MemoryModuleType.NEAREST_VISIBLE_ADULT, new MemoryModuleType[]{MemoryModuleType.HURT_BY_ENTITY, MemoryModuleType.PLAY_DEAD_TICKS, MemoryModuleType.NEAREST_ATTACKABLE, MemoryModuleType.TEMPTING_PLAYER, MemoryModuleType.TEMPTATION_COOLDOWN_TICKS, MemoryModuleType.IS_TEMPTED, MemoryModuleType.HAS_HUNTING_COOLDOWN, MemoryModuleType.IS_PANICKING});
private static final EntityDataAccessor<Integer> DATA_VARIANT = SynchedEntityData.defineId(Axolotl.class, EntityDataSerializers.INT);
private static final EntityDataAccessor<Boolean> DATA_PLAYING_DEAD = SynchedEntityData.defineId(Axolotl.class, EntityDataSerializers.BOOLEAN);
private static final EntityDataAccessor<Boolean> FROM_BUCKET = SynchedEntityData.defineId(Axolotl.class, EntityDataSerializers.BOOLEAN);
@@ -210,7 +217,7 @@
@Override
public int getMaxAirSupply() {
- return 6000;
+ return this.maxAirTicks; // CraftBukkit - SPIGOT-6907: re-implement LivingEntity#setMaximumAir()
}
@Override
@@ -414,10 +421,10 @@
int i = mobeffect != null ? mobeffect.getDuration() : 0;
int j = Math.min(2400, 100 + i);
- player.addEffect(new MobEffectInstance(MobEffects.REGENERATION, j, 0), this);
+ player.addEffect(new MobEffectInstance(MobEffects.REGENERATION, j, 0), this, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.AXOLOTL); // CraftBukkit
}
- player.removeEffect(MobEffects.DIG_SLOWDOWN);
+ player.removeEffect(MobEffects.DIG_SLOWDOWN, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.AXOLOTL); // Paper - Add missing effect cause
}
@Override
@@ -464,7 +471,7 @@
@Override
public Brain<Axolotl> getBrain() {
- return super.getBrain();
+ return (Brain<Axolotl>) super.getBrain(); // CraftBukkit - decompile error
}
@Override

View file

@ -1,20 +0,0 @@
--- a/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java
+++ b/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java
@@ -100,9 +100,15 @@
}
protected void finishConversion(ServerLevel world) {
- this.convertTo(EntityType.ZOMBIFIED_PIGLIN, ConversionParams.single(this, true, true), (entitypigzombie) -> {
+ net.minecraft.world.entity.Entity converted = this.convertTo(EntityType.ZOMBIFIED_PIGLIN, ConversionParams.single(this, true, true), (entitypigzombie) -> { // Paper - Fix issues with mob conversion; reset to prevent event spam
entitypigzombie.addEffect(new MobEffectInstance(MobEffects.CONFUSION, 200, 0));
- });
+ }, org.bukkit.event.entity.EntityTransformEvent.TransformReason.PIGLIN_ZOMBIFIED, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.PIGLIN_ZOMBIFIED); // CraftBukkit - add spawn and transform reasons
+
+ // Paper start - Fix issues with mob conversion; reset to prevent event spam
+ if (converted == null) {
+ this.timeInOverworld = 0;
+ }
+ // Paper end - Fix issues with mob conversion
}
public boolean isAdult() {

View file

@ -1,140 +0,0 @@
--- a/net/minecraft/world/entity/monster/piglin/Piglin.java
+++ b/net/minecraft/world/entity/monster/piglin/Piglin.java
@@ -4,15 +4,6 @@
import com.mojang.serialization.Dynamic;
import java.util.List;
import javax.annotation.Nullable;
-import net.minecraft.core.BlockPos;
-import net.minecraft.nbt.CompoundTag;
-import net.minecraft.network.syncher.EntityDataAccessor;
-import net.minecraft.network.syncher.EntityDataSerializers;
-import net.minecraft.network.syncher.SynchedEntityData;
-import net.minecraft.resources.ResourceLocation;
-import net.minecraft.server.level.ServerLevel;
-import net.minecraft.sounds.SoundEvent;
-import net.minecraft.sounds.SoundEvents;
import net.minecraft.tags.ItemTags;
import net.minecraft.tags.TagKey;
import net.minecraft.util.RandomSource;
@@ -59,6 +50,25 @@
import net.minecraft.world.level.ServerLevelAccessor;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
+// CraftBukkit start
+import java.util.stream.Collectors;
+import java.util.HashSet;
+import java.util.Set;
+import net.minecraft.core.BlockPos;
+import net.minecraft.core.registries.BuiltInRegistries;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.nbt.ListTag;
+import net.minecraft.nbt.StringTag;
+import net.minecraft.nbt.Tag;
+import net.minecraft.network.syncher.EntityDataAccessor;
+import net.minecraft.network.syncher.EntityDataSerializers;
+import net.minecraft.network.syncher.SynchedEntityData;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.sounds.SoundEvent;
+import net.minecraft.sounds.SoundEvents;
+import net.minecraft.world.item.Item;
+// CraftBukkit end
public class Piglin extends AbstractPiglin implements CrossbowAttackMob, InventoryCarrier {
@@ -79,6 +89,10 @@
public boolean cannotHunt;
protected static final ImmutableList<SensorType<? extends Sensor<? super Piglin>>> SENSOR_TYPES = ImmutableList.of(SensorType.NEAREST_LIVING_ENTITIES, SensorType.NEAREST_PLAYERS, SensorType.NEAREST_ITEMS, SensorType.HURT_BY, SensorType.PIGLIN_SPECIFIC_SENSOR);
protected static final ImmutableList<MemoryModuleType<?>> MEMORY_TYPES = ImmutableList.of(MemoryModuleType.LOOK_TARGET, MemoryModuleType.DOORS_TO_CLOSE, MemoryModuleType.NEAREST_LIVING_ENTITIES, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.NEAREST_VISIBLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_ADULT_PIGLINS, MemoryModuleType.NEARBY_ADULT_PIGLINS, MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM, MemoryModuleType.ITEM_PICKUP_COOLDOWN_TICKS, MemoryModuleType.HURT_BY, MemoryModuleType.HURT_BY_ENTITY, new MemoryModuleType[]{MemoryModuleType.WALK_TARGET, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.ATTACK_TARGET, MemoryModuleType.ATTACK_COOLING_DOWN, MemoryModuleType.INTERACTION_TARGET, MemoryModuleType.PATH, MemoryModuleType.ANGRY_AT, MemoryModuleType.UNIVERSAL_ANGER, MemoryModuleType.AVOID_TARGET, MemoryModuleType.ADMIRING_ITEM, MemoryModuleType.TIME_TRYING_TO_REACH_ADMIRE_ITEM, MemoryModuleType.ADMIRING_DISABLED, MemoryModuleType.DISABLE_WALK_TO_ADMIRE_ITEM, MemoryModuleType.CELEBRATE_LOCATION, MemoryModuleType.DANCING, MemoryModuleType.HUNTED_RECENTLY, MemoryModuleType.NEAREST_VISIBLE_BABY_HOGLIN, MemoryModuleType.NEAREST_VISIBLE_NEMESIS, MemoryModuleType.NEAREST_VISIBLE_ZOMBIFIED, MemoryModuleType.RIDE_TARGET, MemoryModuleType.VISIBLE_ADULT_PIGLIN_COUNT, MemoryModuleType.VISIBLE_ADULT_HOGLIN_COUNT, MemoryModuleType.NEAREST_VISIBLE_HUNTABLE_HOGLIN, MemoryModuleType.NEAREST_TARGETABLE_PLAYER_NOT_WEARING_GOLD, MemoryModuleType.NEAREST_PLAYER_HOLDING_WANTED_ITEM, MemoryModuleType.ATE_RECENTLY, MemoryModuleType.NEAREST_REPELLENT});
+ // CraftBukkit start - Custom bartering and interest list
+ public Set<Item> allowedBarterItems = new HashSet<>();
+ public Set<Item> interestItems = new HashSet<>();
+ // CraftBukkit end
public Piglin(EntityType<? extends AbstractPiglin> type, Level world) {
super(type, world);
@@ -97,6 +111,14 @@
}
this.writeInventoryToTag(nbt, this.registryAccess());
+ // CraftBukkit start
+ ListTag barterList = new ListTag();
+ this.allowedBarterItems.stream().map(BuiltInRegistries.ITEM::getKey).map(ResourceLocation::toString).map(StringTag::valueOf).forEach(barterList::add);
+ nbt.put("Bukkit.BarterList", barterList);
+ ListTag interestList = new ListTag();
+ this.interestItems.stream().map(BuiltInRegistries.ITEM::getKey).map(ResourceLocation::toString).map(StringTag::valueOf).forEach(interestList::add);
+ nbt.put("Bukkit.InterestList", interestList);
+ // CraftBukkit end
}
@Override
@@ -105,6 +127,10 @@
this.setBaby(nbt.getBoolean("IsBaby"));
this.setCannotHunt(nbt.getBoolean("CannotHunt"));
this.readInventoryFromTag(nbt, this.registryAccess());
+ // CraftBukkit start
+ this.allowedBarterItems = nbt.getList("Bukkit.BarterList", 8).stream().map(Tag::getAsString).map(ResourceLocation::tryParse).map(BuiltInRegistries.ITEM::getValue).collect(Collectors.toCollection(HashSet::new));
+ this.interestItems = nbt.getList("Bukkit.InterestList", 8).stream().map(Tag::getAsString).map(ResourceLocation::tryParse).map(BuiltInRegistries.ITEM::getValue).collect(Collectors.toCollection(HashSet::new));
+ // CraftBukkit end
}
@VisibleForDebug
@@ -224,7 +250,7 @@
@Override
public Brain<Piglin> getBrain() {
- return super.getBrain();
+ return (Brain<Piglin>) super.getBrain(); // CraftBukkit - Decompile error
}
@Override
@@ -300,9 +326,11 @@
@Override
protected void finishConversion(ServerLevel world) {
PiglinAi.cancelAdmiring(world, this);
+ this.forceDrops = true; // Paper - Add missing forceDrop toggles
this.inventory.removeAllItems().forEach((itemstack) -> {
this.spawnAtLocation(world, itemstack);
});
+ this.forceDrops = false; // Paper - Add missing forceDrop toggles
super.finishConversion(world);
}
@@ -374,7 +402,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 {
@@ -401,8 +429,8 @@
return false;
} else {
TagKey<Item> tagkey = this.getPreferredWeaponType();
- boolean flag = PiglinAi.isLovedItem(newStack) || tagkey != null && newStack.is(tagkey);
- boolean flag1 = PiglinAi.isLovedItem(currentStack) || tagkey != null && currentStack.is(tagkey);
+ boolean flag = PiglinAi.isLovedItem(newStack, this) || tagkey != null && newStack.is(tagkey); // CraftBukkit
+ boolean flag1 = PiglinAi.isLovedItem(currentStack, this) || tagkey != null && currentStack.is(tagkey); // CraftBukkit
return flag && !flag1 ? true : (!flag && flag1 ? false : super.canReplaceCurrentItem(newStack, currentStack, slot));
}
@@ -410,7 +438,7 @@
@Override
protected void pickUpItem(ServerLevel world, ItemEntity itemEntity) {
- this.onItemPickup(itemEntity);
+ // this.onItemPickup(itemEntity); // Paper - EntityPickupItemEvent fixes; call in PiglinAi#pickUpItem after EntityPickupItemEvent is fired
PiglinAi.pickUpItem(world, this, itemEntity);
}
@@ -431,7 +459,7 @@
@Override
protected SoundEvent getAmbientSound() {
- return this.level().isClientSide ? null : (SoundEvent) PiglinAi.getSoundForCurrentActivity(this).orElse((Object) null);
+ return this.level().isClientSide ? null : (SoundEvent) PiglinAi.getSoundForCurrentActivity(this).orElse(null); // CraftBukkit - Decompile error
}
@Override

View file

@ -1,210 +0,0 @@
--- a/net/minecraft/world/entity/monster/piglin/PiglinAi.java
+++ b/net/minecraft/world/entity/monster/piglin/PiglinAi.java
@@ -71,6 +71,13 @@
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.phys.Vec3;
+// CraftBukkit start
+import java.util.stream.Collectors;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
+import org.bukkit.event.entity.EntityRemoveEvent;
+import org.bukkit.event.entity.PiglinBarterEvent;
+// CraftBukkit end
public class PiglinAi {
@@ -166,7 +173,8 @@
}
private static void initRideHoglinActivity(Brain<Piglin> brain) {
- brain.addActivityAndRemoveMemoryWhenStopped(Activity.RIDE, 10, ImmutableList.of(Mount.create(0.8F), SetEntityLookTarget.create(PiglinAi::isPlayerHoldingLovedItem, 8.0F), BehaviorBuilder.sequence(BehaviorBuilder.triggerIf(Entity::isPassenger), TriggerGate.triggerOneShuffled(ImmutableList.builder().addAll(PiglinAi.createLookBehaviors()).add(Pair.of(BehaviorBuilder.triggerIf((entitypiglin) -> {
+ // CraftBukkit - decompile error
+ brain.addActivityAndRemoveMemoryWhenStopped(Activity.RIDE, 10, ImmutableList.of(Mount.create(0.8F), SetEntityLookTarget.create(PiglinAi::isPlayerHoldingLovedItem, 8.0F), BehaviorBuilder.sequence(BehaviorBuilder.triggerIf(Entity::isPassenger), TriggerGate.triggerOneShuffled(ImmutableList.<Pair<? extends net.minecraft.world.entity.ai.behavior.declarative.Trigger<? super LivingEntity>, Integer>>builder().addAll(PiglinAi.createLookBehaviors()).add(Pair.of(BehaviorBuilder.triggerIf((entitypiglin) -> {
return true;
}), 1)).build())), DismountOrSkipMounting.create(8, PiglinAi::wantsToStopRiding)), MemoryModuleType.RIDE_TARGET);
}
@@ -176,7 +184,7 @@
}
private static RunOne<LivingEntity> createIdleLookBehaviors() {
- return new RunOne<>(ImmutableList.builder().addAll(PiglinAi.createLookBehaviors()).add(Pair.of(new DoNothing(30, 60), 1)).build());
+ return new RunOne<>(ImmutableList.<Pair<? extends BehaviorControl<? super LivingEntity>, Integer>>builder().addAll(PiglinAi.createLookBehaviors()).add(Pair.of(new DoNothing(30, 60), 1)).build()); // CraftBukkit - decompile error
}
private static RunOne<Piglin> createIdleMovementBehaviors() {
@@ -197,13 +205,13 @@
protected static void updateActivity(Piglin piglin) {
Brain<Piglin> behaviorcontroller = piglin.getBrain();
- Activity activity = (Activity) behaviorcontroller.getActiveNonCoreActivity().orElse((Object) null);
+ Activity activity = (Activity) behaviorcontroller.getActiveNonCoreActivity().orElse(null); // CraftBukkit - decompile error
behaviorcontroller.setActiveActivityToFirstValid(ImmutableList.of(Activity.ADMIRE_ITEM, Activity.FIGHT, Activity.AVOID, Activity.CELEBRATE, Activity.RIDE, Activity.IDLE));
- Activity activity1 = (Activity) behaviorcontroller.getActiveNonCoreActivity().orElse((Object) null);
+ Activity activity1 = (Activity) behaviorcontroller.getActiveNonCoreActivity().orElse(null); // CraftBukkit - decompile error
if (activity != activity1) {
- Optional optional = PiglinAi.getSoundForCurrentActivity(piglin);
+ Optional<SoundEvent> optional = PiglinAi.getSoundForCurrentActivity(piglin); // CraftBukkit - decompile error
Objects.requireNonNull(piglin);
optional.ifPresent(piglin::makeSound);
@@ -235,23 +243,32 @@
PiglinAi.stopWalking(piglin);
ItemStack itemstack;
- if (itemEntity.getItem().is(Items.GOLD_NUGGET)) {
- piglin.take(itemEntity, itemEntity.getItem().getCount());
- itemstack = itemEntity.getItem();
- itemEntity.discard();
- } else {
+ // CraftBukkit start
+ // Paper start - EntityPickupItemEvent fixes; fix event firing twice
+ if (itemEntity.getItem().is(Items.GOLD_NUGGET)/* && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(piglin, itemEntity, 0, false).isCancelled()*/) { // Paper
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(piglin, itemEntity, 0, false).isCancelled()) return;
+ piglin.onItemPickup(itemEntity); // Paper - moved from Piglin#pickUpItem - call prior to item entity modification
+ // Paper end
+ piglin.take(itemEntity, itemEntity.getItem().getCount());
+ itemstack = itemEntity.getItem();
+ itemEntity.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause
+ } else if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(piglin, itemEntity, itemEntity.getItem().getCount() - 1, false).isCancelled()) {
+ piglin.onItemPickup(itemEntity); // Paper - EntityPickupItemEvent fixes; moved from Piglin#pickUpItem - call prior to item entity modification
piglin.take(itemEntity, 1);
itemstack = PiglinAi.removeOneItemFromItemEntity(itemEntity);
+ } else {
+ return;
}
+ // CraftBukkit end
- if (PiglinAi.isLovedItem(itemstack)) {
+ if (PiglinAi.isLovedItem(itemstack, piglin)) { // CraftBukkit - Changes to allow for custom payment in bartering
piglin.getBrain().eraseMemory(MemoryModuleType.TIME_TRYING_TO_REACH_ADMIRE_ITEM);
PiglinAi.holdInOffhand(world, piglin, itemstack);
PiglinAi.admireGoldItem(piglin);
} else if (PiglinAi.isFood(itemstack) && !PiglinAi.hasEatenRecently(piglin)) {
PiglinAi.eat(piglin);
} else {
- boolean flag = !piglin.equipItemIfPossible(world, itemstack).equals(ItemStack.EMPTY);
+ boolean flag = !piglin.equipItemIfPossible(world, itemstack, null).equals(ItemStack.EMPTY); // CraftBukkit // Paper - pass null item entity to prevent duplicate pickup item event call - called above.
if (!flag) {
PiglinAi.putInInventory(piglin, itemstack);
@@ -261,7 +278,9 @@
private static void holdInOffhand(ServerLevel world, Piglin piglin, ItemStack stack) {
if (PiglinAi.isHoldingItemInOffHand(piglin)) {
+ piglin.forceDrops = true; // Paper - Add missing forceDrop toggles
piglin.spawnAtLocation(world, piglin.getItemInHand(InteractionHand.OFF_HAND));
+ piglin.forceDrops = false; // Paper - Add missing forceDrop toggles
}
piglin.holdInOffHand(stack);
@@ -272,7 +291,7 @@
ItemStack itemstack1 = itemstack.split(1);
if (itemstack.isEmpty()) {
- stack.discard();
+ stack.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause
} else {
stack.setItem(itemstack);
}
@@ -287,9 +306,14 @@
boolean flag1;
if (piglin.isAdult()) {
- flag1 = PiglinAi.isBarterCurrency(itemstack);
+ flag1 = PiglinAi.isBarterCurrency(itemstack, piglin); // CraftBukkit - Changes to allow custom payment for bartering
if (barter && flag1) {
- PiglinAi.throwItems(piglin, PiglinAi.getBarterResponseItems(piglin));
+ // CraftBukkit start
+ PiglinBarterEvent event = CraftEventFactory.callPiglinBarterEvent(piglin, PiglinAi.getBarterResponseItems(piglin), itemstack);
+ if (!event.isCancelled()) {
+ PiglinAi.throwItems(piglin, event.getOutcome().stream().map(CraftItemStack::asNMSCopy).collect(Collectors.toList()));
+ }
+ // CraftBukkit end
} else if (!flag1) {
boolean flag2 = !piglin.equipItemIfPossible(world, itemstack).isEmpty();
@@ -302,7 +326,7 @@
if (!flag1) {
ItemStack itemstack1 = piglin.getMainHandItem();
- if (PiglinAi.isLovedItem(itemstack1)) {
+ if (PiglinAi.isLovedItem(itemstack1, piglin)) { // CraftBukkit - Changes to allow for custom payment in bartering
PiglinAi.putInInventory(piglin, itemstack1);
} else {
PiglinAi.throwItems(piglin, Collections.singletonList(itemstack1));
@@ -316,7 +340,9 @@
protected static void cancelAdmiring(ServerLevel world, Piglin piglin) {
if (PiglinAi.isAdmiringItem(piglin) && !piglin.getOffhandItem().isEmpty()) {
+ piglin.forceDrops = true; // Paper - Add missing forceDrop toggles
piglin.spawnAtLocation(world, piglin.getOffhandItem());
+ piglin.forceDrops = false; // Paper - Add missing forceDrop toggles
piglin.setItemInHand(InteractionHand.OFF_HAND, ItemStack.EMPTY);
}
@@ -379,15 +405,21 @@
return false;
} else if (PiglinAi.isAdmiringDisabled(piglin) && piglin.getBrain().hasMemoryValue(MemoryModuleType.ATTACK_TARGET)) {
return false;
- } else if (PiglinAi.isBarterCurrency(stack)) {
+ } else if (PiglinAi.isBarterCurrency(stack, piglin)) { // CraftBukkit
return PiglinAi.isNotHoldingLovedItemInOffHand(piglin);
} else {
boolean flag = piglin.canAddToInventory(stack);
- return stack.is(Items.GOLD_NUGGET) ? flag : (PiglinAi.isFood(stack) ? !PiglinAi.hasEatenRecently(piglin) && flag : (!PiglinAi.isLovedItem(stack) ? piglin.canReplaceCurrentItem(stack) : PiglinAi.isNotHoldingLovedItemInOffHand(piglin) && flag));
+ return stack.is(Items.GOLD_NUGGET) ? flag : (PiglinAi.isFood(stack) ? !PiglinAi.hasEatenRecently(piglin) && flag : (!PiglinAi.isLovedItem(stack, piglin) ? piglin.canReplaceCurrentItem(stack) : PiglinAi.isNotHoldingLovedItemInOffHand(piglin) && flag)); // Paper - upstream missed isLovedItem check
}
}
+ // CraftBukkit start - Added method to allow checking for custom payment items
+ protected static boolean isLovedItem(ItemStack itemstack, Piglin piglin) {
+ return PiglinAi.isLovedItem(itemstack) || (piglin.interestItems.contains(itemstack.getItem()) || piglin.allowedBarterItems.contains(itemstack.getItem()));
+ }
+ // CraftBukkit end
+
protected static boolean isLovedItem(ItemStack stack) {
return stack.is(ItemTags.PIGLIN_LOVED);
}
@@ -451,6 +483,7 @@
}
public static void angerNearbyPiglins(ServerLevel world, Player player, boolean blockOpen) {
+ if (!player.level().paperConfig().entities.behavior.piglinsGuardChests) return; // Paper - Config option for Piglins guarding chests
List<Piglin> list = player.level().getEntitiesOfClass(Piglin.class, player.getBoundingBox().inflate(16.0D));
list.stream().filter(PiglinAi::isIdle).filter((entitypiglin) -> {
@@ -481,7 +514,7 @@
}
protected static boolean canAdmire(Piglin piglin, ItemStack nearbyItems) {
- return !PiglinAi.isAdmiringDisabled(piglin) && !PiglinAi.isAdmiringItem(piglin) && piglin.isAdult() && PiglinAi.isBarterCurrency(nearbyItems);
+ return !PiglinAi.isAdmiringDisabled(piglin) && !PiglinAi.isAdmiringItem(piglin) && piglin.isAdult() && PiglinAi.isBarterCurrency(nearbyItems, piglin); // CraftBukkit
}
protected static void wasHurtBy(ServerLevel world, Piglin piglin, LivingEntity attacker) {
@@ -735,6 +768,12 @@
return entity.getBrain().hasMemoryValue(MemoryModuleType.ADMIRING_ITEM);
}
+ // CraftBukkit start - Changes to allow custom payment for bartering
+ private static boolean isBarterCurrency(ItemStack itemstack, Piglin piglin) {
+ return PiglinAi.isBarterCurrency(itemstack) || piglin.allowedBarterItems.contains(itemstack.getItem());
+ }
+ // CraftBukkit end
+
private static boolean isBarterCurrency(ItemStack stack) {
return stack.is(PiglinAi.BARTERING_ITEM);
}
@@ -772,7 +811,7 @@
}
private static boolean isNotHoldingLovedItemInOffHand(Piglin piglin) {
- return piglin.getOffhandItem().isEmpty() || !PiglinAi.isLovedItem(piglin.getOffhandItem());
+ return piglin.getOffhandItem().isEmpty() || !PiglinAi.isLovedItem(piglin.getOffhandItem(), piglin); // CraftBukkit - Changes to allow custom payment for bartering
}
public static boolean isZombified(EntityType<?> entityType) {