summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/abl-show.cc2
-rw-r--r--crawl-ref/source/command.cc3
-rw-r--r--crawl-ref/source/delay.cc8
-rw-r--r--crawl-ref/source/describe.cc12
-rw-r--r--crawl-ref/source/directn.cc4
-rw-r--r--crawl-ref/source/dungeon.cc3
-rw-r--r--crawl-ref/source/enum.h8
-rw-r--r--crawl-ref/source/fight.cc4
-rw-r--r--crawl-ref/source/food.cc2
-rw-r--r--crawl-ref/source/item_use.cc8
-rw-r--r--crawl-ref/source/items.cc2
-rw-r--r--crawl-ref/source/main.cc50
-rw-r--r--crawl-ref/source/message.cc2
-rw-r--r--crawl-ref/source/misc.cc6
-rw-r--r--crawl-ref/source/mon-act.cc2
-rw-r--r--crawl-ref/source/mon-stuff.cc4
-rw-r--r--crawl-ref/source/mutation.cc2
-rw-r--r--crawl-ref/source/options.h17
-rw-r--r--crawl-ref/source/ouch.cc2
-rw-r--r--crawl-ref/source/player.cc2
-rw-r--r--crawl-ref/source/shout.cc2
-rw-r--r--crawl-ref/source/skills2.cc4
-rw-r--r--crawl-ref/source/state.cc2
-rw-r--r--crawl-ref/source/travel.cc4
-rw-r--r--crawl-ref/source/tutorial.cc288
-rw-r--r--crawl-ref/source/tutorial.h28
-rw-r--r--crawl-ref/source/view.cc2
27 files changed, 240 insertions, 233 deletions
diff --git a/crawl-ref/source/abl-show.cc b/crawl-ref/source/abl-show.cc
index 7c38f70b67..50bebc1b71 100644
--- a/crawl-ref/source/abl-show.cc
+++ b/crawl-ref/source/abl-show.cc
@@ -2137,7 +2137,7 @@ int choose_ability_menu(const std::vector<talent>& talents)
abil_menu.set_flags(MF_SINGLESELECT | MF_ANYPRINTABLE
| MF_ALWAYS_SHOW_MORE);
- if (Options.tutorial_left)
+ if (Tutorial.tutorial_left)
{
// XXX: This could be buggy if you manage to pick up lots and
// lots of abilities during the tutorial.
diff --git a/crawl-ref/source/command.cc b/crawl-ref/source/command.cc
index 89c59c8bdb..26be6196f8 100644
--- a/crawl-ref/source/command.cc
+++ b/crawl-ref/source/command.cc
@@ -50,6 +50,7 @@
#include "stuff.h"
#include "terrain.h"
#include "transfor.h"
+#include "tutorial.h"
#include "view.h"
#include "viewchar.h"
@@ -2333,7 +2334,7 @@ void list_commands(int hotkey, bool do_redraw_screen)
// Page size is number of lines - one line for --more-- prompt.
cols.set_pagesize(get_number_of_lines() - 1);
- if (Options.tutorial_left)
+ if (Tutorial.tutorial_left)
_add_formatted_tutorial_help(cols);
else
_add_formatted_keyhelp(cols);
diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc
index 3422f8a758..d11b54bc6d 100644
--- a/crawl-ref/source/delay.cc
+++ b/crawl-ref/source/delay.cc
@@ -1587,7 +1587,7 @@ 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)
+ if (Tutorial.tutorial_left && your_talents(false).size() > old_talents)
learned_something_new(TUT_NEW_ABILITY_ITEM);
you.redraw_armour_class = true;
@@ -1897,7 +1897,7 @@ inline static bool _monster_warning(activity_interrupt_type ai,
const_cast<monsters*>(mon)->seen_context = "just seen";
}
- if (Options.tutorial_left)
+ if (Tutorial.tutorial_left)
tutorial_first_monster(*mon);
return (true);
@@ -1920,10 +1920,10 @@ void autotoggle_autopickup(bool off)
mprf(MSGCH_WARN,
"Deactivating autopickup; reactivate with <w>Ctrl+A</w>.");
}
- if (Options.tutorial_left)
+ if (Tutorial.tutorial_left)
{
learned_something_new(TUT_INVISIBLE_DANGER);
- Options.tut_seen_invisible = you.num_turns;
+ Tutorial.tut_seen_invisible = you.num_turns;
}
}
else if (Options.autopickup_on < 0) // was turned off automatically
diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc
index e064ce3bf2..c2495e71f9 100644
--- a/crawl-ref/source/describe.cc
+++ b/crawl-ref/source/describe.cc
@@ -2107,7 +2107,7 @@ void describe_feature_wide(const coord_def& pos)
mouse_control mc(MOUSE_MODE_MORE);
- if (Options.tutorial_left)
+ if (Tutorial.tutorial_left)
tutorial_describe_pos(pos.x, pos.y);
if (getch() == 0)
@@ -2157,7 +2157,7 @@ void get_item_desc(const item_def &item, describe_info &inf, bool terse)
// so we can actually output these spells if space is scarce.
const bool verbose = !terse || !item.has_spells();
inf.body << get_item_description(item, verbose, false,
- Options.tutorial_left);
+ Tutorial.tutorial_left);
}
// Returns true if spells can be shown to player.
@@ -2167,7 +2167,7 @@ static bool _show_item_description(const item_def &item)
const int height = get_number_of_lines();
std::string desc =
- get_item_description(item, true, false, Options.tutorial_left);
+ get_item_description(item, true, false, Tutorial.tutorial_left);
int num_lines = count_desc_lines(desc, lineWidth) + 1;
@@ -2179,7 +2179,7 @@ static bool _show_item_description(const item_def &item)
desc = get_item_description(item, 1, false, true);
print_description(desc);
- if (Options.tutorial_left)
+ if (Tutorial.tutorial_left)
tutorial_describe_item(item);
if (item.has_spells())
@@ -2337,7 +2337,7 @@ void inscribe_item(item_def &item, bool proper_prompt)
prompt = "<cyan>" + prompt + "</cyan>";
formatted_string::parse_string(prompt).display();
- if (Options.tutorial_left && wherey() <= get_number_of_lines() - 5)
+ if (Tutorial.tutorial_left && wherey() <= get_number_of_lines() - 5)
tutorial_inscription_info(need_autoinscribe, prompt);
}
did_prompt = true;
@@ -2992,7 +2992,7 @@ void describe_monsters(const monsters& mons, bool force_seen)
// TODO enne - this should really move into get_monster_db_desc
// and an additional tutorial string added to describe_info.
- if (Options.tutorial_left)
+ if (Tutorial.tutorial_left)
tutorial_describe_monster(&mons);
if (getch() == 0)
diff --git a/crawl-ref/source/directn.cc b/crawl-ref/source/directn.cc
index 8230db5e3e..fc9df131e7 100644
--- a/crawl-ref/source/directn.cc
+++ b/crawl-ref/source/directn.cc
@@ -3384,7 +3384,7 @@ static void _describe_cell(const coord_def& where, bool in_range)
#if DEBUG_DIAGNOSTICS
debug_stethoscope(mgrd(where));
#endif
- if (Options.tutorial_left && tutorial_monster_interesting(mon))
+ if (Tutorial.tutorial_left && tutorial_monster_interesting(mon))
{
std::string msg;
#ifdef USE_TILE
@@ -3471,7 +3471,7 @@ static void _describe_cell(const coord_def& where, bool in_range)
marker.c_str(),
traveldest.c_str());
#else
- if (Options.tutorial_left && tutorial_pos_interesting(where.x, where.y))
+ if (Tutorial.tutorial_left && tutorial_pos_interesting(where.x, where.y))
{
#ifdef USE_TILE
feature_desc += " (<w>Right-click</w> for more information.)";
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index b4c0600289..b0ce733591 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -56,6 +56,7 @@
#include "terrain.h"
#include "traps.h"
#include "travel.h"
+#include "tutorial.h"
#ifdef DEBUG_DIAGNOSTICS
#define DEBUG_TEMPLES 1
@@ -2695,7 +2696,7 @@ static const map_def *_dgn_random_map_for_place(bool minivault)
// Disallow entry vaults for tutorial (only complicates things).
if (!vault
&& lid.branch == BRANCH_MAIN_DUNGEON
- && lid.depth == 1 && !Options.tutorial_left)
+ && lid.depth == 1 && !Tutorial.tutorial_left)
{
vault = random_map_for_tag("entry");
}
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index 83da70dd07..ac7503ec95 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -3058,14 +3058,6 @@ enum tutorial_event_type
};
// NOTE: For numbers higher than 85 change size of tutorial_events in externs.h.
-enum tutorial_types
-{
- TUT_BERSERK_CHAR,
- TUT_MAGIC_CHAR,
- TUT_RANGER_CHAR,
- TUT_TYPES_NUM // 3
-};
-
enum undead_state_type // you.is_undead
{
US_ALIVE = 0,
diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc
index 0bbc50f53a..a6b428fe07 100644
--- a/crawl-ref/source/fight.cc
+++ b/crawl-ref/source/fight.cc
@@ -867,8 +867,8 @@ bool melee_attack::player_attack()
if (player_hits_monster())
{
did_hit = true;
- if (Options.tutorial_left)
- Options.tut_melee_counter++;
+ if (Tutorial.tutorial_left)
+ Tutorial.tut_melee_counter++;
const bool shield_blocked = attack_shield_blocked(true);
diff --git a/crawl-ref/source/food.cc b/crawl-ref/source/food.cc
index 2338a85098..453aada8ce 100644
--- a/crawl-ref/source/food.cc
+++ b/crawl-ref/source/food.cc
@@ -247,7 +247,7 @@ static bool _find_butchering_implement(int &butcher_tool)
if (!potential_candidate)
{
mpr("You don't carry any weapon you could use for butchering.");
- if (Options.tutorial_left)
+ if (Tutorial.tutorial_left)
{
mpr("You should pick up the first knife, dagger, sword or axe "
"you find so you can use it to butcher corpses.",
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index 5ab49f1123..12c02afeb9 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -377,7 +377,7 @@ 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)
+ if (Tutorial.tutorial_left && your_talents(false).size() > old_talents)
learned_something_new(TUT_NEW_ABILITY_ITEM);
// Time calculations.
@@ -3119,8 +3119,8 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus,
}
else
{
- if (Options.tutorial_left)
- Options.tut_throw_counter++;
+ if (Tutorial.tutorial_left)
+ Tutorial.tut_throw_counter++;
// Dropping item copy, since the launched item might be different.
pbolt.drop_item = !did_return;
@@ -3857,7 +3857,7 @@ bool puton_item(int item_slot)
// And calculate the effects.
jewellery_wear_effects(item);
- if (Options.tutorial_left && your_talents(false).size() > old_talents)
+ if (Tutorial.tutorial_left && your_talents(false).size() > old_talents)
learned_something_new(TUT_NEW_ABILITY_ITEM);
// Putting on jewellery is as fast as wielding weapons.
diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc
index 73751e1ab0..969b472cdd 100644
--- a/crawl-ref/source/items.cc
+++ b/crawl-ref/source/items.cc
@@ -1658,7 +1658,7 @@ int move_item_to_player(int obj, int quant_got, bool quiet,
mpr(get_menu_colour_prefix_tags(you.inv[freeslot],
DESC_INVENTORY).c_str());
}
- if (Options.tutorial_left)
+ if (Tutorial.tutorial_left)
{
taken_new_item(item.base_type);
if (is_artefact(item) || get_equip_desc( item ) != ISFLAG_NO_DESC)
diff --git a/crawl-ref/source/main.cc b/crawl-ref/source/main.cc
index 3402701346..ca4c848c95 100644
--- a/crawl-ref/source/main.cc
+++ b/crawl-ref/source/main.cc
@@ -284,7 +284,7 @@ int main( int argc, char *argv[] )
if (game_start)
{
- if (Options.tutorial_left)
+ if (Tutorial.tutorial_left)
_startup_tutorial();
_take_starting_note();
}
@@ -458,7 +458,7 @@ static void _take_starting_note()
static void _startup_tutorial()
{
// Don't allow triggering at game start.
- Options.tut_just_triggered = true;
+ Tutorial.tut_just_triggered = true;
msg::streams(MSGCH_TUTORIAL)
<< "Press any key to start the tutorial intro, or Escape to skip it."
@@ -694,8 +694,8 @@ static void _handle_wizard_command( void )
// Set up the running variables for the current run.
static void _start_running( int dir, int mode )
{
- if (Options.tutorial_events[TUT_SHIFT_RUN] && mode == RMODE_START)
- Options.tutorial_events[TUT_SHIFT_RUN] = false;
+ if (Tutorial.tutorial_events[TUT_SHIFT_RUN] && mode == RMODE_START)
+ Tutorial.tutorial_events[TUT_SHIFT_RUN] = false;
if (i_feel_safe(true))
you.running.initialise(dir, mode);
@@ -950,9 +950,9 @@ static void _input()
const bool player_feels_safe = i_feel_safe();
- if (Options.tutorial_left)
+ if (Tutorial.tutorial_left)
{
- Options.tut_just_triggered = false;
+ Tutorial.tut_just_triggered = false;
if (you.attribute[ATTR_HELD])
learned_something_new(TUT_CAUGHT_IN_NET);
@@ -967,7 +967,7 @@ static void _input()
tutorial_healing_reminder();
}
else if (!you.running
- && Options.tutorial_events[TUT_SHIFT_RUN]
+ && Tutorial.tutorial_events[TUT_SHIFT_RUN]
&& you.num_turns >= 200
&& you.hp == you.hp_max
&& you.magic_points == you.max_magic_points)
@@ -975,7 +975,7 @@ static void _input()
learned_something_new(TUT_SHIFT_RUN);
}
else if (!you.running
- && Options.tutorial_events[TUT_MAP_VIEW]
+ && Tutorial.tutorial_events[TUT_MAP_VIEW]
&& you.num_turns >= 500
&& you.hp == you.hp_max
&& you.magic_points == you.max_magic_points)
@@ -983,7 +983,7 @@ static void _input()
learned_something_new(TUT_MAP_VIEW);
}
else if (!you.running
- && Options.tutorial_events[TUT_AUTO_EXPLORE]
+ && Tutorial.tutorial_events[TUT_AUTO_EXPLORE]
&& you.num_turns >= 700
&& you.hp == you.hp_max
&& you.magic_points == you.max_magic_points)
@@ -996,7 +996,7 @@ static void _input()
if (2*you.hp < you.hp_max)
learned_something_new(TUT_RUN_AWAY);
- if (Options.tutorial_type == TUT_MAGIC_CHAR && you.magic_points < 1)
+ if (Tutorial.tutorial_type == TUT_MAGIC_CHAR && you.magic_points < 1)
learned_something_new(TUT_RETREAT_CASTER);
}
}
@@ -1645,8 +1645,8 @@ void process_command( command_type cmd )
break;
case CMD_SEARCH_STASHES:
- if (Options.tut_stashes)
- Options.tut_stashes = 0;
+ if (Tutorial.tut_stashes)
+ Tutorial.tut_stashes = 0;
StashTrack.search_stashes();
break;
@@ -1813,8 +1813,8 @@ void process_command( command_type cmd )
break;
}
- if (Options.tutorial_left)
- Options.tut_spell_counter++;
+ if (Tutorial.tutorial_left)
+ Tutorial.tut_spell_counter++;
if (!cast_a_spell(cmd == CMD_CAST_SPELL))
flush_input_buffer( FLUSH_ON_FAILURE );
break;
@@ -1837,8 +1837,8 @@ void process_command( command_type cmd )
break;
case CMD_INTERLEVEL_TRAVEL:
- if (Options.tut_travel)
- Options.tut_travel = 0;
+ if (Tutorial.tut_travel)
+ Tutorial.tut_travel = 0;
if (!can_travel_interlevel())
{
@@ -1879,8 +1879,8 @@ void process_command( command_type cmd )
break;
case CMD_DISPLAY_MAP:
- if (Options.tutorial_events[TUT_MAP_VIEW])
- Options.tutorial_events[TUT_MAP_VIEW] = false;
+ if (Tutorial.tutorial_events[TUT_MAP_VIEW])
+ Tutorial.tutorial_events[TUT_MAP_VIEW] = false;
#if (!DEBUG_DIAGNOSTICS)
if (!player_in_mappable_area())
@@ -2092,7 +2092,7 @@ void process_command( command_type cmd )
case CMD_NO_CMD:
default:
- if (Options.tutorial_left)
+ if (Tutorial.tutorial_left)
{
std::string msg = "Unknown command. (For a list of commands type "
"<w>?\?<lightgrey>.)";
@@ -2508,8 +2508,8 @@ static void _decrement_durations()
you.increase_duration(DUR_EXHAUSTED, dur * 2);
// Don't trigger too many tutorial messages.
- const bool tut_slow = Options.tutorial_events[TUT_YOU_ENCHANTED];
- Options.tutorial_events[TUT_YOU_ENCHANTED] = false;
+ const bool tut_slow = Tutorial.tutorial_events[TUT_YOU_ENCHANTED];
+ Tutorial.tutorial_events[TUT_YOU_ENCHANTED] = false;
{
// Don't give duplicate 'You feel yourself slow down' messages.
@@ -2551,7 +2551,7 @@ static void _decrement_durations()
calc_hp();
learned_something_new(TUT_POSTBERSERK);
- Options.tutorial_events[TUT_YOU_ENCHANTED] = tut_slow;
+ Tutorial.tutorial_events[TUT_YOU_ENCHANTED] = tut_slow;
}
if (you.duration[DUR_CORONA])
@@ -2766,7 +2766,7 @@ void world_reacts()
}
#ifdef USE_TILE
- if (Options.tutorial_left)
+ if (Tutorial.tutorial_left)
{
tiles.clear_text_tags(TAG_TUTORIAL);
tiles.place_cursor(CURSOR_TUTORIAL, Region::NO_CURSOR);
@@ -3829,10 +3829,10 @@ static bool _initialise(void)
// For a new game, wipe out monsters in LOS, and
// for new tutorial games also the items.
- zap_los_monsters(Options.tutorial_events[TUT_SEEN_FIRST_OBJECT]);
+ zap_los_monsters(Tutorial.tutorial_events[TUT_SEEN_FIRST_OBJECT]);
// For a newly started tutorial, turn secret doors into normal ones.
- if (Options.tutorial_left)
+ if (Tutorial.tutorial_left)
tutorial_zap_secret_doors();
}
diff --git a/crawl-ref/source/message.cc b/crawl-ref/source/message.cc
index 8958d52e27..05e8e77fab 100644
--- a/crawl-ref/source/message.cc
+++ b/crawl-ref/source/message.cc
@@ -1059,7 +1059,7 @@ void more(bool user_forced)
{
int keypress = 0;
- if (Options.tutorial_left)
+ if (Tutorial.tutorial_left)
{
message_out(crawl_view.msgsz.y - 1,
LIGHTGREY,
diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc
index c3f9f84956..ea245fbff3 100644
--- a/crawl-ref/source/misc.cc
+++ b/crawl-ref/source/misc.cc
@@ -1843,7 +1843,7 @@ void up_stairs(dungeon_feature_type force_stair,
&& (!yesno("Are you sure you want to leave the Dungeon?", false, 'n')
|| !_check_carrying_orb()))
{
- if (Options.tutorial_left)
+ if (Tutorial.tutorial_left)
{
if (!yesno("Are you *sure*? Doing so will end the game!", false,
'n'))
@@ -2701,8 +2701,8 @@ bool go_berserk(bool intentional)
if (!you.can_go_berserk(intentional))
return (false);
- if (Options.tutorial_left)
- Options.tut_berserk_counter++;
+ if (Tutorial.tutorial_left)
+ Tutorial.tut_berserk_counter++;
mpr("A red film seems to cover your vision as you go berserk!");
mpr("You feel yourself moving faster!");
diff --git a/crawl-ref/source/mon-act.cc b/crawl-ref/source/mon-act.cc
index fa6d52143b..6e41ed98d9 100644
--- a/crawl-ref/source/mon-act.cc
+++ b/crawl-ref/source/mon-act.cc
@@ -3060,7 +3060,7 @@ static bool _do_move_monster(monsters *monster, const coord_def& delta)
// this message to avoid confusion.
if (monster->seen_context == _just_seen && !you.see_cell(f))
simple_monster_message(monster, " moves out of view.");
- else if (Options.tutorial_left && (monster->flags & MF_WAS_IN_VIEW)
+ else if (Tutorial.tutorial_left && (monster->flags & MF_WAS_IN_VIEW)
&& !you.see_cell(f))
{
learned_something_new(TUT_MONSTER_LEFT_LOS, monster->pos());
diff --git a/crawl-ref/source/mon-stuff.cc b/crawl-ref/source/mon-stuff.cc
index 47c8e72c98..a1a955030e 100644
--- a/crawl-ref/source/mon-stuff.cc
+++ b/crawl-ref/source/mon-stuff.cc
@@ -498,7 +498,7 @@ int place_monster_corpse(const monsters *monster, bool silent,
static void _tutorial_inspect_kill()
{
- if (Options.tutorial_events[TUT_KILLED_MONSTER])
+ if (Tutorial.tutorial_events[TUT_KILLED_MONSTER])
learned_something_new(TUT_KILLED_MONSTER);
}
@@ -3480,7 +3480,7 @@ void seen_monster(monsters *monster)
if (!mons_is_mimic(monster->type))
{
- if (Options.tutorial_left)
+ if (Tutorial.tutorial_left)
tutorial_first_monster(*monster);
if (MONST_INTERESTING(monster))
diff --git a/crawl-ref/source/mutation.cc b/crawl-ref/source/mutation.cc
index a606296705..55769f6eda 100644
--- a/crawl-ref/source/mutation.cc
+++ b/crawl-ref/source/mutation.cc
@@ -2403,7 +2403,7 @@ bool mutate(mutation_type which_mutation, bool failMsg,
take_note(Note(NOTE_GET_MUTATION, mutat, you.mutation[mutat]));
- if (Options.tutorial_left && your_talents(false).size() > old_talents)
+ if (Tutorial.tutorial_left && your_talents(false).size() > old_talents)
learned_something_new(TUT_NEW_ABILITY_MUT);
return (true);
diff --git a/crawl-ref/source/options.h b/crawl-ref/source/options.h
index f24d7f49c7..4e37f4352d 100644
--- a/crawl-ref/source/options.h
+++ b/crawl-ref/source/options.h
@@ -389,23 +389,6 @@ public:
int prev_wand;
bool prev_randpick;
- ///////////////////////////////////////////////////////////////////////
- // tutorial
- FixedVector<bool, 85> tutorial_events;
- bool tut_explored;
- bool tut_stashes;
- bool tut_travel;
- unsigned int tut_spell_counter;
- unsigned int tut_throw_counter;
- unsigned int tut_berserk_counter;
- unsigned int tut_melee_counter;
- unsigned int tut_last_healed;
- unsigned int tut_seen_invisible;
-
- bool tut_just_triggered;
- unsigned int tutorial_type;
- unsigned int tutorial_left;
-
private:
typedef std::map<std::string, std::string> string_map;
string_map aliases;
diff --git a/crawl-ref/source/ouch.cc b/crawl-ref/source/ouch.cc
index 42c8a9f25d..b9416a97a7 100644
--- a/crawl-ref/source/ouch.cc
+++ b/crawl-ref/source/ouch.cc
@@ -1305,7 +1305,7 @@ void end_game(scorefile_entry &se)
flush_prev_message();
viewwindow(false); // don't do for leaving/winning characters
- if (Options.tutorial_left)
+ if (Tutorial.tutorial_left)
tutorial_death_screen();
}
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index 858b963f84..8c09a7d2ba 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -3101,7 +3101,7 @@ void level_change(bool skip_attribute_increase)
// Increase tutorial time-out now that it's actually become useful
// for a longer time.
- if (Options.tutorial_left && you.experience_level >= 7)
+ if (Tutorial.tutorial_left && you.experience_level >= 7)
tutorial_finished();
}
diff --git a/crawl-ref/source/shout.cc b/crawl-ref/source/shout.cc
index 25edbe3ee9..84fc52a2c1 100644
--- a/crawl-ref/source/shout.cc
+++ b/crawl-ref/source/shout.cc
@@ -261,7 +261,7 @@ void handle_monster_shouts(monsters* monster, bool force)
const int noise_level = get_shout_noise_level(s_type);
const bool heard = noisy(noise_level, monster->pos(), monster->mindex());
- if (Options.tutorial_left && (heard || you.can_see(monster)))
+ if (Tutorial.tutorial_left && (heard || you.can_see(monster)))
learned_something_new(TUT_MONSTER_SHOUT, monster->pos());
}
diff --git a/crawl-ref/source/skills2.cc b/crawl-ref/source/skills2.cc
index ad6045d0b4..c9c0c0046e 100644
--- a/crawl-ref/source/skills2.cc
+++ b/crawl-ref/source/skills2.cc
@@ -1675,7 +1675,7 @@ static void _display_skill_table(bool show_aptitudes, bool show_description)
}
}
- if (Options.tutorial_left)
+ if (Tutorial.tutorial_left)
{
if (show_description || maxln >= bottom_line - 5)
{
@@ -1757,7 +1757,7 @@ void show_skills()
{
// Show skill description.
show_description = !show_description;
- if (Options.tutorial_left)
+ if (Tutorial.tutorial_left)
clrscr();
continue;
}
diff --git a/crawl-ref/source/state.cc b/crawl-ref/source/state.cc
index 6918a7061d..172383cba6 100644
--- a/crawl-ref/source/state.cc
+++ b/crawl-ref/source/state.cc
@@ -219,7 +219,7 @@ bool interrupt_cmd_repeat( activity_interrupt_type ai,
print_formatted_paragraph(text, MSGCH_WARN);
}
- if (Options.tutorial_left)
+ if (Tutorial.tutorial_left)
tutorial_first_monster(*mon);
#else
formatted_string fs( channel_to_colour(MSGCH_WARN) );
diff --git a/crawl-ref/source/travel.cc b/crawl-ref/source/travel.cc
index 23c2e5e6c4..3cd1897d74 100644
--- a/crawl-ref/source/travel.cc
+++ b/crawl-ref/source/travel.cc
@@ -2786,8 +2786,8 @@ void start_travel(const coord_def& p)
void start_explore(bool grab_items)
{
- if (Options.tut_explored)
- Options.tut_explored = false;
+ if (Tutorial.tut_explored)
+ Tutorial.tut_explored = false;
if (!player_in_mappable_area())
{
diff --git a/crawl-ref/source/tutorial.cc b/crawl-ref/source/tutorial.cc
index ed4dc30027..40d2d5cf36 100644
--- a/crawl-ref/source/tutorial.cc
+++ b/crawl-ref/source/tutorial.cc
@@ -80,34 +80,36 @@ static int _get_tutorial_cols()
#endif
}
+tutorial_state Tutorial;
+
void save_tutorial(writer& outf)
{
marshallLong( outf, TUTORIAL_VERSION);
- marshallShort( outf, Options.tutorial_type);
+ marshallShort( outf, Tutorial.tutorial_type);
for (long i = 0; i < TUT_EVENTS_NUM; ++i)
- marshallBoolean( outf, Options.tutorial_events[i] );
+ marshallBoolean( outf, Tutorial.tutorial_events[i] );
}
void load_tutorial(reader& inf)
{
- Options.tutorial_left = 0;
+ Tutorial.tutorial_left = 0;
int version = unmarshallLong(inf);
if (version != TUTORIAL_VERSION)
return;
- Options.tutorial_type = unmarshallShort(inf);
+ Tutorial.tutorial_type = unmarshallShort(inf);
for (long i = 0; i < TUT_EVENTS_NUM; ++i)
{
- Options.tutorial_events[i] = unmarshallBoolean(inf);
- Options.tutorial_left += Options.tutorial_events[i];
+ Tutorial.tutorial_events[i] = unmarshallBoolean(inf);
+ Tutorial.tutorial_left += Tutorial.tutorial_events[i];
}
}
// Override init file definition for some options.
void init_tutorial_options()
{
- if (!Options.tutorial_left)
+ if (!Tutorial.tutorial_left)
return;
Options.delay_message_clear = false;
@@ -153,36 +155,36 @@ bool pick_tutorial()
// Choose character for tutorial game and set starting values.
if (keyn >= 'a' && keyn <= 'a' + TUT_TYPES_NUM - 1)
{
- Options.tutorial_type = keyn - 'a';
- you.species = _get_tutorial_species(Options.tutorial_type);
- you.char_class = _get_tutorial_job(Options.tutorial_type);
+ Tutorial.tutorial_type = keyn - 'a';
+ you.species = _get_tutorial_species(Tutorial.tutorial_type);
+ you.char_class = _get_tutorial_job(Tutorial.tutorial_type);
// Activate all triggers.
// This is rather backwards: If (true) an event still needs to be
// triggered, if (false) the relevant message was already printed.
- Options.tutorial_events.init(true);
- Options.tutorial_left = TUT_EVENTS_NUM;
+ Tutorial.tutorial_events.init(true);
+ Tutorial.tutorial_left = TUT_EVENTS_NUM;
// Used to compare which fighting means was used most often.
// XXX: This gets reset with every save, which seems odd.
// On the other hand, it's precisely between saves that
// players are most likely to forget these.
- Options.tut_spell_counter = 0;
- Options.tut_throw_counter = 0;
- Options.tut_melee_counter = 0;
- Options.tut_berserk_counter = 0;
+ Tutorial.tut_spell_counter = 0;
+ Tutorial.tut_throw_counter = 0;
+ Tutorial.tut_melee_counter = 0;
+ Tutorial.tut_berserk_counter = 0;
// Store whether explore, stash search or travelling was used.
// XXX: Also not stored across save games.
- Options.tut_explored = true;
- Options.tut_stashes = true;
- Options.tut_travel = true;
+ Tutorial.tut_explored = true;
+ Tutorial.tut_stashes = true;
+ Tutorial.tut_travel = true;
// For occasional healing reminders.
- Options.tut_last_healed = 0;
+ Tutorial.tut_last_healed = 0;
// Did the player recently see a monster turn invisible?
- Options.tut_seen_invisible = 0;
+ Tutorial.tut_seen_invisible = 0;
Options.random_pick = false;
if (!Options.book || Options.book == SBT_SUMM)
@@ -218,15 +220,15 @@ bool pick_tutorial()
void tutorial_load_game()
{
- if (!Options.tutorial_left)
+ if (!Tutorial.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;
+ Tutorial.tut_explored = Tutorial.tutorial_events[TUT_AUTO_EXPLORE];
+ Tutorial.tut_stashes = true;
+ Tutorial.tut_travel = true;
}
void print_tutorial_menu(unsigned int type)
@@ -523,7 +525,7 @@ static formatted_string _tutorial_debug()
{
snprintf(info, INFO_SIZE, "%d: %s (%s)",
i, _tut_debug_list(i).c_str(),
- Options.tutorial_events[i] ? "true" : "false");
+ Tutorial.tutorial_events[i] ? "true" : "false");
result += info;
@@ -541,7 +543,7 @@ static formatted_string _tutorial_debug()
}
result += "</lightblue>" EOL EOL;
- snprintf(info, INFO_SIZE, "tutorial_left: %d\n", Options.tutorial_left);
+ snprintf(info, INFO_SIZE, "tutorial_left: %d\n", Tutorial.tutorial_left);
result += info;
result += EOL;
@@ -748,7 +750,7 @@ void tut_starting_screen()
// Once a tutorial character dies, offer some playing hints.
void tutorial_death_screen()
{
- Options.tutorial_left = 0;
+ Tutorial.tutorial_left = 0;
std::string text;
mpr( "Condolences! Your character's premature death is a sad, but "
@@ -760,13 +762,13 @@ void tutorial_death_screen()
MSGCH_TUTORIAL);
more();
- if (Options.tutorial_type == TUT_MAGIC_CHAR
- && Options.tut_spell_counter < Options.tut_melee_counter )
+ if (Tutorial.tutorial_type == TUT_MAGIC_CHAR
+ && Tutorial.tut_spell_counter < Tutorial.tut_melee_counter )
{
text = "As a Conjurer your main weapon should be offensive magic. Cast "
"spells more often! Remember to rest when your Magic is low.";
}
- else if (you.religion == GOD_TROG && Options.tut_berserk_counter <= 3
+ else if (you.religion == GOD_TROG && Tutorial.tut_berserk_counter <= 3
&& !you.duration[DUR_EXHAUSTED])
{
text = "Don't forget to go berserk when fighting particularly "
@@ -779,8 +781,8 @@ void tutorial_death_screen()
"need to go berserk.";
}
}
- else if (Options.tutorial_type == TUT_RANGER_CHAR
- && 2*Options.tut_throw_counter < Options.tut_melee_counter )
+ else if (Tutorial.tutorial_type == TUT_RANGER_CHAR
+ && 2*Tutorial.tut_throw_counter < Tutorial.tut_melee_counter )
{
text = "Your bow and arrows are extremely powerful against distant "
"monsters. Be sure to collect all arrows lying around in the "
@@ -793,8 +795,8 @@ void tutorial_death_screen()
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)
+ if (hint == 0 && Tutorial.tut_throw_counter + Tutorial.tut_spell_counter
+ >= Tutorial.tut_melee_counter)
{
hint = random2(5) + 1;
skip_first_hint = true;
@@ -877,7 +879,7 @@ void tutorial_death_screen()
mpr( "See you next game!", MSGCH_TUTORIAL);
- Options.tutorial_events.init(false);
+ Tutorial.tutorial_events.init(false);
}
// If a character survives until Xp 7, the tutorial is declared finished
@@ -887,7 +889,7 @@ void tutorial_finished()
{
std::string text;
- Options.tutorial_left = 0;
+ Tutorial.tutorial_left = 0;
text = "Congrats! You survived until the end of this tutorial - be sure "
"to try the other ones as well. Note that the command help screen "
"(<w>?\?</w>) will look very different from now on. Here's a last "
@@ -896,13 +898,13 @@ void tutorial_finished()
formatted_message_history(text, MSGCH_TUTORIAL, 0, _get_tutorial_cols());
more();
- if (Options.tut_explored)
+ if (Tutorial.tut_explored)
{
text = "Walking around and exploring levels gets easier by using "
"auto-explore (<w>o</w>). Crawl will let you automatically "
"move to and pick up interesting items.";
}
- else if (Options.tut_travel)
+ else if (Tutorial.tut_travel)
{
text = "There is a convenient way for travelling between far away "
"dungeon levels: press <w>Ctrl-G</w> or <w>G</w> and enter "
@@ -910,7 +912,7 @@ void tutorial_finished()
"issuing <w>Ctrl-G Enter</w> or <w>G Enter</w> will continue "
"it.";
}
- else if (Options.tut_stashes)
+ else if (Tutorial.tut_stashes)
{
text = "You can search among all items existing in the dungeon with "
"the <w>Ctrl-F</w> command. For example, "
@@ -964,13 +966,13 @@ void tutorial_finished()
formatted_message_history(text, MSGCH_TUTORIAL, 0, _get_tutorial_cols());
more();
- Options.tutorial_events.init(false);
+ Tutorial.tutorial_events.init(false);
}
// Occasionally remind religious characters of sacrifices.
void tutorial_dissection_reminder(bool healthy)
{
- if (Options.tut_just_triggered || !Options.tutorial_left)
+ if (Tutorial.tut_just_triggered || !Tutorial.tutorial_left)
return;
// When hungry, give appropriate message or at least don't suggest
@@ -984,11 +986,11 @@ void tutorial_dissection_reminder(bool healthy)
if (!god_likes_fresh_corpses(you.religion))
return;
- if (Options.tutorial_events[TUT_OFFER_CORPSE])
+ if (Tutorial.tutorial_events[TUT_OFFER_CORPSE])
learned_something_new(TUT_OFFER_CORPSE);
else if (one_chance_in(8))
{
- Options.tut_just_triggered = true;
+ Tutorial.tut_just_triggered = true;
std::string text;
text += "If you don't want to eat it, consider offering this "
@@ -1014,16 +1016,16 @@ void tutorial_dissection_reminder(bool healthy)
// Occasionally remind injured characters of resting.
void tutorial_healing_reminder()
{
- if (!Options.tutorial_left)
+ if (!Tutorial.tutorial_left)
return;
if (you.duration[DUR_POISONING] && 2*you.hp < you.hp_max)
{
- if (Options.tutorial_events[TUT_NEED_POISON_HEALING])
+ if (Tutorial.tutorial_events[TUT_NEED_POISON_HEALING])
learned_something_new(TUT_NEED_POISON_HEALING);
}
- else if (Options.tut_seen_invisible > 0
- && you.num_turns - Options.tut_seen_invisible <= 20)
+ else if (Tutorial.tut_seen_invisible > 0
+ && you.num_turns - Tutorial.tut_seen_invisible <= 20)
{
// If we recently encountered an invisible monster, we need a
// special message.
@@ -1032,15 +1034,15 @@ void tutorial_healing_reminder()
}
else
{
- if (Options.tutorial_events[TUT_NEED_HEALING])
+ if (Tutorial.tutorial_events[TUT_NEED_HEALING])
learned_something_new(TUT_NEED_HEALING);
- else if (you.num_turns - Options.tut_last_healed >= 50
+ else if (you.num_turns - Tutorial.tut_last_healed >= 50
&& !you.duration[DUR_POISONING])
{
- if (Options.tut_just_triggered)
+ if (Tutorial.tut_just_triggered)
return;
- Options.tut_just_triggered = 1;
+ Tutorial.tut_just_triggered = 1;
std::string text;
text = "Remember to rest between fights and to enter unexplored "
@@ -1069,7 +1071,7 @@ void tutorial_healing_reminder()
if (is_resting())
stop_running();
}
- Options.tut_last_healed = you.num_turns;
+ Tutorial.tut_last_healed = you.num_turns;
}
}
@@ -1126,7 +1128,7 @@ void taken_new_item(unsigned char item_type)
// Give a special message if you gain a skill you didn't have before.
void tut_gained_new_skill(int skill)
{
- if (!Options.tutorial_left)
+ if (!Tutorial.tutorial_left)
return;
learned_something_new(TUT_SKILL_RAISE);
@@ -1278,9 +1280,9 @@ void tutorial_first_monster(const monsters &mon)
tutorial_event_type et = mon.type == MONS_TOADSTOOL ?
TUT_SEEN_TOADSTOOL : TUT_SEEN_ZERO_EXP_MON;
- if (Options.tutorial_events[et])
+ if (Tutorial.tutorial_events[et])
{
- if (Options.tut_just_triggered)
+ if (Tutorial.tut_just_triggered)
return;
learned_something_new(et, mon.pos());
@@ -1288,13 +1290,13 @@ void tutorial_first_monster(const monsters &mon)
}
// Don't do TUT_SEEN_MONSTER for zero exp monsters.
- if (Options.tutorial_events[TUT_SEEN_MONSTER])
+ if (Tutorial.tutorial_events[TUT_SEEN_MONSTER])
return;
}
- if (!Options.tutorial_events[TUT_SEEN_MONSTER])
+ if (!Tutorial.tutorial_events[TUT_SEEN_MONSTER])
{
- if (Options.tut_just_triggered)
+ if (Tutorial.tut_just_triggered)
return;
if (_mons_is_highlighted(&mon))
@@ -1313,9 +1315,9 @@ void tutorial_first_monster(const monsters &mon)
stop_running();
- Options.tutorial_events[TUT_SEEN_MONSTER] = false;
- Options.tutorial_left--;
- Options.tut_just_triggered = true;
+ Tutorial.tutorial_events[TUT_SEEN_MONSTER] = false;
+ Tutorial.tutorial_left--;
+ Tutorial.tut_just_triggered = true;
std::string text = "That ";
#ifdef USE_TILE
@@ -1356,7 +1358,7 @@ void tutorial_first_monster(const monsters &mon)
formatted_message_history(text, MSGCH_TUTORIAL, 0, _get_tutorial_cols());
- if (Options.tutorial_type == TUT_RANGER_CHAR)
+ if (Tutorial.tutorial_type == TUT_RANGER_CHAR)
{
text = "However, as a hunter you will want to deal with it using your "
"bow. If you have a look at your bow from your "
@@ -1387,7 +1389,7 @@ void tutorial_first_monster(const monsters &mon)
formatted_message_history(text, MSGCH_TUTORIAL, 0,
_get_tutorial_cols());
}
- else if (Options.tutorial_type == TUT_MAGIC_CHAR)
+ else if (Tutorial.tutorial_type == TUT_MAGIC_CHAR)
{
text = "However, as a conjurer you will want to deal with it using "
"magic. If you have a look at your spellbook from your "
@@ -1414,13 +1416,13 @@ void tutorial_first_item(const item_def &item)
if (monster_at(item.pos))
return;
- if (!Options.tutorial_events[TUT_SEEN_FIRST_OBJECT]
- || Options.tut_just_triggered)
+ if (!Tutorial.tutorial_events[TUT_SEEN_FIRST_OBJECT]
+ || Tutorial.tut_just_triggered)
{
// NOTE: Since a new player might not think to pick up a
// corpse (and why should they?), TUT_SEEN_CARRION is done when a
// corpse is first seen.
- if (!Options.tut_just_triggered
+ if (!Tutorial.tut_just_triggered
&& item.base_type == OBJ_CORPSES
&& !monster_at(item.pos))
{
@@ -1431,9 +1433,9 @@ void tutorial_first_item(const item_def &item)
stop_running();
- Options.tutorial_events[TUT_SEEN_FIRST_OBJECT] = false;
- Options.tutorial_left--;
- Options.tut_just_triggered = true;
+ Tutorial.tutorial_events[TUT_SEEN_FIRST_OBJECT] = false;
+ Tutorial.tutorial_left--;
+ Tutorial.tut_just_triggered = true;
std::string text = "That ";
#ifndef USE_TILE
@@ -1620,8 +1622,8 @@ static std::string _describe_portal(const coord_def &gc)
#define DELAY_EVENT \
{ \
- Options.tutorial_events[seen_what] = true; \
- Options.tutorial_left++; \
+ Tutorial.tutorial_events[seen_what] = true; \
+ Tutorial.tutorial_left++; \
return; \
}
@@ -1668,11 +1670,11 @@ static bool _rare_tutorial_event(tutorial_event_type event)
void learned_something_new(tutorial_event_type seen_what, coord_def gc)
{
// Already learned about that.
- if (!Options.tutorial_events[seen_what])
+ if (!Tutorial.tutorial_events[seen_what])
return;
// Don't trigger twice in the same turn.
- if (Options.tut_just_triggered && !_rare_tutorial_event(seen_what))
+ if (Tutorial.tut_just_triggered && !_rare_tutorial_event(seen_what))
return;
std::ostringstream text;
@@ -1681,9 +1683,9 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
const coord_def e = grid2show(gc);
#endif
- Options.tut_just_triggered = true;
- Options.tutorial_events[seen_what] = false;
- Options.tutorial_left--;
+ Tutorial.tut_just_triggered = true;
+ Tutorial.tutorial_events[seen_what] = false;
+ Tutorial.tutorial_left--;
switch (seen_what)
{
@@ -1775,12 +1777,12 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
#endif
".";
- if (Options.tutorial_type == TUT_BERSERK_CHAR)
+ if (Tutorial.tutorial_type == TUT_BERSERK_CHAR)
{
text << "\nAs you're already trained in Axes you should stick "
"with these. Checking other axes can be worthwhile.";
}
- else if (Options.tutorial_type == TUT_MAGIC_CHAR)
+ else if (Tutorial.tutorial_type == TUT_MAGIC_CHAR)
{
text << "\nAs a spellslinger you don't need a weapon to fight. "
"However, you should still carry at least one knife, "
@@ -1805,12 +1807,12 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
"the item in your <w>i</w>nventory will give more "
"information about both missiles and launcher.";
- if (Options.tutorial_type == TUT_RANGER_CHAR)
+ if (Tutorial.tutorial_type == TUT_RANGER_CHAR)
{
text << "\nAs you're already trained in Bows you should stick "
"with arrows and collect more of them in the dungeon.";
}
- else if (Options.tutorial_type == TUT_MAGIC_CHAR)
+ else if (Tutorial.tutorial_type == TUT_MAGIC_CHAR)
{
text << "\nHowever, as a spellslinger, you don't really need "
"another type of ranged attack, unless there's another "
@@ -2204,7 +2206,7 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
"the corresponding faith you'll be asked for confirmation.";
if (you.religion == GOD_NO_GOD
- && Options.tutorial_type == TUT_MAGIC_CHAR)
+ && Tutorial.tutorial_type == TUT_MAGIC_CHAR)
{
text << "\n\nThe best god for an unexperienced conjurer is "
"probably Vehumet, though Sif Muna is a good second "
@@ -2255,7 +2257,7 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
text << "\nIn Tiles, the same can be achieved by clicking on an "
"adjacent door square.";
#endif
- if (!Options.tut_explored)
+ if (!Tutorial.tut_explored)
{
text << "\nTo avoid accidentally opening a door you'd rather "
"remain closed during travel or autoexplore, you can mark "
@@ -2300,16 +2302,16 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
"by killing this monster! Every action will use up some of "
"it to train certain skills. For example, fighting monsters ";
- if (Options.tutorial_type == TUT_BERSERK_CHAR)
+ if (Tutorial.tutorial_type == TUT_BERSERK_CHAR)
{
text << "in melee battle will raise your Axes and Fighting "
"skills.";
}
- else if (Options.tutorial_type == TUT_RANGER_CHAR)
+ else if (Tutorial.tutorial_type == TUT_RANGER_CHAR)
{
text << "using bow and arrows will raise your Bows skill.";
}
- else // if (Options.tutorial_type == TUT_MAGIC_CHAR)
+ else // if (Tutorial.tutorial_type == TUT_MAGIC_CHAR)
{
text << "with offensive magic will raise your Conjurations and "
"Spellcasting skills.";
@@ -2330,7 +2332,7 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
"occasionally increases to your attributes (strength, "
"dexterity, intelligence).";
- if (Options.tutorial_type == TUT_MAGIC_CHAR)
+ if (Tutorial.tutorial_type == TUT_MAGIC_CHAR)
{
text << "\nAlso, new experience levels let you learn more spells "
"(the Spellcasting skill also does this). For now, you "
@@ -2399,9 +2401,9 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
case TUT_YOU_SICK:
// Hack: reset tut_just_triggered, to force recursive calling of
// learned_something_new().
- Options.tut_just_triggered = false;
+ Tutorial.tut_just_triggered = false;
learned_something_new(TUT_YOU_ENCHANTED);
- Options.tut_just_triggered = true;
+ Tutorial.tut_just_triggered = true;
text << "Corpses can be spoiled or inedible, making you sick. "
"Also, some monsters' flesh is less palatable than others'. "
"While sick, your hitpoints won't regenerate and sometimes "
@@ -2420,9 +2422,9 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
case TUT_YOU_POISON:
// Hack: reset tut_just_triggered, to force recursive calling of
// learned_something_new().
- Options.tut_just_triggered = false;
+ Tutorial.tut_just_triggered = false;
learned_something_new(TUT_YOU_ENCHANTED);
- Options.tut_just_triggered = true;
+ Tutorial.tut_just_triggered = true;
text << "Poison will slowly reduce your HP. It wears off with time (";
if (!i_feel_safe())
@@ -2438,9 +2440,9 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
case TUT_YOU_ROTTING:
// Hack: Reset tut_just_triggered, to force recursive calling of
// learned_something_new().
- Options.tut_just_triggered = false;
+ Tutorial.tut_just_triggered = false;
learned_something_new(TUT_YOU_ENCHANTED);
- Options.tut_just_triggered = true;
+ Tutorial.tut_just_triggered = true;
text << "Ugh, your flesh is rotting! Not only does this slowly "
"reduce your HP, it also slowly reduces your <w>maximum</w> "
@@ -2486,7 +2488,7 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
"so you should pick up the first knife, dagger, sword "
"or axe you find. ";
}
- else if (Options.tutorial_type != TUT_MAGIC_CHAR)
+ else if (Tutorial.tutorial_type != TUT_MAGIC_CHAR)
text << "Your starting weapon will do nicely. ";
else if (num == 1)
text << "The slicing weapon you picked up will do nicely. ";
@@ -2499,7 +2501,7 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
text << "Try to dine on chunks in order to save permanent food.";
- if (Options.tutorial_type == TUT_BERSERK_CHAR)
+ if (Tutorial.tutorial_type == TUT_BERSERK_CHAR)
text << "\nNote that you cannot Berserk while hungry or worse.";
break;
@@ -2511,7 +2513,7 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
"In a pinch, potions and fountains also can provide some "
"nutrition, though not as much as food.";
- if (Options.tutorial_type == TUT_MAGIC_CHAR)
+ if (Tutorial.tutorial_type == TUT_MAGIC_CHAR)
text << "\nNote that you cannot cast spells while starving.";
break;
@@ -2552,14 +2554,14 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
"clicking on them.";
#endif
- if (Options.tut_stashes)
+ if (Tutorial.tut_stashes)
{
text << "\n\nYou can easily find items you've left on the floor "
"with the <w>Ctrl-F</w> command, which will let you "
"seach for all known items in the dungeon. For example, "
"<w>Ctrl-F \"knife\"</w> will list all knives. You can "
"can then travel to one of the spots.";
- Options.tut_stashes = false;
+ Tutorial.tut_stashes = false;
}
text << "\n\nBe warned that items that you leave on the floor can "
@@ -2641,7 +2643,7 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
break;
case TUT_AUTO_EXPLORE:
- if (!Options.tut_explored)
+ if (!Tutorial.tut_explored)
return;
text << "Fully exploring a level and picking up all the interesting "
@@ -2650,7 +2652,7 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
"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;
+ Tutorial.tut_explored = false;
break;
case TUT_DONE_EXPLORE:
@@ -2661,7 +2663,7 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
"staircase, and by pressing <w>.</w> or <w>Enter</w> your "
"character can move there, too. ";
- if (Options.tutorial_events[TUT_SEEN_STAIRS])
+ if (Tutorial.tutorial_events[TUT_SEEN_STAIRS])
{
text << "In rare cases, you may have found no downstairs at all. "
"Try searching for secret doors in suspicious looking "
@@ -2697,13 +2699,13 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
case TUT_AUTO_EXCLUSION:
// In the highly unlikely case the player encounters a
// hostile statue or oklob plant during the tutorial...
- if (Options.tut_explored)
+ if (Tutorial.tut_explored)
{
// Hack: Reset tut_just_triggered, to force recursive calling of
// learned_something_new().
- Options.tut_just_triggered = false;
+ Tutorial.tut_just_triggered = false;
learned_something_new(TUT_AUTO_EXPLORE);
- Options.tut_just_triggered = true;
+ Tutorial.tut_just_triggered = true;
}
text << "\nTo prevent autotravel or autoexplore taking you into "
"dangerous territory, you can set travel exclusions by "
@@ -2749,7 +2751,7 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
"make it easier for you to hit it.";
// To prevent this text being immediately followed by the next one...
- Options.tut_last_healed = you.num_turns - 30;
+ Tutorial.tut_last_healed = you.num_turns - 30;
break;
case TUT_NEED_HEALING_INVIS:
@@ -2759,12 +2761,12 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
"to quaff an appropriate potion. For normal resting you will "
"first have to get away from the danger.";
- Options.tut_last_healed = you.num_turns;
+ Tutorial.tut_last_healed = you.num_turns;
break;
case TUT_CAN_BERSERK:
// Don't print this information if the player already knows it.
- if (Options.tut_berserk_counter)
+ if (Tutorial.tut_berserk_counter)
return;
text << "Against particularly difficult foes, you should use your "
@@ -3004,12 +3006,12 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
&& item_cursed(you.inv[wpn]))
{
// Don't trigger if the wielded weapon is cursed.
- Options.tutorial_events[seen_what] = true;
- Options.tutorial_left++;
+ Tutorial.tutorial_events[seen_what] = true;
+ Tutorial.tutorial_left++;
return;
}
- if (Options.tutorial_type == TUT_RANGER_CHAR && wpn != -1
+ if (Tutorial.tutorial_type == TUT_RANGER_CHAR && wpn != -1
&& you.inv[wpn].base_type == OBJ_WEAPONS
&& you.inv[wpn].sub_type == WPN_BOW)
{
@@ -3025,7 +3027,7 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
break;
}
case TUT_FLEEING_MONSTER:
- if (Options.tutorial_type != TUT_BERSERK_CHAR)
+ if (Tutorial.tutorial_type != TUT_BERSERK_CHAR)
return;
text << "Now that monster is scared of you! Note that you do not "
@@ -3089,7 +3091,7 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
// them.
if (mons_class_flag(m->type, M_NO_EXP_GAIN))
{
- Options.tutorial_events[TUT_MONSTER_SHOUT] = true;
+ Tutorial.tutorial_events[TUT_MONSTER_SHOUT] = true;
return;
}
@@ -3296,13 +3298,13 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
"as an attempt to struggle free from the net. With a wielded "
"bladed weapon you will be able to cut the net faster";
- if (Options.tutorial_type == TUT_BERSERK_CHAR)
+ if (Tutorial.tutorial_type == TUT_BERSERK_CHAR)
text << ", especially if you're berserking while doing so";
text << ". Small species may also wriggle out of a net, only damaging "
"it a bit, so as to then <w>f</w>ire it at a monster.";
- if (Options.tutorial_type == TUT_MAGIC_CHAR)
+ if (Tutorial.tutorial_type == TUT_MAGIC_CHAR)
{
text << " Note that casting spells is still very much possible, "
"as is using wands, scrolls and potions.";
@@ -3323,11 +3325,11 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc)
"also check ";
std::vector<std::string> listed;
- if (Options.tutorial_type == TUT_MAGIC_CHAR)
+ if (Tutorial.tutorial_type == TUT_MAGIC_CHAR)
listed.push_back("your spells (<w>z?</w>)");
if (!your_talents(false).empty())
listed.push_back("your <w>a</w>bilities");
- if (Options.tutorial_type != TUT_MAGIC_CHAR || how_mutated())
+ if (Tutorial.tutorial_type != TUT_MAGIC_CHAR || how_mutated())
listed.push_back("your set of mutations (<w>A</w>)");
if (you.religion != GOD_NO_GOD)
listed.push_back("your religious standing (<w>^</w>)");
@@ -3592,7 +3594,7 @@ void tutorial_describe_item(const item_def &item)
<< "The rarer the description, the greater the potential "
<< "value of an item.";
- Options.tutorial_events[TUT_SEEN_RANDART] = false;
+ Tutorial.tutorial_events[TUT_SEEN_RANDART] = false;
}
if (item_known_cursed( item ) && !long_text)
{
@@ -3604,9 +3606,9 @@ void tutorial_describe_item(const item_def &item)
if (!wielded && is_throwable(&you, item))
ostr << " (Throwing it is safe, though.)";
- Options.tutorial_events[TUT_YOU_CURSED] = false;
+ Tutorial.tutorial_events[TUT_YOU_CURSED] = false;
}
- Options.tutorial_events[TUT_SEEN_WEAPON] = false;
+ Tutorial.tutorial_events[TUT_SEEN_WEAPON] = false;
break;
}
case OBJ_MISSILES:
@@ -3635,7 +3637,7 @@ void tutorial_describe_item(const item_def &item)
<< ", first you need to <w>w</w>ield an appropriate "
"launcher.";
}
- Options.tutorial_events[TUT_SEEN_MISSILES] = false;
+ Tutorial.tutorial_events[TUT_SEEN_MISSILES] = false;
break;
case OBJ_ARMOUR:
@@ -3676,7 +3678,7 @@ void tutorial_describe_item(const item_def &item)
".";
}
- if (Options.tutorial_type == TUT_MAGIC_CHAR
+ if (Tutorial.tutorial_type == TUT_MAGIC_CHAR
&& !is_light_armour(item)
&& get_armour_slot(item) == EQ_BODY_ARMOUR)
{
@@ -3686,14 +3688,14 @@ void tutorial_describe_item(const item_def &item)
"elven armour will be generally safe for any aspiring "
"spellcaster.";
}
- else if (Options.tutorial_type == TUT_MAGIC_CHAR
+ else if (Tutorial.tutorial_type == TUT_MAGIC_CHAR
&& is_shield(item))
{
ostr << "\nNote that shields will hinder you ability to "
"cast spells; the larger the shield, the bigger "
"the penalty.";
}
- else if (Options.tutorial_type == TUT_RANGER_CHAR
+ else if (Tutorial.tutorial_type == TUT_RANGER_CHAR
&& is_shield(item))
{
ostr << "\nNote that wearing a shield will greatly decrease "
@@ -3710,7 +3712,7 @@ void tutorial_describe_item(const item_def &item)
<< "The rarer the description, the greater the potential "
<< "value of an item.";
- Options.tutorial_events[TUT_SEEN_RANDART] = false;
+ Tutorial.tutorial_events[TUT_SEEN_RANDART] = false;
}
if (wearable)
{
@@ -3740,7 +3742,7 @@ void tutorial_describe_item(const item_def &item)
ostr << _tut_abilities(item);
}
}
- Options.tutorial_events[TUT_SEEN_ARMOUR] = false;
+ Tutorial.tutorial_events[TUT_SEEN_ARMOUR] = false;
break;
}
case OBJ_WANDS:
@@ -3749,7 +3751,7 @@ void tutorial_describe_item(const item_def &item)
#ifdef USE_TILE
ostr << " Alternatively, simply click on its tile.";
#endif
- Options.tutorial_events[TUT_SEEN_WAND] = false;
+ Tutorial.tutorial_events[TUT_SEEN_WAND] = false;
break;
case OBJ_FOOD:
@@ -3769,7 +3771,7 @@ void tutorial_describe_item(const item_def &item)
"you're probably not part of that group.";
}
}
- Options.tutorial_events[TUT_SEEN_FOOD] = false;
+ Tutorial.tutorial_events[TUT_SEEN_FOOD] = false;
break;
case OBJ_SCROLLS:
@@ -3779,7 +3781,7 @@ void tutorial_describe_item(const item_def &item)
#endif
".";
- Options.tutorial_events[TUT_SEEN_SCROLL] = false;
+ Tutorial.tutorial_events[TUT_SEEN_SCROLL] = false;
break;
case OBJ_JEWELLERY:
@@ -3818,7 +3820,7 @@ void tutorial_describe_item(const item_def &item)
"one) offer certain abilities you can activate. ";
ostr << _tut_abilities(item);
}
- Options.tutorial_events[TUT_SEEN_JEWELLERY] = false;
+ Tutorial.tutorial_events[TUT_SEEN_JEWELLERY] = false;
break;
}
case OBJ_POTIONS:
@@ -3827,7 +3829,7 @@ void tutorial_describe_item(const item_def &item)
"or simply click on it with your <w>left mouse button</w>"
#endif
".";
- Options.tutorial_events[TUT_SEEN_POTION] = false;
+ Tutorial.tutorial_events[TUT_SEEN_POTION] = false;
break;
case OBJ_BOOKS:
@@ -3909,11 +3911,11 @@ void tutorial_describe_item(const item_def &item)
}
}
ostr << "\n";
- Options.tutorial_events[TUT_SEEN_SPBOOK] = false;
+ Tutorial.tutorial_events[TUT_SEEN_SPBOOK] = false;
break;
case OBJ_CORPSES:
- Options.tutorial_events[TUT_SEEN_CARRION] = false;
+ Tutorial.tutorial_events[TUT_SEEN_CARRION] = false;
if (item.sub_type == CORPSE_SKELETON)
{
@@ -4036,7 +4038,7 @@ void tutorial_describe_item(const item_def &item)
"<w>d</w>rop it now.";
}
}
- Options.tutorial_events[TUT_SEEN_STAFF] = false;
+ Tutorial.tutorial_events[TUT_SEEN_STAFF] = false;
break;
case OBJ_MISCELLANY:
@@ -4056,7 +4058,7 @@ void tutorial_describe_item(const item_def &item)
"that can be harnessed by e<w>V</w>oking the item.";
}
- Options.tutorial_events[TUT_SEEN_MISC] = false;
+ Tutorial.tutorial_events[TUT_SEEN_MISC] = false;
break;
default:
@@ -4197,7 +4199,7 @@ static void _tutorial_describe_feature(int x, int y)
"mechanical traps you can't avoid tripping them "
"by levitating or flying over them.";
}
- Options.tutorial_events[TUT_SEEN_TRAP] = false;
+ Tutorial.tutorial_events[TUT_SEEN_TRAP] = false;
break;
case DNGN_TRAP_NATURAL: // only shafts for now
@@ -4205,7 +4207,7 @@ static void _tutorial_describe_feature(int x, int y)
"as shafts, which lead one to three levels down. They "
"can't be disarmed, but you can safely pass over them "
"if you're levitating or flying.";
- Options.tutorial_events[TUT_SEEN_TRAP] = false;
+ Tutorial.tutorial_events[TUT_SEEN_TRAP] = false;
break;
case DNGN_STONE_STAIRS_DOWN_I:
@@ -4226,7 +4228,7 @@ static void _tutorial_describe_feature(int x, int y)
"set of stairs. ";
}
- Options.tutorial_events[TUT_SEEN_STAIRS] = false;
+ Tutorial.tutorial_events[TUT_SEEN_STAIRS] = false;
break;
case DNGN_STONE_STAIRS_UP_I:
@@ -4259,7 +4261,7 @@ static void _tutorial_describe_feature(int x, int y)
"particular set of stairs. ";
}
}
- Options.tutorial_events[TUT_SEEN_STAIRS] = false;
+ Tutorial.tutorial_events[TUT_SEEN_STAIRS] = false;
break;
case DNGN_ESCAPE_HATCH_DOWN:
@@ -4268,17 +4270,17 @@ static void _tutorial_describe_feature(int x, int y)
"<w><<</w> and <w>></w>, respectively. Note that you will "
"usually be unable to return right away.";
- Options.tutorial_events[TUT_SEEN_ESCAPE_HATCH] = false;
+ Tutorial.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;
+ Tutorial.tutorial_events[TUT_SEEN_PORTAL] = false;
break;
case DNGN_CLOSED_DOOR:
case DNGN_DETECTED_SECRET_DOOR:
- if (!Options.tut_explored)
+ if (!Tutorial.tut_explored)
{
ostr << "\nTo avoid accidentally opening a door you'd rather "
"remain closed during travel or autoexplore, you can "
@@ -4344,7 +4346,7 @@ static void _tutorial_describe_feature(int x, int y)
#endif
".";
}
- Options.tutorial_events[TUT_SEEN_ALTAR] = false;
+ Tutorial.tutorial_events[TUT_SEEN_ALTAR] = false;
break;
}
else if (feat >= DNGN_ENTER_FIRST_BRANCH
@@ -4557,7 +4559,7 @@ void tutorial_describe_monster(const monsters *mons)
}
else if (dangerous)
{
- if (!Options.tut_explored && mons->foe != MHITYOU)
+ if (!Tutorial.tut_explored && mons->foe != MHITYOU)
{
ostr << "You can easily mark its square as dangerous to avoid "
"accidentally entering into its field of view when using "
diff --git a/crawl-ref/source/tutorial.h b/crawl-ref/source/tutorial.h
index e1065f9ac9..cf90e840a7 100644
--- a/crawl-ref/source/tutorial.h
+++ b/crawl-ref/source/tutorial.h
@@ -20,6 +20,14 @@ class formatted_string;
class writer;
class reader;
+enum tutorial_types
+{
+ TUT_BERSERK_CHAR,
+ TUT_MAGIC_CHAR,
+ TUT_RANGER_CHAR,
+ TUT_TYPES_NUM // 3
+};
+
void save_tutorial(writer& outf);
void load_tutorial(reader& inf);
void init_tutorial_options(void);
@@ -57,4 +65,24 @@ void tutorial_describe_pos(int x, int y);
bool tutorial_monster_interesting(const monsters *mons);
void tutorial_describe_monster(const monsters *mons);
+struct tutorial_state
+{
+ FixedVector<bool, 85> tutorial_events;
+ bool tut_explored;
+ bool tut_stashes;
+ bool tut_travel;
+ unsigned int tut_spell_counter;
+ unsigned int tut_throw_counter;
+ unsigned int tut_berserk_counter;
+ unsigned int tut_melee_counter;
+ unsigned int tut_last_healed;
+ unsigned int tut_seen_invisible;
+
+ bool tut_just_triggered;
+ unsigned int tutorial_type;
+ unsigned int tutorial_left;
+};
+
+extern tutorial_state Tutorial;
+
#endif
diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc
index ad306499a5..040d938cca 100644
--- a/crawl-ref/source/view.cc
+++ b/crawl-ref/source/view.cc
@@ -686,7 +686,7 @@ static bool player_view_update_at(const coord_def &gc)
}
// Print tutorial messages for features in LOS.
- if (Options.tutorial_left)
+ if (Tutorial.tutorial_left)
tutorial_observe_cell(gc);
if (!player_in_mappable_area())