179 lines
7.1 KiB
Java
179 lines
7.1 KiB
Java
package net.minecraft.world.entity.animal;
|
|
|
|
import net.minecraft.network.syncher.SynchedEntityData;
|
|
import net.minecraft.network.syncher.EntityDataSerializers;
|
|
import javax.annotation.Nullable;
|
|
import net.minecraft.sounds.SoundEvent;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraft.world.item.Items;
|
|
import net.minecraft.world.InteractionHand;
|
|
import net.minecraft.world.entity.EntityDimensions;
|
|
import net.minecraft.world.entity.Pose;
|
|
import net.minecraft.world.entity.Entity;
|
|
import net.minecraft.sounds.SoundEvents;
|
|
import net.minecraft.world.entity.projectile.Snowball;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
import net.minecraft.world.level.LevelReader;
|
|
import net.minecraft.world.level.block.Blocks;
|
|
import net.minecraft.world.level.GameRules;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.world.damagesource.DamageSource;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.nbt.CompoundTag;
|
|
import net.minecraft.world.entity.monster.SharedMonsterAttributes;
|
|
import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal;
|
|
import net.minecraft.world.entity.monster.Enemy;
|
|
import net.minecraft.world.entity.ai.goal.RandomLookAroundGoal;
|
|
import net.minecraft.world.entity.LivingEntity;
|
|
import net.minecraft.world.entity.Mob;
|
|
import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal;
|
|
import net.minecraft.world.entity.player.Player;
|
|
import net.minecraft.world.entity.PathfinderMob;
|
|
import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal;
|
|
import net.minecraft.world.entity.ai.goal.Goal;
|
|
import net.minecraft.world.entity.ai.goal.RangedAttackGoal;
|
|
import net.minecraft.world.level.Level;
|
|
import net.minecraft.world.entity.EntityType;
|
|
import net.minecraft.network.syncher.EntityDataAccessor;
|
|
import net.minecraft.world.entity.monster.RangedAttackMob;
|
|
|
|
public class SnowGolem extends AbstractGolem implements RangedAttackMob {
|
|
private static final EntityDataAccessor<Byte> DATA_PUMPKIN_ID;
|
|
|
|
public SnowGolem(final EntityType<? extends SnowGolem> akr, final Level bjt) {
|
|
super(akr, bjt);
|
|
}
|
|
|
|
@Override
|
|
protected void registerGoals() {
|
|
this.goalSelector.addGoal(1, new RangedAttackGoal(this, 1.25, 20, 10.0f));
|
|
this.goalSelector.addGoal(2, new WaterAvoidingRandomStrollGoal(this, 1.0, 1.0000001E-5f));
|
|
this.goalSelector.addGoal(3, new LookAtPlayerGoal(this, Player.class, 6.0f));
|
|
this.goalSelector.addGoal(4, new RandomLookAroundGoal(this));
|
|
this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Mob.class, 10, true, false, akw -> akw instanceof Enemy));
|
|
}
|
|
|
|
@Override
|
|
protected void registerAttributes() {
|
|
super.registerAttributes();
|
|
this.getAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(4.0);
|
|
this.getAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.20000000298023224);
|
|
}
|
|
|
|
@Override
|
|
protected void defineSynchedData() {
|
|
super.defineSynchedData();
|
|
this.entityData.<Byte>define(SnowGolem.DATA_PUMPKIN_ID, (Byte)16);
|
|
}
|
|
|
|
@Override
|
|
public void addAdditionalSaveData(final CompoundTag jt) {
|
|
super.addAdditionalSaveData(jt);
|
|
jt.putBoolean("Pumpkin", this.hasPumpkin());
|
|
}
|
|
|
|
@Override
|
|
public void readAdditionalSaveData(final CompoundTag jt) {
|
|
super.readAdditionalSaveData(jt);
|
|
if (jt.contains("Pumpkin")) {
|
|
this.setPumpkin(jt.getBoolean("Pumpkin"));
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void aiStep() {
|
|
super.aiStep();
|
|
if (!this.level.isClientSide) {
|
|
int integer2 = Mth.floor(this.getX());
|
|
int integer3 = Mth.floor(this.getY());
|
|
int integer4 = Mth.floor(this.getZ());
|
|
if (this.isInWaterRainOrBubble()) {
|
|
this.hurt(DamageSource.DROWN, 1.0f);
|
|
}
|
|
if (this.level.getBiome(new BlockPos(integer2, 0, integer4)).getTemperature(new BlockPos(integer2, integer3, integer4)) > 1.0f) {
|
|
this.hurt(DamageSource.ON_FIRE, 1.0f);
|
|
}
|
|
if (!this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
|
|
return;
|
|
}
|
|
final BlockState byg5 = Blocks.SNOW.defaultBlockState();
|
|
for (int integer5 = 0; integer5 < 4; ++integer5) {
|
|
integer2 = Mth.floor(this.getX() + (integer5 % 2 * 2 - 1) * 0.25f);
|
|
integer3 = Mth.floor(this.getY());
|
|
integer4 = Mth.floor(this.getZ() + (integer5 / 2 % 2 * 2 - 1) * 0.25f);
|
|
final BlockPos fk7 = new BlockPos(integer2, integer3, integer4);
|
|
if (this.level.getBlockState(fk7).isAir() && this.level.getBiome(fk7).getTemperature(fk7) < 0.8f && byg5.canSurvive(this.level, fk7)) {
|
|
this.level.setBlockAndUpdate(fk7, byg5);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void performRangedAttack(final LivingEntity akw, final float float2) {
|
|
final Snowball ayz4 = new Snowball(this.level, this);
|
|
final double double5 = akw.getEyeY() - 1.100000023841858;
|
|
final double double6 = akw.getX() - this.getX();
|
|
final double double7 = double5 - ayz4.getY();
|
|
final double double8 = akw.getZ() - this.getZ();
|
|
final float float3 = Mth.sqrt(double6 * double6 + double8 * double8) * 0.2f;
|
|
ayz4.shoot(double6, double7 + float3, double8, 1.6f, 12.0f);
|
|
this.playSound(SoundEvents.SNOW_GOLEM_SHOOT, 1.0f, 1.0f / (this.getRandom().nextFloat() * 0.4f + 0.8f));
|
|
this.level.addFreshEntity(ayz4);
|
|
}
|
|
|
|
@Override
|
|
protected float getStandingEyeHeight(final Pose alg, final EntityDimensions ako) {
|
|
return 1.7f;
|
|
}
|
|
|
|
@Override
|
|
protected boolean mobInteract(final Player ayg, final InteractionHand ajh) {
|
|
final ItemStack bek4 = ayg.getItemInHand(ajh);
|
|
if (bek4.getItem() == Items.SHEARS && this.hasPumpkin()) {
|
|
if (!this.level.isClientSide) {
|
|
this.setPumpkin(false);
|
|
bek4.<Player>hurtAndBreak(1, ayg, ayg -> ayg.broadcastBreakEvent(ajh));
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public boolean hasPumpkin() {
|
|
return (this.entityData.<Byte>get(SnowGolem.DATA_PUMPKIN_ID) & 0x10) != 0x0;
|
|
}
|
|
|
|
public void setPumpkin(final boolean boolean1) {
|
|
final byte byte3 = this.entityData.<Byte>get(SnowGolem.DATA_PUMPKIN_ID);
|
|
if (boolean1) {
|
|
this.entityData.<Byte>set(SnowGolem.DATA_PUMPKIN_ID, (byte)(byte3 | 0x10));
|
|
}
|
|
else {
|
|
this.entityData.<Byte>set(SnowGolem.DATA_PUMPKIN_ID, (byte)(byte3 & 0xFFFFFFEF));
|
|
}
|
|
}
|
|
|
|
@Nullable
|
|
@Override
|
|
protected SoundEvent getAmbientSound() {
|
|
return SoundEvents.SNOW_GOLEM_AMBIENT;
|
|
}
|
|
|
|
@Nullable
|
|
@Override
|
|
protected SoundEvent getHurtSound(final DamageSource ajw) {
|
|
return SoundEvents.SNOW_GOLEM_HURT;
|
|
}
|
|
|
|
@Nullable
|
|
@Override
|
|
protected SoundEvent getDeathSound() {
|
|
return SoundEvents.SNOW_GOLEM_DEATH;
|
|
}
|
|
|
|
static {
|
|
DATA_PUMPKIN_ID = SynchedEntityData.<Byte>defineId(SnowGolem.class, EntityDataSerializers.BYTE);
|
|
}
|
|
}
|