abstract
| - 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. }
|