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