static void _gain_level(int new_level) {
    int tier = _find_tier(p_ptr->current_r_idx);
    if (tier < 0 || tier == _MAX_TIERS - 1) return;
    if (p_ptr->lev >= _tiers[tier + 1].level)
    {
        p_ptr->current_r_idx = _random(_tiers[tier+1].r_ids);
        msg_format("You have evolved into a %s.", _mon_name(p_ptr->current_r_idx));
        p_ptr->redraw |= PR_MAP;
    }
}
/******************************************************************************
 * Troll Public API
 ******************************************************************************/
race_t *mon_troll_get_race_t(void)
{
    static race_t me = {0};
    static bool   init = FALSE;

    if (!init)
    {           /* dis, dev, sav, stl, srh, fos, thn, thb */
    skills_t bs = { 25,  18,  30,   1,  13,   7,  65,  30 };
    skills_t xs = {  7,   7,  10,   0,   0,   0,  28,  10 };

        me.skills = bs;
        me.extra_skills = xs;

        me.name = "Troll";
        me.desc =     
            "Trolls are disgusting creatures: Big, strong and stupid. They make excellent warriors "
            "but are hopeless with magical devices. Trolls have incredible powers of regeneration.";

        me.infra = 5;
        me.exp = 150;
        me.base_hp = 50;

        me.calc_bonuses = _calc_bonuses;
        me.calc_weapon_bonuses = _calc_weapon_bonuses;
        me.calc_innate_attacks = _calc_innate_attacks;
        me.get_powers = _get_powers;
        me.get_flags = _get_flags;
        me.get_vulnerabilities = _get_vulnerabilities;
        me.gain_level = _gain_level;
        me.birth = _birth;

        me.flags = RACE_IS_MONSTER;
        me.boss_r_idx = MON_ULIK;
        me.pseudo_class_idx = CLASS_WARRIOR;

        init = TRUE;
    }

    me.subname = _mon_name(p_ptr->current_r_idx);
    me.stats[A_STR] =  3 + p_ptr->lev/12;
    me.stats[A_INT] = -5;
    me.stats[A_WIS] = -5;
    me.stats[A_DEX] = -2 + p_ptr->lev/20;
    me.stats[A_CON] =  3 + p_ptr->lev/13;
    me.stats[A_CHR] =  0;
    me.life = 100 + (p_ptr->lev/10)*4;

    me.equip_template = mon_get_equip_template();
    return &me;
}
/**********************************************************************
 * Public
 **********************************************************************/
race_t *mon_golem_get_race(int psubrace)
{
    static race_t me = {0};
    static bool   init = FALSE;
    int           rank = _rank();

    if (!init)
    {           /* dis, dev, sav, stl, srh, fos, thn, thb */
    skills_t bs = { 25,  18,  40,   0,  10,   7,  70,  30};
    skills_t xs = { 10,   7,  15,   0,   0,   0,  30,  10};

        me.skills = bs;
        me.extra_skills = xs;

        me.infra = 5;
        me.shop_adjust = 130;

        me.name = "Golem";
        me.desc = _desc;
        me.calc_innate_attacks = _calc_innate_attacks;
        me.birth = _birth;
        me.gain_level = _gain_level;
        me.calc_bonuses = _calc_bonuses;
        me.get_powers = _get_powers;
        me.get_flags = _get_flags;
        me.flags = RACE_IS_MONSTER | RACE_IS_NONLIVING;
        me.base_hp = 50;
        me.boss_r_idx = MON_DESTROYER;
        me.pseudo_class_idx = CLASS_MAULER;

        init = TRUE;

    }

    me.subname = _mon_name(p_ptr->current_r_idx);

    me.stats[A_STR] =  1 + rank;
    me.stats[A_INT] = -2 - (rank+1)/2;
    me.stats[A_WIS] = -2 - (rank+1)/2;
    me.stats[A_DEX] = -1 - (rank+1)/2;
    me.stats[A_CON] =  1 + rank;
    me.stats[A_CHR] =  0 + (rank+1)/2;

    switch (psubrace)
    {
    case GOLEM_SKY:
        if (!p_ptr->current_r_idx)
            me.subname = "Sky Golem";
        me.life = 100 + 2*rank;
        me.exp = 250;
        break;

    case GOLEM_SPELLWARP:
        if (!p_ptr->current_r_idx)
            me.subname = "Spellwarp Automaton";
        me.life = 100 + 3*rank;
        me.exp = 350;
        break;

    case GOLEM_COLOSSUS:
    default:
        if (!p_ptr->current_r_idx)
            me.subname = "Colossus";
        if (p_ptr->current_r_idx == MON_COLOSSUS)
        {
            me.stats[A_STR] += 3;
            me.stats[A_DEX] -= 2;
            me.stats[A_CON] += 3;
        }
        me.life = 100 + 5*rank;
        me.exp = 200;
        break;
    }

    return &me;
}
race_t *mon_hound_get_race_t(void)
{
    static race_t me = {0};
    static bool   init = FALSE;

    if (!init)
    {           /* dis, dev, sav, stl, srh, fos, thn, thb */
    skills_t bs = { 25,  20,  31,   4,  20,  15,  56,  30};
    skills_t xs = {  8,   8,  10,   1,   0,   0,  20,   7};

        me.skills = bs;
        me.extra_skills = xs;

        me.name = "Hound";
        me.desc = "While Hounds typically hunt in packs, you have chosen to go it alone. "
                    "You will begin life in the weak form of a Clear Hound. As you mature "
                    "you will take a number of evolutionary steps. At each such step, the "
                    "form you evolve into will be randomly determined. But each tier offers "
                    "more powerful choices than the last and who knows? You may even evolve "
                    "into an Aether Hound some day.\n \n"
                    "Hounds are monsters so cannot choose a normal class. They are not magical "
                    "so cannot cast spells. However, they are fantastic hunters so learn a "
                    "small number of abilities to aid in this endeavor. And of course, you "
                    "are probably aware that hounds love to breathe!\n \n"
                    "The body of the Hound is canine, so they cannot wield weapons. Instead, "
                    "they attack with their vicious bite and razor sharp claws. They are not "
                    "so powerful in melee as are dragons, but they are not that bad either. "
                    "Hounds can wear four rings on their front paws, a pair of boots on their "
                    "hind legs, an amulet around their neck and even a cloak and a suit of "
                    "body armor.";


        me.infra = 5;
        me.exp = 150;
        me.life = 100;
        me.base_hp = 22;

        me.calc_innate_attacks = hound_calc_innate_attacks;
        me.calc_bonuses = _calc_bonuses;
        me.get_powers = _get_powers;
        me.get_flags = _get_flags;
        me.get_vulnerabilities = _get_vulnerabilities;
        me.gain_level = _gain_level;
        me.birth = _birth;

        me.flags = RACE_IS_MONSTER; /* | RACE_IS_ILLITERATE? */
        me.boss_r_idx = MON_CARCHAROTH;

        me.pseudo_class_idx = CLASS_ROGUE;

        init = TRUE;
    }

    me.subname = _mon_name(p_ptr->current_r_idx);
    me.stats[A_STR] =  1 + p_ptr->lev/12;
    me.stats[A_INT] = -3;
    me.stats[A_WIS] = -5;
    me.stats[A_DEX] =  2 + p_ptr->lev/15;
    me.stats[A_CON] =  1 + p_ptr->lev/15;
    me.stats[A_CHR] =  0 + p_ptr->lev/25;
    me.equip_template = mon_get_equip_template();

    return &me;
}