Recent changes Random page
GAMING
Gaming
 
WoWWiki
Halopedia
FFXIclopedia
Age of Conan
Warhammer Online
Grand Theft Wiki
See more...

Source:Options.c

From Wikihack

(Redirected from Options.c)
Jump to: navigation, search
 

Below is the full text to src/options.c from NetHack 3.4.3. To link to a particular line, write [[options.c#line123]], for example.

Contents

[edit] Top of file

1.    /*	SCCS Id: @(#)options.c	3.4	2003/11/14	*/
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
5.    #ifdef OPTION_LISTS_ONLY	/* (AMIGA) external program for opt lists */
6.    #include "config.h"
7.    #include "objclass.h"
8.    #include "flag.h"
9.    NEARDATA struct flag flags;	/* provide linkage */
10.   NEARDATA struct instance_flags iflags;	/* provide linkage */
11.   #define static
12.   #else
13.   #include "hack.h"
14.   #include "tcap.h"
15.   #include <ctype.h>
16.   #endif
17.   
18.   #define WINTYPELEN 16
19.   
20.   #ifdef DEFAULT_WC_TILED_MAP
21.   #define PREFER_TILED TRUE
22.   #else
23.   #define PREFER_TILED FALSE
24.   #endif
25.   

[edit] Bool_Opt

26.   /*
27.    *  NOTE:  If you add (or delete) an option, please update the short
28.    *  options help (option_help()), the long options help (dat/opthelp),
29.    *  and the current options setting display function (doset()),
30.    *  and also the Guidebooks.
31.    *
32.    *  The order matters.  If an option is a an initial substring of another
33.    *  option (e.g. time and timed_delay) the shorter one must come first.
34.    */
35.   
36.   static struct Bool_Opt
37.   {
38.   	const char *name;
39.   	boolean	*addr, initvalue;
40.   	int optflags;
41.   } boolopt[] = {
42.   #ifdef AMIGA
43.   	{"altmeta", &flags.altmeta, TRUE, DISP_IN_GAME},
44.   #else
45.   	{"altmeta", (boolean *)0, TRUE, DISP_IN_GAME},
46.   #endif
47.   	{"ascii_map",     &iflags.wc_ascii_map, !PREFER_TILED, SET_IN_GAME},	/*WC*/
48.   #ifdef MFLOPPY
49.   	{"asksavedisk", &flags.asksavedisk, FALSE, SET_IN_GAME},
50.   #else
51.   	{"asksavedisk", (boolean *)0, FALSE, SET_IN_FILE},
52.   #endif
53.   	{"autodig", &flags.autodig, FALSE, SET_IN_GAME},
54.   	{"autopickup", &flags.pickup, TRUE, SET_IN_GAME},
55.   	{"autoquiver", &flags.autoquiver, FALSE, SET_IN_GAME},
56.   #if defined(MICRO) && !defined(AMIGA)
57.   	{"BIOS", &iflags.BIOS, FALSE, SET_IN_FILE},
58.   #else
59.   	{"BIOS", (boolean *)0, FALSE, SET_IN_FILE},
60.   #endif
61.   #ifdef INSURANCE
62.   	{"checkpoint", &flags.ins_chkpt, TRUE, SET_IN_GAME},
63.   #else
64.   	{"checkpoint", (boolean *)0, FALSE, SET_IN_FILE},
65.   #endif
66.   #ifdef MFLOPPY
67.   	{"checkspace", &iflags.checkspace, TRUE, SET_IN_GAME},
68.   #else
69.   	{"checkspace", (boolean *)0, FALSE, SET_IN_FILE},
70.   #endif
71.   	{"cmdassist", &iflags.cmdassist, TRUE, SET_IN_GAME},
72.   # if defined(MICRO) || defined(WIN32)
73.   	{"color",         &iflags.wc_color,TRUE, SET_IN_GAME},		/*WC*/
74.   # else	/* systems that support multiple terminals, many monochrome */
75.   	{"color",         &iflags.wc_color, FALSE, SET_IN_GAME},	/*WC*/
76.   # endif
77.   	{"confirm",&flags.confirm, TRUE, SET_IN_GAME},
78.   #if defined(TERMLIB) && !defined(MAC_GRAPHICS_ENV)
79.   	{"DECgraphics", &iflags.DECgraphics, FALSE, SET_IN_GAME},
80.   #else
81.   	{"DECgraphics", (boolean *)0, FALSE, SET_IN_FILE},
82.   #endif
83.   	{"eight_bit_tty", &iflags.wc_eight_bit_input, FALSE, SET_IN_GAME},	/*WC*/
84.   #ifdef TTY_GRAPHICS
85.   	{"extmenu", &iflags.extmenu, FALSE, SET_IN_GAME},
86.   #else
87.   	{"extmenu", (boolean *)0, FALSE, SET_IN_FILE},
88.   #endif
89.   #ifdef OPT_DISPMAP
90.   	{"fast_map", &flags.fast_map, TRUE, SET_IN_GAME},
91.   #else
92.   	{"fast_map", (boolean *)0, TRUE, SET_IN_FILE},
93.   #endif
94.   	{"female", &flags.female, FALSE, DISP_IN_GAME},
95.   	{"fixinv", &flags.invlet_constant, TRUE, SET_IN_GAME},
96.   #ifdef AMIFLUSH
97.   	{"flush", &flags.amiflush, FALSE, SET_IN_GAME},
98.   #else
99.   	{"flush", (boolean *)0, FALSE, SET_IN_FILE},
100.  #endif
101.  	{"fullscreen", &iflags.wc2_fullscreen, FALSE, SET_IN_FILE},
102.  	{"help", &flags.help, TRUE, SET_IN_GAME},
103.  	{"hilite_pet",    &iflags.wc_hilite_pet, FALSE, SET_IN_GAME},	/*WC*/
104.  #ifdef ASCIIGRAPH
105.  	{"IBMgraphics", &iflags.IBMgraphics, FALSE, SET_IN_GAME},
106.  #else
107.  	{"IBMgraphics", (boolean *)0, FALSE, SET_IN_FILE},
108.  #endif
109.  #ifndef MAC
110.  	{"ignintr", &flags.ignintr, FALSE, SET_IN_GAME},
111.  #else
112.  	{"ignintr", (boolean *)0, FALSE, SET_IN_FILE},
113.  #endif
114.  	{"large_font", &iflags.obsolete, FALSE, SET_IN_FILE},	/* OBSOLETE */
115.  	{"legacy", &flags.legacy, TRUE, DISP_IN_GAME},
116.  	{"lit_corridor", &flags.lit_corridor, FALSE, SET_IN_GAME},
117.  	{"lootabc", &iflags.lootabc, FALSE, SET_IN_GAME},
118.  #ifdef MAC_GRAPHICS_ENV
119.  	{"Macgraphics", &iflags.MACgraphics, TRUE, SET_IN_GAME},
120.  #else
121.  	{"Macgraphics", (boolean *)0, FALSE, SET_IN_FILE},
122.  #endif
123.  #ifdef MAIL
124.  	{"mail", &flags.biff, TRUE, SET_IN_GAME},
125.  #else
126.  	{"mail", (boolean *)0, TRUE, SET_IN_FILE},
127.  #endif
128.  #ifdef WIZARD
129.  	/* for menu debugging only*/
130.  	{"menu_tab_sep", &iflags.menu_tab_sep, FALSE, SET_IN_GAME},
131.  #else
132.  	{"menu_tab_sep", (boolean *)0, FALSE, SET_IN_FILE},
133.  #endif
134.  	{"mouse_support", &iflags.wc_mouse_support, TRUE, DISP_IN_GAME},	/*WC*/
135.  #ifdef NEWS
136.  	{"news", &iflags.news, TRUE, DISP_IN_GAME},
137.  #else
138.  	{"news", (boolean *)0, FALSE, SET_IN_FILE},
139.  #endif
140.  	{"null", &flags.null, TRUE, SET_IN_GAME},
141.  #ifdef MAC
142.  	{"page_wait", &flags.page_wait, TRUE, SET_IN_GAME},
143.  #else
144.  	{"page_wait", (boolean *)0, FALSE, SET_IN_FILE},
145.  #endif
146.  	{"perm_invent", &flags.perm_invent, FALSE, SET_IN_GAME},
147.  	{"popup_dialog",  &iflags.wc_popup_dialog, FALSE, SET_IN_GAME},	/*WC*/
148.  	{"prayconfirm", &flags.prayconfirm, TRUE, SET_IN_GAME},
149.  	{"preload_tiles", &iflags.wc_preload_tiles, TRUE, DISP_IN_GAME},	/*WC*/
150.  	{"pushweapon", &flags.pushweapon, FALSE, SET_IN_GAME},
151.  #if defined(MICRO) && !defined(AMIGA)
152.  	{"rawio", &iflags.rawio, FALSE, DISP_IN_GAME},
153.  #else
154.  	{"rawio", (boolean *)0, FALSE, SET_IN_FILE},
155.  #endif
156.  	{"rest_on_space", &flags.rest_on_space, FALSE, SET_IN_GAME},
157.  	{"safe_pet", &flags.safe_dog, TRUE, SET_IN_GAME},
158.  #ifdef WIZARD
159.  	{"sanity_check", &iflags.sanity_check, FALSE, SET_IN_GAME},
160.  #else
161.  	{"sanity_check", (boolean *)0, FALSE, SET_IN_FILE},
162.  #endif
163.  #ifdef EXP_ON_BOTL
164.  	{"showexp", &flags.showexp, FALSE, SET_IN_GAME},
165.  #else
166.  	{"showexp", (boolean *)0, FALSE, SET_IN_FILE},
167.  #endif
168.  	{"showrace", &iflags.showrace, FALSE, SET_IN_GAME},
169.  #ifdef SCORE_ON_BOTL
170.  	{"showscore", &flags.showscore, FALSE, SET_IN_GAME},
171.  #else
172.  	{"showscore", (boolean *)0, FALSE, SET_IN_FILE},
173.  #endif
174.  	{"silent", &flags.silent, TRUE, SET_IN_GAME},
175.  	{"softkeyboard", &iflags.wc2_softkeyboard, FALSE, SET_IN_FILE},
176.  	{"sortpack", &flags.sortpack, TRUE, SET_IN_GAME},
177.  	{"sound", &flags.soundok, TRUE, SET_IN_GAME},
178.  	{"sparkle", &flags.sparkle, TRUE, SET_IN_GAME},
179.  	{"standout", &flags.standout, FALSE, SET_IN_GAME},
180.  	{"splash_screen",     &iflags.wc_splash_screen, TRUE, DISP_IN_GAME},	/*WC*/
181.  	{"tiled_map",     &iflags.wc_tiled_map, PREFER_TILED, DISP_IN_GAME},	/*WC*/
182.  	{"time", &flags.time, FALSE, SET_IN_GAME},
183.  #ifdef TIMED_DELAY
184.  	{"timed_delay", &flags.nap, TRUE, SET_IN_GAME},
185.  #else
186.  	{"timed_delay", (boolean *)0, FALSE, SET_IN_GAME},
187.  #endif
188.  	{"tombstone",&flags.tombstone, TRUE, SET_IN_GAME},
189.  	{"toptenwin",&flags.toptenwin, FALSE, SET_IN_GAME},
190.  	{"travel", &iflags.travelcmd, TRUE, SET_IN_GAME},
191.  #ifdef WIN32CON
192.  	{"use_inverse",   &iflags.wc_inverse, TRUE, SET_IN_GAME},		/*WC*/
193.  #else
194.  	{"use_inverse",   &iflags.wc_inverse, FALSE, SET_IN_GAME},		/*WC*/
195.  #endif
196.  	{"verbose", &flags.verbose, TRUE, SET_IN_GAME},
197.  	{"wraptext", &iflags.wc2_wraptext, FALSE, SET_IN_GAME},
198.  	{(char *)0, (boolean *)0, FALSE, 0}
199.  };
200.  

[edit] Comp_Opt

201.  /* compound options, for option_help() and external programs like Amiga
202.   * frontend */
203.  static struct Comp_Opt
204.  {
205.  	const char *name, *descr;
206.  	int size;	/* for frontends and such allocating space --
207.  			 * usually allowed size of data in game, but
208.  			 * occasionally maximum reasonable size for
209.  			 * typing when game maintains information in
210.  			 * a different format */
211.  	int optflags;
212.  } compopt[] = {
213.  	{ "align",    "your starting alignment (lawful, neutral, or chaotic)",
214.  						8, DISP_IN_GAME },
215.  	{ "align_message", "message window alignment", 20, DISP_IN_GAME }, 	/*WC*/
216.  	{ "align_status", "status window alignment", 20, DISP_IN_GAME }, 	/*WC*/
217.  	{ "altkeyhandler", "alternate key handler", 20, DISP_IN_GAME },
218.  	{ "boulder",  "the symbol to use for displaying boulders",
219.  						1, SET_IN_GAME },
220.  	{ "catname",  "the name of your (first) cat (e.g., catname:Tabby)",
221.  						PL_PSIZ, DISP_IN_GAME },
222.  	{ "disclose", "the kinds of information to disclose at end of game",
223.  						sizeof(flags.end_disclose) * 2,
224.  						SET_IN_GAME },
225.  	{ "dogname",  "the name of your (first) dog (e.g., dogname:Fang)",
226.  						PL_PSIZ, DISP_IN_GAME },
227.  	{ "dungeon",  "the symbols to use in drawing the dungeon map",
228.  						MAXDCHARS+1, SET_IN_FILE },
229.  	{ "effects",  "the symbols to use in drawing special effects",
230.  						MAXECHARS+1, SET_IN_FILE },
231.  	{ "font_map", "the font to use in the map window", 40, DISP_IN_GAME },	/*WC*/
232.  	{ "font_menu", "the font to use in menus", 40, DISP_IN_GAME },		/*WC*/
233.  	{ "font_message", "the font to use in the message window",
234.  						40, DISP_IN_GAME },		/*WC*/
235.  	{ "font_size_map", "the size of the map font", 20, DISP_IN_GAME },	/*WC*/
236.  	{ "font_size_menu", "the size of the menu font", 20, DISP_IN_GAME },	/*WC*/
237.  	{ "font_size_message", "the size of the message font", 20, DISP_IN_GAME },	/*WC*/
238.  	{ "font_size_status", "the size of the status font", 20, DISP_IN_GAME },	/*WC*/
239.  	{ "font_size_text", "the size of the text font", 20, DISP_IN_GAME },	/*WC*/
240.  	{ "font_status", "the font to use in status window", 40, DISP_IN_GAME }, /*WC*/
241.  	{ "font_text", "the font to use in text windows", 40, DISP_IN_GAME },	/*WC*/
242.  	{ "fruit",    "the name of a fruit you enjoy eating",
243.  						PL_FSIZ, SET_IN_GAME },
244.  	{ "gender",   "your starting gender (male or female)",
245.  						8, DISP_IN_GAME },
246.  	{ "horsename", "the name of your (first) horse (e.g., horsename:Silver)",
247.  						PL_PSIZ, DISP_IN_GAME },
248.  	{ "map_mode", "map display mode under Windows", 20, DISP_IN_GAME },	/*WC*/
249.  	{ "menustyle", "user interface for object selection",
250.  						MENUTYPELEN, SET_IN_GAME },
251.  	{ "menu_deselect_all", "deselect all items in a menu", 4, SET_IN_FILE },
252.  	{ "menu_deselect_page", "deselect all items on this page of a menu",
253.  						4, SET_IN_FILE },
254.  	{ "menu_first_page", "jump to the first page in a menu",
255.  						4, SET_IN_FILE },
256.  	{ "menu_headings", "bold, inverse, or underline headings", 9, SET_IN_GAME },
257.  	{ "menu_invert_all", "invert all items in a menu", 4, SET_IN_FILE },
258.  	{ "menu_invert_page", "invert all items on this page of a menu",
259.  						4, SET_IN_FILE },
260.  	{ "menu_last_page", "jump to the last page in a menu", 4, SET_IN_FILE },
261.  	{ "menu_next_page", "goto the next menu page", 4, SET_IN_FILE },
262.  	{ "menu_previous_page", "goto the previous menu page", 4, SET_IN_FILE },
263.  	{ "menu_search", "search for a menu item", 4, SET_IN_FILE },
264.  	{ "menu_select_all", "select all items in a menu", 4, SET_IN_FILE },
265.  	{ "menu_select_page", "select all items on this page of a menu",
266.  						4, SET_IN_FILE },
267.  	{ "monsters", "the symbols to use for monsters",
268.  						MAXMCLASSES, SET_IN_FILE },
269.  	{ "msghistory", "number of top line messages to save",
270.  						5, DISP_IN_GAME },
271.  # ifdef TTY_GRAPHICS
272.  	{"msg_window", "the type of message window required",1, SET_IN_GAME},
273.  # else
274.  	{"msg_window", "the type of message window required", 1, SET_IN_FILE},
275.  # endif
276.  	{ "name",     "your character's name (e.g., name:Merlin-W)",
277.  						PL_NSIZ, DISP_IN_GAME },
278.  	{ "number_pad", "use the number pad", 1, SET_IN_GAME},
279.  	{ "objects",  "the symbols to use for objects",
280.  						MAXOCLASSES, SET_IN_FILE },
281.  	{ "packorder", "the inventory order of the items in your pack",
282.  						MAXOCLASSES, SET_IN_GAME },
283.  #ifdef CHANGE_COLOR
284.  	{ "palette",  "palette (00c/880/-fff is blue/yellow/reverse white)",
285.  						15 , SET_IN_GAME },
286.  # if defined(MAC)
287.  	{ "hicolor",  "same as palette, only order is reversed",
288.  						15, SET_IN_FILE },
289.  # endif
290.  #endif
291.  	{ "pettype",  "your preferred initial pet type", 4, DISP_IN_GAME },
292.  	{ "pickup_burden",  "maximum burden picked up before prompt",
293.  						20, SET_IN_GAME },
294.  	{ "pickup_types", "types of objects to pick up automatically",
295.  						MAXOCLASSES, SET_IN_GAME },
296.  	{ "player_selection", "choose character via dialog or prompts",
297.  						12, DISP_IN_GAME },
298.  	{ "race",     "your starting race (e.g., Human, Elf)",
299.  						PL_CSIZ, DISP_IN_GAME },
300.  	{ "role",     "your starting role (e.g., Barbarian, Valkyrie)",
301.  						PL_CSIZ, DISP_IN_GAME },
302.  	{ "runmode", "display frequency when `running' or `travelling'",
303.  						sizeof "teleport", SET_IN_GAME },
304.  	{ "scores",   "the parts of the score list you wish to see",
305.  						32, SET_IN_GAME },
306.  	{ "scroll_amount", "amount to scroll map when scroll_margin is reached",
307.  						20, DISP_IN_GAME }, /*WC*/
308.  	{ "scroll_margin", "scroll map when this far from the edge", 20, DISP_IN_GAME }, /*WC*/
309.  #ifdef MSDOS
310.  	{ "soundcard", "type of sound card to use", 20, SET_IN_FILE },
311.  #endif
312.  	{ "suppress_alert", "suppress alerts about version-specific features",
313.  						8, SET_IN_GAME },
314.  	{ "tile_width", "width of tiles", 20, DISP_IN_GAME},	/*WC*/
315.  	{ "tile_height", "height of tiles", 20, DISP_IN_GAME},	/*WC*/
316.  	{ "tile_file", "name of tile file", 70, DISP_IN_GAME},	/*WC*/
317.  	{ "traps",    "the symbols to use in drawing traps",
318.  						MAXTCHARS+1, SET_IN_FILE },
319.  	{ "vary_msgcount", "show more old messages at a time", 20, DISP_IN_GAME }, /*WC*/
320.  #ifdef MSDOS
321.  	{ "video",    "method of video updating", 20, SET_IN_FILE },
322.  #endif
323.  #ifdef VIDEOSHADES
324.  	{ "videocolors", "color mappings for internal screen routines",
325.  						40, DISP_IN_GAME },
326.  	{ "videoshades", "gray shades to map to black/gray/white",
327.  						32, DISP_IN_GAME },
328.  #endif
329.  #ifdef WIN32CON
330.  	{"subkeyvalue", "override keystroke value", 7, SET_IN_FILE},
331.  #endif
332.  	{ "windowcolors",  "the foreground/background colors of windows",	/*WC*/
333.  						80, DISP_IN_GAME },
334.  	{ "windowtype", "windowing system to use", WINTYPELEN, DISP_IN_GAME },
335.  	{ (char *)0, (char *)0, 0, 0 }
336.  };
337.  
338.  #ifdef OPTION_LISTS_ONLY
339.  #undef static
340.  
341.  #else	/* use rest of file */
342.  
343.  static boolean need_redraw; /* for doset() */
344.  
345.  #if defined(TOS) && defined(TEXTCOLOR)
346.  extern boolean colors_changed;	/* in tos.c */
347.  #endif
348.  
349.  #ifdef VIDEOSHADES
350.  extern char *shade[3];		  /* in sys/msdos/video.c */
351.  extern char ttycolors[CLR_MAX];	  /* in sys/msdos/video.c */
352.  #endif
353.  
354.  static char def_inv_order[MAXOCLASSES] = {
355.  	COIN_CLASS, AMULET_CLASS, WEAPON_CLASS, ARMOR_CLASS, FOOD_CLASS,
356.  	SCROLL_CLASS, SPBOOK_CLASS, POTION_CLASS, RING_CLASS, WAND_CLASS,
357.  	TOOL_CLASS, GEM_CLASS, ROCK_CLASS, BALL_CLASS, CHAIN_CLASS, 0,
358.  };
359.  

[edit] Menu accelerators

360.  /*
361.   * Default menu manipulation command accelerators.  These may _not_ be:
362.   *
363.   *	+ a number - reserved for counts
364.   *	+ an upper or lower case US ASCII letter - used for accelerators
365.   *	+ ESC - reserved for escaping the menu
366.   *	+ NULL, CR or LF - reserved for commiting the selection(s).  NULL
367.   *	  is kind of odd, but the tty's xwaitforspace() will return it if
368.   *	  someone hits a <ret>.
369.   *	+ a default object class symbol - used for object class accelerators
370.   *
371.   * Standard letters (for now) are:
372.   *
373.   *		<  back 1 page
374.   *		>  forward 1 page
375.   *		^  first page
376.   *		|  last page
377.   *		:  search
378.   *
379.   *		page		all
380.   *		 ,    select	 .
381.   *		 \    deselect	 -
382.   *		 ~    invert	 @
383.   *
384.   * The command name list is duplicated in the compopt array.
385.   */
386.  typedef struct {
387.      const char *name;
388.      char cmd;
389.  } menu_cmd_t;
390.  
391.  #define NUM_MENU_CMDS 11
392.  static const menu_cmd_t default_menu_cmd_info[NUM_MENU_CMDS] = {
393.  /* 0*/	{ "menu_first_page",	MENU_FIRST_PAGE },
394.  	{ "menu_last_page",	MENU_LAST_PAGE },
395.  	{ "menu_next_page",	MENU_NEXT_PAGE },
396.  	{ "menu_previous_page",	MENU_PREVIOUS_PAGE },
397.  	{ "menu_select_all",	MENU_SELECT_ALL },
398.  /* 5*/	{ "menu_deselect_all",	MENU_UNSELECT_ALL },
399.  	{ "menu_invert_all",	MENU_INVERT_ALL },
400.  	{ "menu_select_page",	MENU_SELECT_PAGE },
401.  	{ "menu_deselect_page",	MENU_UNSELECT_PAGE },
402.  	{ "menu_invert_page",	MENU_INVERT_PAGE },
403.  /*10*/	{ "menu_search",		MENU_SEARCH },
404.  };
405.  
406.  /*
407.   * Allow the user to map incoming characters to various menu commands.
408.   * The accelerator list must be a valid C string.
409.   */
410.  #define MAX_MENU_MAPPED_CMDS 32	/* some number */
411.         char mapped_menu_cmds[MAX_MENU_MAPPED_CMDS+1];	/* exported */
412.  static char mapped_menu_op[MAX_MENU_MAPPED_CMDS+1];
413.  static short n_menu_mapped = 0;
414.  
415.  
416.  static boolean initial, from_file;
417.  
418.  STATIC_DCL void FDECL(doset_add_menu, (winid,const char *,int));
419.  STATIC_DCL void FDECL(nmcpy, (char *, const char *, int));
420.  STATIC_DCL void FDECL(escapes, (const char *, char *));
421.  STATIC_DCL void FDECL(rejectoption, (const char *));
422.  STATIC_DCL void FDECL(badoption, (const char *));
423.  STATIC_DCL char *FDECL(string_for_opt, (char *,BOOLEAN_P));
424.  STATIC_DCL char *FDECL(string_for_env_opt, (const char *, char *,BOOLEAN_P));
425.  STATIC_DCL void FDECL(bad_negation, (const char *,BOOLEAN_P));
426.  STATIC_DCL int FDECL(change_inv_order, (char *));
427.  STATIC_DCL void FDECL(oc_to_str, (char *, char *));
428.  STATIC_DCL void FDECL(graphics_opts, (char *,const char *,int,int));
429.  STATIC_DCL int FDECL(feature_alert_opts, (char *, const char *));
430.  STATIC_DCL const char *FDECL(get_compopt_value, (const char *, char *));
431.  STATIC_DCL boolean FDECL(special_handling, (const char *, BOOLEAN_P, BOOLEAN_P));
432.  STATIC_DCL void FDECL(warning_opts, (char *,const char *));
433.  STATIC_DCL void FDECL(duplicate_opt_detection, (const char *, int));
434.  
435.  STATIC_OVL void FDECL(wc_set_font_name, (int, char *));
436.  STATIC_OVL int FDECL(wc_set_window_colors, (char *));
437.  STATIC_OVL boolean FDECL(is_wc_option, (const char *));
438.  STATIC_OVL boolean FDECL(wc_supported, (const char *));
439.  STATIC_OVL boolean FDECL(is_wc2_option, (const char *));
440.  STATIC_OVL boolean FDECL(wc2_supported, (const char *));
441.  #ifdef AUTOPICKUP_EXCEPTIONS
442.  STATIC_DCL void FDECL(remove_autopickup_exception, (struct autopickup_exception *));
443.  STATIC_OVL int FDECL(count_ape_maps, (int *, int *));
444.  #endif
445.  

[edit] match_optname

446.  /* check whether a user-supplied option string is a proper leading
447.     substring of a particular option name; option string might have
448.     a colon or equals sign and arbitrary value appended to it */
449.  boolean
450.  match_optname(user_string, opt_name, min_length, val_allowed)
451.  const char *user_string, *opt_name;
452.  int min_length;
453.  boolean val_allowed;
454.  {
455.  	int len = (int)strlen(user_string);
456.  
457.  	if (val_allowed) {
458.  	    const char *p = index(user_string, ':'),
459.  		       *q = index(user_string, '=');
460.  
461.  	    if (!p || (q && q < p)) p = q;
462.  	    while(p && p > user_string && isspace(*(p-1))) p--;
463.  	    if (p) len = (int)(p - user_string);
464.  	}
465.  
466.  	return (len >= min_length) && !strncmpi(opt_name, user_string, len);
467.  }
468.  

[edit] nh_getenv

469.  /* most environment variables will eventually be printed in an error
470.   * message if they don't work, and most error message paths go through
471.   * BUFSZ buffers, which could be overflowed by a maliciously long
472.   * environment variable.  if a variable can legitimately be long, or
473.   * if it's put in a smaller buffer, the responsible code will have to
474.   * bounds-check itself.
475.   */
476.  char *
477.  nh_getenv(ev)
478.  const char *ev;
479.  {
480.  	char *getev = getenv(ev);
481.  
482.  	if (getev && strlen(getev) <= (BUFSZ / 2))
483.  		return getev;
484.  	else
485.  		return (char *)0;
486.  }
487.  

[edit] initoptions

488.  void
489.  initoptions()
490.  {
491.  #ifndef MAC
492.  	char *opts;
493.  #endif
494.  	int i;
495.  
496.  	/* initialize the random number generator */
497.  	setrandom();
498.  
499.  	/* for detection of configfile options specified multiple times */
500.  	iflags.opt_booldup = iflags.opt_compdup = (int *)0;
501.  	
502.  	for (i = 0; boolopt[i].name; i++) {
503.  		if (boolopt[i].addr)
504.  			*(boolopt[i].addr) = boolopt[i].initvalue;
505.  	}
506.  	flags.end_own = FALSE;
507.  	flags.end_top = 3;
508.  	flags.end_around = 2;
509.  	iflags.runmode = RUN_LEAP;
510.  	iflags.msg_history = 20;
511.  #ifdef TTY_GRAPHICS
512.  	iflags.prevmsg_window = 's';
513.  #endif
514.  	iflags.menu_headings = ATR_INVERSE;
515.  
516.  	/* Use negative indices to indicate not yet selected */
517.  	flags.initrole = -1;
518.  	flags.initrace = -1;
519.  	flags.initgend = -1;
520.  	flags.initalign = -1;
521.  
522.  	/* Set the default monster and object class symbols.  Don't use */
523.  	/* memcpy() --- sizeof char != sizeof uchar on some machines.	*/
524.  	for (i = 0; i < MAXOCLASSES; i++)
525.  		oc_syms[i] = (uchar) def_oc_syms[i];
526.  	for (i = 0; i < MAXMCLASSES; i++)
527.  		monsyms[i] = (uchar) def_monsyms[i];
528.  	for (i = 0; i < WARNCOUNT; i++)
529.  		warnsyms[i] = def_warnsyms[i].sym;
530.  	iflags.bouldersym = 0;
531.  	iflags.travelcc.x = iflags.travelcc.y = -1;
532.  	flags.warnlevel = 1;
533.  	flags.warntype = 0L;
534.  
535.       /* assert( sizeof flags.inv_order == sizeof def_inv_order ); */
536.  	(void)memcpy((genericptr_t)flags.inv_order,
537.  		     (genericptr_t)def_inv_order, sizeof flags.inv_order);
538.  	flags.pickup_types[0] = '\0';
539.  	flags.pickup_burden = MOD_ENCUMBER;
540.  
541.  	for (i = 0; i < NUM_DISCLOSURE_OPTIONS; i++)
542.  		flags.end_disclose[i] = DISCLOSE_PROMPT_DEFAULT_NO;
543.  	switch_graphics(ASCII_GRAPHICS);	/* set default characters */
544.  #if defined(UNIX) && defined(TTY_GRAPHICS)
545.  	/*
546.  	 * Set defaults for some options depending on what we can
547.  	 * detect about the environment's capabilities.
548.  	 * This has to be done after the global initialization above
549.  	 * and before reading user-specific initialization via
550.  	 * config file/environment variable below.
551.  	 */
552.  	/* this detects the IBM-compatible console on most 386 boxes */
553.  	if ((opts = nh_getenv("TERM")) && !strncmp(opts, "AT", 2)) {
554.  		switch_graphics(IBM_GRAPHICS);
555.  # ifdef TEXTCOLOR
556.  		iflags.use_color = TRUE;
557.  # endif
558.  	}
559.  #endif /* UNIX && TTY_GRAPHICS */
560.  #if defined(UNIX) || defined(VMS)
561.  # ifdef TTY_GRAPHICS
562.  	/* detect whether a "vt" terminal can handle alternate charsets */
563.  	if ((opts = nh_getenv("TERM")) &&
564.  	    !strncmpi(opts, "vt", 2) && AS && AE &&
565.  	    index(AS, '\016') && index(AE, '\017')) {
566.  		switch_graphics(DEC_GRAPHICS);
567.  	}
568.  # endif
569.  #endif /* UNIX || VMS */
570.  
571.  #ifdef MAC_GRAPHICS_ENV
572.  	switch_graphics(MAC_GRAPHICS);
573.  #endif /* MAC_GRAPHICS_ENV */
574.  	flags.menu_style = MENU_FULL;
575.  
576.  	/* since this is done before init_objects(), do partial init here */
577.  	objects[SLIME_MOLD].oc_name_idx = SLIME_MOLD;
578.  	nmcpy(pl_fruit, OBJ_NAME(objects[SLIME_MOLD]), PL_FSIZ);
579.  #ifndef MAC
580.  	opts = getenv("NETHACKOPTIONS");
581.  	if (!opts) opts = getenv("HACKOPTIONS");
582.  	if (opts) {
583.  		if (*opts == '/' || *opts == '\\' || *opts == '@') {
584.  			if (*opts == '@') opts++;	/* @filename */
585.  			/* looks like a filename */
586.  			if (strlen(opts) < BUFSZ/2)
587.  			    read_config_file(opts);
588.  		} else {
589.  			read_config_file((char *)0);
590.  			/* let the total length of options be long;
591.  			 * parseoptions() will check each individually
592.  			 */
593.  			parseoptions(opts, TRUE, FALSE);
594.  		}
595.  	} else
596.  #endif
597.  		read_config_file((char *)0);
598.  
599.  	(void)fruitadd(pl_fruit);
600.  	/* Remove "slime mold" from list of object names; this will	*/
601.  	/* prevent it from being wished unless it's actually present	*/
602.  	/* as a named (or default) fruit.  Wishing for "fruit" will	*/
603.  	/* result in the player's preferred fruit [better than "\033"].	*/
604.  	obj_descr[SLIME_MOLD].oc_name = "fruit";
605.  
606.  	return;
607.  }
608.  

[edit] nmcpy

609.  STATIC_OVL void
610.  nmcpy(dest, src, maxlen)
611.  	char	*dest;
612.  	const char *src;
613.  	int	maxlen;
614.  {
615.  	int	count;
616.  
617.  	for(count = 1; count < maxlen; count++) {
618.  		if(*src == ',' || *src == '\0') break; /*exit on \0 terminator*/
619.  		*dest++ = *src++;
620.  	}
621.  	*dest = 0;
622.  }
623.  

[edit] escapes

624.  /*
625.   * escapes: escape expansion for showsyms. C-style escapes understood include
626.   * \n, \b, \t, \r, \xnnn (hex), \onnn (octal), \nnn (decimal). The ^-prefix
627.   * for control characters is also understood, and \[mM] followed by any of the
628.   * previous forms or by a character has the effect of 'meta'-ing the value (so
629.   * that the alternate character set will be enabled).
630.   */
631.  STATIC_OVL void
632.  escapes(cp, tp)
633.  const char	*cp;
634.  char *tp;
635.  {
636.      while (*cp)
637.      {
638.  	int	cval = 0, meta = 0;
639.  
640.  	if (*cp == '\\' && index("mM", cp[1])) {
641.  		meta = 1;
642.  		cp += 2;
643.  	}
644.  	if (*cp == '\\' && index("0123456789xXoO", cp[1]))
645.  	{
646.  	    const char *dp, *hex = "00112233445566778899aAbBcCdDeEfF";
647.  	    int dcount = 0;
648.  
649.  	    cp++;
650.  	    if (*cp == 'x' || *cp == 'X')
651.  		for (++cp; (dp = index(hex, *cp)) && (dcount++ < 2); cp++)
652.  		    cval = (cval * 16) + (dp - hex) / 2;
653.  	    else if (*cp == 'o' || *cp == 'O')
654.  		for (++cp; (index("01234567",*cp)) && (dcount++ < 3); cp++)
655.  		    cval = (cval * 8) + (*cp - '0');
656.  	    else
657.  		for (; (index("0123456789",*cp)) && (dcount++ < 3); cp++)
658.  		    cval = (cval * 10) + (*cp - '0');
659.  	}
660.  	else if (*cp == '\\')		/* C-style character escapes */
661.  	{
662.  	    switch (*++cp)
663.  	    {
664.  	    case '\\': cval = '\\'; break;
665.  	    case 'n': cval = '\n'; break;
666.  	    case 't': cval = '\t'; break;
667.  	    case 'b': cval = '\b'; break;
668.  	    case 'r': cval = '\r'; break;
669.  	    default: cval = *cp;
670.  	    }
671.  	    cp++;
672.  	}
673.  	else if (*cp == '^')		/* expand control-character syntax */
674.  	{
675.  	    cval = (*++cp & 0x1f);
676.  	    cp++;
677.  	}
678.  	else
679.  	    cval = *cp++;
680.  	if (meta)
681.  	    cval |= 0x80;
682.  	*tp++ = cval;
683.      }
684.      *tp = '\0';
685.  }
686.  

[edit] rejectoption

687.  STATIC_OVL void
688.  rejectoption(optname)
689.  const char *optname;
690.  {
691.  #ifdef MICRO
692.  	pline("\"%s\" settable only from %s.", optname, configfile);
693.  #else
694.  	pline("%s can be set only from NETHACKOPTIONS or %s.", optname,
695.  			configfile);
696.  #endif
697.  }
698.  

[edit] badoption

699.  STATIC_OVL void
700.  badoption(opts)
701.  const char *opts;
702.  {
703.  	if (!initial) {
704.  	    if (!strncmp(opts, "h", 1) || !strncmp(opts, "?", 1))
705.  		option_help();
706.  	    else
707.  		pline("Bad syntax: %s.  Enter \"?g\" for help.", opts);
708.  	    return;
709.  	}
710.  #ifdef MAC
711.  	else return;
712.  #endif
713.  
714.  	if(from_file)
715.  	    raw_printf("Bad syntax in OPTIONS in %s: %s.", configfile, opts);
716.  	else
717.  	    raw_printf("Bad syntax in NETHACKOPTIONS: %s.", opts);
718.  
719.  	wait_synch();
720.  }
721.  

[edit] string_for_opt

722.  STATIC_OVL char *
723.  string_for_opt(opts, val_optional)
724.  char *opts;
725.  boolean val_optional;
726.  {
727.  	char *colon, *equals;
728.  
729.  	colon = index(opts, ':');
730.  	equals = index(opts, '=');
731.  	if (!colon || (equals && equals < colon)) colon = equals;
732.  
733.  	if (!colon || !*++colon) {
734.  		if (!val_optional) badoption(opts);
735.  		return (char *)0;
736.  	}
737.  	return colon;
738.  }
739.  

[edit] string_for_env_opt

740.  STATIC_OVL char *
741.  string_for_env_opt(optname, opts, val_optional)
742.  const char *optname;
743.  char *opts;
744.  boolean val_optional;
745.  {
746.  	if(!initial) {
747.  		rejectoption(optname);
748.  		return (char *)0;
749.  	}
750.  	return string_for_opt(opts, val_optional);
751.  }
752.  

[edit] bad_negation

753.  STATIC_OVL void
754.  bad_negation(optname, with_parameter)
755.  const char *optname;
756.  boolean with_parameter;
757.  {
758.  	pline_The("%s option may not %sbe negated.",
759.  		optname,
760.  		with_parameter ? "both have a value and " : "");
761.  }
762.  

[edit] change_inv_order

763.  /*
764.   * Change the inventory order, using the given string as the new order.
765.   * Missing characters in the new order are filled in at the end from
766.   * the current inv_order, except for gold, which is forced to be first
767.   * if not explicitly present.
768.   *
769.   * This routine returns 1 unless there is a duplicate or bad char in
770.   * the string.
771.   */
772.  STATIC_OVL int
773.  change_inv_order(op)
774.  char *op;
775.  {
776.      int oc_sym, num;
777.      char *sp, buf[BUFSZ];
778.  
779.      num = 0;
780.  #ifndef GOLDOBJ
781.      if (!index(op, GOLD_SYM))
782.  	buf[num++] = COIN_CLASS;
783.  #else
784.      /*  !!!! probably unnecessary with gold as normal inventory */
785.  #endif
786.  
787.      for (sp = op; *sp; sp++) {
788.  	oc_sym = def_char_to_objclass(*sp);
789.  	/* reject bad or duplicate entries */
790.  	if (oc_sym == MAXOCLASSES ||
791.  		oc_sym == RANDOM_CLASS || oc_sym == ILLOBJ_CLASS ||
792.  		!index(flags.inv_order, oc_sym) || index(sp+1, *sp))
793.  	    return 0;
794.  	/* retain good ones */
795.  	buf[num++] = (char) oc_sym;
796.      }
797.      buf[num] = '\0';
798.  
799.      /* fill in any omitted classes, using previous ordering */
800.      for (sp = flags.inv_order; *sp; sp++)
801.  	if (!index(buf, *sp)) {
802.  	    buf[num++] = *sp;
803.  	    buf[num] = '\0';	/* explicitly terminate for next index() */
804.  	}
805.  
806.      Strcpy(flags.inv_order, buf);
807.      return 1;
808.  }
809.  

[edit] graphics_opts

810.  STATIC_OVL void
811.  graphics_opts(opts, optype, maxlen, offset)
812.  register char *opts;
813.  const char *optype;
814.  int maxlen, offset;
815.  {
816.  	uchar translate[MAXPCHARS+1];
817.  	int length, i;
818.  
819.  	if (!(opts = string_for_env_opt(optype, opts, FALSE)))
820.  		return;
821.  	escapes(opts, opts);
822.  
823.  	length = strlen(opts);
824.  	if (length > maxlen) length = maxlen;
825.  	/* match the form obtained from PC configuration files */
826.  	for (i = 0; i < length; i++)
827.  		translate[i] = (uchar) opts[i];
828.  	assign_graphics(translate, length, maxlen, offset);
829.  }
830.  

[edit] warning_opts

831.  STATIC_OVL void
832.  warning_opts(opts, optype)
833.  register char *opts;
834.  const char *optype;
835.  {
836.  	uchar translate[MAXPCHARS+1];
837.  	int length, i;
838.  
839.  	if (!(opts = string_for_env_opt(optype, opts, FALSE)))
840.  		return;
841.  	escapes(opts, opts);
842.  
843.  	length = strlen(opts);
844.  	if (length > WARNCOUNT) length = WARNCOUNT;
845.  	/* match the form obtained from PC configuration files */
846.  	for (i = 0; i < length; i++)
847.  	     translate[i] = (((i < WARNCOUNT) && opts[i]) ?
848.  			   (uchar) opts[i] : def_warnsyms[i].sym);
849.  	assign_warnings(translate);
850.  }
851.  

[edit] assign_warnings

852.  void
853.  assign_warnings(graph_chars)
854.  register uchar *graph_chars;
855.  {
856.  	int i;
857.  	for (i = 0; i < WARNCOUNT; i++)
858.  	    if (graph_chars[i]) warnsyms[i] = graph_chars[i];
859.  }
860.  

[edit] feature_alert_opts

861.  STATIC_OVL int
862.  feature_alert_opts(op, optn)
863.  char *op;
864.  const char *optn;
865.  {
866.  	char buf[BUFSZ];
867.  	boolean rejectver = FALSE;
868.  	unsigned long fnv = get_feature_notice_ver(op);		/* version.c */
869.  	if (fnv == 0L) return 0;
870.  	if (fnv > get_current_feature_ver())
871.  		rejectver = TRUE;
872.  	else
873.  		flags.suppress_alert = fnv;
874.  	if (rejectver) {
875.  		if (!initial)
876.  			You_cant("disable new feature alerts for future versions.");
877.  		else {
878.  			Sprintf(buf,
879.  				"\n%s=%s Invalid reference to a future version ignored",
880.  				optn, op);
881.  			badoption(buf);
882.  		}
883.  		return 0;
884.  	}
885.  	if (!initial) {
886.  		Sprintf(buf, "%lu.%lu.%lu", FEATURE_NOTICE_VER_MAJ,
887.  			FEATURE_NOTICE_VER_MIN, FEATURE_NOTICE_VER_PATCH);
888.  		pline("Feature change alerts disabled for NetHack %s features and prior.",
889.  			buf);
890.  	}
891.  	return 1;
892.  }
893.  

[edit] set_duplicate_opt_detection

894.  void
895.  set_duplicate_opt_detection(on_or_off)
896.  int on_or_off;
897.  {
898.  	int k, *optptr;
899.  	if (on_or_off != 0) {
900.  		/*-- ON --*/
901.  		if (iflags.opt_booldup)
902.  			impossible("iflags.opt_booldup already on (memory leak)");
903.  		iflags.opt_booldup = (int *)alloc(SIZE(boolopt) * sizeof(int));
904.  		optptr = iflags.opt_booldup;
905.  		for (k = 0; k < SIZE(boolopt); ++k)
906.  			*optptr++ = 0;
907.  			
908.  		if (iflags.opt_compdup)
909.  			impossible("iflags.opt_compdup already on (memory leak)");
910.  		iflags.opt_compdup = (int *)alloc(SIZE(compopt) * sizeof(int));
911.  		optptr = iflags.opt_compdup;
912.  		for (k = 0; k < SIZE(compopt); ++k)
913.  			*optptr++ = 0;
914.  	} else {
915.  		/*-- OFF --*/
916.  		if (iflags.opt_booldup) free((genericptr_t) iflags.opt_booldup);
917.  		iflags.opt_booldup = (int *)0;
918.  		if (iflags.opt_compdup) free((genericptr_t) iflags.opt_compdup);
919.  		iflags.opt_compdup = (int *)0;
920.  	} 
921.  }
922.  

[edit] duplicate_opt_detection

923.  STATIC_OVL void
924.  duplicate_opt_detection(opts, bool_or_comp)
925.  const char *opts;
926.  int bool_or_comp;	/* 0 == boolean option, 1 == compound */
927.  {
928.  	int i, *optptr;
929.  #if defined(MAC)
930.  	/* the Mac has trouble dealing with the output of messages while
931.  	 * processing the config file.  That should get fixed one day.
932.  	 * For now just return.
933.  	 */
934.  	return;
935.  #endif
936.  	if ((bool_or_comp == 0) && iflags.opt_booldup && initial && from_file) {
937.  	    for (i = 0; boolopt[i].name; i++) {
938.  		if (match_optname(opts, boolopt[i].name, 3, FALSE)) {
939.  			optptr = iflags.opt_booldup + i;
940.  			if (*optptr == 1) {
941.  			    raw_printf(
942.  				"\nWarning - Boolean option specified multiple times: %s.\n",
943.  					opts);
944.  			        wait_synch();
945.  			}
946.  			*optptr += 1;
947.  			break; /* don't match multiple options */
948.  		}
949.  	    }
950.  	} else if ((bool_or_comp == 1) && iflags.opt_compdup && initial && from_file) {
951.  	    for (i = 0; compopt[i].name; i++) {
952.  		if (match_optname(opts, compopt[i].name, strlen(compopt[i].name), TRUE)) {
953.  			optptr = iflags.opt_compdup + i;
954.  			if (*optptr == 1) {
955.  			    raw_printf(
956.  				"\nWarning - compound option specified multiple times: %s.\n",
957.  					compopt[i].name);
958.  			        wait_synch();
959.  			}
960.  			*optptr += 1;
961.  			break; /* don't match multiple options */
962.  		}
963.  	    }
964.  	}
965.  }
966.  

[edit] parseoptions

967.  void
968.  parseoptions(opts, tinitial, tfrom_file)
969.  register char *opts;
970.  boolean tinitial, tfrom_file;
971.  {
972.  	register char *op;
973.  	unsigned num;
974.  	boolean negated;
975.  	int i;
976.  	const char *fullname;
977.  
978.  	initial = tinitial;
979.  	from_file = tfrom_file;
980.  	if ((op = index(opts, ',')) != 0) {
981.  		*op++ = 0;
982.  		parseoptions(op, initial, from_file);
983.  	}
984.  	if (strlen(opts) > BUFSZ/2) {
985.  		badoption("option too long");
986.  		return;
987.  	}
988.  
989.  	/* strip leading and trailing white space */
990.  	while (isspace(*opts)) opts++;
991.  	op = eos(opts);
992.  	while (--op >= opts && isspace(*op)) *op = '\0';
993.  
994.  	if (!*opts) return;
995.  	negated = FALSE;
996.  	while ((*opts == '!') || !strncmpi(opts, "no", 2)) {
997.  		if (*opts == '!') opts++; else opts += 2;
998.  		negated = !negated;
999.  	}
1000. 
1001. 	/* variant spelling */
1002. 
1003. 	if (match_optname(opts, "colour", 5, FALSE))
1004. 		Strcpy(opts, "color");	/* fortunately this isn't longer */
1005. 
1006. 	if (!match_optname(opts, "subkeyvalue", 11, TRUE)) /* allow multiple */
1007. 	duplicate_opt_detection(opts, 1);	/* 1 means compound opts */
1008. 
1009. 	/* special boolean options */
1010. 
1011. 	if (match_optname(opts, "female", 3, FALSE)) {
1012. 		if(!initial && flags.female == negated)
1013. 			pline("That is not anatomically possible.");
1014. 		else
1015. 			flags.initgend = flags.female = !negated;
1016. 		return;
1017. 	}
1018. 
1019. 	if (match_optname(opts, "male", 4, FALSE)) {
1020. 		if(!initial && flags.female != negated)
1021. 			pline("That is not anatomically possible.");
1022. 		else
1023. 			flags.initgend = flags.female = negated;
1024. 		return;
1025. 	}
1026. 
1027. #if defined(MICRO) && !defined(AMIGA)
1028. 	/* included for compatibility with old NetHack.cnf files */
1029. 	if (match_optname(opts, "IBM_", 4, FALSE)) {
1030. 		iflags.BIOS = !negated;
1031. 		return;
1032. 	}
1033. #endif /* MICRO */
1034. 
1035. 	/* compound options */
1036. 
1037. 	fullname = "pettype";
1038. 	if (match_optname(opts, fullname, 3, TRUE)) {
1039. 		if ((op = string_for_env_opt(fullname, opts, negated)) != 0) {
1040. 		    if (negated) bad_negation(fullname, TRUE);
1041. 		    else switch (*op) {
1042. 			case 'd':	/* dog */
1043. 			case 'D':
1044. 			    preferred_pet = 'd';
1045. 			    break;
1046. 			case 'c':	/* cat */
1047. 			case 'C':
1048. 			case 'f':	/* feline */
1049. 			case 'F':
1050. 			    preferred_pet = 'c';
1051. 			    break;
1052. 			case 'n':	/* no pet */
1053. 			case 'N':
1054. 			    preferred_pet = 'n';
1055. 			    break;
1056. 			default:
1057. 			    pline("Unrecognized pet type '%s'.", op);
1058. 			    break;
1059. 		    }
1060. 		} else if (negated) preferred_pet = 'n';
1061. 		return;
1062. 	}
1063. 
1064. 	fullname = "catname";
1065. 	if (match_optname(opts, fullname, 3, TRUE)) {
1066. 		if (negated) bad_negation(fullname, FALSE);
1067. 		else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0)
1068. 			nmcpy(catname, op, PL_PSIZ);
1069. 		return;
1070. 	}
1071. 
1072. 	fullname = "dogname";
1073. 	if (match_optname(opts, fullname, 3, TRUE)) {
1074. 		if (negated) bad_negation(fullname, FALSE);
1075. 		else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0)
1076. 			nmcpy(dogname, op, PL_PSIZ);
1077. 		return;
1078. 	}
1079. 
1080. 	fullname = "horsename";
1081. 	if (match_optname(opts, fullname, 5, TRUE)) {
1082. 		if (negated) bad_negation(fullname, FALSE);
1083. 		else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0)
1084. 			nmcpy(horsename, op, PL_PSIZ);
1085. 		return;
1086. 	}
1087. 
1088. 	fullname = "number_pad";
1089. 	if (match_optname(opts, fullname, 10, TRUE)) {
1090. 		boolean compat = (strlen(opts) <= 10);
1091. 		number_pad(iflags.num_pad ? 1 : 0);
1092. 		op = string_for_opt(opts, (compat || !initial));
1093. 		if (!op) {
1094. 		    if (compat || negated || initial) {
1095. 			/* for backwards compatibility, "number_pad" without a
1096. 			   value is a synonym for number_pad:1 */
1097. 			iflags.num_pad = !negated;
1098. 			if (iflags.num_pad) iflags.num_pad_mode = 0;
1099. 		    }
1100. 		    return;
1101. 		}
1102. 		if (negated) {
1103. 		    bad_negation("number_pad", TRUE);
1104. 		    return;
1105. 		}
1106. 		if (*op == '1' || *op == '2') {
1107. 			iflags.num_pad = 1;
1108. 			if (*op == '2') iflags.num_pad_mode = 1;
1109. 			else iflags.num_pad_mode = 0;
1110. 		} else if (*op == '0') {
1111. 			iflags.num_pad = 0;
1112. 			iflags.num_pad_mode = 0;
1113. 		} else badoption(opts);
1114. 		return;
1115. 	}
1116. 
1117. 	fullname = "runmode";
1118. 	if (match_optname(opts, fullname, 4, TRUE)) {
1119. 		if (negated) {
1120. 			iflags.runmode = RUN_TPORT;
1121. 		} else if ((op = string_for_opt(opts, FALSE)) != 0) {
1122. 		    if (!strncmpi(op, "teleport", strlen(op)))
1123. 			iflags.runmode = RUN_TPORT;
1124. 		    else if (!strncmpi(op, "run", strlen(op)))
1125. 			iflags.runmode = RUN_LEAP;
1126. 		    else if (!strncmpi(op, "walk", strlen(op)))
1127. 			iflags.runmode = RUN_STEP;
1128. 		    else if (!strncmpi(op, "crawl", strlen(op)))
1129. 			iflags.runmode = RUN_CRAWL;
1130. 		    else
1131. 			badoption(opts);
1132. 		}
1133. 		return;
1134. 	}
1135. 
1136. 	fullname = "msghistory";
1137. 	if (match_optname(opts, fullname, 3, TRUE)) {
1138. 		op = string_for_env_opt(fullname, opts, negated);
1139. 		if ((negated && !op) || (!negated && op)) {
1140. 			iflags.msg_history = negated ? 0 : atoi(op);
1141. 		} else if (negated) bad_negation(fullname, TRUE);
1142. 		return;
1143. 	}
1144. 
1145. 	fullname="msg_window";
1146. 	/* msg_window:single, combo, full or reversed */
1147. 	if (match_optname(opts, fullname, 4, TRUE)) {
1148. 	/* allow option to be silently ignored by non-tty ports */
1149. #ifdef TTY_GRAPHICS
1150. 		int tmp;
1151. 		if (!(op = string_for_opt(opts, TRUE))) {
1152. 		    tmp = negated ? 's' : 'f';
1153. 		} else {
1154. 			  if (negated) {
1155. 			  	bad_negation(fullname, TRUE);
1156. 			  	return;
1157. 				  }
1158. 		    tmp = tolower(*op);
1159. 		}
1160. 		switch (tmp) {
1161. 			case 's':	/* single message history cycle (default if negated) */
1162. 				iflags.prevmsg_window = 's';
1163. 				break;
1164. 			case 'c':	/* combination: two singles, then full page reversed */
1165. 				iflags.prevmsg_window = 'c';
1166. 				break;
1167. 			case 'f':	/* full page (default if no opts) */
1168. 				iflags.prevmsg_window = 'f';
1169. 				break;
1170. 			case 'r':	/* full page (reversed) */
1171. 				iflags.prevmsg_window = 'r';
1172. 				break;
1173. 			default:
1174. 				badoption(opts);
1175. 		}
1176. #endif
1177. 		return;
1178. 	}
1179. 
1180. 	/* WINCAP
1181. 	 * setting font options  */
1182. 	fullname = "font";
1183. 	if (!strncmpi(opts, fullname, 4))
1184. 	{
1185. 		int wintype = -1;
1186. 		char *fontopts = opts + 4;
1187. 
1188. 		if (!strncmpi(fontopts, "map", 3) ||
1189. 		    !strncmpi(fontopts, "_map", 4))
1190. 			wintype = NHW_MAP;
1191. 		else if (!strncmpi(fontopts, "message", 7) ||
1192. 			 !strncmpi(fontopts, "_message", 8))
1193. 			wintype = NHW_MESSAGE;
1194. 		else if (!strncmpi(fontopts, "text", 4) ||
1195. 			 !strncmpi(fontopts, "_text", 5))
1196. 			wintype = NHW_TEXT;			
1197. 		else if (!strncmpi(fontopts, "menu", 4) ||
1198. 			 !strncmpi(fontopts, "_menu", 5))
1199. 			wintype = NHW_MENU;
1200. 		else if (!strncmpi(fontopts, "status", 6) ||
1201. 			 !strncmpi(fontopts, "_status", 7))
1202. 			wintype = NHW_STATUS;
1203. 		else if (!strncmpi(fontopts, "_size", 5)) {
1204. 			if (!strncmpi(fontopts, "_size_map", 8))
1205. 				wintype = NHW_MAP;
1206. 			else if (!strncmpi(fontopts, "_size_message", 12))
1207. 				wintype = NHW_MESSAGE;
1208. 			else if (!strncmpi(fontopts, "_size_text", 9))
1209. 				wintype = NHW_TEXT;
1210. 			else if (!strncmpi(fontopts, "_size_menu", 9))
1211. 				wintype = NHW_MENU;
1212. 			else if (!strncmpi(fontopts, "_size_status", 11))
1213. 				wintype = NHW_STATUS;
1214. 			else {
1215. 				badoption(opts);
1216. 				return;
1217. 			}
1218. 			if (wintype > 0 && !negated &&
1219. 			    (op = string_for_opt(opts, FALSE)) != 0) {
1220. 			    switch(wintype)  {
1221. 			    	case NHW_MAP:
1222. 					iflags.wc_fontsiz_map = atoi(op);
1223. 					break;
1224. 			    	case NHW_MESSAGE:
1225. 					iflags.wc_fontsiz_message = atoi(op);
1226. 					break;
1227. 			    	case NHW_TEXT:
1228. 					iflags.wc_fontsiz_text = atoi(op);
1229. 					break;
1230. 			    	case NHW_MENU:
1231. 					iflags.wc_fontsiz_menu = atoi(op);
1232. 					break;
1233. 			    	case NHW_STATUS:
1234. 					iflags.wc_fontsiz_status = atoi(op);
1235. 					break;
1236. 			    }
1237. 			}
1238. 			return;
1239. 		} else {
1240. 			badoption(opts);
1241. 		}
1242. 		if (wintype > 0 &&
1243. 		    (op = string_for_opt(opts, FALSE)) != 0) {
1244. 			wc_set_font_name(wintype, op);
1245. #ifdef MAC
1246. 			set_font_name (wintype, op);
1247. #endif
1248. 			return;
1249. 		} else if (negated) bad_negation(fullname, TRUE);
1250. 		return;
1251. 	}
1252. #ifdef CHANGE_COLOR
1253. 	if (match_optname(opts, "palette", 3, TRUE)
1254. # ifdef MAC
1255. 	    || match_optname(opts, "hicolor", 3, TRUE)
1256. # endif
1257. 							) {
1258. 	    int color_number, color_incr;
1259. 
1260. # ifdef MAC
1261. 	    if (match_optname(opts, "hicolor", 3, TRUE)) {
1262. 		if (negated) {
1263. 		    bad_negation("hicolor", FALSE);
1264. 		    return;
1265. 		}
1266. 		color_number = CLR_MAX + 4;	/* HARDCODED inverse number */
1267. 		color_incr = -1;
1268. 	    } else {
1269. # endif
1270. 		if (negated) {
1271. 		    bad_negation("palette", FALSE);
1272. 		    return;
1273. 		}
1274. 		color_number = 0;
1275. 		color_incr = 1;
1276. # ifdef MAC
1277. 	    }
1278. # endif
1279. 	    if ((op = string_for_opt(opts, FALSE)) != (char *)0) {
1280. 		char *pt = op;
1281. 		int cnt, tmp, reverse;
1282. 		long rgb;
1283. 
1284. 		while (*pt && color_number >= 0) {
1285. 		    cnt = 3;
1286. 		    rgb = 0L;
1287. 		    if (*pt == '-') {
1288. 			reverse = 1;
1289. 			pt++;
1290. 		    } else {
1291. 			reverse = 0;
1292. 		    }
1293. 		    while (cnt-- > 0) {
1294. 			if (*pt && *pt != '/') {
1295. # ifdef AMIGA
1296. 			    rgb <<= 4;
1297. # else
1298. 			    rgb <<= 8;
1299. # endif
1300. 			    tmp = *(pt++);
1301. 			    if (isalpha(tmp)) {
1302. 				tmp = (tmp + 9) & 0xf;	/* Assumes ASCII... */
1303. 			    } else {
1304. 				tmp &= 0xf;	/* Digits in ASCII too... */
1305. 			    }
1306. # ifndef AMIGA
1307. 			    /* Add an extra so we fill f -> ff and 0 -> 00 */
1308. 			    rgb += tmp << 4;
1309. # endif
1310. 			    rgb += tmp;
1311. 			}
1312. 		    }
1313. 		    if (*pt == '/') {
1314. 			pt++;
1315. 		    }
1316. 		    change_color(color_number, rgb, reverse);
1317. 		    color_number += color_incr;
1318. 		}
1319. 	    }
1320. 	    if (!initial) {
1321. 		need_redraw = TRUE;
1322. 	    }
1323. 	    return;
1324. 	}
1325. #endif /* CHANGE_COLOR */
1326. 
1327. 	if (match_optname(opts, "fruit", 2, TRUE)) {
1328. 		char empty_str = '\0';
1329. 		op = string_for_opt(opts, negated);
1330. 		if (negated) {
1331. 		    if (op) {
1332. 			bad_negation("fruit", TRUE);
1333. 			return;
1334. 		    }
1335. 		    op = &empty_str;
1336. 		    goto goodfruit;
1337. 		}
1338. 		if (!op) return;
1339. 		if (!initial) {
1340. 		    struct fruit *f;
1341. 
1342. 		    num = 0;
1343. 		    for(f=ffruit; f; f=f->nextf) {
1344. 			if (!strcmp(op, f->fname)) goto goodfruit;
1345. 			num++;
1346. 		    }
1347. 		    if (num >= 100) {
1348. 			pline("Doing that so many times isn't very fruitful.");
1349. 			return;
1350. 		    }
1351. 		}
1352. goodfruit:
1353. 		nmcpy(pl_fruit, op, PL_FSIZ);
1354. 	/* OBJ_NAME(objects[SLIME_MOLD]) won't work after initialization */
1355. 		if (!*pl_fruit)
1356. 		    nmcpy(pl_fruit, "slime mold", PL_FSIZ);
1357. 		if (!initial)
1358. 		    (void)fruitadd(pl_fruit);
1359. 		/* If initial, then initoptions is allowed to do it instead
1360. 		 * of here (initoptions always has to do it even if there's
1361. 		 * no fruit option at all.  Also, we don't want people
1362. 		 * setting multiple fruits in their options.)
1363. 		 */
1364. 		return;
1365. 	}
1366. 
1367. 	/* graphics:string */
1368. 	fullname = "graphics";
1369. 	if (match_optname(opts, fullname, 2, TRUE)) {
1370. 		if (negated) bad_negation(fullname, FALSE);
1371. 		else graphics_opts(opts, fullname, MAXPCHARS, 0);
1372. 		return;
1373. 	}
1374. 	fullname = "dungeon";
1375. 	if (match_optname(opts, fullname, 2, TRUE)) {
1376. 		if (negated) bad_negation(fullname, FALSE);
1377. 		else graphics_opts(opts, fullname, MAXDCHARS, 0);
1378. 		return;
1379. 	}
1380. 	fullname = "traps";
1381. 	if (match_optname(opts, fullname, 2, TRUE)) {
1382. 		if (negated) bad_negation(fullname, FALSE);
1383. 		else graphics_opts(opts, fullname, MAXTCHARS, MAXDCHARS);
1384. 		return;
1385. 	}
1386. 	fullname = "effects";
1387. 	if (match_optname(opts, fullname, 2, TRUE)) {
1388. 		if (negated) bad_negation(fullname, FALSE);
1389. 		else
1390. 		 graphics_opts(opts, fullname, MAXECHARS, MAXDCHARS+MAXTCHARS);
1391. 		return;
1392. 	}
1393. 
1394. 	/* objects:string */
1395. 	fullname = "objects";
1396. 	if (match_optname(opts, fullname, 7, TRUE)) {
1397. 		int length;
1398. 
1399. 		if (negated) {
1400. 		    bad_negation(fullname, FALSE);
1401. 		    return;
1402. 		}
1403. 		if (!(opts = string_for_env_opt(fullname, opts, FALSE)))
1404. 			return;
1405. 		escapes(opts, opts);
1406. 
1407. 		/*
1408. 		 * Override the default object class symbols.  The first
1409. 		 * object in the object class is the "random object".  I
1410. 		 * don't want to use 0 as an object class, so the "random
1411. 		 * object" is basically a place holder.
1412. 		 *
1413. 		 * The object class symbols have already been initialized in
1414. 		 * initoptions().
1415. 		 */
1416. 		length = strlen(opts);
1417. 		if (length >= MAXOCLASSES)
1418. 		    length = MAXOCLASSES-1;	/* don't count RANDOM_OBJECT */
1419. 
1420. 		for (i = 0; i < length; i++)
1421. 		    oc_syms[i+1] = (uchar) opts[i];
1422. 		return;
1423. 	}
1424. 
1425. 	/* monsters:string */
1426. 	fullname = "monsters";
1427. 	if (match_optname(opts, fullname, 8, TRUE)) {
1428. 		int length;
1429. 
1430. 		if (negated) {
1431. 		    bad_negation(fullname, FALSE);
1432. 		    return;
1433. 		}
1434. 		if (!(opts = string_for_env_opt(fullname, opts, FALSE)))
1435. 			return;
1436. 		escapes(opts, opts);
1437. 
1438. 		/* Override default mon class symbols set in initoptions(). */
1439. 		length = strlen(opts);
1440. 		if (length >= MAXMCLASSES)
1441. 		    length = MAXMCLASSES-1;	/* mon class 0 unused */
1442. 
1443. 		for (i = 0; i < length; i++)
1444. 		    monsyms[i+1] = (uchar) opts[i];
1445. 		return;
1446. 	}
1447. 	fullname = "warnings";
1448. 	if (match_optname(opts, fullname, 5, TRUE)) {
1449. 		if (negated) bad_negation(fullname, FALSE);
1450. 		else warning_opts(opts, fullname);
1451. 		return;
1452. 	}
1453. 	/* boulder:symbol */
1454. 	fullname = "boulder";
1455. 	if (match_optname(opts, fullname, 7, TRUE)) {
1456. 		int clash = 0;
1457. 		if (negated) {
1458. 		    bad_negation(fullname, FALSE);
1459. 		    return;
1460. 		}
1461. /*		if (!(opts = string_for_env_opt(fullname, opts, FALSE))) */
1462. 		if (!(opts = string_for_opt(opts, FALSE)))
1463. 			return;
1464. 		escapes(opts, opts);
1465. 		if (def_char_to_monclass(opts[0]) != MAXMCLASSES)
1466. 			clash = 1;
1467. 		else if (opts[0] >= '1' && opts[0] <= '5')
1468. 			clash = 2;
1469. 		if (clash) {
1470. 			/* symbol chosen matches a used monster or warning
1471. 			   symbol which is not good - reject it*/
1472. 			pline(
1473. 		  "Badoption - boulder symbol '%c' conflicts with a %s symbol.",
1474. 				opts[0], (clash == 1) ? "monster" : "warning");
1475. 		} else {
1476. 			/*
1477. 			 * Override the default boulder symbol.
1478. 			 */
1479. 			iflags.bouldersym = (uchar) opts[0];
1480. 		}
1481. 		if (!initial) need_redraw = TRUE;
1482. 		return;
1483. 	}
1484. 
1485. 	/* name:string */
1486. 	fullname = "name";
1487. 	if (match_optname(opts, fullname, 4, TRUE)) {
1488. 		if (negated) bad_negation(fullname, FALSE);
1489. 		else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0)
1490. 			nmcpy(plname, op, PL_NSIZ);
1491. 		return;
1492. 	}
1493. 
1494. 	/* role:string or character:string */
1495. 	fullname = "role";
1496. 	if (match_optname(opts, fullname, 4, TRUE) ||
1497. 	    match_optname(opts, (fullname = "character"), 4, TRUE)) {
1498. 		if (negated) bad_negation(fullname, FALSE);
1499. 		else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
1500. 			if ((flags.initrole = str2role(op)) == ROLE_NONE)
1501. 				badoption(opts);
1502. 			else  /* Backwards compatibility */
1503. 				nmcpy(pl_character, op, PL_NSIZ);
1504. 		}
1505. 		return;
1506. 	}
1507. 
1508. 	/* race:string */
1509. 	fullname = "race";
1510. 	if (match_optname(opts, fullname, 4, TRUE)) {
1511. 		if (negated) bad_negation(fullname, FALSE);
1512. 		else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
1513. 			if ((flags.initrace = str2race(op)) == ROLE_NONE)
1514. 				badoption(opts);
1515. 			else /* Backwards compatibility */
1516. 				pl_race = *op;
1517. 		}
1518. 		return;
1519. 	}
1520. 
1521. 	/* gender:string */
1522. 	fullname = "gender";
1523. 	if (match_optname(opts, fullname, 4, TRUE)) {
1524. 		if (negated) bad_negation(fullname, FALSE);
1525. 		else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
1526. 			if ((flags.initgend = str2gend(op)) == ROLE_NONE)
1527. 				badoption(opts);
1528. 			else
1529. 				flags.female = flags.initgend;
1530. 		}
1531. 		return;
1532. 	}
1533. 
1534. 	/* altkeyhandler:string */
1535. 	fullname = "altkeyhandler";
1536. 	if (match_optname(opts, fullname, 4, TRUE)) {
1537. 		if (negated) bad_negation(fullname, FALSE);
1538. 		else if ((op = string_for_opt(opts, negated))) {
1539. #ifdef WIN32CON
1540. 		    (void)strncpy(iflags.altkeyhandler, op, MAX_ALTKEYHANDLER - 5);
1541. 		    load_keyboard_handler();
1542. #endif
1543. 		}
1544. 		return;
1545. 	}
1546. 
1547. 	/* WINCAP
1548. 	 * align_status:[left|top|right|bottom] */
1549. 	fullname = "align_status";
1550. 	if (match_optname(opts, fullname, sizeof("align_status")-1, TRUE)) {
1551. 		op = string_for_opt(opts, negated);
1552. 		if (op && !negated) {
1553. 		    if (!strncmpi (op, "left", sizeof("left")-1))
1554. 			iflags.wc_align_status = ALIGN_LEFT;
1555. 		    else if (!strncmpi (op, "top", sizeof("top")-1))
1556. 			iflags.wc_align_status = ALIGN_TOP;
1557. 		    else if (!strncmpi (op, "right", sizeof("right")-1))
1558. 			iflags.wc_align_status = ALIGN_RIGHT;
1559. 		    else if (!strncmpi (op, "bottom", sizeof("bottom")-1))
1560. 			iflags.wc_align_status = ALIGN_BOTTOM;
1561. 		    else
1562. 			badoption(opts);
1563. 		} else if (negated) bad_negation(fullname, TRUE);
1564. 		return;
1565. 	}
1566. 	/* WINCAP
1567. 	 * align_message:[left|top|right|bottom] */
1568. 	fullname = "align_message";
1569. 	if (match_optname(opts, fullname, sizeof("align_message")-1, TRUE)) {
1570. 		op = string_for_opt(opts, negated);
1571. 		if (op && !negated) {
1572. 		    if (!strncmpi (op, "left", sizeof("left")-1))
1573. 			iflags.wc_align_message = ALIGN_LEFT;
1574. 		    else if (!strncmpi (op, "top", sizeof("top")-1))
1575. 			iflags.wc_align_message = ALIGN_TOP;
1576. 		    else if (!strncmpi (op, "right", sizeof("right")-1))
1577. 			iflags.wc_align_message = ALIGN_RIGHT;
1578. 		    else if (!strncmpi (op, "bottom", sizeof("bottom")-1))
1579. 			iflags.wc_align_message = ALIGN_BOTTOM;
1580. 		    else
1581. 			badoption(opts);
1582. 		} else if (negated) bad_negation(fullname, TRUE);
1583. 		return;
1584. 	}
1585. 	/* align:string */
1586. 	fullname = "align";
1587. 	if (match_optname(opts, fullname, sizeof("align")-1, TRUE)) {
1588. 		if (negated) bad_negation(fullname, FALSE);
1589. 		else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0)
1590. 			if ((flags.initalign = str2align(op)) == ROLE_NONE)
1591. 				badoption(opts);
1592. 		return;
1593. 	}
1594. 
1595. 	/* the order to list the pack */
1596. 	fullname = "packorder";
1597. 	if (match_optname(opts, fullname, 4, TRUE)) {
1598. 		if (negated) {
1599. 		    bad_negation(fullname, FALSE);
1600. 		    return;
1601. 		} else if (!(op = string_for_opt(opts, FALSE))) return;
1602. 
1603. 		if (!change_inv_order(op))
1604. 			badoption(opts);
1605. 		return;
1606. 	}
1607. 
1608. 	/* maximum burden picked up before prompt (Warren Cheung) */
1609. 	fullname = "pickup_burden";
1610. 	if (match_optname(opts, fullname, 8, TRUE)) {
1611. 		if (negated) {
1612. 			bad_negation(fullname, FALSE);
1613. 			return;
1614. 		} else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
1615. 		    switch (tolower(*op)) {
1616. 				/* Unencumbered */
1617. 				case 'u':
1618. 					flags.pickup_burden = UNENCUMBERED;
1619. 					break;
1620. 				/* Burdened (slight encumbrance) */
1621. 				case 'b':
1622. 					flags.pickup_burden = SLT_ENCUMBER;
1623. 					break;
1624. 				/* streSsed (moderate encumbrance) */
1625. 				case 's':
1626. 					flags.pickup_burden = MOD_ENCUMBER;
1627. 					break;
1628. 				/* straiNed (heavy encumbrance) */
1629. 				case 'n':
1630. 					flags.pickup_burden = HVY_ENCUMBER;
1631. 					break;
1632. 				/* OverTaxed (extreme encumbrance) */
1633. 				case 'o':
1634. 				case 't':
1635. 					flags.pickup_burden = EXT_ENCUMBER;
1636. 					break;
1637. 				/* overLoaded */
1638. 				case 'l':
1639. 					flags.pickup_burden = OVERLOADED;
1640. 					break;
1641. 				default:
1642. 				badoption(opts);
1643. 		    }
1644. 		}
1645. 		return;
1646. 	}
1647. 
1648. 	/* types of objects to pick up automatically */
1649. 	if (match_optname(opts, "pickup_types", 8, TRUE)) {
1650. 		char ocl[MAXOCLASSES + 1], tbuf[MAXOCLASSES + 1],
1651. 		     qbuf[QBUFSZ], abuf[BUFSZ];
1652. 		int oc_sym;
1653. 		boolean badopt = FALSE, compat = (strlen(opts) <= 6), use_menu;
1654. 
1655. 		oc_to_str(flags.pickup_types, tbuf);
1656. 		flags.pickup_types[0] = '\0';	/* all */
1657. 		op = string_for_opt(opts, (compat || !initial));
1658. 		if (!op) {
1659. 		    if (compat || negated || initial) {
1660. 			/* for backwards compatibility, "pickup" without a
1661. 			   value is a synonym for autopickup of all types
1662. 			   (and during initialization, we can't prompt yet) */
1663. 			flags.pickup = !negated;
1664. 			return;
1665. 		    }
1666. 		    oc_to_str(flags.inv_order, ocl);
1667. 		    use_menu = TRUE;
1668. 		    if (flags.menu_style == MENU_TRADITIONAL ||
1669. 			    flags.menu_style == MENU_COMBINATION) {
1670. 			use_menu = FALSE;
1671. 			Sprintf(qbuf, "New pickup_types: [%s am] (%s)",
1672. 				ocl, *tbuf ? tbuf : "all");
1673. 			getlin(qbuf, abuf);
1674. 			op = mungspaces(abuf);
1675. 			if (abuf[0] == '\0' || abuf[0] == '\033')
1676. 			    op = tbuf;		/* restore */
1677. 			else if (abuf[0] == 'm')
1678. 			    use_menu = TRUE;
1679. 		    }
1680. 		    if (use_menu) {
1681. 			(void) choose_classes_menu("Auto-Pickup what?", 1,
1682. 						   TRUE, ocl, tbuf);
1683. 			op = tbuf;
1684. 		    }
1685. 		}
1686. 		if (negated) {
1687. 		    bad_negation("pickup_types", TRUE);
1688. 		    return;
1689. 		}