seen.
Implemented fixed-level randart spell books, which is all randart spellbooks as of now. All my attempts at sorting the spell list so that spells with the same schools group together have utterly failed.
Got rid of the hackish "non-monster origin is stored in item.orig_monnum as (-origin - 2)" logic, replaced with the slightly less hackish "-origin". Added the two enumerations IT_SRC_START and IT_SRC_SHOP to do it. Also, origin_is_god_gift() and origin_is_acquirement() can retrieve the god/source of the item so that you don't have to do the negation and typecasting yourself.
Added some new spell flags:
SPFLAG_BATTLE for non-conjuration spells which are still combat/battle related (branding spells and single school attack spells like "Pain"),
SPFLAG_CARD for spells which are card-type effects which don't show up in ordinary spellbooks (Tomb of Doroklohe and (I assume) Disintigrate)
SPFLAG_TESTING for spells which are only used for testing (Debugging Ray)
SPFLAG_DEVEL for spells that are still under development (Crush, Disrupt, and Detect Magic).
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7742 c06c8d41-db1a-0410-9941-cceddc491573
FWNNTOEERPUKXPE4OC52UABFZLKIU3O5GRNNLDK4QI4HR2IOU36QC N3BAL7TTPTEKB2UOP2YWD7HOBR3735RPRECJOPC647TVFSRFYHNAC 3UTZR7L3VTFUCGNE7HROHQDVGUVI2QI64BNL7SDC5AWHVW2FD6EQC 5VZWOTCDNCSSWVT2ILO6XCR75LBGFREHOR2WC2CJ4WE7NHVPDEMQC EYYWIH7377INOKPRABJUATNQ2YWKLOVHZKQIY55POX2YXVMDDWAAC RIGGVFYNCRFDUUCMIAN7SDEOUL4VMMZI6OYXZW72BVNI4WXJQXWQC 46MRRHVYJ3BS74R2BEVUWEWJCI4FCRBSLZ3NWMQCE6FUCNE5P73QC JJVROJMJVKS7VN5HJNB4ZNCG7Y6EMHJQZR3MDN2VZCFTZC73HOZQC JYEEOUYQ7ZPKOGWUV7VCORBVSOLF2UCBFBH3TR75RGOSS6PNKYUAC KFULGQQOHWUTXOM3BXCCYPGGVGGY4Z6265XUFRCBPNLTZAEHJZSQC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC CHO4U5JC3RNTLXVIDXXJYZMOBZJ4VXW2GVJWDOTBRKK3AJ36LDLQC 7BREK7U6OWZ6YU3JDSJSH4CMNNULDYABCKCAUHGZIUJZBIRJS5WQC NQMXQ6OQVUSC7Y7F7IL252QW4A5JED224EECNHWAM4ZZYVNY745AC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC DDU4A3JGN5IUIPP5IASOODKPR2WBHSDSV4FITZ6HNXNSXXQACWAQC 7QVPQYSZJODY6Z7TW6ZHRCOVS2FBPTAU7SREICKO5LMH4IB3SGVQC KHVK7HH7OIYOBZY52WQGGLC2O4SXTWQS2XAHNJZZ7JZ3QTOUTLNAC SVY2PTCLXR3KNPQAWXVXTTGCC5DR334HOAKHYO3VDDRWM2BWMALAC YYC7LBS5AYZQNLGKCYSFECSA6M6CHR7SRV2GTY7DON6XZKZJ3MJQC PMODADA7C3BWOFCPU37626DKMWENG6FAR5I6TOIQU5OBJBUJTSAQC ZGUJWUFJ4NFFJ6PGXLFGQWCWBCZHPWGWI44NJHJEVPRG5L36PADQC JCWJWGMQIKQGSSFJUQRKNIWW3HBOJSHYDTOPPE5BWOJTIJTDYUTAC IJ4GH6RYJYT4METQIJYT3IITJEHZ4IAF4WBPA5RH6RSYX4KHXMYAC 4NBPZKMZBKB3QYX4FFUAKDXQS43NJCBDLMHKDJFVXHQLX4MQDINAC BSI5DB3LVY42ZHOS46X2CAPPVOSOTTQWFGLTMAKRFTROI5BQWFDQC SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC E6JXIMRH2TX5WHZ6BT2QZ3EANM3PWCHCVYC4XWRJGRBDSP42X2RAC 4GYZYBY7FFORRNPIEFTV4ZM2C7Z6D2KTQOM537ZCC2YBXT2TNSHAC V4DWL5WBO2JCODVS5QQNWXDH4DAYZN3D5V3UDCHM2KKOMADOTEDQC WZNB427K3EUNV3FMVXLQTM4UIHER4FIKQXWLUUXRNQC3OQ33VQYAC 3DQXSE4YGFBBDUWK4YEOFWW4UPWILWELFSLP37SL6BERGAZJC5YAC NDKS43E4XVAU3FDY276OF5JW7E5SF6F5EJD2XLV5JLKZ5W6N554QC V4F3SDV2H4HBH6G6W5M3REN3BDSSE4IDF2RNM7PJMKRW3IDJ7PNAC XI7X6SNTHG67D4NQWM75HWB6TVRXVFDPGNSQLTXN6JAZBZIVZXIQC LY7DLLD7IKL6ZQPVROLDJ46XRM5CMAAEBRFDKJ4M53CPC5GFCGSQC EJKHYV2Z6UPRVYUAL4WRW33GBNHYBFPMPA57HMBX2LQKXHIUO5VQC SRQJVKQVUY7QGCEBA2VQTWEJ7ADIUSY7L46HJQSQNM5DXYRRH5KAC 6FYEYTS5NRD5JAFIBSFHPBCQOKZBMWPWEI26USCI6OBUDGLJQKAAC LDBTCT5WIPLJPZWXS2RUQ26QKISCUUTLO77M464WOE6VSYSNPKYAC KU5FY6KSLTGH44KEZT4SFANRKCTWCQC7VABCMNYJRZNJSYSOXAKQC ZMYKMHWEU26FOUTD26Q4GTAZMI6RNO3K6NHQ2VGTESE3E73GQVCQC 5UXWZHJ23JEPCI7QAF3R7JWV37LHH7I2FEWCFD4JPC5HC7YQQJ2AC 6LT6USGJOTDMRJGXLAN2NSZXK2GKWEXDKKUV6SVV7ZC6WI6EKMDQC VIFZ6DO6GWJGYMXJZKFZ2JYNPHNE74H3OFAOCPISQG7M7A4LCOHAC 6F2J5HCYTKKIGZD4O6FETFA4WOUI4A5VHPVD4U37JPLX6SYX6DQQC FU663V7RFZNSMG5P2E7TZJZWSGXWLCCFXSVGH4Z222FIJTH4R3KAC CI2RMLJLIAZMEGNN6LJN6PSHXHLPG7PXFIDYRGFPVMDPJ2R4S4NQC MV5USMLTBKVRWBAD67UFJ2BS4Y5HEOMYASRSB44DS24BBMRP75RQC O6ZMFKDI3XO2SWPNEYHIPYFDWJR4TVDP5BAATK6LVCVETQID6E7AC I2B33Z7NZGC33AMDSSK446AZZYWKPHWLAGULVHKKZU4MVB4BNJOAC BMKL2AB2HBBBVAHWDYXPYZHSCO345QWOQHFSICFRN5BCYZ3UEK3AC 45CXZWWXI7SGKLHVSRP2U6KNXJBT2XADNLIIHQQJYL2E6QWNURKQC 2DORUQ4B574MDOOMRYWGU5I72AKHMCSTZ6B3VSHQBUQOZYHRC7FAC JVSCP4FTW2G57C6YD5HZOZXTODGZH7TR75JQGFJBEPX3LCZH236QC I7QLYOTE6DLQZM7YWUWYLKHRJRB2A3STQ42ALSRGQICEWKD2QTEQC ZIFFVCQ72K35WGIUMZYN3KOXIUXF2CNXWKG6ZWEZ6LT3NSF3XOQAC PAYI4UTJCR3XZSFOX5L35EURHRXQ6STO4Z7AQ3525QPNL3QYLNBAC VCG3BRIYRTNNWYC3LOXD6KFGXOX37HAFW2HNV7WXVG2V7EUHLDZQC KNO4TZR76DMOYJCF24PSVQW7FUZOTMOJTL7I7J74SM4IHOGDX6TAC HNPSSHGZFQ3E2I6X6VTKZ3WBBM2G25P2D7SIL2SZYKV2CCEA2ADAC 36DYXIWAQTBOCZBCUPYWDKAXVWDU3TRMSM3OCQZGGMWE2KPERJMAC Y2NYY7HWFZ2LQDK3ACSLGS37F2J2IJ5LRGCIMZYXLEOSVPD3A4DAC YFIVTYI7PMVAXV23DUPXPAQNEY3YSFIXQGSN32I3WVHMMD5XS5DQC CIPVRZGLOZHCERK6YPOBV3P2E4IAB4H6D5EHLRQE2O5E4P4VCBUAC int spell_skill2type(unsigned int skill){switch (skill){case SK_CONJURATIONS: return (SPTYP_CONJURATION);case SK_ENCHANTMENTS: return (SPTYP_ENCHANTMENT);case SK_FIRE_MAGIC: return (SPTYP_FIRE);case SK_ICE_MAGIC: return (SPTYP_ICE);case SK_TRANSMIGRATION: return (SPTYP_TRANSMIGRATION);case SK_NECROMANCY: return (SPTYP_NECROMANCY);case SK_SUMMONINGS: return (SPTYP_SUMMONING);case SK_DIVINATIONS: return (SPTYP_DIVINATION);case SK_TRANSLOCATIONS: return (SPTYP_TRANSLOCATION);case SK_POISON_MAGIC: return (SPTYP_POISON);case SK_EARTH_MAGIC: return (SPTYP_EARTH);case SK_AIR_MAGIC: return (SPTYP_AIR);default:case SPTYP_HOLY:#ifdef DEBUG_DIAGNOSTICSmprf(MSGCH_DIAGNOSTICS, "spell_skill2type: called with skill %u",spelltype );#endifreturn (-1);}} // end spell_type2skill()
SPFLAG_NONE = 0x0000,SPFLAG_DIR_OR_TARGET = 0x0001, // use DIR_NONE targetingSPFLAG_TARGET = 0x0002, // use DIR_TARGET targetingSPFLAG_GRID = 0x0004, // use DIR_GRID targetingSPFLAG_DIR = 0x0008, // use DIR_DIR targetingSPFLAG_TARGETING_MASK = 0x000f, // used to test for targetingSPFLAG_HELPFUL = 0x0010, // TARG_FRIENDS usedSPFLAG_NEUTRAL = 0x0020, // TARG_ANY usedSPFLAG_NOT_SELF = 0x0040, // aborts on isMeSPFLAG_UNHOLY = 0x0080, // counts at "unholy"SPFLAG_MAPPING = 0x0100, // a mapping spell of some kindSPFLAG_ESCAPE = 0x0200, // useful for running awaySPFLAG_RECOVERY = 0x0400, // healing or recovery spellSPFLAG_AREA = 0x0800, // area affectSPFLAG_MONSTER = 0x1000 // monster-only spell
SPFLAG_NONE = 0x00000,SPFLAG_DIR_OR_TARGET = 0x00001, // use DIR_NONE targetingSPFLAG_TARGET = 0x00002, // use DIR_TARGET targetingSPFLAG_GRID = 0x00004, // use DIR_GRID targetingSPFLAG_DIR = 0x00008, // use DIR_DIR targetingSPFLAG_TARGETING_MASK = 0x0000f, // used to test for targetingSPFLAG_HELPFUL = 0x00010, // TARG_FRIENDS usedSPFLAG_NEUTRAL = 0x00020, // TARG_ANY usedSPFLAG_NOT_SELF = 0x00040, // aborts on isMeSPFLAG_UNHOLY = 0x00080, // counts at "unholy"SPFLAG_MAPPING = 0x00100, // a mapping spell of some kindSPFLAG_ESCAPE = 0x00200, // useful for running awaySPFLAG_RECOVERY = 0x00400, // healing or recovery spellSPFLAG_AREA = 0x00800, // area affectSPFLAG_BATTLE = 0x01000, // a non-Conjuration spell that// is still a battle spellSPFLAG_CARD = 0x02000, // a card effect spellSPFLAG_MONSTER = 0x04000, // monster-only spellSPFLAG_TESTING = 0x08000, // a testing/debugging spellSPFLAG_DEVEL = 0x10000 // a spell under development
void mark_had_book(const item_def &book){ASSERT(book.base_type == OBJ_BOOKS);if (book.book_number() == BOOK_MANUAL|| book.book_number() == BOOK_DESTRUCTION){return;}for (int i = 0; i < SPELLBOOK_SIZE; i++){spell_type stype = which_spell_in_book(book, i);if (stype == SPELL_NO_SPELL)continue;you.seen_spell[stype] = true;}
}static bool _compare_spells(spell_type a, spell_type b){if (a == SPELL_NO_SPELL && b == SPELL_NO_SPELL)return (false);else if (a != SPELL_NO_SPELL && b == SPELL_NO_SPELL)return (true);else if (a == SPELL_NO_SPELL && b != SPELL_NO_SPELL)return (false);int level_a = spell_difficulty(a);int level_b = spell_difficulty(b);if (level_a != level_b)return (level_a < level_b);unsigned int schools_a = get_spell_disciplines(a);unsigned int schools_b = get_spell_disciplines(b);if (schools_a != schools_b && schools_a != 0 && schools_b != 0){const char* a_type = NULL;const char* b_type = NULL;// Find lowest/earliest school for each spell.for (int i = 0; i <= SPTYP_LAST_EXPONENT; i++){int mask = 1 << i;if (a_type == NULL && (schools_a & mask))a_type = spelltype_name(mask);if (b_type == NULL && (schools_b & mask))b_type = spelltype_name(mask);}ASSERT(a_type != NULL && b_type != NULL);return (strcmp(a_type, b_type));}return (strcmp(spell_title(a), spell_title(b)));}static bool _is_memorized(spell_type spell){for (int i = 0; i < 25; i++){if (you.spells[i] == spell)return (true);}return (false);}bool make_book_level_randart(item_def &book, int level,int num_spells){ASSERT(book.base_type == OBJ_BOOKS);ASSERT(book.book_number() != BOOK_MANUAL&& book.book_number() != BOOK_DESTRUCTION);ASSERT(is_random_artefact(book));ASSERT(!book.props.exists(SPELL_LIST_KEY));god_type god;(void) origin_is_god_gift(book, &god);const bool avoid_uncastable = (god != GOD_NO_GOD && god != GOD_XOM)|| origin_is_acquirement(book);const bool track_levels_had = origin_is_acquirement(book)|| god == GOD_SIF_MUNA;if (level == -1){int max_level =avoid_uncastable ? std::min(9, you.get_experience_level()): 9;level = random_range(1, max_level);// Give a book of a level not seen before, preferably one with// spells of a low enough level for the player to cast, or the// lowest aviable level if all levels which the player can cast// have already been given.if (track_levels_had){unsigned int seen_levels = you.attribute[ATTR_RND_LVL_BOOKS];std::vector<int> 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())];}}ASSERT(level > 0 && level <= 9);if (num_spells == -1)num_spells = SPELLBOOK_SIZE;ASSERT(num_spells > 0 && num_spells <= SPELLBOOK_SIZE);int god_discard = 0;int uncastable_discard = 0;std::vector<spell_type> spell_list;for (int i = 0; i < NUM_SPELLS; i++){const spell_type spell = (spell_type) i;if (!is_valid_spell(spell))continue;if (spell_difficulty(spell) != level)continue;const unsigned int flags = get_spell_flags(spell);const unsigned int schools = get_spell_disciplines(spell);// Don't include schoolless spells, like Smiting.if (schools == 0)continue;// Holy spells don't show up in books.if (schools & SPTYP_HOLY)continue;if (flags & (SPFLAG_MONSTER | SPFLAG_CARD | SPFLAG_TESTING))continue;// Only wizards gets spells still under development.if (flags & SPFLAG_DEVEL){#ifdef WIZARDif (!you.wizard)continue;#elsecontinue;#endif}if (avoid_uncastable && undead_cannot_memorise(spell, you.is_undead)){uncastable_discard++;continue;}if (god_dislikes_spell_type(spell, god)){god_discard++;continue;}// Passed all tests.spell_list.push_back(spell);}if (spell_list.empty()){char buf[80];if (god_discard > 0 && uncastable_discard == 0)sprintf(buf, "%s disliked all level %d spells",god_name(god).c_str(), level);else if (god_discard == 0 && uncastable_discard > 0)sprintf(buf, "No level %d spells can be cast by you", level);else if (god_discard > 0 && uncastable_discard > 0)sprintf(buf, "All level %d spells are either disliked by %s ""or cannot be cast by you.",level, god_name(god).c_str());elsesprintf(buf, "No level %d spells?!?!?!", level);mprf(MSGCH_ERROR, "Could not create fixed level randart spellbook: %s",buf);return (false);}random_shuffle(spell_list.begin(), spell_list.end());if (num_spells > (int) spell_list.size()){num_spells = spell_list.size();#if DEBUG || DEBUG_DIAGNOSTICS// Not many level 8 or 9 spellsif (level < 8){mprf(MSGCH_WARN, "More spells requested for fixed level (%d) ""randart spellbook than there are valid spells.",level);mprf(MSGCH_WARN, "Discarded %d spells due to being uncastable and ""%d spells due to being disliked by %s.",uncastable_discard, god_discard, god_name(god).c_str());}#endif}std::vector<bool> spell_used(spell_list.size(), false);std::vector<bool> avoid_memorised(spell_list.size(), true);spell_type chosen_spells[SPELLBOOK_SIZE];for (int i = 0; i < SPELLBOOK_SIZE; i++){chosen_spells[i] = SPELL_NO_SPELL;}int book_pos = 0;while (book_pos < num_spells){int spell_pos = random2(spell_list.size());if (spell_used[spell_pos])continue;spell_type spell = spell_list[spell_pos];ASSERT(spell != SPELL_NO_SPELL);if (avoid_memorised[spell_pos] && _is_memorized(spell)){// Only once.avoid_memorised[spell_pos] = false;continue;}spell_used[spell_pos] = true;chosen_spells[book_pos++] = spell;}std::sort(chosen_spells, chosen_spells + SPELLBOOK_SIZE,_compare_spells);ASSERT(chosen_spells[0] != SPELL_NO_SPELL);CrawlHashTable &props = book.props;if (!props.exists( SPELL_LIST_KEY ))props[SPELL_LIST_KEY].new_vector(SV_LONG).resize(SPELLBOOK_SIZE);CrawlVector &spell_vec = props[SPELL_LIST_KEY];spell_vec.set_max_size(SPELLBOOK_SIZE);for (int i = 0; i < SPELLBOOK_SIZE; i++)spell_vec[i] = (long) chosen_spells[i];if (track_levels_had)you.attribute[ATTR_RND_LVL_BOOKS] |= (1 << level);return (true);
return (true);}return (false);}bool god_dislikes_spell_type(spell_type spell, god_type god){if (god == GOD_NO_GOD)return (false);unsigned int flags = get_spell_flags(spell);unsigned int schools = get_spell_disciplines(spell);if (is_good_god(god)){if ((flags & SPFLAG_UNHOLY) || (schools & SPTYP_NECROMANCY))return (true);}switch(god){case GOD_ZIN:if (spell == SPELL_POLYMORPH_OTHER || spell == SPELL_ALTER_SELF)return (true);break;case GOD_SHINING_ONE:// TSO dislikes using poison, but is fine with curing it, resisting// it or destroying it.if ((schools & SPTYP_POISON) && spell != SPELL_CURE_POISON_I&& spell != SPELL_CURE_POISON_II && spell != SPELL_RESIST_POISON&& spell != SPELL_IGNITE_POISON){return (true);}// He probably also wouldn't like spells which would put enemies// into a state where attacking them would be unchivalrous.if (spell == SPELL_CAUSE_FEAR || spell == SPELL_PARALYSE|| spell == SPELL_CONFUSE || spell == SPELL_MASS_CONFUSION|| spell == SPELL_SLEEP || spell == SPELL_MASS_SLEEP){return (true);}break;case GOD_YREDELEMNUL:if (schools & SPTYP_HOLY)return (true);break;case GOD_XOM:// Ideally, Xom would only like spells which have a random effect,// are risky to use, or would otherwise amuse him, but that would// be a really small number of spells.// Xom would probably find these extra boring.if (flags & (SPFLAG_HELPFUL | SPFLAG_NEUTRAL | SPFLAG_ESCAPE| SPFLAG_RECOVERY | SPFLAG_MAPPING)){
}// Things are more fun for Xom the less the player knows in// advance.if (schools & SPTYP_DIVINATION)return (true);// Holy spells are probably too useful for Xom to find them// interesting.if (schools & SPTYP_HOLY)return (true);break;case GOD_ELYVILON:// A peaceful god of healing wouldn't like combat spells.if (schools & SPTYP_CONJURATION)return (true);// Also doesn't like battle spells of the non-conjuration type.if (flags & SPFLAG_BATTLE)return true;break;default:break;
switch(god){case GOD_SHINING_ONE:return (school == SPTYP_POISON);case GOD_YREDELEMNUL:return (school == SPTYP_HOLY);case GOD_XOM:return (school == SPTYP_DIVINATION || school == SPTYP_HOLY);case GOD_ELYVILON:return (school == SPTYP_CONJURATION);default:break;}return (false);}
}static god_type _gift_from_god(const item_def item){// maybe god gift?god_type god_gift = GOD_NO_GOD;if (item.orig_monnum < 0){int help = -item.orig_monnum - 2;if (help > GOD_NO_GOD && help < NUM_GODS)god_gift = static_cast<god_type>(help);}return god_gift;
return (spell_difficulty(a) < spell_difficulty(b));}static void _init_randart_book(item_def &book){spell_type spells[SPELLBOOK_SIZE];int spell_count = 0;while(spell_count < SPELLBOOK_SIZE){spell_type spl = static_cast<spell_type>(random2(NUM_SPELLS));if (!is_valid_spell(spl))continue;// Skip monster only spells.if (get_spell_flags(spl) & SPFLAG_MONSTER)continue;// Holy spells don't show up in books.if (spell_typematch(spl, SPTYP_HOLY))continue;// Don't include schoolless spells, like Smiting.if (get_spell_disciplines(spl) == 0)continue;// This spell passes all of the other checks.if (spl == SPELL_DEBUGGING_RAY)continue;// No duplicate spells.bool present = false;for (int i = 0; i < spell_count; i++)if (spells[i] == spl){present = true;break;}if (present)continue;spells[spell_count++] = spl;}std::sort(spells, spells + SPELLBOOK_SIZE, _compare_spell_dificulties);CrawlHashTable &props = book.props;if (!props.exists( SPELL_LIST_KEY ))props[SPELL_LIST_KEY].new_vector(SV_LONG).resize(SPELLBOOK_SIZE);CrawlVector &spell_vec = props[SPELL_LIST_KEY];spell_vec.set_max_size(SPELLBOOK_SIZE);for (int i = 0; i < SPELLBOOK_SIZE; i++)spell_vec[i] = (long) spells[i];
return make_book_level_randart(book, -1, 8);
_init_randart_properties(item);
if (!_init_randart_properties(item)){// Something went wrong that no amount of changing// item.special will fix.item.special = 0;item.props.erase(RANDART_PROPS_KEY);item.props.erase(KNOWN_PROPS_KEY);item.flags &= ~ISFLAG_RANDART;return (false);}
return (spell_by_name(key) == SPELL_NO_SPELL);
spell_type spell = spell_by_name(key);if (spell == SPELL_NO_SPELL)return (true);if (get_spell_flags(spell) & (SPFLAG_MONSTER | SPFLAG_TESTING| SPFLAG_DEVEL)){#ifdef WIZARDreturn (!you.wizard);#elsereturn (true);#endif}return (false);
}}// Extra info on this item wasn't found anywhere else.static void _append_non_item(std::string &desc, std::string key){spell_type type = spell_by_name(key, true);if (type == SPELL_NO_SPELL)return;unsigned int flags = get_spell_flags(type);if (flags & SPFLAG_DEVEL)desc += "$This spell is still being developped, and is only avaible ""via the &Z wizard command.";else if (flags & SPFLAG_TESTING)desc += "$This is a testing spell, only avaible via the ""&Z wizard command.";else if (flags & SPFLAG_MONSTER)desc += "$This is a monster-only spell, only avaible via the ""&Z wizard command.";else if (flags & SPFLAG_CARD)desc += "$This is a card-effect spell, unavailable in ordinary ""spellbooks.";elsedesc += "$Odd, this spell can't be found anywhere. Please ""file a bug report.";#ifdef WIZARDif (!you.wizard)#elseif (true)#endif{if (flags & (SPFLAG_TESTING | SPFLAG_MONSTER | SPFLAG_DEVEL))desc += "$$You aren't in wizard mode, so you shouldn't be ""seeing this entry. Please file a bug report.";
if (!make_item_randart( you.inv[i] ))
if (is_random_artefact(item)){if (!yesno("Is already a randart; wipe and re-use?")){canned_msg( MSG_OK );// If equipped, re-apply benefits.if (j != NUM_EQUIP)use_randart( i );return;}item.special = 0;item.flags &= ~ISFLAG_RANDART;item.props.clear();}if (!make_item_randart( item ))