Source:NetHack 3.0.0/makemon.c
Revision as of 04:51, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 3.0.0/makemon.c moved to Source:NetHack 3.0.0/makemon.c: Robot: moved page)
Below is the full text to makemon.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/makemon.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.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
1. /* SCCS Id: @(#)makemon.c 3.0 88/04/11 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. 7. struct monst zeromonst; 8. static int uncommon P((struct permonst *)); 9. 10. static int monstr[NUMMONS]; 11. 12. #define m_initsgrp(mtmp, x, y) m_initgrp(mtmp, x, y, 3) 13. #define m_initlgrp(mtmp, x, y) m_initgrp(mtmp, x, y, 10) 14. #define toostrong(monindx, lev) (monstr[monindx] > lev) 15. #define tooweak(monindx, lev) (monstr[monindx] < lev) 16. 17. static void 18. m_initgrp(mtmp, x, y, n) /* make a group just like mtmp */ 19. register struct monst *mtmp; 20. register int x, y, n; 21. { 22. coord mm; 23. register int cnt = rnd(n); 24. struct monst *mon; 25. 26. mm.x = x; 27. mm.y = y; 28. while(cnt--) { 29. if (peace_minded(mtmp->data)) continue; 30. /* Don't create groups of peaceful monsters since they'll get 31. * in our way. If the monster has a percentage chance so some 32. * are peaceful and some are not, the result will just be a 33. * smaller group. 34. */ 35. enexto(&mm, mm.x, mm.y); 36. mon = makemon(mtmp->data, mm.x, mm.y); 37. mon->mpeaceful = 0; 38. set_malign(mon); 39. /* Undo the second peace_minded() check in makemon(); if the 40. * monster turned out to be peaceful the first time we didn't 41. * create it at all; we don't want a second check. 42. */ 43. } 44. } 45. 46. static void 47. m_initthrow(mtmp,otyp,oquan) 48. struct monst *mtmp; 49. int otyp,oquan; 50. { 51. register struct obj *otmp; 52. 53. otmp = mksobj(otyp,FALSE); 54. otmp->quan = 2 + rnd(oquan); 55. otmp->owt = weight(otmp); 56. #ifdef TOLKIEN 57. if (otyp == ORCISH_ARROW) otmp->opoisoned = 1; 58. #endif 59. mpickobj(mtmp, otmp); 60. } 61. 62. static void 63. m_initweap(mtmp) 64. register struct monst *mtmp; 65. { 66. register struct permonst *ptr = mtmp->data; 67. #ifdef REINCARNATION 68. if (dlevel==rogue_level) return; 69. #endif 70. /* 71. * first a few special cases: 72. * 73. * giants get a boulder to throw sometimes. 74. * ettins get clubs 75. * kobolds get darts to throw 76. * centaurs get some sort of bow & arrows or bolts 77. * soldiers get all sorts of things. 78. * kops get clubs & cream pies. 79. */ 80. switch (mtmp->data->mlet) { 81. case S_GIANT: 82. if (rn2(2)) (void)mongets(mtmp, (ptr != &mons[PM_ETTIN]) ? 83. BOULDER : CLUB); 84. break; 85. case S_HUMAN: 86. if(is_mercenary(ptr)) 87. switch(monsndx(ptr)) { 88. 89. #ifdef ARMY 90. case PM_SOLDIER: 91. (void) mongets(mtmp, rn2(2) ? SPEAR : SHORT_SWORD); 92. break; 93. case PM_SERGEANT: 94. (void) mongets(mtmp, rn2(2) ? FLAIL : MACE); 95. break; 96. case PM_LIEUTENANT: 97. (void) mongets(mtmp, rn2(2) ? GLAIVE : LONG_SWORD); 98. break; 99. case PM_CAPTAIN: 100. (void) mongets(mtmp, rn2(2) ? LONG_SWORD : SCIMITAR); 101. break; 102. #endif 103. default: if (!rn2(4)) (void) mongets(mtmp, DAGGER); 104. if (!rn2(7)) (void) mongets(mtmp, SPEAR); 105. break; 106. } 107. break; 108. 109. case S_HUMANOID: 110. #ifdef TOLKIEN 111. if (monsndx(ptr) == PM_HOBBIT) { 112. switch (rn2(3)) { 113. case 0: 114. (void)mongets(mtmp, DAGGER); 115. break; 116. case 1: 117. (void)mongets(mtmp, ELVEN_DAGGER); 118. break; 119. } 120. if (!rn2(10)) (void)mongets(mtmp, ELVEN_MITHRIL_COAT); 121. } else if (is_dwarf(ptr)) { 122. (void)mongets(mtmp, DWARVISH_CLOAK); 123. (void)mongets(mtmp, IRON_SHOES); 124. if (!rn2(4)) { 125. (void)mongets(mtmp, DWARVISH_SHORT_SWORD); 126. (void)mongets(mtmp, 127. rn2(3) ? DWARVISH_MATTOCK : AXE); 128. (void)mongets(mtmp, DWARVISH_IRON_HELM); 129. (void)mongets(mtmp, DWARVISH_ROUNDSHIELD); 130. if (!rn2(3)) 131. (void)mongets(mtmp, DWARVISH_MITHRIL_COAT); 132. } else { 133. (void)mongets(mtmp, PICK_AXE); 134. } 135. } else if (is_elf(ptr)) { 136. (void)mongets(mtmp, 137. rn2(2) ? ELVEN_MITHRIL_COAT : ELVEN_CLOAK); 138. if (rn2(2)) (void)mongets(mtmp, ELVEN_LEATHER_HELM); 139. if (rn2(3)) (void)mongets(mtmp, ELVEN_DAGGER); 140. switch (rn2(3)) { 141. case 0: 142. if (!rn2(4)) (void)mongets(mtmp, ELVEN_SHIELD); 143. (void)mongets(mtmp, ELVEN_SHORT_SWORD); 144. (void)mongets(mtmp, ELVEN_BOW); 145. m_initthrow(mtmp, ELVEN_ARROW, 12); 146. break; 147. case 1: 148. (void)mongets(mtmp, ELVEN_BROADSWORD); 149. if (rn2(2)) (void)mongets(mtmp, ELVEN_SHIELD); 150. break; 151. case 2: 152. (void)mongets(mtmp, ELVEN_SPEAR); 153. (void)mongets(mtmp, ELVEN_SHIELD); 154. break; 155. } 156. } 157. #else /* TOLKIEN */ 158. if (is_dwarf(ptr)) { 159. (void)mongets(mtmp, IRON_SHOES); 160. if (rn2(4) == 0) { 161. (void)mongets(mtmp, SHORT_SWORD); 162. (void)mongets(mtmp, 163. (rn2(3) == 0) ? AXE : TWO_HANDED_SWORD); 164. (void)mongets(mtmp, LARGE_SHIELD); 165. if (rn2(3) == 0) 166. (void)mongets(mtmp, DWARVISH_MITHRIL_COAT); 167. } else { 168. (void)mongets(mtmp, PICK_AXE); 169. } 170. } else if (is_elf(ptr)) { 171. (void)mongets(mtmp, ELVEN_CLOAK); 172. if (rn2(3)) (void)mongets(mtmp, DAGGER); 173. switch (rn2(3)) { 174. case 0: 175. if (!rn2(4)) (void)mongets(mtmp, SMALL_SHIELD); 176. (void)mongets(mtmp, SHORT_SWORD); 177. (void)mongets(mtmp, BOW); 178. m_initthrow(mtmp, ARROW, 12); 179. break; 180. case 1: 181. (void)mongets(mtmp, BROADSWORD); 182. if (rn2(2)) (void)mongets(mtmp, SMALL_SHIELD); 183. break; 184. case 2: 185. (void)mongets(mtmp, SPEAR); 186. (void)mongets(mtmp, SMALL_SHIELD); 187. break; 188. } 189. } 190. #endif /* TOLKIEN */ 191. break; 192. # ifdef KOPS 193. case S_KOP: /* create Keystone Kops with cream pies to 194. * throw. As suggested by KAA. [MRS] 195. */ 196. if (!rn2(4)) m_initthrow(mtmp, CREAM_PIE, 2); 197. if (!rn2(3)) (void)mongets(mtmp, (rn2(2)) ? CLUB : RUBBER_HOSE); 198. break; 199. #endif 200. case S_ORC: 201. #ifdef TOLKIEN 202. { int mm = monsndx(ptr); 203. if(rn2(2)) (void)mongets(mtmp, ORCISH_HELM); 204. if (mm == PM_MORDOR_ORC || 205. (mm == PM_ORC_CAPTAIN && rn2(2))) { 206. if(rn2(2)) (void)mongets(mtmp, SCIMITAR); 207. if(rn2(2)) (void)mongets(mtmp, ORCISH_SHIELD); 208. if(rn2(2)) (void)mongets(mtmp, KNIFE); 209. if(rn2(2)) (void)mongets(mtmp, ORCISH_CHAIN_MAIL); 210. } else if (mm == PM_URUK_HAI || mm == PM_ORC_CAPTAIN) { 211. if(rn2(2)) (void)mongets(mtmp, ORCISH_CLOAK); 212. if(rn2(2)) (void)mongets(mtmp, ORCISH_SHORT_SWORD); 213. if(rn2(2)) (void)mongets(mtmp, IRON_SHOES); 214. if(rn2(2)) { 215. (void)mongets(mtmp, ORCISH_BOW); 216. m_initthrow(mtmp, ORCISH_ARROW, 12); 217. } 218. if(rn2(2)) (void)mongets(mtmp, URUK_HAI_SHIELD); 219. } else if (mm != PM_ORC_SHAMAN) { 220. (void)mongets(mtmp, (mm == PM_GOBLIN || rn2(2) == 0) ? 221. ORCISH_DAGGER : SCIMITAR); 222. } 223. } 224. #else /* TOLKIEN */ 225. { int mm = monsndx(ptr); 226. if(rn2(2)) (void)mongets(mtmp, ORCISH_HELM); 227. if (mm == PM_ORC_CAPTAIN) { 228. if(rn2(2)) { 229. if(rn2(2)) (void)mongets(mtmp, SCIMITAR); 230. if(rn2(2)) (void)mongets(mtmp, SMALL_SHIELD); 231. if(rn2(2)) (void)mongets(mtmp, KNIFE); 232. if(rn2(2)) (void)mongets(mtmp, CHAIN_MAIL); 233. } else { 234. if(rn2(2)) (void)mongets(mtmp, SHORT_SWORD); 235. if(rn2(2)) (void)mongets(mtmp, IRON_SHOES); 236. if(rn2(2)) { 237. (void)mongets(mtmp, BOW); 238. m_initthrow(mtmp, ARROW, 12); 239. } 240. if(rn2(2)) (void)mongets(mtmp, SMALL_SHIELD); 241. } 242. } else if (mm != PM_ORC_SHAMAN) { 243. (void)mongets(mtmp, (mm == PM_GOBLIN || rn2(2) == 0) ? 244. DAGGER : SCIMITAR); 245. } 246. } 247. #endif /* TOLKIEN */ 248. break; 249. case S_KOBOLD: 250. if (!rn2(4)) m_initthrow(mtmp, DART, 12); 251. break; 252. 253. case S_CENTAUR: 254. if (rn2(2)) { 255. if(ptr == &mons[PM_FOREST_CENTAUR]) { 256. (void)mongets(mtmp, BOW); 257. m_initthrow(mtmp, ARROW, 12); 258. } else { 259. (void)mongets(mtmp, CROSSBOW); 260. m_initthrow(mtmp, CROSSBOW_BOLT, 12); 261. } 262. } 263. break; 264. case S_WRAITH: 265. (void)mongets(mtmp, KNIFE); 266. (void)mongets(mtmp, LONG_SWORD); 267. break; 268. case S_DEMON: 269. #ifdef HARD 270. if (monsndx(ptr) == PM_BALROG) { 271. (void)mongets(mtmp, BULLWHIP); 272. (void)mongets(mtmp, BROADSWORD); 273. break; 274. } 275. #endif 276. /* prevent djinnis and mail daemons from leaving objects when 277. * they vanish 278. */ 279. if (!is_demon(ptr)) break; 280. /* fall thru */ 281. /* 282. * Now the general case, ~40% chance of getting some type 283. * of weapon. TODO: Add more weapons types (use bigmonst()); 284. */ 285. default: 286. switch(rnd(12)) { 287. case 1: 288. m_initthrow(mtmp, DART, 12); 289. break; 290. case 2: 291. (void) mongets(mtmp, CROSSBOW); 292. m_initthrow(mtmp, CROSSBOW_BOLT, 12); 293. break; 294. case 3: 295. (void) mongets(mtmp, BOW); 296. m_initthrow(mtmp, ARROW, 12); 297. break; 298. case 4: 299. m_initthrow(mtmp, DAGGER, 3); 300. break; 301. case 5: 302. (void) mongets(mtmp, AKLYS); 303. break; 304. default: 305. break; 306. } 307. break; 308. } 309. } 310. 311. static void 312. m_initinv(mtmp) 313. register struct monst *mtmp; 314. { 315. register int cnt; 316. register struct obj *otmp; 317. register struct permonst *ptr = mtmp->data; 318. #ifdef REINCARNATION 319. if (dlevel==rogue_level) return; 320. #endif 321. /* 322. * Soldiers get armour & rations - armour approximates their ac. 323. * Nymphs may get mirror or potion of object detection. 324. */ 325. switch(mtmp->data->mlet) { 326. 327. case S_HUMAN: 328. if(is_mercenary(ptr)) { 329. register int mac; 330. 331. if((mac = ptr->ac) < -1) 332. mac += 7 + mongets(mtmp, (rn2(5)) ? 333. PLATE_MAIL : CRYSTAL_PLATE_MAIL); 334. else if(mac < 3) 335. mac += 6 + mongets(mtmp, (rn2(3)) ? 336. SPLINT_MAIL : BANDED_MAIL); 337. else 338. mac += 3 + mongets(mtmp, (rn2(3)) ? 339. RING_MAIL : STUDDED_LEATHER_ARMOR); 340. 341. if(mac < 10) { 342. mac += 1 + mongets(mtmp, HELMET); 343. if(mac < 10) { 344. mac += 1 + mongets(mtmp, SMALL_SHIELD); 345. if(mac < 10) { 346. mac += 1 + mongets(mtmp, ELVEN_CLOAK); 347. if(mac < 10) 348. mac += 1 +mongets(mtmp, LEATHER_GLOVES); 349. } 350. } 351. } 352. 353. if(mac != 10) { /* make up the difference */ 354. otmp = mksobj(RIN_PROTECTION,FALSE); 355. otmp->spe = (10 - mac); 356. if(otmp->spe < 0) curse(otmp); 357. mpickobj(mtmp, otmp); 358. } 359. #ifdef ARMY 360. if(ptr != &mons[PM_GUARD]) { 361. if (!rn2(3)) (void) mongets(mtmp, K_RATION); 362. if (!rn2(2)) (void) mongets(mtmp, C_RATION); 363. } 364. #endif 365. } 366. break; 367. 368. case S_NYMPH: 369. #ifdef MEDUSA 370. if(!rn2(2)) (void) mongets(mtmp, MIRROR); 371. #endif 372. if(!rn2(2)) (void) mongets(mtmp, POT_OBJECT_DETECTION); 373. break; 374. 375. case S_GIANT: 376. if(mtmp->data == &mons[PM_MINOTAUR]) 377. (void) mongets(mtmp, WAN_DIGGING); 378. else if (is_giant(mtmp->data)) { 379. for(cnt = rn2((int)(mtmp->m_lev / 2)); cnt; cnt--) { 380. do 381. otmp = mkobj(GEM_SYM,FALSE); 382. while (otmp->otyp >= LAST_GEM+5); 383. otmp->quan = 2 + rnd(2); 384. otmp->owt = weight(otmp); 385. mpickobj(mtmp, otmp); 386. } 387. } 388. break; 389. #ifdef TOLKIEN 390. case S_WRAITH: 391. if(mtmp->data == &mons[PM_NAZGUL]) { 392. otmp = mksobj(RIN_INVISIBILITY, FALSE); 393. curse(otmp); 394. mpickobj(mtmp, otmp); 395. } 396. break; 397. #endif 398. default: 399. break; 400. } 401. } 402. 403. /* 404. * called with [x,y] = coordinates; 405. * [0,0] means anyplace 406. * [u.ux,u.uy] means: call mnexto (if !in_mklev) 407. * 408. * In case we make a monster group, only return the one at [x,y]. 409. */ 410. struct monst * 411. makemon(ptr, x, y) 412. register struct permonst *ptr; 413. register int x, y; 414. { 415. register struct monst *mtmp; 416. register int ct; 417. boolean anything = (!ptr); 418. 419. /* if caller wants random location, do it here */ 420. if(x == 0 && y == 0) { 421. do { 422. x = rn1(COLNO-3,2); 423. y = rn2(ROWNO); 424. } while(!goodpos(x, y)); 425. } 426. 427. /* if a monster already exists at the position, return */ 428. if(levl[x][y].mmask) return((struct monst *) 0); 429. 430. if(ptr){ 431. /* if you are to make a specific monster and it has 432. already been genocided, return */ 433. if(ptr->geno & G_GENOD) return((struct monst *) 0); 434. } else { 435. /* make a random (common) monster. */ 436. #ifdef REINCARNATION 437. if (!(ptr = (dlevel==rogue_level) ? roguemon() : rndmonst())) 438. #else 439. if(!(ptr = rndmonst())) 440. #endif 441. { 442. #ifdef DEBUG 443. pline("Warning: no monster."); 444. #endif 445. return((struct monst *) 0); /* no more monsters! */ 446. } 447. } 448. /* if it's unique, don't ever make it again */ 449. if (ptr->geno & G_UNIQ) ptr->geno &= G_GENOD; 450. /* gotmon: /* label not referenced */ 451. mtmp = newmonst(ptr->pxlth); 452. *mtmp = zeromonst; /* clear all entries in structure */ 453. for(ct = 0; ct < ptr->pxlth; ct++) 454. ((char *) &(mtmp->mextra[0]))[ct] = 0; 455. if(type_is_pname(ptr)) 456. Strcpy(NAME(mtmp), ptr->mname); 457. mtmp->nmon = fmon; 458. fmon = mtmp; 459. mtmp->m_id = flags.ident++; 460. mtmp->data = ptr; 461. mtmp->mxlth = ptr->pxlth; 462. 463. mtmp->m_lev = adj_lev(ptr); 464. #ifdef GOLEMS 465. if (is_golem(ptr)) 466. mtmp->mhpmax = mtmp->mhp = golemhp(monsndx(ptr)); 467. else 468. #endif /* GOLEMS */ 469. if(ptr->mlevel > 49) { 470. /* "special" fixed hp monster 471. * the hit points are encoded in the mlevel in a somewhat strange 472. * way to fit in the 50..127 positive range of a signed character 473. * above the 1..49 that indicate "normal" monster levels */ 474. mtmp->mhpmax = mtmp->mhp = 2*(ptr->mlevel - 6); 475. mtmp->m_lev = mtmp->mhp / 4; /* approximation */ 476. } else if((ptr->mlet == S_DRAGON) && (ptr >= &mons[PM_GREY_DRAGON])) 477. mtmp->mhpmax = mtmp->mhp = 80; 478. else if(!mtmp->m_lev) mtmp->mhpmax = mtmp->mhp = rnd(4); 479. else mtmp->mhpmax = mtmp->mhp = d((int)mtmp->m_lev, 8); 480. mtmp->mx = x; 481. mtmp->my = y; 482. levl[x][y].mmask = 1; 483. mtmp->mcansee = 1; 484. mtmp->mpeaceful = peace_minded(ptr); 485. 486. switch(ptr->mlet) { 487. case S_MIMIC: 488. set_mimic_sym(mtmp); 489. break; 490. case S_SPIDER: 491. case S_SNAKE: 492. mtmp->mhide = mtmp->mundetected = 1; 493. if(in_mklev) 494. if(mtmp->mx && mtmp->my) 495. (void) mkobj_at(0, mtmp->mx, mtmp->my); 496. break; 497. case S_CHAMELEON: 498. /* If you're protected with a ring, don't create 499. * any shape-changing chameleons -dgk 500. */ 501. if (Protection_from_shape_changers) 502. mtmp->cham = 0; 503. else { 504. mtmp->cham = 1; 505. (void) newcham(mtmp, rndmonst()); 506. } 507. break; 508. case S_STALKER: 509. case S_EEL: 510. mtmp->minvis = 1; 511. break; 512. case S_LEPRECHAUN: 513. mtmp->msleep = 1; 514. break; 515. case S_NYMPH: 516. if(rn2(5) && !u.uhave_amulet) mtmp->msleep = 1; 517. break; 518. case S_UNICORN: 519. if ((ptr==&mons[PM_WHITE_UNICORN] && 520. u.ualigntyp == U_LAWFUL) || 521. (ptr==&mons[PM_GREY_UNICORN] && 522. u.ualigntyp == U_NEUTRAL) || 523. (ptr==&mons[PM_BLACK_UNICORN] && 524. u.ualigntyp == U_CHAOTIC)) 525. mtmp->mpeaceful = 1; 526. break; 527. } 528. if (ptr == &mons[PM_WIZARD_OF_YENDOR]) { 529. mtmp->iswiz = 1; 530. flags.no_of_wizards++; 531. } 532. 533. if(in_mklev) { 534. if(((is_ndemon(ptr)) || 535. (ptr == &mons[PM_WUMPUS]) || 536. #ifdef WORM 537. (ptr == &mons[PM_LONG_WORM]) || 538. #endif 539. (ptr == &mons[PM_GIANT_EEL])) && rn2(5)) 540. mtmp->msleep = 1; 541. } else { 542. if(x == u.ux && y == u.uy && ptr->mlet != S_GHOST) { 543. mnexto(mtmp); 544. if (ptr->mlet == S_MIMIC) set_mimic_sym(mtmp); 545. } 546. } 547. #ifdef HARD 548. if(is_dprince(ptr)) { 549. mtmp->mpeaceful = mtmp->minvis = 1; 550. # ifdef NAMED_ITEMS 551. if(uwep) 552. if(!strcmp(ONAME(uwep), "Excalibur")) 553. mtmp->mpeaceful = mtmp->mtame = 0; 554. # endif 555. } 556. #endif 557. #ifdef WORM 558. if(ptr == &mons[PM_LONG_WORM] && getwn(mtmp)) initworm(mtmp); 559. #endif 560. set_malign(mtmp); /* having finished peaceful changes */ 561. if(anything) { 562. if((ptr->geno & G_SGROUP) && rn2(2)) 563. m_initsgrp(mtmp, mtmp->mx, mtmp->my); 564. else if(ptr->geno & G_LGROUP) { 565. if(rn2(3)) m_initlgrp(mtmp, mtmp->mx, mtmp->my); 566. else m_initsgrp(mtmp, mtmp->mx, mtmp->my); 567. } 568. } 569. 570. if(is_armed(ptr)) 571. m_initweap(mtmp); /* equip with weapons / armour */ 572. m_initinv(mtmp); /* add on a few special items */ 573. 574. return(mtmp); 575. } 576. 577. void 578. enexto(cc, xx,yy) 579. coord *cc; 580. register xchar xx, yy; 581. { 582. register xchar x,y; 583. coord foo[15], *tfoo; 584. int range, i; 585. 586. tfoo = foo; 587. range = 1; 588. do { /* full kludge action. */ 589. for(x = xx-range; x <= xx+range; x++) 590. if(goodpos(x, yy-range)) { 591. tfoo->x = x; 592. (tfoo++)->y = yy-range; 593. if(tfoo == &foo[15]) goto foofull; 594. } 595. for(x = xx-range; x <= xx+range; x++) 596. if(goodpos(x,yy+range)) { 597. tfoo->x = x; 598. (tfoo++)->y = yy+range; 599. if(tfoo == &foo[15]) goto foofull; 600. } 601. for(y = yy+1-range; y < yy+range; y++) 602. if(goodpos(xx-range,y)) { 603. tfoo->x = xx-range; 604. (tfoo++)->y = y; 605. if(tfoo == &foo[15]) goto foofull; 606. } 607. for(y = yy+1-range; y < yy+range; y++) 608. if(goodpos(xx+range,y)) { 609. tfoo->x = xx+range; 610. (tfoo++)->y = y; 611. if(tfoo == &foo[15]) goto foofull; 612. } 613. range++; 614. } while(tfoo == foo); 615. foofull: 616. i = rn2(tfoo - foo); 617. cc->x = foo[i].x; 618. cc->y = foo[i].y; 619. return; 620. } 621. 622. int 623. goodpos(x, y) 624. { 625. #ifdef STUPID 626. if (x < 1 || x > COLNO-2 || y < 1 || y > ROWNO-2 || 627. levl[x][y].mmask || !ACCESSIBLE(levl[x][y].typ)) 628. return 0; 629. if (IS_DOOR(levl[x][y].typ) && 630. (levl[x][y].doormask & (D_LOCKED | D_CLOSED))) 631. return 0; 632. return !((x == u.ux && y == u.uy) || sobj_at(BOULDER, x, y)); 633. #else 634. return 635. ! (x < 1 || x > COLNO-2 || y < 1 || y > ROWNO-2 || 636. levl[x][y].mmask || !ACCESSIBLE(levl[x][y].typ) || 637. (IS_DOOR(levl[x][y].typ) && 638. (levl[x][y].doormask & (D_LOCKED | D_CLOSED)) ) 639. || (x == u.ux && y == u.uy) 640. || sobj_at(BOULDER, x, y) 641. ); 642. #endif /* STUPID */ 643. } 644. 645. void 646. rloc(mtmp) 647. struct monst *mtmp; 648. { 649. register int tx, ty; 650. 651. #ifdef WORM /* do not relocate worms */ 652. if(mtmp->wormno && mtmp->mx) return; 653. #endif 654. /* if the wiz teleports away to heal, try the up staircase, 655. to block the player's escaping before he's healed */ 656. if(!mtmp->iswiz || !goodpos(tx = xupstair, ty = yupstair)) 657. do { 658. tx = rn1(COLNO-3,2); 659. ty = rn2(ROWNO); 660. } while(!goodpos(tx,ty)); 661. if(mtmp->mx != 0 && mtmp->my != 0) 662. levl[mtmp->mx][mtmp->my].mmask = 0; 663. mtmp->mx = tx; 664. mtmp->my = ty; 665. levl[tx][ty].mmask = 1; 666. if(u.ustuck == mtmp){ 667. if(u.uswallow) { 668. u.ux = tx; 669. u.uy = ty; 670. docrt(); 671. } else u.ustuck = 0; 672. } 673. pmon(mtmp); 674. set_apparxy(mtmp); 675. } 676. 677. struct monst * 678. mkmon_at(name, x, y) 679. char *name; 680. register int x,y; 681. { 682. register int ct; 683. register struct permonst *ptr; 684. 685. for(ct = PM_CHAMELEON; ct >= 0; ct--) { /* Chameleon is last monster */ 686. ptr = &mons[ct]; 687. if(!strcmp(ptr->mname, name)) 688. return(makemon(ptr, x, y)); 689. } 690. return((struct monst *)0); 691. } 692. 693. static int 694. cmnum() { /* return the number of "common" monsters */ 695. 696. int i, count; 697. 698. for(i = count = 0; mons[i].mlet; i++) 699. if(!uncommon(&mons[i])) count++; 700. 701. return(count); 702. } 703. 704. static int 705. uncommon(ptr) 706. struct permonst *ptr; 707. { 708. return (ptr->geno & (G_GENOD | G_NOGEN | G_UNIQ)) || 709. (!Inhell ? ptr->geno & G_HELL : ptr->maligntyp > 0); 710. } 711. 712. /* This routine is designed to return an integer value which represents 713. * an approximation of monster strength. It uses a similar method of 714. * determination as "experience()" to arrive at the strength. 715. */ 716. static int 717. mstrength(ptr) 718. struct permonst *ptr; 719. { 720. int i, tmp2, n, tmp = ptr->mlevel; 721. 722. if(tmp > 49) /* special fixed hp monster */ 723. tmp = 2*(tmp - 6) / 4; 724. 725. /* For creation in groups */ 726. n = (!!(ptr->geno & G_SGROUP)); 727. n += (!!(ptr->geno & G_LGROUP)) << 1; 728. 729. /* For higher ac values */ 730. n += (ptr->ac < 0); 731. 732. /* For very fast monsters */ 733. n += (ptr->mmove >= 18); 734. 735. /* For each attack and "special" attack */ 736. for(i = 0; i < NATTK; i++) { 737. 738. tmp2 = ptr->mattk[i].aatyp; 739. n += (tmp2 > 0); 740. n += (tmp2 == AT_MAGC); 741. } 742. 743. /* For each "special" damage type */ 744. for(i = 0; i < NATTK; i++) { 745. 746. tmp2 = ptr->mattk[i].adtyp; 747. if((tmp2 == AD_DRLI) || (tmp2 == AD_STON)) n += 2; 748. else n += (tmp2 != AD_PHYS); 749. n += ((ptr->mattk[i].damd * ptr->mattk[i].damn) > 23); 750. } 751. 752. /* Finally, adjust the monster level 0 <= n <= 24 (approx.) */ 753. if(n == 0) tmp--; 754. else if(n >= 6) tmp += ( n / 2 ); 755. else tmp += ( n / 3 + 1); 756. 757. return((tmp >= 0) ? tmp : 0); 758. } 759. 760. void 761. init_monstr() 762. { 763. register int ct; 764. 765. for(ct = 0; mons[ct].mlet; ct++) 766. monstr[ct] = mstrength(&(mons[ct])); 767. } 768. 769. struct permonst * 770. rndmonst() { /* select a random monster */ 771. register struct permonst *ptr; 772. register int i, ct; 773. register int zlevel; 774. static int minmlev, maxmlev, accept; 775. static long oldmoves = 0L; /* != 1, starting value of moves */ 776. 777. if(oldmoves != moves) { /* must recalculate accept */ 778. oldmoves = moves; 779. zlevel = u.uhave_amulet ? MAXLEVEL : dlevel; 780. if(cmnum() <= 0) { 781. #ifdef DEBUG 782. pline("cmnum() fails!"); 783. #endif 784. return((struct permonst *) 0); 785. } 786. 787. /* determine the level of the weakest monster to make. */ 788. minmlev = zlevel/6; 789. /* determine the level of the strongest monster to make. */ 790. maxmlev = (zlevel + u.ulevel)>>1; 791. /* 792. * Find out how many monsters exist in the range we have selected. 793. */ 794. for(accept = ct = 0 ; mons[ct].mlet; ct++) { 795. ptr = &(mons[ct]); 796. if(uncommon(ptr)) continue; 797. if(tooweak(ct, minmlev) || toostrong(ct, maxmlev)) 798. continue; 799. accept += (ptr->geno & G_FREQ); 800. } 801. } 802. 803. if(!accept) { 804. #ifdef DEBUG 805. pline("no accept!"); 806. #endif 807. return((struct permonst *) 0); 808. } 809. /* 810. * Now, select a monster at random. 811. */ 812. ct = rnd(accept); 813. for(i = 0; mons[i].mlet && ct > 0; i++) { 814. ptr = &(mons[i]); 815. if(uncommon(ptr)) continue; 816. if(tooweak(i, minmlev) || toostrong(i, maxmlev)) 817. continue; 818. ct -= (ptr->geno & G_FREQ); 819. } 820. if(ct > 0) { 821. #ifdef DEBUG 822. pline("no count!"); 823. #endif 824. return((struct permonst *) 0); 825. } 826. return(ptr); 827. } 828. 829. /* The routine below is used to make one of the multiple types 830. * of a given monster class. It will return 0 if no monsters 831. * in that class can be made. 832. */ 833. 834. struct permonst * 835. mkclass(mlet) 836. char mlet; 837. { 838. register int first, last, num = 0; 839. 840. if(!mlet) { 841. impossible("mkclass called with null arg!"); 842. return((struct permonst *) 0); 843. } 844. /* Assumption #1: monsters of a given class are contiguous in the 845. * mons[] array. 846. */ 847. for(first = 0; mons[first].mlet != mlet; first++) 848. if(!mons[first].mlet) return((struct permonst *) 0); 849. 850. for(last = first; mons[last].mlet && mons[last].mlet == mlet; last++) 851. if(!(mons[last].geno & (G_GENOD | G_NOGEN | G_UNIQ))) 852. num += mons[last].geno & G_FREQ; 853. 854. if(!num) return((struct permonst *) 0); 855. 856. /* Assumption #2: monsters of a given class are presented in ascending 857. * order of strength. 858. */ 859. for(num = rnd(num); num > 0; first++) 860. if(!(mons[first].geno & (G_GENOD | G_NOGEN | G_UNIQ))) { /* consider it */ 861. /* skew towards lower value monsters at lower exp. levels */ 862. if(adj_lev(&mons[first]) > (u.ulevel*2)) num--; 863. num -= mons[first].geno & G_FREQ; 864. } 865. first--; /* correct an off-by-one error */ 866. 867. return(&mons[first]); 868. } 869. 870. int 871. adj_lev(ptr) /* adjust strength of monsters based on dlevel and u.ulevel */ 872. register struct permonst *ptr; 873. { 874. int tmp, tmp2; 875. 876. if((tmp = ptr->mlevel) > 49) return(50); /* "special" demons/devils */ 877. tmp2 = (dlevel - tmp); 878. if(tmp2 < 0) tmp--; /* if mlevel > dlevel decrement tmp */ 879. else tmp += (tmp2 / 5); /* else increment 1 per five diff */ 880. 881. tmp2 = (u.ulevel - ptr->mlevel); /* adjust vs. the player */ 882. if(tmp2 > 0) tmp += (tmp2 / 4); /* level as well */ 883. 884. tmp2 = 3 * ptr->mlevel/ 2; /* crude upper limit */ 885. return((tmp > tmp2) ? tmp2 : (tmp > 0 ? tmp : 0)); /* 0 lower limit */ 886. } 887. 888. struct permonst * 889. grow_up(mtmp) /* mon mtmp "grows up" to a bigger version. */ 890. register struct monst *mtmp; 891. { 892. register int newtype; 893. register struct permonst *ptr = mtmp->data; 894. 895. if (ptr->mlevel >= 50 || mtmp->mhpmax <= 8*mtmp->m_lev) 896. return ptr; 897. newtype = little_to_big(monsndx(ptr)); 898. if (++mtmp->m_lev >= mons[newtype].mlevel) { 899. if (mons[newtype].geno & G_GENOD) { 900. pline("As %s grows up into a%s %s, %s dies!", 901. mon_nam(mtmp), 902. index(vowels,*mons[newtype].mname) ? "n" : "", 903. mons[newtype].mname, 904. mon_nam(mtmp)); 905. mondied(mtmp); 906. return (struct permonst *)0; 907. } 908. mtmp->data = &mons[newtype]; 909. mtmp->m_lev = mons[newtype].mlevel; 910. } 911. if (mtmp->m_lev > 3*mtmp->data->mlevel / 2) 912. mtmp->m_lev = 3*mtmp->data->mlevel / 2; 913. return(mtmp->data); 914. } 915. 916. int 917. mongets(mtmp, otyp) 918. register struct monst *mtmp; 919. register int otyp; 920. { 921. register struct obj *otmp; 922. 923. if((otmp = (otyp) ? mksobj(otyp,FALSE) : mkobj(otyp,FALSE))) { 924. if (mtmp->data->mlet == S_DEMON) { 925. /* demons always get cursed objects */ 926. curse(otmp); 927. } 928. mpickobj(mtmp, otmp); 929. return(otmp->spe); 930. } else return(0); 931. } 932. 933. #ifdef REINCARNATION 934. struct permonst * 935. roguemon() 936. { 937. /* Make a monster for a Rogue-like level; only capital letters. There are 938. * no checks for "too hard" or "too easy", though dragons are specifically 939. * ruled out because playtesting showed they made the level too hard. 940. * Modified from rndmonst(). 941. */ 942. #define isupper(x) ('A'<=(x) && (x)<='Z') 943. register struct permonst *ptr; 944. register int accept,ct,i; 945. 946. /* See how many there are. */ 947. accept = 0; 948. for(ct = PM_APE ; isupper(mons[ct].mlet); ct++) { 949. if (mons[ct].mlet == S_DRAGON) continue; 950. ptr = &(mons[ct]); 951. if(uncommon(ptr)) continue; 952. accept += (ptr->geno & G_FREQ); 953. } 954. if(!accept) return((struct permonst *) 0); 955. 956. /* Now, select one at random. */ 957. ct = rnd(accept); 958. for(i = PM_APE; isupper(mons[i].mlet) && ct > 0; i++) { 959. if (mons[i].mlet == S_DRAGON) continue; 960. ptr = &(mons[i]); 961. if(uncommon(ptr)) continue; 962. ct -= (ptr->geno & G_FREQ); 963. } 964. if(ct > 0) return((struct permonst *) 0); 965. return(ptr); 966. } 967. #endif 968. 969. #ifdef GOLEMS 970. int 971. golemhp(type) 972. int type; 973. { 974. switch(type) { 975. case PM_STRAW_GOLEM: return 20; 976. case PM_ROPE_GOLEM: return 30; 977. case PM_LEATHER_GOLEM: return 40; 978. case PM_WOOD_GOLEM: return 50; 979. case PM_FLESH_GOLEM: return 40; 980. case PM_CLAY_GOLEM: return 50; 981. case PM_STONE_GOLEM: return 60; 982. case PM_IRON_GOLEM: return 80; 983. default: return 0; 984. } 985. } 986. #endif /* GOLEMS */ 987. 988. /* 989. * Alignment vs. yours determines monster's attitude to you. 990. * ( some "animal" types are co-aligned, but also hungry ) 991. */ 992. boolean 993. peace_minded(ptr) 994. register struct permonst *ptr; 995. { 996. schar mal = ptr->maligntyp, ual = u.ualigntyp; 997. 998. if (always_peaceful(ptr)) return TRUE; 999. if (always_hostile(ptr)) return FALSE; 1000. 1001. /* the monster is hostile if its alignment is different from the 1002. * player's */ 1003. if (sgn(mal) != sgn(ual)) return FALSE; 1004. 1005. /* Negative monster hostile to player with Amulet. */ 1006. if (mal < 0 && u.uhave_amulet) return FALSE; 1007. 1008. /* Last case: a chance of a co-aligned monster being 1009. * hostile. This chance is greater if the player has strayed 1010. * (u.ualign negative) or the monster is not strongly aligned. 1011. */ 1012. return !!rn2(16 + (u.ualign < -15 ? -15 : u.ualign)) && 1013. !!rn2(2 + abs(mal)); 1014. } 1015. 1016. /* Set malign to have the proper effect on player alignment if monster is 1017. * killed. Negative numbers mean it's bad to kill this monster; positive 1018. * numbers mean it's good. Since there are more hostile monsters than 1019. * peaceful monsters, the penalty for killing a peaceful monster should be 1020. * greater than the bonus for killing a hostile monster to maintain balance. 1021. * Rules: 1022. * it's bad to kill peaceful monsters, potentially worse to kill always- 1023. * peaceful monsters 1024. * it's never bad to kill a hostile monster, although it may not be good 1025. */ 1026. void 1027. set_malign(mtmp) 1028. struct monst *mtmp; 1029. { 1030. schar mal = mtmp->data->maligntyp; 1031. boolean coaligned = (sgn(mal) == sgn(u.ualigntyp)); 1032. 1033. if (always_peaceful(mtmp->data)) 1034. mtmp->malign = -3*max(5,abs(mal)); 1035. else if (always_hostile(mtmp->data)) { 1036. if (coaligned) 1037. mtmp->malign = 0; 1038. else 1039. mtmp->malign = max(5,abs(mal)); 1040. } else if (coaligned) { 1041. if (mtmp->mpeaceful) 1042. mtmp->malign = -3*max(3,abs(mal)); 1043. else /* renegade */ 1044. mtmp->malign = max(3,abs(mal)); 1045. } else /* not coaligned and therefore hostile */ 1046. mtmp->malign = abs(mal); 1047. } 1048. 1049. static char syms[] = { 0, 0, RING_SYM, WAND_SYM, WEAPON_SYM, FOOD_SYM, GOLD_SYM, 1050. SCROLL_SYM, POTION_SYM, ARMOR_SYM, AMULET_SYM, TOOL_SYM, ROCK_SYM, 1051. GEM_SYM, 1052. #ifdef SPELLS 1053. SPBOOK_SYM, 1054. #endif 1055. S_MIMIC_DEF, S_MIMIC_DEF, S_MIMIC_DEF, 1056. }; 1057. 1058. void 1059. set_mimic_sym(mtmp) /* KAA */ 1060. register struct monst *mtmp; 1061. { 1062. int roomno, rt; 1063. char sym; 1064. if (!mtmp) return; 1065. 1066. syms[0] = UP_SYM; 1067. syms[1] = DN_SYM; 1068. 1069. mtmp->mimic = 1; 1070. roomno = inroom(mtmp->mx, mtmp->my); 1071. if (levl[mtmp->mx][mtmp->my].gmask) 1072. sym = GOLD_SYM; 1073. else if (levl[mtmp->mx][mtmp->my].omask) 1074. sym = o_at(mtmp->mx,mtmp->my)->olet; 1075. else if (IS_DOOR(levl[mtmp->mx][mtmp->my].typ) || 1076. IS_WALL(levl[mtmp->mx][mtmp->my].typ)) 1077. sym = DOOR_SYM; 1078. else if (is_maze_lev) 1079. sym = rn2(2) ? ROCK_SYM : syms[rn2(sizeof syms)]; 1080. else if (roomno < 0) 1081. sym = ROCK_SYM; 1082. else if ((rt = rooms[roomno].rtype) == ZOO || rt == VAULT) 1083. sym = GOLD_SYM; 1084. #ifdef ORACLE 1085. else if (rt == DELPHI) 1086. sym = rn2(2) ? ROCK_SYM : FOUNTAIN_SYM; 1087. #endif 1088. #ifdef ALTARS 1089. else if (rt == TEMPLE) 1090. sym = ALTAR_SYM; 1091. #endif 1092. /* We won't bother with beehives, morgues, barracks, throne rooms 1093. * since they shouldn't contain mimics anyway... 1094. */ 1095. else if (rt >= SHOPBASE) { 1096. int s_sym = get_shop_item(rt - SHOPBASE); 1097. 1098. if (s_sym < 0) sym = objects[-sym].oc_olet; 1099. else if (sym == RANDOM_SYM) 1100. sym = syms[rn2(sizeof(syms)-2) + 2]; 1101. else sym = s_sym; 1102. } else sym = syms[rn2(sizeof syms)]; 1103. mtmp->mappearance = sym; 1104. }