minecraft-src/net/minecraft/world/food/FoodProperties.java
2025-07-04 01:41:11 +03:00

115 lines
4.4 KiB
Java

package net.minecraft.world.food;
import com.google.common.collect.ImmutableList;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import java.util.List;
import java.util.Optional;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.util.ExtraCodecs;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.ItemLike;
public record FoodProperties(
int nutrition, float saturation, boolean canAlwaysEat, float eatSeconds, Optional<ItemStack> usingConvertsTo, List<FoodProperties.PossibleEffect> effects
) {
private static final float DEFAULT_EAT_SECONDS = 1.6F;
public static final Codec<FoodProperties> DIRECT_CODEC = RecordCodecBuilder.create(
instance -> instance.group(
ExtraCodecs.NON_NEGATIVE_INT.fieldOf("nutrition").forGetter(FoodProperties::nutrition),
Codec.FLOAT.fieldOf("saturation").forGetter(FoodProperties::saturation),
Codec.BOOL.optionalFieldOf("can_always_eat", false).forGetter(FoodProperties::canAlwaysEat),
ExtraCodecs.POSITIVE_FLOAT.optionalFieldOf("eat_seconds", 1.6F).forGetter(FoodProperties::eatSeconds),
ItemStack.SINGLE_ITEM_CODEC.optionalFieldOf("using_converts_to").forGetter(FoodProperties::usingConvertsTo),
FoodProperties.PossibleEffect.CODEC.listOf().optionalFieldOf("effects", List.of()).forGetter(FoodProperties::effects)
)
.apply(instance, FoodProperties::new)
);
public static final StreamCodec<RegistryFriendlyByteBuf, FoodProperties> DIRECT_STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.VAR_INT,
FoodProperties::nutrition,
ByteBufCodecs.FLOAT,
FoodProperties::saturation,
ByteBufCodecs.BOOL,
FoodProperties::canAlwaysEat,
ByteBufCodecs.FLOAT,
FoodProperties::eatSeconds,
ItemStack.STREAM_CODEC.apply(ByteBufCodecs::optional),
FoodProperties::usingConvertsTo,
FoodProperties.PossibleEffect.STREAM_CODEC.apply(ByteBufCodecs.list()),
FoodProperties::effects,
FoodProperties::new
);
public int eatDurationTicks() {
return (int)(this.eatSeconds * 20.0F);
}
public static class Builder {
private int nutrition;
private float saturationModifier;
private boolean canAlwaysEat;
private float eatSeconds = 1.6F;
private Optional<ItemStack> usingConvertsTo = Optional.empty();
private final ImmutableList.Builder<FoodProperties.PossibleEffect> effects = ImmutableList.builder();
public FoodProperties.Builder nutrition(int nutrition) {
this.nutrition = nutrition;
return this;
}
public FoodProperties.Builder saturationModifier(float saturationModifier) {
this.saturationModifier = saturationModifier;
return this;
}
public FoodProperties.Builder alwaysEdible() {
this.canAlwaysEat = true;
return this;
}
public FoodProperties.Builder fast() {
this.eatSeconds = 0.8F;
return this;
}
public FoodProperties.Builder effect(MobEffectInstance effect, float probability) {
this.effects.add(new FoodProperties.PossibleEffect(effect, probability));
return this;
}
public FoodProperties.Builder usingConvertsTo(ItemLike item) {
this.usingConvertsTo = Optional.of(new ItemStack(item));
return this;
}
public FoodProperties build() {
float f = FoodConstants.saturationByModifier(this.nutrition, this.saturationModifier);
return new FoodProperties(this.nutrition, f, this.canAlwaysEat, this.eatSeconds, this.usingConvertsTo, this.effects.build());
}
}
public record PossibleEffect(MobEffectInstance effect, float probability) {
public static final Codec<FoodProperties.PossibleEffect> CODEC = RecordCodecBuilder.create(
instance -> instance.group(
MobEffectInstance.CODEC.fieldOf("effect").forGetter(FoodProperties.PossibleEffect::effect),
Codec.floatRange(0.0F, 1.0F).optionalFieldOf("probability", 1.0F).forGetter(FoodProperties.PossibleEffect::probability)
)
.apply(instance, FoodProperties.PossibleEffect::new)
);
public static final StreamCodec<RegistryFriendlyByteBuf, FoodProperties.PossibleEffect> STREAM_CODEC = StreamCodec.composite(
MobEffectInstance.STREAM_CODEC,
FoodProperties.PossibleEffect::effect,
ByteBufCodecs.FLOAT,
FoodProperties.PossibleEffect::probability,
FoodProperties.PossibleEffect::new
);
public MobEffectInstance effect() {
return new MobEffectInstance(this.effect);
}
}
}