home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / games / volume16 / nethack31 / part21 < prev    next >
Internet Message Format  |  1993-02-01  |  59KB

  1. Path: uunet!news.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v16i021:  nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part21/108
  5. Message-ID: <4309@master.CNA.TEK.COM>
  6. Date: 29 Jan 93 20:43:59 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 2094
  9. Approved: billr@saab.CNA.TEK.COM
  10. Xref: uunet comp.sources.games:1578
  11.  
  12. Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
  13. Posting-number: Volume 16, Issue 21
  14. Archive-name: nethack31/Part21
  15. Supersedes: nethack3p9: Volume 10, Issue 46-102
  16. Environment: Amiga, Atari, Mac, MS-DOS, OS2, Unix, VMS, X11
  17.  
  18.  
  19.  
  20. #! /bin/sh
  21. # This is a shell archive.  Remove anything before this line, then unpack
  22. # it by saving it into a file and typing "sh file".  To overwrite existing
  23. # files, type "sh file -c".  You can also feed this as standard input via
  24. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  25. # will see the following message at the end:
  26. #        "End of archive 21 (of 108)."
  27. # Contents:  dat/Healer.des src/mon.c
  28. # Wrapped by billr@saab on Wed Jan 27 16:08:54 1993
  29. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  30. if test -f 'dat/Healer.des' -a "${1}" != "-c" ; then 
  31.   echo shar: Will not clobber existing file \"'dat/Healer.des'\"
  32. else
  33. echo shar: Extracting \"'dat/Healer.des'\" \(11204 characters\)
  34. sed "s/^X//" >'dat/Healer.des' <<'END_OF_FILE'
  35. X#    SCCS Id: @(#)Healer.des    3.1    93/01/23
  36. X#    Copyright (c) 1989 by Jean-Christophe Collet
  37. X#    Copyright (c) 1991 by M. Stephenson
  38. X# NetHack may be freely redistributed.  See license for details.
  39. X#
  40. X#    The "start" level for the quest.
  41. X#
  42. X#    Here you meet your (besieged) class leader, Hippocrates
  43. X#    and receive your quest assignment.
  44. X#
  45. XMAZE: "H-start",' '
  46. XFLAGS: noteleport,hardfloor
  47. XGEOMETRY:center,center
  48. XMAP
  49. XPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
  50. XPPPP........PPPP.....PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP.P..PPPPP......PPPPPPPP
  51. XPPP..........PPPP...PPPPP.........................PPPP..PPPPP........PPPPPPP
  52. XPP............PPPPPPPP..............................PPP...PPPP......PPPPPPPP
  53. XP.....PPPPPPPPPPPPPPP................................PPPPPPPPPPPPPPPPPPPPPPP
  54. XPPPP....PPPPPPPPPPPP...................................PPPPP.PPPPPPPPPPPPPPP
  55. XPPPP........PPPPP.........-----------------------........PP...PPPPPPP.....PP
  56. XPPP............PPPPP....--|.|......S..........S.|--.....PPPP.PPPPPPP.......P
  57. XPPPP..........PPPPP.....|.S.|......-----------|S|.|......PPPPPP.PPP.......PP
  58. XPPPPPP......PPPPPP......|.|.|......|...|......|.|.|.....PPPPPP...PP.......PP
  59. XPPPPPPPPPPPPPPPPPPP.....+.|.|......S.\.S......|.|.+......PPPPPP.PPPP.......P
  60. XPPP...PPPPP...PPPP......|.|.|......|...|......|.|.|.......PPPPPPPPPPP.....PP
  61. XPP.....PPP.....PPP......|.|S|-----------......|.S.|......PPPPPPPPPPPPPPPPPPP
  62. XPPP..PPPPP...PPPP.......--|.S..........S......|.|--.....PPPPPPPPP....PPPPPPP
  63. XPPPPPPPPPPPPPPPP..........-----------------------..........PPPPP..........PP
  64. XPPPPPPPPPPPPPPPPP........................................PPPPPP............P
  65. XPPP.............PPPP...................................PPP..PPPP..........PP
  66. XPP...............PPPPP................................PPPP...PPPP........PPP
  67. XPPP.............PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP....PPPPPP
  68. XPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
  69. XENDMAP
  70. X# Random Monsters
  71. XRANDOM_MONSTERS: 'r', ';', 'D'
  72. X# Dungeon Description
  73. XREGION:(00,00,75,19),lit,"ordinary"
  74. X# Stairs
  75. XSTAIR:(37,9),down
  76. X# Portal arrival point
  77. XBRANCH:(04,12,04,12),(0,0,0,0)
  78. X# Doors
  79. XDOOR:locked,(24,10)
  80. XDOOR:closed,(26,08)
  81. XDOOR:closed,(27,12)
  82. XDOOR:locked,(28,13)
  83. XDOOR:closed,(35,07)
  84. XDOOR:locked,(35,10)
  85. XDOOR:locked,(39,10)
  86. XDOOR:closed,(39,13)
  87. XDOOR:locked,(46,07)
  88. XDOOR:closed,(47,08)
  89. XDOOR:closed,(48,12)
  90. XDOOR:locked,(50,10)
  91. X# Hippocrates
  92. XMONSTER:'@',"Hippocrates",(37,10)
  93. X# The treasure of Hippocrates
  94. XOBJECT:'(',"chest",(37,10)
  95. X# intern guards for the audience chamber
  96. XMONSTER:'@',"intern",(29,08)
  97. XMONSTER:'@',"intern",(29,09)
  98. XMONSTER:'@',"intern",(29,10)
  99. XMONSTER:'@',"intern",(29,11)
  100. XMONSTER:'@',"intern",(40,09)
  101. XMONSTER:'@',"intern",(40,10)
  102. XMONSTER:'@',"intern",(40,11)
  103. XMONSTER:'@',"intern",(40,13)
  104. X# Non diggable walls
  105. XNON_DIGGABLE:(00,00,75,19)
  106. X# Random traps
  107. XTRAP:random,random
  108. XTRAP:random,random
  109. XTRAP:random,random
  110. XTRAP:random,random
  111. XTRAP:random,random
  112. XTRAP:random,random
  113. X# Monsters on siege duty.
  114. XMONSTER: 'r',"rabid rat",random
  115. XMONSTER: 'r',"rabid rat",random
  116. XMONSTER: 'r',"rabid rat",random
  117. XMONSTER: 'r',"rabid rat",random
  118. XMONSTER: 'r',"rabid rat",random
  119. XMONSTER: 'r',"rabid rat",random
  120. XMONSTER: 'r',"rabid rat",random
  121. XMONSTER: 'r',"rabid rat",random
  122. XMONSTER: 'r',"rabid rat",random
  123. XMONSTER: 'r',"rabid rat",random
  124. XMONSTER: ';',"giant eel",random
  125. XMONSTER: ';', random, random
  126. XMONSTER: 'D',random,random,hostile
  127. XMONSTER: 'D',random,random,hostile
  128. XMONSTER: 'D',random,random,hostile
  129. XMONSTER: 'D',random,random,hostile
  130. XMONSTER: 'D',random,random,hostile
  131. X#
  132. X#    The "locate" level for the quest.
  133. X#
  134. X#    Here you have to find the Temple of Coeus to go
  135. X#    further towards your assigned quest.
  136. X#
  137. X
  138. XMAZE: "H-locate",' '
  139. XFLAGS: hardfloor
  140. X#
  141. XINIT_MAP: '.' , 'P', true , true , lit , false
  142. XGEOMETRY:center,center
  143. XMAP
  144. XPPPPPPPPPPPPP.......PPPPPPPPPPP
  145. XPPPPPPPP...............PPPPPPPP
  146. XPPPP.....-------------...PPPPPP
  147. XPPPPP....|.S.........|....PPPPP
  148. XPPP......+.|.........|...PPPPPP
  149. XPPP......+.|.........|..PPPPPPP
  150. XPPPP.....|.S.........|..PPPPPPP
  151. XPPPPP....-------------....PPPPP
  152. XPPPPPPPP...............PPPPPPPP
  153. XPPPPPPPPPPP........PPPPPPPPPPPP
  154. XENDMAP
  155. X# Dungeon Description
  156. XREGION:(03,00,26,09),lit,"ordinary"
  157. XREGION:(12,03,20,06),lit,"temple"
  158. X# Doors
  159. XDOOR:closed,(09,04)
  160. XDOOR:closed,(09,05)
  161. XDOOR:locked,(11,03)
  162. XDOOR:locked,(11,06)
  163. X# Stairs
  164. XSTAIR:(04,04),up
  165. XSTAIR:(20,06),down
  166. X# Non diggable walls
  167. XNON_DIGGABLE:(11,02,21,07)
  168. X# Altar in the temple.
  169. XALTAR:(13,05), chaos, shrine
  170. X# Objects
  171. XOBJECT:random,random,random
  172. XOBJECT:random,random,random
  173. XOBJECT:random,random,random
  174. XOBJECT:random,random,random
  175. XOBJECT:random,random,random
  176. XOBJECT:random,random,random
  177. XOBJECT:random,random,random
  178. XOBJECT:random,random,random
  179. XOBJECT:random,random,random
  180. XOBJECT:random,random,random
  181. XOBJECT:random,random,random
  182. XOBJECT:random,random,random
  183. XOBJECT:random,random,random
  184. XOBJECT:random,random,random
  185. XOBJECT:random,random,random
  186. X# Random traps
  187. XTRAP:random,random
  188. XTRAP:random,random
  189. XTRAP:random,random
  190. XTRAP:random,random
  191. XTRAP:random,random
  192. XTRAP:random,random
  193. X# Random monsters.
  194. XMONSTER:'r',"rabid rat",random
  195. XMONSTER:'r',"rabid rat",random
  196. XMONSTER:'r',"rabid rat",random
  197. XMONSTER:'r',"rabid rat",random
  198. XMONSTER:'r',"rabid rat",random
  199. XMONSTER:'r',"rabid rat",random
  200. XMONSTER:'r',"rabid rat",random
  201. XMONSTER:'r',"rabid rat",random
  202. XMONSTER:'r',"rabid rat",random
  203. XMONSTER:'r',"rabid rat",random
  204. XMONSTER:'r',"rabid rat",random
  205. XMONSTER:'r',"rabid rat",random
  206. XMONSTER:'r',"rabid rat",random
  207. XMONSTER:'r',"rabid rat",random
  208. XMONSTER:'r',"rabid rat",random
  209. XMONSTER:'r',"rabid rat",random
  210. XMONSTER:'r',"rabid rat",random
  211. XMONSTER:'r',random,random,hostile
  212. XMONSTER:';',"giant eel",random
  213. XMONSTER:';',"giant eel",random
  214. XMONSTER:';',"giant eel",random
  215. XMONSTER:';',"giant eel",random
  216. XMONSTER:';',"giant eel",random
  217. XMONSTER:';',"electric eel",random
  218. XMONSTER:';',"electric eel",random
  219. XMONSTER:';',"kraken",random
  220. XMONSTER:';',random, random,hostile
  221. XMONSTER:';',random, random,hostile
  222. XMONSTER: 'D',random,random,hostile
  223. XMONSTER: 'D',random,random,hostile
  224. XMONSTER: 'D',random,random,hostile
  225. XMONSTER: 'D',random,random,hostile
  226. XMONSTER: 'D',random,random,hostile
  227. X
  228. X#
  229. X#    The "goal" level for the quest.
  230. X#
  231. X#    Here you meet Cyclops your nemesis monster.  You have to
  232. X#    defeat Cyclops in combat to gain the artifact you have
  233. X#    been assigned to retrieve.
  234. X#
  235. X
  236. XMAZE: "H-goal", 'P'
  237. X#
  238. XINIT_MAP: '.' , 'P' , false , true , lit , false
  239. XGEOMETRY:center,center
  240. XMAP
  241. X.P....................................PP.
  242. XPP.......PPPPPPP....PPPPPPP....PPPP...PP.
  243. X...PPPPPPP....PPPPPPP.....PPPPPP..PPP...P
  244. X...PP..............................PPP...
  245. X..PP..............................PP.....
  246. X..PP..............................PPP....
  247. X..PPP..............................PP....
  248. X.PPP..............................PPPP...
  249. X...PP............................PPP...PP
  250. X..PPPP...PPPPP..PPPP...PPPPP.....PP...PP.
  251. XP....PPPPP...PPPP..PPPPP...PPPPPPP...PP..
  252. XPPP..................................PPP.
  253. XENDMAP
  254. X# Random Monsters
  255. XRANDOM_MONSTERS: 'r', ';', 'D'
  256. X# Dungeon Description
  257. XREGION:(00,00,40,11),lit,"ordinary"
  258. X# Stairs
  259. XSTAIR:(38,10),up
  260. X# Non diggable walls
  261. XNON_DIGGABLE:(00,00,40,11)
  262. X# Objects
  263. XOBJECT:')',"quarterstaff",(20,06),blessed,0,"The Staff of Aesculapius"
  264. XOBJECT:'/',"lightning",(20,06)
  265. XOBJECT:random,random,random
  266. XOBJECT:random,random,random
  267. XOBJECT:random,random,random
  268. XOBJECT:random,random,random
  269. XOBJECT:random,random,random
  270. XOBJECT:random,random,random
  271. XOBJECT:random,random,random
  272. XOBJECT:random,random,random
  273. XOBJECT:random,random,random
  274. XOBJECT:random,random,random
  275. XOBJECT:random,random,random
  276. XOBJECT:random,random,random
  277. XOBJECT:random,random,random
  278. XOBJECT:random,random,random
  279. X# Random traps
  280. XTRAP:random,random
  281. XTRAP:random,random
  282. XTRAP:random,random
  283. XTRAP:random,random
  284. XTRAP:random,random
  285. XTRAP:random,random
  286. X# Random monsters.
  287. XMONSTER:'H',"Cyclops",(20,06),hostile
  288. XMONSTER:'r',"rabid rat",random
  289. XMONSTER:'r',"rabid rat",random
  290. XMONSTER:'r',"rabid rat",random
  291. XMONSTER:'r',"rabid rat",random
  292. XMONSTER:'r',"rabid rat",random
  293. XMONSTER:'r',"rabid rat",random
  294. XMONSTER:'r',"rabid rat",random
  295. XMONSTER:'r',"rabid rat",random
  296. XMONSTER:'r',"rabid rat",random
  297. XMONSTER:'r',"rabid rat",random
  298. XMONSTER:'r',"rabid rat",random
  299. XMONSTER:'r',"rabid rat",random
  300. XMONSTER:'r',"rabid rat",random
  301. XMONSTER:'r',"rabid rat",random
  302. XMONSTER:'r',"rabid rat",random
  303. XMONSTER:'r',"rabid rat",random
  304. XMONSTER:'r',random,random,hostile
  305. XMONSTER:'r',random,random,hostile
  306. XMONSTER:';',"giant eel",random
  307. XMONSTER:';',"giant eel",random
  308. XMONSTER:';',"giant eel",random
  309. XMONSTER:';',"giant eel",random
  310. XMONSTER:';',"giant eel",random
  311. XMONSTER:';',"giant eel",random
  312. XMONSTER:';',"electric eel",random
  313. XMONSTER:';',"electric eel",random
  314. XMONSTER:';',random,random,hostile
  315. XMONSTER: 'D',random,random,hostile
  316. XMONSTER: 'D',random,random,hostile
  317. XMONSTER: 'D',random,random,hostile
  318. XMONSTER: 'D',random,random,hostile
  319. XMONSTER: 'D',random,random,hostile
  320. X
  321. X#
  322. X#    The "fill" levels for the quest.
  323. X#
  324. X#    These levels are used to fill out any levels not occupied by specific
  325. X#    levels as defined above. "filla" is the upper filler, between the
  326. X#    start and locate levels, and "fillb" the lower between the locate
  327. X#    and goal levels.
  328. X#
  329. X
  330. XMAZE: "H-filla" , 'P'
  331. XINIT_MAP: '.' , 'P' , false , true , lit , false
  332. XNOMAP
  333. X# Random Monsters
  334. XRANDOM_MONSTERS: 'r', ';', 'D'
  335. X#
  336. XSTAIR: random, up
  337. XSTAIR: random, down
  338. X#
  339. XOBJECT: random, random, random
  340. XOBJECT: random, random, random
  341. XOBJECT: random, random, random
  342. XOBJECT: random, random, random
  343. XOBJECT: random, random, random
  344. XOBJECT: random, random, random
  345. XOBJECT: random, random, random
  346. XOBJECT: random, random, random
  347. X#
  348. XMONSTER: 'r', "rabid rat", random
  349. XMONSTER: 'r', "rabid rat", random
  350. XMONSTER: 'r', "rabid rat", random
  351. XMONSTER: 'r', "rabid rat", random
  352. XMONSTER: 'r', random, random,hostile
  353. XMONSTER: 'r', random, random,hostile
  354. XMONSTER: ';', "giant eel", random
  355. XMONSTER: ';', "giant eel", random
  356. XMONSTER: ';', "electric eel", random
  357. XMONSTER: 'D',random,random,hostile
  358. XMONSTER: 'D',random,random,hostile
  359. XMONSTER: 'D',random,random,hostile
  360. XMONSTER: 'D',random,random,hostile
  361. X#
  362. XTRAP: random, random
  363. XTRAP: random, random
  364. XTRAP: random, random
  365. XTRAP: random, random
  366. X
  367. XMAZE: "H-fillb" , 'P'
  368. XINIT_MAP: '.' , 'P' , false , true , lit , false
  369. XNOMAP
  370. X# Random Monsters
  371. XRANDOM_MONSTERS: 'r', ';', 'D'
  372. X#
  373. XSTAIR: random, up
  374. XSTAIR: random, down
  375. X#
  376. XOBJECT: random, random, random
  377. XOBJECT: random, random, random
  378. XOBJECT: random, random, random
  379. XOBJECT: random, random, random
  380. XOBJECT: random, random, random
  381. XOBJECT: random, random, random
  382. XOBJECT: random, random, random
  383. XOBJECT: random, random, random
  384. XOBJECT: random, random, random
  385. XOBJECT: random, random, random
  386. XOBJECT: random, random, random
  387. X#
  388. XMONSTER: 'r', "rabid rat", random
  389. XMONSTER: 'r', "rabid rat", random
  390. XMONSTER: 'r', "rabid rat", random
  391. XMONSTER: 'r', "rabid rat", random
  392. XMONSTER: 'r', "rabid rat", random
  393. XMONSTER: 'r', random, random,hostile
  394. XMONSTER: 'r', random, random,hostile
  395. XMONSTER: ';', "giant eel", random
  396. XMONSTER: ';', "giant eel", random
  397. XMONSTER: ';', "giant eel", random
  398. XMONSTER: ';', "giant eel", random
  399. XMONSTER: ';', "giant eel", random
  400. XMONSTER: ';', "electric eel", random
  401. XMONSTER: ';', "electric eel", random
  402. XMONSTER: 'D',random,random,hostile
  403. XMONSTER: 'D',random,random,hostile
  404. XMONSTER: 'D',random,random,hostile
  405. XMONSTER: 'D',random,random,hostile
  406. X#
  407. XTRAP: random, random
  408. XTRAP: random, random
  409. XTRAP: random, random
  410. XTRAP: random, random
  411. END_OF_FILE
  412. if test 11204 -ne `wc -c <'dat/Healer.des'`; then
  413.     echo shar: \"'dat/Healer.des'\" unpacked with wrong size!
  414. fi
  415. # end of 'dat/Healer.des'
  416. fi
  417. if test -f 'src/mon.c' -a "${1}" != "-c" ; then 
  418.   echo shar: Will not clobber existing file \"'src/mon.c'\"
  419. else
  420. echo shar: Extracting \"'src/mon.c'\" \(42736 characters\)
  421. sed "s/^X//" >'src/mon.c' <<'END_OF_FILE'
  422. X/*    SCCS Id: @(#)mon.c    3.1    93/01/19    */
  423. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  424. X/* NetHack may be freely redistributed.  See license for details. */
  425. X
  426. X/* If you're using precompiled headers, you don't want this either */
  427. X#ifdef MICROPORT_BUG
  428. X#define MKROOM_H
  429. X#endif
  430. X
  431. X#include "hack.h"
  432. X#include "mfndpos.h"
  433. X#include "edog.h"
  434. X#include <ctype.h>
  435. X
  436. XSTATIC_DCL boolean FDECL(restrap,(struct monst *));
  437. XSTATIC_DCL void NDECL(dmonsfree);
  438. X
  439. X#ifdef OVL1
  440. X#define warnDelay 10
  441. Xlong lastwarntime;
  442. Xint lastwarnlev;
  443. Xconst char *warnings[] = {
  444. X    "white", "pink", "red", "ruby", "purple", "black" };
  445. X
  446. Xstatic void NDECL(warn_effects);
  447. X
  448. X#endif /* OVL1 */
  449. X
  450. X#ifdef OVLB
  451. Xstatic struct obj *FDECL(make_corpse,(struct monst *));
  452. Xstatic void FDECL(m_detach,(struct monst *));
  453. X
  454. Xstruct monst *fdmon;    /* chain of dead monsters, need not be saved */
  455. X            /* otherwise used only in priest.c */
  456. X
  457. X/* Creates a monster corpse, a "special" corpse, or nothing if it doesn't
  458. X * leave corpses.  Monsters which leave "special" corpses should have
  459. X * G_NOCORPSE set in order to prevent wishing for one, finding tins of one,
  460. X * etc....
  461. X */
  462. Xstatic struct obj *
  463. Xmake_corpse(mtmp)
  464. Xregister struct monst *mtmp;
  465. X{
  466. X    register struct permonst *mdat = mtmp->data;
  467. X    int num;
  468. X    struct obj *obj = (struct obj *)0;
  469. X    int x = mtmp->mx, y = mtmp->my;
  470. X    int mndx = monsndx(mdat);
  471. X
  472. X    switch(mndx) {
  473. X        case PM_GRAY_DRAGON:
  474. X        case PM_RED_DRAGON:
  475. X        case PM_ORANGE_DRAGON:
  476. X        case PM_WHITE_DRAGON:
  477. X        case PM_BLACK_DRAGON:
  478. X        case PM_BLUE_DRAGON:
  479. X        case PM_GREEN_DRAGON:
  480. X        case PM_YELLOW_DRAGON:
  481. X        /* Make dragon scales.  This assumes that the order of the */
  482. X        /* dragons is the same as the order of the scales.       */
  483. X        if (!rn2(3)) {
  484. X            obj = mksobj_at(GRAY_DRAGON_SCALES +
  485. X                    monsndx(mdat)-PM_GRAY_DRAGON, x, y, FALSE);
  486. X            obj->spe = 0;
  487. X            obj->cursed = obj->blessed = FALSE;
  488. X        }
  489. X        goto default_1;
  490. X
  491. X        case PM_WHITE_UNICORN:
  492. X        case PM_GRAY_UNICORN:
  493. X        case PM_BLACK_UNICORN:
  494. X        (void) mksobj_at(UNICORN_HORN, x, y, TRUE);
  495. X        goto default_1;
  496. X        case PM_LONG_WORM:
  497. X        (void) mksobj_at(WORM_TOOTH, x, y, TRUE);
  498. X        goto default_1;
  499. X        case PM_KOBOLD_MUMMY:
  500. X        case PM_GNOME_MUMMY:
  501. X        case PM_ORC_MUMMY:
  502. X        case PM_ELF_MUMMY:
  503. X        case PM_HUMAN_MUMMY:
  504. X        case PM_GIANT_MUMMY:
  505. X        case PM_ETTIN_MUMMY:
  506. X        (void) mksobj_at(MUMMY_WRAPPING, x, y, TRUE); /* and fall through */
  507. X        case PM_KOBOLD_ZOMBIE:
  508. X        case PM_GNOME_ZOMBIE:
  509. X        case PM_ORC_ZOMBIE:
  510. X        case PM_ELF_ZOMBIE:
  511. X        case PM_HUMAN_ZOMBIE:
  512. X        case PM_GIANT_ZOMBIE:
  513. X        case PM_ETTIN_ZOMBIE:
  514. X        switch (mndx) {
  515. X            case PM_KOBOLD_ZOMBIE:
  516. X            case PM_KOBOLD_MUMMY:
  517. X            num = PM_KOBOLD; break;
  518. X            case PM_GNOME_MUMMY:
  519. X            case PM_GNOME_ZOMBIE:
  520. X            num = PM_GNOME; break;
  521. X            case PM_ORC_MUMMY:
  522. X            case PM_ORC_ZOMBIE:
  523. X            num = PM_ORC; break;
  524. X            case PM_ELF_MUMMY:
  525. X            case PM_ELF_ZOMBIE:
  526. X            num = PM_ELF; break;
  527. X            case PM_HUMAN_MUMMY:
  528. X            case PM_HUMAN_ZOMBIE:
  529. X            num = PM_HUMAN; break;
  530. X            case PM_GIANT_MUMMY:
  531. X            case PM_GIANT_ZOMBIE:
  532. X            num = PM_GIANT; break;
  533. X            case PM_ETTIN_MUMMY:
  534. X            case PM_ETTIN_ZOMBIE:
  535. X#ifdef GCC_WARN
  536. X            default:
  537. X#endif
  538. X            num = PM_ETTIN; break;
  539. X        }
  540. X        obj = mkcorpstat(CORPSE, &mons[num], x, y, TRUE);
  541. X        obj->age -= 100;        /* this is an *OLD* corpse */
  542. X        break;
  543. X        case PM_IRON_GOLEM:
  544. X        num = d(2,6);
  545. X        while (num--)
  546. X            obj = mksobj_at(IRON_CHAIN, x, y, TRUE);
  547. X        mtmp->mnamelth = 0;
  548. X        break;
  549. X        case PM_CLAY_GOLEM:
  550. X        obj = mksobj_at(ROCK, x, y, FALSE);
  551. X        obj->quan = (long)(rn2(20) + 50);
  552. X        obj->owt = weight(obj);
  553. X        mtmp->mnamelth = 0;
  554. X        break;
  555. X        case PM_STONE_GOLEM:
  556. X        obj = mkcorpstat(STATUE, mdat, x, y, FALSE);
  557. X        break;
  558. X        case PM_WOOD_GOLEM:
  559. X        num = d(2,4);
  560. X        while(num--) {
  561. X            obj = mksobj_at(QUARTERSTAFF, x, y, TRUE);
  562. X            if (obj && obj->oartifact) {    /* don't allow this */
  563. X                artifact_exists(obj, ONAME(obj), FALSE);
  564. X                Strcpy(ONAME(obj), "");  obj->onamelth = 0;
  565. X            }
  566. X        }
  567. X        mtmp->mnamelth = 0;
  568. X        break;
  569. X        case PM_LEATHER_GOLEM:
  570. X        num = d(2,4);
  571. X        while(num--)
  572. X            obj = mksobj_at(LEATHER_ARMOR, x, y, TRUE);
  573. X        mtmp->mnamelth = 0;
  574. X        break;
  575. X        default_1:
  576. X        default:
  577. X        if (mdat->geno & G_NOCORPSE)
  578. X            return (struct obj *)0;
  579. X        else obj = mkcorpstat(CORPSE, mdat, x, y, TRUE);
  580. X        break;
  581. X    }
  582. X    /* All special cases should precede the G_NOCORPSE check */
  583. X
  584. X    /* Note: oname() cannot be used generically for non-inventory objects
  585. X     * unless you fix the link from the previous object in the chains.
  586. X     * (Here we know it's the first one, so there was no link.)
  587. X     */
  588. X    if (mtmp->mnamelth) {
  589. X        obj = oname(obj, NAME(mtmp), 0);
  590. X        fobj = obj;
  591. X        level.objects[x][y] = obj;
  592. X    }
  593. X    stackobj(fobj);
  594. X    newsym(x, y);
  595. X    return obj;
  596. X}
  597. X
  598. X#endif /* OVLB */
  599. X#ifdef OVL1
  600. X
  601. Xstatic void
  602. Xwarn_effects()
  603. X{
  604. X    if (warnlevel == 100) {
  605. X    if(!Blind &&
  606. X        (warnlevel > lastwarnlev || moves > lastwarntime + warnDelay)) {
  607. X        Your("%s %s!", aobjnam(uwep, "glow"),
  608. X         Hallucination ? hcolor() : light_blue);
  609. X        lastwarnlev = warnlevel;
  610. X        lastwarntime = moves;
  611. X    }
  612. X    warnlevel = 0;
  613. X    return;
  614. X    }
  615. X
  616. X    if(warnlevel >= SIZE(warnings))
  617. X    warnlevel = SIZE(warnings)-1;
  618. X    if(!Blind && warnlevel >= 0)
  619. X    if(warnlevel > lastwarnlev || moves > lastwarntime + warnDelay) {
  620. X        register const char *rr;
  621. X
  622. X        lastwarntime = moves;
  623. X        lastwarnlev = warnlevel;
  624. X        switch((int) (Warning & (LEFT_RING | RIGHT_RING))) {
  625. X        case LEFT_RING:
  626. X        rr = Hallucination ? "left mood ring glows" : "left ring glows";
  627. X        break;
  628. X        case RIGHT_RING:
  629. X        rr = Hallucination ? "right mood ring glows"
  630. X            : "right ring glows";
  631. X        break;
  632. X        case LEFT_RING | RIGHT_RING:
  633. X        rr = Hallucination ? "mood rings glow" : "rings both glow";
  634. X        break;
  635. X        default:
  636. X        if (Hallucination)
  637. X            Your("spider-sense is tingling....");
  638. X        else
  639. X            You("feel apprehensive as you sense a %s flash.",
  640. X            warnings[warnlevel]);
  641. X        return;
  642. X        }
  643. X        Your("%s %s!", rr, Hallucination ? hcolor() : warnings[warnlevel]);
  644. X    }
  645. X}
  646. X
  647. X/* check mtmp and water for compatibility, 0 (survived), 1 (drowned) */
  648. Xint
  649. Xminwater(mtmp)
  650. Xregister struct monst *mtmp;
  651. X{
  652. X    boolean inpool, infountain;
  653. X
  654. X    inpool = is_pool(mtmp->mx,mtmp->my);
  655. X    infountain = IS_FOUNTAIN(levl[mtmp->mx][mtmp->my].typ);
  656. X
  657. X    /* Gremlin multiplying won't go on forever since the hit points
  658. X     * keep going down, and when it gets to 1 hit point the clone
  659. X     * function will fail.
  660. X     */
  661. X    if(mtmp->data->mlet == S_GREMLIN && (inpool || infountain) && rn2(3)) {
  662. X    struct monst *mtmp2 = clone_mon(mtmp);
  663. X
  664. X    if (mtmp2) {
  665. X        mtmp2->mhpmax = (mtmp->mhpmax /= 2);
  666. X        if(cansee(mtmp->mx,mtmp->my))
  667. X        pline("%s multiplies.", Monnam(mtmp));
  668. X        dryup(mtmp->mx,mtmp->my);
  669. X    }
  670. X    return (0);
  671. X    }
  672. X    if (inpool) {
  673. X    /* most monsters drown in pools */
  674. X    if (!is_flyer(mtmp->data) && !is_clinger(mtmp->data)
  675. X        && !is_swimmer(mtmp->data) && !magic_breathing(mtmp->data)) {
  676. X        if (cansee(mtmp->mx,mtmp->my))
  677. X        pline("%s drowns.", Monnam(mtmp));
  678. X        mondead(mtmp);
  679. X        return (1);
  680. X    }
  681. X    } else {
  682. X    /* but eels have a difficult time outside */
  683. X    if (mtmp->data->mlet == S_EEL) {
  684. X        if(mtmp->mhp > 1) mtmp->mhp--;
  685. X        mtmp->mflee = 1;
  686. X        mtmp->mfleetim += 2;
  687. X    }
  688. X    }
  689. X    return (0);
  690. X}
  691. X
  692. Xvoid
  693. Xmovemon()
  694. X{
  695. X    register struct monst *mtmp;
  696. X    register boolean tametype = TRUE;
  697. X
  698. X    warnlevel = 0;
  699. X
  700. X    while(1) {
  701. X    /* Find a monster that we have not treated yet.
  702. X     * Note that mtmp or mtmp->nmon might get killed
  703. X     * while mtmp moves, so we cannot just walk down the
  704. X     * chain (even new monsters might get created!)
  705. X     *
  706. X     * Do tame monsters first.  Necessary so that when the tame
  707. X     * monster attacks something, the something gets a chance to
  708. X     * attack the tame monster back (which it's permitted to do
  709. X     * only if it hasn't made its move yet).
  710. X     */
  711. X    for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  712. X        if(mtmp->mlstmv < monstermoves &&
  713. X           ((mtmp->mtame>0) == tametype)) goto next_mon;
  714. X    if(tametype) {
  715. X        /* checked all tame monsters, now do other ones */
  716. X        tametype = FALSE;
  717. X        continue;
  718. X    }
  719. X    /* treated all monsters */
  720. X    break;
  721. X
  722. X    next_mon:
  723. X    mtmp->mlstmv = monstermoves;
  724. X
  725. X    if(mtmp->mhp <= 0) {
  726. X        impossible("Monster with zero hp?");
  727. X        mtmp->mhp = mtmp->mhpmax = 1; /* repair */
  728. X    }
  729. X    if (minwater(mtmp)) continue;
  730. X
  731. X    if(mtmp->mblinded && !--mtmp->mblinded)
  732. X        mtmp->mcansee = 1;
  733. X    if(mtmp->mfrozen && !--mtmp->mfrozen)
  734. X        mtmp->mcanmove = 1;
  735. X    if(mtmp->mfleetim && !--mtmp->mfleetim)
  736. X        mtmp->mflee = 0;
  737. X    if (is_hider(mtmp->data)) {
  738. X        /* unwatched mimics and piercers may hide again  [MRS] */
  739. X        if(restrap(mtmp))   continue;
  740. X        if(mtmp->m_ap_type == M_AP_FURNITURE ||
  741. X                    mtmp->m_ap_type == M_AP_OBJECT)
  742. X            continue;
  743. X        if(mtmp->mundetected) continue;
  744. X    }
  745. X    if(mtmp->mspeed != MSLOW || !(moves%2)) {
  746. X        /* continue if the monster died fighting */
  747. X        if (Conflict && !mtmp->iswiz && mtmp->mcansee) {
  748. X        /* Note:
  749. X         *  Conflict does not take effect in the first round.
  750. X         *  Therefore, A monster when stepping into the area will
  751. X         *  get to swing at you.
  752. X         *
  753. X         *  The call to fightm() must be _last_.  The monster might
  754. X         *  have died if it returns 1.
  755. X         */
  756. X        if (couldsee(mtmp->mx,mtmp->my) &&
  757. X            (distu(mtmp->mx,mtmp->my) <= BOLT_LIM*BOLT_LIM) &&
  758. X                                fightm(mtmp))
  759. X             continue;    /* mon might have died */
  760. X        }
  761. X        if(dochugw(mtmp))
  762. X        /* otherwise just move the monster */
  763. X        continue;
  764. X    }
  765. X    if(mtmp->mspeed == MFAST && dochugw(mtmp))
  766. X        continue;
  767. X    }
  768. X    if(warnlevel > 0)
  769. X    warn_effects();
  770. X
  771. X    dmonsfree(); /* remove all dead monsters */
  772. X}
  773. X
  774. X#endif /* OVL1 */
  775. X#ifdef OVLB
  776. X
  777. Xvoid
  778. Xmeatgold(mtmp)
  779. X    register struct monst *mtmp;
  780. X{
  781. X    register struct obj *otmp;
  782. X
  783. X    /* If a pet, eating is handled separately, in dog.c */
  784. X    if (mtmp->mtame) return;
  785. X
  786. X    /* Eats topmost metal object if it is there */
  787. X    for (otmp = level.objects[mtmp->mx][mtmp->my];
  788. X                            otmp; otmp = otmp->nexthere)
  789. X        if (is_metallic(otmp) && touch_artifact(otmp,mtmp)) {
  790. X            if (cansee(mtmp->mx,mtmp->my) && flags.verbose)
  791. X            pline("%s eats %s!", Monnam(mtmp),
  792. X                distant_name(otmp,doname));
  793. X            else if (flags.soundok && flags.verbose)
  794. X            You("hear a crunching sound.");
  795. X            mtmp->meating = otmp->owt/2 + 1;
  796. X            /* Heal up to the object's weight in hp */
  797. X            if (mtmp->mhp < mtmp->mhpmax) {
  798. X            mtmp->mhp += objects[otmp->otyp].oc_weight;
  799. X            if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax;
  800. X            }
  801. X            if(otmp == uball) {
  802. X            unpunish();
  803. X            delobj(otmp);
  804. X            } else if(otmp == uchain)
  805. X            unpunish();    /* frees uchain */
  806. X            else
  807. X            delobj(otmp);
  808. X            /* Left behind a pile? */
  809. X            if(rnd(25) < 3) (void) mksobj_at(ROCK, mtmp->mx, mtmp->my, TRUE);
  810. X            newsym(mtmp->mx, mtmp->my);
  811. X            break;
  812. X        }
  813. X}
  814. X
  815. Xvoid
  816. Xmeatobj(mtmp)        /* for gelatinous cubes */
  817. X    register struct monst *mtmp;
  818. X{
  819. X    register struct obj *otmp, *otmp2;
  820. X
  821. X    /* If a pet, eating is handled separately, in dog.c */
  822. X    if (mtmp->mtame) return;
  823. X
  824. X    /* Eats organic objects, including cloth and wood, if there */
  825. X    /* Engulfs others, except huge rocks and metal attached to player */
  826. X    for (otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp = otmp2) {
  827. X        otmp2 = otmp->nexthere;
  828. X        if(is_organic(otmp) && touch_artifact(otmp,mtmp)) {
  829. X        if (otmp->otyp == CORPSE && otmp->corpsenm == PM_COCKATRICE
  830. X                        && !resists_ston(mtmp->data))
  831. X            continue;
  832. X        if (cansee(mtmp->mx,mtmp->my) && flags.verbose)
  833. X            pline("%s eats %s!", Monnam(mtmp),
  834. X                distant_name(otmp, doname));
  835. X        else if (flags.soundok && flags.verbose)
  836. X            You("hear a slurping sound.");
  837. X        /* Heal up to the object's weight in hp */
  838. X        if (mtmp->mhp < mtmp->mhpmax) {
  839. X            mtmp->mhp += objects[otmp->otyp].oc_weight;
  840. X            if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax;
  841. X        }
  842. X        delobj(otmp);        /* munch */
  843. X        } else if (otmp->oclass != ROCK_CLASS &&
  844. X                    otmp != uball && otmp != uchain) {
  845. X        if (cansee(mtmp->mx, mtmp->my) && flags.verbose)
  846. X            pline("%s engulfs %s.", Monnam(mtmp),
  847. X                distant_name(otmp,doname));
  848. X        freeobj(otmp);
  849. X        mpickobj(mtmp, otmp);    /* slurp */
  850. X        }
  851. X        /* Engulf & devour is instant, so don't set meating */
  852. X        newsym(mtmp->mx, mtmp->my);
  853. X    }
  854. X}
  855. X
  856. Xvoid
  857. Xmpickgold(mtmp)
  858. X    register struct monst *mtmp;
  859. X{
  860. X    register struct obj *gold;
  861. X
  862. X    if ((gold = g_at(mtmp->mx, mtmp->my)) != 0) {
  863. X    mtmp->mgold += gold->quan;
  864. X    delobj(gold);
  865. X    if (cansee(mtmp->mx, mtmp->my) ) {
  866. X        if (flags.verbose && !mtmp->isgd)
  867. X        pline("%s picks up some gold.", Monnam(mtmp));
  868. X        newsym(mtmp->mx, mtmp->my);
  869. X    }
  870. X    }
  871. X}
  872. X
  873. X/* Now includes giants which pick up enormous rocks.  KAA */
  874. Xvoid
  875. Xmpickgems(mtmp)
  876. X    register struct monst *mtmp;
  877. X{
  878. X    register struct obj *otmp;
  879. X
  880. X    for(otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp=otmp->nexthere)
  881. X        if(throws_rocks(mtmp->data) ? otmp->otyp == BOULDER :
  882. X        (otmp->oclass == GEM_CLASS &&
  883. X         objects[otmp->otyp].oc_material != MINERAL))
  884. X        if (touch_artifact(otmp,mtmp))
  885. X        if(mtmp->data->mlet != S_UNICORN
  886. X            || objects[otmp->otyp].oc_material == GEMSTONE){
  887. X            if (cansee(mtmp->mx,mtmp->my) && flags.verbose)
  888. X            pline("%s picks up %s.", Monnam(mtmp),
  889. X                distant_name(otmp, doname));
  890. X            freeobj(otmp);
  891. X            mpickobj(mtmp, otmp);
  892. X            if (otmp->otyp == BOULDER)
  893. X            unblock_point(otmp->ox,otmp->oy);    /* vision */
  894. X            newsym(mtmp->mx, mtmp->my);
  895. X            return;    /* pick only one object */
  896. X        }
  897. X}
  898. X
  899. X#endif /* OVLB */
  900. X#ifdef OVL2
  901. X
  902. Xvoid
  903. Xmpickstuff(mtmp, str)
  904. X    register struct monst *mtmp;
  905. X    register const char *str;
  906. X{
  907. X    register struct obj *otmp;
  908. X
  909. X/*    prevent shopkeepers from leaving the door of their shop */
  910. X    if(mtmp->isshk && inhishop(mtmp)) return;
  911. X
  912. X    for(otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp=otmp->nexthere)
  913. X/*    Nymphs take everything.  Most monsters don't pick up corpses. */
  914. X        if (
  915. X#ifdef MUSE
  916. X        !str ? searches_for_item(mtmp,otmp) :
  917. X#endif
  918. X          (index(str, otmp->oclass)
  919. X           && (otmp->otyp != CORPSE || mtmp->data->mlet == S_NYMPH))) {
  920. X        if (!touch_artifact(otmp,mtmp)) return;
  921. X        if (!can_carry(mtmp,otmp)) return;
  922. X        if (cansee(mtmp->mx,mtmp->my) && flags.verbose)
  923. X            pline("%s picks up %s.", Monnam(mtmp), doname(otmp));
  924. X        freeobj(otmp);
  925. X        mpickobj(mtmp, otmp);
  926. X#ifdef MUSE
  927. X        m_dowear(mtmp, FALSE);
  928. X#endif
  929. X        newsym(mtmp->mx, mtmp->my);
  930. X        return;            /* pick only one object */
  931. X        }
  932. X}
  933. X
  934. X#endif /* OVL2 */
  935. X#ifdef OVL0
  936. X
  937. Xint
  938. Xcurr_mon_load(mtmp)
  939. Xregister struct monst *mtmp;
  940. X{
  941. X    register int curload = 0;
  942. X    register struct obj *obj;
  943. X
  944. X    for(obj = mtmp->minvent; obj; obj = obj->nobj) {
  945. X        if(obj->otyp != BOULDER || !throws_rocks(mtmp->data))
  946. X            curload += obj->owt;
  947. X    }
  948. X
  949. X    return curload;
  950. X}
  951. X
  952. Xint
  953. Xmax_mon_load(mtmp)
  954. Xregister struct monst *mtmp;
  955. X{
  956. X    register long maxload;
  957. X
  958. X    /* Base monster carrying capacity is equal to human maximum
  959. X     * carrying capacity, or half human maximum if not strong.
  960. X     * (for a polymorphed player, the value used would be the
  961. X     * non-polymorphed carrying capacity instead of max/half max).
  962. X     * This is then modified by the ratio between the monster weights
  963. X     * and human weights.  Corpseless monsters are given a capacity
  964. X     * proportional to their size instead of weight.
  965. X     */
  966. X    if (!mtmp->data->cwt)
  967. X        maxload = (MAX_CARR_CAP * (long)mtmp->data->msize) / MZ_HUMAN;
  968. X    else if (!strongmonst(mtmp->data)
  969. X        || (strongmonst(mtmp->data) && (mtmp->data->cwt > WT_HUMAN)))
  970. X        maxload = (MAX_CARR_CAP * (long)mtmp->data->cwt) / WT_HUMAN;
  971. X    else    maxload = MAX_CARR_CAP; /*strong monsters w/cwt <= WT_HUMAN*/
  972. X
  973. X    if (!strongmonst(mtmp->data)) maxload /= 2;
  974. X
  975. X    if (maxload < 1) maxload = 1;
  976. X
  977. X    return (int) maxload;
  978. X}
  979. X
  980. X/* for restricting monsters' object-pickup */
  981. Xboolean
  982. Xcan_carry(mtmp,otmp)
  983. Xstruct monst *mtmp;
  984. Xstruct obj *otmp;
  985. X{
  986. X    register int newload = otmp->owt;
  987. X
  988. X    if (otmp->otyp == CORPSE && otmp->corpsenm == PM_COCKATRICE
  989. X                        && !resists_ston(mtmp->data))
  990. X        return(FALSE);
  991. X    if (mtmp->isshk) return(TRUE); /* no limit */
  992. X    if (mtmp->mpeaceful && !mtmp->mtame) return(FALSE);
  993. X    /* otherwise players might find themselves obligated to violate
  994. X     * their alignment if the monster takes something they need
  995. X     */
  996. X
  997. X    /* special--boulder throwers carry unlimited amounts of boulders */
  998. X    if (throws_rocks(mtmp->data) && otmp->otyp == BOULDER)
  999. X        return(TRUE);
  1000. X
  1001. X    /* nymphs deal in stolen merchandise, but not boulders or statues */
  1002. X    if (mtmp->data->mlet == S_NYMPH)
  1003. X        return !(otmp->oclass == ROCK_CLASS);
  1004. X
  1005. X    if(curr_mon_load(mtmp) + newload > max_mon_load(mtmp)) return(FALSE);
  1006. X
  1007. X    return(TRUE);
  1008. X}
  1009. X
  1010. X/* return number of acceptable neighbour positions */
  1011. Xint
  1012. Xmfndpos(mon, poss, info, flag)
  1013. X    register struct monst *mon;
  1014. X    coord *poss;    /* coord poss[9] */
  1015. X    long *info;    /* long info[9] */
  1016. X    long flag;
  1017. X{
  1018. X    register xchar x,y,nx,ny;
  1019. X    register int cnt = 0;
  1020. X    register uchar ntyp;
  1021. X    uchar nowtyp;
  1022. X    boolean wantpool,poolok,lavaok,nodiag;
  1023. X    int maxx, maxy;
  1024. X
  1025. X    x = mon->mx;
  1026. X    y = mon->my;
  1027. X    nowtyp = levl[x][y].typ;
  1028. X
  1029. X    nodiag = (mon->data == &mons[PM_GRID_BUG]);
  1030. X    wantpool = mon->data->mlet == S_EEL;
  1031. X    poolok = is_flyer(mon->data) || is_clinger(mon->data) ||
  1032. X         (is_swimmer(mon->data) && !wantpool);
  1033. X    lavaok = is_flyer(mon->data) || is_clinger(mon->data) ||
  1034. X         (mon->data == &mons[PM_FIRE_ELEMENTAL]);
  1035. Xnexttry:    /* eels prefer the water, but if there is no water nearby,
  1036. X           they will crawl over land */
  1037. X    if(mon->mconf) {
  1038. X        flag |= ALLOW_ALL;
  1039. X        flag &= ~NOTONL;
  1040. X    }
  1041. X    if(!mon->mcansee)
  1042. X        flag |= ALLOW_SSM;
  1043. X    maxx = min(x+1,COLNO-1);
  1044. X    maxy = min(y+1,ROWNO-1);
  1045. X    for(nx = max(1,x-1); nx <= maxx; nx++)
  1046. X      for(ny = max(0,y-1); ny <= maxy; ny++) {
  1047. X        if(nx == x && ny == y) continue;
  1048. X        if(IS_ROCK(ntyp = levl[nx][ny].typ) && !(flag & ALLOW_WALL) &&
  1049. X        !((flag & ALLOW_DIG) && may_dig(nx,ny))) continue;
  1050. X        if(IS_DOOR(ntyp) && !amorphous(mon->data) &&
  1051. X           ((levl[nx][ny].doormask & D_CLOSED && !(flag & OPENDOOR)) ||
  1052. X        (levl[nx][ny].doormask & D_LOCKED && !(flag & UNLOCKDOOR))
  1053. X           ) && !(flag & (ALLOW_WALL|ALLOW_DIG|BUSTDOOR))) continue;
  1054. X        if(nx != x && ny != y && (nodiag ||
  1055. X#ifdef REINCARNATION
  1056. X           ((IS_DOOR(nowtyp) &&
  1057. X         ((levl[x][y].doormask & ~D_BROKEN) || Is_rogue_level(&u.uz))) ||
  1058. X        (IS_DOOR(ntyp) &&
  1059. X         ((levl[nx][ny].doormask & ~D_BROKEN) || Is_rogue_level(&u.uz))))
  1060. X#else
  1061. X           ((IS_DOOR(nowtyp) && (levl[x][y].doormask & ~D_BROKEN)) ||
  1062. X        (IS_DOOR(ntyp) && (levl[nx][ny].doormask & ~D_BROKEN)))
  1063. X#endif
  1064. X           ))
  1065. X        continue;
  1066. X        if((is_pool(nx,ny) == wantpool || poolok) &&
  1067. X           (lavaok || !is_lava(nx,ny))) {
  1068. X        int dispx, dispy;
  1069. X        boolean monseeu = (!Invis || perceives(mon->data));
  1070. X        boolean checkobj = OBJ_AT(nx,ny);
  1071. X
  1072. X        /* Displacement also displaces the Elbereth/scare monster,
  1073. X         * as long as you are visible.
  1074. X         */
  1075. X        if(Displaced && monseeu && (mon->mux==nx) && (mon->muy==ny)) {
  1076. X            dispx = u.ux;
  1077. X            dispy = u.uy;
  1078. X        } else {
  1079. X            dispx = nx;
  1080. X            dispy = ny;
  1081. X        }
  1082. X
  1083. X        info[cnt] = 0;
  1084. X        if(((checkobj || Displaced) &&
  1085. X            sobj_at(SCR_SCARE_MONSTER, dispx, dispy))
  1086. X#ifdef ELBERETH
  1087. X               || sengr_at("Elbereth", dispx, dispy)
  1088. X#endif
  1089. X               ) {
  1090. X            if(!(flag & ALLOW_SSM)) continue;
  1091. X            info[cnt] |= ALLOW_SSM;
  1092. X        }
  1093. X        if((nx == u.ux && ny == u.uy) ||
  1094. X           (nx == mon->mux && ny == mon->muy)) {
  1095. X            if (nx == u.ux && ny == u.uy) {
  1096. X                /* If it's right next to you, it found you,
  1097. X                 * displaced or no.  We must set mux and muy
  1098. X                 * right now, so when we return we can tell
  1099. X                 * that the ALLOW_U means to attack _you_ and
  1100. X                 * not the image.
  1101. X                 */
  1102. X                mon->mux = u.ux;
  1103. X                mon->muy = u.uy;
  1104. X            }
  1105. X            if(!(flag & ALLOW_U)) continue;
  1106. X            info[cnt] |= ALLOW_U;
  1107. X        } else {
  1108. X            if(MON_AT(nx, ny)) {
  1109. X                if(!(flag & ALLOW_M)) continue;
  1110. X                info[cnt] |= ALLOW_M;
  1111. X                if((m_at(nx,ny))->mtame) {
  1112. X                    if(!(flag & ALLOW_TM)) continue;
  1113. X                    info[cnt] |= ALLOW_TM;
  1114. X                }
  1115. X            }
  1116. X            /* Note: ALLOW_SANCT only prevents movement, not */
  1117. X            /* attack, into a temple. */
  1118. X            if(level.flags.has_temple &&
  1119. X               *in_rooms(nx, ny, TEMPLE) &&
  1120. X               !*in_rooms(x, y, TEMPLE) &&
  1121. X               in_your_sanctuary(nx, ny)){
  1122. X                if(!(flag & ALLOW_SANCT)) continue;
  1123. X                info[cnt] |= ALLOW_SANCT;
  1124. X            }
  1125. X        }
  1126. X        if(checkobj && sobj_at(CLOVE_OF_GARLIC, nx, ny)) {
  1127. X            if(flag & NOGARLIC) continue;
  1128. X            info[cnt] |= NOGARLIC;
  1129. X        }
  1130. X        if(checkobj && sobj_at(BOULDER, nx, ny)) {
  1131. X            if(!(flag & ALLOW_ROCK)) continue;
  1132. X            info[cnt] |= ALLOW_ROCK;
  1133. X        }
  1134. X        if (monseeu && onlineu(nx,ny)) {
  1135. X            if(flag & NOTONL) continue;
  1136. X            info[cnt] |= NOTONL;
  1137. X        }
  1138. X        /* we cannot avoid traps of an unknown kind */
  1139. X        { register struct trap *ttmp = t_at(nx, ny);
  1140. X          register long tt;
  1141. X            if(ttmp) {
  1142. X                if(ttmp->ttyp >= TRAPNUM || ttmp->ttyp == 0)  {
  1143. Ximpossible("A monster looked at a very strange trap of type %d.", ttmp->ttyp);
  1144. X                    continue;
  1145. X                }
  1146. X                tt = 1L << ttmp->ttyp;
  1147. X                if(mon->mtrapseen & tt) {
  1148. X
  1149. X                    if(!(flag & tt)) continue;
  1150. X                    info[cnt] |= tt;
  1151. X                }
  1152. X            }
  1153. X        }
  1154. X        poss[cnt].x = nx;
  1155. X        poss[cnt].y = ny;
  1156. X        cnt++;
  1157. X        }
  1158. X    }
  1159. X    if(!cnt && wantpool && !is_pool(x,y)) {
  1160. X        wantpool = FALSE;
  1161. X        goto nexttry;
  1162. X    }
  1163. X    return(cnt);
  1164. X}
  1165. X
  1166. X#endif /* OVL0 */
  1167. X#ifdef OVL1
  1168. X
  1169. Xboolean
  1170. Xmonnear(mon, x, y)
  1171. Xregister struct monst *mon;
  1172. Xregister int x,y;
  1173. X/* Is the square close enough for the monster to move or attack into? */
  1174. X{
  1175. X    register int distance = dist2(mon->mx, mon->my, x, y);
  1176. X    if (distance==2 && mon->data==&mons[PM_GRID_BUG]) return 0;
  1177. X    return (distance < 3);
  1178. X}
  1179. X
  1180. X#endif /* OVL1 */
  1181. X#ifdef OVL2
  1182. X
  1183. XSTATIC_OVL void
  1184. Xdmonsfree()
  1185. X{
  1186. Xregister struct monst *mtmp;
  1187. X    while ((mtmp = fdmon) != 0) {
  1188. X        fdmon = mtmp->nmon;
  1189. X        dealloc_monst(mtmp);
  1190. X    }
  1191. X}
  1192. X
  1193. X#endif /* OVL2 */
  1194. X#ifdef OVLB
  1195. X/* we do not free monsters immediately, in order to have their name
  1196. X   available shortly after their demise */
  1197. Xvoid
  1198. Xmonfree(mtmp)
  1199. Xregister struct monst *mtmp;
  1200. X{
  1201. X    mtmp->nmon = fdmon;
  1202. X    fdmon = mtmp;
  1203. X}
  1204. X
  1205. X/* called when monster is moved to larger structure */
  1206. Xvoid
  1207. Xreplmon(mtmp, mtmp2)
  1208. Xregister struct monst *mtmp, *mtmp2;
  1209. X{
  1210. X    relmon(mtmp);
  1211. X    monfree(mtmp);
  1212. X    place_monster(mtmp2, mtmp2->mx, mtmp2->my);
  1213. X    if (mtmp2->wormno)        /* update level.monsters[wseg->wx][wseg->wy] */
  1214. X    place_wsegs(mtmp2); /* locations to mtmp2 not mtmp. */
  1215. X    mtmp2->nmon = fmon;
  1216. X    fmon = mtmp2;
  1217. X    if (u.ustuck == mtmp) u.ustuck = mtmp2;
  1218. X    if (mtmp2->isshk) replshk(mtmp,mtmp2);
  1219. X}
  1220. X
  1221. X/* release mon from display and monster list */
  1222. Xvoid
  1223. Xrelmon(mon)
  1224. Xregister struct monst *mon;
  1225. X{
  1226. X    register struct monst *mtmp;
  1227. X
  1228. X    if (fmon == (struct monst *)0)  panic ("relmon: no fmon available.");
  1229. X
  1230. X    remove_monster(mon->mx, mon->my);
  1231. X
  1232. X    if(mon == fmon) fmon = fmon->nmon;
  1233. X    else {
  1234. X        for(mtmp = fmon; mtmp && mtmp->nmon != mon; mtmp = mtmp->nmon) ;
  1235. X        if(mtmp)    mtmp->nmon = mon->nmon;
  1236. X        else        panic("relmon: mon not in list.");
  1237. X    }
  1238. X}
  1239. X
  1240. X/* remove effects of mtmp from other data structures */
  1241. Xstatic void
  1242. Xm_detach(mtmp)
  1243. Xregister struct monst *mtmp;
  1244. X{
  1245. X#ifdef WALKIES
  1246. X    if(mtmp->mleashed) m_unleash(mtmp);
  1247. X#endif
  1248. X        /* to prevent an infinite relobj-flooreffects-hmon-killed loop */
  1249. X    mtmp->mtrapped = 0;
  1250. X    mtmp->mhp = 0; /* simplify some tests: force mhp to 0 */
  1251. X    relobj(mtmp, 0, FALSE);
  1252. X    relmon(mtmp);
  1253. X    newsym(mtmp->mx,mtmp->my);
  1254. X    unstuck(mtmp);
  1255. X    fill_pit(mtmp->mx, mtmp->my);
  1256. X
  1257. X    if(mtmp->isshk) shkgone(mtmp);
  1258. X    if(mtmp->wormno) wormgone(mtmp);
  1259. X}
  1260. X
  1261. Xvoid
  1262. Xmondead(mtmp)
  1263. Xregister struct monst *mtmp;
  1264. X{
  1265. X    int tmp, nk;
  1266. X
  1267. X    if(mtmp->isgd) {
  1268. X        /* if we're going to abort the death, it *must* be before
  1269. X         * the m_detach or there will be relmon problems later */
  1270. X        if(!grddead(mtmp)) return;
  1271. X    }
  1272. X
  1273. X    /* restore chameleon, lycanthropes to true form at death */
  1274. X    if(mtmp->cham) mtmp->data = &mons[PM_CHAMELEON];
  1275. X    if(mtmp->data == &mons[PM_WEREJACKAL])
  1276. X        mtmp->data = &mons[PM_HUMAN_WEREJACKAL];
  1277. X    if(mtmp->data == &mons[PM_WEREWOLF])
  1278. X        mtmp->data = &mons[PM_HUMAN_WEREWOLF];
  1279. X    if(mtmp->data == &mons[PM_WERERAT])
  1280. X        mtmp->data = &mons[PM_HUMAN_WERERAT];
  1281. X
  1282. X    /* if MAXMONNO monsters of a given type have died, and it
  1283. X     * can be done, extinguish that monster.
  1284. X     *
  1285. X     * u.nr_killed does double duty as total number of dead monsters
  1286. X     * and as experience factor for the player killing more monsters.
  1287. X     * this means that a dragon dying by other means reduces the
  1288. X     * experience the player gets for killing a dragon directly; this
  1289. X     * is probably not too bad, since the player likely finagled the
  1290. X     * first dead dragon via ring of conflict or pets, and extinguishing
  1291. X     * based on only player kills probably opens more avenues of abuse
  1292. X     * for rings of conflict and such.
  1293. X     */
  1294. X    tmp = monsndx(mtmp->data);
  1295. X    u.nr_killed[tmp]++;
  1296. X    nk = u.nr_killed[tmp];
  1297. X    if(nk > (tmp == PM_NAZGUL ? 9 : tmp == PM_ERINYES ? 3 : MAXMONNO) &&
  1298. X                !(mons[tmp].geno & (G_NOGEN | G_EXTINCT))) {
  1299. X#ifdef DEBUG
  1300. X        pline("Automatically extinguished %s.", makeplural(mons[tmp].mname));
  1301. X#endif
  1302. X        mons[tmp].geno |= G_EXTINCT;
  1303. X    }
  1304. X#ifdef MAIL
  1305. X    /* if the mail daemon dies, no more mail delivery.  -3. */
  1306. X    else if(tmp==PM_MAIL_DAEMON) mons[tmp].geno |= G_GENOD;
  1307. X#endif
  1308. X
  1309. X#ifdef KOPS
  1310. X    if(mtmp->data->mlet == S_KOP && allow_kops) {
  1311. X        /* Dead Kops may come back. */
  1312. X        switch(rnd(5)) {
  1313. X        case 1:         /* returns near the stairs */
  1314. X            (void) makemon(mtmp->data,xdnstair,ydnstair);
  1315. X            break;
  1316. X        case 2:         /* randomly */
  1317. X            (void) makemon(mtmp->data,0,0);
  1318. X            break;
  1319. X        default:
  1320. X            break;
  1321. X        }
  1322. X    }
  1323. X#endif
  1324. X    if(mtmp->iswiz) wizdead(mtmp);
  1325. X#ifdef MULDGN
  1326. X    if(mtmp->data->msound == MS_NEMESIS) nemdead();
  1327. X#endif
  1328. X    m_detach(mtmp);
  1329. X    monfree(mtmp);
  1330. X}
  1331. X
  1332. X/* drop (perhaps) a cadaver and remove monster */
  1333. Xvoid
  1334. Xmondied(mdef)
  1335. Xregister struct monst *mdef;
  1336. X{
  1337. X    mondead(mdef);
  1338. X    if(rn2(3)
  1339. X#ifdef REINCARNATION
  1340. X       && !Is_rogue_level(&u.uz)
  1341. X#endif
  1342. X                    )
  1343. X        (void) make_corpse(mdef);
  1344. X}
  1345. X
  1346. X/* monster disappears, not dies */
  1347. Xvoid
  1348. Xmongone(mdef)
  1349. Xregister struct monst *mdef;
  1350. X{
  1351. X    register struct obj *otmp, *otmp2;
  1352. X
  1353. X    /* release monster's inventory */
  1354. X    for (otmp = mdef->minvent; otmp; otmp = otmp2) {
  1355. X        otmp2 = otmp->nobj;
  1356. X        obfree(otmp, (struct obj *)0);
  1357. X    }
  1358. X    mdef->minvent = 0;
  1359. X    mdef->mgold = 0;
  1360. X    m_detach(mdef);
  1361. X    monfree(mdef);
  1362. X}
  1363. X
  1364. X/* drop a statue or rock and remove monster */
  1365. Xvoid
  1366. Xmonstone(mdef)
  1367. Xregister struct monst *mdef;
  1368. X{
  1369. X    struct obj *otmp, *contents;
  1370. X    xchar x = mdef->mx, y = mdef->my;
  1371. X
  1372. X    if((int)mdef->data->msize > MZ_TINY ||
  1373. X       !rn2(2 + ((mdef->data->geno & G_FREQ) > 2))) {
  1374. X        otmp = mk_named_object(STATUE, mdef->data, x, y,
  1375. X            NAME(mdef), (int)mdef->mnamelth);
  1376. X        contents = otmp->cobj = mdef->minvent;
  1377. X        while(contents) {
  1378. X            contents->owornmask = 0L;
  1379. X            contents = contents->nobj;
  1380. X        }
  1381. X        mdef->minvent = (struct obj *)0;
  1382. X        if (mdef->mgold) {
  1383. X            struct obj *au;
  1384. X            au = mksobj(GOLD_PIECE, FALSE, FALSE);
  1385. X            au->quan = mdef->mgold;
  1386. X            au->owt = weight(au);
  1387. X            mdef->mgold = 0;
  1388. X            au->nobj = otmp->cobj;
  1389. X            otmp->cobj = au;
  1390. X        }
  1391. X        otmp->owt = weight(otmp);
  1392. X    } else
  1393. X        otmp = mksobj_at(ROCK, x, y, TRUE);
  1394. X
  1395. X    mondead(mdef);
  1396. X
  1397. X    stackobj(otmp);
  1398. X    if (cansee(x, y)) newsym(x,y);
  1399. X}
  1400. X
  1401. X/* another monster has killed the monster mdef */
  1402. Xvoid
  1403. Xmonkilled(mdef, fltxt, how)
  1404. Xregister struct monst *mdef;
  1405. Xconst char *fltxt;
  1406. Xuchar how;
  1407. X{
  1408. X    if (cansee(mdef->mx, mdef->my) && fltxt)
  1409. X        pline("%s is %s%s%s!", Monnam(mdef),
  1410. X            (is_demon(mdef->data) || is_undead(mdef->data)) ?
  1411. X             "destroyed" : "killed",
  1412. X            *fltxt ? " by the " : "",
  1413. X            fltxt
  1414. X         );
  1415. X    else if(mdef->mtame)
  1416. X        You("have a sad feeling for a moment, then it passes.");
  1417. X
  1418. X    /* no corpses if digested */
  1419. X    if(how == AD_DGST)
  1420. X        mondead(mdef);
  1421. X    else
  1422. X        mondied(mdef);
  1423. X}
  1424. X
  1425. Xvoid
  1426. Xunstuck(mtmp)
  1427. Xregister struct monst *mtmp;
  1428. X{
  1429. X    if(u.ustuck == mtmp) {
  1430. X        if(u.uswallow){
  1431. X            u.ux = mtmp->mx;
  1432. X            u.uy = mtmp->my;
  1433. X            u.uswallow = 0;
  1434. X            u.uswldtim = 0;
  1435. X            if (Punished) placebc();
  1436. X            vision_full_recalc = 1;
  1437. X            docrt();
  1438. X        }
  1439. X        u.ustuck = 0;
  1440. X    }
  1441. X}
  1442. X
  1443. Xvoid
  1444. Xkilled(mtmp)
  1445. Xregister struct monst *mtmp;
  1446. X{
  1447. X    xkilled(mtmp, 1);
  1448. X}
  1449. X
  1450. X/* the player has killed the monster mtmp */
  1451. Xvoid
  1452. Xxkilled(mtmp, dest)
  1453. X    register struct monst *mtmp;
  1454. X/*
  1455. X * Dest=1, normal; dest=0, don't print message; dest=2, don't drop corpse
  1456. X * either; dest=3, message but no corpse
  1457. X */
  1458. X    int    dest;
  1459. X{
  1460. X    register int tmp, x = mtmp->mx, y = mtmp->my;
  1461. X    register struct permonst *mdat;
  1462. X    register struct obj *otmp;
  1463. X    register struct trap *t;
  1464. X    boolean chance, redisp = FALSE;
  1465. X    boolean wasinside = u.uswallow && (u.ustuck == mtmp);
  1466. X
  1467. X    if (dest & 1) {
  1468. X        if(!canseemon(mtmp) && !sensemon(mtmp)) You("destroy it!");
  1469. X        else {
  1470. X        You("destroy %s!",
  1471. X            mtmp->mtame ? x_monnam(mtmp, 0, "poor", 0)
  1472. X            : mon_nam(mtmp));
  1473. X        }
  1474. X    }
  1475. X
  1476. X    if (mtmp->mtrapped &&
  1477. X        ((t = t_at(x, y)) && (t->ttyp == PIT || t->ttyp == SPIKED_PIT)) &&
  1478. X        sobj_at(BOULDER, x, y))
  1479. X        dest ^= 2; /*
  1480. X                * Prevent corpses/treasure being created "on top"
  1481. X                * of the boulder that is about to fall in. This is
  1482. X                * out of order, but cannot be helped unless this
  1483. X                * whole routine is rearranged.
  1484. X                */
  1485. X
  1486. X    /* dispose of monster and make cadaver */
  1487. X    if(stoned) monstone(mtmp);
  1488. X    else mondead(mtmp);
  1489. X
  1490. X    mdat = mtmp->data; /* note: mondead can change mtmp->data */
  1491. X
  1492. X    if (stoned) {
  1493. X        stoned = FALSE;
  1494. X        goto cleanup;
  1495. X    }
  1496. X
  1497. X    if((dest & 2)
  1498. X#ifdef REINCARNATION
  1499. X         || Is_rogue_level(&u.uz)
  1500. X#endif
  1501. X       || (mdat == &mons[PM_WRAITH] && Is_valley(&u.uz) && rn2(5)))
  1502. X        goto cleanup;
  1503. X
  1504. X#ifdef MAIL
  1505. X    if(mdat == &mons[PM_MAIL_DAEMON]) {
  1506. X        (void) mksobj_at(SCR_MAIL, x, y, FALSE);
  1507. X        stackobj(fobj);
  1508. X        redisp = TRUE;
  1509. X    }
  1510. X#endif
  1511. X    if(!accessible(x, y)) {
  1512. X        /* might be mimic in wall or dead eel or in a pool or lava */
  1513. X        redisp = TRUE;
  1514. X        if(wasinside) spoteffects();
  1515. X    } else if(x != u.ux || y != u.uy) {
  1516. X        /* might be here after swallowed */
  1517. X        if (!rn2(6) && !(mdat->geno & G_NOCORPSE)
  1518. X#ifdef KOPS
  1519. X                    && mdat->mlet != S_KOP
  1520. X#endif
  1521. X                            ) {
  1522. X            int typ;
  1523. X
  1524. X            otmp = mkobj_at(RANDOM_CLASS, x, y, TRUE);
  1525. X            /* Don't create large objects from small monsters */
  1526. X            typ = otmp->otyp;
  1527. X            if (mdat->msize < MZ_HUMAN && typ != FOOD_RATION
  1528. X#ifdef WALKIES
  1529. X                && typ != LEASH
  1530. X#endif
  1531. X                && typ != FIGURINE
  1532. X                && (otmp->owt > 3 ||
  1533. X                (typ >= SPEAR && typ <= LANCE) ||
  1534. X                (typ >= SCIMITAR && typ <= KATANA) ||
  1535. X                (typ == MORNING_STAR || typ == QUARTERSTAFF) ||
  1536. X                (typ >= BARDICHE && typ <= VOULGE) ||
  1537. X                (typ >= PLATE_MAIL &&
  1538. X                        typ <= YELLOW_DRAGON_SCALE_MAIL) ||
  1539. X                (typ == LARGE_SHIELD))) {
  1540. X                delobj(otmp);
  1541. X            } else redisp = TRUE;
  1542. X        }
  1543. X        /* Whether or not it always makes a corpse is, in theory,
  1544. X         * different from whether or not the corpse is "special";
  1545. X         * if we want both, we have to specify it explicitly.
  1546. X         */
  1547. X        if (bigmonst(mdat) || mdat == &mons[PM_LIZARD]
  1548. X               || is_golem(mdat)
  1549. X               || is_mplayer(mdat)
  1550. X               || is_rider(mdat))
  1551. X            chance = 1;
  1552. X        else chance = !rn2((int)
  1553. X            (2 + ((mdat->geno & G_FREQ)<2) + verysmall(mdat)));
  1554. X        if (chance)
  1555. X            (void) make_corpse(mtmp);
  1556. X    }
  1557. X    if(redisp) newsym(x,y);
  1558. Xcleanup:
  1559. X    /* punish bad behaviour */
  1560. X    if(is_human(mdat) && !always_hostile(mdat) &&
  1561. X       (monsndx(mdat) < PM_ARCHEOLOGIST || monsndx(mdat) > PM_WIZARD) &&
  1562. X       u.ualign.type != A_CHAOTIC) {
  1563. X        HTelepat &= ~INTRINSIC;
  1564. X        change_luck(-2);
  1565. X        if (Blind && !Telepat)
  1566. X            see_monsters(); /* Can't sense monsters any more. */
  1567. X    }
  1568. X    if((mtmp->mpeaceful && !rn2(2)) || mtmp->mtame)    change_luck(-1);
  1569. X    if (mdat->mlet == S_UNICORN &&
  1570. X                sgn(u.ualign.type) == sgn(mdat->maligntyp))
  1571. X        change_luck(-5);
  1572. X
  1573. X    /* give experience points */
  1574. X    tmp = experience(mtmp, u.nr_killed[monsndx(mdat)] + 1);
  1575. X    more_experienced(tmp, 0);
  1576. X    newexplevel();        /* will decide if you go up */
  1577. X
  1578. X    /* adjust alignment points */
  1579. X#ifdef MULDGN
  1580. X    if(mdat->msound == MS_LEADER)        /* REAL BAD! */
  1581. X        adjalign(-(u.ualign.record+(int)ALIGNLIM/2));
  1582. X    else if(mdat->msound == MS_NEMESIS)    /* Real good! */
  1583. X        adjalign((int)(ALIGNLIM/4));
  1584. X    else if(mdat->msound == MS_GUARDIAN)    /* Bad */
  1585. X        adjalign(-(int)(ALIGNLIM/8));
  1586. X    else
  1587. X#endif
  1588. X        if (mtmp->ispriest) {
  1589. X        adjalign((p_coaligned(mtmp)) ? -2 : 2);
  1590. X        if(mdat->maligntyp == A_NONE)
  1591. X            adjalign((int)(ALIGNLIM / 4));        /* BIG bonus */
  1592. X    } else if(mtmp->mtame)
  1593. X        adjalign(-15);    /* bad!! */
  1594. X    else if (mtmp->mpeaceful)
  1595. X        adjalign(-5);
  1596. X
  1597. X    /* malign was already adjusted for u.ualign.type and randomization */
  1598. X    adjalign(mtmp->malign);
  1599. X}
  1600. X
  1601. X/* changes the monster into a stone monster of the same type */
  1602. X/* this should only be called when poly_when_stoned() is true */
  1603. Xvoid
  1604. Xmon_to_stone(mtmp)
  1605. X    register struct monst *mtmp;
  1606. X{
  1607. X    if(mtmp->data->mlet == S_GOLEM) {
  1608. X    /* it's a golem, and not a stone golem */
  1609. X    if(canseemon(mtmp))
  1610. X        pline("%s solidifies...", Monnam(mtmp));
  1611. X    (void) newcham(mtmp, &mons[PM_STONE_GOLEM]);
  1612. X    if(canseemon(mtmp))
  1613. X        pline("Now it's %s", a_monnam(mtmp));
  1614. X    } else
  1615. X    impossible("Can't polystone %s", a_monnam(mtmp));
  1616. X}
  1617. X
  1618. Xvoid
  1619. Xmnexto(mtmp)    /* Make monster mtmp next to you (if possible) */
  1620. X    struct monst *mtmp;
  1621. X{
  1622. X    coord mm;
  1623. X
  1624. X    if(!enexto(&mm, u.ux, u.uy, mtmp->data)) return;
  1625. X
  1626. X    rloc_to(mtmp, mm.x, mm.y);
  1627. X}
  1628. X
  1629. X/* mnearto()
  1630. X * Put monster near (or at) location if possible.
  1631. X * Returns:
  1632. X *    1 - if a monster was moved from x, y to put mtmp at x, y.
  1633. X *    0 - in most cases.
  1634. X */
  1635. Xboolean
  1636. Xmnearto(mtmp,x,y,move_other)
  1637. Xregister struct monst *mtmp;
  1638. Xxchar x, y;
  1639. Xboolean move_other;    /* make sure mtmp gets to x, y! so move m_at(x, y) */
  1640. X{
  1641. X    struct monst *othermon = (struct monst *)0;
  1642. X    xchar newx, newy;
  1643. X    coord mm;
  1644. X
  1645. X    if ((mtmp->mx == x) && (mtmp->my == y)) return(FALSE);
  1646. X
  1647. X    if (move_other && (othermon = m_at(x, y))) {
  1648. X        if (othermon->wormno)
  1649. X            remove_worm(othermon);
  1650. X        else
  1651. X            remove_monster(x, y);
  1652. X    }
  1653. X
  1654. X    newx = x;
  1655. X    newy = y;
  1656. X
  1657. X    if (!goodpos(newx, newy, mtmp, mtmp->data)) {
  1658. X        /* actually we have real problems if enexto ever fails.
  1659. X         * migrating_mons that need to be placed will cause
  1660. X         * no end of trouble.
  1661. X         */
  1662. X        if (!enexto(&mm, newx, newy, mtmp->data)) return(FALSE);
  1663. X        newx = mm.x; newy = mm.y;
  1664. X    }
  1665. X
  1666. X    rloc_to(mtmp, newx, newy);
  1667. X
  1668. X    if (move_other && othermon) {
  1669. X        othermon->mx = othermon->my = 0;
  1670. X        (void) mnearto(othermon, x, y, FALSE);
  1671. X        if ((othermon->mx != x) || (othermon->my != y))
  1672. X        return(TRUE);
  1673. X    }
  1674. X
  1675. X    return(FALSE);
  1676. X}
  1677. X
  1678. X
  1679. Xstatic const char *poiseff[] = {
  1680. X
  1681. X    " feel very weak", "r brain is on fire",
  1682. X    "r judgement is impaired", "r muscles won't obey you",
  1683. X    " feel very sick", " break out in hives"
  1684. X};
  1685. X
  1686. Xvoid
  1687. Xpoisontell(typ)
  1688. X
  1689. X    int    typ;
  1690. X{
  1691. X    pline("You%s.", poiseff[typ]);
  1692. X}
  1693. X
  1694. Xvoid
  1695. Xpoisoned(string, typ, pname, fatal)
  1696. Xregister const char *string, *pname;
  1697. Xregister int  typ, fatal;
  1698. X{
  1699. X    register int i, plural;
  1700. X    boolean thrown_weapon = !strncmp(string, "poison", 6);
  1701. X        /* admittedly a kludge... */
  1702. X
  1703. X    if(strcmp(string, "blast") && !thrown_weapon) {
  1704. X        /* 'blast' has already given a 'poison gas' message */
  1705. X        /* so have "poison arrow", "poison dart", etc... */
  1706. X        plural = (string[strlen(string) - 1] == 's')? 1 : 0;
  1707. X        /* avoid "The" Orcus's sting was poisoned... */
  1708. X        pline("%s%s %s poisoned!", isupper(*string) ? "" : "The ",
  1709. X            string, plural ? "were" : "was");
  1710. X    }
  1711. X
  1712. X    if(Poison_resistance) {
  1713. X        if(!strcmp(string, "blast")) shieldeff(u.ux, u.uy);
  1714. X        pline("The poison doesn't seem to affect you.");
  1715. X        return;
  1716. X    }
  1717. X    i = rn2(fatal + 20*thrown_weapon);
  1718. X    if(i == 0 && typ != A_CHA) {
  1719. X        u.uhp = -1;
  1720. X        pline("The poison was deadly...");
  1721. X    } else if(i <= 5) {
  1722. X        pline("You%s!", poiseff[typ]);
  1723. X        (void) adjattrib(typ, thrown_weapon ? -1 : -rn1(3,3), TRUE);
  1724. X    } else {
  1725. X        i = thrown_weapon ? rnd(6) : rn1(10,6);
  1726. X        if(Half_physical_damage) i = (i+1) / 2;
  1727. X        losehp(i, pname, KILLED_BY_AN);
  1728. X    }
  1729. X    if(u.uhp < 1) {
  1730. X        killer_format = KILLED_BY_AN;
  1731. X        killer = pname;
  1732. X        done(POISONING);
  1733. X    }
  1734. X}
  1735. X
  1736. X/* monster responds to player action; not the same as a passive attack */
  1737. X/* assumes reason for response has been tested, and response _must_ be made */
  1738. Xvoid
  1739. Xm_respond(mtmp)
  1740. Xregister struct monst *mtmp;
  1741. X{
  1742. X    if(mtmp->data->msound == MS_SHRIEK) {
  1743. X    if(flags.soundok)
  1744. X        pline("%s shrieks.", Monnam(mtmp));
  1745. X    aggravate();
  1746. X    }
  1747. X}
  1748. X
  1749. X#endif /* OVLB */
  1750. X#ifdef OVL2
  1751. X
  1752. Xvoid
  1753. Xsetmangry(mtmp)
  1754. Xregister struct monst *mtmp;
  1755. X{
  1756. X    mtmp->data->mflags3 &= ~M3_WAITMASK;
  1757. X    if(!mtmp->mpeaceful) return;
  1758. X    if(mtmp->mtame) return;
  1759. X    mtmp->mpeaceful = 0;
  1760. X    if(mtmp->ispriest) {
  1761. X        if(p_coaligned(mtmp)) adjalign(-5); /* very bad */
  1762. X        else adjalign(2);
  1763. X    } else
  1764. X        adjalign(-1);        /* attacking peaceful monsters is bad */
  1765. X    if(humanoid(mtmp->data) || mtmp->isshk || mtmp->isgd)
  1766. X        pline("%s gets angry!", Monnam(mtmp));
  1767. X#ifdef SOUNDS
  1768. X    else if (flags.verbose && flags.soundok) growl(mtmp);
  1769. X#endif
  1770. X}
  1771. X
  1772. Xvoid
  1773. Xwakeup(mtmp)
  1774. Xregister struct monst *mtmp;
  1775. X{
  1776. X    mtmp->msleep = 0;
  1777. X    mtmp->meating = 0;    /* assume there's no salvagable food left */
  1778. X    setmangry(mtmp);
  1779. X    if(mtmp->m_ap_type) seemimic(mtmp);
  1780. X}
  1781. X
  1782. X/* Wake up nearby monsters. */
  1783. Xvoid
  1784. Xwake_nearby()
  1785. X{
  1786. X    register struct monst *mtmp;
  1787. X
  1788. X    for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  1789. X        if (distu(mtmp->mx,mtmp->my) < u.ulevel*20) {
  1790. X        if(mtmp->msleep)  mtmp->msleep = 0;
  1791. X        if(mtmp->mtame)   EDOG(mtmp)->whistletime = moves;
  1792. X        }
  1793. X    }
  1794. X}
  1795. X
  1796. X/* NOTE: we must check for mimicry before calling this routine */
  1797. Xvoid
  1798. Xseemimic(mtmp)
  1799. Xregister struct monst *mtmp;
  1800. X{
  1801. X    /*
  1802. X     *  Discovered mimics don't block light.
  1803. X     */
  1804. X    if ((mtmp->m_ap_type == M_AP_FURNITURE &&
  1805. X        (mtmp->mappearance==S_hcdoor || mtmp->mappearance==S_vcdoor))||
  1806. X        (mtmp->m_ap_type == M_AP_OBJECT && mtmp->mappearance == BOULDER))
  1807. X        unblock_point(mtmp->mx,mtmp->my);
  1808. X
  1809. X    mtmp->m_ap_type = M_AP_NOTHING;
  1810. X    mtmp->mappearance = 0;
  1811. X    newsym(mtmp->mx,mtmp->my);
  1812. X}
  1813. X
  1814. X/* force all chameleons to become normal */
  1815. Xvoid
  1816. Xrescham()
  1817. X{
  1818. X    register struct monst *mtmp;
  1819. X
  1820. X    for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  1821. X        if(mtmp->cham) {
  1822. X            mtmp->cham = 0;
  1823. X            (void) newcham(mtmp, &mons[PM_CHAMELEON]);
  1824. X        }
  1825. X        if(is_were(mtmp->data) && mtmp->data->mlet != S_HUMAN)
  1826. X            new_were(mtmp);
  1827. X        if(mtmp->m_ap_type && cansee(mtmp->mx, mtmp->my)) {
  1828. X            seemimic(mtmp);
  1829. X            /* we pretend that the mimic doesn't */
  1830. X            /* know that it has been unmasked.   */
  1831. X            mtmp->msleep = 1;
  1832. X        }
  1833. X    }
  1834. X}
  1835. X
  1836. X/* Let the chameleons change again -dgk */
  1837. Xvoid
  1838. Xrestartcham()
  1839. X{
  1840. X    register struct monst *mtmp;
  1841. X
  1842. X    for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  1843. X        if (mtmp->data == &mons[PM_CHAMELEON])
  1844. X            mtmp->cham = 1;
  1845. X        if(mtmp->data->mlet == S_MIMIC && mtmp->msleep &&
  1846. X                cansee(mtmp->mx, mtmp->my)) {
  1847. X            set_mimic_sym(mtmp);
  1848. X            newsym(mtmp->mx,mtmp->my);
  1849. X        }
  1850. X    }
  1851. X}
  1852. X
  1853. X/* unwatched hiders may hide again; if so, a 1 is returned.  */
  1854. XSTATIC_OVL boolean
  1855. Xrestrap(mtmp)
  1856. Xregister struct monst *mtmp;
  1857. X{
  1858. X    if(mtmp->cham || mtmp->mcan || mtmp->m_ap_type ||
  1859. X       cansee(mtmp->mx, mtmp->my) || rn2(3) || (mtmp == u.ustuck))
  1860. X        return(FALSE);
  1861. X
  1862. X    if(mtmp->data->mlet == S_MIMIC) {
  1863. X        set_mimic_sym(mtmp);
  1864. X        return(TRUE);
  1865. X    } else
  1866. X        if(levl[mtmp->mx][mtmp->my].typ == ROOM)  {
  1867. X        mtmp->mundetected = 1;
  1868. X        return(TRUE);
  1869. X        }
  1870. X
  1871. X    return(FALSE);
  1872. X}
  1873. X
  1874. X/* make a chameleon look like a new monster; returns 1 if it actually changed */
  1875. Xint
  1876. Xnewcham(mtmp, mdat)
  1877. Xregister struct monst *mtmp;
  1878. Xregister struct permonst *mdat;
  1879. X{
  1880. X    register int mhp, hpn, hpd;
  1881. X    int tryct;
  1882. X    struct permonst *olddata = mtmp->data;
  1883. X
  1884. X    /* mdat = 0 -> caller wants a random monster shape */
  1885. X    tryct = 0;
  1886. X    if(mdat == 0) {
  1887. X        while (++tryct < 100) {
  1888. X            mdat = &mons[rn2(NUMMONS)];
  1889. X            /* polyok rules out all M2_PNAME and M2_WERE's */
  1890. X            if (!is_human(mdat) && polyok(mdat)
  1891. X                    && !(mdat->geno & G_GENOD))
  1892. X                break;
  1893. X        }
  1894. X        if (tryct >= 100) return(0); /* Should never happen */
  1895. X    }
  1896. X
  1897. X    if(is_male(mdat)) {
  1898. X        if(mtmp->female) mtmp->female = FALSE;
  1899. X    } else if (is_female(mdat)) {
  1900. X        if(!mtmp->female) mtmp->female = TRUE;
  1901. X    } else if (!is_neuter(mdat)) {
  1902. X        if(!rn2(10)) mtmp->female = !mtmp->female;
  1903. X    }
  1904. X
  1905. X    if(mdat == mtmp->data) return(0);    /* still the same monster */
  1906. X
  1907. X    if(mtmp->wormno) {            /* throw tail away */
  1908. X        wormgone(mtmp);
  1909. X        place_monster(mtmp, mtmp->mx, mtmp->my);
  1910. X    }
  1911. X
  1912. X    hpn = mtmp->mhp;
  1913. X    hpd = (mtmp->m_lev < 50) ? ((int)mtmp->m_lev)*8 : mdat->mlevel;
  1914. X    if(!hpd) hpd = 4;
  1915. X
  1916. X    mtmp->m_lev = adj_lev(mdat);        /* new monster level */
  1917. X
  1918. X    mhp = (mtmp->m_lev < 50) ? ((int)mtmp->m_lev)*8 : mdat->mlevel;
  1919. X    if(!mhp) mhp = 4;
  1920. X
  1921. X    /* new hp: same fraction of max as before */
  1922. X#ifndef LINT
  1923. X    mtmp->mhp = (int)(((long)hpn*(long)mhp)/(long)hpd);
  1924. X#endif
  1925. X    if(mtmp->mhp < 0) mtmp->mhp = hpn;    /* overflow */
  1926. X/* Unlikely but not impossible; a 1HD creature with 1HP that changes into a
  1927. X   0HD creature will require this statement */
  1928. X    if (!mtmp->mhp) mtmp->mhp = 1;
  1929. X
  1930. X/* and the same for maximum hit points */
  1931. X    hpn = mtmp->mhpmax;
  1932. X#ifndef LINT
  1933. X    mtmp->mhpmax = (int)(((long)hpn*(long)mhp)/(long)hpd);
  1934. X#endif
  1935. X    if(mtmp->mhpmax < 0) mtmp->mhpmax = hpn;    /* overflow */
  1936. X    if (!mtmp->mhpmax) mtmp->mhpmax = 1;
  1937. X
  1938. X    mtmp->data = mdat;
  1939. X    mtmp->minvis = !!(mdat->mlet == S_STALKER);
  1940. X    if (!hides_under(mdat) || !OBJ_AT(mtmp->mx, mtmp->my))
  1941. X        mtmp->mundetected = 0;
  1942. X    if (u.ustuck == mtmp) {
  1943. X        if(u.uswallow) {
  1944. X            if(!attacktype(mdat,AT_ENGL)) {
  1945. X                /* Does mdat care? */
  1946. X                if (!noncorporeal(mdat) && !amorphous(mdat) &&
  1947. X                    !is_whirly(mdat) &&
  1948. X                    (mdat != &mons[PM_YELLOW_LIGHT])) {
  1949. X                    You("break out of %s%s!", mon_nam(mtmp),
  1950. X                        (is_animal(mdat)?
  1951. X                        "'s stomach" : ""));
  1952. X                    mtmp->mhp = 1;  /* almost dead */
  1953. X                }
  1954. X                expels(mtmp, olddata, FALSE);
  1955. X            }
  1956. X        } else {
  1957. X            if(!sticks(mdat)
  1958. X#ifdef POLYSELF
  1959. X                && !sticks(uasmon)
  1960. X#endif
  1961. X                )
  1962. X                unstuck(mtmp);
  1963. X        }
  1964. X    }
  1965. X
  1966. X    if ( (mdat == &mons[PM_LONG_WORM]) && (mtmp->wormno = get_wormno()) ) {
  1967. X        /* we can now create worms with tails - 11/91 */
  1968. X        initworm(mtmp, rn2(5));
  1969. X        if (count_wsegs(mtmp))
  1970. X        place_worm_tail_randomly(mtmp, mtmp->mx, mtmp->my);
  1971. X    }
  1972. X
  1973. X    newsym(mtmp->mx,mtmp->my);
  1974. X#ifdef MUSE
  1975. X    mon_break_armor(mtmp);
  1976. X    possibly_unwield(mtmp);
  1977. X#endif
  1978. X    return(1);
  1979. X}
  1980. X
  1981. X#endif /* OVL2 */
  1982. X#ifdef OVLB
  1983. X
  1984. Xvoid
  1985. Xgolemeffects(mon, damtype, dam)
  1986. Xregister struct monst *mon;
  1987. Xint damtype, dam;
  1988. X{
  1989. X    int heal=0, slow=0;
  1990. X
  1991. X    if (mon->data != &mons[PM_FLESH_GOLEM]
  1992. X                    && mon->data != &mons[PM_IRON_GOLEM])
  1993. X        return;
  1994. X
  1995. X    if (mon->data == &mons[PM_FLESH_GOLEM]) {
  1996. X        if (damtype == AD_ELEC) heal = dam / 6;
  1997. X        else if (damtype == AD_FIRE || damtype == AD_COLD) slow = 1;
  1998. X    } else {
  1999. X        if (damtype == AD_ELEC) slow = 1;
  2000. X        else if (damtype == AD_FIRE) heal = dam;
  2001. X    }
  2002. X    if (slow) {
  2003. X        if (mon->mspeed != MSLOW) {
  2004. X            if (mon->mspeed == MFAST) mon->mspeed = 0;
  2005. X            else mon->mspeed = MSLOW;
  2006. X            if (cansee(mon->mx, mon->my))
  2007. X                pline("%s seems to be moving slower.",
  2008. X                    Monnam(mon));
  2009. X        }
  2010. X    }
  2011. X    if (heal) {
  2012. X        if (mon->mhp < mon->mhpmax) {
  2013. X            mon->mhp += dam;
  2014. X            if (mon->mhp > mon->mhpmax) mon->mhp = mon->mhpmax;
  2015. X            if (cansee(mon->mx, mon->my))
  2016. X                pline("%s seems healthier.", Monnam(mon));
  2017. X        }
  2018. X    }
  2019. X}
  2020. X
  2021. Xboolean
  2022. Xangry_guards(silent)
  2023. Xregister boolean silent;
  2024. X{
  2025. X    register struct monst *mtmp;
  2026. X    register int ct = 0, nct = 0, sct = 0, slct = 0;
  2027. X
  2028. X    for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  2029. X        if((mtmp->data == &mons[PM_WATCHMAN] ||
  2030. X                   mtmp->data == &mons[PM_WATCH_CAPTAIN])
  2031. X                    && mtmp->mpeaceful) {
  2032. X            ct++;
  2033. X            if(cansee(mtmp->mx, mtmp->my) && mtmp->mcanmove) {
  2034. X                if (distu(mtmp->mx, mtmp->my) == 2) nct++;
  2035. X                else sct++;
  2036. X            }
  2037. X            if(mtmp->msleep || mtmp->mfrozen) {
  2038. X                slct++;
  2039. X                mtmp->msleep = mtmp->mfrozen = 0;
  2040. X            }
  2041. X            mtmp->mpeaceful = 0;
  2042. X        }
  2043. X    }
  2044. X    if(ct) {
  2045. X        if(!silent) { /* do we want pline msgs? */
  2046. X        if(slct) pline("The guard%s wake%s up!",
  2047. X                 slct > 1 ? "s" : "", slct == 1 ? "s" : "");
  2048. X        if(nct || sct) {
  2049. X            if(nct) pline("The guard%s get%s angry!",
  2050. X                nct == 1 ? "" : "s", nct == 1 ? "s" : "");
  2051. X            else if(!Blind)
  2052. X                You("see %sangry guard%s approaching!",
  2053. X                  sct == 1 ? "an " : "", sct > 1 ? "s" : "");
  2054. X        } else if(flags.soundok)
  2055. X            You("hear the shrill sound of a guard's whistle.");
  2056. X        }
  2057. X        return(TRUE);
  2058. X    }
  2059. X    return(FALSE);
  2060. X}
  2061. X
  2062. Xvoid
  2063. Xpacify_guards()
  2064. X{
  2065. X    register struct monst *mtmp;
  2066. X
  2067. X    for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  2068. X        if (mtmp->data == &mons[PM_WATCHMAN] ||
  2069. X        mtmp->data == &mons[PM_WATCH_CAPTAIN])
  2070. X        mtmp->mpeaceful = 1;
  2071. X    }
  2072. X}
  2073. X#endif /* OVLB */
  2074. X
  2075. X/*mon.c*/
  2076. END_OF_FILE
  2077. if test 42736 -ne `wc -c <'src/mon.c'`; then
  2078.     echo shar: \"'src/mon.c'\" unpacked with wrong size!
  2079. fi
  2080. # end of 'src/mon.c'
  2081. fi
  2082. echo shar: End of archive 21 \(of 108\).
  2083. cp /dev/null ark21isdone
  2084. MISSING=""
  2085. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
  2086. 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
  2087. 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
  2088. 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
  2089. 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
  2090. 101 102 103 104 105 106 107 108 ; do
  2091.     if test ! -f ark${I}isdone ; then
  2092.     MISSING="${MISSING} ${I}"
  2093.     fi
  2094. done
  2095. if test "${MISSING}" = "" ; then
  2096.     echo You have unpacked all 108 archives.
  2097.     echo "Now execute 'rebuild.sh'"
  2098.     rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
  2099. else
  2100.     echo You still need to unpack the following archives:
  2101.     echo "        " ${MISSING}
  2102. fi
  2103. ##  End of shell archive.
  2104. exit 0
  2105.