Source:NetHack 1.4f/do.c
Jump to navigation
Jump to search
Below is the full text to do.c from the source code of NetHack 1.4f. To link to a particular line, write [[NetHack 1.4f/do.c#line123]], for example.
Warning! This is the source code from an old release. For the latest release, see Source code
Screenshots and source code from Hack are used under the CWI license.
1. /* SCCS Id: @(#)do.c 1.4 87/08/08 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 == GOLD_SYM) { /* 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. 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. }