home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume16 / nethck31 / part45 < prev    next >
Encoding:
Internet Message Format  |  1993-01-31  |  57.2 KB

  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: v16i053:  nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part45/108
  5. Message-ID: <4347@master.CNA.TEK.COM>
  6. Date: 30 Jan 93 01:13:52 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 1770
  9. Approved: billr@saab.CNA.TEK.COM
  10. Xref: uunet comp.sources.games:1602
  11.  
  12. Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
  13. Posting-number: Volume 16, Issue 53
  14. Archive-name: nethack31/Part45
  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 45 (of 108)."
  27. # Contents:  src/muse.c sys/amiga/Install.ami
  28. # Wrapped by billr@saab on Wed Jan 27 16:09:04 1993
  29. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  30. if test -f 'src/muse.c' -a "${1}" != "-c" ; then 
  31.   echo shar: Will not clobber existing file \"'src/muse.c'\"
  32. else
  33. echo shar: Extracting \"'src/muse.c'\" \(37553 characters\)
  34. sed "s/^X//" >'src/muse.c' <<'END_OF_FILE'
  35. X/*    SCCS Id: @(#)muse.c    3.1    93/01/03    */
  36. X/* Monster item usage routine.  Copyright (C) 1990 by Ken Arromdee */
  37. X/* NetHack may be freely redistributed.  See license for details.  */
  38. X
  39. X#include "hack.h"
  40. X
  41. X#ifdef MUSE
  42. X
  43. Xextern int monstr[];
  44. X
  45. Xboolean m_using = FALSE;
  46. X
  47. X/* Let monsters use magic items.  Arbitrary assumptions: Monsters only use
  48. X * scrolls when they can see, monsters know when wands have 0 charges, monsters
  49. X * cannot recognize if items are cursed are not, monsters which are confused
  50. X * don't know not to read scrolls, etc....
  51. X */
  52. X
  53. Xstatic int FDECL(precheck, (struct monst *,struct obj *));
  54. Xstatic void FDECL(mzapmsg, (struct monst *,struct obj *,BOOLEAN_P));
  55. Xstatic void FDECL(mreadmsg, (struct monst *,struct obj *));
  56. Xstatic void FDECL(mquaffmsg, (struct monst *,struct obj *));
  57. Xstatic int FDECL(mbhitm, (struct monst *,struct obj *));
  58. Xstatic void FDECL(mbhit,
  59. X    (struct monst *,int,int FDECL((*),(MONST_P,OBJ_P)),
  60. X    int FDECL((*),(OBJ_P,OBJ_P)),struct obj *));
  61. Xstatic void FDECL(you_aggravate, (struct monst *));
  62. X
  63. Xstatic struct musable {
  64. X    struct obj *offensive;
  65. X    struct obj *defensive;
  66. X    struct obj *misc;
  67. X    int has_offense, has_defense, has_misc;
  68. X    /* =0, no capability; otherwise, different numbers.
  69. X     * If it's an object, the object is also set (it's 0 otherwise).
  70. X     */
  71. X} m;
  72. Xstatic int trapx, trapy;
  73. Xstatic boolean zap_oseen;
  74. X    /* for wands which use mbhitm and are zapped at players.  We usually
  75. X     * want an oseen local to the function, but this is impossible since the
  76. X     * function mbhitm has to be compatible with the normal zap routines,
  77. X     * and those routines don't remember who zapped the wand.
  78. X     */
  79. X
  80. X/* Any preliminary checks which may result in the monster being unable to use
  81. X * the item.  Returns 0 if nothing happened, 2 if the monster can't do anything
  82. X * (i.e. it teleported) and 1 if it's dead.
  83. X */
  84. Xstatic int
  85. Xprecheck(mon, obj)
  86. Xstruct monst *mon;
  87. Xstruct obj *obj;
  88. X{
  89. X    boolean vis = cansee(mon->mx, mon->my);
  90. X
  91. X    if (!obj) return 0;
  92. X    if (obj->oclass == POTION_CLASS) {
  93. X        coord cc;
  94. X        static const char *empty = "The potion turns out to be empty.";
  95. X        const char * potion_descr ;
  96. X        struct monst *mtmp;
  97. X
  98. X        potion_descr = OBJ_DESCR(objects[obj->otyp]);
  99. X        if (!strcmp(potion_descr, "milky") && !rn2(13)) {
  100. X        if (!enexto(&cc, mon->mx, mon->my, &mons[PM_GHOST])) return 0;
  101. X        mquaffmsg(mon, obj);
  102. X        m_useup(mon, obj);
  103. X        mtmp = makemon(&mons[PM_GHOST], cc.x, cc.y);
  104. X        if (!mtmp) {
  105. X            if (vis) pline(empty);
  106. X        } else {
  107. X            if (vis) {
  108. X            pline("As %s opens the bottle, an enormous %s emerges!",
  109. X               mon_nam(mon),
  110. X               Hallucination ? rndmonnam() : (const char *)"ghost");
  111. X            pline("%s is frightened to death, and unable to move.",
  112. X                Monnam(mon));
  113. X            }
  114. X            mon->mcanmove = 0;
  115. X            mon->mfrozen = 3;
  116. X        }
  117. X        return 2;
  118. X        }
  119. X        if (!strcmp(potion_descr, "smoky") && !rn2(13)) {
  120. X        if (!enexto(&cc, mon->mx, mon->my, &mons[PM_DJINNI])) return 0;
  121. X        mquaffmsg(mon, obj);
  122. X        m_useup(mon, obj);
  123. X        mtmp = makemon(&mons[PM_DJINNI], cc.x, cc.y);
  124. X        if (!mtmp) {
  125. X            if (vis) pline(empty);
  126. X        } else {
  127. X            if (vis)
  128. X            pline("In a cloud of smoke, %s emerges!",
  129. X                            a_monnam(mtmp));
  130. X            pline("%s speaks.", vis ? Monnam(mtmp) : "Something");
  131. X        /* I suspect few players will be upset that monsters */
  132. X        /* can't wish for wands of death here.... */
  133. X            if (rn2(2)) {
  134. X            verbalize("You freed me!");
  135. X            mtmp->mpeaceful = 1;
  136. X            set_malign(mtmp);
  137. X            } else {
  138. X            verbalize("It is about time.");
  139. X            if (vis) pline("%s vanishes.", Monnam(mtmp));
  140. X            mongone(mtmp);
  141. X            }
  142. X        }
  143. X        return 2;
  144. X        }
  145. X    }
  146. X    if (obj->oclass == WAND_CLASS && obj->cursed && !rn2(100)) {
  147. X        int dam = d(obj->spe+2, 6);
  148. X
  149. X#ifdef SOUNDS
  150. X        if (flags.soundok)
  151. X#endif
  152. X                {
  153. X        if (vis) pline("%s zaps %s, which suddenly explodes!",
  154. X            Monnam(mon), an(xname(obj)));
  155. X        else You("hear a zap and an explosion in the distance.");
  156. X        }
  157. X        m_useup(mon, obj);
  158. X        if (mon->mhp <= dam) {
  159. X        monkilled(mon, "", AD_RBRE);
  160. X        return 1;
  161. X        }
  162. X        else mon->mhp -= dam;
  163. X        m.has_defense = m.has_offense = m.has_misc = 0;
  164. X        /* Only one needed to be set to 0 but the others are harmless */
  165. X    }
  166. X    return 0;
  167. X}
  168. X
  169. Xstatic void
  170. Xmzapmsg(mtmp, otmp, self)
  171. Xstruct monst *mtmp;
  172. Xstruct obj *otmp;
  173. Xboolean self;
  174. X{
  175. X    if (!cansee(mtmp->mx, mtmp->my)) {
  176. X#ifdef SOUNDS
  177. X        if (flags.soundok)
  178. X#endif
  179. X            You("hear a distant zap.");
  180. X    } else if (self)
  181. X        pline("%s zaps %sself with %s!",
  182. X            Monnam(mtmp),
  183. X            gender(mtmp)==2 ? "it" : gender(mtmp) ? "her" : "him",
  184. X            doname(otmp));
  185. X    else {
  186. X        pline("%s zaps %s!", Monnam(mtmp), an(xname(otmp)));
  187. X        stop_occupation();
  188. X    }
  189. X}
  190. X
  191. Xstatic void
  192. Xmreadmsg(mtmp, otmp)
  193. Xstruct monst *mtmp;
  194. Xstruct obj *otmp;
  195. X{
  196. X    boolean vis = (cansee(mtmp->mx, mtmp->my));
  197. X#ifdef SOUNDS
  198. X    if (flags.soundok)
  199. X#endif
  200. X        otmp->dknown = 1;
  201. X    if (!vis) {
  202. X#ifdef SOUNDS
  203. X        if (flags.soundok)
  204. X#endif
  205. X            You("hear %s reading %s.",
  206. X            an(Hallucination ? rndmonnam() : mtmp->data->mname),
  207. X            singular(otmp, doname));
  208. X    } else pline("%s reads %s!", Monnam(mtmp), singular(otmp,doname));
  209. X    if (mtmp->mconf
  210. X#ifdef SOUNDS
  211. X        && (vis || flags.soundok)
  212. X#endif
  213. X                    )
  214. X        pline("Being confused, %s mispronounces the magic words...",
  215. X            vis ? mon_nam(mtmp) : gender(mtmp)==2 ? "it" :
  216. X            gender(mtmp) ? "he" : "she");
  217. X}
  218. X
  219. Xstatic void
  220. Xmquaffmsg(mtmp, otmp)
  221. Xstruct monst *mtmp;
  222. Xstruct obj *otmp;
  223. X{
  224. X    if (cansee(mtmp->mx, mtmp->my)) {
  225. X        otmp->dknown = 1;
  226. X        pline("%s drinks %s!", Monnam(mtmp), singular(otmp, doname));
  227. X    } else
  228. X#ifdef SOUNDS
  229. X        if (flags.soundok)
  230. X#endif
  231. X            You("hear a chugging sound.");
  232. X}
  233. X
  234. X/* Defines for various types of stuff.  The order in which monsters prefer
  235. X * to use them is determined by the order of the code logic, not the
  236. X * numerical order in which they are defined.
  237. X */
  238. X#define MUSE_SCR_TELEPORTATION 1
  239. X#define MUSE_WAN_TELEPORTATION_SELF 2
  240. X#define MUSE_POT_HEALING 3
  241. X#define MUSE_POT_EXTRA_HEALING 4
  242. X#define MUSE_WAN_DIGGING 5
  243. X#define MUSE_TRAPDOOR 6
  244. X#define MUSE_TELEPORT_TRAP 7
  245. X#define MUSE_UPSTAIRS 8
  246. X#define MUSE_DOWNSTAIRS 9
  247. X#define MUSE_WAN_CREATE_MONSTER 10
  248. X#define MUSE_SCR_CREATE_MONSTER 11
  249. X#define MUSE_UP_LADDER 12
  250. X#define MUSE_DN_LADDER 13
  251. X#define MUSE_SSTAIRS 14
  252. X#define MUSE_WAN_TELEPORTATION 15
  253. X#ifdef ARMY
  254. X# define MUSE_BUGLE 16
  255. X#endif
  256. X/*
  257. X#define MUSE_INNATE_TPT 9999
  258. X * We cannot use this.  Since monsters get unlimited teleportation, if they
  259. X * were allowed to teleport at will you could never catch them.  Instead,
  260. X * assume they only teleport at random times, despite the inconsistency that if
  261. X * you polymorph into one you teleport at will.
  262. X */
  263. X
  264. X/* Select a defensive item/action for a monster.  Returns TRUE iff one is
  265. X * found.
  266. X */
  267. Xboolean
  268. Xfind_defensive(mtmp)
  269. Xstruct monst *mtmp;
  270. X{
  271. X    register struct obj *obj;
  272. X    struct trap *t;
  273. X    int x=mtmp->mx, y=mtmp->my;
  274. X    boolean stuck = (mtmp == u.ustuck);
  275. X    boolean immobile = (mtmp->data->mmove == 0);
  276. X
  277. X    if (mtmp->mpeaceful || is_animal(mtmp->data) || mindless(mtmp->data))
  278. X        return 0;
  279. X    if (u.uswallow && stuck) return 0;
  280. X    if(dist2(x, y, mtmp->mux, mtmp->muy) > 25)
  281. X        return 0;
  282. X    if(mtmp->mhp >= mtmp->mhpmax ||
  283. X            (mtmp->mhp >= 10 && mtmp->mhp*5 >= mtmp->mhpmax))
  284. X        return 0;
  285. X
  286. X    m.defensive = (struct obj *)0;
  287. X    m.has_defense = 0;
  288. X
  289. X    if (levl[x][y].typ == STAIRS && !stuck && !immobile) {
  290. X        if (x == xdnstair && y == ydnstair)
  291. X            m.has_defense = MUSE_DOWNSTAIRS;
  292. X        if (x == xupstair && y == yupstair && ledger_no(&u.uz) != 1)
  293. X    /* Unfair to let the monsters leave the dungeon with the Amulet */
  294. X    /* (or go to the endlevel since you also need it, to get there) */
  295. X            m.has_defense = MUSE_UPSTAIRS;
  296. X    } else if (levl[x][y].typ == LADDER && !stuck && !immobile) {
  297. X        if (x == xupladder && y == yupladder)
  298. X            m.has_defense = MUSE_UP_LADDER;
  299. X        if (x == xdnladder && y == ydnladder)
  300. X            m.has_defense = MUSE_DN_LADDER;
  301. X    } else if (sstairs.sx &&
  302. X           sstairs.sx == mtmp->mx && sstairs.sy == mtmp->my) {
  303. X        m.has_defense = MUSE_SSTAIRS;
  304. X    } else if (!stuck && !immobile) {
  305. X    /* Note: trapdoors take precedence over teleport traps. */
  306. X        int xx, yy;
  307. X
  308. X        for(xx = x-1; xx <= x+1; xx++) for(yy = y-1; yy <= y+1; yy++)
  309. X        if (isok(xx,yy))
  310. X        if (xx != u.ux && yy != u.uy)
  311. X        if (mtmp->data != &mons[PM_GRID_BUG] || xx == x || yy == y)
  312. X        if ((xx==x && yy==y) || !level.monsters[xx][yy])
  313. X        if ((t = t_at(xx,yy)) != 0) {
  314. X            if (t->ttyp == TRAPDOOR
  315. X                && !is_floater(mtmp->data)
  316. X                && !mtmp->isshk && !mtmp->isgd
  317. X                && !mtmp->ispriest
  318. X                && Can_fall_thru(&u.uz)
  319. X                        ) {
  320. X                trapx = xx;
  321. X                trapy = yy;
  322. X                m.has_defense = MUSE_TRAPDOOR;
  323. X            } else if (t->ttyp == TELEP_TRAP && m.has_defense != MUSE_TRAPDOOR) {
  324. X                trapx = xx;
  325. X                trapy = yy;
  326. X                m.has_defense = MUSE_TELEPORT_TRAP;
  327. X            }
  328. X        }
  329. X    }
  330. X
  331. X    if (nohands(mtmp->data))    /* can't use objects */
  332. X        goto botm;
  333. X
  334. X#ifdef ARMY
  335. X    if (is_mercenary(mtmp->data) && (obj = m_carrying(mtmp, BUGLE))) {
  336. X        int xx, yy;
  337. X        struct monst *mon;
  338. X
  339. X        /* Distance is arbitrary.  What we really want to do is
  340. X         * have the soldier play the bugle when it sees or
  341. X         * remembers soldiers nearby...
  342. X         */
  343. X        for(xx = x-3; xx <= x+3; xx++) for(yy = y-3; yy <= y+3; yy++)
  344. X        if (isok(xx,yy))
  345. X        if ((mon = m_at(xx,yy)) && is_mercenary(mon->data) &&
  346. X                mon->data != &mons[PM_GUARD] &&
  347. X                (mon->msleep || (!mon->mcanmove))) {
  348. X            m.defensive = obj;
  349. X            m.has_defense = MUSE_BUGLE;
  350. X        }
  351. X    }
  352. X#endif
  353. X    if (m.has_defense == MUSE_UPSTAIRS ||
  354. X            m.has_defense == MUSE_DOWNSTAIRS ||
  355. X            m.has_defense == MUSE_UP_LADDER ||
  356. X            m.has_defense == MUSE_DN_LADDER ||
  357. X            m.has_defense == MUSE_SSTAIRS ||
  358. X#ifdef ARMY
  359. X            m.has_defense == MUSE_BUGLE ||
  360. X#endif
  361. X            m.has_defense == MUSE_TRAPDOOR)
  362. X        goto botm;
  363. X#define nomore(x) if(m.has_defense==x) continue;
  364. X    for (obj = mtmp->minvent; obj; obj = obj->nobj) {
  365. X        /* nomore(MUSE_WAN_DIGGING); */
  366. X        if (m.has_defense == MUSE_WAN_DIGGING) break;
  367. X        if (obj->otyp == WAN_DIGGING && obj->spe > 0 && !stuck
  368. X            && !mtmp->isshk && !mtmp->isgd && !mtmp->ispriest
  369. X            && !is_floater(mtmp->data)
  370. X#ifdef MULDGN
  371. X            && !Is_knox(&u.uz)
  372. X#endif
  373. X            && !In_endgame(&u.uz)) {
  374. X            m.defensive = obj;
  375. X            m.has_defense = MUSE_WAN_DIGGING;
  376. X        }
  377. X        nomore(MUSE_TELEPORT_TRAP);
  378. X        nomore(MUSE_WAN_TELEPORTATION_SELF);
  379. X        nomore(MUSE_WAN_TELEPORTATION);
  380. X        if(obj->otyp == WAN_TELEPORTATION && obj->spe > 0) {
  381. X            m.defensive = obj;
  382. X            m.has_defense = (mon_has_amulet(mtmp))
  383. X                ? MUSE_WAN_TELEPORTATION
  384. X                : MUSE_WAN_TELEPORTATION_SELF;
  385. X        }
  386. X        nomore(MUSE_SCR_TELEPORTATION);
  387. X        if(obj->otyp == SCR_TELEPORTATION && mtmp->mcansee
  388. X           && haseyes(mtmp->data)
  389. X           && (!obj->cursed ||
  390. X               (!mtmp->isshk && !mtmp->isgd && !mtmp->ispriest))) {
  391. X            m.defensive = obj;
  392. X            m.has_defense = MUSE_SCR_TELEPORTATION;
  393. X        }
  394. X        nomore(MUSE_POT_EXTRA_HEALING);
  395. X        if(obj->otyp == POT_EXTRA_HEALING) {
  396. X            m.defensive = obj;
  397. X            m.has_defense = MUSE_POT_EXTRA_HEALING;
  398. X        }
  399. X        nomore(MUSE_WAN_CREATE_MONSTER);
  400. X        if(obj->otyp == WAN_CREATE_MONSTER && obj->spe > 0) {
  401. X            m.defensive = obj;
  402. X            m.has_defense = MUSE_WAN_CREATE_MONSTER;
  403. X        }
  404. X        nomore(MUSE_POT_HEALING);
  405. X        if(obj->otyp == POT_HEALING) {
  406. X            m.defensive = obj;
  407. X            m.has_defense = MUSE_POT_HEALING;
  408. X        }
  409. X        nomore(MUSE_SCR_CREATE_MONSTER);
  410. X        if(obj->otyp == SCR_CREATE_MONSTER) {
  411. X            m.defensive = obj;
  412. X            m.has_defense = MUSE_SCR_CREATE_MONSTER;
  413. X        }
  414. X    }
  415. Xbotm:    return !!m.has_defense;
  416. X#undef nomore
  417. X}
  418. X
  419. X/* Perform a defensive action for a monster.  Must be called immediately
  420. X * after find_defensive().  Return values are 0: did something, 1: died,
  421. X * 2: did something and can't attack again (i.e. teleported).
  422. X */
  423. Xint
  424. Xuse_defensive(mtmp)
  425. Xstruct monst *mtmp;
  426. X{
  427. X    int i;
  428. X    struct obj *otmp = m.defensive;
  429. X    boolean vis = cansee(mtmp->mx, mtmp->my);
  430. X    boolean vismon = canseemon(mtmp);
  431. X    boolean oseen = otmp && (otmp->oclass == SCROLL_CLASS || vis);
  432. X
  433. X    if ((i = precheck(mtmp, otmp)) != 0) return i;
  434. X    switch(m.has_defense) {
  435. X#ifdef ARMY
  436. X    case MUSE_BUGLE:
  437. X        if (canseemon(mtmp))
  438. X            pline("%s plays %s!", Monnam(mtmp), doname(otmp));
  439. X        else if (flags.soundok)
  440. X            You("hear the sound of a bugle!");
  441. X        awaken_soldiers();
  442. X        return 2;
  443. X#endif
  444. X    case MUSE_WAN_TELEPORTATION_SELF:
  445. X        mzapmsg(mtmp, otmp, TRUE);
  446. X        otmp->spe--;
  447. X        if (oseen) makeknown(WAN_TELEPORTATION);
  448. Xmon_tele:
  449. X        if(level.flags.noteleport) {
  450. X            if (vismon)
  451. X              pline("A mysterious force prevents %s from teleporting!",
  452. X            mon_nam(mtmp));
  453. X            return 2;
  454. X        }
  455. X        if((/*mon_has_amulet(mtmp)||*/ Is_wiz1_level(&u.uz) ||
  456. X              Is_wiz2_level(&u.uz) || Is_wiz3_level(&u.uz))
  457. X                                && !rn2(3)) {
  458. X            if (vismon)
  459. X            pline("%s seems disoriented for a moment.",
  460. X                Monnam(mtmp));
  461. X            return 2;
  462. X        }
  463. X        rloc(mtmp);
  464. X        return 2;
  465. X    case MUSE_WAN_TELEPORTATION:
  466. X        zap_oseen = oseen;
  467. X        mzapmsg(mtmp, otmp, FALSE);
  468. X        otmp->spe--;
  469. X        m_using = TRUE;
  470. X        mbhit(mtmp,rn1(8,6),mbhitm,bhito,otmp);
  471. X        m_using = FALSE;
  472. X        return 2;
  473. X    case MUSE_SCR_TELEPORTATION:
  474. X        {
  475. X        int obj_is_cursed = otmp->cursed;
  476. X
  477. X        mreadmsg(mtmp, otmp);
  478. X        m_useup(mtmp, otmp);    /* otmp might be free'ed */
  479. X        if (oseen) makeknown(SCR_TELEPORTATION);
  480. X        if (obj_is_cursed) {
  481. X            if (mon_has_amulet(mtmp) || In_endgame(&u.uz)) {
  482. X                if (vismon)
  483. X                pline("%s seems very disoriented for a moment.",
  484. X                    Monnam(mtmp));
  485. X                return 2;
  486. X            }
  487. X            if (Is_botlevel(&u.uz)) goto mon_tele;
  488. X            else {
  489. X                int nlev;
  490. X                d_level flev;
  491. X
  492. X                if (rn2(5)) nlev = rnd((int)depth(&u.uz) + 3);
  493. X                else {
  494. X                pline("%s shudders for a moment.",
  495. X                            Monnam(mtmp));
  496. X                return 2; 
  497. X                }
  498. X                if (nlev == depth(&u.uz)) {
  499. X                if (u.uz.dlevel == 1) nlev++;
  500. X                else if (In_hell(&u.uz)) nlev--;
  501. X                else nlev++;
  502. X                }
  503. X                get_level(&flev, nlev);
  504. X                migrate_to_level(mtmp, ledger_no(&flev), 0);
  505. X            }
  506. X        } else goto mon_tele;
  507. X        return 2;
  508. X        }
  509. X    case MUSE_WAN_DIGGING:
  510. X        mzapmsg(mtmp, otmp, FALSE);
  511. X        otmp->spe--;
  512. X        if (oseen) makeknown(WAN_DIGGING);
  513. X        if(IS_FURNITURE(levl[mtmp->mx][mtmp->my].typ)
  514. X           || (sstairs.sx && sstairs.sx == mtmp->mx &&
  515. X                sstairs.sy == mtmp->my)) {
  516. X            pline("The digging ray is ineffective.");
  517. X            return 2;
  518. X        }
  519. X        if (!Can_dig_down(&u.uz)) {
  520. X            if(canseemon(mtmp))
  521. X            pline("The floor here is too hard to dig in.");
  522. X            return 2;
  523. X        }
  524. X        seetrap(maketrap(mtmp->mx, mtmp->my, TRAPDOOR));
  525. X        if (vis) {
  526. X            pline("%s's made a hole in the floor.", Monnam(mtmp));
  527. X            pline("%s falls through...", Monnam(mtmp));
  528. X        } else
  529. X# ifdef SOUNDS
  530. X            if (flags.soundok)
  531. X# endif
  532. X            You("hear something crash through the floor.");
  533. X        /* we made sure that there is a level for mtmp to go to */
  534. X        migrate_to_level(mtmp, ledger_no(&u.uz)+1, 0);
  535. X        return 2;
  536. X    case MUSE_WAN_CREATE_MONSTER:
  537. X        {    coord cc;
  538. X        struct permonst *pm=rndmonst();
  539. X
  540. X        if (!enexto(&cc, mtmp->mx, mtmp->my, pm)) return 0;
  541. X        mzapmsg(mtmp, otmp, FALSE);
  542. X        otmp->spe--;
  543. X        if (oseen) makeknown(WAN_CREATE_MONSTER);
  544. X        (void) makemon(pm, cc.x, cc.y);
  545. X        return 2;
  546. X        }
  547. X    case MUSE_SCR_CREATE_MONSTER:
  548. X        {    coord cc;
  549. X        struct permonst *pm=rndmonst();
  550. X        int cnt = 1;
  551. X
  552. X        if (!rn2(73)) cnt += rnd(4);
  553. X        if (mtmp->mconf || otmp->cursed) cnt += 12;
  554. X        mreadmsg(mtmp, otmp);
  555. X        while(cnt--) {
  556. X            struct monst *mon;
  557. X
  558. X            if (!enexto(&cc, mtmp->mx, mtmp->my, pm)) continue;
  559. X            mon = makemon(mtmp->mconf ? &mons[PM_ACID_BLOB]
  560. X                : rndmonst(), cc.x, cc.y);
  561. X            if (mon) newsym(mon->mx,mon->my);
  562. X        }
  563. X        if (oseen && !objects[SCR_CREATE_MONSTER].oc_name_known
  564. X              && !objects[SCR_CREATE_MONSTER].oc_uname)
  565. X            docall(otmp); /* not makeknown(); be consistent */
  566. X        m_useup(mtmp, otmp);
  567. X        return 2;
  568. X        }
  569. X    case MUSE_TRAPDOOR:
  570. X        /* trapdoors on "bottom" levels of dungeons are rock-drop
  571. X         * trapdoors, not holes in the floor.  We check here for
  572. X         * safety.
  573. X         */
  574. X        if (Is_botlevel(&u.uz)) return 0;
  575. X        if (vis) pline("%s %s into a trapdoor!", Monnam(mtmp),
  576. X            makeplural(locomotion(mtmp->data, "jump")));
  577. X        seetrap(t_at(trapx,trapy));
  578. X
  579. X        /*  don't use rloc_to() because worm tails must "move" */
  580. X        remove_monster(mtmp->mx, mtmp->my);
  581. X        newsym(mtmp->mx, mtmp->my);    /* update old location */
  582. X        place_monster(mtmp, trapx, trapy);
  583. X        if (mtmp->wormno) worm_move(mtmp);
  584. X        newsym(trapx, trapy);
  585. X
  586. X        migrate_to_level(mtmp, ledger_no(&u.uz)+1, 0);
  587. X        return 2;
  588. X    case MUSE_UPSTAIRS:
  589. X        /* Monsters without amulets escape the dungeon and are
  590. X         * gone for good when they leave up the up stairs.
  591. X         * Monsters with amulets would reach the endlevel,
  592. X         * which we cannot allow since that would leave the
  593. X         * player stranded.
  594. X         */
  595. X        if (ledger_no(&u.uz) == 1) {
  596. X            if (mon_has_special(mtmp))
  597. X                return 0;
  598. X            if (vismon) pline("%s escapes the dungeon!",
  599. X                Monnam(mtmp));
  600. X            mongone(mtmp);
  601. X            return 2;
  602. X        }
  603. X        if (vismon) pline("%s escapes upstairs!", Monnam(mtmp));
  604. X        migrate_to_level(mtmp, ledger_no(&u.uz)-1, 2);
  605. X        return 2;
  606. X    case MUSE_DOWNSTAIRS:
  607. X        if (vismon) pline("%s escapes downstairs!", Monnam(mtmp));
  608. X        migrate_to_level(mtmp, ledger_no(&u.uz)+1, 1);
  609. X        return 2;
  610. X    case MUSE_UP_LADDER:
  611. X        if (vismon) pline("%s escapes up the ladder!", Monnam(mtmp));
  612. X        migrate_to_level(mtmp, ledger_no(&u.uz)-1, 4);
  613. X        return 2;
  614. X    case MUSE_DN_LADDER:
  615. X        if (vismon) pline("%s escapes down the ladder!", Monnam(mtmp));
  616. X        migrate_to_level(mtmp, ledger_no(&u.uz)+1, 3);
  617. X        return 2;
  618. X    case MUSE_SSTAIRS:
  619. X        /* the stairs leading up from the 1st level are */
  620. X        /* regular stairs, not sstairs.            */
  621. X        if (sstairs.up) {
  622. X            if (vismon)
  623. X                pline("%s escapes upstairs!", Monnam(mtmp));
  624. X            if(Inhell) {
  625. X                migrate_to_level(mtmp,
  626. X                     ledger_no(&sstairs.tolev), 0);
  627. X                return 2;
  628. X            }
  629. X        } else    if (vismon)
  630. X            pline("%s escapes downstairs!", Monnam(mtmp));
  631. X        migrate_to_level(mtmp, ledger_no(&sstairs.tolev), 5);
  632. X        return 2;
  633. X    case MUSE_TELEPORT_TRAP:
  634. X        if (vis) pline("%s %s onto a teleport trap!", Monnam(mtmp),
  635. X            makeplural(locomotion(mtmp->data, "jump")));
  636. X        seetrap(t_at(trapx,trapy));
  637. X
  638. X        /*  don't use rloc_to() because worm tails must "move" */
  639. X        remove_monster(mtmp->mx, mtmp->my);
  640. X        newsym(mtmp->mx, mtmp->my);    /* update old location */
  641. X        place_monster(mtmp, trapx, trapy);
  642. X        if (mtmp->wormno) worm_move(mtmp);
  643. X        newsym(trapx, trapy);
  644. X
  645. X        goto mon_tele;
  646. X    case MUSE_POT_HEALING:
  647. X        mquaffmsg(mtmp, otmp);
  648. X        i = d(5,2) + 5 * !!bcsign(otmp);
  649. X        mtmp->mhp += i;
  650. X        if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = ++mtmp->mhpmax;
  651. X        if (!otmp->cursed) mtmp->mcansee = 1;
  652. X        if (vismon) pline("%s begins to look better.", Monnam(mtmp));
  653. X        if (oseen) makeknown(POT_HEALING);
  654. X        m_useup(mtmp, otmp);
  655. X        return 2;
  656. X    case MUSE_POT_EXTRA_HEALING:
  657. X        mquaffmsg(mtmp, otmp);
  658. X        i = d(5,4) + 5 * !!bcsign(otmp);
  659. X        mtmp->mhp += i;
  660. X        if (mtmp->mhp > mtmp->mhpmax)
  661. X            mtmp->mhp = (mtmp->mhpmax += (otmp->blessed ? 5 : 2));
  662. X        mtmp->mcansee = 1;
  663. X        if (vismon) pline("%s looks much better.", Monnam(mtmp));
  664. X        if (oseen) makeknown(POT_EXTRA_HEALING);
  665. X        m_useup(mtmp, otmp);
  666. X        return 2;
  667. X    case 0: return 0; /* i.e. an exploded wand */
  668. X    default: impossible("%s wanted to perform action %d?", Monnam(mtmp),
  669. X            m.has_defense);
  670. X        break;
  671. X    }
  672. X    return 0;
  673. X}
  674. X
  675. Xint
  676. Xrnd_defensive_item(mtmp)
  677. Xstruct monst *mtmp;
  678. X{
  679. X    struct permonst *pm = mtmp->data;
  680. X    int difficulty = monstr[(monsndx(pm))];
  681. X
  682. X    if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
  683. X            || pm->mlet == S_GHOST
  684. X# ifdef KOPS
  685. X            || pm->mlet == S_KOP
  686. X# endif
  687. X        ) return 0;
  688. X    switch (rn2(8 + (difficulty > 3) + (difficulty > 6) +
  689. X                (difficulty > 8))) {
  690. X        case 0: case 1:
  691. X            return SCR_TELEPORTATION;
  692. X        case 2: return SCR_CREATE_MONSTER;
  693. X        case 3: case 4:
  694. X            return POT_HEALING;
  695. X        case 5: return POT_EXTRA_HEALING;
  696. X        case 6: case 9:
  697. X            return WAN_TELEPORTATION;
  698. X        case 7: if (is_floater(pm) || mtmp->isshk || mtmp->isgd
  699. X                        || mtmp->ispriest
  700. X                                    )
  701. X                return 0;
  702. X            else
  703. X                return WAN_DIGGING;
  704. X        case 8: case 10:
  705. X            return WAN_CREATE_MONSTER;
  706. X    }
  707. X    /*NOTREACHED*/
  708. X    return 0;
  709. X}
  710. X
  711. X#define MUSE_WAN_DEATH 1
  712. X#define MUSE_WAN_SLEEP 2
  713. X#define MUSE_WAN_FIRE 3
  714. X#define MUSE_WAN_COLD 4
  715. X#define MUSE_WAN_LIGHTNING 5
  716. X#define MUSE_WAN_MAGIC_MISSILE 6
  717. X#define MUSE_WAN_STRIKING 7
  718. X#define MUSE_SCR_FIRE 8
  719. X#define MUSE_POT_PARALYSIS 9
  720. X#define MUSE_POT_BLINDNESS 10
  721. X#define MUSE_POT_CONFUSION 11
  722. X
  723. X/* Select an offensive item/action for a monster.  Returns TRUE iff one is
  724. X * found.
  725. X */
  726. Xboolean
  727. Xfind_offensive(mtmp)
  728. Xstruct monst *mtmp;
  729. X{
  730. X    register struct obj *obj;
  731. X    boolean ranged_stuff = lined_up(mtmp);
  732. X
  733. X    m.offensive = (struct obj *)0;
  734. X    m.has_offense = 0;
  735. X    if (mtmp->mpeaceful || is_animal(mtmp->data) ||
  736. X                mindless(mtmp->data) || nohands(mtmp->data))
  737. X        return 0;
  738. X    if (u.uswallow) return 0;
  739. X    if (in_your_sanctuary(mtmp->mx, mtmp->my)) return 0;
  740. X
  741. X    if (!ranged_stuff) return 0;
  742. X#define nomore(x) if(m.has_offense==x) continue;
  743. X    for(obj=mtmp->minvent; obj; obj=obj->nobj) {
  744. X        /* nomore(MUSE_WAN_DEATH); */
  745. X        if (m.has_defense == WAN_DEATH) break;
  746. X        if(obj->otyp == WAN_DEATH && obj->spe > 0) {
  747. X            m.offensive = obj;
  748. X            m.has_offense = MUSE_WAN_DEATH;
  749. X        }
  750. X        nomore(MUSE_WAN_SLEEP);
  751. X        if(obj->otyp == WAN_SLEEP && obj->spe > 0 && multi >= 0) {
  752. X            m.offensive = obj;
  753. X            m.has_offense = MUSE_WAN_SLEEP;
  754. X        }
  755. X        nomore(MUSE_WAN_FIRE);
  756. X        if(obj->otyp == WAN_FIRE && obj->spe > 0) {
  757. X            m.offensive = obj;
  758. X            m.has_offense = MUSE_WAN_FIRE;
  759. X        }
  760. X        nomore(MUSE_WAN_COLD);
  761. X        if(obj->otyp == WAN_COLD && obj->spe > 0) {
  762. X            m.offensive = obj;
  763. X            m.has_offense = MUSE_WAN_COLD;
  764. X        }
  765. X        nomore(MUSE_WAN_LIGHTNING);
  766. X        if(obj->otyp == WAN_LIGHTNING && obj->spe > 0) {
  767. X            m.offensive = obj;
  768. X            m.has_offense = MUSE_WAN_LIGHTNING;
  769. X        }
  770. X        nomore(MUSE_WAN_MAGIC_MISSILE);
  771. X        if(obj->otyp == WAN_MAGIC_MISSILE && obj->spe > 0) {
  772. X            m.offensive = obj;
  773. X            m.has_offense = MUSE_WAN_MAGIC_MISSILE;
  774. X        }
  775. X        nomore(MUSE_WAN_STRIKING);
  776. X        if(obj->otyp == WAN_STRIKING && obj->spe > 0) {
  777. X            m.offensive = obj;
  778. X            m.has_offense = MUSE_WAN_STRIKING;
  779. X        }
  780. X        nomore(MUSE_POT_PARALYSIS);
  781. X        if(obj->otyp == POT_PARALYSIS && multi >= 0) {
  782. X            m.offensive = obj;
  783. X            m.has_offense = MUSE_POT_PARALYSIS;
  784. X        }
  785. X        nomore(MUSE_POT_BLINDNESS);
  786. X        if(obj->otyp == POT_BLINDNESS) {
  787. X            m.offensive = obj;
  788. X            m.has_offense = MUSE_POT_BLINDNESS;
  789. X        }
  790. X        nomore(MUSE_POT_CONFUSION);
  791. X        if(obj->otyp == POT_CONFUSION) {
  792. X            m.offensive = obj;
  793. X            m.has_offense = MUSE_POT_CONFUSION;
  794. X        }
  795. X#if 0
  796. X        nomore(MUSE_SCR_FIRE);
  797. X        /* even more restrictive than ranged_stuff */
  798. X        if(obj->otyp == SCR_FIRE && resists_fire(mtmp->data)
  799. X           && distu(mtmp->mx,mtmp->my)==1
  800. X           && mtmp->mcansee && haseyes(mtmp->data)) {
  801. X            m.offensive = obj;
  802. X            m.has_offense = MUSE_SCR_FIRE;
  803. X        }
  804. X#endif
  805. X    }
  806. X    return !!m.has_offense;
  807. X#undef nomore
  808. X}
  809. X
  810. Xstatic int
  811. Xmbhitm(mtmp, otmp)
  812. Xregister struct monst *mtmp;
  813. Xregister struct obj *otmp;
  814. X{
  815. X    int tmp;
  816. X
  817. X    if (mtmp != &youmonst) {
  818. X        mtmp->msleep = 0;
  819. X        if (mtmp->m_ap_type) seemimic(mtmp);
  820. X    }
  821. X    switch(otmp->otyp) {
  822. X    case WAN_STRIKING:
  823. X        if (mtmp == &youmonst) {
  824. X            if (zap_oseen) makeknown(WAN_STRIKING);
  825. X            if (rnd(20) < 10 + u.uac) {
  826. X                pline("The wand hits you!");
  827. X                tmp = d(2,12);
  828. X                if(Half_spell_damage) tmp = (tmp+1) / 2;
  829. X                losehp(tmp, "wand", KILLED_BY_AN);
  830. X            } else pline("The wand misses you.");
  831. X            stop_occupation();
  832. X            nomul(0);
  833. X        } else if (rnd(20) < 10+find_mac(mtmp)) {
  834. X            tmp = d(2,12);
  835. X            if(Half_spell_damage) tmp = (tmp+1) / 2;
  836. X            hit("wand", mtmp, exclam(tmp));
  837. X            (void) resist(mtmp, otmp->oclass, tmp, TELL);
  838. X            if (cansee(mtmp->mx, mtmp->my) && zap_oseen)
  839. X                makeknown(WAN_STRIKING);
  840. X        } else {
  841. X            miss("wand", mtmp);
  842. X            if (cansee(mtmp->mx, mtmp->my) && zap_oseen)
  843. X                makeknown(WAN_STRIKING);
  844. X        }
  845. X        break;
  846. X    case WAN_TELEPORTATION:
  847. X        if (mtmp == &youmonst) {
  848. X            if (zap_oseen) makeknown(WAN_TELEPORTATION);
  849. X            tele();
  850. X        } else {
  851. X            /* for consistency with zap.c, don't identify */
  852. X            if (mtmp->ispriest &&
  853. X                *in_rooms(mtmp->mx, mtmp->my, TEMPLE)) {
  854. X                if (cansee(mtmp->mx, mtmp->my))
  855. X                pline("%s resists the magic!", Monnam(mtmp));
  856. X                mtmp->msleep = 0;
  857. X                if(mtmp->m_ap_type) seemimic(mtmp);
  858. X            } else
  859. X                rloc(mtmp);
  860. X        }
  861. X        break;
  862. X    case WAN_CANCELLATION:
  863. X    case SPE_CANCELLATION:
  864. X        cancel_monst(mtmp, otmp, FALSE, TRUE, FALSE);
  865. X        break;
  866. X    }
  867. X    return 0;
  868. X}
  869. X
  870. X/* A modified bhit() for monsters.  Based on bhit() in zap.c.  Unlike
  871. X * buzz(), bhit() doesn't take into account the possibility of a monster
  872. X * zapping you, so we need a special function for it.  (Unless someone wants
  873. X * to merge the two functions...)
  874. X */
  875. Xstatic void
  876. Xmbhit(mon,range,fhitm,fhito,obj)
  877. Xstruct monst *mon;            /* monster shooting the wand */
  878. Xregister int range;            /* direction and range */
  879. Xint FDECL((*fhitm),(MONST_P,OBJ_P));
  880. Xint FDECL((*fhito),(OBJ_P,OBJ_P));    /* fns called when mon/obj hit */
  881. Xstruct obj *obj;            /* 2nd arg to fhitm/fhito */
  882. X{
  883. X    register struct monst *mtmp;
  884. X    register struct obj *otmp;
  885. X    register uchar typ;
  886. X    int ddx, ddy;
  887. X
  888. X    bhitpos.x = mon->mx;
  889. X    bhitpos.y = mon->my;
  890. X    ddx = sgn(mon->mux - mon->mx);
  891. X    ddy = sgn(mon->muy - mon->my);
  892. X
  893. X    while(range-- > 0) {
  894. X        int x,y;
  895. X
  896. X        bhitpos.x += ddx;
  897. X        bhitpos.y += ddy;
  898. X        x = bhitpos.x; y = bhitpos.y;
  899. X        if (find_drawbridge(&x,&y))
  900. X            switch (obj->otyp) {
  901. X            case WAN_STRIKING:
  902. X                destroy_drawbridge(x,y);
  903. X            }
  904. X        if(bhitpos.x==u.ux && bhitpos.y==u.uy) {
  905. X            (*fhitm)(&youmonst, obj);
  906. X            range -= 3;
  907. X        } else if(MON_AT(bhitpos.x, bhitpos.y)){
  908. X            mtmp = m_at(bhitpos.x,bhitpos.y);
  909. X            (*fhitm)(mtmp, obj);
  910. X            range -= 3;
  911. X        }
  912. X        /* modified by GAN to hit all objects */
  913. X        if(fhito){
  914. X            int hitanything = 0;
  915. X            register struct obj *next_obj;
  916. X
  917. X            for(otmp = level.objects[bhitpos.x][bhitpos.y];
  918. X                            otmp; otmp = next_obj) {
  919. X            /* Fix for polymorph bug, Tim Wright */
  920. X            next_obj = otmp->nexthere;
  921. X            hitanything += (*fhito)(otmp, obj);
  922. X            }
  923. X            if(hitanything)    range--;
  924. X        }
  925. X        typ = levl[bhitpos.x][bhitpos.y].typ;
  926. X        if(IS_DOOR(typ) || typ == SDOOR) {
  927. X            switch (obj->otyp) {
  928. X            case WAN_STRIKING:
  929. X                if (doorlock(obj, bhitpos.x, bhitpos.y))
  930. X                makeknown(obj->otyp);
  931. X                break;
  932. X            }
  933. X        }
  934. X        if(!ZAP_POS(typ) || (IS_DOOR(typ) &&
  935. X           (levl[bhitpos.x][bhitpos.y].doormask & (D_LOCKED | D_CLOSED)))
  936. X          ) {
  937. X            bhitpos.x -= ddx;
  938. X            bhitpos.y -= ddy;
  939. X            break;
  940. X        }
  941. X    }
  942. X}
  943. X
  944. X/* Perform an offensive action for a monster.  Must be called immediately
  945. X * after find_offensive().  Return values are same as use_defensive().
  946. X */
  947. Xint
  948. Xuse_offensive(mtmp)
  949. Xstruct monst *mtmp;
  950. X{
  951. X    int i;
  952. X    struct obj *otmp = m.offensive;
  953. X    boolean vis = cansee(mtmp->mx, mtmp->my);
  954. X    boolean oseen = otmp && (otmp->oclass == SCROLL_CLASS || vis);
  955. X
  956. X    if ((i = precheck(mtmp, otmp)) != 0) return i;
  957. X    switch(m.has_offense) {
  958. X    case MUSE_WAN_DEATH:
  959. X    case MUSE_WAN_SLEEP:
  960. X    case MUSE_WAN_FIRE:
  961. X    case MUSE_WAN_COLD:
  962. X    case MUSE_WAN_LIGHTNING:
  963. X    case MUSE_WAN_MAGIC_MISSILE:
  964. X        mzapmsg(mtmp, otmp, FALSE);
  965. X        otmp->spe--;
  966. X        if (oseen) makeknown(otmp->otyp);
  967. X        m_using = TRUE;
  968. X        buzz((int)(-30 - (otmp->otyp - WAN_MAGIC_MISSILE)),
  969. X            (otmp->otyp == WAN_MAGIC_MISSILE) ? 2 : 6,
  970. X            mtmp->mx, mtmp->my,
  971. X            sgn(mtmp->mux-mtmp->mx), sgn(mtmp->muy-mtmp->my));
  972. X        m_using = FALSE;
  973. X        return (mtmp->mhp <= 0) ? 1 : 2;
  974. X    case MUSE_WAN_TELEPORTATION:
  975. X    case MUSE_WAN_STRIKING:
  976. X        zap_oseen = oseen;
  977. X        mzapmsg(mtmp, otmp, FALSE);
  978. X        otmp->spe--;
  979. X        m_using = TRUE;
  980. X        mbhit(mtmp,rn1(8,6),mbhitm,bhito,otmp);
  981. X        m_using = FALSE;
  982. X        return 2;
  983. X#if 0
  984. X    case MUSE_SCR_FIRE:
  985. X        mreadmsg(mtmp, otmp);
  986. X        if (mtmp->mconf) {
  987. X            if (vis)
  988. X                pline("Oh, what a pretty fire!");
  989. X        } else {
  990. X            struct monst *mtmp2;
  991. X            int num;
  992. X
  993. X            if (vis)
  994. X                pline("The scroll erupts in a tower of flame!");
  995. X            shieldeff(mtmp->mx, mtmp->my);
  996. X            pline("%s is uninjured.", Monnam(mtmp));
  997. X            (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
  998. X            (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
  999. X            (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
  1000. X            num = (2*(rn1(3, 3) + 2 * bcsign(otmp)) + 1)/3;
  1001. X            if (Fire_resistance)
  1002. X                You("are not affected.");
  1003. X            if (Half_spell_damage) num = (num+1) / 2;
  1004. X            else losehp(num, "scroll of fire", KILLED_BY_AN);
  1005. X            for(mtmp2 = fmon; mtmp2; mtmp2 = mtmp2->nmon) {
  1006. X               if(mtmp == mtmp2) continue;
  1007. X               if(dist2(mtmp2->mx,mtmp2->my,mtmp->mx,mtmp->my) < 3){
  1008. X                if (resists_fire(mtmp2->data)) continue;
  1009. X                mtmp2->mhp -= num;
  1010. X                if(resists_cold(mtmp2->data))
  1011. X                    mtmp2->mhp -= 3*num;
  1012. X                if(mtmp2->mhp < 1) {
  1013. X                    mondied(mtmp2);
  1014. X                    break;
  1015. X                }
  1016. X                }
  1017. X            }
  1018. X        }
  1019. X        return 2;
  1020. X#endif
  1021. X    case MUSE_POT_PARALYSIS:
  1022. X    case MUSE_POT_BLINDNESS:
  1023. X    case MUSE_POT_CONFUSION:
  1024. X        /* Note: this setting of dknown doesn't suffice.  A monster
  1025. X         * which is out of sight might throw and it hits something _in_
  1026. X         * sight, a problem not existing with wands because wand rays
  1027. X         * are not objects.  Also set dknown in mthrowu.c.
  1028. X         */
  1029. X        if (cansee(mtmp->mx, mtmp->my)) {
  1030. X            otmp->dknown = 1;
  1031. X            pline("%s hurls %s!", Monnam(mtmp),
  1032. X                        singular(otmp, doname));
  1033. X        }
  1034. X        m_throw(mtmp, mtmp->mx, mtmp->my, sgn(mtmp->mux-mtmp->mx),
  1035. X            sgn(mtmp->muy-mtmp->my),
  1036. X            distmin(mtmp->mx,mtmp->my,mtmp->mux,mtmp->muy), otmp);
  1037. X        return 2;
  1038. X    case 0: return 0; /* i.e. an exploded wand */
  1039. X    default: impossible("%s wanted to perform action %d?", Monnam(mtmp),
  1040. X            m.has_offense);
  1041. X        break;
  1042. X    }
  1043. X    return 0;
  1044. X}
  1045. X
  1046. Xint
  1047. Xrnd_offensive_item(mtmp)
  1048. Xstruct monst *mtmp;
  1049. X{
  1050. X    struct permonst *pm = mtmp->data;
  1051. X    int difficulty = monstr[(monsndx(pm))];
  1052. X
  1053. X    if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
  1054. X            || pm->mlet == S_GHOST
  1055. X# ifdef KOPS
  1056. X            || pm->mlet == S_KOP
  1057. X# endif
  1058. X        ) return 0;
  1059. X    if (difficulty > 7 && !rn2(35)) return WAN_DEATH;
  1060. X    switch (rn2(7 - (difficulty < 4) + 4 * (difficulty > 6))) {
  1061. X        case 0: case 1:
  1062. X            return WAN_STRIKING;
  1063. X        case 2: return POT_CONFUSION;
  1064. X        case 3: return POT_BLINDNESS;
  1065. X        case 4: return POT_PARALYSIS;
  1066. X        case 5: case 6:
  1067. X            return WAN_MAGIC_MISSILE;
  1068. X        case 7: return WAN_SLEEP;
  1069. X        case 8: return WAN_FIRE;
  1070. X        case 9: return WAN_COLD;
  1071. X        case 10: return WAN_LIGHTNING;
  1072. X    }
  1073. X    /*NOTREACHED*/
  1074. X    return 0;
  1075. X}
  1076. X
  1077. X#define MUSE_POT_GAIN_LEVEL 1
  1078. X#define MUSE_WAN_MAKE_INVISIBLE 2
  1079. X#define MUSE_POT_INVISIBILITY 3
  1080. X#define MUSE_POLY_TRAP 4
  1081. X#define MUSE_WAN_POLYMORPH 5
  1082. X#define MUSE_POT_SPEED 6
  1083. X#define MUSE_WAN_SPEED_MONSTER 7
  1084. Xboolean
  1085. Xfind_misc(mtmp)
  1086. Xstruct monst *mtmp;
  1087. X{
  1088. X    register struct obj *obj;
  1089. X    int x=mtmp->mx, y=mtmp->my;
  1090. X#ifdef POLYSELF
  1091. X    struct trap *t;
  1092. X    int xx, yy;
  1093. X    boolean immobile = (mtmp->data->mmove == 0);
  1094. X#endif
  1095. X    boolean stuck = (mtmp == u.ustuck);
  1096. X
  1097. X    m.misc = (struct obj *)0;
  1098. X    m.has_misc = 0;
  1099. X    if (is_animal(mtmp->data) || mindless(mtmp->data))
  1100. X        return 0;
  1101. X    if (u.uswallow && stuck) return 0;
  1102. X
  1103. X    /* We arbitrarily limit to times when a player is nearby for the
  1104. X     * same reason as Junior Pac-Man doesn't have energizers eaten until
  1105. X     * you can see them...
  1106. X     */
  1107. X    if(dist2(x, y, mtmp->mux, mtmp->muy) > 36)
  1108. X        return 0;
  1109. X
  1110. X#ifdef POLYSELF
  1111. X    if (!stuck && !immobile &&
  1112. X            !mtmp->cham && monstr[(monsndx(mtmp->data))] < 6)
  1113. X      for(xx = x-1; xx <= x+1; xx++)
  1114. X        for(yy = y-1; yy <= y+1; yy++)
  1115. X        if (isok(xx,yy) && (xx != u.ux || yy != u.uy))
  1116. X            if (mtmp->data != &mons[PM_GRID_BUG] || xx == x || yy == y)
  1117. X            if (/* (xx==x && yy==y) || */ !level.monsters[xx][yy])
  1118. X                if ((t = t_at(xx,yy)) != 0) {
  1119. X                if (t->ttyp == POLY_TRAP) {
  1120. X                    trapx = xx;
  1121. X                    trapy = yy;
  1122. X                    m.has_misc = MUSE_POLY_TRAP;
  1123. X                    return TRUE;
  1124. X                }
  1125. X                }
  1126. X#endif
  1127. X    if (nohands(mtmp->data))
  1128. X        return 0;
  1129. X
  1130. X#define nomore(x) if(m.has_misc==x) continue;
  1131. X    for(obj=mtmp->minvent; obj; obj=obj->nobj) {
  1132. X        /* Monsters shouldn't recognize cursed items; this kludge is */
  1133. X        /* necessary to prevent serious problems though... */
  1134. X        if(obj->otyp == POT_GAIN_LEVEL && (!obj->cursed ||
  1135. X                (!mtmp->isgd && !mtmp->isshk && !mtmp->ispriest))) {
  1136. X            m.misc = obj;
  1137. X            m.has_misc = MUSE_POT_GAIN_LEVEL;
  1138. X        }
  1139. X        /* Note: peaceful/tame monsters won't make themselves
  1140. X         * invisible unless you can see them.  Not really right, but...
  1141. X         */
  1142. X        nomore(MUSE_WAN_MAKE_INVISIBLE);
  1143. X        if(obj->otyp == WAN_MAKE_INVISIBLE && obj->spe > 0 &&
  1144. X             !mtmp->minvis && (!mtmp->mpeaceful || See_invisible)
  1145. X            && (mtmp->data != &mons[PM_MEDUSA] || mtmp->mcan)) {
  1146. X            m.misc = obj;
  1147. X            m.has_misc = MUSE_WAN_MAKE_INVISIBLE;
  1148. X        }
  1149. X        nomore(MUSE_POT_INVISIBILITY);
  1150. X        if(obj->otyp == POT_INVISIBILITY &&
  1151. X             !mtmp->minvis && (!mtmp->mpeaceful || See_invisible)) {
  1152. X            m.misc = obj;
  1153. X            m.has_misc = MUSE_POT_INVISIBILITY;
  1154. X        }
  1155. X        nomore(MUSE_WAN_SPEED_MONSTER);
  1156. X        if(obj->otyp == WAN_SPEED_MONSTER && obj->spe > 0
  1157. X                && mtmp->mspeed != MFAST && !mtmp->isgd) {
  1158. X            m.misc = obj;
  1159. X            m.has_misc = MUSE_WAN_SPEED_MONSTER;
  1160. X        }
  1161. X        nomore(MUSE_POT_SPEED);
  1162. X        if(obj->otyp == POT_SPEED && mtmp->mspeed != MFAST
  1163. X                            && !mtmp->isgd) {
  1164. X            m.misc = obj;
  1165. X            m.has_misc = MUSE_POT_SPEED;
  1166. X        }
  1167. X        nomore(MUSE_WAN_POLYMORPH);
  1168. X        if(obj->otyp == WAN_POLYMORPH && !mtmp->cham
  1169. X                && monstr[(monsndx(mtmp->data))] < 6) {
  1170. X            m.misc = obj;
  1171. X            m.has_misc = MUSE_WAN_POLYMORPH;
  1172. X        }
  1173. X    }
  1174. X    return !!m.has_misc;
  1175. X#undef nomore
  1176. X}
  1177. X
  1178. Xint
  1179. Xuse_misc(mtmp)
  1180. Xstruct monst *mtmp;
  1181. X{
  1182. X    int i;
  1183. X    struct obj *otmp = m.misc;
  1184. X    boolean vis = cansee(mtmp->mx, mtmp->my);
  1185. X    boolean vismon = canseemon(mtmp);
  1186. X    boolean oseen = otmp && (otmp->oclass == SCROLL_CLASS || vis);
  1187. X
  1188. X    if ((i = precheck(mtmp, otmp)) != 0) return i;
  1189. X    switch(m.has_misc) {
  1190. X    case MUSE_POT_GAIN_LEVEL:
  1191. X        mquaffmsg(mtmp, otmp);
  1192. X        if (otmp->cursed) {
  1193. X            if (Can_rise_up(&u.uz)) {
  1194. X            register int tolev = depth(&u.uz)-1;
  1195. X            d_level tolevel;
  1196. X
  1197. X            get_level(&tolevel, tolev);
  1198. X            /* insurance against future changes... */
  1199. X            if(on_level(&tolevel, &u.uz)) goto skipmsg;
  1200. X            if (vismon) {
  1201. X                pline("%s rises up, through the ceiling!",
  1202. X                Monnam(mtmp));
  1203. X                if(!objects[POT_GAIN_LEVEL].oc_name_known
  1204. X                  && !objects[POT_GAIN_LEVEL].oc_uname)
  1205. X                docall(otmp);
  1206. X            }
  1207. X            m_useup(mtmp, otmp);
  1208. X            migrate_to_level(mtmp, ledger_no(&tolevel), 0);
  1209. X            return 2;
  1210. X            } else {
  1211. Xskipmsg:
  1212. X            if (vismon) {
  1213. X                pline("%s looks uneasy.", Monnam(mtmp));
  1214. X                if(!objects[POT_GAIN_LEVEL].oc_name_known
  1215. X                  && !objects[POT_GAIN_LEVEL].oc_uname)
  1216. X                docall(otmp);
  1217. X            }
  1218. X            m_useup(mtmp, otmp);
  1219. X            return 2;
  1220. X            }
  1221. X        }
  1222. X        if (vismon) pline("%s seems more experienced.", Monnam(mtmp));
  1223. X        i = rnd(8);
  1224. X        if (oseen) makeknown(POT_GAIN_LEVEL);
  1225. X        m_useup(mtmp, otmp);
  1226. X        if (!grow_up(mtmp,(struct monst *)0)) return 1;
  1227. X            /* grew into genocided monster */
  1228. X        mtmp->mhp += i;
  1229. X        mtmp->mhpmax += i;
  1230. X        return 2;
  1231. X    case MUSE_WAN_MAKE_INVISIBLE:
  1232. X        mzapmsg(mtmp, otmp, TRUE);
  1233. X        otmp->spe--;
  1234. X        mtmp->minvis = 1;
  1235. X        newsym(mtmp->mx,mtmp->my);
  1236. X        if (mtmp->wormno) see_wsegs(mtmp);
  1237. X        return 2;
  1238. X    case MUSE_POT_INVISIBILITY:
  1239. X        mquaffmsg(mtmp, otmp);
  1240. X        if (vis) pline("Gee, all of a sudden %s can't see %sself.",
  1241. X            mon_nam(mtmp),
  1242. X            humanoid(mtmp->data) ? (mtmp->female ? "her" : "him")
  1243. X                         : "it");
  1244. X        if (oseen) makeknown(POT_INVISIBILITY);
  1245. X        mtmp->minvis = 1;
  1246. X        newsym(mtmp->mx,mtmp->my);
  1247. X        if (mtmp->wormno) see_wsegs(mtmp);
  1248. X        if (otmp->cursed) {
  1249. X            mtmp->minvis = 0;
  1250. X            pline("For some reason, %s presence is known to you.",
  1251. X                s_suffix(mon_nam(mtmp)));
  1252. X            you_aggravate(mtmp);
  1253. X            mtmp->minvis = 1;
  1254. X            newsym(mtmp->mx,mtmp->my);
  1255. X        }
  1256. X        m_useup(mtmp, otmp);
  1257. X        return 2;
  1258. X    case MUSE_WAN_SPEED_MONSTER:
  1259. X        mzapmsg(mtmp, otmp, TRUE);
  1260. X        otmp->spe--;
  1261. X        if (mtmp->mspeed == MSLOW) mtmp->mspeed = 0;
  1262. X        else mtmp->mspeed = MFAST;
  1263. X        return 2;
  1264. X    case MUSE_POT_SPEED:
  1265. X        mquaffmsg(mtmp, otmp);
  1266. X        if (vismon) pline("%s is suddenly moving much faster.",
  1267. X            Monnam(mtmp));
  1268. X        if (oseen) makeknown(POT_SPEED);
  1269. X        if (mtmp->mspeed == MSLOW) mtmp->mspeed = 0;
  1270. X        else mtmp->mspeed = MFAST;
  1271. X        m_useup(mtmp, otmp);
  1272. X        return 2;
  1273. X    case MUSE_WAN_POLYMORPH:
  1274. X        mzapmsg(mtmp, otmp, TRUE);
  1275. X        otmp->spe--;
  1276. X        (void) newcham(mtmp, rndmonst());
  1277. X        if (oseen) makeknown(WAN_POLYMORPH);
  1278. X        return 2;
  1279. X#ifdef POLYSELF
  1280. X    case MUSE_POLY_TRAP:
  1281. X        if (vismon)
  1282. X            pline("%s deliberately goes onto a polymorph trap!",
  1283. X              Monnam(mtmp));
  1284. X        seetrap(t_at(trapx,trapy));
  1285. X
  1286. X        /*  don't use rloc() due to worms */
  1287. X        remove_monster(mtmp->mx, mtmp->my);
  1288. X        newsym(mtmp->mx, mtmp->my);
  1289. X        place_monster(mtmp, trapx, trapy);
  1290. X        if (mtmp->wormno) worm_move(mtmp);
  1291. X        newsym(trapx, trapy);
  1292. X
  1293. X        (void) newcham(mtmp, (struct permonst *)0);
  1294. X        return 2;
  1295. X#endif
  1296. X    case 0: return 0; /* i.e. an exploded wand */
  1297. X    default: impossible("%s wanted to perform action %d?", Monnam(mtmp),
  1298. X            m.has_misc);
  1299. X        break;
  1300. X    }
  1301. X    return 0;
  1302. X}
  1303. X
  1304. Xstatic void
  1305. Xyou_aggravate(mtmp)
  1306. Xstruct monst *mtmp;
  1307. X{
  1308. X    cls();
  1309. X    show_glyph(mtmp->mx, mtmp->my, mon_to_glyph(mtmp));
  1310. X    display_self();
  1311. X    You("feel aggravated at %s.", mon_nam(mtmp));
  1312. X    display_nhwindow(WIN_MAP, TRUE);
  1313. X    docrt();
  1314. X    if (unconscious()) {
  1315. X        multi = -1;
  1316. X        nomovemsg =
  1317. X              "Aggravated, you are jolted into full consciousness.";
  1318. X    }
  1319. X}
  1320. X
  1321. Xint
  1322. Xrnd_misc_item(mtmp)
  1323. Xstruct monst *mtmp;
  1324. X{
  1325. X    struct permonst *pm = mtmp->data;
  1326. X    int difficulty = monstr[(monsndx(pm))];
  1327. X
  1328. X    if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
  1329. X            || pm->mlet == S_GHOST
  1330. X# ifdef KOPS
  1331. X            || pm->mlet == S_KOP
  1332. X# endif
  1333. X        ) return 0;
  1334. X    /* Unlike other rnd_item functions, we only allow _weak_ monsters
  1335. X     * to have this item; after all, the item will be used to strengthen
  1336. X     * the monster and strong monsters won't use it at all...
  1337. X     */
  1338. X    if (difficulty < 6 && !rn2(30)) return WAN_POLYMORPH;
  1339. X
  1340. X    switch (rn2(7)) {
  1341. X        case 0: case 1:
  1342. X            if (mtmp->isgd) return 0;
  1343. X            return POT_SPEED;
  1344. X        case 2:
  1345. X            if (mtmp->mpeaceful && !See_invisible) return 0;
  1346. X            return WAN_MAKE_INVISIBLE;
  1347. X        case 3:
  1348. X            if (mtmp->mpeaceful && !See_invisible) return 0;
  1349. X            return POT_INVISIBILITY;
  1350. X        case 4:
  1351. X            if (mtmp->isgd) return 0;
  1352. X            return WAN_SPEED_MONSTER;
  1353. X        case 5: case 6:
  1354. X            return POT_GAIN_LEVEL;
  1355. X    }
  1356. X    /*NOTREACHED*/
  1357. X    return 0;
  1358. X}
  1359. X
  1360. Xboolean
  1361. Xsearches_for_item(mon, obj)
  1362. Xstruct monst *mon;
  1363. Xstruct obj *obj;
  1364. X{
  1365. X    int typ = obj->otyp;
  1366. X
  1367. X    if (is_animal(mon->data) || mindless(mon->data)) return FALSE;
  1368. X    return((obj->oclass == WAND_CLASS && objects[typ].oc_dir == RAY)
  1369. X        || typ == WAN_STRIKING
  1370. X        || (!mon->minvis &&
  1371. X            (typ == WAN_MAKE_INVISIBLE || typ == POT_INVISIBILITY))
  1372. X        || (mon->mspeed != MFAST &&
  1373. X            (typ == WAN_SPEED_MONSTER || typ == POT_SPEED))
  1374. X        || typ == POT_HEALING
  1375. X        || typ == POT_EXTRA_HEALING
  1376. X        || typ == POT_GAIN_LEVEL
  1377. X        || (monstr[monsndx(mon->data)] < 6 && typ == WAN_POLYMORPH)
  1378. X        || (!is_floater(mon->data) && typ == WAN_DIGGING)
  1379. X        || typ == WAN_TELEPORTATION
  1380. X        || typ == SCR_TELEPORTATION
  1381. X        || typ == WAN_CREATE_MONSTER
  1382. X        || typ == SCR_CREATE_MONSTER
  1383. X        || typ == POT_PARALYSIS
  1384. X        || typ == POT_BLINDNESS
  1385. X        || typ == POT_CONFUSION
  1386. X        || (typ == PICK_AXE && needspick(mon->data))
  1387. X    );
  1388. X}
  1389. X#endif
  1390. X
  1391. X/*muse.c*/
  1392. END_OF_FILE
  1393. if test 37553 -ne `wc -c <'src/muse.c'`; then
  1394.     echo shar: \"'src/muse.c'\" unpacked with wrong size!
  1395. fi
  1396. # end of 'src/muse.c'
  1397. fi
  1398. if test -f 'sys/amiga/Install.ami' -a "${1}" != "-c" ; then 
  1399.   echo shar: Will not clobber existing file \"'sys/amiga/Install.ami'\"
  1400. else
  1401. echo shar: Extracting \"'sys/amiga/Install.ami'\" \(16547 characters\)
  1402. sed "s/^X//" >'sys/amiga/Install.ami' <<'END_OF_FILE'
  1403. X
  1404. X      Using, Compiling, and Installing Amiga NetHack 3.1
  1405. X      (or Everything You Never Wanted to Know Before NetHacking)
  1406. X
  1407. X         Last Revision: 12 January 1993 for NetHack 3.1
  1408. X
  1409. X
  1410. XI. Introduction
  1411. X
  1412. XI.A. Overview
  1413. X    Welcome to Amiga NetHack!  If this is your first visit to our fair
  1414. X    city, you are in for an amazing and dangerous journey; if you have
  1415. X    visited us before, beware! the city has changed in many strange and
  1416. X    subtle ways; it has also grown quite a bit.  This missive brings to
  1417. X    light those mundane tasks which must be dealt with before beginning
  1418. X    your journey; for those of you who are faced with the task of
  1419. X    installing the pre-fabricated version of our town, section III
  1420. X    (Installing Amiga NetHack 3.1) will guide you through the task at
  1421. X    hand.  If you are ready to visit, the local visitors guide is in
  1422. X    section II (Using Amiga NetHack 3.1); please also see the general
  1423. X    guide packaged separately (the file GuideBook).  Finally, for those
  1424. X    brave souls among you who prefer to scratch-build your own models,
  1425. X    your guidance is in section IV (Compiling Amiga NetHack 3.1).
  1426. X    
  1427. X    To all our visitors, a hearty Welcome! - and please be careful.
  1428. X
  1429. X    [Those responsible for the previous paragraphs have been sacked.  The
  1430. X    documentation has been completed at great expense in a more traditional
  1431. X    style. -- The Management]
  1432. X
  1433. XI.B. Getting Help
  1434. X    If you have questions about strategy, weapons, or monsters, the best
  1435. X    place to go for help is the Usenet newsgroup rec.games.hack.  If you
  1436. X    have problems with installation or think you have found a bug in
  1437. X    the game, please report it by electronic mail to the development
  1438. X    group at nethack-bugs@linc.cis.upenn.edu, where it will be routed
  1439. X    to the appropriate person.  Include your configuration, the version of
  1440. X    NetHack you are playing, and as much specific information as possible.
  1441. X    As NetHack runs on many different machines, be sure to mention that
  1442. X    you are playing the Amiga version.  Finally, if you are having trouble
  1443. X    compiling NetHack, you may use the same address, or, for compiler
  1444. X    specific problems, send mail to:
  1445. X        Greg Olson (golson@sundown.sun.com)  for Manx
  1446. X        Ken Lorber (keni@oasys.dt.navy.mil) for SAS/C, or
  1447. X        Richard Addison (addison@pollux.usc.edu) for either.
  1448. X    We do not currently have a contact for the DICE port.
  1449. X
  1450. XI.C. Credits
  1451. X    Olaf Seibert first ported NetHack 2.3 and 3.0 to the Amiga.  Richard
  1452. X    Addison, Jochen Erwied, Mark Gooderum, Ken Lorber, Greg Olson, Mike
  1453. X    Passaretti, and Gregg Wonderly polished and extended the 3.0 and 3.1
  1454. X    ports.
  1455. X
  1456. X
  1457. XII. Using Amiga NetHack 3.1
  1458. X
  1459. XII.A. Sources of Information
  1460. X    Where to go depends on what you want to find out.  If you want to find
  1461. X    out about distributing NetHack, read the license (in NetHack:license or
  1462. X    type ?i during the game).  For an introduction to NetHack, read the
  1463. X    GuideBook file.  Finally, for information during the game on all kinds
  1464. X    of things, type ? and select from the menu.
  1465. X
  1466. XII.B. The Amiga NetHack WorkBench Front End
  1467. X    The Amiga NetHack Front End looks more or less like a WorkBench
  1468. X    Drawer - and acts the same way.  Games start with double clicks and
  1469. X    menus provide more detailed control of games and defaults.  On-line
  1470. X    help is available - just press the help key.
  1471. X
  1472. X    Just as with WorkBench itself, options for games are set using the Info
  1473. X    menu item to modify Tooltypes.  Most common options can be set more 
  1474. X    easily using buttons available via Info also.
  1475. X
  1476. X    You can adjust the following using the ToolTypes from the Info command:
  1477. X
  1478. X    * OPTIONS=<options> - Options as available in the NetHack.cnf file.
  1479. X
  1480. X    * HACKDIR=<directory> - Set NetHack working directory to be this
  1481. X      directory.
  1482. X
  1483. X    * LEVELS=<levels> - Intermediate level saving device/directory.
  1484. X
  1485. X    * PATH=<path> - To search for files such as rumors, help, etc.
  1486. X
  1487. X    * CMDLINE=<args> - Arguments as passed on the CLI command line.
  1488. X      Note:  only the following flags are valid: n, X, D, and r.
  1489. X
  1490. X    * SCORE <options> - Display the record of scores.  Options as
  1491. X      available on the CLI command line after a -s flag.
  1492. X
  1493. X    Note that the NetHack.cnf file is read first, then the ToolTypes.  This
  1494. X    means that the options specified in the NetHack.cnf act as defaults
  1495. X    which can be overridden by an individual's personal icon's ToolTypes.
  1496. X    Thus the system oriented entries (HACKDIR, LEVELS, and PATH) should
  1497. X    generally be set only in NetHack.cnf.  NetHack.cnf should have default
  1498. X    values for OPTIONS, which will generally be overridden by ToolTypes
  1499. X    entries.
  1500. X
  1501. X    Also, there is one additional option that may be specified in the
  1502. X    NetHack.cnf file or on an OPTIONS line: flush.  When enabled, flush
  1503. X    discards all characters in the queue except the first, which limits
  1504. X    typeahead accidents.  The default setting is noflush.
  1505. X
  1506. X    Usually, most of the confusing options will be set in the NetHack.cnf
  1507. X    file once when the game is installed and can be ignored after that.
  1508. X
  1509. XII.C. The Amiga NetHack CLI Front End
  1510. X    The CLI Front End provides the standard Unix-like command line interface
  1511. X    to NetHack.  Unlike the Unix front end however, the CLI front end will
  1512. X    ask if you want to play again before exiting.  See the ManPage file for
  1513. X    the standard Unix flags for NetHack.  In addition to those flags, Amiga
  1514. X    NetHack accepts flags -l to force non-interlaced mode and -L to force
  1515. X    interlaced mode.
  1516. X
  1517. X
  1518. XIII. Installing Amiga NetHack 3.1
  1519. X
  1520. XIII.A. General Installation
  1521. X    Installation should be easy - basically it consists of putting files
  1522. X    where they belong and adding assigns to your startup.  If you are
  1523. X    installing from the official binary distribution, simply unpacking
  1524. X    each archive in the appropriate directory will put the files in the
  1525. X    places they belong (note that the archives may have been split
  1526. X    for distribution).  If you are installing from source, most of this
  1527. X    work will be done by the time the build is finished.
  1528. X
  1529. X    IF YOU ALREADY HAVE A PREVIOUS VERSION INSTALLED YOU MUST DELETE THE
  1530. X    OLD SAVE AND BONES FILES - THEY WILL NOT WORK!
  1531. X
  1532. XWill NetHack fit on your machine?
  1533. X    NetHack 3.1 is large.  NetHack 3.1 is very large.  You will need:
  1534. X    > Amiga 500, 1000, 2000, 2500, or 3000.  The A600, A1200, and A4000
  1535. X      should work, but have not been tested.
  1536. X    > WorkBench 1.3 or 2.04.  WorkBench 1.2 will NOT work; we will NOT
  1537. X      be fixing that.  WorkBench 2.1 and 3.0 should work but have not been
  1538. X      tested.
  1539. X    > At least 2 meg of RAM.  NetHack will NOT run in 1 meg.
  1540. X    > Mass storage: NetHack will run on one floppy - but it won't be nice.
  1541. X      Two floppies are almost enough.  A hard drive with over 3 meg of
  1542. X      free space is recommended.
  1543. X
  1544. XFind space for the files
  1545. X    Floppy installation:
  1546. X    Format four disks named:
  1547. X        NetHack
  1548. X        HackExe
  1549. X        NHsave
  1550. X        NHlevels
  1551. X    Hard Disk installation:
  1552. X        cd to wherever you want to install NetHack
  1553. X    makedir NetHack
  1554. X    makedir NetHack/save
  1555. X    makedir NetHack/levels
  1556. X    In s:User-Sequence (under 2.0 or later) or s:Startup (under 1.3),
  1557. X    assign NetHack: to the NetHack directory you created above.
  1558. X    assign HackExe: to the same directory.
  1559. XInstall the files
  1560. X    Unpack the archives in the directories or onto the disks (you can
  1561. X    tell what to unpack where by the file names).  Use the table in the
  1562. X    next section to see where things should end up.  Be sure that the
  1563. X    file 8 ends up in NetHack:hack/8.
  1564. X
  1565. XConfiguration
  1566. X    Using your favorite text editor, edit NetHack:NetHack.cnf to match
  1567. X    your system.  Check HackExe:NetHack.dir and be sure that the paths
  1568. X    are correct.  The HackWB program uses several standard Amiga programs
  1569. X    that must be installed in their standard places: c:copy, c:rename.
  1570. X
  1571. XIII.B. File Location Table
  1572. X    NetHack:
  1573. X    A-filla.lev    A-fillb.lev    A-goal.lev    A-locate.lev
  1574. X    A-start.lev    air.lev        asmodeus.lev    astral.lev
  1575. X    B-filla.lev    B-fillb.lev    B-goal.lev    B-locate.lev
  1576. X    B-start.lev    baalz.lev    bigroom.lev    C-filla.lev
  1577. X    C-fillb.lev    C-goal.lev    C-locate.lev    C-start.lev
  1578. X    castle.lev    cmdhelp        data        default.icon
  1579. X    dungeon        E-filla.lev    E-fillb.lev    E-goal.lev
  1580. X    E-locate.lev    E-start.lev    earth.lev    fakewiz1.lev
  1581. X    fakewiz2.lev    fire.lev    Guidebook    Guidebook.info
  1582. X    H-filla.lev    H-fillb.lev    H-goal.lev    H-locate.lev
  1583. X    H-start.lev    hack/8        hack.font    HackWB
  1584. X    HackWB.info    HackCli        help        hh
  1585. X    history        juiblex.lev    K-filla.lev    K-fillb.lev
  1586. X    K-goal.lev    K-locate.lev    K-start.lev    knox.lev
  1587. X    license        logfile        ManPage        ManPage.info
  1588. X    medusa-1.lev    medusa-2.lev    minefill.lev    minetown.lev
  1589. X    mine_end.lev    NetHack.cnf    NetHack.c01    NetHack.d00
  1590. X    news        NewGame.info    opthelp        options
  1591. X    oracle.lev    oracles        orcus.lev    P-filla.lev
  1592. X    P-fillb.lev    P-goal.lev    P-locate.lev    P-start.lev
  1593. X    perm        quest.dat    R-filla.lev    R-fillb.lev
  1594. X    R-goal.lev    R-locate.lev    R-start.lev    ReadMe
  1595. X    ReadMe.info    record        recover        rumors
  1596. X    S-filla.lev    S-fillb.lev    S-goal.lev    S-locate.lev
  1597. X    S-start.lev    sanctum.lev    T-filla.lev    T-fillb.lev
  1598. X    T-goal.lev    T-locate.lev    T-start.lev    tower1.lev
  1599. X    tower2.lev    tower3.lev    V-filla.lev    V-fillb.lev
  1600. X    V-goal.lev    V-locate.lev    V-start.lev    valley.lev
  1601. X    W-filla.lev    W-fillb.lev    W-goal.lev    W-locate.lev
  1602. X    W-start.lev    water.lev    wizard1.lev    wizard2.lev
  1603. X    wizard3.lev    wizhelp
  1604. X
  1605. X    HackExe:
  1606. X    NetHack.dir
  1607. X    NetHack.c00
  1608. X
  1609. X
  1610. XIV. Compiling Amiga NetHack 3.1
  1611. X
  1612. XIV.A. Compilation Overview
  1613. X    Compiling NetHack is not very hard - basically you do a little
  1614. X    configuration and start make.  It does, however, require a good amount
  1615. X    of disk space - almost 7 meg (and subject to change; more if you are
  1616. X    not doing the simple compile - more on that later).  It also needs a
  1617. X    good bit of memory.
  1618. X
  1619. XIV.B. Basic Compilation
  1620. X    NetHack can be built with SAS/C version 5.10b, Manx/Aztec version 5,
  1621. X    or the registered version of DICE.  The "official" compiler for NetHack 3.1
  1622. X    patchlevel 0 is SAS/C 5.10b - we expect to be moving to SAS/C version 6.2
  1623. X    after it is released (6.0 was not available soon enough to gain our
  1624. X    confidence for releasing binaries based on it).  The game will compile
  1625. X    under SAS/C 6.x with small changes.
  1626. X
  1627. XIV.B.1. Introduction to Compiling NetHack
  1628. X    Before doing any compilation, read the README files distributed
  1629. X    with the source.  These should familiarize you with the source tree
  1630. X    layout, and what files are shared with what computers.  Generally,
  1631. X    everything in the sys/amiga directory is used exclusively by the Amiga.
  1632. X
  1633. X    The makefile (Makefile.ami) is set up to depend upon certain assignments,
  1634. X    providing the developer with a fairly flexible environment.  See
  1635. X    makefile.ami for assignment assumptions.
  1636. X
  1637. X    Edit config.h to your liking and system configuration.  The following
  1638. X    need to be checked:
  1639. X
  1640. X    UNIX - undef
  1641. X    MACROCPATH - undef
  1642. X    HACKDIR - define as "NetHack:"
  1643. X
  1644. X    For SAS/C 6.x, in config.h, make sure that '#define NEARDATA' is used
  1645. X    and not '#define NEARDATA __near'.  The v5 compiler recognizes a
  1646. X    different syntax than the v6 compiler for this construct. You will
  1647. X    need to build without __near for now to get around this problem.
  1648. X
  1649. X    At this point, you're almost ready to begin a compile.  Read VERY
  1650. X    CAREFULLY through the Makefile to familiarize yourself with which
  1651. X    assignments are assumed.  Otherwise, you're going to get something
  1652. X    like "Insert NHS: in any drive." requestors.  You will need the
  1653. X    programs uudecode, flex, and bison.  Be sure the p bit is set in
  1654. X    the permissions for ifchange.  The first thing Makefile.ami does
  1655. X    is build a program called 'makedefs', which handles a variety of
  1656. X    data file generation, and a pair of programs called 'lev_comp' and
  1657. X    'dgn_comp' which compile the special levels.  Makedefs will then be
  1658. X    run to create a few files, followed by an alphabetically sorted
  1659. X    compilation of the entire source tree.  This compilation process
  1660. X    will compile selected files from the Amiga:, Share:, and NHS:
  1661. X    directories.  If all goes well, all of the  objects will be linked
  1662. X    together to form a binary.  After building the main binary, a make
  1663. X    install will build the auxiliary files including help files, special
  1664. X    levels, icons, and the font files and will put these files into their
  1665. X    final positions.  The first make run should be done in OBJ: and the
  1666. X    make install should be done in NetHack:; for both runs, the makefile
  1667. X    is Amiga:Makefile.ami.
  1668. X
  1669. X    For SAS/C 6.x: in Makefile.ami, comment out the SAS5 macros and
  1670. X    uncomment the SAS6 macros.
  1671. X
  1672. X    Note that not all the source is simple C code.  If you are modifying
  1673. X    lev_comp or dgn_comp you may need bison and/or flex (depending on what
  1674. X    modifications you are making).  If you wish to modify the Intuition
  1675. X    windows in HackWB, the (uuencoded) PowerWindows files are provided.  You
  1676. X    do not need any of these tools to simply build NetHack - all the C output
  1677. X    files are provided in the source distribution.  Also, the ifchange
  1678. X    script requires a version of diff that produces standard Unix format
  1679. X    context diffs for proper operation - the version shipped with SASC
  1680. X    is not sufficient.
  1681. X
  1682. X    If you do not have bison and flex, copy the files from Share:.  The
  1683. X    include files go in incl: and the C files go in util:.  If the compile
  1684. X    fails due to prototype errors for malloc and realloc, try deleting
  1685. X    the first line of lev_comp.c and dgn_comp.c.
  1686. X
  1687. XIV.B.2. Compiling NetHack with SAS/C version 5
  1688. X
  1689. X    NOTE WELL - Amiga NetHack will be dropping support for SAS/C version 5
  1690. X    and moving to SAS/C version 6 almost immediately.  Upgrade now!  You
  1691. X    have been warned.
  1692. X
  1693. X    This version of NetHack was developed with SAS/C 5.10b and SAS/C 6.1.
  1694. X    Earlier versions of the compiler are known to cause problems - don't
  1695. X    use them.
  1696. X
  1697. X    A couple of notes and warnings from the SAS/C users on the team:
  1698. X
  1699. X    * Included in the SAS/C port is code for generating a SnapShot.tb
  1700. X      file upon catching various internal disasters.  That is why the
  1701. X      -d1 flag is in the makefile.  This adds about 270K to the disk
  1702. X      image, but it does not increase the run time memory requirements.
  1703. X          (But note that this is not useful for split binaries - see below.)
  1704. X
  1705. X    * The 5.10b optimizer does not produce correct code for NetHack.
  1706. X
  1707. X    * There are a large number of warnings under SAS/C, which are
  1708. X      harmless.
  1709. X
  1710. X    * Some versions of flex produce #line statements with the file name
  1711. X      in quotes: version 5.10b doesn't like this.  For some reason lc tries
  1712. X      to access this file, which results in a bogus requestor for "Util:
  1713. X      (yes, there is one quote mark in front of Util:) - select cancel
  1714. X      and ignore the problem or add -L to the FLEX definition in
  1715. X      Makefile.ami.  SAS says that this will be fixed in 6.0.
  1716. X
  1717. XIV.B.3. Compiling NetHack with SAS/C version 6
  1718. X    Very simliar to compiling under version 5 except all the command lines
  1719. X    are different - see the Makefile.  Also, see the note above about
  1720. X    NEARDATA.
  1721. X
  1722. XIV.B.4. Compiling NetHack with Manx/Aztec version 5
  1723. X    The Manx port has not been tested recently and is probably broken.  We
  1724. X    expect to have it back in shape soon but we welcome context diffs.  As
  1725. X    of the last check, NetHack required version 5.0B of the compiler.  
  1726. X
  1727. XIV.B.5    Compiling NetHack with the registered version of DICE
  1728. X    The DICE port was complete at one point but has not been tested in
  1729. X    several months - it probably will not work as is.  We welcome context
  1730. X    diffs (or volunteers) to fix it.
  1731. X
  1732. XIV.C. Advanced Compilation
  1733. X    As mentioned above, NetHack is very large.  There are several
  1734. X    techniques under development by the Amiga NetHack Team for dealing
  1735. X    with the situation.  As they are completed, they will be documented
  1736. X    here.  Before attempting any of them, you MUST do a "normal" build
  1737. X    as documented above; the techniques described below require the
  1738. X    auxiliary files from a normal build to form a complete NetHack
  1739. X    installation.
  1740. X
  1741. XIV.C.1 Splitter
  1742. X    Splitter addresses two problems with NetHack: first, the long startup
  1743. X    time of the game, and second, the size of the binary (which will not fit
  1744. X    on a single disk).  See the file split/split.doc for information on
  1745. X    splitter.  The normal install target in Makefile.ami will build the
  1746. X    split version of NetHack as part of the normal install process; the
  1747. X    front ends will run from either the normal version (HackExe:NetHack) or,
  1748. X    preferably, from the split version (NetHack.c#?  NetHack.d#?) - the
  1749. X    decision is based on the presence (or absence) of HackExe:NetHack.dir.
  1750. X    Note that the contents of NetHack.dir after a build will generally not
  1751. X    be the correct contents for a floppy based system.
  1752. X   
  1753. END_OF_FILE
  1754. if test 16547 -ne `wc -c <'sys/amiga/Install.ami'`; then
  1755.     echo shar: \"'sys/amiga/Install.ami'\" unpacked with wrong size!
  1756. fi
  1757. # end of 'sys/amiga/Install.ami'
  1758. fi
  1759. echo shar: End of archive 45 \(of 108\).
  1760. cp /dev/null ark45isdone
  1761. MISSING=""
  1762. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
  1763. 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
  1764. 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
  1765. 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
  1766. 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
  1767. 101 102 103 104 105 106 107 108 ; do
  1768.     if test ! -f ark${I}isdone ; then
  1769.     MISSING="${MISSING} ${I}"
  1770.     fi
  1771. done
  1772. if test "${MISSING}" = "" ; then
  1773.     echo You have unpacked all 108 archives.
  1774.     echo "Now execute 'rebuild.sh'"
  1775.     rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
  1776. else
  1777.     echo You still need to unpack the following archives:
  1778.     echo "        " ${MISSING}
  1779. fi
  1780. ##  End of shell archive.
  1781. exit 0
  1782.