{
  "format_version": "1.21.0",
  "minecraft:entity": {
    "description": {
      "identifier": "cyn_hao:pegasus",
      "is_spawnable": true,
      "is_summonable": true,
      "is_experimental": false,

      "animations": {
        "bucking_controller": "controller.animation.cyn_hao.horse.bucking",
        "special_breed": "controller.animation.cyn_hao.special_breed",
        
        // flight management
        // animations that modifies the speed of this flyer when wild and tame
				"flyer_speed_wild": "animation.cyn_hao.flyer.speed_-5",
        "flyer_speed_tame": "animation.cyn_hao.flyer.speed_1",

        // controllers that determine WHEN to apply those speed modifiers
        "flyer_speed_wild_controller": "controller.animation.cyn_hao.flyer.air.speed_wild",
        "flyer_speed_tame_controller": "controller.animation.cyn_hao.flyer.air.speed_tame",

        // flight effects
				"slow_fall": "animation.cyn_hao.flyer.slow_fall"
      },
      "scripts": {
        "animate": [
          // animation controller to make the horse play the
          // angry sound when bucking, like vanilla horses
          "bucking_controller",

          // animation controller to update it's special_breed property
          // after it has become active
          "special_breed",

          // controllers that apply speed modifiers to flyers 
          // otherwise they are fast / slow
          // modifier determined by the above animations
					{ "flyer_speed_wild_controller": "!query.is_tamed && query.can_fly" },
          { "flyer_speed_tame_controller": "query.is_tamed && query.has_player_rider" },
					
					// grants slow fall for 65 seconds every 60 seconds
					"slow_fall"
        ]
      },

      "properties": {
        // Flyer checks
        // Can this flyer fly in air?
        "cyn:flyer_air": {
          "type": "bool",
          "default": true,
          "client_sync": true
        },

        // Can this flyer fly in water?
        "cyn:flyer_water": {
          "type": "bool",
          "default": false,
          "client_sync": true
        },
        
        

        // "Color" properties
				"cyn_hao:base_id": {
					"type": "int",
          "range": [0, 2],
					"default": 0,
					"client_sync": true
				},
        

        
        // Attribute Properties
        // These properties track what group this horse is in
        // per attribute
        // since the RP doesn't use these values at all,
        // client sync can actually be false for once!
        // MAKE SURE THE RANGES OF ALL THESE MATCH!!!
        // the script assumes a size of 10 so that
        // we can just have one function run on each of these

        // Default of 3
        "cyn_hao:health_group_id": {
          "type": "int",
          "range": [0, 9],
          "default": 3,
          "client_sync": true
        },
        "cyn_hao:speed_group_id": {
          "type": "int",
          "range": [0, 9],
          "default": 3,
          "client_sync": true
        },
        "cyn_hao:jump_group_id": {
          "type": "int",
          "range": [0, 9],
          "default": 3,
          "client_sync": true
        },



        // Scale Properties
        // all horses use horse absolute limits,
        // since nothing has greater limits than horses,
        // and most have smaller (ie within horse limits)
        "cyn_hao:height_scale": {
          "type": "float",
          "range": [
            -0.125, 
            0.1875
          ],
          "default": 0.0,
          "client_sync": true
        },
        "cyn_hao:density_scale": {
          "type": "float",
          "range": [
            -0.1875, 
            0.0875
          ],
          "default": 0.0,
          "client_sync": true
        },

        // NOTE that the random_scale anim
        // uses tail_scale DIRECTLY in the scale,
        // compared to the other props are the leg / body OFFSET scale
        // that's why it has no negetive
        "cyn_hao:tail_scale": {
          "type": "float",
          "range": [
            0.45,
            1.875
          ],
          "default": 1.0,
          "client_sync": true
        },



        // Equipment Properties
        // Done here since I couldn't get
        // query.armor_material_slot to work,
        // even when copying from horse Render Controller
        "cyn_hao:armor_type": {
          "type": "int",
          // 0 = no armor
          // 1 = leather
          // 2 = iron
          // 3 = gold
          // 4 = diamond
          "range": [0, 4],
          "default": 0,
          "client_sync": true
        },
        "cyn_hao:carpet_color": {
          "type": "int",
          // 0 to 17
          // 0 is no carpet
          // 1 - 16 are carpet colors + 1
          // 17 is moss carpet
          "range": [0, 17],
          "default": 0,
          "client_sync": true
        },


        
        // Behavior properties
        "cyn_hao:just_born":{
          "type": "bool",
          "default": false,
          "client_sync": true
        },
        "cyn_hao:special_breed": {
          "type": "bool",
          "default": false,
          "client_sync": true
        }
			}
    },

    "component_groups": {
      // Attribute Range Groups
      // Since we can't set them directly via script,
      // we have multiple groups of ranges
      // babies will still choose a random value,
      // but at least that random value will remain in
      // "range" of the parents' average, breeding up
      // oh how I love excel...

      // NOTE that these groups contain the upper, tamed horse limits!
      // Wild horses will NEVER spawn in group

      // Health
      "cyn_hao:group_health_0": {
        "minecraft:health": {
          "value": {
            "range_min": 20,
            "range_max": 23
          }
        }
      },
      "cyn_hao:group_health_1": {
        "minecraft:health": {
          "value": {
            "range_min": 23,
            "range_max": 26
          }
        }
      },
      "cyn_hao:group_health_2": {
        "minecraft:health": {
          "value": {
            "range_min": 26,
            "range_max": 29
          }
        }
      },
      "cyn_hao:group_health_3": {
        "minecraft:health": {
          "value": {
            "range_min": 29,
            "range_max": 32
          }
        }
      },
      "cyn_hao:group_health_4": {
        "minecraft:health": {
          "value": {
            "range_min": 32,
            "range_max": 35
          }
        }
      },
      "cyn_hao:group_health_5": {
        "minecraft:health": {
          "value": {
            "range_min": 35,
            "range_max": 38
          }
        }
      },
      "cyn_hao:group_health_6": {
        "minecraft:health": {
          "value": {
            "range_min": 38,
            "range_max": 41
          }
        }
      },
      "cyn_hao:group_health_7": {
        "minecraft:health": {
          "value": {
            "range_min": 41,
            "range_max": 44
          }
        }
      },
      "cyn_hao:group_health_8": {
        "minecraft:health": {
          "value": {
            "range_min": 44,
            "range_max": 47
          }
        }
      },
      "cyn_hao:group_health_9": {
        "minecraft:health": {
          "value": {
            "range_min": 47,
            "range_max": 50
          }
        }
      },
 
      "cyn_hao:group_speed_0": {
        "minecraft:movement": {
          "value": {
            "range_min": 0.23,
            "range_max": 0.262
          }
        }
      },
      "cyn_hao:group_speed_1": {
        "minecraft:movement": {
          "value": {
            "range_min": 0.262,
            "range_max": 0.294
          }
        }
      },
      "cyn_hao:group_speed_2": {
        "minecraft:movement": {
          "value": {
            "range_min": 0.294,
            "range_max": 0.326
          }
        }
      },
      "cyn_hao:group_speed_3": {
        "minecraft:movement": {
          "value": {
            "range_min": 0.326,
            "range_max": 0.358
          }
        }
      },
      "cyn_hao:group_speed_4": {
        "minecraft:movement": {
          "value": {
            "range_min": 0.358,
            "range_max": 0.39
          }
        }
      },
      "cyn_hao:group_speed_5": {
        "minecraft:movement": {
          "value": {
            "range_min": 0.39,
            "range_max": 0.422
          }
        }
      },
      "cyn_hao:group_speed_6": {
        "minecraft:movement": {
          "value": {
            "range_min": 0.422,
            "range_max": 0.454
          }
        }
      },
      "cyn_hao:group_speed_7": {
        "minecraft:movement": {
          "value": {
            "range_min": 0.454,
            "range_max": 0.486
          }
        }
      },
      "cyn_hao:group_speed_8": {
        "minecraft:movement": {
          "value": {
            "range_min": 0.486,
            "range_max": 0.518
          }
        }
      },
      "cyn_hao:group_speed_9": {
        "minecraft:movement": {
          "value": {
            "range_min": 0.518,
            "range_max": 0.55
          }
        }
      },
 
      "cyn_hao:group_jump_0": {
        "minecraft:horse.jump_strength": {
          "value": {
            "range_min": 0.7,
            "range_max": 0.76
          }
        }
      },
      "cyn_hao:group_jump_1": {
        "minecraft:horse.jump_strength": {
          "value": {
            "range_min": 0.76,
            "range_max": 0.82
          }
        }
      },
      "cyn_hao:group_jump_2": {
        "minecraft:horse.jump_strength": {
          "value": {
            "range_min": 0.82,
            "range_max": 0.88
          }
        }
      },
      "cyn_hao:group_jump_3": {
        "minecraft:horse.jump_strength": {
          "value": {
            "range_min": 0.88,
            "range_max": 0.94
          }
        }
      },
      "cyn_hao:group_jump_4": {
        "minecraft:horse.jump_strength": {
          "value": {
            "range_min": 0.94,
            "range_max": 1
          }
        }
      },
      "cyn_hao:group_jump_5": {
        "minecraft:horse.jump_strength": {
          "value": {
            "range_min": 1,
            "range_max": 1.06
          }
        }
      },
      "cyn_hao:group_jump_6": {
        "minecraft:horse.jump_strength": {
          "value": {
            "range_min": 1.06,
            "range_max": 1.12
          }
        }
      },
      "cyn_hao:group_jump_7": {
        "minecraft:horse.jump_strength": {
          "value": {
            "range_min": 1.12,
            "range_max": 1.18
          }
        }
      },
      "cyn_hao:group_jump_8": {
        "minecraft:horse.jump_strength": {
          "value": {
            "range_min": 1.18,
            "range_max": 1.24
          }
        }
      },
      "cyn_hao:group_jump_9": {
        "minecraft:horse.jump_strength": {
          "value": {
            "range_min": 1.24,
            "range_max": 1.3
          }
        }
      },








      
      // Dyed Leather Armor
      // Unfortunately, it seems like using query.armor_color_slot in a material's
      // color field to set the color of a texture is currently bugged 
      // at the time of making this file:
      // https://bugs.mojang.com/browse/MCPE-183985

      // Therefore, we unfortunately have to just resolve to dyeing similar to
      // sheep, wolf and cat collars with the minecraft:is_dyeable component
      // so we will use behavior animation controller to apply or remove the dyeable component
      // as is neccessary, and change the texture to instead work how the sheep one does
      // (instead of referring to the vanilla leather horse armor)
      "cyn_hao:group_horse_dyeable": {
        "minecraft:is_dyeable": {
          "interact_text": "action.interact.dye"
        }
      },
      
      // since we can't set properties on spawn
      // (they don't get set since entity doesn't exist yet)
      // call an event with a command to play born anim
      "cyn_hao:group_horse_born_start": {
        "minecraft:is_baby": {
        },
        "minecraft:scale": {
          "value": 0.5
        },
        "minecraft:ageable": {
					"grow_up": {
						"event": "cyn_hao:event_horse_born_end",
						"target": "self"
					},
					"duration": 4.5
				},

        "minecraft:scheduler": {
          "min_delay_secs": 0,
          "max_delay_secs": 0,
          "scheduled_events": [
            {
              "event": "cyn_hao:event_set_property_just_born_true"
            }
          ]
        }
      },

      "cyn_hao:group_horse_baby": {
        "minecraft:type_family": {
         "family": [ "cyn_hao:horses", "cyn_hao:baby_horse", "cyn_hao:pegasus", "horse", "mob" ]
        },
        "minecraft:is_baby": {
        },
        "minecraft:scale_by_age": {
          "start_scale": 0.5,
          "end_scale": 1.0
        },
        "minecraft:ageable": { 
          "duration": 1200,
          "feed_items": [
            {
              "item": "wheat",
              "growth": 0.016667
            },
            {
              "item": "sugar",
              "growth": 0.025
            },
            {
              "item": "hay_block",
              "growth": 0.15
            },
            {
              "item": "apple",
              "growth": 0.05
            },
            {
              "item": "golden_carrot",
              "growth": 0.05
            },
            {
              "item": "golden_apple",
              "growth": 0.2
            },
            {
              "item": "appleEnchanted",
              "growth": 0.2
            }
          ],
          "grow_up": {
            "event": "cyn_hao:ageable_grow_up",
            "target": "self"
          }
        },
        "minecraft:behavior.follow_parent": {
          "priority": 4,
          "speed_multiplier": 1.0
        }
      },

      "cyn_hao:group_horse_adult": {
        "minecraft:experience_reward": {
          "on_bred": "Math.Random(1,7)",
          "on_death": "query.last_hit_by_player ? Math.Random(1,3) : 0"
        },
        "minecraft:loot": {
          "table": "loot_tables/cynosia/horses/entities/cyn_pegasus.json"
        },
        "minecraft:behavior.breed": {
          "priority": 2,
          "speed_multiplier": 1.0
        }
      },



      "cyn_hao:group_horse_wild": {
        "minecraft:behavior.mount_pathing": {
          "priority": 2,
          "speed_multiplier": 1.5,
          "target_dist": 0.0,
          "track_target": true
        },
        "minecraft:tamemount": {
          "min_temper": 0,
          "max_temper": 100,
          "feed_text": "action.interact.feed",
          "ride_text": "action.interact.mount",
          "feed_items": [
            {
              "item": "wheat",
              "temper_mod": 3
            },
            {
              "item": "sugar",
              "temper_mod": 3
            },
            {
              "item": "apple",
              "temper_mod": 3
            },
            {
              "item": "golden_carrot",
              "temper_mod": 5
            },
            {
              "item": "golden_apple",
              "temper_mod": 10
            },
            {
              "item": "appleEnchanted",
              "temper_mod": 10
            }
          ],
          "auto_reject_items": [
            {
              "item": "horsearmorleather"
            },
            {
              "item": "horsearmoriron"
            },
            {
              "item": "horsearmorgold"
            },
            {
              "item": "horsearmordiamond"
            },
            {
              "item": "saddle"
            }
          ],
          "tame_event": {
            "event": "cyn_hao:event_on_tame",
            "target": "self"
          }
        },

        // cycling between flying and walking
				"minecraft:timer": {
					"looping": true,
					"randomInterval": true,
					"time": [5, 120],
					"time_down_event": {
					  "event": "cyn_hao:event_flyer_wild_roll",
					  "target": "self"
					}
				}
      },

      "cyn_hao:group_flyer_wild_flying": {
				"minecraft:can_fly": {
				},
				"minecraft:navigation.float": {	
					"can_path_over_water": true	
				},
				"minecraft:behavior.float_wander": {
					"priority": 2,
					"float_duration": [ 5, 60 ],
					"must_reach": true
				}
			},

			"cyn_hao:group_flyer_wild_grounded": {
				"minecraft:navigation.walk": {
					"can_path_over_water": true,
					"avoid_water": true,
					"avoid_damage_blocks": true
				},

				"minecraft:behavior.random_stroll": {
					"priority": 8,
					"speed_multiplier": 1.0
				}
			},


      "cyn_hao:group_horse_tamed": {
        "minecraft:type_family": {
        // anything with the cyn:flyer tag can be flown by the player
        // (provided our cyn flyer_flight script is present as well)
        "family": [ "cyn:flyer", "cyn_hao:horses", "cyn_hao:tamed_horse", "cyn_hao:pegasus", "horse", "mob" ]
        },
        "minecraft:is_tamed": {
        },

        // default horse armor color is brown
        "minecraft:color": {
          "value": 12
        },

        "minecraft:inventory": {
          "inventory_size": 18,
          "container_type": "horse"
        },

        "minecraft:behavior.panic": {
          "priority": 3,
          "speed_multiplier": 1.2
        },

        // since this is a flyer, which has 2 different navigations
        // when wild, which we remove when we tame them, 
        // give them their navigation back
        "minecraft:navigation.walk": {
          "can_path_over_water": false,
          "avoid_water": true,
          "avoid_damage_blocks": true
        }
      },



      // Special Breeding Mode
      // When fed their special item, they will be in special mode
      // for 20 seconds, during which their breeds will be different
      "cyn_hao:group_special_breed_fairy": {
        "minecraft:breedable": {
          // color and scale properties are handled via script
          "parent_centric_attribute_blending": [
            "minecraft:health",
            "minecraft:movement",
            "minecraft:horse.jump_strength"
          ],
          "require_tame": true,
          "inherit_tamed": false,
          "allow_sitting": true,
          "extra_baby_chance": 0.10,
          "breed_cooldown": 300,
          "breeds_with": [
            {
              "mate_type": "cyn_hao:rainbow_horse",
              "baby_type": "cyn_hao:fairy_horse",
              "breed_event": {
                "event": "cyn_hao:event_horse_born_special",
                "target": "baby"
              }
            }
          ],
          "breed_items": [
            "golden_carrot",
            "golden_apple",
            "appleEnchanted"
          ]
        },

        // Special Breeding State lasts for 3 minutes
        "minecraft:timer": {
          "time": 180,
          "looping": false,
          "time_down_event": {
            "event": "cyn_hao:event_normal_breed",
            "target": "self"
          }
        }
      },

      // Normal Breeding Mode
      "cyn_hao:group_normal_breed": {
        "minecraft:breedable": {
          // color and scale properties are handled via script
          "parent_centric_attribute_blending": [
            "minecraft:health",
            "minecraft:movement",
            "minecraft:horse.jump_strength"
          ],
          "require_tame": true,
          "inherit_tamed": false,
          "allow_sitting": true,
          "extra_baby_chance": 0.10,
          "breed_cooldown": 300,
          "breeds_with": [
            {
              "mate_type": "cyn_hao:pegasus",
              "baby_type": "cyn_hao:pegasus",
              "breed_event": {
                "event": "cyn_hao:event_horse_born_normal",
                "target": "baby"
              }
            }
          ],
          "breed_items": [
            "golden_carrot",
            "golden_apple",
            "appleEnchanted"
          ]
        }
      },


      // horse movement groups
      // not much to say about wandering
      "cyn_hao:group_horse_movement_wandering": {
        "minecraft:behavior.random_look_around_and_sit": {
          "priority": 4,
          "continue_if_leashed": true,
          "continue_sitting_on_reload": true,
          "min_look_count": 3,
          "max_look_count": 8,
          "min_look_time": 80,
          "max_look_time": 100,
          "min_angle_of_view_horizontal": -30,
          "max_angle_of_view_horizontal": 30,
          "random_look_around_cooldown": 5,
          "probability": 0.002
        },
        "minecraft:behavior.random_stroll": {
          "priority": 6,
          "speed_multiplier": 0.7,
          "interval": 180
        }
      },
      
      // following is a little janky, since there's suprisingly
      // little I could find to get an entity to,
      // of it's own free will, follow a player that is NOT
      // it's owner
      // And, unfortunately, many of the component classes in the
      // script API are still in experiemental
      // So the current solution is to make the horse constantly
      // "attack" the player
      // This has the downside of overriding attack-able horses'
      // default targetting and attacking behavior while following,
      // but that seems acceptable enough, at least for now
      // maybe in the future when the things we need to change owners
      // comes out of experimental we can re-visit this

      // Another downside (though smaller) is that horses also won't 
      // follow players in creative
      "cyn_hao:group_horse_movement_following": {

        // follow from a ludicrious distance
        "minecraft:follow_range": {
					"value": 1200,
					"max": 1200
				},

        // stay within 3 blocks of the player
				"minecraft:behavior.ranged_attack": {
					"priority": 1,
					"attack_interval": 0.1,
					"attack_radius": 3.0,
          "ranged_fov": 359,
          "set_persistent": true,
          "speed_multiplier": 1.0,
          "target_in_sight_time": 0,
          "x_max_rotation": 359,
          "y_max_head_rotation": 359
				},

        // "target" players 
        "minecraft:behavior.nearest_attackable_target": {
          "priority": 2,
          "reselect_targets": true,
					"must_see_forget_duration": 1200.0,
          "must_see": true,
          "attack_owner": true,
          "entity_types": [
            {
              "filters": {
                "test": "is_family",
                "subject": "other",
                "value": "player"
              },
              "max_dist": 1200.0
            }
          ]
        }
        
      },

      // define default targetting of attack-able horses
      // this is overridden when the horse follows the player,
      // and restored when they stop following
      "cyn_hao:group_horse_default_targetting": {
      },

      // if there becomes a better way to make entities sit
      // (atm we can't force sitting in API as there's no
      // EntitySittableComponent) maybe update this
      // for the time being, random look and sit is used
      // as it seems like random_sitting only works with
      // panda runtime identifier
      "cyn_hao:group_horse_movement_sitting": {
        "minecraft:behavior.random_look_around_and_sit": {
          "priority": 4,
          "continue_if_leashed": true,
          "continue_sitting_on_reload": true,
          "min_look_count": 20,
          "max_look_count": 50,
          "min_look_time": 80,
          "max_look_time": 100,
          "min_angle_of_view_horizontal": -30,
          "max_angle_of_view_horizontal": 30,
          "random_look_around_cooldown": 5,
          "probability": 1.0
        }
      },





      // unfortunately seat position in scripts is readonly
      // and seat pos vector doesn't accept molang,
      // so we define 3 "close enough" seat position heights
      // and set them with an environment sensor
      // (not in the spawn_event since properties aren't yet inited there)
      "cyn_hao:group_horse_seat_check": {
        "minecraft:environment_sensor": {
          "triggers": [
            {
              "event": "cyn_hao:event_horse_seat_short",
              "target": "self",
              "filters": {
                "all_of": [
                  {
                    "test": "float_property",
                    "domain": "cyn_hao:height_scale",
                    "operator": ">=",
                    "value": -0.05
                  },
                  {
                    "test": "float_property",
                    "domain": "cyn_hao:height_scale",
                    "operator": "<",
                    "value": 0.00
                  }
                ]
              }
            },
            {
              "event": "cyn_hao:event_horse_seat_medium",
              "target": "self",
              "filters": {
                "all_of": [
                  {
                    "test": "float_property",
                    "domain": "cyn_hao:height_scale",
                    "operator": ">=",
                    "value": 0.00
                  },
                  {
                    "test": "float_property",
                    "domain": "cyn_hao:height_scale",
                    "operator": "<",
                    "value": 0.05
                  }
                ]
              }
            },
            {
              "event": "cyn_hao:event_horse_seat_tall",
              "target": "self",
              "filters": {
                "all_of": [
                  {
                    "test": "float_property",
                    "domain": "cyn_hao:height_scale",
                    "operator": ">=",
                    "value": 0.05
                  },
                  {
                    "test": "float_property",
                    "domain": "cyn_hao:height_scale",
                    "operator": "<",
                    "value": 0.10
                  }
                ]
              }
            }          
          ]
        }
      },

      "cyn_hao:group_horse_seat_short": {
        "minecraft:rideable": {
          "seat_count": 1,
          "crouching_skip_interact": true,
          "family_types": [
            "player"
          ],
          "interact_text": "action.interact.ride.horse",
          "seats": {
            "position": [ 0.0, 1.07, -0.2 ]
          }
        }
      },

      "cyn_hao:group_horse_seat_medium": {
        "minecraft:rideable": {
          "seat_count": 1,
          "crouching_skip_interact": true,
          "family_types": [
            "player"
          ],
          "interact_text": "action.interact.ride.horse",
          "seats": {
            "position": [ 0.0, 1.17, -0.2 ]
          }
        }
      },

      "cyn_hao:group_horse_seat_tall": {
        "minecraft:rideable": {
          "seat_count": 1,
          "crouching_skip_interact": true,
          "family_types": [
            "player"
          ],
          "interact_text": "action.interact.ride.horse",
          "seats": {
            "position": [ 0.0, 1.27, -0.2 ]
          }
        }
      },



      "cyn_hao:group_horse_saddled": {
        "minecraft:is_saddled": {
        },
        "minecraft:input_ground_controlled": {
        },
        "minecraft:can_power_jump": {
        },
        "minecraft:behavior.player_ride_tamed": {
        }
      },

      "cyn_hao:group_horse_chested": {
        "minecraft:is_chested": {
        }
      }
    },



    "components": {
      // Attributes
      // unfortunately I couldn't get "actual" inheritance to work,
      // so for now I had to simply give up and just
      // allow ALL horses to use the tame values we want,
      // and hope parent_centric_attribute_blending
      // does heavy-enough lifting
      "minecraft:health": {
        "value": {
          "range_min": 15,
          "range_max": 40
        }
      },
      "minecraft:movement": {
        "value": {
          "range_min": 0.12,
          "range_max": 0.45
        }
      },
      "minecraft:horse.jump_strength": {
        "value": {
          "range_min": 0.5,
          "range_max": 1.15
        }
      },

      // make horses take slightly less fall damage since they can jump
      // so high they hurt themselves
      "minecraft:damage_sensor": {
        "triggers": {
          "cause": "fall",
          "deals_damage": true,
          "damage_modifier": -4
        }
      },

      "minecraft:is_hidden_when_invisible": {
      },

      "minecraft:type_family": {
        // anything with the cyn:flyer tag can be flown by the player
        // (provided our cyn flyer_flight script is present as well)
        // HOWEVER, we only want to grant it when they are tamed
        "family": [ "cyn_hao:horses", "cyn_hao:pegasus", "horse", "mob" ]
      },
      "minecraft:breathable": {
        "total_supply": 15,
        "suffocate_time": 0
      },
      "minecraft:collision_box": {
        "width": 1.0,
        "height": 1.6
      },
      "minecraft:hurt_on_condition": {
        "damage_conditions": [
          {
            "filters": {
              "test": "in_lava",
              "subject": "self",
              "operator": "==",
              "value": true
            },
            "cause": "lava",
            "damage_per_tick": 4
          }
        ]
      },
      "minecraft:nameable": {
      },

      // give horses step height
      "minecraft:variable_max_auto_step": {
				"base_value": 1.0,
				"controlled_value": 1.0,
				"jump_prevented_value": 1.0
			},
      "minecraft:leashable": {
        "soft_distance": 4.0,
        "hard_distance": 6.0,
        "max_distance": 10.0
      },
      "minecraft:balloonable": {
      },
      "minecraft:healable": {
        "items": [
          {
            "item": "wheat",
            "heal_amount": 2
          },
          {
            "item": "sugar",
            "heal_amount": 1
          },
          {
            "item": "hay_block",
            "heal_amount": 20
          },
          {
            "item": "apple",
            "heal_amount": 3
          },
          {
            "item": "golden_carrot",
            "heal_amount": 4
          },
          {
            "item": "golden_apple",
            "heal_amount": 10
          },
          {
            "item": "appleEnchanted",
            "heal_amount": 10
          }
        ]
      },

      // This horse is only acquired through breeding,
      // so make them persistent by NOT having the
      // minecraft:despawn component

      
      "minecraft:movement.basic": {},
      "minecraft:jump.static": {},
      "minecraft:behavior.float": {
        "priority": 1,
        "sink_with_passengers": true
      },
      "minecraft:behavior.tempt": {
        "priority": 5,
        "speed_multiplier": 1.2,
        "items": [
          "golden_apple",
          "appleEnchanted",
          "golden_carrot"
        ]
      },
      "minecraft:behavior.look_at_player": {
        "priority": 7,
        "look_distance": 6.0,
        "probability": 0.02
      },
      "minecraft:behavior.random_look_around": {
        "priority": 8
      },

      "minecraft:physics": {
      },
      "minecraft:pushable": {
        "is_pushable": true,
        "is_pushable_by_piston": true
      },
      "minecraft:conditional_bandwidth_optimization": {
      },
      



      // Equipment
      "minecraft:equippable": {
        "slots": [
          {
            "slot": 0,
            "item": "saddle",
            "accepted_items": [ "saddle" ],
            "on_equip": {
              "event": "cyn_hao:event_horse_saddled"
            },
            "on_unequip": {
              "event": "cyn_hao:event_horse_unsaddled"
            }
          },
          {
            "slot": 1,
            "item": "horsearmoriron",
            "accepted_items": [
              "horsearmorleather",
              "horsearmoriron",
              "horsearmorgold",
              "horsearmordiamond"
            ],
            "on_equip": {
              "event": "cyn_hao:event_horse_update_armor",
              "target": "self"
            },
            "on_unequip": {
              "event": "cyn_hao:event_horse_reset_armor",
              "target": "self"
            }
          },
          {
            "slot": 2,
            "item": "carpet",
            // Why doesn't this list do anything???
            // Going to assume it's bugged or something,
            // or maybe ONLY works in slots 0 and/or 1
            // as even specifying minecraft: in front of all the carpets
            // did not "lock" the slot to that item
            // couldn't really find anyone talking about it either,
            // so maybe it's just me

            // additionally, even copying slot 0 (saddle) COMPLETELY
            // and pasting down here, but changing slot to 1,
            // did not limit the items to saddle
            "accepted_items": [
              "white_carpet",
              "orange_carpet",
              "magenta_carpet",
              "light_blue_carpet",
              "yellow_carpet",
              "lime_carpet",
              "pink_carpet",
              "gray_carpet",
              "light_gray_carpet",
              "cyan_carpet",
              "purple_carpet",
              "blue_carpet",
              "brown_carpet",
              "green_carpet",
              "red_carpet",
              "black_carpet",
              "moss_carpet"
            ],
            "on_equip": {
              "event": "cyn_hao:event_horse_update_carpet",
              "target": "self"
            },
            "on_unequip": {
              "event": "cyn_hao:event_horse_reset_carpet",
              "target": "self"
            }
          }
        ]
      },

      // Right-Click Interactions
      // Untamed, Saddling, Chesting, Armoring, Movement
      // All done here since we can use a has_component filter for is_tamed,
      // and then don't have to worry about multiple component groups
      "minecraft:interact": {
        "interactions": [
          // Untamed Interactions
          // Trying to put a saddle, chest, armor, or carpet on an untamed horse
          // will make it play it's "mad" sound and rear animation

          // -------------------------
          // NOTE - Make sure if we update the list of auto-rejected items, 
          // we also updated the same list in the cyn_hao:group_horse_wild minecraft:tamemount component!
          // -------------------------
          {
            "play_sounds": "mad",
            "on_interact": {
              "filters": {
                "all_of": [
                  { "test": "has_component", "subject": "self", "operator": "not", "value": "minecraft:is_tamed" },
                  { "test": "is_family", "subject": "other", "value": "player" },
                  { "test": "is_sneak_held", "subject": "other", "value": false },
                  {
                    "any_of": [
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "saddle" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "chest" },

                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "white_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "orange_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "magenta_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "light_blue_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "yellow_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "lime_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "pink_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "gray_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "light_gray_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "cyan_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "purple_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "blue_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "brown_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "green_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "red_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "black_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "moss_carpet" },

                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "leather_horse_armor" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "iron_horse_armor" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "golden_horse_armor" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "diamond_horse_armor" },

                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "cyn_hao:horse_whistle" }
                    ]
                  }
                ]
              },
              "target": "self",
              "event": "cyn_hao:event_horse_angry"
            },
            "interact_text": "action.interact.cyn_hao.horse.untamed"
          },

          // Saddling
          // Saddle equipping and unequipping events are handled
          // in the above minecraft:equippable component
          {
            "play_sounds": "saddle",
            "on_interact": {
              "filters": {
                "all_of": [
                  { "test": "has_component", "subject": "self", "operator": "equals", "value": "minecraft:is_tamed" },
                  { "test": "has_equipment", "subject": "self", "domain": "inventory", "operator": "not", "value": "saddle" },
                  { "test": "has_equipment", "subject": "other", "domain": "hand", "value": "saddle" },
                  { "test": "is_family", "subject": "other", "value": "player" },
                  { "test": "is_sneak_held", "subject": "other", "value": false }
                ]
              },
              "target": "self"
            },
            "equip_item_slot": "0",
            "interact_text": "action.interact.saddle"
          },
          
          // Chesting
          // since chests are not placed in an inventory slot,
          // this interaction will call the event that chests the horse
          {
            "play_sounds": "armor.equip_generic",
            "on_interact": {
              "filters": {
                "all_of": [
                  { "test": "has_component", "subject": "self", "operator": "equals", "value": "minecraft:is_tamed" },
                  { "test": "has_component", "subject": "self", "operator": "not", "value": "minecraft:is_chested" },
                  { "test": "has_equipment", "subject": "other", "domain": "hand", "value": "chest" },
                  { "test": "is_family", "subject": "other", "value": "player" },
                  { "test": "is_sneak_held", "subject": "other", "value": false }
                ]
              },
              "event": "minecraft:on_chest",
              "target": "self"
            },
            "use_item": true,
            "interact_text": "action.interact.attachchest"
          },

          // Un-Chesting
          // since chests are not placed in an inventory slot,
          // this interaction will call the event that un-chests the horse
          {
            "play_sounds": "shear",
            "on_interact": {
              "filters": {
                "all_of": [
                  { "test": "has_component", "subject": "self", "operator": "equals", "value": "minecraft:is_tamed" },
                  { "test": "has_component", "subject": "self", "operator": "equals", "value": "minecraft:is_chested" },
                  { "test": "has_equipment", "subject": "other", "domain": "hand", "value": "minecraft:shears" },
                  { "test": "is_family", "subject": "other", "value": "player" },
                  { "test": "is_sneak_held", "subject": "other", "value": false }
                ]
              },
              "event": "cyn_hao:remove_chest",
              "target": "self"
            },
            "use_item": false,
            "interact_text": "action.interact.cyn_hao.horse.chest.remove"
          },

          // Armoring
          // Armor equipping and unequipping is handled
          // in the above minecraft:equippable component
          // Setting which armor is in the slot is done by a scriptEvent
          // that assigns the "cyn_hao:armor_type" property when called
          // by the aforementioned minecraft_equippable component
          // The render controller then queries this property to render the correct texture

          // as much as I wanted everything to be in the same place, it doesn't seem
          // like there's a way to access the armor's type, even through alias ID
          // query.armor_texture_slot is so so close, but unfortunately can't call it in filters or set_property events
          // plus, I couldn't get it to work anyway - no armor slot was returning anything? Probably user error though
          {
            "play_sounds": "armor.equip_generic",
            "on_interact": {
              "filters": {
                "all_of": [
                  { "test": "has_component", "subject": "self", "operator": "equals", "value": "minecraft:is_tamed" },
                  { "test": "is_family", "subject": "other", "value": "player" },
                  { "test": "is_sneak_held", "subject": "other", "value": false },
                  {
                    "none_of": [
                      { "test": "has_equipment", "subject": "self", "domain": "inventory", "value": "leather_horse_armor" },
                      { "test": "has_equipment", "subject": "self", "domain": "inventory", "value": "iron_horse_armor" },
                      { "test": "has_equipment", "subject": "self", "domain": "inventory", "value": "golden_horse_armor" },
                      { "test": "has_equipment", "subject": "self", "domain": "inventory", "value": "diamond_horse_armor" }
                    ]
                  },
                  {
                    "any_of": [
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "leather_horse_armor" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "iron_horse_armor" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "golden_horse_armor" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "diamond_horse_armor" }
                    ]
                  }
                ]
              },
              "target": "self"
            },
            "equip_item_slot": "1",
            "interact_text": "action.interact.equiphorsearmor"
          },

          // Carpetting
          // Carpet equipping and unequipping is handled
          // in the above minecraft:equippable component
          // Setting which carpet is in the slot is done by a scriptEvent
          // that assigns the "cyn_hao:carpet_color" property when called
          // by the aforementioned minecraft_equippable component
          // The render controller then queries this property to render the correct texture

          // as much as I wanted everything to be in the same place, it doesn't seem
          // like there's a way to access the carpet's color, even through alias ID
          // query.is_item_name_any is so so close, but unfortunately can't call queries in filters
          {
            // for reasons clearly FAR beyond my understanding,
            // I can't get play_sounds to work here no matter what I try
            // EVEN THOUGH playing the "carpet" sound event (which I defined)
            // in the saddle part of interaction DOES WORK,
            // I simply can't get it to work here.
            // so instead, the above on_equip carpet even also runs /playsound
            // annoying, but whatever works I suppose
            "play_sounds": "carpet",
            "on_interact": {
              "filters": {
                "all_of": [
                  { "test": "has_component", "subject": "self", "operator": "equals", "value": "minecraft:is_tamed" },
                  { "test": "is_family", "subject": "other", "value": "player" },
                  { "test": "is_sneak_held", "subject": "other", "value": false },
                  {
                    "none_of": [
                      { "test": "has_equipment", "subject": "self", "domain": "inventory", "value": "white_carpet" },
                      { "test": "has_equipment", "subject": "self", "domain": "inventory", "value": "orange_carpet" },
                      { "test": "has_equipment", "subject": "self", "domain": "inventory", "value": "magenta_carpet" },
                      { "test": "has_equipment", "subject": "self", "domain": "inventory", "value": "light_blue_carpet" },
                      { "test": "has_equipment", "subject": "self", "domain": "inventory", "value": "yellow_carpet" },
                      { "test": "has_equipment", "subject": "self", "domain": "inventory", "value": "lime_carpet" },
                      { "test": "has_equipment", "subject": "self", "domain": "inventory", "value": "pink_carpet" },
                      { "test": "has_equipment", "subject": "self", "domain": "inventory", "value": "gray_carpet" },
                      { "test": "has_equipment", "subject": "self", "domain": "inventory", "value": "light_gray_carpet" },
                      { "test": "has_equipment", "subject": "self", "domain": "inventory", "value": "cyan_carpet" },
                      { "test": "has_equipment", "subject": "self", "domain": "inventory", "value": "purple_carpet" },
                      { "test": "has_equipment", "subject": "self", "domain": "inventory", "value": "blue_carpet" },
                      { "test": "has_equipment", "subject": "self", "domain": "inventory", "value": "brown_carpet" },
                      { "test": "has_equipment", "subject": "self", "domain": "inventory", "value": "green_carpet" },
                      { "test": "has_equipment", "subject": "self", "domain": "inventory", "value": "red_carpet" },
                      { "test": "has_equipment", "subject": "self", "domain": "inventory", "value": "black_carpet" }
                    ]
                  },
                  {
                    "any_of": [
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "white_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "orange_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "magenta_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "light_blue_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "yellow_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "lime_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "pink_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "gray_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "light_gray_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "cyan_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "purple_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "blue_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "brown_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "green_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "red_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "black_carpet" },
                      { "test": "has_equipment", "subject": "player", "domain": "hand", "value": "moss_carpet" }
                    ]
                  }

                ]
              },
              "target": "self"
            },
            "equip_item_slot": "2",
            "interact_text": "action.interact.equipcarpet"
          },

          // Movement
          // Movement mode events are called through scripts,
          // but we keep a component here that does nothing
          // so that right clicking a horse with a whistle does NOT make you mount it
          {
            "on_interact": {
              "filters": {
                "all_of": [
                  { "test": "has_component", "subject": "self", "operator": "equals", "value": "minecraft:is_tamed" },
                  { "test": "has_equipment", "subject": "other", "domain": "hand", "value": "cyn_hao:horse_whistle" },
                  { "test": "is_family", "subject": "other", "value": "player" },
                  { "test": "is_sneak_held", "subject": "other", "value": false }
                ]
              }
            }
          },

          // Special Breeding
          // Activates this horse's "special" breeding state
          // Also runs commands that play the eating sound
          {
            "on_interact": {
              "filters": {
                "all_of": [
                  { "test": "has_component", "subject": "self", "operator": "equals", "value": "minecraft:is_tamed" },
                  { "test": "bool_property", "domain": "cyn_hao:special_breed", "operator": "equals", "value": false },
                  { "test": "has_equipment", "subject": "other", "domain": "hand", "value": "minecraft:diamond" },
                  { "test": "is_family", "subject": "other", "value": "player" },
                  { "test": "is_sneak_held", "subject": "other", "value": false } 
                ]
              },
              "event": "cyn_hao:event_special_breed",
              "target": "self"
            },
            "use_item": true
          }
        ]
      }

    },



    "events": {
      "minecraft:entity_spawned": {
        "sequence": [
          {
            "randomize": [
              {
                // sequence-in-sequence since we do not
                // want to apply seat positions to babies
                "weight": 36,
                "add": {
                  "component_groups": [
                    "cyn_hao:group_horse_adult",
                    "cyn_hao:group_horse_wild",
                    // adults need their seat position set
                    "cyn_hao:group_horse_seat_check",
                    "cyn_hao:group_flyer_wild_grounded"
                  ]
                }
              },
              {
                "weight": 9,
                "add": {
                  "component_groups": [
                    "cyn_hao:group_horse_born_start"
                  ]
                }
              }
            ]
          },

          // Color Properties
          // Randomly set since this entity comes from breeding,
          // in which it inherits it's parents colors anyway
          
          // Base Coats
          {
            "set_property": {
              "cyn_hao:base_id": "math.random_integer(0, 2)"
            }
          },

          // Random Attributes
          // NOTE that wild horses do NOT select from
          // all the groups! Their range only goes up to group 5
          {
            "sequence": [
              // Health
              {
                "randomize": [
                  {
                    "weight": 1,
                    "add": {
                      "component_groups": [
                        "cyn_hao:group_health_0"
                      ]
                    },
                    "set_property": {
                      "cyn_hao:health_group_id": 0
                    }
                  },
                  {
                    "weight": 1,
                    "add": {
                      "component_groups": [
                        "cyn_hao:group_health_1"
                      ]
                    },
                    "set_property": {
                      "cyn_hao:health_group_id": 1
                    }
                  },
                  {
                    "weight": 1,
                    "add": {
                      "component_groups": [
                        "cyn_hao:group_health_2"
                      ]
                    },
                    "set_property": {
                      "cyn_hao:health_group_id": 2
                    }
                  },
                  {
                    "weight": 1,
                    "add": {
                      "component_groups": [
                        "cyn_hao:group_health_3"
                      ]
                    },
                    "set_property": {
                      "cyn_hao:health_group_id": 3
                    }
                  },
                  {
                    "weight": 1,
                    "add": {
                      "component_groups": [
                        "cyn_hao:group_health_4"
                      ]
                    },
                    "set_property": {
                      "cyn_hao:health_group_id": 4
                    }
                  },
                  {
                    "weight": 1,
                    "add": {
                      "component_groups": [
                        "cyn_hao:group_health_5"
                      ]
                    },
                    "set_property": {
                      "cyn_hao:health_group_id": 5
                    }
                  }
                ]
              },
              
              // Speed
              {
                "randomize": [
                  {
                    "weight": 1,
                    "add": {
                      "component_groups": [
                        "cyn_hao:group_speed_0"
                      ]
                    },
                    "set_property": {
                      "cyn_hao:speed_group_id": 0
                    }
                  },
                  {
                    "weight": 1,
                    "add": {
                      "component_groups": [
                        "cyn_hao:group_speed_1"
                      ]
                    },
                    "set_property": {
                      "cyn_hao:speed_group_id": 1
                    }
                  },
                  {
                    "weight": 1,
                    "add": {
                      "component_groups": [
                        "cyn_hao:group_speed_2"
                      ]
                    },
                    "set_property": {
                      "cyn_hao:speed_group_id": 2
                    }
                  },
                  {
                    "weight": 1,
                    "add": {
                      "component_groups": [
                        "cyn_hao:group_speed_3"
                      ]
                    },
                    "set_property": {
                      "cyn_hao:speed_group_id": 3
                    }
                  },
                  {
                    "weight": 1,
                    "add": {
                      "component_groups": [
                        "cyn_hao:group_speed_4"
                      ]
                    },
                    "set_property": {
                      "cyn_hao:speed_group_id": 4
                    }
                  },
                  {
                    "weight": 1,
                    "add": {
                      "component_groups": [
                        "cyn_hao:group_speed_5"
                      ]
                    },
                    "set_property": {
                      "cyn_hao:speed_group_id": 5
                    }
                  }
                ]
              },

              // Jump
              {
                "randomize": [
                  {
                    "weight": 1,
                    "add": {
                      "component_groups": [
                        "cyn_hao:group_jump_0"
                      ]
                    },
                    "set_property": {
                      "cyn_hao:jump_group_id": 0
                    }
                  },
                  {
                    "weight": 1,
                    "add": {
                      "component_groups": [
                        "cyn_hao:group_jump_1"
                      ]
                    },
                    "set_property": {
                      "cyn_hao:jump_group_id": 1
                    }
                  },
                  {
                    "weight": 1,
                    "add": {
                      "component_groups": [
                        "cyn_hao:group_jump_2"
                      ]
                    },
                    "set_property": {
                      "cyn_hao:jump_group_id": 2
                    }
                  },
                  {
                    "weight": 1,
                    "add": {
                      "component_groups": [
                        "cyn_hao:group_jump_3"
                      ]
                    },
                    "set_property": {
                      "cyn_hao:jump_group_id": 3
                    }
                  },
                  {
                    "weight": 1,
                    "add": {
                      "component_groups": [
                        "cyn_hao:group_jump_4"
                      ]
                    },
                    "set_property": {
                      "cyn_hao:jump_group_id": 4
                    }
                  },
                  {
                    "weight": 1,
                    "add": {
                      "component_groups": [
                        "cyn_hao:group_jump_5"
                      ]
                    },
                    "set_property": {
                      "cyn_hao:jump_group_id": 5
                    }
                  }
                ]
              }
            ]
          },

          // Random Height and Density
          // NOTE that these are the bounds for WILD horses!!!
          // Bred horses use the ABSOLUTE bounds
          {
            "set_property": {
              "cyn_hao:height_scale": "math.random(-0.04, 0.075)",
              "cyn_hao:density_scale": "math.random(-0.075, 0.03)",
              "cyn_hao:tail_scale": "math.random(0.75, 1.25)"
            }
          }
        ]
      },



      // 10 different groups defined since we set the property value
      // in script, and then immediately trigger the appropriate group,
      // which happens in the same tick, so the property isn't actually
      // correctly set yet
      // so instead in the script we call one of these 10 groups

      // Health
      // Health
      // Health
      "cyn_hao:event_health_group_0": {
        "add": {
          "component_groups": [
            "cyn_hao:group_health_0"
          ]
        },
        "set_property": {
          "cyn_hao:health_group_id": 0
        }
      },
      "cyn_hao:event_health_group_1": {
        "add": {
          "component_groups": [
            "cyn_hao:group_health_1"
          ]
        },
        "set_property": {
          "cyn_hao:health_group_id": 1
        }
      },
      "cyn_hao:event_health_group_2": {
        "add": {
          "component_groups": [
            "cyn_hao:group_health_2"
          ]
        },
        "set_property": {
          "cyn_hao:health_group_id": 2
        }
      },
      "cyn_hao:event_health_group_3": {
        "add": {
          "component_groups": [
            "cyn_hao:group_health_3"
          ]
        },
        "set_property": {
          "cyn_hao:health_group_id": 3
        }
      },
      "cyn_hao:event_health_group_4": {
        "add": {
          "component_groups": [
            "cyn_hao:group_health_4"
          ]
        },
        "set_property": {
          "cyn_hao:health_group_id": 4
        }
      },
      "cyn_hao:event_health_group_5": {
        "add": {
          "component_groups": [
            "cyn_hao:group_health_5"
          ]
        },
        "set_property": {
          "cyn_hao:health_group_id": 5
        }
      },
      "cyn_hao:event_health_group_6": {
        "add": {
          "component_groups": [
            "cyn_hao:group_health_6"
          ]
        },
        "set_property": {
          "cyn_hao:health_group_id": 6
        }
      },
      "cyn_hao:event_health_group_7": {
        "add": {
          "component_groups": [
            "cyn_hao:group_health_7"
          ]
        },
        "set_property": {
          "cyn_hao:health_group_id": 7
        }
      },
      "cyn_hao:event_health_group_8": {
        "add": {
          "component_groups": [
            "cyn_hao:group_health_8"
          ]
        },
        "set_property": {
          "cyn_hao:health_group_id": 8
        }
      },
      "cyn_hao:event_health_group_9": {
        "add": {
          "component_groups": [
            "cyn_hao:group_health_9"
          ]
        },
        "set_property": {
          "cyn_hao:health_group_id": 9
        }
      },



      // Speed
      // Speed
      // Speed
      "cyn_hao:event_speed_group_0": {
        "add": {
          "component_groups": [
            "cyn_hao:group_speed_0"
          ]
        },
        "set_property": {
          "cyn_hao:speed_group_id": 0
        }
      },
      "cyn_hao:event_speed_group_1": {
        "add": {
          "component_groups": [
            "cyn_hao:group_speed_1"
          ]
        },
        "set_property": {
          "cyn_hao:speed_group_id": 1
        }
      },
      "cyn_hao:event_speed_group_2": {
        "add": {
          "component_groups": [
            "cyn_hao:group_speed_2"
          ]
        },
        "set_property": {
          "cyn_hao:speed_group_id": 2
        }
      },
      "cyn_hao:event_speed_group_3": {
        "add": {
          "component_groups": [
            "cyn_hao:group_speed_3"
          ]
        },
        "set_property": {
          "cyn_hao:speed_group_id": 3
        }
      },
      "cyn_hao:event_speed_group_4": {
        "add": {
          "component_groups": [
            "cyn_hao:group_speed_4"
          ]
        },
        "set_property": {
          "cyn_hao:speed_group_id": 4
        }
      },
      "cyn_hao:event_speed_group_5": {
        "add": {
          "component_groups": [
            "cyn_hao:group_speed_5"
          ]
        },
        "set_property": {
          "cyn_hao:speed_group_id": 5
        }
      },
      "cyn_hao:event_speed_group_6": {
        "add": {
          "component_groups": [
            "cyn_hao:group_speed_6"
          ]
        },
        "set_property": {
          "cyn_hao:speed_group_id": 6
        }
      },
      "cyn_hao:event_speed_group_7": {
        "add": {
          "component_groups": [
            "cyn_hao:group_speed_7"
          ]
        },
        "set_property": {
          "cyn_hao:speed_group_id": 7
        }
      },
      "cyn_hao:event_speed_group_8": {
        "add": {
          "component_groups": [
            "cyn_hao:group_speed_8"
          ]
        },
        "set_property": {
          "cyn_hao:speed_group_id": 8
        }
      },
      "cyn_hao:event_speed_group_9": {
        "add": {
          "component_groups": [
            "cyn_hao:group_speed_9"
          ]
        },
        "set_property": {
          "cyn_hao:speed_group_id": 9
        }
      },


      // Jump
      // Jump
      // Jump
      "cyn_hao:event_jump_group_0": {
        "add": {
          "component_groups": [
            "cyn_hao:group_jump_0"
          ]
        },
        "set_property": {
          "cyn_hao:jump_group_id": 0
        }
      },
      "cyn_hao:event_jump_group_1": {
        "add": {
          "component_groups": [
            "cyn_hao:group_jump_1"
          ]
        },
        "set_property": {
          "cyn_hao:jump_group_id": 1
        }
      },
      "cyn_hao:event_jump_group_2": {
        "add": {
          "component_groups": [
            "cyn_hao:group_jump_2"
          ]
        },
        "set_property": {
          "cyn_hao:jump_group_id": 2
        }
      },
      "cyn_hao:event_jump_group_3": {
        "add": {
          "component_groups": [
            "cyn_hao:group_jump_3"
          ]
        },
        "set_property": {
          "cyn_hao:jump_group_id": 3
        }
      },
      "cyn_hao:event_jump_group_4": {
        "add": {
          "component_groups": [
            "cyn_hao:group_jump_4"
          ]
        },
        "set_property": {
          "cyn_hao:jump_group_id": 4
        }
      },
      "cyn_hao:event_jump_group_5": {
        "add": {
          "component_groups": [
            "cyn_hao:group_jump_5"
          ]
        },
        "set_property": {
          "cyn_hao:jump_group_id": 5
        }
      },
      "cyn_hao:event_jump_group_6": {
        "add": {
          "component_groups": [
            "cyn_hao:group_jump_6"
          ]
        },
        "set_property": {
          "cyn_hao:jump_group_id": 6
        }
      },
      "cyn_hao:event_jump_group_7": {
        "add": {
          "component_groups": [
            "cyn_hao:group_jump_7"
          ]
        },
        "set_property": {
          "cyn_hao:jump_group_id": 7
        }
      },
      "cyn_hao:event_jump_group_8": {
        "add": {
          "component_groups": [
            "cyn_hao:group_jump_8"
          ]
        },
        "set_property": {
          "cyn_hao:jump_group_id": 8
        }
      },
      "cyn_hao:event_jump_group_9": {
        "add": {
          "component_groups": [
            "cyn_hao:group_jump_9"
          ]
        },
        "set_property": {
          "cyn_hao:jump_group_id": 9
        }
      },



      // born events called FROM parents, ON baby
      "cyn_hao:event_horse_born_normal": {
        "queue_command": {
          "command": [
            "scriptevent cyn:hao horseBorn_normal"
          ]
        },
        "add": {
          "component_groups": [
            "cyn_hao:group_horse_born_start"
          ]
        }
      },

      "cyn_hao:event_horse_born_special": {
        "queue_command": {
          "command": [
            "scriptevent cyn:hao horseBorn_special"
          ]
        },
        "add": {
          "component_groups": [
            "cyn_hao:group_horse_born_start"
          ]
        }
      },

      "cyn_hao:event_set_property_just_born_true": {
        "set_property": {
          "cyn_hao:just_born": true
        },
        // make the horse unable to move while being born
        // done with slowness so that parent's movements are still inherited
        "queue_command": {
          "command": "effect @s slowness 5 100 true"
        }
      },

      "cyn_hao:event_horse_born_end": {
        "remove": {
          "component_groups": [
            "cyn_hao:group_horse_born_start"
          ]
        },
        "add": {
          "component_groups": [
            "cyn_hao:group_horse_baby",
            "cyn_hao:group_horse_movement_wandering"
          ]
        },
        "set_property": {
          "cyn_hao:just_born": false
        }
      },



      "minecraft:spawn_adult": {
        "add": {
          "component_groups": [
            "cyn_hao:group_horse_adult",
            "cyn_hao:group_horse_wild",
            // adults need their seat position set
            "cyn_hao:group_horse_seat_check",
            "cyn_hao:group_flyer_wild_grounded"
          ]
        }
      },



      "cyn_hao:event_horse_angry": {
        "queue_command": {
          "command": [
            "title @a[r=5] actionbar This horse has not been tamed!",
            "playanimation @s idle_rear"
          ]
        }
      },



      "cyn_hao:event_on_tame": {
        "remove": {
          "component_groups": [
            "cyn_hao:group_horse_wild",
            "cyn_hao:group_flyer_wild_grounded",
            "cyn_hao:group_flyer_wild_flying"
          ]
        },
        "add": {
          "component_groups": [
            "cyn_hao:group_horse_tamed",
            "cyn_hao:group_horse_unchested",
            "cyn_hao:group_horse_movement_wandering",
            "cyn_hao:group_normal_breed"
          ]
        }
      },



      // when a baby horse grows up, we remove
      // the "cyn_hao:baby_horse" tag it got when
      // it was born
      // this way, any other breedings will NOT
      // select the baby horse!
      "cyn_hao:ageable_grow_up": {
        "queue_command": {
          "command": "tag @s remove cyn_hao:baby_horse"
        },
        "remove": {
          "component_groups": [
            "cyn_hao:group_horse_baby"
          ]
        },
        "add": {
          "component_groups": [
            "cyn_hao:group_horse_adult",
            "cyn_hao:group_horse_wild",
            // adults need their seat position set
            "cyn_hao:group_horse_seat_check",
            "cyn_hao:group_flyer_wild_grounded"
          ]
        }
      },



      "cyn_hao:event_horse_saddled": {
        "add": {
          "component_groups": [
            "cyn_hao:group_horse_saddled"
          ]
        }
      },
      "cyn_hao:event_horse_unsaddled": {
        "remove": {
          "component_groups": [
            "cyn_hao:group_horse_saddled"
          ]
        }
      },



      "minecraft:on_chest": {
        "add": {
          "component_groups": [
            "cyn_hao:group_horse_chested"
          ]
        }
      },
      "cyn_hao:remove_chest": {
        "remove": {
          "component_groups": [
            "cyn_hao:group_horse_chested"
          ]
        },
        "queue_command": {
          "command": "scriptevent cyn:hao removeChest"
        }
      },



      "cyn_hao:event_horse_update_armor": {
        "add": {
          "component_groups": [
            "cyn_hao:group_horse_dyeable"
          ]
        },
        "queue_command": {
          "command":"scriptevent cyn:hao updateArmor"
        }
      },
      "cyn_hao:event_horse_reset_armor": {
        "remove": {
          "component_groups": [
            "cyn_hao:group_horse_dyeable"
          ]
        },
        "set_property": {
          "cyn_hao:armor_type": 0
        },
        "queue_command": {
          "command": "playsound armor.equip_wolf @a ~ ~ ~ 1.0"
        }
      },



      "cyn_hao:event_horse_update_carpet": {
        "queue_command": {
          "command":[
            "scriptevent cyn:hao updateCarpet",
            "playsound use.cloth @a ~ ~ ~ 1.0"
          ]
        }
      },
      "cyn_hao:event_horse_reset_carpet": {
        "set_property": {
          "cyn_hao:carpet_color": 0
        },
        "queue_command": {
          "command": "playsound dig.cloth @a ~ ~ ~ 1.0"
        }
      },



      // movement modes
      // these events are called through scripts
      "cyn_hao:event_horse_movement_wander": {
        "remove": {
          "component_groups": [
            "cyn_hao:group_horse_movement_following",
            "cyn_hao:group_horse_movement_sitting"
          ]
        },
        "add": {
          "component_groups": [
            "cyn_hao:group_horse_movement_wandering",
            "cyn_hao:group_horse_default_targetting"
          ]
        }
      },
      "cyn_hao:event_horse_movement_follow": {
        "remove": {
          "component_groups": [
            "cyn_hao:group_horse_movement_wandering",
            "cyn_hao:group_horse_movement_sitting",
            "cyn_hao:group_horse_default_targetting"
          ]
        },
        "add": {
          "component_groups": [
            "cyn_hao:group_horse_movement_following"
          ]
        }
      },
      "cyn_hao:event_horse_movement_sit": {
        "remove": {
          "component_groups": [
            "cyn_hao:group_horse_movement_following",
            "cyn_hao:group_horse_movement_wandering"
          ]
        },
        "add": {
          "component_groups": [
            "cyn_hao:group_horse_movement_sitting",
            "cyn_hao:group_horse_default_targetting"
          ]
        }
      },



      // seat positions
      "cyn_hao:event_horse_seat_refresh": {
        "remove": {
          "component_groups": [
            "cyn_hao:group_horse_seat_shortest",
            "cyn_hao:group_horse_seat_short",
            "cyn_hao:group_horse_seat_medium",
            "cyn_hao:group_horse_seat_tall",
            "cyn_hao:group_horse_seat_tallest"
          ]
        },
        "add": {
          "component_groups": [
            "cyn_hao:group_horse_seat_check"
          ]
        }
      },

      // seat positions
      "cyn_hao:event_horse_seat_shortest": {
        "remove": {
          "component_groups": [
            "cyn_hao:group_horse_seat_check"
          ]
        },
        "add": {
          "component_groups": [
            "cyn_hao:group_horse_seat_shortest"
          ]
        }
      },
      "cyn_hao:event_horse_seat_short": {
        "remove": {
          "component_groups": [
            "cyn_hao:group_horse_seat_check"
          ]
        },
        "add": {
          "component_groups": [
            "cyn_hao:group_horse_seat_short"
          ]
        }
      },
      "cyn_hao:event_horse_seat_medium": {
        "remove": {
          "component_groups": [
            "cyn_hao:group_horse_seat_check"
          ]
        },
        "add": {
          "component_groups": [
            "cyn_hao:group_horse_seat_medium"
          ]
        }
      },
      "cyn_hao:event_horse_seat_tall": {
        "remove": {
          "component_groups": [
            "cyn_hao:group_horse_seat_check"
          ]
        },
        "add": {
          "component_groups": [
            "cyn_hao:group_horse_seat_tall"
          ]
        }
      },
      "cyn_hao:event_horse_seat_tallest": {
        "remove": {
          "component_groups": [
            "cyn_hao:group_horse_seat_check"
          ]
        },
        "add": {
          "component_groups": [
            "cyn_hao:group_horse_seat_tallest"
          ]
        }
      },




      // flying
      // it's rare, since tamed flyers don't fly,
      // but it is possible if a flyer was bred
      // and then kept wild
      "cyn_hao:event_flyer_wild_roll": {
				"randomize": [
					// Set Flying
					{
						"weight": 33,
						"remove": {
							"component_groups": [
								"cyn_hao:group_flyer_wild_grounded"
							]
						},
						"add": {
							"component_groups": [
								"cyn_hao:group_flyer_wild_flying"
							]
						}
					},

					// Set Grounded
					{
						"weight": 33,
						"remove": {
							"component_groups": [
								"cyn_hao:group_flyer_wild_flying"
							]
						},
						"add": {
							"component_groups": [
								"cyn_hao:group_flyer_wild_grounded"
							]
						}
					},

					// Remain in current movement state
					{
						"weight": 33
					}
				]
			},


      // Breeding
      "cyn_hao:event_normal_breed": {
        "remove": {
          "component_groups": [
            "cyn_hao:group_special_breed_fairy"
          ]
        },
        "add": {
          "component_groups": [
            "cyn_hao:group_normal_breed"
          ]
        },
        "set_property": {
          "cyn_hao:special_breed": false
        }
      },
      
      "cyn_hao:event_special_breed": {
        "remove": {
          "component_groups": [
            "cyn_hao:group_normal_breed"
          ]
        },
        "add": {
          "component_groups": [
            "cyn_hao:group_special_breed_fairy"
          ]
        },
        "set_property": {
          "cyn_hao:special_breed": true
        },
        "queue_command": {
          "command": [
            "playsound mob.horse.eat @a ~ ~ ~ 1.0",
            "playsound random.levelup @a ~ ~ ~ 0.5"
          ]
        }
      }
    }
  }
}
