1 1.11 dholland /* $NetBSD: hack.objnam.c,v 1.11 2011/08/07 06:03:45 dholland Exp $ */ 2 1.4 christos 3 1.2 mycroft /* 4 1.6 jsm * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, 5 1.6 jsm * Amsterdam 6 1.6 jsm * All rights reserved. 7 1.6 jsm * 8 1.6 jsm * Redistribution and use in source and binary forms, with or without 9 1.6 jsm * modification, are permitted provided that the following conditions are 10 1.6 jsm * met: 11 1.6 jsm * 12 1.6 jsm * - Redistributions of source code must retain the above copyright notice, 13 1.6 jsm * this list of conditions and the following disclaimer. 14 1.6 jsm * 15 1.6 jsm * - Redistributions in binary form must reproduce the above copyright 16 1.6 jsm * notice, this list of conditions and the following disclaimer in the 17 1.6 jsm * documentation and/or other materials provided with the distribution. 18 1.6 jsm * 19 1.6 jsm * - Neither the name of the Stichting Centrum voor Wiskunde en 20 1.6 jsm * Informatica, nor the names of its contributors may be used to endorse or 21 1.6 jsm * promote products derived from this software without specific prior 22 1.6 jsm * written permission. 23 1.6 jsm * 24 1.6 jsm * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 25 1.6 jsm * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 26 1.6 jsm * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 27 1.6 jsm * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 28 1.6 jsm * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 29 1.6 jsm * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 30 1.6 jsm * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 31 1.6 jsm * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32 1.6 jsm * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 1.6 jsm * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 1.6 jsm * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 1.6 jsm */ 36 1.6 jsm 37 1.6 jsm /* 38 1.6 jsm * Copyright (c) 1982 Jay Fenlason <hack (at) gnu.org> 39 1.6 jsm * All rights reserved. 40 1.6 jsm * 41 1.6 jsm * Redistribution and use in source and binary forms, with or without 42 1.6 jsm * modification, are permitted provided that the following conditions 43 1.6 jsm * are met: 44 1.6 jsm * 1. Redistributions of source code must retain the above copyright 45 1.6 jsm * notice, this list of conditions and the following disclaimer. 46 1.6 jsm * 2. Redistributions in binary form must reproduce the above copyright 47 1.6 jsm * notice, this list of conditions and the following disclaimer in the 48 1.6 jsm * documentation and/or other materials provided with the distribution. 49 1.6 jsm * 3. The name of the author may not be used to endorse or promote products 50 1.6 jsm * derived from this software without specific prior written permission. 51 1.6 jsm * 52 1.6 jsm * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 53 1.6 jsm * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 54 1.6 jsm * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 55 1.6 jsm * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 56 1.6 jsm * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 57 1.6 jsm * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 58 1.6 jsm * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 59 1.6 jsm * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 60 1.6 jsm * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 61 1.6 jsm * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 62 1.2 mycroft */ 63 1.2 mycroft 64 1.4 christos #include <sys/cdefs.h> 65 1.2 mycroft #ifndef lint 66 1.11 dholland __RCSID("$NetBSD: hack.objnam.c,v 1.11 2011/08/07 06:03:45 dholland Exp $"); 67 1.4 christos #endif /* not lint */ 68 1.1 cgd 69 1.4 christos #include <stdlib.h> 70 1.4 christos #include "hack.h" 71 1.4 christos #include "extern.h" 72 1.9 dholland #define Snprintf (void) snprintf 73 1.1 cgd #define Strcat (void) strcat 74 1.1 cgd #define Strcpy (void) strcpy 75 1.1 cgd #define PREFIX 15 76 1.1 cgd 77 1.10 dholland static char *strprepend(char *, char *); 78 1.10 dholland static char *sitoa(int); 79 1.10 dholland 80 1.10 dholland static char * 81 1.8 dholland strprepend(char *s, char *pref) 82 1.4 christos { 83 1.4 christos int i = strlen(pref); 84 1.4 christos if (i > PREFIX) { 85 1.1 cgd pline("WARNING: prefix too short."); 86 1.4 christos return (s); 87 1.1 cgd } 88 1.1 cgd s -= i; 89 1.1 cgd (void) strncpy(s, pref, i); /* do not copy trailing 0 */ 90 1.4 christos return (s); 91 1.1 cgd } 92 1.1 cgd 93 1.10 dholland static char * 94 1.8 dholland sitoa(int a) 95 1.4 christos { 96 1.4 christos static char buf[13]; 97 1.9 dholland Snprintf(buf, sizeof(buf), (a < 0) ? "%d" : "+%d", a); 98 1.4 christos return (buf); 99 1.1 cgd } 100 1.1 cgd 101 1.4 christos char * 102 1.8 dholland typename(int otyp) 103 1.1 cgd { 104 1.4 christos static char buf[BUFSZ]; 105 1.9 dholland size_t bufpos; 106 1.4 christos struct objclass *ocl = &objects[otyp]; 107 1.5 jsm const char *an = ocl->oc_name; 108 1.5 jsm const char *dn = ocl->oc_descr; 109 1.4 christos char *un = ocl->oc_uname; 110 1.4 christos int nn = ocl->oc_name_known; 111 1.4 christos switch (ocl->oc_olet) { 112 1.1 cgd case POTION_SYM: 113 1.1 cgd Strcpy(buf, "potion"); 114 1.1 cgd break; 115 1.1 cgd case SCROLL_SYM: 116 1.1 cgd Strcpy(buf, "scroll"); 117 1.1 cgd break; 118 1.1 cgd case WAND_SYM: 119 1.1 cgd Strcpy(buf, "wand"); 120 1.1 cgd break; 121 1.1 cgd case RING_SYM: 122 1.1 cgd Strcpy(buf, "ring"); 123 1.1 cgd break; 124 1.1 cgd default: 125 1.4 christos if (nn) { 126 1.1 cgd Strcpy(buf, an); 127 1.4 christos if (otyp >= TURQUOISE && otyp <= JADE) 128 1.1 cgd Strcat(buf, " stone"); 129 1.9 dholland if (un) { 130 1.9 dholland bufpos = strlen(buf); 131 1.9 dholland Snprintf(buf+bufpos, sizeof(buf)-bufpos, 132 1.9 dholland " called %s", un); 133 1.9 dholland } 134 1.9 dholland if (dn) { 135 1.9 dholland bufpos = strlen(buf); 136 1.9 dholland Snprintf(buf+bufpos, sizeof(buf)-bufpos, 137 1.9 dholland " (%s)", dn); 138 1.9 dholland } 139 1.1 cgd } else { 140 1.9 dholland strlcpy(buf, dn ? dn : an, sizeof(buf)); 141 1.9 dholland if (ocl->oc_olet == GEM_SYM) { 142 1.9 dholland strlcat(buf, " gem", sizeof(buf)); 143 1.9 dholland } 144 1.9 dholland if (un) { 145 1.9 dholland bufpos = strlen(buf); 146 1.9 dholland Snprintf(buf+bufpos, sizeof(buf)-bufpos, 147 1.9 dholland " called %s", un); 148 1.9 dholland } 149 1.1 cgd } 150 1.4 christos return (buf); 151 1.1 cgd } 152 1.1 cgd /* here for ring/scroll/potion/wand */ 153 1.9 dholland if (nn) { 154 1.9 dholland bufpos = strlen(buf); 155 1.9 dholland Snprintf(buf+bufpos, sizeof(buf)-bufpos, " of %s", an); 156 1.9 dholland } 157 1.9 dholland if (un) { 158 1.9 dholland bufpos = strlen(buf); 159 1.9 dholland Snprintf(buf+bufpos, sizeof(buf)-bufpos, " called %s", un); 160 1.9 dholland } 161 1.9 dholland if (dn) { 162 1.9 dholland bufpos = strlen(buf); 163 1.9 dholland Snprintf(buf+bufpos, sizeof(buf)-bufpos, " (%s)", dn); 164 1.9 dholland } 165 1.4 christos return (buf); 166 1.1 cgd } 167 1.1 cgd 168 1.4 christos char * 169 1.8 dholland xname(struct obj *obj) 170 1.1 cgd { 171 1.4 christos static char bufr[BUFSZ]; 172 1.9 dholland /* caution: doname() and aobjnam() below "know" these sizes */ 173 1.4 christos char *buf = &(bufr[PREFIX]); /* leave room for "17 -3 " */ 174 1.9 dholland size_t bufmax = sizeof(bufr) - PREFIX; 175 1.4 christos int nn = objects[obj->otyp].oc_name_known; 176 1.5 jsm const char *an = objects[obj->otyp].oc_name; 177 1.5 jsm const char *dn = objects[obj->otyp].oc_descr; 178 1.4 christos char *un = objects[obj->otyp].oc_uname; 179 1.4 christos int pl = (obj->quan != 1); 180 1.9 dholland 181 1.4 christos if (!obj->dknown && !Blind) 182 1.4 christos obj->dknown = 1;/* %% doesnt belong here */ 183 1.4 christos switch (obj->olet) { 184 1.1 cgd case AMULET_SYM: 185 1.1 cgd Strcpy(buf, (obj->spe < 0 && obj->known) 186 1.4 christos ? "cheap plastic imitation of the " : ""); 187 1.4 christos Strcat(buf, "Amulet of Yendor"); 188 1.1 cgd break; 189 1.1 cgd case TOOL_SYM: 190 1.4 christos if (!nn) { 191 1.9 dholland strlcpy(buf, dn, bufmax); 192 1.1 cgd break; 193 1.1 cgd } 194 1.9 dholland strlcpy(buf, an, bufmax); 195 1.1 cgd break; 196 1.1 cgd case FOOD_SYM: 197 1.4 christos if (obj->otyp == DEAD_HOMUNCULUS && pl) { 198 1.1 cgd pl = 0; 199 1.1 cgd Strcpy(buf, "dead homunculi"); 200 1.1 cgd break; 201 1.1 cgd } 202 1.1 cgd /* fungis ? */ 203 1.11 dholland /* FALLTHROUGH */ 204 1.1 cgd case WEAPON_SYM: 205 1.4 christos if (obj->otyp == WORM_TOOTH && pl) { 206 1.1 cgd pl = 0; 207 1.1 cgd Strcpy(buf, "worm teeth"); 208 1.1 cgd break; 209 1.1 cgd } 210 1.4 christos if (obj->otyp == CRYSKNIFE && pl) { 211 1.1 cgd pl = 0; 212 1.1 cgd Strcpy(buf, "crysknives"); 213 1.1 cgd break; 214 1.1 cgd } 215 1.11 dholland /* FALLTHROUGH */ 216 1.1 cgd case ARMOR_SYM: 217 1.1 cgd case CHAIN_SYM: 218 1.1 cgd case ROCK_SYM: 219 1.9 dholland strlcpy(buf, an, bufmax); 220 1.1 cgd break; 221 1.1 cgd case BALL_SYM: 222 1.9 dholland Snprintf(buf, bufmax, "%sheavy iron ball", 223 1.1 cgd (obj->owt > objects[obj->otyp].oc_weight) ? "very " : ""); 224 1.1 cgd break; 225 1.1 cgd case POTION_SYM: 226 1.4 christos if (nn || un || !obj->dknown) { 227 1.1 cgd Strcpy(buf, "potion"); 228 1.4 christos if (pl) { 229 1.1 cgd pl = 0; 230 1.1 cgd Strcat(buf, "s"); 231 1.1 cgd } 232 1.4 christos if (!obj->dknown) 233 1.4 christos break; 234 1.4 christos if (un) { 235 1.1 cgd Strcat(buf, " called "); 236 1.9 dholland strlcat(buf, un, bufmax); 237 1.1 cgd } else { 238 1.1 cgd Strcat(buf, " of "); 239 1.9 dholland strlcat(buf, an, bufmax); 240 1.1 cgd } 241 1.1 cgd } else { 242 1.9 dholland strlcpy(buf, dn, bufmax); 243 1.9 dholland strlcat(buf, " potion", bufmax); 244 1.1 cgd } 245 1.1 cgd break; 246 1.1 cgd case SCROLL_SYM: 247 1.1 cgd Strcpy(buf, "scroll"); 248 1.4 christos if (pl) { 249 1.1 cgd pl = 0; 250 1.1 cgd Strcat(buf, "s"); 251 1.1 cgd } 252 1.4 christos if (!obj->dknown) 253 1.4 christos break; 254 1.4 christos if (nn) { 255 1.1 cgd Strcat(buf, " of "); 256 1.9 dholland strlcat(buf, an, bufmax); 257 1.4 christos } else if (un) { 258 1.1 cgd Strcat(buf, " called "); 259 1.9 dholland strlcat(buf, un, bufmax); 260 1.1 cgd } else { 261 1.1 cgd Strcat(buf, " labeled "); 262 1.9 dholland strlcat(buf, dn, bufmax); 263 1.1 cgd } 264 1.1 cgd break; 265 1.1 cgd case WAND_SYM: 266 1.4 christos if (!obj->dknown) 267 1.9 dholland Snprintf(buf, bufmax, "wand"); 268 1.4 christos else if (nn) 269 1.9 dholland Snprintf(buf, bufmax, "wand of %s", an); 270 1.4 christos else if (un) 271 1.9 dholland Snprintf(buf, bufmax, "wand called %s", un); 272 1.1 cgd else 273 1.9 dholland Snprintf(buf, bufmax, "%s wand", dn); 274 1.1 cgd break; 275 1.1 cgd case RING_SYM: 276 1.4 christos if (!obj->dknown) 277 1.9 dholland Snprintf(buf, bufmax, "ring"); 278 1.4 christos else if (nn) 279 1.9 dholland Snprintf(buf, bufmax, "ring of %s", an); 280 1.4 christos else if (un) 281 1.9 dholland Snprintf(buf, bufmax, "ring called %s", un); 282 1.1 cgd else 283 1.9 dholland Snprintf(buf, bufmax, "%s ring", dn); 284 1.1 cgd break; 285 1.1 cgd case GEM_SYM: 286 1.4 christos if (!obj->dknown) { 287 1.1 cgd Strcpy(buf, "gem"); 288 1.1 cgd break; 289 1.1 cgd } 290 1.4 christos if (!nn) { 291 1.9 dholland Snprintf(buf, bufmax, "%s gem", dn); 292 1.1 cgd break; 293 1.1 cgd } 294 1.9 dholland strlcpy(buf, an, bufmax); 295 1.4 christos if (obj->otyp >= TURQUOISE && obj->otyp <= JADE) 296 1.9 dholland strlcat(buf, " stone", bufmax); 297 1.1 cgd break; 298 1.1 cgd default: 299 1.9 dholland Snprintf(buf, bufmax, "glorkum %c (0%o) %u %d", 300 1.4 christos obj->olet, obj->olet, obj->otyp, obj->spe); 301 1.1 cgd } 302 1.4 christos if (pl) { 303 1.4 christos char *p; 304 1.1 cgd 305 1.4 christos for (p = buf; *p; p++) { 306 1.4 christos if (!strncmp(" of ", p, 4)) { 307 1.1 cgd /* pieces of, cloves of, lumps of */ 308 1.4 christos int c1, c2 = 's'; 309 1.1 cgd 310 1.1 cgd do { 311 1.4 christos c1 = c2; 312 1.4 christos c2 = *p; 313 1.4 christos *p++ = c1; 314 1.4 christos } while (c1); 315 1.1 cgd goto nopl; 316 1.1 cgd } 317 1.1 cgd } 318 1.4 christos p = eos(buf) - 1; 319 1.4 christos if (*p == 's' || *p == 'z' || *p == 'x' || 320 1.9 dholland (*p == 'h' && p[-1] == 's')) { 321 1.9 dholland /* boxes */ 322 1.9 dholland strlcat(buf, "es", bufmax); 323 1.9 dholland } else if (*p == 'y' && !strchr(vowels, p[-1])) { 324 1.9 dholland /* rubies, zruties */ 325 1.9 dholland *p = '\0'; 326 1.9 dholland strlcat(buf, "ies", bufmax); 327 1.9 dholland } else { 328 1.9 dholland strlcat(buf, "s", bufmax); 329 1.9 dholland } 330 1.1 cgd } 331 1.1 cgd nopl: 332 1.4 christos if (obj->onamelth) { 333 1.9 dholland strlcat(buf, " named ", bufmax); 334 1.9 dholland strlcat(buf, ONAME(obj), bufmax); 335 1.1 cgd } 336 1.4 christos return (buf); 337 1.1 cgd } 338 1.1 cgd 339 1.4 christos char * 340 1.8 dholland doname(struct obj *obj) 341 1.1 cgd { 342 1.4 christos char prefix[PREFIX]; 343 1.4 christos char *bp = xname(obj); 344 1.9 dholland size_t bppos, bpmax; 345 1.9 dholland 346 1.9 dholland /* XXX do this better somehow w/o knowing internals of xname() */ 347 1.9 dholland bpmax = BUFSZ - PREFIX; 348 1.9 dholland 349 1.4 christos if (obj->quan != 1) 350 1.9 dholland Snprintf(prefix, sizeof(prefix), "%u ", obj->quan); 351 1.1 cgd else 352 1.1 cgd Strcpy(prefix, "a "); 353 1.4 christos switch (obj->olet) { 354 1.1 cgd case AMULET_SYM: 355 1.4 christos if (strncmp(bp, "cheap ", 6)) 356 1.1 cgd Strcpy(prefix, "the "); 357 1.1 cgd break; 358 1.1 cgd case ARMOR_SYM: 359 1.4 christos if (obj->owornmask & W_ARMOR) 360 1.9 dholland strlcat(bp, " (being worn)", bpmax); 361 1.11 dholland /* FALLTHROUGH */ 362 1.1 cgd case WEAPON_SYM: 363 1.4 christos if (obj->known) { 364 1.9 dholland strlcat(prefix, sitoa(obj->spe), sizeof(prefix)); 365 1.9 dholland strlcat(prefix, " ", sizeof(prefix)); 366 1.1 cgd } 367 1.1 cgd break; 368 1.1 cgd case WAND_SYM: 369 1.9 dholland if (obj->known) { 370 1.9 dholland bppos = strlen(bp); 371 1.9 dholland Snprintf(bp+bppos, bpmax-bppos, " (%d)", obj->spe); 372 1.9 dholland } 373 1.1 cgd break; 374 1.1 cgd case RING_SYM: 375 1.4 christos if (obj->owornmask & W_RINGR) 376 1.9 dholland strlcat(bp, " (on right hand)", bpmax); 377 1.4 christos if (obj->owornmask & W_RINGL) 378 1.9 dholland strlcat(bp, " (on left hand)", bpmax); 379 1.4 christos if (obj->known && (objects[obj->otyp].bits & SPEC)) { 380 1.9 dholland strlcat(prefix, sitoa(obj->spe), sizeof(prefix)); 381 1.9 dholland strlcat(prefix, " ", sizeof(prefix)); 382 1.1 cgd } 383 1.1 cgd break; 384 1.1 cgd } 385 1.4 christos if (obj->owornmask & W_WEP) 386 1.9 dholland strlcat(bp, " (weapon in hand)", bpmax); 387 1.4 christos if (obj->unpaid) 388 1.9 dholland strlcat(bp, " (unpaid)", bpmax); 389 1.4 christos if (!strcmp(prefix, "a ") && strchr(vowels, *bp)) 390 1.1 cgd Strcpy(prefix, "an "); 391 1.1 cgd bp = strprepend(bp, prefix); 392 1.4 christos return (bp); 393 1.1 cgd } 394 1.1 cgd 395 1.1 cgd /* used only in hack.fight.c (thitu) */ 396 1.4 christos void 397 1.9 dholland setan(const char *str, char *buf, size_t bufmax) 398 1.1 cgd { 399 1.4 christos if (strchr(vowels, *str)) 400 1.9 dholland Snprintf(buf, bufmax, "an %s", str); 401 1.1 cgd else 402 1.9 dholland Snprintf(buf, bufmax, "a %s", str); 403 1.1 cgd } 404 1.1 cgd 405 1.4 christos char * 406 1.8 dholland aobjnam(struct obj *otmp, const char *verb) 407 1.4 christos { 408 1.4 christos char *bp = xname(otmp); 409 1.4 christos char prefix[PREFIX]; 410 1.9 dholland size_t bpmax; 411 1.9 dholland 412 1.9 dholland /* XXX do this better somehow w/o knowing internals of xname() */ 413 1.9 dholland bpmax = BUFSZ - PREFIX; 414 1.9 dholland 415 1.4 christos if (otmp->quan != 1) { 416 1.9 dholland Snprintf(prefix, sizeof(prefix), "%u ", otmp->quan); 417 1.1 cgd bp = strprepend(bp, prefix); 418 1.1 cgd } 419 1.4 christos if (verb) { 420 1.1 cgd /* verb is given in plural (i.e., without trailing s) */ 421 1.9 dholland strlcat(bp, " ", bpmax); 422 1.4 christos if (otmp->quan != 1) 423 1.9 dholland strlcat(bp, verb, bpmax); 424 1.4 christos else if (!strcmp(verb, "are")) 425 1.9 dholland strlcat(bp, "is", bpmax); 426 1.1 cgd else { 427 1.9 dholland strlcat(bp, verb, bpmax); 428 1.9 dholland strlcat(bp, "s", bpmax); 429 1.1 cgd } 430 1.1 cgd } 431 1.4 christos return (bp); 432 1.1 cgd } 433 1.1 cgd 434 1.4 christos char * 435 1.8 dholland Doname(struct obj *obj) 436 1.1 cgd { 437 1.4 christos char *s = doname(obj); 438 1.1 cgd 439 1.4 christos if ('a' <= *s && *s <= 'z') 440 1.4 christos *s -= ('a' - 'A'); 441 1.4 christos return (s); 442 1.1 cgd } 443 1.1 cgd 444 1.10 dholland static const char *const wrp[] = {"wand", "ring", "potion", "scroll", "gem"}; 445 1.10 dholland static const char wrpsym[] = {WAND_SYM, RING_SYM, POTION_SYM, SCROLL_SYM, GEM_SYM}; 446 1.1 cgd 447 1.4 christos struct obj * 448 1.8 dholland readobjnam(char *bp) 449 1.4 christos { 450 1.4 christos char *p; 451 1.7 dholland unsigned ii; 452 1.7 dholland int i; 453 1.4 christos int cnt, spe, spesgn, typ, heavy; 454 1.4 christos char let; 455 1.4 christos char *un, *dn, *an; 456 1.4 christos /* int the = 0; char *oname = 0; */ 457 1.1 cgd cnt = spe = spesgn = typ = heavy = 0; 458 1.1 cgd let = 0; 459 1.1 cgd an = dn = un = 0; 460 1.4 christos for (p = bp; *p; p++) 461 1.4 christos if ('A' <= *p && *p <= 'Z') 462 1.4 christos *p += 'a' - 'A'; 463 1.4 christos if (!strncmp(bp, "the ", 4)) { 464 1.4 christos /* the = 1; */ 465 1.1 cgd bp += 4; 466 1.4 christos } else if (!strncmp(bp, "an ", 3)) { 467 1.1 cgd cnt = 1; 468 1.1 cgd bp += 3; 469 1.4 christos } else if (!strncmp(bp, "a ", 2)) { 470 1.1 cgd cnt = 1; 471 1.1 cgd bp += 2; 472 1.1 cgd } 473 1.4 christos if (!cnt && digit(*bp)) { 474 1.1 cgd cnt = atoi(bp); 475 1.4 christos while (digit(*bp)) 476 1.4 christos bp++; 477 1.4 christos while (*bp == ' ') 478 1.4 christos bp++; 479 1.1 cgd } 480 1.4 christos if (!cnt) 481 1.4 christos cnt = 1; /* %% what with "gems" etc. ? */ 482 1.1 cgd 483 1.4 christos if (*bp == '+' || *bp == '-') { 484 1.1 cgd spesgn = (*bp++ == '+') ? 1 : -1; 485 1.1 cgd spe = atoi(bp); 486 1.4 christos while (digit(*bp)) 487 1.4 christos bp++; 488 1.4 christos while (*bp == ' ') 489 1.4 christos bp++; 490 1.1 cgd } else { 491 1.4 christos p = strrchr(bp, '('); 492 1.4 christos if (p) { 493 1.4 christos if (p > bp && p[-1] == ' ') 494 1.4 christos p[-1] = 0; 495 1.4 christos else 496 1.4 christos *p = 0; 497 1.1 cgd p++; 498 1.1 cgd spe = atoi(p); 499 1.4 christos while (digit(*p)) 500 1.4 christos p++; 501 1.4 christos if (strcmp(p, ")")) 502 1.4 christos spe = 0; 503 1.4 christos else 504 1.4 christos spesgn = 1; 505 1.4 christos } 506 1.4 christos } 507 1.4 christos /* 508 1.4 christos * now we have the actual name, as delivered by xname, say green 509 1.4 christos * potions called whisky scrolls labeled "QWERTY" egg dead zruties 510 1.4 christos * fortune cookies very heavy iron ball named hoei wand of wishing 511 1.4 christos * elven cloak 512 1.4 christos */ 513 1.4 christos for (p = bp; *p; p++) 514 1.4 christos if (!strncmp(p, " named ", 7)) { 515 1.4 christos *p = 0; 516 1.4 christos /* oname = p+7; */ 517 1.4 christos } 518 1.4 christos for (p = bp; *p; p++) 519 1.4 christos if (!strncmp(p, " called ", 8)) { 520 1.4 christos *p = 0; 521 1.4 christos un = p + 8; 522 1.4 christos } 523 1.4 christos for (p = bp; *p; p++) 524 1.4 christos if (!strncmp(p, " labeled ", 9)) { 525 1.4 christos *p = 0; 526 1.4 christos dn = p + 9; 527 1.4 christos } 528 1.1 cgd /* first change to singular if necessary */ 529 1.4 christos if (cnt != 1) { 530 1.1 cgd /* find "cloves of garlic", "worthless pieces of blue glass" */ 531 1.4 christos for (p = bp; *p; p++) 532 1.4 christos if (!strncmp(p, "s of ", 5)) { 533 1.4 christos while ((*p = p[1]) != '\0') 534 1.4 christos p++; 535 1.4 christos goto sing; 536 1.4 christos } 537 1.1 cgd /* remove -s or -es (boxes) or -ies (rubies, zruties) */ 538 1.1 cgd p = eos(bp); 539 1.4 christos if (p[-1] == 's') { 540 1.4 christos if (p[-2] == 'e') { 541 1.4 christos if (p[-3] == 'i') { 542 1.4 christos if (!strcmp(p - 7, "cookies")) 543 1.1 cgd goto mins; 544 1.4 christos Strcpy(p - 3, "y"); 545 1.1 cgd goto sing; 546 1.1 cgd } 547 1.1 cgd /* note: cloves / knives from clove / knife */ 548 1.4 christos if (!strcmp(p - 6, "knives")) { 549 1.4 christos Strcpy(p - 3, "fe"); 550 1.1 cgd goto sing; 551 1.1 cgd } 552 1.1 cgd /* note: nurses, axes but boxes */ 553 1.4 christos if (!strcmp(p - 5, "boxes")) { 554 1.1 cgd p[-2] = 0; 555 1.1 cgd goto sing; 556 1.1 cgd } 557 1.1 cgd } 558 1.4 christos mins: 559 1.1 cgd p[-1] = 0; 560 1.1 cgd } else { 561 1.4 christos if (!strcmp(p - 9, "homunculi")) { 562 1.4 christos Strcpy(p - 1, "us"); /* !! makes string 563 1.4 christos * longer */ 564 1.1 cgd goto sing; 565 1.1 cgd } 566 1.4 christos if (!strcmp(p - 5, "teeth")) { 567 1.4 christos Strcpy(p - 5, "tooth"); 568 1.1 cgd goto sing; 569 1.1 cgd } 570 1.1 cgd /* here we cannot find the plural suffix */ 571 1.1 cgd } 572 1.1 cgd } 573 1.1 cgd sing: 574 1.4 christos if (!strcmp(bp, "amulet of yendor")) { 575 1.1 cgd typ = AMULET_OF_YENDOR; 576 1.1 cgd goto typfnd; 577 1.1 cgd } 578 1.1 cgd p = eos(bp); 579 1.4 christos if (!strcmp(p - 5, " mail")) { /* Note: ring mail is not a ring ! */ 580 1.1 cgd let = ARMOR_SYM; 581 1.1 cgd an = bp; 582 1.1 cgd goto srch; 583 1.1 cgd } 584 1.7 dholland for (ii = 0; ii < sizeof(wrpsym); ii++) { 585 1.7 dholland int j = strlen(wrp[ii]); 586 1.7 dholland if (!strncmp(bp, wrp[ii], j)) { 587 1.7 dholland let = wrpsym[ii]; 588 1.1 cgd bp += j; 589 1.4 christos if (!strncmp(bp, " of ", 4)) 590 1.4 christos an = bp + 4; 591 1.1 cgd /* else if(*bp) ?? */ 592 1.1 cgd goto srch; 593 1.1 cgd } 594 1.7 dholland if (!strcmp(p - j, wrp[ii])) { 595 1.7 dholland let = wrpsym[ii]; 596 1.1 cgd p -= j; 597 1.1 cgd *p = 0; 598 1.4 christos if (p[-1] == ' ') 599 1.4 christos p[-1] = 0; 600 1.1 cgd dn = bp; 601 1.1 cgd goto srch; 602 1.1 cgd } 603 1.1 cgd } 604 1.4 christos if (!strcmp(p - 6, " stone")) { 605 1.1 cgd p[-6] = 0; 606 1.1 cgd let = GEM_SYM; 607 1.1 cgd an = bp; 608 1.1 cgd goto srch; 609 1.1 cgd } 610 1.4 christos if (!strcmp(bp, "very heavy iron ball")) { 611 1.1 cgd heavy = 1; 612 1.1 cgd typ = HEAVY_IRON_BALL; 613 1.1 cgd goto typfnd; 614 1.1 cgd } 615 1.1 cgd an = bp; 616 1.1 cgd srch: 617 1.4 christos if (!an && !dn && !un) 618 1.1 cgd goto any; 619 1.1 cgd i = 1; 620 1.4 christos if (let) 621 1.4 christos i = bases[letindex(let)]; 622 1.4 christos while (i <= NROFOBJECTS && (!let || objects[i].oc_olet == let)) { 623 1.5 jsm const char *zn = objects[i].oc_name; 624 1.1 cgd 625 1.4 christos if (!zn) 626 1.4 christos goto nxti; 627 1.4 christos if (an && strcmp(an, zn)) 628 1.1 cgd goto nxti; 629 1.4 christos if (dn && (!(zn = objects[i].oc_descr) || strcmp(dn, zn))) 630 1.1 cgd goto nxti; 631 1.4 christos if (un && (!(zn = objects[i].oc_uname) || strcmp(un, zn))) 632 1.1 cgd goto nxti; 633 1.1 cgd typ = i; 634 1.1 cgd goto typfnd; 635 1.4 christos nxti: 636 1.1 cgd i++; 637 1.1 cgd } 638 1.1 cgd any: 639 1.4 christos if (!let) 640 1.4 christos let = wrpsym[rn2(sizeof(wrpsym))]; 641 1.1 cgd typ = probtype(let); 642 1.1 cgd typfnd: 643 1.4 christos { 644 1.4 christos struct obj *otmp; 645 1.4 christos let = objects[typ].oc_olet; 646 1.4 christos otmp = mksobj(typ); 647 1.4 christos if (heavy) 648 1.4 christos otmp->owt += 15; 649 1.4 christos if (cnt > 0 && strchr("%?!*)", let) && 650 1.1 cgd (cnt < 4 || (let == WEAPON_SYM && typ <= ROCK && cnt < 20))) 651 1.4 christos otmp->quan = cnt; 652 1.1 cgd 653 1.4 christos if (spe > 3 && spe > otmp->spe) 654 1.4 christos spe = 0; 655 1.4 christos else if (let == WAND_SYM) 656 1.4 christos spe = otmp->spe; 657 1.4 christos if (spe == 3 && u.uluck < 0) 658 1.4 christos spesgn = -1; 659 1.4 christos if (let != WAND_SYM && spesgn == -1) 660 1.4 christos spe = -spe; 661 1.4 christos if (let == BALL_SYM) 662 1.4 christos spe = 0; 663 1.4 christos else if (let == AMULET_SYM) 664 1.4 christos spe = -1; 665 1.4 christos else if (typ == WAN_WISHING && rn2(10)) 666 1.4 christos spe = (rn2(10) ? -1 : 0); 667 1.4 christos otmp->spe = spe; 668 1.1 cgd 669 1.4 christos if (spesgn == -1) 670 1.4 christos otmp->cursed = 1; 671 1.1 cgd 672 1.4 christos return (otmp); 673 1.4 christos } 674 1.1 cgd } 675