Difference between revisions of "Source:Hack 1.0/hack.mon.c"
Jump to navigation
Jump to search
m (Automated source code upload) |
Kernigh bot (talk | contribs) m (Hack 1.0/hack.mon.c moved to Source:Hack 1.0/hack.mon.c: Robot: moved page) |
(No difference)
|
Latest revision as of 22:28, 3 March 2008
Below is the full text to hack.mon.c from the source code of Hack 1.0. To link to a particular line, write [[Hack 1.0/hack.mon.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. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ 2. 3. #include "hack.h" 4. #include "hack.mfndpos.h" 5. #define SIZE(x) (int)(sizeof(x) / sizeof(x[0])) 6. #define NULL (char *) 0 7. extern struct monst *makemon(); 8. 9. int warnlevel; /* used by movemon and dochugw */ 10. long lastwarntime; 11. int lastwarnlev; 12. char *warnings[] = { 13. "white", "pink", "red", "ruby", "purple", "black" 14. }; 15. 16. movemon() 17. { 18. register struct monst *mtmp; 19. register int fr; 20. 21. warnlevel = 0; 22. 23. while(1) { 24. /* find a monster that we haven't treated yet */ 25. /* note that mtmp or mtmp->nmon might get killed 26. while mtmp moves, so we cannot just walk down the 27. chain (even new monsters might get created!) */ 28. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 29. if(mtmp->mlstmv < moves) goto next_mon; 30. /* treated all monsters */ 31. break; 32. 33. next_mon: 34. mtmp->mlstmv = moves; 35. if(mtmp->mblinded && !--mtmp->mblinded) 36. mtmp->mcansee = 1; 37. if(mtmp->mimic) continue; 38. if(mtmp->mspeed != MSLOW || !(moves%2)){ 39. /* continue if the monster died fighting */ 40. fr = -1; 41. if(Conflict && cansee(mtmp->mx,mtmp->my) 42. && (fr = fightm(mtmp)) == 2) 43. continue; 44. if(fr<0 && dochugw(mtmp)) 45. continue; 46. } 47. if(mtmp->mspeed == MFAST && dochugw(mtmp)) 48. continue; 49. } 50. 51. warnlevel -= u.ulevel; 52. if(warnlevel >= SIZE(warnings)) 53. warnlevel = SIZE(warnings)-1; 54. if(warnlevel >= 0) 55. if(warnlevel > lastwarnlev || moves > lastwarntime + 5){ 56. register char *rr; 57. switch(Warning & (LEFT_RING | RIGHT_RING)){ 58. case LEFT_RING: 59. rr = "Your left ring glows"; 60. break; 61. case RIGHT_RING: 62. rr = "Your right ring glows"; 63. break; 64. case LEFT_RING | RIGHT_RING: 65. rr = "Both your rings glow"; 66. break; 67. default: 68. rr = "Your fingertips glow"; 69. break; 70. } 71. pline("%s %s!", rr, warnings[warnlevel]); 72. lastwarntime = moves; 73. lastwarnlev = warnlevel; 74. } 75. 76. dmonsfree(); /* remove all dead monsters */ 77. } 78. 79. justswld(mtmp,name) 80. register struct monst *mtmp; 81. char *name; 82. { 83. 84. mtmp->mx = u.ux; 85. mtmp->my = u.uy; 86. u.ustuck = mtmp; 87. pmon(mtmp); 88. kludge("%s swallows you!",name); 89. more(); 90. seeoff(1); 91. u.uswallow = 1; 92. swallowed(); 93. } 94. 95. youswld(mtmp,dam,die,name) 96. register struct monst *mtmp; 97. register dam,die; 98. char *name; 99. { 100. if(mtmp != u.ustuck) return; 101. kludge("%s digests you!",name); 102. u.uhp -= dam; 103. if(u.uswldtim++ == die){ 104. pline("It totally digests you!"); 105. u.uhp = -1; 106. } 107. if(u.uhp < 1) done_in_by(mtmp); 108. } 109. 110. dochugw(mtmp) register struct monst *mtmp; { 111. register x = mtmp->mx; 112. register y = mtmp->my; 113. register d = dochug(mtmp); 114. register dd; 115. if(!d) /* monster still alive */ 116. if(Warning) 117. if(!mtmp->mpeaceful) 118. if((dd = dist(mtmp->mx,mtmp->my)) < dist(x,y)) 119. if(dd < 100) 120. if(!cansee(mtmp->mx, mtmp->my) || (mtmp->minvis && !See_invisible)) 121. if(mtmp->data->mlevel > warnlevel) 122. warnlevel = mtmp->data->mlevel; 123. return(d); 124. } 125. 126. /* returns 1 if monster died moving, 0 otherwise */ 127. dochug(mtmp) 128. register struct monst *mtmp; 129. { 130. register struct permonst *mdat; 131. register tmp; 132. 133. if(mtmp->cham && !rn2(6)) 134. (void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]); 135. mdat = mtmp->data; 136. if(mdat->mlevel < 0) 137. panic("bad monster %c (%d)",mdat->mlet,mdat->mlevel); 138. if((!(moves%20) || index("ViT",mdat->mlet)) && 139. mtmp->mhp<mtmp->orig_hp) 140. mtmp->mhp++; /* regenerate monsters. */ 141. if(mtmp->mfroz) return(0); /* frozen monsters don't do anything. */ 142. if(mtmp->msleep) {/* wake up a monster, or get out of here. */ 143. if(cansee(mtmp->mx,mtmp->my) && !Stealth && 144. (!index("NL",mdat->mlet) || !rn2(50)) && 145. (Aggravate_monster || (!rn2(7) && !mtmp->mimic))) 146. mtmp->msleep = 0; 147. else return(0); 148. } 149. 150. /* not frozen or sleeping: wipe out texts written in the dust */ 151. wipe_engr_at(mtmp->mx, mtmp->my, 1); 152. 153. /* confused monsters get unconfused with small probability */ 154. if(mtmp->mconf && !rn2(50)) mtmp->mconf = 0; 155. 156. /* some monsters teleport */ 157. if(mtmp->mflee && index("tNL", mdat->mlet) && !rn2(40)){ 158. rloc(mtmp); 159. return(0); 160. } 161. if(mdat->mmove < rnd(6)) return(0); 162. if((mtmp->mflee || 163. mtmp->mconf || 164. (index("BIuy", mdat->mlet) && !rn2(4)) || 165. (mdat->mlet == 'L' && !u.ugold && (mtmp->mgold || rn2(2))) || 166. dist(mtmp->mx,mtmp->my) > 2 || 167. (!mtmp->mcansee && !rn2(4)) || 168. mtmp->mpeaceful 169. ) && (tmp = m_move(mtmp,0)) && mdat->mmove <= 12) 170. return(tmp == 2); 171. if(tmp == 2) return(1); /* monster died moving */ 172. 173. if(!index("Ea", mdat->mlet) && dist(mtmp->mx, mtmp->my) < 3 && 174. !mtmp->mpeaceful && u.uhp > 0 && 175. !sengr_at("Elbereth", u.ux, u.uy) && 176. !sobj_at(SCR_SCARE_MONSTER, u.ux, u.uy)) { 177. if(mhitu(mtmp)) 178. return(1); /* monster died (e.g. 'y' or 'F') */ 179. } 180. /* extra movement for fast monsters */ 181. if(mdat->mmove-12 > rnd(12)) tmp = m_move(mtmp,1); 182. return(tmp == 2); 183. } 184. 185. inrange(mtmp) 186. register struct monst *mtmp; 187. { 188. register schar tx,ty; 189. 190. /* spit fire only when both in a room or both in a corridor */ 191. if(inroom(u.ux,u.uy) != inroom(mtmp->mx,mtmp->my)) return; 192. tx = u.ux - mtmp->mx; 193. ty = u.uy - mtmp->my; 194. if((!tx && abs(ty) < 8) || (!ty && abs(tx) < 8) 195. || (abs(tx) == abs(ty) && abs(tx) < 8)){ 196. /* spit fire in the direction of @ (not nec. hitting) */ 197. buzz(-1,mtmp->mx,mtmp->my,sgn(tx),sgn(ty)); 198. if(u.uhp < 1) done_in_by(mtmp); 199. } 200. } 201. 202. m_move(mtmp,after) 203. register struct monst *mtmp; 204. { 205. register struct monst *mtmp2; 206. register nx,ny,omx,omy,appr,nearer,cnt,i,j; 207. xchar gx,gy,nix,niy,chcnt; 208. schar chi; 209. boolean likegold, likegems, likeobjs; 210. schar mmoved = 0; /* not strictly nec.: chi >= 0 will do */ 211. coord poss[9]; 212. int info[9]; 213. 214. if(mtmp->mtrapped) { 215. i = mintrap(mtmp); 216. if(i == 2) return(2); /* he died */ 217. if(i == 1) return(0); /* still in trap, so didnt move */ 218. } 219. if(mtmp->mhide && o_at(mtmp->mx,mtmp->my) && rn2(10)) 220. return(0); /* do not leave hiding place */ 221. 222. /* my dog gets a special treatment */ 223. if(mtmp->mtame) { 224. return( dog_move(mtmp, after) ); 225. } 226. 227. /* likewise for shopkeeper */ 228. if(mtmp->isshk) { 229. mmoved = shk_move(); 230. goto postmov; 231. } 232. 233. /* and for the guard */ 234. if(mtmp->isgd) { 235. mmoved = gd_move(); 236. goto postmov; 237. } 238. 239. if(mtmp->data->mlet == 't' && !rn2(5)) { 240. if(rn2(2)) 241. mnexto(mtmp); 242. else 243. rloc(mtmp); 244. mmoved = 1; 245. goto postmov; 246. } 247. if(mtmp->data->mlet == 'D' && !mtmp->mcan) 248. inrange(mtmp); 249. if(!Blind && !Confusion && mtmp->data->mlet == 'U' && !mtmp->mcan 250. && cansee(mtmp->mx,mtmp->my) && rn2(5)) { 251. pline("%s's gaze has confused you!", Monnam(mtmp)); 252. if(rn2(5)) mtmp->mcan = 1; 253. Confusion = d(3,4); /* timeout */ 254. } 255. if(!mtmp->mflee && u.uswallow && u.ustuck != mtmp) return(1); 256. appr = 1; 257. if(mtmp->mflee) appr = -1; 258. if(mtmp->mconf || Invis || !mtmp->mcansee || 259. (index("BIy",mtmp->data->mlet) && !rn2(3))) 260. appr = 0; 261. omx = mtmp->mx; 262. omy = mtmp->my; 263. gx = u.ux; 264. gy = u.uy; 265. if(mtmp->data->mlet == 'L' && appr == 1 && mtmp->mgold > u.ugold) 266. appr = -1; 267. #ifdef TRACK 268. /* random criterion for 'smell' 269. should use mtmp->msmell 270. */ 271. if('a' <= mtmp->data->mlet && mtmp->data->mlet <= 'z') { 272. extern coord *gettrack(); 273. register coord *cp; 274. schar mroom; 275. mroom = inroom(omx,omy); 276. if(mroom < 0 || mroom != inroom(u.ux,u.uy)){ 277. cp = gettrack(omx,omy); 278. if(cp){ 279. gx = cp->x; 280. gy = cp->y; 281. } 282. } 283. } 284. #endif TRACK 285. /* look for gold or jewels nearby */ 286. likegold = (index("LOD", mtmp->data->mlet) != NULL); 287. likegems = (index("ODu", mtmp->data->mlet) != NULL); 288. likeobjs = mtmp->mhide; 289. #define SRCHRADIUS 25 290. { xchar mind = SRCHRADIUS; /* not too far away */ 291. register int dd; 292. if(likegold){ 293. register struct gen *gold; 294. for(gold = fgold; gold; gold = gold->ngen) 295. if((dd = DIST(omx,omy,gold->gx,gold->gy)) < mind){ 296. mind = dd; 297. gx = gold->gx; 298. gy = gold->gy; 299. } 300. } 301. if(likegems || likeobjs){ 302. register struct obj *otmp; 303. for(otmp = fobj; otmp; otmp = otmp->nobj) 304. if(likeobjs || otmp->olet == GEM_SYM) 305. if(mtmp->data->mlet != 'u' || 306. objects[otmp->otyp].g_val != 0) 307. if((dd = DIST(omx,omy,otmp->ox,otmp->oy)) < mind){ 308. mind = dd; 309. gx = otmp->ox; 310. gy = otmp->oy; 311. } 312. } 313. if(mind < SRCHRADIUS && appr == -1) { 314. if(dist(omx,omy) < 10) { 315. gx = u.ux; 316. gy = u.uy; 317. } else 318. appr = 1; 319. } 320. } 321. nix = omx; 322. niy = omy; 323. cnt = mfndpos(mtmp,poss,info, 324. mtmp->data->mlet == 'u' ? NOTONL : 325. index(" VWZ", mtmp->data->mlet) ? NOGARLIC : ALLOW_TRAPS); 326. /* ALLOW_ROCK for some monsters ? */ 327. chcnt = 0; 328. chi = -1; 329. for(i=0; i<cnt; i++) { 330. nx = poss[i].x; 331. ny = poss[i].y; 332. for(j=0; j<MTSZ && j<cnt-1; j++) 333. if(nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y) 334. if(rn2(4*(cnt-j))) goto nxti; 335. #ifdef STUPID 336. /* some stupid compilers think that this is too complicated */ 337. { int d1 = DIST(nx,ny,gx,gy); 338. int d2 = DIST(nix,niy,gx,gy); 339. nearer = (d1 < d2); 340. } 341. #else 342. nearer = (DIST(nx,ny,gx,gy) < DIST(nix,niy,gx,gy)); 343. #endif STUPID 344. if((appr == 1 && nearer) || (appr == -1 && !nearer) || 345. !mmoved || 346. (!appr && !rn2(++chcnt))){ 347. nix = nx; 348. niy = ny; 349. chi = i; 350. mmoved = 1; 351. } 352. nxti: ; 353. } 354. if(mmoved){ 355. if(info[chi] & ALLOW_M){ 356. mtmp2 = m_at(nix,niy); 357. if(hitmm(mtmp,mtmp2) == 1 && rn2(4) && 358. hitmm(mtmp2,mtmp) == 2) return(2); 359. return(0); 360. } 361. if(info[chi] & ALLOW_U){ 362. (void) hitu(mtmp, d(mtmp->data->damn, mtmp->data->damd)+1); 363. return(0); 364. } 365. mtmp->mx = nix; 366. mtmp->my = niy; 367. for(j=MTSZ-1; j>0; j--) mtmp->mtrack[j] = mtmp->mtrack[j-1]; 368. mtmp->mtrack[0].x = omx; 369. mtmp->mtrack[0].y = omy; 370. #ifndef NOWORM 371. if(mtmp->wormno) worm_move(mtmp); 372. #endif NOWORM 373. } else { 374. if(mtmp->data->mlet == 'u' && rn2(2)){ 375. rloc(mtmp); 376. return(0); 377. } 378. #ifndef NOWORM 379. if(mtmp->wormno) worm_nomove(mtmp); 380. #endif NOWORM 381. } 382. postmov: 383. if(mmoved == 1) { 384. if(mintrap(mtmp) == 2) /* he died */ 385. return(2); 386. if(likegold) mpickgold(mtmp); 387. if(likegems) mpickgems(mtmp); 388. if(mtmp->mhide) mtmp->mundetected = 1; 389. } 390. pmon(mtmp); 391. return(mmoved); 392. } 393. 394. mpickgold(mtmp) register struct monst *mtmp; { 395. register struct gen *gold; 396. while(gold = g_at(mtmp->mx, mtmp->my, fgold)){ 397. mtmp->mgold += gold->gflag; 398. freegold(gold); 399. if(levl[mtmp->mx][mtmp->my].scrsym == '$') 400. newsym(mtmp->mx, mtmp->my); 401. } 402. } 403. 404. mpickgems(mtmp) register struct monst *mtmp; { 405. register struct obj *otmp; 406. for(otmp = fobj; otmp; otmp = otmp->nobj) 407. if(otmp->olet == GEM_SYM) 408. if(otmp->ox == mtmp->mx && otmp->oy == mtmp->my) 409. if(mtmp->data->mlet != 'u' || objects[otmp->otyp].g_val != 0){ 410. freeobj(otmp); 411. mpickobj(mtmp, otmp); 412. if(levl[mtmp->mx][mtmp->my].scrsym == GEM_SYM) 413. newsym(mtmp->mx, mtmp->my); /* %% */ 414. return; /* pick only one object */ 415. } 416. } 417. 418. /* return number of acceptable neighbour positions */ 419. mfndpos(mon,poss,info,flag) 420. register struct monst *mon; coord poss[9]; int info[9], flag; { 421. register int x,y,nx,ny,cnt = 0,tmp; 422. register struct monst *mtmp; 423. x = mon->mx; 424. y = mon->my; 425. if(mon->mconf) { 426. flag |= ALLOW_ALL; 427. flag &= ~NOTONL; 428. } 429. for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++) 430. if(nx != x || ny != y) if(isok(nx,ny)) 431. if((tmp = levl[nx][ny].typ) >= DOOR) 432. if(!(nx != x && ny != y && 433. (levl[x][y].typ == DOOR || tmp == DOOR))){ 434. info[cnt] = 0; 435. if(nx == u.ux && ny == u.uy){ 436. if(!(flag & ALLOW_U)) continue; 437. info[cnt] = ALLOW_U; 438. } else if(mtmp = m_at(nx,ny)){ 439. if(!(flag & ALLOW_M)) continue; 440. info[cnt] = ALLOW_M; 441. if(mtmp->mtame){ 442. if(!(flag & ALLOW_TM)) continue; 443. info[cnt] |= ALLOW_TM; 444. } 445. } 446. if(sobj_at(CLOVE_OF_GARLIC, nx, ny)) { 447. if(flag & NOGARLIC) continue; 448. info[cnt] |= NOGARLIC; 449. } 450. if(sobj_at(SCR_SCARE_MONSTER, nx, ny) || 451. (!mon->mpeaceful && sengr_at("Elbereth", nx, ny))) { 452. if(!(flag & ALLOW_SSM)) continue; 453. info[cnt] |= ALLOW_SSM; 454. } 455. if(sobj_at(ENORMOUS_ROCK, nx, ny)) { 456. if(!(flag & ALLOW_ROCK)) continue; 457. info[cnt] |= ALLOW_ROCK; 458. } 459. if(!Invis && online(nx,ny)){ 460. if(flag & NOTONL) continue; 461. info[cnt] |= NOTONL; 462. } 463. /* we cannot avoid traps of an unknown kind */ 464. { register struct gen *gtmp = g_at(nx, ny, ftrap); 465. register int tt; 466. if(gtmp) { 467. tt = 1 << (gtmp->gflag & ~SEEN); 468. if(mon->mtrapseen & tt){ 469. if(!(flag & tt)) continue; 470. info[cnt] |= tt; 471. } 472. } 473. } 474. poss[cnt].x = nx; 475. poss[cnt].y = ny; 476. cnt++; 477. } 478. return(cnt); 479. } 480. 481. dist(x,y) int x,y; { 482. return((x-u.ux)*(x-u.ux) + (y-u.uy)*(y-u.uy)); 483. } 484. 485. poisoned(string, pname) 486. register char *string, *pname; 487. { 488. if(Blind) pline("It was poisoned."); 489. else pline("The %s was poisoned!",string); 490. if(Poison_resistance) { 491. pline("The poison doesn't seem to affect you."); 492. return; 493. } 494. switch(rnd(6)) { 495. case 1: 496. u.uhp = -1; 497. break; 498. case 2: 499. case 3: 500. case 4: 501. losestr(rn1(3,3)); 502. break; 503. case 5: 504. case 6: 505. losehp(rn1(10,6), pname); 506. return; 507. } 508. if(u.uhp < 1) killer = pname; 509. } 510. 511. mondead(mtmp) 512. register struct monst *mtmp; 513. { 514. relobj(mtmp,1); 515. unpmon(mtmp); 516. relmon(mtmp); 517. if(u.ustuck == mtmp) { 518. u.ustuck = 0; 519. if(u.uswallow) { 520. u.uswallow = 0; 521. setsee(); 522. docrt(); 523. } 524. } 525. if(mtmp->isshk) shkdead(); 526. if(mtmp->isgd) gddead(); 527. #ifndef NOWORM 528. if(mtmp->wormno) wormdead(mtmp); 529. #endif NOWORM 530. monfree(mtmp); 531. } 532. 533. /* called when monster is moved to larger structure */ 534. replmon(mtmp,mtmp2) 535. register struct monst *mtmp, *mtmp2; 536. { 537. relmon(mtmp); 538. monfree(mtmp); 539. mtmp2->nmon = fmon; 540. fmon = mtmp2; 541. } 542. 543. relmon(mon) 544. register struct monst *mon; 545. { 546. register struct monst *mtmp; 547. 548. if(mon == fmon) fmon = fmon->nmon; 549. else { 550. for(mtmp = fmon; mtmp->nmon != mon; mtmp = mtmp->nmon) ; 551. mtmp->nmon = mon->nmon; 552. } 553. } 554. 555. /* we do not free monsters immediately, in order to have their name 556. available shortly after their demise */ 557. struct monst *fdmon; /* chain of dead monsters, need not to be saved */ 558. 559. monfree(mtmp) register struct monst *mtmp; { 560. mtmp->nmon = fdmon; 561. fdmon = mtmp; 562. } 563. 564. dmonsfree(){ 565. register struct monst *mtmp; 566. while(mtmp = fdmon){ 567. fdmon = mtmp->nmon; 568. free((char *) mtmp); 569. } 570. } 571. 572. killed(mtmp) struct monst *mtmp; { 573. #ifdef lint 574. #define NEW_SCORING 575. #endif lint 576. register int tmp,tmp2,nk,x,y; 577. register struct permonst *mdat = mtmp->data; 578. if(mtmp->cham) mdat = PM_CHAM; 579. if(Blind) pline("You destroy it!"); 580. else { 581. pline("You destroy %s!", 582. mtmp->mtame ? amonnam(mtmp, "poor") : monnam(mtmp)); 583. } 584. if(u.umconf) { 585. if(!Blind) pline("Your hands stop glowing blue."); 586. u.umconf = 0; 587. } 588. 589. /* count killed monsters */ 590. #define MAXMONNO 100 591. nk = 1; /* in case we cannot find it in mons */ 592. tmp = mdat - mons; /* index in mons array (if not 'd', '@', ...) */ 593. if(tmp >= 0 && tmp < CMNUM+2) { 594. extern char fut_geno[]; 595. u.nr_killed[tmp]++; 596. if((nk = u.nr_killed[tmp]) > MAXMONNO && 597. !index(fut_geno, mdat->mlet)) 598. charcat(fut_geno, mdat->mlet); 599. } 600. 601. /* punish bad behaviour */ 602. if(mdat->mlet == '@') Telepat = 0, u.uluck -= 2; 603. if(mtmp->mpeaceful || mtmp->mtame) u.uluck--; 604. if(mdat->mlet == 'u') u.uluck -= 5; 605. 606. /* give experience points */ 607. tmp = 1 + mdat->mlevel * mdat->mlevel; 608. if(mdat->ac < 3) tmp += 2*(7 - mdat->ac); 609. if(index("AcsSDXaeRTVWU&In:P", mdat->mlet)) 610. tmp += 2*mdat->mlevel; 611. if(index("DeV&P",mdat->mlet)) tmp += (7*mdat->mlevel); 612. if(mdat->mlevel > 6) tmp += 50; 613. 614. #ifdef NEW_SCORING 615. /* ------- recent addition: make nr of points decrease 616. when this is not the first of this kind */ 617. { int ul = u.ulevel; 618. int ml = mdat->mlevel; 619. 620. if(ul < 14) /* points are given based on present and future level */ 621. for(tmp2 = 0; !tmp2 || ul + tmp2 <= ml; tmp2++) 622. if(u.uexp + 1 + (tmp + ((tmp2 <= 0) ? 0 : 4<<(tmp2-1)))/nk 623. >= 10*pow((unsigned)(ul-1))) 624. if(++ul == 14) break; 625. 626. tmp2 = ml - ul -1; 627. tmp = (tmp + ((tmp2 < 0) ? 0 : 4<<tmp2))/nk; 628. if(!tmp) tmp = 1; 629. } 630. /* note: ul is not necessarily the future value of u.ulevel */ 631. /* ------- end of recent valuation change ------- */ 632. #endif NEW_SCORING 633. 634. u.uexp += tmp; 635. u.urexp += 4*tmp; 636. flags.botl = 1; 637. while(u.ulevel < 14 && u.uexp >= 10*pow(u.ulevel-1)){ 638. pline("Welcome to level %d.", ++u.ulevel); 639. tmp = rnd(10); 640. if(tmp < 3) tmp = rnd(10); 641. u.uhpmax += tmp; 642. u.uhp += tmp; 643. flags.botl = 1; 644. } 645. 646. /* dispose of monster and make cadaver */ 647. x = mtmp->mx; y = mtmp->my; 648. mondead(mtmp); 649. tmp = mdat->mlet; 650. if(tmp == 'm') { /* he killed a minotaur, give him a wand of digging */ 651. /* note: the dead minotaur will be on top of it! */ 652. mksobj_at(WAND_SYM, WAN_DIGGING, x, y); 653. /* if(cansee(x,y)) atl(x,y,fobj->olet); */ 654. stackobj(fobj); 655. } else 656. #ifndef NOWORM 657. if(tmp == 'w') { 658. mksobj_at(WEAPON_SYM, WORM_TOOTH, x, y); 659. stackobj(fobj); 660. } else 661. #endif NOWORM 662. if(!letter(tmp) || !rn2(3)) tmp = 0; 663. 664. if(levl[x][y].typ >= DOOR) /* might be mimic in wall */ 665. if(x != u.ux || y != u.uy) /* might be here after swallowed */ 666. if(index("NTVm&",mdat->mlet) || rn2(5)) { 667. mkobj_at(tmp,x,y); 668. if(cansee(x,y)) atl(x,y,fobj->olet); 669. stackobj(fobj); 670. } 671. } 672. 673. kludge(str,arg) 674. register char *str,*arg; 675. { 676. if(Blind) { 677. if(*str == '%') pline(str,"It"); 678. else pline(str,"it"); 679. } else pline(str,arg); 680. } 681. 682. rescham() /* force all chameleons to become normal */ 683. { 684. register struct monst *mtmp; 685. 686. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 687. if(mtmp->cham) { 688. mtmp->cham = 0; 689. (void) newcham(mtmp,PM_CHAM); 690. } 691. } 692. 693. newcham(mtmp,mdat) /* make a chameleon look like a new monster */ 694. /* returns 1 if the monster actually changed */ 695. register struct monst *mtmp; 696. register struct permonst *mdat; 697. { 698. register mhp, hpn, hpd; 699. 700. if(mdat == mtmp->data) return(0); /* still the same monster */ 701. #ifndef NOWORM 702. if(mtmp->wormno) wormdead(mtmp); /* throw tail away */ 703. #endif NOWORM 704. hpn = mtmp->mhp; 705. hpd = (mtmp->data->mlevel)*8; 706. if(!hpd) hpd = 4; 707. mtmp->data = mdat; 708. mhp = (mdat->mlevel)*8; 709. /* new hp: same fraction of max as before */ 710. mtmp->mhp = 2 + (hpn*mhp)/hpd; 711. hpn = mtmp->orig_hp; 712. mtmp->orig_hp = 2 + (hpn*mhp)/hpd; 713. mtmp->minvis = (mdat->mlet == 'I') ? 1 : 0; 714. #ifndef NOWORM 715. if(mdat->mlet == 'w' && getwn(mtmp)) initworm(mtmp); 716. #endif NOWORM 717. unpmon(mtmp); /* necessary for 'I' and to force pmon */ 718. pmon(mtmp); 719. return(1); 720. } 721. 722. mnexto(mtmp) /* Make monster mtmp next to you (if possible) */ 723. struct monst *mtmp; 724. { 725. extern coord enexto(); 726. coord mm; 727. mm = enexto(u.ux, u.uy); 728. mtmp->mx = mm.x; 729. mtmp->my = mm.y; 730. pmon(mtmp); 731. } 732. 733. rloc(mtmp) 734. struct monst *mtmp; 735. { 736. register tx,ty; 737. register char ch = mtmp->data->mlet; 738. 739. #ifndef NOWORM 740. if(ch == 'w' && mtmp->mx) return; /* do not relocate worms */ 741. #endif NOWORM 742. do { 743. tx = rn1(COLNO-3,2); 744. ty = rn2(ROWNO); 745. } while(!goodpos(tx,ty)); 746. mtmp->mx = tx; 747. mtmp->my = ty; 748. if(u.ustuck == mtmp){ 749. if(u.uswallow) { 750. u.ux = tx; 751. u.uy = ty; 752. docrt(); 753. } else u.ustuck = 0; 754. } 755. pmon(mtmp); 756. } 757. 758. ishuman(mtmp) register struct monst *mtmp; { 759. return(mtmp->data->mlet == '@'); 760. } 761. 762. setmangry(mtmp) register struct monst *mtmp; { 763. if(!mtmp->mpeaceful) return; 764. if(mtmp->mtame) return; 765. mtmp->mpeaceful = 0; 766. if(ishuman(mtmp)) pline("%s gets angry!", Monnam(mtmp)); 767. }