package net.minecraft.world.entity.monster; import net.minecraft.server.level.ServerLevel; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; import net.minecraft.util.RandomSource; import net.minecraft.world.DifficultyInstance; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntitySpawnReason; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.SpawnGroupData; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal; import net.minecraft.world.entity.monster.piglin.AbstractPiglin; import net.minecraft.world.entity.projectile.AbstractArrow; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; import net.minecraft.world.level.ServerLevelAccessor; import net.minecraft.world.level.pathfinder.PathType; import org.jetbrains.annotations.Nullable; public class WitherSkeleton extends AbstractSkeleton { public WitherSkeleton(EntityType entityType, Level level) { super(entityType, level); this.setPathfindingMalus(PathType.LAVA, 8.0F); } @Override protected void registerGoals() { this.targetSelector.addGoal(3, new NearestAttackableTargetGoal(this, AbstractPiglin.class, true)); super.registerGoals(); } @Override protected SoundEvent getAmbientSound() { return SoundEvents.WITHER_SKELETON_AMBIENT; } @Override protected SoundEvent getHurtSound(DamageSource damageSource) { return SoundEvents.WITHER_SKELETON_HURT; } @Override protected SoundEvent getDeathSound() { return SoundEvents.WITHER_SKELETON_DEATH; } @Override SoundEvent getStepSound() { return SoundEvents.WITHER_SKELETON_STEP; } @Override protected void dropCustomDeathLoot(ServerLevel level, DamageSource damageSource, boolean recentlyHit) { super.dropCustomDeathLoot(level, damageSource, recentlyHit); if (damageSource.getEntity() instanceof Creeper creeper && creeper.canDropMobsSkull()) { creeper.increaseDroppedSkulls(); this.spawnAtLocation(level, Items.WITHER_SKELETON_SKULL); } } @Override protected void populateDefaultEquipmentSlots(RandomSource random, DifficultyInstance difficulty) { this.setItemSlot(EquipmentSlot.MAINHAND, new ItemStack(Items.STONE_SWORD)); } @Override protected void populateDefaultEquipmentEnchantments(ServerLevelAccessor level, RandomSource random, DifficultyInstance difficulty) { } @Nullable @Override public SpawnGroupData finalizeSpawn( ServerLevelAccessor serverLevelAccessor, DifficultyInstance difficultyInstance, EntitySpawnReason entitySpawnReason, @Nullable SpawnGroupData spawnGroupData ) { SpawnGroupData spawnGroupData2 = super.finalizeSpawn(serverLevelAccessor, difficultyInstance, entitySpawnReason, spawnGroupData); this.getAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(4.0); this.reassessWeaponGoal(); return spawnGroupData2; } @Override public boolean doHurtTarget(ServerLevel serverLevel, Entity entity) { if (!super.doHurtTarget(serverLevel, entity)) { return false; } else { if (entity instanceof LivingEntity) { ((LivingEntity)entity).addEffect(new MobEffectInstance(MobEffects.WITHER, 200), this); } return true; } } @Override protected AbstractArrow getArrow(ItemStack arrow, float velocity, @Nullable ItemStack weapon) { AbstractArrow abstractArrow = super.getArrow(arrow, velocity, weapon); abstractArrow.igniteForSeconds(100.0F); return abstractArrow; } @Override public boolean canBeAffected(MobEffectInstance effectInstance) { return effectInstance.is(MobEffects.WITHER) ? false : super.canBeAffected(effectInstance); } }