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. */
5 #ifdef OPTION_LISTS_ONLY /* (AMIGA) external program for opt lists */
9 NEARDATA
struct flag flags
; /* provide linkage */
10 NEARDATA
struct instance_flags iflags
; /* provide linkage */
18 #if defined(GL_GRAPHICS) || defined(SDL_GRAPHICS)
19 #include "winGL.h" /* Sdlgl_parse_options */
26 #ifdef DEFAULT_WC_TILED_MAP
27 #define PREFER_TILED TRUE
29 #define PREFER_TILED FALSE
32 #ifdef CURSES_GRAPHICS
33 extern int curses_read_attrs(char *attrs
);
37 * NOTE: If you add (or delete) an option, please update the short
38 * options help (option_help()), the long options help (dat/opthelp),
39 * and the current options setting display function (doset()),
40 * and also the Guidebooks.
42 * The order matters. If an option is a an initial substring of another
43 * option (e.g. time and timed_delay) the shorter one must come first.
46 static struct Bool_Opt
49 boolean
*addr
, initvalue
;
53 {"alphabet_inv", &flags
.alphabetinv
, FALSE
, SET_IN_FILE
},
56 {"altmeta", &flags
.altmeta
, TRUE
, DISP_IN_GAME
},
58 {"altmeta", (boolean
*)0, TRUE
, DISP_IN_GAME
},
60 {"ascii_map", &iflags
.wc_ascii_map
, !PREFER_TILED
, SET_IN_GAME
}, /*WC*/
62 {"asksavedisk", &flags
.asksavedisk
, FALSE
, SET_IN_GAME
},
64 {"asksavedisk", (boolean
*)0, FALSE
, SET_IN_GAME
},
66 {"autodig", &flags
.autodig
, FALSE
, SET_IN_GAME
},
68 {"autopickup", &flags
.pickup
, FALSE
, SET_IN_GAME
},
70 {"autoopen", &iflags
.autoopen
, TRUE
, SET_IN_GAME
},
71 #endif /* AUTO_OPEN */
72 {"autoquiver", &flags
.autoquiver
, FALSE
, SET_IN_GAME
},
74 {"bash_reminder", &flags
.bash_reminder
, TRUE
, SET_IN_GAME
},
76 #if defined(MICRO) && !defined(AMIGA)
77 {"BIOS", &iflags
.BIOS
, FALSE
, SET_IN_FILE
},
79 {"BIOS", (boolean
*)0, FALSE
, SET_IN_FILE
},
81 {"bones", &iflags
.bones
, TRUE
, SET_IN_FILE
},
83 {"checkpoint", &flags
.ins_chkpt
, TRUE
, SET_IN_GAME
},
85 {"checkpoint", (boolean
*)0, FALSE
, SET_IN_FILE
},
88 {"checkspace", &iflags
.checkspace
, TRUE
, SET_IN_GAME
},
90 {"checkspace", (boolean
*)0, FALSE
, SET_IN_FILE
},
92 {"cmdassist", &iflags
.cmdassist
, TRUE
, SET_IN_GAME
},
93 # if defined(MICRO) || defined(WIN32) || defined(UNIX) || defined(CURSES_GRAPHICS)
94 {"color", &iflags
.wc_color
,TRUE
, SET_IN_GAME
}, /*WC*/
95 # else /* systems that support multiple terminals, many monochrome */
96 {"color", &iflags
.wc_color
, FALSE
, SET_IN_GAME
}, /*WC*/
99 {"contentwarning", &flags
.contentwarning
, TRUE
, SET_IN_FILE
},
101 {"confirm",&flags
.confirm
, TRUE
, SET_IN_GAME
},
102 #ifdef CURSES_GRAPHICS
103 {"classic_status", &iflags
.classic_status
, TRUE
, SET_IN_GAME
},
104 {"cursesgraphics", &iflags
.cursesgraphics
, TRUE
, SET_IN_GAME
},
106 {"classic_status", (boolean
*)0, TRUE
, SET_IN_FILE
},
107 {"cursesgraphics", (boolean
*)0, FALSE
, SET_IN_FILE
},
109 #ifndef PUBLIC_SERVER
110 {"death_explore", &iflags
.death_expl
, TRUE
, SET_IN_GAME
},
112 #if defined(TERMLIB) && !defined(MAC_GRAPHICS_ENV)
113 {"DECgraphics", &iflags
.DECgraphics
, FALSE
, SET_IN_GAME
},
115 {"DECgraphics", (boolean
*)0, FALSE
, SET_IN_FILE
},
117 {"eatingboulders", &flags
.eatingboulders
, TRUE
, SET_IN_GAME
},
118 {"eatingconfirm", &flags
.eatingconfirm
, FALSE
, SET_IN_GAME
},
119 {"eatingdoors", &flags
.eatingdoors
, TRUE
, SET_IN_GAME
},
120 {"eatingwalls", &flags
.eatingwalls
, TRUE
, SET_IN_GAME
},
121 {"eight_bit_tty", &iflags
.wc_eight_bit_input
, FALSE
, SET_IN_GAME
}, /*WC*/
122 {"epyxmode", &flags
.epyxmode
, TRUE
, SET_IN_GAME
},
123 #if defined(TTY_GRAPHICS) || defined(CURSES_GRAPIHCS)
124 {"extmenu", &iflags
.extmenu
, FALSE
, SET_IN_GAME
},
126 {"extmenu", (boolean
*)0, FALSE
, SET_IN_FILE
},
129 {"fast_map", &flags
.fast_map
, TRUE
, SET_IN_GAME
},
131 {"fast_map", (boolean
*)0, TRUE
, SET_IN_FILE
},
133 {"female", &flags
.female
, FALSE
, DISP_IN_GAME
},
134 {"fixinv", &flags
.invlet_constant
, TRUE
, SET_IN_FILE
},
136 {"flush", &flags
.amiflush
, FALSE
, SET_IN_GAME
},
138 {"flush", (boolean
*)0, FALSE
, SET_IN_FILE
},
140 {"fullscreen", &iflags
.wc2_fullscreen
, FALSE
, SET_IN_FILE
},
141 {"gmmessage", &flags
.gmmessage
, TRUE
, SET_IN_GAME
},
142 {"graffitihilite", &flags
.graffitihilite
, TRUE
, SET_IN_GAME
},
143 {"guicolor", &iflags
.wc2_guicolor
, TRUE
, SET_IN_GAME
},
144 {"help", &flags
.help
, TRUE
, SET_IN_GAME
},
145 {"hilite_pet", &iflags
.wc_hilite_pet
, TRUE
, SET_IN_GAME
}, /*WC*/
146 {"hitpointbar", &flags
.hitpointbar
, TRUE
, SET_IN_GAME
},
148 {"IBMgraphics", &iflags
.IBMgraphics
, FALSE
, SET_IN_GAME
},
150 {"IBMgraphics", (boolean
*)0, FALSE
, SET_IN_FILE
},
153 {"ignintr", &flags
.ignintr
, FALSE
, SET_IN_GAME
},
155 {"ignintr", (boolean
*)0, FALSE
, SET_IN_FILE
},
157 {"inertiaconfirm", &flags
.inertiaconfirm
, FALSE
, SET_IN_GAME
},
159 {"invweight", &flags
.invweight
, TRUE
, SET_IN_GAME
},
161 {"invweight", (boolean
*)0, FALSE
, SET_IN_FILE
},
163 /*WAC the keep savefile option...*/
165 {"keep_savefile", &flags
.keep_savefile
, FALSE
, SET_IN_FILE
},
167 {"keep_savefile", (boolean
*)0, FALSE
, DISP_IN_GAME
},
169 {"knapsacklimit", &flags
.knapsacklimit
, FALSE
, SET_IN_GAME
},
171 {"large_font", &iflags
.obsolete
, FALSE
, SET_IN_FILE
}, /* OBSOLETE */
172 {"legacy", &flags
.legacy
, TRUE
, DISP_IN_GAME
},
173 {"lit_corridor", &flags
.lit_corridor
, TRUE
, SET_IN_GAME
},
174 {"lootabc", &iflags
.lootabc
, FALSE
, SET_IN_GAME
},
175 #ifdef MAC_GRAPHICS_ENV
176 {"Macgraphics", &iflags
.MACgraphics
, TRUE
, SET_IN_GAME
},
178 {"Macgraphics", (boolean
*)0, FALSE
, SET_IN_FILE
},
181 {"mail", &flags
.biff
, TRUE
, SET_IN_GAME
},
183 {"mail", (boolean
*)0, TRUE
, SET_IN_FILE
},
186 {"materialglyph", &flags
.materialglyph
, FALSE
, SET_IN_GAME
},
188 {"memorizationknown", &iflags
.memorizationknown
, FALSE
, SET_IN_GAME
},
190 #if defined(STATUS_COLORS) && defined(TEXTCOLOR)
191 {"statuscolors", &iflags
.use_status_colors
, TRUE
, SET_IN_GAME
},
193 {"statuscolors", (boolean
*)0, TRUE
, SET_IN_GAME
},
197 {"menucolors", &iflags
.use_menu_color
, TRUE
, SET_IN_GAME
},
199 {"menucolors", &iflags
.use_menu_color
, FALSE
, SET_IN_GAME
},
202 {"menucolors", (boolean
*)0, FALSE
, SET_IN_GAME
},
204 /* Not supported in tty at the moment (hence SET_IN_FILE), but curses has it */
205 {"menu_on_esc", &flags
.menu_on_esc
, TRUE
, SET_IN_GAME
},
206 {"menu_glyphs", &iflags
.use_menu_glyphs
, FALSE
, SET_IN_GAME
},
208 /* for menu debugging only*/
209 {"menu_tab_sep", &iflags
.menu_tab_sep
, FALSE
, SET_IN_GAME
},
211 {"menu_tab_sep", (boolean
*)0, FALSE
, SET_IN_FILE
},
214 {"missing_safety", &flags
.missing_safety
, TRUE
, SET_IN_GAME
},
217 {"mon_polycontrol", &iflags
.mon_polycontrol
, FALSE
, SET_IN_GAME
},
219 {"mon_polycontrol", (boolean
*)0, FALSE
, SET_IN_FILE
},
222 {"moreforced", &flags
.moreforced
, TRUE
, SET_IN_GAME
},
224 #ifdef CURSES_GRAPHICS
225 {"mouse_support", &iflags
.wc_mouse_support
, FALSE
, DISP_IN_GAME
}, /*WC*/
227 {"mouse_support", &iflags
.wc_mouse_support
, TRUE
, DISP_IN_GAME
}, /*WC*/
230 {"news", &iflags
.news
, TRUE
, DISP_IN_GAME
},
232 {"news", (boolean
*)0, FALSE
, SET_IN_FILE
},
234 {"numpadmessage", &iflags
.numpadmessage
, TRUE
, SET_IN_GAME
},
235 {"null", &flags
.null
, TRUE
, SET_IN_GAME
},
237 {"page_wait", &flags
.page_wait
, TRUE
, SET_IN_GAME
},
239 {"page_wait", (boolean
*)0, FALSE
, SET_IN_FILE
},
241 {"paranoidquit", &flags
.paranoidquit
, TRUE
, SET_IN_GAME
},
242 {"perm_invent", &flags
.perm_invent
, TRUE
, SET_IN_GAME
},
243 {"pickup_thrown", &flags
.pickup_thrown
, TRUE
, SET_IN_GAME
},
244 {"pickup_cursed", &flags
.pickup_cursed
, FALSE
, SET_IN_GAME
},
246 {"pokedex", &flags
.pokedex
, TRUE
, SET_IN_GAME
},
248 {"popup_dialog", &iflags
.wc_popup_dialog
, TRUE
, SET_IN_GAME
}, /*WC*/
249 {"prayconfirm", &flags
.prayconfirm
, TRUE
, SET_IN_GAME
},
250 {"preload_tiles", &iflags
.wc_preload_tiles
, TRUE
, DISP_IN_GAME
}, /*WC*/
251 {"pushweapon", &flags
.pushweapon
, FALSE
, SET_IN_GAME
},
252 {"quiver_fired", &iflags
.quiver_fired
, FALSE
, SET_IN_GAME
},
253 {"qwertz_layout", &iflags
.qwertz_layout
, FALSE
, SET_IN_GAME
},
254 {"radar", (boolean
*)0, FALSE
, SET_IN_FILE
}, /* OBSOLETE */
255 #if defined(MICRO) && !defined(AMIGA)
256 {"rawio", &iflags
.rawio
, FALSE
, DISP_IN_GAME
},
258 {"rawio", (boolean
*)0, FALSE
, SET_IN_FILE
},
260 {"rest_on_space", &flags
.rest_on_space
, FALSE
, SET_IN_GAME
},
261 {"safe_pet", &flags
.safe_dog
, TRUE
, SET_IN_GAME
},
262 #if defined(OBJ_SANITY)
263 {"sanity_check", &iflags
.sanity_check
, TRUE
, SET_IN_GAME
},
264 #elif defined(WIZARD)
265 {"sanity_check", &iflags
.sanity_check
, FALSE
, SET_IN_GAME
},
267 {"sanity_check", (boolean
*)0, FALSE
, SET_IN_FILE
},
269 {"should_change_color", &iflags
.should_change_color
, TRUE
, SET_IN_FILE
},
270 {"showexp", &flags
.showexp
, FALSE
, SET_IN_GAME
},
271 {"showrace", &iflags
.showrace
, FALSE
, SET_IN_GAME
},
272 #ifdef REALTIME_ON_BOTL
273 {"showrealtime", &iflags
.showrealtime
, FALSE
, SET_IN_GAME
},
275 {"showscore", &flags
.showscore
, FALSE
, SET_IN_GAME
},
276 {"showsym", &iflags
.showsym
, TRUE
, SET_IN_GAME
},
277 /* WAC made the [ xx pts] dmg display optional */
279 {"showdmg", &flags
.showdmg
, TRUE
, SET_IN_GAME
},
281 {"showdmg", (boolean
*)0, FALSE
, SET_IN_FILE
},
284 {"showweight", &flags
.showweight
, FALSE
, SET_IN_GAME
},
286 {"showweight", (boolean
*)0, FALSE
, SET_IN_FILE
},
289 {"showmc", &flags
.showmc
, FALSE
, SET_IN_GAME
},
290 {"showmovement", &flags
.showmovement
, FALSE
, SET_IN_GAME
},
291 {"showlongstats", &flags
.showlongstats
, FALSE
, SET_IN_GAME
},
292 {"showsanity", &flags
.showsanity
, FALSE
, SET_IN_GAME
},
293 {"showsymbiotehp", &flags
.showsymbiotehp
, FALSE
, SET_IN_GAME
},
295 {"silent", &flags
.silent
, TRUE
, SET_IN_GAME
},
296 {"simpledescs", &flags
.simpledescs
, FALSE
, SET_IN_GAME
},
297 {"softkeyboard", &iflags
.wc2_softkeyboard
, FALSE
, SET_IN_FILE
},
298 {"sortpack", &flags
.sortpack
, TRUE
, SET_IN_GAME
},
299 {"sound", &flags
.soundok
, TRUE
, SET_IN_GAME
},
300 {"sparkle", &flags
.sparkle
, TRUE
, SET_IN_GAME
},
301 {"standout", &flags
.standout
, FALSE
, SET_IN_GAME
},
302 {"splash_screen", &iflags
.wc_splash_screen
, TRUE
, DISP_IN_GAME
}, /*WC*/
304 {"tabcursesconfirm", &flags
.tabcursesconfirm
, FALSE
, SET_IN_GAME
},
306 {"tech_description", &flags
.tech_description
, TRUE
, SET_IN_GAME
},
308 {"tiled_map", &iflags
.wc_tiled_map
, PREFER_TILED
, DISP_IN_GAME
}, /*WC*/
309 {"time", &flags
.time
, TRUE
, SET_IN_GAME
},
311 {"timed_autosave", &flags
.etimed_autosave
, TRUE
, SET_IN_GAME
},
312 {"quick_autosave", &flags
.xtimed_autosave
, FALSE
, SET_IN_GAME
},
314 {"tombstone",&flags
.tombstone
, TRUE
, SET_IN_GAME
},
315 {"toptenwin",&flags
.toptenwin
, FALSE
, SET_IN_GAME
},
316 {"travel", &iflags
.travelcmd
, TRUE
, SET_IN_GAME
},
318 {"use_inverse", &iflags
.wc_inverse
, TRUE
, SET_IN_GAME
}, /*WC*/
320 {"use_inverse", &iflags
.wc_inverse
, FALSE
, SET_IN_GAME
}, /*WC*/
322 {"verbose", &flags
.verbose
, TRUE
, SET_IN_GAME
},
323 {"wallglyph", &flags
.wallglyph
, TRUE
, SET_IN_GAME
},
324 {"winggraphics", &iflags
.winggraphics
, FALSE
, DISP_IN_GAME
},
325 {"wraptext", &iflags
.wc2_wraptext
, FALSE
, SET_IN_GAME
},
327 {"blindfox", &flags
.blindfox
, FALSE
, DISP_IN_GAME
},
328 {"dudley", &flags
.dudley
, FALSE
, DISP_IN_GAME
},
329 {"gehenna", &flags
.gehenna
, FALSE
, DISP_IN_GAME
},
330 {"hippie", &flags
.hippie
, FALSE
, DISP_IN_GAME
},
331 {"iwbtg", &flags
.iwbtg
, FALSE
, DISP_IN_GAME
},
332 {"elmstreet", &flags
.elmstreet
, FALSE
, DISP_IN_GAME
},
333 {"lostsoul", &flags
.lostsoul
, FALSE
, DISP_IN_GAME
},
334 {"uberlostsoul", &flags
.uberlostsoul
, FALSE
, DISP_IN_GAME
},
336 {"gmmode", &flags
.gmmode
, FALSE
, DISP_IN_GAME
},
337 {"supergmmode", &flags
.supergmmode
, FALSE
, DISP_IN_GAME
},
339 {"assholemode", &flags
.assholemode
, FALSE
, DISP_IN_GAME
},
340 {"wonderland", &flags
.wonderland
, FALSE
, DISP_IN_GAME
},
341 {"zapem", &flags
.zapem
, FALSE
, DISP_IN_GAME
},
343 {"askforalias", &flags
.askforalias
, FALSE
, DISP_IN_GAME
},
345 {"hybridangbander", &flags
.hybridangbander
, FALSE
, SET_IN_FILE
},
346 {"hybridaquarian", &flags
.hybridaquarian
, FALSE
, SET_IN_FILE
},
347 {"hybridcurser", &flags
.hybridcurser
, FALSE
, SET_IN_FILE
},
348 {"hybridhaxor", &flags
.hybridhaxor
, FALSE
, SET_IN_FILE
},
349 {"hybridhomicider", &flags
.hybridhomicider
, FALSE
, SET_IN_FILE
},
350 {"hybridsuxxor", &flags
.hybridsuxxor
, FALSE
, SET_IN_FILE
},
351 {"hybridwarper", &flags
.hybridwarper
, FALSE
, SET_IN_FILE
},
352 {"hybridrandomizer", &flags
.hybridrandomizer
, FALSE
, SET_IN_FILE
},
353 {"hybridnullrace", &flags
.hybridnullrace
, FALSE
, SET_IN_FILE
},
354 {"hybridmazewalker", &flags
.hybridmazewalker
, FALSE
, SET_IN_FILE
},
355 {"hybridsoviet", &flags
.hybridsoviet
, FALSE
, SET_IN_FILE
},
356 {"hybridxrace", &flags
.hybridxrace
, FALSE
, SET_IN_FILE
},
357 {"hybridheretic", &flags
.hybridheretic
, FALSE
, SET_IN_FILE
},
358 {"hybridsokosolver", &flags
.hybridsokosolver
, FALSE
, SET_IN_FILE
},
359 {"hybridspecialist", &flags
.hybridspecialist
, FALSE
, SET_IN_FILE
},
360 {"hybridamerican", &flags
.hybridamerican
, FALSE
, SET_IN_FILE
},
361 {"hybridminimalist", &flags
.hybridminimalist
, FALSE
, SET_IN_FILE
},
362 {"hybridnastinator", &flags
.hybridnastinator
, FALSE
, SET_IN_FILE
},
363 {"hybridrougelike", &flags
.hybridrougelike
, FALSE
, SET_IN_FILE
},
364 {"hybridsegfaulter", &flags
.hybridsegfaulter
, FALSE
, SET_IN_FILE
},
365 {"hybridironman", &flags
.hybridironman
, FALSE
, SET_IN_FILE
},
366 {"hybridamnesiac", &flags
.hybridamnesiac
, FALSE
, SET_IN_FILE
},
367 {"hybridproblematic", &flags
.hybridproblematic
, FALSE
, SET_IN_FILE
},
368 {"hybridwindinhabitant", &flags
.hybridwindinhabitant
, FALSE
, SET_IN_FILE
},
369 {"hybridaggravator", &flags
.hybridaggravator
, FALSE
, SET_IN_FILE
},
370 {"hybridevilvariant", &flags
.hybridevilvariant
, FALSE
, SET_IN_FILE
},
371 {"hybridlevelscaler", &flags
.hybridlevelscaler
, FALSE
, SET_IN_FILE
},
372 {"hybriderosator", &flags
.hybriderosator
, FALSE
, SET_IN_FILE
},
373 {"hybridroommate", &flags
.hybridroommate
, FALSE
, SET_IN_FILE
},
374 {"hybridextravator", &flags
.hybridextravator
, FALSE
, SET_IN_FILE
},
375 {"hybridhallucinator", &flags
.hybridhallucinator
, FALSE
, SET_IN_FILE
},
376 {"hybridbossrusher", &flags
.hybridbossrusher
, FALSE
, SET_IN_FILE
},
377 {"hybriddorian", &flags
.hybriddorian
, FALSE
, SET_IN_FILE
},
378 {"hybridtechless", &flags
.hybridtechless
, FALSE
, SET_IN_FILE
},
379 {"hybridblait", &flags
.hybridblait
, FALSE
, SET_IN_FILE
},
380 {"hybridgrouper", &flags
.hybridgrouper
, FALSE
, SET_IN_FILE
},
381 {"hybridscriptor", &flags
.hybridscriptor
, FALSE
, SET_IN_FILE
},
382 {"hybridunbalancor", &flags
.hybridunbalancor
, FALSE
, SET_IN_FILE
},
383 {"hybridbeacher", &flags
.hybridbeacher
, FALSE
, SET_IN_FILE
},
384 {"hybridstairseeker", &flags
.hybridstairseeker
, FALSE
, SET_IN_FILE
},
385 {"hybridmatrayser", &flags
.hybridmatrayser
, FALSE
, SET_IN_FILE
},
386 {"hybridfeminizer", &flags
.hybridfeminizer
, FALSE
, SET_IN_FILE
},
387 {"hybridchallenger", &flags
.hybridchallenger
, FALSE
, SET_IN_FILE
},
388 {"hybridhardmoder", &flags
.hybridhardmoder
, FALSE
, SET_IN_FILE
},
389 {"hybridstunfish", &flags
.hybridstunfish
, FALSE
, SET_IN_FILE
},
390 {"hybridkillfiller", &flags
.hybridkillfiller
, FALSE
, SET_IN_FILE
},
391 {"hybridbadstatter", &flags
.hybridbadstatter
, FALSE
, SET_IN_FILE
},
392 {"hybriddroughter", &flags
.hybriddroughter
, FALSE
, SET_IN_FILE
},
393 {"hybridvanillaoid", &flags
.hybridvanillaoid
, FALSE
, SET_IN_FILE
},
395 {"randomhybrids", &flags
.randomhybrids
, TRUE
, DISP_IN_GAME
},
397 {(char *)0, (boolean
*)0, FALSE
, 0}
400 void * nh_option_get_boolopt()
402 return (void *)boolopt
;
405 /* compound options, for option_help() and external programs like Amiga
407 static struct Comp_Opt
409 const char *name
, *descr
;
410 int size
; /* for frontends and such allocating space --
411 * usually allowed size of data in game, but
412 * occasionally maximum reasonable size for
413 * typing when game maintains information in
414 * a different format */
417 { "align", "your starting alignment (lawful, neutral, or chaotic)",
419 { "align_message", "message window alignment", 20, DISP_IN_GAME
}, /*WC*/
420 { "align_status", "status window alignment", 20, DISP_IN_GAME
}, /*WC*/
421 { "altkeyhandler", "alternate key handler", 20, DISP_IN_GAME
},
422 { "boulder", "the symbol to use for displaying boulders",
424 { "catname", "the name of your (first) cat (e.g., catname:Tabby)",
425 PL_PSIZ
, DISP_IN_GAME
},
426 /* { "coinsname", "the name of your (first) pile of copper coins (e.g., coinsname:Dollars)",
427 PL_PSIZ, DISP_IN_GAME },*/
428 { "disclose", "the kinds of information to disclose at end of game",
429 sizeof(flags
.end_disclose
) * 2,
431 { "dogname", "the name of your (first) dog (e.g., dogname:Fang)",
432 PL_PSIZ
, DISP_IN_GAME
},
433 { "dragonname", "the name of your (first) dragon (e.g., dragonname:Wintersdotir)",
434 PL_PSIZ
, DISP_IN_GAME
},
435 { "monkeyname", "the name of your (first) monkey (e.g., monkeyname:DonkeyKong)",
436 PL_PSIZ
, DISP_IN_GAME
},
437 { "parrotname", "the name of your (first) parrot (e.g., parrotname:Polly)",
438 PL_PSIZ
, DISP_IN_GAME
},
439 { "girlname", "the name of your (first) girl (e.g., girlname:Sarah)",
440 PL_PSIZ
, DISP_IN_GAME
},
441 { "boyname", "the name of your (first) boy (e.g., boyname:Jonas)",
442 PL_PSIZ
, DISP_IN_GAME
},
443 { "ravenname", "the name of your (first) raven (e.g., ravenname:Nevermore)",
444 PL_PSIZ
, DISP_IN_GAME
},
446 { "dumpfile", "where to dump data (e.g., dumpfile:/tmp/dump.nh)",
448 PL_PSIZ
, DISP_IN_GAME
},
450 PL_PSIZ
, SET_IN_GAME
},
453 { "dungeon", "the symbols to use in drawing the dungeon map",
454 MAXDCHARS
+1, SET_IN_FILE
},
455 { "effects", "the symbols to use in drawing special effects",
456 MAXECHARS
+1, SET_IN_FILE
},
457 { "font_map", "the font to use in the map window", 40, DISP_IN_GAME
}, /*WC*/
458 { "font_menu", "the font to use in menus", 40, DISP_IN_GAME
}, /*WC*/
459 { "font_message", "the font to use in the message window",
460 40, DISP_IN_GAME
}, /*WC*/
461 { "font_size_map", "the size of the map font", 20, DISP_IN_GAME
}, /*WC*/
462 { "font_size_menu", "the size of the menu font", 20, DISP_IN_GAME
}, /*WC*/
463 { "font_size_message", "the size of the message font", 20, DISP_IN_GAME
}, /*WC*/
464 { "font_size_status", "the size of the status font", 20, DISP_IN_GAME
}, /*WC*/
465 { "font_size_text", "the size of the text font", 20, DISP_IN_GAME
}, /*WC*/
466 { "font_status", "the font to use in status window", 40, DISP_IN_GAME
}, /*WC*/
467 { "font_text", "the font to use in text windows", 40, DISP_IN_GAME
}, /*WC*/
468 { "fruit", "the name of a fruit you enjoy eating",
469 PL_FSIZ
, SET_IN_GAME
},
470 { "gender", "your starting gender (male or female)",
472 { "ghoulname", "the name of your (first) ghoul (e.g., ghoulname:Casper)",
473 PL_PSIZ
, DISP_IN_GAME
},
474 { "horsename", "the name of your (first) horse (e.g., horsename:Silver)",
475 PL_PSIZ
, DISP_IN_GAME
},
476 /* { "lichenname", "the name of your (first) lichen (e.g., lichenname:Fungus)",
477 PL_PSIZ, DISP_IN_GAME },*/
478 { "map_mode", "map display mode under Windows", 20, DISP_IN_GAME
}, /*WC*/
479 { "menucolor", "set menu colors", PL_PSIZ
, SET_IN_FILE
},
480 { "menustyle", "user interface for object selection",
481 MENUTYPELEN
, SET_IN_GAME
},
482 { "menu_deselect_all", "deselect all items in a menu", 4, SET_IN_FILE
},
483 { "menu_deselect_page", "deselect all items on this page of a menu",
485 { "menu_first_page", "jump to the first page in a menu",
487 { "menu_headings", "bold, inverse, or underline headings", 9, SET_IN_GAME
},
488 { "menu_invert_all", "invert all items in a menu", 4, SET_IN_FILE
},
489 { "menu_invert_page", "invert all items on this page of a menu",
491 { "menu_last_page", "jump to the last page in a menu", 4, SET_IN_FILE
},
492 { "menu_next_page", "goto the next menu page", 4, SET_IN_FILE
},
493 { "menu_previous_page", "goto the previous menu page", 4, SET_IN_FILE
},
494 { "menu_search", "search for a menu item", 4, SET_IN_FILE
},
495 { "menu_select_all", "select all items in a menu", 4, SET_IN_FILE
},
496 { "menu_select_page", "select all items on this page of a menu",
498 { "monsters", "the symbols to use for monsters",
499 MAXMCLASSES
, SET_IN_FILE
},
500 { "msghistory", "number of top line messages to save",
503 {"msg_window", "the type of message window required",1, SET_IN_GAME
},
505 {"msg_window", "the type of message window required", 1, SET_IN_FILE
},
507 { "name", "your character's name (e.g., name:Merlin-W)",
508 PL_NSIZ
, DISP_IN_GAME
},
509 { "number_pad", "use the number pad", 1, SET_IN_GAME
},
510 { "objects", "the symbols to use for objects",
511 MAXOCLASSES
, SET_IN_FILE
},
512 { "packorder", "the inventory order of the items in your pack",
513 MAXOCLASSES
, SET_IN_GAME
},
515 { "palette", "palette (00c/880/-fff is blue/yellow/reverse white)",
518 { "hicolor", "same as palette, only order is reversed",
522 { "petattr", "attributes for highlighting pets", 12, SET_IN_FILE
},
523 { "pettype", "your preferred initial pet type", 4, DISP_IN_GAME
},
524 { "pickup_burden", "maximum burden picked up before prompt",
526 { "pickup_types", "types of objects to pick up automatically",
527 MAXOCLASSES
, SET_IN_GAME
},
528 { "pilesize", "maximum number of items on floor to list automatically",
530 { "plalias", "your alias name",
531 PL_NSIZ
, DISP_IN_GAME
},
532 { "player_selection", "choose character via dialog or prompts",
534 { "race", "your starting race (e.g., Human, Elf)",
535 PL_CSIZ
, DISP_IN_GAME
},
536 { "ratname", "the name of your (first) rat (e.g., ratname:Squeak)",
537 PL_PSIZ
, DISP_IN_GAME
},
538 { "role", "your starting role (e.g., Barbarian, Valkyrie)",
539 PL_CSIZ
, DISP_IN_GAME
},
540 /* { "rothename", "the name of your (first) rothe (e.g., rothename:Badger)",
541 PL_PSIZ, DISP_IN_GAME },*/
542 { "runmode", "display frequency when `running' or `travelling'",
543 sizeof "teleport", SET_IN_GAME
},
544 { "scores", "the parts of the score list you wish to see",
546 { "scroll_amount", "amount to scroll map when scroll_margin is reached",
547 20, DISP_IN_GAME
}, /*WC*/
548 { "scroll_margin", "scroll map when this far from the edge", 20, DISP_IN_GAME
}, /*WC*/
549 { "sortloot", "sort object selection lists by description", 4, SET_IN_GAME
},
551 { "soundcard", "type of sound card to use", 20, SET_IN_FILE
},
553 { "statuscolor", "set status colors", PL_PSIZ
, SET_IN_FILE
},
554 { "suppress_alert", "suppress alerts about version-specific features",
556 { "tile_width", "width of tiles", 20, DISP_IN_GAME
}, /*WC*/
557 { "tile_height", "height of tiles", 20, DISP_IN_GAME
}, /*WC*/
558 { "tile_file", "name of tile file", 70, DISP_IN_GAME
}, /*WC*/
559 { "tileset", "name of predefined tileset to use",
560 PL_PSIZ
, SET_IN_GAME
},
561 { "traps", "the symbols to use in drawing traps",
562 MAXTCHARS
+1, SET_IN_FILE
},
563 { "vary_msgcount", "show more old messages at a time", 20, DISP_IN_GAME
}, /*WC*/
565 { "video", "method of video updating", 20, SET_IN_FILE
},
568 { "videocolors", "color mappings for internal screen routines",
571 { "videoshades", "gray shades to map to black/gray/white",
576 {"subkeyvalue", "override keystroke value", 7, SET_IN_FILE
},
578 { "windowcolors", "the foreground/background colors of windows", /*WC*/
580 { "windowtype", "windowing system to use", WINTYPELEN
, DISP_IN_GAME
},
581 { "wolfname", "the name of your (first) wolf (e.g., wolfname:Beast)",
582 PL_PSIZ
, DISP_IN_GAME
},
583 { (char *)0, (char *)0, 0, 0 }
586 static struct Bool_Tile_Opt
590 unsigned long initvalue
;
592 {"transparent", TILESET_TRANSPARENT
, 0},
593 {"pseudo3D", TILESET_PSEUDO3D
, 0},
597 #ifdef OPTION_LISTS_ONLY
600 #else /* use rest of file */
602 static boolean need_redraw
; /* for doset() */
604 #if defined(TOS) && defined(TEXTCOLOR)
605 extern boolean colors_changed
; /* in tos.c */
609 extern char *shade
[3]; /* in sys/msdos/video.c */
610 extern char ttycolors
[CLR_MAX
]; /* in sys/msdos/video.c, win/tty/termcap.c*/
613 static char def_inv_order
[MAXOCLASSES
] = {
614 COIN_CLASS
, AMULET_CLASS
, IMPLANT_CLASS
, WEAPON_CLASS
, ARMOR_CLASS
, FOOD_CLASS
,
615 SCROLL_CLASS
, SPBOOK_CLASS
, POTION_CLASS
, RING_CLASS
, WAND_CLASS
,
616 TOOL_CLASS
, GEM_CLASS
, ROCK_CLASS
, BALL_CLASS
, CHAIN_CLASS
, VENOM_CLASS
, 0, 0,
620 * Default menu manipulation command accelerators. These may _not_ be:
622 * + a number - reserved for counts
623 * + an upper or lower case US ASCII letter - used for accelerators
624 * + ESC - reserved for escaping the menu
625 * + NULL, CR or LF - reserved for commiting the selection(s). NULL
626 * is kind of odd, but the tty's xwaitforspace() will return it if
627 * someone hits a <ret>.
628 * + a default object class symbol - used for object class accelerators
630 * Standard letters (for now) are:
643 * The command name list is duplicated in the compopt array.
650 #define NUM_MENU_CMDS 11
651 static const menu_cmd_t default_menu_cmd_info
[NUM_MENU_CMDS
] = {
652 /* 0*/ { "menu_first_page", MENU_FIRST_PAGE
},
653 { "menu_last_page", MENU_LAST_PAGE
},
654 { "menu_next_page", MENU_NEXT_PAGE
},
655 { "menu_previous_page", MENU_PREVIOUS_PAGE
},
656 { "menu_select_all", MENU_SELECT_ALL
},
657 /* 5*/ { "menu_deselect_all", MENU_UNSELECT_ALL
},
658 { "menu_invert_all", MENU_INVERT_ALL
},
659 { "menu_select_page", MENU_SELECT_PAGE
},
660 { "menu_deselect_page", MENU_UNSELECT_PAGE
},
661 { "menu_invert_page", MENU_INVERT_PAGE
},
662 /*10*/ { "menu_search", MENU_SEARCH
},
666 * Allow the user to map incoming characters to various menu commands.
667 * The accelerator list must be a valid C string.
669 #define MAX_MENU_MAPPED_CMDS 32 /* some number */
670 char mapped_menu_cmds
[MAX_MENU_MAPPED_CMDS
+1]; /* exported */
671 static char mapped_menu_op
[MAX_MENU_MAPPED_CMDS
+1];
672 static short n_menu_mapped
= 0;
674 static boolean initial
, from_file
;
676 STATIC_DCL
void doset_add_menu(winid
,const char *,int);
677 STATIC_DCL
void nmcpy(char *, const char *, int);
678 STATIC_DCL
void escapes(const char *, char *);
679 STATIC_DCL
void rejectoption(const char *);
680 STATIC_DCL
void badoption(const char *);
681 STATIC_OVL
void badtileoption(const char *);
682 STATIC_DCL
char *string_for_opt(char *,BOOLEAN_P
);
683 STATIC_OVL
char *string_for_tile_opt(char *, BOOLEAN_P
);
684 STATIC_DCL
char *string_for_env_opt(const char *, char *,BOOLEAN_P
);
685 STATIC_DCL
void bad_negation(const char *,BOOLEAN_P
);
686 STATIC_DCL
int change_inv_order(char *);
687 STATIC_DCL
void oc_to_str(char *, char *);
688 STATIC_DCL
void graphics_opts(char *,const char *,int,int);
689 STATIC_DCL
int feature_alert_opts(char *, const char *);
690 STATIC_DCL
const char *get_compopt_value(const char *, char *);
691 STATIC_DCL boolean
special_handling(const char *, BOOLEAN_P
, BOOLEAN_P
);
692 STATIC_DCL
void warning_opts(char *,const char *);
693 STATIC_DCL
void duplicate_opt_detection(const char *, int);
695 STATIC_OVL
void wc_set_font_name(int, char *);
696 STATIC_OVL
int wc_set_window_colors(char *);
697 STATIC_OVL boolean
is_wc_option(const char *);
698 STATIC_OVL boolean
wc_supported(const char *);
699 STATIC_OVL boolean
is_wc2_option(const char *);
700 STATIC_OVL boolean
wc2_supported(const char *);
701 #ifdef AUTOPICKUP_EXCEPTIONS
702 STATIC_DCL
void remove_autopickup_exception(struct autopickup_exception
*);
703 STATIC_OVL
int count_ape_maps(int *, int *);
706 /* check whether a user-supplied option string is a proper leading
707 substring of a particular option name; option string might have
708 a colon or equals sign and arbitrary value appended to it */
710 match_optname(user_string
, opt_name
, min_length
, val_allowed
)
711 const char *user_string
, *opt_name
;
715 int len
= (int)strlen(user_string
);
718 const char *p
= index(user_string
, ':'),
719 *q
= index(user_string
, '=');
721 if (!p
|| (q
&& q
< p
)) p
= q
;
722 while(p
&& p
> user_string
&& isspace(*(p
-1))) p
--;
723 if (p
) len
= (int)(p
- user_string
);
726 return (len
>= min_length
) && !strncmpi(opt_name
, user_string
, len
);
729 /* most environment variables will eventually be printed in an error
730 * message if they don't work, and most error message paths go through
731 * BUFSZ buffers, which could be overflowed by a maliciously long
732 * environment variable. if a variable can legitimately be long, or
733 * if it's put in a smaller buffer, the responsible code will have to
734 * bounds-check itself.
740 char *getev
= getenv(ev
);
742 if (getev
&& strlen(getev
) <= (BUFSZ
/ 2))
756 /* initialize the random number generator */
759 /* for detection of configfile options specified multiple times */
760 iflags
.opt_booldup
= iflags
.opt_compdup
= (int *)0;
762 for (i
= 0; boolopt
[i
].name
; i
++) {
764 *(boolopt
[i
].addr
) = boolopt
[i
].initvalue
;
766 flags
.end_own
= FALSE
;
768 flags
.end_around
= 2;
769 iflags
.runmode
= RUN_LEAP
;
770 iflags
.msg_history
= 20;
772 iflags
.prevmsg_window
= 's';
774 iflags
.menu_headings
= ATR_INVERSE
;
777 /* Use negative indices to indicate not yet selected */
781 flags
.initalign
= -1;
783 /* Set the default monster and object class symbols. Don't use */
784 /* memcpy() --- sizeof char != sizeof uchar on some machines. */
785 for (i
= 0; i
< MAXOCLASSES
; i
++)
786 oc_syms
[i
] = (uchar
) def_oc_syms
[i
];
787 for (i
= 0; i
< MAXMCLASSES
; i
++)
788 monsyms
[i
] = (uchar
) def_monsyms
[i
];
789 for (i
= 0; i
< WARNCOUNT
; i
++)
790 warnsyms
[i
] = def_warnsyms
[i
].sym
;
791 iflags
.bouldersym
= 0;
792 iflags
.travelcc
.x
= iflags
.travelcc
.y
= -1;
793 flags
.warnlevel
= /*1*/0;
796 /* assert( sizeof flags.inv_order == sizeof def_inv_order ); */
797 (void)memcpy((void *)flags
.inv_order
,
798 (void *)def_inv_order
, sizeof flags
.inv_order
);
799 flags
.pickup_types
[0] = '\0';
800 flags
.pickup_burden
= MOD_ENCUMBER
;
801 iflags
.sortloot
= 'n';
803 for (i
= 0; i
< NUM_DISCLOSURE_OPTIONS
; i
++)
804 flags
.end_disclose
[i
] = DISCLOSE_PROMPT_DEFAULT_NO
;
805 switch_graphics(ASCII_GRAPHICS
); /* set default characters */
806 #if defined(UNIX) && defined(TTY_GRAPHICS)
808 * Set defaults for some options depending on what we can
809 * detect about the environment's capabilities.
810 * This has to be done after the global initialization above
811 * and before reading user-specific initialization via
812 * config file/environment variable below.
814 /* this detects the IBM-compatible console on most 386 boxes */
815 if ((opts
= nh_getenv("TERM")) && !strncmp(opts
, "AT", 2)) {
816 switch_graphics(IBM_GRAPHICS
);
818 iflags
.use_color
= TRUE
;
821 #endif /* UNIX && TTY_GRAPHICS */
822 #if defined(UNIX) || defined(VMS)
824 /* detect whether a "vt" terminal can handle alternate charsets */
825 if ((opts
= nh_getenv("TERM")) &&
826 !strncmpi(opts
, "vt", 2) && AS
&& AE
&&
827 index(AS
, '\016') && index(AE
, '\017')) {
828 switch_graphics(DEC_GRAPHICS
);
831 #endif /* UNIX || VMS */
833 #ifdef MAC_GRAPHICS_ENV
834 switch_graphics(MAC_GRAPHICS
);
835 #endif /* MAC_GRAPHICS_ENV */
836 flags
.menu_style
= MENU_FULL
;
838 /* since this is done before init_objects(), do partial init here */
839 objects
[SLIME_MOLD
].oc_name_idx
= SLIME_MOLD
;
840 nmcpy(pl_fruit
, OBJ_NAME(objects
[SLIME_MOLD
]), PL_FSIZ
);
842 opts
= getenv(NETHACK_ENV_OPTIONS
);
843 if (!opts
) opts
= getenv("NETHACKOPTIONS");
844 if (!opts
) opts
= getenv("HACKOPTIONS");
846 if (*opts
== '/' || *opts
== '\\' || *opts
== '@') {
847 if (*opts
== '@') opts
++; /* @filename */
848 /* looks like a filename */
849 if (strlen(opts
) < BUFSZ
/2)
850 read_config_file(opts
);
852 read_config_file((char *)0);
853 /* let the total length of options be long;
854 * parseoptions() will check each individually
856 parseoptions(opts
, TRUE
, FALSE
);
860 read_config_file((char *)0);
862 (void)fruitadd(pl_fruit
);
863 /* Remove "slime mold" from list of object names; this will */
864 /* prevent it from being wished unless it's actually present */
865 /* as a named (or default) fruit. Wishing for "fruit" will */
866 /* result in the player's preferred fruit [better than "\033"]. */
867 obj_descr
[SLIME_MOLD
].oc_name
= "fruit";
869 if (flags
.lit_corridor
&& iflags
.use_color
) {
870 showsyms
[S_darkroom
]=showsyms
[S_room
];
872 showsyms
[S_darkroom
]=showsyms
[S_stone
];
875 #if defined(GL_GRAPHICS) || defined(SDL_GRAPHICS)
876 /* -AJA- SDL/GL support. Needs to happen after main config
877 * file has been read.
879 opts
= getenv(SDLGL_ENV_VAR
);
881 Sdlgl_parse_options(opts
, TRUE
, FALSE
);
888 nmcpy(dest
, src
, maxlen
)
895 for(count
= 1; count
< maxlen
; count
++) {
896 if(*src
== ',' || *src
== '\0') break; /*exit on \0 terminator*/
903 * escapes(): escape expansion for showsyms. C-style escapes understood
904 * include \n, \b, \t, \r, \xnnn (hex), \onnn (octal), \nnn (decimal).
905 * (Note: unlike in C, leading digit 0 is not used to indicate octal;
906 * the letter o (either upper or lower case) is used for that.
907 * The ^-prefix for control characters is also understood, and \[mM]
908 * has the effect of 'meta'-ing the value which follows (so that the
909 * alternate character set will be enabled).
915 * For 3.4.3 and earlier, input ending with "\M", backslash, or caret
916 * prior to terminating '\0' would pull that '\0' into the output and then
917 * keep processing past it, potentially overflowing the output buffer.
918 * Now, trailing \ or ^ will act like \\ or \^ and add '\\' or '^' to the
919 * output and stop there; trailing \M will fall through to \<other> and
920 * yield 'M', then stop. Any \X or \O followed by something other than
921 * an appropriate digit will also fall through to \<other> and yield 'X'
922 * or 'O', plus stop if the non-digit is end-of-string.
926 const char *cp
; /* might be 'tp', updating in place */
927 char *tp
; /* result is never longer than 'cp' */
929 static NEARDATA
const char oct
[] = "01234567", dec
[] = "0123456789",
930 hex
[] = "00112233445566778899aAbBcCdDeEfF";
932 int cval
, meta
, dcount
;
935 /* \M has to be followed by something to do meta conversion,
936 otherwise it will just be \M which ultimately yields 'M' */
937 meta
= (*cp
== '\\' && (cp
[1] == 'm' || cp
[1] == 'M') && cp
[2]);
941 cval
= dcount
= 0; /* for decimal, octal, hexadecimal cases */
942 if ((*cp
!= '\\' && *cp
!= '^') || !cp
[1]) {
943 /* simple character, or nothing left for \ or ^ to escape */
945 } else if (*cp
== '^') { /* expand control-character syntax */
946 cval
= (*++cp
& 0x1f);
949 /* remaining cases are all for backslash; we know cp[1] is not \0 */
950 } else if (index(dec
, cp
[1])) {
951 ++cp
; /* move past backslash to first digit */
953 cval
= (cval
* 10) + (*cp
- '0');
954 } while (*++cp
&& index(dec
, *cp
) && ++dcount
< 3);
955 } else if ((cp
[1] == 'o' || cp
[1] == 'O') && cp
[2]
956 && index(oct
, cp
[2])) {
957 cp
+= 2; /* move past backslash and 'O' */
959 cval
= (cval
* 8) + (*cp
- '0');
960 } while (*++cp
&& index(oct
, *cp
) && ++dcount
< 3);
961 } else if ((cp
[1] == 'x' || cp
[1] == 'X') && cp
[2]
962 && (dp
= index(hex
, cp
[2])) != 0) {
963 cp
+= 2; /* move past backslash and 'X' */
965 cval
= (cval
* 16) + ((int) (dp
- hex
) / 2);
966 } while (*++cp
&& (dp
= index(hex
, *cp
)) != 0 && ++dcount
< 2);
967 } else { /* C-style character escapes */
998 rejectoption(optname
)
1002 pline("\"%s\" settable only from %s.", optname
, configfile
);
1004 pline("%s can be set only from %s or %s.", optname
,
1005 NETHACK_ENV_OPTIONS
, configfile
);
1014 if (!strncmp(opts
, "h", 1) || !strncmp(opts
, "?", 1))
1017 pline("Bad syntax: %s. Enter \"?g\" for help.", opts
);
1025 raw_printf("Bad syntax in OPTIONS in %s: %s.", configfile
, opts
);
1027 raw_printf("Bad syntax in %s: %s.", NETHACK_ENV_OPTIONS
, opts
);
1036 raw_printf("Bad syntax in AUTHENTICATION in %s: %s.", configfile
, opts
);
1044 raw_printf("Bad syntax in TILESET in %s: %s.", configfile
, opts
);
1049 string_for_opt(opts
, val_optional
)
1051 boolean val_optional
;
1053 char *colon
, *equals
;
1055 colon
= index(opts
, ':');
1056 equals
= index(opts
, '=');
1057 if (!colon
|| (equals
&& equals
< colon
)) colon
= equals
;
1059 if (!colon
|| !*++colon
) {
1060 if (!val_optional
) badoption(opts
);
1067 string_for_auth_opt(opts
, val_optional
)
1069 boolean val_optional
;
1071 char *colon
= string_for_opt(opts
, TRUE
);
1072 if (!colon
&& !val_optional
) badauthoption(opts
);
1077 string_for_tile_opt(opts
, val_optional
)
1079 boolean val_optional
;
1081 char *colon
= string_for_opt(opts
, TRUE
);
1082 if (!colon
&& !val_optional
) badtileoption(opts
);
1087 string_for_env_opt(optname
, opts
, val_optional
)
1088 const char *optname
;
1090 boolean val_optional
;
1093 rejectoption(optname
);
1096 return string_for_opt(opts
, val_optional
);
1100 bad_negation(optname
, with_parameter
)
1101 const char *optname
;
1102 boolean with_parameter
;
1104 pline_The("%s option may not %sbe negated.",
1106 with_parameter
? "both have a value and " : "");
1110 * Change the inventory order, using the given string as the new order.
1111 * Missing characters in the new order are filled in at the end from
1112 * the current inv_order, except for gold, which is forced to be first
1113 * if not explicitly present.
1115 * This routine returns 1 unless there is a duplicate or bad char in
1119 change_inv_order(op
)
1123 char *sp
, buf
[BUFSZ
];
1127 if (!index(op
, GOLD_SYM
))
1128 buf
[num
++] = COIN_CLASS
;
1130 /* !!!! probably unnecessary with gold as normal inventory */
1133 for (sp
= op
; *sp
; sp
++) {
1134 oc_sym
= def_char_to_objclass(*sp
);
1135 /* reject bad or duplicate entries */
1136 if (oc_sym
== MAXOCLASSES
||
1137 oc_sym
== RANDOM_CLASS
|| oc_sym
== ILLOBJ_CLASS
||
1138 !index(flags
.inv_order
, oc_sym
) || index(sp
+1, *sp
))
1140 /* retain good ones */
1141 buf
[num
++] = (char) oc_sym
;
1145 /* fill in any omitted classes, using previous ordering */
1146 for (sp
= flags
.inv_order
; *sp
; sp
++)
1147 if (!index(buf
, *sp
)) {
1149 buf
[num
] = '\0'; /* explicitly terminate for next index() */
1152 strcpy(flags
.inv_order
, buf
);
1157 graphics_opts(opts
, optype
, maxlen
, offset
)
1158 register char *opts
;
1162 uchar translate
[MAXPCHARS
+1];
1165 if (!(opts
= string_for_env_opt(optype
, opts
, FALSE
)))
1167 escapes(opts
, opts
);
1169 length
= strlen(opts
);
1170 if (length
> maxlen
) length
= maxlen
;
1171 /* match the form obtained from PC configuration files */
1172 for (i
= 0; i
< length
; i
++)
1173 translate
[i
] = (uchar
) opts
[i
];
1174 assign_graphics(translate
, length
, maxlen
, offset
);
1178 warning_opts(opts
, optype
)
1179 register char *opts
;
1182 uchar translate
[MAXPCHARS
+1];
1185 if (!(opts
= string_for_env_opt(optype
, opts
, FALSE
)))
1187 escapes(opts
, opts
);
1189 length
= strlen(opts
);
1190 if (length
> WARNCOUNT
) length
= WARNCOUNT
;
1191 /* match the form obtained from PC configuration files */
1192 for (i
= 0; i
< length
; i
++)
1193 translate
[i
] = (((i
< WARNCOUNT
) && opts
[i
]) ?
1194 (uchar
) opts
[i
] : def_warnsyms
[i
].sym
);
1195 assign_warnings(translate
);
1199 assign_warnings(graph_chars
)
1200 register uchar
*graph_chars
;
1203 for (i
= 0; i
< WARNCOUNT
; i
++)
1204 if (graph_chars
[i
]) warnsyms
[i
] = graph_chars
[i
];
1208 feature_alert_opts(op
, optn
)
1213 boolean rejectver
= FALSE
;
1214 unsigned long fnv
= get_feature_notice_ver(op
); /* version.c */
1215 if (fnv
== 0L) return 0;
1216 if (fnv
> get_current_feature_ver())
1219 flags
.suppress_alert
= fnv
;
1222 You_cant("disable new feature alerts for future versions.");
1225 "\n%s=%s Invalid reference to a future version ignored",
1232 sprintf(buf
, "%lu.%lu.%lu", FEATURE_NOTICE_VER_MAJ
,
1233 FEATURE_NOTICE_VER_MIN
, FEATURE_NOTICE_VER_PATCH
);
1234 pline("Feature change alerts disabled for Slash'EM %s features and prior.",
1241 set_duplicate_opt_detection(on_or_off
)
1245 if (on_or_off
!= 0) {
1247 if (iflags
.opt_booldup
)
1248 impossible("iflags.opt_booldup already on (memory leak)");
1249 iflags
.opt_booldup
= (int *)alloc(SIZE(boolopt
) * sizeof(int));
1250 optptr
= iflags
.opt_booldup
;
1251 for (k
= 0; k
< SIZE(boolopt
); ++k
)
1254 if (iflags
.opt_compdup
)
1255 impossible("iflags.opt_compdup already on (memory leak)");
1256 iflags
.opt_compdup
= (int *)alloc(SIZE(compopt
) * sizeof(int));
1257 optptr
= iflags
.opt_compdup
;
1258 for (k
= 0; k
< SIZE(compopt
); ++k
)
1262 if (iflags
.opt_booldup
) free((void *) iflags
.opt_booldup
);
1263 iflags
.opt_booldup
= (int *)0;
1264 if (iflags
.opt_compdup
) free((void *) iflags
.opt_compdup
);
1265 iflags
.opt_compdup
= (int *)0;
1270 duplicate_opt_detection(opts
, bool_or_comp
)
1272 int bool_or_comp
; /* 0 == boolean option, 1 == compound */
1276 /* the Mac has trouble dealing with the output of messages while
1277 * processing the config file. That should get fixed one day.
1278 * For now just return.
1282 if ((bool_or_comp
== 0) && iflags
.opt_booldup
&& initial
&& from_file
) {
1283 for (i
= 0; boolopt
[i
].name
; i
++) {
1284 if (match_optname(opts
, boolopt
[i
].name
, 3, FALSE
)) {
1285 optptr
= iflags
.opt_booldup
+ i
;
1288 "\nWarning - Boolean option specified multiple times: %s.\n",
1293 break; /* don't match multiple options */
1296 } else if ((bool_or_comp
== 1) && iflags
.opt_compdup
&& initial
&& from_file
) {
1297 for (i
= 0; compopt
[i
].name
; i
++) {
1298 if (match_optname(opts
, compopt
[i
].name
, strlen(compopt
[i
].name
), TRUE
)) {
1299 optptr
= iflags
.opt_compdup
+ i
;
1302 "\nWarning - compound option specified multiple times: %s.\n",
1307 break; /* don't match multiple options */
1314 extern struct menucoloring
*menu_colorings
;
1316 static const struct {
1320 {"black", CLR_BLACK
},
1322 {"green", CLR_GREEN
},
1323 {"brown", CLR_BROWN
},
1325 {"magenta", CLR_MAGENTA
},
1328 {"orange", CLR_ORANGE
},
1329 {"lightgreen", CLR_BRIGHT_GREEN
},
1330 {"yellow", CLR_YELLOW
},
1331 {"lightblue", CLR_BRIGHT_BLUE
},
1332 {"lightmagenta", CLR_BRIGHT_MAGENTA
},
1333 {"lightcyan", CLR_BRIGHT_CYAN
},
1334 {"white", CLR_WHITE
}
1337 static const struct {
1344 {"underline", ATR_ULINE
},
1345 {"blink", ATR_BLINK
},
1346 {"inverse", ATR_INVERSE
}
1350 /* parse '"regex_string"=color' and add it to menucoloring */
1352 add_menu_coloring(str
)
1357 int i
, c
= NO_COLOR
, a
= ATR_NONE
;
1358 struct menucoloring
*tmp
;
1359 char *tmps
, *cs
= strchr(str
, '=');
1364 const char *err
= (char *)0;
1366 if (!cs
|| !str
) return FALSE
;
1370 while (*tmps
&& isspace(*tmps
)) tmps
++;
1372 for (i
= 0; i
< SIZE(colornames
); i
++)
1373 if (strstri(tmps
, colornames
[i
].name
) == tmps
) {
1374 c
= colornames
[i
].color
;
1377 if ((i
== SIZE(colornames
)) && (*tmps
>= '0' && *tmps
<='9'))
1380 if (c
> 15) return FALSE
;
1382 tmps
= strchr(str
, '&');
1385 while (*tmps
&& isspace(*tmps
)) tmps
++;
1386 for (i
= 0; i
< SIZE(attrnames
); i
++)
1387 if (strstri(tmps
, attrnames
[i
].name
) == tmps
) {
1388 a
= attrnames
[i
].attr
;
1391 if ((i
== SIZE(attrnames
)) && (*tmps
>= '0' && *tmps
<='9'))
1397 if ((*tmps
== '"') || (*tmps
== '\'')) {
1399 while (isspace(*cs
)) cs
--;
1406 tmp
= (struct menucoloring
*)alloc(sizeof(struct menucoloring
));
1408 #ifdef USE_REGEX_MATCH
1410 tmp
->match
.translate
= 0;
1411 tmp
->match
.fastmap
= 0;
1412 tmp
->match
.buffer
= 0;
1413 tmp
->match
.allocated
= 0;
1414 tmp
->match
.regs_allocated
= REGS_FIXED
;
1415 err
= re_compile_pattern(tmps
, strlen(tmps
), &tmp
->match
);
1418 errnum
= regcomp(&tmp
->match
, tmps
, REG_EXTENDED
| REG_NOSUB
);
1420 regerror(errnum
, &tmp
->match
, errbuf
, sizeof(errbuf
));
1426 tmp
->match
= (char *)alloc(strlen(tmps
)+1);
1427 (void) memcpy((void *)tmp
->match
, (void *)tmps
, strlen(tmps
)+1);
1430 raw_printf("\nMenucolor regex error: %s\n", err
);
1435 tmp
->next
= menu_colorings
;
1438 menu_colorings
= tmp
;
1442 #endif /* MENU_COLOR */
1444 #if defined(STATUS_COLORS) && defined(TEXTCOLOR)
1451 const struct name_value status_colornames
[] = {
1452 { "black", CLR_BLACK
},
1454 { "green", CLR_GREEN
},
1455 { "brown", CLR_BROWN
},
1456 { "blue", CLR_BLUE
},
1457 { "magenta", CLR_MAGENTA
},
1458 { "cyan", CLR_CYAN
},
1459 { "gray", CLR_GRAY
},
1460 { "orange", CLR_ORANGE
},
1461 { "lightgreen", CLR_BRIGHT_GREEN
},
1462 { "yellow", CLR_YELLOW
},
1463 { "lightblue", CLR_BRIGHT_BLUE
},
1464 { "lightmagenta", CLR_BRIGHT_MAGENTA
},
1465 { "lightcyan", CLR_BRIGHT_CYAN
},
1466 { "white", CLR_WHITE
},
1470 const struct name_value status_attrnames
[] = {
1471 { "none", ATR_NONE
},
1472 { "bold", ATR_BOLD
},
1474 { "underline", ATR_ULINE
},
1475 { "blink", ATR_BLINK
},
1476 { "inverse", ATR_INVERSE
},
1481 value_of_name(name
, name_values
)
1483 const struct name_value
*name_values
;
1485 while (name_values
->name
&& !strstri(name_values
->name
, name
))
1487 return name_values
->value
;
1491 parse_color_option(start
)
1494 struct color_option result
= {NO_COLOR
, 0};
1499 for (end
= start
; *end
!= '&' && *end
!= '\0'; ++end
);
1502 result
.color
= value_of_name(start
, status_colornames
);
1504 while (last
== '&') {
1505 for (start
= ++end
; *end
!= '&' && *end
!= '\0'; ++end
);
1508 attr
= value_of_name(start
, status_attrnames
);
1510 result
.attr_bits
|= 1 << attr
;
1516 const struct percent_color_option
*hp_colors
= NULL
;
1517 const struct percent_color_option
*pw_colors
= NULL
;
1518 const struct text_color_option
*text_colors
= NULL
;
1520 struct percent_color_option
*
1521 add_percent_option(new_option
, list_head
)
1522 struct percent_color_option
*new_option
;
1523 struct percent_color_option
*list_head
;
1525 if (list_head
== NULL
)
1527 if (new_option
->percentage
<= list_head
->percentage
) {
1528 new_option
->next
= list_head
;
1531 list_head
->next
= add_percent_option(new_option
, list_head
->next
);
1536 parse_status_color_option(start
)
1541 while (*start
&& isspace(*start
)) start
++;
1542 for (middle
= start
; *middle
!= ':' && *middle
!= '=' && *middle
!= '\0'; ++middle
);
1544 if (middle
- start
> 2 && start
[2] == '%') {
1545 struct percent_color_option
*percent_color_option
=
1546 (struct percent_color_option
*)alloc(sizeof(*percent_color_option
));
1547 percent_color_option
->next
= NULL
;
1548 percent_color_option
->percentage
= atoi(start
+ 3);
1549 percent_color_option
->color_option
= parse_color_option(middle
);
1551 if (percent_color_option
->color_option
.color
>= 0
1552 && percent_color_option
->color_option
.attr_bits
>= 0) {
1553 if (!strcmpi(start
, "hp")) {
1554 hp_colors
= add_percent_option(percent_color_option
, hp_colors
);
1557 if (!strcmpi(start
, "pw")) {
1558 pw_colors
= add_percent_option(percent_color_option
, pw_colors
);
1562 free(percent_color_option
);
1565 int length
= strlen(start
) + 1;
1566 struct text_color_option
*text_color_option
=
1567 (struct text_color_option
*)alloc(sizeof(*text_color_option
));
1568 text_color_option
->next
= NULL
;
1569 text_color_option
->text
= (char *)alloc(length
);
1570 memcpy((char *)text_color_option
->text
, start
, length
);
1571 text_color_option
->color_option
= parse_color_option(middle
);
1572 if (text_color_option
->color_option
.color
>= 0
1573 && text_color_option
->color_option
.attr_bits
>= 0) {
1574 text_color_option
->next
= text_colors
;
1575 text_colors
= text_color_option
;
1578 free(text_color_option
->text
);
1579 free(text_color_option
);
1585 parse_status_color_options(start
)
1589 char *end
= start
- 1;
1591 while (last
== ',') {
1592 for (start
= ++end
; *end
!= ',' && *end
!= '\0'; ++end
);
1595 ok
= parse_status_color_option(start
) && ok
;
1601 #endif /* STATUS_COLORS */
1604 parseoptions(opts
, tinitial
, tfrom_file
)
1605 register char *opts
;
1606 boolean tinitial
, tfrom_file
;
1612 const char *fullname
;
1615 from_file
= tfrom_file
;
1616 if ((op
= index(opts
, ',')) != 0) {
1618 parseoptions(op
, initial
, from_file
);
1620 if (strlen(opts
) > BUFSZ
/2) {
1621 badoption("option too long");
1625 /* strip leading and trailing white space */
1626 opts
= stripspace(opts
);
1630 while ((*opts
== '!') || !strncmpi(opts
, "no", 2)) {
1631 if (*opts
== '!') opts
++; else opts
+= 2;
1635 /* variant spelling */
1637 if (match_optname(opts
, "hybridangbander", 15, FALSE
)) {
1638 flags
.hybridization
++;
1640 if (match_optname(opts
, "hybridaquarian", 14, FALSE
)) {
1641 flags
.hybridization
++;
1643 if (match_optname(opts
, "hybridcurser", 12, FALSE
)) {
1644 flags
.hybridization
++;
1646 if (match_optname(opts
, "hybridhaxor", 11, FALSE
)) {
1647 flags
.hybridization
++;
1649 if (match_optname(opts
, "hybridhomicider", 15, FALSE
)) {
1650 flags
.hybridization
++;
1652 if (match_optname(opts
, "hybridsuxxor", 11, FALSE
)) {
1653 flags
.hybridization
++;
1655 if (match_optname(opts
, "hybridwarper", 12, FALSE
)) {
1656 flags
.hybridization
++;
1658 if (match_optname(opts
, "hybridrandomizer", 16, FALSE
)) {
1659 flags
.hybridization
++;
1661 if (match_optname(opts
, "hybridnullrace", 14, FALSE
)) {
1662 flags
.hybridization
++;
1664 if (match_optname(opts
, "hybridmazewalker", 16, FALSE
)) {
1665 flags
.hybridization
++;
1667 if (match_optname(opts
, "hybridsoviet", 12, FALSE
)) {
1668 flags
.hybridization
++;
1670 if (match_optname(opts
, "hybridxrace", 11, FALSE
)) {
1671 flags
.hybridization
++;
1673 if (match_optname(opts
, "hybridheretic", 13, FALSE
)) {
1674 flags
.hybridization
++;
1676 if (match_optname(opts
, "hybridsokosolver", 16, FALSE
)) {
1677 flags
.hybridization
++;
1679 if (match_optname(opts
, "hybridspecialist", 16, FALSE
)) {
1680 flags
.hybridization
++;
1682 if (match_optname(opts
, "hybridamerican", 14, FALSE
)) {
1683 flags
.hybridization
++;
1685 if (match_optname(opts
, "hybridminimalist", 16, FALSE
)) {
1686 flags
.hybridization
++;
1688 if (match_optname(opts
, "hybridnastinator", 16, FALSE
)) {
1689 flags
.hybridization
++;
1691 if (match_optname(opts
, "hybridrougelike", 15, FALSE
)) {
1692 flags
.hybridization
++;
1694 if (match_optname(opts
, "hybridsegfaulter", 16, FALSE
)) {
1695 flags
.hybridization
++;
1697 if (match_optname(opts
, "hybridironman", 13, FALSE
)) {
1698 flags
.hybridization
++;
1700 if (match_optname(opts
, "hybridamnesiac", 14, FALSE
)) {
1701 flags
.hybridization
++;
1703 if (match_optname(opts
, "hybridproblematic", 17, FALSE
)) {
1704 flags
.hybridization
++;
1706 if (match_optname(opts
, "hybridwindinhabitant", 20, FALSE
)) {
1707 flags
.hybridization
++;
1709 if (match_optname(opts
, "hybridaggravator", 16, FALSE
)) {
1710 flags
.hybridization
++;
1712 if (match_optname(opts
, "hybridevilvariant", 17, FALSE
)) {
1713 flags
.hybridization
++;
1715 if (match_optname(opts
, "hybridlevelscaler", 17, FALSE
)) {
1716 flags
.hybridization
++;
1718 if (match_optname(opts
, "hybriderosator", 14, FALSE
)) {
1719 flags
.hybridization
++;
1721 if (match_optname(opts
, "hybridroommate", 14, FALSE
)) {
1722 flags
.hybridization
++;
1724 if (match_optname(opts
, "hybridextravator", 16, FALSE
)) {
1725 flags
.hybridization
++;
1727 if (match_optname(opts
, "hybridhallucinator", 18, FALSE
)) {
1728 flags
.hybridization
++;
1730 if (match_optname(opts
, "hybridbossrusher", 16, FALSE
)) {
1731 flags
.hybridization
++;
1733 if (match_optname(opts
, "hybriddorian", 12, FALSE
)) {
1734 flags
.hybridization
++;
1736 if (match_optname(opts
, "hybridtechless", 14, FALSE
)) {
1737 flags
.hybridization
++;
1739 if (match_optname(opts
, "hybridblait", 11, FALSE
)) {
1740 flags
.hybridization
++;
1742 if (match_optname(opts
, "hybridgrouper", 13, FALSE
)) {
1743 flags
.hybridization
++;
1745 if (match_optname(opts
, "hybridscriptor", 14, FALSE
)) {
1746 flags
.hybridization
++;
1748 if (match_optname(opts
, "hybridunbalancor", 16, FALSE
)) {
1749 flags
.hybridization
++;
1751 if (match_optname(opts
, "hybridbeacher", 13, FALSE
)) {
1752 flags
.hybridization
++;
1754 if (match_optname(opts
, "hybridstairseeker", 17, FALSE
)) {
1755 flags
.hybridization
++;
1757 if (match_optname(opts
, "hybridmatrayser", 15, FALSE
)) {
1758 flags
.hybridization
++;
1760 if (match_optname(opts
, "hybridfeminizer", 15, FALSE
)) {
1761 flags
.hybridization
++;
1763 if (match_optname(opts
, "hybridchallenger", 16, FALSE
)) {
1764 flags
.hybridization
++;
1766 if (match_optname(opts
, "hybridhardmoder", 15, FALSE
)) {
1767 flags
.hybridization
++;
1769 if (match_optname(opts
, "hybridstunfish", 14, FALSE
)) {
1770 flags
.hybridization
++;
1772 if (match_optname(opts
, "hybridkillfiller", 16, FALSE
)) {
1773 flags
.hybridization
++;
1775 if (match_optname(opts
, "hybridbadstatter", 16, FALSE
)) {
1776 flags
.hybridization
++;
1778 if (match_optname(opts
, "hybriddroughter", 15, FALSE
)) {
1779 flags
.hybridization
++;
1781 if (match_optname(opts
, "hybridvanillaoid", 16, FALSE
)) {
1782 flags
.hybridization
++;
1785 if (match_optname(opts
, "colour", 5, FALSE
))
1786 strcpy(opts
, "color"); /* fortunately this isn't longer */
1787 if (match_optname(opts
, "menucolours", 11, FALSE
))
1788 strcpy(opts
, "menucolors"); /* fortunately this isn't longer */
1789 if (match_optname(opts
, "statuscolours", 13, FALSE
))
1790 strcpy(opts
, "statuscolors"); /* fortunately this isn't longer */
1792 if (!match_optname(opts
, "subkeyvalue", 11, TRUE
)) /* allow multiple */
1793 duplicate_opt_detection(opts
, 1); /* 1 means compound opts */
1795 /* special boolean options */
1797 if (match_optname(opts
, "female", 3, FALSE
)) {
1798 if(!initial
&& flags
.female
== negated
)
1799 pline("That is not anatomically possible.");
1801 flags
.initgend
= flags
.female
= !negated
;
1805 if (match_optname(opts
, "male", 4, FALSE
)) {
1806 if(!initial
&& flags
.female
!= negated
)
1807 pline("That is not anatomically possible.");
1809 flags
.initgend
= flags
.female
= negated
;
1813 #if defined(MICRO) && !defined(AMIGA)
1814 /* included for compatibility with old NetHack.cnf files */
1815 if (match_optname(opts
, "IBM_", 4, FALSE
)) {
1816 iflags
.BIOS
= !negated
;
1821 /* compound options */
1823 fullname
= "pettype";
1824 if (match_optname(opts
, fullname
, 3, TRUE
)) {
1825 if ((op
= string_for_env_opt(fullname
, opts
, negated
)) != 0) {
1826 if (negated
) bad_negation(fullname
, TRUE
);
1830 preferred_pet
= 'd';
1834 case 'f': /* feline */
1836 preferred_pet
= 'c';
1838 case 'n': /* no pet */
1840 preferred_pet
= 'n';
1843 pline("Unrecognized pet type '%s'.", op
);
1846 } else if (negated
) preferred_pet
= 'n';
1850 fullname
= "ghoulname";
1851 if (match_optname(opts
, fullname
, 3, TRUE
)) {
1852 if (negated
) bad_negation(fullname
, FALSE
);
1853 else if ((op
= string_for_env_opt(fullname
, opts
, FALSE
)) != 0)
1854 nmcpy(ghoulname
, op
, PL_PSIZ
);
1858 fullname
= "wolfname";
1859 if (match_optname(opts
, fullname
, 3, TRUE
)) {
1860 if (negated
) bad_negation(fullname
, FALSE
);
1861 else if ((op
= string_for_env_opt(fullname
, opts
, FALSE
)) != 0)
1862 nmcpy(wolfname
, op
, PL_PSIZ
);
1866 fullname
= "catname";
1867 if (match_optname(opts
, fullname
, 3, TRUE
)) {
1868 if (negated
) bad_negation(fullname
, FALSE
);
1869 else if ((op
= string_for_env_opt(fullname
, opts
, FALSE
)) != 0)
1870 nmcpy(catname
, op
, PL_PSIZ
);
1874 fullname
= "dogname";
1875 if (match_optname(opts
, fullname
, 3, TRUE
)) {
1876 if (negated
) bad_negation(fullname
, FALSE
);
1877 else if ((op
= string_for_env_opt(fullname
, opts
, FALSE
)) != 0)
1878 nmcpy(dogname
, op
, PL_PSIZ
);
1882 fullname
= "monkeyname";
1883 if (match_optname(opts
, fullname
, 3, TRUE
)) {
1884 if (negated
) bad_negation(fullname
, FALSE
);
1885 else if ((op
= string_for_env_opt(fullname
, opts
, FALSE
)) != 0)
1886 nmcpy(monkeyname
, op
, PL_PSIZ
);
1890 fullname
= "parrotname";
1891 if (match_optname(opts
, fullname
, 3, TRUE
)) {
1892 if (negated
) bad_negation(fullname
, FALSE
);
1893 else if ((op
= string_for_env_opt(fullname
, opts
, FALSE
)) != 0)
1894 nmcpy(parrotname
, op
, PL_PSIZ
);
1898 fullname
= "girlname";
1899 if (match_optname(opts
, fullname
, 3, TRUE
)) {
1900 if (negated
) bad_negation(fullname
, FALSE
);
1901 else if ((op
= string_for_env_opt(fullname
, opts
, FALSE
)) != 0)
1902 nmcpy(girlname
, op
, PL_PSIZ
);
1906 fullname
= "boyname";
1907 if (match_optname(opts
, fullname
, 3, TRUE
)) {
1908 if (negated
) bad_negation(fullname
, FALSE
);
1909 else if ((op
= string_for_env_opt(fullname
, opts
, FALSE
)) != 0)
1910 nmcpy(boyname
, op
, PL_PSIZ
);
1914 fullname
= "ravenname";
1915 if (match_optname(opts
, fullname
, 3, TRUE
)) {
1916 if (negated
) bad_negation(fullname
, FALSE
);
1917 else if ((op
= string_for_env_opt(fullname
, opts
, FALSE
)) != 0)
1918 nmcpy(ravenname
, op
, PL_PSIZ
);
1922 fullname
= "dragonname";
1923 if (match_optname(opts
, fullname
, 3, TRUE
)) {
1924 if (negated
) bad_negation(fullname
, FALSE
);
1925 else if ((op
= string_for_env_opt(fullname
, opts
, FALSE
)) != 0)
1926 nmcpy(dragonname
, op
, PL_PSIZ
);
1931 fullname
= "dumpfile";
1932 if (match_optname(opts
, fullname
, 3, TRUE
)) {
1934 if (negated
) bad_negation(fullname
, FALSE
);
1935 else if ((op
= string_for_opt(opts
, !tfrom_file
)) != 0
1937 nmcpy(dump_fn
, op
, PL_PSIZ
);
1943 fullname
= "horsename";
1944 if (match_optname(opts
, fullname
, 5, TRUE
)) {
1945 if (negated
) bad_negation(fullname
, FALSE
);
1946 else if ((op
= string_for_env_opt(fullname
, opts
, FALSE
)) != 0)
1947 nmcpy(horsename
, op
, PL_PSIZ
);
1951 /* menucolor:"regex_string"=color */
1952 fullname
= "menucolor";
1953 if (match_optname(opts
, fullname
, 9, TRUE
)) {
1955 if (negated
) bad_negation(fullname
, FALSE
);
1956 else if ((op
= string_for_env_opt(fullname
, opts
, FALSE
)) != 0)
1957 if (!add_menu_coloring(op
))
1963 fullname
= "ratname";
1964 if (match_optname(opts
, fullname
, 3, TRUE
)) {
1965 if (negated
) bad_negation(fullname
, FALSE
);
1966 else if ((op
= string_for_env_opt(fullname
, opts
, FALSE
)) != 0)
1967 nmcpy(ratname
, op
, PL_PSIZ
);
1971 /* fullname = "lichenname";
1972 if (match_optname(opts, fullname, 3, TRUE)) {
1973 if (negated) bad_negation(fullname, FALSE);
1974 else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0)
1975 nmcpy(lichenname, op, PL_PSIZ);
1979 fullname = "coinsname";
1980 if (match_optname(opts, fullname, 3, TRUE)) {
1981 if (negated) bad_negation(fullname, FALSE);
1982 else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0)
1983 nmcpy(coinsname, op, PL_PSIZ);
1987 fullname = "rothename";
1988 if (match_optname(opts, fullname, 3, TRUE)) {
1989 if (negated) bad_negation(fullname, FALSE);
1990 else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0)
1991 nmcpy(rothename, op, PL_PSIZ);
1995 fullname
= "number_pad";
1996 if (match_optname(opts
, fullname
, 10, TRUE
)) {
1997 boolean compat
= (strlen(opts
) <= 10);
1998 op
= string_for_opt(opts
, (compat
|| !initial
));
2000 if (compat
|| negated
|| initial
) {
2001 /* for backwards compatibility, "number_pad" without a
2002 value is a synonym for number_pad:1 */
2003 iflags
.num_pad
= !negated
;
2004 if (iflags
.num_pad
) iflags
.num_pad_mode
= 0;
2005 number_pad(iflags
.num_pad
);
2010 bad_negation("number_pad", TRUE
);
2013 if (*op
== '1' || *op
== '2') {
2015 if (*op
== '2') iflags
.num_pad_mode
= 1;
2016 else iflags
.num_pad_mode
= 0;
2018 } else if (*op
== '0') {
2020 iflags
.num_pad_mode
= 0;
2022 } else badoption(opts
);
2026 fullname
= "qwertz_layout";
2027 if (match_optname(opts
, fullname
, 6, FALSE
)) {
2032 iflags
.qwertz_layout
=!negated
;
2036 fullname
= "runmode";
2037 if (match_optname(opts
, fullname
, 4, TRUE
)) {
2039 iflags
.runmode
= RUN_TPORT
;
2040 } else if ((op
= string_for_opt(opts
, FALSE
)) != 0) {
2041 if (!strncmpi(op
, "teleport", strlen(op
)))
2042 iflags
.runmode
= RUN_TPORT
;
2043 else if (!strncmpi(op
, "run", strlen(op
)))
2044 iflags
.runmode
= RUN_LEAP
;
2045 else if (!strncmpi(op
, "walk", strlen(op
)))
2046 iflags
.runmode
= RUN_STEP
;
2047 else if (!strncmpi(op
, "crawl", strlen(op
)))
2048 iflags
.runmode
= RUN_CRAWL
;
2055 fullname
= "msghistory";
2056 if (match_optname(opts
, fullname
, 3, TRUE
)) {
2057 op
= string_for_env_opt(fullname
, opts
, negated
);
2058 if ((negated
&& !op
) || (!negated
&& op
)) {
2059 iflags
.msg_history
= negated
? 0 : atoi(op
);
2060 } else if (negated
) bad_negation(fullname
, TRUE
);
2064 fullname
="msg_window";
2065 /* msg_window:single, combo, full or reversed */
2066 if (match_optname(opts
, fullname
, 4, TRUE
)) {
2067 /* allow option to be silently ignored by non-tty ports */
2070 if (!(op
= string_for_opt(opts
, TRUE
))) {
2071 tmp
= negated
? 's' : 'f';
2074 bad_negation(fullname
, TRUE
);
2080 case 's': /* single message history cycle (default if negated) */
2081 iflags
.prevmsg_window
= 's';
2083 case 'c': /* combination: two singles, then full page reversed */
2084 iflags
.prevmsg_window
= 'c';
2086 case 'f': /* full page (default if no opts) */
2087 iflags
.prevmsg_window
= 'f';
2089 case 'r': /* full page (reversed) */
2090 iflags
.prevmsg_window
= 'r';
2100 * setting font options */
2102 if (!strncmpi(opts
, fullname
, 4))
2105 char *fontopts
= opts
+ 4;
2107 if (!strncmpi(fontopts
, "map", 3) ||
2108 !strncmpi(fontopts
, "_map", 4))
2110 else if (!strncmpi(fontopts
, "message", 7) ||
2111 !strncmpi(fontopts
, "_message", 8))
2112 wintype
= NHW_MESSAGE
;
2113 else if (!strncmpi(fontopts
, "text", 4) ||
2114 !strncmpi(fontopts
, "_text", 5))
2116 else if (!strncmpi(fontopts
, "menu", 4) ||
2117 !strncmpi(fontopts
, "_menu", 5))
2119 else if (!strncmpi(fontopts
, "status", 6) ||
2120 !strncmpi(fontopts
, "_status", 7))
2121 wintype
= NHW_STATUS
;
2122 else if (!strncmpi(fontopts
, "_size", 5)) {
2123 if (!strncmpi(fontopts
, "_size_map", 8))
2125 else if (!strncmpi(fontopts
, "_size_message", 12))
2126 wintype
= NHW_MESSAGE
;
2127 else if (!strncmpi(fontopts
, "_size_text", 9))
2129 else if (!strncmpi(fontopts
, "_size_menu", 9))
2131 else if (!strncmpi(fontopts
, "_size_status", 11))
2132 wintype
= NHW_STATUS
;
2137 if (wintype
> 0 && !negated
&&
2138 (op
= string_for_opt(opts
, FALSE
)) != 0) {
2141 iflags
.wc_fontsiz_map
= atoi(op
);
2144 iflags
.wc_fontsiz_message
= atoi(op
);
2147 iflags
.wc_fontsiz_text
= atoi(op
);
2150 iflags
.wc_fontsiz_menu
= atoi(op
);
2153 iflags
.wc_fontsiz_status
= atoi(op
);
2162 (op
= string_for_opt(opts
, FALSE
)) != 0) {
2163 wc_set_font_name(wintype
, op
);
2165 set_font_name (wintype
, op
);
2168 } else if (negated
) bad_negation(fullname
, TRUE
);
2172 if (match_optname(opts
, "palette", 3, TRUE
)
2174 || match_optname(opts
, "hicolor", 3, TRUE
)
2177 int color_number
, color_incr
;
2180 if (match_optname(opts
, "hicolor", 3, TRUE
)) {
2182 bad_negation("hicolor", FALSE
);
2185 color_number
= CLR_MAX
+ 4; /* HARDCODED inverse number */
2190 bad_negation("palette", FALSE
);
2198 if ((op
= string_for_opt(opts
, FALSE
)) != (char *)0) {
2200 int cnt
, tmp
, reverse
;
2203 while (*pt
&& color_number
>= 0) {
2213 if (*pt
&& *pt
!= '/') {
2221 tmp
= (tmp
+ 9) & 0xf; /* Assumes ASCII... */
2223 tmp
&= 0xf; /* Digits in ASCII too... */
2226 /* Add an extra so we fill f -> ff and 0 -> 00 */
2235 change_color(color_number
, rgb
, reverse
);
2236 color_number
+= color_incr
;
2244 #endif /* CHANGE_COLOR */
2246 if (match_optname(opts
, "fruit", 2, TRUE
)) {
2247 char empty_str
= '\0';
2248 op
= string_for_opt(opts
, negated
);
2251 bad_negation("fruit", TRUE
);
2262 for(f
=ffruit
; f
; f
=f
->nextf
) {
2263 if (!strcmp(op
, f
->fname
)) goto goodfruit
;
2267 pline("Doing that so many times isn't very fruitful.");
2272 nmcpy(pl_fruit
, op
, PL_FSIZ
);
2273 /* OBJ_NAME(objects[SLIME_MOLD]) won't work after initialization */
2275 nmcpy(pl_fruit
, "slime mold", PL_FSIZ
);
2277 (void)fruitadd(pl_fruit
);
2278 /* If initial, then initoptions is allowed to do it instead
2279 * of here (initoptions always has to do it even if there's
2280 * no fruit option at all. Also, we don't want people
2281 * setting multiple fruits in their options.)
2286 /* graphics:string */
2287 fullname
= "graphics";
2288 if (match_optname(opts
, fullname
, 2, TRUE
)) {
2289 if (negated
) bad_negation(fullname
, FALSE
);
2290 else graphics_opts(opts
, fullname
, MAXPCHARS
, 0);
2293 fullname
= "dungeon";
2294 if (match_optname(opts
, fullname
, 2, TRUE
)) {
2295 if (negated
) bad_negation(fullname
, FALSE
);
2296 else graphics_opts(opts
, fullname
, MAXDCHARS
, 0);
2300 if (match_optname(opts
, fullname
, 2, TRUE
)) {
2301 if (negated
) bad_negation(fullname
, FALSE
);
2302 else graphics_opts(opts
, fullname
, MAXTCHARS
, MAXDCHARS
);
2305 fullname
= "effects";
2306 if (match_optname(opts
, fullname
, 2, TRUE
)) {
2307 if (negated
) bad_negation(fullname
, FALSE
);
2309 graphics_opts(opts
, fullname
, MAXECHARS
, MAXDCHARS
+MAXTCHARS
);
2313 /* objects:string */
2314 fullname
= "objects";
2315 if (match_optname(opts
, fullname
, 7, TRUE
)) {
2319 bad_negation(fullname
, FALSE
);
2322 if (!(opts
= string_for_env_opt(fullname
, opts
, FALSE
)))
2324 escapes(opts
, opts
);
2327 * Override the default object class symbols. The first
2328 * object in the object class is the "random object". I
2329 * don't want to use 0 as an object class, so the "random
2330 * object" is basically a place holder.
2332 * The object class symbols have already been initialized in
2335 length
= strlen(opts
);
2336 if (length
>= MAXOCLASSES
)
2337 length
= MAXOCLASSES
-1; /* don't count RANDOM_OBJECT */
2339 for (i
= 0; i
< length
; i
++)
2340 oc_syms
[i
+1] = (uchar
) opts
[i
];
2344 /* monsters:string */
2345 fullname
= "monsters";
2346 if (match_optname(opts
, fullname
, 8, TRUE
)) {
2350 bad_negation(fullname
, FALSE
);
2353 if (!(opts
= string_for_env_opt(fullname
, opts
, FALSE
)))
2355 escapes(opts
, opts
);
2357 /* Override default mon class symbols set in initoptions(). */
2358 length
= strlen(opts
);
2359 if (length
>= MAXMCLASSES
)
2360 length
= MAXMCLASSES
-1; /* mon class 0 unused */
2362 for (i
= 0; i
< length
; i
++)
2363 monsyms
[i
+1] = (uchar
) opts
[i
];
2366 fullname
= "warnings";
2367 if (match_optname(opts
, fullname
, 5, TRUE
)) {
2368 if (negated
) bad_negation(fullname
, FALSE
);
2369 else warning_opts(opts
, fullname
);
2372 /* boulder:symbol */
2373 fullname
= "boulder";
2374 if (match_optname(opts
, fullname
, 7, TRUE
)) {
2377 bad_negation(fullname
, FALSE
);
2380 /* if (!(opts = string_for_env_opt(fullname, opts, FALSE))) */
2381 if (!(opts
= string_for_opt(opts
, FALSE
)))
2383 escapes(opts
, opts
);
2384 if (def_char_to_monclass(opts
[0]) != MAXMCLASSES
)
2386 else if (opts
[0] >= '1' && opts
[0] <= '5')
2389 /* symbol chosen matches a used monster or warning
2390 symbol which is not good - reject it*/
2392 "Badoption - boulder symbol '%c' conflicts with a %s symbol.",
2393 opts
[0], (clash
== 1) ? "monster" : "warning");
2396 * Override the default boulder symbol.
2398 iflags
.bouldersym
= (uchar
) opts
[0];
2400 if (!initial
) need_redraw
= TRUE
;
2406 if (match_optname(opts
, fullname
, 4, TRUE
)) {
2407 if (negated
) bad_negation(fullname
, FALSE
);
2408 else if ((op
= string_for_env_opt(fullname
, opts
, FALSE
)) != 0)
2409 #ifdef PROXY_GRAPHICS
2411 * Can't change player name if authentication required.
2413 if (!getenv("HACKAUTHENTICATION"))
2415 nmcpy(plname
, op
, PL_NSIZ
);
2419 /* role:string or character:string */
2421 if (match_optname(opts
, fullname
, 4, TRUE
) ||
2422 match_optname(opts
, (fullname
= "character"), 4, TRUE
)) {
2423 if (negated
) bad_negation(fullname
, FALSE
);
2424 else if ((op
= string_for_env_opt(fullname
, opts
, FALSE
)) != 0) {
2425 if ((flags
.initrole
= str2role(op
)) == ROLE_NONE
)
2427 else /* Backwards compatibility */
2428 nmcpy(pl_character
, op
, PL_NSIZ
);
2435 if (match_optname(opts
, fullname
, 4, TRUE
)) {
2436 if (negated
) bad_negation(fullname
, FALSE
);
2437 else if ((op
= string_for_env_opt(fullname
, opts
, FALSE
)) != 0) {
2438 if ((flags
.initrace
= str2race(op
)) == ROLE_NONE
)
2440 else /* Backwards compatibility */
2447 fullname
= "gender";
2448 if (match_optname(opts
, fullname
, 4, TRUE
)) {
2449 if (negated
) bad_negation(fullname
, FALSE
);
2450 else if ((op
= string_for_env_opt(fullname
, opts
, FALSE
)) != 0) {
2451 if ((flags
.initgend
= str2gend(op
)) == ROLE_NONE
)
2454 flags
.female
= flags
.initgend
;
2459 /* altkeyhandler:string */
2460 fullname
= "altkeyhandler";
2461 if (match_optname(opts
, fullname
, 4, TRUE
)) {
2462 if (negated
) bad_negation(fullname
, FALSE
);
2463 else if ((op
= string_for_opt(opts
, negated
))) {
2465 (void)strncpy(iflags
.altkeyhandler
, op
, MAX_ALTKEYHANDLER
- 5);
2466 load_keyboard_handler();
2473 * align_status:[left|top|right|bottom] */
2474 fullname
= "align_status";
2475 if (match_optname(opts
, fullname
, sizeof("align_status")-1, TRUE
)) {
2476 op
= string_for_opt(opts
, negated
);
2477 if (op
&& !negated
) {
2478 if (!strncmpi (op
, "left", sizeof("left")-1))
2479 iflags
.wc_align_status
= ALIGN_LEFT
;
2480 else if (!strncmpi (op
, "top", sizeof("top")-1))
2481 iflags
.wc_align_status
= ALIGN_TOP
;
2482 else if (!strncmpi (op
, "right", sizeof("right")-1))
2483 iflags
.wc_align_status
= ALIGN_RIGHT
;
2484 else if (!strncmpi (op
, "bottom", sizeof("bottom")-1))
2485 iflags
.wc_align_status
= ALIGN_BOTTOM
;
2488 } else if (negated
) bad_negation(fullname
, TRUE
);
2492 * align_message:[left|top|right|bottom] */
2493 fullname
= "align_message";
2494 if (match_optname(opts
, fullname
, sizeof("align_message")-1, TRUE
)) {
2495 op
= string_for_opt(opts
, negated
);
2496 if (op
&& !negated
) {
2497 if (!strncmpi (op
, "left", sizeof("left")-1))
2498 iflags
.wc_align_message
= ALIGN_LEFT
;
2499 else if (!strncmpi (op
, "top", sizeof("top")-1))
2500 iflags
.wc_align_message
= ALIGN_TOP
;
2501 else if (!strncmpi (op
, "right", sizeof("right")-1))
2502 iflags
.wc_align_message
= ALIGN_RIGHT
;
2503 else if (!strncmpi (op
, "bottom", sizeof("bottom")-1))
2504 iflags
.wc_align_message
= ALIGN_BOTTOM
;
2507 } else if (negated
) bad_negation(fullname
, TRUE
);
2512 if (match_optname(opts
, fullname
, sizeof("align")-1, TRUE
)) {
2513 if (negated
) bad_negation(fullname
, FALSE
);
2514 else if ((op
= string_for_env_opt(fullname
, opts
, FALSE
)) != 0)
2515 if ((flags
.initalign
= str2align(op
)) == ROLE_NONE
)
2520 /* the order to list the pack */
2521 fullname
= "packorder";
2522 if (match_optname(opts
, fullname
, 4, TRUE
)) {
2524 bad_negation(fullname
, FALSE
);
2526 } else if (!(op
= string_for_opt(opts
, FALSE
))) return;
2528 if (!change_inv_order(op
))
2533 /* maximum burden picked up before prompt (Warren Cheung) */
2534 fullname
= "pickup_burden";
2535 if (match_optname(opts
, fullname
, 8, TRUE
)) {
2537 bad_negation(fullname
, FALSE
);
2539 } else if ((op
= string_for_env_opt(fullname
, opts
, FALSE
)) != 0) {
2540 switch (tolower(*op
)) {
2543 flags
.pickup_burden
= UNENCUMBERED
;
2545 /* Burdened (slight encumbrance) */
2547 flags
.pickup_burden
= SLT_ENCUMBER
;
2549 /* streSsed (moderate encumbrance) */
2551 flags
.pickup_burden
= MOD_ENCUMBER
;
2553 /* straiNed (heavy encumbrance) */
2555 flags
.pickup_burden
= HVY_ENCUMBER
;
2557 /* OverTaxed (extreme encumbrance) */
2560 flags
.pickup_burden
= EXT_ENCUMBER
;
2564 flags
.pickup_burden
= OVERLOADED
;
2573 /* types of objects to pick up automatically */
2574 if (match_optname(opts
, "pickup_types", 8, TRUE
)) {
2575 char ocl
[MAXOCLASSES
+ 1], tbuf
[MAXOCLASSES
+ 1],
2576 qbuf
[QBUFSZ
], abuf
[BUFSZ
];
2578 boolean badopt
= FALSE
, compat
= (strlen(opts
) <= 6), use_menu
;
2580 oc_to_str(flags
.pickup_types
, tbuf
);
2581 flags
.pickup_types
[0] = '\0'; /* all */
2582 op
= string_for_opt(opts
, (compat
|| !initial
));
2584 if (compat
|| negated
|| initial
) {
2585 /* for backwards compatibility, "pickup" without a
2586 value is a synonym for autopickup of all types
2587 (and during initialization, we can't prompt yet) */
2588 flags
.pickup
= !negated
;
2591 oc_to_str(flags
.inv_order
, ocl
);
2593 if (flags
.menu_style
== MENU_TRADITIONAL
||
2594 flags
.menu_style
== MENU_COMBINATION
) {
2596 sprintf(qbuf
, "New pickup_types: [%s am] (%s)",
2597 ocl
, *tbuf
? tbuf
: "none");
2599 op
= mungspaces(abuf
);
2600 if (abuf
[0] == '\0' || abuf
[0] == '\033')
2601 op
= tbuf
; /* restore */
2602 else if (abuf
[0] == 'm')
2606 (void) choose_classes_menu("Auto-Pickup what?", 1,
2612 bad_negation("pickup_types", TRUE
);
2615 while (*op
== ' ') op
++;
2616 if (*op
!= 'a' && *op
!= 'A') {
2619 oc_sym
= def_char_to_objclass(*op
);
2620 /* make sure all are valid obj symbols occuring once */
2621 if (oc_sym
!= MAXOCLASSES
&&
2622 !index(flags
.pickup_types
, oc_sym
)) {
2623 flags
.pickup_types
[num
] = (char)oc_sym
;
2624 flags
.pickup_types
[++num
] = '\0';
2629 if (badopt
) badoption(opts
);
2634 fullname
= "pilesize";
2635 if (match_optname(opts
, fullname
, sizeof("pilesize")-1, TRUE
)) {
2637 bad_negation(fullname
, FALSE
);
2639 } else if (!(op
= string_for_opt(opts
, FALSE
))) return;
2640 iflags
.pilesize
= atoi(op
);
2641 if (iflags
.pilesize
< 1) iflags
.pilesize
= 1;
2646 * player_selection: dialog | prompts */
2647 fullname
= "player_selection";
2648 if (match_optname(opts
, fullname
, sizeof("player_selection")-1, TRUE
)) {
2649 op
= string_for_opt(opts
, negated
);
2650 if (op
&& !negated
) {
2651 if (!strncmpi (op
, "dialog", sizeof("dialog")-1))
2652 iflags
.wc_player_selection
= VIA_DIALOG
;
2653 else if (!strncmpi (op
, "prompt", sizeof("prompt")-1))
2654 iflags
.wc_player_selection
= VIA_PROMPTS
;
2657 } else if (negated
) bad_negation(fullname
, TRUE
);
2661 /* things to disclose at end of game */
2662 if (match_optname(opts
, "disclose", 7, TRUE
)) {
2664 * The order that the end_disclore options are stored:
2665 * inventory, attribs, vanquished, genocided, conduct
2666 * There is an array in flags:
2667 * end_disclose[NUM_DISCLOSURE_OPT];
2668 * with option settings for the each of the following:
2669 * iagvc [see disclosure_options in decl.c]:
2670 * Legal setting values in that array are:
2671 * DISCLOSE_PROMPT_DEFAULT_YES ask with default answer yes
2672 * DISCLOSE_PROMPT_DEFAULT_NO ask with default answer no
2673 * DISCLOSE_YES_WITHOUT_PROMPT always disclose and don't ask
2674 * DISCLOSE_NO_WITHOUT_PROMPT never disclose and don't ask
2676 * Those setting values can be used in the option
2677 * string as a prefix to get the desired behaviour.
2679 * For backward compatibility, no prefix is required,
2680 * and the presence of a i,a,g,v, or c without a prefix
2681 * sets the corresponding value to DISCLOSE_YES_WITHOUT_PROMPT.
2683 boolean badopt
= FALSE
;
2684 int idx
, prefix_val
;
2686 op
= string_for_opt(opts
, TRUE
);
2687 if (op
&& negated
) {
2688 bad_negation("disclose", TRUE
);
2691 /* "disclose" without a value means "all with prompting"
2692 and negated means "none without prompting" */
2693 if (!op
|| !strcmpi(op
, "all") || !strcmpi(op
, "none")) {
2694 if (op
&& !strcmpi(op
, "none")) negated
= TRUE
;
2695 for (num
= 0; num
< NUM_DISCLOSURE_OPTIONS
; num
++)
2696 flags
.end_disclose
[num
] = negated
?
2697 DISCLOSE_NO_WITHOUT_PROMPT
:
2698 DISCLOSE_PROMPT_DEFAULT_YES
;
2704 while (*op
&& num
< sizeof flags
.end_disclose
- 1) {
2705 register char c
, *dop
;
2706 static char valid_settings
[] = {
2707 DISCLOSE_PROMPT_DEFAULT_YES
,
2708 DISCLOSE_PROMPT_DEFAULT_NO
,
2709 DISCLOSE_YES_WITHOUT_PROMPT
,
2710 DISCLOSE_NO_WITHOUT_PROMPT
,
2714 if (c
== 'k') c
= 'v'; /* killed -> vanquished */
2715 dop
= index(disclosure_options
, c
);
2717 idx
= dop
- disclosure_options
;
2718 if (idx
< 0 || idx
> NUM_DISCLOSURE_OPTIONS
- 1) {
2719 impossible("bad disclosure index %d %c",
2723 if (prefix_val
!= -1) {
2724 flags
.end_disclose
[idx
] = prefix_val
;
2727 flags
.end_disclose
[idx
] = DISCLOSE_YES_WITHOUT_PROMPT
;
2728 } else if (index(valid_settings
, c
)) {
2730 } else if (c
== ' ') {
2736 if (badopt
) badoption(opts
);
2740 /* scores:5t[op] 5a[round] o[wn] */
2741 if (match_optname(opts
, "scores", 4, TRUE
)) {
2743 bad_negation("scores", FALSE
);
2746 if (!(op
= string_for_opt(opts
, FALSE
))) return;
2753 while (digit(*op
)) op
++;
2754 } else if (*op
== '!') {
2758 while (*op
== ' ') op
++;
2762 case 'T': flags
.end_top
= inum
;
2765 case 'A': flags
.end_around
= inum
;
2768 case 'O': flags
.end_own
= !negated
;
2770 default: badoption(opts
);
2773 while (letter(*++op
) || *op
== ' ') continue;
2774 if (*op
== '/') op
++;
2779 fullname
= "statuscolor";
2780 if (match_optname(opts
, fullname
, 11, TRUE
)) {
2781 #if defined(STATUS_COLORS) && defined(TEXTCOLOR)
2782 if (negated
) bad_negation(fullname
, FALSE
);
2783 else if ((op
= string_for_env_opt(fullname
, opts
, FALSE
)) != 0)
2784 if (!parse_status_color_options(op
))
2790 fullname
= "sortloot";
2791 if (match_optname(opts
, fullname
, 4, TRUE
)) {
2792 op
= string_for_env_opt(fullname
, opts
, FALSE
);
2794 switch (tolower(*op
)) {
2797 case 'f': iflags
.sortloot
= tolower(*op
);
2799 default: badoption(opts
);
2806 fullname
= "suppress_alert";
2807 if (match_optname(opts
, fullname
, 4, TRUE
)) {
2808 op
= string_for_opt(opts
, negated
);
2809 if (negated
) bad_negation(fullname
, FALSE
);
2810 else if (op
) (void) feature_alert_opts(op
,fullname
);
2814 fullname
= "tileset";
2815 if (match_optname(opts
, fullname
, 4, TRUE
)) {
2816 if (negated
|| (op
= string_for_opt(opts
, TRUE
)) == 0)
2820 * The tileset may not be defined (yet) if we're
2821 * in initial mode, otherwise it must exist.
2824 int len
= strlen(op
);
2825 for(i
= 0; i
< no_tilesets
; i
++)
2826 if (len
== strlen(tilesets
[i
].name
) &&
2827 !strncmpi(tilesets
[i
].name
, op
, len
))
2829 if (i
== no_tilesets
) {
2830 pline("Tileset %s not defined.", op
);
2833 else /* Use canonical case */
2834 strcpy(tileset
, tilesets
[i
].name
);
2837 nmcpy(tileset
, op
, PL_PSIZ
);
2844 #if defined(VIDEOSHADES) && !defined(NO_TERMS)
2845 /* videocolors:string */
2846 fullname
= "videocolors";
2847 if (match_optname(opts
, fullname
, 6, TRUE
) ||
2848 match_optname(opts
, "videocolours", 10, TRUE
)) {
2850 bad_negation(fullname
, FALSE
);
2853 else if (!(opts
= string_for_env_opt(fullname
, opts
, FALSE
))) {
2856 if (!assign_videocolors(opts
))
2861 /* videoshades:string */
2862 fullname
= "videoshades";
2863 if (match_optname(opts
, fullname
, 6, TRUE
)) {
2865 bad_negation(fullname
, FALSE
);
2868 else if (!(opts
= string_for_env_opt(fullname
, opts
, FALSE
))) {
2871 if (!assign_videoshades(opts
))
2876 #endif /* VIDEOSHADES */
2879 /* video:string -- must be after longer tests */
2881 if (match_optname(opts
, fullname
, 5, TRUE
)) {
2883 bad_negation(fullname
, FALSE
);
2886 else if (!(opts
= string_for_env_opt(fullname
, opts
, FALSE
))) {
2889 if (!assign_video(opts
))
2893 # endif /* NO_TERMS */
2894 /* soundcard:string -- careful not to match boolean 'sound' */
2895 fullname
= "soundcard";
2896 if (match_optname(opts
, fullname
, 6, TRUE
)) {
2898 bad_negation(fullname
, FALSE
);
2901 else if (!(opts
= string_for_env_opt(fullname
, opts
, FALSE
))) {
2904 if (!assign_soundcard(opts
))
2911 * map_mode:[tiles|ascii4x6|ascii6x8|ascii8x8|ascii16x8|ascii7x12|ascii8x12|
2912 ascii16x12|ascii12x16|ascii10x18|fit_to_screen] */
2913 fullname
= "map_mode";
2914 if (match_optname(opts
, fullname
, sizeof("map_mode")-1, TRUE
)) {
2915 op
= string_for_opt(opts
, negated
);
2916 if (op
&& !negated
) {
2917 if (!strncmpi (op
, "tiles", sizeof("tiles")-1))
2918 iflags
.wc_map_mode
= MAP_MODE_TILES
;
2919 else if (!strncmpi (op
, "ascii4x6", sizeof("ascii4x6")-1))
2920 iflags
.wc_map_mode
= MAP_MODE_ASCII4x6
;
2921 else if (!strncmpi (op
, "ascii6x8", sizeof("ascii6x8")-1))
2922 iflags
.wc_map_mode
= MAP_MODE_ASCII6x8
;
2923 else if (!strncmpi (op
, "ascii8x8", sizeof("ascii8x8")-1))
2924 iflags
.wc_map_mode
= MAP_MODE_ASCII8x8
;
2925 else if (!strncmpi (op
, "ascii16x8", sizeof("ascii16x8")-1))
2926 iflags
.wc_map_mode
= MAP_MODE_ASCII16x8
;
2927 else if (!strncmpi (op
, "ascii7x12", sizeof("ascii7x12")-1))
2928 iflags
.wc_map_mode
= MAP_MODE_ASCII7x12
;
2929 else if (!strncmpi (op
, "ascii8x12", sizeof("ascii8x12")-1))
2930 iflags
.wc_map_mode
= MAP_MODE_ASCII8x12
;
2931 else if (!strncmpi (op
, "ascii16x12", sizeof("ascii16x12")-1))
2932 iflags
.wc_map_mode
= MAP_MODE_ASCII16x12
;
2933 else if (!strncmpi (op
, "ascii12x16", sizeof("ascii12x16")-1))
2934 iflags
.wc_map_mode
= MAP_MODE_ASCII12x16
;
2935 else if (!strncmpi (op
, "ascii10x18", sizeof("ascii10x18")-1))
2936 iflags
.wc_map_mode
= MAP_MODE_ASCII10x18
;
2937 else if (!strncmpi (op
, "fit_to_screen", sizeof("fit_to_screen")-1))
2938 iflags
.wc_map_mode
= MAP_MODE_ASCII_FIT_TO_SCREEN
;
2941 } else if (negated
) bad_negation(fullname
, TRUE
);
2945 * scroll_amount:nn */
2946 fullname
= "scroll_amount";
2947 if (match_optname(opts
, fullname
, sizeof("scroll_amount")-1, TRUE
)) {
2948 op
= string_for_opt(opts
, negated
);
2949 if ((negated
&& !op
) || (!negated
&& op
)) {
2950 iflags
.wc_scroll_amount
= negated
? 1 : atoi(op
);
2951 } else if (negated
) bad_negation(fullname
, TRUE
);
2955 * scroll_margin:nn */
2956 fullname
= "scroll_margin";
2957 if (match_optname(opts
, fullname
, sizeof("scroll_margin")-1, TRUE
)) {
2958 op
= string_for_opt(opts
, negated
);
2959 if ((negated
&& !op
) || (!negated
&& op
)) {
2960 iflags
.wc_scroll_margin
= negated
? 5 : atoi(op
);
2961 } else if (negated
) bad_negation(fullname
, TRUE
);
2964 fullname
= "subkeyvalue";
2965 if (match_optname(opts
, fullname
, 5, TRUE
)) {
2966 if (negated
) bad_negation(fullname
, FALSE
);
2968 #if defined(WIN32CON)
2969 op
= string_for_opt(opts
, 0);
2970 map_subkeyvalue(op
);
2977 fullname
= "tile_width";
2978 if (match_optname(opts
, fullname
, sizeof("tile_width")-1, TRUE
)) {
2979 op
= string_for_opt(opts
, negated
);
2980 if ((negated
&& !op
) || (!negated
&& op
)) {
2981 iflags
.wc_tile_width
= negated
? 0 : atoi(op
);
2982 } else if (negated
) bad_negation(fullname
, TRUE
);
2987 fullname
= "tile_file";
2988 if (match_optname(opts
, fullname
, sizeof("tile_file")-1, TRUE
)) {
2989 if ((op
= string_for_opt(opts
, FALSE
)) != 0) {
2990 if (iflags
.wc_tile_file
) free(iflags
.wc_tile_file
);
2991 iflags
.wc_tile_file
= (char *)alloc(strlen(op
) + 1);
2992 strcpy(iflags
.wc_tile_file
, op
);
2998 fullname
= "tile_height";
2999 if (match_optname(opts
, fullname
, sizeof("tile_height")-1, TRUE
)) {
3000 op
= string_for_opt(opts
, negated
);
3001 if ((negated
&& !op
) || (!negated
&& op
)) {
3002 iflags
.wc_tile_height
= negated
? 0 : atoi(op
);
3003 } else if (negated
) bad_negation(fullname
, TRUE
);
3007 * vary_msgcount:nn */
3008 fullname
= "vary_msgcount";
3009 if (match_optname(opts
, fullname
, sizeof("vary_msgcount")-1, TRUE
)) {
3010 op
= string_for_opt(opts
, negated
);
3011 if ((negated
&& !op
) || (!negated
&& op
)) {
3012 iflags
.wc_vary_msgcount
= negated
? 0 : atoi(op
);
3013 } else if (negated
) bad_negation(fullname
, TRUE
);
3016 fullname
= "windowtype";
3022 match_optname(opts
, fullname
, 3, TRUE
)) {
3024 bad_negation(fullname
, FALSE
);
3026 } else if ((op
= string_for_env_opt(fullname
, opts
, FALSE
)) != 0) {
3027 char buf
[WINTYPELEN
];
3028 nmcpy(buf
, op
, WINTYPELEN
);
3029 choose_windows(buf
);
3035 * setting window colors
3036 * syntax: windowcolors=menu foregrnd/backgrnd text foregrnd/backgrnd
3038 fullname
= "windowcolors";
3039 if (match_optname(opts
, fullname
, 7, TRUE
)) {
3040 if ((op
= string_for_opt(opts
, FALSE
)) != 0) {
3041 if (!wc_set_window_colors(op
))
3043 } else if (negated
) bad_negation(fullname
, TRUE
);
3048 * term_cols:amount */
3049 fullname
= "term_cols";
3050 if (match_optname(opts
, fullname
, sizeof("term_cols")-1, TRUE
)) {
3051 op
= string_for_opt(opts
, negated
);
3052 iflags
.wc2_term_cols
= op
? atoi(op
) : 0;
3053 if (negated
) bad_negation(fullname
, FALSE
);
3058 * term_rows:amount */
3059 fullname
= "term_rows";
3060 if (match_optname(opts
, fullname
, sizeof("term_rows")-1, TRUE
)) {
3061 op
= string_for_opt(opts
, negated
);
3062 iflags
.wc2_term_rows
= op
? atoi(op
) : 0;
3063 if (negated
) bad_negation(fullname
, FALSE
);
3070 fullname
= "petattr";
3071 if (match_optname(opts
, fullname
, sizeof("petattr")-1, TRUE
)) {
3072 op
= string_for_opt(opts
, negated
);
3073 if (op
&& !negated
) {
3074 iflags
.wc2_petattr
= atoi(op
);
3077 } else if (negated
) bad_negation(fullname
, TRUE
);
3083 * windowborders:n */
3084 fullname
= "windowborders";
3085 if (match_optname(opts
, fullname
, sizeof("windowborders")-1, TRUE
)) {
3086 op
= string_for_opt(opts
, negated
);
3087 if (negated
&& op
) bad_negation(fullname
, TRUE
);
3090 iflags
.wc2_windowborders
= 2; /* Off */
3092 iflags
.wc2_windowborders
= 1; /* On */
3093 else /* Value supplied */
3094 iflags
.wc2_windowborders
= atoi(op
);
3095 if ((iflags
.wc2_windowborders
> 3) ||
3096 (iflags
.wc2_windowborders
< 1)) {
3097 iflags
.wc2_windowborders
= 0;
3104 /* menustyle:traditional or combo or full or partial */
3105 if (match_optname(opts
, "menustyle", 4, TRUE
)) {
3107 boolean val_required
= (strlen(opts
) > 5 && !negated
);
3109 if (!(op
= string_for_opt(opts
, !val_required
))) {
3110 if (val_required
) return; /* string_for_opt gave feedback */
3111 tmp
= negated
? 'n' : 'f';
3116 case 'n': /* none */
3117 case 't': /* traditional */
3118 flags
.menu_style
= MENU_TRADITIONAL
;
3120 case 'c': /* combo: trad.class sel+menu */
3121 flags
.menu_style
= MENU_COMBINATION
;
3123 case 'p': /* partial: no class menu */
3124 flags
.menu_style
= MENU_PARTIAL
;
3126 case 'f': /* full: class menu + menu */
3127 flags
.menu_style
= MENU_FULL
;
3135 fullname
= "menu_headings";
3136 if (match_optname(opts
, fullname
, 12, TRUE
)) {
3138 bad_negation(fullname
, FALSE
);
3141 else if (!(opts
= string_for_env_opt(fullname
, opts
, FALSE
))) {
3144 if (!strcmpi(opts
,"bold"))
3145 iflags
.menu_headings
= ATR_BOLD
;
3146 else if (!strcmpi(opts
,"inverse"))
3147 iflags
.menu_headings
= ATR_INVERSE
;
3148 else if (!strcmpi(opts
,"underline"))
3149 iflags
.menu_headings
= ATR_ULINE
;
3155 /* check for menu command mapping */
3156 for (i
= 0; i
< NUM_MENU_CMDS
; i
++) {
3157 fullname
= default_menu_cmd_info
[i
].name
;
3158 if (match_optname(opts
, fullname
, (int)strlen(fullname
), TRUE
)) {
3160 bad_negation(fullname
, FALSE
);
3161 else if ((op
= string_for_opt(opts
, FALSE
)) != 0) {
3163 char c
, op_buf
[BUFSZ
];
3164 boolean isbad
= FALSE
;
3166 escapes(op
, op_buf
);
3169 if (c
== 0 || c
== '\r' || c
== '\n' || c
== '\033' ||
3170 c
== ' ' || digit(c
) || (letter(c
) && c
!= '@'))
3172 else /* reject default object class symbols */
3173 for (j
= 1; j
< MAXOCLASSES
; j
++)
3174 if (c
== def_oc_syms
[i
]) {
3182 add_menu_cmd_alias(c
, default_menu_cmd_info
[i
].cmd
);
3188 /* OK, if we still haven't recognized the option, check the boolean
3191 for (i
= 0; boolopt
[i
].name
; i
++) {
3192 if (match_optname(opts
, boolopt
[i
].name
, 3, FALSE
)) {
3193 /* options that don't exist */
3194 if (!boolopt
[i
].addr
) {
3195 if (!initial
&& !negated
)
3196 pline_The("\"%s\" option is not available.",
3200 /* options that must come from config file */
3201 if (!initial
&& (boolopt
[i
].optflags
== SET_IN_FILE
)) {
3202 rejectoption(boolopt
[i
].name
);
3206 if (iflags
.debug_fuzzer
&& !initial
) {
3207 /* don't randomly toggle this/these */
3208 if (boolopt
[i
].addr
== &flags
.silent
) return;
3209 if (boolopt
[i
].addr
== &flags
.ins_chkpt
) return;
3212 *(boolopt
[i
].addr
) = !negated
;
3214 duplicate_opt_detection(boolopt
[i
].name
, 0);
3216 #if defined(TERMLIB) || defined(ASCIIGRAPH) || defined(MAC_GRAPHICS_ENV) || defined(CURSES_GRAPHICS)
3219 || (boolopt
[i
].addr
) == &iflags
.DECgraphics
3222 || (boolopt
[i
].addr
) == &iflags
.IBMgraphics
3224 # ifdef MAC_GRAPHICS_ENV
3225 || (boolopt
[i
].addr
) == &iflags
.MACgraphics
3227 # ifdef CURSES_GRAPHICS
3228 || (boolopt
[i
].addr
) == &iflags
.cursesgraphics
3231 # ifdef REINCARNATION
3232 /* [ALI] GTK port may call doset() after initial
3233 * but before we start a game. Prevent false match.
3235 if (!initial
&& u
.uz
.dlevel
&&
3236 Is_rogue_level(&u
.uz
))
3237 assign_rogue_graphics(isrougelike
);
3241 if ((boolopt
[i
].addr
) == &iflags
.DECgraphics
)
3242 switch_graphics(iflags
.DECgraphics
?
3243 DEC_GRAPHICS
: ASCII_GRAPHICS
);
3246 if ((boolopt
[i
].addr
) == &iflags
.IBMgraphics
)
3247 switch_graphics(iflags
.IBMgraphics
?
3248 IBM_GRAPHICS
: ASCII_GRAPHICS
);
3250 # ifdef MAC_GRAPHICS_ENV
3251 if ((boolopt
[i
].addr
) == &iflags
.MACgraphics
)
3252 switch_graphics(iflags
.MACgraphics
?
3253 MAC_GRAPHICS
: ASCII_GRAPHICS
);
3255 # ifdef CURSES_GRAPHICS
3256 if ((boolopt
[i
].addr
) == &iflags
.cursesgraphics
)
3257 switch_graphics(iflags
.cursesgraphics
?
3258 CURS_GRAPHICS
: ASCII_GRAPHICS
);
3260 # ifdef REINCARNATION
3261 if (!initial
&& u
.uz
.dlevel
&&
3262 Is_rogue_level(&u
.uz
))
3263 assign_rogue_graphics(TRUE
);
3266 #endif /* TERMLIB || ASCIIGRAPH || MAC_GRAPHICS_ENV */
3268 /* only do processing below if setting with doset() */
3269 if (initial
) return;
3271 if ((boolopt
[i
].addr
) == &flags
.time
3272 || (boolopt
[i
].addr
) == &flags
.showexp
3273 || (boolopt
[i
].addr
) == &flags
.showscore
3275 || (boolopt
[i
].addr
) == &flags
.showweight
3277 || (boolopt
[i
].addr
) == &flags
.showmc
3278 || (boolopt
[i
].addr
) == &flags
.showmovement
3279 || (boolopt
[i
].addr
) == &flags
.showsanity
3280 || (boolopt
[i
].addr
) == &flags
.showlongstats
3281 || (boolopt
[i
].addr
) == &flags
.showsymbiotehp
3286 else if ((boolopt
[i
].addr
) == &flags
.epyxmode
) {
3287 if (isrougelike
|| Is_rogue_level(&u
.uz
)) assign_rogue_graphics(TRUE
);
3291 else if ((boolopt
[i
].addr
) == &flags
.invlet_constant
) {
3292 if (flags
.invlet_constant
) reassign();
3295 else if ((boolopt
[i
].addr
) == &flags
.biff
) {
3296 if (flags
.biff
) lan_mail_init();
3297 else lan_mail_finish();
3300 else if ((boolopt
[i
].addr
) == &flags
.lit_corridor
) {
3302 * All corridor squares seen via night vision or
3303 * candles & lamps change. Update them by calling
3304 * newsym() on them. Don't do this if we are
3305 * initializing the options --- the vision system
3310 vision_recalc(2); /* shut down vision */
3311 vision_full_recalc
= 1; /* delayed recalc */
3312 if (iflags
.use_color
) need_redraw
= TRUE
; /* darkroom refresh */
3315 else if ((boolopt
[i
].addr
) == &iflags
.use_inverse
||
3316 (boolopt
[i
].addr
) == &iflags
.showrace
||
3317 (boolopt
[i
].addr
) == &iflags
.hilite_pet
||
3318 (boolopt
[i
].addr
) == &iflags
.wc2_guicolor
) {
3321 #ifdef CURSES_GRAPHICS
3322 else if ((boolopt
[i
].addr
) == &iflags
.cursesgraphics
) {
3327 else if ((boolopt
[i
].addr
) == &iflags
.use_color
) {
3330 if ((boolopt
[i
].addr
) == &iflags
.use_color
3340 else if ((boolopt
[i
].addr
) == &flags
.perm_invent
)
3347 /* out of valid options */
3353 register char *opts
;
3357 const char *fullname
;
3359 if (strlen(opts
) > BUFSZ
/2) {
3360 badauthoption("option too long");
3364 /* strip leading and trailing white space */
3365 while (isspace((int)*opts
)) opts
++;
3367 while (--op
>= opts
&& isspace((int)*op
)) *op
= '\0';
3371 while ((*opts
== '!') || !strncmpi(opts
, "no", 2)) {
3372 if (*opts
== '!') opts
++; else opts
+= 2;
3376 /* compound options */
3379 if (match_optname(opts
, fullname
, 4, TRUE
)) {
3380 if (negated
) bad_negation(fullname
, FALSE
);
3381 else if ((op
= string_for_auth_opt(opts
, FALSE
)) != 0)
3382 nmcpy(authentication
.prog
, op
, BUFSZ
);
3387 if (match_optname(opts
, fullname
, 4, TRUE
)) {
3388 if (negated
) bad_negation(fullname
, FALSE
);
3389 else if ((op
= string_for_auth_opt(opts
, FALSE
)) != 0)
3390 nmcpy(authentication
.args
, op
, BUFSZ
);
3394 /* out of valid options */
3395 badauthoption(opts
);
3399 parseauthentication(opts
)
3400 register char *opts
;
3404 /* Initial values */
3405 authentication
.prog
[0] = '\0';
3406 authentication
.args
[0] = '\0';
3408 while ((op
= index(opts
, ',')) != 0) {
3415 if (!authentication
.prog
[0] && authentication
.args
[0])
3416 badauthoption("Arguments given but no program specified.");
3420 parsetilesetopt(opts
)
3421 register char *opts
;
3426 const char *fullname
;
3428 if (strlen(opts
) > BUFSZ
/2) {
3429 badtileoption("option too long");
3433 /* strip leading and trailing white space */
3434 while (isspace((int)*opts
)) opts
++;
3436 while (--op
>= opts
&& isspace((int)*op
)) *op
= '\0';
3440 while ((*opts
== '!') || !strncmpi(opts
, "no", 2)) {
3441 if (*opts
== '!') opts
++; else opts
+= 2;
3445 /* compound options */
3448 if (match_optname(opts
, fullname
, 4, TRUE
)) {
3449 if (negated
) bad_negation(fullname
, FALSE
);
3450 else if ((op
= string_for_tile_opt(opts
, FALSE
)) != 0)
3451 nmcpy(tilesets
[no_tilesets
].name
, op
, PL_PSIZ
);
3455 fullname
= "filename";
3456 if (match_optname(opts
, fullname
, 4, TRUE
)) {
3457 if (negated
) bad_negation(fullname
, FALSE
);
3458 else if ((op
= string_for_tile_opt(opts
, FALSE
)) != 0)
3459 nmcpy(tilesets
[no_tilesets
].file
, op
,
3460 TILESET_MAX_FILENAME
);
3464 /* OK, if we still haven't recognized the option, check the boolean
3467 for (i
= 0; booltileopt
[i
].name
; i
++) {
3468 if (match_optname(opts
, booltileopt
[i
].name
, 3, FALSE
)) {
3470 tilesets
[no_tilesets
].flags
&= ~booltileopt
[i
].flag
;
3472 tilesets
[no_tilesets
].flags
|= booltileopt
[i
].flag
;
3477 /* out of valid options */
3478 badtileoption(opts
);
3483 register char *opts
;
3488 if (no_tilesets
>= MAXNOTILESETS
) {
3489 badtileoption("too many tilesets");
3493 /* Initial values */
3494 tilesets
[no_tilesets
].name
[0] = '\0';
3495 tilesets
[no_tilesets
].file
[0] = '\0';
3496 tilesets
[no_tilesets
].flags
= 0;
3497 for (i
= 0; booltileopt
[i
].name
; i
++)
3498 tilesets
[no_tilesets
].flags
|= booltileopt
[i
].initvalue
;
3500 while ((op
= index(opts
, ',')) != 0) {
3502 parsetilesetopt(opts
);
3505 parsetilesetopt(opts
);
3507 if (tilesets
[no_tilesets
].name
[0] == '\0' ||
3508 tilesets
[no_tilesets
].file
[0] == '\0') {
3509 badtileoption("Incomplete tileset definition.");
3516 static NEARDATA
const char *menutype
[] = {
3517 "traditional", "combination", "partial", "full"
3520 static NEARDATA
const char *burdentype
[] = {
3521 "unencumbered", "burdened", "stressed",
3522 "strained", "overtaxed", "overloaded"
3525 static NEARDATA
const char *runmodes
[] = {
3526 "teleport", "run", "walk", "crawl"
3529 static NEARDATA
const char *sortltype
[] = {
3530 "none", "loot", "full"
3534 * Convert the given string of object classes to a string of default object
3543 while ((i
= (int) *src
++) != 0) {
3544 if (i
< 0 || i
>= MAXOCLASSES
)
3545 impossible("oc_to_str: illegal object class %d", i
);
3547 *dest
++ = def_oc_syms
[i
];
3553 * Add the given mapping to the menu command map list. Always keep the
3554 * maps valid C strings.
3557 add_menu_cmd_alias(from_ch
, to_ch
)
3558 char from_ch
, to_ch
;
3560 if (n_menu_mapped
>= MAX_MENU_MAPPED_CMDS
)
3561 pline("out of menu map space.");
3563 mapped_menu_cmds
[n_menu_mapped
] = from_ch
;
3564 mapped_menu_op
[n_menu_mapped
] = to_ch
;
3566 mapped_menu_cmds
[n_menu_mapped
] = 0;
3567 mapped_menu_op
[n_menu_mapped
] = 0;
3572 * Map the given character to its corresponding menu command. If it
3573 * doesn't match anything, just return the original.
3579 char *found
= index(mapped_menu_cmds
, ch
);
3581 int idx
= found
- mapped_menu_cmds
;
3582 ch
= mapped_menu_op
[idx
];
3588 #if defined(MICRO) || defined(MAC) || defined(WIN32)
3589 # define OPTIONS_HEADING "OPTIONS"
3591 # define OPTIONS_HEADING NETHACK_ENV_OPTIONS
3594 static char fmtstr_doset_add_menu
[] = "%s%-15s [%s] ";
3595 static char fmtstr_doset_add_menu_tab
[] = "%s\t[%s]";
3598 doset_add_menu(win
, option
, indexoffset
)
3599 winid win
; /* window to add to */
3600 const char *option
; /* option name */
3601 int indexoffset
; /* value to add to index in compopt[], or zero
3602 if option cannot be changed */
3604 const char *value
= "unknown"; /* current value */
3605 char buf
[BUFSZ
], buf2
[BUFSZ
];
3610 if (indexoffset
== 0) {
3612 value
= get_compopt_value(option
, buf2
);
3614 for (i
=0; compopt
[i
].name
; i
++)
3615 if (strcmp(option
, compopt
[i
].name
) == 0) break;
3617 if (compopt
[i
].name
) {
3618 any
.a_int
= i
+ 1 + indexoffset
;
3619 value
= get_compopt_value(option
, buf2
);
3621 /* We are trying to add an option not found in compopt[].
3622 This is almost certainly bad, but we'll let it through anyway
3623 (with a zero value, so it can't be selected). */
3627 /* " " replaces "a - " -- assumes menus follow that style */
3628 if (!iflags
.menu_tab_sep
)
3629 sprintf(buf
, fmtstr_doset_add_menu
, any
.a_int
? "" : " ", option
, value
);
3631 sprintf(buf
, fmtstr_doset_add_menu_tab
, option
, value
);
3632 add_menu(win
, NO_GLYPH
, &any
, 0, 0, ATR_NONE
, buf
, MENU_UNSELECTED
);
3635 /* Changing options via menu by Per Liboriussen */
3639 char buf
[BUFSZ
], buf2
[BUFSZ
];
3640 int i
, pass
, boolcount
, pick_cnt
, pick_idx
, opt_indx
;
3644 menu_item
*pick_list
;
3645 int indexoffset
, startpass
, endpass
;
3646 boolean setinitial
= FALSE
, fromfile
= FALSE
;
3647 int biggest_name
= 0;
3649 if (moves
< 50 && iflags
.numpadmessage
) {
3651 if (!(iflags
.num_pad
)) {
3652 if (yn("Do you want to turn on the number pad?") == 'y') {
3654 iflags
.num_pad_mode
= 1;
3655 iflags
.numpadmessage
= FALSE
;
3656 } else if (yn("Do you want to turn this annoying message off?") == 'y') {
3657 iflags
.numpadmessage
= FALSE
;
3658 pline("In order to turn the message off for all subsequent games too, add OPTIONS=nonumpadmessage to your configuration file.");
3660 if (u
.annoyingmessages
++ > 5) iflags
.numpadmessage
= FALSE
;
3663 else if (iflags
.num_pad
) {
3664 if (yn("Do you want to turn off the number pad?") == 'y') {
3666 iflags
.num_pad_mode
= 0;
3667 iflags
.numpadmessage
= FALSE
;
3668 } else if (yn("Do you want to turn this annoying message off?") == 'y') {
3669 iflags
.numpadmessage
= FALSE
;
3670 pline("In order to turn the message off for all subsequent games too, add OPTIONS=nonumpadmessage to your configuration file.");
3672 if (u
.annoyingmessages
++ > 5) iflags
.numpadmessage
= FALSE
;
3677 tmpwin
= create_nhwindow(NHW_MENU
);
3682 /* I'm just so sick of seeing players spend half an hour staring at the boolean options when all they want to do is
3683 * obviously to turn the goddamn number pad on. --Amy */
3684 add_menu(tmpwin
, NO_GLYPH
, &any
, 0, 0, iflags
.menu_headings
,
3685 "IMPORTANT: The number_pad option is all the way down at the compound options,", MENU_UNSELECTED
);
3686 add_menu(tmpwin
, NO_GLYPH
, &any
, 0, 0, iflags
.menu_headings
,
3687 "so scroll down there if you want to turn the number pad on!!!", MENU_UNSELECTED
);
3688 add_menu(tmpwin
, NO_GLYPH
, &any
, 0, 0, iflags
.menu_headings
,
3689 "Scroll with the space bar or the > key, NOT the arrow keys!", MENU_UNSELECTED
);
3691 add_menu(tmpwin
, NO_GLYPH
, &any
, 0, 0, ATR_NONE
,
3692 " ", MENU_UNSELECTED
);
3694 add_menu(tmpwin
, NO_GLYPH
, &any
, 0, 0, iflags
.menu_headings
,
3695 "Booleans (selecting will toggle value):", MENU_UNSELECTED
);
3697 /* first list any other non-modifiable booleans, then modifiable ones */
3698 for (pass
= 0; pass
<= 1; pass
++)
3699 for (i
= 0; boolopt
[i
].name
; i
++)
3700 if ((bool_p
= boolopt
[i
].addr
) != 0 &&
3701 ((boolopt
[i
].optflags
== DISP_IN_GAME
&& pass
== 0) ||
3702 (boolopt
[i
].optflags
== SET_IN_GAME
&& pass
== 1))) {
3703 if (bool_p
== &flags
.female
) continue; /* obsolete */
3706 if (bool_p
== &iflags
.sanity_check
&& !wizard
) continue;
3708 if (bool_p
== &iflags
.menu_tab_sep
&& !wizard
) continue;
3710 if (is_wc_option(boolopt
[i
].name
) &&
3711 !wc_supported(boolopt
[i
].name
)) continue;
3712 if (is_wc2_option(boolopt
[i
].name
) &&
3713 !wc2_supported(boolopt
[i
].name
)) continue;
3714 any
.a_int
= (pass
== 0) ? 0 : i
+ 1;
3715 if (!iflags
.menu_tab_sep
)
3716 sprintf(buf
, "%s%-13s [%s]",
3717 pass
== 0 ? " " : "",
3718 boolopt
[i
].name
, *bool_p
? "true" : "false");
3720 sprintf(buf
, "%s\t[%s]",
3721 boolopt
[i
].name
, *bool_p
? "true" : "false");
3722 add_menu(tmpwin
, NO_GLYPH
, &any
, 0, 0,
3723 ATR_NONE
, buf
, MENU_UNSELECTED
);
3727 indexoffset
= boolcount
;
3729 add_menu(tmpwin
, NO_GLYPH
, &any
, 0, 0, ATR_NONE
, "", MENU_UNSELECTED
);
3730 add_menu(tmpwin
, NO_GLYPH
, &any
, 0, 0, iflags
.menu_headings
,
3731 "Compounds (selecting will prompt for new value):",
3734 startpass
= DISP_IN_GAME
;
3735 endpass
= SET_IN_GAME
;
3737 /* spin through the options to find the biggest name
3738 and adjust the format string accordingly if needed */
3740 for (i
= 0; compopt
[i
].name
; i
++)
3741 if (compopt
[i
].optflags
>= startpass
&& compopt
[i
].optflags
<= endpass
&&
3742 strlen(compopt
[i
].name
) > (unsigned) biggest_name
)
3743 biggest_name
= (int) strlen(compopt
[i
].name
);
3744 if (biggest_name
> 30) biggest_name
= 30;
3745 if (!iflags
.menu_tab_sep
)
3746 sprintf(fmtstr_doset_add_menu
, "%%s%%-%ds [%%s]", biggest_name
);
3748 /* deliberately put `name', `role', `race', `gender' first */
3749 doset_add_menu(tmpwin
, "name", 0);
3750 doset_add_menu(tmpwin
, "role", 0);
3751 doset_add_menu(tmpwin
, "race", 0);
3752 doset_add_menu(tmpwin
, "gender", 0);
3754 for (pass
= startpass
; pass
<= endpass
; pass
++)
3755 for (i
= 0; compopt
[i
].name
; i
++)
3756 if (compopt
[i
].optflags
== pass
) {
3757 if (!strcmp(compopt
[i
].name
, "name") ||
3758 !strcmp(compopt
[i
].name
, "role") ||
3759 !strcmp(compopt
[i
].name
, "race") ||
3760 !strcmp(compopt
[i
].name
, "gender"))
3762 else if (is_wc_option(compopt
[i
].name
) &&
3763 !wc_supported(compopt
[i
].name
))
3765 else if (is_wc2_option(compopt
[i
].name
) &&
3766 !wc2_supported(compopt
[i
].name
))
3769 doset_add_menu(tmpwin
, compopt
[i
].name
,
3770 (pass
== DISP_IN_GAME
) ? 0 : indexoffset
);
3772 #ifdef AUTOPICKUP_EXCEPTIONS
3774 sprintf(buf
, "autopickup exceptions (%d currently set)",
3775 count_ape_maps((int *)0, (int *)0));
3776 add_menu(tmpwin
, NO_GLYPH
, &any
, 0, 0, ATR_NONE
, buf
, MENU_UNSELECTED
);
3778 #endif /* AUTOPICKUP_EXCEPTIONS */
3779 #ifdef PREFIXES_IN_USE
3781 add_menu(tmpwin
, NO_GLYPH
, &any
, 0, 0, ATR_NONE
, "", MENU_UNSELECTED
);
3782 add_menu(tmpwin
, NO_GLYPH
, &any
, 0, 0, iflags
.menu_headings
,
3783 "Variable playground locations:", MENU_UNSELECTED
);
3784 for (i
= 0; i
< PREFIX_COUNT
; i
++)
3785 doset_add_menu(tmpwin
, fqn_prefix_names
[i
], 0);
3788 add_menu(tmpwin
, NO_GLYPH
, &any
, 0, 0, ATR_NONE
,
3789 " ", MENU_UNSELECTED
);
3790 add_menu(tmpwin
, NO_GLYPH
, &any
, 0, 0, iflags
.menu_headings
,
3791 "Attention: DO NOT press ESC here or you'll cancel your changes!!", MENU_UNSELECTED
);
3792 add_menu(tmpwin
, NO_GLYPH
, &any
, 0, 0, iflags
.menu_headings
,
3793 "Scroll out of the menu via spacebar or > to save your changes!!!", MENU_UNSELECTED
);
3795 end_menu(tmpwin
, "Set what options?");
3796 need_redraw
= FALSE
;
3797 if ((pick_cnt
= select_menu(tmpwin
, PICK_ANY
, &pick_list
)) > 0) {
3799 * Walk down the selection list and either invert the booleans
3800 * or prompt for new values. In most cases, call parseoptions()
3801 * to take care of options that require special attention, like
3804 for (pick_idx
= 0; pick_idx
< pick_cnt
; ++pick_idx
) {
3805 opt_indx
= pick_list
[pick_idx
].item
.a_int
- 1;
3806 #ifdef AUTOPICKUP_EXCEPTIONS
3807 if (opt_indx
== -2) {
3808 special_handling("autopickup_exception",
3809 setinitial
, fromfile
);
3812 if (opt_indx
< boolcount
) {
3813 /* boolean option */
3814 sprintf(buf
, "%s%s", *boolopt
[opt_indx
].addr
? "!" : "",
3815 boolopt
[opt_indx
].name
);
3816 parseoptions(buf
, setinitial
, fromfile
);
3817 if (wc_supported(boolopt
[opt_indx
].name
) ||
3818 wc2_supported(boolopt
[opt_indx
].name
))
3819 preference_update(boolopt
[opt_indx
].name
);
3821 /* compound option */
3822 opt_indx
-= boolcount
;
3824 if (!special_handling(compopt
[opt_indx
].name
,
3825 setinitial
, fromfile
)) {
3826 sprintf(buf
, "Set %s to what?", compopt
[opt_indx
].name
);
3828 if (buf2
[0] == '\033')
3830 sprintf(buf
, "%s:%s", compopt
[opt_indx
].name
, buf2
);
3832 parseoptions(buf
, setinitial
, fromfile
);
3834 if (wc_supported(compopt
[opt_indx
].name
) ||
3835 wc2_supported(compopt
[opt_indx
].name
))
3836 preference_update(compopt
[opt_indx
].name
);
3839 free((void *)pick_list
);
3840 pick_list
= (menu_item
*)0;
3843 destroy_nhwindow(tmpwin
);
3845 if (flags
.lit_corridor
&& iflags
.use_color
) {
3846 showsyms
[S_darkroom
]=showsyms
[S_room
];
3848 showsyms
[S_darkroom
]=showsyms
[S_stone
];
3850 if (!(InterfaceScrewed
|| u
.uprops
[INTERFACE_SCREW
].extrinsic
|| have_interfacescrewstone())) (void) doredraw();
3856 special_handling(optname
, setinitial
, setfromfile
)
3857 const char *optname
;
3858 boolean setinitial
,setfromfile
;
3864 boolean retval
= FALSE
;
3866 /* Special handling of menustyle, pickup_burden, pickup_types,
3867 * disclose, runmode, msg_window, menu_headings, and number_pad options.
3868 #ifdef AUTOPICKUP_EXCEPTIONS
3869 * Also takes care of interactive autopickup_exception_handling changes.
3872 if (!strcmp("menustyle", optname
)) {
3873 const char *style_name
;
3874 menu_item
*style_pick
= (menu_item
*)0;
3875 tmpwin
= create_nhwindow(NHW_MENU
);
3877 for (i
= 0; i
< SIZE(menutype
); i
++) {
3878 style_name
= menutype
[i
];
3879 /* note: separate `style_name' variable used
3880 to avoid an optimizer bug in VAX C V2.3 */
3882 add_menu(tmpwin
, NO_GLYPH
, &any
, *style_name
, 0,
3883 ATR_NONE
, style_name
, MENU_UNSELECTED
);
3885 end_menu(tmpwin
, "Select menustyle:");
3886 if (select_menu(tmpwin
, PICK_ONE
, &style_pick
) > 0) {
3887 flags
.menu_style
= style_pick
->item
.a_int
- 1;
3888 free((void *)style_pick
);
3890 destroy_nhwindow(tmpwin
);
3892 } else if (!strcmp("pickup_burden", optname
)) {
3893 const char *burden_name
, *burden_letters
= "ubsntl";
3894 menu_item
*burden_pick
= (menu_item
*)0;
3895 tmpwin
= create_nhwindow(NHW_MENU
);
3897 for (i
= 0; i
< SIZE(burdentype
); i
++) {
3898 burden_name
= burdentype
[i
];
3900 add_menu(tmpwin
, NO_GLYPH
, &any
, burden_letters
[i
], 0,
3901 ATR_NONE
, burden_name
, MENU_UNSELECTED
);
3903 end_menu(tmpwin
, "Select encumbrance level:");
3904 if (select_menu(tmpwin
, PICK_ONE
, &burden_pick
) > 0) {
3905 flags
.pickup_burden
= burden_pick
->item
.a_int
- 1;
3906 free((void *)burden_pick
);
3908 destroy_nhwindow(tmpwin
);
3910 } else if (!strcmp("pickup_types", optname
)) {
3911 /* parseoptions will prompt for the list of types */
3912 parseoptions(strcpy(buf
, "pickup_types"), setinitial
, setfromfile
);
3914 } else if (!strcmp("disclose", optname
)) {
3915 int pick_cnt
, pick_idx
, opt_idx
;
3916 menu_item
*disclosure_category_pick
= (menu_item
*)0;
3918 * The order of disclose_names[]
3919 * must correspond to disclosure_options in decl.h
3921 static const char *disclosure_names
[] = {
3922 "inventory", "attributes", "vanquished", "genocides", "conduct"
3924 int disc_cat
[NUM_DISCLOSURE_OPTIONS
];
3925 const char *disclosure_name
;
3927 tmpwin
= create_nhwindow(NHW_MENU
);
3929 for (i
= 0; i
< NUM_DISCLOSURE_OPTIONS
; i
++) {
3930 disclosure_name
= disclosure_names
[i
];
3932 add_menu(tmpwin
, NO_GLYPH
, &any
, disclosure_options
[i
], 0,
3933 ATR_NONE
, disclosure_name
, MENU_UNSELECTED
);
3936 end_menu(tmpwin
, "Change which disclosure options categories:");
3937 if ((pick_cnt
= select_menu(tmpwin
, PICK_ANY
, &disclosure_category_pick
)) > 0) {
3938 for (pick_idx
= 0; pick_idx
< pick_cnt
; ++pick_idx
) {
3939 opt_idx
= disclosure_category_pick
[pick_idx
].item
.a_int
- 1;
3940 disc_cat
[opt_idx
] = 1;
3942 free((void *)disclosure_category_pick
);
3943 disclosure_category_pick
= (menu_item
*)0;
3945 destroy_nhwindow(tmpwin
);
3947 for (i
= 0; i
< NUM_DISCLOSURE_OPTIONS
; i
++) {
3950 menu_item
*disclosure_option_pick
= (menu_item
*)0;
3951 sprintf(dbuf
, "Disclosure options for %s:", disclosure_names
[i
]);
3952 tmpwin
= create_nhwindow(NHW_MENU
);
3954 any
.a_char
= DISCLOSE_NO_WITHOUT_PROMPT
;
3955 add_menu(tmpwin
, NO_GLYPH
, &any
, 'a', 0,
3956 ATR_NONE
,"Never disclose and don't prompt", MENU_UNSELECTED
);
3958 any
.a_char
= DISCLOSE_YES_WITHOUT_PROMPT
;
3959 add_menu(tmpwin
, NO_GLYPH
, &any
, 'b', 0,
3960 ATR_NONE
,"Always disclose and don't prompt", MENU_UNSELECTED
);
3962 any
.a_char
= DISCLOSE_PROMPT_DEFAULT_NO
;
3963 add_menu(tmpwin
, NO_GLYPH
, &any
, 'c', 0,
3964 ATR_NONE
,"Prompt and default answer to \"No\"", MENU_UNSELECTED
);
3966 any
.a_char
= DISCLOSE_PROMPT_DEFAULT_YES
;
3967 add_menu(tmpwin
, NO_GLYPH
, &any
, 'd', 0,
3968 ATR_NONE
,"Prompt and default answer to \"Yes\"", MENU_UNSELECTED
);
3969 end_menu(tmpwin
, dbuf
);
3970 if (select_menu(tmpwin
, PICK_ONE
, &disclosure_option_pick
) > 0) {
3971 flags
.end_disclose
[i
] = disclosure_option_pick
->item
.a_char
;
3972 free((void *)disclosure_option_pick
);
3974 destroy_nhwindow(tmpwin
);
3978 } else if (!strcmp("runmode", optname
)) {
3979 const char *mode_name
;
3980 menu_item
*mode_pick
= (menu_item
*)0;
3981 tmpwin
= create_nhwindow(NHW_MENU
);
3983 for (i
= 0; i
< SIZE(runmodes
); i
++) {
3984 mode_name
= runmodes
[i
];
3986 add_menu(tmpwin
, NO_GLYPH
, &any
, *mode_name
, 0,
3987 ATR_NONE
, mode_name
, MENU_UNSELECTED
);
3989 end_menu(tmpwin
, "Select run/travel display mode:");
3990 if (select_menu(tmpwin
, PICK_ONE
, &mode_pick
) > 0) {
3991 iflags
.runmode
= mode_pick
->item
.a_int
- 1;
3992 free((void *)mode_pick
);
3994 destroy_nhwindow(tmpwin
);
3996 } else if (!strcmp("sortloot", optname
)) {
3997 const char *sortl_name
;
3998 menu_item
*sortl_pick
= (menu_item
*)0;
3999 tmpwin
= create_nhwindow(NHW_MENU
);
4001 for (i
= 0; i
< SIZE(sortltype
); i
++) {
4002 sortl_name
= sortltype
[i
];
4003 any
.a_char
= *sortl_name
;
4004 add_menu(tmpwin
, NO_GLYPH
, &any
, *sortl_name
, 0,
4005 ATR_NONE
, sortl_name
, MENU_UNSELECTED
);
4007 end_menu(tmpwin
, "Select loot sorting type:");
4008 if (select_menu(tmpwin
, PICK_ONE
, &sortl_pick
) > 0) {
4009 iflags
.sortloot
= sortl_pick
->item
.a_char
;
4010 free((void *)sortl_pick
);
4012 destroy_nhwindow(tmpwin
);
4016 else if (!strcmp("msg_window", optname
)) {
4017 /* by Christian W. Cooper */
4018 menu_item
*window_pick
= (menu_item
*)0;
4019 tmpwin
= create_nhwindow(NHW_MENU
);
4022 add_menu(tmpwin
, NO_GLYPH
, &any
, 's', 0,
4023 ATR_NONE
, "single", MENU_UNSELECTED
);
4025 add_menu(tmpwin
, NO_GLYPH
, &any
, 'c', 0,
4026 ATR_NONE
, "combination", MENU_UNSELECTED
);
4028 add_menu(tmpwin
, NO_GLYPH
, &any
, 'f', 0,
4029 ATR_NONE
, "full", MENU_UNSELECTED
);
4031 add_menu(tmpwin
, NO_GLYPH
, &any
, 'r', 0,
4032 ATR_NONE
, "reversed", MENU_UNSELECTED
);
4033 end_menu(tmpwin
, "Select message history display type:");
4034 if (select_menu(tmpwin
, PICK_ONE
, &window_pick
) > 0) {
4035 iflags
.prevmsg_window
= window_pick
->item
.a_char
;
4036 free((void *)window_pick
);
4038 destroy_nhwindow(tmpwin
);
4042 else if (!strcmp("align_message", optname
) ||
4043 !strcmp("align_status", optname
)) {
4044 menu_item
*window_pick
= (menu_item
*)0;
4046 boolean msg
= (*(optname
+6) == 'm');
4048 tmpwin
= create_nhwindow(NHW_MENU
);
4050 any
.a_int
= ALIGN_TOP
;
4051 add_menu(tmpwin
, NO_GLYPH
, &any
, 't', 0,
4052 ATR_NONE
, "top", MENU_UNSELECTED
);
4053 any
.a_int
= ALIGN_BOTTOM
;
4054 add_menu(tmpwin
, NO_GLYPH
, &any
, 'b', 0,
4055 ATR_NONE
, "bottom", MENU_UNSELECTED
);
4056 any
.a_int
= ALIGN_LEFT
;
4057 add_menu(tmpwin
, NO_GLYPH
, &any
, 'l', 0,
4058 ATR_NONE
, "left", MENU_UNSELECTED
);
4059 any
.a_int
= ALIGN_RIGHT
;
4060 add_menu(tmpwin
, NO_GLYPH
, &any
, 'r', 0,
4061 ATR_NONE
, "right", MENU_UNSELECTED
);
4062 sprintf(abuf
, "Select %s window placement relative to the map:",
4063 msg
? "message" : "status");
4064 end_menu(tmpwin
, abuf
);
4065 if (select_menu(tmpwin
, PICK_ONE
, &window_pick
) > 0) {
4066 if (msg
) iflags
.wc_align_message
= window_pick
->item
.a_int
;
4067 else iflags
.wc_align_status
= window_pick
->item
.a_int
;
4068 free((void *)window_pick
);
4070 destroy_nhwindow(tmpwin
);
4072 } else if (!strcmp("number_pad", optname
)) {
4073 static const char *npchoices
[3] =
4074 {"0 (off)", "1 (on)", "2 (on, DOS compatible)"};
4075 const char *npletters
= "abc";
4076 menu_item
*mode_pick
= (menu_item
*)0;
4078 tmpwin
= create_nhwindow(NHW_MENU
);
4080 for (i
= 0; i
< SIZE(npchoices
); i
++) {
4082 add_menu(tmpwin
, NO_GLYPH
, &any
, npletters
[i
], 0,
4083 ATR_NONE
, npchoices
[i
], MENU_UNSELECTED
);
4085 end_menu(tmpwin
, "Select number_pad mode:");
4086 if (select_menu(tmpwin
, PICK_ONE
, &mode_pick
) > 0) {
4087 int mode
= mode_pick
->item
.a_int
- 1;
4091 iflags
.num_pad_mode
= 1;
4095 iflags
.num_pad_mode
= 0;
4100 iflags
.num_pad_mode
= 0;
4102 free((void *)mode_pick
);
4103 number_pad(iflags
.num_pad
);
4105 destroy_nhwindow(tmpwin
);
4107 } else if (!strcmp("menu_headings", optname
)) {
4108 static const char *mhchoices
[3] = {"bold", "inverse", "underline"};
4109 const char *npletters
= "biu";
4110 menu_item
*mode_pick
= (menu_item
*)0;
4112 tmpwin
= create_nhwindow(NHW_MENU
);
4114 for (i
= 0; i
< SIZE(mhchoices
); i
++) {
4116 add_menu(tmpwin
, NO_GLYPH
, &any
, npletters
[i
], 0,
4117 ATR_NONE
, mhchoices
[i
], MENU_UNSELECTED
);
4119 end_menu(tmpwin
, "How to highlight menu headings:");
4120 if (select_menu(tmpwin
, PICK_ONE
, &mode_pick
) > 0) {
4121 int mode
= mode_pick
->item
.a_int
- 1;
4124 iflags
.menu_headings
= ATR_ULINE
;
4127 iflags
.menu_headings
= ATR_BOLD
;
4131 iflags
.menu_headings
= ATR_INVERSE
;
4133 free((void *)mode_pick
);
4135 destroy_nhwindow(tmpwin
);
4137 #ifdef AUTOPICKUP_EXCEPTIONS
4138 } else if (!strcmp("autopickup_exception", optname
)) {
4140 int pick_cnt
, pick_idx
, opt_idx
, pass
;
4141 int totalapes
= 0, numapes
[2] = {0,0};
4142 menu_item
*pick_list
= (menu_item
*)0;
4145 struct autopickup_exception
*ape
;
4146 static const char *action_titles
[] = {
4147 "a", "add new autopickup exception",
4148 "l", "list autopickup exceptions",
4149 "r", "remove existing autopickup exception",
4150 "e", "exit this menu",
4154 totalapes
= count_ape_maps(&numapes
[AP_LEAVE
], &numapes
[AP_GRAB
]);
4155 tmpwin
= create_nhwindow(NHW_MENU
);
4158 for (i
= 0; i
< SIZE(action_titles
) ; i
+= 2) {
4160 if (!totalapes
&& (i
>= 2 && i
< 6)) continue;
4161 add_menu(tmpwin
, NO_GLYPH
, &any
, *action_titles
[i
],
4162 0, ATR_NONE
, action_titles
[i
+1], MENU_UNSELECTED
);
4164 end_menu(tmpwin
, "Do what?");
4165 if ((pick_cnt
= select_menu(tmpwin
, PICK_ONE
, &pick_list
)) > 0) {
4166 for (pick_idx
= 0; pick_idx
< pick_cnt
; ++pick_idx
) {
4167 opt_idx
= pick_list
[pick_idx
].item
.a_int
- 1;
4169 free((void *)pick_list
);
4170 pick_list
= (menu_item
*)0;
4172 destroy_nhwindow(tmpwin
);
4173 if (pick_cnt
< 1) return FALSE
;
4175 if (opt_idx
== 0) { /* add new */
4176 getlin("What new autopickup exception pattern?", &apebuf
[1]);
4177 if (apebuf
[1] == '\033') return FALSE
;
4179 strcat(apebuf
,"\"");
4180 add_autopickup_exception(apebuf
);
4182 } else if (opt_idx
== 3) {
4184 } else { /* remove */
4185 tmpwin
= create_nhwindow(NHW_MENU
);
4187 for (pass
= AP_LEAVE
; pass
<= AP_GRAB
; ++pass
) {
4188 if (numapes
[pass
] == 0) continue;
4189 ape
= iflags
.autopickup_exceptions
[pass
];
4191 add_menu(tmpwin
, NO_GLYPH
, &any
, 0, 0, iflags
.menu_headings
,
4192 (pass
== 0) ? "Never pickup" : "Always pickup",
4194 for (i
= 0; i
< numapes
[pass
] && ape
; i
++) {
4195 any
.a_void
= (opt_idx
== 1) ? 0 : ape
;
4196 sprintf(apebuf
, "\"%s\"", ape
->pattern
);
4197 add_menu(tmpwin
, NO_GLYPH
, &any
,
4198 0, 0, ATR_NONE
, apebuf
, MENU_UNSELECTED
);
4202 sprintf(apebuf
, "%s autopickup exceptions",
4203 (opt_idx
== 1) ? "List of" : "Remove which");
4204 end_menu(tmpwin
, apebuf
);
4205 pick_cnt
= select_menu(tmpwin
,
4206 (opt_idx
== 1) ? PICK_NONE
: PICK_ANY
,
4209 for (pick_idx
= 0; pick_idx
< pick_cnt
; ++pick_idx
)
4210 remove_autopickup_exception(
4211 (struct autopickup_exception
*)pick_list
[pick_idx
].item
.a_void
);
4213 free((void *)pick_list
);
4214 pick_list
= (menu_item
*)0;
4215 destroy_nhwindow(tmpwin
);
4219 #endif /* AUTOPICKUP_EXCEPTIONS */
4224 #define rolestring(val,array,field) ((val >= 0) ? array[val].field : \
4225 (val == ROLE_RANDOM) ? randomrole : none)
4227 /* This is ugly. We have all the option names in the compopt[] array,
4228 but we need to look at each option individually to get the value. */
4229 STATIC_OVL
const char *
4230 get_compopt_value(optname
, buf
)
4231 const char *optname
;
4234 char ocl
[MAXOCLASSES
+1];
4235 static const char none
[] = "(none)", randomrole
[] = "random",
4236 to_be_done
[] = "(to be done)",
4237 defopt
[] = "default",
4242 if (!strcmp(optname
,"align_message"))
4243 sprintf(buf
, "%s", iflags
.wc_align_message
== ALIGN_TOP
? "top" :
4244 iflags
.wc_align_message
== ALIGN_LEFT
? "left" :
4245 iflags
.wc_align_message
== ALIGN_BOTTOM
? "bottom" :
4246 iflags
.wc_align_message
== ALIGN_RIGHT
? "right" :
4248 else if (!strcmp(optname
,"align_status"))
4249 sprintf(buf
, "%s", iflags
.wc_align_status
== ALIGN_TOP
? "top" :
4250 iflags
.wc_align_status
== ALIGN_LEFT
? "left" :
4251 iflags
.wc_align_status
== ALIGN_BOTTOM
? "bottom" :
4252 iflags
.wc_align_status
== ALIGN_RIGHT
? "right" :
4254 else if (!strcmp(optname
,"align"))
4255 sprintf(buf
, "%s", rolestring(flags
.initalign
, aligns
, adj
));
4257 else if (!strcmp(optname
,"altkeyhandler"))
4258 sprintf(buf
, "%s", iflags
.altkeyhandler
[0] ?
4259 iflags
.altkeyhandler
: "default");
4261 else if (!strcmp(optname
, "boulder"))
4262 sprintf(buf
, "%c", iflags
.bouldersym
?
4263 iflags
.bouldersym
: oc_syms
[(int)objects
[BOULDER
].oc_class
]);
4264 else if (!strcmp(optname
, "catname"))
4265 sprintf(buf
, "%s", catname
[0] ? catname
: none
);
4266 /* else if (!strcmp(optname, "coinsname"))
4267 sprintf(buf, "%s", coinsname[0] ? coinsname : none );*/
4268 else if (!strcmp(optname
, "disclose")) {
4269 for (i
= 0; i
< NUM_DISCLOSURE_OPTIONS
; i
++) {
4271 if (i
) strcat(buf
," ");
4273 topt
[0] = flags
.end_disclose
[i
];
4275 topt
[0] = disclosure_options
[i
];
4279 else if (!strcmp(optname
, "dogname"))
4280 sprintf(buf
, "%s", dogname
[0] ? dogname
: none
);
4281 else if (!strcmp(optname
, "dragonname"))
4282 sprintf(buf
, "%s", dragonname
[0] ? dragonname
: none
);
4283 else if (!strcmp(optname
, "monkeyname"))
4284 sprintf(buf
, "%s", monkeyname
[0] ? monkeyname
: none
);
4285 else if (!strcmp(optname
, "parrotname"))
4286 sprintf(buf
, "%s", parrotname
[0] ? parrotname
: none
);
4287 else if (!strcmp(optname
, "girlname"))
4288 sprintf(buf
, "%s", girlname
[0] ? girlname
: none
);
4289 else if (!strcmp(optname
, "boyname"))
4290 sprintf(buf
, "%s", boyname
[0] ? boyname
: none
);
4291 else if (!strcmp(optname
, "ravenname"))
4292 sprintf(buf
, "%s", ravenname
[0] ? ravenname
: none
);
4293 else if (!strcmp(optname
, "plalias"))
4294 sprintf(buf
, "%s", plalias
[0] ? plalias
: none
);
4296 else if (!strcmp(optname
, "dumpfile"))
4297 sprintf(buf
, "%s", dump_fn
[0] ? dump_fn
: none
);
4299 else if (!strcmp(optname
, "dungeon"))
4300 sprintf(buf
, "%s", to_be_done
);
4301 else if (!strcmp(optname
, "effects"))
4302 sprintf(buf
, "%s", to_be_done
);
4303 else if (!strcmp(optname
, "font_map"))
4304 sprintf(buf
, "%s", iflags
.wc_font_map
? iflags
.wc_font_map
: defopt
);
4305 else if (!strcmp(optname
, "font_message"))
4306 sprintf(buf
, "%s", iflags
.wc_font_message
? iflags
.wc_font_message
: defopt
);
4307 else if (!strcmp(optname
, "font_status"))
4308 sprintf(buf
, "%s", iflags
.wc_font_status
? iflags
.wc_font_status
: defopt
);
4309 else if (!strcmp(optname
, "font_menu"))
4310 sprintf(buf
, "%s", iflags
.wc_font_menu
? iflags
.wc_font_menu
: defopt
);
4311 else if (!strcmp(optname
, "font_text"))
4312 sprintf(buf
, "%s", iflags
.wc_font_text
? iflags
.wc_font_text
: defopt
);
4313 else if (!strcmp(optname
, "font_size_map")) {
4314 if (iflags
.wc_fontsiz_map
) sprintf(buf
, "%d", iflags
.wc_fontsiz_map
);
4315 else strcpy(buf
, defopt
);
4317 else if (!strcmp(optname
, "font_size_message")) {
4318 if (iflags
.wc_fontsiz_message
) sprintf(buf
, "%d",
4319 iflags
.wc_fontsiz_message
);
4320 else strcpy(buf
, defopt
);
4322 else if (!strcmp(optname
, "font_size_status")) {
4323 if (iflags
.wc_fontsiz_status
) sprintf(buf
, "%d", iflags
.wc_fontsiz_status
);
4324 else strcpy(buf
, defopt
);
4326 else if (!strcmp(optname
, "font_size_menu")) {
4327 if (iflags
.wc_fontsiz_menu
) sprintf(buf
, "%d", iflags
.wc_fontsiz_menu
);
4328 else strcpy(buf
, defopt
);
4330 else if (!strcmp(optname
, "font_size_text")) {
4331 if (iflags
.wc_fontsiz_text
) sprintf(buf
, "%d",iflags
.wc_fontsiz_text
);
4332 else strcpy(buf
, defopt
);
4334 else if (!strcmp(optname
, "fruit"))
4335 sprintf(buf
, "%s", pl_fruit
);
4336 else if (!strcmp(optname
, "gender"))
4337 sprintf(buf
, "%s", rolestring(flags
.initgend
, genders
, adj
));
4338 else if (!strcmp(optname
, "ghoulname"))
4339 sprintf(buf
, "%s", ghoulname
[0] ? ghoulname
: none
);
4340 else if (!strcmp(optname
, "horsename"))
4341 sprintf(buf
, "%s", horsename
[0] ? horsename
: none
);
4342 /* else if (!strcmp(optname, "lichenname"))
4343 sprintf(buf, "%s", lichenname[0] ? lichenname : none );*/
4344 else if (!strcmp(optname
, "map_mode"))
4346 iflags
.wc_map_mode
== MAP_MODE_TILES
? "tiles" :
4347 iflags
.wc_map_mode
== MAP_MODE_ASCII4x6
? "ascii4x6" :
4348 iflags
.wc_map_mode
== MAP_MODE_ASCII6x8
? "ascii6x8" :
4349 iflags
.wc_map_mode
== MAP_MODE_ASCII8x8
? "ascii8x8" :
4350 iflags
.wc_map_mode
== MAP_MODE_ASCII16x8
? "ascii16x8" :
4351 iflags
.wc_map_mode
== MAP_MODE_ASCII7x12
? "ascii7x12" :
4352 iflags
.wc_map_mode
== MAP_MODE_ASCII8x12
? "ascii8x12" :
4353 iflags
.wc_map_mode
== MAP_MODE_ASCII16x12
? "ascii16x12" :
4354 iflags
.wc_map_mode
== MAP_MODE_ASCII12x16
? "ascii12x16" :
4355 iflags
.wc_map_mode
== MAP_MODE_ASCII10x18
? "ascii10x18" :
4356 iflags
.wc_map_mode
== MAP_MODE_ASCII_FIT_TO_SCREEN
?
4357 "fit_to_screen" : defopt
);
4358 else if (!strcmp(optname
, "menustyle"))
4359 sprintf(buf
, "%s", menutype
[(int)flags
.menu_style
] );
4360 else if (!strcmp(optname
, "menu_deselect_all"))
4361 sprintf(buf
, "%s", to_be_done
);
4362 else if (!strcmp(optname
, "menu_deselect_page"))
4363 sprintf(buf
, "%s", to_be_done
);
4364 else if (!strcmp(optname
, "menu_first_page"))
4365 sprintf(buf
, "%s", to_be_done
);
4366 else if (!strcmp(optname
, "menu_invert_all"))
4367 sprintf(buf
, "%s", to_be_done
);
4368 else if (!strcmp(optname
, "menu_headings")) {
4369 sprintf(buf
, "%s", (iflags
.menu_headings
== ATR_BOLD
) ?
4370 "bold" : (iflags
.menu_headings
== ATR_INVERSE
) ?
4371 "inverse" : (iflags
.menu_headings
== ATR_ULINE
) ?
4372 "underline" : "unknown");
4374 else if (!strcmp(optname
, "menu_invert_page"))
4375 sprintf(buf
, "%s", to_be_done
);
4376 else if (!strcmp(optname
, "menu_last_page"))
4377 sprintf(buf
, "%s", to_be_done
);
4378 else if (!strcmp(optname
, "menu_next_page"))
4379 sprintf(buf
, "%s", to_be_done
);
4380 else if (!strcmp(optname
, "menu_previous_page"))
4381 sprintf(buf
, "%s", to_be_done
);
4382 else if (!strcmp(optname
, "menu_search"))
4383 sprintf(buf
, "%s", to_be_done
);
4384 else if (!strcmp(optname
, "menu_select_all"))
4385 sprintf(buf
, "%s", to_be_done
);
4386 else if (!strcmp(optname
, "menu_select_page"))
4387 sprintf(buf
, "%s", to_be_done
);
4388 else if (!strcmp(optname
, "monsters"))
4389 sprintf(buf
, "%s", to_be_done
);
4390 else if (!strcmp(optname
, "msghistory"))
4391 sprintf(buf
, "%u", iflags
.msg_history
);
4393 else if (!strcmp(optname
, "msg_window"))
4394 sprintf(buf
, "%s", (iflags
.prevmsg_window
=='s') ? "single" :
4395 (iflags
.prevmsg_window
=='c') ? "combination" :
4396 (iflags
.prevmsg_window
=='f') ? "full" : "reversed");
4398 else if (!strcmp(optname
, "name"))
4399 sprintf(buf
, "%s", plname
);
4400 else if (!strcmp(optname
, "number_pad"))
4402 (!iflags
.num_pad
) ? "0=off" :
4403 (iflags
.num_pad_mode
) ? "2=on, DOS compatible" : "1=on");
4404 else if (!strcmp(optname
, "objects"))
4405 sprintf(buf
, "%s", to_be_done
);
4406 else if (!strcmp(optname
, "packorder")) {
4407 oc_to_str(flags
.inv_order
, ocl
);
4408 sprintf(buf
, "%s", ocl
);
4411 else if (!strcmp(optname
, "palette"))
4412 sprintf(buf
, "%s", get_color_string());
4414 else if (!strcmp(optname
, "pettype"))
4415 sprintf(buf
, "%s", (preferred_pet
== 'c') ? "cat" :
4416 (preferred_pet
== 'd') ? "dog" :
4417 (preferred_pet
== 'n') ? "none" : "random");
4418 else if (!strcmp(optname
, "pickup_burden"))
4419 sprintf(buf
, "%s", burdentype
[flags
.pickup_burden
] );
4420 else if (!strcmp(optname
, "pickup_types")) {
4421 oc_to_str(flags
.pickup_types
, ocl
);
4422 sprintf(buf
, "%s", ocl
[0] ? ocl
: "none" );
4424 else if (!strcmp(optname
, "pilesize")) {
4425 sprintf(buf
, "%u", iflags
.pilesize
);
4427 else if (!strcmp(optname
, "race"))
4428 sprintf(buf
, "%s", rolestring(flags
.initrace
, races
, noun
));
4429 else if (!strcmp(optname
, "role"))
4430 sprintf(buf
, "%s", rolestring(flags
.initrole
, roles
, name
.m
));
4431 else if (!strcmp(optname
, "ratname"))
4432 sprintf(buf
, "%s", ratname
[0] ? ratname
: none
);
4433 /* else if (!strcmp(optname, "rothename"))
4434 sprintf(buf, "%s", rothename[0] ? rothename : none );*/
4435 else if (!strcmp(optname
, "runmode"))
4436 sprintf(buf
, "%s", runmodes
[iflags
.runmode
]);
4437 else if (!strcmp(optname
, "scores")) {
4438 sprintf(buf
, "%d top/%d around%s", flags
.end_top
,
4439 flags
.end_around
, flags
.end_own
? "/own" : "");
4441 else if (!strcmp(optname
, "scroll_amount")) {
4442 if (iflags
.wc_scroll_amount
) sprintf(buf
, "%d",iflags
.wc_scroll_amount
);
4443 else strcpy(buf
, defopt
);
4445 else if (!strcmp(optname
, "scroll_margin")) {
4446 if (iflags
.wc_scroll_margin
) sprintf(buf
, "%d",iflags
.wc_scroll_margin
);
4447 else strcpy(buf
, defopt
);
4449 else if (!strcmp(optname
, "sortloot")) {
4450 char *sortname
= (char *)NULL
;
4451 for (i
=0; i
< SIZE(sortltype
) && sortname
==(char *)NULL
; i
++) {
4452 if (iflags
.sortloot
== sortltype
[i
][0])
4453 sortname
= (char *)sortltype
[i
];
4455 if (sortname
!= (char *)NULL
)
4456 sprintf(buf
, "%s", sortname
);
4458 else if (!strcmp(optname
, "player_selection"))
4459 sprintf(buf
, "%s", iflags
.wc_player_selection
? "prompts" : "dialog");
4461 else if (!strcmp(optname
, "soundcard"))
4462 sprintf(buf
, "%s", to_be_done
);
4464 else if (!strcmp(optname
, "suppress_alert")) {
4465 if (flags
.suppress_alert
== 0L)
4468 sprintf(buf
, "%lu.%lu.%lu",
4469 FEATURE_NOTICE_VER_MAJ
,
4470 FEATURE_NOTICE_VER_MIN
,
4471 FEATURE_NOTICE_VER_PATCH
);
4473 else if (!strcmp(optname
, "term_cols")) {
4474 if (iflags
.wc2_term_cols
) sprintf(buf
, "%d",iflags
.wc2_term_cols
);
4475 else strcpy(buf
, defopt
);
4477 else if (!strcmp(optname
, "term_rows")) {
4478 if (iflags
.wc2_term_rows
) sprintf(buf
, "%d",iflags
.wc2_term_rows
);
4479 else strcpy(buf
, defopt
);
4481 else if (!strcmp(optname
, "tile_file"))
4482 sprintf(buf
, "%s", iflags
.wc_tile_file
? iflags
.wc_tile_file
: defopt
);
4483 else if (!strcmp(optname
, "tile_height")) {
4484 if (iflags
.wc_tile_height
) sprintf(buf
, "%d",iflags
.wc_tile_height
);
4485 else strcpy(buf
, defopt
);
4487 else if (!strcmp(optname
, "tile_width")) {
4488 if (iflags
.wc_tile_width
) sprintf(buf
, "%d",iflags
.wc_tile_width
);
4489 else strcpy(buf
, defopt
);
4491 else if (!strcmp(optname
, "tileset"))
4492 sprintf(buf
, "%s", tileset
[0] ? tileset
: none
);
4493 else if (!strcmp(optname
, "traps"))
4494 sprintf(buf
, "%s", to_be_done
);
4495 else if (!strcmp(optname
, "vary_msgcount")) {
4496 if (iflags
.wc_vary_msgcount
) sprintf(buf
, "%d",iflags
.wc_vary_msgcount
);
4497 else strcpy(buf
, defopt
);
4500 else if (!strcmp(optname
, "video"))
4501 sprintf(buf
, "%s", to_be_done
);
4505 else if (!strcmp(optname
, "videoshades"))
4506 sprintf(buf
, "%s-%s-%s", shade
[0],shade
[1],shade
[2]);
4507 else if (!strcmp(optname
, "videocolors"))
4508 sprintf(buf
, "%d-%d-%d-%d-%d-%d-%d-%d-%d-%d-%d-%d",
4509 ttycolors
[CLR_RED
], ttycolors
[CLR_GREEN
],
4510 ttycolors
[CLR_BROWN
], ttycolors
[CLR_BLUE
],
4511 ttycolors
[CLR_MAGENTA
], ttycolors
[CLR_CYAN
],
4512 ttycolors
[CLR_ORANGE
], ttycolors
[CLR_BRIGHT_GREEN
],
4513 ttycolors
[CLR_YELLOW
], ttycolors
[CLR_BRIGHT_BLUE
],
4514 ttycolors
[CLR_BRIGHT_MAGENTA
],
4515 ttycolors
[CLR_BRIGHT_CYAN
]);
4517 else if (!strcmp(optname
, "videocolors"))
4518 sprintf(buf
, "%d-%d-%d-%d-%d-%d-%d-%d-%d-%d-%d-%d-%d-%d-%d",
4519 ttycolors
[CLR_RED
], ttycolors
[CLR_GREEN
],
4520 ttycolors
[CLR_BROWN
], ttycolors
[CLR_BLUE
],
4521 ttycolors
[CLR_MAGENTA
], ttycolors
[CLR_CYAN
],
4522 ttycolors
[CLR_GRAY
], ttycolors
[CLR_BLACK
],
4523 ttycolors
[CLR_ORANGE
], ttycolors
[CLR_BRIGHT_GREEN
],
4524 ttycolors
[CLR_YELLOW
], ttycolors
[CLR_BRIGHT_BLUE
],
4525 ttycolors
[CLR_BRIGHT_MAGENTA
],
4526 ttycolors
[CLR_BRIGHT_CYAN
], ttycolors
[CLR_WHITE
]);
4528 #endif /* VIDEOSHADES */
4529 else if (!strcmp(optname
,"windowborders"))
4530 sprintf(buf
, "%s", iflags
.wc2_windowborders
== 1 ? "1=on" :
4531 iflags
.wc2_windowborders
== 2 ? "2=off" :
4532 iflags
.wc2_windowborders
== 3 ? "3=auto" :
4534 else if (!strcmp(optname
, "windowtype"))
4535 sprintf(buf
, "%s", windowprocs
.name
);
4536 else if (!strcmp(optname
, "windowcolors"))
4537 sprintf(buf
, "%s/%s %s/%s %s/%s %s/%s",
4538 iflags
.wc_foregrnd_menu
? iflags
.wc_foregrnd_menu
: defbrief
,
4539 iflags
.wc_backgrnd_menu
? iflags
.wc_backgrnd_menu
: defbrief
,
4540 iflags
.wc_foregrnd_message
? iflags
.wc_foregrnd_message
: defbrief
,
4541 iflags
.wc_backgrnd_message
? iflags
.wc_backgrnd_message
: defbrief
,
4542 iflags
.wc_foregrnd_status
? iflags
.wc_foregrnd_status
: defbrief
,
4543 iflags
.wc_backgrnd_status
? iflags
.wc_backgrnd_status
: defbrief
,
4544 iflags
.wc_foregrnd_text
? iflags
.wc_foregrnd_text
: defbrief
,
4545 iflags
.wc_backgrnd_text
? iflags
.wc_backgrnd_text
: defbrief
);
4546 else if (!strcmp(optname
, "wolfname"))
4547 sprintf(buf
, "%s", wolfname
[0] ? wolfname
: none
);
4548 #ifdef PREFIXES_IN_USE
4550 for (i
= 0; i
< PREFIX_COUNT
; ++i
)
4551 if (!strcmp(optname
, fqn_prefix_names
[i
]) && fqn_prefix
[i
])
4552 sprintf(buf
, "%s", fqn_prefix
[i
]);
4556 if (buf
[0]) return buf
;
4557 else return "unknown";
4563 char buf
[BUFSZ
], ocl
[MAXOCLASSES
+1];
4565 flags
.pickup
= !flags
.pickup
;
4567 oc_to_str(flags
.pickup_types
, ocl
);
4568 sprintf(buf
, "ON, for %s objects%s", ocl
[0] ? ocl
: "no",
4569 #ifdef AUTOPICKUP_EXCEPTIONS
4570 (iflags
.autopickup_exceptions
[AP_LEAVE
] ||
4571 iflags
.autopickup_exceptions
[AP_GRAB
]) ?
4572 ((count_ape_maps((int *)0, (int *)0) == 1) ?
4573 ", with one exception" : ", with some exceptions") :
4579 pline("Autopickup: %s.", buf
);
4583 #ifdef AUTOPICKUP_EXCEPTIONS
4585 add_autopickup_exception(mapping
)
4586 const char *mapping
;
4588 struct autopickup_exception
*ape
, **apehead
;
4589 char text
[256], *text2
;
4591 boolean grab
= FALSE
;
4593 if (sscanf(mapping
, "\"%255[^\"]\"", text
) == 1) {
4595 if (*text2
== '<') { /* force autopickup */
4598 } else if (*text2
== '>') { /* default - Do not pickup */
4602 textsize
= strlen(text2
);
4603 apehead
= (grab
) ? &iflags
.autopickup_exceptions
[AP_GRAB
] :
4604 &iflags
.autopickup_exceptions
[AP_LEAVE
];
4605 ape
= (struct autopickup_exception
*)
4606 alloc(sizeof(struct autopickup_exception
));
4607 ape
->pattern
= (char *) alloc(textsize
+1);
4608 strcpy(ape
->pattern
, text2
);
4610 if (!*apehead
) ape
->next
= (struct autopickup_exception
*)0;
4611 else ape
->next
= *apehead
;
4614 raw_print("syntax error in AUTOPICKUP_EXCEPTION");
4621 remove_autopickup_exception(whichape
)
4622 struct autopickup_exception
*whichape
;
4624 struct autopickup_exception
*ape
, *prev
= 0;
4625 int chain
= whichape
->grab
? AP_GRAB
: AP_LEAVE
;
4627 for (ape
= iflags
.autopickup_exceptions
[chain
]; ape
;) {
4628 if (ape
== whichape
) {
4629 struct autopickup_exception
*freeape
= ape
;
4631 if (prev
) prev
->next
= ape
;
4632 else iflags
.autopickup_exceptions
[chain
] = ape
;
4633 free(freeape
->pattern
);
4643 count_ape_maps(leave
, grab
)
4646 struct autopickup_exception
*ape
;
4647 int pass
, totalapes
, numapes
[2] = {0,0};
4649 for (pass
= AP_LEAVE
; pass
<= AP_GRAB
; ++pass
) {
4650 ape
= iflags
.autopickup_exceptions
[pass
];
4656 totalapes
= numapes
[AP_LEAVE
] + numapes
[AP_GRAB
];
4657 if (leave
) *leave
= numapes
[AP_LEAVE
];
4658 if (grab
) *grab
= numapes
[AP_GRAB
];
4663 free_autopickup_exceptions()
4665 struct autopickup_exception
*ape
;
4668 for (pass
= AP_LEAVE
; pass
<= AP_GRAB
; ++pass
) {
4669 while((ape
= iflags
.autopickup_exceptions
[pass
]) != 0) {
4671 iflags
.autopickup_exceptions
[pass
] = ape
->next
;
4676 #endif /* AUTOPICKUP_EXCEPTIONS */
4678 /* data for option_help() */
4679 static const char *opt_intro
[] = {
4681 " SlashEM Options Help:",
4683 #define CONFIG_SLOT 3 /* fill in next value at run-time */
4685 #define ENV_SLOT 4 /* substitute variable name in next value at run-time */
4686 #if !defined(MICRO) && !defined(MAC)
4687 "or use `%s=\"<options>\"' in your environment",
4689 "(<options> is a list of options separated by commas)",
4691 "-- for example, $ DEFINE %s \"noautopickup,fruit:kumquat\"",
4693 "or press \"O\" while playing and use the menu.",
4695 "Boolean options (which can be negated by prefixing them with '!' or \"no\"):",
4699 static const char *opt_epilog
[] = {
4701 "Some of the options can be set only before the game is started; those",
4702 "items will not be selectable in the 'O' command's menu.",
4709 char buf
[BUFSZ
], buf2
[BUFSZ
];
4713 datawin
= create_nhwindow(NHW_TEXT
);
4714 sprintf(buf
, "Set options as OPTIONS=<options> in %s", configfile
);
4715 opt_intro
[CONFIG_SLOT
] = (const char *) buf
;
4716 for (i
= 0; opt_intro
[i
]; i
++)
4719 sprintf(buf2
, opt_intro
[ENV_SLOT
], NETHACK_ENV_OPTIONS
);
4720 putstr(datawin
, 0, buf2
);;
4723 putstr(datawin
, 0, opt_intro
[i
]);
4725 /* Boolean options */
4726 for (i
= 0; boolopt
[i
].name
; i
++) {
4727 if (boolopt
[i
].addr
) {
4730 if (boolopt
[i
].addr
== &iflags
.sanity_check
&& !wizard
) continue;
4732 if (boolopt
[i
].addr
== &iflags
.menu_tab_sep
&& !wizard
) continue;
4734 next_opt(datawin
, boolopt
[i
].name
);
4737 next_opt(datawin
, "");
4739 /* Compound options */
4740 putstr(datawin
, 0, "Compound options:");
4741 for (i
= 0; compopt
[i
].name
; i
++) {
4742 sprintf(buf2
, "`%s'", compopt
[i
].name
);
4743 sprintf(buf
, "%-20s - %s%c", buf2
, compopt
[i
].descr
,
4744 compopt
[i
+1].name
? ',' : '.');
4745 putstr(datawin
, 0, buf
);
4748 for (i
= 0; opt_epilog
[i
]; i
++)
4749 putstr(datawin
, 0, opt_epilog
[i
]);
4751 display_nhwindow(datawin
, FALSE
);
4752 destroy_nhwindow(datawin
);
4757 * prints the next boolean option, on the same line if possible, on a new
4758 * line if not. End with next_opt("").
4761 next_opt(datawin
, str
)
4765 static char *buf
= 0;
4769 if (!buf
) *(buf
= (char *)alloc(BUFSZ
)) = '\0';
4773 if (s
> &buf
[1] && s
[-2] == ',')
4774 strcpy(s
- 2, "."); /* replace last ", " */
4775 i
= COLNO
; /* (greater than COLNO - 2) */
4777 i
= strlen(buf
) + strlen(str
) + 2;
4780 if (i
> COLNO
- 2) { /* rule of thumb */
4781 putstr(datawin
, 0, buf
);
4788 putstr(datawin
, 0, str
);
4794 /* Returns the fid of the fruit type; if that type already exists, it
4795 * returns the fid of that one; if it does not exist, it adds a new fruit
4796 * type to the chain and returns the new one.
4803 register struct fruit
*f
;
4804 struct fruit
*lastf
= 0;
4805 int highest_fruit_id
= 0;
4807 boolean user_specified
= (str
== pl_fruit
);
4808 int len
= strlen(str
);
4809 /* if not user-specified, then it's a fruit name for a fruit on
4813 /* Note: every fruit has an id (spe for fruit objects) of at least
4816 if (user_specified
) {
4817 /* disallow naming after other foods (since it'd be impossible
4818 * to tell the difference)
4821 boolean found
= FALSE
, numeric
= FALSE
;
4823 for (i
= bases
[FOOD_CLASS
]; objects
[i
].oc_class
== FOOD_CLASS
;
4825 if (!strcmp(OBJ_NAME(objects
[i
]), pl_fruit
)) {
4835 for(c
= pl_fruit
; *c
>= '0' && *c
<= '9'; c
++)
4837 if (isspace(*c
) || *c
== 0) numeric
= TRUE
;
4839 if (found
|| numeric
||
4840 !strncmp(str
, "cursed ", 7) ||
4841 !strncmp(str
, "uncursed ", 9) ||
4842 !strncmp(str
, "blessed ", 8) ||
4843 !strncmp(str
, "partly eaten ", 13) ||
4844 (!strncmp(str
, "tin of ", 7) &&
4845 (!strcmp(str
+7, "spinach") ||
4846 name_to_mon(str
+7) >= LOW_PM
)) ||
4847 !strcmp(str
, "empty tin") ||
4848 (((len
> 7 && !strncmp(eos(str
)-7," corpse",7)) ||
4849 (len
> 4 && !strncmp(eos(str
)-4, " egg",4))) &&
4850 name_to_mon(str
) >= LOW_PM
))
4852 strcpy(buf
, pl_fruit
);
4853 strcpy(pl_fruit
, "candied ");
4854 nmcpy(pl_fruit
+8, buf
, PL_FSIZ
-8);
4857 for(f
=ffruit
; f
; f
= f
->nextf
) {
4859 if(f
->fid
> highest_fruit_id
) highest_fruit_id
= f
->fid
;
4860 if(!strncmp(str
, f
->fname
, PL_FSIZ
))
4863 /* if adding another fruit would overflow spe, use a random
4864 fruit instead... we've got a lot to choose from. */
4865 if (highest_fruit_id
>= 127) return rnd(127);
4868 if (ffruit
) lastf
->nextf
= f
;
4870 strcpy(f
->fname
, str
);
4871 f
->fid
= highest_fruit_id
;
4874 if (user_specified
) current_fruit
= highest_fruit_id
;
4879 * This is a somewhat generic menu for taking a list of NetHack style
4880 * class choices and presenting them via a description
4881 * rather than the traditional NetHack characters.
4882 * (Benefits users whose first exposure to NetHack is via tiles).
4885 * The title at the top of the menu.
4887 * category: 0 = monster class
4891 * FALSE = PICK_ONE, TRUE = PICK_ANY
4894 * a null terminated string containing the list of choices.
4897 * a null terminated string containing the selected characters.
4899 * Returns number selected.
4902 choose_classes_menu(prompt
, category
, way
, class_list
, class_select
)
4909 menu_item
*pick_list
= (menu_item
*)0;
4915 int next_accelerator
, accelerator
;
4917 if (class_list
== (char *)0 || class_select
== (char *)0) return 0;
4919 next_accelerator
= 'a';
4921 win
= create_nhwindow(NHW_MENU
);
4923 while (*class_list
) {
4931 text
= monexplain
[def_char_to_monclass(*class_list
)];
4932 accelerator
= *class_list
;
4933 sprintf(buf
, "%s", text
);
4936 text
= objexplain
[def_char_to_objclass(*class_list
)];
4937 accelerator
= next_accelerator
;
4938 sprintf(buf
, "%c %s", *class_list
, text
);
4941 impossible("choose_classes_menu: invalid category %d",
4944 if (way
&& *class_select
) { /* Selections there already */
4945 if (index(class_select
, *class_list
)) {
4949 any
.a_int
= *class_list
;
4950 add_menu(win
, NO_GLYPH
, &any
, accelerator
,
4951 category
? *class_list
: 0,
4952 ATR_NONE
, buf
, selected
);
4956 if (next_accelerator
== ('z' + 1)) next_accelerator
= 'A';
4957 if (next_accelerator
== ('Z' + 1)) break;
4960 end_menu(win
, prompt
);
4961 n
= select_menu(win
, way
? PICK_ANY
: PICK_ONE
, &pick_list
);
4962 destroy_nhwindow(win
);
4964 for (i
= 0; i
< n
; ++i
)
4965 *class_select
++ = (char)pick_list
[i
].item
.a_int
;
4966 free((void *)pick_list
);
4968 } else if (n
== -1) {
4969 class_select
= eos(class_select
);
4973 *class_select
= '\0';
4977 struct wc_Opt wc_options
[] = {
4978 {"ascii_map", WC_ASCII_MAP
},
4979 {"color", WC_COLOR
},
4980 {"eight_bit_tty", WC_EIGHT_BIT_IN
},
4981 {"hilite_pet", WC_HILITE_PET
},
4982 {"popup_dialog", WC_POPUP_DIALOG
},
4983 {"player_selection", WC_PLAYER_SELECTION
},
4984 {"preload_tiles", WC_PRELOAD_TILES
},
4985 {"tiled_map", WC_TILED_MAP
},
4986 {"tile_file", WC_TILE_FILE
},
4987 {"tile_width", WC_TILE_WIDTH
},
4988 {"tile_height", WC_TILE_HEIGHT
},
4989 {"use_inverse", WC_INVERSE
},
4990 {"align_message", WC_ALIGN_MESSAGE
},
4991 {"align_status", WC_ALIGN_STATUS
},
4992 {"font_map", WC_FONT_MAP
},
4993 {"font_menu", WC_FONT_MENU
},
4994 {"font_message",WC_FONT_MESSAGE
},
4996 {"perm_invent",WC_PERM_INVENT
},
4998 {"font_size_map", WC_FONTSIZ_MAP
},
4999 {"font_size_menu", WC_FONTSIZ_MENU
},
5000 {"font_size_message", WC_FONTSIZ_MESSAGE
},
5001 {"font_size_status", WC_FONTSIZ_STATUS
},
5002 {"font_size_text", WC_FONTSIZ_TEXT
},
5003 {"font_status", WC_FONT_STATUS
},
5004 {"font_text", WC_FONT_TEXT
},
5005 {"map_mode", WC_MAP_MODE
},
5006 {"scroll_amount", WC_SCROLL_AMOUNT
},
5007 {"scroll_margin", WC_SCROLL_MARGIN
},
5008 {"splash_screen", WC_SPLASH_SCREEN
},
5009 {"vary_msgcount",WC_VARY_MSGCOUNT
},
5010 {"windowcolors", WC_WINDOWCOLORS
},
5011 {"mouse_support", WC_MOUSE_SUPPORT
},
5015 struct wc_Opt wc2_options
[] = {
5016 {"fullscreen", WC2_FULLSCREEN
},
5017 {"softkeyboard", WC2_SOFTKEYBOARD
},
5018 {"wraptext", WC2_WRAPTEXT
},
5019 {"term_cols", WC2_TERM_COLS
},
5020 {"term_rows", WC2_TERM_ROWS
},
5021 {"windowborders", WC2_WINDOWBORDERS
},
5022 {"petattr", WC2_PETATTR
},
5023 {"guicolor", WC2_GUICOLOR
},
5029 * If a port wants to change or ensure that the
5030 * SET_IN_FILE, DISP_IN_GAME, or SET_IN_GAME status of an option is
5031 * correct (for controlling its display in the option menu) call
5032 * set_option_mod_status()
5033 * with the second argument of 0,2, or 3 respectively.
5036 set_option_mod_status(optnam
, status
)
5041 if (status
< SET_IN_FILE
|| status
> SET_IN_GAME
) {
5042 impossible("set_option_mod_status: status out of range %d.",
5046 for (k
= 0; boolopt
[k
].name
; k
++) {
5047 if (!strncmpi(boolopt
[k
].name
, optnam
, strlen(optnam
))) {
5048 boolopt
[k
].optflags
= status
;
5052 for (k
= 0; compopt
[k
].name
; k
++) {
5053 if (!strncmpi(compopt
[k
].name
, optnam
, strlen(optnam
))) {
5054 compopt
[k
].optflags
= status
;
5061 * You can set several wc_options in one call to
5062 * set_wc_option_mod_status() by setting
5063 * the appropriate bits for each option that you
5064 * are setting in the optmask argument
5066 * example: set_wc_option_mod_status(WC_COLOR|WC_SCROLL_MARGIN, SET_IN_GAME);
5069 set_wc_option_mod_status(optmask
, status
)
5070 unsigned long optmask
;
5074 if (status
< SET_IN_FILE
|| status
> SET_IN_GAME
) {
5075 impossible("set_wc_option_mod_status: status out of range %d.",
5079 while (wc_options
[k
].wc_name
) {
5080 if (optmask
& wc_options
[k
].wc_bit
) {
5081 set_option_mod_status(wc_options
[k
].wc_name
, status
);
5088 is_wc_option(optnam
)
5092 while (wc_options
[k
].wc_name
) {
5093 if (strcmp(wc_options
[k
].wc_name
, optnam
) == 0)
5101 wc_supported(optnam
)
5105 while (wc_options
[k
].wc_name
) {
5106 if (!strcmp(wc_options
[k
].wc_name
, optnam
) &&
5107 (windowprocs
.wincap
& wc_options
[k
].wc_bit
))
5116 * You can set several wc2_options in one call to
5117 * set_wc2_option_mod_status() by setting
5118 * the appropriate bits for each option that you
5119 * are setting in the optmask argument
5121 * example: set_wc2_option_mod_status(WC2_FULLSCREEN|WC2_SOFTKEYBOARD|WC2_WRAPTEXT, SET_IN_FILE);
5125 set_wc2_option_mod_status(optmask
, status
)
5126 unsigned long optmask
;
5130 if (status
< SET_IN_FILE
|| status
> SET_IN_GAME
) {
5131 impossible("set_wc2_option_mod_status: status out of range %d.",
5135 while (wc2_options
[k
].wc_name
) {
5136 if (optmask
& wc2_options
[k
].wc_bit
) {
5137 set_option_mod_status(wc2_options
[k
].wc_name
, status
);
5144 is_wc2_option(optnam
)
5148 while (wc2_options
[k
].wc_name
) {
5149 if (strcmp(wc2_options
[k
].wc_name
, optnam
) == 0)
5157 wc2_supported(optnam
)
5161 while (wc2_options
[k
].wc_name
) {
5162 if (!strcmp(wc2_options
[k
].wc_name
, optnam
) &&
5163 (windowprocs
.wincap2
& wc2_options
[k
].wc_bit
))
5172 wc_set_font_name(wtype
, fontname
)
5176 char **fn
= (char **)0;
5177 if (!fontname
) return;
5180 fn
= &iflags
.wc_font_map
;
5183 fn
= &iflags
.wc_font_message
;
5186 fn
= &iflags
.wc_font_text
;
5189 fn
= &iflags
.wc_font_menu
;
5192 fn
= &iflags
.wc_font_status
;
5199 *fn
= (char *)alloc(strlen(fontname
) + 1);
5200 strcpy(*fn
, fontname
);
5206 wc_set_window_colors(op
)
5210 * menu white/black message green/yellow status white/blue text white/black
5215 char *wn
, *tfg
, *tbg
, *newop
;
5216 static const char *wnames
[] = { "menu", "message", "status", "text" };
5217 static const char *shortnames
[] = { "mnu", "msg", "sts", "txt" };
5218 static char **fgp
[] = {
5219 &iflags
.wc_foregrnd_menu
,
5220 &iflags
.wc_foregrnd_message
,
5221 &iflags
.wc_foregrnd_status
,
5222 &iflags
.wc_foregrnd_text
5224 static char **bgp
[] = {
5225 &iflags
.wc_backgrnd_menu
,
5226 &iflags
.wc_backgrnd_message
,
5227 &iflags
.wc_backgrnd_status
,
5228 &iflags
.wc_backgrnd_text
5232 newop
= mungspaces(buf
);
5233 while (newop
&& *newop
) {
5235 wn
= tfg
= tbg
= (char *)0;
5237 /* until first non-space in case there's leading spaces - before colorname*/
5238 while(*newop
&& isspace(*newop
)) newop
++;
5239 if (*newop
) wn
= newop
;
5242 /* until first space - colorname*/
5243 while(*newop
&& !isspace(*newop
)) newop
++;
5244 if (*newop
) *newop
= '\0';
5248 /* until first non-space - before foreground*/
5249 while(*newop
&& isspace(*newop
)) newop
++;
5250 if (*newop
) tfg
= newop
;
5253 /* until slash - foreground */
5254 while(*newop
&& *newop
!= '/') newop
++;
5255 if (*newop
) *newop
= '\0';
5259 /* until first non-space (in case there's leading space after slash) - before background */
5260 while(*newop
&& isspace(*newop
)) newop
++;
5261 if (*newop
) tbg
= newop
;
5264 /* until first space - background */
5265 while(*newop
&& !isspace(*newop
)) newop
++;
5266 if (*newop
) *newop
++ = '\0';
5268 for (j
= 0; j
< 4; ++j
) {
5269 if (!strcmpi(wn
, wnames
[j
]) ||
5270 !strcmpi(wn
, shortnames
[j
])) {
5271 if (tfg
&& !strstri(tfg
, " ")) {
5272 if (*fgp
[j
]) free(*fgp
[j
]);
5273 *fgp
[j
] = (char *)alloc(strlen(tfg
) + 1);
5274 strcpy(*fgp
[j
], tfg
);
5276 if (tbg
&& !strstri(tbg
, " ")) {
5277 if (*bgp
[j
]) free(*bgp
[j
]);
5278 *bgp
[j
] = (char *)alloc(strlen(tbg
) + 1);
5279 strcpy(*bgp
[j
], tbg
);
5288 #endif /* OPTION_LISTS_ONLY */
5290 /* for option nastytrap by Amy: select a random option and change its value
5291 * booleans just become true if they were false and in reverse, compound options get set to some random value
5292 * known problem: some options might not always be compiled into the game */
5294 randomoptionchange()
5298 flags
.autodig
= !flags
.autodig
;
5301 flags
.pickup
= !flags
.pickup
;
5305 iflags
.autoopen
= !iflags
.autoopen
;
5309 flags
.autoquiver
= !flags
.autoquiver
;
5312 flags
.bash_reminder
= !flags
.bash_reminder
;
5315 flags
.ins_chkpt
= !flags
.ins_chkpt
;
5318 iflags
.cmdassist
= !iflags
.cmdassist
;
5321 iflags
.wc_color
= !iflags
.wc_color
;
5324 flags
.confirm
= !flags
.confirm
;
5327 flags
.eatingboulders
= !flags
.eatingboulders
;
5330 flags
.eatingconfirm
= !flags
.eatingconfirm
;
5333 flags
.eatingdoors
= !flags
.eatingdoors
;
5336 flags
.eatingwalls
= !flags
.eatingwalls
;
5339 iflags
.wc_eight_bit_input
= !iflags
.wc_eight_bit_input
;
5342 #if defined(TTY_GRAPHICS) || defined(CURSES_GRAPIHCS)
5343 iflags
.extmenu
= !iflags
.extmenu
;
5347 flags
.invlet_constant
= !flags
.invlet_constant
;
5350 flags
.graffitihilite
= !flags
.graffitihilite
;
5353 flags
.help
= !flags
.help
;
5356 iflags
.wc_hilite_pet
= !iflags
.wc_hilite_pet
;
5359 flags
.hitpointbar
= !flags
.hitpointbar
;
5362 flags
.inertiaconfirm
= !flags
.inertiaconfirm
;
5366 flags
.invweight
= !flags
.invweight
;
5370 flags
.knapsacklimit
= !flags
.knapsacklimit
;
5373 flags
.lit_corridor
= !flags
.lit_corridor
;
5376 iflags
.lootabc
= !iflags
.lootabc
;
5379 flags
.materialglyph
= !flags
.materialglyph
;
5382 iflags
.memorizationknown
= !iflags
.memorizationknown
;
5385 flags
.menu_on_esc
= !flags
.menu_on_esc
;
5388 iflags
.use_menu_glyphs
= !iflags
.use_menu_glyphs
;
5391 flags
.moreforced
= !flags
.moreforced
;
5394 iflags
.numpadmessage
= !iflags
.numpadmessage
;
5397 flags
.paranoidquit
= !flags
.paranoidquit
;
5400 flags
.pickup_thrown
= !flags
.pickup_thrown
;
5403 flags
.pickup_cursed
= !flags
.pickup_cursed
;
5406 flags
.pokedex
= !flags
.pokedex
;
5409 iflags
.wc_popup_dialog
= !iflags
.wc_popup_dialog
;
5412 flags
.prayconfirm
= !flags
.prayconfirm
;
5415 flags
.pushweapon
= !flags
.pushweapon
;
5418 iflags
.quiver_fired
= !iflags
.quiver_fired
;
5421 iflags
.qwertz_layout
= !iflags
.qwertz_layout
;
5424 flags
.rest_on_space
= !flags
.rest_on_space
;
5427 flags
.safe_dog
= !flags
.safe_dog
;
5430 iflags
.should_change_color
= !iflags
.should_change_color
;
5433 flags
.showexp
= !flags
.showexp
;
5436 iflags
.showrace
= !iflags
.showrace
;
5439 #ifdef REALTIME_ON_BOTL
5440 iflags
.showrealtime
= !iflags
.showrealtime
;
5444 flags
.showscore
= !flags
.showscore
;
5447 iflags
.showsym
= !iflags
.showsym
;
5451 flags
.showdmg
= !flags
.showdmg
;
5456 flags
.showweight
= !flags
.showweight
;
5460 flags
.showmc
= !flags
.showmc
;
5463 flags
.showmovement
= !flags
.showmovement
;
5466 flags
.showlongstats
= !flags
.showlongstats
;
5469 flags
.showsanity
= !flags
.showsanity
;
5472 flags
.showsymbiotehp
= !flags
.showsymbiotehp
;
5475 flags
.silent
= !flags
.silent
;
5478 flags
.simpledescs
= !flags
.simpledescs
;
5481 flags
.sortpack
= !flags
.sortpack
;
5484 flags
.sparkle
= !flags
.sparkle
;
5487 flags
.standout
= !flags
.standout
;
5490 flags
.tech_description
= !flags
.tech_description
;
5493 flags
.tombstone
= !flags
.tombstone
;
5496 flags
.toptenwin
= !flags
.toptenwin
;
5499 iflags
.travelcmd
= !iflags
.travelcmd
;
5502 iflags
.wc_inverse
= !iflags
.wc_inverse
;
5505 flags
.verbose
= !flags
.verbose
;
5508 flags
.wallglyph
= !flags
.wallglyph
;
5513 flags
.menu_style
= MENU_TRADITIONAL
;
5516 flags
.menu_style
= MENU_COMBINATION
;
5519 flags
.menu_style
= MENU_PARTIAL
;
5522 flags
.menu_style
= MENU_FULL
;
5530 iflags
.num_pad_mode
= 0;
5534 iflags
.num_pad_mode
= 0;
5538 iflags
.num_pad_mode
= 1;
5545 iflags
.runmode
= RUN_TPORT
;
5548 iflags
.runmode
= RUN_LEAP
;
5551 iflags
.runmode
= RUN_STEP
;
5554 iflags
.runmode
= RUN_CRAWL
;
5559 iflags
.msg_history
= rnd(60);
5564 iflags
.prevmsg_window
= 's';
5567 iflags
.prevmsg_window
= 'c';
5570 iflags
.prevmsg_window
= 'f';
5573 iflags
.prevmsg_window
= 'r';
5580 flags
.pickup_burden
= UNENCUMBERED
;
5583 flags
.pickup_burden
= SLT_ENCUMBER
;
5586 flags
.pickup_burden
= MOD_ENCUMBER
;
5589 flags
.pickup_burden
= HVY_ENCUMBER
;
5592 flags
.pickup_burden
= EXT_ENCUMBER
;
5595 flags
.pickup_burden
= OVERLOADED
;
5600 iflags
.pilesize
= rnd(10);
5605 iflags
.sortloot
= 'n';
5608 iflags
.sortloot
= 'l';
5611 iflags
.sortloot
= 'f';
5616 flags
.epyxmode
= !flags
.epyxmode
;
5617 if (isrougelike
|| Is_rogue_level(&u
.uz
)) assign_rogue_graphics(TRUE
);