as well as a few features. A bit of a clean-up and a few additions.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2001 c06c8d41-db1a-0410-9941-cceddc491573
ESWIM76FGJL4QFLSHU6AC4D74PT7OPLQ7ZCJYWLZS5UCBAJDXYHAC RSIUBEQUGNU4LO6KH4PKVROWQS33DAKSY4XFVGN7T3CEKSXABCSAC U3KGUJJQWQORJIIFH3ADVNIEEX5HOX6KEOXO7DJSL7L3Z6GG3PAQC IXVKL2SINZN4DMJSZSYFVK5YLGSBGV4KCN7GKYQL7SZQDCM3S7YQC JWOMWPRTOIUVAA3TLIGSB4HVFINNUDTKO2TKVAUCXE26G3KTKYOAC TZ643KHSE5CUPXFSQ7VYVOCM5MTQ7F4SENEYQX2RNFHGHLQVS3RQC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC X3RDT655FEYO6XEVPIUAPEPJZAFE55KZBH2AZOLK3NGHINMVIGFQC 2N5AKUYV6EUUT254C47WSHZKD7FGN65JKJ3RCKSDP74XJIHIFMDQC 77H4BWWPPGLM3PLZH4QTAJRXIZTSDVNCOKZE223I437FN2UJ34RQC 7NDXS36TE7QVXTXJWMYSVG5UHCCLPIO4VL6NXFGTDK3ZNKE3A2IAC XRZPPYWPWUOM4SFNI6BHKH2UKJQNLKOV6Y7XIEPEZXE5QYRT26PAC HYS3HXTXATFPN7GLN3WBGDCP22UT2D3JBVUS7SP5FE7L54TDCJRQC TRNEOO3YKZSUGYTJZDDXZTJFQJXY6PWKBDJXAOLY3FZAD6WHTUTQC 6HQB2N6N75R2RGKJFWRUN7WAC2PNGWQFXTII5DTRLTHZ2BOTMTVAC RCU52DRCPWJVQ6HME4QR6V6EVQWTBKZTPWDI47UGUDAUBPOO5YNAC SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC IHIJSWVOONSTA2WCHKW3YKBLETUQECFVBVLMET5SGQZ4C6U3GCUQC ODNAIEJW732NG7USKQKCIP4R4DAEYXXJQX6LY7TIN32NKE75454QC CRX4RG35C3DH57NIXCW4CG4X7SBMSX7TAJR2BAFQ4LQKCLYUNANQC JVSCP4FTW2G57C6YD5HZOZXTODGZH7TR75JQGFJBEPX3LCZH236QC QRD2M37AMG76CPGCALZQ3N2PZ3OZ3MFETMVAEHBJJVVH2BCPVGUAC WXSNNK2RXP3DQFAEQGQUZJHFWXJC7ZKG2WURZGL566UDM4YXFSWQC "<lightgray>b<magenta> or <brown>K<magenta>. You can gain ""information about it by pressing <w>x<magenta>, moving the cursor ""on the monster and then pressing <w>v<magenta>. To attack it with ""your wielded weapon, just move into it.";
"<lightgray>b<magenta> or <brown>K<magenta>. ";if (get_mons_colour(&mon) != (&mon)->colour)learned_something_new(TUT_MONSTER_BRAND);else{text += "You can gain information about it by pressing <w>x<magenta> ""and moving the cursor on the monster.";}text += "\nTo attack this monster with your wielded weapon, just move into ""it.";
"bow. Do this as follows: <w>wbff<magenta> where <w>wb<magenta> ""wields the bow, and <w>ff<magenta> fires appropriate ammunition ""(your arrows) at the nearest hostile monster. If you'd like to ""choose a new monster you can type <w>f<magenta> followed by ""<w>+<magenta> or <w>-<magenta> instead to cycle through the ""available targets. Then press <w>Enter<magenta>, <w>f<magenta> ""or <w>.<magenta> to fire. If you miss, <w>ff<magenta> fires at ""the previous target again.";
"bow. If you have a look at your bow with <w>v<magenta>, you'll ""find an explanation of how to do this. First <w>w<magenta>ield ""it, then follow the instructions.";
"Do this as follows: <w>Za.<magenta> where <w>Za<magenta> zaps ""the first spell you know, ";text += spell_title(get_spell_by_letter('a'));text += ", and <w>.<magenta> shoots at the targetted monster (the closest ""hostile monster). To target a different monster, use <w>+<magenta> ""or <w>-<magenta> to cycle through the available targets. ""<w>Enter<magenta>, <w>f<magenta> or <w>.<magenta> will fire. If you ""miss, <w>Za<magenta> followed by any of the aforementioned keys ""will fire at it again.";
"If you have a look at your spellbook with <w>v<magenta>, you'll ""find an explanation of how to do this.";
"depicted by <w>^<magenta>. They can do physical damage (with ""darts or needles, for example) or have other, more magical ""effects, like teleportation.";
"depicted by " << colour_to_tag(colour) << "^<magenta>. They ""can do physical damage (with darts or needles, for example) ""or have other, more magical effects, like teleportation.";
text << "One of your skills just got raised. Type <w>m<magenta> to take ""a look at your skills screen.";
text << "One of your skills just got raised. To view or manage your ""skill set, type <w>m<magenta>.";
}// a short explanation of Crawl's target mode// and the most important commandsstatic std::string tut_target_mode(bool spells = false){std::string result;result = "You'll then find yourself in target mode with the nearest monster ""or previous target already targetted. You can also cycle through ""all hostile monsters in sight with <w>+<magenta> or <w>-<magenta>. ""Once you're aiming at the correct monster, simply hit ""<w>f<magenta>, <w>Enter<magenta> or <w>.<magenta> to shoot at it. ""If you miss, <w> ";if (spells)result += "Zap";elseresult += "ff";result += "<magenta> fires at the same target again.";return (result);}static std::string tut_throw_stuff(item_def &item){std::string result;result = "To do this, type <w>t<magenta> to throw, then <w>";result += item.slot;result += "<magenta> for ";result += (item.quantity > 1 ? "these" : "this");result += " ";result += item_base_name(item);result += (item.quantity > 1? "s" : "");result += ". ";result += tut_target_mode();return (result);}void tutorial_describe_item(item_def &item){std::ostringstream ostr;ostr << "<magenta>";switch (item.base_type){case OBJ_WEAPONS:{// for identified artefacts don't give all this information// (The screen is likely to overflow.)if (is_artefact(item) && item_type_known(item))return;item_def *weap = you.slot_item(EQ_WEAPON);bool wielded = (*weap).slot == item.slot;bool long_text = false;if (!wielded){ostr << "You can wield this weapon with <w>w<magenta>, or use ""<w>'<magenta> to switch between the weapons in slot ""a and b. (Use <w>=<magenta> to adjust item slots.)";// weapon skill used by this weapon and the best weapon skillint curr_wpskill, best_wpskill;// maybe this is a launching weaponif (is_range_weapon(item)){// then only compare with other launcher skillscurr_wpskill = range_skill(item);best_wpskill = best_skill(SK_SLINGS, SK_DARTS, 99);}else{// compare with other melee weaponscurr_wpskill = weapon_skill(item);best_wpskill = best_skill(SK_SHORT_BLADES, SK_STAVES, 99);// maybe unarmed is betterif (you.skills[SK_UNARMED_COMBAT] > you.skills[best_wpskill])best_wpskill = SK_UNARMED_COMBAT;}if (you.skills[curr_wpskill] + 2 < you.skills[best_wpskill]){ostr << "\nOn second look you've been training in <w>"<< skill_name(best_wpskill)<< "<magenta> for a while, so maybe you should ""continue training that rather than <w>"<< skill_name(curr_wpskill)<< "<magenta>. (Type <w>m<magenta> to see the skill ""management screen for the actual numbers.)";long_text = true;}}else // wielded weapon{if (is_range_weapon(item)){ostr << "To attack a monster, you only need to ""<w>f<magenta>ire the appropriate type of ammunition. ";ostr << tut_target_mode();}else{ostr << "To attack a monster, you can simply walk into it.";}}if (is_throwable(item, you.body_size()) && !long_text){ostr << "\n\nSome weapons (including this one), can also be used ""for ranged combat. ";ostr << tut_throw_stuff(item);long_text = true;}if (!item_type_known(item) &&(is_artefact(item) || get_equip_desc( item ) != ISFLAG_NO_DESC)){ostr << "\n\nWeapons and armour that have unusual descriptions "<< "like this are much more likely to be of higher "<< "enchantment or have special properties, good or bad. "<< "The rarer the description, the greater the potential "<< "value of an item.";Options.tutorial_events[TUT_SEEN_RANDART] = 0;}if (item_known_cursed( item ) && !long_text){ostr << "\n\nOnce wielded, a cursed weapon won't leave your hands ""again until the curse has been lifted by reading a ""scroll of remove curse.";if (!wielded && is_throwable(item, you.body_size()))ostr << " (Throwing it is safe, though.)";Options.tutorial_events[TUT_YOU_CURSED] = 0;}Options.tutorial_events[TUT_SEEN_WEAPON] = 0;break;}case OBJ_MISSILES:if (item.sub_type == MI_JAVELIN || item.sub_type == MI_SLING_BULLET|| item.sub_type == MI_DART || item.sub_type == MI_STONE){ostr << item.name(DESC_CAP_YOUR)<< " can be thrown without the use of a launcher. ";ostr << tut_throw_stuff(item);}else if (is_launched(&you, you.weapon(), item)){ostr << "As you're already wielding the appropriate launcher, ""you can simply <w>f<magenta>ire "<< (item.quantity > 1 ? "these" : "this")<< " " << item.name(DESC_BASENAME)<< (item.quantity > 1? "s" : "")<< ". ";ostr << tut_target_mode();}else{ostr << "To shoot "<< (item.quantity > 1 ? "these" : "this")<< " " << item.name(DESC_BASENAME)<< (item.quantity > 1? "s" : "")<< ", first you need to <w>w<magenta>ield an appropriate ""launcher.";}Options.tutorial_events[TUT_SEEN_MISSILES] = 0;break;case OBJ_ARMOUR:ostr << "You can wear pieces of armour with <w>W<magenta> and take ""them off again with <w>T<magenta>. ";if (!item_type_known(item) &&(is_artefact(item) || get_equip_desc( item ) != ISFLAG_NO_DESC)){ostr << "\n\nWeapons and armour that have unusual descriptions "<< "like this are much more likely to be of higher "<< "enchantment or have special properties, good or bad. "<< "The rarer the description, the greater the potential "<< "value of an item.";Options.tutorial_events[TUT_SEEN_RANDART] = 0;}if (item_known_cursed( item )){ostr << "\nA cursed piece of armour, once worn, cannot be removed ""again until the curse has been lifted by reading a ""scroll of remove curse.";}Options.tutorial_events[TUT_SEEN_ARMOUR] = 0;break;case OBJ_WANDS:ostr << "The magic within can be unleashed by <w>z<magenta>apping it.";Options.tutorial_events[TUT_SEEN_WAND] = 0;break;case OBJ_FOOD:ostr << "Food can simply be <w>e<magenta>aten. ";if (item.sub_type == FOOD_CHUNK){ostr << "Note that most species refuse to eat raw meat unless ""really hungry. ";if (item.special < 100){ostr << "Even fewer can safely digest rotten meat, and you're ""probably not part of this group.";}}Options.tutorial_events[TUT_SEEN_FOOD] = 0;break;case OBJ_SCROLLS:ostr << "Type <w>r<magenta> to read this scroll. ";Options.tutorial_events[TUT_SEEN_SCROLL] = 0;break;case OBJ_JEWELLERY:ostr << "Jewellery can be <w>P<magenta>ut on or <w>R<magenta>emoved ""again. ";if (item_known_cursed( item )){ostr << "\nA cursed piece of jewellery will cling to its ""unfortunate wearer's neck or fingers until the curse is ""finally lifted when he or she reads a scroll of remove ""curse.";}Options.tutorial_events[TUT_SEEN_JEWELLERY] = 0;break;case OBJ_POTIONS:ostr << "Use <w>q<magenta> to quaff this potion. ";Options.tutorial_events[TUT_SEEN_POTION] = 0;break;case OBJ_BOOKS:if (!item_ident(item, ISFLAG_KNOW_TYPE)){ostr << "It's a book, you can <w>r<magenta>ead it. ";}else{if (item.sub_type == BOOK_MANUAL){ostr << "A manual can greatly help you in training a skill. ""To use it, <w>r<magenta>ead it while your experience ""pool (the number in brackets) is full. Note that ""this will drain said pool, so only use this manual ""if you think you need the skill in question.";}else{ostr << "A spellbook! You could <w>M<magenta>emorize some ""spells and then cast them with <w>Z<magenta>. ";if (you.religion == GOD_TROG){ostr << "\nAs a worshipper of "<< god_name(GOD_TROG)<< ", though, you might instead wish to burn this ""tome of hated magic, by using the corresponding ""<w>a<magenta>bility. ""Note that this only works on books that are ""lying on the floor and not on your current ""square. ";}else if (!you.skills[SK_SPELLCASTING]){ostr << "\nFor now, however, that will have to wait ""until you've learned the basics of Spellcasting ""by reading lots of scrolls.";}else{ostr << "Do this as follows: Type <w>Z<magenta>, then ""choose the spell you want to cast (with ""<w>?<magenta>), for example <w>a<magenta>, ""which is the first spell you know, "<< spell_title(get_spell_by_letter('a'))<< ". ";ostr << tut_target_mode(true);}}}Options.tutorial_events[TUT_SEEN_SPBOOK] = 0;break;case OBJ_CORPSES:ostr << "Corpses lying on the floor can be <w>D<magenta>issected ""with a sharp implement to produce chunks for food ""(though they may not be healthy)";if (god_likes_butchery(you.religion)){ostr << ", or as a sacrifice to "<< god_name(you.religion)<< " (while <w>p<magenta>raying)";}ostr << ". ";if (item.special < 100)ostr << "Rotten corpses won't be of any use to you, though, so ""you might just as well <w>d<magenta>rop this.";Options.tutorial_events[TUT_SEEN_CARRION] = 0;break;case OBJ_STAVES:ostr << "Staffs have to be <w>w<magenta>ielded to be of use. ""There are staves that help spellcasters, and others that ""allow you to harness spells hidden within.";if (!item_ident(item, ISFLAG_KNOW_TYPE)){ostr << "\n\nTo find out what this staff might do, you have to ""wield it, then <w>E<magenta>voke it to see if anything ""interesting happens. If nothing happens, it's probably ""an ancient staff capable of enhancing certain spell ""schools while suppressing others. ";if (you.spell_no){ostr << "You can find out which one, by casting spells while ""wielding this staff. Eventually, the staff might ""react to a spell of its school and identify itself.";}}Options.tutorial_events[TUT_SEEN_STAFF] = 0;break;case OBJ_MISCELLANY:ostr << "Miscellanous items sometimes harbour magical powers. Try ""<w>w<magenta>ielding and <w>E<magenta>voking it.";Options.tutorial_events[TUT_SEEN_MISC] = 0;break;default:return;}std::string broken = ostr.str();linebreak_string2(broken, get_tutorial_cols());formatted_string::parse_block(broken, false).display();
bool tutorial_feat_interesting(int feat){switch (feat){case DNGN_CLOSED_DOOR:case DNGN_OPEN_DOOR:case DNGN_ORCISH_IDOL:case DNGN_GRANITE_STATUE:case DNGN_SILVER_STATUE:case DNGN_ORANGE_CRYSTAL_STATUE:case DNGN_TRAP_MAGICAL:case DNGN_TRAP_MECHANICAL:case DNGN_STONE_STAIRS_DOWN_I:case DNGN_STONE_STAIRS_DOWN_II:case DNGN_STONE_STAIRS_DOWN_III:case DNGN_STONE_STAIRS_UP_I:case DNGN_STONE_STAIRS_UP_II:case DNGN_STONE_STAIRS_UP_III:case DNGN_ROCK_STAIRS_DOWN:case DNGN_ROCK_STAIRS_UP:return true;default:return false;}}void tutorial_describe_feature(int feat){std::ostringstream ostr;ostr << "<magenta>";switch (feat){case DNGN_CLOSED_DOOR:ostr << "You can open it by walking into it.";Options.tutorial_events[TUT_SEEN_DOOR];break;case DNGN_OPEN_DOOR:ostr << "You can close an open door if you stand next to it while ""the doorway's empty, and then press <w>c<magenta> followed ""by the direction of the door.";Options.tutorial_events[TUT_SEEN_DOOR];break;case DNGN_ORCISH_IDOL:case DNGN_GRANITE_STATUE:case DNGN_SILVER_STATUE:case DNGN_ORANGE_CRYSTAL_STATUE:ostr << "Beware! Sometimes such a statue actually has a mind of its own.";break;case DNGN_TRAP_MAGICAL:case DNGN_TRAP_MECHANICAL:ostr << "These nasty constructions can do physical damage (with ""darts or needles, for example) or have other, more magical ""effects. ";if (feat == DNGN_TRAP_MECHANICAL){ostr << "You can attempt to deactivate the mechanical type by ""standing next to it and then pressing <w>Shift<magenta> ""and the direction of the trap. Note that this usually ""causes the trap to go off, so it can be quite a ""dangerous task.";}Options.tutorial_events[TUT_SEEN_TRAP];break;case DNGN_STONE_STAIRS_DOWN_I:case DNGN_STONE_STAIRS_DOWN_II:case DNGN_STONE_STAIRS_DOWN_III:ostr << "You can enter the next (deeper) level by following them ""down (<w>><magenta>). To get back to this level again, ""press <w><<<magenta> while standing on the upstairs.";Options.tutorial_events[TUT_SEEN_STAIRS];break;case DNGN_STONE_STAIRS_UP_I:case DNGN_STONE_STAIRS_UP_II:case DNGN_STONE_STAIRS_UP_III:if (you.your_level < 1){ostr << "These stairs lead out of the dungeon. Following them ""will end the game. The only way to win is to transport ""the fabled orb of Zot outside.";}else{ostr << "You can enter the previous (lower) level by following ""these down (<w><<<magenta>). To get back to this level ""again, press <w>><magenta> while standing on the ""downstairs.";}Options.tutorial_events[TUT_SEEN_STAIRS];break;case DNGN_ROCK_STAIRS_DOWN:case DNGN_ROCK_STAIRS_UP:ostr << "Escape hatches can be used to quickly leave a level with ""<w><<<magenta> and <w>><magenta>, respectively. Note that ""you will usually be unable to return right away.";Options.tutorial_events[TUT_SEEN_ESCAPE_HATCH];break;default:return;}std::string broken = ostr.str();linebreak_string2(broken, get_tutorial_cols());formatted_string::parse_block(broken, false).display();}
TUT_YOU_CURSED,TUT_YOU_HUNGRY,TUT_YOU_STARVING,TUT_MULTI_PICKUP, // 30TUT_HEAVY_LOAD,TUT_ROTTEN_FOOD,TUT_NEED_HEALING,
TUT_YOU_CURSED,TUT_YOU_HUNGRY,TUT_YOU_STARVING, // 35TUT_YOU_MUTATED,TUT_POSTBERSERK,// warningTUT_RUN_AWAY, // 38TUT_RETREAT_CASTER,TUT_WIELD_WEAPON,TUT_NEED_HEALING,
mpr(feature_desc.c_str());
if (Options.tutorial_left && tutorial_feat_interesting(grd[mx][my])){feature_desc += " (Press <w>v<lightgray> for more information.)";print_formatted_paragraph(feature_desc, 80);}elsempr(feature_desc.c_str());