minecraft-src/net/minecraft/world/entity/animal/Salmon.java
2025-07-04 03:15:13 +03:00

169 lines
5.3 KiB
Java

package net.minecraft.world.entity.animal;
import java.util.function.IntFunction;
import net.minecraft.core.component.DataComponents;
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.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.util.ByIdMap;
import net.minecraft.util.StringRepresentable;
import net.minecraft.util.ByIdMap.OutOfBoundsStrategy;
import net.minecraft.util.StringRepresentable.EnumCodec;
import net.minecraft.util.random.SimpleWeightedRandomList;
import net.minecraft.world.DifficultyInstance;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.EntityDimensions;
import net.minecraft.world.entity.EntitySpawnReason;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Pose;
import net.minecraft.world.entity.SpawnGroupData;
import net.minecraft.world.entity.VariantHolder;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.component.CustomData;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.ServerLevelAccessor;
import org.jetbrains.annotations.Nullable;
public class Salmon extends AbstractSchoolingFish implements VariantHolder<Salmon.Variant> {
private static final String TAG_TYPE = "type";
private static final EntityDataAccessor<Integer> DATA_TYPE = SynchedEntityData.defineId(Salmon.class, EntityDataSerializers.INT);
public Salmon(EntityType<? extends Salmon> entityType, Level level) {
super(entityType, level);
this.refreshDimensions();
}
@Override
public int getMaxSchoolSize() {
return 5;
}
@Override
public ItemStack getBucketItemStack() {
return new ItemStack(Items.SALMON_BUCKET);
}
@Override
protected SoundEvent getAmbientSound() {
return SoundEvents.SALMON_AMBIENT;
}
@Override
protected SoundEvent getDeathSound() {
return SoundEvents.SALMON_DEATH;
}
@Override
protected SoundEvent getHurtSound(DamageSource damageSource) {
return SoundEvents.SALMON_HURT;
}
@Override
protected SoundEvent getFlopSound() {
return SoundEvents.SALMON_FLOP;
}
@Override
protected void defineSynchedData(Builder builder) {
super.defineSynchedData(builder);
builder.define(DATA_TYPE, Salmon.Variant.MEDIUM.id());
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> dataAccessor) {
super.onSyncedDataUpdated(dataAccessor);
if (DATA_TYPE.equals(dataAccessor)) {
this.refreshDimensions();
}
}
@Override
public void addAdditionalSaveData(CompoundTag tag) {
super.addAdditionalSaveData(tag);
tag.putString("type", this.getVariant().getSerializedName());
}
@Override
public void readAdditionalSaveData(CompoundTag tag) {
super.readAdditionalSaveData(tag);
this.setVariant(Salmon.Variant.byName(tag.getString("type")));
}
@Override
public void saveToBucketTag(ItemStack stack) {
Bucketable.saveDefaultDataToBucketTag(this, stack);
CustomData.update(DataComponents.BUCKET_ENTITY_DATA, stack, compoundTag -> compoundTag.putString("type", this.getVariant().getSerializedName()));
}
@Override
public void loadFromBucketTag(CompoundTag tag) {
Bucketable.loadDefaultDataFromBucketTag(this, tag);
this.setVariant(Salmon.Variant.byName(tag.getString("type")));
}
public void setVariant(Salmon.Variant variant) {
this.entityData.set(DATA_TYPE, variant.id);
}
public Salmon.Variant getVariant() {
return (Salmon.Variant)Salmon.Variant.BY_ID.apply(this.entityData.get(DATA_TYPE));
}
@Nullable
@Override
public SpawnGroupData finalizeSpawn(
ServerLevelAccessor level, DifficultyInstance difficulty, EntitySpawnReason spawnReason, @Nullable SpawnGroupData spawnGroupData
) {
SimpleWeightedRandomList.Builder<Salmon.Variant> builder = SimpleWeightedRandomList.builder();
builder.add(Salmon.Variant.SMALL, 30);
builder.add(Salmon.Variant.MEDIUM, 50);
builder.add(Salmon.Variant.LARGE, 15);
builder.build().getRandomValue(this.random).ifPresent(this::setVariant);
return super.finalizeSpawn(level, difficulty, spawnReason, spawnGroupData);
}
public float getSalmonScale() {
return this.getVariant().boundingBoxScale;
}
@Override
protected EntityDimensions getDefaultDimensions(Pose pose) {
return super.getDefaultDimensions(pose).scale(this.getSalmonScale());
}
public static enum Variant implements StringRepresentable {
SMALL("small", 0, 0.5F),
MEDIUM("medium", 1, 1.0F),
LARGE("large", 2, 1.5F);
public static final EnumCodec<Salmon.Variant> CODEC = StringRepresentable.fromEnum(Salmon.Variant::values);
static final IntFunction<Salmon.Variant> BY_ID = ByIdMap.continuous(Salmon.Variant::id, values(), OutOfBoundsStrategy.CLAMP);
private final String name;
final int id;
final float boundingBoxScale;
private Variant(final String name, final int id, final float boundingBoxScale) {
this.name = name;
this.id = id;
this.boundingBoxScale = boundingBoxScale;
}
@Override
public String getSerializedName() {
return this.name;
}
int id() {
return this.id;
}
static Salmon.Variant byName(String name) {
return (Salmon.Variant)CODEC.byName(name, MEDIUM);
}
}
}