Example #1
0
void t_mage_guild_window::scroll_hero_list( int first )
{
	int i;
	t_hero const*   hero;
	std::string     spell_name = get_spell_name( m_current_spell );
	std::string     text;

	m_first_hero = first;
	text = get_mage_guild_text( m_current_spell );
	for (i = 0; i < k_hero_icon_count && i + m_first_hero < m_heroes.size(); i++)
	{
		hero = m_heroes[i + first];
		m_hero_frames[i].frame->set_visible( true );
		m_hero_frames[i].icon->set_visible( true );
		m_hero_frames[i].text->set_visible( true );
		m_hero_frames[i].icon->set_bitmap( hero->get_portrait() );
		m_hero_frames[i].text->set_text( replace_keywords( text, hero, m_current_spell, m_town->get_grail_data()));
	}
	while (i < k_hero_icon_count)
	{
		m_hero_frames[i].frame->set_visible( false );
		m_hero_frames[i].icon->set_visible( false );
		m_hero_frames[i].text->set_visible( false );
		i++;
	}
	m_last_hero_button->set_visible( first > 0 );
	m_next_hero_button->set_visible( first + k_hero_icon_count < m_heroes.size() );
	if (m_heroes.size() == 0)
	{
		m_hero_frames[0].text->set_text( replace_keywords( k_no_heroes_know, "%spell_name",
			                                               spell_name ) );
		m_hero_frames[0].text->set_visible( true );
	}
}
bool t_parchment_visitor::visit_spell( t_artifact_prop::t_single_spell& effect )
{
	if (effect.get_effect() != k_artifact_effect_learn_spell)
		return false;

	t_spell spell = effect.get_spell();

	if (!m_message.empty())
		m_message += "\n";
	if (m_hero.in_spellbook( spell ))
	{
		m_message += k_text_already_known;
	}
	else if (!m_hero.learn_spell( spell ))
	{
		t_town_type alignment = get_spell_alignment( spell );
		int			level = get_spell_level( spell );
		t_skill     skill;

		skill.skill = t_skill_type( alignment + k_skill_life_magic );
		skill.level = t_skill_mastery( level + k_mastery_none );
		m_message += k_text_insufficient_skill;
		m_message = replace_keywords( m_message, skill );
	}
	else
	{
		m_message += k_text_learned;
		m_result = true;
	}

	m_message = replace_keywords( m_message, &m_hero );
	m_message = replace_keywords( m_message, "%spell_name", get_spell_name( spell ));
	return false;
}
Example #3
0
void t_mage_guild_window::spell_click( t_button*, t_spell spell )
{
	std::string text = get_spell_help( spell );

	text += "\n\n" + k_text_cost.get() + ": " + format_string( "%i", get_spell_cost( spell ));
	m_index_window->set_visible( false );
	m_detail_window->set_visible( true );
	m_spell_name->set_text( get_spell_name( spell ));
	m_spell_text->set_text( text );

	// compute size of description text.
	t_screen_rect rect   = m_spell_text->get_screen_rect();
	int           height = m_spell_text->get_text_height();

	if (height > m_maximum_description_height)
		height = m_maximum_description_height;
	rect.bottom = rect.top + height;
	m_spell_text->move_screen_rect( rect );

	// find size of flavor text
	t_screen_rect flavor_rect = rect;

	flavor_rect.top = rect.bottom + 20;
	flavor_rect.bottom = rect.top + m_maximum_description_height;
	if (flavor_rect.bottom < flavor_rect.top)
	{
		m_spell_comment->set_visible( false );
	}
	else
	{
		m_spell_comment->set_visible( true );
		m_spell_comment->move_screen_rect( flavor_rect );
		m_spell_comment->set_text( get_spell_flavor_text( spell ));
	}

	// set spell icon
	t_bitmap_layer const* frame;
	t_town_type           alignment;

	m_spell_icon->set_spell( spell );
	alignment = get_spell_alignment( spell );
	frame = m_frame_bitmaps->find( k_town_keyword[alignment] );
	m_spell_frame->set_bitmap( frame );
	m_current_spell = spell;

	// set large spell window
	m_large_spell_icon = get_spell_icon( spell, 180 );
	m_large_spell_icon_window->set_bitmap( m_large_spell_icon );

	m_spell_name_banner->set_visible( true );
	m_last_spell_button->set_visible( get_last_spell( spell, m_spells ) != k_spell_none );
	m_next_spell_button->set_visible( get_next_spell( spell, m_spells ) != k_spell_none );

	m_heroes.clear();
	set_hero_list( m_town->get_garrison() );
	if (m_adjacent_army != 0)
		set_hero_list( m_adjacent_army->get_creatures() );
	scroll_hero_list( 0 );
}
Example #4
0
// -------------------------------------------------------------------
// window to display a skill icon
// -------------------------------------------------------------------
void t_spell_icon_window::set_spell( t_spell spell )
{
	if (spell == m_spell)
		return;
	m_spell = spell;
	set_visible( spell != k_spell_none );
	if (spell != k_spell_none )
	{
		set_bitmap( get_spell_icon( spell, m_height ));
		set_help_balloon_text( get_spell_name( spell ));
	}
}
Example #5
0
/*
 * Learn the specified spell.
 */
void spell_learn(int spell)
{
    int i;

    magic_type *mt_ptr;

    /* Learn the spell */
    p_ptr->spell_flags[spell] |= PY_SPELL_LEARNED;
    
    /* Find the next open entry in "spell_order[]" */
    for (i = 0; i < PY_MAX_SPELLS; i++) {
	/* Stop at the first empty space */
	if (p_ptr->spell_order[i] == 99)
	    break;
    }

    /* Add the spell to the known list */
    p_ptr->spell_order[i] = spell;

    /* Access the spell */
    mt_ptr = &mp_ptr->info[spell];

    /* Mention the result */
    msgt(MSG_STUDY, "You have learned the %s of %s.", 
		   magic_desc[mp_ptr->spell_realm][SPELL_NOUN],
		   get_spell_name(mt_ptr->index));

    /* Sound */
    sound(MSG_STUDY);

    /* One less spell available */
    p_ptr->new_spells--;

    /* Message if needed */
    if (p_ptr->new_spells) {
	/* Message */
	msg("You can learn %d more %s%s.", p_ptr->new_spells,
		   magic_desc[mp_ptr->spell_realm][SPELL_NOUN],
		   ((p_ptr->new_spells != 1)
		    && (!mp_ptr->spell_book != TV_DRUID_BOOK)) ? "s" : "");
    }

    /* Redraw Study Status */
    p_ptr->redraw |= (PR_STUDY | PR_OBJECT);
}
Example #6
0
static void _learn_spell(int book, int spell)
{
    int idx = _spell_index(book, spell);
    int i;
    
    p_ptr->spell_learned1 |= (1L << idx);

    /* Find the next open entry in "p_ptr->spell_order[]" */
    for (i = 0; i < 64; i++)
    {
        /* Stop at the first empty space */
        if (p_ptr->spell_order[i] == 99) break;
    }

    /* Add the spell to the known list */
    p_ptr->spell_order[i++] = spell;
    
    msg_format("You have learned the technique of %s.", get_spell_name(_books[book].spells[spell].fn));
}
Example #7
0
/*
 * Learn the specified spell.
 */
void spell_learn(int spell)
{
	int i;
	const char *p = ((cp_ptr->spell_book == TV_MAGIC_BOOK) ? "spell" : "prayer");

	/* Learn the spell */
	p_ptr->spell_flags[spell] |= PY_SPELL_LEARNED;

	/* Find the next open entry in "spell_order[]" */
	for (i = 0; i < PY_MAX_SPELLS; i++)
	{
		/* Stop at the first empty space */
		if (p_ptr->spell_order[i] == 99) break;
	}

	/* Add the spell to the known list */
	p_ptr->spell_order[i] = spell;

	/* Mention the result */
	msgt(MSG_STUDY, "You have learned the %s of %s.",
	           p, get_spell_name(cp_ptr->spell_book, spell));

	/* One less spell available */
	p_ptr->new_spells--;

	/* Message if needed */
	if (p_ptr->new_spells)
	{
		/* Message */
		msg("You can learn %d more %s%s.",
		           p_ptr->new_spells, p, PLURAL(p_ptr->new_spells));
	}

	/* Redraw Study Status */
	p_ptr->redraw |= (PR_STUDY | PR_OBJECT);
}
Example #8
0
bool t_mass_spell_base::begin_casting()
{
	t_combat_creature_list::iterator index = m_battlefield.creatures_begin();
	t_combat_creature_list::iterator end   = m_battlefield.creatures_end();
	t_combat_spell_ptr               spell_object;
	std::string                      help_text;

	for (; index != end; index++)
	{
		if (spell_can_affect( *m_caster, **index ))
			break;
	}

	std::string text;

	if (index == end)
	{
		text = replace_keywords( k_text_no_effect, "%spell_name", get_spell_name( m_spell ));
		ok_dialog( text, true );
		return false;
	}
	m_battlefield.begin_spell( 0 );
	return true;
}
Example #9
0
spell_stats_ptr spell_stats(spell_info *spell)
{
    cptr name = get_spell_name(spell->fn);
    return spell_stats_aux(name);
}
Example #10
0
/**
 * Display a row of the spell menu
 */
static void spell_menu_display(menu_type * m, int oid, bool cursor,
							   int row, int col, int wid)
{
	struct spell_menu_data *d = menu_priv(m);
	int spell = d->spells[oid];
	const magic_type *s_ptr = &mp_ptr->info[spell];

	char help[30];

	int attr_name, attr_extra, attr_book;
	int tval = mp_ptr->spell_book;
	const char *comment = NULL;

	/* Choose appropriate spellbook color. */
	if (tval == TV_MAGIC_BOOK) {
		if (d->book_sval < SV_BOOK_MIN_GOOD)
			attr_book = TERM_L_RED;
		else
			attr_book = TERM_RED;
	} else if (tval == TV_PRAYER_BOOK) {
		if (d->book_sval < SV_BOOK_MIN_GOOD)
			attr_book = TERM_L_BLUE;
		else
			attr_book = TERM_BLUE;
	} else if (tval == TV_DRUID_BOOK) {
		if (d->book_sval < SV_BOOK_MIN_GOOD)
			attr_book = TERM_L_GREEN;
		else
			attr_book = TERM_GREEN;
	} else if (tval == TV_NECRO_BOOK) {
		if (d->book_sval < SV_BOOK_MIN_GOOD)
			attr_book = TERM_L_PURPLE;
		else
			attr_book = TERM_PURPLE;
	} else
		attr_book = TERM_WHITE;

	if (p_ptr->spell_flags[spell] & PY_SPELL_FORGOTTEN) {
		comment = " forgotten";
		attr_name = TERM_L_WHITE;
		attr_extra = TERM_L_WHITE;
	} else if (p_ptr->spell_flags[spell] & PY_SPELL_LEARNED) {
		if (p_ptr->spell_flags[spell] & PY_SPELL_WORKED) {
			/* Get extra info */
			get_spell_info(mp_ptr->spell_book, s_ptr->index, help,
						   sizeof(help));
			comment = help;
			attr_name = attr_book;
			attr_extra = TERM_DEEP_L_BLUE;
		} else {
			comment = " untried";
			attr_name = TERM_WHITE;
			attr_extra = TERM_WHITE;
		}
	} else if (s_ptr->slevel <= p_ptr->lev) {
		comment = " unknown";
		attr_extra = TERM_L_WHITE;
		attr_name = TERM_WHITE;
	} else {
		comment = " difficult";
		attr_extra = TERM_MUD;
		attr_name = TERM_MUD;
	}

	/* Dump the spell --(-- */
	c_put_str(attr_name, format("%-30s", get_spell_name(s_ptr->index)),
			  row, col);
	put_str(format
			("%2d %4d %3d%%", s_ptr->slevel, s_ptr->smana,
			 spell_chance(spell)), row, col + 30);
	c_put_str(attr_extra, format("%s", comment), row, col + 42);
}
Example #11
0
// -------------------------------------------------------------------
// window to display spells available in mage guild
// -------------------------------------------------------------------
void t_mage_guild_window::create_spell_icons()
{
	static int const          k_layout[5][3][3] = 
	{
		{ { 1, 2, 3 },	{ 4, 5 },	{ 6, 7 } },
		{ { 1, 2, 3 },	{ 4, 5 },	{ 6, 7 } },
		{ { 1, 2 },		{ 3, 4 },	{ 5, 6 } },
		{ { 1, 2 },		{ 3 },		{ 4 } },
		{ { 1 },		{ 2 },		{ 3 } },
	};

	int                       level;
	t_guild_spell_list const& spells = m_town->get_spells();
	int                       i;
	int                       spell_count[5][3];
	std::string               layer_name;
	t_screen_rect             rect;
	t_screen_rect             text_frame_rect;
	t_screen_rect             text_rect;
	t_bitmap_layer const *    frame;
	t_bitmap_layer const *    layer;
	t_screen_rect             icon_rect;
	t_window*                 window;
	t_button*                 button;
	t_text_window*            text_window;
	t_town_type               alignment;
	t_spell                   spell;
	int                       frame_number;
	int                       library;
	int                       count;

	memset( spell_count, 0, sizeof(spell_count));
	rect = m_book_bitmaps->find( "level_1_frame_1" )->get_rect();
	text_frame_rect = m_book_bitmaps->find( "spell_background" )->get_rect() - rect.top_left();
	text_rect = m_book_bitmaps->find( "level_1_name_1" )->get_rect() - rect.top_left();
	icon_rect = m_frame_bitmaps->find( "spell_icon" )->get_rect();
	for (i = 0; i < m_spells.size(); i++)
	{
		// spell icon
		spell = m_spells[i];
		level = get_spell_level( spell );
		alignment = get_spell_alignment( spell );
		if (alignment == m_town->get_type())
			library = 0;
		else if (alignment == m_town->get_library_type( k_town_library_1 ))
			library = 1;
		else
			library = 2;
		count = spell_count[level-1][library]++;
		frame_number = k_layout[level-1][library][count];
		layer_name = format_string( "level_%i_frame_%i", level, frame_number );
		layer = m_book_bitmaps->find( layer_name );
		if (layer)
			rect = layer->get_rect();
		else
		{
			DEBUG_MESSAGE( format_string( "Missing asset in dialog.mage_guild.book:  %s", layer_name.c_str() ).c_str() );
			assert( !"Missing Asset" );
			continue;
		}

		// frame
		frame = m_frame_bitmaps->find( k_town_keyword[alignment] );
		window = new t_bitmap_layer_window( frame, rect.top_left(), m_index_window, false );
		window->set_visible(false);
		int page = 0;
		if( level > 2 )
			page = 1;
		m_frames_list[page].push_back(window);

		// icon
		button = new t_button( icon_rect.top_left() + rect.top_left(), m_index_window );
		window = new t_spell_icon_window( spell, icon_rect - icon_rect.top_left(), button );
		button->set_released_image( window );
		button->set_click_handler( add_2nd_argument( bound_handler( *this,
			                       &t_mage_guild_window::spell_click ), spell ));
		button->set_visible(false);
		m_icon_list[page].push_back(button);

		// spell desc background
		layer = m_book_bitmaps->find( "spell_background" );
		t_screen_rect desc_rect =  text_frame_rect + rect.top_left();
		window = new t_bitmap_layer_window( layer, desc_rect.top_left(), m_index_window, false );
		window->set_visible(false);
		m_label_banner_list[page].push_back(window);

		// spell name
		text_window = new t_text_window( get_font( 14 ), 
			                             text_rect + rect.top_left() + t_screen_point(0,0),
										 m_index_window, get_spell_name( spell ),
										 t_pixel_24(0,0,0));
		text_window->set_center_horizontal();
		text_window->set_center_vertical();
		text_window->set_drop_shadow( true, t_pixel_24(200,200,200));
		text_window->set_visible(false);
		m_spellname_list[page].push_back(text_window);
	}

	// Details page stuff
	layer = m_book_bitmaps->find( "spell_name_background" );
	rect = layer->get_rect();
	m_spell_name_banner = new t_bitmap_layer_window( layer, rect.top_left(), m_detail_window, false );
	m_spell_name_banner->set_visible(false);

	layer = m_book_bitmaps->find( "hero_list_background" );
	rect = layer->get_rect();
	window = new t_bitmap_layer_window( layer, rect.top_left(), m_detail_window, false );
//	window->set_visible(false);

	rect = m_book_bitmaps->find( "spell_frame" )->get_rect();
	m_spell_frame = new t_bitmap_layer_window( 0, rect.top_left(), m_detail_window );
	m_spell_icon = new t_spell_icon_window( k_spell_none, icon_rect + rect.top_left(),
		                                    m_detail_window );

	rect = m_book_bitmaps->find( "icon_silhouette" )->get_rect();
	m_large_spell_icon_window = new t_blended_bitmap_window( 0, rect.top_left(), m_detail_window,
		                                                     true, 4 );
}
Example #12
0
void infoSpells(const Player* viewer, Creature* target, bool notSelf) {
    Player *player = target->getAsPlayer();
    const Anchor* anchor=0;
    MagicType castingType = target->getCastingType();
    int     min = (castingType == Divine ? (int)MIN_DOMAIN : (int)MIN_SCHOOL) + 1, max = (castingType == Divine ? (int)MAX_DOMAIN : (int)MAX_SCHOOL);
    char    spl[max][MAXSPELL][24], list[MAXSPELL][24];
    int     count=0, j[max], l = sizeof(list);
    int     i=0,n=0;
    bstring str="";
    bstring skillName="";

    if(notSelf)
        viewer->printColor("\n^Y%M's Spells Known: ", target);
    else
        viewer->printColor("\n^YSpells known: ");

    zero(j, sizeof(j));
    zero(spl, sizeof(spl));
    for(i = 0; i < get_spell_list_size() ; i++) {
        if(target->spellIsKnown(i)) {
            count++;

            if(castingType == Divine) {
                n = (int)get_spell_domain(i);
                // monsters ignore these rules - move into the "other" category
                if(n == DOMAIN_CANNOT_CAST && !player)
                    n = NO_DOMAIN;
            } else {
                n = (int)get_spell_school(i);
                // monsters ignore these rules - move into the "other" category
                if(n == SCHOOL_CANNOT_CAST && !player)
                    n = NO_SCHOOL;
            }

            strcpy(spl[n][j[n]++], get_spell_name(i));
        }
    }

    if(!count) {
        viewer->print("None.");
    } else {
        viewer->print("%d", count);
        for(n = min; n < max; n++) {
            if(j[n]) {
                memcpy(list, spl[n], l);
                qsort((void *) list, j[n], 24, (PFNCOMPARE) strcmp);
                str = "";
                for(i = 0; i < j[n]; i++) {
                    str += list[i];
                    str += ", ";
                }

                if(castingType == Divine) {
                    if((DomainOfMagic)n == NO_DOMAIN) {
                        skillName = "Other";
                    } else if((DomainOfMagic)n == DOMAIN_CANNOT_CAST) {
                        skillName = "Not Castable";
                    } else {
                        skillName = gConfig->getSkillDisplayName(spellSkill((DomainOfMagic)n));
                    }
                } else{
                    if((SchoolOfMagic)n == NO_SCHOOL) {
                        skillName = "Other";
                    } else if((SchoolOfMagic)n == SCHOOL_CANNOT_CAST) {
                        skillName = "Not Castable";
                    } else {
                        skillName = gConfig->getSkillDisplayName(spellSkill((SchoolOfMagic)n));
                    }
                }
                str = str.substr(0, str.length() - 2) + ".";
                viewer->printColor("\n^W%s:^x %s", skillName.c_str(), str.c_str());
            }
        }
    }

    viewer->print("\n\n");




    spellsUnder(viewer, target, notSelf);

    if(!player)
        return;

    if(player->hasAnchor(0) || player->hasAnchor(1) || player->hasAnchor(2)) {
        viewer->printColor("^YCurrent Dimensional Anchors\n");

        for(i=0; i<MAX_DIMEN_ANCHORS; i++) {
            if(player->hasAnchor(i)) {
                anchor = player->getAnchor(i);
                viewer->printColor("^c%s ^x-> ^c%s", anchor->getAlias().c_str(),
                    anchor->getRoomName().c_str());

                if(viewer->isStaff())
                    viewer->print("  %s", (anchor->getMapMarker() ? anchor->getMapMarker()->str() : anchor->getRoom().str()).c_str());

                viewer->print("\n");
            }
        }
    }
}
Example #13
0
/*
 * Calculate number of spells player should have, and forget,
 * or remember, spells until that number is properly reflected.
 *
 * Note that this function induces various "status" messages,
 * which must be bypasses until the character is created.
 */
static void calc_spells(void)
{
	int i, j, k, levels;
	int num_allowed, num_known;
	int percent_spells;

	const magic_type *s_ptr;

	s16b old_spells;

	cptr p = ((cp_ptr->spell_book == TV_MAGIC_BOOK) ? "spell" : "prayer");


	/* Hack -- must be literate */
	if (!cp_ptr->spell_book) return;

	/* Hack -- wait for creation */
	if (!character_generated) return;

	/* Hack -- handle "xtra" mode */
	if (character_xtra) return;

	/* Save the new_spells value */
	old_spells = p_ptr->new_spells;


	/* Determine the number of spells allowed */
	levels = p_ptr->lev - cp_ptr->spell_first + 1;

	/* Hack -- no negative spells */
	if (levels < 0) levels = 0;

	/* Number of 1/100 spells per level */
	percent_spells = adj_mag_study[p_ptr->state.stat_ind[cp_ptr->spell_stat]];

	/* Extract total allowed spells (rounded up) */
	num_allowed = (((percent_spells * levels) + 50) / 100);

	/* Assume none known */
	num_known = 0;

	/* Count the number of spells we know */
	for (j = 0; j < PY_MAX_SPELLS; j++)
	{
		/* Count known spells */
		if (p_ptr->spell_flags[j] & PY_SPELL_LEARNED)
		{
			num_known++;
		}
	}

	/* See how many spells we must forget or may learn */
	p_ptr->new_spells = num_allowed - num_known;



	/* Forget spells which are too hard */
	for (i = PY_MAX_SPELLS - 1; i >= 0; i--)
	{
		/* Get the spell */
		j = p_ptr->spell_order[i];

		/* Skip non-spells */
		if (j >= 99) continue;

		/* Get the spell */
		s_ptr = &mp_ptr->info[j];

		/* Skip spells we are allowed to know */
		if (s_ptr->slevel <= p_ptr->lev) continue;

		/* Is it known? */
		if (p_ptr->spell_flags[j] & PY_SPELL_LEARNED)
		{
			/* Mark as forgotten */
			p_ptr->spell_flags[j] |= PY_SPELL_FORGOTTEN;

			/* No longer known */
			p_ptr->spell_flags[j] &= ~PY_SPELL_LEARNED;

			/* Message */
			msg_format("You have forgotten the %s of %s.", p,
			           get_spell_name(cp_ptr->spell_book, j));

			/* One more can be learned */
			p_ptr->new_spells++;
		}
	}


	/* Forget spells if we know too many spells */
	for (i = PY_MAX_SPELLS - 1; i >= 0; i--)
	{
		/* Stop when possible */
		if (p_ptr->new_spells >= 0) break;

		/* Get the (i+1)th spell learned */
		j = p_ptr->spell_order[i];

		/* Skip unknown spells */
		if (j >= 99) continue;

		/* Forget it (if learned) */
		if (p_ptr->spell_flags[j] & PY_SPELL_LEARNED)
		{
			/* Mark as forgotten */
			p_ptr->spell_flags[j] |= PY_SPELL_FORGOTTEN;

			/* No longer known */
			p_ptr->spell_flags[j] &= ~PY_SPELL_LEARNED;

			/* Message */
			msg_format("You have forgotten the %s of %s.", p,
			           get_spell_name(cp_ptr->spell_book, j));

			/* One more can be learned */
			p_ptr->new_spells++;
		}
	}


	/* Check for spells to remember */
	for (i = 0; i < PY_MAX_SPELLS; i++)
	{
		/* None left to remember */
		if (p_ptr->new_spells <= 0) break;

		/* Get the next spell we learned */
		j = p_ptr->spell_order[i];

		/* Skip unknown spells */
		if (j >= 99) break;

		/* Get the spell */
		s_ptr = &mp_ptr->info[j];

		/* Skip spells we cannot remember */
		if (s_ptr->slevel > p_ptr->lev) continue;

		/* First set of spells */
		if (p_ptr->spell_flags[j] & PY_SPELL_FORGOTTEN)
		{
			/* No longer forgotten */
			p_ptr->spell_flags[j] &= ~PY_SPELL_FORGOTTEN;

			/* Known once more */
			p_ptr->spell_flags[j] |= PY_SPELL_LEARNED;

			/* Message */
			msg_format("You have remembered the %s of %s.",
			           p, get_spell_name(cp_ptr->spell_book, j));

			/* One less can be learned */
			p_ptr->new_spells--;
		}
	}


	/* Assume no spells available */
	k = 0;

	/* Count spells that can be learned */
	for (j = 0; j < PY_MAX_SPELLS; j++)
	{
		/* Get the spell */
		s_ptr = &mp_ptr->info[j];

		/* Skip spells we cannot remember or don't exist */
		if (s_ptr->slevel > p_ptr->lev || s_ptr->slevel == 0) continue;

		/* Skip spells we already know */
		if (p_ptr->spell_flags[j] & PY_SPELL_LEARNED)
		{
			continue;
		}

		/* Count it */
		k++;
	}

	/* Cannot learn more spells than exist */
	if (p_ptr->new_spells > k) p_ptr->new_spells = k;

	/* Spell count changed */
	if (old_spells != p_ptr->new_spells)
	{
		/* Message if needed */
		if (p_ptr->new_spells)
		{
			/* Message */
			msg_format("You can learn %d more %s%s.",
			           p_ptr->new_spells, p,
			           (p_ptr->new_spells != 1) ? "s" : "");
		}

		/* Redraw Study Status */
		p_ptr->redraw |= (PR_STUDY | PR_OBJECT);
	}
}