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