objnam.c (11389B)
1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 2 /* objnam.c - version 1.0.2 */ 3 4 #include "hack.h" 5 #define Sprintf (void) sprintf 6 #define Strcat (void) strcat 7 #define Strcpy (void) strcpy 8 #define PREFIX 15 9 extern char *eos(); 10 extern int bases[]; 11 12 char * 13 strprepend(s,pref) register char *s, *pref; { 14 register int i = strlen(pref); 15 if(i > PREFIX) { 16 pline("WARNING: prefix too short."); 17 return(s); 18 } 19 s -= i; 20 (void) strncpy(s, pref, i); /* do not copy trailing 0 */ 21 return(s); 22 } 23 24 char * 25 sitoa(a) int a; { 26 static char buf[13]; 27 Sprintf(buf, (a < 0) ? "%d" : "+%d", a); 28 return(buf); 29 } 30 31 char * 32 typename(otyp) 33 register int otyp; 34 { 35 static char buf[BUFSZ]; 36 register struct objclass *ocl = &objects[otyp]; 37 register char *an = ocl->oc_name; 38 register char *dn = ocl->oc_descr; 39 register char *un = ocl->oc_uname; 40 register int nn = ocl->oc_name_known; 41 switch(ocl->oc_olet) { 42 case POTION_SYM: 43 Strcpy(buf, "potion"); 44 break; 45 case SCROLL_SYM: 46 Strcpy(buf, "scroll"); 47 break; 48 case WAND_SYM: 49 Strcpy(buf, "wand"); 50 break; 51 case RING_SYM: 52 Strcpy(buf, "ring"); 53 break; 54 default: 55 if(nn) { 56 Strcpy(buf, an); 57 if(otyp >= TURQUOISE && otyp <= JADE) 58 Strcat(buf, " stone"); 59 if(un) 60 Sprintf(eos(buf), " called %s", un); 61 if(dn) 62 Sprintf(eos(buf), " (%s)", dn); 63 } else { 64 Strcpy(buf, dn ? dn : an); 65 if(ocl->oc_olet == GEM_SYM) 66 Strcat(buf, " gem"); 67 if(un) 68 Sprintf(eos(buf), " called %s", un); 69 } 70 return(buf); 71 } 72 /* here for ring/scroll/potion/wand */ 73 if(nn) 74 Sprintf(eos(buf), " of %s", an); 75 if(un) 76 Sprintf(eos(buf), " called %s", un); 77 if(dn) 78 Sprintf(eos(buf), " (%s)", dn); 79 return(buf); 80 } 81 82 char * 83 xname(obj) 84 register struct obj *obj; 85 { 86 static char bufr[BUFSZ]; 87 register char *buf = &(bufr[PREFIX]); /* leave room for "17 -3 " */ 88 register int nn = objects[obj->otyp].oc_name_known; 89 register char *an = objects[obj->otyp].oc_name; 90 register char *dn = objects[obj->otyp].oc_descr; 91 register char *un = objects[obj->otyp].oc_uname; 92 register int pl = (obj->quan != 1); 93 if(!obj->dknown && !Blind) obj->dknown = 1; /* %% doesnt belong here */ 94 switch(obj->olet) { 95 case AMULET_SYM: 96 Strcpy(buf, (obj->spe < 0 && obj->known) 97 ? "cheap plastic imitation of the " : ""); 98 Strcat(buf,"Amulet of Yendor"); 99 break; 100 case TOOL_SYM: 101 if(!nn) { 102 Strcpy(buf, dn); 103 break; 104 } 105 Strcpy(buf,an); 106 break; 107 case FOOD_SYM: 108 if(obj->otyp == DEAD_HOMUNCULUS && pl) { 109 pl = 0; 110 Strcpy(buf, "dead homunculi"); 111 break; 112 } 113 /* fungis ? */ 114 /* fall into next case */ 115 case WEAPON_SYM: 116 if(obj->otyp == WORM_TOOTH && pl) { 117 pl = 0; 118 Strcpy(buf, "worm teeth"); 119 break; 120 } 121 if(obj->otyp == CRYSKNIFE && pl) { 122 pl = 0; 123 Strcpy(buf, "crysknives"); 124 break; 125 } 126 /* fall into next case */ 127 case ARMOR_SYM: 128 case CHAIN_SYM: 129 case ROCK_SYM: 130 Strcpy(buf,an); 131 break; 132 case BALL_SYM: 133 Sprintf(buf, "%sheavy iron ball", 134 (obj->owt > objects[obj->otyp].oc_weight) ? "very " : ""); 135 break; 136 case POTION_SYM: 137 if(nn || un || !obj->dknown) { 138 Strcpy(buf, "potion"); 139 if(pl) { 140 pl = 0; 141 Strcat(buf, "s"); 142 } 143 if(!obj->dknown) break; 144 if(un) { 145 Strcat(buf, " called "); 146 Strcat(buf, un); 147 } else { 148 Strcat(buf, " of "); 149 Strcat(buf, an); 150 } 151 } else { 152 Strcpy(buf, dn); 153 Strcat(buf, " potion"); 154 } 155 break; 156 case SCROLL_SYM: 157 Strcpy(buf, "scroll"); 158 if(pl) { 159 pl = 0; 160 Strcat(buf, "s"); 161 } 162 if(!obj->dknown) break; 163 if(nn) { 164 Strcat(buf, " of "); 165 Strcat(buf, an); 166 } else if(un) { 167 Strcat(buf, " called "); 168 Strcat(buf, un); 169 } else { 170 Strcat(buf, " labeled "); 171 Strcat(buf, dn); 172 } 173 break; 174 case WAND_SYM: 175 if(!obj->dknown) 176 Sprintf(buf, "wand"); 177 else if(nn) 178 Sprintf(buf, "wand of %s", an); 179 else if(un) 180 Sprintf(buf, "wand called %s", un); 181 else 182 Sprintf(buf, "%s wand", dn); 183 break; 184 case RING_SYM: 185 if(!obj->dknown) 186 Sprintf(buf, "ring"); 187 else if(nn) 188 Sprintf(buf, "ring of %s", an); 189 else if(un) 190 Sprintf(buf, "ring called %s", un); 191 else 192 Sprintf(buf, "%s ring", dn); 193 break; 194 case GEM_SYM: 195 if(!obj->dknown) { 196 Strcpy(buf, "gem"); 197 break; 198 } 199 if(!nn) { 200 Sprintf(buf, "%s gem", dn); 201 break; 202 } 203 Strcpy(buf, an); 204 if(obj->otyp >= TURQUOISE && obj->otyp <= JADE) 205 Strcat(buf, " stone"); 206 break; 207 default: 208 Sprintf(buf,"glorkum %c (0%o) %u %d", 209 obj->olet,obj->olet,obj->otyp,obj->spe); 210 } 211 if(pl) { 212 register char *p; 213 214 for(p = buf; *p; p++) { 215 if(!strncmp(" of ", p, 4)) { 216 /* pieces of, cloves of, lumps of */ 217 register int c1, c2 = 's'; 218 219 do { 220 c1 = c2; c2 = *p; *p++ = c1; 221 } while(c1); 222 goto nopl; 223 } 224 } 225 p = eos(buf)-1; 226 if(*p == 's' || *p == 'z' || *p == 'x' || 227 (*p == 'h' && p[-1] == 's')) 228 Strcat(buf, "es"); /* boxes */ 229 else if(*p == 'y' && !index(vowels, p[-1])) 230 Strcpy(p, "ies"); /* rubies, zruties */ 231 else 232 Strcat(buf, "s"); 233 } 234 nopl: 235 if(obj->onamelth) { 236 Strcat(buf, " named "); 237 Strcat(buf, ONAME(obj)); 238 } 239 return(buf); 240 } 241 242 char * 243 doname(obj) 244 register struct obj *obj; 245 { 246 char prefix[PREFIX]; 247 register char *bp = xname(obj); 248 if(obj->quan != 1) 249 Sprintf(prefix, "%u ", obj->quan); 250 else 251 Strcpy(prefix, "a "); 252 switch(obj->olet) { 253 case AMULET_SYM: 254 if(strncmp(bp, "cheap ", 6)) 255 Strcpy(prefix, "the "); 256 break; 257 case ARMOR_SYM: 258 if(obj->owornmask & W_ARMOR) 259 Strcat(bp, " (being worn)"); 260 /* fall into next case */ 261 case WEAPON_SYM: 262 if(obj->known) { 263 Strcat(prefix, sitoa(obj->spe)); 264 Strcat(prefix, " "); 265 } 266 break; 267 case WAND_SYM: 268 if(obj->known) 269 Sprintf(eos(bp), " (%d)", obj->spe); 270 break; 271 case RING_SYM: 272 if(obj->owornmask & W_RINGR) Strcat(bp, " (on right hand)"); 273 if(obj->owornmask & W_RINGL) Strcat(bp, " (on left hand)"); 274 if(obj->known && (objects[obj->otyp].bits & SPEC)) { 275 Strcat(prefix, sitoa(obj->spe)); 276 Strcat(prefix, " "); 277 } 278 break; 279 } 280 if(obj->owornmask & W_WEP) 281 Strcat(bp, " (weapon in hand)"); 282 if(obj->unpaid) 283 Strcat(bp, " (unpaid)"); 284 if(!strcmp(prefix, "a ") && index(vowels, *bp)) 285 Strcpy(prefix, "an "); 286 bp = strprepend(bp, prefix); 287 return(bp); 288 } 289 290 /* used only in fight.c (thitu) */ 291 setan(str,buf) 292 register char *str,*buf; 293 { 294 if(index(vowels,*str)) 295 Sprintf(buf, "an %s", str); 296 else 297 Sprintf(buf, "a %s", str); 298 } 299 300 char * 301 aobjnam(otmp,verb) register struct obj *otmp; register char *verb; { 302 register char *bp = xname(otmp); 303 char prefix[PREFIX]; 304 if(otmp->quan != 1) { 305 Sprintf(prefix, "%u ", otmp->quan); 306 bp = strprepend(bp, prefix); 307 } 308 309 if(verb) { 310 /* verb is given in plural (i.e., without trailing s) */ 311 Strcat(bp, " "); 312 if(otmp->quan != 1) 313 Strcat(bp, verb); 314 else if(!strcmp(verb, "are")) 315 Strcat(bp, "is"); 316 else { 317 Strcat(bp, verb); 318 Strcat(bp, "s"); 319 } 320 } 321 return(bp); 322 } 323 324 char * 325 Doname(obj) 326 register struct obj *obj; 327 { 328 register char *s = doname(obj); 329 330 if('a' <= *s && *s <= 'z') *s -= ('a' - 'A'); 331 return(s); 332 } 333 334 char *wrp[] = { "wand", "ring", "potion", "scroll", "gem" }; 335 char wrpsym[] = { WAND_SYM, RING_SYM, POTION_SYM, SCROLL_SYM, GEM_SYM }; 336 337 struct obj * 338 readobjnam(bp) register char *bp; { 339 register char *p; 340 register int i; 341 int cnt, spe, spesgn, typ, heavy; 342 char let; 343 char *un, *dn, *an; 344 /* int the = 0; char *oname = 0; */ 345 cnt = spe = spesgn = typ = heavy = 0; 346 let = 0; 347 an = dn = un = 0; 348 for(p = bp; *p; p++) 349 if('A' <= *p && *p <= 'Z') *p += 'a'-'A'; 350 if(!strncmp(bp, "the ", 4)){ 351 /* the = 1; */ 352 bp += 4; 353 } else if(!strncmp(bp, "an ", 3)){ 354 cnt = 1; 355 bp += 3; 356 } else if(!strncmp(bp, "a ", 2)){ 357 cnt = 1; 358 bp += 2; 359 } 360 if(!cnt && digit(*bp)){ 361 cnt = atoi(bp); 362 while(digit(*bp)) bp++; 363 while(*bp == ' ') bp++; 364 } 365 if(!cnt) cnt = 1; /* %% what with "gems" etc. ? */ 366 367 if(*bp == '+' || *bp == '-'){ 368 spesgn = (*bp++ == '+') ? 1 : -1; 369 spe = atoi(bp); 370 while(digit(*bp)) bp++; 371 while(*bp == ' ') bp++; 372 } else { 373 p = rindex(bp, '('); 374 if(p) { 375 if(p > bp && p[-1] == ' ') p[-1] = 0; 376 else *p = 0; 377 p++; 378 spe = atoi(p); 379 while(digit(*p)) p++; 380 if(strcmp(p, ")")) spe = 0; 381 else spesgn = 1; 382 } 383 } 384 /* now we have the actual name, as delivered by xname, say 385 green potions called whisky 386 scrolls labeled "QWERTY" 387 egg 388 dead zruties 389 fortune cookies 390 very heavy iron ball named hoei 391 wand of wishing 392 elven cloak 393 */ 394 for(p = bp; *p; p++) if(!strncmp(p, " named ", 7)) { 395 *p = 0; 396 /* oname = p+7; */ 397 } 398 for(p = bp; *p; p++) if(!strncmp(p, " called ", 8)) { 399 *p = 0; 400 un = p+8; 401 } 402 for(p = bp; *p; p++) if(!strncmp(p, " labeled ", 9)) { 403 *p = 0; 404 dn = p+9; 405 } 406 407 /* first change to singular if necessary */ 408 if(cnt != 1) { 409 /* find "cloves of garlic", "worthless pieces of blue glass" */ 410 for(p = bp; *p; p++) if(!strncmp(p, "s of ", 5)){ 411 while(*p = p[1]) p++; 412 goto sing; 413 } 414 /* remove -s or -es (boxes) or -ies (rubies, zruties) */ 415 p = eos(bp); 416 if(p[-1] == 's') { 417 if(p[-2] == 'e') { 418 if(p[-3] == 'i') { 419 if(!strcmp(p-7, "cookies")) 420 goto mins; 421 Strcpy(p-3, "y"); 422 goto sing; 423 } 424 425 /* note: cloves / knives from clove / knife */ 426 if(!strcmp(p-6, "knives")) { 427 Strcpy(p-3, "fe"); 428 goto sing; 429 } 430 431 /* note: nurses, axes but boxes */ 432 if(!strcmp(p-5, "boxes")) { 433 p[-2] = 0; 434 goto sing; 435 } 436 } 437 mins: 438 p[-1] = 0; 439 } else { 440 if(!strcmp(p-9, "homunculi")) { 441 Strcpy(p-1, "us"); /* !! makes string longer */ 442 goto sing; 443 } 444 if(!strcmp(p-5, "teeth")) { 445 Strcpy(p-5, "tooth"); 446 goto sing; 447 } 448 /* here we cannot find the plural suffix */ 449 } 450 } 451 sing: 452 if(!strcmp(bp, "amulet of yendor")) { 453 typ = AMULET_OF_YENDOR; 454 goto typfnd; 455 } 456 p = eos(bp); 457 if(!strcmp(p-5, " mail")){ /* Note: ring mail is not a ring ! */ 458 let = ARMOR_SYM; 459 an = bp; 460 goto srch; 461 } 462 for(i = 0; i < sizeof(wrpsym); i++) { 463 register int j = strlen(wrp[i]); 464 if(!strncmp(bp, wrp[i], j)){ 465 let = wrpsym[i]; 466 bp += j; 467 if(!strncmp(bp, " of ", 4)) an = bp+4; 468 /* else if(*bp) ?? */ 469 goto srch; 470 } 471 if(!strcmp(p-j, wrp[i])){ 472 let = wrpsym[i]; 473 p -= j; 474 *p = 0; 475 if(p[-1] == ' ') p[-1] = 0; 476 dn = bp; 477 goto srch; 478 } 479 } 480 if(!strcmp(p-6, " stone")){ 481 p[-6] = 0; 482 let = GEM_SYM; 483 an = bp; 484 goto srch; 485 } 486 if(!strcmp(bp, "very heavy iron ball")){ 487 heavy = 1; 488 typ = HEAVY_IRON_BALL; 489 goto typfnd; 490 } 491 an = bp; 492 srch: 493 if(!an && !dn && !un) 494 goto any; 495 i = 1; 496 if(let) i = bases[letindex(let)]; 497 while(i <= NROFOBJECTS && (!let || objects[i].oc_olet == let)){ 498 register char *zn = objects[i].oc_name; 499 500 if(!zn) goto nxti; 501 if(an && strcmp(an, zn)) 502 goto nxti; 503 if(dn && (!(zn = objects[i].oc_descr) || strcmp(dn, zn))) 504 goto nxti; 505 if(un && (!(zn = objects[i].oc_uname) || strcmp(un, zn))) 506 goto nxti; 507 typ = i; 508 goto typfnd; 509 nxti: 510 i++; 511 } 512 any: 513 if(!let) let = wrpsym[rn2(sizeof(wrpsym))]; 514 typ = probtype(let); 515 typfnd: 516 { register struct obj *otmp; 517 extern struct obj *mksobj(); 518 let = objects[typ].oc_olet; 519 otmp = mksobj(typ); 520 if(heavy) 521 otmp->owt += 15; 522 if(cnt > 0 && index("%?!*)", let) && 523 (cnt < 4 || (let == WEAPON_SYM && typ <= ROCK && cnt < 20))) 524 otmp->quan = cnt; 525 526 if(spe > 3 && spe > otmp->spe) 527 spe = 0; 528 else if(let == WAND_SYM) 529 spe = otmp->spe; 530 if(spe == 3 && u.uluck < 0) 531 spesgn = -1; 532 if(let != WAND_SYM && spesgn == -1) 533 spe = -spe; 534 if(let == BALL_SYM) 535 spe = 0; 536 else if(let == AMULET_SYM) 537 spe = -1; 538 else if(typ == WAN_WISHING && rn2(10)) 539 spe = (rn2(10) ? -1 : 0); 540 otmp->spe = spe; 541 542 if(spesgn == -1) 543 otmp->cursed = 1; 544 545 return(otmp); 546 } 547 }