summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2009-05-25 07:09:56 +0000
committerzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2009-05-25 07:09:56 +0000
commit781c1cda9ce49cec2064cbf438e52ef6aaff41a3 (patch)
tree27f2e13f6ddc8307b10efdb99935bc1fcbb2f2ab
parent7a3b0b0a92e9e07200a598d743af697c9ea6aae8 (diff)
downloadcrawl-ref-781c1cda9ce49cec2064cbf438e52ef6aaff41a3.tar.gz
crawl-ref-781c1cda9ce49cec2064cbf438e52ef6aaff41a3.zip
Added some new tutorial events (not tested with the tile build):
* Auto-explore hint (200 turns after level map hint). * Explanation of the "Your equipment suddenly weighs less" message. * Explanations of trap and heap branding (non-tile builds only). * A note that monsters that have moved out of LOS haven't just vanished. * Events for gaining an ability from a mutation and gaining one from an item which was just equipped, separate from the event for the first divinely granted ability. * An explanation that shouting monsters have just noticed you, plus that their shout is likely to attract the attention of other monsters. * A "seen portal vault entrance" event, since the entry to the sewers can appear on DL 3 through 6, and there's also a very small chance of a Zigguart entrance apearing as early as DL 3. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@9823 c06c8d41-db1a-0410-9941-cceddc491573
-rw-r--r--crawl-ref/source/acr.cc8
-rw-r--r--crawl-ref/source/delay.cc6
-rw-r--r--crawl-ref/source/effects.cc1
-rw-r--r--crawl-ref/source/enum.h57
-rw-r--r--crawl-ref/source/externs.h2
-rw-r--r--crawl-ref/source/item_use.cc11
-rw-r--r--crawl-ref/source/monstuff.cc5
-rw-r--r--crawl-ref/source/mutation.cc7
-rw-r--r--crawl-ref/source/religion.cc2
-rw-r--r--crawl-ref/source/tutorial.cc273
-rw-r--r--crawl-ref/source/view.cc11
11 files changed, 341 insertions, 42 deletions
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index 61683c32e8..1b56a12daf 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -935,6 +935,14 @@ static void _input()
{
learned_something_new(TUT_MAP_VIEW);
}
+ else if (!you.running
+ && Options.tutorial_events[TUT_AUTO_EXPLORE]
+ && you.num_turns >= 700
+ && you.hp == you.hp_max
+ && you.magic_points == you.max_magic_points)
+ {
+ learned_something_new(TUT_AUTO_EXPLORE);
+ }
}
else
{
diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc
index 13e06420ca..0e9fc81352 100644
--- a/crawl-ref/source/delay.cc
+++ b/crawl-ref/source/delay.cc
@@ -13,6 +13,7 @@ REVISION("$Rev$");
#include <stdio.h>
#include <string.h>
+#include "abl-show.h"
#include "clua.h"
#include "command.h"
#include "database.h"
@@ -1417,6 +1418,8 @@ static void _finish_delay(const delay_queue_item &delay)
void armour_wear_effects(const int item_slot)
{
+ const unsigned int old_talents = your_talents(false).size();
+
item_def &arm = you.inv[item_slot];
const bool was_known = item_type_known(arm);
@@ -1592,6 +1595,9 @@ void armour_wear_effects(const int item_slot)
if (eq_slot == EQ_SHIELD)
warn_shield_penalties();
+ if (Options.tutorial_left && your_talents(false).size() > old_talents)
+ learned_something_new(TUT_NEW_ABILITY_ITEM);
+
you.redraw_armour_class = true;
you.redraw_evasion = true;
}
diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc
index e76c01bc0d..52d7a395c8 100644
--- a/crawl-ref/source/effects.cc
+++ b/crawl-ref/source/effects.cc
@@ -3104,6 +3104,7 @@ static void _rot_inventory_food(long time_delta)
if (burden_changed_by_rot)
{
mpr("Your equipment suddenly weighs less.", MSGCH_ROTTEN_MEAT);
+ learned_something_new(TUT_ROTTEN_GONE);
burden_change();
}
}
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index 349f2dac78..1df5512b5a 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -2890,66 +2890,75 @@ enum tutorial_event_type
TUT_SEEN_STAIRS, // 15
TUT_SEEN_ESCAPE_HATCH,
TUT_SEEN_BRANCH,
+ TUT_SEEN_PORTAL,
TUT_SEEN_TRAP,
- TUT_SEEN_ALTAR,
- TUT_SEEN_SHOP, // 20
+ TUT_SEEN_ALTAR, // 20
+ TUT_SEEN_SHOP,
TUT_SEEN_DOOR,
TUT_SEEN_SECRET_DOOR,
// other 'first events'
TUT_SEEN_MONSTER,
- TUT_MONSTER_BRAND,
- TUT_MONSTER_FRIENDLY, // 25
+ TUT_MONSTER_BRAND, // 25
+ TUT_MONSTER_FRIENDLY,
+ TUT_MONSTER_SHOUT,
+ TUT_MONSTER_LEFT_LOS,
TUT_KILLED_MONSTER,
- TUT_NEW_LEVEL,
+ TUT_NEW_LEVEL, // 30
TUT_SKILL_RAISE,
TUT_GAINED_MAGICAL_SKILL,
- TUT_GAINED_MELEE_SKILL, // 30
+ TUT_GAINED_MELEE_SKILL,
TUT_GAINED_RANGED_SKILL,
- TUT_CHOOSE_STAT,
+ TUT_CHOOSE_STAT, // 35
TUT_MAKE_CHUNKS,
TUT_OFFER_CORPSE,
- TUT_NEW_ABILITY, // 35
+ TUT_NEW_ABILITY_GOD,
+ TUT_NEW_ABILITY_MUT,
+ TUT_NEW_ABILITY_ITEM, // 40
TUT_FLEEING_MONSTER,
TUT_ROTTEN_FOOD,
+ TUT_ROTTEN_GONE,
TUT_CONVERT,
- TUT_GOD_DISPLEASED,
- TUT_EXCOMMUNICATE, // 40
+ TUT_GOD_DISPLEASED, // 45
+ TUT_EXCOMMUNICATE,
TUT_SPELL_MISCAST,
TUT_SPELL_HUNGER,
TUT_GLOWING,
- TUT_YOU_RESIST,
+ TUT_YOU_RESIST, // 50
// status changes
- TUT_YOU_ENCHANTED, // 45
+ TUT_YOU_ENCHANTED,
TUT_YOU_SICK,
TUT_YOU_POISON,
TUT_YOU_ROTTING,
- TUT_YOU_CURSED,
- TUT_YOU_HUNGRY, // 50
+ TUT_YOU_CURSED, // 55
+ TUT_YOU_HUNGRY,
TUT_YOU_STARVING,
TUT_YOU_MUTATED,
TUT_CAN_BERSERK,
- TUT_POSTBERSERK,
- TUT_CAUGHT_IN_NET, // 55
+ TUT_POSTBERSERK, // 60
+ TUT_CAUGHT_IN_NET,
// warning
TUT_RUN_AWAY,
TUT_RETREAT_CASTER,
TUT_WIELD_WEAPON,
- TUT_NEED_HEALING,
- TUT_NEED_POISON_HEALING, // 60
+ TUT_NEED_HEALING, // 65
+ TUT_NEED_POISON_HEALING,
TUT_INVISIBLE_DANGER,
TUT_NEED_HEALING_INVIS,
TUT_ABYSS,
// interface
- TUT_MULTI_PICKUP,
- TUT_HEAVY_LOAD, // 65
+ TUT_MULTI_PICKUP, // 70
+ TUT_HEAVY_LOAD,
TUT_SHIFT_RUN,
TUT_MAP_VIEW,
- TUT_DONE_EXPLORE,
+ TUT_AUTO_EXPLORE,
+ TUT_DONE_EXPLORE, // 75
TUT_STAIR_BRAND,
- TUT_LOAD_SAVED_GAME, // 70
- TUT_EVENTS_NUM // 71
+ TUT_HEAP_BRAND,
+ TUT_TRAP_BRAND,
+ TUT_LOAD_SAVED_GAME,
+ TUT_EVENTS_NUM // 80
};
-// NOTE: For numbers higher than 75 change size of tutorial_events in externs.h.
+// NOTE: For numbers higher than 85 change size of tutorial_events in externs.h.
enum tutorial_types
{
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index 05c5120d2f..e24e96cc73 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -2254,7 +2254,7 @@ public:
///////////////////////////////////////////////////////////////////////
// tutorial
- FixedVector<bool, 75> tutorial_events;
+ FixedVector<bool, 85> tutorial_events;
bool tut_explored;
bool tut_stashes;
bool tut_travel;
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index 60547947e4..776f68adb3 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -18,6 +18,7 @@ REVISION("$Rev$");
#include "externs.h"
+#include "abl-show.h"
#include "beam.h"
#include "cio.h"
#include "cloud.h"
@@ -335,6 +336,8 @@ bool wield_weapon(bool auto_wield, int slot, bool show_weff_messages,
if (you.equip[EQ_WEAPON] != -1 && !unwield_item(show_weff_messages))
return (false);
+ const unsigned int old_talents = your_talents(false).size();
+
you.equip[EQ_WEAPON] = item_slot;
// Any oddness on wielding taken care of here.
@@ -346,6 +349,9 @@ bool wield_weapon(bool auto_wield, int slot, bool show_weff_messages,
if (show_weff_messages)
wield_warning();
+ if (Options.tutorial_left && your_talents(false).size() > old_talents)
+ learned_something_new(TUT_NEW_ABILITY_ITEM);
+
// Time calculations.
you.time_taken /= 2;
@@ -3604,12 +3610,17 @@ bool puton_item(int item_slot)
hand_used = EQ_RIGHT_RING;
}
+ const unsigned int old_talents = your_talents(false).size();
+
// Actually equip the item.
you.equip[hand_used] = item_slot;
// And calculate the effects.
jewellery_wear_effects(item);
+ if (Options.tutorial_left && your_talents(false).size() > old_talents)
+ learned_something_new(TUT_NEW_ABILITY_ITEM);
+
// Putting on jewellery is as fast as wielding weapons.
you.time_taken /= 2;
you.turn_is_over = true;
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index 4b6913717e..25700e20be 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -7799,6 +7799,11 @@ static bool _do_move_monster(monsters *monster, const coord_def& delta)
// this message to avoid confusion.
if (monster->seen_context == _just_seen && !see_grid(f))
simple_monster_message(monster, " moves out of view.");
+ else if (Options.tutorial_left && (monster->flags & MF_WAS_IN_VIEW)
+ && !see_grid(f))
+ {
+ learned_something_new(TUT_MONSTER_LEFT_LOS, monster->pos());
+ }
// The seen context no longer applies if the monster is moving normally.
monster->seen_context.clear();
diff --git a/crawl-ref/source/mutation.cc b/crawl-ref/source/mutation.cc
index e61888f960..bc1966fd8f 100644
--- a/crawl-ref/source/mutation.cc
+++ b/crawl-ref/source/mutation.cc
@@ -26,6 +26,7 @@ REVISION("$Rev$");
#include "externs.h"
+#include "abl-show.h"
#include "cio.h"
#include "defines.h"
#include "effects.h"
@@ -2214,6 +2215,8 @@ bool mutate(mutation_type which_mutation, bool failMsg,
return (false);
ASSERT(rc == 0);
+ const unsigned int old_talents = your_talents(false).size();
+
bool gain_msg = true;
bool stat_msg = false;
@@ -2301,6 +2304,10 @@ bool mutate(mutation_type which_mutation, bool failMsg,
xom_is_stimulated(_calc_mutation_amusement_value(mutat));
take_note(Note(NOTE_GET_MUTATION, mutat, you.mutation[mutat]));
+
+ if (Options.tutorial_left && your_talents(false).size() > old_talents)
+ learned_something_new(TUT_NEW_ABILITY_MUT);
+
return (true);
}
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index f9f4a24a62..61bd4b4a0f 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -3381,7 +3381,7 @@ void gain_piety(int pgn)
make_stringf("You can now %s.", pmsg).c_str());
}
- learned_something_new(TUT_NEW_ABILITY);
+ learned_something_new(TUT_NEW_ABILITY_GOD);
}
if (you.religion == GOD_SHINING_ONE)
diff --git a/crawl-ref/source/tutorial.cc b/crawl-ref/source/tutorial.cc
index c1981c2072..6ff5b7018f 100644
--- a/crawl-ref/source/tutorial.cc
+++ b/crawl-ref/source/tutorial.cc
@@ -63,7 +63,7 @@ static void _tutorial_describe_feature(int x, int y);
static bool _water_is_disturbed(int x, int y);
//#define TUTORIAL_DEBUG
-#define TUTORIAL_VERSION 8
+#define TUTORIAL_VERSION 9
static int _get_tutorial_cols()
{
@@ -348,7 +348,7 @@ static std::string _tut_debug_list(int event)
return "seen first food";
case TUT_SEEN_CARRION:
return "seen first corpse";
- case TUT_SEE_GOLD:
+ case TUT_SEEN_GOLD:
return "seen first pile of gold";
case TUT_SEEN_JEWELLERY:
return "seen first jewellery";
@@ -362,6 +362,8 @@ static std::string _tut_debug_list(int event)
return "seen first escape hatch";
case TUT_SEEN_BRANCH:
return "seen first branch entrance";
+ case TUT_SEEN_PORTAL:
+ return "seen first portal vault entrance";
case TUT_SEEN_TRAP:
return "encountered a trap";
case TUT_SEEN_ALTAR:
@@ -402,6 +404,8 @@ static std::string _tut_debug_list(int event)
return "were encumbered";
case TUT_ROTTEN_FOOD:
return "carried rotten food";
+ case TUT_ROTTEN_GONE:
+ return "rotten food rotted away completely";
case TUT_NEED_HEALING:
return "needed healing";
case TUT_NEED_POISON_HEALING:
@@ -422,12 +426,18 @@ static std::string _tut_debug_list(int event)
return "learned about shift-run";
case TUT_MAP_VIEW:
return "learned about the level map";
+ case TUT_AUTO_EXPLORE:
+ return "learned about auto-explore";
case TUT_DONE_EXPLORE:
return "explored a level";
case TUT_YOU_MUTATED:
return "caught a mutation";
- case TUT_NEW_ABILITY:
+ case TUT_NEW_ABILITY_GOD:
return "gained a divine ability";
+ case TUT_NEW_ABILITY_MUT:
+ return "gained a mutation-granted ability";
+ case TUT_NEW_ABILITY_ITEM:
+ return "gained an item-granted ability";
case TUT_WIELD_WEAPON:
return "wielded an unsuitable weapon";
case TUT_FLEEING_MONSTER:
@@ -436,6 +446,8 @@ static std::string _tut_debug_list(int event)
return "learned about colour brandings";
case TUT_MONSTER_FRIENDLY:
return "seen first friendly monster";
+ case TUT_MONSTER_SHOUT:
+ return "experienced first shouting monster";
case TUT_CONVERT:
return "converted to a god";
case TUT_GOD_DISPLEASED:
@@ -450,6 +462,10 @@ static std::string _tut_debug_list(int event)
return "player glowing from contamination";
case TUT_STAIR_BRAND:
return "saw stairs with objects on it";
+ case TUT_HEAP_BRAND:
+ return "saw heap of objects";
+ case TUT_TRAP_BRAND:
+ return "saw trap with objects on it";
case TUT_YOU_RESIST:
return "resisted some magic";
case TUT_CAUGHT_IN_NET:
@@ -1468,6 +1484,64 @@ static int _num_butchery_tools()
return (num);
}
+static std::string _describe_portal(const coord_def &gc)
+{
+ const std::string desc = feature_description(gc);
+
+ std::ostringstream text;
+
+ // Zigguart entrances can rarely appear as early as DL 3.
+ if (desc.find("zig") != std::string::npos)
+ {
+ text << "is a portal to a set of special levels filled with very "
+ "tough monsters; you probably shouldn't even think of going "
+ "in here. Additionally, entering a zigguart takes a lot of "
+ "gold, a lot more than you'd have right now; don't bother "
+ "saving gold up for it, since at this point your gold is "
+ "better spent at shops buying items which can help you "
+ "survive."
+
+ "\n\nIf you <w>still</w> want to enter (and somehow have "
+ "gathered enough gold to do so) ";
+ }
+ // For the sake of completeness, though it's very unlikely that a
+ // player will find a bazaar entrance before reahing XL 7.
+ else if (desc.find("bazaar") != std::string::npos)
+ {
+ text << "is a portal to an inter-dimensional bazaar filled with "
+ "shops. It will disappear if you don't enter it soon, "
+ "so hurry. To enter ";
+ }
+ // The sewers can appear from DL 3 to DL 6.
+ else
+ {
+ text << "is a portal to a special level where you'll have to fight "
+ "your way back to the exit through some tougher than average "
+ "monsters (the monsters around the portal should give a "
+ "good indication as to how tough), but with the reward of "
+ "some good loot. There's no penalty for skipping it, but if "
+ "you do skip it the portal will disappear, so you have to "
+ "decide now if you want to risk it. To enter ";
+ }
+
+ text << "stand over the portal and press <w>></w>. To return find "
+#ifdef USE_TILE
+ "a similar looking portal tile "
+#else
+ "another <w>\\</w> "
+#endif
+ "(though NOT the ancient stone arch you'll start out on) "
+ "and press <w><<</w>.";
+
+#ifdef USE_TILE
+ text << "\nAlternatively, clicking on your <w>left mouse button</w> "
+ "while pressing the <w>Shift key</w> will let you enter any "
+ "portal you're standing on.";
+#endif
+
+ return (text.str());
+}
+
#define DELAY_EVENT \
{ \
Options.tutorial_events[seen_what] = true; \
@@ -1920,6 +1994,32 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
"altars at which you might convert to a new god.";
break;
+ case TUT_SEEN_PORTAL:
+ // Delay in the unlikely event that a player still in tutorial mode
+ // creates a portal with a Trowel card, since a portal vault
+ // entry's description doesn't seem to get set properly until
+ // after the vault is done being placed.
+ if (you.pos() == gc)
+ DELAY_EVENT;
+
+ text << "This ";
+#ifndef USE_TILE
+ // Is a monster blocking the view?
+ if (monster_at(gc))
+ DELAY_EVENT;
+
+ object = env.show(e);
+ colour = env.show_col(e);
+ { unsigned short dummy; get_item_symbol( object, &ch, &dummy ); }
+
+ text << _colourize_glyph(colour, ch) << " ";
+#else
+ tiles.place_cursor(CURSOR_TUTORIAL, gc);
+ tiles.add_text_tag(TAG_TUTORIAL, "Portal", gc);
+#endif
+ text << _describe_portal(gc);
+ break;
+
case TUT_STAIR_BRAND:
#ifdef USE_TILE
// XXX: How does stair branding work with tiles?
@@ -1936,6 +2036,36 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
#endif
break;
+ case TUT_HEAP_BRAND:
+#ifdef USE_TILE
+ // XXX: How does heap branding work with tiles?
+ return;
+#else
+ // Monster or player standing on heap.
+ if (monster_at(gc) || (you.pos() == gc))
+ DELAY_EVENT;
+
+ text << "If two or more items are on a single square then the square "
+ "will be highlighted, and the symbol for the item on the top "
+ "of the heap will be shown.";
+#endif
+ break;
+
+ case TUT_TRAP_BRAND:
+#ifdef USE_TILE
+ // XXX: How does trap branding work with tiles?
+ return;
+#else
+ // Monster or player standing on trap.
+ if (monster_at(gc) || (you.pos() == gc))
+ DELAY_EVENT;
+
+ text << "If any items are covering a trap then that will be "
+ "indicated by highlighting the <w>^</w> symbol, instead of "
+ "hiding the trap symbol with an item glyph.";
+#endif
+ break;
+
case TUT_SEEN_TRAP:
if (you.pos() == gc)
text << "Oops... you just triggered a trap. ";
@@ -2325,6 +2455,12 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
"just as well <w>d</w>rop them now.";
break;
+ case TUT_ROTTEN_GONE:
+ text << "One of the skeletons or rotten chunks of meat you carried "
+ "rotted away completely, or one of the rotten corpses you "
+ "carried rotted away into a skeleton.";
+ break;
+
case TUT_MAKE_CHUNKS:
text << "How lucky! That monster left a corpse which you can now "
"<w>c</w>hop up";
@@ -2407,6 +2543,19 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
#endif
break;
+ case TUT_AUTO_EXPLORE:
+ if (!Options.tut_explored)
+ DELAY_EVENT;
+
+ text << "Fully exploring a level and piciking up all the interesting "
+ "looking items can be tedious. To save on this tedium you "
+ "can press <w>o</w> to auto-explore, which will "
+ "automatically explore unmapped regions, automatically pick "
+ "up interesting items, and stop if a monster or interesting "
+ "dungeon feature (stairs, altar, etc) is encountered.";
+ Options.tut_explored = false;
+ break;
+
case TUT_DONE_EXPLORE:
// XXX: You'll only get this message if you're using auto exploration.
text << "Hey, you've finished exploring the dungeon on this level! "
@@ -2557,20 +2706,20 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
"have three levels. Check your mutations with <w>A</w>.";
break;
- case TUT_NEW_ABILITY:
+ case TUT_NEW_ABILITY_GOD:
switch (you.religion)
{
// Gods where first granted ability is active.
case GOD_KIKUBAAQUDGHA: case GOD_YREDELEMNUL: case GOD_NEMELEX_XOBEH:
case GOD_ZIN: case GOD_OKAWARU: case GOD_SIF_MUNA:
case GOD_TROG: case GOD_ELYVILON: case GOD_LUGONU:
- text << "You just gained a new ability. Press <w>a</w> to "
+ text << "You just gained a divine ability. Press <w>a</w> to "
"take a look at your abilities or to use one of them.";
break;
// Gods where first granted ability is passive.
default:
- text << "You just gained a new ability. Press <w>^</w> "
+ text << "You just gained a divine ability. Press <w>^</w> "
#ifdef USE_TILE
"or press <w>Shift</w> and <w>right-click</w> on the "
"player tile "
@@ -2580,6 +2729,20 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
}
break;
+ case TUT_NEW_ABILITY_MUT:
+ text << "That mutation granted you a new ability. Press <w>a</w> to "
+ "take a look at your abilities or to use one of them.";
+ break;
+ break;
+
+ case TUT_NEW_ABILITY_ITEM:
+ text << "That item you just equipped granted you a new ability "
+ "(un-equipping the item will remove the ability). "
+ "Press <w>a</w> to take a look at your abilities or to "
+ "use one of them.";
+ break;
+ break;
+
case TUT_CONVERT:
_new_god_conduct();
break;
@@ -2768,10 +2931,15 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
break;
case TUT_MONSTER_FRIENDLY:
+ {
+ const monsters *m = monster_at(gc);
+
+ if (!m)
+ DELAY_EVENT;
+
#ifdef USE_TILE
tiles.place_cursor(CURSOR_TUTORIAL, gc);
- if (const monsters *m = monster_at(gc))
- tiles.add_text_tag(TAG_TUTORIAL, m->name(DESC_CAP_A), gc);
+ tiles.add_text_tag(TAG_TUTORIAL, m->name(DESC_CAP_A), gc);
#endif
text << "That monster is friendly to you and will attack your "
"enemies, though you'll get only half the experience for "
@@ -2779,12 +2947,69 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
"yourself. You can command your allies by pressing <w>t</w> "
"to talk to them.";
- if (!mons_att_wont_attack(monster_at(gc)->attitude))
+ if (!mons_att_wont_attack(m->attitude))
text << "\n\nHowever, it is only <w>temporarily</w> friendly, "
"and will become dangerous again when this friendliness "
"wears off.";
break;
+ }
+ case TUT_MONSTER_SHOUT:
+ {
+ const monsters* m = monster_at(gc);
+
+ if (!m)
+ DELAY_EVENT;
+
+ const bool vis = you.can_see(m);
+
+#ifdef USE_TILE
+ if (vis)
+ {
+ tiles.place_cursor(CURSOR_TUTORIAL, gc);
+ tiles.add_text_tag(TAG_TUTORIAL, m->name(DESC_CAP_A), gc);
+ }
+#endif
+ if (!vis)
+ {
+ text << "Uh-oh, some monster noticed you, either one that's "
+ "around a corner or one that's invisible. Plus, the "
+ "noise it made will alert other monsters in the "
+ "vacinity, who will come to check out what the commotion "
+ "was about.";
+ }
+ else if (mons_shouts(m->type, false) == S_SILENT)
+ {
+ text << "Uh-oh, that monster noticed you! Forutnately, it "
+ "didn't make any noise, but many mosters <w>do</w> make "
+ "noise when they notice you, which alerts other monsters "
+ "in the area, who will come to check out what the "
+ "commotion was about.";
+ }
+ else
+ {
+ text << "Uh-oh, taht monster noticed you! Plus, the "
+ "noise it made will alert other monsters in the "
+ "vacinity, who will come to check out what the commotion "
+ "was about.";
+ }
+ break;
+ }
+
+ case TUT_MONSTER_LEFT_LOS:
+ {
+ const monsters* m = monster_at(gc);
+
+ if (!m || !you.can_see(m))
+ DELAY_EVENT;
+
+ text << m->name(DESC_CAP_THE, true) << " didn't vanish, but merely "
+ "moved onto a square which isn't in your current LOS. It "
+ "will still be there, unless something happens to it in the "
+ "short amount of time it's out of sight.";
+ break;
+ }
+
case TUT_SEEN_MONSTER:
case TUT_SEEN_FIRST_OBJECT:
// Handled in special functions.
@@ -3704,6 +3929,7 @@ static bool _tutorial_feat_interesting(dungeon_feature_type feat)
case DNGN_STONE_STAIRS_UP_III:
case DNGN_ESCAPE_HATCH_DOWN:
case DNGN_ESCAPE_HATCH_UP:
+ case DNGN_ENTER_PORTAL_VAULT:
return (true);
default:
return (false);
@@ -3830,6 +4056,11 @@ static void _tutorial_describe_feature(int x, int y)
Options.tutorial_events[TUT_SEEN_ESCAPE_HATCH] = false;
break;
+ case DNGN_ENTER_PORTAL_VAULT:
+ ostr << "This " << _describe_portal(where);
+ Options.tutorial_events[TUT_SEEN_PORTAL] = false;
+ break;
+
default:
if (feat >= DNGN_ALTAR_FIRST_GOD && feat <= DNGN_ALTAR_LAST_GOD)
{
@@ -4139,15 +4370,31 @@ void tutorial_observe_cell(const coord_def& gc)
learned_something_new(TUT_SEEN_STAIRS, gc);
else if (is_feature('_', gc))
learned_something_new(TUT_SEEN_ALTAR, gc);
+ else if (is_feature('^', gc))
+ learned_something_new(TUT_SEEN_TRAP, gc);
else if (grd(gc) == DNGN_CLOSED_DOOR)
learned_something_new(TUT_SEEN_DOOR, gc);
else if (grd(gc) == DNGN_ENTER_SHOP)
learned_something_new(TUT_SEEN_SHOP, gc);
+ else if (grd(gc) == DNGN_ENTER_PORTAL_VAULT)
+ learned_something_new(TUT_SEEN_PORTAL, gc);
- if (igrd(gc) != NON_ITEM
- && Options.feature_item_brand != CHATTR_NORMAL
- && (is_feature('>', gc) || is_feature('<', gc)))
+ const int it = igrd(gc);
+ if (it != NON_ITEM)
{
- learned_something_new(TUT_STAIR_BRAND, gc);
+ const item_def& item(mitm[it]);
+
+ if (Options.feature_item_brand != CHATTR_NORMAL
+ && (is_feature('>', gc) || is_feature('<', gc)))
+ {
+ learned_something_new(TUT_STAIR_BRAND, gc);
+ }
+ else if (Options.trap_item_brand != CHATTR_NORMAL
+ && is_feature('^', gc))
+ {
+ learned_something_new(TUT_TRAP_BRAND, gc);
+ }
+ else if (Options.heap_brand != CHATTR_NORMAL && item.link != NON_ITEM)
+ learned_something_new(TUT_HEAP_BRAND, gc);
}
}
diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc
index 91077e12df..4cbd7f586e 100644
--- a/crawl-ref/source/view.cc
+++ b/crawl-ref/source/view.cc
@@ -1214,9 +1214,11 @@ void handle_monster_shouts(monsters* monster, bool force)
}
}
- const int noise_level = get_shout_noise_level(s_type);
- if (noise_level > 0)
- noisy(noise_level, monster->pos());
+ const int noise_level = get_shout_noise_level(s_type);
+ const bool heard = noisy(noise_level, monster->pos());
+
+ if (Options.tutorial_left && (heard || you.can_see(monster)))
+ learned_something_new(TUT_MONSTER_SHOUT, monster->pos());
}
#ifdef WIZARD
@@ -1624,6 +1626,9 @@ bool noisy(int loudness, const coord_def& where, const char *msg, bool mermaid)
{
bool ret = false;
+ if (loudness <= 0)
+ return (false);
+
// If the origin is silenced there is no noise.
if (silenced(where))
return (false);