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
The NetHack General Public License applies to screenshots, source code and other content from NetHack. |
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 /**/