Merge branch 'panlord-colour'
[crawl.git] / crawl-ref / source / describe.cc
index 57906ea..0e5c25e 100644 (file)
@@ -22,6 +22,7 @@
 #include "database.h"
 #include "decks.h"
 #include "delay.h"
+#include "describe-spells.h"
 #include "directn.h"
 #include "english.h"
 #include "env.h"
@@ -290,7 +291,7 @@ static vector<string> _randart_propnames(const item_def& item,
     if (is_unrandom_artefact(item))
     {
         const unrandart_entry *entry = get_unrand_entry(item.special);
-        if (entry && entry->inscrip != NULL)
+        if (entry && entry->inscrip != nullptr)
             propnames.push_back(entry->inscrip);
      }
 
@@ -1579,37 +1580,6 @@ static string _describe_deck(const item_def &item)
     return description;
 }
 
-// Adds a list of all spells contained in a book or rod to its
-// description string.
-void append_spells(string &desc, const item_def &item)
-{
-    if (!item.has_spells())
-        return;
-
-    desc += "\n\nSpells                             Type                      Level\n";
-
-    for (int j = 0; j < SPELLBOOK_SIZE; ++j)
-    {
-        spell_type stype = which_spell_in_book(item, j);
-        if (stype == SPELL_NO_SPELL)
-            continue;
-
-        string name = (is_memorised(stype) ? "*" : "");
-                    name += spell_title(stype);
-        desc += chop_string(name, 35);
-
-        string schools;
-        if (item.base_type == OBJ_RODS)
-            schools = "Evocations";
-        else
-            schools = spell_schools_string(stype);
-
-        desc += chop_string(schools, 65 - 36);
-
-        desc += make_stringf("%d\n", spell_difficulty(stype));
-    }
-}
-
 // ========================================================================
 //      Public Functions
 // ========================================================================
@@ -1773,7 +1743,7 @@ string get_item_description(const item_def &item, bool verbose,
         if (!verbose
             && (Options.dump_book_spells || is_random_artefact(item)))
         {
-            append_spells(desc, item);
+            desc += describe_item_spells(item);
             if (desc.empty())
                 need_extra_line = false;
             else
@@ -1917,7 +1887,7 @@ string get_item_description(const item_def &item, bool verbose,
         }
         else if (Options.dump_book_spells)
         {
-            append_spells(desc, item);
+            desc += describe_item_spells(item);
             if (desc.empty())
                 need_extra_line = false;
             else
@@ -2203,14 +2173,6 @@ static bool _can_show_spells(const item_def &item)
                || player_can_memorise_from_spellbook(item));
 }
 
-static void _show_spells(const item_def &item)
-{
-    formatted_string fs;
-    item_def dup = item;
-    spellbook_contents(dup, &fs);
-    fs.display(2, -2);
-}
-
 static void _show_item_description(const item_def &item)
 {
     const unsigned int lineWidth = get_number_of_cols() - 1;
@@ -2233,26 +2195,11 @@ static void _show_item_description(const item_def &item)
         hints_describe_item(item);
 
     if (_can_show_spells(item))
-      _show_spells(item);
-}
-
-static bool _describe_spells(const item_def &item)
-{
-    const int c = getchm();
-    if (c < 'a' || c > 'h')     //jmf: was 'g', but 8=h
     {
-        clear_messages();
-        return false;
+        formatted_string fdesc;
+        fdesc.cprintf("%s", desc.c_str());
+        list_spellset(item_spellset(item), &item, fdesc);
     }
-
-    const int spell_index = letter_to_index(c);
-
-    const spell_type nthing = which_spell_in_book(item, spell_index);
-    if (nthing == SPELL_NO_SPELL)
-        return false;
-
-    describe_spell(nthing, &item);
-    return item.is_valid();
 }
 
 static bool _can_memorise(item_def &item)
@@ -2270,35 +2217,6 @@ static void _update_inscription(item_def &item)
     }
 }
 
-static bool _describe_spellbook(item_def &item)
-{
-    while (true)
-    {
-        // Memorised spell while reading a spellbook.
-        if (already_learning_spell(-1))
-            return false;
-
-        _show_item_description(item);
-        _update_inscription(item);
-
-        cgotoxy(1, wherey());
-        textcolour(LIGHTGREY);
-
-        if (_can_memorise(item) && !crawl_state.player_is_dead())
-        {
-            cprintf("Select a spell to read its description, to "
-                    "memorise it or to forget it.");
-        }
-        else
-            cprintf("Select a spell to read its description.");
-
-        if (_describe_spells(item))
-            continue;
-
-        return true;
-    }
-}
-
 // it takes a key and a list of commands and it returns
 // the command from the list which corresponds to the key
 static command_type _get_action(int key, vector<command_type> actions)
@@ -2340,7 +2258,7 @@ static bool _actions_prompt(item_def &item, bool allow_inscribe, bool do_prompt)
 {
 #ifdef USE_TILE_LOCAL
     PrecisionMenu menu;
-    TextItem* tmp = NULL;
+    TextItem* tmp = nullptr;
     MenuFreeform* freeform = new MenuFreeform();
     menu.set_select_type(PrecisionMenu::PRECISION_SINGLESELECT);
     freeform->init(coord_def(1, 1),
@@ -2579,10 +2497,20 @@ bool describe_item(item_def &item, bool allow_inscribe, bool shopping)
     tiles_crt_control show_as_menu(CRT_MENU, "describe_item");
 #endif
 
-    if (_can_show_spells(item))
-        return _describe_spellbook(item);
-
+    // we might destroy the item, so save this first.
+    const bool item_had_spells = _can_show_spells(item);
     _show_item_description(item);
+
+    // spellbooks & rods have their own UIs, so we don't currently support the
+    // inscribe/drop/etc prompt UI for them.
+    // ...it would be nice if we did, though.
+    if (item_had_spells)
+    {
+        // only continue the inventory loop if we didn't start memorizing a
+        // spell & didn't destroy the item for amnesia.
+        return !already_learning_spell() && item.is_valid();
+    }
+
     _update_inscription(item);
 
     if (allow_inscribe && crawl_state.game_is_tutorial())
@@ -2635,13 +2563,16 @@ void inscribe_item(item_def &item, bool msgwin)
     char buf[79];
     int ret;
     if (msgwin)
-        ret = msgwin_get_line(prompt, buf, sizeof buf, NULL, item.inscription);
+    {
+        ret = msgwin_get_line(prompt, buf, sizeof buf, nullptr,
+                              item.inscription);
+    }
     else
     {
         _safe_newline();
         prompt = "<cyan>" + prompt + "</cyan>";
         formatted_string::parse_string(prompt).display();
-        ret = cancellable_get_line(buf, sizeof buf, NULL, NULL,
+        ret = cancellable_get_line(buf, sizeof buf, nullptr, nullptr,
                                   item.inscription);
     }
 
@@ -2793,7 +2724,7 @@ string get_skill_description(skill_type skill, bool need_title)
 // forget it and BOOK_NEITHER if you can do neither
 static int _get_spell_description(const spell_type spell,
                                    string &description,
-                                   const item_def* item = NULL)
+                                   const item_def* item = nullptr)
 {
     description.reserve(500);
 
@@ -3319,6 +3250,10 @@ static string _monster_spells_description(const monster_info& mi)
     if (mi.type == MONS_PANDEMONIUM_LORD)
         return "It may possess any of a vast number of diabolical powers.\n";
 
+    // Ditto for (a)liches.
+    if (mi.type == MONS_LICH || mi.type == MONS_ANCIENT_LICH)
+        return "It has mastered any of a vast number of powerful spells.\n";
+
     // Show monster spells and spell-like abilities.
     if (!mi.has_spells())
         return "";
@@ -3718,7 +3653,7 @@ static string _monster_stat_description(const monster_info& mi)
         "tiny",
         "very small",
         "small",
-        NULL,     // don't display anything for 'medium'
+        nullptr,     // don't display anything for 'medium'
         "large",
         "very large",
         "giant",
@@ -3893,8 +3828,8 @@ void get_monster_db_desc(const monster_info& mi, describe_info &inf,
         symbol_suffix += symbol;
         symbol_suffix += "_suffix";
 
-        string suffix = getLongDescription(symbol_suffix);
-              suffix += getLongDescription(symbol_suffix + "_examine");
+        string suffix = getLongDescription(symbol_suffix)
+                      + getLongDescription(symbol_suffix + "_examine");
 
         if (!suffix.empty())
             inf.body << "\n" << suffix;