From 7fcfce7d250e09f85bc09f9e720dda5cf723e68e Mon Sep 17 00:00:00 2001 From: j-p-e-g Date: Mon, 29 Dec 2008 11:11:32 +0000 Subject: * Dump spells contained in randart spellbooks, marking memorised spells with an asterisk. * Sif Muna no longer gifts the books specific to Kiku and Vehumet (Necronomicon, Annihilations, Demonology) though the spells contained there-in may crop up in randart books. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@8011 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/chardump.cc | 23 ++++++++----- crawl-ref/source/command.cc | 54 +---------------------------- crawl-ref/source/describe.cc | 81 ++++++++++++++++++++++++++++++++++++++------ crawl-ref/source/describe.h | 2 ++ crawl-ref/source/effects.cc | 64 +++++++++++++++++++--------------- crawl-ref/source/initfile.cc | 14 +++++--- crawl-ref/source/items.cc | 12 +++---- crawl-ref/source/makeitem.cc | 10 +++--- crawl-ref/source/randart.cc | 4 +-- crawl-ref/source/religion.cc | 2 +- crawl-ref/source/spl-book.cc | 26 +++++++------- crawl-ref/source/spl-book.h | 1 + 12 files changed, 164 insertions(+), 129 deletions(-) (limited to 'crawl-ref') diff --git a/crawl-ref/source/chardump.cc b/crawl-ref/source/chardump.cc index 6f50aa8146..1e614e9b74 100644 --- a/crawl-ref/source/chardump.cc +++ b/crawl-ref/source/chardump.cc @@ -653,7 +653,7 @@ static void _sdump_religion(dump_params &par) } } -static bool dump_item_origin(const item_def &item, int value) +static bool _dump_item_origin(const item_def &item, int value) { #define fs(x) (flags & (x)) const int flags = Options.dump_item_origins; @@ -661,10 +661,11 @@ static bool dump_item_origin(const item_def &item, int value) return (true); if (fs(IODS_ARTEFACTS) - && (is_random_artefact(item) || is_fixed_artefact(item)) - && item_ident(item, ISFLAG_KNOW_PROPERTIES)) + && (is_random_artefact(item) || is_fixed_artefact(item)) + && item_ident(item, ISFLAG_KNOW_PROPERTIES)) + { return (true); - + } if (fs(IODS_EGO_ARMOUR) && item.base_type == OBJ_ARMOUR && item_type_known( item )) { @@ -682,16 +683,22 @@ static bool dump_item_origin(const item_def &item, int value) return (true); if (fs(IODS_RUNES) && item.base_type == OBJ_MISCELLANY - && item.sub_type == MISC_RUNE_OF_ZOT) + && item.sub_type == MISC_RUNE_OF_ZOT) + { return (true); + } if (fs(IODS_RODS) && item.base_type == OBJ_STAVES - && item_is_rod(item)) + && item_is_rod(item)) + { return (true); + } if (fs(IODS_STAVES) && item.base_type == OBJ_STAVES - && !item_is_rod(item)) + && !item_is_rod(item)) + { return (true); + } if (fs(IODS_BOOKS) && item.base_type == OBJ_BOOKS) return (true); @@ -790,7 +797,7 @@ static void _sdump_inventory(dump_params &par) } if (origin_describable(you.inv[j]) - && dump_item_origin(you.inv[j], ival)) + && _dump_item_origin(you.inv[j], ival)) { text += "\n" " (" + origin_desc(you.inv[j]) + ")"; } diff --git a/crawl-ref/source/command.cc b/crawl-ref/source/command.cc index 1fbab5fdfe..7751761b85 100644 --- a/crawl-ref/source/command.cc +++ b/crawl-ref/source/command.cc @@ -1247,58 +1247,6 @@ static bool _append_books(std::string &desc, item_def &item, std::string key) 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$"; - - for (int j = 0; j < 8; j++) - { - spell_type stype = which_spell_in_book(item, 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; - } - } - } - desc += name; - - for (unsigned int i = 36; i < 65 - name.length(); i++) - desc += " "; - - char sval[3]; - itoa( spell_difficulty( stype ), sval, 10 ); - desc += sval; - desc += "$"; - } - -} - static bool _do_description(std::string key, std::string type, std::string footer = "") { @@ -1411,7 +1359,7 @@ static bool _do_description(std::string key, std::string type, || get_item_by_name(&mitm[thing_created], name, OBJ_STAVES)) { if (!_append_books(desc, mitm[thing_created], key)) - _append_spells(desc, mitm[thing_created]); + append_spells(desc, mitm[thing_created]); } else _append_non_item(desc, key); diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc index 42bf6aa797..25a95d3f45 100644 --- a/crawl-ref/source/describe.cc +++ b/crawl-ref/source/describe.cc @@ -1625,6 +1625,58 @@ static std::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(std::string &desc, const item_def &item) +{ + if (!item.has_spells()) + return; + + desc += "$$Spells Type Level$"; + + for (int j = 0; j < 8; j++) + { + spell_type stype = which_spell_in_book(item, j); + if (stype == SPELL_NO_SPELL) + continue; + + std::string name = (is_memorised(stype)) ? "*" : ""; + 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; + } + } + } + desc += name; + + for (unsigned int i = 36; i < 65 - name.length(); i++) + desc += " "; + + char sval[3]; + itoa( spell_difficulty( stype ), sval, 10 ); + desc += sval; + desc += "$"; + } +} + // ======================================================================== // Public Functions // ======================================================================== @@ -1714,7 +1766,8 @@ std::string get_item_description( const item_def &item, bool verbose, description << ".$"; } else if (verbose || (item.base_type != OBJ_WEAPONS - && item.base_type != OBJ_ARMOUR)) + && item.base_type != OBJ_ARMOUR + && item.base_type != OBJ_BOOKS)) { description << "$$"; @@ -1779,7 +1832,7 @@ std::string get_item_description( const item_def &item, bool verbose, std::string desc; switch (item.base_type) { - // Weapons, armour, jewellery might be artefacts. + // Weapons, armour, jewellery, books might be artefacts. case OBJ_WEAPONS: desc = _describe_weapon( item, verbose ); if (desc.empty()) @@ -1804,6 +1857,22 @@ std::string get_item_description( const item_def &item, bool verbose, description << desc; break; + case OBJ_BOOKS: + if (!player_can_read_spellbook( item )) + { + description << "$This book is beyond your current level of " + "understanding."; + } + else if (!verbose && is_random_artefact( item )) + { + append_spells( desc, item ); + if (desc.empty()) + need_extra_line = false; + else + description << desc; + } + break; + case OBJ_MISSILES: description << _describe_ammo( item ); break; @@ -1905,14 +1974,6 @@ std::string get_item_description( const item_def &item, bool verbose, description << _describe_deck( item ); break; - case OBJ_BOOKS: - if (!player_can_read_spellbook( item )) - { - description << "$This book is beyond your current level of " - "understanding."; - } - break; - case OBJ_POTIONS: #ifdef DEBUG_BLOOD_POTIONS // List content of timer vector for blood potions. diff --git a/crawl-ref/source/describe.h b/crawl-ref/source/describe.h index 1b938b6740..ab661c919c 100644 --- a/crawl-ref/source/describe.h +++ b/crawl-ref/source/describe.h @@ -27,6 +27,8 @@ enum item_description_type NUM_IDESC }; +void append_spells(std::string &desc, const item_def &item); + // last updated 12may2000 {dlb} /* *********************************************************************** * called from: chardump - spells4 diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc index 9b34adb9de..72de9af7fd 100644 --- a/crawl-ref/source/effects.cc +++ b/crawl-ref/source/effects.cc @@ -1186,8 +1186,7 @@ static int _find_acquirement_subtype(object_class_type class_wanted, // much too good (most spells, lots of books here, // id wand charges, gives magic resistance), // something will eventually have to be done. -- bwr - if (best_any >= SK_FIGHTING - && best_any <= SK_STAVES) + if (best_any >= SK_FIGHTING && best_any <= SK_STAVES) { // Fighter mages get the fighting enchantment books if (!you.had_book[BOOK_WAR_CHANTS]) @@ -1275,7 +1274,7 @@ static int _find_acquirement_subtype(object_class_type class_wanted, } // If the book is invalid find any valid one. - while (book_rarity(type_wanted) == 100) + while (type_wanted == BOOK_HEALING) type_wanted = random2(NUM_NORMAL_BOOKS); break; @@ -1423,8 +1422,8 @@ static void _do_book_acquirement(item_def &book, int agent) // items() shouldn't make book a randart for acquirement items. ASSERT(!is_random_artefact(book)); - // Non-normal books are rare enough without turning them into - // randart books. + // Non-normal books (i.e. manuals/book of destruction) are rare enough + // without turning them into randart books. if (book.sub_type > MAX_NORMAL_BOOK) return; @@ -1445,36 +1444,35 @@ static void _do_book_acquirement(item_def &book, int agent) std::vector vec; for (int i = 1; i <= 9 && (vec.empty() || i <= max_level); i++) - { if (!(seen_levels & (1 << i))) vec.push_back(i); - } + if (vec.size() > 0) level = vec[random2(vec.size())]; else level = -1; } - int choice_weights[4] = { - 55, // fixed themed - 24, // leave alone - level == -1 ? 0 : 12, // fixed level - agent == GOD_XOM ? 0 : 6, // manual (too useful for Xom) - }; + int choice = random_choose_weighted( + 55, BOOK_RANDART_THEME, + 24, book.sub_type, + level == -1 ? 0 : 12, BOOK_RANDART_LEVEL, + agent == GOD_XOM ? 0 : 6, BOOK_MANUAL, // too useful for Xom + 0); + + // No changes. + if (choice == book.sub_type) + return; - int choice = choose_random_weighted(choice_weights, choice_weights + 4); + book.sub_type = choice; - switch(choice) + switch (choice) { - case 0: + case BOOK_RANDART_THEME: make_book_theme_randart(book, 0, 0, 7, 22); break; - case 1: - // Leave alone - break; - - case 2: + case BOOK_RANDART_LEVEL: { int num_spells = 7 - (level + 1) / 2 + random_range(1, 2); make_book_level_randart(book, level, num_spells); @@ -1482,7 +1480,7 @@ static void _do_book_acquirement(item_def &book, int agent) } // Spell discipline manual - case 3: + case BOOK_MANUAL: { int weights[SK_POISON_MAGIC - SK_CONJURATIONS + 1]; int total_weights = 0; @@ -1559,15 +1557,13 @@ bool acquirement(object_class_type class_wanted, int agent, } } - const bool god_agent = agent > GOD_NO_GOD && agent < NUM_GODS; - if (grid_destroys_items(grd(you.pos()))) { // How sad (and stupid). if (!silenced(you.pos()) && !quiet) mprf(MSGCH_SOUND, grid_item_destruction_message(grd(you.pos()))); - if (god_agent) + if (agent > GOD_NO_GOD && agent < NUM_GODS) { if (agent == GOD_XOM) simple_god_message(" snickers.", GOD_XOM); @@ -1596,7 +1592,7 @@ bool acquirement(object_class_type class_wanted, int agent, // Don't generate randart books in items(), we do that // ourselves. - int want_arts = class_wanted == OBJ_BOOKS ? 0 : 1; + int want_arts = (class_wanted == OBJ_BOOKS ? 0 : 1); thing_created = items( want_arts, class_wanted, type_wanted, true, MAKE_GOOD_ITEM, MAKE_ITEM_RANDOM_RACE, @@ -1661,6 +1657,20 @@ bool acquirement(object_class_type class_wanted, int agent, continue; } } + + // Sif Muna shouldn't gift Vehumet or Kiku's special books. + // (The spells therein are still fair game for randart books.) + if (agent == GOD_SIF_MUNA + && doodad.sub_type >= MIN_GOD_ONLY_BOOK + && doodad.sub_type <= MAX_GOD_ONLY_BOOK) + { + ASSERT(doodad.base_type == OBJ_BOOKS); + + // Try again. + destroy_item(thing_created); + thing_created = NON_ITEM; + continue; + } break; } @@ -1822,7 +1832,7 @@ bool acquirement(object_class_type class_wanted, int agent, if (is_random_artefact(thing)) { if (!is_unrandom_artefact(thing) - && !thing.base_type == OBJ_BOOKS) + && thing.base_type != OBJ_BOOKS) { // Give another name that takes god gift into account; // artefact books already do that. diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc index 14e9e69f57..bbd6dcdc4f 100644 --- a/crawl-ref/source/initfile.cc +++ b/crawl-ref/source/initfile.cc @@ -2832,15 +2832,21 @@ void game_options::read_option_line(const std::string &str, bool runscript) { const std::string &ch = choices[i]; if (ch == "artefacts" || ch == "artifacts" - || ch == "artefact" || ch == "artifact") + || ch == "artefact" || ch == "artifact") + { dump_item_origins |= IODS_ARTEFACTS; + } else if (ch == "ego_arm" || ch == "ego armour" - || ch == "ego_armour") + || ch == "ego_armour") + { dump_item_origins |= IODS_EGO_ARMOUR; + } else if (ch == "ego_weap" || ch == "ego weapon" - || ch == "ego_weapon" || ch == "ego weapons" - || ch == "ego_weapons") + || ch == "ego_weapon" || ch == "ego weapons" + || ch == "ego_weapons") + { dump_item_origins |= IODS_EGO_WEAPON; + } else if (ch == "jewellery" || ch == "jewelry") dump_item_origins |= IODS_JEWELLERY; else if (ch == "runes") diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc index 990dd46204..49c376408e 100644 --- a/crawl-ref/source/items.cc +++ b/crawl-ref/source/items.cc @@ -1061,7 +1061,7 @@ bool origin_is_god_gift(const item_def& item, god_type *god) if (iorig > GOD_NO_GOD && iorig < NUM_GODS) { *god = static_cast(iorig); - return(true); + return (true); } return (false); @@ -2570,16 +2570,16 @@ bool item_is_equipped(const item_def &item, bool quiver_too) bool item_def::has_spells() const { return ((base_type == OBJ_BOOKS && item_type_known(*this) - && sub_type != BOOK_DESTRUCTION - && sub_type != BOOK_MANUAL) + && sub_type != BOOK_DESTRUCTION + && sub_type != BOOK_MANUAL) || count_staff_spells(*this, true) > 1); } int item_def::book_number() const { - return (base_type == OBJ_BOOKS? sub_type : - base_type == OBJ_STAVES? sub_type + NUM_BOOKS - STAFF_SMITING : - -1); + return (base_type == OBJ_BOOKS ? sub_type : + base_type == OBJ_STAVES ? sub_type + NUM_BOOKS - STAFF_SMITING + : -1); } bool item_def::cursed() const diff --git a/crawl-ref/source/makeitem.cc b/crawl-ref/source/makeitem.cc index bd98b43d61..bd4ee4a76d 100644 --- a/crawl-ref/source/makeitem.cc +++ b/crawl-ref/source/makeitem.cc @@ -2424,7 +2424,7 @@ static void _generate_book_item(item_def& item, int allow_uniques, continue; } } - while (book_rarity(item.sub_type) == 100); + while (item.sub_type == BOOK_HEALING); // Tome of destruction: rare! if (item_level > 10 && x_chance_in_y(21 + item_level, 7000)) @@ -2664,7 +2664,7 @@ static void _generate_misc_item(item_def& item, int force_type, int item_race) // Returns item slot or NON_ITEM if it fails. int items( int allow_uniques, // not just true-false, - // because of BCR acquirement hack + // because of BCR acquirement hack object_class_type force_class, // desired OBJECTS class {dlb} int force_type, // desired SUBTYPE - enum varies by OBJ bool dont_place, // don't randomly place item on level @@ -2681,9 +2681,9 @@ int items( int allow_uniques, // not just true-false, // force_ego = SPWPN_VORPAL, and a random weapon of a type // appropriate for the vorpal brand will be chosen. ASSERT(force_ego <= 0 - || (force_class == OBJ_WEAPONS || force_class == OBJ_ARMOUR - || force_class == OBJ_MISSILES) - && force_type != OBJ_RANDOM); + || force_type != OBJ_RANDOM + && (force_class == OBJ_WEAPONS || force_class == OBJ_ARMOUR + || force_class == OBJ_MISSILES)); // Find an empty slot for the item (with culling if required). int p = get_item_slot(10); diff --git a/crawl-ref/source/randart.cc b/crawl-ref/source/randart.cc index 482d732e12..0ba286f991 100644 --- a/crawl-ref/source/randart.cc +++ b/crawl-ref/source/randart.cc @@ -1153,7 +1153,7 @@ static bool _init_randart_book(item_def &book) ASSERT(book.plus != 0); god_type god; - bool redo = !origin_is_god_gift(book, &god) || god != GOD_XOM; + bool redo = (!origin_is_god_gift(book, &god) || god != GOD_XOM); // Plus and plus2 contain paramaters to make_book_foo_randart() // which might get changed after the book has been made into a @@ -2110,7 +2110,7 @@ bool make_item_randart( item_def &item ) } } - // This already is a randart. + // This item already is a randart. if (item.flags & ISFLAG_RANDART) return (true); diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index d3bc89da58..2ca8d4d9b4 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -1987,7 +1987,7 @@ static void _do_god_gift(bool prayed_for) } if (gift != NUM_BOOKS - && !(grid_destroys_items(grd(you.pos())))) + && !grid_destroys_items(grd(you.pos()))) { if (gift == OBJ_RANDOM) success = acquirement(OBJ_BOOKS, you.religion); diff --git a/crawl-ref/source/spl-book.cc b/crawl-ref/source/spl-book.cc index dad9800e5d..b8ecd5d7c0 100644 --- a/crawl-ref/source/spl-book.cc +++ b/crawl-ref/source/spl-book.cc @@ -1137,8 +1137,8 @@ void mark_had_book(const item_def &book) int level = book.plus; ASSERT(level > 0 && level <= 9); - if (origin_is_acquirement(book) || - origin_is_god_gift(book, &god) && god == GOD_SIF_MUNA) + if (origin_is_acquirement(book) + || origin_is_god_gift(book, &god) && god == GOD_SIF_MUNA) { you.attribute[ATTR_RND_LVL_BOOKS] |= (1 << level); } @@ -1191,6 +1191,7 @@ int read_book( item_def &book, read_book_action_type action ) // from memorise as well. set_ident_flags( book, ISFLAG_KNOW_TYPE ); + set_ident_flags( book, ISFLAG_IDENT_MASK); return (keyin); } @@ -1714,13 +1715,11 @@ static bool _compare_spells(spell_type a, spell_type b) return (strcmp(spell_title(a), spell_title(b))); } -static bool _is_memorised(spell_type spell) +bool is_memorised(spell_type spell) { for (int i = 0; i < 25; i++) - { if (you.spells[i] == spell) return (true); - } return (false); } @@ -1802,8 +1801,7 @@ static void _get_spell_list(std::vector &spell_list, int level, } -bool make_book_level_randart(item_def &book, int level, - int num_spells) +bool make_book_level_randart(item_def &book, int level, int num_spells) { ASSERT(book.base_type == OBJ_BOOKS); @@ -1815,7 +1813,7 @@ bool make_book_level_randart(item_def &book, int level, if (!is_random_artefact(book)) { - // Stuf parameters into book.plus and book.plus2, then call + // Stuff parameters into book.plus and book.plus2, then call // make_item_randart(), which will call us back. if (level == -1) { @@ -1922,7 +1920,7 @@ bool make_book_level_randart(item_def &book, int level, spell_type spell = spell_list[spell_pos]; ASSERT(spell != SPELL_NO_SPELL); - if (avoid_memorised[spell_pos] && _is_memorised(spell)) + if (avoid_memorised[spell_pos] && is_memorised(spell)) { // Only once. avoid_memorised[spell_pos] = false; @@ -2044,12 +2042,14 @@ static bool _get_weighted_discs(bool completely_random, god_type god, } } - do { + do + { disc1 = ok_discs[choose_random_weighted(skill_weights, skill_weights + num_discs)]; disc2 = ok_discs[choose_random_weighted(apt_weights, apt_weights + num_discs)]; - } while(disciplines_conflict(disc1, disc2)); + } + while(disciplines_conflict(disc1, disc2)); return (true); } @@ -2093,7 +2093,7 @@ static void _get_weighted_spells(bool completely_random, god_type god, int c = 1; if (!you.seen_spell[spell]) c = 4; - else if (!_is_memorised(spell)) + else if (!is_memorised(spell)) c = 2; int total_skill = 0; @@ -2124,7 +2124,7 @@ static void _get_weighted_spells(bool completely_random, god_type god, int book_pos = 0; int spells_left = spell_list.size(); - while(book_pos < num_spells && max_levels > 0 && spells_left > 0) + while (book_pos < num_spells && max_levels > 0 && spells_left > 0) { spell_type spell = (spell_type) choose_random_weighted(spell_weights, diff --git a/crawl-ref/source/spl-book.h b/crawl-ref/source/spl-book.h index 41abf8a158..b43aeddf53 100644 --- a/crawl-ref/source/spl-book.h +++ b/crawl-ref/source/spl-book.h @@ -59,6 +59,7 @@ spell_type which_spell_in_book(int sbook_type, int spl); // returns amount practised (or -1 for abort) int staff_spell( int zap_device_2 ); +bool is_memorised(spell_type spell); bool undead_cannot_memorise(spell_type spell, char being); -- cgit v1.2.3-54-g00ecf