1use std::io::{Read, Write};
4
5use mcproto_codec::error::{CodecError, CodecKind};
6
7use crate::{
8 Boolean, Float, IdOr, IdSet, Identifier, Int, Nbt, PrefixedArray, PrefixedOptional,
9 PrefixedString, ProtocolEnum, SoundEvent, TextComponent, TypeCodec, TypeStructCodec, VarInt,
10};
11
12use super::{ResolvableProfile, Slot, types::*};
13
14macro_rules! component_struct {
15 ($name:ident) => {
16 #[doc = concat!("Wire payload for the `", stringify!($name), "` structured item component.")]
17 #[derive(Debug, Clone, PartialEq, TypeStructCodec)]
18 #[type_struct_codec(kind = StructuredComponent)]
19 pub struct $name;
20 };
21 ($name:ident { $($field:ident: $ty:ty),* $(,)? }) => {
22 #[doc = concat!("Wire payload for the `", stringify!($name), "` structured item component.")]
23 #[derive(Debug, Clone, PartialEq, TypeStructCodec)]
24 #[type_struct_codec(kind = StructuredComponent)]
25 pub struct $name { $(pub $field: $ty,)* }
26 };
27}
28
29component_struct!(CustomDataComponent { data: Nbt });
30component_struct!(MaxStackSizeComponent {
31 max_stack_size: VarInt
32});
33component_struct!(MaxDamageComponent { max_damage: VarInt });
34component_struct!(DamageComponent { damage: VarInt });
35component_struct!(UnbreakableComponent);
36component_struct!(CustomNameComponent {
37 name: TextComponent
38});
39component_struct!(ItemNameComponent {
40 name: TextComponent
41});
42component_struct!(ItemModelComponent { model: Identifier });
43component_struct!(LoreComponent { lines: PrefixedArray<TextComponent> });
44component_struct!(RarityComponent { rarity: Rarity });
45component_struct!(EnchantmentsComponent { enchantments: PrefixedArray<EnchantmentEntry> });
46component_struct!(CanPlaceOnComponent { predicates: PrefixedArray<BlockPredicate> });
47component_struct!(CanBreakComponent { predicates: PrefixedArray<BlockPredicate> });
48component_struct!(AttributeModifiersComponent { modifiers: PrefixedArray<AttributeModifier> });
49component_struct!(CustomModelDataComponent {
50 floats: PrefixedArray<Float>, flags: PrefixedArray<Boolean>,
51 strings: PrefixedArray<PrefixedString>, colors: PrefixedArray<Int>,
52});
53component_struct!(TooltipDisplayComponent {
54 hide_tooltip: Boolean, hidden_components: PrefixedArray<DataComponentType>,
55});
56component_struct!(RepairCostComponent { cost: VarInt });
57component_struct!(CreativeSlotLockComponent);
58component_struct!(EnchantmentGlintOverrideComponent { has_glint: Boolean });
59component_struct!(IntangibleProjectileComponent { empty: Nbt });
60component_struct!(FoodComponent {
61 nutrition: VarInt,
62 saturation_modifier: Float,
63 can_always_eat: Boolean,
64});
65component_struct!(ConsumableComponent {
66 consume_seconds: Float, animation: ItemUseAnimation, sound: IdOr<SoundEvent>,
67 has_consume_particles: Boolean, effects: PrefixedArray<ConsumeEffect>,
68});
69component_struct!(UseRemainderComponent { remainder: Box<Slot> });
70component_struct!(UseCooldownComponent {
71 seconds: Float, cooldown_group: PrefixedOptional<Identifier>,
72});
73component_struct!(UseEffectsComponent {
74 can_sprint: Boolean,
75 interact_vibrations: Boolean,
76 speed_multiplier: Float,
77});
78component_struct!(MinimumAttackChargeComponent {
79 minimum_attack_charge: Float
80});
81component_struct!(DamageTypeComponent {
82 damage_type_id: VarInt
83});
84component_struct!(DamageResistantComponent { types: IdSet });
85component_struct!(AttackRangeComponent {
86 min_reach: Float,
87 max_reach: Float,
88 min_creative_reach: Float,
89 max_creative_reach: Float,
90 hitbox_margin: Float,
91 mob_factor: Float,
92});
93component_struct!(ToolComponent {
94 rules: PrefixedArray<ToolRule>, default_mining_speed: Float,
95 damage_per_block: VarInt, can_destroy_blocks_in_creative: Boolean,
96});
97component_struct!(WeaponComponent {
98 damage_per_attack: VarInt,
99 disable_blocking_for: Float
100});
101component_struct!(EnchantableComponent { value: VarInt });
102component_struct!(EquippableComponent {
103 slot: EquipmentSlot, equip_sound: IdOr<SoundEvent>,
104 model: PrefixedOptional<Identifier>, camera_overlay: PrefixedOptional<Identifier>,
105 allowed_entities: PrefixedOptional<IdSet>, dispensable: Boolean, swappable: Boolean,
106 damage_on_hurt: Boolean, can_be_sheared: Boolean, shearing_sound: IdOr<SoundEvent>,
107});
108component_struct!(RepairableComponent { items: IdSet });
109component_struct!(GliderComponent);
110component_struct!(TooltipStyleComponent { style: Identifier });
111component_struct!(DeathProtectionComponent { effects: PrefixedArray<ConsumeEffect> });
112component_struct!(BlocksAttacksComponent {
113 block_delay_seconds: Float, disable_cooldown_scale: Float,
114 damage_reductions: PrefixedArray<DamageReduction>, item_damage_threshold: Float,
115 item_damage_base: Float, item_damage_factor: Float,
116 bypassed_by: PrefixedOptional<IdSet>,
117 block_sound: PrefixedOptional<IdOr<SoundEvent>>,
118 disable_sound: PrefixedOptional<IdOr<SoundEvent>>,
119});
120component_struct!(StoredEnchantmentsComponent { enchantments: PrefixedArray<EnchantmentEntry> });
121component_struct!(DyedColorComponent { color: Int });
122component_struct!(MapColorComponent { color: Int });
123component_struct!(MapIdComponent { id: VarInt });
124component_struct!(MapDecorationsComponent { data: Nbt });
125component_struct!(MapPostProcessingComponent {
126 processing: MapPostProcessing
127});
128component_struct!(ChargedProjectilesComponent { projectiles: PrefixedArray<Slot> });
129component_struct!(BundleContentsComponent { items: PrefixedArray<Slot> });
130component_struct!(PotionContentsComponent {
131 potion_id: PrefixedOptional<VarInt>, custom_color: PrefixedOptional<Int>,
132 custom_effects: PrefixedArray<PotionEffect>, custom_name: PrefixedOptional<PrefixedString>,
133});
134component_struct!(PotionDurationScaleComponent {
135 effect_multiplier: Float
136});
137component_struct!(SuspiciousStewEffectsComponent { effects: PrefixedArray<SuspiciousStewEffect> });
138component_struct!(WritableBookContentComponent { pages: PrefixedArray<Filterable<PrefixedString>> });
139component_struct!(WrittenBookContentComponent {
140 title: Filterable<PrefixedString>, author: PrefixedString, generation: VarInt,
141 pages: PrefixedArray<Filterable<TextComponent>>, resolved: Boolean,
142});
143component_struct!(TrimComponent {
144 material: IdOr<TrimMaterial>, pattern: IdOr<TrimPattern>,
145});
146component_struct!(DebugStickStateComponent { data: Nbt });
147component_struct!(EntityDataComponent {
148 entity_type_id: VarInt,
149 data: Nbt
150});
151component_struct!(BucketEntityDataComponent { data: Nbt });
152component_struct!(BlockEntityDataComponent {
153 block_entity_type_id: VarInt,
154 data: Nbt
155});
156component_struct!(InstrumentComponent { instrument: IdOr<Instrument> });
157component_struct!(PiercingWeaponComponent {
158 deals_knockback: Boolean, dismounts: Boolean,
159 sound: PrefixedOptional<SoundEvent>, hit_sound: PrefixedOptional<SoundEvent>,
160});
161component_struct!(KineticWeaponComponent {
162 contact_cooldown_ticks: VarInt, delay_ticks: VarInt,
163 dismount_conditions: PrefixedOptional<KineticWeaponCondition>,
164 knockback_conditions: PrefixedOptional<KineticWeaponCondition>,
165 damage_conditions: PrefixedOptional<KineticWeaponCondition>,
166 forward_movement: Float, damage_multiplier: Float,
167 sound: PrefixedOptional<SoundEvent>, hit_sound: PrefixedOptional<SoundEvent>,
168});
169component_struct!(SwingAnimationComponent {
170 animation_type: SwingAnimationType,
171 duration: VarInt
172});
173component_struct!(AdditionalTradeCostComponent {
174 additional_trade_cost: VarInt
175});
176component_struct!(DyeComponent { color: DyeColor });
177component_struct!(ProvidesTrimMaterialComponent { material: IdOr<TrimMaterial> });
178component_struct!(OminousBottleAmplifierComponent { amplifier: VarInt });
179component_struct!(JukeboxPlayableComponent { song: IdOr<JukeboxSong> });
180component_struct!(ProvidesBannerPatternsComponent { patterns: IdSet });
181component_struct!(RecipesComponent { data: Nbt });
182component_struct!(LodestoneTrackerComponent {
183 target: PrefixedOptional<GlobalPosition>, tracked: Boolean,
184});
185component_struct!(FireworkExplosionComponent {
186 explosion: FireworkExplosion
187});
188component_struct!(FireworksComponent {
189 flight_duration: VarInt, explosions: PrefixedArray<FireworkExplosion>,
190});
191component_struct!(ProfileComponent {
192 profile: ResolvableProfile
193});
194component_struct!(NoteBlockSoundComponent { sound: Identifier });
195component_struct!(BannerPatternsComponent { layers: PrefixedArray<BannerPatternLayer> });
196component_struct!(BaseColorComponent { color: DyeColor });
197component_struct!(PotDecorationsComponent { decorations: PrefixedArray<VarInt> });
198component_struct!(ContainerComponent { items: PrefixedArray<Slot> });
199component_struct!(BlockStateComponent { properties: PrefixedArray<BlockStateProperty> });
200component_struct!(BeesComponent { bees: PrefixedArray<Bee> });
201component_struct!(LockComponent { key: NbtString });
202component_struct!(ContainerLootComponent { data: Nbt });
203component_struct!(BreakSoundComponent { sound: IdOr<SoundEvent> });
204component_struct!(SulfurCubeContentComponent { content: Box<Slot> });
205
206component_struct!(VillagerVariantComponent { variant_id: VarInt });
207component_struct!(WolfVariantComponent { variant_id: VarInt });
208component_struct!(WolfSoundVariantComponent { variant_id: VarInt });
209component_struct!(WolfCollarComponent { color: DyeColor });
210component_struct!(FoxVariantComponent {
211 variant: FoxVariant
212});
213component_struct!(SalmonSizeComponent { size: SalmonSize });
214component_struct!(ParrotVariantComponent {
215 variant: ParrotVariant
216});
217component_struct!(TropicalFishPatternComponent {
218 pattern: TropicalFishPattern
219});
220component_struct!(TropicalFishBaseColorComponent { color: DyeColor });
221component_struct!(TropicalFishPatternColorComponent { color: DyeColor });
222component_struct!(MooshroomVariantComponent {
223 variant: MooshroomVariant
224});
225component_struct!(RabbitVariantComponent {
226 variant: RabbitVariant
227});
228component_struct!(PigVariantComponent { variant_id: VarInt });
229component_struct!(PigSoundVariantComponent { variant_id: VarInt });
230component_struct!(CowVariantComponent { variant_id: VarInt });
231component_struct!(CowSoundVariantComponent { variant_id: VarInt });
232component_struct!(ChickenVariantComponent { variant_id: VarInt });
233component_struct!(ChickenSoundVariantComponent { variant_id: VarInt });
234component_struct!(FrogVariantComponent { variant_id: VarInt });
235component_struct!(HorseVariantComponent {
236 variant: HorseVariant
237});
238component_struct!(PaintingVariantComponent { variant: IdOr<PaintingVariant> });
239component_struct!(LlamaVariantComponent {
240 variant: LlamaVariant
241});
242component_struct!(AxolotlVariantComponent {
243 variant: AxolotlVariant
244});
245component_struct!(ZombieNautilusVariantComponent { variant_id: VarInt });
246component_struct!(CatVariantComponent { variant_id: VarInt });
247component_struct!(CatSoundVariantComponent { variant_id: VarInt });
248component_struct!(CatCollarComponent { color: DyeColor });
249component_struct!(SheepColorComponent { color: DyeColor });
250component_struct!(ShulkerColorComponent { color: DyeColor });
251
252macro_rules! small_enum {
253 ($name:ident { $($variant:ident = $id:literal),+ $(,)? }) => {
254 #[derive(Debug, Clone, Copy, PartialEq, Eq, ProtocolEnum)]
255 #[protocol_enum(repr = VarInt)]
256 pub enum $name { $($variant = $id,)+ }
257 };
258}
259
260small_enum!(FoxVariant { Red = 0, Snow = 1 });
261small_enum!(SalmonSize { Small = 0, Medium = 1, Large = 2 });
262small_enum!(ParrotVariant { RedBlue = 0, Blue = 1, Green = 2, YellowBlue = 3, Gray = 4 });
263small_enum!(TropicalFishPattern {
264 Kob = 0, Sunstreak = 1, Snooper = 2, Dasher = 3, Brinely = 4, Spotty = 5,
265 Flopper = 6, Stripey = 7, Glitter = 8, Blockfish = 9, Betty = 10, Clayfish = 11,
266});
267small_enum!(MooshroomVariant { Red = 0, Brown = 1 });
268small_enum!(RabbitVariant {
269 Brown = 0, White = 1, Black = 2, WhiteSplotched = 3, Gold = 4, Salt = 5, Evil = 6,
270});
271small_enum!(HorseVariant {
272 White = 0, Creamy = 1, Chestnut = 2, Brown = 3, Black = 4, Gray = 5, DarkBrown = 6,
273});
274small_enum!(LlamaVariant { Creamy = 0, White = 1, Brown = 2, Gray = 3 });
275small_enum!(AxolotlVariant { Lucy = 0, Wild = 1, Gold = 2, Cyan = 3, Blue = 4 });
276
277macro_rules! data_components {
278 ($($variant:ident($payload:ty) = $id:literal => $key:literal),+ $(,)?) => {
279 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, ProtocolEnum)]
281 #[protocol_enum(repr = VarInt)]
282 pub enum DataComponentType { $($variant = $id,)+ }
283
284 impl DataComponentType {
285 pub const fn identifier(self) -> &'static str {
287 match self { $(Self::$variant => $key,)+ }
288 }
289 }
290
291 #[derive(Debug, Clone, PartialEq)]
293 pub enum DataComponent { $($variant($payload),)+ }
294
295 impl DataComponent {
296 pub const fn component_type(&self) -> DataComponentType {
298 match self { $(Self::$variant(_) => DataComponentType::$variant,)+ }
299 }
300 }
301
302 impl TypeCodec for DataComponent {
303 fn encode(&self, writer: &mut impl Write) -> Result<(), CodecError> {
304 self.component_type().encode(writer)
305 .map_err(|e| e.with_context(CodecKind::DataComponent))?;
306 match self { $(Self::$variant(value) => value.encode(writer),)+ }
307 .map_err(|e| e.with_context(CodecKind::DataComponent))
308 }
309 fn decode(reader: &mut impl Read) -> Result<Self, CodecError> {
310 let ty = DataComponentType::decode(reader)
311 .map_err(|e| e.with_context(CodecKind::DataComponent))?;
312 match ty { $(DataComponentType::$variant => <$payload>::decode(reader).map(Self::$variant),)+ }
313 .map_err(|e| e.with_context(CodecKind::DataComponent))
314 }
315 }
316 };
317}
318
319data_components! {
320 CustomData(CustomDataComponent)=0=>"minecraft:custom_data",
321 MaxStackSize(MaxStackSizeComponent)=1=>"minecraft:max_stack_size",
322 MaxDamage(MaxDamageComponent)=2=>"minecraft:max_damage",
323 Damage(DamageComponent)=3=>"minecraft:damage",
324 Unbreakable(UnbreakableComponent)=4=>"minecraft:unbreakable",
325 CustomName(CustomNameComponent)=5=>"minecraft:custom_name",
326 ItemName(ItemNameComponent)=6=>"minecraft:item_name",
327 ItemModel(ItemModelComponent)=7=>"minecraft:item_model",
328 Lore(LoreComponent)=8=>"minecraft:lore",
329 Rarity(RarityComponent)=9=>"minecraft:rarity",
330 Enchantments(EnchantmentsComponent)=10=>"minecraft:enchantments",
331 CanPlaceOn(CanPlaceOnComponent)=11=>"minecraft:can_place_on",
332 CanBreak(CanBreakComponent)=12=>"minecraft:can_break",
333 AttributeModifiers(AttributeModifiersComponent)=13=>"minecraft:attribute_modifiers",
334 CustomModelData(CustomModelDataComponent)=14=>"minecraft:custom_model_data",
335 TooltipDisplay(TooltipDisplayComponent)=15=>"minecraft:tooltip_display",
336 RepairCost(RepairCostComponent)=16=>"minecraft:repair_cost",
337 CreativeSlotLock(CreativeSlotLockComponent)=17=>"minecraft:creative_slot_lock",
338 EnchantmentGlintOverride(EnchantmentGlintOverrideComponent)=18=>"minecraft:enchantment_glint_override",
339 IntangibleProjectile(IntangibleProjectileComponent)=19=>"minecraft:intangible_projectile",
340 Food(FoodComponent)=20=>"minecraft:food",
341 Consumable(ConsumableComponent)=21=>"minecraft:consumable",
342 UseRemainder(UseRemainderComponent)=22=>"minecraft:use_remainder",
343 UseCooldown(UseCooldownComponent)=23=>"minecraft:use_cooldown",
344 UseEffects(UseEffectsComponent)=24=>"minecraft:use_effects",
345 MinimumAttackCharge(MinimumAttackChargeComponent)=25=>"minecraft:minimum_attack_charge",
346 DamageType(DamageTypeComponent)=26=>"minecraft:damage_type",
347 DamageResistant(DamageResistantComponent)=27=>"minecraft:damage_resistant",
348 AttackRange(AttackRangeComponent)=28=>"minecraft:attack_range",
349 Tool(ToolComponent)=29=>"minecraft:tool",
350 Weapon(WeaponComponent)=30=>"minecraft:weapon",
351 Enchantable(EnchantableComponent)=31=>"minecraft:enchantable",
352 Equippable(EquippableComponent)=32=>"minecraft:equippable",
353 Repairable(RepairableComponent)=33=>"minecraft:repairable",
354 Glider(GliderComponent)=34=>"minecraft:glider",
355 TooltipStyle(TooltipStyleComponent)=35=>"minecraft:tooltip_style",
356 DeathProtection(DeathProtectionComponent)=36=>"minecraft:death_protection",
357 BlocksAttacks(BlocksAttacksComponent)=37=>"minecraft:blocks_attacks",
358 StoredEnchantments(StoredEnchantmentsComponent)=38=>"minecraft:stored_enchantments",
359 DyedColor(DyedColorComponent)=39=>"minecraft:dyed_color",
360 MapColor(MapColorComponent)=40=>"minecraft:map_color",
361 MapId(MapIdComponent)=41=>"minecraft:map_id",
362 MapDecorations(MapDecorationsComponent)=42=>"minecraft:map_decorations",
363 MapPostProcessing(MapPostProcessingComponent)=43=>"minecraft:map_post_processing",
364 ChargedProjectiles(ChargedProjectilesComponent)=44=>"minecraft:charged_projectiles",
365 BundleContents(BundleContentsComponent)=45=>"minecraft:bundle_contents",
366 PotionContents(PotionContentsComponent)=46=>"minecraft:potion_contents",
367 PotionDurationScale(PotionDurationScaleComponent)=47=>"minecraft:potion_duration_scale",
368 SuspiciousStewEffects(SuspiciousStewEffectsComponent)=48=>"minecraft:suspicious_stew_effects",
369 WritableBookContent(WritableBookContentComponent)=49=>"minecraft:writable_book_content",
370 WrittenBookContent(WrittenBookContentComponent)=50=>"minecraft:written_book_content",
371 Trim(TrimComponent)=51=>"minecraft:trim",
372 DebugStickState(DebugStickStateComponent)=52=>"minecraft:debug_stick_state",
373 EntityData(EntityDataComponent)=53=>"minecraft:entity_data",
374 BucketEntityData(BucketEntityDataComponent)=54=>"minecraft:bucket_entity_data",
375 BlockEntityData(BlockEntityDataComponent)=55=>"minecraft:block_entity_data",
376 Instrument(InstrumentComponent)=56=>"minecraft:instrument",
377 PiercingWeapon(PiercingWeaponComponent)=57=>"minecraft:piercing_weapon",
378 KineticWeapon(KineticWeaponComponent)=58=>"minecraft:kinetic_weapon",
379 SwingAnimation(SwingAnimationComponent)=59=>"minecraft:swing_animation",
380 AdditionalTradeCost(AdditionalTradeCostComponent)=60=>"minecraft:additional_trade_cost",
381 Dye(DyeComponent)=61=>"minecraft:dye",
382 ProvidesTrimMaterial(ProvidesTrimMaterialComponent)=62=>"minecraft:provides_trim_material",
383 OminousBottleAmplifier(OminousBottleAmplifierComponent)=63=>"minecraft:ominous_bottle_amplifier",
384 JukeboxPlayable(JukeboxPlayableComponent)=64=>"minecraft:jukebox_playable",
385 ProvidesBannerPatterns(ProvidesBannerPatternsComponent)=65=>"minecraft:provides_banner_patterns",
386 Recipes(RecipesComponent)=66=>"minecraft:recipes",
387 LodestoneTracker(LodestoneTrackerComponent)=67=>"minecraft:lodestone_tracker",
388 FireworkExplosion(FireworkExplosionComponent)=68=>"minecraft:firework_explosion",
389 Fireworks(FireworksComponent)=69=>"minecraft:fireworks",
390 Profile(ProfileComponent)=70=>"minecraft:profile",
391 NoteBlockSound(NoteBlockSoundComponent)=71=>"minecraft:note_block_sound",
392 BannerPatterns(BannerPatternsComponent)=72=>"minecraft:banner_patterns",
393 BaseColor(BaseColorComponent)=73=>"minecraft:base_color",
394 PotDecorations(PotDecorationsComponent)=74=>"minecraft:pot_decorations",
395 Container(ContainerComponent)=75=>"minecraft:container",
396 BlockState(BlockStateComponent)=76=>"minecraft:block_state",
397 Bees(BeesComponent)=77=>"minecraft:bees",
398 Lock(LockComponent)=78=>"minecraft:lock",
399 ContainerLoot(ContainerLootComponent)=79=>"minecraft:container_loot",
400 BreakSound(BreakSoundComponent)=80=>"minecraft:break_sound",
401 SulfurCubeContent(SulfurCubeContentComponent)=81=>"minecraft:sulfur_cube_content",
402 VillagerVariant(VillagerVariantComponent)=82=>"minecraft:villager/variant",
403 WolfVariant(WolfVariantComponent)=83=>"minecraft:wolf/variant",
404 WolfSoundVariant(WolfSoundVariantComponent)=84=>"minecraft:wolf/sound_variant",
405 WolfCollar(WolfCollarComponent)=85=>"minecraft:wolf/collar",
406 FoxVariant(FoxVariantComponent)=86=>"minecraft:fox/variant",
407 SalmonSize(SalmonSizeComponent)=87=>"minecraft:salmon/size",
408 ParrotVariant(ParrotVariantComponent)=88=>"minecraft:parrot/variant",
409 TropicalFishPattern(TropicalFishPatternComponent)=89=>"minecraft:tropical_fish/pattern",
410 TropicalFishBaseColor(TropicalFishBaseColorComponent)=90=>"minecraft:tropical_fish/base_color",
411 TropicalFishPatternColor(TropicalFishPatternColorComponent)=91=>"minecraft:tropical_fish/pattern_color",
412 MooshroomVariant(MooshroomVariantComponent)=92=>"minecraft:mooshroom/variant",
413 RabbitVariant(RabbitVariantComponent)=93=>"minecraft:rabbit/variant",
414 PigVariant(PigVariantComponent)=94=>"minecraft:pig/variant",
415 PigSoundVariant(PigSoundVariantComponent)=95=>"minecraft:pig/sound_variant",
416 CowVariant(CowVariantComponent)=96=>"minecraft:cow/variant",
417 CowSoundVariant(CowSoundVariantComponent)=97=>"minecraft:cow/sound_variant",
418 ChickenVariant(ChickenVariantComponent)=98=>"minecraft:chicken/variant",
419 ChickenSoundVariant(ChickenSoundVariantComponent)=99=>"minecraft:chicken/sound_variant",
420 FrogVariant(FrogVariantComponent)=100=>"minecraft:frog/variant",
421 HorseVariant(HorseVariantComponent)=101=>"minecraft:horse/variant",
422 PaintingVariant(PaintingVariantComponent)=102=>"minecraft:painting/variant",
423 LlamaVariant(LlamaVariantComponent)=103=>"minecraft:llama/variant",
424 AxolotlVariant(AxolotlVariantComponent)=104=>"minecraft:axolotl/variant",
425 ZombieNautilusVariant(ZombieNautilusVariantComponent)=105=>"minecraft:zombie_nautilus/variant",
426 CatVariant(CatVariantComponent)=106=>"minecraft:cat/variant",
427 CatSoundVariant(CatSoundVariantComponent)=107=>"minecraft:cat/sound_variant",
428 CatCollar(CatCollarComponent)=108=>"minecraft:cat/collar",
429 SheepColor(SheepColorComponent)=109=>"minecraft:sheep/color",
430 ShulkerColor(ShulkerColorComponent)=110=>"minecraft:shulker/color",
431}