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. */
| 8167 | * adding a new entry--for user specified fruits only. |
| 8168 | */ |
| 8169 | int |
| 8170 | fruitadd(char *str, struct fruit *replace_fruit) |
| 8171 | { |
| 8172 | int i; |
| 8173 | struct fruit *f; |
| 8174 | int highest_fruit_id = 0, globpfx; |
| 8175 | char buf[PL_FSIZ], altname[PL_FSIZ]; |
| 8176 | boolean user_specified = (str == svp.pl_fruit); |
| 8177 | /* if not user-specified, then it's a fruit name for a fruit on |
| 8178 | * a bones level or from orctown raider's loot... |
| 8179 | */ |
| 8180 | |
| 8181 | /* Note: every fruit has an id (kept in obj->spe) of at least 1; |
| 8182 | * 0 is an error. |
| 8183 | */ |
| 8184 | if (user_specified) { |
| 8185 | boolean found = FALSE, numeric = FALSE; |
| 8186 | |
| 8187 | /* force fruit to be singular; this handling is not |
| 8188 | needed--or wanted--for fruits from bones because |
| 8189 | they already received it in their original game; |
| 8190 | str==pl_fruit but makesingular() creates a copy |
| 8191 | so we need to copy that back into pl_fruit */ |
| 8192 | nmcpy(svp.pl_fruit, makesingular(str), PL_FSIZ); |
| 8193 | |
| 8194 | /* disallow naming after other foods (since it'd be impossible |
| 8195 | * to tell the difference); globs might have a size prefix which |
| 8196 | * needs to be skipped in order to match the object type name |
| 8197 | */ |
| 8198 | globpfx = (!strncmp(svp.pl_fruit, "small ", 6) |
| 8199 | || !strncmp(svp.pl_fruit, "large ", 6)) ? 6 |
| 8200 | : (!strncmp(svp.pl_fruit, "medium ", 7)) ? 7 |
| 8201 | : (!strncmp(svp.pl_fruit, "very large ", 11)) ? 11 |
| 8202 | : 0; |
| 8203 | for (i = svb.bases[FOOD_CLASS]; objects[i].oc_class == FOOD_CLASS; |
| 8204 | i++) { |
| 8205 | if (!strcmp(OBJ_NAME(objects[i]), svp.pl_fruit) |
| 8206 | || (globpfx > 0 && !strcmp(OBJ_NAME(objects[i]), |
| 8207 | &svp.pl_fruit[globpfx]))) { |
| 8208 | found = TRUE; |
| 8209 | break; |
| 8210 | } |
| 8211 | } |
| 8212 | if (!found) { |
| 8213 | char *c; |
| 8214 | |
| 8215 | for (c = svp.pl_fruit; *c >= '0' && *c <= '9'; c++) |
| 8216 | continue; |
| 8217 | if (!*c || isspace((uchar) *c)) |
| 8218 | numeric = TRUE; |
| 8219 | } |
| 8220 | if (found || numeric |
| 8221 | /* these checks for applying food attributes to actual items |
| 8222 | are case sensitive; "glob of foo" is caught by 'found' |
| 8223 | if 'foo' is a valid glob; when not valid, allow it as-is */ |
| 8224 | || !strncmp(svp.pl_fruit, "cursed ", 7) |
| 8225 | || !strncmp(svp.pl_fruit, "uncursed ", 9) |
| 8226 | || !strncmp(svp.pl_fruit, "blessed ", 8) |
no test coverage detected