1*25fdf802Sjsg /* $OpenBSD: hack.objnam.c,v 1.12 2023/09/06 11:53:56 jsg Exp $ */
2d0b779f3Sniklas
3df930be7Sderaadt /*
4d25013f2Scamield * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
5d25013f2Scamield * Amsterdam
6d25013f2Scamield * All rights reserved.
7d25013f2Scamield *
8d25013f2Scamield * Redistribution and use in source and binary forms, with or without
9d25013f2Scamield * modification, are permitted provided that the following conditions are
10d25013f2Scamield * met:
11d25013f2Scamield *
12d25013f2Scamield * - Redistributions of source code must retain the above copyright notice,
13d25013f2Scamield * this list of conditions and the following disclaimer.
14d25013f2Scamield *
15d25013f2Scamield * - Redistributions in binary form must reproduce the above copyright
16d25013f2Scamield * notice, this list of conditions and the following disclaimer in the
17d25013f2Scamield * documentation and/or other materials provided with the distribution.
18d25013f2Scamield *
19d25013f2Scamield * - Neither the name of the Stichting Centrum voor Wiskunde en
20d25013f2Scamield * Informatica, nor the names of its contributors may be used to endorse or
21d25013f2Scamield * promote products derived from this software without specific prior
22d25013f2Scamield * written permission.
23d25013f2Scamield *
24d25013f2Scamield * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25d25013f2Scamield * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26d25013f2Scamield * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27d25013f2Scamield * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
28d25013f2Scamield * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29d25013f2Scamield * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30d25013f2Scamield * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31d25013f2Scamield * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32d25013f2Scamield * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33d25013f2Scamield * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34d25013f2Scamield * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35d25013f2Scamield */
36d25013f2Scamield
37d25013f2Scamield /*
38d25013f2Scamield * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
39d25013f2Scamield * All rights reserved.
40d25013f2Scamield *
41d25013f2Scamield * Redistribution and use in source and binary forms, with or without
42d25013f2Scamield * modification, are permitted provided that the following conditions
43d25013f2Scamield * are met:
44d25013f2Scamield * 1. Redistributions of source code must retain the above copyright
45d25013f2Scamield * notice, this list of conditions and the following disclaimer.
46d25013f2Scamield * 2. Redistributions in binary form must reproduce the above copyright
47d25013f2Scamield * notice, this list of conditions and the following disclaimer in the
48d25013f2Scamield * documentation and/or other materials provided with the distribution.
49d25013f2Scamield * 3. The name of the author may not be used to endorse or promote products
50d25013f2Scamield * derived from this software without specific prior written permission.
51d25013f2Scamield *
52d25013f2Scamield * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
53d25013f2Scamield * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
54d25013f2Scamield * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
55d25013f2Scamield * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56d25013f2Scamield * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57d25013f2Scamield * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
58d25013f2Scamield * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59d25013f2Scamield * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60d25013f2Scamield * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
61d25013f2Scamield * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62df930be7Sderaadt */
63df930be7Sderaadt
644a5fbbc4Spjanzen #include <ctype.h>
654a5fbbc4Spjanzen #include <stdio.h>
664a5fbbc4Spjanzen #include <stdlib.h>
67aed906e4Smestre
68df930be7Sderaadt #include "hack.h"
69aed906e4Smestre
70df930be7Sderaadt #define PREFIX 15
71df930be7Sderaadt extern int bases[];
72df930be7Sderaadt
73846311fcStdeval static char bufr[BUFSZ];
74846311fcStdeval
754a5fbbc4Spjanzen static char *sitoa(int);
764a5fbbc4Spjanzen
77df930be7Sderaadt char *
strprepend(char * s,char * pref)784a5fbbc4Spjanzen strprepend(char *s, char *pref)
794a5fbbc4Spjanzen {
804a5fbbc4Spjanzen int i = strlen(pref);
814a5fbbc4Spjanzen
82df930be7Sderaadt if(i > PREFIX) {
83df930be7Sderaadt pline("WARNING: prefix too short.");
84df930be7Sderaadt return(s);
85df930be7Sderaadt }
86df930be7Sderaadt s -= i;
87df930be7Sderaadt (void) strncpy(s, pref, i); /* do not copy trailing 0 */
88df930be7Sderaadt return(s);
89df930be7Sderaadt }
90df930be7Sderaadt
914a5fbbc4Spjanzen static char *
sitoa(int a)924a5fbbc4Spjanzen sitoa(int a)
934a5fbbc4Spjanzen {
94df930be7Sderaadt static char buf[13];
954a5fbbc4Spjanzen
9642ceebb3Sderaadt snprintf(buf, sizeof buf, (a < 0) ? "%d" : "+%d", a);
97df930be7Sderaadt return(buf);
98df930be7Sderaadt }
99df930be7Sderaadt
100df930be7Sderaadt char *
typename(int otyp)1014a5fbbc4Spjanzen typename(int otyp)
102df930be7Sderaadt {
103df930be7Sderaadt static char buf[BUFSZ];
1044a5fbbc4Spjanzen struct objclass *ocl = &objects[otyp];
1054a5fbbc4Spjanzen char *an = ocl->oc_name;
1064a5fbbc4Spjanzen char *dn = ocl->oc_descr;
1074a5fbbc4Spjanzen char *un = ocl->oc_uname;
1084a5fbbc4Spjanzen char *bp;
1094a5fbbc4Spjanzen int nn = ocl->oc_name_known;
1104a5fbbc4Spjanzen
111df930be7Sderaadt switch(ocl->oc_olet) {
112df930be7Sderaadt case POTION_SYM:
11342ceebb3Sderaadt strlcpy(buf, "potion", sizeof buf);
114df930be7Sderaadt break;
115df930be7Sderaadt case SCROLL_SYM:
11642ceebb3Sderaadt strlcpy(buf, "scroll", sizeof buf);
117df930be7Sderaadt break;
118df930be7Sderaadt case WAND_SYM:
11942ceebb3Sderaadt strlcpy(buf, "wand", sizeof buf);
120df930be7Sderaadt break;
121df930be7Sderaadt case RING_SYM:
12242ceebb3Sderaadt strlcpy(buf, "ring", sizeof buf);
123df930be7Sderaadt break;
124df930be7Sderaadt default:
125df930be7Sderaadt if(nn) {
12642ceebb3Sderaadt strlcpy(buf, an, sizeof buf);
127df930be7Sderaadt if(otyp >= TURQUOISE && otyp <= JADE)
12842ceebb3Sderaadt strlcat(buf, " stone", sizeof buf);
129846311fcStdeval if(un) {
130846311fcStdeval bp = eos(buf);
131846311fcStdeval snprintf(bp, buf + sizeof buf - bp,
132846311fcStdeval " called %s", un);
133846311fcStdeval }
134846311fcStdeval if(dn) {
135846311fcStdeval bp = eos(buf);
136846311fcStdeval snprintf(bp, buf + sizeof buf - bp,
137846311fcStdeval " (%s)", dn);
138846311fcStdeval }
139df930be7Sderaadt } else {
14042ceebb3Sderaadt strlcpy(buf, dn ? dn : an, sizeof buf);
141df930be7Sderaadt if(ocl->oc_olet == GEM_SYM)
14242ceebb3Sderaadt strlcat(buf, " gem", sizeof buf);
143846311fcStdeval if(un) {
144846311fcStdeval bp = eos(buf);
145846311fcStdeval snprintf(bp, buf + sizeof buf - bp,
146846311fcStdeval " called %s", un);
147846311fcStdeval }
148df930be7Sderaadt }
149df930be7Sderaadt return(buf);
150df930be7Sderaadt }
151df930be7Sderaadt /* here for ring/scroll/potion/wand */
152846311fcStdeval if(nn) {
153846311fcStdeval bp = eos(buf);
154846311fcStdeval snprintf(bp, buf + sizeof buf - bp, " of %s", an);
155846311fcStdeval }
156846311fcStdeval if(un) {
157846311fcStdeval bp = eos(buf);
158846311fcStdeval snprintf(bp, buf + sizeof buf - bp, " called %s", un);
159846311fcStdeval }
160846311fcStdeval if(dn) {
161846311fcStdeval bp = eos(buf);
162846311fcStdeval snprintf(bp, buf + sizeof buf - bp, " (%s)", dn);
163846311fcStdeval }
164df930be7Sderaadt return(buf);
165df930be7Sderaadt }
166df930be7Sderaadt
167df930be7Sderaadt char *
xname(struct obj * obj)1684a5fbbc4Spjanzen xname(struct obj *obj)
169df930be7Sderaadt {
1704a5fbbc4Spjanzen char *buf = &(bufr[PREFIX]); /* leave room for "17 -3 " */
1714a5fbbc4Spjanzen int nn = objects[obj->otyp].oc_name_known;
1724a5fbbc4Spjanzen char *an = objects[obj->otyp].oc_name;
1734a5fbbc4Spjanzen char *dn = objects[obj->otyp].oc_descr;
1744a5fbbc4Spjanzen char *un = objects[obj->otyp].oc_uname;
1754a5fbbc4Spjanzen int pl = (obj->quan != 1);
176846311fcStdeval size_t len = bufr + sizeof bufr - buf;
1774a5fbbc4Spjanzen
1781ccb6c7bStodd if(!obj->dknown && !Blind) obj->dknown = 1; /* %% doesn't belong here */
179df930be7Sderaadt switch(obj->olet) {
180df930be7Sderaadt case AMULET_SYM:
181846311fcStdeval strlcpy(buf, (obj->spe < 0 && obj->known)
182846311fcStdeval ? "cheap plastic imitation of the " : "", len);
183846311fcStdeval strlcat(buf,"Amulet of Yendor", len);
184df930be7Sderaadt break;
185df930be7Sderaadt case TOOL_SYM:
186df930be7Sderaadt if(!nn) {
187846311fcStdeval strlcpy(buf, dn, len);
188df930be7Sderaadt break;
189df930be7Sderaadt }
190846311fcStdeval strlcpy(buf,an,len);
191df930be7Sderaadt break;
192df930be7Sderaadt case FOOD_SYM:
193df930be7Sderaadt if(obj->otyp == DEAD_HOMUNCULUS && pl) {
194df930be7Sderaadt pl = 0;
195846311fcStdeval strlcpy(buf, "dead homunculi", len);
196df930be7Sderaadt break;
197df930be7Sderaadt }
198df930be7Sderaadt /* fungis ? */
199df930be7Sderaadt /* fall into next case */
200df930be7Sderaadt case WEAPON_SYM:
201df930be7Sderaadt if(obj->otyp == WORM_TOOTH && pl) {
202df930be7Sderaadt pl = 0;
203846311fcStdeval strlcpy(buf, "worm teeth", len);
204df930be7Sderaadt break;
205df930be7Sderaadt }
206df930be7Sderaadt if(obj->otyp == CRYSKNIFE && pl) {
207df930be7Sderaadt pl = 0;
208846311fcStdeval strlcpy(buf, "crysknives", len);
209df930be7Sderaadt break;
210df930be7Sderaadt }
211df930be7Sderaadt /* fall into next case */
212df930be7Sderaadt case ARMOR_SYM:
213df930be7Sderaadt case CHAIN_SYM:
214df930be7Sderaadt case ROCK_SYM:
215846311fcStdeval strlcpy(buf,an,len);
216df930be7Sderaadt break;
217df930be7Sderaadt case BALL_SYM:
218846311fcStdeval snprintf(buf, len, "%sheavy iron ball",
219df930be7Sderaadt (obj->owt > objects[obj->otyp].oc_weight) ? "very " : "");
220df930be7Sderaadt break;
221df930be7Sderaadt case POTION_SYM:
222df930be7Sderaadt if(nn || un || !obj->dknown) {
223846311fcStdeval strlcpy(buf, "potion", len);
224df930be7Sderaadt if(pl) {
225df930be7Sderaadt pl = 0;
226846311fcStdeval strlcat(buf, "s", len);
227df930be7Sderaadt }
228df930be7Sderaadt if(!obj->dknown) break;
229df930be7Sderaadt if(un) {
230846311fcStdeval strlcat(buf, " called ", len);
231846311fcStdeval strlcat(buf, un, len);
232df930be7Sderaadt } else {
233846311fcStdeval strlcat(buf, " of ", len);
234846311fcStdeval strlcat(buf, an, len);
235df930be7Sderaadt }
236df930be7Sderaadt } else {
237846311fcStdeval strlcpy(buf, dn, len);
238846311fcStdeval strlcat(buf, " potion", len);
239df930be7Sderaadt }
240df930be7Sderaadt break;
241df930be7Sderaadt case SCROLL_SYM:
242846311fcStdeval strlcpy(buf, "scroll", len);
243df930be7Sderaadt if(pl) {
244df930be7Sderaadt pl = 0;
245846311fcStdeval strlcat(buf, "s", len);
246df930be7Sderaadt }
247df930be7Sderaadt if(!obj->dknown) break;
248df930be7Sderaadt if(nn) {
249846311fcStdeval strlcat(buf, " of ", len);
250846311fcStdeval strlcat(buf, an, len);
251df930be7Sderaadt } else if(un) {
252846311fcStdeval strlcat(buf, " called ", len);
253846311fcStdeval strlcat(buf, un, len);
254df930be7Sderaadt } else {
255846311fcStdeval strlcat(buf, " labeled ", len);
256846311fcStdeval strlcat(buf, dn, len);
257df930be7Sderaadt }
258df930be7Sderaadt break;
259df930be7Sderaadt case WAND_SYM:
260df930be7Sderaadt if(!obj->dknown)
261846311fcStdeval snprintf(buf, len, "wand");
262df930be7Sderaadt else if(nn)
263846311fcStdeval snprintf(buf, len, "wand of %s", an);
264df930be7Sderaadt else if(un)
265846311fcStdeval snprintf(buf, len, "wand called %s", un);
266df930be7Sderaadt else
267846311fcStdeval snprintf(buf, len, "%s wand", dn);
268df930be7Sderaadt break;
269df930be7Sderaadt case RING_SYM:
270df930be7Sderaadt if(!obj->dknown)
271846311fcStdeval snprintf(buf, len, "ring");
272df930be7Sderaadt else if(nn)
273846311fcStdeval snprintf(buf, len, "ring of %s", an);
274df930be7Sderaadt else if(un)
275846311fcStdeval snprintf(buf, len, "ring called %s", un);
276df930be7Sderaadt else
277846311fcStdeval snprintf(buf, len, "%s ring", dn);
278df930be7Sderaadt break;
279df930be7Sderaadt case GEM_SYM:
280df930be7Sderaadt if(!obj->dknown) {
281846311fcStdeval strlcpy(buf, "gem", len);
282df930be7Sderaadt break;
283df930be7Sderaadt }
284df930be7Sderaadt if(!nn) {
285846311fcStdeval snprintf(buf, len, "%s gem", dn);
286df930be7Sderaadt break;
287df930be7Sderaadt }
288846311fcStdeval strlcpy(buf, an, len);
289df930be7Sderaadt if(obj->otyp >= TURQUOISE && obj->otyp <= JADE)
290846311fcStdeval strlcat(buf, " stone", len);
291df930be7Sderaadt break;
292df930be7Sderaadt default:
293846311fcStdeval snprintf(buf,len,"glorkum %c (0%o) %u %d",
294df930be7Sderaadt obj->olet,obj->olet,obj->otyp,obj->spe);
295df930be7Sderaadt }
296df930be7Sderaadt if(pl) {
2974a5fbbc4Spjanzen char *p;
298df930be7Sderaadt
299df930be7Sderaadt for(p = buf; *p; p++) {
300df930be7Sderaadt if(!strncmp(" of ", p, 4)) {
301df930be7Sderaadt /* pieces of, cloves of, lumps of */
3024a5fbbc4Spjanzen int c1, c2 = 's';
303df930be7Sderaadt
304df930be7Sderaadt do {
305df930be7Sderaadt c1 = c2; c2 = *p; *p++ = c1;
306df930be7Sderaadt } while(c1);
307df930be7Sderaadt goto nopl;
308df930be7Sderaadt }
309df930be7Sderaadt }
310df930be7Sderaadt p = eos(buf)-1;
311df930be7Sderaadt if(*p == 's' || *p == 'z' || *p == 'x' ||
312df930be7Sderaadt (*p == 'h' && p[-1] == 's'))
313846311fcStdeval strlcat(buf, "es", len); /* boxes */
314180acc8fSmillert else if(*p == 'y' && !strchr(vowels, p[-1]))
315846311fcStdeval /* rubies, zruties */
316846311fcStdeval strlcpy(p, "ies", bufr + sizeof bufr - p);
317df930be7Sderaadt else
318846311fcStdeval strlcat(buf, "s", len);
319df930be7Sderaadt }
320df930be7Sderaadt nopl:
321df930be7Sderaadt if(obj->onamelth) {
322846311fcStdeval strlcat(buf, " named ", len);
323846311fcStdeval strlcat(buf, ONAME(obj), len);
324df930be7Sderaadt }
325df930be7Sderaadt return(buf);
326df930be7Sderaadt }
327df930be7Sderaadt
328df930be7Sderaadt char *
doname(struct obj * obj)3294a5fbbc4Spjanzen doname(struct obj *obj)
330df930be7Sderaadt {
331df930be7Sderaadt char prefix[PREFIX];
3324a5fbbc4Spjanzen char *bp = xname(obj);
3334a5fbbc4Spjanzen char *p;
3344a5fbbc4Spjanzen
335df930be7Sderaadt if(obj->quan != 1)
33642ceebb3Sderaadt snprintf(prefix, sizeof prefix, "%u ", obj->quan);
337df930be7Sderaadt else
33842ceebb3Sderaadt strlcpy(prefix, "a ", sizeof prefix);
339df930be7Sderaadt switch(obj->olet) {
340df930be7Sderaadt case AMULET_SYM:
341df930be7Sderaadt if(strncmp(bp, "cheap ", 6))
34242ceebb3Sderaadt strlcpy(prefix, "the ", sizeof prefix);
343df930be7Sderaadt break;
344df930be7Sderaadt case ARMOR_SYM:
345df930be7Sderaadt if(obj->owornmask & W_ARMOR)
346846311fcStdeval strlcat(bp, " (being worn)", bufr + sizeof bufr - bp);
347df930be7Sderaadt /* fall into next case */
348df930be7Sderaadt case WEAPON_SYM:
349df930be7Sderaadt if(obj->known) {
35042ceebb3Sderaadt strlcat(prefix, sitoa(obj->spe), sizeof prefix);
35142ceebb3Sderaadt strlcat(prefix, " ", sizeof prefix);
352df930be7Sderaadt }
353df930be7Sderaadt break;
354df930be7Sderaadt case WAND_SYM:
355846311fcStdeval if(obj->known) {
356846311fcStdeval p = eos(bp);
357846311fcStdeval snprintf(p, bufr + sizeof bufr - p, " (%d)", obj->spe);
358846311fcStdeval }
359df930be7Sderaadt break;
360df930be7Sderaadt case RING_SYM:
361846311fcStdeval if(obj->owornmask & W_RINGR)
362846311fcStdeval strlcat(bp, " (on right hand)", bufr + sizeof bufr - bp);
363846311fcStdeval if(obj->owornmask & W_RINGL)
364846311fcStdeval strlcat(bp, " (on left hand)", bufr + sizeof bufr - bp);
365df930be7Sderaadt if(obj->known && (objects[obj->otyp].bits & SPEC)) {
36642ceebb3Sderaadt strlcat(prefix, sitoa(obj->spe), sizeof prefix);
36742ceebb3Sderaadt strlcat(prefix, " ", sizeof prefix);
368df930be7Sderaadt }
369df930be7Sderaadt break;
370df930be7Sderaadt }
371df930be7Sderaadt if(obj->owornmask & W_WEP)
372846311fcStdeval strlcat(bp, " (weapon in hand)", bufr + sizeof bufr - bp);
373df930be7Sderaadt if(obj->unpaid)
374846311fcStdeval strlcat(bp, " (unpaid)", bufr + sizeof bufr - bp);
375180acc8fSmillert if(!strcmp(prefix, "a ") && strchr(vowels, *bp))
37642ceebb3Sderaadt strlcpy(prefix, "an ", sizeof prefix);
377df930be7Sderaadt bp = strprepend(bp, prefix);
378df930be7Sderaadt return(bp);
379df930be7Sderaadt }
380df930be7Sderaadt
381df930be7Sderaadt /* used only in hack.fight.c (thitu) */
3824a5fbbc4Spjanzen void
setan(char * str,char * buf,size_t len)3834a5fbbc4Spjanzen setan(char *str, char *buf, size_t len)
384df930be7Sderaadt {
385180acc8fSmillert if(strchr(vowels,*str))
386846311fcStdeval snprintf(buf, len, "an %s", str);
387df930be7Sderaadt else
388846311fcStdeval snprintf(buf, len, "a %s", str);
389df930be7Sderaadt }
390df930be7Sderaadt
391df930be7Sderaadt char *
aobjnam(struct obj * otmp,char * verb)3924a5fbbc4Spjanzen aobjnam(struct obj *otmp, char *verb)
3934a5fbbc4Spjanzen {
3944a5fbbc4Spjanzen char *bp = xname(otmp);
395df930be7Sderaadt char prefix[PREFIX];
3964a5fbbc4Spjanzen
397df930be7Sderaadt if(otmp->quan != 1) {
39842ceebb3Sderaadt snprintf(prefix, sizeof prefix, "%u ", otmp->quan);
399df930be7Sderaadt bp = strprepend(bp, prefix);
400df930be7Sderaadt }
401df930be7Sderaadt
402df930be7Sderaadt if(verb) {
403df930be7Sderaadt /* verb is given in plural (i.e., without trailing s) */
404846311fcStdeval strlcat(bp, " ", bufr + sizeof bufr - bp);
405df930be7Sderaadt if(otmp->quan != 1)
406846311fcStdeval strlcat(bp, verb, bufr + sizeof bufr - bp);
407df930be7Sderaadt else if(!strcmp(verb, "are"))
408846311fcStdeval strlcat(bp, "is", bufr + sizeof bufr - bp);
409df930be7Sderaadt else {
410846311fcStdeval strlcat(bp, verb, bufr + sizeof bufr - bp);
411846311fcStdeval strlcat(bp, "s", bufr + sizeof bufr - bp);
412df930be7Sderaadt }
413df930be7Sderaadt }
414df930be7Sderaadt return(bp);
415df930be7Sderaadt }
416df930be7Sderaadt
417df930be7Sderaadt char *
Doname(struct obj * obj)4184a5fbbc4Spjanzen Doname(struct obj *obj)
419df930be7Sderaadt {
4204a5fbbc4Spjanzen char *s = doname(obj);
421df930be7Sderaadt
422df930be7Sderaadt if('a' <= *s && *s <= 'z') *s -= ('a' - 'A');
423df930be7Sderaadt return(s);
424df930be7Sderaadt }
425df930be7Sderaadt
426df930be7Sderaadt char *wrp[] = { "wand", "ring", "potion", "scroll", "gem" };
427df930be7Sderaadt char wrpsym[] = { WAND_SYM, RING_SYM, POTION_SYM, SCROLL_SYM, GEM_SYM };
428df930be7Sderaadt
429df930be7Sderaadt struct obj *
readobjnam(char * bp,size_t len)4304a5fbbc4Spjanzen readobjnam(char *bp, size_t len)
431846311fcStdeval {
4324a5fbbc4Spjanzen char *p, *cp = bp;
4334a5fbbc4Spjanzen int i;
434df930be7Sderaadt int cnt, spe, spesgn, typ, heavy;
435df930be7Sderaadt char let;
436df930be7Sderaadt char *un, *dn, *an;
4374a5fbbc4Spjanzen
438df930be7Sderaadt /* int the = 0; char *oname = 0; */
439df930be7Sderaadt cnt = spe = spesgn = typ = heavy = 0;
440df930be7Sderaadt let = 0;
441df930be7Sderaadt an = dn = un = 0;
442846311fcStdeval for(p = cp; *p; p++)
443df930be7Sderaadt if('A' <= *p && *p <= 'Z') *p += 'a'-'A';
444846311fcStdeval if(!strncmp(cp, "the ", 4)){
445df930be7Sderaadt /* the = 1; */
446846311fcStdeval cp += 4;
447846311fcStdeval } else if(!strncmp(cp, "an ", 3)){
448df930be7Sderaadt cnt = 1;
449846311fcStdeval cp += 3;
450846311fcStdeval } else if(!strncmp(cp, "a ", 2)){
451df930be7Sderaadt cnt = 1;
452846311fcStdeval cp += 2;
453df930be7Sderaadt }
454cb40a3d3Smmcc if(!cnt && isdigit((unsigned char)*cp)){
455846311fcStdeval cnt = atoi(cp);
456cb40a3d3Smmcc while(isdigit((unsigned char)*cp)) cp++;
457846311fcStdeval while(*cp == ' ') cp++;
458df930be7Sderaadt }
459df930be7Sderaadt if(!cnt) cnt = 1; /* %% what with "gems" etc. ? */
460df930be7Sderaadt
461846311fcStdeval if(*cp == '+' || *cp == '-'){
462846311fcStdeval spesgn = (*cp++ == '+') ? 1 : -1;
463846311fcStdeval spe = atoi(cp);
464cb40a3d3Smmcc while(isdigit((unsigned char)*cp)) cp++;
465846311fcStdeval while(*cp == ' ') cp++;
466df930be7Sderaadt } else {
467846311fcStdeval p = strrchr(cp, '(');
468df930be7Sderaadt if(p) {
469846311fcStdeval if(p > cp && p[-1] == ' ') p[-1] = 0;
470df930be7Sderaadt else *p = 0;
471df930be7Sderaadt p++;
472df930be7Sderaadt spe = atoi(p);
473cb40a3d3Smmcc while(isdigit((unsigned char)*p)) p++;
474df930be7Sderaadt if(strcmp(p, ")")) spe = 0;
475df930be7Sderaadt else spesgn = 1;
476df930be7Sderaadt }
477df930be7Sderaadt }
478df930be7Sderaadt /* now we have the actual name, as delivered by xname, say
479df930be7Sderaadt green potions called whisky
480df930be7Sderaadt scrolls labeled "QWERTY"
481df930be7Sderaadt egg
482df930be7Sderaadt dead zruties
483df930be7Sderaadt fortune cookies
484df930be7Sderaadt very heavy iron ball named hoei
485df930be7Sderaadt wand of wishing
486df930be7Sderaadt elven cloak
487df930be7Sderaadt */
488846311fcStdeval for(p = cp; *p; p++) if(!strncmp(p, " named ", 7)) {
489df930be7Sderaadt *p = 0;
490df930be7Sderaadt /* oname = p+7; */
491df930be7Sderaadt }
492846311fcStdeval for(p = cp; *p; p++) if(!strncmp(p, " called ", 8)) {
493df930be7Sderaadt *p = 0;
494df930be7Sderaadt un = p+8;
495df930be7Sderaadt }
496846311fcStdeval for(p = cp; *p; p++) if(!strncmp(p, " labeled ", 9)) {
497df930be7Sderaadt *p = 0;
498df930be7Sderaadt dn = p+9;
499df930be7Sderaadt }
500df930be7Sderaadt
501df930be7Sderaadt /* first change to singular if necessary */
502df930be7Sderaadt if(cnt != 1) {
503df930be7Sderaadt /* find "cloves of garlic", "worthless pieces of blue glass" */
504846311fcStdeval for(p = cp; *p; p++) if(!strncmp(p, "s of ", 5)){
5054a5fbbc4Spjanzen while ((*p = p[1]))
5064a5fbbc4Spjanzen p++;
507df930be7Sderaadt goto sing;
508df930be7Sderaadt }
509df930be7Sderaadt /* remove -s or -es (boxes) or -ies (rubies, zruties) */
510846311fcStdeval p = eos(cp);
511df930be7Sderaadt if(p[-1] == 's') {
512df930be7Sderaadt if(p[-2] == 'e') {
513df930be7Sderaadt if(p[-3] == 'i') {
514df930be7Sderaadt if(!strcmp(p-7, "cookies"))
515df930be7Sderaadt goto mins;
516846311fcStdeval strlcpy(p-3, "y", bp + len - (p-3));
517df930be7Sderaadt goto sing;
518df930be7Sderaadt }
519df930be7Sderaadt
520df930be7Sderaadt /* note: cloves / knives from clove / knife */
521df930be7Sderaadt if(!strcmp(p-6, "knives")) {
522846311fcStdeval strlcpy(p-3, "fe", bp + len - (p-3));
523df930be7Sderaadt goto sing;
524df930be7Sderaadt }
525df930be7Sderaadt
526df930be7Sderaadt /* note: nurses, axes but boxes */
527df930be7Sderaadt if(!strcmp(p-5, "boxes")) {
528df930be7Sderaadt p[-2] = 0;
529df930be7Sderaadt goto sing;
530df930be7Sderaadt }
531df930be7Sderaadt }
532df930be7Sderaadt mins:
533df930be7Sderaadt p[-1] = 0;
534df930be7Sderaadt } else {
535df930be7Sderaadt if(!strcmp(p-9, "homunculi")) {
536846311fcStdeval strlcpy(p-1, "us", bp + len - (p-1));
537df930be7Sderaadt goto sing;
538df930be7Sderaadt }
539df930be7Sderaadt if(!strcmp(p-5, "teeth")) {
540846311fcStdeval strlcpy(p-5, "tooth", bp + len - (p-5));
541df930be7Sderaadt goto sing;
542df930be7Sderaadt }
543df930be7Sderaadt /* here we cannot find the plural suffix */
544df930be7Sderaadt }
545df930be7Sderaadt }
546df930be7Sderaadt sing:
547846311fcStdeval if(!strcmp(cp, "amulet of yendor")) {
548df930be7Sderaadt typ = AMULET_OF_YENDOR;
549df930be7Sderaadt goto typfnd;
550df930be7Sderaadt }
551846311fcStdeval p = eos(cp);
552df930be7Sderaadt if(!strcmp(p-5, " mail")){ /* Note: ring mail is not a ring ! */
553df930be7Sderaadt let = ARMOR_SYM;
554846311fcStdeval an = cp;
555df930be7Sderaadt goto srch;
556df930be7Sderaadt }
557df930be7Sderaadt for(i = 0; i < sizeof(wrpsym); i++) {
5584a5fbbc4Spjanzen int j = strlen(wrp[i]);
559846311fcStdeval if(!strncmp(cp, wrp[i], j)){
560df930be7Sderaadt let = wrpsym[i];
561846311fcStdeval cp += j;
562846311fcStdeval if(!strncmp(cp, " of ", 4)) an = cp+4;
563846311fcStdeval /* else if(*cp) ?? */
564df930be7Sderaadt goto srch;
565df930be7Sderaadt }
566df930be7Sderaadt if(!strcmp(p-j, wrp[i])){
567df930be7Sderaadt let = wrpsym[i];
568df930be7Sderaadt p -= j;
569df930be7Sderaadt *p = 0;
570df930be7Sderaadt if(p[-1] == ' ') p[-1] = 0;
571846311fcStdeval dn = cp;
572df930be7Sderaadt goto srch;
573df930be7Sderaadt }
574df930be7Sderaadt }
575df930be7Sderaadt if(!strcmp(p-6, " stone")){
576df930be7Sderaadt p[-6] = 0;
577df930be7Sderaadt let = GEM_SYM;
578846311fcStdeval an = cp;
579df930be7Sderaadt goto srch;
580df930be7Sderaadt }
581846311fcStdeval if(!strcmp(cp, "very heavy iron ball")){
582df930be7Sderaadt heavy = 1;
583df930be7Sderaadt typ = HEAVY_IRON_BALL;
584df930be7Sderaadt goto typfnd;
585df930be7Sderaadt }
586846311fcStdeval an = cp;
587df930be7Sderaadt srch:
588df930be7Sderaadt if(!an && !dn && !un)
589df930be7Sderaadt goto any;
590df930be7Sderaadt i = 1;
591df930be7Sderaadt if(let) i = bases[letindex(let)];
592df930be7Sderaadt while(i <= NROFOBJECTS && (!let || objects[i].oc_olet == let)){
5934a5fbbc4Spjanzen char *zn = objects[i].oc_name;
594df930be7Sderaadt
595df930be7Sderaadt if(!zn) goto nxti;
596df930be7Sderaadt if(an && strcmp(an, zn))
597df930be7Sderaadt goto nxti;
598df930be7Sderaadt if(dn && (!(zn = objects[i].oc_descr) || strcmp(dn, zn)))
599df930be7Sderaadt goto nxti;
600df930be7Sderaadt if(un && (!(zn = objects[i].oc_uname) || strcmp(un, zn)))
601df930be7Sderaadt goto nxti;
602df930be7Sderaadt typ = i;
603df930be7Sderaadt goto typfnd;
604df930be7Sderaadt nxti:
605df930be7Sderaadt i++;
606df930be7Sderaadt }
607df930be7Sderaadt any:
608df930be7Sderaadt if(!let) let = wrpsym[rn2(sizeof(wrpsym))];
609df930be7Sderaadt typ = probtype(let);
610df930be7Sderaadt typfnd:
6114a5fbbc4Spjanzen { struct obj *otmp;
612df930be7Sderaadt let = objects[typ].oc_olet;
613df930be7Sderaadt otmp = mksobj(typ);
614df930be7Sderaadt if(heavy)
615df930be7Sderaadt otmp->owt += 15;
616180acc8fSmillert if(cnt > 0 && strchr("%?!*)", let) &&
617df930be7Sderaadt (cnt < 4 || (let == WEAPON_SYM && typ <= ROCK && cnt < 20)))
618df930be7Sderaadt otmp->quan = cnt;
619df930be7Sderaadt
620df930be7Sderaadt if(spe > 3 && spe > otmp->spe)
621df930be7Sderaadt spe = 0;
622df930be7Sderaadt else if(let == WAND_SYM)
623df930be7Sderaadt spe = otmp->spe;
624df930be7Sderaadt if(spe == 3 && u.uluck < 0)
625df930be7Sderaadt spesgn = -1;
626df930be7Sderaadt if(let != WAND_SYM && spesgn == -1)
627df930be7Sderaadt spe = -spe;
628df930be7Sderaadt if(let == BALL_SYM)
629df930be7Sderaadt spe = 0;
630df930be7Sderaadt else if(let == AMULET_SYM)
631df930be7Sderaadt spe = -1;
632df930be7Sderaadt else if(typ == WAN_WISHING && rn2(10))
633df930be7Sderaadt spe = (rn2(10) ? -1 : 0);
634df930be7Sderaadt otmp->spe = spe;
635df930be7Sderaadt
636df930be7Sderaadt if(spesgn == -1)
637df930be7Sderaadt otmp->cursed = 1;
638df930be7Sderaadt
639df930be7Sderaadt return(otmp);
640df930be7Sderaadt }
641df930be7Sderaadt }
642