package net.minecraft.world.entity; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.List; import java.util.Optional; import net.minecraft.core.Holder; import net.minecraft.core.HolderSet; import net.minecraft.core.RegistryCodecs; import net.minecraft.core.registries.Registries; import net.minecraft.resources.Identifier; import net.minecraft.resources.ResourceKey; import net.minecraft.util.ExtraCodecs; import net.minecraft.util.valueproviders.FloatProvider; import net.minecraft.util.valueproviders.FloatProviders; import net.minecraft.world.damagesource.DamageType; import net.minecraft.world.entity.ai.attributes.Attribute; import net.minecraft.world.entity.ai.attributes.AttributeModifier; import net.minecraft.world.item.Item; public record SulfurCubeArchetype( HolderSet items, List attributeModifiers, boolean buoyant, Optional explosion, Optional contactDamage, SulfurCubeArchetype.KnockbackModifiers knockbackModifiers ) { public static final Codec DIRECT_CODEC = RecordCodecBuilder.create( i -> i.group( RegistryCodecs.homogeneousList(Registries.ITEM).fieldOf("items").forGetter(SulfurCubeArchetype::items), SulfurCubeArchetype.AttributeEntry.CODEC.listOf().fieldOf("attribute_modifiers").forGetter(SulfurCubeArchetype::attributeModifiers), Codec.BOOL.optionalFieldOf("buoyant", false).forGetter(SulfurCubeArchetype::buoyant), SulfurCubeArchetype.ExplosionData.CODEC.optionalFieldOf("explosion").forGetter(SulfurCubeArchetype::explosion), SulfurCubeArchetype.ContactDamage.CODEC.optionalFieldOf("contact_damage").forGetter(SulfurCubeArchetype::contactDamage), SulfurCubeArchetype.KnockbackModifiers.CODEC.fieldOf("knockback_modifiers").forGetter(SulfurCubeArchetype::knockbackModifiers) ) .apply(i, SulfurCubeArchetype::new) ); public static SulfurCubeArchetype.KnockbackModifiers DEFAULT_KNOCKBACK_MODIFIERS = new SulfurCubeArchetype.KnockbackModifiers(0.33F, 0.06F); public record AttributeEntry(Holder attribute, AttributeModifier modifier) { public static final Codec CODEC = RecordCodecBuilder.create( i -> i.group( Attribute.CODEC.fieldOf("attribute").forGetter(SulfurCubeArchetype.AttributeEntry::attribute), AttributeModifier.MAP_CODEC.forGetter(SulfurCubeArchetype.AttributeEntry::modifier) ) .apply(i, SulfurCubeArchetype.AttributeEntry::new) ); public static SulfurCubeArchetype.AttributeEntry add(final Holder attribute, final double amount, final ResourceKey archetype) { return new SulfurCubeArchetype.AttributeEntry( attribute, new AttributeModifier( Identifier.withDefaultNamespace(archetype.identifier().getPath() + "_add_" + ((ResourceKey)attribute.unwrapKey().get()).identifier().getPath()), amount, AttributeModifier.Operation.ADD_VALUE ) ); } public static SulfurCubeArchetype.AttributeEntry multiply( final Holder attribute, final double amount, final ResourceKey archetype ) { return new SulfurCubeArchetype.AttributeEntry( attribute, new AttributeModifier( Identifier.withDefaultNamespace(archetype.identifier().getPath() + "_mul_" + ((ResourceKey)attribute.unwrapKey().get()).identifier().getPath()), amount - 1.0, AttributeModifier.Operation.ADD_MULTIPLIED_TOTAL ) ); } } public record ContactDamage(Holder damageType, FloatProvider amount, boolean attributeToSource) { public static final Codec CODEC = RecordCodecBuilder.create( i -> i.group( DamageType.CODEC.fieldOf("damage_type").forGetter(SulfurCubeArchetype.ContactDamage::damageType), FloatProviders.codec(0.0F).fieldOf("amount").forGetter(SulfurCubeArchetype.ContactDamage::amount), Codec.BOOL.fieldOf("attribute_to_source").forGetter(SulfurCubeArchetype.ContactDamage::attributeToSource) ) .apply(i, SulfurCubeArchetype.ContactDamage::new) ); } public record ExplosionData(int power, boolean causesFire, int fuse) { public static final Codec CODEC = RecordCodecBuilder.create( i -> i.group( ExtraCodecs.NON_NEGATIVE_INT.fieldOf("power").forGetter(SulfurCubeArchetype.ExplosionData::power), Codec.BOOL.fieldOf("causes_fire").forGetter(SulfurCubeArchetype.ExplosionData::causesFire), ExtraCodecs.POSITIVE_INT.fieldOf("fuse").forGetter(SulfurCubeArchetype.ExplosionData::fuse) ) .apply(i, SulfurCubeArchetype.ExplosionData::new) ); } public record KnockbackModifiers(float horizontalPower, float verticalPower) { public static final Codec CODEC = RecordCodecBuilder.create( i -> i.group( Codec.FLOAT.fieldOf("horizontal_power").forGetter(SulfurCubeArchetype.KnockbackModifiers::horizontalPower), Codec.FLOAT.fieldOf("vertical_power").forGetter(SulfurCubeArchetype.KnockbackModifiers::verticalPower) ) .apply(i, SulfurCubeArchetype.KnockbackModifiers::new) ); } }