269 lines
8.8 KiB
Java
269 lines
8.8 KiB
Java
package net.minecraft.world.entity.npc;
|
|
|
|
import java.util.AbstractList;
|
|
import net.minecraft.network.syncher.SynchedEntityData;
|
|
import net.minecraft.network.syncher.EntityDataSerializers;
|
|
import java.util.Iterator;
|
|
import java.util.Set;
|
|
import com.google.common.collect.Sets;
|
|
import net.minecraft.core.particles.ParticleOptions;
|
|
import net.minecraft.world.damagesource.DamageSource;
|
|
import net.minecraft.world.entity.Entity;
|
|
import net.minecraft.world.level.dimension.DimensionType;
|
|
import net.minecraft.nbt.ListTag;
|
|
import net.minecraft.nbt.Tag;
|
|
import net.minecraft.sounds.SoundEvents;
|
|
import net.minecraft.sounds.SoundEvent;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraft.advancements.CriteriaTriggers;
|
|
import net.minecraft.server.level.ServerPlayer;
|
|
import net.minecraft.world.item.trading.MerchantOffer;
|
|
import net.minecraft.world.entity.EntityDimensions;
|
|
import net.minecraft.world.entity.Pose;
|
|
import net.minecraft.nbt.CompoundTag;
|
|
import net.minecraft.world.entity.SpawnGroupData;
|
|
import net.minecraft.world.entity.MobSpawnType;
|
|
import net.minecraft.world.DifficultyInstance;
|
|
import net.minecraft.world.level.LevelAccessor;
|
|
import net.minecraft.world.level.Level;
|
|
import net.minecraft.world.entity.EntityType;
|
|
import net.minecraft.world.SimpleContainer;
|
|
import net.minecraft.world.item.trading.MerchantOffers;
|
|
import javax.annotation.Nullable;
|
|
import net.minecraft.world.entity.player.Player;
|
|
import net.minecraft.network.syncher.EntityDataAccessor;
|
|
import net.minecraft.world.item.trading.Merchant;
|
|
import net.minecraft.world.entity.AgableMob;
|
|
|
|
public abstract class AbstractVillager extends AgableMob implements Npc, Merchant {
|
|
private static final EntityDataAccessor<Integer> DATA_UNHAPPY_COUNTER;
|
|
@Nullable
|
|
private Player tradingPlayer;
|
|
@Nullable
|
|
protected MerchantOffers offers;
|
|
private final SimpleContainer inventory;
|
|
|
|
public AbstractVillager(final EntityType<? extends AbstractVillager> akr, final Level bjt) {
|
|
super(akr, bjt);
|
|
this.inventory = new SimpleContainer(8);
|
|
}
|
|
|
|
@Override
|
|
public SpawnGroupData finalizeSpawn(final LevelAccessor bju, final DifficultyInstance ajg, final MobSpawnType akz, @Nullable SpawnGroupData alj, @Nullable final CompoundTag jt) {
|
|
if (alj == null) {
|
|
alj = new AgableMobGroupData();
|
|
((AgableMobGroupData)alj).setShouldSpawnBaby(false);
|
|
}
|
|
return super.finalizeSpawn(bju, ajg, akz, alj, jt);
|
|
}
|
|
|
|
public int getUnhappyCounter() {
|
|
return this.entityData.<Integer>get(AbstractVillager.DATA_UNHAPPY_COUNTER);
|
|
}
|
|
|
|
public void setUnhappyCounter(final int integer) {
|
|
this.entityData.<Integer>set(AbstractVillager.DATA_UNHAPPY_COUNTER, integer);
|
|
}
|
|
|
|
@Override
|
|
public int getVillagerXp() {
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
protected float getStandingEyeHeight(final Pose alg, final EntityDimensions ako) {
|
|
if (this.isBaby()) {
|
|
return 0.81f;
|
|
}
|
|
return 1.62f;
|
|
}
|
|
|
|
@Override
|
|
protected void defineSynchedData() {
|
|
super.defineSynchedData();
|
|
this.entityData.<Integer>define(AbstractVillager.DATA_UNHAPPY_COUNTER, 0);
|
|
}
|
|
|
|
@Override
|
|
public void setTradingPlayer(@Nullable final Player ayg) {
|
|
this.tradingPlayer = ayg;
|
|
}
|
|
|
|
@Nullable
|
|
@Override
|
|
public Player getTradingPlayer() {
|
|
return this.tradingPlayer;
|
|
}
|
|
|
|
public boolean isTrading() {
|
|
return this.tradingPlayer != null;
|
|
}
|
|
|
|
@Override
|
|
public MerchantOffers getOffers() {
|
|
if (this.offers == null) {
|
|
this.offers = new MerchantOffers();
|
|
this.updateTrades();
|
|
}
|
|
return this.offers;
|
|
}
|
|
|
|
@Override
|
|
public void overrideOffers(@Nullable final MerchantOffers bix) {
|
|
}
|
|
|
|
@Override
|
|
public void overrideXp(final int integer) {
|
|
}
|
|
|
|
@Override
|
|
public void notifyTrade(final MerchantOffer biw) {
|
|
biw.increaseUses();
|
|
this.ambientSoundTime = -this.getAmbientSoundInterval();
|
|
this.rewardTradeXp(biw);
|
|
if (this.tradingPlayer instanceof ServerPlayer) {
|
|
CriteriaTriggers.TRADE.trigger((ServerPlayer)this.tradingPlayer, this, biw.getResult());
|
|
}
|
|
}
|
|
|
|
protected abstract void rewardTradeXp(final MerchantOffer biw);
|
|
|
|
@Override
|
|
public boolean showProgressBar() {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void notifyTradeUpdated(final ItemStack bek) {
|
|
if (!this.level.isClientSide && this.ambientSoundTime > -this.getAmbientSoundInterval() + 20) {
|
|
this.ambientSoundTime = -this.getAmbientSoundInterval();
|
|
this.playSound(this.getTradeUpdatedSound(!bek.isEmpty()), this.getSoundVolume(), this.getVoicePitch());
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public SoundEvent getNotifyTradeSound() {
|
|
return SoundEvents.VILLAGER_YES;
|
|
}
|
|
|
|
protected SoundEvent getTradeUpdatedSound(final boolean boolean1) {
|
|
return boolean1 ? SoundEvents.VILLAGER_YES : SoundEvents.VILLAGER_NO;
|
|
}
|
|
|
|
public void playCelebrateSound() {
|
|
this.playSound(SoundEvents.VILLAGER_CELEBRATE, this.getSoundVolume(), this.getVoicePitch());
|
|
}
|
|
|
|
@Override
|
|
public void addAdditionalSaveData(final CompoundTag jt) {
|
|
super.addAdditionalSaveData(jt);
|
|
final MerchantOffers bix3 = this.getOffers();
|
|
if (!bix3.isEmpty()) {
|
|
jt.put("Offers", bix3.createTag());
|
|
}
|
|
final ListTag jz4 = new ListTag();
|
|
for (int integer5 = 0; integer5 < this.inventory.getContainerSize(); ++integer5) {
|
|
final ItemStack bek6 = this.inventory.getItem(integer5);
|
|
if (!bek6.isEmpty()) {
|
|
((AbstractList<CompoundTag>)jz4).add(bek6.save(new CompoundTag()));
|
|
}
|
|
}
|
|
jt.put("Inventory", jz4);
|
|
}
|
|
|
|
@Override
|
|
public void readAdditionalSaveData(final CompoundTag jt) {
|
|
super.readAdditionalSaveData(jt);
|
|
if (jt.contains("Offers", 10)) {
|
|
this.offers = new MerchantOffers(jt.getCompound("Offers"));
|
|
}
|
|
final ListTag jz3 = jt.getList("Inventory", 10);
|
|
for (int integer4 = 0; integer4 < jz3.size(); ++integer4) {
|
|
final ItemStack bek5 = ItemStack.of(jz3.getCompound(integer4));
|
|
if (!bek5.isEmpty()) {
|
|
this.inventory.addItem(bek5);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Nullable
|
|
@Override
|
|
public Entity changeDimension(final DimensionType cbf) {
|
|
this.stopTrading();
|
|
return super.changeDimension(cbf);
|
|
}
|
|
|
|
protected void stopTrading() {
|
|
this.setTradingPlayer(null);
|
|
}
|
|
|
|
@Override
|
|
public void die(final DamageSource ajw) {
|
|
super.die(ajw);
|
|
this.stopTrading();
|
|
}
|
|
|
|
protected void addParticlesAroundSelf(final ParticleOptions gt) {
|
|
for (int integer3 = 0; integer3 < 5; ++integer3) {
|
|
final double double4 = this.random.nextGaussian() * 0.02;
|
|
final double double5 = this.random.nextGaussian() * 0.02;
|
|
final double double6 = this.random.nextGaussian() * 0.02;
|
|
this.level.addParticle(gt, this.getRandomX(1.0), this.getRandomY() + 1.0, this.getRandomZ(1.0), double4, double5, double6);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean canBeLeashed(final Player ayg) {
|
|
return false;
|
|
}
|
|
|
|
public SimpleContainer getInventory() {
|
|
return this.inventory;
|
|
}
|
|
|
|
@Override
|
|
public boolean setSlot(final int integer, final ItemStack bek) {
|
|
if (super.setSlot(integer, bek)) {
|
|
return true;
|
|
}
|
|
final int integer2 = integer - 300;
|
|
if (integer2 >= 0 && integer2 < this.inventory.getContainerSize()) {
|
|
this.inventory.setItem(integer2, bek);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public Level getLevel() {
|
|
return this.level;
|
|
}
|
|
|
|
protected abstract void updateTrades();
|
|
|
|
protected void addOffersFromItemListings(final MerchantOffers bix, final VillagerTrades.ItemListing[] arr, final int integer) {
|
|
final Set<Integer> set5 = Sets.newHashSet();
|
|
if (arr.length > integer) {
|
|
while (set5.size() < integer) {
|
|
set5.add(this.random.nextInt(arr.length));
|
|
}
|
|
}
|
|
else {
|
|
for (int integer2 = 0; integer2 < arr.length; ++integer2) {
|
|
set5.add(integer2);
|
|
}
|
|
}
|
|
for (final Integer integer3 : set5) {
|
|
final VillagerTrades.ItemListing f8 = arr[integer3];
|
|
final MerchantOffer biw9 = f8.getOffer(this, this.random);
|
|
if (biw9 != null) {
|
|
bix.add(biw9);
|
|
}
|
|
}
|
|
}
|
|
|
|
static {
|
|
DATA_UNHAPPY_COUNTER = SynchedEntityData.<Integer>defineId(AbstractVillager.class, EntityDataSerializers.INT);
|
|
}
|
|
}
|