Source:Hack 1.0/hack.read.c

Below is the full text to hack.read.c from the source code of Hack 1.0. To link to a particular line, write [[Hack 1.0/hack.read.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 "hack.h"  4. 5.   extern struct monst *makemon; 6.   int identify; 7.    8.    doread { 9.   	register struct obj *scroll; 10.  	register boolean confused = (Confusion != 0); 11.  	register boolean known = FALSE; 12.   13.   	scroll = getobj("?", "read"); 14.  	if(!scroll) return(0); 15.  	if(!scroll->dknown && Blind) { 16.  	    pline("Being blind, you cannot read the formula on the scroll."); 17.  	    return(0); 18.  	}  19.   	if(Blind) 20.  	  pline("As you pronounce the formula on it, the scroll disappears."); 21.  	else 22.  	  pline("As you read the scroll, it disappears."); 23.  	if(confused) 24.  	  pline("Being confused, you mispronounce the magic words ... "); 25.   26.   	switch(scroll->otyp) { 27.   28.   	case SCR_ENCHANT_ARMOR: 29.  	    {	extern struct obj *some_armor; 30.  		register struct obj *otmp = some_armor; 31.  		if(!otmp) { 32.  			strange_feeling(scroll); 33.  			return(1); 34.  		}  35.   		if(confused) { 36.  			pline("Your %s glows silver for a moment.",  37.   				objects[otmp->otyp].oc_name); 38.  			otmp->rustfree = 1; 39.  			break; 40.  		}  41.   		if(otmp->spe*2 + objects[otmp->otyp].a_ac > 23 &&  42.   			!rn2(3)) { 43.  	pline("Your %s glows violently green for a while, then evaporates.",  44.   			objects[otmp->otyp].oc_name); 45.  			useup(otmp); 46.  			break; 47.  		}  48.   		pline("Your %s glows green for a moment.",  49.   			objects[otmp->otyp].oc_name); 50.  		otmp->cursed = 0; 51.  		otmp->spe++; 52.  		break; 53.  	    }  54.   	case SCR_DESTROY_ARMOR: 55.  		if(confused) { 56.  			register struct obj *otmp = some_armor; 57.  			if(!otmp) { 58.  				strange_feeling(scroll); 59.  				return(1); 60.  			}  61.   			pline("Your %s glows purple for a moment.",  62.   				objects[otmp->otyp].oc_name); 63.  			otmp->rustfree = 0; 64.  			break; 65.  		}  66.   		if(uarm) { 67.  		    pline("Your armor turns to dust and falls to the floor!"); 68.  		    useup(uarm); 69.  		} else if(uarmh) { 70.  		    pline("Your helmet turns to dust and is blown away!"); 71.  		    useup(uarmh); 72.  		} else if(uarmg) { 73.  			pline("Your gloves vanish!"); 74.  			useup(uarmg); 75.  			selftouch("You"); 76.  		} else { 77.  			strange_feeling(scroll); 78.  			return(1); 79.  		}  80.   		break; 81.  	case SCR_CONFUSE_MONSTER: 82.  		if(confused) { 83.  			pline("Your hands begin to glow purple."); 84.  			Confusion += rnd(100); 85.  		} else { 86.  			pline("Your hands begin to glow blue."); 87.  			u.umconf = 1; 88.  		}  89.   		break; 90.  	case SCR_SCARE_MONSTER: 91.  	    {	register int ct = 0; 92.  		register struct monst *mtmp; 93.   94.   		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 95.  			if(cansee(mtmp->mx,mtmp->my)) { 96.  				if(confused) 97.  					mtmp->mflee = mtmp->mfroz = 98.  					mtmp->msleep = 0; 99.  				else 100. 					mtmp->mflee = 1; 101. 				ct++; 102. 			}  103.  		if(!ct) { 104. 		    if(confused) 105. 			pline("You hear sad wailing in the distance."); 106. 		    else 107. 			pline("You hear maniacal laughter in the distance."); 108. 		}  109.  		break; 110. 	    }  111.  	case SCR_BLANK_PAPER: 112. 		if(confused) 113. 		    pline("You see strange patterns on this scroll."); 114. 		else 115. 		    pline("This scroll seems to be blank."); 116. 		break; 117. 	case SCR_REMOVE_CURSE: 118. 	    {	register struct obj *obj; 119. 		if(confused) 120. 		  pline("You feel like you need some help."); 121. 		else 122. 		  pline("You feel like someone is helping you."); 123. 		for(obj = invent; obj ; obj = obj->nobj) 124. 			if(obj->owornmask) 125. 				obj->cursed = confused; 126. 		if(Punished && !confused) { 127. 			Punished = 0; 128. 			freeobj(uchain); 129. 			unpobj(uchain); 130. 			free((char *) uchain); 131. 			uball->spe = 0; 132. 			uball->owornmask &= ~W_BALL; 133. 			uchain = uball = (struct obj *) 0; 134. 		}  135.  		break; 136. 	    }  137.  	case SCR_CREATE_MONSTER: 138. 	    {	register int cnt = 1; 139.  140.  		if(!rn2(73)) cnt += rn2(4) + 1; 141. 		if(confused) cnt += 12; 142. 		while(cnt--) 143. 		    (void) makemon(confused ? PM_ACIDBLOB :  144.  			(struct permonst *) 0, u.ux, u.uy); 145. 		break; 146. 	    }  147.  	case SCR_ENCHANT_WEAPON: 148. 		if(!uwep) { 149. 			strange_feeling(scroll); 150. 			return(1); 151. 		}  152.  		if(confused) { 153. 			pline("Your %s glows silver for a moment.",  154.  				objects[uwep->otyp].oc_name); 155. 			uwep->rustfree = 1; 156. 		} else 157. 			if(!chwepon(scroll, 1)) return(1); 158. 		break; 159. 	case SCR_DAMAGE_WEAPON: 160. 		if(confused) { 161. 			pline("Your %s glows purple for a moment.",  162.  				objects[uwep->otyp].oc_name); 163. 			uwep->rustfree = 0; 164. 		} else 165. 			if(!chwepon(scroll, -1)) return(1); 166. 		break; 167. 	case SCR_TAMING: 168. 	    {	register int i,j; 169. 		register int bd = confused ? 5 : 1; 170.  		register struct monst *mtmp; 171.  172.  		for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++) 173. 		if(mtmp = m_at(u.ux+i, u.uy+j)) 174. 			(void) tamedog(mtmp, (struct obj *) 0); 175. 		break; 176. 	    }  177.  	case SCR_GENOCIDE: 178. 	    {	extern char genocided[], fut_geno[]; 179. 		char buf[BUFSZ]; 180. 		register struct monst *mtmp, *mtmp2; 181.  182.  		pline("You have found a scroll of genocide!"); 183. 		known = TRUE; 184. 		if(confused) 185. 			*buf = u.usym; 186. 		else do { 187. 	    pline("What monster do you want to genocide (Type the letter)? "); 188. 			getlin(buf); 189. 		} while(strlen(buf) != 1 || !letter(*buf)); 190. 		if(!index(fut_geno, *buf)) 191. 			charcat(fut_geno, *buf); 192. 		if(!index(genocided, *buf)) 193. 			charcat(genocided, *buf); 194. 		else { 195. 			pline("Such monsters do not exist in this world."); 196. 			break; 197. 		}  198.  		for(mtmp = fmon; mtmp; mtmp = mtmp2){ 199. 			mtmp2 = mtmp->nmon; 200. 			if(mtmp->data->mlet == *buf) 201. 				mondead(mtmp); 202. 		}  203.  		pline("Wiped out all %c's.", *buf); 204. 		if(*buf == u.usym) { 205. 			killer = "scroll of genocide"; 206. 			u.uhp = -1; 207. 		}  208.   break; 209. 		}  210.  	case SCR_LIGHT: 211. 		if(!Blind) known = TRUE; 212. 		litroom(!confused); 213. 		break; 214. 	case SCR_TELEPORTATION: 215. 		if(confused) 216. 			level_tele; 217. 		else { 218. #ifdef QUEST 219. 			register int oux = u.ux, ouy = u.uy; 220. 			tele; 221. 			if(dist(oux, ouy) > 100) known = TRUE; 222. #else QUEST 223. 			register int uroom = inroom(u.ux, u.uy); 224. 			tele; 225. 			if(uroom != inroom(u.ux, u.uy)) known = TRUE; 226. #endif QUEST 227. 		}  228.  		break; 229. 	case SCR_GOLD_DETECTION: 230. 	    {	register struct gen *head = confused ? ftrap : fgold; 231. 		register struct gen *gtmp; 232.  233.  		if(!head) { 234. 			strange_feeling(scroll); 235. 			return(1); 236. 		} else { 237. 			known = TRUE; 238. 			for(gtmp = head; gtmp; gtmp = gtmp->ngen) 239. 				if(gtmp->gx != u.ux || gtmp->gy != u.uy) 240. 					goto outgoldmap; 241. 			/* only under me - no separate display required */ 242. 			if(confused) 243. 			    pline("You feel very giddy!"); 244. 			else 245. 			    pline("You notice some gold between your feet."); 246. 			break; 247. 		outgoldmap: 248. 			cls; 249. 			for(gtmp = head; gtmp; gtmp = gtmp->ngen) 250. 				at(gtmp->gx, gtmp->gy, '$'); 251. 			prme; 252. 			if(confused) 253. 			    pline("You feel very greedy!"); 254. 			else 255. 			    pline("You feel very greedy, and sense gold!"); 256. 			more; 257. 			docrt; 258. 		}  259.  		break; 260. 	    }  261.  	case SCR_FOOD_DETECTION: 262. 	    {	register ct = 0, ctu = 0; 263. 		register struct obj *obj; 264. 		register char foodsym = confused ? POTION_SYM : FOOD_SYM; 265.  266.  		for(obj = fobj; obj; obj = obj->nobj) 267. 			if(obj->olet == FOOD_SYM) { 268. 				if(obj->ox == u.ux && obj->oy == u.uy) ctu++; 269. 				else ct++; 270. 			}  271.  		if(!ct && !ctu) { 272. 			strange_feeling(scroll); 273. 			return(1); 274. 		} else if(!ct) { 275. 			known = TRUE; 276. 			pline("You smell %s close nearby.",  277.  				confused ? "something" : "food"); 278. 			  279.  		} else { 280. 			known = TRUE; 281. 			cls; 282. 			for(obj = fobj; obj; obj = obj->nobj) 283. 			    if(obj->olet == foodsym) 284. 				at(obj->ox, obj->oy, FOOD_SYM); 285. 			prme; 286. 			pline("Your nose tingles and you smell %s!",  287.  				confused ? "something" : "food"); 288. 			more; 289. 			docrt; 290. 		}  291.  		break; 292. 	    }  293.  	case SCR_IDENTIFY: 294. 		/* known = TRUE; */ 295. 		if(confused) 296. 			pline("You identify this as an identify scroll."); 297. 		else 298. 			pline("This is an identify scroll."); 299. 		useup(scroll); 300. 		objects[SCR_IDENTIFY].oc_name_known = 1; 301. 		if(!confused) 302. 		    while(  303.  			!ggetobj("identify", identify, rn2(5) ? 1 : rn2(5)) 304.  			&& invent  305.  		    ); 306. 		return(1); 307. 	case SCR_MAGIC_MAPPING: 308. 	    {	register struct rm *lev; 309. 		register int num, zx, zy; 310.  311.  		known = TRUE; 312. 		pline("On this scroll %s a map!",  313.  			confused ? "was" : "is"); 314. 		for(zy = 0; zy < ROWNO; zy++) 315. 			for(zx = 0; zx < COLNO; zx++) { 316. 				if(confused && rn2(7)) continue; 317. 				lev = &(levl[zx][zy]); 318. 				if((num = lev->typ) == 0) 319. 					continue; 320. 				if(num == SCORR) { 321. 					lev->typ = CORR; 322. 					lev->scrsym = CORR_SYM; 323. 				} else 324. 				if(num == SDOOR) { 325. 					lev->typ = DOOR; 326. 					lev->scrsym = '+'; 327. 					/* do sth in doors ? */ 328.  				} else if(lev->seen) continue; 329. #ifndef QUEST 330. 				if(num != ROOM) 331. #endif QUEST 332. 				{  333.  				  lev->seen = lev->new = 1; 334. 				  on_scr(zx,zy); 335. 				}  336.  			}  337.  		break; 338. 	    }  339.  	case SCR_AMNESIA: 340. 	    {	register int zx, zy; 341.  342.  		known = TRUE; 343. 		for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++) 344. 		    if(!confused || rn2(7)) 345. 			if(!cansee(zx,zy)) 346. 			    levl[zx][zy].seen = 0; 347. 		docrt; 348. 		pline("Thinking of Maud you forget everything else."); 349. 		break; 350. 	    }  351.  	case SCR_FIRE: 352. 	    {	register int num; 353.  354.  		known = TRUE; 355. 		if(confused) { 356. 		    pline("The scroll catches fire and you burn your hands."); 357. 		    losehp(1, "scroll of fire"); 358. 		} else { 359. 		    pline("The scroll erupts in a tower of flame!"); 360. 		    if(Fire_resistance) 361. 			pline("You are uninjured."); 362. 		    else { 363. 			num = rnd(6); 364. 			u.uhpmax -= num; 365. 			losehp(num, "scroll of fire"); 366. 		    }  367.  		}  368.  		break; 369. 	    }  370.  	case SCR_PUNISHMENT: 371. 		known = TRUE; 372. 		if(confused) { 373. 			pline("You feel guilty."); 374. 			break; 375. 		}  376.  		pline("You are being punished for your misbehaviour!"); 377. 		if(Punished){ 378. 			pline("Your iron ball gets heavier."); 379. 			uball->owt += 15; 380. 			break; 381. 		}  382.  		Punished = INTRINSIC; 383. 		mkobj_at(CHAIN_SYM, u.ux, u.uy); 384. 		setworn(fobj, W_CHAIN); 385. 		mkobj_at(BALL_SYM, u.ux, u.uy); 386. 		setworn(fobj, W_BALL); 387. 		uball->spe = 1;		/* special ball (see save) */ 388. 		break; 389. 	default: 390. 		pline("What weird language is this written in? (%d)",  391.  			scroll->otyp); 392. 		impossible; 393. 	}  394.  	if(!objects[scroll->otyp].oc_name_known) { 395. 		if(known && !confused) { 396. 			objects[scroll->otyp].oc_name_known = 1; 397. 			u.urexp += 10; 398. 		} else if(!objects[scroll->otyp].oc_uname) 399.  docall(scroll); 400. 	}  401.  	useup(scroll); 402. 	return(1); 403. }  404.   405.  identify(otmp) 406. register struct obj *otmp; 407. {  408.  	objects[otmp->otyp].oc_name_known = 1; 409. 	otmp->known = otmp->dknown = 1; 410. 	prinv(otmp); 411. 	return(1); 412. }  413.   414.  litroom(on) 415. register boolean on; 416. {  417.  	register num,zx,zy; 418.  419.  	/* first produce the text (provided he is not blind) */ 420. 	if(Blind) goto do_it; 421. 	if(!on) { 422. 		if(u.uswallow || !xdnstair || levl[u.ux][u.uy].typ == CORR ||  423.  		    !levl[u.ux][u.uy].lit) { 424. 			pline("It seems even darker in here than before."); 425. 			return; 426. 		} else 427.  pline("It suddenly becomes dark in here."); 428. 	} else { 429. 		if(u.uswallow){ 430. 			pline("%s's stomach is lit.", Monnam(u.ustuck)); 431. 			return; 432. 		}  433.  		if(!xdnstair){ 434. 			pline("Nothing Happens"); 435. 			return; 436. 		}  437.  #ifdef QUEST 438. 		pline("The cave lights up around you, then fades."); 439. 		return; 440. #else QUEST 441. 		if(levl[u.ux][u.uy].typ == CORR) { 442. 		    pline("The corridor lights up around you, then fades."); 443. 		    return; 444. 		} else if(levl[u.ux][u.uy].lit) { 445. 		    pline("The light here seems better now."); 446. 		    return; 447. 		} else 448. 		    pline("The room is lit."); 449. #endif QUEST 450. 	}  451.   452.  do_it: 453. #ifdef QUEST 454. 	return; 455. #else QUEST 456. 	if(levl[u.ux][u.uy].lit == on) 457. 		return; 458. 	if(levl[u.ux][u.uy].typ == DOOR) { 459. 		if(levl[u.ux][u.uy+1].typ >= ROOM) zy = u.uy+1; 460. 		else if(levl[u.ux][u.uy-1].typ >= ROOM) zy = u.uy-1; 461. 		else zy = u.uy; 462. 		if(levl[u.ux+1][u.uy].typ >= ROOM) zx = u.ux+1; 463. 		else if(levl[u.ux-1][u.uy].typ >= ROOM) zx = u.ux-1; 464. 		else zx = u.ux; 465. 	} else { 466. 		zx = u.ux; 467. 		zy = u.uy; 468. 	}  469.  	for(seelx = u.ux; (num = levl[seelx-1][zy].typ) != CORR && num != 0;  470.  		seelx--); 471. 	for(seehx = u.ux; (num = levl[seehx+1][zy].typ) != CORR && num != 0;  472.  		seehx++); 473. 	for(seely = u.uy; (num = levl[zx][seely-1].typ) != CORR && num != 0;  474.  		seely--); 475. 	for(seehy = u.uy; (num = levl[zx][seehy+1].typ) != CORR && num != 0;  476.  		seehy++); 477. 	for(zy = seely; zy <= seehy; zy++) 478. 		for(zx = seelx; zx <= seehx; zx++) { 479. 			levl[zx][zy].lit = on; 480. 			if(!Blind && dist(zx,zy) > 2) 481. 				if(on) prl(zx,zy); else nosee(zx,zy); 482. 		}  483.  	if(!on) seehx = 0; 484. #endif	QUEST 485. }