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