spells within, and vice versa: when searching for spells, say which books/rods it can be found in.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7051 c06c8d41-db1a-0410-9941-cceddc491573
KNO4TZR76DMOYJCF24PSVQW7FUZOTMOJTL7I7J74SM4IHOGDX6TAC
HNPSSHGZFQ3E2I6X6VTKZ3WBBM2G25P2D7SIL2SZYKV2CCEA2ADAC
SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
CA3UUPVVUCMU7V7AUUIG6LOPEQEQKNYRPCSKF7FECSCA6VCZYAAAC
J44YLLLSMPKEY3IXV3CPOM257PQZW45A4QWSSBYVFXS5T5XGQQWAC
X4OVIUAVNYPQYIL5WU6F263TZZL22Z22LHAFJJLOGOPXWCCT7LMQC
VCG3BRIYRTNNWYC3LOXD6KFGXOX37HAFW2HNV7WXVG2V7EUHLDZQC
}
}
}
// Adds a list of all books/rods that contain a given spell (by name)
// to a description string.
static bool _append_books(std::string &desc, item_def &item, std::string key)
{
spell_type type = spell_by_name(key, true);
if (type == SPELL_NO_SPELL)
return (false);
set_ident_flags(item, ISFLAG_IDENT_MASK);
std::vector<std::string> books;
std::vector<std::string> rods;
item.base_type = OBJ_BOOKS;
for (int i = 0; i < NUM_BOOKS; i++)
for (int j = 0; j < 8; j++)
if (which_spell_in_book(i, j) == type)
{
item.sub_type = i;
books.push_back(item.name(DESC_PLAIN));
}
item.base_type = OBJ_STAVES;
int book;
for (int i = STAFF_SMITING; i < NUM_STAVES; i++)
{
item.sub_type = i;
book = item.book_number();
for (int j = 0; j < 8; j++)
if (which_spell_in_book(book, j) == type)
rods.push_back(item.name(DESC_PLAIN));
}
if (books.empty() && rods.empty())
return (false);
if (!books.empty())
{
desc += "$$This spell can be found in the following book";
if (books.size() > 1)
desc += "s";
desc += ":$";
desc += comma_separated_line(books.begin(), books.end(), "$", "$");
if (!rods.empty())
{
desc += "$$... and the following rod";
if (rods.size() > 1)
desc += "s";
desc += ":$";
desc += comma_separated_line(rods.begin(), rods.end(), "$", "$");
}
}
else // rods-only
{
desc += "$$This spell can be found in the following rod";
if (rods.size() > 1)
desc += "s";
desc += ":$";
desc += comma_separated_line(rods.begin(), rods.end(), "$", "$");
}
return (true);
}
// Adds a list of all spells contained in a book or rod to its
// description string.
static void _append_spells(std::string &desc, const item_def &item)
{
if (!item.has_spells())
return;
desc += "$$Spells Type Level$";
const int type = item.book_number();
for (int j = 0; j < 8; j++)
{
spell_type stype = which_spell_in_book(type, j);
if (stype == SPELL_NO_SPELL)
continue;
std::string name = spell_title(stype);
desc += name;
for (unsigned int i = 0; i < 35 - name.length(); i++)
desc += " ";
name = "";
if (item.base_type == OBJ_STAVES)
name += "Evocations";
else
{
bool already = false;
for (int i = 0; i <= SPTYP_LAST_EXPONENT; i++)
{
if (spell_typematch( stype, 1 << i ))
{
if (already)
name += "/" ;
name += spelltype_name( 1 << i );
already = true;
}
}
if (get_item_by_name(&mitm[thing_created], name, OBJ_WEAPONS))
if (_append_books(desc, mitm[thing_created], key))
{
// nothing to be done
}
else if (get_item_by_name(&mitm[thing_created], name, OBJ_BOOKS)
|| get_item_by_name(&mitm[thing_created], name, OBJ_STAVES))
{
_append_spells(desc, mitm[thing_created]);
}
else if (get_item_by_name(&mitm[thing_created], name, OBJ_WEAPONS))