diff options
Diffstat (limited to 'crawl-ref/source')
-rw-r--r-- | crawl-ref/source/describe.cc | 36 | ||||
-rw-r--r-- | crawl-ref/source/item_use.cc | 6 | ||||
-rw-r--r-- | crawl-ref/source/spl-book.cc | 114 | ||||
-rw-r--r-- | crawl-ref/source/spl-book.h | 3 |
4 files changed, 122 insertions, 37 deletions
diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc index ca8c6e66b4..68b2a77587 100644 --- a/crawl-ref/source/describe.cc +++ b/crawl-ref/source/describe.cc @@ -32,6 +32,7 @@ REVISION("$Rev$"); #include "fight.h" #include "food.h" #include "ghost.h" +#include "invent.h" #include "it_use2.h" #include "itemname.h" #include "itemprop.h" @@ -2184,7 +2185,7 @@ static bool _describe_spells(const item_def &item) if (nthing == SPELL_NO_SPELL) return (false); - describe_spell( nthing ); + describe_spell( nthing, &item ); return (true); } @@ -2202,13 +2203,23 @@ void describe_item( item_def &item, bool allow_inscribe ) while (true) { + // Memorised spell while reading a spellbook. + if (you.turn_is_over) + return; + const bool spells_shown = _show_item_description(item); if (spells_shown) { cgotoxy(1, wherey()); textcolor(LIGHTGREY); - cprintf("Select a spell to read its description."); + + if (item.base_type == OBJ_BOOKS && in_inventory(item)) + cprintf("Select a spell to read its description or to " + "memorize it."); + else + cprintf("Select a spell to read its description."); + if (_describe_spells(item)) continue; return; @@ -2383,7 +2394,7 @@ void inscribe_item(item_def &item, bool proper_prompt) // Describes (most) every spell in the game. // //--------------------------------------------------------------- -void describe_spell(spell_type spelled) +void describe_spell(spell_type spelled, const item_def* item) { std::string description; @@ -2405,6 +2416,7 @@ void describe_spell(spell_type spelled) #endif } + bool can_mem = false; if (you_cannot_memorise(spelled)) { description += "$$"; @@ -2413,13 +2425,27 @@ void describe_spell(spell_type spelled) description += lowercase_string(species_name(you.species, 0)); description += "."; } + else if (item && item->base_type == OBJ_BOOKS && in_inventory(*item)) + { + can_mem = true; + description += "$$"; + description += "(M)emorise this spell."; + } print_description(description); mouse_control mc(MOUSE_MODE_MORE); - if (getch() == 0) - getch(); + char ch; + if ((ch = getch()) == 0) + ch = getch(); + + if (can_mem && toupper(ch) == 'M') + { + if (!learn_spell(spelled, *item, false) || !you.turn_is_over) + more(); + redraw_screen(); + } } static std::string _describe_draconian_role(const monsters *mon) diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc index 3779037005..c5cbc035f2 100644 --- a/crawl-ref/source/item_use.cc +++ b/crawl-ref/source/item_use.cc @@ -4667,7 +4667,11 @@ static void handle_read_book(int item_slot) return; } - describe_spell(spell); + describe_spell(spell, &book); + + // Player memorised spell which was being looked at. + if (you.turn_is_over) + return; } } diff --git a/crawl-ref/source/spl-book.cc b/crawl-ref/source/spl-book.cc index d81492307b..6d335f6334 100644 --- a/crawl-ref/source/spl-book.cc +++ b/crawl-ref/source/spl-book.cc @@ -879,7 +879,11 @@ int spellbook_contents( item_def &book, read_book_action_type action, break; case RBOOK_READ_SPELL: - out.cprintf( "Select a spell to read its description." EOL ); + if (book.base_type == OBJ_BOOKS && in_inventory(book)) + out.cprintf( "Select a spell to read its description or to " + "memorise it." EOL ); + else + out.cprintf( "Select a spell to read its description." EOL ); break; default: @@ -1494,20 +1498,24 @@ static spell_type _choose_mem_spell(spell_list &spells, spell_menu.set_highlighter(NULL); spell_menu.set_tag("spell"); - std::string more_str = make_stringf("%d spell level%s left", + std::string more_str = make_stringf("<lightgreen>%d spell level%s left" + "<lightgreen>", player_spell_levels(), player_spell_levels() > 1 ? "s" : ""); if (num_unreadable > 0) - more_str += make_stringf(", %u unreadable spellbook%s", + more_str += make_stringf(", <lightmagenta>%u unreadable spellbook%s" + "</lightmagenta>", num_unreadable, num_unreadable > 1 ? "s" : ""); if (num_race > 0) - more_str += make_stringf(", %u spell%s unmemorizable", num_race, + more_str += make_stringf(", <lightred>%u spell%s unmemorizable" + "</lightred>", + num_race, num_race > 1 ? "s" : ""); - spell_menu.set_more(formatted_string(more_str)); + spell_menu.set_more(formatted_string::parse_string(more_str)); for (unsigned int i = 0; i < spells.size(); i++) { @@ -1565,11 +1573,12 @@ static spell_type _choose_mem_spell(spell_list &spells, } } -bool learn_spell() +bool can_learn_spell(bool silent) { if (player_in_bat_form()) { - canned_msg(MSG_PRESENT_FORM); + if (!silent) + canned_msg(MSG_PRESENT_FORM); return (false); } @@ -1582,22 +1591,34 @@ bool learn_spell() if (j == 0) { - mpr("You can't use spell magic! I'm afraid it's scrolls only for now."); + if (!silent) + mpr("You can't use spell magic! I'm afraid it's scrolls only " + "for now."); return (false); } if (you.confused()) { - mpr("You are too confused!"); + if (!silent) + mpr("You are too confused!"); return (false); } if (you.duration[DUR_BERSERKER]) { - canned_msg(MSG_TOO_BERSERK); + if (!silent) + canned_msg(MSG_TOO_BERSERK); return (false); } + return (true); +} + +bool learn_spell() +{ + if (!can_learn_spell()) + return (false); + spell_list mem_spells; spells_to_books book_hash; @@ -1609,16 +1630,45 @@ bool learn_spell() spell_type specspell = _choose_mem_spell(mem_spells, book_hash, num_unreadable, num_race); - // MATT if (specspell == SPELL_NO_SPELL) { canned_msg( MSG_OK ); return (false); } - if (player_spell_levels() < spell_levels_required(specspell)) + spells_to_books::iterator it = book_hash.find(specspell); + + item_def book; + book.base_type = OBJ_BOOKS; + book.sub_type = it->second; + book.quantity = 1; + book.flags |= ISFLAG_IDENT_MASK; + + return learn_spell(specspell, book, true); +} + +bool learn_spell(spell_type specspell, const item_def &book, + bool is_safest_book) +{ + if (!can_learn_spell()) + return (false); + + if (you_cannot_memorise(specspell)) { - mpr("You can't memorise that many levels of magic yet!"); + mprf("You cannot memorise that spell because you are a %s.", + lowercase_string(species_name(you.species, 0)).c_str()); + return (false); + } + + if (player_knows_spell(specspell)) + { + mpr("You already know that spell!"); + return (false); + } + + if (you.spell_no >= 21 && specspell != SPELL_SELECTIVE_AMNESIA) + { + mpr("Your head is already too full of spells!"); return (false); } @@ -1628,26 +1678,28 @@ bool learn_spell() return (false); } - int chance = spell_fail(specspell); + if (player_spell_levels() < spell_levels_required(specspell)) + { + mpr("You can't memorise that many levels of magic yet!"); + return (false); + } - spells_to_books::iterator it = book_hash.find(specspell); + int chance = spell_fail(specspell); - if (chance > 0 && is_dangerous_spellbook(it->second)) + if (chance > 0 && is_dangerous_spellbook(book)) { - item_def book; - book.base_type = OBJ_BOOKS; - book.sub_type = it->second; - book.quantity = 1; - book.flags |= ISFLAG_IDENT_MASK; + std::string prompt; - char buf[180]; + if (is_safest_book) + prompt = "The only spellbook you have which contains that spell "; + else + prompt = "The spellbook you are reading from "; + prompt += make_stringf("is %s, a dangerous spellbook which will " + "strike back at you if your memorisation " + "attempt fails. Attempt to memorise anyway?", + book.name(DESC_NOCAP_THE).c_str()); - sprintf(buf, "The only spellbook you have which contains that spell " - "is %s, a dangerous spellbook which will strike back at you " - "if your memorisation attempt fails. Attempt to memorise " - "anyway?", - book.name(DESC_NOCAP_THE).c_str()); - if (!yesno(buf, false, 'n')) + if (!yesno(prompt.c_str(), false, 'n')) { canned_msg( MSG_OK ); return (false); @@ -1695,21 +1747,21 @@ bool learn_spell() mpr("You fail to memorise the spell."); you.turn_is_over = true; - if (it->second == BOOK_NECRONOMICON) + if (book.sub_type == BOOK_NECRONOMICON) { mpr("The pages of the Necronomicon glow with a dark malevolence..."); MiscastEffect( &you, MISC_KNOWN_MISCAST, SPTYP_NECROMANCY, 8, random2avg(88, 3), "reading the Necronomicon" ); } - else if (it->second == BOOK_DEMONOLOGY) + else if (book.sub_type == BOOK_DEMONOLOGY) { mpr("This book does not appreciate being disturbed by one of your ineptitude!"); MiscastEffect( &you, MISC_KNOWN_MISCAST, SPTYP_SUMMONING, 7, random2avg(88, 3), "reading the book of Demonology" ); } - else if (it->second == BOOK_ANNIHILATIONS) + else if (book.sub_type == BOOK_ANNIHILATIONS) { mpr("This book does not appreciate being disturbed by one of your ineptitude!"); MiscastEffect( &you, MISC_KNOWN_MISCAST, SPTYP_CONJURATION, diff --git a/crawl-ref/source/spl-book.h b/crawl-ref/source/spl-book.h index ae57a4ebe1..50803c3bbe 100644 --- a/crawl-ref/source/spl-book.h +++ b/crawl-ref/source/spl-book.h @@ -49,7 +49,10 @@ int read_book( item_def &item, read_book_action_type action ); * called from: acr * *********************************************************************** */ bool player_can_memorise(const item_def &book); +bool can_learn_spell(bool silent = false); bool learn_spell(); +bool learn_spell(spell_type spell, const item_def &book, + bool is_safest_book); bool player_can_read_spellbook( const item_def &book ); |