minecraft-src/net/minecraft/world/entity/monster/Skeleton.java
2025-07-04 03:45:38 +03:00

137 lines
3.8 KiB
Java

package net.minecraft.world.entity.monster;
import com.google.common.annotations.VisibleForTesting;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.network.syncher.SynchedEntityData.Builder;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.ConversionParams;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
public class Skeleton extends AbstractSkeleton {
private static final int TOTAL_CONVERSION_TIME = 300;
private static final EntityDataAccessor<Boolean> DATA_STRAY_CONVERSION_ID = SynchedEntityData.defineId(Skeleton.class, EntityDataSerializers.BOOLEAN);
public static final String CONVERSION_TAG = "StrayConversionTime";
private static final int NOT_CONVERTING = -1;
private int inPowderSnowTime;
private int conversionTime;
public Skeleton(EntityType<? extends Skeleton> entityType, Level level) {
super(entityType, level);
}
@Override
protected void defineSynchedData(Builder builder) {
super.defineSynchedData(builder);
builder.define(DATA_STRAY_CONVERSION_ID, false);
}
public boolean isFreezeConverting() {
return this.getEntityData().get(DATA_STRAY_CONVERSION_ID);
}
public void setFreezeConverting(boolean isFrozen) {
this.entityData.set(DATA_STRAY_CONVERSION_ID, isFrozen);
}
@Override
public boolean isShaking() {
return this.isFreezeConverting();
}
@Override
public void tick() {
if (!this.level().isClientSide && this.isAlive() && !this.isNoAi()) {
if (this.isInPowderSnow) {
if (this.isFreezeConverting()) {
this.conversionTime--;
if (this.conversionTime < 0) {
this.doFreezeConversion();
}
} else {
this.inPowderSnowTime++;
if (this.inPowderSnowTime >= 140) {
this.startFreezeConversion(300);
}
}
} else {
this.inPowderSnowTime = -1;
this.setFreezeConverting(false);
}
}
super.tick();
}
@Override
public void addAdditionalSaveData(CompoundTag tag) {
super.addAdditionalSaveData(tag);
tag.putInt("StrayConversionTime", this.isFreezeConverting() ? this.conversionTime : -1);
}
@Override
public void readAdditionalSaveData(CompoundTag tag) {
super.readAdditionalSaveData(tag);
int i = tag.getIntOr("StrayConversionTime", -1);
if (i != -1) {
this.startFreezeConversion(i);
} else {
this.setFreezeConverting(false);
}
}
@VisibleForTesting
public void startFreezeConversion(int conversionTime) {
this.conversionTime = conversionTime;
this.setFreezeConverting(true);
}
protected void doFreezeConversion() {
this.convertTo(EntityType.STRAY, ConversionParams.single(this, true, true), stray -> {
if (!this.isSilent()) {
this.level().levelEvent(null, 1048, this.blockPosition(), 0);
}
});
}
@Override
public boolean canFreeze() {
return false;
}
@Override
protected SoundEvent getAmbientSound() {
return SoundEvents.SKELETON_AMBIENT;
}
@Override
protected SoundEvent getHurtSound(DamageSource damageSource) {
return SoundEvents.SKELETON_HURT;
}
@Override
protected SoundEvent getDeathSound() {
return SoundEvents.SKELETON_DEATH;
}
@Override
SoundEvent getStepSound() {
return SoundEvents.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.SKELETON_SKULL);
}
}
}