Source:Hack 1.0/hack.do.c

Below is the full text to hack.do.c from the source code of Hack 1.0. To link to a particular line, write [[Hack 1.0/hack.do.c#line123 ]], for example.

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

1.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ 2.     3.    #include   4.    #include   5.    #include "hack.h"  6.    #include "def.func_tab.h"  7. 8.   extern char *getenv,*parse,*getlogin,*lowc,*unctrl; 9.   extern int float_down; 10.  extern char *nomovemsg, *catmore; 11.  extern struct obj *splitobj, *addinv; 12.  extern boolean hmon; 13.   14.   /*	Routines to do various user commands */ 15.   16.   int done1; 17.   18.   dodrink { 19.  	register struct obj *otmp,*objs; 20.  	register struct monst *mtmp; 21.  	register int unkn = 0, nothing = 0; 22.   23.   	otmp = getobj("!", "drink"); 24.  	if(!otmp) return(0); 25.  	switch(otmp->otyp){ 26.  	case POT_RESTORE_STRENGTH: 27.  		unkn++; 28.  		pline("Wow!  This makes you feel great!"); 29.  		if(u.ustr < u.ustrmax) { 30.  			u.ustr = u.ustrmax; 31.  			flags.botl = 1; 32.  		}  33.   		break; 34.  	case POT_BOOZE: 35.  		unkn++; 36.  		pline("Ooph!  This tastes like liquid fire!"); 37.  		Confusion += d(3,8); 38.  		/* the whiskey makes us feel better */ 39.  		if(u.uhp < u.uhpmax) losehp(-1, "bottle of whiskey"); 40.  		if(!rn2(4)) { 41.  			pline("You pass out."); 42.  			multi = -rnd(15); 43.  			nomovemsg = "You awake with a headache."; 44.  		}  45.   		break; 46.  	case POT_INVISIBILITY: 47.  		if(Invis) 48.  		  nothing++; 49.  		else { 50.  		  if(!Blind) 51.  		    pline("Gee!  All of a sudden, you can't see yourself."); 52.  		  else 53.  		    pline("You feel rather airy."), unkn++; 54.  		  newsym(u.ux,u.uy); 55.  		}  56.   		Invis += rn1(15,31); 57.  		break; 58.  	case POT_FRUIT_JUICE: 59.  		pline("This tastes like fruit juice."); 60.  		lesshungry(20); 61.  		break; 62.  	case POT_HEALING: 63.  		pline("You begin to feel better."); 64.  		flags.botl = 1; 65.  		u.uhp += rnd(10); 66.  		if(u.uhp > u.uhpmax) 67.  			u.uhp = ++u.uhpmax; 68.  		if(Blind) Blind = 1;	/* see on next move */ 69.  		if(Sick) Sick = 0; 70.  		break; 71.  	case POT_PARALYSIS: 72.  		pline("Your feet are frozen to the floor!"); 73.  		nomul(-(rn1(10,25))); 74.  		break; 75.  	case POT_MONSTER_DETECTION: 76.  		if(!fmon) { 77.  			strange_feeling(otmp); 78.  			return(1); 79.  		} else { 80.  			cls; 81.  			for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 82.  				if(mtmp->mx > 0) 83.  				at(mtmp->mx,mtmp->my,mtmp->data->mlet); 84.  			prme; 85.  			pline("You sense the presence of monsters."); 86.  			more; 87.  			docrt; 88.  		}  89.   		break; 90.  	case POT_OBJECT_DETECTION: 91.  		if(!fobj) { 92.  			strange_feeling(otmp); 93.  			return(1); 94.  		} else { 95.  		    for(objs = fobj; objs; objs = objs->nobj) 96.  			if(objs->ox != u.ux || objs->oy != u.uy) 97.  				goto outobjmap; 98.  		    pline("You sense the presence of objects close nearby."); 99.  		    break; 100. 		outobjmap: 101. 			cls; 102. 			for(objs = fobj; objs; objs = objs->nobj) 103. 				at(objs->ox,objs->oy,objs->olet); 104. 			prme; 105. 			pline("You sense the presence of objects."); 106. 			more; 107. 			docrt; 108. 		}  109.  		break; 110. 	case POT_SICKNESS: 111. 		pline("Yech! This stuff tastes like poison."); 112. 		if(Poison_resistance) 113.     pline("(But in fact it was biologically contaminated orange juice.)"); 114. 		losestr(rn1(4,3)); 115. 		losehp(rnd(10), "poison potion"); 116. 		break; 117. 	case POT_CONFUSION: 118. 		if(!Confusion) 119. 			pline("Huh, What?  Where am I?"); 120. 		else 121. 			nothing++; 122. 		Confusion += rn1(7,16); 123. 		break; 124. 	case POT_GAIN_STRENGTH: 125. 		pline("Wow do you feel strong!"); 126. 		if(u.ustr == 118) break; 127. 		if(u.ustr > 17) u.ustr += rnd(118-u.ustr); 128. 		else u.ustr++; 129. 		if(u.ustr > u.ustrmax) u.ustrmax = u.ustr; 130. 		flags.botl = 1; 131. 		break; 132. 	case POT_SPEED: 133. 		if(Wounded_legs) { 134. 			if((Wounded_legs & BOTH_SIDES) == BOTH_SIDES) 135. 				pline("Your legs feel somewhat better."); 136. 			else 137. 				pline("Your leg feels somewhat better."); 138. 			Wounded_legs = 0; 139. 			unkn++; 140. 			break; 141. 		}  142.  		if(!(Fast & ~INTRINSIC)) 143. 			pline("You are suddenly moving much faster."); 144. 		else 145. 			pline("Your legs get new energy."), unkn++; 146. 		Fast += rn1(10,100); 147. 		break; 148. 	case POT_BLINDNESS: 149. 		if(!Blind) 150. 			pline("A cloud of darkness falls upon you."); 151. 		else 152. 			nothing++; 153. 		Blind += rn1(100,250); 154. 		seeoff(0); 155. 		break; 156. 	case POT_GAIN_LEVEL: 157. 		pluslvl; 158. 		break; 159. 	case POT_EXTRA_HEALING: 160. 		pline("You feel much better."); 161. 		flags.botl = 1; 162. 		u.uhp += d(2,20)+1; 163. 		if(u.uhp > u.uhpmax) 164. 			u.uhp = (u.uhpmax += 2); 165. 		if(Blind) Blind = 1; 166. 		if(Sick) Sick = 0; 167. 		break; 168. 	case POT_LEVITATION: 169. 		if(!Levitation) 170. 			float_up; 171. 		else 172. 			nothing++; 173. 		Levitation += rnd(100); 174. 		u.uprops[PROP(RIN_LEVITATION)].p_tofn = float_down; 175. 		break; 176. 	default: 177. 		pline("What a funny potion! (%d)", otmp->otyp); 178. 		impossible; 179. 		return(0); 180. 	}  181.  	if(nothing) { 182. 	    unkn++; 183. 	    pline("You have a peculiar feeling for a moment, then it passes."); 184. 	}  185.  	if(otmp->dknown && !objects[otmp->otyp].oc_name_known) { 186. 		if(!unkn) { 187. 			objects[otmp->otyp].oc_name_known = 1; 188. 			u.urexp += 10; 189. 		} else if(!objects[otmp->otyp].oc_uname) 190.  docall(otmp); 191. 	}  192.  	useup(otmp); 193. 	return(1); 194. }  195.   196.  pluslvl 197. {  198.  	register num; 199.  200.  	pline("You feel more experienced."); 201. 	num = rnd(10); 202. 	u.uhpmax += num; 203. 	u.uhp += num; 204. 	u.uexp = (10*pow(u.ulevel-1))+1; 205. 	pline("Welcome to level %d.", ++u.ulevel); 206. 	flags.botl = 1; 207. }  208.   209.  strange_feeling(obj) 210. register struct obj *obj; 211. {  212.  	pline("You have a strange feeling for a moment, then it passes."); 213. 	if(!objects[obj->otyp].oc_name_known && !objects[obj->otyp].oc_uname) 214. 		docall(obj); 215. 	useup(obj); 216. }  217.   218.  dodrop { 219. 	register struct obj *obj; 220.  221.  	obj = getobj("0$#", "drop"); 222. 	if(!obj) return(0); 223. 	if(obj->olet == '$') { 224. 		if(obj->quan == 0) 225. 			pline("You didn't drop any gold pieces."); 226. 		else { 227. 			mkgold((int) obj->quan, u.ux, u.uy); 228. 			pline("You dropped %u gold piece%s.",  229.  				obj->quan, plur(obj->quan)); 230. 			if(Invis) newsym(u.ux, u.uy); 231. 		}  232.  		free((char *) obj); 233. 		return(1); 234. 	}  235.   return(drop(obj)); 236. }  237.   238.  drop(obj) register struct obj *obj; { 239. 	if(obj->owornmask & (W_ARMOR | W_RING)){ 240. 		pline("You cannot drop something you are wearing."); 241. 		return(0); 242. 	}  243.  	if(obj == uwep) { 244. 		if(uwep->cursed) { 245. 			pline("Your weapon is welded to your hand!"); 246. 			return(0); 247. 		}  248.   setuwep((struct obj *) 0); 249. 	}  250.  	pline("You dropped %s.", doname(obj)); 251. 	dropx(obj); 252. 	return(1); 253. }  254.   255.  dropx(obj) register struct obj *obj; { 256. 	if(obj->otyp == CRYSKNIFE) 257. 		obj->otyp = WORM_TOOTH; 258. 	freeinv(obj); 259. 	obj->ox = u.ux; 260. 	obj->oy = u.uy; 261. 	obj->nobj = fobj; 262. 	fobj = obj; 263. 	if(Invis) newsym(u.ux,u.uy); 264. 	subfrombill(obj); 265. 	stackobj(obj); 266. }  267.   268.  /* drop several things */ 269. doddrop { 270. 	return(ggetobj("drop", drop, 0)); 271. }  272.   273.  rhack(cmd) 274. register char *cmd; 275. {  276.  	register struct func_tab *tlist = list; 277. 	boolean firsttime = FALSE; 278. 	register res; 279.  280.  	if(!cmd) { 281. 		firsttime = TRUE; 282. 		flags.nopick = 0; 283. 		cmd = parse; 284. 	}  285.  	if(!*cmd || *cmd == 0377) 286. 		return;		/* probably we just had an interrupt */ 287. 	if(movecm(cmd)) { 288. 	walk: 289. 		if(multi) flags.mv = 1; 290. 		domove; 291. 		return; 292. 	}  293.  	if(movecm(lowc(cmd))) { 294. 		flags.run = 1; 295. 	rush: 296. 		if(firsttime){ 297. 			if(!multi) multi = COLNO; 298. 			u.last_str_turn = 0; 299. 		}  300.  		flags.mv = 1; 301. #ifdef QUEST 302. 		if(flags.run >= 4) finddir; 303. 		if(firsttime){ 304. 			u.ux0 = u.ux + u.dx; 305. 			u.uy0 = u.uy + u.dy; 306. 		}  307.  #endif QUEST 308. 		domove; 309. 		return; 310. 	}  311.  	if((*cmd == 'f' && movecm(cmd+1)) ||  312.  		movecm(unctrl(cmd))) { 313. 		flags.run = 2; 314. 		goto rush; 315. 	}  316.  	if(*cmd == 'F' && movecm(lowc(cmd+1))) { 317. 		flags.run = 3; 318. 		goto rush; 319. 	}  320.  	if(*cmd == 'm' && movecm(cmd+1)) { 321. 		flags.run = 0; 322. 		flags.nopick = 1; 323. 		goto walk; 324. 	}  325.  	if(*cmd == 'M' && movecm(lowc(cmd+1))) { 326. 		flags.run = 1; 327. 		flags.nopick = 1; 328. 		goto rush; 329. 	}  330.  #ifdef QUEST 331. 	if(*cmd == cmd[1] && (*cmd == 'f' || *cmd == 'F')) { 332. 		flags.run = 4; 333. 		if(*cmd == 'F') flags.run += 2; 334. 		if(cmd[2] == '-') flags.run += 1; 335. 		goto rush; 336. 	}  337.  #endif QUEST 338. 	while(tlist->f_char) { 339. 		if(*cmd == tlist->f_char){ 340. 			res = (*(tlist->f_funct))(0); 341. 			if(!res) { 342. 				flags.move = 0; 343. 				multi = 0; 344. 			}  345.   return; 346. 		}  347.   tlist++; 348. 	}  349.  	pline("Unknown command '%s'",cmd); 350. 	multi = flags.move = 0; 351. }  352.   353.  doredraw 354. {  355.  	docrt; 356. 	return(0); 357. }  358.   359.  dohelp 360. {  361.  	if(child(1)){ 362. 		execl(catmore,"more","help",(char *)0); 363. 		exit(1); 364. 	}  365.   return(0); 366. }  367.   368.  #ifdef SHELL 369. dosh{ 370. register char *str; 371. 	if(child(0)) { 372. 		(void) chdir(getenv("HOME")); 373. 		if(str = getenv("SHELL")) execl(str,str,(char *) 0); 374. 		if(strcmp("player", getlogin)) 375. 			execl("/bin/sh","sh",(char *) 0); 376. 		pline("sh: cannot execute."); 377. 		exit(1); 378. 	}  379.   return(0); 380. }  381.  #endif SHELL 382.  383.  #ifdef BSD 384. #include	  385. #else 386. #include	  387. #endif BSD 388.  389.  child(wt) { 390. register int f = fork; 391. 	if(f == 0){		/* child */ 392. 		settty((char *) 0); 393. 		(void) setuid(getuid); 394. 		return(1); 395. 	}  396.  	if(f == -1) {	/* cannot fork */ 397. 		pline("Fork failed. Try again."); 398. 		return(0); 399. 	}  400.  	/* fork succeeded; wait for child to exit */ 401. 	(void) signal(SIGINT,SIG_IGN); 402. 	(void) signal(SIGQUIT,SIG_IGN); 403. 	(void) wait((union wait *) 0); 404. 	setctty; 405. 	(void) signal(SIGINT,done1); 406. #ifdef WIZARD 407. 	if(wizard) (void) signal(SIGQUIT,SIG_DFL); 408. #endif WIZARD 409. 	if(wt) getret; 410. 	docrt; 411. 	return(0); 412. }  413.   414.  dodown 415. {  416.  	if(u.ux != xdnstair || u.uy != ydnstair) { 417. 		pline("You can't go down here."); 418. 		return(0); 419. 	}  420.  	if(u.ustuck) { 421. 		pline("You are being held, and cannot go down."); 422. 		return(1); 423. 	}  424.  	if(Levitation) { 425. 		pline("You're floating high above the stairs."); 426. 		return(0); 427. 	}  428.   429.  	goto_level(dlevel+1, TRUE); 430. 	return(1); 431. }  432.   433.  doup 434. {  435.  	if(u.ux != xupstair || u.uy != yupstair) { 436. 		pline("You can't go up here."); 437. 		return(0); 438. 	}  439.  	if(u.ustuck) { 440. 		pline("You are being held, and cannot go up."); 441. 		return(1); 442. 	}  443.  	if(inv_weight + 5 > 0) { 444. 		pline("Your load is too heavy to climb the stairs."); 445. 		return(1); 446. 	}  447.   448.  	goto_level(dlevel-1, TRUE); 449. 	return(1); 450. }  451.   452.  goto_level(newlevel, at_stairs) 453. register int newlevel; 454. register boolean at_stairs; 455. {  456.  	register fd; 457. 	register boolean up = (newlevel < dlevel); 458.  459.  	if(newlevel <= 0) done("escaped");	/* in fact < 0 is impossible */ 460. 	if(newlevel == dlevel) return;		/* this cannot happen either */ 461.  462.  	glo(dlevel); 463. 	fd = creat(lock,FMASK); 464. 	if(fd < 0) { 465. 		/*  466.  		 * This is not quite impossible: e.g., we may have 467. 		 * exceeded our quota. If that is the case then we 468. * cannot leave this level, and cannot save either. 469. 		 */  470.  		pline("A mysterious force prevents you from going %d.",  471.  			up ? "up" : "down"); 472. 		return; 473. 	}  474.   475.  	if(Punished) unplacebc; 476. 	keepdogs; 477. 	seeoff(1); 478. 	flags.nscrinh = 1; 479. 	u.ux = FAR;				/* hack */ 480. 	(void) inshop;			/* probably was a trapdoor */ 481.  482.  	savelev(fd); 483. 	(void) close(fd); 484.  485.  	dlevel = newlevel; 486. 	if(maxdlevel < dlevel) 487. 		maxdlevel = dlevel; 488. 	glo(dlevel); 489. 	if((fd = open(lock,0)) < 0) 490. 		mklev; 491. 	else { 492. 		(void) getlev(fd); 493. 		(void) close(fd); 494. 	}  495.   496.  	if(at_stairs) { 497. 	    if(up) { 498. 		u.ux = xdnstair; 499. 		u.uy = ydnstair; 500. 		if(!u.ux) {		/* entering a maze from below? */ 501.  		    u.ux = xupstair;	/* this will confuse the player! */ 502.  		    u.uy = yupstair; 503. 		}  504.  		if(Punished){ 505. 			pline("With great effort you climb the stairs"); 506. 			placebc(1); 507. 		}  508.  	    } else { 509. 		u.ux = xupstair; 510. 		u.uy = yupstair; 511. 		if(inv_weight + 5 > 0 || Punished){ 512. 			pline("You fall down the stairs."); 513. 			losehp(rnd(3), "fall"); 514. 			if(Punished) { 515. 			    if(uwep != uball && rn2(3)){ 516. 				pline("... and are hit by the iron ball"); 517. 				losehp(rnd(20), "iron ball"); 518. 			    }  519.  			    placebc(1); 520. 			}  521.   selftouch("Falling, you"); 522. 		}  523.    }  524.  	} else {	/* trapdoor or level_tele */ 525. 	    do { 526. 		u.ux = rnd(COLNO-1); 527. 		u.uy = rn2(ROWNO); 528. 	    } while(levl[u.ux][u.uy].typ != ROOM ||  529.  			m_at(u.ux,u.uy)); 530. 	    if(Punished){ 531. 		if(uwep != uball && !up /* %% */ && rn2(5)){ 532. 			pline("The iron ball falls on your head."); 533. 			losehp(rnd(25), "iron ball"); 534. 		}  535.  		placebc(1); 536. 	    }  537.  	    selftouch("Falling, you"); 538. 	}  539.  	(void) inshop; 540. #ifdef TRACK 541. 	initrack; 542. #endif TRACK 543.  544.  	losedogs; 545. 	flags.nscrinh = 0; 546. 	setsee; 547. 	docrt; 548. 	pickup; 549. 	read_engr_at(u.ux,u.uy); 550. }  551.   552.  donull { 553. 	return(1);	/* Do nothing, but let other things happen */ 554. }  555.   556.  struct monst *bhit, *boomhit; 557. dothrow 558. {  559.  	register struct obj *obj; 560. 	register struct monst *mon; 561. 	register tmp; 562.  563.  	obj = getobj("#)", "throw");	/* it is also possible to throw food */  564.  					/* (or jewels, or iron balls ... ) */ 565.  	if(!obj || !getdir)  566.  		return(0);  567.  	if(obj->owornmask & (W_ARMOR | W_RING)){  568.  		pline("You can't throw something you are wearing");  569.  		return(0);  570.  	}  571.  	if(obj == uwep){  572.  		if(obj->cursed){  573.  			pline("Your weapon is welded to your hand");  574.  			return(1);  575.  		}  576.  		if(obj->quan > 1)  577.  			setuwep(splitobj(obj, 1));  578.  		else  579.  			setuwep((struct obj *) 0);  580.  	}  581.  	else if(obj->quan > 1)  582.  		(void) splitobj(obj, 1);  583.  	freeinv(obj);  584.  	if(u.uswallow) {  585.  		mon = u.ustuck;  586.  		bhitpos.x = mon->mx;  587.  		bhitpos.y = mon->my;  588.  	} else if(obj->otyp == BOOMERANG) {  589.  		mon = boomhit(u.dx,u.dy);  590.  		/* boomhit delivers -1 if the thing was caught */  591.  		if((int) mon == -1) {  592.  			(void) addinv(obj);  593.  			return(1);  594.  		}  595.  	} else 596. 		mon = bhit(u.dx,u.dy,  597.  			(!Punished || obj != uball) ? 8 :  598.  				!u.ustuck ? 5 : 1,  599.  			obj->olet); 600. 	if(mon) { 601. 		/* awake monster if sleeping */ 602. 		wakeup(mon); 603.  604.  		if(obj->olet == WEAPON_SYM) { 605. 			tmp = -1+u.ulevel+mon->data->ac+abon; 606. 			if(obj->otyp < ROCK) { 607. 				if(!uwep ||  608.  				    uwep->otyp != obj->otyp+(BOW-ARROW)) 609. 					tmp -= 4; 610. 				else { 611. 					tmp += uwep->spe; 612. 				}  613.  			} else 614. 			if(obj->otyp == BOOMERANG) tmp += 4; 615. 			tmp += obj->spe; 616. 			if(u.uswallow || tmp >= rnd(20)) { 617. 				if(hmon(mon,obj,1) == TRUE){ 618. 				  /* mon still alive */ 619. #ifndef NOWORM 620. 				  cutworm(mon,bhitpos.x,bhitpos.y,obj->otyp); 621. #endif NOWORM 622. 				} else mon = 0; 623. 				/* weapons thrown disappear sometimes */ 624. 				if(obj->otyp < BOOMERANG && rn2(3)) { 625. 					/* check bill; free */ 626. 					obfree(obj, (struct obj *) 0); 627. 					return(1); 628. 				}  629.  			} else miss(objects[obj->otyp].oc_name, mon); 630. 		} else if(obj->otyp == HEAVY_IRON_BALL) { 631. 			tmp = -1+u.ulevel+mon->data->ac+abon; 632. 			if(!Punished || obj != uball) tmp += 2; 633. 			if(u.utrap) tmp -= 2; 634. 			if(u.uswallow || tmp >= rnd(20)) { 635. 				if(hmon(mon,obj,1) == FALSE) 636. 					mon = 0;	/* he died */ 637. 			} else miss("iron ball", mon); 638. 		} else { 639. 			if(cansee(bhitpos.x,bhitpos.y)) 640. 				pline("You miss %s.",monnam(mon)); 641. 			else pline("You miss it."); 642. 			if(obj->olet == FOOD_SYM && mon->data->mlet == 'd') 643. 				if(tamedog(mon,obj)) return(1); 644. 			if(obj->olet == GEM_SYM && mon->data->mlet == 'u'){ 645. 			 if(obj->dknown && objects[obj->otyp].oc_name_known){ 646. 			  if(objects[obj->otyp].g_val > 0){ 647. 			    u.uluck += 5; 648. 			    goto valuable; 649. 			  } else { 650. 			    pline("%s is not interested in your junk.",  651.  				Monnam(mon)); 652. 			  }  653.  			 } else { /* value unknown to @ */ 654. 			    u.uluck++; 655. 			valuable: 656. 			    pline("%s graciously accepts your gift.",  657.  				Monnam(mon)); 658. 			    mpickobj(mon, obj); 659. 			    rloc(mon); 660. 			    return(1); 661. 			 }  662.  			}  663.  		}  664.  	}  665.  	obj->ox = bhitpos.x;  666. obj->oy = bhitpos.y; 667. obj->nobj = fobj; 668. 	fobj = obj; 669. 	/* prevent him from throwing articles to the exit and escaping */ 670. 	/* subfrombill(obj); */ 671. 	stackobj(obj); 672. 	if(Punished && obj == uball &&  673.  		(bhitpos.x != u.ux || bhitpos.y != u.uy)){ 674. 		freeobj(uchain); 675. 		unpobj(uchain); 676. 		if(u.utrap){ 677. 			if(u.utraptype == TT_PIT) 678. 				pline("The ball pulls you out of the pit!"); 679. 			else { 680. 			    register int side = 681. 				rn2(3) ? LEFT_SIDE : RIGHT_SIDE; 682. 			    pline("The ball pulls you out of the bear trap."); 683. 			    pline("Your %s leg is severely damaged.",  684.  				(side == LEFT_SIDE) ? "left" : "right"); 685. 			    Wounded_legs |= side + rnd(1000); 686. 			    losehp(2, "thrown ball"); 687. 			}  688.  			u.utrap = 0; 689. 		}  690.  		unsee; 691. 		uchain->nobj = fobj; 692. 		fobj = uchain; 693. 		u.ux = uchain->ox = bhitpos.x - u.dx; 694. 		u.uy = uchain->oy = bhitpos.y - u.dy; 695. 		setsee; 696. 		(void) inshop; 697. 	}  698.  	if(cansee(bhitpos.x, bhitpos.y)) prl(bhitpos.x,bhitpos.y); 699. 	return(1); 700. }  701.   702.  getdir 703. {  704.  char buf[2]; 705. 	pline("What direction?"); 706. 	buf[0] = readchar; 707. 	buf[1] = 0; 708. 	return(movecm(buf)); 709. }  710.   711.  /* split obj so that it gets size num */ 712. /* remainder is put in the object structure delivered by this call */ 713. struct obj * 714. splitobj(obj, num) register struct obj *obj; register int num; { 715. register struct obj *otmp; 716. 	otmp = newobj(0); 717. 	*otmp = *obj;		/* copies whole structure */ 718. 	otmp->o_id = flags.ident++; 719. 	otmp->onamelth = 0; 720. 	obj->quan = num; 721. 	obj->owt = weight(obj); 722. 	otmp->quan -= num; 723. 	otmp->owt = weight(otmp);	/* -= obj->owt ? */ 724.  	obj->nobj = otmp; 725. 	if(obj->unpaid) splitbill(obj,otmp); 726. 	return(otmp); 727. }  728.   729.  char * 730. lowc(str) 731. register char *str; 732. {  733.  	static char buf[2]; 734.  735.  	if(*str >= 'A' && *str <= 'Z') *buf = *str+'a'-'A'; 736. 	else *buf = *str; 737. 	buf[1] = 0; 738. 	return(buf); 739. }  740.   741.  char * 742. unctrl(str) 743. register char *str; 744. {  745.  	static char buf[2]; 746. 	if(*str >= ('A' & 037) && *str <= ('Z' & 037)) 747. 		*buf = *str + 0140; 748. 	else *buf = *str; 749. 	buf[1] = 0; 750. 	return(buf); 751. }