diff options
-rw-r--r-- | crawl-ref/source/acr.cc | 9 | ||||
-rw-r--r-- | crawl-ref/source/command.cc | 3 | ||||
-rw-r--r-- | crawl-ref/source/describe.cc | 6 | ||||
-rw-r--r-- | crawl-ref/source/mon-data.h | 15 | ||||
-rw-r--r-- | crawl-ref/source/tutorial.cc | 130 | ||||
-rw-r--r-- | crawl-ref/source/tutorial.h | 2 |
6 files changed, 119 insertions, 46 deletions
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index a70ac3a84c..fd3735db07 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -267,6 +267,8 @@ int main( int argc, char *argv[] ) // Warn player about their weapon, if unsuitable. wield_warning(false); + _prep_input(); + if (game_start) { if (Options.tutorial_left) @@ -274,9 +276,7 @@ int main( int argc, char *argv[] ) _take_starting_note(); } else - learned_something_new(TUT_LOAD_SAVED_GAME); - - _prep_input(); + tutorial_load_game(); // Catch up on any experience levels we did not assign last time. This // can happen if Crawl sees SIGHUP while it is waiting for the player @@ -422,9 +422,6 @@ static void _startup_tutorial() // Don't allow triggering at game start. Options.tut_just_triggered = true; - // Print stats and everything. - _prep_input(); - msg::streams(MSGCH_TUTORIAL) << "Press any key to start the tutorial intro, or Escape to skip it." << std::endl; diff --git a/crawl-ref/source/command.cc b/crawl-ref/source/command.cc index 2152b851b0..7aff78807c 100644 --- a/crawl-ref/source/command.cc +++ b/crawl-ref/source/command.cc @@ -1384,7 +1384,8 @@ static bool _do_description(std::string key, std::string type, append_armour_stats(desc, mitm[thing_created]); desc += "$"; } - else if (get_item_by_name(&mitm[thing_created], name, OBJ_MISSILES)) + else if (get_item_by_name(&mitm[thing_created], name, OBJ_MISSILES) + && mitm[thing_created].sub_type != MI_THROWING_NET) { append_missile_info(desc); desc += "$"; diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc index 796b75b7e1..9560964968 100644 --- a/crawl-ref/source/describe.cc +++ b/crawl-ref/source/describe.cc @@ -1220,7 +1220,7 @@ static std::string _describe_ammo( const item_def &item ) if (always_destroyed) description += "$It will always be destroyed upon impact."; - else + else if (item.sub_type != MI_THROWING_NET) append_missile_info(description); if (item_ident( item, ISFLAG_KNOW_PLUSES ) && item.plus >= MAX_WPN_ENCHANT) @@ -2839,12 +2839,12 @@ void get_monster_db_desc(const monsters& mons, describe_info &inf, case MONS_VAMPIRE: case MONS_VAMPIRE_KNIGHT: case MONS_VAMPIRE_MAGE: - if (you.is_undead == US_ALIVE) + if (you.is_undead == US_ALIVE && !mons_wont_attack(&mons)) inf.body << "$It wants to drink your blood!$"; break; case MONS_REAPER: - if (you.is_undead == US_ALIVE) + if (you.is_undead == US_ALIVE && !mons_wont_attack(&mons)) inf.body << "$It has come for your soul!$"; break; diff --git a/crawl-ref/source/mon-data.h b/crawl-ref/source/mon-data.h index 3009a58604..151693960e 100644 --- a/crawl-ref/source/mon-data.h +++ b/crawl-ref/source/mon-data.h @@ -56,11 +56,8 @@ exp_mod: see give_adjusted_experience() in monstuff.cc - the experience given for killing this monster is calculated something like this: - experience = hp_max * HD * HD * exp_mod / 10 - I think. - Actually it is - experience = (16 + maxhp) * HD * HD * exp_mod * (100 + diff) * speed + experience = (16 + maxhp) * HD * HD * exp_mod * (100 + diff. score) * speed / 100000 with a minimum of 1, and maximum 15000 (jpeg) @@ -4031,7 +4028,7 @@ static monsterentry mondata[] = { MONS_ILSUIW, 'm', GREEN, "Ilsuiw", M_UNIQUE | M_WARM_BLOOD | M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS, MR_RES_POISON | MR_RES_COLD, - 500, 10, MONS_MERFOLK, MONS_MERFOLK, MH_NATURAL, 90, + 500, 10, MONS_MERFOLK, MONS_MERFOLK, MH_NATURAL, -7, { {AT_HIT, AF_PLAIN, 10}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 9, 2, 4, 0 }, 5, 18, MST_ILSUIW, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, @@ -4065,7 +4062,7 @@ static monsterentry mondata[] = { M_UNIQUE | M_SPELLCASTER | M_SEE_INVIS | M_EVIL | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_SPEAKS, MR_RES_FIRE | MR_RES_COLD, - 600, 12, MONS_ORC, MONS_ORC, MH_NATURAL, 50, + 600, 12, MONS_ORC, MONS_ORC, MH_NATURAL, -5, { {AT_HIT, AF_PLAIN, 6}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 10, 2, 3, 0 }, 9, 11, MST_ORC_SORCERER, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH, @@ -4078,8 +4075,8 @@ static monsterentry mondata[] = { | M_SPEAKS, MR_NO_FLAGS, 600, 15, MONS_ORC, MONS_ORC, MH_NATURAL, -3, - { {AT_HIT, AF_PLAIN, 32}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, - { 15, 4, 7, 0 }, + { {AT_HIT, AF_PLAIN, 35}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, + { 18, 4, 7, 20 }, 3, 10, MST_DAEVA, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, HT_LAND, 10, DEFAULT_ENERGY, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM }, @@ -4415,7 +4412,7 @@ static monsterentry mondata[] = { MONS_EUSTACHIO, '@', GREEN, "Eustachio", M_UNIQUE | M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_SPEAKS, MR_NO_FLAGS, - 550, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, 24, + 550, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, { {AT_HIT, AF_PLAIN, 6}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 4, 0, 0, 40 }, 0, 13, MST_EUSTACHIO, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, diff --git a/crawl-ref/source/tutorial.cc b/crawl-ref/source/tutorial.cc index c58cf6cd91..62b21fa015 100644 --- a/crawl-ref/source/tutorial.cc +++ b/crawl-ref/source/tutorial.cc @@ -213,6 +213,19 @@ bool pick_tutorial() return (false); } +void tutorial_load_game() +{ + if (!Options.tutorial_left) + return; + + learned_something_new(TUT_LOAD_SAVED_GAME); + + // Reinitialise counters for explore, stash search and travelling. + Options.tut_explored = Options.tutorial_events[TUT_AUTO_EXPLORE]; + Options.tut_stashes = true; + Options.tut_travel = true; +} + void print_tutorial_menu(unsigned int type) { char letter = 'a' + type; @@ -609,7 +622,6 @@ static void _tutorial_stats_intro() #endif } - static void _tutorial_message_intro() { std::string result; @@ -711,7 +723,12 @@ void tut_starting_screen() if (i < MAX_INFO) { +#ifndef USE_TILE ch = c_getch(); +#else + mouse_control mc(MOUSE_MODE_MORE); + ch = getch(); +#endif redraw_screen(); if (ch == ESCAPE) break; @@ -767,12 +784,15 @@ void tutorial_death_screen() else { int hint = random2(6); + + bool skip_first_hint = false; // If a character has been unusually busy with projectiles and spells // give some other hint rather than the first one. if (hint == 0 && Options.tut_throw_counter + Options.tut_spell_counter >= Options.tut_melee_counter) { - hint = random2(5)+1; + hint = random2(5) + 1; + skip_first_hint = true; } // FIXME: The hints below could be somewhat less random, so that e.g. // the message for fighting several monsters in a corridor only happens @@ -780,6 +800,20 @@ void tutorial_death_screen() // or the one about using consumable objects only if you actually have // any (useful or unidentified) scrolls/wands/potions. + if (hint == 5) + { + std::vector<monsters*> visible = + get_nearby_monsters(false, true, true, false); + + if (visible.size() < 2) + { + if (skip_first_hint) + hint = random2(4) + 1; + else + hint = random2(5); + } + } + switch (hint) { case 0: @@ -1232,31 +1266,32 @@ void tutorial_first_monster(const monsters &mon) { if (!Options.tutorial_events[TUT_SEEN_MONSTER]) { - if (get_mons_colour(&mon) != mon.colour) + if (Options.tut_just_triggered) + return; + + if (_mons_is_highlighted(&mon)) learned_something_new(TUT_MONSTER_BRAND, mon.pos()); if (mons_friendly(&mon)) learned_something_new(TUT_MONSTER_FRIENDLY, mon.pos()); - if (!Options.tut_just_triggered - && one_chance_in(4) - && you.religion == GOD_TROG && !you.duration[DUR_BERSERKER] - && !you.duration[DUR_EXHAUSTED] - && you.hunger_state >= HS_SATIATED) + if (you.religion == GOD_TROG && !you.duration[DUR_BERSERKER] + && !you.duration[DUR_EXHAUSTED] && you.hunger_state >= HS_SATIATED + && one_chance_in(4)) { learned_something_new(TUT_CAN_BERSERK); } return; } - // XXX: Crude hack (and doesn't really work either): - // If the first monster is sleeping wake it - // (highlighting is an unnecessary complication). if (_mons_is_highlighted(&mon)) - noisy(1, mon.pos()); - + { + // Make first monster notice player, so we can explain the brand + // some time later. + monsters *m = monster_at(mon.pos()); + behaviour_event( m, ME_ALERT, MHITYOU, you.pos() ); + } stop_running(); - viewwindow(true, false); Options.tutorial_events[TUT_SEEN_MONSTER] = false; Options.tutorial_left--; Options.tut_just_triggered = true; @@ -1302,6 +1337,7 @@ void tutorial_first_monster(const monsters &mon) "death by misclicking."; #endif + viewwindow(true, false); formatted_message_history(text, MSGCH_TUTORIAL, 0, _get_tutorial_cols()); if (Options.tutorial_type == TUT_RANGER_CHAR) @@ -1350,7 +1386,7 @@ void tutorial_first_monster(const monsters &mon) _get_tutorial_cols()); } - if (get_mons_colour(&mon) != mon.colour) + if (_mons_is_highlighted(&mon)) learned_something_new(TUT_MONSTER_BRAND, mon.pos()); if (mons_friendly(&mon)) learned_something_new(TUT_MONSTER_FRIENDLY, mon.pos()); @@ -1379,7 +1415,6 @@ void tutorial_first_item(const item_def &item) stop_running(); - viewwindow(true, false); Options.tutorial_events[TUT_SEEN_FIRST_OBJECT] = false; Options.tutorial_left--; Options.tut_just_triggered = true; @@ -1397,6 +1432,8 @@ void tutorial_first_item(const item_def &item) tiles.place_cursor(CURSOR_TUTORIAL, gc); tiles.add_text_tag(TAG_TUTORIAL, item.name(DESC_CAP_A), gc); #endif + + viewwindow(true, false); text += "is an item. If you move there and press <w>g</w> or " "<w>,</w> you will pick it up. " #ifndef USE_TILE @@ -1577,6 +1614,45 @@ static std::string _describe_portal(const coord_def &gc) return; \ } +// Really rare or important events should get a comment even if +// learned_something_new() was already triggered this turn. +static bool _rare_tutorial_event(tutorial_event_type event) +{ + switch (event) + { + case TUT_SEEN_SECRET_DOOR: + case TUT_KILLED_MONSTER: + case TUT_NEW_LEVEL: + case TUT_YOU_ENCHANTED: + case TUT_YOU_SICK: + case TUT_YOU_POISON: + case TUT_YOU_ROTTING: + case TUT_YOU_CURSED: + case TUT_YOU_HUNGRY: + case TUT_YOU_STARVING: + case TUT_NEED_POISON_HEALING: + case TUT_INVISIBLE_DANGER: + case TUT_NEED_HEALING_INVIS: + case TUT_ABYSS: + case TUT_RUN_AWAY: + case TUT_RETREAT_CASTER: + case TUT_YOU_MUTATED: + case TUT_NEW_ABILITY_GOD: + case TUT_NEW_ABILITY_MUT: + case TUT_NEW_ABILITY_ITEM: + case TUT_CONVERT: + case TUT_GOD_DISPLEASED: + case TUT_EXCOMMUNICATE: + case TUT_GLOWING: + case TUT_CAUGHT_IN_NET: + case TUT_GAINED_MAGICAL_SKILL: + case TUT_CHOOSE_STAT: + return (true); + default: + return (false); + } +} + // Here most of the tutorial messages for various triggers are handled. void learned_something_new(tutorial_event_type seen_what, coord_def gc) { @@ -1585,7 +1661,7 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc) return; // Don't trigger twice in the same turn. - if (Options.tut_just_triggered) + if (Options.tut_just_triggered && !_rare_tutorial_event(seen_what)) return; std::ostringstream text; @@ -1780,7 +1856,8 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc) #ifdef USE_TILE " or by clicking on it with your <w>left mouse button</w>" #endif - "."; + ". However, it is usually best to conserve rations and fruit " + "until you are hungry or even starving."; break; case TUT_SEEN_CARRION: @@ -2056,16 +2133,15 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc) break; case TUT_STAIR_BRAND: -#ifdef USE_TILE - text << "A small question mark on a stair tile signifies that there " - "are items in that position that you may want to check out."; - break; -#else // Monster or player standing on stairs. if (monster_at(gc) || you.pos() == gc) DELAY_EVENT; viewwindow(true, false); +#ifdef USE_TILE + text << "A small question mark on a stair tile signifies that there " + "are items in that position that you may want to check out."; +#else text << "If any items are covering stairs or an escape hatch, then " "that will be indicated by highlighting the <w><<</w> or " "<w>></w> symbol, instead of hiding the stair symbol with " @@ -2178,13 +2254,14 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc) break; case TUT_SEEN_DOOR: + if (you.num_turns < 1) + DELAY_EVENT; + #ifdef USE_TILE tiles.place_cursor(CURSOR_TUTORIAL, gc); tiles.add_text_tag(TAG_TUTORIAL, "Closed door", gc); #endif viewwindow(true, false); - if (you.num_turns < 1) - DELAY_EVENT; text << "That " #ifndef USE_TILE @@ -2400,6 +2477,7 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc) break; case TUT_YOU_CURSED: + viewwindow(true, false); text << "Curses are comparatively harmless, but they do mean that " "you cannot remove cursed equipment and will have to suffer " "the (possibly) bad effects until you find and read a scroll " @@ -2477,9 +2555,9 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc) break; case TUT_HEAVY_LOAD: + viewwindow(true, false); if (you.burden_state != BS_UNENCUMBERED) { - viewwindow(true, false); text << "It is not usually a good idea to run around encumbered; " "it slows you down and increases your hunger."; } diff --git a/crawl-ref/source/tutorial.h b/crawl-ref/source/tutorial.h index 3d185d9145..921bafec72 100644 --- a/crawl-ref/source/tutorial.h +++ b/crawl-ref/source/tutorial.h @@ -28,6 +28,7 @@ void load_tutorial(reader& inf); void init_tutorial_options(void); bool pick_tutorial(void); +void tutorial_load_game(void); void print_tutorial_menu(unsigned int type); void tutorial_zap_secret_doors(void); @@ -59,5 +60,4 @@ void tutorial_describe_pos(int x, int y); bool tutorial_monster_interesting(const monsters *mons); void tutorial_describe_monster(const monsters *mons); - #endif |