Source:NetHack 2.3e/do.c
Jump to navigation
Jump to search
Below is the full text to do.c from the source code of NetHack 2.3e.
Warning! This is the source code from an old release. For newer releases, see Source code
Screenshots and source code from Hack are used under the CWI license.
1. /* SCCS Id: @(#)do.c 2.3 88/02/11 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. 4. /* Contains code for 'd', 'D' (drop), '>', '<' (up, down) and 't' (throw) */ 5. 6. #include "hack.h" 7. 8. extern struct obj *splitobj(), *addinv(); 9. extern boolean hmon(); 10. extern boolean level_exists[]; 11. extern struct monst youmonst; 12. extern char *Doname(); 13. extern char *nomovemsg; 14. int identify(); 15. #ifdef KAA 16. extern char *xname(); 17. #endif 18. 19. dodrop() { 20. if(u.ugold) return(drop(getobj("0$#", "drop"))); 21. else 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 | W_TOOL)){ 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. #ifdef WALKIES 62. if (obj->otyp == LEASH) { 63. register struct monst *mtmp = fmon; 64. while (mtmp && !mtmp->mleashed) mtmp = mtmp->nmon; 65. if (mtmp) { 66. pline ("Your leash is tied around your hand."); 67. return (0); 68. } 69. } 70. #endif 71. #ifdef SINKS 72. if((obj->olet == RING_SYM) && IS_SINK(levl[u.ux][u.uy].typ)) 73. if (u.uswallow) { 74. freeinv(obj); 75. mpickobj(u.ustuck,obj); 76. return(1); 77. } 78. else { 79. dosinkring(obj); 80. return(1); 81. } 82. #endif 83. pline("You dropped %s.", doname(obj)); 84. dropx(obj); 85. return(1); 86. } 87. 88. /* Called in several places - should not produce texts */ 89. dropx(obj) 90. register struct obj *obj; 91. { 92. freeinv(obj); 93. dropy(obj); 94. } 95. 96. dropy(obj) 97. register struct obj *obj; 98. { 99. if(obj->otyp == CRYSKNIFE) 100. obj->otyp = WORM_TOOTH; 101. /* uswallow check done by GAN 01/29/87 */ 102. if(u.uswallow) 103. mpickobj(u.ustuck,obj); 104. else { 105. obj->ox = u.ux; 106. obj->oy = u.uy; 107. /* Blind check added by GAN 02/18/87 */ 108. if(Blind) { 109. #ifdef KAA 110. if(obj->olet != ')') 111. #endif 112. obj->dknown = index("/=!?*",obj->olet) ? 0 : 1; 113. obj->known = 0; 114. } 115. obj->nobj = fobj; 116. fobj = obj; 117. if(Invisible) newsym(u.ux,u.uy); 118. subfrombill(obj); 119. stackobj(obj); 120. } 121. } 122. 123. /* drop several things */ 124. doddrop() { 125. return(ggetobj("drop", drop, 0)); 126. } 127. 128. dodown() 129. { 130. if(u.ux != xdnstair || u.uy != ydnstair) { 131. pline("You can't go down here."); 132. return(0); 133. } 134. if(u.ustuck) { 135. pline("You are being held, and cannot go down."); 136. return(1); 137. } 138. if(Levitation) { 139. pline("Your floating high above the stairs."); 140. return(0); 141. } 142. 143. goto_level(dlevel+1, TRUE); 144. return(1); 145. } 146. 147. doup() 148. { 149. if(u.ux != xupstair || u.uy != yupstair) { 150. pline("You can't go up here."); 151. return(0); 152. } 153. if(u.ustuck) { 154. pline("You are being held, and cannot go up."); 155. return(1); 156. } 157. if(!Levitation && inv_weight() + 5 > 0) { 158. pline("Your load is too heavy to climb the stairs."); 159. return(1); 160. } 161. 162. goto_level(dlevel-1, TRUE); 163. return(1); 164. } 165. 166. goto_level(newlevel, at_stairs) 167. register int newlevel; 168. register boolean at_stairs; 169. { 170. register fd; 171. register boolean up = (newlevel < dlevel); 172. 173. if(newlevel <= 0) done("escaped"); /* in fact < 0 is impossible */ 174. if(newlevel > MAXLEVEL) newlevel = MAXLEVEL; /* strange ... */ 175. if(newlevel == dlevel) return; /* this can happen */ 176. 177. glo(dlevel); 178. #ifdef DGK 179. /* Use O_TRUNC to force the file to be shortened if it already 180. * exists and is currently longer. 181. */ 182. fd = open(lock, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FMASK); 183. #else 184. fd = creat(lock, FMASK); 185. #endif 186. if(fd < 0) { 187. /* 188. * This is not quite impossible: e.g., we may have 189. * exceeded our quota. If that is the case then we 190. * cannot leave this level, and cannot save either. 191. * Another possibility is that the directory was not 192. * writable. 193. */ 194. #ifdef DGK 195. pline("Cannot create level file '%s'.", lock); 196. #else 197. pline("A mysterious force prevents you from going %s.", 198. up ? "up" : "down"); 199. #endif 200. return; 201. } 202. 203. #ifdef DGK 204. if (!savelev(fd, dlevel, COUNT)) { 205. (void) close(fd); 206. (void) unlink(lock); 207. pline("HACK is out of disk space for making levels!"); 208. pline("You can save, quit, or continue playing."); 209. return; 210. } 211. #endif 212. if(Punished) unplacebc(); 213. u.utrap = 0; /* needed in level_tele */ 214. u.ustuck = 0; /* idem */ 215. keepdogs(); 216. seeoff(1); 217. if(u.uswallow) /* idem */ 218. u.uswldtim = u.uswallow = 0; 219. flags.nscrinh = 1; 220. u.ux = FAR; /* hack */ 221. (void) inshop(); /* probably was a trapdoor */ 222. 223. #ifdef DGK 224. savelev(fd,dlevel, WRITE); 225. #else 226. savelev(fd,dlevel); 227. #endif 228. (void) close(fd); 229. 230. dlevel = newlevel; 231. if(maxdlevel < dlevel) 232. maxdlevel = dlevel; 233. glo(dlevel); 234. #ifdef MSDOS 235. /* If the level has no where yet, it hasn't been made 236. */ 237. if(!fileinfo[dlevel].where) 238. #else 239. if(!level_exists[dlevel]) 240. #endif 241. mklev(); 242. else { 243. extern int hackpid; 244. #ifdef DGK 245. /* If not currently accessible, swap it in. 246. */ 247. if (fileinfo[dlevel].where != ACTIVE) 248. swapin_file(dlevel); 249. 250. if((fd = open(lock, O_RDONLY | O_BINARY)) < 0) { 251. #else 252. if((fd = open(lock,0)) < 0) { 253. #endif 254. pline("Cannot open %s .", lock); 255. pline("Probably someone removed it."); 256. done("tricked"); 257. } 258. getlev(fd, hackpid, dlevel); 259. (void) close(fd); 260. } 261. 262. if(at_stairs) { 263. if(up) { 264. u.ux = xdnstair; 265. u.uy = ydnstair; 266. if(!u.ux) { /* entering a maze from below? */ 267. u.ux = xupstair; /* this will confuse the player! */ 268. u.uy = yupstair; 269. } 270. /* Remove bug which crashes with levitation/punishment KAA */ 271. if(Punished) { 272. if(!Levitation) 273. pline("With great effort you climb the stairs."); 274. placebc(1); 275. } 276. } else { 277. u.ux = xupstair; 278. u.uy = yupstair; 279. if(inv_weight() + 5 > 0 || Punished){ 280. pline("You fall down the stairs."); /* %% */ 281. losehp(rnd(3), "fall"); 282. if(Punished) { 283. if(uwep != uball && rn2(3)){ 284. pline("... and are hit by the iron ball."); 285. losehp(rnd(20), "iron ball"); 286. } 287. placebc(1); 288. } 289. selftouch("Falling, you"); 290. } 291. } 292. { register struct monst *mtmp = m_at(u.ux, u.uy); 293. if(mtmp) 294. mnexto(mtmp); 295. } 296. } else { /* trapdoor or level_tele */ 297. do { 298. u.ux = rnd(COLNO-1); 299. u.uy = rn2(ROWNO); 300. } while(levl[u.ux][u.uy].typ != ROOM || 301. m_at(u.ux,u.uy)); 302. if(Punished){ 303. if(uwep != uball && !up /* %% */ && rn2(5)){ 304. pline("The iron ball falls on your head."); 305. losehp(rnd(25), "iron ball"); 306. } 307. placebc(1); 308. } 309. selftouch("Falling, you"); 310. } 311. (void) inshop(); 312. initrack(); 313. 314. losedogs(); 315. { register struct monst *mtmp; 316. if(mtmp = m_at(u.ux, u.uy)) mnexto(mtmp); /* riv05!a3 */ 317. } 318. flags.nscrinh = 0; 319. setsee(); 320. seeobjs(); /* make old cadavers disappear - riv05!a3 */ 321. docrt(); 322. pickup(1); 323. read_engr_at(u.ux,u.uy); 324. } 325. 326. donull() { 327. return(1); /* Do nothing, but let other things happen */ 328. } 329. 330. #if defined(KAA) && defined(KOPS) 331. wipeoff() 332. { 333. if(u.ucreamed < 4) u.ucreamed = 0; 334. else u.ucreamed -= 4; 335. if(u.ucreamed > 0) { 336. Blinded -= 4; 337. if(Blind <= 1) { 338. pline("You've got the glop off."); 339. u.ucreamed = 0; 340. Blinded = 1; 341. return(0); 342. } 343. return(1); /* still busy */ 344. } 345. pline("Your face feels clean now."); 346. u.ucreamed = 0; 347. return(0); 348. } 349. 350. dowipe() 351. { 352. if(u.ucreamed) { 353. #ifdef DGKMOD 354. set_occupation(wipeoff, "wiping off your face", 0); 355. #else 356. occupation = wipeoff; 357. occtxt = "wiping off your face"; 358. #endif 359. return(1); 360. } 361. pline("Your face is already clean."); 362. return(1); 363. } 364. #endif 365. 366. /* split obj so that it gets size num */ 367. /* remainder is put in the object structure delivered by this call */ 368. struct obj * 369. splitobj(obj, num) register struct obj *obj; register int num; { 370. register struct obj *otmp; 371. otmp = newobj(0); 372. *otmp = *obj; /* copies whole structure */ 373. otmp->o_id = flags.ident++; 374. otmp->onamelth = 0; 375. obj->quan = num; 376. obj->owt = weight(obj); 377. otmp->quan -= num; 378. otmp->owt = weight(otmp); /* -= obj->owt ? */ 379. obj->nobj = otmp; 380. if(obj->unpaid) splitbill(obj,otmp); 381. return(otmp); 382. } 383. 384. more_experienced(exp,rexp) 385. register int exp, rexp; 386. { 387. extern char pl_character[]; 388. 389. u.uexp += exp; 390. u.urexp += 4*exp + rexp; 391. if(exp) flags.botl = 1; 392. if(u.urexp >= ((pl_character[0] == 'W') ? 1000 : 2000)) 393. flags.beginner = 0; 394. } 395. 396. set_wounded_legs(side, timex) 397. register long side; 398. register int timex; 399. { 400. if(!Wounded_legs || (Wounded_legs & TIMEOUT)) 401. Wounded_legs |= side + timex; 402. else 403. Wounded_legs |= side; 404. } 405. 406. heal_legs() 407. { 408. if(Wounded_legs) { 409. if((Wounded_legs & BOTH_SIDES) == BOTH_SIDES) 410. pline("Your legs feel somewhat better."); 411. else 412. pline("Your leg feels somewhat better."); 413. Wounded_legs = 0; 414. } 415. } 416. 417. #ifdef SINKS 418. trycall(obj) 419. register struct obj *obj; 420. { 421. if(!objects[obj->otyp].oc_name_known && 422. !objects[obj->otyp].oc_uname) 423. docall(obj); 424. } 425. 426. dosinkring(obj) /* obj is a ring being dropped over a kitchen sink */ 427. register struct obj *obj; 428. { 429. register struct obj *otmp,*otmp2; 430. register short eaten; 431. pline("You drop %s down the drain.", doname(obj)); 432. switch(obj->otyp) { 433. case RIN_ADORNMENT: { 434. pline("The faucets flash brightly for a moment."); 435. trycall(obj); 436. break; 437. } 438. case RIN_REGENERATION: { 439. pline("The sink looks as good as new."); 440. trycall(obj); 441. break; 442. } 443. case RIN_SEARCHING: 444. break; 445. case RIN_SEE_INVISIBLE: 446. break; 447. case RIN_STEALTH: { 448. pline("The sink seems to blend into the floor for a moment."); 449. trycall(obj); 450. break; 451. } 452. case RIN_LEVITATION: { 453. pline("The sink quivers upward for a moment."); 454. trycall(obj); 455. break; 456. } 457. case RIN_POISON_RESISTANCE: 458. break; 459. case RIN_AGGRAVATE_MONSTER: 460. break; 461. case RIN_HUNGER: { 462. eaten = 0; 463. for(otmp=fobj; otmp; otmp=otmp2) { 464. otmp2 = otmp->nobj; 465. if(otmp->ox == u.ux && otmp->oy == u.uy) 466. if(!Punished || 467. (otmp->otyp != HEAVY_IRON_BALL && otmp->otyp != IRON_CHAIN)) { 468. eaten++; 469. pline("Suddenly, %s vanishes from the sink!",doname(otmp)); 470. delobj(otmp); 471. } 472. } 473. if(eaten) 474. trycall(obj); 475. break; 476. } 477. case RIN_FIRE_RESISTANCE: { 478. pline("The hot water faucet flashes brightly for a moment."); 479. trycall(obj); 480. break; 481. } 482. case RIN_COLD_RESISTANCE: { 483. pline("The cold water faucet flashes brightly for a moment."); 484. trycall(obj); 485. break; 486. } 487. case RIN_PROTECTION_FROM_SHAPE_CHAN: { 488. pline("The sink momentarily looks nothing like a fountain."); 489. trycall(obj); 490. break; 491. } 492. case RIN_CONFLICT: 493. break; 494. case RIN_GAIN_STRENGTH: 495. break; 496. case RIN_INCREASE_DAMAGE: 497. break; 498. case RIN_PROTECTION: 499. break; 500. case RIN_WARNING: { 501. pline("The sink glows white for a moment."); 502. trycall(obj); 503. break; 504. } 505. case RIN_TELEPORTATION: /* fall through */ 506. case RIN_TELEPORT_CONTROL: { 507. pline("The sink momentarily vanishes."); 508. trycall(obj); 509. break; 510. } 511. case RIN_POLYMORPH: /* fall through */ 512. case RIN_POLYMORPH_CONTROL: { 513. pline("The sink momentarily looks like a fountain."); 514. trycall(obj); 515. break; 516. } 517. } 518. if (!rn2(20)) { 519. pline("The sink backs up, leaving %s.", doname(obj)); 520. dropx(obj); 521. } 522. else 523. useup(obj); 524. } 525. #endif