211 lines
6.8 KiB
Java
211 lines
6.8 KiB
Java
package net.minecraft.world.entity;
|
|
|
|
import net.minecraft.network.syncher.SynchedEntityData;
|
|
import net.minecraft.network.syncher.EntityDataSerializers;
|
|
import net.minecraft.core.particles.ParticleOptions;
|
|
import net.minecraft.core.particles.ParticleTypes;
|
|
import net.minecraft.world.item.Item;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraft.world.item.SpawnEggItem;
|
|
import net.minecraft.world.InteractionHand;
|
|
import net.minecraft.world.entity.player.Player;
|
|
import net.minecraft.nbt.CompoundTag;
|
|
import javax.annotation.Nullable;
|
|
import net.minecraft.world.DifficultyInstance;
|
|
import net.minecraft.world.level.LevelAccessor;
|
|
import net.minecraft.world.level.Level;
|
|
import net.minecraft.network.syncher.EntityDataAccessor;
|
|
|
|
public abstract class AgableMob extends PathfinderMob {
|
|
private static final EntityDataAccessor<Boolean> DATA_BABY_ID;
|
|
protected int age;
|
|
protected int forcedAge;
|
|
protected int forcedAgeTimer;
|
|
|
|
protected AgableMob(final EntityType<? extends AgableMob> akr, final Level bjt) {
|
|
super(akr, bjt);
|
|
}
|
|
|
|
@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();
|
|
}
|
|
final AgableMobGroupData a7 = (AgableMobGroupData)alj;
|
|
if (a7.isShouldSpawnBaby() && a7.getGroupSize() > 0 && this.random.nextFloat() <= a7.getBabySpawnChance()) {
|
|
this.setAge(-24000);
|
|
}
|
|
a7.increaseGroupSizeByOne();
|
|
return super.finalizeSpawn(bju, ajg, akz, alj, jt);
|
|
}
|
|
|
|
@Nullable
|
|
public abstract AgableMob getBreedOffspring(final AgableMob akl);
|
|
|
|
protected void onOffspringSpawnedFromEgg(final Player ayg, final AgableMob akl) {
|
|
}
|
|
|
|
public boolean mobInteract(final Player ayg, final InteractionHand ajh) {
|
|
final ItemStack bek4 = ayg.getItemInHand(ajh);
|
|
final Item bef5 = bek4.getItem();
|
|
if (bef5 instanceof SpawnEggItem && ((SpawnEggItem)bef5).spawnsEntity(bek4.getTag(), this.getType())) {
|
|
if (!this.level.isClientSide) {
|
|
final AgableMob akl6 = this.getBreedOffspring(this);
|
|
if (akl6 != null) {
|
|
akl6.setAge(-24000);
|
|
akl6.moveTo(this.getX(), this.getY(), this.getZ(), 0.0f, 0.0f);
|
|
this.level.addFreshEntity(akl6);
|
|
if (bek4.hasCustomHoverName()) {
|
|
akl6.setCustomName(bek4.getHoverName());
|
|
}
|
|
this.onOffspringSpawnedFromEgg(ayg, akl6);
|
|
if (!ayg.abilities.instabuild) {
|
|
bek4.shrink(1);
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
protected void defineSynchedData() {
|
|
super.defineSynchedData();
|
|
this.entityData.<Boolean>define(AgableMob.DATA_BABY_ID, false);
|
|
}
|
|
|
|
public int getAge() {
|
|
if (this.level.isClientSide) {
|
|
return this.entityData.<Boolean>get(AgableMob.DATA_BABY_ID) ? -1 : 1;
|
|
}
|
|
return this.age;
|
|
}
|
|
|
|
public void ageUp(final int integer, final boolean boolean2) {
|
|
final int integer3;
|
|
int integer2 = integer3 = this.getAge();
|
|
integer2 += integer * 20;
|
|
if (integer2 > 0) {
|
|
integer2 = 0;
|
|
}
|
|
final int integer4 = integer2 - integer3;
|
|
this.setAge(integer2);
|
|
if (boolean2) {
|
|
this.forcedAge += integer4;
|
|
if (this.forcedAgeTimer == 0) {
|
|
this.forcedAgeTimer = 40;
|
|
}
|
|
}
|
|
if (this.getAge() == 0) {
|
|
this.setAge(this.forcedAge);
|
|
}
|
|
}
|
|
|
|
public void ageUp(final int integer) {
|
|
this.ageUp(integer, false);
|
|
}
|
|
|
|
public void setAge(final int integer) {
|
|
final int integer2 = this.age;
|
|
this.age = integer;
|
|
if ((integer2 < 0 && integer >= 0) || (integer2 >= 0 && integer < 0)) {
|
|
this.entityData.<Boolean>set(AgableMob.DATA_BABY_ID, integer < 0);
|
|
this.ageBoundaryReached();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void addAdditionalSaveData(final CompoundTag jt) {
|
|
super.addAdditionalSaveData(jt);
|
|
jt.putInt("Age", this.getAge());
|
|
jt.putInt("ForcedAge", this.forcedAge);
|
|
}
|
|
|
|
@Override
|
|
public void readAdditionalSaveData(final CompoundTag jt) {
|
|
super.readAdditionalSaveData(jt);
|
|
this.setAge(jt.getInt("Age"));
|
|
this.forcedAge = jt.getInt("ForcedAge");
|
|
}
|
|
|
|
@Override
|
|
public void onSyncedDataUpdated(final EntityDataAccessor<?> sb) {
|
|
if (AgableMob.DATA_BABY_ID.equals(sb)) {
|
|
this.refreshDimensions();
|
|
}
|
|
super.onSyncedDataUpdated(sb);
|
|
}
|
|
|
|
@Override
|
|
public void aiStep() {
|
|
super.aiStep();
|
|
if (this.level.isClientSide) {
|
|
if (this.forcedAgeTimer > 0) {
|
|
if (this.forcedAgeTimer % 4 == 0) {
|
|
this.level.addParticle(ParticleTypes.HAPPY_VILLAGER, this.getRandomX(1.0), this.getRandomY() + 0.5, this.getRandomZ(1.0), 0.0, 0.0, 0.0);
|
|
}
|
|
--this.forcedAgeTimer;
|
|
}
|
|
}
|
|
else if (this.isAlive()) {
|
|
int integer2 = this.getAge();
|
|
if (integer2 < 0) {
|
|
++integer2;
|
|
this.setAge(integer2);
|
|
}
|
|
else if (integer2 > 0) {
|
|
--integer2;
|
|
this.setAge(integer2);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected void ageBoundaryReached() {
|
|
}
|
|
|
|
@Override
|
|
public boolean isBaby() {
|
|
return this.getAge() < 0;
|
|
}
|
|
|
|
static {
|
|
DATA_BABY_ID = SynchedEntityData.<Boolean>defineId(AgableMob.class, EntityDataSerializers.BOOLEAN);
|
|
}
|
|
|
|
public static class AgableMobGroupData implements SpawnGroupData {
|
|
private int groupSize;
|
|
private boolean shouldSpawnBaby;
|
|
private float babySpawnChance;
|
|
|
|
public AgableMobGroupData() {
|
|
this.shouldSpawnBaby = true;
|
|
this.babySpawnChance = 0.05f;
|
|
}
|
|
|
|
public int getGroupSize() {
|
|
return this.groupSize;
|
|
}
|
|
|
|
public void increaseGroupSizeByOne() {
|
|
++this.groupSize;
|
|
}
|
|
|
|
public boolean isShouldSpawnBaby() {
|
|
return this.shouldSpawnBaby;
|
|
}
|
|
|
|
public void setShouldSpawnBaby(final boolean boolean1) {
|
|
this.shouldSpawnBaby = boolean1;
|
|
}
|
|
|
|
public float getBabySpawnChance() {
|
|
return this.babySpawnChance;
|
|
}
|
|
|
|
public void setBabySpawnChance(final float float1) {
|
|
this.babySpawnChance = float1;
|
|
}
|
|
}
|
|
}
|