Source:NetHack 1.3d/do.c

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