From 0ce424b71afe81ee6f6e8266208035e5a746ed68 Mon Sep 17 00:00:00 2001 From: "nethack.allison" Date: Tue, 3 Oct 2006 02:38:40 +0000 Subject: [PATCH] symset restrictions attribute (trunk only) Pat Rankin wrote: > I was about to also suggest that there > be a rogue/non-rogue (with perhaps a third choice meaning "both") > attribute. That way we could keep the rogue choices from being > listed in the "symset" menu and the non-rogue choices from the > "roguesymset" menu. Players who deliberately wanted to switch > over would need to modify the attribute, possibly on a cloned set. > Or perhaps they could just explicitly set their desired choices > via NETHACKOPTIONS or .nethackrc and not use the 'O' menues--the > new attribute doesn't necessary have to block which sets get used > where, just filter menu entries to display the most applicable > candidates. --- dat/symbols | 3 +++ include/rm.h | 22 ++++++++++++---------- src/drawing.c | 25 +++++++++++++++++++++++++ src/files.c | 43 +++++++++++++++++++++++++++++++++++++++---- src/options.c | 39 ++++++++++++++++++++++++++++++++------- 5 files changed, 111 insertions(+), 21 deletions(-) diff --git a/dat/symbols b/dat/symbols index adaa0e477..108d761d1 100644 --- a/dat/symbols +++ b/dat/symbols @@ -160,6 +160,7 @@ finish start: RogueIBM Handling: IBM + Restrictions: rogue S_weapon: \x29 S_amulet: \x2c S_food: \x3a @@ -190,6 +191,7 @@ finish start: RogueEpyx Description: Rogue level color symbol set like Epyx Rogue + Restrictions: rogue Handling: IBM Color: Yes S_weapon: \x18 # up arrow @@ -267,6 +269,7 @@ start: RogueEpyx finish start: RogueWindows + Restrictions: rogue Handling: IBM S_weapon: \x29 S_amulet: \x2c diff --git a/include/rm.h b/include/rm.h index 244bcc86a..8c840693e 100644 --- a/include/rm.h +++ b/include/rm.h @@ -241,21 +241,23 @@ struct symparse { /* linked list of symsets and their characteristics */ struct symsetentry { - struct symsetentry *next; /* next in list */ - char *name; /* ptr to symset name */ - char *desc; /* ptr to description */ - int idx; /* an index value */ - int handling; /* known handlers value */ - Bitfield(nocolor,1); /* don't use color if set */ - /* 7 free bits */ + struct symsetentry *next; /* next in list */ + char *name; /* ptr to symset name */ + char *desc; /* ptr to description */ + int idx; /* an index value */ + int handling; /* known handlers value */ + Bitfield(nocolor,1); /* don't use color if set */ + Bitfield(primary,1); /* restricted for use as primary set */ + Bitfield(rogue,1); /* restricted for use as rogue lev set */ + /* 5 free bits */ }; /* * Graphics sets for display symbols */ #define DEFAULT_GRAPHICS 0 /* regular characters: '-', '+', &c */ -#define PRIMARY 0 /* primary graphics */ -#define ROGUESET 1 /* rogue graphics */ +#define PRIMARY 0 /* primary graphics set */ +#define ROGUESET 1 /* rogue graphics set */ #define NUM_GRAPHICS 2 /* @@ -269,11 +271,11 @@ struct symsetentry { extern const struct symdef defsyms[MAXPCHARS]; /* defaults */ extern const struct symdef def_warnsyms[WARNCOUNT]; -extern struct symsetentry symset[NUM_GRAPHICS]; /* from drawing.c */ extern int currentgraphics; /* from drawing.c */ extern uchar showsyms[]; #ifdef LOADSYMSETS +extern struct symsetentry symset[NUM_GRAPHICS]; /* from drawing.c */ #define SYMHANDLING(ht) (symset[currentgraphics].handling == (ht)) #else #define SYMHANDLING(ht) ((ht) == H_UNK) diff --git a/src/drawing.c b/src/drawing.c index 0f69eeb32..11d569ad9 100644 --- a/src/drawing.c +++ b/src/drawing.c @@ -541,6 +541,11 @@ boolean name_too; symset[which_set].nocolor = 0; symset[which_set].handling = H_UNK; + symset[which_set].desc = (char *)0; + symset[which_set].nocolor = 0; + /* initialize restriction bits */ + symset[which_set].primary = 0; + symset[which_set].rogue = 0; if (name_too) { if (symset[which_set].name) @@ -562,6 +567,25 @@ const char *known_handling[] = { (const char *)0, }; +/* + * Accepted keywords for symset restrictions. + * These can be virtually anything that you want to + * be able to test in the code someplace. + * Be sure to: + * - add a corresponding Bitfield to the symsetentry struct in rm.h + * - initialize the field to zero in parse_sym_line in the SYM_CONTROL + * case 0 section of the idx switch. The location is prefaced with + * with a comment stating "initialize restriction bits". + * - set the value appropriately based on the index of your keyword + * under the case 5 sections of the same SYM_CONTROL idx switches. + * - add the field to clear_symsetentry() + */ +const char *known_restrictions[] = { + "primary", + "rogue", + (const char *)0, +}; + struct symparse loadsyms[] = { {SYM_CONTROL, 0, "start"}, {SYM_CONTROL, 0, "begin"}, @@ -570,6 +594,7 @@ struct symparse loadsyms[] = { {SYM_CONTROL, 3, "description"}, {SYM_CONTROL, 4, "color"}, {SYM_CONTROL, 4, "colour"}, + {SYM_CONTROL, 5, "restrictions"}, {SYM_PCHAR, S_stone, "S_stone"}, {SYM_PCHAR, S_vwall, "S_vwall"}, {SYM_PCHAR, S_hwall, "S_hwall"}, diff --git a/src/files.c b/src/files.c index 92f740b7e..3151a03e3 100644 --- a/src/files.c +++ b/src/files.c @@ -2426,9 +2426,10 @@ read_wizkit() #endif /*WIZARD*/ #ifdef LOADSYMSETS -extern struct symsetentry *symset_list; /* options.c */ -extern struct symparse loadsyms[]; /* drawing.c */ -extern const char *known_handling[]; /* drawing.c */ +extern struct symsetentry *symset_list; /* options.c */ +extern struct symparse loadsyms[]; /* drawing.c */ +extern const char *known_handling[]; /* drawing.c */ +extern const char *known_restrictions[]; /* drawing.c */ static int symset_count = 0; /* for pick-list building only */ static boolean chosen_symset_start = FALSE, chosen_symset_end = FALSE; @@ -2481,7 +2482,7 @@ parse_sym_line(buf, which_set) char *buf; int which_set; { - int val; + int i, val; struct symparse *symp = (struct symparse *)0; char *bufp, *commentp, *altp; @@ -2553,6 +2554,9 @@ int which_set; Strcpy(tmpsp->name, bufp); tmpsp->desc = (char *)0; tmpsp->nocolor = 0; + /* initialize restriction bits */ + tmpsp->primary = 0; + tmpsp->rogue = 0; break; case 3: /* description:something */ tmpsp = symset_list; /* most recent symset */ @@ -2561,6 +2565,21 @@ int which_set; Strcpy(tmpsp->desc, bufp); } break; + case 5: + /* restrictions: xxxx*/ + tmpsp = symset_list; /* most recent symset */ + i = 0; + while (known_restrictions[i]) { + if (!strcmpi(known_restrictions[i], bufp)) { + switch(i) { + case 0: tmpsp->primary = 1; break; + case 1: tmpsp->rogue = 1; break; + } + break; /* while loop */ + } + i++; + } + break; } } return 1; @@ -2573,6 +2592,7 @@ int which_set; if (!strcmpi(bufp, symset[which_set].name)) { /* matches desired one */ chosen_symset_start = TRUE; + /* these init_*() functions clear symset fields too */ # ifdef REINCARNATION if (which_set == ROGUESET) init_r_symbols(); # endif @@ -2605,6 +2625,21 @@ int which_set; } } break; + case 5: /* restrictions: xxxx*/ + i = 0; + while (known_restrictions[i]) { + if (!strcmpi(known_restrictions[i], bufp)) { + switch(i) { + case 0: symset[which_set].primary = 1; + break; + case 1: symset[which_set].rogue = 1; + break; + } + break; /* while loop */ + } + i++; + } + break; } } else { /* !SYM_CONTROL */ val = sym_val(bufp); diff --git a/src/options.c b/src/options.c index 81af6d972..14554a11c 100644 --- a/src/options.c +++ b/src/options.c @@ -3155,11 +3155,15 @@ boolean setinitial,setfromfile; } else if (!strcmp("symset", optname) || !strcmp("roguesymset", optname)) { menu_item *symset_pick = (menu_item *)0; - boolean rogueflag = (*optname == 'r'); + boolean primaryflag = (*optname == 's'), + rogueflag = (*optname == 'r'), + ready_to_switch = FALSE, + nothing_to_do = FALSE; #ifdef LOADSYMSETS int res; char *symset_name, fmtstr[20]; struct symsetentry *sl; + int setcount = 0; #endif int chosen = -2, which_set = #ifdef REINCARNATION @@ -3179,22 +3183,43 @@ boolean setinitial,setfromfile; if (res && symset_list) { char symsetchoice[BUFSZ]; int let = 'a', biggest = 0, thissize = 0; - tmpwin = create_nhwindow(NHW_MENU); - start_menu(tmpwin); - any.a_int = 1; - add_menu(tmpwin, NO_GLYPH, &any, let++, 0, - ATR_NONE, "Default Symbols", MENU_UNSELECTED); sl = symset_list; while (sl) { + /* check restrictions */ + if ((!rogueflag && sl->rogue) || + (!primaryflag && sl->primary)) { + sl = sl->next; + continue; + } + setcount++; /* find biggest name */ if (sl->name) thissize = strlen(sl->name); if (thissize > biggest) biggest = thissize; sl = sl->next; } + if (!setcount) { + pline("There are no appropriate %ssymbol sets available.", + (rogueflag) ? "rogue level " : + (primaryflag) ? "primary " : + ""); + return TRUE; + } + Sprintf(fmtstr,"%%-%ds %%s", biggest + 5); - + tmpwin = create_nhwindow(NHW_MENU); + start_menu(tmpwin); + any.a_int = 1; + add_menu(tmpwin, NO_GLYPH, &any, let++, 0, + ATR_NONE, "Default Symbols", MENU_UNSELECTED); + sl = symset_list; while (sl) { + /* check restrictions */ + if ((!rogueflag && sl->rogue) || + (!primaryflag && sl->primary)) { + sl = sl->next; + continue; + } if (sl->name) { any.a_int = sl->idx + 2; Sprintf(symsetchoice, fmtstr, sl->name, -- 2.40.0