1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 2: /* hack.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, STRLEN(" of "))) { 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 ", STRLEN("cheap "))) 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 hack.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 ", STRLEN("the "))){ 351: /* the = 1; */ 352: bp += STRLEN("the "); 353: } else if(!strncmp(bp, "an ", STRLEN("an "))){ 354: cnt = 1; 355: bp += STRLEN("an "); 356: } else if(!strncmp(bp, "a ", STRLEN("a "))){ 357: cnt = 1; 358: bp += STRLEN("a "); 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 ", STRLEN(" named "))) { 395: *p = 0; 396: /* oname = p+STRLEN(" named "); */ 397: } 398: for(p = bp; *p; p++) if(!strncmp(p, " called ", STRLEN(" called "))) { 399: *p = 0; 400: un = p+STRLEN(" called "); 401: } 402: for(p = bp; *p; p++) if(!strncmp(p, " labeled ", STRLEN(" labeled "))) { 403: *p = 0; 404: dn = p+STRLEN(" labeled "); 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 ", STRLEN("s of "))){ 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-STRLEN("cookies"), "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-STRLEN("knives"), "knives")) { 427: Strcpy(p-3, "fe"); 428: goto sing; 429: } 430: 431: /* note: nurses, axes but boxes */ 432: if(!strcmp(p-STRLEN("boxes"), "boxes")) { 433: p[-2] = 0; 434: goto sing; 435: } 436: } 437: mins: 438: p[-1] = 0; 439: } else { 440: if(!strcmp(p-STRLEN("homunculi"), "homunculi")) { 441: Strcpy(p-1, "us"); /* !! makes string longer */ 442: goto sing; 443: } 444: if(!strcmp(p-STRLEN("teeth"), "teeth")) { 445: Strcpy(p-STRLEN("teeth"), "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-STRLEN(" mail"), " 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 ", STRLEN(" of "))) an = bp+STRLEN(" of "); 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-STRLEN(" stone"), " stone")){ 481: p[-STRLEN(" stone")] = 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: }