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 $ */
4 /* $DragonFly: src/games/hack/hack.objnam.c,v 1.4 2006/08/21 19:45:32 pavalos Exp $ */
7 #define Sprintf (void) sprintf
8 #define Strcat (void) strcat
9 #define Strcpy (void) strcpy
13 static char *strprepend(char *, char *);
14 static char *sitoa(int);
17 strprepend(char *s
, char *pref
)
21 pline("WARNING: prefix too short.");
25 strncpy(s
, pref
, i
); /* do not copy trailing 0 */
33 Sprintf(buf
, (a
< 0) ? "%d" : "+%d", a
);
40 static char buf
[BUFSZ
];
41 struct objclass
*ocl
= &objects
[otyp
];
42 const char *an
= ocl
->oc_name
;
43 const char *dn
= ocl
->oc_descr
;
44 char *un
= ocl
->oc_uname
;
45 int nn
= ocl
->oc_name_known
;
46 switch(ocl
->oc_olet
) {
48 Strcpy(buf
, "potion");
51 Strcpy(buf
, "scroll");
62 if(otyp
>= TURQUOISE
&& otyp
<= JADE
)
63 Strcat(buf
, " stone");
65 Sprintf(eos(buf
), " called %s", un
);
67 Sprintf(eos(buf
), " (%s)", dn
);
69 Strcpy(buf
, dn
? dn
: an
);
70 if(ocl
->oc_olet
== GEM_SYM
)
73 Sprintf(eos(buf
), " called %s", un
);
77 /* here for ring/scroll/potion/wand */
79 Sprintf(eos(buf
), " of %s", an
);
81 Sprintf(eos(buf
), " called %s", un
);
83 Sprintf(eos(buf
), " (%s)", dn
);
88 xname(struct obj
*obj
)
90 static char bufr
[BUFSZ
];
91 char *buf
= &(bufr
[PREFIX
]); /* leave room for "17 -3 " */
92 int nn
= objects
[obj
->otyp
].oc_name_known
;
93 const char *an
= objects
[obj
->otyp
].oc_name
;
94 const char *dn
= objects
[obj
->otyp
].oc_descr
;
95 char *un
= objects
[obj
->otyp
].oc_uname
;
96 int pl
= (obj
->quan
!= 1);
97 if(!obj
->dknown
&& !Blind
) obj
->dknown
= 1; /* %% doesnt belong here */
100 Strcpy(buf
, (obj
->spe
< 0 && obj
->known
)
101 ? "cheap plastic imitation of the " : "");
102 Strcat(buf
,"Amulet of Yendor");
112 if(obj
->otyp
== DEAD_HOMUNCULUS
&& pl
) {
114 Strcpy(buf
, "dead homunculi");
118 /* fall into next case */
120 if(obj
->otyp
== WORM_TOOTH
&& pl
) {
122 Strcpy(buf
, "worm teeth");
125 if(obj
->otyp
== CRYSKNIFE
&& pl
) {
127 Strcpy(buf
, "crysknives");
130 /* fall into next case */
137 Sprintf(buf
, "%sheavy iron ball",
138 (obj
->owt
> objects
[obj
->otyp
].oc_weight
) ? "very " : "");
141 if(nn
|| un
|| !obj
->dknown
) {
142 Strcpy(buf
, "potion");
147 if(!obj
->dknown
) break;
149 Strcat(buf
, " called ");
157 Strcat(buf
, " potion");
161 Strcpy(buf
, "scroll");
166 if(!obj
->dknown
) break;
171 Strcat(buf
, " called ");
174 Strcat(buf
, " labeled ");
180 Sprintf(buf
, "wand");
182 Sprintf(buf
, "wand of %s", an
);
184 Sprintf(buf
, "wand called %s", un
);
186 Sprintf(buf
, "%s wand", dn
);
190 Sprintf(buf
, "ring");
192 Sprintf(buf
, "ring of %s", an
);
194 Sprintf(buf
, "ring called %s", un
);
196 Sprintf(buf
, "%s ring", dn
);
204 Sprintf(buf
, "%s gem", dn
);
208 if(obj
->otyp
>= TURQUOISE
&& obj
->otyp
<= JADE
)
209 Strcat(buf
, " stone");
212 Sprintf(buf
,"glorkum %c (0%o) %u %d",
213 obj
->olet
,obj
->olet
,obj
->otyp
,obj
->spe
);
218 for(p
= buf
; *p
; p
++) {
219 if(!strncmp(" of ", p
, 4)) {
220 /* pieces of, cloves of, lumps of */
224 c1
= c2
; c2
= *p
; *p
++ = c1
;
230 if(*p
== 's' || *p
== 'z' || *p
== 'x' ||
231 (*p
== 'h' && p
[-1] == 's'))
232 Strcat(buf
, "es"); /* boxes */
233 else if(*p
== 'y' && !index(vowels
, p
[-1]))
234 Strcpy(p
, "ies"); /* rubies, zruties */
240 Strcat(buf
, " named ");
241 Strcat(buf
, ONAME(obj
));
247 doname(struct obj
*obj
)
250 char *bp
= xname(obj
);
252 Sprintf(prefix
, "%u ", obj
->quan
);
254 Strcpy(prefix
, "a ");
257 if(strncmp(bp
, "cheap ", 6))
258 Strcpy(prefix
, "the ");
261 if(obj
->owornmask
& W_ARMOR
)
262 Strcat(bp
, " (being worn)");
263 /* fall into next case */
266 Strcat(prefix
, sitoa(obj
->spe
));
272 Sprintf(eos(bp
), " (%d)", obj
->spe
);
275 if(obj
->owornmask
& W_RINGR
) Strcat(bp
, " (on right hand)");
276 if(obj
->owornmask
& W_RINGL
) Strcat(bp
, " (on left hand)");
277 if(obj
->known
&& (objects
[obj
->otyp
].bits
& SPEC
)) {
278 Strcat(prefix
, sitoa(obj
->spe
));
283 if(obj
->owornmask
& W_WEP
)
284 Strcat(bp
, " (weapon in hand)");
286 Strcat(bp
, " (unpaid)");
287 if(!strcmp(prefix
, "a ") && index(vowels
, *bp
))
288 Strcpy(prefix
, "an ");
289 bp
= strprepend(bp
, prefix
);
293 /* used only in hack.fight.c (thitu) */
295 setan(const char *str
, char *buf
)
297 if(index(vowels
,*str
))
298 Sprintf(buf
, "an %s", str
);
300 Sprintf(buf
, "a %s", str
);
304 aobjnam(struct obj
*otmp
, const char *verb
)
306 char *bp
= xname(otmp
);
308 if(otmp
->quan
!= 1) {
309 Sprintf(prefix
, "%u ", otmp
->quan
);
310 bp
= strprepend(bp
, prefix
);
314 /* verb is given in plural (i.e., without trailing s) */
318 else if(!strcmp(verb
, "are"))
329 Doname(struct obj
*obj
)
331 char *s
= doname(obj
);
333 if('a' <= *s
&& *s
<= 'z') *s
-= ('a' - 'A');
337 static const char *wrp
[] = { "wand", "ring", "potion", "scroll", "gem" };
338 char wrpsym
[] = { WAND_SYM
, RING_SYM
, POTION_SYM
, SCROLL_SYM
, GEM_SYM
};
345 int cnt
, spe
, spesgn
, typ
, heavy
;
348 cnt
= spe
= spesgn
= typ
= heavy
= 0;
352 if('A' <= *p
&& *p
<= 'Z') *p
+= 'a'-'A';
353 if(!strncmp(bp
, "the ", 4)){
355 } else if(!strncmp(bp
, "an ", 3)){
358 } else if(!strncmp(bp
, "a ", 2)){
362 if(!cnt
&& digit(*bp
)){
364 while(digit(*bp
)) bp
++;
365 while(*bp
== ' ') bp
++;
367 if(!cnt
) cnt
= 1; /* %% what with "gems" etc. ? */
369 if(*bp
== '+' || *bp
== '-'){
370 spesgn
= (*bp
++ == '+') ? 1 : -1;
372 while(digit(*bp
)) bp
++;
373 while(*bp
== ' ') bp
++;
377 if(p
> bp
&& p
[-1] == ' ') p
[-1] = 0;
381 while(digit(*p
)) p
++;
382 if(strcmp(p
, ")")) spe
= 0;
386 /* now we have the actual name, as delivered by xname, say
387 green potions called whisky
388 scrolls labeled "QWERTY"
392 very heavy iron ball named hoei
396 for(p
= bp
; *p
; p
++) if(!strncmp(p
, " named ", 7)) {
399 for(p
= bp
; *p
; p
++) if(!strncmp(p
, " called ", 8)) {
403 for(p
= bp
; *p
; p
++) if(!strncmp(p
, " labeled ", 9)) {
408 /* first change to singular if necessary */
410 /* find "cloves of garlic", "worthless pieces of blue glass" */
411 for(p
= bp
; *p
; p
++) if(!strncmp(p
, "s of ", 5)){
412 while((*p
= p
[1])) p
++;
415 /* remove -s or -es (boxes) or -ies (rubies, zruties) */
420 if(!strcmp(p
-7, "cookies"))
426 /* note: cloves / knives from clove / knife */
427 if(!strcmp(p
-6, "knives")) {
432 /* note: nurses, axes but boxes */
433 if(!strcmp(p
-5, "boxes")) {
441 if(!strcmp(p
-9, "homunculi")) {
442 Strcpy(p
-1, "us"); /* !! makes string longer */
445 if(!strcmp(p
-5, "teeth")) {
446 Strcpy(p
-5, "tooth");
449 /* here we cannot find the plural suffix */
453 if(!strcmp(bp
, "amulet of yendor")) {
454 typ
= AMULET_OF_YENDOR
;
458 if(!strcmp(p
-5, " mail")){ /* Note: ring mail is not a ring ! */
463 for(i
= 0; (unsigned)i
< sizeof(wrpsym
); i
++) {
464 int j
= strlen(wrp
[i
]);
465 if(!strncmp(bp
, wrp
[i
], j
)){
468 if(!strncmp(bp
, " of ", 4)) an
= bp
+4;
469 /* else if(*bp) ?? */
472 if(!strcmp(p
-j
, wrp
[i
])){
476 if(p
[-1] == ' ') p
[-1] = 0;
481 if(!strcmp(p
-6, " stone")){
487 if(!strcmp(bp
, "very heavy iron ball")){
489 typ
= HEAVY_IRON_BALL
;
494 if(!an
&& !dn
&& !un
)
497 if(let
) i
= bases
[letindex(let
)];
498 while(i
<= NROFOBJECTS
&& (!let
|| objects
[i
].oc_olet
== let
)){
499 const char *zn
= objects
[i
].oc_name
;
502 if(an
&& strcmp(an
, zn
))
504 if(dn
&& (!(zn
= objects
[i
].oc_descr
) || strcmp(dn
, zn
)))
506 if(un
&& (!(zn
= objects
[i
].oc_uname
) || strcmp(un
, zn
)))
514 if(!let
) let
= wrpsym
[rn2(sizeof(wrpsym
))];
518 let
= objects
[typ
].oc_olet
;
522 if(cnt
> 0 && index("%?!*)", let
) &&
523 (cnt
< 4 || (let
== WEAPON_SYM
&& typ
<= ROCK
&& cnt
< 20)))
526 if(spe
> 3 && spe
> otmp
->spe
)
528 else if(let
== WAND_SYM
)
530 if(spe
== 3 && u
.uluck
< 0)
532 if(let
!= WAND_SYM
&& spesgn
== -1)
536 else if(let
== AMULET_SYM
)
538 else if(typ
== WAN_WISHING
&& rn2(10))
539 spe
= (rn2(10) ? -1 : 0);