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