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