1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2 /* hack.objnam.c - version 1.0.2 */
3 /* $FreeBSD: src/games/hack/hack.objnam.c,v 1.3 1999/11/16 02:57:08 billf Exp $ */
6 #define Sprintf (void) sprintf
7 #define Strcat (void) strcat
8 #define Strcpy (void) strcpy
12 static char *strprepend(char *, char *);
13 static char *sitoa(int);
16 strprepend(char *s
, char *pref
)
21 pline("WARNING: prefix too short.");
25 strncpy(s
, pref
, i
); /* do not copy trailing 0 */
34 Sprintf(buf
, (a
< 0) ? "%d" : "+%d", a
);
41 static char buf
[BUFSZ
];
42 struct objclass
*ocl
= &objects
[otyp
];
43 const char *an
= ocl
->oc_name
;
44 const char *dn
= ocl
->oc_descr
;
45 char *un
= ocl
->oc_uname
;
46 int nn
= ocl
->oc_name_known
;
48 switch (ocl
->oc_olet
) {
50 Strcpy(buf
, "potion");
53 Strcpy(buf
, "scroll");
64 if (otyp
>= TURQUOISE
&& otyp
<= JADE
)
65 Strcat(buf
, " stone");
67 Sprintf(eos(buf
), " called %s", un
);
69 Sprintf(eos(buf
), " (%s)", dn
);
71 Strcpy(buf
, dn
? dn
: an
);
72 if (ocl
->oc_olet
== GEM_SYM
)
75 Sprintf(eos(buf
), " called %s", un
);
79 /* here for ring/scroll/potion/wand */
81 Sprintf(eos(buf
), " of %s", an
);
83 Sprintf(eos(buf
), " called %s", un
);
85 Sprintf(eos(buf
), " (%s)", dn
);
90 xname(struct obj
*obj
)
92 static char bufr
[BUFSZ
];
93 /* caution: doname() and aobjnam() below "know" these sizes */
94 char *buf
= &(bufr
[PREFIX
]); /* leave room for "17 -3 " */
95 int nn
= objects
[obj
->otyp
].oc_name_known
;
96 const char *an
= objects
[obj
->otyp
].oc_name
;
97 const char *dn
= objects
[obj
->otyp
].oc_descr
;
98 char *un
= objects
[obj
->otyp
].oc_uname
;
99 int pl
= (obj
->quan
!= 1);
101 if (!obj
->dknown
&& !Blind
) /* %% doesnt belong here */
105 Strcpy(buf
, (obj
->spe
< 0 && obj
->known
)
106 ? "cheap plastic imitation of the " : "");
107 Strcat(buf
, "Amulet of Yendor");
117 if (obj
->otyp
== DEAD_HOMUNCULUS
&& pl
) {
119 Strcpy(buf
, "dead homunculi");
123 /* fall into next case */
125 if (obj
->otyp
== WORM_TOOTH
&& pl
) {
127 Strcpy(buf
, "worm teeth");
130 if (obj
->otyp
== CRYSKNIFE
&& pl
) {
132 Strcpy(buf
, "crysknives");
135 /* fall into next case */
142 Sprintf(buf
, "%sheavy iron ball",
143 (obj
->owt
> objects
[obj
->otyp
].oc_weight
) ? "very " : "");
146 if (nn
|| un
|| !obj
->dknown
) {
147 Strcpy(buf
, "potion");
155 Strcat(buf
, " called ");
163 Strcat(buf
, " potion");
167 Strcpy(buf
, "scroll");
178 Strcat(buf
, " called ");
181 Strcat(buf
, " labeled ");
187 Sprintf(buf
, "wand");
189 Sprintf(buf
, "wand of %s", an
);
191 Sprintf(buf
, "wand called %s", un
);
193 Sprintf(buf
, "%s wand", dn
);
197 Sprintf(buf
, "ring");
199 Sprintf(buf
, "ring of %s", an
);
201 Sprintf(buf
, "ring called %s", un
);
203 Sprintf(buf
, "%s ring", dn
);
211 Sprintf(buf
, "%s gem", dn
);
215 if (obj
->otyp
>= TURQUOISE
&& obj
->otyp
<= JADE
)
216 Strcat(buf
, " stone");
219 Sprintf(buf
, "glorkum %c (0%o) %u %d",
220 obj
->olet
, obj
->olet
, obj
->otyp
, obj
->spe
);
225 for (p
= buf
; *p
; p
++)
226 if (!strncmp(" of ", p
, 4)) {
227 /* pieces of, cloves of, lumps of */
238 if (*p
== 's' || *p
== 'z' || *p
== 'x' ||
239 (*p
== 'h' && p
[-1] == 's'))
240 Strcat(buf
, "es"); /* boxes */
241 else if (*p
== 'y' && !strchr(vowels
, p
[-1]))
242 Strcpy(p
, "ies"); /* rubies, zruties */
248 Strcat(buf
, " named ");
249 Strcat(buf
, ONAME(obj
));
255 doname(struct obj
*obj
)
258 char *bp
= xname(obj
);
261 Sprintf(prefix
, "%u ", obj
->quan
);
263 Strcpy(prefix
, "a ");
266 if (strncmp(bp
, "cheap ", 6))
267 Strcpy(prefix
, "the ");
270 if (obj
->owornmask
& W_ARMOR
)
271 Strcat(bp
, " (being worn)");
272 /* fall into next case */
275 Strcat(prefix
, sitoa(obj
->spe
));
281 Sprintf(eos(bp
), " (%d)", obj
->spe
);
284 if (obj
->owornmask
& W_RINGR
)
285 Strcat(bp
, " (on right hand)");
286 if (obj
->owornmask
& W_RINGL
)
287 Strcat(bp
, " (on left hand)");
288 if (obj
->known
&& (objects
[obj
->otyp
].bits
& SPEC
)) {
289 Strcat(prefix
, sitoa(obj
->spe
));
294 if (obj
->owornmask
& W_WEP
)
295 Strcat(bp
, " (weapon in hand)");
297 Strcat(bp
, " (unpaid)");
298 if (!strcmp(prefix
, "a ") && strchr(vowels
, *bp
))
299 Strcpy(prefix
, "an ");
300 bp
= strprepend(bp
, prefix
);
304 /* used only in hack.fight.c (thitu) */
306 setan(const char *str
, char *buf
)
308 if (strchr(vowels
, *str
))
309 Sprintf(buf
, "an %s", str
);
311 Sprintf(buf
, "a %s", str
);
315 aobjnam(struct obj
*otmp
, const char *verb
)
317 char *bp
= xname(otmp
);
320 if (otmp
->quan
!= 1) {
321 Sprintf(prefix
, "%u ", otmp
->quan
);
322 bp
= strprepend(bp
, prefix
);
326 /* verb is given in plural (i.e., without trailing s) */
330 else if (!strcmp(verb
, "are"))
341 Doname(struct obj
*obj
)
343 char *s
= doname(obj
);
345 if ('a' <= *s
&& *s
<= 'z')
350 static const char *wrp
[] = { "wand", "ring", "potion", "scroll", "gem" };
351 char wrpsym
[] = { WAND_SYM
, RING_SYM
, POTION_SYM
, SCROLL_SYM
, GEM_SYM
};
358 int cnt
, spe
, spesgn
, typ
, heavy
;
362 cnt
= spe
= spesgn
= typ
= heavy
= 0;
365 for (p
= bp
; *p
; p
++)
366 if ('A' <= *p
&& *p
<= 'Z')
368 if (!strncmp(bp
, "the ", 4))
370 else if (!strncmp(bp
, "an ", 3)) {
373 } else if (!strncmp(bp
, "a ", 2)) {
377 if (!cnt
&& digit(*bp
)) {
384 if (!cnt
) /* %% what with "gems" etc. ? */
387 if (*bp
== '+' || *bp
== '-') {
388 spesgn
= (*bp
++ == '+') ? 1 : -1;
395 p
= strrchr(bp
, '(');
397 if (p
> bp
&& p
[-1] == ' ')
412 * now we have the actual name, as delivered by xname, say
413 * green potions called whisky
414 * scrolls labeled "QWERTY"
418 * very heavy iron ball named hoei
422 for (p
= bp
; *p
; p
++)
423 if (!strncmp(p
, " named ", 7))
426 for (p
= bp
; *p
; p
++)
427 if (!strncmp(p
, " called ", 8)) {
431 for (p
= bp
; *p
; p
++)
432 if (!strncmp(p
, " labeled ", 9)) {
437 /* first change to singular if necessary */
439 /* find "cloves of garlic", "worthless pieces of blue glass" */
440 for (p
= bp
; *p
; p
++)
441 if (!strncmp(p
, "s of ", 5)) {
446 /* remove -s or -es (boxes) or -ies (rubies, zruties) */
451 if (!strcmp(p
- 7, "cookies"))
457 /* note: cloves / knives from clove / knife */
458 if (!strcmp(p
- 6, "knives")) {
463 /* note: nurses, axes but boxes */
464 if (!strcmp(p
- 5, "boxes")) {
472 if (!strcmp(p
- 9, "homunculi")) {
473 Strcpy(p
- 1, "us"); /* !! makes string longer */
476 if (!strcmp(p
- 5, "teeth")) {
477 Strcpy(p
- 5, "tooth");
480 /* here we cannot find the plural suffix */
484 if (!strcmp(bp
, "amulet of yendor")) {
485 typ
= AMULET_OF_YENDOR
;
489 if (!strcmp(p
- 5, " mail")) { /* Note: ring mail is not a ring ! */
494 for (i
= 0; (unsigned)i
< sizeof(wrpsym
); i
++) {
495 int j
= strlen(wrp
[i
]);
496 if (!strncmp(bp
, wrp
[i
], j
)) {
499 if (!strncmp(bp
, " of ", 4))
501 /* else if (*bp) ?? */
504 if (!strcmp(p
- j
, wrp
[i
])) {
514 if (!strcmp(p
- 6, " stone")) {
520 if (!strcmp(bp
, "very heavy iron ball")) {
522 typ
= HEAVY_IRON_BALL
;
527 if (!an
&& !dn
&& !un
)
531 i
= bases
[letindex(let
)];
532 while (i
<= NROFOBJECTS
&& (!let
|| objects
[i
].oc_olet
== let
)) {
533 const char *zn
= objects
[i
].oc_name
;
537 if (an
&& strcmp(an
, zn
))
539 if (dn
&& (!(zn
= objects
[i
].oc_descr
) || strcmp(dn
, zn
)))
541 if (un
&& (!(zn
= objects
[i
].oc_uname
) || strcmp(un
, zn
)))
550 let
= wrpsym
[rn2(sizeof(wrpsym
))];
555 let
= objects
[typ
].oc_olet
;
559 if (cnt
> 0 && strchr("%?!*)", let
) &&
560 (cnt
< 4 || (let
== WEAPON_SYM
&& typ
<= ROCK
&& cnt
< 20)))
563 if (spe
> 3 && spe
> otmp
->spe
)
565 else if (let
== WAND_SYM
)
567 if (spe
== 3 && u
.uluck
< 0)
569 if (let
!= WAND_SYM
&& spesgn
== -1)
573 else if (let
== AMULET_SYM
)
575 else if (typ
== WAN_WISHING
&& rn2(10))
576 spe
= (rn2(10) ? -1 : 0);