Source:NetHack 3.2.0/do name.c

From NetHackWiki
Revision as of 08:22, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 3.2.0/do name.c moved to Source:NetHack 3.2.0/do name.c: Robot: moved page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Below is the full text to do_name.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.0/do_name.c#line123]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

1.    /*	SCCS Id: @(#)do_name.c	3.2	96/03/17	*/
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    #include "hack.h"
6.    
7.    #ifdef OVLB
8.    
9.    static void FDECL(do_oname, (struct obj *));
10.   
11.   void
12.   getpos(cc,force,goal)
13.   coord	*cc;
14.   boolean force;
15.   const char *goal;
16.   {
17.       int cx, cy, i, c;
18.       int sidx, tx, ty;
19.       boolean msg_given = TRUE;	/* clear message window by default */
20.       const char *sdp;
21.       if(flags.num_pad) sdp = ndir; else sdp = sdir;	/* DICE workaround */
22.   
23.       if (flags.verbose) {
24.   	pline("(For instructions type a ?)");
25.   	msg_given = TRUE;
26.       }
27.       cx = cc->x;
28.       cy = cc->y;
29.   #ifdef CLIPPING
30.       cliparound(cx, cy);
31.   #endif
32.       curs(WIN_MAP, cx,cy);
33.       flush_screen(0);
34.   #ifdef MAC
35.       lock_mouse_cursor(TRUE);
36.   #endif
37.       while ((c = nh_poskey(&tx, &ty, &sidx)) != '.') {
38.   	if (c == '\033') {
39.   	    cx = cy = -10;
40.   	    msg_given = TRUE;	/* force clear */
41.   	    break;
42.   	}
43.   	if(c == 0) {
44.   	    /* a mouse click event, just assign and return */
45.   	    cx = tx;
46.   	    cy = ty;
47.   	    break;
48.   	}
49.   	for(i=0; i<8; i++)
50.   	    if (sdp[i] == c) {
51.   		if (1 <= cx + xdir[i] && cx + xdir[i] < COLNO)
52.   		    cx += xdir[i];
53.   		if (0 <= cy + ydir[i] && cy + ydir[i] < ROWNO)
54.   		    cy += ydir[i];
55.   		goto nxtc;
56.   	    } else if (sdp[i] == lowc((char)c)) {
57.   		cx += xdir[i]*8;
58.   		cy += ydir[i]*8;
59.   		if(cx < 1) cx = 1;
60.   		if(cx > COLNO-1) cx = COLNO-1;
61.   		if(cy < 0) cy = 0;
62.   		if(cy > ROWNO-1) cy = ROWNO-1;
63.   		goto nxtc;
64.   	    }
65.   
66.   	if(c == '?'){
67.   	    char sbuf[80];
68.   	    winid tmpwin = create_nhwindow(NHW_MENU);
69.   	    Sprintf(sbuf, "Use [%s] to move the cursor to %s.",
70.   		  flags.num_pad ? "2468" : "hjkl", goal);
71.   	    putstr(tmpwin, 0, sbuf);
72.   	    putstr(tmpwin, 0,
73.   		   "Use [HJKL] to move the cursor 8 units at a time.");
74.   	    putstr(tmpwin, 0, "Or enter a background symbol (ex. <).");
75.   	    putstr(tmpwin, 0, "Type a . when you are at the right place.");
76.   	    if(!force)
77.   		putstr(tmpwin, 0, "Type Space or Escape when you're done.");
78.   	    putstr(tmpwin, 0, "");
79.   	    display_nhwindow(tmpwin, TRUE);
80.   	    destroy_nhwindow(tmpwin);
81.   	} else {
82.   	    if (!index(quitchars, c)) {
83.   		char matching[MAXPCHARS];
84.   		int pass, lo_x, lo_y, hi_x, hi_y, k = 0;
85.   		(void)memset((genericptr_t)matching, 0, sizeof matching);
86.   		for (sidx = 1; sidx < MAXPCHARS; sidx++)
87.   		    if (c == defsyms[sidx].sym || c == (int)showsyms[sidx])
88.   			matching[sidx] = (char) ++k;
89.   		if (k) {
90.   		    for (pass = 0; pass <= 1; pass++) {
91.   			/* pass 0: just past current pos to lower right;
92.   			   pass 1: upper left corner to current pos */
93.   			lo_y = (pass == 0) ? cy : 0;
94.   			hi_y = (pass == 0) ? ROWNO - 1 : cy;
95.   			for (ty = lo_y; ty <= hi_y; ty++) {
96.   			    lo_x = (pass == 0 && ty == lo_y) ? cx + 1 : 1;
97.   			    hi_x = (pass == 1 && ty == hi_y) ? cx : COLNO - 1;
98.   			    for (tx = lo_x; tx <= hi_x; tx++) {
99.   				k = levl[tx][ty].glyph;
100.  				if (glyph_is_cmap(k) &&
101.  					matching[glyph_to_cmap(k)]) {
102.  				    cx = tx,  cy = ty;
103.  				    if (msg_given) {
104.  					clear_nhwindow(WIN_MESSAGE);
105.  					msg_given = FALSE;
106.  				    }
107.  				    goto nxtc;
108.  				}
109.  			    }	/* column */
110.  			}	/* row */
111.  		    }		/* pass */
112.  		    pline("Can't find dungeon feature '%c'", c);
113.  		    msg_given = TRUE;
114.  		    goto nxtc;
115.  		} else {
116.  		    pline("Unknown direction: '%s' (%s).",
117.  			  visctrl((char)c),
118.  			  !force ? "aborted" :
119.  			  flags.num_pad ? "use 2468 or ." : "use hjkl or .");
120.  		    msg_given = TRUE;
121.  		} /* k => matching */
122.  	    } /* !quitchars */
123.  	    if (force) goto nxtc;
124.  	    pline("Done.");
125.  	    msg_given = FALSE;	/* suppress clear */
126.  	    cx = -1;
127.  	    cy = 0;
128.  	    break;
129.  	}
130.      nxtc:	;
131.  #ifdef CLIPPING
132.  	cliparound(cx, cy);
133.  #endif
134.  	curs(WIN_MAP,cx,cy);
135.  	flush_screen(0);
136.      }
137.  #ifdef MAC
138.      lock_mouse_cursor(FALSE);
139.  #endif
140.      if (msg_given) clear_nhwindow(WIN_MESSAGE);
141.      cc->x = cx;
142.      cc->y = cy;
143.      return;
144.  }
145.  
146.  struct monst *
147.  christen_monst(mtmp, name)
148.  struct monst *mtmp;
149.  const char *name;
150.  {
151.  	int lth, i;
152.  	struct monst *mtmp2;
153.  	char buf[PL_PSIZ];
154.  
155.  	/* dogname & catname are PL_PSIZ arrays; object names have same limit */
156.  	lth = *name ? (int)(strlen(name) + 1) : 0;
157.  	if(lth > PL_PSIZ){
158.  		lth = PL_PSIZ;
159.  		name = strncpy(buf, name, PL_PSIZ - 1);
160.  		buf[PL_PSIZ - 1] = '\0';
161.  	}
162.  	if (lth == mtmp->mnamelth) {
163.  		/* don't need to allocate a new monst struct */
164.  		if (lth) Strcpy(NAME(mtmp), name);
165.  		return mtmp;
166.  	}
167.  	mtmp2 = newmonst(mtmp->mxlth + lth);
168.  	*mtmp2 = *mtmp;
169.  	for(i=0; i<mtmp->mxlth; i++)
170.  		((char *) mtmp2->mextra)[i] = ((char *) mtmp->mextra)[i];
171.  	mtmp2->mnamelth = lth;
172.  	if (lth) Strcpy(NAME(mtmp2), name);
173.  	replmon(mtmp,mtmp2);
174.  	return(mtmp2);
175.  }
176.  
177.  int
178.  do_mname()
179.  {
180.  	char buf[BUFSZ];
181.  	coord cc;
182.  	register int cx,cy;
183.  	register struct monst *mtmp;
184.  	register char *curr;
185.  	char qbuf[QBUFSZ];
186.  
187.  	if (Hallucination) {
188.  		You("would never recognize it anyway.");
189.  		return 0;
190.  	}
191.  	cc.x = u.ux;
192.  	cc.y = u.uy;
193.  	getpos(&cc, FALSE, "the monster you want to name");
194.  	cx = cc.x;
195.  	cy = cc.y;
196.  	if(cx < 0) return(0);
197.  	if (cx == u.ux && cy == u.uy) {
198.  		pline("This %s creature is called %s and cannot be renamed.",
199.  		ACURR(A_CHA) > 14 ?
200.  		(flags.female ? "beautiful" : "handsome") :
201.  		"ugly",
202.  		plname);
203.  		return(0);
204.  	}
205.  	mtmp = m_at(cx, cy);
206.  	if (!mtmp || (!sensemon(mtmp) &&
207.  			(!cansee(cx,cy) || mtmp->mundetected
208.  			|| mtmp->m_ap_type == M_AP_FURNITURE
209.  			|| mtmp->m_ap_type == M_AP_OBJECT
210.  			|| (mtmp->minvis && !See_invisible)))) {
211.  		pline("I see no monster there.");
212.  		return(0);
213.  	}
214.  	Sprintf(qbuf, "What do you want to call %s?", x_monnam(mtmp, 0,
215.  		(char *)0, 1));
216.  	getlin(qbuf,buf);
217.  	if(!*buf || *buf == '\033') return(0);
218.  
219.  	/* strip trailing spaces; unnames monster if all spaces */
220.  	for (curr = eos(buf); curr > buf; )
221.  		if (*--curr == ' ') *curr = '\0'; else break;
222.  
223.  	if (type_is_pname(mtmp->data))
224.  	    pline("%s doesn't like being called names!", Monnam(mtmp));
225.  	else (void) christen_monst(mtmp, buf);
226.  	return(0);
227.  }
228.  
229.  /*
230.   * This routine changes the address of obj. Be careful not to call it
231.   * when there might be pointers around in unknown places. For now: only
232.   * when obj is in the inventory.
233.   */
234.  static
235.  void
236.  do_oname(obj)
237.  register struct obj *obj;
238.  {
239.  	char buf[BUFSZ], qbuf[QBUFSZ];
240.  	register char *curr;
241.  	const char *aname;
242.  	short objtyp;
243.  
244.  	Sprintf(qbuf, "What do you want to name %s?", doname(obj));
245.  	getlin(qbuf, buf);
246.  	if(!*buf || *buf == '\033')	return;
247.  
248.  	/* strip trailing spaces; unnames item if all spaces */
249.  	for (curr = eos(buf); curr > buf; )
250.  		if (*--curr == ' ') *curr = '\0'; else break;
251.  
252.  	/* relax restrictions over proper capitalization for artifacts */
253.  	if ((aname = artifact_name(buf, &objtyp)) != 0 && objtyp == obj->otyp)
254.  		Strcpy(buf, aname);
255.  
256.  	if (obj->oartifact) {
257.  		pline_The("artifact seems to resist the attempt.");
258.  		return;
259.  	} else if (restrict_name(obj, buf) || exist_artifact(obj->otyp, buf)) {
260.  		int n = rn2((int)strlen(buf));
261.  		register char c1, c2;
262.  
263.  		c1 = lowc(buf[n]);
264.  		do c2 = 'a' + rn2('z'-'a'); while (c1 == c2);
265.  		buf[n] = (buf[n] == c1) ? c2 : highc(c2);  /* keep same case */
266.  		pline("While engraving your %s slips.", body_part(HAND));
267.  		display_nhwindow(WIN_MESSAGE, FALSE);
268.  		You("engrave: \"%s\".",buf);
269.  	}
270.  	obj = oname(obj, buf);
271.  	if (obj->where == OBJ_INVENT)
272.  		update_inventory();
273.  }
274.  
275.  struct obj *
276.  oname(obj, name)
277.  struct obj *obj;
278.  const char *name;
279.  {
280.  	struct obj *otmp;
281.  	int lth;
282.  	char buf[PL_PSIZ];
283.  
284.  	lth = *name ? (int)(strlen(name) + 1) : 0;
285.  	if (lth > PL_PSIZ) {
286.  		lth = PL_PSIZ;
287.  		name = strncpy(buf, name, PL_PSIZ - 1);
288.  		buf[PL_PSIZ - 1] = '\0';
289.  	}
290.  	/* If named artifact exists in the game, do not create another.
291.  	 * Also trying to create an artifact shouldn't de-artifact
292.  	 * it (e.g. Excalibur from prayer). In this case the object
293.  	 * will retain its current name. */
294.  	if (obj->oartifact || (lth && exist_artifact(obj->otyp, name)))
295.  		return obj;
296.  	if (lth == obj->onamelth) {
297.  		/* no need to replace entire object */
298.  		if (lth) Strcpy(ONAME(obj), name);
299.  		return obj;
300.  	}
301.  
302.  	otmp = newobj(lth);
303.  	*otmp = *obj;	/* the cobj pointer is copied to otmp */
304.  	otmp->onamelth = lth;
305.  	otmp->timed = 0;	/* not timed, yet */
306.  	otmp->lamplit = 0;	/* ditto */
307.  	/* __GNUC__ note:  if the assignment of otmp->onamelth immediately
308.  	   precedes this `if' statement, a gcc bug will miscompile the
309.  	   test on vax (`insv' instruction used to store bitfield does
310.  	   not set condition codes, but optimizer behaves as if it did).
311.  	   gcc-2.8.0 should finally fix this.... */
312.  	if (lth) {
313.  		Strcpy(ONAME(otmp), name);
314.  		artifact_exists(otmp, name, TRUE);
315.  	}
316.  
317.  	if (obj->owornmask) {
318.  		setworn((struct obj *)0, obj->owornmask);
319.  		setworn(otmp, otmp->owornmask);
320.  	}
321.  
322.  	/*
323.  	 * Finish inserting otmp right after obj in whatever chain
324.  	 * it is on.  Then extract obj from the chain(s).  Don't use
325.  	 * obj_extract_self(), we are doing an in-place swap, not
326.  	 * actually moving something.
327.  	 */
328.  	switch (obj->where) {
329.  	    case OBJ_FREE:
330.  		/* do nothing */
331.  		break;
332.  	    case OBJ_INVENT:
333.  		obj->nobj = otmp;
334.  		extract_nobj(obj, &invent);
335.  		break;
336.  	    case OBJ_CONTAINED:
337.  		obj->nobj = otmp;
338.  		extract_nobj(obj, &obj->ocontainer);
339.  		break;
340.  	    case OBJ_MINVENT:
341.  		obj->nobj = otmp;
342.  		extract_nobj(obj, &obj->ocarry->minvent);
343.  		break;
344.  	    case OBJ_FLOOR:
345.  		obj->nobj = otmp;
346.  		obj->nexthere = otmp;
347.  		extract_nobj(obj, &fobj);
348.  		extract_nexthere(obj, &level.objects[obj->ox][obj->oy]);
349.  		break;
350.  	    default:
351.  		panic("oname: obj position");
352.  		break;
353.  	}
354.  
355.  	/* fix ocontainer pointers */
356.  	if (Has_contents(obj)) {
357.  		struct obj *inside;
358.  
359.  		for(inside = obj->cobj; inside; inside = inside->nobj)
360.  			inside->ocontainer = otmp;
361.  	}
362.  
363.  	/* move timers and light sources from obj to otmp */
364.  	if (obj->timed) obj_move_timers(obj, otmp);
365.  	if (obj->lamplit) obj_move_light_source(obj, otmp);
366.  
367.  	/* obfree(obj, otmp);	/* now unnecessary: no pointers on bill */
368.  	dealloc_obj(obj);	/* let us hope nobody else saved a pointer */
369.  	return otmp;
370.  }
371.  
372.  static NEARDATA const char callable[] = {
373.  	SCROLL_CLASS, POTION_CLASS, WAND_CLASS, RING_CLASS, AMULET_CLASS,
374.  	GEM_CLASS, SPBOOK_CLASS, ARMOR_CLASS, TOOL_CLASS, 0 };
375.  
376.  int
377.  ddocall()
378.  {
379.  	register struct obj *obj;
380.  #ifdef REDO
381.  	char	ch;
382.  #endif
383.  	char allowall[2];
384.  
385.  	switch(
386.  #ifdef REDO
387.  		ch =
388.  #endif
389.  		ynq("Name an individual object?")) {
390.  	case 'q':
391.  		break;
392.  	case 'y':
393.  #ifdef REDO
394.  		savech(ch);
395.  #endif
396.  		allowall[0] = ALL_CLASSES; allowall[1] = '\0';
397.  		obj = getobj(allowall, "name");
398.  		if(obj) do_oname(obj);
399.  		break;
400.  	default :
401.  #ifdef REDO
402.  		savech(ch);
403.  #endif
404.  		obj = getobj(callable, "call");
405.  		if (obj) {
406.  			if (!obj->dknown) {
407.  				You("would never recognize another one.");
408.  				return 0;
409.  			}
410.  			docall(obj);
411.  		}
412.  		break;
413.  	}
414.  	return 0;
415.  }
416.  
417.  void
418.  docall(obj)
419.  register struct obj *obj;
420.  {
421.  	char buf[BUFSZ], qbuf[QBUFSZ];
422.  	struct obj otemp;
423.  	register char **str1;
424.  	register char *str;
425.  
426.  	if (!obj->dknown) return; /* probably blind */
427.  	otemp = *obj;
428.  	otemp.quan = 1L;
429.  	otemp.onamelth = 0;
430.  	if (objects[otemp.otyp].oc_class == POTION_CLASS && otemp.corpsenm) {
431.  		/* kludge, meaning it's sink water */
432.  		Sprintf(qbuf,"Call a stream of %s fluid:",
433.  				OBJ_DESCR(objects[otemp.otyp]));
434.  	} else
435.  		Sprintf(qbuf, "Call %s:", an(xname(&otemp)));
436.  	getlin(qbuf, buf);
437.  	if(!*buf || *buf == '\033')
438.  		return;
439.  
440.  	/* clear old name */
441.  	str1 = &(objects[obj->otyp].oc_uname);
442.  	if(*str1) free((genericptr_t)*str1);
443.  
444.  	/* strip trailing spaces; uncalls item if all spaces */
445.  	for (str = eos(buf); str > buf; )
446.  		if (*--str == ' ') *str = '\0'; else break;
447.  	if (!*buf) {
448.  		if (*str1)	/* had name, so possibly remove from disco[] */
449.  			undiscover_object(obj->otyp),  *str1 = (char *)0;
450.  	} else {
451.  		*str1 = strcpy((char *) alloc((unsigned)strlen(buf)+1), buf);
452.  		discover_object(obj->otyp, FALSE); /* possibly add to disco[] */
453.  	}
454.  }
455.  
456.  #endif /*OVLB*/
457.  #ifdef OVL0
458.  
459.  static const char *ghostnames[] = {
460.  	/* these names should have length < PL_NSIZ */
461.  	/* Capitalize the names for aesthetics -dgk */
462.  	"Adri", "Andries", "Andreas", "Bert", "David", "Dirk", "Emile",
463.  	"Frans", "Fred", "Greg", "Hether", "Jay", "John", "Jon", "Karnov",
464.  	"Kay", "Kenny", "Kevin", "Maud", "Michiel", "Mike", "Peter", "Robert",
465.  	"Ron", "Tom", "Wilmar", "Nick Danger", "Phoenix", "Jiro", "Mizue",
466.  	"Stephan", "Lance Braccus", "Shadowhawk"
467.  };
468.  
469.  /* Monster naming functions:
470.   * x_monnam is the generic monster-naming function.
471.   *		  seen	      unseen	   detected		  named
472.   * mon_nam:	the newt	it	the invisible orc	Fido
473.   * l_monnam:	newt		it	invisible orc		dog called fido
474.   * Monnam:	The newt	It	The invisible orc	Fido
475.   * Adjmonnam:	The poor newt	It	The poor invisible orc	The poor Fido
476.   * Amonnam:	A newt		It	An invisible orc	Fido
477.   * a_monnam:	a newt		it	an invisible orc	Fido
478.   * m_monnam:	newt		xan	orc			Fido
479.   */
480.  
481.  char *
482.  x_monnam(mtmp, article, adjective, called)
483.  register struct monst *mtmp;
484.  /* Articles:
485.   * 0: "the" in front of everything except names and "it"
486.   * 1: "the" in front of everything except "it"; looks bad for names unless you
487.   *    are also using an adjective.
488.   * 2: "a" in front of everything except "it".
489.   * 3: no article at all.
490.   * 4: no article; "it" and invisible suppressed.
491.   */
492.  int article, called;
493.  const char *adjective;
494.  {
495.  #ifdef LINT	/* static char buf[BUFSZ]; */
496.  	char buf[BUFSZ];
497.  #else
498.  	static char buf[BUFSZ];
499.  #endif
500.  	struct permonst *mdat = mtmp->data;
501.  	char *name = 0;
502.  	int force_the = 0, trunam = (article == 4);
503.  
504.  	buf[0] = '\0';
505.  	if (mtmp->ispriest || mtmp->isminion) {
506.  	    name = priestname(mtmp);
507.  	    if ((trunam || article == 3) && !strncmp(name, "the ", 4))
508.  		name += 4;
509.  	    return strcpy(buf, name);
510.  	}
511.  	if (!trunam && !canspotmon(mtmp) &&
512.  		!(u.uswallow && mtmp == u.ustuck) && !killer) {
513.  	    if (!(cansee(bhitpos.x, bhitpos.y) && mon_visible(mtmp))) {
514.  		Strcpy(buf, "it");
515.  		return  buf;
516.  	    }
517.  	}
518.  	if (trunam || !Hallucination) {
519.  	    if (mtmp->isshk) {
520.  		Strcpy(buf, shkname(mtmp));
521.  		if ((mdat == &mons[PM_SHOPKEEPER] && !mtmp->minvis) || trunam)
522.  		    return buf;
523.  		/* For normal shopkeepers, just 'Asidonhopo'.
524.  		 * For unusual ones, 'Asidonhopo the invisible shopkeeper'
525.  		 * or 'Asidonhopo the blue dragon'.
526.  		 */
527.  		Strcat(buf, " ");
528.  	    } else if (mtmp->mnamelth) {
529.  		name = NAME(mtmp);
530.  	    }
531.  	}
532.  
533.  	if (!trunam) {
534.  	    force_the = (!Hallucination &&
535.  			 (mdat == &mons[PM_WIZARD_OF_YENDOR] || mtmp->isshk));
536.  	    if (force_the ||
537.  		    ((article == 1 || ((!name || called) && article == 0)) &&
538.  			(Hallucination || !type_is_pname(mdat))))
539.  		Strcat(buf, "the ");
540.  	    if (adjective)
541.  		Strcat(strcat(buf, adjective), " ");
542.  	    if (mtmp->minvis && !Blind)
543.  		Strcat(buf, "invisible ");
544.  	}
545.  
546.  	if (name && !called) {
547.  	    Strcat(buf, name);
548.  	    goto bot_nam;
549.  	}
550.  
551.  	if (Hallucination && !trunam) {
552.  	    Strcat(buf, rndmonnam());
553.  	} else if (mdat == &mons[PM_GHOST]) {
554.  	    register const char *gn = (const char *) mtmp->mextra;
555.  	    if (!*gn) {
556.  		/* ghost doesn't have a name yet; give it one now
557.  		   (might also want to look in scorefile) */
558.  		gn = rn2(5) ? ghostnames[rn2(SIZE(ghostnames))] :
559.  			      (const char *)plname;
560.  		Strcpy((char *) mtmp->mextra, gn);
561.  	    }
562.  	    Sprintf(buf, "%s ghost", s_suffix((char *) mtmp->mextra));
563.  	} else if (is_mplayer(mdat) && !In_endgame(&u.uz)) {
564.  	    char pbuf[BUFSZ];
565.  	    Strcpy(pbuf, rank_of((int)mtmp->m_lev,
566.  				 highc(mdat->mname[0]),
567.  				 (boolean)mtmp->female));
568.  	    Strcat(buf, lcase(pbuf));
569.  	} else {
570.  	    Strcat(buf, mdat->mname);
571.  	}
572.  
573.  	if (name) {	/* if we reach here, `name' implies `called' */
574.  	    Strcat(buf, " called ");
575.  	    Strcat(buf, NAME(mtmp));
576.  	}
577.   bot_nam:
578.  	if (article == 2 && !force_the && (!name || called) &&
579.  		(Hallucination || !type_is_pname(mdat)))
580.  	    return an(buf);
581.  	else
582.  	    return buf;
583.  }
584.  
585.  #endif /* OVL0 */
586.  #ifdef OVLB
587.  
588.  char *
589.  l_monnam(mtmp)
590.  register struct monst *mtmp;
591.  {
592.  	return(x_monnam(mtmp, 3, (char *)0, 1));
593.  }
594.  
595.  #endif /* OVLB */
596.  #ifdef OVL0
597.  
598.  char *
599.  mon_nam(mtmp)
600.  register struct monst *mtmp;
601.  {
602.  	return(x_monnam(mtmp, 0, (char *)0, 0));
603.  }
604.  
605.  char *
606.  Monnam(mtmp)
607.  register struct monst *mtmp;
608.  {
609.  	register char *bp = mon_nam(mtmp);
610.  
611.  	*bp = highc(*bp);
612.  	return(bp);
613.  }
614.  
615.  /* monster's own name */
616.  char *
617.  m_monnam(mtmp)
618.  struct monst *mtmp;
619.  {
620.  	char *result;
621.  	unsigned save_invis = mtmp->minvis;
622.  
623.  	mtmp->minvis = 0;  /* affects priestname() as well as x_monnam() */
624.  	result = x_monnam(mtmp, 4, (char *)0, 0);
625.  	mtmp->minvis = save_invis;
626.  	return result;
627.  }
628.  
629.  #endif /* OVL0 */
630.  #ifdef OVLB
631.  
632.  char *
633.  Adjmonnam(mtmp, adj)
634.  register struct monst *mtmp;
635.  register const char *adj;
636.  {
637.  	register char *bp = x_monnam(mtmp,1,adj,0);
638.  
639.  	*bp = highc(*bp);
640.  	return(bp);
641.  }
642.  
643.  char *
644.  a_monnam(mtmp)
645.  register struct monst *mtmp;
646.  {
647.  	return x_monnam(mtmp, 2, (char *)0, 0);
648.  }
649.  
650.  char *
651.  Amonnam(mtmp)
652.  register struct monst *mtmp;
653.  {
654.  	register char *bp = a_monnam(mtmp);
655.  
656.  	*bp = highc(*bp);
657.  	return(bp);
658.  }
659.  
660.  static const char *bogusmons[] = {
661.  	"jumbo shrimp", "giant pigmy", "gnu", "killer penguin",
662.  	"giant cockroach", "giant slug", "maggot", "pterodactyl",
663.  	"tyrannosaurus rex", "basilisk", "beholder", "nightmare",
664.  	"efreeti", "marid", "rot grub", "bookworm", "doppelganger",
665.  	"shadow", "hologram", "jester", "attorney", "sleazoid",
666.  	"killer tomato", "amazon", "robot", "battlemech",
667.  	"rhinovirus", "harpy", "lion-dog", "rat-ant",
668.  						/* misc. */
669.  	"grue", "Christmas-tree monster", "luck sucker", "paskald",
670.  	"brogmoid", "dornbeast",		/* Quendor (Zork, &c.) */
671.  	"Ancient Multi-Hued Dragon", "Evil Iggy",
672.  						/* Moria */
673.  	"emu", "kestrel", "xeroc", "venus flytrap",
674.  						/* Rogue */
675.  	"creeping coins",			/* Wizardry */
676.  	"hydra", "siren",			/* Greek legend */
677.  	"killer bunny",				/* Monty Python */
678.  	"rodent of unusual size",		/* The Princess Bride */
679.  	"Smokey the bear",	/* "Only you can prevent forest fires!" */
680.  	"Luggage",				/* Discworld */
681.  	"Ent",					/* Lord of the Rings */
682.  	"tangle tree", "nickelpede", "wiggle",	/* Xanth */
683.  	"white rabbit", "snark",		/* Lewis Carroll */
684.  	"pushmi-pullyu",			/* Dr. Doolittle */
685.  	"smurf",				/* The Smurfs */
686.  	"tribble", "Klingon", "Borg",		/* Star Trek */
687.  	"Ewok",					/* Star Wars */
688.  	"Totoro",				/* Tonari no Totoro */
689.  	"ohmu",					/* Nausicaa */
690.  	"youma",				/* Sailor Moon */
691.  	"Godzilla", "King Kong",		/* monster movies */
692.  	"earthquake beast",			/* old L of SH */
693.  	"Invid",				/* Robotech */
694.  	"Terminator",				/* The Terminator */
695.  	"boomer",				/* Bubblegum Crisis */
696.  	"Dalek",				/* Dr. Who ("Exterminate!") */
697.  	"microscopic space fleet", "Ravenous Bugblatter Beast of Traal",
698.  						/* HGttG */
699.  	"teenage mutant ninja turtle",		/* TMNT */
700.  	"samurai rabbit",			/* Usagi Yojimbo */
701.  	"aardvark",				/* Cerebus */
702.  	"Audrey II",				/* Little Shop of Horrors */
703.  	"witch doctor", "one-eyed one-horned flying purple people eater",
704.  						/* 50's rock 'n' roll */
705.  	"Barney the dinosaur"			/* saccharine kiddy TV */
706.  };
707.  
708.  const char *
709.  rndmonnam()	/* Random name of monster type, if hallucinating */
710.  {
711.  	int name;
712.  
713.  	do {
714.  	    name = rn1(SPECIAL_PM + SIZE(bogusmons) - LOW_PM, LOW_PM);
715.  	} while (name < SPECIAL_PM &&
716.  	    (type_is_pname(&mons[name]) || (mons[name].geno & G_NOGEN)));
717.  
718.  	if (name >= SPECIAL_PM) return bogusmons[name - SPECIAL_PM];
719.  	return mons[name].mname;
720.  }
721.  
722.  const char *pronoun_pairs[][2] = {
723.  	{"him", "her"}, {"Him", "Her"}, {"his", "her"}, {"His", "Her"},
724.  	{"he", "she"}, {"He", "She"},
725.  	{0, 0}
726.  };
727.  
728.  char *
729.  self_pronoun(str, pronoun)
730.  const char *str;
731.  const char *pronoun;
732.  {
733.  	static NEARDATA char buf[BUFSZ];
734.  	register int i;
735.  
736.  	for(i=0; pronoun_pairs[i][0]; i++) {
737.  		if(!strncmp(pronoun, pronoun_pairs[i][0], 3)) {
738.  			Sprintf(buf, str, pronoun_pairs[i][flags.female]);
739.  			return buf;
740.  		}
741.  	}
742.  	impossible("never heard of pronoun %s?", pronoun);
743.  	Sprintf(buf, str, pronoun_pairs[i][0]);
744.  	return buf;
745.  }
746.  
747.  #ifdef REINCARNATION
748.  const char *
749.  roguename() /* Name of a Rogue player */
750.  {
751.  	char *i, *opts;
752.  
753.  	if ((opts = getenv("ROGUEOPTS")) != 0) {
754.  		for (i = opts; *i; i++)
755.  			if (!strncmp("name=",i,5)) {
756.  				char *j;
757.  				if ((j = index(i+5,',')) != 0)
758.  					*j = (char)0;
759.  				return i+5;
760.  			}
761.  	}
762.  	return rn2(3) ? (rn2(2) ? "Michael Toy" : "Kenneth Arnold")
763.  		: "Glenn Wichman";
764.  }
765.  #endif /* REINCARNATION */
766.  #endif /* OVLB */
767.  
768.  #ifdef OVL2
769.  
770.  static NEARDATA const char *hcolors[] = {
771.  	"ultraviolet", "infrared", "bluish-orange",
772.  	"reddish-green", "dark white", "light black", "sky blue-pink",
773.  	"salty", "sweet", "sour", "bitter",
774.  	"striped", "spiral", "swirly", "plaid", "checkered", "argyle",
775.  	"paisley", "blotchy", "guernsey-spotted", "polka-dotted",
776.  	"square", "round", "triangular",
777.  	"cabernet", "sangria", "fuchsia", "wisteria",
778.  	"lemon-lime", "strawberry-banana", "peppermint",
779.  	"romantic", "incandescent"
780.  };
781.  
782.  const char *
783.  hcolor(colorpref)
784.  const char *colorpref;
785.  {
786.  	return (Hallucination || !colorpref) ?
787.  		hcolors[rn2(SIZE(hcolors))] : colorpref;
788.  }
789.  #endif /* OVL2 */
790.  
791.  /*do_name.c*/