summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/initfile.cc
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2006-11-22 08:41:20 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2006-11-22 08:41:20 +0000
commit1d0f57cbceb778139ca215cc4fcfd1584951f6dd (patch)
treecafd60c944c51fcce778aa5d6912bc548c518339 /crawl-ref/source/initfile.cc
parent6f5e187a9e5cd348296dba2fd89d2e206e775a01 (diff)
downloadcrawl-ref-1d0f57cbceb778139ca215cc4fcfd1584951f6dd.tar.gz
crawl-ref-1d0f57cbceb778139ca215cc4fcfd1584951f6dd.zip
Merged stone_soup r15:451 into trunk.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@452 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/initfile.cc')
-rw-r--r--crawl-ref/source/initfile.cc1248
1 files changed, 865 insertions, 383 deletions
diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc
index 46bf73e40e..a797100754 100644
--- a/crawl-ref/source/initfile.cc
+++ b/crawl-ref/source/initfile.cc
@@ -13,6 +13,8 @@
*/
#include "AppHdr.h"
+#include "externs.h"
+
#include "initfile.h"
#include <stdio.h>
@@ -21,9 +23,9 @@
#include <ctype.h>
#include "clua.h"
+#include "delay.h"
#include "Kills.h"
#include "files.h"
-#include "externs.h"
#include "defines.h"
#include "libutil.h"
#include "player.h"
@@ -33,34 +35,23 @@
#include "items.h"
#include "view.h"
-game_options Options;
-
-extern void (*viewwindow) (char, bool);
-extern unsigned char (*mapch) (unsigned char);
-extern unsigned char (*mapch2) (unsigned char);
-extern unsigned char mapchar3(unsigned char ldfk);
-extern unsigned char mapchar4(unsigned char ldfk);
+const std::string game_options::interrupt_prefix = "interrupt_";
+game_options Options;
-#ifdef UNIX
-extern int character_set; // unices only
-#endif
-
-static std::string & tolower_string( std::string &str );
+std::string &tolower_string( std::string &str );
const static char *obj_syms = ")([/%.?=!.+\\0}X$";
const static int obj_syms_len = 16;
static void read_startup_prefs();
-static void read_options(InitLineInput &il, bool runscript);
-template<class A, class B> void append_vector(
- std::vector<A> &dest, const std::vector<B> &src)
+template<class A, class B> void append_vector(A &dest, const B &src)
{
dest.insert( dest.end(), src.begin(), src.end() );
}
// returns -1 if unmatched else returns 0-15
-static short str_to_colour( const std::string &str )
+int str_to_colour( const std::string &str, int default_colour )
{
int ret;
@@ -71,6 +62,15 @@ static short str_to_colour( const std::string &str )
"lightred", "lightmagenta", "yellow", "white"
};
+ const std::string element_cols[] =
+ {
+ "fire", "ice", "earth", "electricity", "air", "poison", "water",
+ "magic", "mutagenic", "warp", "enchant", "heal", "holy", "dark",
+ "death", "necro", "unholy", "vehumet", "crystal", "blood", "smoke",
+ "slime", "jewel", "elven", "dwarven", "orcish", "gila", "floor",
+ "rock", "stone", "random"
+ };
+
for (ret = 0; ret < 16; ret++)
{
if (str == cols[ret])
@@ -88,6 +88,21 @@ static short str_to_colour( const std::string &str )
if (ret == 16)
{
+ // Maybe we have an element colour attribute.
+ for (unsigned i = 0; i < sizeof(element_cols) / sizeof(*element_cols);
+ ++i)
+ {
+ if (str == element_cols[i])
+ {
+ // Ugh.
+ ret = element_type(EC_FIRE + i);
+ break;
+ }
+ }
+ }
+
+ if (ret == 16)
+ {
// Check if we have a direct colour index
const char *s = str.c_str();
char *es = NULL;
@@ -96,7 +111,7 @@ static short str_to_colour( const std::string &str )
ret = ci;
}
- return ((ret == 16) ? -1 : ret);
+ return ((ret == 16) ? default_colour : ret);
}
// returns -1 if unmatched else returns 0-15
@@ -121,16 +136,16 @@ static int str_to_channel_colour( const std::string &str )
static const std::string message_channel_names[ NUM_MESSAGE_CHANNELS ] =
{
- "plain", "prompt", "god", "duration", "danger", "warning", "food",
- "recovery", "talk", "intrinsic_gain", "mutation", "monster_spell",
- "monster_enchant", "monster_damage", "rotten_meat", "equipment",
- "diagnostic",
+ "plain", "prompt", "god", "pray", "duration", "danger", "warning", "food",
+ "recovery", "sound", "talk", "intrinsic_gain", "mutation", "monster_spell",
+ "monster_enchant", "monster_damage", "monster_target",
+ "rotten_meat", "equipment", "floor", "multiturn", "diagnostic",
};
-// returns -1 if unmatched else returns 0-15
+// returns -1 if unmatched else returns 0--(NUM_MESSAGE_CHANNELS-1)
int str_to_channel( const std::string &str )
{
- short ret;
+ int ret;
for (ret = 0; ret < NUM_MESSAGE_CHANNELS; ret++)
{
@@ -149,6 +164,19 @@ std::string channel_to_str( int channel )
return message_channel_names[channel];
}
+static int str_to_book( const std::string& str )
+{
+ if ( str == "fire" || str == "flame" )
+ return SBT_FIRE;
+ if ( str == "cold" || str == "ice" )
+ return SBT_COLD;
+ if ( str == "summ" || str == "summoning" )
+ return SBT_SUMM;
+ if ( str == "random" )
+ return SBT_RANDOM;
+ return SBT_NO_SELECTION;
+}
+
static int str_to_weapon( const std::string &str )
{
if (str == "shortsword" || str == "short sword")
@@ -249,7 +277,7 @@ static char str_to_race( const std::string &str )
index -= (SP_CENTAUR - SP_RED_DRACONIAN - 1);
// SP_HUMAN is at 1, therefore we must subtract one.
- return ((index != -1) ? index_to_letter( index - 1 ) : '\0');
+ return ((index != -1) ? index_to_letter( index - 1 ) : 0);
}
static char str_to_class( const std::string &str )
@@ -265,10 +293,10 @@ static char str_to_class( const std::string &str )
if (index == -1)
index = get_class_index_by_name( str.c_str() );
- return ((index != -1) ? index_to_letter( index ) : '\0');
+ return ((index != -1) ? index_to_letter( index ) : 0);
}
-static std::string & tolower_string( std::string &str )
+std::string & tolower_string( std::string &str )
{
if (str.length())
{
@@ -285,10 +313,10 @@ static bool read_bool( const std::string &field, bool def_value )
{
bool ret = def_value;
- if (field == "true" || field == "1")
+ if (field == "true" || field == "1" || field == "yes")
ret = true;
- if (field == "false" || field == "0")
+ if (field == "false" || field == "0" || field == "no")
ret = false;
return (ret);
@@ -323,211 +351,379 @@ static unsigned curses_attribute(const std::string &field)
return CHATTR_NORMAL;
}
+void game_options::add_dump_fields(const std::string &text)
+{
+ // Easy; chardump.cc has most of the intelligence.
+ append_vector(dump_order, split_string(",", text, true, true));
+}
-static void reset_startup_options(bool clear_name = true)
+void game_options::reset_startup_options()
{
- if (clear_name)
- you.your_name[0] = '\0';
- Options.race = '\0';
- Options.cls = '\0';
- Options.weapon = WPN_UNKNOWN;
- Options.random_pick = false;
- Options.chaos_knight = GOD_NO_GOD;
- Options.death_knight = DK_NO_SELECTION;
- Options.priest = GOD_NO_GOD;
+ race = 0;
+ cls = 0;
+ weapon = WPN_UNKNOWN;
+ book = SBT_NO_SELECTION;
+ random_pick = false;
+ chaos_knight = GOD_NO_GOD;
+ death_knight = DK_NO_SELECTION;
+ priest = GOD_NO_GOD;
}
-void reset_options(bool clear_name)
+void game_options::set_default_activity_interrupts()
{
- // Option initialization
- Options.activity_interrupts[ ACT_MULTIDROP ] =
- AI_HP_LOSS | AI_STAT_CHANGE | AI_TELEPORT;
- Options.activity_interrupts[ ACT_RUNNING ] =
- 0xFFFF ^ AI_SEE_MONSTER;
- Options.activity_interrupts[ ACT_TRAVELING ] =
- 0xFFFF ^ (AI_MESSAGE | AI_SEE_MONSTER);
-
- reset_startup_options(clear_name);
- Options.prev_race = 0;
- Options.prev_cls = 0;
- Options.prev_ck = GOD_NO_GOD;
- Options.prev_dk = DK_NO_SELECTION;
- Options.prev_pr = GOD_NO_GOD;
- Options.prev_weapon = WPN_UNKNOWN;
- Options.prev_randpick = false;
- Options.remember_name = false;
-
- Options.autopickups = 0x0000;
- Options.verbose_dump = false;
- Options.detailed_stat_dump = true;
- Options.colour_map = false;
- Options.clean_map = false;
- Options.show_uncursed = true;
- Options.always_greet = false;
- Options.easy_open = true;
- Options.easy_armour = true;
- Options.easy_butcher = false;
- Options.easy_confirm = CONFIRM_SAFE_EASY;
- Options.easy_quit_item_prompts = false;
- Options.hp_warning = 10;
- Options.hp_attention = 25;
- Options.terse_hand = true;
- Options.auto_list = false;
- Options.delay_message_clear = false;
- Options.pickup_dropped = true;
- Options.travel_colour = true;
- Options.travel_delay = -1;
- Options.travel_stair_cost = 500;
- Options.travel_exclude_radius2 = 68;
- Options.show_waypoints = true;
- Options.item_colour = false;
-
- Options.detected_item_colour = DARKGREY;
- Options.detected_monster_colour= DARKGREY;
- Options.remembered_monster_colour = 0;
-
- Options.easy_exit_menu = true;
- Options.dos_use_background_intensity = false;
- Options.assign_item_slot = SS_FORWARD;
-
- Options.macro_meta_entry = true;
+ for (int adelay = 0; adelay < NUM_DELAYS; ++adelay)
+ for (int aint = 0; aint < NUM_AINTERRUPTS; ++aint)
+ activity_interrupts[adelay][aint] = true;
+
+ const char *default_activity_interrupts[] = {
+ "interrupt_armour_on = hp_loss, monster_attack",
+ "interrupt_armour_off = interrupt_armour_on",
+ "interrupt_drop_item = interrupt_armour_on",
+ "interrupt_jewellery_on = interrupt_armour_on",
+ "interrupt_memorise = interrupt_armour_on, stat",
+ "interrupt_butcher = interrupt_armour_on, teleport, stat",
+ "interrupt_passwall = interrupt_butcher",
+ "interrupt_multidrop = interrupt_butcher",
+ "interrupt_macro = interrupt_multidrop",
+ "interrupt_travel = interrupt_butcher, statue, hungry, burden, monster",
+ "interrupt_run = interrupt_travel, message",
+ "interrupt_rest = interrupt_run",
+
+ // Stair ascents/descents cannot be interrupted, attempts to interrupt
+ // the delay will just trash all queued delays, including travel.
+ "interrupt_ascending_stairs =",
+ "interrupt_descending_stairs =",
+ "interrupt_uninterruptible =",
+ "interrupt_autopickup =",
+ "interrupt_weapon_swap =",
+
+ NULL
+ };
- // 10 was the cursor step default on Linux.
- Options.level_map_cursor_step = 10;
+ for (int i = 0; default_activity_interrupts[i]; ++i)
+ read_option_line( default_activity_interrupts[i], false );
+}
-#ifdef STASH_TRACKING
- Options.stash_tracking = STM_NONE;
+void game_options::clear_activity_interrupts(
+ FixedVector<bool, NUM_AINTERRUPTS> &eints)
+{
+ for (int i = 0; i < NUM_AINTERRUPTS; ++i)
+ eints[i] = false;
+}
+
+void game_options::set_activity_interrupt(
+ FixedVector<bool, NUM_AINTERRUPTS> &eints,
+ const std::string &interrupt)
+{
+ if (interrupt.find(interrupt_prefix) == 0)
+ {
+ std::string delay_name = interrupt.substr( interrupt_prefix.length() );
+ delay_type delay = get_delay(delay_name);
+ if (delay == NUM_DELAYS)
+ {
+ fprintf(stderr, "Unknown delay: %s\n", delay_name.c_str());
+ return;
+ }
+
+ FixedVector<bool, NUM_AINTERRUPTS> &refints =
+ activity_interrupts[delay];
+
+ for (int i = 0; i < NUM_AINTERRUPTS; ++i)
+ if (refints[i])
+ eints[i] = true;
+
+ return;
+ }
+
+ activity_interrupt_type ai = get_activity_interrupt(interrupt);
+ if (ai == NUM_AINTERRUPTS)
+ {
+ fprintf(stderr, "Delay interrupt name \"%s\" not recognised.\n",
+ interrupt.c_str());
+ return;
+ }
+
+ eints[ai] = true;
+}
+
+void game_options::set_activity_interrupt(const std::string &activity_name,
+ const std::string &interrupt_names,
+ bool append_interrupts)
+{
+ const delay_type delay = get_delay(activity_name);
+ if (delay == NUM_DELAYS)
+ {
+ fprintf(stderr, "Unknown delay: %s\n", activity_name.c_str());
+ return;
+ }
+
+ FixedVector<bool, NUM_AINTERRUPTS> &eints = activity_interrupts[ delay ];
+
+ if (!append_interrupts)
+ clear_activity_interrupts(eints);
+
+ std::vector<std::string> interrupts = split_string(",", interrupt_names);
+ for (int i = 0, size = interrupts.size(); i < size; ++i)
+ set_activity_interrupt(eints, interrupts[i]);
+
+ eints[AI_FORCE_INTERRUPT] = true;
+}
+
+void game_options::reset_options()
+{
+ set_default_activity_interrupts();
+
+ reset_startup_options();
+
+#ifdef SAVE_DIR_PATH
+ save_dir = SAVE_DIR_PATH;
+#else
+ save_dir.clear();
+#endif
+
+ player_name.clear();
+
+ autopickup_on = true;
+ autoprayer_on = false;
+ fizzlecheck_on = false;
+
+ prev_race = 0;
+ prev_cls = 0;
+ prev_ck = GOD_NO_GOD;
+ prev_dk = DK_NO_SELECTION;
+ prev_pr = GOD_NO_GOD;
+ prev_weapon = WPN_UNKNOWN;
+ prev_book = SBT_NO_SELECTION;
+ prev_randpick = false;
+ remember_name = false;
+
+#ifdef USE_ASCII_CHARACTERS
+ char_set = CSET_ASCII;
+#else
+ char_set = CSET_IBM;
+#endif
+ init_char_table(char_set);
+
+ // set it to the .crawlrc default
+ autopickups = ((1L << 15) | // gold
+ (1L << 6) | // scrolls
+ (1L << 8) | // potions
+ (1L << 10) | // books
+ (1L << 7) | // jewellery
+ (1L << 3) | // wands
+ (1L << 4)); // food
+ verbose_dump = false;
+ detailed_stat_dump = true;
+ colour_map = true;
+ clean_map = false;
+ show_uncursed = true;
+ always_greet = true;
+ easy_open = true;
+ easy_unequip = true;
+ easy_butcher = true;
+ easy_confirm = CONFIRM_SAFE_EASY;
+ easy_quit_item_prompts = true;
+ hp_warning = 10;
+ hp_attention = 25;
+ confirm_self_target = true;
+ safe_autopickup = false;
+ use_notes = true;
+ note_skill_max = false;
+ note_all_spells = false;
+ note_hp_percent = 0;
+ ood_interesting = 8;
+ terse_hand = false;
+ increasing_skill_progress = false;
+
+ // [ds] Grumble grumble.
+ auto_list = true;
+
+ delay_message_clear = false;
+ pickup_dropped = false;
+ pickup_thrown = true;
+
+ travel_colour = true;
+ travel_delay = 10;
+ travel_stair_cost = 500;
+ travel_exclude_radius2 = 68;
+
+ sort_menus = false;
+
+ tc_reachable = BLUE;
+ tc_excluded = LIGHTMAGENTA;
+ tc_exclude_circle = RED;
+ tc_dangerous = CYAN;
+ tc_disconnected = DARKGREY;
+
+ show_waypoints = true;
+ item_colour = true;
+
+ // [ds] Default to jazzy colours.
+ detected_item_colour = LIGHTGREEN;
+ detected_monster_colour= LIGHTRED;
+
+ easy_exit_menu = true;
+#ifdef DOS
+ dos_use_background_intensity = false;
+#else
+ dos_use_background_intensity = true;
#endif
- Options.explore_stop = ES_ITEM | ES_STAIR | ES_SHOP | ES_ALTAR;
- Options.target_zero_exp = true;
- Options.target_wrap = false;
- Options.target_oos = true;
- Options.target_los_first = true;
- Options.dump_kill_places = KDO_ONE_PLACE;
- Options.dump_message_count = 4;
- Options.dump_item_origins = IODS_ARTIFACTS | IODS_RODS;
- Options.dump_item_origin_price = -1;
- Options.drop_mode = DM_SINGLE;
+ assign_item_slot = SS_FORWARD;
- Options.flush_input[ FLUSH_ON_FAILURE ] = true;
- Options.flush_input[ FLUSH_BEFORE_COMMAND ] = false;
- Options.flush_input[ FLUSH_ON_MESSAGE ] = false;
- Options.flush_input[ FLUSH_LUA ] = true;
+ macro_meta_entry = true;
+
+ // 10 was the cursor step default on Linux.
+ level_map_cursor_step = 10;
- Options.lowercase_invocations = false;
+#ifdef STASH_TRACKING
+ stash_tracking = STM_ALL;
+#endif
+ explore_stop = ES_ITEM | ES_STAIR | ES_SHOP | ES_ALTAR;
+ safe_zero_exp = true;
+ target_zero_exp = false;
+ target_wrap = true;
+ target_oos = true;
+ target_los_first = true;
+ dump_kill_places = KDO_ONE_PLACE;
+ dump_message_count = 7;
+ dump_item_origins = IODS_ARTIFACTS | IODS_RODS;
+ dump_item_origin_price = -1;
+
+ drop_mode = DM_SINGLE;
+
+ flush_input[ FLUSH_ON_FAILURE ] = true;
+ flush_input[ FLUSH_BEFORE_COMMAND ] = false;
+ flush_input[ FLUSH_ON_MESSAGE ] = false;
+ flush_input[ FLUSH_LUA ] = true;
+
+ lowercase_invocations = false;
// Note: These fire options currently match the old behaviour. -- bwr
- Options.fire_items_start = 0; // start at slot 'a'
+ fire_items_start = 0; // start at slot 'a'
- Options.fire_order[0] = FIRE_LAUNCHER; // fire first from bow...
- Options.fire_order[1] = FIRE_DART; // then only consider darts
+ fire_order[0] = FIRE_LAUNCHER; // fire first from bow...
+ fire_order[1] = FIRE_DART; // then only consider darts
- // clear the reast of the list
+ // clear the rest of the list
for (int i = 2; i < NUM_FIRE_TYPES; i++)
- Options.fire_order[i] = FIRE_NONE;
+ fire_order[i] = FIRE_NONE;
+
+#ifdef WIZARD
+ fsim_rounds = 40000L;
+ fsim_mons = "worm";
+ fsim_str = fsim_int = fsim_dex = 15;
+ fsim_xl = 10;
+ fsim_kit.clear();
+#endif
// These are only used internally, and only from the commandline:
// XXX: These need a better place.
- Options.sc_entries = 0;
- Options.sc_format = SCORE_REGULAR;
+ sc_entries = 0;
+ sc_format = SCORE_REGULAR;
-//#ifdef USE_COLOUR_OPTS
- Options.friend_brand = CHATTR_NORMAL;
- Options.heap_brand = CHATTR_NORMAL;
- Options.stab_brand = CHATTR_NORMAL;
- Options.may_stab_brand = CHATTR_NORMAL;
- Options.no_dark_brand = 0;
-//#endif
+ friend_brand = CHATTR_NORMAL;
+ heap_brand = CHATTR_NORMAL;
+ stab_brand = CHATTR_NORMAL;
+ may_stab_brand = CHATTR_NORMAL;
+ no_dark_brand = 0;
#ifdef WIZARD
- Options.wiz_mode = WIZ_NO;
+ wiz_mode = WIZ_NO;
#endif
// map each colour to itself as default
#ifdef USE_8_COLOUR_TERM_MAP
for (int i = 0; i < 16; i++)
- Options.colour[i] = i % 8;
+ colour[i] = i % 8;
- Options.colour[ DARKGREY ] = COL_TO_REPLACE_DARKGREY;
+ colour[ DARKGREY ] = COL_TO_REPLACE_DARKGREY;
#else
for (int i = 0; i < 16; i++)
- Options.colour[i] = i;
+ colour[i] = i;
#endif
// map each channel to plain (well, default for now since I'm testing)
for (int i = 0; i < NUM_MESSAGE_CHANNELS; i++)
- Options.channels[i] = MSGCOL_DEFAULT;
+ channels[i] = MSGCOL_DEFAULT;
// Clear vector options.
- Options.banned_objects.clear();
- Options.stop_travel.clear();
- Options.sound_mappings.clear();
- Options.menu_colour_mappings.clear();
- Options.drop_filter.clear();
-
- Options.named_options.clear();
+ dump_order.clear();
+ add_dump_fields("header,stats,misc,inventory,skills,"
+ "spells,mutations,messages,screenshot,kills,notes");
+
+ banned_objects.clear();
+ note_monsters.clear();
+ note_messages.clear();
+ autoinscriptions.clear();
+ note_items.clear();
+ note_skill_levels.clear();
+ travel_stop_message.clear();
+ sound_mappings.clear();
+ menu_colour_mappings.clear();
+ drop_filter.clear();
+ map_file_name.clear();
+ named_options.clear();
+
+ clear_cset_overrides();
+ clear_feature_overrides();
// Map each category to itself. The user can override in init.txt
- Options.kill_map[KC_YOU] = KC_YOU;
- Options.kill_map[KC_FRIENDLY] = KC_FRIENDLY;
- Options.kill_map[KC_OTHER] = KC_OTHER;
+ kill_map[KC_YOU] = KC_YOU;
+ kill_map[KC_FRIENDLY] = KC_FRIENDLY;
+ kill_map[KC_OTHER] = KC_OTHER;
// Setup travel information. What's a better place to do this?
initialise_travel();
}
-void read_init_file(bool runscript)
+// returns where the init file was read from
+std::string read_init_file(bool runscript)
{
- FILE *f;
- char name_buff[kPathLen];
+ const char* locations_data[][2] = {
+ { SysEnv.crawl_rc, "" },
+ { SysEnv.crawl_dir, "init.txt" },
+#ifdef MULTIUSER
+ { SysEnv.home, "/.crawlrc" },
+ { SysEnv.home, "init.txt" },
+#endif
+ { "", "init.txt" },
+#ifdef WIN32CONSOLE
+ { "", ".crawlrc" },
+ { "", "_crawlrc" },
+#endif
+ { NULL, NULL } // placeholder to mark end
+ };
- reset_options(!runscript);
+ Options.reset_options();
- if (!runscript)
- you.your_name[0] = '\0';
-
- if (SysEnv.crawl_rc)
- {
- f = fopen(SysEnv.crawl_rc, "r");
+ FILE* f = NULL;
+ char name_buff[kPathLen];
+ // Check all possibilities for init.txt
+ for ( int i = 0; f == NULL && locations_data[i][1] != NULL; ++i ) {
+ // Don't look at unset options
+ if ( locations_data[i][0] != NULL ) {
+ snprintf( name_buff, sizeof name_buff, "%s%s",
+ locations_data[i][0], locations_data[i][1] );
+ f = fopen( name_buff, "r" );
+ }
}
- else if (SysEnv.crawl_dir)
- {
- strncpy(name_buff, SysEnv.crawl_dir, kPathLen);
- name_buff[ kPathLen - 1 ] = '\0';
- strncat(name_buff, "init.txt", kPathLen);
- name_buff[ kPathLen - 1 ] = '\0';
- f = fopen(name_buff, "r");
- }
-#ifdef MULTIUSER
- else if (SysEnv.home)
+ if ( f == NULL )
{
- // init.txt isn't such a good choice if we're looking in
- // the user's home directory, we'll use Un*x standard
- strncpy(name_buff, SysEnv.home, kPathLen);
- name_buff[ kPathLen - 1 ] = '\0';
-
- // likely not to have a closing slash so we'll insert one...
- strncat(name_buff, "/.crawlrc", kPathLen);
- name_buff[ kPathLen - 1 ] = '\0';
-
- f = fopen(name_buff, "r");
- }
+#ifdef MULTIUSER
+ return "not found (~/.crawlrc missing)";
+#else
+ return "not found (init.txt missing from current directory)";
#endif
- else
- {
- f = fopen("init.txt", "r");
}
- if (f == NULL)
- return;
-
+ read_options(f, runscript);
if (!runscript)
read_startup_prefs();
- read_options(f, runscript);
fclose(f);
+ return std::string(name_buff);
} // end read_init_file()
static void read_startup_prefs()
@@ -536,19 +732,21 @@ static void read_startup_prefs()
FILE *f = fopen(fn.c_str(), "r");
if (!f)
return;
- read_options(f);
- fclose(f);
- Options.prev_randpick = Options.random_pick;
- Options.prev_weapon = Options.weapon;
- Options.prev_pr = Options.priest;
- Options.prev_dk = Options.death_knight;
- Options.prev_ck = Options.chaos_knight;
- Options.prev_cls = Options.cls;
- Options.prev_race = Options.race;
- Options.prev_name = you.your_name;
+ game_options temp;
+ FileLineInput fl(f);
+ temp.read_options(fl, false);
+ fclose(f);
- reset_startup_options();
+ Options.prev_randpick = temp.random_pick;
+ Options.prev_weapon = temp.weapon;
+ Options.prev_pr = temp.priest;
+ Options.prev_dk = temp.death_knight;
+ Options.prev_ck = temp.chaos_knight;
+ Options.prev_cls = temp.cls;
+ Options.prev_race = temp.race;
+ Options.prev_book = temp.book;
+ Options.prev_name = temp.player_name;
}
static void write_newgame_options(FILE *f)
@@ -589,6 +787,15 @@ static void write_newgame_options(FILE *f)
Options.prev_pr == GOD_YREDELEMNUL? "yredelemnul" :
"random");
}
+
+ if (Options.prev_book != SBT_NO_SELECTION )
+ {
+ fprintf(f, "book = %s\n",
+ Options.prev_book == SBT_FIRE ? "fire" :
+ Options.prev_book == SBT_COLD ? "cold" :
+ Options.prev_book == SBT_SUMM ? "summ" :
+ "random");
+ }
}
void write_newgame_options_file()
@@ -606,15 +813,9 @@ void save_player_name()
if (!Options.remember_name)
return ;
- std::string playername = you.your_name;
-
// Read other preferences
read_startup_prefs();
- // Put back your name
- strncpy(you.your_name, playername.c_str(), kNameLen);
- you.your_name[kNameLen - 1] = 0;
-
// And save
write_newgame_options_file();
}
@@ -622,16 +823,21 @@ void save_player_name()
void read_options(FILE *f, bool runscript)
{
FileLineInput fl(f);
- read_options(fl, runscript);
+ Options.read_options(fl, runscript);
}
void read_options(const std::string &s, bool runscript)
{
StringLineInput st(s);
- read_options(st, runscript);
+ Options.read_options(st, runscript);
+}
+
+game_options::game_options()
+{
+ reset_options();
}
-static void read_options(InitLineInput &il, bool runscript)
+void game_options::read_options(InitLineInput &il, bool runscript)
{
unsigned int line = 0;
@@ -759,7 +965,7 @@ static void read_options(InitLineInput &il, bool runscript)
continue;
}
- parse_option_line(str, runscript);
+ read_option_line(str, runscript);
}
#ifdef CLUA_BINDINGS
@@ -774,6 +980,9 @@ static void read_options(InitLineInput &il, bool runscript)
}
}
#endif
+
+ // Validate save_dir
+ check_savedir(save_dir);
}
static int str_to_killcategory(const std::string &s)
@@ -791,15 +1000,15 @@ static int str_to_killcategory(const std::string &s)
return -1;
}
-static void do_kill_map(const std::string &from, const std::string &to)
+void game_options::do_kill_map(const std::string &from, const std::string &to)
{
int ifrom = str_to_killcategory(from),
ito = str_to_killcategory(to);
if (ifrom != -1 && ito != -1)
- Options.kill_map[ifrom] = ito;
+ kill_map[ifrom] = ito;
}
-void parse_option_line(const std::string &str, bool runscript)
+void game_options::read_option_line(const std::string &str, bool runscript)
{
std::string key = "";
std::string subkey = "";
@@ -808,6 +1017,8 @@ void parse_option_line(const std::string &str, bool runscript)
int first_equals = str.find('=');
int first_dot = str.find('.');
+ bool plus_equal = false;
+
// all lines with no equal-signs we ignore
if (first_equals < 0)
return;
@@ -828,6 +1039,15 @@ void parse_option_line(const std::string &str, bool runscript)
// Clean up our data...
tolower_string( trim_string( key ) );
+
+ // Is this a case of key += val?
+ if (key.length() && key[key.length() - 1] == '+')
+ {
+ plus_equal = true;
+ key = key.substr(0, key.length() - 1);
+ trim_string(key);
+ }
+
tolower_string( trim_string( subkey ) );
// some fields want capitals... none care about external spaces
@@ -839,7 +1059,12 @@ void parse_option_line(const std::string &str, bool runscript)
if (key != "name" && key != "crawl_dir"
&& key != "race" && key != "class" && key != "ban_pickup"
&& key != "stop_travel" && key != "sound"
- && key != "drop_filter" && key != "lua_file")
+ && key != "travel_stop_message"
+ && key != "drop_filter" && key != "lua_file"
+ && key != "note_items" && key != "autoinscribe"
+ && key != "note_monsters" && key != "note_messages"
+ && key.find("cset") != 0 && key != "dungeon"
+ && key != "feature")
{
tolower_string( field );
}
@@ -847,6 +1072,9 @@ void parse_option_line(const std::string &str, bool runscript)
// everything not a valid line is treated as a comment
if (key == "autopickup")
{
+ // clear out autopickup
+ autopickups = 0L;
+
for (size_t i = 0; i < field.length(); i++)
{
char type = field[i];
@@ -880,7 +1108,7 @@ void parse_option_line(const std::string &str, bool runscript)
;
if (j < obj_syms_len)
- Options.autopickups |= (1L << j);
+ autopickups |= (1L << j);
else
{
fprintf( stderr, "Bad object type '%c' for autopickup.\n",
@@ -891,59 +1119,100 @@ void parse_option_line(const std::string &str, bool runscript)
else if (key == "name")
{
// field is already cleaned up from trim_string()
- strncpy(you.your_name, field.c_str(), kNameLen);
- you.your_name[ kNameLen - 1 ] = '\0';
+ player_name = field;
}
- else if (key == "verbose_dump")
+ else if (key == "char_set" || key == "ascii_display")
{
- // gives verbose info in char dumps
- Options.verbose_dump = read_bool( field, Options.verbose_dump );
+ bool valid = true;
+
+ if (key == "ascii_display")
+ {
+ char_set =
+ read_bool(field, char_set == CSET_ASCII)?
+ CSET_ASCII
+ : CSET_IBM;
+ valid = true;
+ }
+ else
+ {
+ if (field == "ascii")
+ char_set = CSET_ASCII;
+ else if (field == "ibm")
+ char_set = CSET_IBM;
+ else if (field == "dec")
+ char_set = CSET_DEC;
+ else
+ {
+ fprintf( stderr, "Bad character set: %s\n", field.c_str() );
+ valid = false;
+ }
+ }
+ if (valid)
+ init_char_table(char_set);
+ }
+ else if (key == "default_autopickup")
+ {
+ // should autopickup default to on or off?
+ autopickup_on = read_bool( field, autopickup_on );
+ }
+ else if (key == "default_autoprayer")
+ {
+ // should autoprayer default to on or off?
+ autoprayer_on = read_bool( field, autoprayer_on );
+ }
+ else if (key == "default_fizzlecheck")
+ {
+ // should fizzlecheck default to on or off?
+ fizzlecheck_on = read_bool( field, fizzlecheck_on );
}
else if (key == "detailed_stat_dump")
{
- Options.detailed_stat_dump =
- read_bool( field, Options.detailed_stat_dump );
+ detailed_stat_dump =
+ read_bool( field, detailed_stat_dump );
}
else if (key == "clean_map")
{
// removes monsters/clouds from map
- Options.clean_map = read_bool( field, Options.clean_map );
+ clean_map = read_bool( field, clean_map );
}
else if (key == "colour_map" || key == "color_map")
{
// colour-codes play-screen map
- Options.colour_map = read_bool( field, Options.colour_map );
+ colour_map = read_bool( field, colour_map );
}
else if (key == "easy_confirm")
{
// allows both 'Y'/'N' and 'y'/'n' on yesno() prompts
if (field == "none")
- Options.easy_confirm = CONFIRM_NONE_EASY;
+ easy_confirm = CONFIRM_NONE_EASY;
else if (field == "safe")
- Options.easy_confirm = CONFIRM_SAFE_EASY;
+ easy_confirm = CONFIRM_SAFE_EASY;
else if (field == "all")
- Options.easy_confirm = CONFIRM_ALL_EASY;
+ easy_confirm = CONFIRM_ALL_EASY;
}
- else if (key == "easy_quit_item_lists")
+ else if (key == "easy_quit_item_lists"
+ || key == "easy_quit_item_prompts")
{
// allow aborting of item lists with space
- Options.easy_quit_item_prompts = read_bool( field,
- Options.easy_quit_item_prompts );
+ easy_quit_item_prompts = read_bool( field,
+ easy_quit_item_prompts );
}
else if (key == "easy_open")
{
// automatic door opening with movement
- Options.easy_open = read_bool( field, Options.easy_open );
+ easy_open = read_bool( field, easy_open );
}
- else if (key == "easy_armour" || key == "easy_armour")
+ else if (key == "easy_armor"
+ || key == "easy_armour"
+ || key == "easy_unequip")
{
// automatic removal of armour when dropping
- Options.easy_armour = read_bool( field, Options.easy_armour );
+ easy_unequip = read_bool( field, easy_unequip );
}
else if (key == "easy_butcher")
{
// automatic knife switching
- Options.easy_butcher = read_bool( field, Options.easy_butcher );
+ easy_butcher = read_bool( field, easy_butcher );
}
else if (key == "lua_file" && runscript)
{
@@ -960,7 +1229,7 @@ void parse_option_line(const std::string &str, bool runscript)
const int result_col = str_to_colour( field );
if (orig_col != -1 && result_col != -1)
- Options.colour[orig_col] = result_col;
+ colour[orig_col] = result_col;
else
{
fprintf( stderr, "Bad colour -- %s=%d or %s=%d\n",
@@ -973,7 +1242,7 @@ void parse_option_line(const std::string &str, bool runscript)
const int col = str_to_channel_colour( field );
if (chnl != -1 && col != -1)
- Options.channels[chnl] = col;
+ channels[chnl] = col;
else if (chnl == -1)
fprintf( stderr, "Bad channel -- %s\n", subkey.c_str() );
else if (col == -1)
@@ -986,7 +1255,7 @@ void parse_option_line(const std::string &str, bool runscript)
const int col = str_to_colour( field );
if (col != -1)
- Options.background = col;
+ background = col;
else
fprintf( stderr, "Bad colour -- %s\n", field.c_str() );
@@ -995,7 +1264,7 @@ void parse_option_line(const std::string &str, bool runscript)
{
const int col = str_to_colour( field );
if (col != -1)
- Options.detected_item_colour = col;
+ detected_item_colour = col;
else
fprintf( stderr, "Bad detected_item_colour -- %s\n",
field.c_str());
@@ -1004,102 +1273,116 @@ void parse_option_line(const std::string &str, bool runscript)
{
const int col = str_to_colour( field );
if (col != -1)
- Options.detected_monster_colour = col;
+ detected_monster_colour = col;
else
fprintf( stderr, "Bad detected_monster_colour -- %s\n",
field.c_str());
}
- else if (key == "remembered_monster_colour")
+ else if (key.find(interrupt_prefix) == 0)
{
- if (field == "real")
- Options.remembered_monster_colour = 0xFFFFU;
- else if (field == "auto")
- Options.remembered_monster_colour = 0;
- else {
- const int col = str_to_colour( field );
- if (col != -1)
- Options.remembered_monster_colour = col;
- else
- fprintf( stderr, "Bad remembered_monster_colour -- %s\n",
- field.c_str());
- }
+ set_activity_interrupt(key.substr(interrupt_prefix.length()),
+ field,
+ plus_equal);
+ }
+ else if (key.find("cset") == 0)
+ {
+ std::string cset = key.substr(4);
+ if (!cset.empty() && cset[0] == '_')
+ cset = cset.substr(1);
+
+ char_set_type cs = NUM_CSET;
+ if (cset == "ascii")
+ cs = CSET_ASCII;
+ else if (cset == "ibm")
+ cs = CSET_IBM;
+ else if (cset == "dec")
+ cs = CSET_DEC;
+
+ add_cset_override(cs, field);
+ }
+ else if (key == "feature" || key == "dungeon")
+ {
+ std::vector<std::string> defs = split_string(";", field);
+
+ for (int i = 0, size = defs.size(); i < size; ++i)
+ add_feature_override( defs[i] );
}
else if (key == "friend_brand")
{
// Use curses attributes to mark friend
// Some may look bad on some terminals.
// As a suggestion, try "rxvt -rv -fn 10x20" under Un*xes
- Options.friend_brand = curses_attribute(field);
+ friend_brand = curses_attribute(field);
}
else if (key == "stab_brand")
{
- Options.stab_brand = curses_attribute(field);
+ stab_brand = curses_attribute(field);
}
else if (key == "may_stab_brand")
{
- Options.may_stab_brand = curses_attribute(field);
+ may_stab_brand = curses_attribute(field);
}
else if (key == "no_dark_brand")
{
// This is useful for terms where dark grey does
// not have standout modes (since it's black on black).
// This option will use light-grey instead in these cases.
- Options.no_dark_brand = read_bool( field, Options.no_dark_brand );
+ no_dark_brand = read_bool( field, no_dark_brand );
}
else if (key == "heap_brand")
{
// See friend_brand option upstairs. no_dark_brand applies
// here as well.
- Options.heap_brand = curses_attribute(field);
- }
- else if (key == "show_uncursed")
- {
- // label known uncursed items as "uncursed"
- Options.show_uncursed = read_bool( field, Options.show_uncursed );
+ heap_brand = curses_attribute(field);
}
else if (key == "always_greet")
{
// show greeting when reloading game
- Options.always_greet = read_bool( field, Options.always_greet );
+ always_greet = read_bool( field, always_greet );
}
else if (key == "weapon")
{
// choose this weapon for classes that get choice
- Options.weapon = str_to_weapon( field );
+ weapon = str_to_weapon( field );
+ }
+ else if (key == "book")
+ {
+ // choose this book for classes that get choice
+ book = str_to_book( field );
}
else if (key == "chaos_knight")
{
// choose god for Chaos Knights
if (field == "xom")
- Options.chaos_knight = GOD_XOM;
+ chaos_knight = GOD_XOM;
else if (field == "makhleb")
- Options.chaos_knight = GOD_MAKHLEB;
+ chaos_knight = GOD_MAKHLEB;
else if (field == "random")
- Options.chaos_knight = GOD_RANDOM;
+ chaos_knight = GOD_RANDOM;
}
else if (key == "death_knight")
{
if (field == "necromancy")
- Options.death_knight = DK_NECROMANCY;
+ death_knight = DK_NECROMANCY;
else if (field == "yredelemnul")
- Options.death_knight = DK_YREDELEMNUL;
+ death_knight = DK_YREDELEMNUL;
else if (field == "random")
- Options.death_knight = DK_RANDOM;
+ death_knight = DK_RANDOM;
}
else if (key == "priest")
{
// choose this weapon for classes that get choice
if (field == "zin")
- Options.priest = GOD_ZIN;
+ priest = GOD_ZIN;
else if (field == "yredelemnul")
- Options.priest = GOD_YREDELEMNUL;
+ priest = GOD_YREDELEMNUL;
else if (field == "random")
- Options.priest = GOD_RANDOM;
+ priest = GOD_RANDOM;
}
else if (key == "fire_items_start")
{
if (isalpha( field[0] ))
- Options.fire_items_start = letter_to_index( field[0] );
+ fire_items_start = letter_to_index( field[0] );
else
{
fprintf( stderr, "Bad fire item start index -- %s\n",
@@ -1109,39 +1392,69 @@ void parse_option_line(const std::string &str, bool runscript)
else if (key == "assign_item_slot")
{
if (field == "forward")
- Options.assign_item_slot = SS_FORWARD;
+ assign_item_slot = SS_FORWARD;
else if (field == "backward")
- Options.assign_item_slot = SS_BACKWARD;
+ assign_item_slot = SS_BACKWARD;
}
else if (key == "fire_order")
{
- str_to_fire_order( field, Options.fire_order );
+ str_to_fire_order( field, fire_order );
}
else if (key == "random_pick")
{
// randomly generate character
- Options.random_pick = read_bool( field, Options.random_pick );
+ random_pick = read_bool( field, random_pick );
}
else if (key == "remember_name")
{
- Options.remember_name = read_bool( field, Options.remember_name );
+ remember_name = read_bool( field, remember_name );
}
+ else if (key == "save_dir")
+ {
+ // If SAVE_DIR_PATH was defined, there are very likely security issues
+ // with allowing the user to specify a different directory.
+#ifndef SAVE_DIR_PATH
+ save_dir = field;
+#endif
+ }
else if (key == "hp_warning")
{
- Options.hp_warning = atoi( field.c_str() );
- if (Options.hp_warning < 0 || Options.hp_warning > 100)
+ hp_warning = atoi( field.c_str() );
+ if (hp_warning < 0 || hp_warning > 100)
{
- Options.hp_warning = 0;
+ hp_warning = 0;
fprintf( stderr, "Bad HP warning percentage -- %s\n",
field.c_str() );
}
}
+ else if (key == "ood_interesting")
+ {
+ ood_interesting = atoi( field.c_str() );
+ }
+ else if (key == "note_monsters")
+ {
+ append_vector(note_monsters, split_string(",", field));
+ }
+ else if (key == "note_messages")
+ {
+ append_vector(note_messages, split_string(",", field));
+ }
+ else if (key == "note_hp_percent")
+ {
+ note_hp_percent = atoi( field.c_str() );
+ if (note_hp_percent < 0 || note_hp_percent > 100)
+ {
+ note_hp_percent = 0;
+ fprintf( stderr, "Bad HP note percentage -- %s\n",
+ field.c_str() );
+ }
+ }
else if (key == "hp_attention")
{
- Options.hp_attention = atoi( field.c_str() );
- if (Options.hp_attention < 0 || Options.hp_attention > 100)
+ hp_attention = atoi( field.c_str() );
+ if (hp_attention < 0 || hp_attention > 100)
{
- Options.hp_attention = 0;
+ hp_attention = 0;
fprintf( stderr, "Bad HP attention percentage -- %s\n",
field.c_str() );
}
@@ -1155,158 +1468,242 @@ void parse_option_line(const std::string &str, bool runscript)
if (SysEnv.crawl_dir)
{
- strncpy(SysEnv.crawl_dir, field.c_str(), kNameLen - 1);
- SysEnv.crawl_dir[ kNameLen - 1 ] = '\0';
+ strncpy(SysEnv.crawl_dir, field.c_str(), kPathLen - 1);
+ SysEnv.crawl_dir[ kPathLen - 1 ] = 0;
}
}
else if (key == "race")
{
- Options.race = str_to_race( field );
+ race = str_to_race( field );
- if (Options.race == '\0')
+ if (race == 0)
fprintf( stderr, "Unknown race choice: %s\n", field.c_str() );
}
else if (key == "class")
{
- Options.cls = str_to_class( field );
+ cls = str_to_class( field );
- if (Options.cls == '\0')
+ if (cls == 0)
fprintf( stderr, "Unknown class choice: %s\n", field.c_str() );
}
else if (key == "auto_list")
{
- Options.auto_list = read_bool( field, Options.auto_list );
+ auto_list = read_bool( field, auto_list );
+ }
+ else if (key == "confirm_self_target")
+ {
+ confirm_self_target = read_bool( field, confirm_self_target );
+ }
+ else if (key == "safe_autopickup")
+ {
+ safe_autopickup = read_bool( field, safe_autopickup );
+ }
+ else if (key == "use_notes")
+ {
+ use_notes = read_bool( field, use_notes );
+ }
+ else if (key == "note_skill_max")
+ {
+ note_skill_max = read_bool( field, note_skill_max );
+ }
+ else if (key == "note_all_spells")
+ {
+ note_all_spells = read_bool( field, note_all_spells );
}
else if (key == "delay_message_clear")
{
- Options.delay_message_clear = read_bool( field, Options.delay_message_clear );
+ delay_message_clear = read_bool( field, delay_message_clear );
}
else if (key == "terse_hand")
{
- Options.terse_hand = read_bool( field, Options.terse_hand );
+ terse_hand = read_bool( field, terse_hand );
+ }
+ else if (key == "increasing_skill_progress")
+ {
+ increasing_skill_progress = read_bool( field, increasing_skill_progress );
}
else if (key == "flush")
{
if (subkey == "failure")
{
- Options.flush_input[FLUSH_ON_FAILURE]
- = read_bool(field, Options.flush_input[FLUSH_ON_FAILURE]);
+ flush_input[FLUSH_ON_FAILURE]
+ = read_bool(field, flush_input[FLUSH_ON_FAILURE]);
}
else if (subkey == "command")
{
- Options.flush_input[FLUSH_BEFORE_COMMAND]
- = read_bool(field, Options.flush_input[FLUSH_BEFORE_COMMAND]);
+ flush_input[FLUSH_BEFORE_COMMAND]
+ = read_bool(field, flush_input[FLUSH_BEFORE_COMMAND]);
}
else if (subkey == "message")
{
- Options.flush_input[FLUSH_ON_MESSAGE]
- = read_bool(field, Options.flush_input[FLUSH_ON_MESSAGE]);
+ flush_input[FLUSH_ON_MESSAGE]
+ = read_bool(field, flush_input[FLUSH_ON_MESSAGE]);
}
else if (subkey == "lua")
{
- Options.flush_input[FLUSH_LUA]
- = read_bool(field, Options.flush_input[FLUSH_LUA]);
+ flush_input[FLUSH_LUA]
+ = read_bool(field, flush_input[FLUSH_LUA]);
}
}
else if (key == "lowercase_invocations")
{
- Options.lowercase_invocations
- = read_bool(field, Options.lowercase_invocations);
+ lowercase_invocations
+ = read_bool(field, lowercase_invocations);
}
else if (key == "wiz_mode")
{
// wiz_mode is recognized as a legal key in all compiles -- bwr
#ifdef WIZARD
if (field == "never")
- Options.wiz_mode = WIZ_NEVER;
+ wiz_mode = WIZ_NEVER;
else if (field == "no")
- Options.wiz_mode = WIZ_NO;
+ wiz_mode = WIZ_NO;
else if (field == "yes")
- Options.wiz_mode = WIZ_YES;
+ wiz_mode = WIZ_YES;
else
fprintf(stderr, "Unknown wiz_mode option: %s\n", field.c_str());
#endif
}
else if (key == "ban_pickup")
{
- append_vector(Options.banned_objects, split_string(",", field));
+ append_vector(banned_objects, split_string(",", field));
+ }
+ else if (key == "note_items")
+ {
+ append_vector(note_items, split_string(",", field));
+ }
+ else if (key == "autoinscribe")
+ {
+ std::vector<std::string> thesplit =
+ split_string(":", field);
+ autoinscriptions.push_back(
+ std::pair<text_pattern,std::string>(thesplit[0],
+ thesplit[1]));
+ }
+ else if (key == "map_file_name")
+ {
+ map_file_name = field;
+ }
+ else if (key == "note_skill_levels")
+ {
+ std::vector<std::string> thesplit = split_string(",", field);
+ for ( unsigned i = 0; i < thesplit.size(); ++i ) {
+ int num = atoi(thesplit[i].c_str());
+ if ( num > 0 && num <= 27 ) {
+ note_skill_levels.push_back(num);
+ }
+ else {
+ fprintf(stderr, "Bad skill level to note -- %s\n",
+ thesplit[i].c_str());
+ continue;
+ }
+ }
}
else if (key == "pickup_thrown")
{
- Options.pickup_thrown = read_bool(field, Options.pickup_thrown);
+ pickup_thrown = read_bool(field, pickup_thrown);
}
else if (key == "pickup_dropped")
{
- Options.pickup_dropped = read_bool(field, Options.pickup_dropped);
+ pickup_dropped = read_bool(field, pickup_dropped);
}
- else if (key == "show_waypoints")
+#ifdef WIZARD
+ else if (key == "fsim_kit")
{
- Options.show_waypoints = read_bool(field, Options.show_waypoints);
+ append_vector(fsim_kit, split_string(",", field));
+ }
+ else if (key == "fsim_rounds")
+ {
+ fsim_rounds = atol(field.c_str());
+ if (fsim_rounds < 1000)
+ fsim_rounds = 1000;
+ if (fsim_rounds > 500000L)
+ fsim_rounds = 500000L;
+ }
+ else if (key == "fsim_mons")
+ {
+ fsim_mons = field;
+ }
+ else if (key == "fsim_str")
+ {
+ fsim_str = atoi(field.c_str());
+ }
+ else if (key == "fsim_int")
+ {
+ fsim_int = atoi(field.c_str());
+ }
+ else if (key == "fsim_dex")
+ {
+ fsim_dex = atoi(field.c_str());
+ }
+ else if (key == "fsim_xl")
+ {
+ fsim_xl = atoi(field.c_str());
+ }
+#endif // WIZARD
+ else if (key == "sort_menus")
+ {
+ sort_menus = read_bool(field, sort_menus);
}
else if (key == "travel_delay")
{
// Read travel delay in milliseconds.
- Options.travel_delay = atoi( field.c_str() );
- if (Options.travel_delay < -1)
- Options.travel_delay = -1;
- if (Options.travel_delay > 2000)
- Options.travel_delay = 2000;
+ travel_delay = atoi( field.c_str() );
+ if (travel_delay < -1)
+ travel_delay = -1;
+ if (travel_delay > 2000)
+ travel_delay = 2000;
}
else if (key == "level_map_cursor_step")
{
- Options.level_map_cursor_step = atoi( field.c_str() );
- if (Options.level_map_cursor_step < 1)
- Options.level_map_cursor_step = 1;
- if (Options.level_map_cursor_step > 50)
- Options.level_map_cursor_step = 50;
+ level_map_cursor_step = atoi( field.c_str() );
+ if (level_map_cursor_step < 1)
+ level_map_cursor_step = 1;
+ if (level_map_cursor_step > 50)
+ level_map_cursor_step = 50;
}
else if (key == "macro_meta_entry")
{
- Options.macro_meta_entry = read_bool(field, Options.macro_meta_entry);
- }
- else if (key == "travel_stair_cost")
- {
- Options.travel_stair_cost = atoi( field.c_str() );
- if (Options.travel_stair_cost < 1)
- Options.travel_stair_cost = 1;
- else if (Options.travel_stair_cost > 1000)
- Options.travel_stair_cost = 1000;
+ macro_meta_entry = read_bool(field, macro_meta_entry);
}
else if (key == "travel_exclude_radius2")
{
- Options.travel_exclude_radius2 = atoi( field.c_str() );
- if (Options.travel_exclude_radius2 < 0)
- Options.travel_exclude_radius2 = 0;
- else if (Options.travel_exclude_radius2 > 400)
- Options.travel_exclude_radius2 = 400;
+ travel_exclude_radius2 = atoi( field.c_str() );
+ if (travel_exclude_radius2 < 0)
+ travel_exclude_radius2 = 0;
+ else if (travel_exclude_radius2 > 400)
+ travel_exclude_radius2 = 400;
}
- else if (key == "stop_travel")
+ else if (key == "stop_travel" || key == "travel_stop_message")
{
std::vector<std::string> fragments = split_string(",", field);
- for (int i = 0, count = fragments.size(); i < count; ++i) {
+ for (int i = 0, count = fragments.size(); i < count; ++i)
+ {
if (fragments[i].length() == 0)
continue;
std::string::size_type pos = fragments[i].find(":");
- if (pos && pos != std::string::npos) {
+ if (pos && pos != std::string::npos)
+ {
std::string prefix = fragments[i].substr(0, pos);
int channel = str_to_channel( prefix );
- if (channel != -1 || prefix == "any") {
+ if (channel != -1 || prefix == "any")
+ {
std::string s = fragments[i].substr( pos + 1 );
trim_string( s );
- Options.stop_travel.push_back(
+ travel_stop_message.push_back(
message_filter( channel, s ) );
continue;
}
}
- Options.stop_travel.push_back(
+ travel_stop_message.push_back(
message_filter( fragments[i] ) );
}
}
else if (key == "drop_filter")
{
- append_vector(Options.drop_filter, split_string(",", field));
+ append_vector(drop_filter, split_string(",", field));
}
else if (key == "travel_avoid_terrain")
{
@@ -1314,48 +1711,64 @@ void parse_option_line(const std::string &str, bool runscript)
for (int i = 0, count = seg.size(); i < count; ++i)
prevent_travel_to( seg[i] );
}
- else if (key == "travel_colour")
+ else if (key == "tc_reachable")
+ {
+ tc_reachable = str_to_colour(field, tc_reachable);
+ }
+ else if (key == "tc_excluded")
+ {
+ tc_excluded = str_to_colour(field, tc_excluded);
+ }
+ else if (key == "tc_exclude_circle")
{
- Options.travel_colour = read_bool(field, Options.travel_colour);
+ tc_exclude_circle =
+ str_to_colour(field, tc_exclude_circle);
}
- else if (key == "item_colour")
+ else if (key == "tc_dangerous")
{
- Options.item_colour = read_bool(field, Options.item_colour);
+ tc_dangerous = str_to_colour(field, tc_dangerous);
+ }
+ else if (key == "tc_disconnected")
+ {
+ tc_disconnected = str_to_colour(field, tc_disconnected);
+ }
+ else if (key == "item_colour" || key == "item_color")
+ {
+ item_colour = read_bool(field, item_colour);
}
else if (key == "easy_exit_menu")
{
- Options.easy_exit_menu = read_bool(field, Options.easy_exit_menu);
+ easy_exit_menu = read_bool(field, easy_exit_menu);
}
else if (key == "dos_use_background_intensity")
{
- Options.dos_use_background_intensity =
- read_bool(field, Options.dos_use_background_intensity);
+ dos_use_background_intensity =
+ read_bool(field, dos_use_background_intensity);
}
else if (key == "explore_stop")
{
- Options.explore_stop = ES_NONE;
+ explore_stop = ES_NONE;
std::vector<std::string> stops = split_string(",", field);
for (int i = 0, count = stops.size(); i < count; ++i)
{
const std::string &c = stops[i];
if (c == "item" || c == "items")
- Options.explore_stop |= ES_ITEM;
+ explore_stop |= ES_ITEM;
else if (c == "shop" || c == "shops")
- Options.explore_stop |= ES_SHOP;
+ explore_stop |= ES_SHOP;
else if (c == "stair" || c == "stairs")
- Options.explore_stop |= ES_STAIR;
+ explore_stop |= ES_STAIR;
else if (c == "altar" || c == "altars")
- Options.explore_stop |= ES_ALTAR;
+ explore_stop |= ES_ALTAR;
}
}
#ifdef STASH_TRACKING
else if (key == "stash_tracking")
{
- Options.stash_tracking =
- field == "explicit"? STM_EXPLICIT :
+ stash_tracking =
field == "dropped" ? STM_DROPPED :
field == "all" ? STM_ALL :
- STM_NONE;
+ STM_EXPLICIT;
}
else if (key == "stash_filter")
{
@@ -1374,7 +1787,7 @@ void parse_option_line(const std::string &str, bool runscript)
sound_mapping mapping;
mapping.pattern = sub.substr(0, cpos);
mapping.soundfile = sub.substr(cpos + 1);
- Options.sound_mappings.push_back(mapping);
+ sound_mappings.push_back(mapping);
}
}
}
@@ -1389,13 +1802,20 @@ void parse_option_line(const std::string &str, bool runscript)
mapping.pattern = sub.substr(cpos + 1);
mapping.colour = str_to_colour(sub.substr(0, cpos));
if (mapping.colour != -1)
- Options.menu_colour_mappings.push_back(mapping);
+ menu_colour_mappings.push_back(mapping);
}
}
}
+ else if (key == "dump_order")
+ {
+ if (!plus_equal)
+ dump_order.clear();
+
+ add_dump_fields(field);
+ }
else if (key == "dump_kill_places")
{
- Options.dump_kill_places =
+ dump_kill_places =
field == "none"? KDO_NO_PLACES :
field == "all" ? KDO_ALL_PLACES :
KDO_ONE_PLACE;
@@ -1417,66 +1837,66 @@ void parse_option_line(const std::string &str, bool runscript)
else if (key == "dump_message_count")
{
// Capping is implicit
- Options.dump_message_count = atoi( field.c_str() );
+ dump_message_count = atoi( field.c_str() );
}
else if (key == "dump_item_origins")
{
- Options.dump_item_origins = IODS_PRICE;
+ dump_item_origins = IODS_PRICE;
std::vector<std::string> choices = split_string(",", field);
for (int i = 0, count = choices.size(); i < count; ++i)
{
const std::string &ch = choices[i];
if (ch == "artifacts")
- Options.dump_item_origins |= IODS_ARTIFACTS;
+ dump_item_origins |= IODS_ARTIFACTS;
else if (ch == "ego_arm" || ch == "ego armour"
|| ch == "ego_armour")
- Options.dump_item_origins |= IODS_EGO_ARMOUR;
+ dump_item_origins |= IODS_EGO_ARMOUR;
else if (ch == "ego_weap" || ch == "ego weapon"
|| ch == "ego_weapon" || ch == "ego weapons"
|| ch == "ego_weapons")
- Options.dump_item_origins |= IODS_EGO_WEAPON;
+ dump_item_origins |= IODS_EGO_WEAPON;
else if (ch == "jewellery" || ch == "jewelry")
- Options.dump_item_origins |= IODS_JEWELLERY;
+ dump_item_origins |= IODS_JEWELLERY;
else if (ch == "runes")
- Options.dump_item_origins |= IODS_RUNES;
+ dump_item_origins |= IODS_RUNES;
else if (ch == "rods")
- Options.dump_item_origins |= IODS_RODS;
+ dump_item_origins |= IODS_RODS;
else if (ch == "staves")
- Options.dump_item_origins |= IODS_STAVES;
+ dump_item_origins |= IODS_STAVES;
else if (ch == "books")
- Options.dump_item_origins |= IODS_BOOKS;
+ dump_item_origins |= IODS_BOOKS;
else if (ch == "all" || ch == "everything")
- Options.dump_item_origins = IODS_EVERYTHING;
+ dump_item_origins = IODS_EVERYTHING;
}
}
else if (key == "dump_item_origin_price")
{
- Options.dump_item_origin_price = atoi( field.c_str() );
- if (Options.dump_item_origin_price < -1)
- Options.dump_item_origin_price = -1;
+ dump_item_origin_price = atoi( field.c_str() );
+ if (dump_item_origin_price < -1)
+ dump_item_origin_price = -1;
}
- else if (key == "target_zero_exp")
+ else if (key == "safe_zero_exp")
{
- Options.target_zero_exp = read_bool(field, Options.target_zero_exp);
+ safe_zero_exp = read_bool(field, safe_zero_exp);
}
- else if (key == "target_wrap")
+ else if (key == "target_zero_exp")
{
- Options.target_wrap = read_bool(field, Options.target_wrap);
+ target_zero_exp = read_bool(field, target_zero_exp);
}
else if (key == "target_oos")
{
- Options.target_oos = read_bool(field, Options.target_oos);
+ target_oos = read_bool(field, target_oos);
}
else if (key == "target_los_first")
{
- Options.target_los_first = read_bool(field, Options.target_los_first);
+ target_los_first = read_bool(field, target_los_first);
}
else if (key == "drop_mode")
{
if (field.find("multi") != std::string::npos)
- Options.drop_mode = DM_MULTI;
+ drop_mode = DM_MULTI;
else
- Options.drop_mode = DM_SINGLE;
+ drop_mode = DM_SINGLE;
}
// Catch-all else, copies option into map
else
@@ -1490,7 +1910,7 @@ void parse_option_line(const std::string &str, bool runscript)
if (clua.error.length())
mpr(clua.error.c_str());
#endif
- Options.named_options[key] = orig_field;
+ named_options[key] = orig_field;
}
}
}
@@ -1530,8 +1950,19 @@ static const char *cmd_ops[] = { "scores", "name", "race", "class",
const int num_cmd_ops = 10;
bool arg_seen[num_cmd_ops];
+static void set_crawl_path(const std::string &path)
+{
+ const std::string::size_type slash = path.rfind(FILE_SEPARATOR);
+ SysEnv.crawl_executable_path =
+ slash != std::string::npos? path.substr(0, slash + 1)
+ : std::string("");
+}
+
bool parse_args( int argc, char **argv, bool rc_only )
{
+ if (argc >= 1)
+ set_crawl_path(argv[0]);
+
if (argc < 2) // no args!
return (true);
@@ -1630,10 +2061,7 @@ bool parse_args( int argc, char **argv, bool rc_only )
return (false);
if (!rc_only)
- {
- strncpy(you.your_name, next_arg, kNameLen);
- you.your_name[ kNameLen - 1 ] = '\0';
- }
+ Options.player_name = next_arg;
nextUsed = true;
break;
@@ -1673,12 +2101,8 @@ bool parse_args( int argc, char **argv, bool rc_only )
if (!rc_only)
{
- viewwindow = &viewwindow3;
- mapch = &mapchar3;
- mapch2 = &mapchar4;
-#ifdef UNIX
- character_set = 0;
-#endif
+ Options.char_set = CSET_ASCII;
+ init_char_table(Options.char_set);
}
break;
@@ -1709,3 +2133,61 @@ bool parse_args( int argc, char **argv, bool rc_only )
return (true);
}
+
+//////////////////////////////////////////////////////////////////////////
+// game_options
+
+int game_options::o_int(const char *name, int def) const
+{
+ int val = def;
+ opt_map::const_iterator i = named_options.find(name);
+ if (i != named_options.end())
+ {
+ val = atoi(i->second.c_str());
+ }
+ return (val);
+}
+
+long game_options::o_long(const char *name, long def) const
+{
+ long val = def;
+ opt_map::const_iterator i = named_options.find(name);
+ if (i != named_options.end())
+ {
+ const char *s = i->second.c_str();
+ char *es = NULL;
+ long num = strtol(s, &es, 10);
+ if (s != (const char *) es && es)
+ val = num;
+ }
+ return (val);
+}
+
+bool game_options::o_bool(const char *name, bool def) const
+{
+ bool val = def;
+ opt_map::const_iterator i = named_options.find(name);
+ if (i != named_options.end())
+ val = read_bool(i->second, val);
+ return (val);
+}
+
+std::string game_options::o_str(const char *name, const char *def) const
+{
+ std::string val;
+ opt_map::const_iterator i = named_options.find(name);
+ if (i != named_options.end())
+ val = i->second;
+ else if (def)
+ val = def;
+ return (val);
+}
+
+int game_options::o_colour(const char *name, int def) const
+{
+ std::string val = o_str(name);
+ trim_string(val);
+ tolower_string(val);
+ int col = str_to_colour(val);
+ return (col == -1? def : col);
+}