3 * @brief Misc functions.
23 #include "dgn-overview.h"
25 #include "env.h" // LSTATE_STILL_WINDS
26 #include "errors.h" // sysfail
28 #include "god-passive.h" // passive_t::want_curses, no_haste
30 #include "item-prop.h"
31 #include "item-status-flag-type.h"
34 #include "level-state-type.h"
48 #include "stringutil.h"
49 #include "tag-version.h"
51 #include "transform.h"
56 static bool _is_consonant(char let);
57 static char _random_vowel();
58 static char _random_cons();
59 static string _random_consonant_set(size_t seed);
61 static void _maybe_identify_pack_item()
63 for (auto &item : you.inv)
64 if (item.defined() && !get_ident_type(item))
65 maybe_identify_base_type(item);
68 // quant_name is useful since it prints out a different number of items
69 // than the item actually contains.
70 string quant_name(const item_def &item, int quant,
71 description_level_type des, bool terse)
73 // item_name now requires a "real" item, so we'll mangle a tmp
77 return tmp.name(des, terse);
80 static const char* _interesting_origin(const item_def &item)
82 if (origin_as_god_gift(item) != GOD_NO_GOD)
85 if (item.orig_monnum == MONS_DONALD && get_equip_desc(item)
86 && item.is_type(OBJ_ARMOUR, ARM_KITE_SHIELD))
95 * What inscription should be appended to the given item's name?
97 static string _item_inscription(const item_def &item)
99 vector<string> insparts;
101 if (const char *orig = _interesting_origin(item))
103 if (Options.show_god_gift == MB_TRUE
104 || Options.show_god_gift == MB_MAYBE && !fully_identified(item))
106 insparts.push_back(orig);
110 if (is_artefact(item))
112 const string part = artefact_inscription(item);
114 insparts.push_back(part);
117 if (!item.inscription.empty())
118 insparts.push_back(item.inscription);
120 if (insparts.empty())
123 return make_stringf(" {%s}",
124 comma_separated_line(begin(insparts),
129 string item_def::name(description_level_type descrip, bool terse, bool ident,
130 bool with_inscription, bool quantity_in_words,
131 iflags_t ignore_flags) const
133 if (crawl_state.game_is_arena())
135 ignore_flags |= ISFLAG_KNOW_PLUSES | ISFLAG_KNOW_CURSE
136 | ISFLAG_COSMETIC_MASK;
139 if (descrip == DESC_NONE)
144 const string auxname = name_aux(descrip, terse, ident, with_inscription,
147 const bool startvowel = is_vowel(auxname[0]);
149 if (descrip == DESC_INVENTORY_EQUIP || descrip == DESC_INVENTORY)
151 if (in_inventory(*this)) // actually in inventory
153 buff << index_to_letter(link);
163 if (base_type == OBJ_BOOKS && (ident || item_type_known(*this))
164 && book_has_title(*this))
166 if (descrip != DESC_DBNAME)
167 descrip = DESC_PLAIN;
170 if (terse && descrip != DESC_DBNAME)
171 descrip = DESC_PLAIN;
173 monster_flags_t corpse_flags;
175 // no "a dragon scales"
176 const bool always_plural = armour_is_hide(*this)
177 && sub_type != ARM_TROLL_LEATHER_ARMOUR;
179 if ((base_type == OBJ_CORPSES && is_named_corpse(*this)
180 && !(((corpse_flags.flags = props[CORPSE_NAME_TYPE_KEY].get_int64())
182 && !(corpse_flags & MF_NAME_DEFINITE))
183 && !(corpse_flags & MF_NAME_SUFFIX)
184 && !starts_with(get_corpse_name(*this), "shaped "))
185 || item_is_orb(*this) || item_is_horn_of_geryon(*this)
186 || (ident || item_type_known(*this)) && is_artefact(*this)
187 && special != UNRAND_OCTOPUS_KING_RING)
189 // Artefacts always get "the" unless we just want the plain name.
201 else if (quantity > 1 || always_plural)
205 case DESC_THE: buff << "the "; break;
206 case DESC_YOUR: buff << "your "; break;
207 case DESC_ITS: buff << "its "; break;
209 case DESC_INVENTORY_EQUIP:
216 if (descrip != DESC_BASENAME && descrip != DESC_QUALNAME
217 && descrip != DESC_DBNAME && !always_plural)
219 if (quantity_in_words)
220 buff << number_in_words(quantity) << " ";
222 buff << quantity << " ";
229 case DESC_THE: buff << "the "; break;
230 case DESC_YOUR: buff << "your "; break;
231 case DESC_ITS: buff << "its "; break;
233 case DESC_INVENTORY_EQUIP:
235 buff << (startvowel ? "an " : "a "); break;
244 if (descrip == DESC_INVENTORY_EQUIP)
246 equipment_type eq = item_equip_slot(*this);
256 if (is_weapon(*this))
258 else if (you.species == SP_FELID)
259 buff << " (in mouth)";
261 buff << " (in " << you.hand_name(false) << ")";
276 buff << ((eq == EQ_LEFT_RING || eq == EQ_RING_ONE)
279 buff << you.hand_name(false);
283 if (you.species == SP_OCTOPODE && form_keeps_mutations())
284 buff << " (around mantle)";
286 buff << " (around neck)";
294 buff << " (on tentacle)";
297 buff << " (on amulet)";
300 die("Item in an invalid slot");
304 else if (you.launcher_action.item_is_quivered(*this))
305 buff << " (quivered ammo)";
306 else if (you.quiver_action.item_is_quivered(*this))
307 buff << " (quivered)";
310 if (descrip != DESC_BASENAME && descrip != DESC_DBNAME && with_inscription)
311 buff << _item_inscription(*this);
313 // These didn't have "cursed " prepended; add them here so that
314 // it comes after the inscription.
315 if (terse && descrip != DESC_DBNAME && descrip != DESC_BASENAME
316 && descrip != DESC_QUALNAME
317 && is_artefact(*this) && cursed()
318 && !testbits(ignore_flags, ISFLAG_KNOW_CURSE)
319 && (ident || item_ident(*this, ISFLAG_KNOW_CURSE)))
327 static bool _missile_brand_is_prefix(special_missile_type brand)
335 case SPMSL_EXPLODING:
336 #if TAG_MAJOR_VERSION == 34
346 static bool _missile_brand_is_postfix(special_missile_type brand)
348 return brand != SPMSL_NORMAL && !_missile_brand_is_prefix(brand);
351 const char* missile_brand_name(const item_def &item, mbn_type t)
353 const special_missile_type brand
354 = static_cast<special_missile_type>(item.brand);
357 #if TAG_MAJOR_VERSION == 34
364 return t == MBN_NAME ? "poisoned" : "poison";
366 return t == MBN_NAME ? "curare-tipped" : "curare";
367 #if TAG_MAJOR_VERSION == 34
368 case SPMSL_EXPLODING:
369 return t == MBN_TERSE ? "explode" : "exploding";
372 case SPMSL_RETURNING:
373 return t == MBN_TERSE ? "return" : "returning";
374 case SPMSL_PENETRATION:
375 return t == MBN_TERSE ? "penet" : "penetration";
379 #if TAG_MAJOR_VERSION == 34
380 case SPMSL_PARALYSIS:
383 return t == MBN_TERSE ? "slow" : "slowing";
385 return t == MBN_TERSE ? "sleep" : "sleeping";
386 case SPMSL_CONFUSION:
387 return t == MBN_TERSE ? "conf" : "confusion";
389 return t == MBN_TERSE ? "sick" : "sickness";
392 return t == MBN_NAME ? "datura-tipped" : "datura";
395 case SPMSL_DISPERSAL:
396 return t == MBN_TERSE ? "disperse" : "dispersal";
398 return t == MBN_NAME ? "atropa-tipped" : "atropa";
402 return t == MBN_TERSE ? "buggy" : "bugginess";
406 static const char *weapon_brands_terse[] =
408 "", "flame", "freeze", "holy", "elec",
409 #if TAG_MAJOR_VERSION == 34
410 "obsolete", "obsolete",
412 "venom", "protect", "drain", "speed", "vorpal",
413 #if TAG_MAJOR_VERSION == 34
414 "obsolete", "obsolete",
416 "vamp", "pain", "antimagic", "distort",
417 #if TAG_MAJOR_VERSION == 34
418 "obsolete", "obsolete",
421 #if TAG_MAJOR_VERSION == 34
424 "penet", "reap", "spect", "vorpal", "acid",
425 #if TAG_MAJOR_VERSION > 34
431 static const char *weapon_brands_verbose[] =
433 "", "flaming", "freezing", "holy wrath", "electrocution",
434 #if TAG_MAJOR_VERSION == 34
435 "orc slaying", "dragon slaying",
437 "venom", "protection", "draining", "speed", "vorpality",
438 #if TAG_MAJOR_VERSION == 34
441 "vampirism", "pain", "antimagic", "distortion",
442 #if TAG_MAJOR_VERSION == 34
443 "reaching", "returning",
446 #if TAG_MAJOR_VERSION == 34
447 "evasion", "confusion",
449 "penetration", "reaping", "spectralizing", "vorpal", "acid",
450 #if TAG_MAJOR_VERSION > 34
456 static const char *weapon_brands_adj[] =
458 "", "flaming", "freezing", "holy", "electric",
459 #if TAG_MAJOR_VERSION == 34
460 "orc-killing", "dragon-slaying",
462 "venomous", "protective", "draining", "fast", "vorpal",
463 #if TAG_MAJOR_VERSION == 34
464 "flaming", "freezing",
466 "vampiric", "painful", "antimagic", "distorting",
467 #if TAG_MAJOR_VERSION == 34
468 "reaching", "returning",
471 #if TAG_MAJOR_VERSION == 34
472 "evasive", "confusing",
474 "penetrating", "reaping", "spectral", "vorpal", "acidic",
475 #if TAG_MAJOR_VERSION > 34
481 static const set<brand_type> brand_prefers_adj =
482 { SPWPN_VAMPIRISM, SPWPN_ANTIMAGIC, SPWPN_VORPAL, SPWPN_SPECTRAL };
485 * What's the name of a type of weapon brand?
487 * @param brand The type of brand in question.
488 * @param bool Whether to use a terse or verbose name.
489 * @return The name of the given brand.
491 const char* brand_type_name(brand_type brand, bool terse)
493 COMPILE_CHECK(ARRAYSZ(weapon_brands_terse) == NUM_SPECIAL_WEAPONS);
494 COMPILE_CHECK(ARRAYSZ(weapon_brands_verbose) == NUM_SPECIAL_WEAPONS);
496 if (brand < 0 || brand >= NUM_SPECIAL_WEAPONS)
497 return terse ? "buggy" : "bugginess";
499 return (terse ? weapon_brands_terse : weapon_brands_verbose)[brand];
502 const char* brand_type_adj(brand_type brand)
504 COMPILE_CHECK(ARRAYSZ(weapon_brands_terse) == NUM_SPECIAL_WEAPONS);
505 COMPILE_CHECK(ARRAYSZ(weapon_brands_verbose) == NUM_SPECIAL_WEAPONS);
507 if (brand < 0 || brand >= NUM_SPECIAL_WEAPONS)
510 return weapon_brands_adj[brand];
514 * What's the name of a given weapon's brand?
516 * @param item The weapon with the brand.
517 * @param bool Whether to use a terse or verbose name.
518 * @return The name of the given item's brand.
520 const char* weapon_brand_name(const item_def& item, bool terse,
521 brand_type override_brand)
523 const brand_type brand = override_brand ? override_brand : get_weapon_brand(item);
525 return brand_type_name(brand, terse);
528 const char* armour_ego_name(const item_def& item, bool terse)
532 switch (get_armour_ego_type(item))
534 case SPARM_NORMAL: return "";
536 // "naga barding of running" doesn't make any sense, and yes,
537 // they are possible. The terse ego name for these is {run}
538 // still to avoid player confusion, it used to be {sslith}.
539 if (item.sub_type == ARM_BARDING && you.species == SP_NAGA)
540 return "speedy slithering";
543 case SPARM_FIRE_RESISTANCE: return "fire resistance";
544 case SPARM_COLD_RESISTANCE: return "cold resistance";
545 case SPARM_POISON_RESISTANCE: return "poison resistance";
546 case SPARM_SEE_INVISIBLE: return "see invisible";
547 case SPARM_INVISIBILITY: return "invisibility";
548 case SPARM_STRENGTH: return "strength";
549 case SPARM_DEXTERITY: return "dexterity";
550 case SPARM_INTELLIGENCE: return "intelligence";
551 case SPARM_PONDEROUSNESS: return "ponderousness";
552 case SPARM_FLYING: return "flying";
554 case SPARM_WILLPOWER: return "willpower";
555 case SPARM_PROTECTION: return "protection";
556 case SPARM_STEALTH: return "stealth";
557 case SPARM_RESISTANCE: return "resistance";
558 case SPARM_POSITIVE_ENERGY: return "positive energy";
559 case SPARM_ARCHMAGI: return "the Archmagi";
560 #if TAG_MAJOR_VERSION == 34
561 case SPARM_JUMPING: return "jumping";
563 case SPARM_PRESERVATION: return "preservation";
564 case SPARM_REFLECTION: return "reflection";
565 case SPARM_SPIRIT_SHIELD: return "spirit shield";
566 case SPARM_ARCHERY: return "archery";
567 case SPARM_REPULSION: return "repulsion";
568 #if TAG_MAJOR_VERSION == 34
569 case SPARM_CLOUD_IMMUNE: return "cloud immunity";
571 case SPARM_HARM: return "harm";
572 case SPARM_SHADOWS: return "shadows";
573 case SPARM_RAMPAGING: return "rampaging";
574 default: return "bugginess";
579 switch (get_armour_ego_type(item))
581 case SPARM_NORMAL: return "";
582 case SPARM_RUNNING: return "run";
583 case SPARM_FIRE_RESISTANCE: return "rF+";
584 case SPARM_COLD_RESISTANCE: return "rC+";
585 case SPARM_POISON_RESISTANCE: return "rPois";
586 case SPARM_SEE_INVISIBLE: return "SInv";
587 case SPARM_INVISIBILITY: return "+Inv";
588 case SPARM_STRENGTH: return "Str+3";
589 case SPARM_DEXTERITY: return "Dex+3";
590 case SPARM_INTELLIGENCE: return "Int+3";
591 case SPARM_PONDEROUSNESS: return "ponderous";
592 case SPARM_FLYING: return "Fly";
593 case SPARM_WILLPOWER: return "Will+";
594 case SPARM_PROTECTION: return "AC+3";
595 case SPARM_STEALTH: return "Stlth+";
596 case SPARM_RESISTANCE: return "rC+ rF+";
597 case SPARM_POSITIVE_ENERGY: return "rN+";
598 case SPARM_ARCHMAGI: return "Archmagi";
599 #if TAG_MAJOR_VERSION == 34
600 case SPARM_JUMPING: return "obsolete";
602 case SPARM_PRESERVATION: return "rCorr";
603 case SPARM_REFLECTION: return "reflect";
604 case SPARM_SPIRIT_SHIELD: return "Spirit";
605 case SPARM_ARCHERY: return "archery";
606 case SPARM_REPULSION: return "repulsion";
607 #if TAG_MAJOR_VERSION == 34
608 case SPARM_CLOUD_IMMUNE: return "obsolete";
610 case SPARM_HARM: return "harm";
611 case SPARM_SHADOWS: return "shadows";
612 case SPARM_RAMPAGING: return "rampage";
613 default: return "buggy";
618 static const char* _wand_type_name(int wandtype)
622 case WAND_FLAME: return "flame";
623 case WAND_PARALYSIS: return "paralysis";
624 case WAND_DIGGING: return "digging";
625 case WAND_ICEBLAST: return "iceblast";
626 case WAND_POLYMORPH: return "polymorph";
627 case WAND_ENSLAVEMENT: return "enslavement";
628 case WAND_ACID: return "acid";
629 case WAND_RANDOM_EFFECTS: return "random effects";
630 case WAND_DISINTEGRATION: return "disintegration";
631 default: return item_type_removed(OBJ_WANDS, wandtype)
637 static const char* wand_secondary_string(uint32_t s)
639 static const char* const secondary_strings[] = {
640 "", "jewelled ", "curved ", "long ", "short ", "twisted ", "crooked ",
641 "forked ", "shiny ", "blackened ", "tapered ", "glowing ", "worn ",
642 "encrusted ", "runed ", "sharpened "
644 COMPILE_CHECK(ARRAYSZ(secondary_strings) == NDSC_WAND_SEC);
645 return secondary_strings[s % NDSC_WAND_SEC];
648 static const char* wand_primary_string(uint32_t p)
650 static const char* const primary_strings[] = {
651 "iron", "brass", "bone", "wooden", "copper", "gold", "silver",
652 "bronze", "ivory", "glass", "lead", "fluorescent"
654 COMPILE_CHECK(ARRAYSZ(primary_strings) == NDSC_WAND_PRI);
655 return primary_strings[p % NDSC_WAND_PRI];
658 const char* potion_type_name(int potiontype)
660 switch (static_cast<potion_type>(potiontype))
662 case POT_CURING: return "curing";
663 case POT_HEAL_WOUNDS: return "heal wounds";
664 case POT_HASTE: return "haste";
665 case POT_MIGHT: return "might";
666 case POT_ATTRACTION: return "attraction";
667 case POT_BRILLIANCE: return "brilliance";
668 case POT_FLIGHT: return "flight";
669 case POT_CANCELLATION: return "cancellation";
670 case POT_AMBROSIA: return "ambrosia";
671 case POT_INVISIBILITY: return "invisibility";
672 case POT_DEGENERATION: return "degeneration";
673 case POT_EXPERIENCE: return "experience";
674 case POT_MAGIC: return "magic";
675 case POT_BERSERK_RAGE: return "berserk rage";
676 case POT_MUTATION: return "mutation";
677 case POT_RESISTANCE: return "resistance";
678 case POT_LIGNIFY: return "lignification";
680 // FIXME: Remove this once known-items no longer uses this as a sentinel.
683 CASE_REMOVED_POTIONS(potiontype); // TODO: this will crash, is that correct??
687 static const char* scroll_type_name(int scrolltype)
689 switch (static_cast<scroll_type>(scrolltype))
691 case SCR_IDENTIFY: return "identify";
692 case SCR_TELEPORTATION: return "teleportation";
693 case SCR_FEAR: return "fear";
694 case SCR_NOISE: return "noise";
695 case SCR_REMOVE_CURSE: return "remove curse";
696 case SCR_SUMMONING: return "summoning";
697 case SCR_ENCHANT_WEAPON: return "enchant weapon";
698 case SCR_ENCHANT_ARMOUR: return "enchant armour";
699 case SCR_TORMENT: return "torment";
700 case SCR_RANDOM_USELESSNESS: return "random uselessness";
701 case SCR_IMMOLATION: return "immolation";
702 case SCR_BLINKING: return "blinking";
703 case SCR_MAGIC_MAPPING: return "magic mapping";
704 case SCR_FOG: return "fog";
705 case SCR_ACQUIREMENT: return "acquirement";
706 case SCR_BRAND_WEAPON: return "brand weapon";
707 case SCR_HOLY_WORD: return "holy word";
708 case SCR_VULNERABILITY: return "vulnerability";
709 case SCR_SILENCE: return "silence";
710 case SCR_AMNESIA: return "amnesia";
711 #if TAG_MAJOR_VERSION == 34
712 case SCR_CURSE_WEAPON: return "curse weapon";
713 case SCR_CURSE_ARMOUR: return "curse armour";
714 case SCR_CURSE_JEWELLERY: return "curse jewellery";
716 default: return item_type_removed(OBJ_SCROLLS,
724 * Get the name for the effect provided by a kind of jewellery.
726 * @param jeweltype The jewellery_type of the item in question.
727 * @return A string describing the effect of the given jewellery
730 const char* jewellery_effect_name(int jeweltype, bool terse)
734 switch (static_cast<jewellery_type>(jeweltype))
736 #if TAG_MAJOR_VERSION == 34
737 case RING_REGENERATION: return "obsoleteness";
739 case RING_PROTECTION: return "protection";
740 case RING_PROTECTION_FROM_FIRE: return "protection from fire";
741 case RING_POISON_RESISTANCE: return "poison resistance";
742 case RING_PROTECTION_FROM_COLD: return "protection from cold";
743 case RING_STRENGTH: return "strength";
744 case RING_SLAYING: return "slaying";
745 case RING_SEE_INVISIBLE: return "see invisible";
746 case RING_RESIST_CORROSION: return "resist corrosion";
747 case RING_ATTENTION: return "attention";
748 case RING_TELEPORTATION: return "teleportation";
749 case RING_EVASION: return "evasion";
750 #if TAG_MAJOR_VERSION == 34
751 case RING_SUSTAIN_ATTRIBUTES: return "sustain attributes";
753 case RING_STEALTH: return "stealth";
754 case RING_DEXTERITY: return "dexterity";
755 case RING_INTELLIGENCE: return "intelligence";
756 case RING_WIZARDRY: return "wizardry";
757 case RING_MAGICAL_POWER: return "magical power";
758 case RING_FLIGHT: return "flight";
759 case RING_LIFE_PROTECTION: return "positive energy";
760 case RING_WILLPOWER: return "willpower";
761 case RING_FIRE: return "fire";
762 case RING_ICE: return "ice";
763 #if TAG_MAJOR_VERSION == 34
764 case RING_TELEPORT_CONTROL: return "teleport control";
766 case AMU_MANA_REGENERATION: return "magic regeneration";
767 case AMU_ACROBAT: return "the acrobat";
768 #if TAG_MAJOR_VERSION == 34
769 case AMU_RAGE: return "rage";
770 case AMU_THE_GOURMAND: return "gourmand";
771 case AMU_HARM: return "harm";
772 case AMU_CONSERVATION: return "conservation";
773 case AMU_CONTROLLED_FLIGHT: return "controlled flight";
775 case AMU_INACCURACY: return "inaccuracy";
776 case AMU_NOTHING: return "nothing";
777 case AMU_GUARDIAN_SPIRIT: return "guardian spirit";
778 case AMU_FAITH: return "faith";
779 case AMU_REFLECTION: return "reflection";
780 case AMU_REGENERATION: return "regeneration";
781 default: return "buggy jewellery";
786 if (jewellery_base_ability_string(jeweltype)[0] != '\0')
787 return jewellery_base_ability_string(jeweltype);
788 switch (static_cast<jewellery_type>(jeweltype))
790 #if TAG_MAJOR_VERSION == 34
791 case RING_REGENERATION: return "obsoleteness";
793 case RING_PROTECTION: return "AC";
794 case RING_PROTECTION_FROM_FIRE: return "rF+";
795 case RING_POISON_RESISTANCE: return "rPois";
796 case RING_PROTECTION_FROM_COLD: return "rC+";
797 case RING_STRENGTH: return "Str";
798 case RING_SLAYING: return "Slay";
799 case RING_SEE_INVISIBLE: return "sInv";
800 case RING_RESIST_CORROSION: return "rCorr";
801 case RING_ATTENTION: return "Stlth-";
802 case RING_EVASION: return "EV";
803 case RING_STEALTH: return "Stlth+";
804 case RING_DEXTERITY: return "Dex";
805 case RING_INTELLIGENCE: return "Int";
806 case RING_MAGICAL_POWER: return "MP+9";
807 case RING_FLIGHT: return "+Fly";
808 case RING_LIFE_PROTECTION: return "rN+";
809 case RING_WILLPOWER: return "Will+";
810 case AMU_REGENERATION: return "Regen";
811 #if TAG_MAJOR_VERSION == 34
812 case AMU_RAGE: return "+Rage";
814 case AMU_ACROBAT: return "Acrobat";
815 case AMU_NOTHING: return "";
816 default: return "buggy";
822 * Get the name for the category of a type of jewellery.
824 * @param jeweltype The jewellery_type of the item in question.
825 * @return A string describing the kind of jewellery it is.
827 static const char* _jewellery_class_name(int jeweltype)
829 #if TAG_MAJOR_VERSION == 34
830 if (jeweltype == RING_REGENERATION)
834 if (jeweltype < RING_FIRST_RING || jeweltype >= NUM_JEWELLERY
835 || jeweltype >= NUM_RINGS && jeweltype < AMU_FIRST_AMULET)
837 return "buggy"; // "buggy buggy jewellery"
840 if (jeweltype < NUM_RINGS)
846 * Get the name for a type of jewellery.
848 * @param jeweltype The jewellery_type of the item in question.
849 * @return The full name of the jewellery type in question.
851 static string jewellery_type_name(int jeweltype)
853 return make_stringf("%s %s", _jewellery_class_name(jeweltype),
854 jewellery_effect_name(jeweltype));
858 static const char* ring_secondary_string(uint32_t s)
860 static const char* const secondary_strings[] = {
861 "", "encrusted ", "glowing ", "tubular ", "runed ", "blackened ",
862 "scratched ", "small ", "large ", "twisted ", "shiny ", "notched ",
865 COMPILE_CHECK(ARRAYSZ(secondary_strings) == NDSC_JEWEL_SEC);
866 return secondary_strings[s % NDSC_JEWEL_SEC];
869 static const char* ring_primary_string(uint32_t p)
871 static const char* const primary_strings[] = {
872 "wooden", "silver", "golden", "iron", "steel", "tourmaline", "brass",
873 "copper", "granite", "ivory", "ruby", "marble", "jade", "glass",
874 "agate", "bone", "diamond", "emerald", "peridot", "garnet", "opal",
875 "pearl", "coral", "sapphire", "cabochon", "gilded", "onyx", "bronze",
878 COMPILE_CHECK(ARRAYSZ(primary_strings) == NDSC_JEWEL_PRI);
879 return primary_strings[p % NDSC_JEWEL_PRI];
882 static const char* amulet_secondary_string(uint32_t s)
884 static const char* const secondary_strings[] = {
885 "dented ", "square ", "thick ", "thin ", "runed ", "blackened ",
886 "glowing ", "small ", "large ", "twisted ", "tiny ", "triangular ",
889 COMPILE_CHECK(ARRAYSZ(secondary_strings) == NDSC_JEWEL_SEC);
890 return secondary_strings[s % NDSC_JEWEL_SEC];
893 static const char* amulet_primary_string(uint32_t p)
895 static const char* const primary_strings[] = {
896 "sapphire", "zirconium", "golden", "emerald", "garnet", "bronze",
897 "brass", "copper", "ruby", "citrine", "bone", "platinum", "jade",
898 "fluorescent", "amethyst", "cameo", "pearl", "blue", "peridot",
899 "jasper", "diamond", "malachite", "steel", "cabochon", "silver",
900 "soapstone", "lapis lazuli", "filigree", "beryl"
902 COMPILE_CHECK(ARRAYSZ(primary_strings) == NDSC_JEWEL_PRI);
903 return primary_strings[p % NDSC_JEWEL_PRI];
906 const char* rune_type_name(short p)
908 switch (static_cast<rune_type>(p))
910 case RUNE_DIS: return "iron";
911 case RUNE_GEHENNA: return "obsidian";
912 case RUNE_COCYTUS: return "icy";
913 case RUNE_TARTARUS: return "bone";
914 case RUNE_SLIME: return "slimy";
915 case RUNE_VAULTS: return "silver";
916 case RUNE_SNAKE: return "serpentine";
917 case RUNE_ELF: return "elven";
918 case RUNE_TOMB: return "golden";
919 case RUNE_SWAMP: return "decaying";
920 case RUNE_SHOALS: return "barnacled";
921 case RUNE_SPIDER: return "gossamer";
922 case RUNE_FOREST: return "mossy";
924 // pandemonium and abyss runes:
925 case RUNE_DEMONIC: return "demonic";
926 case RUNE_ABYSSAL: return "abyssal";
928 // special pandemonium runes:
929 case RUNE_MNOLEG: return "glowing";
930 case RUNE_LOM_LOBON: return "magical";
931 case RUNE_CEREBOV: return "fiery";
932 case RUNE_GLOORX_VLOQ: return "dark";
933 default: return "buggy";
937 static string misc_type_name(int type)
939 #if TAG_MAJOR_VERSION == 34
940 if (is_deck_type(type))
941 return "removed deck";
944 switch (static_cast<misc_item_type>(type))
946 #if TAG_MAJOR_VERSION == 34
947 case MISC_CRYSTAL_BALL_OF_ENERGY: return "removed crystal ball";
949 case MISC_BOX_OF_BEASTS: return "box of beasts";
950 #if TAG_MAJOR_VERSION == 34
951 case MISC_BUGGY_EBONY_CASKET: return "removed ebony casket";
952 case MISC_FAN_OF_GALES: return "removed fan of gales";
953 case MISC_LAMP_OF_FIRE: return "removed lamp of fire";
954 case MISC_BUGGY_LANTERN_OF_SHADOWS: return "removed lantern of shadows";
956 case MISC_HORN_OF_GERYON: return "horn of Geryon";
957 case MISC_LIGHTNING_ROD: return "lightning rod";
958 #if TAG_MAJOR_VERSION == 34
959 case MISC_BOTTLED_EFREET: return "empty flask";
960 case MISC_RUNE_OF_ZOT: return "obsolete rune of zot";
961 case MISC_STONE_OF_TREMORS: return "removed stone of tremors";
963 case MISC_QUAD_DAMAGE: return "quad damage";
964 case MISC_PHIAL_OF_FLOODS: return "phial of floods";
965 #if TAG_MAJOR_VERSION == 34
966 case MISC_SACK_OF_SPIDERS: return "removed sack of spiders";
968 case MISC_PHANTOM_MIRROR: return "phantom mirror";
969 case MISC_ZIGGURAT: return "figurine of a ziggurat";
970 #if TAG_MAJOR_VERSION == 34
971 case MISC_XOMS_CHESSBOARD: return "removed chess piece";
973 case MISC_TIN_OF_TREMORSTONES: return "tin of tremorstones";
974 case MISC_CONDENSER_VANE: return "condenser vane";
977 return "buggy miscellaneous item";
981 static bool _book_visually_special(uint32_t s)
983 return s & 128; // one in ten books; c.f. item_colour()
986 static const char* book_secondary_string(uint32_t s)
988 if (!_book_visually_special(s))
991 static const char* const secondary_strings[] = {
992 "", "chunky ", "thick ", "thin ", "wide ", "glowing ",
993 "dog-eared ", "oblong ", "runed ", "", "", ""
995 return secondary_strings[(s / NDSC_BOOK_PRI) % ARRAYSZ(secondary_strings)];
998 static const char* book_primary_string(uint32_t p)
1000 static const char* const primary_strings[] = {
1001 "paperback", "hardcover", "leatherbound", "metal-bound", "papyrus",
1003 COMPILE_CHECK(NDSC_BOOK_PRI == ARRAYSZ(primary_strings));
1005 return primary_strings[p % ARRAYSZ(primary_strings)];
1008 static const char* _book_type_name(int booktype)
1010 switch (static_cast<book_type>(booktype))
1012 case BOOK_MINOR_MAGIC: return "Minor Magic";
1013 case BOOK_CONJURATIONS: return "Conjurations";
1014 case BOOK_FLAMES: return "Flames";
1015 case BOOK_FROST: return "Frost";
1016 case BOOK_SUMMONINGS: return "Summonings";
1017 case BOOK_FIRE: return "Fire";
1018 case BOOK_ICE: return "Ice";
1019 case BOOK_SPATIAL_TRANSLOCATIONS: return "Spatial Translocations";
1020 case BOOK_HEXES: return "Hexes";
1021 case BOOK_TEMPESTS: return "the Tempests";
1022 case BOOK_DEATH: return "Death";
1023 case BOOK_MISFORTUNE: return "Misfortune";
1024 case BOOK_CHANGES: return "Changes";
1025 case BOOK_TRANSFIGURATIONS: return "Transfigurations";
1026 #if TAG_MAJOR_VERSION == 34
1027 case BOOK_BATTLE: return "Battle";
1029 case BOOK_CLOUDS: return "Clouds";
1030 case BOOK_NECROMANCY: return "Necromancy";
1031 case BOOK_CALLINGS: return "Callings";
1032 case BOOK_MALEDICT: return "Maledictions";
1033 case BOOK_AIR: return "Air";
1034 case BOOK_SKY: return "the Sky";
1035 case BOOK_WARP: return "the Warp";
1036 #if TAG_MAJOR_VERSION == 34
1037 case BOOK_ENVENOMATIONS: return "Envenomations";
1039 case BOOK_ANNIHILATIONS: return "Annihilations";
1040 case BOOK_UNLIFE: return "Unlife";
1041 #if TAG_MAJOR_VERSION == 34
1042 case BOOK_CONTROL: return "Control";
1044 case BOOK_GEOMANCY: return "Geomancy";
1045 case BOOK_EARTH: return "the Earth";
1046 #if TAG_MAJOR_VERSION == 34
1047 case BOOK_WIZARDRY: return "Wizardry";
1049 case BOOK_POWER: return "Power";
1050 case BOOK_CANTRIPS: return "Cantrips";
1051 case BOOK_PARTY_TRICKS: return "Party Tricks";
1052 case BOOK_DEBILITATION: return "Debilitation";
1053 case BOOK_DRAGON: return "the Dragon";
1054 case BOOK_BURGLARY: return "Burglary";
1055 case BOOK_DREAMS: return "Dreams";
1056 case BOOK_ALCHEMY: return "Alchemy";
1057 #if TAG_MAJOR_VERSION == 34
1058 case BOOK_BEASTS: return "Beasts";
1060 case BOOK_RANDART_LEVEL: return "Fixed Level";
1061 case BOOK_RANDART_THEME: return "Fixed Theme";
1062 default: return "Bugginess";
1066 static const char* staff_secondary_string(uint32_t s)
1068 static const char* const secondary_strings[] = {
1069 "crooked ", "knobbly ", "weird ", "gnarled ", "thin ", "curved ",
1070 "twisted ", "thick ", "long ", "short ",
1072 COMPILE_CHECK(NDSC_STAVE_SEC == ARRAYSZ(secondary_strings));
1073 return secondary_strings[s % ARRAYSZ(secondary_strings)];
1076 static const char* staff_primary_string(uint32_t p)
1078 static const char* const primary_strings[] = {
1079 "glowing ", "jewelled ", "runed ", "smoking "
1081 COMPILE_CHECK(NDSC_STAVE_PRI == ARRAYSZ(primary_strings));
1082 return primary_strings[p % ARRAYSZ(primary_strings)];
1085 static const char* staff_type_name(int stafftype)
1087 switch ((stave_type)stafftype)
1089 case STAFF_FIRE: return "fire";
1090 case STAFF_COLD: return "cold";
1091 case STAFF_POISON: return "poison";
1092 case STAFF_DEATH: return "death";
1093 case STAFF_CONJURATION: return "conjuration";
1094 case STAFF_AIR: return "air";
1095 case STAFF_EARTH: return "earth";
1096 default: return item_type_removed(OBJ_STAVES, stafftype)
1102 const char *base_type_string(const item_def &item)
1104 return base_type_string(item.base_type);
1107 const char *base_type_string(object_class_type type)
1111 case OBJ_WEAPONS: return "weapon";
1112 case OBJ_MISSILES: return "missile";
1113 case OBJ_ARMOUR: return "armour";
1114 case OBJ_WANDS: return "wand";
1115 case OBJ_SCROLLS: return "scroll";
1116 case OBJ_JEWELLERY: return "jewellery";
1117 case OBJ_POTIONS: return "potion";
1118 case OBJ_BOOKS: return "book";
1119 case OBJ_STAVES: return "staff";
1120 #if TAG_MAJOR_VERSION == 34
1121 case OBJ_RODS: return "removed rod";
1123 case OBJ_ORBS: return "orb";
1124 case OBJ_MISCELLANY: return "miscellaneous";
1125 case OBJ_CORPSES: return "corpse";
1126 case OBJ_GOLD: return "gold";
1127 case OBJ_RUNES: return "rune";
1132 string sub_type_string(const item_def &item, bool known)
1134 const object_class_type type = item.base_type;
1135 const int sub_type = item.sub_type;
1139 case OBJ_WEAPONS: // deliberate fall through, as XXX_prop is a local
1140 case OBJ_MISSILES: // variable to item-prop.cc.
1142 return item_base_name(type, sub_type);
1143 case OBJ_WANDS: return _wand_type_name(sub_type);
1144 case OBJ_SCROLLS: return scroll_type_name(sub_type);
1145 case OBJ_JEWELLERY: return jewellery_type_name(sub_type);
1146 case OBJ_POTIONS: return potion_type_name(sub_type);
1149 if (sub_type == BOOK_MANUAL)
1153 string bookname = "manual of ";
1154 bookname += skill_name(static_cast<skill_type>(item.plus));
1157 else if (sub_type == BOOK_NECRONOMICON)
1158 return "Necronomicon";
1159 else if (sub_type == BOOK_GRAND_GRIMOIRE)
1160 return "Grand Grimoire";
1161 #if TAG_MAJOR_VERSION == 34
1162 else if (sub_type == BOOK_BUGGY_DESTRUCTION)
1163 return "tome of obsoleteness";
1165 else if (sub_type == BOOK_YOUNG_POISONERS)
1166 return "Young Poisoner's Handbook";
1167 else if (sub_type == BOOK_FEN)
1169 #if TAG_MAJOR_VERSION == 34
1170 else if (sub_type == BOOK_AKASHIC_RECORD)
1171 return "Akashic Record";
1174 return string("book of ") + _book_type_name(sub_type);
1176 case OBJ_STAVES: return staff_type_name(static_cast<stave_type>(sub_type));
1177 #if TAG_MAJOR_VERSION == 34
1178 case OBJ_RODS: return "removed rod";
1180 case OBJ_MISCELLANY: return misc_type_name(sub_type);
1181 // these repeat as base_type_string
1182 case OBJ_ORBS: return "orb of Zot";
1183 case OBJ_CORPSES: return "corpse";
1184 case OBJ_GOLD: return "gold";
1185 case OBJ_RUNES: return "rune of Zot";
1191 * What's the name for the weapon used by a given ghost / pan lord?
1193 * There's no actual weapon info, just brand, so we have to improvise...
1195 * @param brand The brand_type used by the ghost or pan lord.
1196 * @param mtype Monster type; determines whether the fake weapon is
1197 * described as a `weapon` or a `touch`.
1198 * @return The name of the ghost's weapon (e.g. "weapon of flaming",
1199 * "antimagic weapon"). SPWPN_NORMAL returns "".
1201 string ghost_brand_name(brand_type brand, monster_type mtype)
1203 if (brand == SPWPN_NORMAL)
1205 const bool weapon = mtype != MONS_PANDEMONIUM_LORD;
1208 // n.b. vorpal only works if it is adjectival
1209 if (brand_prefers_adj.count(brand))
1210 return make_stringf("%s weapon", brand_type_adj(brand));
1212 return make_stringf("weapon of %s", brand_type_name(brand, false));
1215 return make_stringf("%s touch", brand_type_adj(brand));
1218 string ego_type_string(const item_def &item, bool terse)
1220 switch (item.base_type)
1223 return armour_ego_name(item, terse);
1225 if (get_weapon_brand(item) != SPWPN_NORMAL)
1226 return weapon_brand_name(item, terse);
1231 if (item.props.exists(DAMNATION_BOLT_KEY))
1233 return missile_brand_name(item, terse ? MBN_TERSE : MBN_BRAND);
1235 return jewellery_effect_name(item.sub_type, terse);
1242 * When naming the given item, should the base name be used?
1244 static bool _use_basename(const item_def &item, description_level_type desc,
1247 const bool know_type = ident || item_type_known(item);
1248 return desc == DESC_BASENAME
1249 || desc == DESC_DBNAME && !know_type;
1253 * When naming the given item, should identifiable properties be mentioned?
1255 static bool _know_any_ident(const item_def &item, description_level_type desc,
1258 return desc != DESC_QUALNAME && desc != DESC_DBNAME
1259 && !_use_basename(item, desc, ident);
1263 * When naming the given item, should the specified identifiable property be
1266 static bool _know_ident(const item_def &item, description_level_type desc,
1267 bool ident, iflags_t ignore_flags,
1268 item_status_flag_type vprop)
1270 return _know_any_ident(item, desc, ident)
1271 && !testbits(ignore_flags, vprop)
1272 && (ident || item_ident(item, vprop));
1276 * When naming the given item, should the curse be mentioned?
1278 static bool _know_curse(const item_def &item, description_level_type desc,
1279 bool ident, iflags_t ignore_flags)
1281 return _know_ident(item, desc, ident, ignore_flags, ISFLAG_KNOW_CURSE);
1285 * When naming the given item, should the pluses be mentioned?
1287 static bool _know_pluses(const item_def &item, description_level_type desc,
1288 bool ident, iflags_t ignore_flags)
1290 return _know_ident(item, desc, ident, ignore_flags, ISFLAG_KNOW_PLUSES);
1294 * When naming the given item, should the brand be mentioned?
1296 static bool _know_ego(const item_def &item, description_level_type desc,
1297 bool ident, iflags_t ignore_flags)
1299 return _know_any_ident(item, desc, ident)
1300 && !testbits(ignore_flags, ISFLAG_KNOW_TYPE)
1301 && (ident || item_type_known(item));
1305 * The curse-describing prefix to a weapon's name, including trailing space if
1306 * appropriate. (Empty if the weapon isn't cursed, or if the curse shouldn't be
1309 static string _curse_prefix(const item_def &weap, description_level_type desc,
1310 bool terse, bool ident, iflags_t ignore_flags)
1312 if (!_know_curse(weap, desc, ident, ignore_flags) || terse)
1318 // We don't bother printing "uncursed" if the item is identified
1319 // for pluses (its state should be obvious), this is so that
1320 // the weapon name is kept short (there isn't a lot of room
1321 // for the name on the main screen). If you're going to change
1322 // this behaviour, *please* make it so that there is an option
1323 // that maintains this behaviour. -- bwr
1324 if (_know_pluses(weap, desc, ident, ignore_flags))
1326 // Nor for artefacts. Again, the state should be obvious. --jpeg
1327 if (!ident && !item_type_known(weap)
1328 || !is_artefact(weap))
1336 * The plus-describing prefix to a weapon's name, including trailing space.
1338 static string _plus_prefix(const item_def &weap)
1340 if (is_unrandom_artefact(weap, UNRAND_WOE))
1342 return make_stringf("%+d ", weap.plus);
1346 * Cosmetic text for weapons (e.g. glowing, runed). Includes trailing space,
1347 * if appropriate. (Empty if there is no cosmetic property, or if it's
1348 * marked to be ignored.)
1350 static string _cosmetic_text(const item_def &weap, iflags_t ignore_flags)
1352 const iflags_t desc = get_equip_desc(weap);
1353 if (testbits(ignore_flags, desc))
1360 case ISFLAG_GLOWING:
1368 * Surrounds a given string with the weapon's brand-describing prefix/suffix
1371 string weapon_brand_desc(const char *body, const item_def &weap,
1372 bool terse, brand_type override_brand)
1375 const string brand_name = weapon_brand_name(weap, terse, override_brand);
1377 if (brand_name.empty())
1381 return make_stringf("%s (%s)", body, brand_name.c_str());
1383 const brand_type brand = override_brand ? override_brand :
1384 get_weapon_brand(weap);
1386 if (brand_prefers_adj.count(brand))
1387 return make_stringf("%s %s", brand_type_adj(brand), body);
1388 else if (brand == SPWPN_NORMAL)
1390 if (get_equip_desc(weap))
1391 return make_stringf("enchanted %s", body);
1396 return make_stringf("%s of %s", body, brand_name.c_str());
1400 * Build the appropriate name for a given weapon.
1402 * @param weap The weapon in question.
1403 * @param desc The type of name to provide. (E.g. the name to be used
1404 * in database lookups for description, or...)
1405 * @param terse Whether to provide a terse version of the name for
1406 * display in the HUD.
1407 * @param ident Whether the weapon should be named as if it were
1409 * @param inscr Whether an inscription will be added later.
1410 * @param ignore_flags Identification flags on the weapon to ignore.
1412 * @return A name for the weapon.
1415 static string _name_weapon(const item_def &weap, description_level_type desc,
1416 bool terse, bool ident, bool inscr,
1417 iflags_t ignore_flags)
1419 const bool dbname = (desc == DESC_DBNAME);
1420 const bool basename = _use_basename(weap, desc, ident);
1421 const bool qualname = (desc == DESC_QUALNAME);
1423 const bool know_curse = _know_curse(weap, desc, ident, ignore_flags);
1424 const bool know_pluses = _know_pluses(weap, desc, ident, ignore_flags);
1425 const bool know_ego = _know_ego(weap, desc, ident, ignore_flags);
1427 const string curse_prefix
1428 = _curse_prefix(weap, desc, terse, ident, ignore_flags);
1429 const string plus_text = know_pluses ? _plus_prefix(weap) : "";
1431 if (is_artefact(weap) && !dbname)
1433 const string long_name = curse_prefix + plus_text
1434 + get_artefact_name(weap, ident);
1436 // crop long artefact names when not controlled by webtiles -
1437 // webtiles displays weapon names across multiple lines
1439 if (!tiles.is_controlled_from_web())
1442 const bool has_inscript = desc != DESC_BASENAME
1443 && desc != DESC_DBNAME
1445 const string inscription = _item_inscription(weap);
1447 const int total_length = long_name.size()
1448 + (has_inscript ? inscription.size() : 0);
1449 const string inv_slot_text = "x) ";
1450 const int max_length = crawl_view.hudsz.x - inv_slot_text.size();
1451 if (!terse || total_length <= max_length)
1459 // special case: these two shouldn't ever have their base name revealed
1460 // (since showing 'eudaemon blade' is unhelpful in the former case, and
1461 // showing 'broad axe' is misleading in the latter)
1462 // could be a flag, but doesn't seem worthwhile for only two items
1463 if (is_unrandom_artefact(weap, UNRAND_ZEALOT_SWORD)
1464 || is_unrandom_artefact(weap, UNRAND_DEMON_AXE))
1469 const string short_name
1470 = curse_prefix + plus_text + get_artefact_base_name(weap, true);
1474 const bool show_cosmetic = !basename && !qualname && !dbname
1475 && !know_pluses && !know_ego
1477 && !(ignore_flags & ISFLAG_COSMETIC_MASK);
1479 const string cosmetic_text
1480 = show_cosmetic ? _cosmetic_text(weap, ignore_flags) : "";
1481 const string base_name = item_base_name(weap);
1482 const string name_with_ego
1483 = know_ego ? weapon_brand_desc(base_name.c_str(), weap, terse)
1485 const string curse_suffix
1486 = know_curse && weap.cursed() && terse ? " (curse)" : "";
1487 return curse_prefix + plus_text + cosmetic_text
1488 + name_with_ego + curse_suffix;
1491 // Note that "terse" is only currently used for the "in hand" listing on
1493 string item_def::name_aux(description_level_type desc, bool terse, bool ident,
1494 bool with_inscription, iflags_t ignore_flags) const
1497 const int item_typ = sub_type;
1499 const bool know_type = ident || item_type_known(*this);
1501 const bool dbname = (desc == DESC_DBNAME);
1502 const bool basename = _use_basename(*this, desc, ident);
1503 const bool qualname = (desc == DESC_QUALNAME);
1505 const bool know_curse = _know_curse(*this, desc, ident, ignore_flags);
1506 const bool know_pluses = _know_pluses(*this, desc, ident, ignore_flags);
1507 const bool know_brand = _know_ego(*this, desc, ident, ignore_flags);
1509 const bool know_ego = know_brand;
1511 // Display runed/glowing/embroidered etc?
1512 // Only display this if brand is unknown.
1513 const bool show_cosmetic = !know_pluses && !know_brand
1514 && !basename && !qualname && !dbname
1516 && !(ignore_flags & ISFLAG_COSMETIC_MASK);
1518 const bool need_plural = !basename && !dbname;
1525 buff << _name_weapon(*this, desc, terse, ident, with_inscription,
1531 special_missile_type msl_brand = get_ammo_brand(*this);
1533 if (!terse && !dbname && !basename)
1535 if (props.exists(DAMNATION_BOLT_KEY)) // hack alert
1536 buff << "damnation ";
1537 else if (_missile_brand_is_prefix(msl_brand)) // see below for postfix brands
1538 buff << missile_brand_name(*this, MBN_NAME) << ' ';
1541 buff << ammo_name(static_cast<missile_type>(item_typ));
1543 if (msl_brand != SPMSL_NORMAL
1544 && !basename && !dbname)
1548 if (props.exists(DAMNATION_BOLT_KEY)) // still a hack
1549 buff << " (damnation)";
1551 buff << " (" << missile_brand_name(*this, MBN_TERSE) << ")";
1553 else if (_missile_brand_is_postfix(msl_brand)) // see above for prefix brands
1554 buff << " of " << missile_brand_name(*this, MBN_NAME);
1560 if (know_curse && !terse)
1564 else if (!know_pluses)
1565 buff << "uncursed ";
1569 // If we know enough to know it has *something* ('shiny' etc),
1570 // but we know it has no ego, it must have a plus. (or maybe a curse.)
1571 // If we don't know what the plus is, call it 'enchanted'.
1572 if (!terse && know_ego && get_armour_ego_type(*this) == SPARM_NORMAL &&
1573 !know_pluses && !is_artefact(*this) && get_equip_desc(*this))
1575 buff << "enchanted ";
1578 // Don't list unenchantable armor as +0.
1579 if (know_pluses && armour_is_enchantable(*this))
1580 buff << make_stringf("%+d ", plus);
1582 if (item_typ == ARM_GLOVES || item_typ == ARM_BOOTS)
1585 if (is_artefact(*this) && !dbname)
1587 buff << get_artefact_name(*this, ident);
1593 switch (get_equip_desc(*this))
1595 case ISFLAG_EMBROIDERED_SHINY:
1596 if (testbits(ignore_flags, ISFLAG_EMBROIDERED_SHINY))
1598 if (item_typ == ARM_ROBE || item_typ == ARM_CLOAK
1599 || item_typ == ARM_GLOVES || item_typ == ARM_BOOTS
1600 || item_typ == ARM_SCARF
1601 || get_armour_slot(*this) == EQ_HELMET
1602 && !is_hard_helmet(*this))
1604 buff << "embroidered ";
1606 else if (item_typ != ARM_LEATHER_ARMOUR
1607 && item_typ != ARM_ANIMAL_SKIN)
1616 if (!testbits(ignore_flags, ISFLAG_RUNED))
1620 case ISFLAG_GLOWING:
1621 if (!testbits(ignore_flags, ISFLAG_GLOWING))
1627 buff << item_base_name(*this);
1629 if (know_ego && !is_artefact(*this))
1631 const special_armour_type sparm = get_armour_ego_type(*this);
1633 if (sparm != SPARM_NORMAL)
1639 buff << armour_ego_name(*this, terse);
1645 if (know_curse && cursed() && terse)
1657 buff << "wand of " << _wand_type_name(item_typ);
1660 buff << wand_secondary_string(subtype_rnd / NDSC_WAND_PRI)
1661 << wand_primary_string(subtype_rnd % NDSC_WAND_PRI)
1668 if (know_type && charges > 0)
1669 buff << " (" << charges << ")";
1681 buff << "potion of " << potion_type_name(item_typ);
1684 const int pqual = PQUAL(subtype_rnd);
1685 const int pcolour = PCOLOUR(subtype_rnd);
1687 static const char *potion_qualifiers[] =
1689 "", "bubbling ", "fuming ", "fizzy ", "viscous ", "lumpy ",
1690 "smoky ", "glowing ", "sedimented ", "metallic ", "murky ",
1691 "gluggy ", "oily ", "slimy ", "emulsified ",
1693 COMPILE_CHECK(ARRAYSZ(potion_qualifiers) == PDQ_NQUALS);
1695 static const char *potion_colours[] =
1697 #if TAG_MAJOR_VERSION == 34
1700 "blue", "black", "silvery", "cyan", "purple", "orange",
1701 "inky", "red", "yellow", "green", "brown", "ruby", "white",
1702 "emerald", "grey", "pink", "coppery", "golden", "dark", "puce",
1703 "amethyst", "sapphire",
1705 COMPILE_CHECK(ARRAYSZ(potion_colours) == PDC_NCOLOURS);
1707 const char *qualifier =
1708 (pqual < 0 || pqual >= PDQ_NQUALS) ? "bug-filled "
1709 : potion_qualifiers[pqual];
1711 const char *clr = (pcolour < 0 || pcolour >= PDC_NCOLOURS) ?
1712 "bogus" : potion_colours[pcolour];
1714 buff << qualifier << clr << " potion";
1718 #if TAG_MAJOR_VERSION == 34
1720 buff << "removed food"; break;
1732 buff << "of " << scroll_type_name(item_typ);
1734 buff << "labelled " << make_name(subtype_rnd, MNAME_SCROLL);
1741 if (jewellery_is_amulet(*this))
1749 const bool is_randart = is_artefact(*this);
1751 if (know_curse && !terse)
1755 else if (desc != DESC_PLAIN
1756 && (!is_randart || !know_type)
1757 && (!jewellery_has_pluses(*this) || !know_pluses)
1758 // If the item is worn, its curse status is known,
1759 // no need to belabour the obvious.
1760 && get_equip_slot(this) == -1)
1762 buff << "uncursed ";
1766 if (is_randart && !dbname)
1768 buff << get_artefact_name(*this, ident);
1774 if (know_pluses && jewellery_has_pluses(*this))
1775 buff << make_stringf("%+d ", plus);
1777 buff << jewellery_type_name(item_typ);
1781 if (jewellery_is_amulet(*this))
1783 buff << amulet_secondary_string(subtype_rnd / NDSC_JEWEL_PRI)
1784 << amulet_primary_string(subtype_rnd % NDSC_JEWEL_PRI)
1787 else // i.e., a ring
1789 buff << ring_secondary_string(subtype_rnd / NDSC_JEWEL_PRI)
1790 << ring_primary_string(subtype_rnd % NDSC_JEWEL_PRI)
1794 if (know_curse && cursed() && terse)
1798 case OBJ_MISCELLANY:
1800 if (!dbname && item_typ == MISC_ZIGGURAT && you.zigs_completed > 0)
1801 buff << "+" << you.zigs_completed << " ";
1803 buff << misc_type_name(item_typ);
1805 if (is_xp_evoker(*this) && !dbname && !evoker_charges(sub_type))
1807 else if (is_xp_evoker(*this) &&
1808 !dbname && evoker_max_charges(sub_type) > 1)
1810 buff << " (" << evoker_charges(sub_type) << "/"
1811 << evoker_max_charges(sub_type) << ")";
1818 if (is_random_artefact(*this) && !dbname && !basename)
1820 buff << get_artefact_name(*this, ident);
1826 buff << (item_typ == BOOK_MANUAL ? "manual" : "book");
1827 else if (!know_type)
1829 buff << book_secondary_string(rnd)
1830 << book_primary_string(rnd) << " "
1831 << (item_typ == BOOK_MANUAL ? "manual" : "book");
1834 buff << sub_type_string(*this, !dbname);
1837 #if TAG_MAJOR_VERSION == 34
1839 buff << "removed rod";
1844 if (know_curse && !terse)
1848 else if (desc != DESC_PLAIN
1849 && (!know_type || !is_artefact(*this)))
1851 buff << "uncursed ";
1859 buff << staff_secondary_string(subtype_rnd / NDSC_STAVE_PRI)
1860 << staff_primary_string(subtype_rnd % NDSC_STAVE_PRI);
1866 buff << "staff of " << staff_type_name(item_typ);
1868 if (know_curse && cursed() && terse)
1872 // rearranged 15 Apr 2000 {dlb}:
1874 buff.str("Orb of Zot");
1879 buff << rune_type_name(sub_type) << " ";
1880 buff << "rune of Zot";
1884 buff << "gold piece";
1889 if (dbname && item_typ == CORPSE_SKELETON)
1890 return "decaying skeleton";
1892 monster_flags_t name_flags;
1893 const string _name = get_corpse_name(*this, &name_flags);
1894 const monster_flags_t name_type = name_flags & MF_NAME_MASK;
1896 const bool shaped = starts_with(_name, "shaped ");
1898 if (!_name.empty() && name_type == MF_NAME_ADJECTIVE)
1899 buff << _name << " ";
1901 if ((name_flags & MF_NAME_SPECIES) && name_type == MF_NAME_REPLACE)
1902 buff << _name << " ";
1903 else if (!dbname && !starts_with(_name, "the "))
1905 const monster_type mc = mon_type;
1906 if (!(mons_is_unique(mc) && mons_species(mc) == mc))
1907 buff << mons_type_name(mc, DESC_PLAIN) << ' ';
1909 if (!_name.empty() && shaped)
1910 buff << _name << ' ';
1913 if (item_typ == CORPSE_BODY)
1915 else if (item_typ == CORPSE_SKELETON)
1918 buff << "corpse bug";
1920 if (!_name.empty() && !shaped && name_type != MF_NAME_ADJECTIVE
1921 && !(name_flags & MF_NAME_SPECIES) && name_type != MF_NAME_SUFFIX
1924 buff << " of " << _name;
1933 // One plural to rule them all.
1934 if (need_plural && quantity > 1 && !basename && !qualname)
1935 buff.str(pluralise(buff.str()));
1937 // debugging output -- oops, I probably block it above ... dang! {dlb}
1938 if (buff.str().length() < 3)
1940 buff << "bad item (cl:" << static_cast<int>(base_type)
1941 << ",ty:" << item_typ << ",pl:" << plus
1942 << ",pl2:" << plus2 << ",sp:" << special
1943 << ",qu:" << quantity << ")";
1949 // WARNING: You can break save compatibility if you edit this without
1950 // amending tags.cc to properly marshall the change.
1951 bool item_type_has_ids(object_class_type base_type)
1953 COMPILE_CHECK(NUM_WEAPONS < MAX_SUBTYPES);
1954 COMPILE_CHECK(NUM_MISSILES < MAX_SUBTYPES);
1955 COMPILE_CHECK(NUM_ARMOURS < MAX_SUBTYPES);
1956 COMPILE_CHECK(NUM_WANDS < MAX_SUBTYPES);
1957 COMPILE_CHECK(NUM_SCROLLS < MAX_SUBTYPES);
1958 COMPILE_CHECK(NUM_JEWELLERY < MAX_SUBTYPES);
1959 COMPILE_CHECK(NUM_POTIONS < MAX_SUBTYPES);
1960 COMPILE_CHECK(NUM_BOOKS < MAX_SUBTYPES);
1961 COMPILE_CHECK(NUM_STAVES < MAX_SUBTYPES);
1962 COMPILE_CHECK(NUM_MISCELLANY < MAX_SUBTYPES);
1963 #if TAG_MAJOR_VERSION == 34
1964 COMPILE_CHECK(NUM_RODS < MAX_SUBTYPES);
1965 COMPILE_CHECK(NUM_FOODS < MAX_SUBTYPES);
1968 return base_type == OBJ_WANDS || base_type == OBJ_SCROLLS
1969 || base_type == OBJ_JEWELLERY || base_type == OBJ_POTIONS
1970 || base_type == OBJ_STAVES || base_type == OBJ_BOOKS;
1973 bool item_brand_known(const item_def& item)
1975 return item_ident(item, ISFLAG_KNOW_TYPE)
1976 || is_artefact(item)
1977 && artefact_known_property(item, ARTP_BRAND);
1980 bool item_type_known(const item_def& item)
1982 if (item_ident(item, ISFLAG_KNOW_TYPE))
1985 // Artefacts have different descriptions from other items,
1986 // so we can't use general item knowledge for them.
1987 if (is_artefact(item))
1990 if (item.base_type == OBJ_MISSILES)
1993 if (item.base_type == OBJ_MISCELLANY)
1996 #if TAG_MAJOR_VERSION == 34
1997 if (item.is_type(OBJ_BOOKS, BOOK_BUGGY_DESTRUCTION))
2001 if (item.is_type(OBJ_BOOKS, BOOK_MANUAL))
2004 if (!item_type_has_ids(item.base_type))
2006 return you.type_ids[item.base_type][item.sub_type];
2009 bool item_type_unknown(const item_def& item)
2011 if (item_type_known(item))
2014 if (is_artefact(item))
2017 return item_type_has_ids(item.base_type);
2020 bool item_type_known(const object_class_type base_type, const int sub_type)
2022 if (!item_type_has_ids(base_type))
2024 return you.type_ids[base_type][sub_type];
2027 bool set_ident_type(item_def &item, bool identify)
2029 if (is_artefact(item) || crawl_state.game_is_arena())
2032 if (!set_ident_type(item.base_type, item.sub_type, identify))
2035 if (in_inventory(item))
2037 shopping_list.cull_identical_items(item);
2039 item_skills(item, you.skills_to_show);
2042 if (identify && notes_are_active()
2043 && is_interesting_item(item)
2044 && !(item.flags & (ISFLAG_NOTED_ID | ISFLAG_NOTED_GET)))
2046 // Make a note of it.
2047 take_note(Note(NOTE_ID_ITEM, 0, 0, item.name(DESC_A),
2048 origin_desc(item)));
2050 // Sometimes (e.g. shops) you can ID an item before you get it;
2051 // don't note twice in those cases.
2052 item.flags |= (ISFLAG_NOTED_ID | ISFLAG_NOTED_GET);
2058 bool set_ident_type(object_class_type basetype, int subtype, bool identify)
2060 if (!item_type_has_ids(basetype))
2063 if (you.type_ids[basetype][subtype] == identify)
2066 you.type_ids[basetype][subtype] = identify;
2067 request_autoinscribe();
2069 // Our item knowledge changed in a way that could possibly affect shop
2071 shopping_list.item_type_identified(basetype, subtype);
2073 // We identified something, maybe we identified other things by process of
2075 if (identify && !(you.pending_revival || crawl_state.updating_scores))
2076 _maybe_identify_pack_item();
2081 void pack_item_identify_message(int base_type, int sub_type)
2083 for (const auto &item : you.inv)
2084 if (item.defined() && item.is_type(base_type, sub_type))
2085 mprf_nocap("%s", item.name(DESC_INVENTORY_EQUIP).c_str());
2088 bool get_ident_type(const item_def &item)
2090 if (is_artefact(item))
2093 return get_ident_type(item.base_type, item.sub_type);
2096 bool get_ident_type(object_class_type basetype, int subtype)
2098 if (!item_type_has_ids(basetype))
2100 ASSERT(subtype < MAX_SUBTYPES);
2101 return you.type_ids[basetype][subtype];
2104 static MenuEntry* _fixup_runeorb_entry(MenuEntry* me)
2106 auto entry = static_cast<InvEntry*>(me);
2109 if (entry->item->base_type == OBJ_RUNES)
2111 auto rune = static_cast<rune_type>(entry->item->sub_type);
2113 // Make Gloorx's rune more distinguishable from uncollected runes.
2114 if (you.runes[rune])
2116 colour = (rune == RUNE_GLOORX_VLOQ) ? colour_t{LIGHTGREY}
2117 : rune_colour(rune);
2123 text += colour_to_str(colour);
2125 text += rune_type_name(rune);
2126 text += " rune of Zot";
2127 if (!you.runes[rune])
2130 text += branches[rune_location(rune)].longname;
2134 text += colour_to_str(colour);
2138 else if (entry->item->is_type(OBJ_ORBS, ORB_ZOT))
2140 if (player_has_orb())
2141 entry->text = "<magenta>The Orb of Zot</magenta>";
2144 entry->text = "<darkgrey>The Orb of Zot"
2145 " (the Realm of Zot)</darkgrey>";
2152 void display_runes()
2154 auto col = runes_in_pack() < ZOT_ENTRY_RUNES ? "lightgrey" :
2155 runes_in_pack() < you.obtainable_runes ? "green" :
2158 auto title = make_stringf("<white>Runes of Zot (</white>"
2159 "<%s>%d</%s><white> collected) & Orbs of Power</white>",
2160 col, runes_in_pack(), col);
2162 InvMenu menu(MF_NOSELECT | MF_ALLOW_FORMATTING);
2164 menu.set_title(title);
2166 vector<item_def> items;
2168 if (!crawl_state.game_is_sprint())
2170 // Add the runes in order of challenge (semi-arbitrary).
2171 for (branch_iterator it(branch_iterator_type::danger); it; ++it)
2173 const branch_type br = it->id;
2174 if (!connected_branch_can_exist(br))
2177 for (auto rune : branches[br].runes)
2180 item.base_type = OBJ_RUNES;
2181 item.sub_type = rune;
2182 item.quantity = you.runes[rune] ? 1 : 0;
2184 items.push_back(item);
2190 // We don't know what runes are accessible in the sprint, so just show
2191 // the ones you have. We can't iterate over branches as above since the
2192 // elven rune and mossy rune may exist in sprint.
2193 for (int i = 0; i < NUM_RUNE_TYPES; ++i)
2198 item.base_type = OBJ_RUNES;
2202 items.push_back(item);
2207 item.base_type = OBJ_ORBS;
2208 item.sub_type = ORB_ZOT;
2209 item.quantity = player_has_orb() ? 1 : 0;
2210 items.push_back(item);
2212 // We've sorted this vector already, so disable menu sorting. Maybe we
2213 // could a menu entry comparator and modify InvMenu::load_items() to allow
2214 // passing this in instead of doing a sort ahead of time.
2215 menu.load_items(items, _fixup_runeorb_entry, 0, false);
2220 // Seed ranges for _random_consonant_set: (B)eginning and one-past-the-(E)nd
2221 // of the (B)eginning, (E)nding, and (M)iddle cluster ranges.
2222 const size_t RCS_BB = 0;
2223 const size_t RCS_EB = 27;
2224 const size_t RCS_BE = 14;
2225 const size_t RCS_EE = 56;
2226 const size_t RCS_BM = 0;
2227 const size_t RCS_EM = 67;
2228 const size_t RCS_END = RCS_EM;
2230 #define ITEMNAME_SIZE 200
2232 * Make a random name from the given seed.
2234 * Used for: Pandemonium demonlords, shopkeepers, scrolls, random artefacts.
2236 * This function is insane, but that might be useful.
2238 * @param seed The seed to generate the name from.
2239 * The same seed will always generate the same name.
2240 * By default a random number from the current RNG.
2241 * @param name_type The type of name to be generated.
2242 * If MNAME_SCROLL, increase length by 6 and force to allcaps.
2243 * If MNAME_JIYVA, start with J, do not generate spaces,
2244 * recurse instead of ploggifying, and cap length at 8.
2245 * Otherwise, no special behaviour.
2246 * @return A randomly generated name.
2247 * E.g. "Joiduir", "Jays Fya", ZEFOKY WECZYXE,
2248 * THE GIAGGOSTUONO, etc.
2250 string make_name(uint32_t seed, makename_type name_type)
2252 // use the seed to select sequence, rather than seed per se. This is
2253 // because it is not important that the sequence be randomly distributed
2255 rng::subgenerator subgen(you.game_seed, static_cast<uint64_t>(seed));
2259 bool has_space = false; // Keep track of whether the name contains a space.
2263 len += (random2(5) == 0) ? random2(6) : 1;
2265 if (name_type == MNAME_SCROLL) // scrolls have longer names
2268 const size_t maxlen = name_type == MNAME_JIYVA ? 8 : SIZE_MAX;
2269 len = min(len, maxlen);
2271 ASSERT_RANGE(len, 1, ITEMNAME_SIZE + 1);
2273 static const int MAX_ITERS = 150;
2274 for (int iters = 0; iters < MAX_ITERS && name.length() < len; ++iters)
2276 const char prev_char = name.length() ? name[name.length() - 1]
2278 const char penult_char = name.length() > 1 ? name[name.length() - 2]
2280 if (name.empty() && name_type == MNAME_JIYVA)
2282 // Start the name with a predefined letter.
2285 else if (name.empty() || prev_char == ' ')
2287 // Start the word with any letter.
2288 name += 'a' + random2(26);
2290 else if (!has_space && name_type != MNAME_JIYVA
2291 && name.length() > 5 && name.length() < len - 4
2292 && random2(5) != 0) // 4/5 chance
2294 // Hand out a space.
2297 else if (name.length()
2298 && (_is_consonant(prev_char)
2299 || (name.length() > 1
2300 && !_is_consonant(prev_char)
2301 && _is_consonant(penult_char)
2302 && random2(5) <= 1))) // 2/5
2305 const char vowel = _random_vowel();
2310 || name.length() <= 2 || name.length() >= len - 3
2311 || prev_char == ' ' || penult_char == ' '
2312 || name_type == MNAME_JIYVA
2313 || name.length() > 2
2314 && _is_consonant(prev_char)
2315 && _is_consonant(penult_char))
2317 // Replace the space with something else if ...
2318 // * the name is really short
2319 // * we're close to the start/end of the name
2320 // * we just got a space
2321 // * we're generating a jiyva name, or
2322 // * the last two letters were consonants
2326 else if (name.length() > 1
2327 && vowel == prev_char
2328 && (vowel == 'y' || vowel == 'i'
2329 || random2(5) <= 1))
2331 // Replace the vowel with something else if the previous
2332 // letter was the same, and it's a 'y', 'i' or with 2/5 chance.
2338 else // We want a consonant.
2340 // Are we at start or end of the (sub) name?
2341 const bool beg = (name.empty() || prev_char == ' ');
2342 const bool end = (name.length() >= len - 2);
2344 // Use one of number of predefined letter combinations.
2345 if ((len > 3 || !name.empty())
2346 && random2(7) <= 1 // 2/7 chance
2349 const int first = (beg ? RCS_BB : (end ? RCS_BE : RCS_BM));
2350 const int last = (beg ? RCS_EB : (end ? RCS_EE : RCS_EM));
2352 const int range = last - first;
2354 const int cons_seed = random2(range) + first;
2356 const string consonant_set = _random_consonant_set(cons_seed);
2358 ASSERT(consonant_set.size() > 1);
2359 len += consonant_set.size() - 2; // triples increase len
2360 name += consonant_set;
2362 else // Place a single letter instead.
2364 // Pick a random consonant.
2365 name += _random_cons();
2369 if (name[name.length() - 1] == ' ')
2371 ASSERT(name_type != MNAME_JIYVA);
2376 // Catch early exit and try to give a final letter.
2377 const char last_char = name[name.length() - 1];
2381 && !_is_consonant(name[name.length() - 1])
2382 && (name.length() < len // early exit
2384 && random2(3) != 0))) // 2/3 chance for other short names
2386 // Specifically, add a consonant.
2387 name += _random_cons();
2390 if (maxlen != SIZE_MAX)
2391 name = chop_string(name, maxlen);
2392 trim_string_right(name);
2394 // Fallback if the name was too short.
2395 if (name.length() < 4)
2397 // convolute & recurse
2398 if (name_type == MNAME_JIYVA)
2399 return make_name(rng::get_uint32(), MNAME_JIYVA);
2404 string uppercased_name;
2405 for (size_t i = 0; i < name.length(); i++)
2407 if (name_type == MNAME_JIYVA)
2408 ASSERT(name[i] != ' ');
2410 if (name_type == MNAME_SCROLL || i == 0 || name[i - 1] == ' ')
2411 uppercased_name += toupper_safe(name[i]);
2413 uppercased_name += name[i];
2416 return uppercased_name;
2418 #undef ITEMNAME_SIZE
2421 * Is the given character a lower-case ascii consonant?
2423 * For our purposes, y is not a consonant.
2425 static bool _is_consonant(char let)
2427 static const set<char> all_consonants = { 'b', 'c', 'd', 'f', 'g',
2428 'h', 'j', 'k', 'l', 'm',
2429 'n', 'p', 'q', 'r', 's',
2430 't', 'v', 'w', 'x', 'z' };
2431 return all_consonants.count(let);
2434 // Returns a random vowel (a, e, i, o, u with equal probability) or space
2435 // or 'y' with lower chances.
2436 static char _random_vowel()
2438 static const char vowels[] = "aeiouaeiouaeiouy ";
2439 return vowels[random2(sizeof(vowels) - 1)];
2442 // Returns a random consonant with not quite equal probability.
2443 // Does not include 'y'.
2444 static char _random_cons()
2446 static const char consonants[] = "bcdfghjklmnpqrstvwxzcdfghlmnrstlmnrst";
2447 return consonants[random2(sizeof(consonants) - 1)];
2451 * Choose a random consonant tuple/triple, based on the given seed.
2453 * @param seed The index into the consonant array; different seed ranges are
2454 * expected to correspond with the place in the name being
2455 * generated where the consonants should be inserted.
2456 * @return A random length 2 or 3 consonant set; e.g. "kl", "str", etc.
2457 * If the seed is out of bounds, return "";
2459 static string _random_consonant_set(size_t c)
2461 // Pick a random combination of consonants from the set below.
2462 // begin -> [RCS_BB, RCS_EB) = [ 0, 27)
2463 // middle -> [RCS_BM, RCS_EM) = [ 0, 67)
2464 // end -> [RCS_BE, RCS_EE) = [14, 56)
2466 static const string consonant_sets[] = {
2467 // 0-13: start, middle
2468 "kl", "gr", "cl", "cr", "fr",
2469 "pr", "tr", "tw", "br", "pl",
2470 "bl", "str", "shr", "thr",
2471 // 14-26: start, middle, end
2472 "sm", "sh", "ch", "th", "ph",
2473 "pn", "kh", "gh", "mn", "ps",
2475 // 27-55: middle, end
2476 "ts", "cs", "xt", "nt", "ll",
2477 "rr", "ss", "wk", "wn", "ng",
2478 "cw", "mp", "ck", "nk", "dd",
2479 "tt", "bb", "pp", "nn", "mm",
2480 "kk", "gg", "ff", "pt", "tz",
2481 "dgh", "rgh", "rph", "rch",
2482 // 56-66: middle only
2483 "cz", "xk", "zx", "xz", "cv",
2484 "vv", "nl", "rh", "dw", "nw",
2487 COMPILE_CHECK(ARRAYSZ(consonant_sets) == RCS_END);
2489 ASSERT_RANGE(c, 0, ARRAYSZ(consonant_sets));
2491 return consonant_sets[c];
2495 * Write all possible scroll names to the given file.
2497 static void _test_scroll_names(const string& fname)
2499 FILE *f = fopen(fname.c_str(), "w");
2501 sysfail("can't write test output");
2504 for (int i = 0; i < 151; i++)
2506 for (int j = 0; j < 151; j++)
2508 const int seed = i | (j << 8) | (OBJ_SCROLLS << 16);
2509 const string name = make_name(seed, MNAME_SCROLL);
2510 if (name.length() > longest.length())
2512 fprintf(f, "%s\n", name.c_str());
2516 fprintf(f, "\nLongest: %s (%d)\n", longest.c_str(), (int)longest.length());
2522 * Write one million random Jiyva names to the given file.
2524 static void _test_jiyva_names(const string& fname)
2526 FILE *f = fopen(fname.c_str(), "w");
2528 sysfail("can't write test output");
2532 for (int i = 0; i < 1000000; i++)
2534 const string name = make_name(rng::get_uint32(), MNAME_JIYVA);
2535 ASSERT(name[0] == 'J');
2536 if (name.length() > longest.length())
2538 fprintf(f, "%s\n", name.c_str());
2541 fprintf(f, "\nLongest: %s (%d)\n", longest.c_str(), (int)longest.length());
2549 * Currently just a stress test iterating over all possible scroll names.
2551 void make_name_tests()
2553 _test_jiyva_names("jiyva_names.out");
2554 _test_scroll_names("scroll_names.out");
2557 for (int i = 0; i < 1000000; ++i)
2561 bool is_interesting_item(const item_def& item)
2563 if (fully_identified(item) && is_artefact(item))
2566 const string iname = item_prefix(item, false) + " " + item.name(DESC_PLAIN);
2567 for (const text_pattern &pat : Options.note_items)
2568 if (pat.matches(iname))
2575 * Is an item a potentially life-saving consumable in emergency situations?
2576 * Unlike similar functions, this one never takes temporary conditions into
2577 * account. It does, however, take religion and mutations into account.
2578 * Permanently unusable items are in general not considered emergency items.
2580 * @param item The item being queried.
2581 * @return True if the item is known to be an emergency item.
2583 bool is_emergency_item(const item_def &item)
2585 if (!item_type_known(item))
2588 switch (item.base_type)
2591 switch (item.sub_type)
2593 case SCR_TELEPORTATION:
2595 return you.species != SP_FORMICID;
2603 if (you.species == SP_MUMMY)
2606 switch (item.sub_type)
2609 return !have_passive(passive_t::no_haste)
2610 && you.species != SP_FORMICID;
2611 case POT_HEAL_WOUNDS:
2612 return you.can_potion_heal();
2614 case POT_RESISTANCE:
2626 * Is an item a particularly good consumable? Unlike similar functions,
2627 * this one never takes temporary conditions into account. Permanently
2628 * unusable items are in general not considered good.
2630 * @param item The item being queried.
2631 * @return True if the item is known to be good.
2633 bool is_good_item(const item_def &item)
2635 if (!item_type_known(item))
2638 if (is_emergency_item(item))
2641 switch (item.base_type)
2644 return item.sub_type == SCR_ACQUIREMENT;
2646 if (you.species == SP_MUMMY)
2648 switch (item.sub_type)
2650 case POT_EXPERIENCE:
2654 CASE_REMOVED_POTIONS(item.sub_type)
2662 * Is an item strictly harmful?
2664 * @param item The item being queried.
2665 * @return True if the item is known to have only harmful effects.
2667 bool is_bad_item(const item_def &item)
2669 if (!item_type_known(item))
2672 switch (item.base_type)
2675 switch (item.sub_type)
2677 #if TAG_MAJOR_VERSION == 34
2678 case SCR_CURSE_ARMOUR:
2679 case SCR_CURSE_WEAPON:
2680 if (you.species == SP_FELID)
2682 case SCR_CURSE_JEWELLERY:
2683 return !have_passive(passive_t::want_curses);
2691 // Can't be bad if you can't use them.
2692 if (you.species == SP_MUMMY)
2695 switch (item.sub_type)
2697 case POT_DEGENERATION:
2701 CASE_REMOVED_POTIONS(item.sub_type);
2704 // Potentially useful. TODO: check the properties.
2705 if (is_artefact(item))
2708 switch (item.sub_type)
2710 case AMU_INACCURACY:
2711 case RING_ATTENTION:
2713 case RING_TELEPORTATION:
2714 return !(you.stasis() || crawl_state.game_is_sprint());
2716 case RING_PROTECTION:
2718 case RING_DEXTERITY:
2719 case RING_INTELLIGENCE:
2721 return item_ident(item, ISFLAG_KNOW_PLUSES) && item.plus <= 0;
2732 * Is an item dangerous but potentially worthwhile?
2734 * @param item The item being queried.
2735 * @param temp Should temporary conditions such as transformations and
2736 * vampire state be taken into account? Religion (but
2737 * not its absence) is considered to be permanent here.
2738 * @return True if using the item is known to be risky but occasionally
2741 bool is_dangerous_item(const item_def &item, bool temp)
2743 if (!item_type_known(item))
2746 // useless items can hardly be dangerous.
2747 if (is_useless_item(item, temp))
2750 switch (item.base_type)
2753 switch (item.sub_type)
2755 case SCR_IMMOLATION:
2756 case SCR_VULNERABILITY:
2759 return !you.get_mutation_level(MUT_TORMENT_RESISTANCE)
2760 || !temp && you.species == SP_VAMPIRE;
2762 return you.undead_or_demonic();
2768 switch (item.sub_type)
2771 if (have_passive(passive_t::cleanse_mut_potions))
2773 // intentional fallthrough
2775 case POT_ATTRACTION:
2781 case OBJ_MISCELLANY:
2782 // Tremorstones will blow you right up.
2783 return item.sub_type == MISC_TIN_OF_TREMORSTONES;
2786 if (you.get_mutation_level(MUT_NO_LOVE)
2787 && is_unrandom_artefact(item, UNRAND_RATSKIN_CLOAK))
2789 // some people don't like being randomly attacked by rats.
2790 // weird but what can you do.
2794 // Tilting at windmills can be dangerous.
2795 return get_armour_ego_type(item) == SPARM_RAMPAGING;
2802 static bool _invisibility_is_useless(const bool temp)
2804 // If you're Corona'd or a TSO-ite, this is always useless.
2805 return temp ? you.backlit()
2806 : you.haloed() && will_have_passive(passive_t::halo);
2810 * Is an item (more or less) useless to the player? Uselessness includes
2811 * but is not limited to situations such as:
2812 * \li The item cannot be used.
2813 * \li Using the item would have no effect.
2814 * \li Using the item would have purely negative effects (<tt>is_bad_item</tt>).
2815 * \li Using the item is expected to produce no benefit for a player of their
2816 * religious standing. For example, magic enhancers for Trog worshippers
2817 * are "useless", even if the player knows a spell and therefore could
2820 * @param item The item being queried.
2821 * @param temp Should temporary conditions such as transformations and
2822 * vampire state be taken into account? Religion (but
2823 * not its absence) is considered to be permanent here.
2824 * @param ident Should uselessness be checked as if the item were already
2826 * @return True if the item is known to be useless.
2828 bool is_useless_item(const item_def &item, bool temp, bool ident)
2830 // During game startup, no item is useless. If someone re-glyphs an item
2831 // based on its uselessness, the glyph-to-item cache will use the useless
2832 // value even if your god or species can make use of it.
2833 if (you.species == SP_UNKNOWN)
2836 switch (item.base_type)
2839 if (you.species == SP_FELID)
2842 if (!you.could_wield(item, true, !temp)
2843 && !is_throwable(&you, item))
2845 // Weapon is too large (or small) to be wielded and cannot
2846 // be thrown either.
2850 if (you.undead_or_demonic() && is_holy_item(item, false))
2852 if (!temp && you.form == transformation::lich
2853 && you.species != SP_DEMONSPAWN)
2863 if ((you.has_spell(SPELL_SANDBLAST)
2864 || !you.num_turns && you.char_class == JOB_EARTH_ELEMENTALIST)
2865 && item.sub_type == MI_STONE)
2870 // Save for the above spells, all missiles are useless for felids.
2871 if (you.species == SP_FELID)
2874 // These are the same checks as in is_throwable(), except that
2875 // we don't take launchers into account.
2876 switch (item.sub_type)
2879 return !you.can_throw_large_rocks();
2881 return you.body_size(PSIZE_BODY, !temp) < SIZE_MEDIUM
2882 && !you.can_throw_large_rocks();
2888 if (!can_wear_armour(item, false, true))
2891 if (is_shield(item) && you.get_mutation_level(MUT_MISSING_HAND))
2894 if (is_artefact(item))
2897 if (item.sub_type == ARM_SCARF && (ident || item_type_known(item)))
2899 special_armour_type ego = get_armour_ego_type(item);
2902 case SPARM_SPIRIT_SHIELD:
2903 return you.spirit_shield(false, false);
2904 case SPARM_REPULSION:
2905 return temp && have_passive(passive_t::upgraded_storm_shield)
2906 || you.get_mutation_level(MUT_DISTORTION_FIELD) == 3;
2914 if (temp && silenced(you.pos()))
2915 return true; // can't use scrolls while silenced
2917 if (!ident && !item_type_known(item))
2920 // A bad item is always useless.
2921 if (is_bad_item(item))
2924 switch (item.sub_type)
2926 case SCR_RANDOM_USELESSNESS:
2928 case SCR_TELEPORTATION:
2929 return you.species == SP_FORMICID
2930 || crawl_state.game_is_sprint()
2931 || player_in_branch(BRANCH_GAUNTLET);
2933 return you.species == SP_FORMICID;
2935 return you_worship(GOD_TROG);
2936 #if TAG_MAJOR_VERSION == 34
2937 case SCR_CURSE_WEAPON: // for non-Ashenzari, already handled
2938 case SCR_CURSE_ARMOUR:
2940 case SCR_ENCHANT_WEAPON:
2941 case SCR_ENCHANT_ARMOUR:
2942 case SCR_BRAND_WEAPON:
2943 return you.species == SP_FELID;
2945 return you.get_mutation_level(MUT_NO_LOVE) > 0;
2947 return temp && (env.level_state & LSTATE_STILL_WINDS);
2953 if (you.get_mutation_level(MUT_NO_ARTIFICE))
2956 #if TAG_MAJOR_VERSION == 34
2957 if (is_known_empty_wand(item))
2960 if (!ident && !item_type_known(item))
2963 if (item.sub_type == WAND_ENSLAVEMENT)
2964 return you.get_mutation_level(MUT_NO_LOVE);
2970 // Mummies and liches can't use potions.
2971 if (you.undead_state(temp) == US_UNDEAD && you.species != SP_GHOUL)
2974 if (!ident && !item_type_known(item))
2977 // A bad item is always useless.
2978 if (is_bad_item(item))
2981 switch (item.sub_type)
2983 case POT_BERSERK_RAGE:
2984 return !you.can_go_berserk(true, true, true, nullptr, temp);
2986 return you.stasis();
2988 return !you.can_safely_mutate(temp);
2991 return you.undead_state(temp)
2992 && (you.species != SP_VAMPIRE
2993 || temp && !you.vampire_alive);
2996 return you.permanent_flight()
2997 || you.racial_permanent_flight();
2998 case POT_HEAL_WOUNDS:
2999 return !you.can_potion_heal();
3000 case POT_INVISIBILITY:
3001 return _invisibility_is_useless(temp);
3002 case POT_BRILLIANCE:
3003 return you_worship(GOD_TROG);
3004 case POT_ATTRACTION:
3006 CASE_REMOVED_POTIONS(item.sub_type)
3012 if (!ident && !item_type_known(item))
3015 // Potentially useful. TODO: check the properties.
3016 if (is_artefact(item))
3019 if (is_bad_item(item))
3022 switch (item.sub_type)
3024 case RING_RESIST_CORROSION:
3025 return you.res_corr(false, false);
3028 return (you.species == SP_DEMIGOD && !you.religion)
3029 || you_worship(GOD_GOZAG)
3030 || (you_worship(GOD_RU) && you.piety == piety_breakpoint(5));
3032 case AMU_GUARDIAN_SPIRIT:
3033 return you.spirit_shield(false, false);
3035 case RING_LIFE_PROTECTION:
3036 return player_prot_life(false, temp, false) == 3;
3038 case AMU_REGENERATION:
3039 return you.get_mutation_level(MUT_NO_REGENERATION) > 0
3041 && (you.get_mutation_level(MUT_INHIBITED_REGENERATION) > 0
3042 || you.species == SP_VAMPIRE)
3043 && regeneration_is_inhibited());
3045 #if TAG_MAJOR_VERSION == 34
3046 case AMU_MANA_REGENERATION:
3047 return you_worship(GOD_PAKELLAS);
3050 case RING_SEE_INVISIBLE:
3051 return you.innate_sinv();
3053 case RING_POISON_RESISTANCE:
3054 return player_res_poison(false, temp, false) > 0
3055 && (temp || you.species != SP_VAMPIRE);
3058 return you_worship(GOD_TROG);
3060 case RING_TELEPORTATION:
3061 return !is_bad_item(item);
3064 return you.permanent_flight()
3065 || you.racial_permanent_flight()
3066 || you.get_mutation_level(MUT_NO_ARTIFICE);
3069 return you.get_mutation_level(MUT_NO_STEALTH);
3075 #if TAG_MAJOR_VERSION == 34
3081 if (you.species == SP_FELID)
3083 if (!you.could_wield(item, true, !temp))
3085 // Weapon is too large (or small) to be wielded and cannot
3086 // be thrown either.
3089 if (!ident && !item_type_known(item))
3095 if (you.has_spell(SPELL_ANIMATE_DEAD)
3096 || you.has_spell(SPELL_ANIMATE_SKELETON)
3097 || you.has_spell(SPELL_SIMULACRUM)
3098 || you_worship(GOD_YREDELEMNUL) && !you.penance[GOD_YREDELEMNUL]
3099 && you.piety >= piety_breakpoint(0))
3106 case OBJ_MISCELLANY:
3107 switch (item.sub_type)
3109 #if TAG_MAJOR_VERSION == 34
3110 case MISC_BUGGY_EBONY_CASKET:
3111 return item_type_known(item);
3113 // These can always be used.
3114 #if TAG_MAJOR_VERSION == 34
3115 case MISC_BUGGY_LANTERN_OF_SHADOWS:
3120 // Purely summoning misc items don't work w/ sac love
3121 case MISC_BOX_OF_BEASTS:
3122 case MISC_HORN_OF_GERYON:
3123 case MISC_PHANTOM_MIRROR:
3124 return you.get_mutation_level(MUT_NO_LOVE)
3125 || you.get_mutation_level(MUT_NO_ARTIFICE);
3127 case MISC_CONDENSER_VANE:
3128 if (temp && (env.level_state & LSTATE_STILL_WINDS))
3130 // Intentional fallthrough to check artifice
3133 return you.get_mutation_level(MUT_NO_ARTIFICE);
3137 if (!ident && !item_type_known(item))
3139 if (item_type_known(item) && item.sub_type != BOOK_MANUAL)
3141 // Spellbooks are useless if all spells are either in the library
3142 // already or are uncastable.
3143 bool useless = true;
3144 for (spell_type st : spells_in_book(item))
3145 if (!you.spell_library[st] && you_can_memorise(st))
3149 // If we're here, it's a manual.
3150 if (you.skills[item.plus] >= 27)
3152 if (is_useless_skill((skill_type)item.plus))
3162 string item_prefix(const item_def &item, bool temp)
3164 vector<const char *> prefixes;
3166 if (!item.defined())
3169 if (fully_identified(item))
3170 prefixes.push_back("identified");
3171 else if (item_ident(item, ISFLAG_KNOW_TYPE)
3172 || get_ident_type(item))
3174 prefixes.push_back("known");
3177 prefixes.push_back("unidentified");
3179 // Sometimes this is abbreviated out of the item name.
3180 if (item_type_has_curses(item.base_type)
3181 && item_ident(item, ISFLAG_KNOW_CURSE) && !item.cursed())
3183 prefixes.push_back("uncursed");
3186 if (god_hates_item(item))
3188 prefixes.push_back("evil_item");
3189 prefixes.push_back("forbidden");
3192 if (is_emergency_item(item))
3193 prefixes.push_back("emergency_item");
3194 if (is_good_item(item))
3195 prefixes.push_back("good_item");
3196 if (is_dangerous_item(item, temp))
3197 prefixes.push_back("dangerous_item");
3198 if (is_bad_item(item))
3199 prefixes.push_back("bad_item");
3200 if (is_useless_item(item, temp))
3201 prefixes.push_back("useless_item");
3203 if (item_is_stationary(item))
3204 prefixes.push_back("stationary");
3206 switch (item.base_type)
3210 if (is_range_weapon(item))
3211 prefixes.push_back("ranged");
3212 else if (is_melee_weapon(item)) // currently redundant
3213 prefixes.push_back("melee");
3218 if (is_artefact(item))
3219 prefixes.push_back("artefact");
3223 if (item_is_equipped(item, true))
3224 prefixes.push_back("equipped");
3228 if (item.sub_type != BOOK_MANUAL && item.sub_type != NUM_BOOKS)
3229 prefixes.push_back("spellbook");
3236 prefixes.push_back(item_class_name(item.base_type, true));
3238 string result = comma_separated_line(prefixes.begin(), prefixes.end(),
3245 * Return an item's name surrounded by colour tags, using menu colouring
3247 * @param item The item being queried
3248 * @param desc The description level to use for the name string
3249 * @return A string containing the item's name surrounded by colour tags
3251 string menu_colour_item_name(const item_def &item, description_level_type desc)
3253 const string cprf = item_prefix(item);
3254 const string item_name = item.name(desc);
3256 const int col = menu_colour(item_name, cprf, "pickup");
3260 const string colour = colour_to_str(col);
3261 const char * const colour_z = colour.c_str();
3262 return make_stringf("<%s>%s</%s>", colour_z, item_name.c_str(), colour_z);
3265 typedef map<string, item_kind> item_names_map;
3266 static item_names_map item_names_cache;
3268 typedef map<unsigned, vector<string> > item_names_by_glyph_map;
3269 static item_names_by_glyph_map item_names_by_glyph_cache;
3271 void init_item_name_cache()
3273 item_names_cache.clear();
3274 item_names_by_glyph_cache.clear();
3276 for (int i = 0; i < NUM_OBJECT_CLASSES; i++)
3278 const object_class_type base_type = static_cast<object_class_type>(i);
3280 for (const auto sub_type : all_item_subtypes(base_type))
3282 if (base_type == OBJ_BOOKS)
3284 if (sub_type == BOOK_RANDART_LEVEL
3285 || sub_type == BOOK_RANDART_THEME)
3287 // These are randart only and have no fixed names.
3293 if (base_type == OBJ_BOOKS && sub_type == BOOK_MANUAL)
3294 npluses = NUM_SKILLS;
3297 item.base_type = base_type;
3298 item.sub_type = sub_type;
3299 for (int plus = 0; plus <= npluses; plus++)
3302 item.plus = max(0, plus - 1);
3303 string name = item.name(plus || item.base_type == OBJ_RUNES ? DESC_PLAIN : DESC_DBNAME,
3306 cglyph_t g = get_item_glyph(item);
3308 if (base_type == OBJ_JEWELLERY && sub_type >= NUM_RINGS
3309 && sub_type < AMU_FIRST_AMULET)
3313 else if (name.find("buggy") != string::npos)
3315 mprf(MSGCH_ERROR, "Bad name for item name cache: %s",
3320 if (!item_names_cache.count(name))
3322 item_names_cache[name] = { base_type, (uint8_t)sub_type,
3323 (int8_t)item.plus, 0 };
3325 item_names_by_glyph_cache[g.ch].push_back(name);
3331 ASSERT(!item_names_cache.empty());
3334 item_kind item_kind_by_name(const string &name)
3336 return lookup(item_names_cache, lowercase_string(name),
3337 { OBJ_UNASSIGNED, 0, 0, 0 });
3340 vector<string> item_name_list_for_glyph(char32_t glyph)
3342 return lookup(item_names_by_glyph_cache, glyph, {});
3345 bool is_named_corpse(const item_def &corpse)
3347 ASSERT(corpse.base_type == OBJ_CORPSES);
3349 return corpse.props.exists(CORPSE_NAME_KEY);
3352 string get_corpse_name(const item_def &corpse, monster_flags_t *name_type)
3354 ASSERT(corpse.base_type == OBJ_CORPSES);
3356 if (!corpse.props.exists(CORPSE_NAME_KEY))
3359 if (name_type != nullptr)
3360 name_type->flags = corpse.props[CORPSE_NAME_TYPE_KEY].get_int64();
3362 return corpse.props[CORPSE_NAME_KEY].get_string();