]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - hack/hack.objnam.c
1 /* $NetBSD: hack.objnam.c,v 1.9 2009/06/07 20:13:18 dholland Exp $ */
4 * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
12 * - Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * - Neither the name of the Stichting Centrum voor Wiskunde en
20 * Informatica, nor the names of its contributors may be used to endorse or
21 * promote products derived from this software without specific prior
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
28 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
39 * All rights reserved.
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution.
49 * 3. The name of the author may not be used to endorse or promote products
50 * derived from this software without specific prior written permission.
52 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
53 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
54 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
55 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
58 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
61 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64 #include <sys/cdefs.h>
66 __RCSID("$NetBSD: hack.objnam.c,v 1.9 2009/06/07 20:13:18 dholland Exp $");
72 #define Snprintf (void) snprintf
73 #define Strcat (void) strcat
74 #define Strcpy (void) strcpy
78 strprepend(char *s
, char *pref
)
82 pline("WARNING: prefix too short.");
86 (void) strncpy(s
, pref
, i
); /* do not copy trailing 0 */
94 Snprintf(buf
, sizeof(buf
), (a
< 0) ? "%d" : "+%d", a
);
101 static char buf
[BUFSZ
];
103 struct objclass
*ocl
= &objects
[otyp
];
104 const char *an
= ocl
->oc_name
;
105 const char *dn
= ocl
->oc_descr
;
106 char *un
= ocl
->oc_uname
;
107 int nn
= ocl
->oc_name_known
;
108 switch (ocl
->oc_olet
) {
110 Strcpy(buf
, "potion");
113 Strcpy(buf
, "scroll");
124 if (otyp
>= TURQUOISE
&& otyp
<= JADE
)
125 Strcat(buf
, " stone");
127 bufpos
= strlen(buf
);
128 Snprintf(buf
+bufpos
, sizeof(buf
)-bufpos
,
132 bufpos
= strlen(buf
);
133 Snprintf(buf
+bufpos
, sizeof(buf
)-bufpos
,
137 strlcpy(buf
, dn
? dn
: an
, sizeof(buf
));
138 if (ocl
->oc_olet
== GEM_SYM
) {
139 strlcat(buf
, " gem", sizeof(buf
));
142 bufpos
= strlen(buf
);
143 Snprintf(buf
+bufpos
, sizeof(buf
)-bufpos
,
149 /* here for ring/scroll/potion/wand */
151 bufpos
= strlen(buf
);
152 Snprintf(buf
+bufpos
, sizeof(buf
)-bufpos
, " of %s", an
);
155 bufpos
= strlen(buf
);
156 Snprintf(buf
+bufpos
, sizeof(buf
)-bufpos
, " called %s", un
);
159 bufpos
= strlen(buf
);
160 Snprintf(buf
+bufpos
, sizeof(buf
)-bufpos
, " (%s)", dn
);
166 xname(struct obj
*obj
)
168 static char bufr
[BUFSZ
];
169 /* caution: doname() and aobjnam() below "know" these sizes */
170 char *buf
= &(bufr
[PREFIX
]); /* leave room for "17 -3 " */
171 size_t bufmax
= sizeof(bufr
) - PREFIX
;
172 int nn
= objects
[obj
->otyp
].oc_name_known
;
173 const char *an
= objects
[obj
->otyp
].oc_name
;
174 const char *dn
= objects
[obj
->otyp
].oc_descr
;
175 char *un
= objects
[obj
->otyp
].oc_uname
;
176 int pl
= (obj
->quan
!= 1);
178 if (!obj
->dknown
&& !Blind
)
179 obj
->dknown
= 1;/* %% doesnt belong here */
182 Strcpy(buf
, (obj
->spe
< 0 && obj
->known
)
183 ? "cheap plastic imitation of the " : "");
184 Strcat(buf
, "Amulet of Yendor");
188 strlcpy(buf
, dn
, bufmax
);
191 strlcpy(buf
, an
, bufmax
);
194 if (obj
->otyp
== DEAD_HOMUNCULUS
&& pl
) {
196 Strcpy(buf
, "dead homunculi");
200 /* fall into next case */
202 if (obj
->otyp
== WORM_TOOTH
&& pl
) {
204 Strcpy(buf
, "worm teeth");
207 if (obj
->otyp
== CRYSKNIFE
&& pl
) {
209 Strcpy(buf
, "crysknives");
212 /* fall into next case */
216 strlcpy(buf
, an
, bufmax
);
219 Snprintf(buf
, bufmax
, "%sheavy iron ball",
220 (obj
->owt
> objects
[obj
->otyp
].oc_weight
) ? "very " : "");
223 if (nn
|| un
|| !obj
->dknown
) {
224 Strcpy(buf
, "potion");
232 Strcat(buf
, " called ");
233 strlcat(buf
, un
, bufmax
);
236 strlcat(buf
, an
, bufmax
);
239 strlcpy(buf
, dn
, bufmax
);
240 strlcat(buf
, " potion", bufmax
);
244 Strcpy(buf
, "scroll");
253 strlcat(buf
, an
, bufmax
);
255 Strcat(buf
, " called ");
256 strlcat(buf
, un
, bufmax
);
258 Strcat(buf
, " labeled ");
259 strlcat(buf
, dn
, bufmax
);
264 Snprintf(buf
, bufmax
, "wand");
266 Snprintf(buf
, bufmax
, "wand of %s", an
);
268 Snprintf(buf
, bufmax
, "wand called %s", un
);
270 Snprintf(buf
, bufmax
, "%s wand", dn
);
274 Snprintf(buf
, bufmax
, "ring");
276 Snprintf(buf
, bufmax
, "ring of %s", an
);
278 Snprintf(buf
, bufmax
, "ring called %s", un
);
280 Snprintf(buf
, bufmax
, "%s ring", dn
);
288 Snprintf(buf
, bufmax
, "%s gem", dn
);
291 strlcpy(buf
, an
, bufmax
);
292 if (obj
->otyp
>= TURQUOISE
&& obj
->otyp
<= JADE
)
293 strlcat(buf
, " stone", bufmax
);
296 Snprintf(buf
, bufmax
, "glorkum %c (0%o) %u %d",
297 obj
->olet
, obj
->olet
, obj
->otyp
, obj
->spe
);
302 for (p
= buf
; *p
; p
++) {
303 if (!strncmp(" of ", p
, 4)) {
304 /* pieces of, cloves of, lumps of */
316 if (*p
== 's' || *p
== 'z' || *p
== 'x' ||
317 (*p
== 'h' && p
[-1] == 's')) {
319 strlcat(buf
, "es", bufmax
);
320 } else if (*p
== 'y' && !strchr(vowels
, p
[-1])) {
321 /* rubies, zruties */
323 strlcat(buf
, "ies", bufmax
);
325 strlcat(buf
, "s", bufmax
);
330 strlcat(buf
, " named ", bufmax
);
331 strlcat(buf
, ONAME(obj
), bufmax
);
337 doname(struct obj
*obj
)
340 char *bp
= xname(obj
);
343 /* XXX do this better somehow w/o knowing internals of xname() */
344 bpmax
= BUFSZ
- PREFIX
;
347 Snprintf(prefix
, sizeof(prefix
), "%u ", obj
->quan
);
349 Strcpy(prefix
, "a ");
352 if (strncmp(bp
, "cheap ", 6))
353 Strcpy(prefix
, "the ");
356 if (obj
->owornmask
& W_ARMOR
)
357 strlcat(bp
, " (being worn)", bpmax
);
358 /* fall into next case */
361 strlcat(prefix
, sitoa(obj
->spe
), sizeof(prefix
));
362 strlcat(prefix
, " ", sizeof(prefix
));
368 Snprintf(bp
+bppos
, bpmax
-bppos
, " (%d)", obj
->spe
);
372 if (obj
->owornmask
& W_RINGR
)
373 strlcat(bp
, " (on right hand)", bpmax
);
374 if (obj
->owornmask
& W_RINGL
)
375 strlcat(bp
, " (on left hand)", bpmax
);
376 if (obj
->known
&& (objects
[obj
->otyp
].bits
& SPEC
)) {
377 strlcat(prefix
, sitoa(obj
->spe
), sizeof(prefix
));
378 strlcat(prefix
, " ", sizeof(prefix
));
382 if (obj
->owornmask
& W_WEP
)
383 strlcat(bp
, " (weapon in hand)", bpmax
);
385 strlcat(bp
, " (unpaid)", bpmax
);
386 if (!strcmp(prefix
, "a ") && strchr(vowels
, *bp
))
387 Strcpy(prefix
, "an ");
388 bp
= strprepend(bp
, prefix
);
392 /* used only in hack.fight.c (thitu) */
394 setan(const char *str
, char *buf
, size_t bufmax
)
396 if (strchr(vowels
, *str
))
397 Snprintf(buf
, bufmax
, "an %s", str
);
399 Snprintf(buf
, bufmax
, "a %s", str
);
403 aobjnam(struct obj
*otmp
, const char *verb
)
405 char *bp
= xname(otmp
);
409 /* XXX do this better somehow w/o knowing internals of xname() */
410 bpmax
= BUFSZ
- PREFIX
;
412 if (otmp
->quan
!= 1) {
413 Snprintf(prefix
, sizeof(prefix
), "%u ", otmp
->quan
);
414 bp
= strprepend(bp
, prefix
);
417 /* verb is given in plural (i.e., without trailing s) */
418 strlcat(bp
, " ", bpmax
);
420 strlcat(bp
, verb
, bpmax
);
421 else if (!strcmp(verb
, "are"))
422 strlcat(bp
, "is", bpmax
);
424 strlcat(bp
, verb
, bpmax
);
425 strlcat(bp
, "s", bpmax
);
432 Doname(struct obj
*obj
)
434 char *s
= doname(obj
);
436 if ('a' <= *s
&& *s
<= 'z')
441 const char *const wrp
[] = {"wand", "ring", "potion", "scroll", "gem"};
442 const char wrpsym
[] = {WAND_SYM
, RING_SYM
, POTION_SYM
, SCROLL_SYM
, GEM_SYM
};
450 int cnt
, spe
, spesgn
, typ
, heavy
;
453 /* int the = 0; char *oname = 0; */
454 cnt
= spe
= spesgn
= typ
= heavy
= 0;
457 for (p
= bp
; *p
; p
++)
458 if ('A' <= *p
&& *p
<= 'Z')
460 if (!strncmp(bp
, "the ", 4)) {
463 } else if (!strncmp(bp
, "an ", 3)) {
466 } else if (!strncmp(bp
, "a ", 2)) {
470 if (!cnt
&& digit(*bp
)) {
478 cnt
= 1; /* %% what with "gems" etc. ? */
480 if (*bp
== '+' || *bp
== '-') {
481 spesgn
= (*bp
++ == '+') ? 1 : -1;
488 p
= strrchr(bp
, '(');
490 if (p
> bp
&& p
[-1] == ' ')
505 * now we have the actual name, as delivered by xname, say green
506 * potions called whisky scrolls labeled "QWERTY" egg dead zruties
507 * fortune cookies very heavy iron ball named hoei wand of wishing
510 for (p
= bp
; *p
; p
++)
511 if (!strncmp(p
, " named ", 7)) {
515 for (p
= bp
; *p
; p
++)
516 if (!strncmp(p
, " called ", 8)) {
520 for (p
= bp
; *p
; p
++)
521 if (!strncmp(p
, " labeled ", 9)) {
525 /* first change to singular if necessary */
527 /* find "cloves of garlic", "worthless pieces of blue glass" */
528 for (p
= bp
; *p
; p
++)
529 if (!strncmp(p
, "s of ", 5)) {
530 while ((*p
= p
[1]) != '\0')
534 /* remove -s or -es (boxes) or -ies (rubies, zruties) */
539 if (!strcmp(p
- 7, "cookies"))
544 /* note: cloves / knives from clove / knife */
545 if (!strcmp(p
- 6, "knives")) {
549 /* note: nurses, axes but boxes */
550 if (!strcmp(p
- 5, "boxes")) {
558 if (!strcmp(p
- 9, "homunculi")) {
559 Strcpy(p
- 1, "us"); /* !! makes string
563 if (!strcmp(p
- 5, "teeth")) {
564 Strcpy(p
- 5, "tooth");
567 /* here we cannot find the plural suffix */
571 if (!strcmp(bp
, "amulet of yendor")) {
572 typ
= AMULET_OF_YENDOR
;
576 if (!strcmp(p
- 5, " mail")) { /* Note: ring mail is not a ring ! */
581 for (ii
= 0; ii
< sizeof(wrpsym
); ii
++) {
582 int j
= strlen(wrp
[ii
]);
583 if (!strncmp(bp
, wrp
[ii
], j
)) {
586 if (!strncmp(bp
, " of ", 4))
588 /* else if(*bp) ?? */
591 if (!strcmp(p
- j
, wrp
[ii
])) {
601 if (!strcmp(p
- 6, " stone")) {
607 if (!strcmp(bp
, "very heavy iron ball")) {
609 typ
= HEAVY_IRON_BALL
;
614 if (!an
&& !dn
&& !un
)
618 i
= bases
[letindex(let
)];
619 while (i
<= NROFOBJECTS
&& (!let
|| objects
[i
].oc_olet
== let
)) {
620 const char *zn
= objects
[i
].oc_name
;
624 if (an
&& strcmp(an
, zn
))
626 if (dn
&& (!(zn
= objects
[i
].oc_descr
) || strcmp(dn
, zn
)))
628 if (un
&& (!(zn
= objects
[i
].oc_uname
) || strcmp(un
, zn
)))
637 let
= wrpsym
[rn2(sizeof(wrpsym
))];
642 let
= objects
[typ
].oc_olet
;
646 if (cnt
> 0 && strchr("%?!*)", let
) &&
647 (cnt
< 4 || (let
== WEAPON_SYM
&& typ
<= ROCK
&& cnt
< 20)))
650 if (spe
> 3 && spe
> otmp
->spe
)
652 else if (let
== WAND_SYM
)
654 if (spe
== 3 && u
.uluck
< 0)
656 if (let
!= WAND_SYM
&& spesgn
== -1)
660 else if (let
== AMULET_SYM
)
662 else if (typ
== WAN_WISHING
&& rn2(10))
663 spe
= (rn2(10) ? -1 : 0);