summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/acr.cc9
-rw-r--r--crawl-ref/source/command.cc3
-rw-r--r--crawl-ref/source/describe.cc6
-rw-r--r--crawl-ref/source/mon-data.h15
-rw-r--r--crawl-ref/source/tutorial.cc130
-rw-r--r--crawl-ref/source/tutorial.h2
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