Source:NetHack 2.2a/do.c

Below is the full text to do.c from the source code of NetHack 2.2a. To link to a particular line, write [[NetHack 2.2a/do.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.c	2.0	87/09/15 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.     4.    /* Contains code for 'd', 'D' (drop), '>', '<' (up, down) and 't' (throw) */ 5.    6.    #include "hack.h"  7. 8.   extern struct obj *splitobj, *addinv; 9.   extern boolean hmon; 10.  extern boolean level_exists[]; 11.  extern struct monst youmonst; 12.  extern char *Doname; 13.  extern char *nomovemsg; 14.  int	identify; 15.  #ifdef KAA 16.  extern char *xname; 17.  #endif 18.   19.   dodrop { 20.  	if(u.ugold)	return(drop(getobj("0$#", "drop"))); 21.  	else		return(drop(getobj("0#", "drop"))); 22.  }  23.    24.   static 25.  drop(obj) register struct obj *obj; { 26.  	if(!obj) return(0); 27.  	if(obj->olet == GOLD_SYM) {		/* pseudo object */ 28.  		register long amount = OGOLD(obj); 29.   30.   		if(amount == 0) 31.  			pline("You didn't drop any gold pieces."); 32.  /* Fix bug with dropping huge amounts of gold read as negative    KAA */ 33.  		else if(amount < 0) { 34.  			u.ugold += amount; 35.  	pline("The LRS would be very interested to know you have that much."); 36.  		} else { 37.  			/* uswallow test added by GAN 01/29/87 */ 38.  			pline("You dropped %ld gold piece%s.",  39.   				 amount, plur(amount)); 40.  			if(u.uswallow) 41.  				(u.ustuck)->mgold += amount; 42.  			else { 43.  				mkgold(amount, u.ux, u.uy); 44.  				if(Invisible) newsym(u.ux, u.uy); 45.  			}  46.   		}  47.   		free((char *) obj); 48.  		return(1); 49.  	}  50.   	if(obj->owornmask & (W_ARMOR | W_RING)){ 51.  		pline("You cannot drop something you are wearing."); 52.  		return(0); 53.  	}  54.   	if(obj == uwep) { 55.  		if(uwep->cursed) { 56.  			pline("Your weapon is welded to your hand!"); 57.  			return(0); 58.  		}  59.   		setuwep((struct obj *) 0); 60.  	}  61.   #ifdef WALKIES 62.          if (obj->otyp == LEASH) { 63.              register struct monst *mtmp = fmon; 64.              while (mtmp && !mtmp->mleashed) mtmp = mtmp->nmon; 65.              if (mtmp) { 66.                  pline ("Your leash is tied around your hand."); 67.                  return (0); 68.              }  69.           }  70.   #endif 71.  	pline("You dropped %s.", doname(obj)); 72.  	dropx(obj); 73.  	return(1); 74.  }  75.    76.   /* Called in several places - should not produce texts */ 77.  dropx(obj) 78.  register struct obj *obj; 79.  {  80.   	freeinv(obj); 81.  	dropy(obj); 82.  }  83.    84.   dropy(obj) 85.  register struct obj *obj; 86.  {  87.   	if(obj->otyp == CRYSKNIFE) 88.  		obj->otyp = WORM_TOOTH; 89.  	/* uswallow check done by GAN 01/29/87 */ 90.  	if(u.uswallow) 91.  		mpickobj(u.ustuck,obj); 92.  	else  { 93.  		obj->ox = u.ux; 94.  		obj->oy = u.uy; 95.  		/* Blind check added by GAN 02/18/87 */ 96.  		if(Blind)  { 97.  #ifdef KAA 98.  			if(obj->olet != ')')  99.   #endif  100.  			    obj->dknown = index("/=!?*",obj->olet) ? 0 : 1;  101.  			obj->known = 0;  102.  		}  103.  		obj->nobj = fobj;  104.  		fobj = obj;  105.  		if(Invisible) newsym(u.ux,u.uy);  106.  		subfrombill(obj);  107.  		stackobj(obj);  108.  	}  109.  }  110.   111.  /* drop several things */  112.  doddrop {  113.  	return(ggetobj("drop", drop, 0));  114.  }  115.   116.  dodown  117.  {  118.  	if(u.ux != xdnstair || u.uy != ydnstair) {  119.  		pline("You can't go down here.");  120.  		return(0);  121.  	}  122.  	if(u.ustuck) {  123.  		pline("You are being held, and cannot go down.");  124.  		return(1);  125.  	}  126.  	if(Levitation) {  127.  		pline("Your floating high above the stairs.");  128.  		return(0);  129.  	}  130.   131.  	goto_level(dlevel+1, TRUE);  132.  	return(1);  133.  }  134.   135.  doup  136.  {  137.  	if(u.ux != xupstair || u.uy != yupstair) { 138. 		pline("You can't go up here."); 139. 		return(0); 140. 	}  141.  	if(u.ustuck) { 142. 		pline("You are being held, and cannot go up."); 143. 		return(1); 144. 	}  145.  	if(!Levitation && inv_weight + 5 > 0) { 146. 		pline("Your load is too heavy to climb the stairs."); 147. 		return(1); 148. 	}  149.   150.  	goto_level(dlevel-1, TRUE); 151. 	return(1); 152. }  153.   154.  goto_level(newlevel, at_stairs) 155. register int newlevel; 156. register boolean at_stairs; 157. {  158.  	register fd; 159. 	register boolean up = (newlevel < dlevel); 160.  161.  	if(newlevel <= 0) done("escaped");    /* in fact < 0 is impossible */ 162. 	if(newlevel > MAXLEVEL) newlevel = MAXLEVEL;	/* strange ... */ 163.  	if(newlevel == dlevel) return;	      /* this can happen */ 164.  165.  	glo(dlevel); 166. #ifdef DGK 167. 	/* Use O_TRUNC to force the file to be shortened if it already 168. 	 * exists and is currently longer. 169. 	 */  170.  	fd = open(lock, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FMASK); 171. #else 172. 	fd = creat(lock, FMASK); 173. #endif 174. 	if(fd < 0) { 175. 		/*  176.  		 * This is not quite impossible: e.g., we may have 177. 		 * exceeded our quota. If that is the case then we 178. * cannot leave this level, and cannot save either. 179. 		 * Another possibility is that the directory was not 180. 		 * writable. 181. 		 */  182.  #ifdef DGK 183. 		pline("Cannot create level file '%s'.", lock); 184. #else 185. 		pline("A mysterious force prevents you from going %s.",  186.  			up ? "up" : "down"); 187. #endif 188. 		return; 189. 	}  190.   191.  #ifdef DGK 192. 	if (!savelev(fd, dlevel, COUNT)) { 193. 		(void) close(fd); 194. 		(void) unlink(lock); 195. 		pline("HACK is out of disk space for making levels!"); 196. 		pline("You can save, quit, or continue playing."); 197. 		return; 198. 	}  199.  #endif 200. 	if(Punished) unplacebc; 201. 	u.utrap = 0;				/* needed in level_tele */ 202. 	u.ustuck = 0;				/* idem */ 203. 	keepdogs; 204. 	seeoff(1); 205. 	if(u.uswallow)				/* idem */ 206. 		u.uswldtim = u.uswallow = 0; 207. 	flags.nscrinh = 1; 208. 	u.ux = FAR;				/* hack */ 209. 	(void) inshop;			/* probably was a trapdoor */ 210.  211.  #ifdef DGK 212. 	savelev(fd,dlevel, WRITE); 213. #else 214. 	savelev(fd,dlevel); 215. #endif 216. 	(void) close(fd); 217.  218.  	dlevel = newlevel; 219. 	if(maxdlevel < dlevel) 220. 		maxdlevel = dlevel; 221. 	glo(dlevel); 222. #ifdef MSDOS 223. 	/* If the level has no where yet, it hasn't been made 224. 	 */  225.  	if(!fileinfo[dlevel].where) 226. #else 227. 	if(!level_exists[dlevel]) 228. #endif 229. 		mklev; 230. 	else { 231. 		extern int hackpid; 232. #ifdef DGK 233. 		/* If not currently accessible, swap it in. 234. 		 */  235.  		if (fileinfo[dlevel].where != ACTIVE) 236. 			swapin_file(dlevel); 237.  238.  		if((fd = open(lock, O_RDONLY | O_BINARY)) < 0) { 239. #else 240. 		if((fd = open(lock,0)) < 0) { 241. #endif 242. 			pline("Cannot open %s .", lock); 243. 			pline("Probably someone removed it."); 244. 			done("tricked"); 245. 		}  246.  		getlev(fd, hackpid, dlevel); 247. 		(void) close(fd); 248. 	}  249.   250.  	if(at_stairs) { 251. 	    if(up) { 252. 		u.ux = xdnstair; 253. 		u.uy = ydnstair; 254. 		if(!u.ux) {		/* entering a maze from below? */ 255.  		    u.ux = xupstair;	/* this will confuse the player! */ 256.  		    u.uy = yupstair; 257. 		}  258.  /* Remove bug which crashes with levitation/punishment  KAA */ 259. 		if(Punished) { 260. 		    if(!Levitation) 261. 			pline("With great effort you climb the stairs."); 262. 		    placebc(1); 263. 		}  264.  	    } else { 265. 		u.ux = xupstair; 266. 		u.uy = yupstair; 267. 		if(inv_weight + 5 > 0 || Punished){ 268. 			pline("You fall down the stairs.");	/* %% */ 269. 			losehp(rnd(3), "fall"); 270. 			if(Punished) { 271. 			    if(uwep != uball && rn2(3)){ 272. 				pline("... and are hit by the iron ball."); 273. 				losehp(rnd(20), "iron ball"); 274. 			    }  275.  			    placebc(1); 276. 			}  277.  			selftouch("Falling, you"); 278. 		}  279.  	    }  280.  	    { register struct monst *mtmp = m_at(u.ux, u.uy); 281. 	      if(mtmp) 282. 		mnexto(mtmp); 283. 	    }  284.  	} else {	/* trapdoor or level_tele */ 285. 	    do { 286. 		u.ux = rnd(COLNO-1); 287. 		u.uy = rn2(ROWNO); 288. 	    } while(levl[u.ux][u.uy].typ != ROOM ||  289.  			m_at(u.ux,u.uy)); 290. 	    if(Punished){ 291. 		if(uwep != uball && !up /* %% */ && rn2(5)){ 292. 			pline("The iron ball falls on your head."); 293. 			losehp(rnd(25), "iron ball"); 294. 		}  295.  		placebc(1); 296. 	    }  297.  	    selftouch("Falling, you"); 298. 	}  299.  	(void) inshop; 300. 	initrack; 301.  302.  	losedogs; 303. 	{ register struct monst *mtmp; 304. 	  if(mtmp = m_at(u.ux, u.uy)) mnexto(mtmp);	/* riv05!a3 */ 305. 	}  306.  	flags.nscrinh = 0; 307. 	setsee; 308. 	seeobjs;	/* make old cadavers disappear - riv05!a3 */ 309. 	docrt; 310. 	pickup(1); 311. 	read_engr_at(u.ux,u.uy); 312. }  313.   314.  donull { 315. 	return(1);	/* Do nothing, but let other things happen */ 316. }  317.   318.  #if defined(KAA) && defined(KOPS) 319. wipeoff 320. {  321.  	if(u.ucreamed < 4)	u.ucreamed = 0; 322. 	else			u.ucreamed -= 4; 323. 	if(u.ucreamed > 0)  { 324. 		Blinded -= 4; 325. 		if(Blind <= 1) { 326. 			pline("You've got the glop off."); 327. 			u.ucreamed = 0; 328. 			Blinded = 1; 329. 			return(0); 330. 		}  331.  		return(1);		/* still busy */ 332. 	}  333.  	pline("Your face feels clean now."); 334. 	u.ucreamed = 0; 335. 	return(0); 336. }  337.  	  338.  dowipe 339. {  340.  	if(u.ucreamed)  { 341. #ifdef DGKMOD 342. 		set_occupation(wipeoff, "wiping off your face", 0); 343. #else 344. 		occupation = wipeoff; 345. 		occtxt = "wiping off your face"; 346. #endif 347. 		return(1); 348. 	}  349.  	pline("Your face is already clean."); 350. 	return(1); 351. }  352.  #endif 353.  354.  /* split obj so that it gets size num */ 355. /* remainder is put in the object structure delivered by this call */ 356. struct obj * 357. splitobj(obj, num) register struct obj *obj; register int num; { 358. register struct obj *otmp; 359. 	otmp = newobj(0); 360. 	*otmp = *obj;		/* copies whole structure */ 361. 	otmp->o_id = flags.ident++; 362. 	otmp->onamelth = 0; 363. 	obj->quan = num; 364. 	obj->owt = weight(obj); 365. 	otmp->quan -= num; 366. 	otmp->owt = weight(otmp);	/* -= obj->owt ? */ 367.  	obj->nobj = otmp; 368. 	if(obj->unpaid) splitbill(obj,otmp); 369. 	return(otmp); 370. }  371.   372.  more_experienced(exp,rexp) 373. register int exp, rexp; 374. {  375.  	extern char pl_character[]; 376.  377.  	u.uexp += exp; 378. 	u.urexp += 4*exp + rexp; 379. 	if(exp) flags.botl = 1; 380. 	if(u.urexp >= ((pl_character[0] == 'W') ? 1000 : 2000)) 381.  		flags.beginner = 0; 382. }  383.   384.  set_wounded_legs(side, timex) 385. register long side; 386. register int timex; 387. {  388.  	if(!Wounded_legs || (Wounded_legs & TIMEOUT)) 389. 		Wounded_legs |= side + timex; 390. 	else 391. 		Wounded_legs |= side; 392. }  393.   394.  heal_legs 395. {  396.  	if(Wounded_legs) { 397. 		if((Wounded_legs & BOTH_SIDES) == BOTH_SIDES) 398. 			pline("Your legs feel somewhat better."); 399. 		else 400. 			pline("Your leg feels somewhat better."); 401. 		Wounded_legs = 0; 402. 	}  403.  }