Source:NetHack 3.0.0/dbridge.c

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

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

1.   /*	SCCS Id: @(#)dbridge.c	3.0	88/18/12 2.   /* 	Copyright (c) 1989 by Jean-Christophe Collet */ 3.   /* NetHack may be freely redistributed. See license for details. */ 4.     5.    /*  6.     * This file contains the drawbridge manipulation (create, open, close,  7.     * destroy). 8.    */  9.     10.   #include "hack.h"  11. 12.  boolean 13.  is_pool(x,y) 14.  int x,y; 15.  {  16.   	if(levl[x][y].typ == POOL || levl[x][y].typ == MOAT) return TRUE; 17.  #ifdef STRONGHOLD 18.  	if(levl[x][y].typ == DRAWBRIDGE_UP &&  19.   		(levl[x][y].drawbridgemask & DB_UNDER) == DB_MOAT) return TRUE; 20.  #endif 21.  	return FALSE; 22.  }  23.    24.   #ifdef STRONGHOLD 25.  void 26.  initsym(x,y) 27.  int x,y; 28.  {  29.   	char oldseen; 30.  	struct rm *crm = &levl[x][y]; 31.   32.   	oldseen = crm->seen; 33.  	crm->seen = 1; 34.  	crm->scrsym = news0(x,y); 35.  	crm->seen = oldseen; 36.  }  37.    38.   static void 39.  redosym(x,y) 40.  int x,y; 41.  {  42.   	if(cansee(x,y)) { 43.  		if (Invisible || x != u.ux || y != u.uy) 44.  			newsym(x,y); 45.  	} else { 46.  		initsym(x,y); 47.  		levl[x][y].seen = 0; 48.  	}  49.   }  50.    51.   /*  52.    * We want to know whether a wall (or a door) is the portcullis (passageway) 53.   * of an eventual drawbridge. 54.   *  55.    * Return value: the direction of the drawbridge. 56.   */  57.    58.   int 59.  is_drawbridge_wall(x,y) 60.  int x,y; 61.  {  62.   	struct rm *lev; 63.   64.   	lev = &levl[x][y]; 65.  	if ( lev->typ == VWALL || lev->typ == DOOR) { 66.  		if (IS_DRAWBRIDGE(levl[x+1][y].typ) &&  67.   		    (levl[x+1][y].drawbridgemask & DB_DIR) == DB_WEST) 68.  			return (DB_WEST); 69.  		if (IS_DRAWBRIDGE(levl[x-1][y].typ) &&  70.   		    (levl[x-1][y].drawbridgemask & DB_DIR) == DB_EAST) 71.  			return (DB_EAST); 72.  	}  73.   	if ( lev->typ == HWALL || lev->typ == DOOR) { 74.  		if (IS_DRAWBRIDGE(levl[x][y-1].typ) &&  75.   		    (levl[x][y-1].drawbridgemask & DB_DIR) == DB_SOUTH) 76.  			return (DB_SOUTH); 77.  		if (IS_DRAWBRIDGE(levl[x][y+1].typ) &&  78.   		    (levl[x][y+1].drawbridgemask & DB_DIR) == DB_NORTH) 79.  			return (DB_NORTH); 80.  	}  81.   	return (-1); 82.  }  83.    84.   /*  85.   * Use is_db_wall where you want to verify that a  86. * drawbridge "wall" is UP in the location x, y  87. * (instead of UP or DOWN, as with is_drawbridge_wall). 88.  */  89.   boolean 90.  is_db_wall(x,y) 91.  int x,y; 92.  {  93.   	return( (levl[x][y].typ == VWALL || levl[x][y].typ == HWALL) &&  94.   		levl[x][y].diggable & W_GATEWAY); 95.  }  96.    97.   /*  98.    * Return true with x,y pointing to the drawbridge if x,y initially indicate 99.   * a drawbridge or drawbridge wall. 100.  */  101.  boolean 102. find_drawbridge(x,y) 103. int *x,*y; 104. {  105.  	int dir; 106.  107.  	if (IS_DRAWBRIDGE(levl[*x][*y].typ)) 108. 		return TRUE; 109. 	dir = is_drawbridge_wall(*x,*y); 110. 	if (dir >= 0) { 111. 		switch(dir) { 112. 		      case DB_NORTH: (*y)++; break; 113. 		      case DB_SOUTH: (*y)--; break; 114. 		      case DB_EAST:  (*x)--; break; 115. 		      case DB_WEST:  (*x)++; break; 116. 		}  117.  		return TRUE; 118. 	}  119.  	return FALSE; 120. }  121.   122.  /*  123.   * Find the drawbridge wall associated with a drawbridge. 124.  */  125.  static void 126. get_wall_for_db(x,y) 127. int *x,*y; 128. {  129.  	switch (levl[*x][*y].drawbridgemask & DB_DIR) { 130. 	      case DB_NORTH: (*y)--; break; 131. 	      case DB_SOUTH: (*y)++; break; 132. 	      case DB_EAST:  (*x)++; break; 133. 	      case DB_WEST:  (*x)--; break; 134. 	}  135.  }  136.   137.  /*  138.   * Creation of a drawbridge at pos x,y. 139.  *	dir is the direction. 140.  *	flag must be put to TRUE if we want the drawbridge to be opened. 141.  */  142.   143.  boolean 144. create_drawbridge(x,y,dir,flag) 145. int x,y,dir; 146. boolean flag; 147. {  148.  	int x2,y2; 149. 	uchar wall; 150.  151.  	x2 = x; y2 = y;  152. switch(dir) { 153. 		case DB_NORTH: 154. 			wall = HWALL; 155. 			y2--; 156. 			break; 157. 		case DB_SOUTH: 158. 			wall = HWALL; 159. 			y2++; 160. 			break; 161. 		case DB_EAST: 162. 			wall = VWALL; 163. 			x2++; 164. 			break; 165. 		case DB_WEST: 166. 			wall = VWALL; 167. 			x2--; 168. 			break; 169. 	}  170.  	if (!IS_WALL(levl[x2][y2].typ)) 171. 		return(FALSE); 172. 	if (flag) {		/* We want the bridge open */ 173. 		levl[x][y].typ = DRAWBRIDGE_DOWN; 174. 		levl[x2][y2].typ = DOOR; 175. 		levl[x2][y2].doormask = D_NODOOR; 176. 	} else { 177. 		levl[x][y].typ = DRAWBRIDGE_UP; 178. 		levl[x2][y2].typ = wall; 179. 		/* Beware, drawbridges are non-diggable. */ 180.  		levl[x2][y2].diggable = (W_NONDIGGABLE | W_GATEWAY); 181. 	}  182.  	levl[x][y].drawbridgemask = dir;	/* always have DB_MOAT */ 183. 	initsym(x,y); 184. 	initsym(x2,y2); 185. 	return(TRUE); 186. }  187.   188.  /*  189.   * Close the drawbridge located at x,y 190.  */  191.   192.  void 193. close_drawbridge(x,y) 194. int x,y; 195. {  196.  	register struct rm *lev1, *lev2; 197. 	struct monst *mtmp; 198. 	struct obj *otmp, *otmp2; 199. 	int x2, y2; 200.  201.  	lev1 = &levl[x][y]; 202. 	if (lev1->typ != DRAWBRIDGE_DOWN) return; 203. 	if (cansee(x,y)) 204. 		You("see a drawbridge going up!"); 205. 	lev1->typ = DRAWBRIDGE_UP; 206. 	x2 = x; y2 = y;  207. get_wall_for_db(&x2,&y2); 208. 	lev2 = &levl[x2][y2]; 209. 	switch (lev1->drawbridgemask & DB_DIR) { 210. 		case DB_NORTH: 211. 		case DB_SOUTH: 212. 			lev2->typ = HWALL; 213. 			break; 214. 		case DB_WEST: 215. 		case DB_EAST: 216. 			lev2->typ = VWALL; 217. 			break; 218. 	}  219.  	lev2->diggable = (W_NONDIGGABLE | W_GATEWAY); 220. 	if ((lev1->drawbridgemask & DB_UNDER) == DB_MOAT) { 221. 	    if (lev1->mmask && !is_flyer((mtmp = m_at(x,y))->data)) { 222. 		if (is_swimmer(mtmp->data)) { 223. 		    if (flags.soundok) You("hear a splash."); 224. 		} else { 225. 		    if (cansee(x,y)) 226. 			pline("%s drowns.",Monnam(mtmp)); 227. 		    else if (flags.soundok) 228. 			You("hear a splash!"); 229. 		    xkilled(mtmp,2); 230. 		}  231.  	    }  232.  	    if (u.ux == x && u.uy == y &&  233.  		!(Levitation 234. # ifdef POLYSELF 235. 		|| is_flyer(uasmon) 236. # endif 237. 		)) {  238.  		    /* is the player *THAT* stupid ? */ 239.  		    You("fall from the drawbridge."); 240. 		    if (!Wwalking) drown; 241. 	    }  242.  	}  243.  	if (lev2->mmask && !noncorporeal((mtmp = m_at(x2, y2))->data)) { 244. 		if (cansee(x2,y2)) 245. 		    pline("%s is crushed by the portcullis.",Monnam(mtmp)); 246. 		else if (flags.soundok) 247. 		    You("hear a crushing sound."); 248. 		xkilled(mtmp,2); 249. 	}  250.  	if (u.ux == x2 && u.uy == y2) {	/* More stupidity ? */ 251.  		coord xy; 252.  253.  		You("are crushed by a falling portcullis."); 254. 		killer = "closing drawbridge"; 255. 		done("died"); 256. 		/* So, you didn't die */ 257. 		pline("A %s force teleports you away...",  258.  		      Hallucination ? "normal" : "strange"); 259. 		enexto(&xy, x2, y2); 260. 		teleds(xy.x, xy.y); 261. 	}  262.  	redosym(x,y); 263. 	for (otmp=fobj;otmp;otmp = otmp2) { 264. 		otmp2 = otmp->nobj; 265. 		if ((otmp->ox == x && otmp->oy == y) ||  266.  		     (otmp->ox == x2 && otmp->oy == y2)) 267. 		  delobj(otmp); 268. 	}  269.  	redosym(x2,y2); 270. }  271.   272.  /*  273.   * Open the drawbridge located at x,y 274.  */  275.   276.  void 277. open_drawbridge(x,y) 278. int x,y; 279. {  280.  	register struct rm *lev1, *lev2; 281. 	int x2, y2; 282.  283.  	lev1 = &levl[x][y]; 284. 	if (lev1->typ != DRAWBRIDGE_UP) return; 285. 	if (cansee(x,y)) 286. 		You("see a drawbridge coming down!"); 287. 	lev1->typ = DRAWBRIDGE_DOWN; 288. 	x2 = x; y2 = y;  289. get_wall_for_db(&x2,&y2); 290. 	lev2 = &levl[x2][y2]; 291. 	lev2->typ = DOOR; 292. 	lev2->doormask = D_NODOOR; 293. 	if (u.ux == x && u.uy == y) { 294. 		if (cansee(x2,y2)) 295. 			newsym(x2,y2); 296. 		You("are hit by the descending drawbridge!"); 297. 		killer = "descending drawbridge"; 298. 		done("died"); 299. 	}  300.  	redosym(x,y); 301. 	redosym(x2,y2); 302. }  303.   304.  /*  305.   * Let's destroy the drawbridge located at x,y 306.  */  307.   308.  void 309. destroy_drawbridge(x,y) 310. int x,y; 311. {  312.  	register struct rm *lev1, *lev2; 313. 	int x2, y2; 314.  315.  	lev1 = &levl[x][y]; 316. 	if (!IS_DRAWBRIDGE(lev1->typ)) 317. 	  return; 318. 	x2 = x; y2 = y;  319. get_wall_for_db(&x2,&y2); 320. 	lev2 = &levl[x2][y2]; 321. 	if ((lev1->drawbridgemask & DB_UNDER) == DB_MOAT) { 322. 	    if (lev1->typ == DRAWBRIDGE_UP) { 323. 		if (cansee(x2,y2)) 324. 		    pline("The portcullis of the drawbridge falls into the moat!"); 325. 		else if (flags.soundok) 326. 		    You("hear a big *SPLASH*!"); 327. 	    } else { 328. 		if (cansee(x,y)) 329. 		    pline("The drawbridge collapses into the moat!"); 330. 		else if (flags.soundok) 331. 		    You("hear a big *SPLASH*!"); 332. 	    }  333.  	    lev1->typ = MOAT; 334. 	    if (u.ux == x && u.uy == y && !(Levitation 335. # ifdef POLYSELF 336. 		|| is_flyer(uasmon) 337. # endif 338. 		)) {  339.  		    /* is the player *THAT* stupid ? */ 340.  		    You("fall from the drawbridge."); 341. 		    if (!Wwalking) drown; 342. 	    }  343.  	} else { 344. 	    if (cansee(x,y)) 345. 		pline("The drawbridge disintegrates!"); 346. 	    else 347. 		You("hear a big *CRASH*!"); 348. 	    lev1->typ = ROOM; 349. 	}  350.  	lev2->typ = DOOR; 351. 	lev2->doormask = D_NODOOR; 352. 	if (u.ux == x2 && u.uy == y2) {	/* More stupidity ? */ 353.  		coord xy; 354.  355.  		You("are crushed by a falling portcullis."); 356. 		killer = "collapsing drawbridge"; 357. 		done("died"); 358. 		/* So, you didn't die */ 359. 		pline("A %s force teleports you away...",  360.  		      Hallucination ? "normal" : "strange"); 361. 		enexto(&xy, x2, y2); 362. 		teleds(xy.x, xy.y); 363. 	}  364.  	redosym(x,y); 365. 	redosym(x2,y2); 366. }  367.   368.  #endif /* STRONGHOLD /**/