--- a/net/minecraft/world/entity/npc/WanderingTrader.java +++ b/net/minecraft/world/entity/npc/WanderingTrader.java @@ -10,7 +10,7 @@ import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; import net.minecraft.stats.Stats; -import net.minecraft.world.InteractionHand; +import net.minecraft.world.EnumHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.AgeableMob; @@ -20,11 +20,11 @@ import net.minecraft.world.entity.ai.goal.AvoidEntityGoal; import net.minecraft.world.entity.ai.goal.FloatGoal; import net.minecraft.world.entity.ai.goal.Goal; -import net.minecraft.world.entity.ai.goal.InteractGoal; 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.PathfinderGoalInteract; import net.minecraft.world.entity.ai.goal.TradeWithPlayerGoal; import net.minecraft.world.entity.ai.goal.UseItemGoal; import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal; @@ -47,26 +47,33 @@ import net.minecraft.world.phys.Vec3; import org.apache.commons.lang3.tuple.Pair; -public class WanderingTrader extends AbstractVillager { +// CraftBukkit start +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.inventory.CraftMerchantRecipe; +import org.bukkit.entity.AbstractVillager; +import org.bukkit.event.entity.VillagerAcquireTradeEvent; +// CraftBukkit end +public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVillager { + private static final int NUMBER_OF_TRADE_OFFERS = 5; @Nullable private BlockPos wanderTarget; private int despawnDelay; - public WanderingTrader(EntityType entitytype, Level level) { - super(entitytype, level); + public WanderingTrader(EntityType entityType, Level level) { + super(entityType, level); + this.setDespawnDelay(48000); // CraftBukkit - set default from MobSpawnerTrader } @Override - @Override protected void registerGoals() { this.goalSelector.addGoal(0, new FloatGoal(this)); - this.goalSelector.addGoal(0, new UseItemGoal<>(this, PotionUtils.setPotion(new ItemStack(Items.POTION), Potions.INVISIBILITY), SoundEvents.WANDERING_TRADER_DISAPPEARED, (wanderingtrader) -> { - return this.level().isNight() && !wanderingtrader.isInvisible(); + this.goalSelector.addGoal(0, new UseItemGoal<>(this, PotionUtils.setPotion(new ItemStack(Items.POTION), Potions.INVISIBILITY), SoundEvents.WANDERING_TRADER_DISAPPEARED, (entityvillagertrader) -> { + return this.level().isNight() && !entityvillagertrader.isInvisible(); })); - this.goalSelector.addGoal(0, new UseItemGoal<>(this, new ItemStack(Items.MILK_BUCKET), SoundEvents.WANDERING_TRADER_REAPPEARED, (wanderingtrader) -> { - return this.level().isDay() && wanderingtrader.isInvisible(); + this.goalSelector.addGoal(0, new UseItemGoal<>(this, new ItemStack(Items.MILK_BUCKET), SoundEvents.WANDERING_TRADER_REAPPEARED, (entityvillagertrader) -> { + return this.level().isDay() && entityvillagertrader.isInvisible(); })); this.goalSelector.addGoal(1, new TradeWithPlayerGoal(this)); this.goalSelector.addGoal(1, new AvoidEntityGoal<>(this, Zombie.class, 8.0F, 0.5D, 0.5D)); @@ -81,30 +88,27 @@ this.goalSelector.addGoal(2, new WanderingTrader.WanderToPositionGoal(this, 2.0D, 0.35D)); 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)); + this.goalSelector.addGoal(9, new PathfinderGoalInteract(this, Player.class, 3.0F, 1.0F)); this.goalSelector.addGoal(10, new LookAtPlayerGoal(this, Mob.class, 8.0F)); } @Nullable @Override - @Override - public AgeableMob getBreedOffspring(ServerLevel serverlevel, AgeableMob ageablemob) { + public AgeableMob getBreedOffspring(ServerLevel level, AgeableMob otherParent) { return null; } @Override - @Override public boolean showProgressBar() { return false; } @Override - @Override - public InteractionResult mobInteract(Player player, InteractionHand interactionhand) { - ItemStack itemstack = player.getItemInHand(interactionhand); + public InteractionResult mobInteract(Player player, EnumHand hand) { + ItemStack itemstack = player.getItemInHand(hand); if (!itemstack.is(Items.VILLAGER_SPAWN_EGG) && this.isAlive() && !this.isTrading() && !this.isBaby()) { - if (interactionhand == InteractionHand.MAIN_HAND) { + if (hand == EnumHand.MAIN_HAND) { player.awardStat(Stats.TALKED_TO_VILLAGER); } @@ -119,29 +123,37 @@ return InteractionResult.sidedSuccess(this.level().isClientSide); } } else { - return super.mobInteract(player, interactionhand); + return super.mobInteract(player, hand); } } @Override - @Override protected void updateTrades() { if (this.level().enabledFeatures().contains(FeatureFlags.TRADE_REBALANCE)) { this.experimentalUpdateTrades(); } else { - VillagerTrades.ItemListing[] avillagertrades_itemlisting = (VillagerTrades.ItemListing[]) VillagerTrades.WANDERING_TRADER_TRADES.get(1); - VillagerTrades.ItemListing[] avillagertrades_itemlisting1 = (VillagerTrades.ItemListing[]) VillagerTrades.WANDERING_TRADER_TRADES.get(2); + VillagerTrades.ItemListing[] avillagertrades_imerchantrecipeoption = (VillagerTrades.ItemListing[]) VillagerTrades.WANDERING_TRADER_TRADES.get(1); + VillagerTrades.ItemListing[] avillagertrades_imerchantrecipeoption1 = (VillagerTrades.ItemListing[]) VillagerTrades.WANDERING_TRADER_TRADES.get(2); - if (avillagertrades_itemlisting != null && avillagertrades_itemlisting1 != null) { - MerchantOffers merchantoffers = this.getOffers(); + if (avillagertrades_imerchantrecipeoption != null && avillagertrades_imerchantrecipeoption1 != null) { + MerchantOffers merchantrecipelist = this.getOffers(); - this.addOffersFromItemListings(merchantoffers, avillagertrades_itemlisting, 5); - int i = this.random.nextInt(avillagertrades_itemlisting1.length); - VillagerTrades.ItemListing villagertrades_itemlisting = avillagertrades_itemlisting1[i]; - MerchantOffer merchantoffer = villagertrades_itemlisting.getOffer(this, this.random); + this.addOffersFromItemListings(merchantrecipelist, avillagertrades_imerchantrecipeoption, 5); + int i = this.random.nextInt(avillagertrades_imerchantrecipeoption1.length); + VillagerTrades.ItemListing villagertrades_imerchantrecipeoption = avillagertrades_imerchantrecipeoption1[i]; + MerchantOffer merchantrecipe = villagertrades_imerchantrecipeoption.getOffer(this, this.random); - if (merchantoffer != null) { - merchantoffers.add(merchantoffer); + if (merchantrecipe != null) { + // CraftBukkit start + VillagerAcquireTradeEvent event = new VillagerAcquireTradeEvent((AbstractVillager) getBukkitEntity(), merchantrecipe.asBukkit()); + // Suppress during worldgen + if (this.valid) { + Bukkit.getPluginManager().callEvent(event); + } + if (!event.isCancelled()) { + merchantrecipelist.add(CraftMerchantRecipe.fromBukkit(event.getRecipe()).toMinecraft()); + } + // CraftBukkit end } } @@ -149,54 +161,50 @@ } private void experimentalUpdateTrades() { - MerchantOffers merchantoffers = this.getOffers(); + MerchantOffers merchantrecipelist = this.getOffers(); Iterator iterator = VillagerTrades.EXPERIMENTAL_WANDERING_TRADER_TRADES.iterator(); while (iterator.hasNext()) { Pair pair = (Pair) iterator.next(); - VillagerTrades.ItemListing[] avillagertrades_itemlisting = (VillagerTrades.ItemListing[]) pair.getLeft(); + VillagerTrades.ItemListing[] avillagertrades_imerchantrecipeoption = (VillagerTrades.ItemListing[]) pair.getLeft(); - this.addOffersFromItemListings(merchantoffers, avillagertrades_itemlisting, (Integer) pair.getRight()); + this.addOffersFromItemListings(merchantrecipelist, avillagertrades_imerchantrecipeoption, (Integer) pair.getRight()); } } @Override - @Override - public void addAdditionalSaveData(CompoundTag compoundtag) { - super.addAdditionalSaveData(compoundtag); - compoundtag.putInt("DespawnDelay", this.despawnDelay); + public void addAdditionalSaveData(CompoundTag compound) { + super.addAdditionalSaveData(compound); + compound.putInt("DespawnDelay", this.despawnDelay); if (this.wanderTarget != null) { - compoundtag.put("WanderTarget", NbtUtils.writeBlockPos(this.wanderTarget)); + compound.put("WanderTarget", NbtUtils.writeBlockPos(this.wanderTarget)); } } @Override - @Override - public void readAdditionalSaveData(CompoundTag compoundtag) { - super.readAdditionalSaveData(compoundtag); - if (compoundtag.contains("DespawnDelay", 99)) { - this.despawnDelay = compoundtag.getInt("DespawnDelay"); + public void readAdditionalSaveData(CompoundTag compound) { + super.readAdditionalSaveData(compound); + if (compound.contains("DespawnDelay", 99)) { + this.despawnDelay = compound.getInt("DespawnDelay"); } - if (compoundtag.contains("WanderTarget")) { - this.wanderTarget = NbtUtils.readBlockPos(compoundtag.getCompound("WanderTarget")); + if (compound.contains("WanderTarget")) { + this.wanderTarget = NbtUtils.readBlockPos(compound.getCompound("WanderTarget")); } this.setAge(Math.max(0, this.getAge())); } @Override - @Override - public boolean removeWhenFarAway(double d0) { + public boolean removeWhenFarAway(double distanceToClosestPlayer) { return false; } @Override - @Override - protected void rewardTradeXp(MerchantOffer merchantoffer) { - if (merchantoffer.shouldRewardExp()) { + protected void rewardTradeXp(MerchantOffer offer) { + if (offer.shouldRewardExp()) { int i = 3 + this.random.nextInt(4); this.level().addFreshEntity(new ExperienceOrb(this.level(), this.getX(), this.getY() + 0.5D, this.getZ(), i)); @@ -205,43 +213,37 @@ } @Override - @Override protected SoundEvent getAmbientSound() { return this.isTrading() ? SoundEvents.WANDERING_TRADER_TRADE : SoundEvents.WANDERING_TRADER_AMBIENT; } @Override - @Override - protected SoundEvent getHurtSound(DamageSource damagesource) { + protected SoundEvent getHurtSound(DamageSource damageSource) { return SoundEvents.WANDERING_TRADER_HURT; } @Override - @Override protected SoundEvent getDeathSound() { return SoundEvents.WANDERING_TRADER_DEATH; } @Override - @Override - protected SoundEvent getDrinkingSound(ItemStack itemstack) { - return itemstack.is(Items.MILK_BUCKET) ? SoundEvents.WANDERING_TRADER_DRINK_MILK : SoundEvents.WANDERING_TRADER_DRINK_POTION; + protected SoundEvent getDrinkingSound(ItemStack stack) { + return stack.is(Items.MILK_BUCKET) ? SoundEvents.WANDERING_TRADER_DRINK_MILK : SoundEvents.WANDERING_TRADER_DRINK_POTION; } @Override - @Override - protected SoundEvent getTradeUpdatedSound(boolean flag) { - return flag ? SoundEvents.WANDERING_TRADER_YES : SoundEvents.WANDERING_TRADER_NO; + protected SoundEvent getTradeUpdatedSound(boolean getYesSound) { + return getYesSound ? SoundEvents.WANDERING_TRADER_YES : SoundEvents.WANDERING_TRADER_NO; } @Override - @Override public SoundEvent getNotifyTradeSound() { return SoundEvents.WANDERING_TRADER_YES; } - public void setDespawnDelay(int i) { - this.despawnDelay = i; + public void setDespawnDelay(int despawnDelay) { + this.despawnDelay = despawnDelay; } public int getDespawnDelay() { @@ -249,7 +251,6 @@ } @Override - @Override public void aiStep() { super.aiStep(); if (!this.level().isClientSide) { @@ -265,8 +266,8 @@ } - public void setWanderTarget(@Nullable BlockPos blockpos) { - this.wanderTarget = blockpos; + public void setWanderTarget(@Nullable BlockPos wanderTarget) { + this.wanderTarget = wanderTarget; } @Nullable @@ -280,48 +281,45 @@ final double stopDistance; final double speedModifier; - WanderToPositionGoal(WanderingTrader wanderingtrader, double d0, double d1) { - this.trader = wanderingtrader; + WanderToPositionGoal(WanderingTrader entityvillagertrader, double d0, double d1) { + this.trader = entityvillagertrader; this.stopDistance = d0; this.speedModifier = d1; - this.setFlags(EnumSet.of(Goal.Flag.MOVE)); + this.setFlags(EnumSet.of(Goal.Type.MOVE)); } @Override - @Override public void stop() { this.trader.setWanderTarget((BlockPos) null); WanderingTrader.this.navigation.stop(); } @Override - @Override public boolean canUse() { - BlockPos blockpos = this.trader.getWanderTarget(); + BlockPos blockposition = this.trader.getWanderTarget(); - return blockpos != null && this.isTooFarAway(blockpos, this.stopDistance); + return blockposition != null && this.isTooFarAway(blockposition, this.stopDistance); } @Override - @Override public void tick() { - BlockPos blockpos = this.trader.getWanderTarget(); + BlockPos blockposition = this.trader.getWanderTarget(); - if (blockpos != null && WanderingTrader.this.navigation.isDone()) { - if (this.isTooFarAway(blockpos, 10.0D)) { - Vec3 vec3 = (new Vec3((double) blockpos.getX() - this.trader.getX(), (double) blockpos.getY() - this.trader.getY(), (double) blockpos.getZ() - this.trader.getZ())).normalize(); - Vec3 vec31 = vec3.scale(10.0D).add(this.trader.getX(), this.trader.getY(), this.trader.getZ()); + if (blockposition != null && WanderingTrader.this.navigation.isDone()) { + if (this.isTooFarAway(blockposition, 10.0D)) { + Vec3 vec3d = (new Vec3((double) blockposition.getX() - this.trader.getX(), (double) blockposition.getY() - this.trader.getY(), (double) blockposition.getZ() - this.trader.getZ())).normalize(); + Vec3 vec3d1 = vec3d.scale(10.0D).add(this.trader.getX(), this.trader.getY(), this.trader.getZ()); - WanderingTrader.this.navigation.moveTo(vec31.x, vec31.y, vec31.z, this.speedModifier); + WanderingTrader.this.navigation.moveTo(vec3d1.x, vec3d1.y, vec3d1.z, this.speedModifier); } else { - WanderingTrader.this.navigation.moveTo((double) blockpos.getX(), (double) blockpos.getY(), (double) blockpos.getZ(), this.speedModifier); + WanderingTrader.this.navigation.moveTo((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), this.speedModifier); } } } - private boolean isTooFarAway(BlockPos blockpos, double d0) { - return !blockpos.closerToCenterThan(this.trader.position(), d0); + private boolean isTooFarAway(BlockPos pos, double distance) { + return !pos.closerToCenterThan(this.trader.position(), distance); } } }