Source:NetHack 3.0.0/do name.c

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

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

1.   /*	SCCS Id: @(#)do_name.c	3.0	88/11/24 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.   static 8.   char * 9.   visctrl(c) 10.  char c;  11. { 12.   #ifdef LINT	/* static char ccc[3]; */ 13.  	char ccc[3]; 14.  #else 15.  	static char ccc[3]; 16.  #endif 17.   18.   	if(c < 040) { 19.  		ccc[0] = '^'; 20.  		ccc[1] = c + 0100; 21.  		ccc[2] = 0; 22.  	} else { 23.  		ccc[0] = c;  24. ccc[1] = 0; 25.  	}  26.   	return(ccc); 27.  }  28.    29.   void 30.  getpos(cc,force,goal) 31.  coord	*cc; 32.  int force; char *goal; 33.  {  34.   	register int cx, cy, i, c;  35. char *sdp = flags.num_pad ? ndir : sdir; 36.  	if(flags.verbose) pline("(For instructions type a ?)"); 37.  	cx = u.ux; 38.  	cy = u.uy; 39.  	curs(cx,cy+2); 40.  	while((c = readchar) != '.'){ 41.  		for(i=0; i<8; i++) if(sdp[i] == c){ 42.  			if(1 <= cx + xdir[i] && cx + xdir[i] <= COLNO) 43.  				cx += xdir[i]; 44.  			if(0 <= cy + ydir[i] && cy + ydir[i] <= ROWNO-1) 45.  				cy += ydir[i]; 46.  			goto nxtc; 47.  		}  48.   		if(c == '?'){ 49.  		    if(flags.verbose) { 50.  			pline("Use [%s] to move the cursor to %s.",  51.   			      flags.num_pad ? "2468" : "hjkl", goal); 52.  			pline("Type a . when you are at the right place."); 53.  		    }  54.   		} else { 55.  			pline("Unknown direction: '%s' (%s).",  56.   				visctrl(c),  57.   				force ?  58.   				    flags.num_pad ? "use 2468 or ." :  59.   						    "use hjkl or ." :  60.   				    "aborted"); 61.  			if(force) goto nxtc; 62.  			cc->x = -1; 63.  			cc->y = 0; 64.  			return; 65.  		}  66.   	nxtc:	; 67.  		curs(cx,cy+2); 68.  	}  69.   	cc->x = cx; 70.  	cc->y = cy; 71.  	return; 72.  }  73.    74.   int 75.  do_mname{ 76.  	char buf[BUFSZ]; 77.  	coord cc; 78.  	register int cx,cy,lth,i; 79.  	register struct monst *mtmp, *mtmp2; 80.  	register char *curr; 81.  	boolean blank; 82.   83.   	getpos(&cc, 0, "the monster you want to name"); 84.  	cx = cc.x;  85. cy = cc.y; 86. if(cx < 0) return(0); 87.  	if (cx == u.ux && cy == u.uy) { 88.  		pline("This %s creature is called %s and cannot be renamed.",  89.   		ACURR(A_CHA) > 14 ?  90.   		(flags.female ? "beautiful" : "handsome") : 91.   		"ugly",  92.   		plname); 93.  		return(0); 94.  	}  95.   	if (!cansee(cx, cy) || !levl[cx][cy].mmask ||  96.   	    (mtmp = m_at(cx, cy))->mimic) { 97.  		pline("I see no monster there."); 98.  		return(0); 99.  	}  100.  	pline("What do you want to call %s? ", lmonnam(mtmp)); 101. 	getlin(buf); 102. 	clrlin; 103. 	if(!*buf || *buf == '\033') return(0); 104.  105.  	/* unnames monster if all spaces */ 106. 	for (curr = buf, blank = 1; *curr; blank = (*curr++ == ' ')); 107. 	if(blank) *buf = '\0'; 108.  109.   	if(type_is_pname(mtmp->data)) { 110.  	    pline("%s doesn't like being called names!", Monnam(mtmp)); 111.  	    if(!mtmp->mtame) { 112.  		pline("%s gets %sangry!", Monnam(mtmp),  113.   		      mtmp->mpeaceful ? "" : "very "); 114.  		mtmp->mpeaceful = mtmp->msleep = 0; 115.  	    }  116.   	    return(0); 117.  	}  118.  	lth = strlen(buf)+1; 119. 	if(lth > 63){ 120. 		buf[62] = 0; 121. 		lth = 63; 122. 	}  123.  	mtmp2 = newmonst(mtmp->mxlth + lth); 124. 	*mtmp2 = *mtmp; 125. 	for(i=0; imxlth; i++) 126. 		((char *) mtmp2->mextra)[i] = ((char *) mtmp->mextra)[i]; 127. 	mtmp2->mnamelth = lth; 128. 	Strcpy(NAME(mtmp2), buf); 129. 	replmon(mtmp,mtmp2); 130. 	return(0); 131. }  132.   133.  /*  134.   * This routine changes the address of  obj. Be careful not to call it 135. * when there might be pointers around in unknown places. For now: only 136.  * when  obj  is in the inventory. 137.  */  138.  static 139. void 140. do_oname(obj) 141. register struct obj *obj; 142. {  143.  	char buf[BUFSZ]; 144. 	register char *curr; 145. 	boolean blank; 146.  147.  	pline("What do you want to name %s? ", doname(obj)); 148. 	getlin(buf); 149. 	clrlin; 150. 	if(!*buf || *buf == '\033')	return; 151.  152.  	/* unnames item if all spaces */ 153. 	for (curr = buf, blank = 1; *curr; blank = (*curr++ == ' ')); 154. 	if(blank) *buf = '\0'; 155.  156.  #ifdef NAMED_ITEMS 157. 	if(is_artifact(obj) || restr_name(obj, buf)) 158. 		pline("Somehow you can't seem to engrave that word."); 159. 	else 160. #endif 161. 		(void)oname(obj, buf, 1); 162. }  163.   164.  struct obj * 165. oname(obj, buf, ininv) 166. register struct obj *obj; 167. char	*buf; 168. register int ininv; 169. {  170.  	register struct obj *otmp, *otmp2; 171. 	register int	lth; 172.  173.  	lth = *buf ? strlen(buf)+1 : 0; 174. 	if(lth > 63){ 175. 		buf[62] = 0; 176. 		lth = 63; 177. 	}  178.  	otmp2 = newobj(lth); 179. 	*otmp2 = *obj; 180. 	otmp2->onamelth = lth; 181. #ifdef __GNUC__ 182. 	/* Without the following line, the program gives anything an empty 183. 	 * name when I try to #name it. Probably a compiler bug, but at the 184. 	 * point where I discovered this, there's no time to check to make 185. 	 * sure. 186. 	 */  187.  	if (buf) (void)donull; 188. #endif 189. 	if(lth) Strcpy(ONAME(otmp2), buf); 190.  191.  	setworn((struct obj *)0, obj->owornmask); 192. 	setworn(otmp2, otmp2->owornmask); 193.  194.  	if (ininv) { 195. 		/* do freeinv(obj); etc. by hand in order to preserve 196. 		   the position of this object in the inventory */ 197. 		if(obj == invent) invent = otmp2; 198. 		else for(otmp = invent; ; otmp = otmp->nobj){ 199. 			if(!otmp) 200. 				panic("oname: cannot find obj."); 201. 			if(otmp->nobj == obj){ 202. 				otmp->nobj = otmp2; 203. 				break; 204. 			}  205.  		}  206.  	}  207.  	/* obfree(obj, otmp2);	/* now unnecessary: no pointers on bill */ 208. 	free((genericptr_t) obj);	/* let us hope nobody else saved a pointer */ 209. 	return otmp2; 210. }  211.   212.  static const char callable[] = { 213. 	SCROLL_SYM, POTION_SYM, WAND_SYM, RING_SYM, AMULET_SYM, GEM_SYM, 214. #ifdef SPELLS 215. 	SPBOOK_SYM, 216. #endif 217. 	ARMOR_SYM, 0 }; 218.  219.  int 220. ddocall 221. {  222.  	register struct obj *obj; 223. #ifdef REDO 224. 	char	ch; 225.  226.  	if (!in_doagain) 227. #endif 228. 		pline("Name an individual object? "); 229. 	switch(  230.  #ifdef REDO  231.  		ch =  232.  #endif  233.  		ynq) { 234. 	case 'q': 235. 		break; 236. 	case 'y': 237. #ifdef REDO 238. 		savech(ch); 239. #endif 240. 		obj = getobj("#", "name"); 241. 		if(obj) do_oname(obj); 242. 		break; 243. 	default: 244. #ifdef REDO 245. 		savech(ch); 246. #endif 247. 		obj = getobj(callable, "call"); 248. 		if(obj) docall(obj); 249. 	}  250.  	return 0; 251. }  252.   253.  void 254. docall(obj) 255. register struct obj *obj; 256. {  257.  	char buf[BUFSZ]; 258. 	struct obj otemp; 259. 	register char **str1; 260. 	register char *str; 261. 	boolean blank; 262.  263.  	otemp = *obj; 264. 	otemp.quan = 1; 265. 	otemp.onamelth = 0; 266. 	if (otemp.corpsenm) { /* kludge, meaning it's sink water */ 267. 		pline("Call a stream of %s fluid: ",  268.  				objects[otemp.otyp].oc_descr); 269. 	} else { 270. 		str = xname(&otemp); 271. 		pline("Call %s %s: ", index(vowels,*str) ? "an" : "a", str); 272. 	}  273.  	getlin(buf); 274. 	clrlin; 275. 	if(!*buf || *buf == '\033') 276. 		return; 277.  278.  	/* clear old name */ 279. 	str1 = &(objects[obj->otyp].oc_uname); 280. 	if(*str1) free(*str1); 281.  282.  	/* uncalls item if all spaces */ 283. 	for (str = buf, blank = 1; *str; blank = (*str++ == ' ')); 284. 	if(blank) *buf = '\0'; 285. 	if (!*buf) { 286. 		*str1 = NULL; 287. 		return; 288. 	}  289.   290.  	str = (char *) alloc((unsigned)strlen(buf)+1); 291. 	Strcpy(str,buf); 292. 	*str1 = str; 293. }  294.   295.  const char *ghostnames[] = { 296. 	/* these names should have length < PL_NSIZ */ 297. 	/* Capitalize the names for aesthetics -dgk */ 298. 	"Adri", "Andries", "Andreas", "Bert", "David", "Dirk", "Emile", 299. 	"Frans", "Fred", "Greg", "Hether", "Jay", "John", "Jon", "Karnov", 300. 	"Kay", "Kenny", "Kevin", "Maud", "Michiel", "Mike", "Peter", "Robert", 301. 	"Ron", "Tom", "Wilmar", "Nick Danger", "Phoenix", "Miracleman", 302. 	"Stephan", "Lance Braccus", "Shadowhawk" 303. };  304.   305.  char * 306. x_monnam(mtmp, vb) 307. register struct monst *mtmp; 308. int vb; 309. {  310.  #ifdef LINT	/* static char buf[BUFSZ]; */ 311. 	char buf[BUFSZ]; 312. #else 313. 	static char buf[BUFSZ]; 314. #endif 315. 	boolean isinvis = (mtmp->minvis && mtmp->data != &mons[PM_STALKER]  316.  				&& mtmp->data != &mons[PM_GHOST]); 317.  318.  	buf[0] = '\0'; 319. #if defined(ALTARS) && defined(THEOLOGY) 320. 	if(mtmp->ispriest) return(priestname(mtmp)); 321. #endif 322. 	if(mtmp->isshk) { 323. 		Strcpy(buf, shkname(mtmp)); 324. 		if (mtmp->data == &mons[PM_SHOPKEEPER] && !mtmp->minvis) 325. 		    return(buf); 326. 		/* For normal shopkeepers, just 'Asidonhopo'. 327. 		 * For unusual ones, 'Asidonhopo the invisible shopkeeper' 328. 		 * or 'Asidonhopo the blue dragon'. 329. 		 */  330.  		Strcat(buf, " "); 331. 	} else if(mtmp->mnamelth && !vb) { 332. 		if(isinvis) { 333. 		    Strcpy(buf, "the invisible "); 334. 		    Strcat(buf, NAME(mtmp)); 335. 		} else 336. 		    Strcpy(buf, NAME(mtmp)); 337. 		return(buf); 338. 	}  339.   340.  	switch(mtmp->data->mlet) { 341. 	    case S_GHOST: 342. 		{ register char *gn = (char *) mtmp->mextra; 343. 		  if(!*gn) {		/* might also look in scorefile */ 344. 		    gn = ghostnames[rn2(SIZE(ghostnames))]; 345. 			Strcpy((char *) mtmp->mextra, !rn2(5) ? plname : gn); 346. 		  }  347.  		  Sprintf(buf, "%s's ghost", gn); 348. 		}  349.  		break; 350. 	    default: 351. 		if (mtmp->minvis) 352. 			Strcat(buf, "the invisible "); 353. 		else if (!type_is_pname(mtmp->data) || Hallucination  354.  				|| mtmp->data == &mons[PM_WIZARD_OF_YENDOR]) 355. 			Strcat(buf, "the "); 356. 		Strcat(buf, Hallucination ? rndmonnam : mtmp->data->mname); 357. 	}  358.  	if(vb && mtmp->mnamelth) { 359. 		Strcat(buf, " called "); 360. 		Strcat(buf, NAME(mtmp)); 361. 	}  362.  	return(buf); 363. }  364.   365.  char * 366. lmonnam(mtmp) 367. register struct monst *mtmp; 368. {  369.  	return(x_monnam(mtmp, 1)); 370. }  371.   372.  char * 373. mon_nam(mtmp) 374. register struct monst *mtmp; 375. {  376.  	return(x_monnam(mtmp, 0)); 377. }  378.   379.  char * 380. Monnam(mtmp) 381. register struct monst *mtmp; 382. {  383.  	register char *bp = mon_nam(mtmp); 384.  385.  	if('a' <= *bp && *bp <= 'z') *bp += ('A' - 'a'); 386. 	return(bp); 387. }  388.   389.  char * 390. a_monnam(mtmp,adj) 391. register struct monst *mtmp; 392. register char *adj; 393. {  394.  	register char *bp = mon_nam(mtmp); 395. #ifdef LINT	/* static char buf[BUFSZ]; */ 396. 	char buf[BUFSZ]; 397. #else 398. 	static char buf[BUFSZ]; 399. #endif 400.  401.  	if(!strncmp(bp, "the ", 4)) bp += 4; 402. 	Sprintf(buf, "the %s %s", adj, bp); 403. 	return(buf); 404. }  405.   406.  char * 407. Amonnam(mtmp, adj) 408. register struct monst *mtmp; 409. register char *adj; 410. {  411.  	register char *bp = a_monnam(mtmp,adj); 412.  413.  	*bp = 'T'; 414. 	return(bp); 415. }  416.   417.  char * 418. Xmonnam(mtmp) 419. register struct monst *mtmp; 420. {  421.  	register char *bp = Monnam(mtmp); 422.  423.  	if(!strncmp(bp, "The ", 4) && !type_is_pname(mtmp->data)) { 424. 		if(index(vowels,*(bp+4))) { 425. 			*((++bp)+1) = 'n'; 426. 		} else 427. 			bp += 2; 428. 		*bp = 'A'; 429. 	}  430.  	return(bp); 431. }  432.   433.  char * 434. defmonnam(mtmp) 435. register struct monst *mtmp; 436. {  437.  	register char *bp = Xmonnam(mtmp); 438.  439.  	if (!strncmp(bp,"A ",2) || !strncmp(bp,"An ",3)) *bp = 'a'; 440. 	return(bp); 441. }  442.   443.  char * 444. rndmonnam {  /* Random name of monster type, if hallucinating */ 445. 	int name; 446.  447.  	do { 448. 		name = rn2(PM_CHAMELEON); 449. 		/* chameleon: last monster before player classes */ 450. 	} while(type_is_pname(&mons[name]) || (mons[name].geno & G_NOGEN)); 451. 	return(mons[name].mname); 452. }  453.   454.  #ifdef REINCARNATION 455. char * 456. roguename /* Name of a Rogue player */ 457. {  458.  	char *i, *opts; 459.  460.  	if(opts = getenv("ROGUEOPTS")) { 461. 		for(i=opts; *i; i++) 462. 			if (!strncmp("name=",i,5)) { 463. 				char *j; 464. 				if (j=index(i+5,',')) 465. 					*j = (char)0; 466. 				return i+5; 467. 			}  468.  	}  469.  	return rn2(3) ? (rn2(2) ? "Michael Toy" : "Kenneth Arnold") 470. 		: "Glenn Wichman"; 471. }  472.  #endif 473.