From 2a2e2b299e2082159f8d439f67f04d84c681029d Mon Sep 17 00:00:00 2001 From: arromdee Date: Sun, 11 Dec 2011 18:11:29 +0000 Subject: [PATCH] I haven't been active in the past decade, but here's a small patch. Main branch only. This adds a check when setting a new fruit so that if no fruits have been created since the last time the option has been set, the current fruit is overwritten. Result: the user cannot repeatedly set the fruit option and overflow the maximum fruit number. --- include/extern.h | 2 +- include/flag.h | 1 + src/cmd.c | 14 ++++++++++++++ src/mkobj.c | 1 + src/options.c | 39 +++++++++++++++++++++++++++++++++++---- src/restore.c | 2 +- 6 files changed, 53 insertions(+), 6 deletions(-) diff --git a/include/extern.h b/include/extern.h index b8173a5cc..d58d18314 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1610,7 +1610,7 @@ E int NDECL(doset); E int NDECL(dotogglepickup); E void NDECL(option_help); E void FDECL(next_opt, (winid,const char *)); -E int FDECL(fruitadd, (char *)); +E int FDECL(fruitadd, (char *,struct fruit *)); E int FDECL(choose_classes_menu, (const char *,int,BOOLEAN_P,char *,char *)); E void FDECL(add_menu_cmd_alias, (CHAR_P, CHAR_P)); E char FDECL(map_menu_cmd, (CHAR_P)); diff --git a/include/flag.h b/include/flag.h index a4e53408d..dc26b5bf3 100644 --- a/include/flag.h +++ b/include/flag.h @@ -76,6 +76,7 @@ struct flag { char end_disclose[NUM_DISCLOSURE_OPTIONS + 1]; /* disclose various info upon exit */ char menu_style; /* User interface style setting */ + boolean made_fruit; /* don't easily let the user overflow the number of fruits */ /* KMH, role patch -- Variables used during startup. * diff --git a/src/cmd.c b/src/cmd.c index 67193ff78..312cd7ac3 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -2053,6 +2053,20 @@ int final; if (wizard) Sprintf(eos(buf), " (%d)", u.ublesscnt); #endif you_can(buf,""); + if (wizard) { + int fcount = 0; + struct fruit *f; + char buf2[BUFSZ]; + for(f=ffruit; f; f = f->nextf) + { + Sprintf(buf, "Fruit %d ", ++fcount); + Sprintf(buf2, "%s (id %d)", f->fname, f->fid); + enl_msg(buf, "is ", "was ", buf2, ""); + } + enl_msg("The current fruit ", "is ", "was ", pl_fruit, ""); + Sprintf(buf, "%d", flags.made_fruit); + enl_msg("The made fruit flag ", "is ", "was ", buf, ""); + } } { diff --git a/src/mkobj.c b/src/mkobj.c index 4fba48b59..c470809d7 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -680,6 +680,7 @@ boolean artif; break; case SLIME_MOLD: otmp->spe = context.current_fruit; + flags.made_fruit = TRUE; break; case KELP_FROND: otmp->quan = (long) rnd(2); diff --git a/src/options.c b/src/options.c index ba3f67113..d806fa1d7 100644 --- a/src/options.c +++ b/src/options.c @@ -721,7 +721,7 @@ initoptions_finish() #endif read_config_file((char *)0, SET_IN_FILE); - (void)fruitadd(pl_fruit); + (void)fruitadd(pl_fruit, (struct fruit *)0); /* Remove "slime mold" from list of object names; this will */ /* prevent it from being wished unless it's actually present */ /* as a named (or default) fruit. Wishing for "fruit" will */ @@ -1673,6 +1673,8 @@ boolean tinitial, tfrom_file; #endif /* CHANGE_COLOR */ if (match_optname(opts, "fruit", 2, TRUE)) { + struct fruit *forig = 0; + char empty_str = '\0'; if (duplicate) complain_about_duplicate(opts,1); op = string_for_opt(opts, negated); @@ -1690,13 +1692,22 @@ boolean tinitial, tfrom_file; num = 0; for(f=ffruit; f; f=f->nextf) { - if (!strcmp(op, f->fname)) goto goodfruit; + if (!strcmp(op, f->fname)) + break; num++; } if (num >= 100) { pline("Doing that so many times isn't very fruitful."); return; } + if (!flags.made_fruit) { + for(forig=ffruit; forig; forig=forig->nextf) { + if (!strcmp(pl_fruit, forig->fname)) { + break; + } + } + + } } goodfruit: nmcpy(pl_fruit, op, PL_FSIZ); @@ -1704,7 +1715,7 @@ goodfruit: if (!*pl_fruit) nmcpy(pl_fruit, "slime mold", PL_FSIZ); if (!initial) { - (void)fruitadd(pl_fruit); + (void)fruitadd(pl_fruit, forig); pline("Fruit is now \"%s\".", pl_fruit); } /* If initial, then initoptions is allowed to do it instead @@ -4218,10 +4229,13 @@ const char *str; /* Returns the fid of the fruit type; if that type already exists, it * returns the fid of that one; if it does not exist, it adds a new fruit * type to the chain and returns the new one. + * If replace_fruit is sent in, replace the fruit in the chain rather than + * adding a new entry--for user specified fruits only. */ int -fruitadd(str) +fruitadd(str, replace_fruit) char *str; +struct fruit *replace_fruit; { register int i; register struct fruit *f; @@ -4282,10 +4296,27 @@ char *str; nmcpy(pl_fruit+8, buf, PL_FSIZ-8); } *altname = '\0'; + /* This flag indicates that a fruit has been made since the + * last time the user set the fruit. If it hasn't, we can + * safely overwrite the current fruit, preventing the user from + * setting many fruits in a row and overflowing. + * Possible expansion: check for specific fruit IDs, not for + * any fruit. + */ + flags.made_fruit = FALSE; + if (replace_fruit) { + for(f=ffruit; f; f = f->nextf) { + if (f == replace_fruit) { + copynchars(f->fname, str, PL_FSIZ-1); + goto nonew; + } + } + } } else { /* not user_supplied, so assumed to be from bones */ copynchars(altname, str, PL_FSIZ-1); sanitize_name(altname); + flags.made_fruit = TRUE; /* for safety. Any fruit name added from a bones level should exist anyway. */ } for(f=ffruit; f; f = f->nextf) { if(f->fid > highest_fruit_id) highest_fruit_id = f->fid; diff --git a/src/restore.c b/src/restore.c index 4d5136f7a..ef7e192dc 100644 --- a/src/restore.c +++ b/src/restore.c @@ -508,7 +508,7 @@ register struct obj *otmp; if (oldf->fid == otmp->spe) break; if (!oldf) impossible("no old fruit?"); - else otmp->spe = fruitadd(oldf->fname); + else otmp->spe = fruitadd(oldf->fname, (struct fruit *)0); } STATIC_OVL -- 2.40.0