home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume7 / nethack3 / part29 < prev    next >
Internet Message Format  |  1989-07-31  |  56KB

  1. Path: uunet!zephyr.ens.tek.com!tektronix!tekgen!tekred!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v07i084:  NetHack3 -  display oriented dungeons & dragons (Ver. 3.0), Part29/38
  5. Message-ID: <4341@tekred.CNA.TEK.COM>
  6. Date: 24 Jul 89 19:06:58 GMT
  7. Sender: nobody@tekred.CNA.TEK.COM
  8. Lines: 2060
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
  12. Posting-number: Volume 7, Issue 84
  13. Archive-name: NetHack3/Part29
  14.  
  15.  
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 29 (of 38)."
  24. # Contents:  amiga/Makefile.ami src/dog.c src/mkroom.c src/mthrowu.c
  25. #   src/spell.c
  26. # Wrapped by billr@saab on Sun Jul 23 21:33:12 1989
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'amiga/Makefile.ami' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'amiga/Makefile.ami'\"
  30. else
  31. echo shar: Extracting \"'amiga/Makefile.ami'\" \(10847 characters\)
  32. sed "s/^X//" >'amiga/Makefile.ami' <<'END_OF_FILE'
  33. X#    Hack Makefile.
  34. X#    SCCS Id: @(#)Makefile.ami       3.0     89/04/23
  35. X
  36. X# This makefile is specifically for the Amiga.
  37. X
  38. XCFLAGS      = +cd -e200
  39. XCPPFLAGS  = -I -Iamiga: -Iinclude:
  40. XCC      = cc
  41. X
  42. X#   Use my special modified Cpp (-w flag writes all #defines)
  43. X#   since the one built in Manx CC is too stupid for now.
  44. X
  45. X.c.o:
  46. X    Cpp $(CPPFLAGS) $< ram:_$*.c
  47. X    cc  $(CFLAGS) -o $*.o ram:_$*.c
  48. X    delete ram:_$*.c
  49. X
  50. X#   Search path for default rules: (for my special modified Make)
  51. X
  52. X.PATH:    src1: src2:
  53. X
  54. X.PRECIOUS:  include:config.h include:decl.h include:_hack.h \
  55. X        include:permonst.h include:you.h
  56. X
  57. X
  58. X# object files for makedefs
  59. XMAKEOBJS = makedefs.o monst.o objects.o
  60. X
  61. X# object files for level compiler
  62. XSPLEVOBJS = lev_comp.o lev_lex.o lev_main.o monst.o objects.o
  63. X
  64. X# make NetHack
  65. XGAME     = nethack
  66. X
  67. X# if you defined RANDOM in unixconf.h/pcconf.h since your system did not come
  68. X# with a reasonable random number generator
  69. XRANDOBJ = random.o
  70. X
  71. X# nothing below this line should have to be changed
  72. X#
  73. X# other things that have to be reconfigured are in config.h,
  74. X# {unixconf.h, pcconf.h, amiconf.h}, and possibly system.h
  75. X
  76. X# HACKCSRC = alloc.c apply.c artifact.c attrib.c bones.c cmd.c dbridge.c \
  77. X#        decl.c demon.c do.c do_name.c do_wear.c dog.c dogmove.c dokick.c \
  78. X#        dothrow.c eat.c end.c engrave.c exper.c extralev.c fountain.c \
  79. X#        getline.c hack.c invent.c lock.c mail.c makemon.c mcastu.c mhitm.c \
  80. X#        mhitu.c mklev.c mkmaze.c mkobj.c mkroom.c mon.c mondata.c \
  81. X#        monmove.c monst.c mthrowu.c music.c o_init.c objects.c objnam.c \
  82. X#        options.c pager.c pickup.c polyself.c potion.c pray.c pri.c \
  83. X#        priest.c prisym.c read.c restore.c rip.c rnd.c rumors.c save.c \
  84. X#        search.c shk.c shknam.c sit.c sounds.c sp_lev.c spell.c steal.c \
  85. X#        termcap.c timeout.c topl.c topten.c track.c trap.c u_init.c \
  86. X#        uhitm.c vault.c version.c weapon.c were.c wield.c wizard.c worm.c \
  87. X#        worn.c write.c zap.c
  88. X
  89. X# all .c files but msdos.c, tos.c, *main.c, *tty.c, *unix.c, (system specific)
  90. X# and makedefs.c, lev_comp.c, panic.c (not part of any nethack)
  91. X
  92. X# CSOURCES = $(HACKCSRC) pcmain.c makedefs.c panic.c
  93. X
  94. X# HACKINCL = artifact.h attrib.h config.h coord.h decl.h edog.h epri.h eshk.h \
  95. X#        extern.h flag.h func_tab.h global.h gold.h hack.h lev.h mfndpos.h \
  96. X#        mkroom.h monattk.h mondata.h monflag.h monst.h monsym.h msdos.h \
  97. X#        obj.h objclass.h permonst.h prop.h rm.h sp_lev.h spell.h \
  98. X#        tradstdc.h trapname.h vault.h wseg.h you.h youprop.h
  99. X
  100. X# all .h files except date.h, onames.h, pm.h & trap.h which would cause
  101. X# dependency loops if run through "make depend".
  102. X
  103. X# HSOURCES = $(HACKINCL) date.h onames.h pm.h trap.h
  104. X
  105. X# SOURCES = $(CSOURCES) $(HSOURCES)
  106. X
  107. XAOBJ  = amidos.o amitcap.o amitty.o amiunix.o amiwind.o
  108. XHOBJ1 = alloc.o apply.o artifact.o attrib.o bones.o cmd.o dbridge.o decl.o \
  109. X    demon.o do.o do_name.o do_wear.o dog.o dogmove.o dokick.o dothrow.o \
  110. X    eat.o end.o engrave.o exper.o extralev.o fountain.o getline.o hack.o \
  111. X    invent.o lock.o
  112. XHOBJ2 = mail.o main.o makemon.o mcastu.o mhitm.o mhitu.o mklev.o mkmaze.o \
  113. X    mkobj.o mkroom.o mon.o mondata.o monmove.o monst.o mthrowu.o music.o \
  114. X    o_init.o objects.o objnam.o options.o pager.o pickup.o polyself.o \
  115. X    potion.o pray.o pri.o priest.o prisym.o read.o restore.o rip.o rnd.o \
  116. X    rumors.o save.o
  117. XHOBJ3 = search.o shk.o shknam.o sit.o sounds.o sp_lev.o spell.o steal.o \
  118. X    timeout.o topl.o topten.o track.o trap.o u_init.o \
  119. X    uhitm.o vault.o version.o weapon.o were.o wield.o wizard.o \
  120. X    worm.o worn.o write.o zap.o $(RANDOBJ)
  121. X
  122. XHOBJ =    $(AOBJ) $(HOBJ1) $(HOBJ2) $(HOBJ3)
  123. X
  124. X# the .o files from the HACKCSRC list, plus main.o tty.o unix.o
  125. X
  126. X$(GAME): $(HOBJ)
  127. X    ln -f ami.lnk
  128. X
  129. Xlink:
  130. X    ln -f ami.lnk
  131. X
  132. Xobj1:    $(HOBJ1)
  133. Xobj2:    $(HOBJ2)
  134. Xobj3:    $(HOBJ3)
  135. X
  136. X#
  137. X#    Please note:    The dependency lines for the modules here are
  138. X#            deliberately incorrect.  Including "hack.h" in
  139. X#            the dependency list would cause a dependency
  140. X#            loop.
  141. X#
  142. Xmakedefs:    $(MAKEOBJS)
  143. X    ln -o makedefs $(MAKEOBJS) -lcl
  144. X
  145. Xmakedefs.o:  include:config.h include:permonst.h include:objclass.h
  146. X
  147. Xlev_comp:  $(SPLEVOBJS)
  148. X    ln -o lev_comp $(SPLEVOBJS) -lcl
  149. X
  150. Xlev_comp.o:  include:hack.h include:sp_lev.h
  151. X    Cpp $(CPPFLAGS) src1:lev_comp.c ram:_lev_comp.c
  152. X    cc  +cd -e300 -o lev_comp.o ram:_lev_comp.c
  153. X    delete ram:_lev_comp.c
  154. Xlev_lex.o:  include:lev_comp.h include:hack.h include:sp_lev.h
  155. X    Cpp $(CPPFLAGS) src1:lev_lex.c ram:_lev_lex.c
  156. X    cc  +cd -e300 -o lev_lex.o ram:_lev_lex.c
  157. X    delete ram:_lev_lex.c
  158. Xlev_main.o:  include:hack.h include:sp_lev.h
  159. X    Cpp $(CPPFLAGS) src1:lev_main.c ram:_lev_main.c
  160. X    cc  +cd -e300 -o lev_main.o ram:_lev_main.c
  161. X    delete ram:_lev_main.c
  162. X
  163. X#
  164. X#    The following include files depend on makedefs to be created.
  165. X#    As a result, they are not defined in HACKINCL, instead, their
  166. X#    dependencies are explicitly outlined here.
  167. X#
  168. X
  169. X#
  170. X#    date.h should be remade any time any of the source or include code
  171. X#    is modified.  Unfortunately, this would make the contents of this
  172. X#    file far more complex.    Since "hack.h" depends on most of the include
  173. X#    files, we kludge around this by making date.h dependent on hack.h,
  174. X#    even though it doesn't include this file.
  175. X#
  176. Xinclude:date.h:      include:hack.h makedefs $(AOBJ)
  177. X    -makedefs -v
  178. X
  179. Xinclude:trap.h:      include:config.h makedefs
  180. X    -makedefs -t
  181. X    copy makedefs.1 include:trap.h
  182. X
  183. Xinclude:onames.h:    makedefs
  184. X    -makedefs -o
  185. X
  186. Xinclude:pm.h:         makedefs
  187. X    -makedefs -p
  188. X
  189. X#
  190. X#    The following programs vary depending on what OS you are using.
  191. X#    As a result, they are not defined in HACKSRC, and their dependancies
  192. X#    are explicitly outlined here.
  193. X#
  194. X
  195. Xamidos.o: include:hack.h amiga:amidos.c
  196. X    $(CC) $(CFLAGS) amiga:amidos.c -o amidos.o
  197. X
  198. Xamitcap.o: include:hack.h amiga:amitcap.c
  199. X    $(CC) $(CFLAGS) amiga:amitcap.c -o amitcap.o
  200. X
  201. Xamitty.o: include:hack.h amiga:amitty.c
  202. X    $(CC) $(CFLAGS) amiga:amitty.c -o amitty.o
  203. X
  204. Xamiunix.o: include:hack.h amiga:amiunix.c
  205. X    $(CC) $(CFLAGS) amiga:amiunix.c -o amiunix.o
  206. X
  207. Xamiwind.o: include:hack.h amiga:amiwind.c amiga:amimenu.c
  208. X    $(CC) $(CFLAGS) +IData:syms/amiga.syms amiga:amiwind.c -o amiwind.o
  209. X
  210. Xmain.o: include:hack.h src2:pcmain.c
  211. X    Cpp $(CPPFLAGS) src2:pcmain.c ram:_main.c
  212. X    cc  $(CFLAGS) -o main.o ram:_main.c
  213. X    delete ram:_main.c
  214. X
  215. X# Pre-include hack.h to save disk I/O. Rename the original hack.h
  216. X# to _hack.h though. The -w option makes Cpp write out all
  217. X# necessary #defines at the end of the output.
  218. X
  219. Xinclude:hack.h: include:_hack.h makedefs
  220. X    -Cpp -Iinclude: -Iamiga: -w include:_hack.h hack.h
  221. X    -copy hack.h include:hack.h
  222. X
  223. Xclean:
  224. X    delete *.o ram:_*.c ram:ctmp*
  225. X
  226. Xspotless: clean
  227. X    delete $(GAME) lev_comp makedefs
  228. X    delete include:onames.h include:pm.h
  229. X    setdate include:onames.h include:pm.h
  230. X    setdate makedefs.c
  231. X#(make sure files exist and have timestamps in the right order for next compile)
  232. X
  233. X
  234. X# DO NOT DELETE THIS LINE
  235. X
  236. Xalloc.o:  include:config.h
  237. Xapply.o:  include:hack.h include:edog.h
  238. Xartifact.o:  include:hack.h include:artifact.h
  239. Xattrib.o:  include:hack.h
  240. Xbones.o:  include:hack.h
  241. Xcmd.o:    include:hack.h include:func_tab.h
  242. Xdbridge.o:  include:hack.h
  243. Xdecl.o:  include:hack.h
  244. Xdemon.o:  include:hack.h
  245. Xdo.o:  include:hack.h
  246. Xdo_name.o:  include:hack.h
  247. Xdo_wear.o:  include:hack.h
  248. Xdog.o:    include:hack.h include:edog.h
  249. Xdogmove.o:  include:hack.h include:mfndpos.h include:edog.h
  250. Xdokick.o:  include:hack.h
  251. Xdothrow.o:  include:hack.h
  252. Xeat.o:    include:hack.h
  253. Xend.o:    include:hack.h include:eshk.h
  254. Xengrave.o:  include:hack.h
  255. Xexper.o:  include:hack.h
  256. Xextralev.o:  include:hack.h
  257. Xfountain.o:  include:hack.h
  258. Xgetline.o: include:hack.h include:func_tab.h
  259. Xhack.o:  include:hack.h
  260. Xinvent.o:  include:hack.h include:lev.h include:wseg.h
  261. Xlock.o:  include:hack.h
  262. Xmail.o:  include:hack.h
  263. Xmakemon.o:  include:hack.h
  264. Xmcastu.o:  include:hack.h
  265. Xmhitm.o:  include:hack.h include:artifact.h
  266. Xmhitu.o:  include:hack.h include:artifact.h include:edog.h
  267. Xmklev.o:  include:hack.h
  268. Xmkmaze.o:  include:hack.h
  269. Xmkobj.o:  include:hack.h
  270. Xmkroom.o:  include:hack.h
  271. Xmon.o:    include:hack.h include:mfndpos.h include:artifact.h
  272. Xmondata.o:  include:hack.h include:eshk.h include:epri.h
  273. Xmonmove.o:  include:hack.h include:mfndpos.h include:artifact.h
  274. Xmonst.o:  include:config.h include:permonst.h include:monsym.h include:eshk.h include:vault.h include:epri.h
  275. X    Cpp $(CPPFLAGS) src2:monst.c ram:_monst.c
  276. X    cc  $(CFLAGS) -z4000 -o monst.o ram:_monst.c
  277. X    delete ram:_monst.c
  278. Xmthrowu.o:  include:hack.h
  279. Xmusic.o:  include:hack.h
  280. Xo_init.o:  include:hack.h
  281. Xobjects.o:  include:config.h include:obj.h include:objclass.h include:prop.h
  282. X    Cpp $(CPPFLAGS) src2:objects.c ram:_objects.c
  283. X    cc  $(CFLAGS) -z8000 +q -o objects.o ram:_objects.c
  284. X    delete ram:_objects.c
  285. Xobjnam.o:  include:hack.h
  286. Xoptions.o:  include:hack.h
  287. Xpager.o:  include:hack.h
  288. Xpickup.o:  include:hack.h
  289. Xpolyself.o:  include:hack.h
  290. Xpotion.o:  include:hack.h
  291. Xpray.o:  include:hack.h
  292. Xpri.o:    include:hack.h
  293. Xpriest.o:  include:hack.h include:mfndpos.h include:eshk.h include:epri.h
  294. Xprisym.o:  include:hack.h include:wseg.h include:lev.h
  295. Xread.o:  include:hack.h
  296. Xrestore.o:  include:hack.h include:lev.h include:wseg.h
  297. Xrip.o:    include:hack.h
  298. X    Cpp $(CPPFLAGS) src2:rip.c ram:_rip.c
  299. X    cc  $(CFLAGS) +q -o rip.o ram:_rip.c
  300. X    delete ram:_rip.c
  301. Xrnd.o:    include:hack.h
  302. Xrumors.o:  include:hack.h
  303. Xsave.o:  include:hack.h include:lev.h include:wseg.h
  304. Xsearch.o:  include:hack.h include:artifact.h
  305. Xshk.o:    include:hack.h include:eshk.h
  306. Xshknam.o:  include:hack.h include:eshk.h
  307. Xsit.o:    include:hack.h
  308. Xsounds.o:  include:hack.h include:edog.h include:eshk.h
  309. Xsp_lev.o:  include:hack.h include:sp_lev.h
  310. Xspell.o:  include:hack.h
  311. Xsteal.o:  include:hack.h
  312. Xtimeout.o:  include:hack.h
  313. Xtopl.o:  include:hack.h
  314. Xtopten.o:  include:hack.h
  315. Xtrack.o:  include:hack.h
  316. Xtrap.o:  include:hack.h include:edog.h include:trapname.h
  317. Xu_init.o:  include:hack.h
  318. Xuhitm.o:  include:hack.h include:artifact.h
  319. Xvault.o:  include:hack.h include:vault.h
  320. Xversion.o:  include:hack.h include:date.h
  321. Xweapon.o:  include:hack.h
  322. Xwere.o:  include:hack.h
  323. Xwield.o:  include:hack.h
  324. Xwizard.o:  include:hack.h
  325. Xworm.o:  include:hack.h include:wseg.h
  326. Xworn.o:  include:hack.h
  327. Xwrite.o:  include:hack.h
  328. Xzap.o:    include:hack.h
  329. Xinclude:config.h:  include:tradstdc.h include:global.h
  330. X    -setdate include:config.h
  331. Xinclude:decl.h:  include:spell.h include:obj.h include:you.h include:onames.h include:pm.h
  332. X    -setdate include:decl.h
  333. Xinclude:global.h:  include:coord.h include:unixconf.h include:pcconf.h include:tosconf.h include:amiconf.h
  334. X    -setdate include:global.h
  335. Xinclude:_hack.h:  include:config.h include:decl.h include:monsym.h include:mkroom.h include:objclass.h include:gold.h include:trap.h include:flag.h include:rm.h
  336. X    -setdate include:_hack.h
  337. Xinclude:permonst.h:  include:monattk.h include:monflag.h
  338. X    -setdate include:permonst.h
  339. Xinclude:you.h:    include:attrib.h include:monst.h include:youprop.h
  340. X    -setdate include:you.h
  341. Xinclude:youprop.h:  include:prop.h include:permonst.h include:mondata.h include:pm.h
  342. X    -setdate include:youprop.h
  343. X# DEPENDENCIES MUST END AT END OF FILE
  344. X# IF YOU PUT STUFF HERE IT WILL GO AWAY
  345. X# see make depend above
  346. END_OF_FILE
  347. if test 10847 -ne `wc -c <'amiga/Makefile.ami'`; then
  348.     echo shar: \"'amiga/Makefile.ami'\" unpacked with wrong size!
  349. fi
  350. # end of 'amiga/Makefile.ami'
  351. fi
  352. if test -f 'src/dog.c' -a "${1}" != "-c" ; then 
  353.   echo shar: Will not clobber existing file \"'src/dog.c'\"
  354. else
  355. echo shar: Extracting \"'src/dog.c'\" \(7862 characters\)
  356. sed "s/^X//" >'src/dog.c' <<'END_OF_FILE'
  357. X/*    SCCS Id: @(#)dog.c    3.0    89/06/12
  358. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  359. X/* NetHack may be freely redistributed.  See license for details. */
  360. X
  361. X#include "hack.h"
  362. X#include "edog.h"
  363. X
  364. Xchar dogname[63] = DUMMY;
  365. Xchar catname[63] = DUMMY;
  366. X
  367. X#define domestic(mtmp)    (mtmp->data->msound == MS_BARK || mtmp->data->msound == MS_MEW)
  368. X
  369. Xvoid
  370. Xinitedog(mtmp)
  371. Xregister struct monst *mtmp;
  372. X{
  373. X    mtmp->mtame = domestic(mtmp) ? 10 : 5;
  374. X    mtmp->mpeaceful = 1;
  375. X    mtmp->mleashed = 0;
  376. X    mtmp->meating = 0;
  377. X    EDOG(mtmp)->droptime = 0;
  378. X    EDOG(mtmp)->dropdist = 10000;
  379. X    EDOG(mtmp)->apport = 10;
  380. X    EDOG(mtmp)->whistletime = 0;
  381. X    EDOG(mtmp)->hungrytime = 1000 + moves;
  382. X}
  383. X
  384. Xvoid
  385. Xmake_familiar(otmp)
  386. Xregister struct obj *otmp;
  387. X{
  388. X    register struct monst *mtmp;
  389. X    register struct permonst *pm;
  390. X
  391. Xtop:
  392. X    if (otmp) pm = &mons[otmp->corpsenm]; /* Figurine; otherwise spell */
  393. X    else if (rn2(3)) {
  394. X        if (!(pm = rndmonst())) {
  395. X        pline("There seems to be nothing available for a familiar.");
  396. X        return;
  397. X        }
  398. X    }
  399. X    else if ((pl_character[0]=='W' || rn2(2)) && pl_character[0]!='C')
  400. X        pm = &mons[PM_KITTEN];
  401. X    else pm = &mons[PM_LITTLE_DOG];
  402. X
  403. X    pm->pxlth += sizeof(struct edog);
  404. X    mtmp = makemon(pm, u.ux, u.uy);
  405. X    pm->pxlth -= sizeof(struct edog);
  406. X    if (!mtmp) { /* monster was genocided */
  407. X        if (otmp)
  408. X        pline("The figurine writhes and then shatters into pieces!");
  409. X        else goto top;
  410. X        /* rndmonst() returns something not genocided always, so this
  411. X         * means it was a cat or dog; loop back to try again until
  412. X         * either rndmonst() is called, or if only one of cat/dog
  413. X         * was genocided, they get the other.
  414. X         */
  415. X        return;
  416. X    }
  417. X    initedog(mtmp);
  418. X    if (otmp && otmp->cursed) { /* cursed figurine */
  419. X        You("get a bad feeling about this.");
  420. X        mtmp->mtame = mtmp->mpeaceful = 0;
  421. X    }
  422. X}
  423. X
  424. Xstruct monst *
  425. Xmakedog() {
  426. X    register struct monst *mtmp;
  427. X    register char *petname;
  428. X
  429. X    if (pl_character[0]=='C' || (pl_character[0] != 'W' && rn2(2))) {
  430. X        mons[PM_LITTLE_DOG].pxlth = sizeof(struct edog);
  431. X        mtmp = makemon(&mons[PM_LITTLE_DOG], u.ux, u.uy);
  432. X        mons[PM_LITTLE_DOG].pxlth = 0;
  433. X        petname = dogname;
  434. X    } else {
  435. X        mons[PM_KITTEN].pxlth = sizeof(struct edog);
  436. X        mtmp = makemon(&mons[PM_KITTEN], u.ux, u.uy);
  437. X        mons[PM_KITTEN].pxlth = 0;
  438. X        petname = catname;
  439. X    }
  440. X
  441. X    if(!mtmp) return((struct monst *) 0); /* dogs were genocided */
  442. X
  443. X    if (petname[0]) {
  444. X        register struct monst *mtmp2;
  445. X
  446. X        mtmp->mnamelth = strlen(petname) + 1;
  447. X        mtmp2 = newmonst(sizeof(struct edog) + mtmp->mnamelth);
  448. X        *mtmp2 = *mtmp;
  449. X
  450. X        replmon(mtmp, mtmp2);
  451. X        mtmp = mtmp2;
  452. X        Strcpy(NAME(mtmp), petname);
  453. X        petname[0] = '\0'; /* name first only; actually unnecessary */
  454. X    }
  455. X    initedog(mtmp);
  456. X    return(mtmp);
  457. X}
  458. X
  459. X/* attach the monsters that went down (or up) together with @ */
  460. Xstruct monst *mydogs = 0;
  461. X/* monsters that fell through a trapdoor or stepped on a tele-trap. */
  462. X/* 'down' is now true only of trapdooor falling, not for tele-trap. */
  463. Xstruct monst *fallen_down = 0;
  464. X                
  465. Xvoid
  466. Xlosedogs(){
  467. X    register struct monst *mtmp,*mtmp0,*mtmp2;
  468. X
  469. X    while(mtmp = mydogs){
  470. X        mydogs = mtmp->nmon;
  471. X        mtmp->nmon = fmon;
  472. X        fmon = mtmp;
  473. X        mnexto(mtmp);
  474. X    }
  475. X#ifdef LINT
  476. X    mtmp0 = (struct monst *)0;
  477. X#endif
  478. X    for(mtmp = fallen_down; mtmp; mtmp = mtmp2) {
  479. X        mtmp2 = mtmp->nmon;
  480. X        if(mtmp->mx == dlevel) {
  481. X            mtmp->mx = 0;
  482. X            if(mtmp == fallen_down)
  483. X            fallen_down = mtmp->nmon;
  484. X            else
  485. X            mtmp0->nmon = mtmp->nmon;
  486. X            mtmp->nmon = fmon;
  487. X            fmon = mtmp;
  488. X            if (mtmp->isshk)
  489. X            home_shk(mtmp);
  490. X            else
  491. X            rloc(mtmp);
  492. X        } else
  493. X            mtmp0 = mtmp;
  494. X    }
  495. X}
  496. X
  497. Xvoid
  498. Xkeepdogs(){
  499. Xregister struct monst *mtmp;
  500. X    for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  501. X        if(((dist(mtmp->mx,mtmp->my) < 3 && levl_follower(mtmp)) ||
  502. X        /* the wiz will level t-port from anywhere to chase
  503. X           the amulet; if you don't have it, will chase you
  504. X           only if in range. -3. */
  505. X            (u.uhave_amulet && mtmp->iswiz))
  506. X            && !mtmp->msleep && !mtmp->mfroz) {
  507. X#ifdef WORM
  508. X        /* Bug "fix" for worm changing levels collapsing dungeon
  509. X         */
  510. X        if (mtmp->data == &mons[PM_LONG_WORM]) {
  511. X            if (canseemon(mtmp) || (Blind && Telepat))
  512. X                pline("The worm can't fit down the stairwell.");
  513. X# ifdef WALKIES
  514. X            if (mtmp->mleashed) {
  515. X                pline("The leash slides off the slimy worm.");
  516. X                m_unleash(mtmp);
  517. X            }
  518. X# endif
  519. X            continue;
  520. X        }
  521. X#endif
  522. X        if (mon_has_amulet(mtmp)) {
  523. X            pline("%s seems very disoriented for a moment.",
  524. X                Monnam(mtmp));
  525. X#ifdef WALKIES
  526. X            if (mtmp->mleashed) {
  527. X                pline("%s leash suddenly comes loose.",
  528. X                    is_female(mtmp) ? "Her" :
  529. X                    humanoid(mtmp->data) ? "His" : "Its");
  530. X                m_unleash(mtmp);
  531. X            }
  532. X#endif
  533. X            continue;
  534. X        }
  535. X        relmon(mtmp);
  536. X        mtmp->mx = mtmp->my = 0; /* to avoid mnexto()/mmask problem */
  537. X        mtmp->nmon = mydogs;
  538. X        mydogs = mtmp;
  539. X        unpmon(mtmp);
  540. X        keepdogs();    /* we destroyed the link, so use recursion */
  541. X        return;        /* (admittedly somewhat primitive) */
  542. X    }
  543. X}
  544. X
  545. Xvoid
  546. Xfall_down(mtmp, tolev) 
  547. Xregister struct monst *mtmp; 
  548. Xregister int tolev;
  549. X{
  550. X    relmon(mtmp);
  551. X    mtmp->nmon = fallen_down;
  552. X    fallen_down = mtmp;
  553. X#ifdef WALKIES
  554. X    if (mtmp->mleashed)  {
  555. X        pline("The leash comes off!");
  556. X        m_unleash(mtmp);
  557. X    }
  558. X#endif
  559. X    unpmon(mtmp);
  560. X    mtmp->mtame = 0;
  561. X    mtmp->mx = tolev; 
  562. X    mtmp->my = 0;
  563. X        /* make sure to reset mtmp->mx to 0 when releasing, */
  564. X        /* so rloc() on next level doesn't affect mmask */
  565. X}
  566. X
  567. X/* return quality of food; the lower the better */
  568. X/* fungi will eat even tainted food */
  569. Xint
  570. Xdogfood(mon,obj)
  571. Xstruct monst *mon;
  572. Xregister struct obj *obj;
  573. X{
  574. X    boolean carn = carnivorous(mon->data);
  575. X
  576. X    switch(obj->olet) {
  577. X    case FOOD_SYM:
  578. X        if (obj->otyp == CORPSE && obj->corpsenm == PM_COCKATRICE &&
  579. X        !resists_ston(mon->data))
  580. X            return TABU;
  581. X
  582. X        if (!carn && !herbivorous(mon->data))
  583. X            return (obj->cursed ? UNDEF : APPORT);
  584. X
  585. X        switch (obj->otyp) {
  586. X        case TRIPE_RATION:
  587. X            return (carn ? DOGFOOD : MANFOOD);
  588. X        case CORPSE:
  589. X        case EGG:
  590. X            if ((obj->age + 50 <= moves && mon->data->mlet != S_FUNGUS) ||
  591. X            (poisonous(&mons[obj->corpsenm]) && !resists_poison(mon->data)) ||
  592. X            (obj->corpsenm == PM_COCKATRICE && !resists_ston(mon->data)))
  593. X            return POISON;
  594. X            else return (carn ? CADAVER : MANFOOD);
  595. X        case DEAD_LIZARD:
  596. X            return (carn ? ACCFOOD : MANFOOD);
  597. X        default:
  598. X            return (obj->otyp < CARROT ? ACCFOOD : MANFOOD);
  599. X        }
  600. X    default:
  601. X        if(!obj->cursed) return(APPORT);
  602. X        /* fall into next case */
  603. X    case BALL_SYM:
  604. X    case CHAIN_SYM:
  605. X    case ROCK_SYM:
  606. X        return(UNDEF);
  607. X    }
  608. X}
  609. X
  610. X/* return roomnumber or -1 */
  611. Xint
  612. Xinroom(x,y) xchar x,y; {
  613. X    register struct mkroom *croom = &rooms[0];
  614. X    while(croom->hx >= 0){
  615. X        if(croom->hx >= x-1 && croom->lx <= x+1 &&
  616. X           croom->hy >= y-1 && croom->ly <= y+1)
  617. X            return(croom - rooms);
  618. X        croom++;
  619. X    }
  620. X    return(-1);    /* not in room or on door */
  621. X}
  622. X
  623. Xint
  624. Xtamedog(mtmp, obj)
  625. Xregister struct monst *mtmp;
  626. Xregister struct obj *obj;
  627. X{
  628. X    register struct monst *mtmp2;
  629. X
  630. X    /* worst case, at least he'll be peaceful. */
  631. X    mtmp->mpeaceful = 1;
  632. X    if(flags.moonphase == FULL_MOON && night() && rn2(6) && obj
  633. X                        && mtmp->data->mlet == S_DOG)
  634. X        return(0);
  635. X
  636. X    /* If we cannot tame him, at least he's no longer afraid. */
  637. X    mtmp->mflee = 0;
  638. X    mtmp->mfleetim = 0;
  639. X    if(mtmp->mtame || mtmp->mfroz ||
  640. X#ifdef WORM
  641. X       mtmp->wormno ||
  642. X#endif
  643. X       mtmp->isshk || mtmp->isgd ||
  644. X#if defined(ALTARS) && defined(THEOLOGY)
  645. X       mtmp->ispriest ||
  646. X#endif
  647. X#ifdef POLYSELF
  648. X       is_human(mtmp->data) || (is_demon(mtmp->data) && !is_demon(uasmon)))
  649. X#else
  650. X       is_human(mtmp->data) || is_demon(mtmp->data))
  651. X#endif
  652. X        return(0);
  653. X    /* no tame long worms so they don't try to follow you down stairs
  654. X       or get in your way */
  655. X    if(obj) {
  656. X        if(dogfood(mtmp, obj) >= MANFOOD) return(0);
  657. X        if(cansee(mtmp->mx,mtmp->my)){
  658. X            pline("%s devours the %s.", Monnam(mtmp),
  659. X                objects[obj->otyp].oc_name);
  660. X        }
  661. X        obfree(obj, (struct obj *)0);
  662. X    }
  663. X    mtmp2 = newmonst(sizeof(struct edog) + mtmp->mnamelth);
  664. X    *mtmp2 = *mtmp;
  665. X    mtmp2->mxlth = sizeof(struct edog);
  666. X    if(mtmp->mnamelth) Strcpy(NAME(mtmp2), NAME(mtmp));
  667. X    initedog(mtmp2);
  668. X    replmon(mtmp,mtmp2);
  669. X    return(1);
  670. X}
  671. END_OF_FILE
  672. if test 7862 -ne `wc -c <'src/dog.c'`; then
  673.     echo shar: \"'src/dog.c'\" unpacked with wrong size!
  674. fi
  675. # end of 'src/dog.c'
  676. fi
  677. if test -f 'src/mkroom.c' -a "${1}" != "-c" ; then 
  678.   echo shar: Will not clobber existing file \"'src/mkroom.c'\"
  679. else
  680. echo shar: Extracting \"'src/mkroom.c'\" \(10546 characters\)
  681. sed "s/^X//" >'src/mkroom.c' <<'END_OF_FILE'
  682. X/*    SCCS Id: @(#)mkroom.c    3.0    88/11/24
  683. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  684. X/* NetHack may be freely redistributed.  See license for details. */
  685. X
  686. X/*
  687. X * Entry points:
  688. X *    mkroom() -- make and stock a room of a given type
  689. X *    nexttodoor() -- return TRUE if adjacent to a door
  690. X *    has_dnstairs() -- return TRUE if given room has a down staircase
  691. X *    has_upstairs() -- return TRUE if given room has an up staircase
  692. X *    dist2() -- Euclidean square-of-distance function
  693. X *    courtmon() -- generate a court monster
  694. X */
  695. X#include "hack.h"
  696. X
  697. Xstatic void mkshop(), mkzoo(), mkswamp();
  698. X#ifdef ORACLE
  699. Xstatic void mkdelphi();
  700. X#endif
  701. X#if defined(ALTARS) && defined(THEOLOGY)
  702. Xstatic void mktemple();
  703. X#endif
  704. X
  705. Xstatic struct permonst *morguemon();
  706. X#ifdef ARMY
  707. Xstatic struct permonst *squadmon();
  708. X#endif
  709. X
  710. X#define sq(x) ((x)*(x))
  711. X
  712. Xstatic boolean
  713. Xisbig(sroom)
  714. Xregister struct mkroom *sroom;
  715. X{
  716. X    register int area = (sroom->hx - sroom->lx) * (sroom->hy - sroom->ly);
  717. X    return( area > 20 );
  718. X}
  719. X
  720. Xvoid
  721. Xmkroom(roomtype)
  722. X/* make and stock a room of a given type */
  723. Xint    roomtype;
  724. X{
  725. X
  726. X    if (roomtype >= SHOPBASE)
  727. X    mkshop();    /* someday, we should be able to specify shop type */
  728. X    else switch(roomtype) {
  729. X#ifdef THRONES
  730. X    case COURT:    mkzoo(COURT); break;
  731. X#endif
  732. X    case ZOO:    mkzoo(ZOO); break;
  733. X    case BEEHIVE:    mkzoo(BEEHIVE); break;
  734. X    case MORGUE:    mkzoo(MORGUE); break;
  735. X    case BARRACKS:    mkzoo(BARRACKS); break;
  736. X    case SWAMP:    mkswamp(); break;
  737. X#ifdef ORACLE
  738. X    case DELPHI:    mkdelphi(); break;
  739. X#endif
  740. X#if defined(ALTARS) && defined(THEOLOGY)
  741. X    case TEMPLE:    mktemple(); break;
  742. X#endif
  743. X    default:    impossible("Tried to make a room of type %d.", roomtype);
  744. X    }
  745. X}
  746. X
  747. Xstatic void
  748. Xmkshop()
  749. X{
  750. X    register struct mkroom *sroom;
  751. X    int i = -1;
  752. X#ifdef WIZARD
  753. X    register char *ep;
  754. X
  755. X    /* first determine shoptype */
  756. X    if(wizard){
  757. X        ep = getenv("SHOPTYPE");
  758. X        if(ep){
  759. X            if(*ep == 'z' || *ep == 'Z'){
  760. X                mkzoo(ZOO);
  761. X                return;
  762. X            }
  763. X            if(*ep == 'm' || *ep == 'M'){
  764. X                mkzoo(MORGUE);
  765. X                return;
  766. X            }
  767. X            if(*ep == 'b' || *ep == 'B'){
  768. X                mkzoo(BEEHIVE);
  769. X                return;
  770. X            }
  771. X#ifdef THRONES
  772. X            if(*ep == 't' || *ep == 'T'){
  773. X                mkzoo(COURT);
  774. X                return;
  775. X            }
  776. X#endif
  777. X#ifdef ARMY
  778. X            if(*ep == 's' || *ep == 'S'){
  779. X                mkzoo(BARRACKS);
  780. X                return;
  781. X            }
  782. X#endif /* ARMY */
  783. X#if defined(ALTARS) && defined(THEOLOGY)
  784. X            if(*ep == '_'){
  785. X                mktemple();
  786. X                return;
  787. X            }
  788. X#endif
  789. X            if(*ep == '}'){
  790. X                mkswamp();
  791. X                return;
  792. X            }
  793. X            for(i=0; shtypes[i].name; i++)
  794. X                if(*ep == shtypes[i].symb) goto gottype;
  795. X            i = -1;
  796. X        }
  797. X    }
  798. Xgottype:
  799. X#endif
  800. X    for(sroom = &rooms[0]; ; sroom++){
  801. X        if(sroom->hx < 0) return;
  802. X        if(sroom - rooms >= nroom) {
  803. X            pline("rooms not closed by -1?");
  804. X            return;
  805. X        }
  806. X        if(sroom->rtype != OROOM) continue;
  807. X        if(!sroom->rlit || has_dnstairs(sroom) || has_upstairs(sroom))
  808. X            continue;
  809. X        if(
  810. X#ifdef WIZARD
  811. X           (wizard && ep && sroom->doorct != 0) ||
  812. X#endif
  813. X            sroom->doorct == 1) break;
  814. X    }
  815. X
  816. X    if(i < 0) {            /* shoptype not yet determined */
  817. X        register int j;
  818. X
  819. X        /* pick a shop type at random */
  820. X        for(j = rn2(100), i = 0; j -= shtypes[i].prob; i++)
  821. X        if (j < 0)    break;
  822. X
  823. X        /* big rooms cannot be wand or book shops,
  824. X         * - so make them general stores
  825. X         */
  826. X        if(isbig(sroom) && (shtypes[i].symb == WAND_SYM
  827. X#ifdef SPELLS
  828. X                || shtypes[i].symb == SPBOOK_SYM
  829. X#endif
  830. X                                )) i = 0;
  831. X    }
  832. X    sroom->rtype = SHOPBASE + i;
  833. X
  834. X    /* stock the room with a shopkeeper and artifacts */
  835. X    stock_room(&(shtypes[i]), sroom);
  836. X}
  837. X
  838. Xstatic struct mkroom *
  839. Xpick_room()
  840. X/* pick an unused room, preferably with only one door */
  841. X{
  842. X    register struct mkroom *sroom;
  843. X    register int i = nroom;
  844. X
  845. X    for(sroom = &rooms[rn2(nroom)]; i--; sroom++) {
  846. X        if(sroom == &rooms[nroom])
  847. X            sroom = &rooms[0];
  848. X        if(sroom->hx < 0)
  849. X            return (struct mkroom *)0;
  850. X        if(sroom->rtype != OROOM)    continue;
  851. X        if(has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3)))
  852. X            continue;
  853. X        if(sroom->doorct == 1 || !rn2(5))
  854. X            return sroom;
  855. X    }
  856. X    return (struct mkroom *)0;
  857. X}
  858. X
  859. Xstatic void
  860. Xmkzoo(type)
  861. Xint type;
  862. X{
  863. X    register struct mkroom *sroom;
  864. X    struct monst *mon;
  865. X    register int sx,sy,i;
  866. X    int sh, tx, ty, goldlim = 500 * dlevel;
  867. X
  868. X    if(!(sroom = pick_room())) return;
  869. X
  870. X    sroom->rtype = type;
  871. X    sh = sroom->fdoor;
  872. X    switch(type) {
  873. X        case COURT:
  874. X        tx = somex(sroom); ty = somey(sroom); break;
  875. X        /* TODO: try to ensure the enthroned monster is an M2_PRINCE */
  876. X        case BEEHIVE:
  877. X        tx = sroom->lx + (sroom->hx - sroom->lx + 1)/2;
  878. X        ty = sroom->ly + (sroom->hy - sroom->ly + 1)/2;
  879. X        break;
  880. X    }
  881. X    for(sx = sroom->lx; sx <= sroom->hx; sx++)
  882. X        for(sy = sroom->ly; sy <= sroom->hy; sy++){
  883. X        if((sx == sroom->lx && doors[sh].x == sx-1) ||
  884. X           (sx == sroom->hx && doors[sh].x == sx+1) ||
  885. X           (sy == sroom->ly && doors[sh].y == sy-1) ||
  886. X           (sy == sroom->hy && doors[sh].y == sy+1)) continue;
  887. X        mon = makemon(
  888. X#ifdef THRONES
  889. X            (type == COURT) ? courtmon() :
  890. X#endif
  891. X#ifdef ARMY
  892. X            (type == BARRACKS) ? squadmon() :
  893. X#endif
  894. X            (type == MORGUE) ? morguemon() :
  895. X            (type == BEEHIVE) ?
  896. X            (sx == tx && sy == ty ? &mons[PM_QUEEN_BEE] : 
  897. X             &mons[PM_KILLER_BEE]) :
  898. X            (struct permonst *) 0,
  899. X           sx, sy);
  900. X        if(mon) {
  901. X            mon->msleep = 1;
  902. X#ifdef THRONES
  903. X            if (type==COURT && mon->mpeaceful) {
  904. X                mon->mpeaceful = 0;
  905. X                mon->malign = max(3,abs(mon->data->maligntyp));
  906. X            }
  907. X#endif
  908. X        }
  909. X        switch(type) {
  910. X            case ZOO:
  911. X            i = sq(dist2(sx,sy,doors[sh].x,doors[sh].y));
  912. X            if(i >= goldlim) i = 5*dlevel;
  913. X            goldlim -= i;
  914. X            mkgold((long)(10 + rn2(i)), sx, sy);
  915. X            break;
  916. X            case MORGUE:
  917. X            if(!rn2(5))
  918. X                (void) mk_tt_corpse(sx, sy);
  919. X            if(!rn2(10))    /* lots of treasure buried with dead */
  920. X                (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, sx, sy);
  921. X            break;
  922. X            case BEEHIVE:
  923. X            if(!rn2(3))
  924. X                (void) mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy);
  925. X            break;
  926. X            case BARRACKS:
  927. X            if(!rn2(20))    /* the payroll and some loot */
  928. X                (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, sx, sy);
  929. X            break;
  930. X        }
  931. X    }
  932. X#ifdef THRONES
  933. X    if(type == COURT)  {
  934. X        levl[tx][ty].typ = THRONE;
  935. X        levl[tx][ty].scrsym = THRONE_SYM;
  936. X
  937. X        tx = somex(sroom);
  938. X        ty = somey(sroom);
  939. X        mkgold((long) rn1(50 * dlevel,10), sx, sy);
  940. X        (void) mksobj_at(CHEST, sx, sy);    /* the royal coffers */
  941. X    }
  942. X#endif
  943. X
  944. X}
  945. X
  946. Xstatic struct permonst *
  947. Xmorguemon()
  948. X{
  949. X    register int i = rn2(100), hd = rn2(dlevel);
  950. X
  951. X    if(hd > 10 && i < 10)
  952. X        return((Inhell) ? mkclass(S_DEMON) : &mons[ndemon()]);
  953. X    if(hd > 8 && i > 85)
  954. X        return(mkclass(S_VAMPIRE));
  955. X
  956. X    return((i < 20) ? &mons[PM_GHOST]
  957. X            : (i < 40) ? &mons[PM_WRAITH] : mkclass(S_ZOMBIE));
  958. X}
  959. X
  960. Xstatic void
  961. Xmkswamp()    /* Michiel Huisjes & Fred de Wilde */
  962. X{
  963. X    register struct mkroom *sroom;
  964. X    register int sx,sy,i,eelct = 0;
  965. X
  966. X    for(i=0; i<5; i++) {        /* 5 tries */
  967. X        sroom = &rooms[rn2(nroom)];
  968. X        if(sroom->hx < 0 || sroom->rtype != OROOM ||
  969. X           has_upstairs(sroom) || has_dnstairs(sroom))
  970. X            continue;
  971. X
  972. X        /* satisfied; make a swamp */
  973. X        sroom->rtype = SWAMP;
  974. X        for(sx = sroom->lx; sx <= sroom->hx; sx++)
  975. X        for(sy = sroom->ly; sy <= sroom->hy; sy++)
  976. X        if(levl[sx][sy].omask == 0 && levl[sx][sy].gmask == 0 &&
  977. X           levl[sx][sy].mmask == 0 &&
  978. X           !t_at(sx,sy) && !nexttodoor(sx,sy)) {
  979. X            if((sx+sy)%2) {
  980. X            levl[sx][sy].typ = POOL;
  981. X            levl[sx][sy].scrsym = POOL_SYM;
  982. X            if(!eelct || !rn2(4)) {
  983. X                (void) makemon(mkclass(S_EEL), sx, sy);
  984. X                eelct++;
  985. X            }
  986. X            } else if(!rn2(4))    /* swamps tend to be moldy */
  987. X            (void) makemon(mkclass(S_FUNGUS), sx, sy);
  988. X        }
  989. X    }
  990. X}
  991. X
  992. X#ifdef ORACLE
  993. Xstatic void
  994. Xmkdelphi()
  995. X{
  996. X    register struct mkroom *sroom;
  997. X    register struct monst *oracl;
  998. X    int dy,xx,yy;
  999. X
  1000. X    if(doorindex >= DOORMAX) return;
  1001. X    if(!(sroom = pick_room())) return;
  1002. X
  1003. X    if(!place_oracle(sroom,&dy,&xx,&yy)) return;
  1004. X
  1005. X    /* set up Oracle and environment */
  1006. X    if(!(oracl = makemon(&mons[PM_ORACLE],xx,yy))) return;
  1007. X    sroom->rtype = DELPHI;
  1008. X    oracl->mpeaceful = 1;
  1009. X
  1010. X    yy -= dy;
  1011. X    if(ACCESSIBLE(levl[xx-1][yy].typ))
  1012. X        (void) mkstatue(&mons[PM_FOREST_CENTAUR], xx-1, yy);
  1013. X    if(ACCESSIBLE(levl[xx][yy].typ))
  1014. X        (void) mkstatue(&mons[PM_MOUNTAIN_CENTAUR], xx, yy);
  1015. X    if(ACCESSIBLE(levl[xx+1][yy].typ))
  1016. X        (void) mkstatue(&mons[PM_PLAINS_CENTAUR], xx+1, yy);
  1017. X# ifdef FOUNTAINS
  1018. X    mkfount(0,sroom);
  1019. X# endif
  1020. X}
  1021. X#endif
  1022. X
  1023. X#if defined(ALTARS) && defined(THEOLOGY)
  1024. Xvoid
  1025. Xshrine_pos(sx,sy,troom)
  1026. Xint *sx,*sy;
  1027. Xstruct mkroom *troom;
  1028. X{
  1029. X    *sx = troom->lx + ((troom->hx - troom->lx) / 2);
  1030. X    *sy = troom->ly + ((troom->hy - troom->ly) / 2);
  1031. X}
  1032. X
  1033. Xstatic void
  1034. Xmktemple()
  1035. X{
  1036. X    register struct mkroom *sroom;
  1037. X    int sx,sy;
  1038. X
  1039. X    if(!(sroom = pick_room())) return;
  1040. X
  1041. X    /* set up Priest and shrine */
  1042. X    sroom->rtype = TEMPLE;
  1043. X    shrine_pos(&sx,&sy,sroom);
  1044. X    /*
  1045. X     * In temples, shrines are blessed altars
  1046. X     * located in the center of the room
  1047. X     */
  1048. X    levl[sx][sy].typ = ALTAR;
  1049. X    levl[sx][sy].scrsym = ALTAR_SYM;
  1050. X    levl[sx][sy].altarmask = rn2((int)A_LAW+1) | A_SHRINE;
  1051. X    priestini(dlevel, sx, sy, (int) levl[sx][sy].altarmask);
  1052. X}
  1053. X#endif
  1054. X
  1055. Xboolean
  1056. Xnexttodoor(sx,sy)
  1057. Xregister int sx, sy;
  1058. X{
  1059. X    register int dx, dy;
  1060. X    register struct rm *lev;
  1061. X    for(dx = -1; dx <= 1; dx++) for(dy = -1; dy <= 1; dy++)
  1062. X        if(IS_DOOR((lev = &levl[sx+dx][sy+dy])->typ) ||
  1063. X            lev->typ == SDOOR)
  1064. X            return(TRUE);
  1065. X    return(FALSE);
  1066. X}
  1067. X
  1068. Xboolean
  1069. Xhas_dnstairs(sroom)
  1070. Xregister struct mkroom *sroom;
  1071. X{
  1072. X    return(sroom->lx <= xdnstair && xdnstair <= sroom->hx &&
  1073. X           sroom->ly <= ydnstair && ydnstair <= sroom->hy);
  1074. X}
  1075. X
  1076. Xboolean
  1077. Xhas_upstairs(sroom)
  1078. Xregister struct mkroom *sroom;
  1079. X{
  1080. X    return(sroom->lx <= xupstair && xupstair <= sroom->hx &&
  1081. X           sroom->ly <= yupstair && yupstair <= sroom->hy);
  1082. X}
  1083. X
  1084. Xint
  1085. Xdist2(x0,y0,x1,y1)
  1086. Xint x0, y0, x1, y1;
  1087. X{
  1088. X    register int dx = x0 - x1, dy = y0 - y1;
  1089. X    return sq(dx) + sq(dy);
  1090. X}
  1091. X
  1092. X#ifdef THRONES
  1093. Xstruct permonst *
  1094. Xcourtmon()
  1095. X{
  1096. X    int     i = rn2(60) + rn2(3*dlevel);
  1097. X    if (i > 100)        return(mkclass(S_DRAGON));
  1098. X    else if (i > 95)    return(mkclass(S_GIANT));
  1099. X    else if (i > 85)    return(mkclass(S_TROLL));
  1100. X    else if (i > 75)    return(mkclass(S_CENTAUR));
  1101. X    else if (i > 60)    return(mkclass(S_ORC));
  1102. X    else if (i > 45)    return(&mons[PM_BUGBEAR]);
  1103. X    else if (i > 30)    return(&mons[PM_HOBGOBLIN]);
  1104. X    else if (i > 15)    return(mkclass(S_GNOME));
  1105. X    else            return(mkclass(S_KOBOLD));
  1106. X}
  1107. X#endif /* THRONES /**/
  1108. X
  1109. X#ifdef ARMY
  1110. X#define        NSTYPES    (PM_CAPTAIN-PM_SOLDIER+1)
  1111. X
  1112. Xstruct {
  1113. X    unsigned    pm;
  1114. X    unsigned    prob;
  1115. X}   squadprob[NSTYPES] = {
  1116. X    PM_SOLDIER, 80, PM_SERGEANT, 15, PM_LIEUTENANT, 4, PM_CAPTAIN, 1
  1117. X};
  1118. X
  1119. Xstatic struct permonst *
  1120. Xsquadmon() {        /* return soldier types. */
  1121. X
  1122. X    register struct permonst *ptr;
  1123. X    register int    i, cpro, sel = rnd(80+dlevel);
  1124. X
  1125. X    for(cpro = i = 0; i < NSTYPES; i++)
  1126. X        if((cpro += squadprob[i].prob) > sel) {
  1127. X
  1128. X        ptr = &mons[squadprob[i].pm];
  1129. X        goto gotone;
  1130. X        }
  1131. X    ptr = &mons[squadprob[rn2(NSTYPES)].pm];
  1132. Xgotone:
  1133. X    if(!(ptr->geno & G_GENOD))  return(ptr);
  1134. X    else                return((struct permonst *) 0);
  1135. X}
  1136. X#endif /* ARMY /* */
  1137. END_OF_FILE
  1138. if test 10546 -ne `wc -c <'src/mkroom.c'`; then
  1139.     echo shar: \"'src/mkroom.c'\" unpacked with wrong size!
  1140. fi
  1141. # end of 'src/mkroom.c'
  1142. fi
  1143. if test -f 'src/mthrowu.c' -a "${1}" != "-c" ; then 
  1144.   echo shar: Will not clobber existing file \"'src/mthrowu.c'\"
  1145. else
  1146. echo shar: Extracting \"'src/mthrowu.c'\" \(10474 characters\)
  1147. sed "s/^X//" >'src/mthrowu.c' <<'END_OF_FILE'
  1148. X/*    SCCS Id: @(#)mthrowu.c    3.0    88/04/13
  1149. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  1150. X/* NetHack may be freely redistributed.  See license for details. */
  1151. X
  1152. X#include    "hack.h"
  1153. X
  1154. Xstatic int movedist();
  1155. X
  1156. X#define URETREATING(x,y) (movedist(u.ux,u.uy,x,y) > movedist(u.ux0,u.uy0,x,y))
  1157. X
  1158. Xboolean lined_up();
  1159. X
  1160. Xschar    tbx = 0, tby = 0;    /* used for direction of throw, buzz, etc. */
  1161. X
  1162. Xconst char *breathwep[] = {    "fragments",
  1163. X                "fire",
  1164. X                "sleep gas",
  1165. X                "frost",
  1166. X                "death",
  1167. X                "lightning",
  1168. X                "poison gas",
  1169. X                "acid"
  1170. X};
  1171. X
  1172. Xint
  1173. Xthitu(tlev, dam, name)    /* u is hit by sth, but not a monster */
  1174. X    register int tlev, dam;
  1175. X    register char *name;
  1176. X{
  1177. X    char buf[BUFSZ];
  1178. X    boolean acidic = (!strcmp(name, "splash of venom") && dam);
  1179. X    /* A horrible kludge... the problem is that we want to do something
  1180. X     * special--and we can't do it after returning since we might die and
  1181. X     * not return, but the special stuff should be done anyway...
  1182. X     */
  1183. X
  1184. X    setan(name, buf);
  1185. X    if(u.uac + tlev <= rnd(20)) {
  1186. X        if(Blind || !flags.verbose) pline("It misses.");
  1187. X        else You("are almost hit by %s!", buf);
  1188. X        return(0);
  1189. X    } else {
  1190. X        if(Blind || !flags.verbose) You("are hit!");
  1191. X        else You("are hit by %s!", buf);
  1192. X        Strcpy(buf,name);
  1193. X        /* If name came from xname() we must copy it, otherwise if
  1194. X         * you die, the possession identify will call xname(),
  1195. X         * overwriting xname's buffer, and your tombstone will say
  1196. X         * you were killed by a green gem or some such.
  1197. X         */
  1198. X#ifdef POLYSELF
  1199. X        if (acidic && resists_acid(uasmon))
  1200. X            pline("It doesn't seem to hurt you.");
  1201. X        else {
  1202. X#endif
  1203. X            if (acidic) pline("It burns!");
  1204. X            losehp(dam, buf);
  1205. X#ifdef POLYSELF
  1206. X        }
  1207. X#endif
  1208. X        return(1);
  1209. X    }
  1210. X}
  1211. X
  1212. X/* Be sure this corresponds with what happens to player-thrown objects in
  1213. X * dothrow.c (for consistency). --KAA
  1214. X */
  1215. Xstatic void
  1216. Xdrop_throw(obj, ohit, x, y)
  1217. Xregister struct obj *obj;
  1218. Xboolean ohit;
  1219. Xint x,y;
  1220. X{
  1221. X    int create;
  1222. X
  1223. X    if (obj->otyp == CREAM_PIE || obj->olet == VENOM_SYM)
  1224. X        create = 0;
  1225. X    else if (ohit &&
  1226. X         ((obj->otyp >= ARROW && obj->otyp <= SHURIKEN) ||
  1227. X          obj->otyp == ROCK))
  1228. X        create = !rn2(3);
  1229. X    else create = 1;
  1230. X    if (create && !flooreffects(obj,x,y)) {
  1231. X        obj->ox = x;
  1232. X        obj->oy = y;
  1233. X        obj->nobj = fobj;
  1234. X        fobj = obj;
  1235. X        stackobj(fobj);
  1236. X        levl[x][y].omask = 1;
  1237. X    } else free((genericptr_t)obj);
  1238. X}
  1239. X
  1240. Xstatic void
  1241. Xm_throw(x, y, dx, dy, range, obj)
  1242. X    register int x,y,dx,dy,range;        /* direction and range */
  1243. X    register struct obj *obj;
  1244. X{
  1245. X    register struct monst *mtmp;
  1246. X    struct obj *singleobj;
  1247. X    char sym = obj->olet;
  1248. X    int damage;
  1249. X    int hitu, blindinc=0;
  1250. X
  1251. X    bhitpos.x = x;
  1252. X    bhitpos.y = y;
  1253. X
  1254. X    singleobj = splitobj(obj, (int)obj->quan-1);
  1255. X    /* splitobj leaves the new object in the chain (i.e. the monster's
  1256. X     * inventory).  Remove it.  We can do this in 1 line, but it's highly
  1257. X     * dependent on the fact that we know splitobj() places it immediately
  1258. X     * after obj.
  1259. X     */
  1260. X    obj->nobj = singleobj->nobj;
  1261. X
  1262. X    if(sym) {
  1263. X        tmp_at(-1, sym);    /* open call */
  1264. X        tmp_at(-3, (int)AT_OBJ);
  1265. X    }
  1266. X    while(range-- > 0) { /* Actually the loop is always exited by break */
  1267. X        bhitpos.x += dx;
  1268. X        bhitpos.y += dy;
  1269. X        if(levl[bhitpos.x][bhitpos.y].mmask) {
  1270. X            mtmp = m_at(bhitpos.x,bhitpos.y);
  1271. X
  1272. X            if(mtmp->data->ac + 8 + obj->spe <= rnd(20)) {
  1273. X            miss(distant_name(singleobj,xname), mtmp);
  1274. X            if (!range) { /* Last position; object drops */
  1275. X                drop_throw(singleobj, 0, mtmp->mx, mtmp->my);
  1276. X                break;
  1277. X            }
  1278. X            } else {
  1279. X            damage = dmgval(obj, mtmp->data);
  1280. X            if (damage < 1) damage = 1;
  1281. X            if (obj->otyp==ACID_VENOM && resists_acid(mtmp->data))
  1282. X                damage = 0;
  1283. X            hit(distant_name(singleobj,xname), mtmp,exclam(damage));
  1284. X            if (obj->opoisoned) {
  1285. X                if (resists_poison(mtmp->data))
  1286. X                kludge("The poison doesn't seem to affect %s.",
  1287. X                                mon_nam(mtmp));
  1288. X                else {
  1289. X                if (rn2(10)) damage += rnd(6);
  1290. X                else {
  1291. X                    pline("The poison was deadly...");
  1292. X                    damage = mtmp->mhp;
  1293. X                }
  1294. X                }
  1295. X            }
  1296. X            if (obj->otyp==ACID_VENOM && cansee(mtmp->mx,mtmp->my)){
  1297. X                if (resists_acid(mtmp->data)) {
  1298. X                pline("%s is unaffected.", Monnam(mtmp));
  1299. X                damage = 0;
  1300. X                } else pline("The acid burns %s!", mon_nam(mtmp));
  1301. X            }
  1302. X            mtmp->mhp -= damage;
  1303. X            if(mtmp->mhp < 1) {
  1304. X                if (cansee(mtmp->mx, mtmp->my))
  1305. X                pline("%s is killed!", Monnam(mtmp));
  1306. X                mondied(mtmp);
  1307. X            }
  1308. X
  1309. X            if((obj->otyp == CREAM_PIE) ||
  1310. X               (obj->otyp == BLINDING_VENOM)) {
  1311. X                if (cansee(mtmp->mx, mtmp->my))
  1312. X                pline("%s is blinded by the %s.",
  1313. X                      Monnam(mtmp), xname(singleobj));
  1314. X                if(mtmp->msleep) mtmp->msleep = 0;
  1315. X                mtmp->mcansee = 0;
  1316. X                {
  1317. X                register unsigned rnd_tmp = rnd(25) + 20;
  1318. X                if((mtmp->mblinded + rnd_tmp) > 127)
  1319. X                    mtmp->mblinded = 127;
  1320. X                else mtmp->mblinded += rnd_tmp;
  1321. X                }
  1322. X            }
  1323. X            drop_throw(singleobj, 1, bhitpos.x, bhitpos.y);
  1324. X            break;
  1325. X            }
  1326. X        }
  1327. X        if (bhitpos.x == u.ux && bhitpos.y == u.uy) {
  1328. X            if (multi) nomul(0);
  1329. X
  1330. X            switch(obj->otyp) {
  1331. X                int dam;
  1332. X                case CREAM_PIE:
  1333. X                case BLINDING_VENOM:
  1334. X                hitu = thitu(8, 0, xname(singleobj));
  1335. X                break;
  1336. X                default:
  1337. X                dam = dmgval(obj, uasmon);
  1338. X                if (dam < 1) dam = 1;
  1339. X                hitu = thitu(8+obj->spe, dam, xname(singleobj));
  1340. X            }
  1341. X            if (obj->opoisoned)
  1342. X                /* it's safe to call xname twice because it's the
  1343. X                   same object both times... */
  1344. X                poisoned(xname(singleobj), A_STR, xname(singleobj));
  1345. X            if(hitu && (obj->otyp == CREAM_PIE ||
  1346. X                     obj->otyp == BLINDING_VENOM)) {
  1347. X                blindinc = rnd(25);
  1348. X                if(obj->otyp == CREAM_PIE) {
  1349. X                if(!Blind) pline("Yecch!  You've been creamed.");
  1350. X                else    pline("There's something sticky all over your %s.", body_part(FACE));
  1351. X                } else {    /* venom in the eyes */
  1352. X                if(Blindfolded) /* nothing */ ;
  1353. X                else if(!Blind) pline("The venom blinds you.");
  1354. X                else    Your("%s sting.",
  1355. X                    makeplural(body_part(EYE)));
  1356. X                }
  1357. X            }
  1358. X            if (hitu || !range) {
  1359. X                drop_throw(singleobj, hitu, u.ux, u.uy);
  1360. X                break;
  1361. X            }
  1362. X        } else if (!range    /* reached end of path */
  1363. X            /* missile hits edge of screen */
  1364. X            || !isok(bhitpos.x+dx,bhitpos.y+dy)
  1365. X            /* missile hits the wall */
  1366. X            || IS_WALL(levl[bhitpos.x+dx][bhitpos.y+dy].typ)
  1367. X            || levl[bhitpos.x+dx][bhitpos.y+dy].typ == SDOOR
  1368. X            || levl[bhitpos.x+dx][bhitpos.y+dy].typ == SCORR
  1369. X#ifdef SINKS
  1370. X            /* Thrown objects "sink" */
  1371. X            || IS_SINK(levl[bhitpos.x][bhitpos.y].typ)
  1372. X#endif
  1373. X                                ) {
  1374. X            drop_throw(singleobj, 0, bhitpos.x, bhitpos.y);
  1375. X            break;
  1376. X        }
  1377. X        tmp_at(bhitpos.x, bhitpos.y);
  1378. X    }
  1379. X    tmp_at(bhitpos.x, bhitpos.y);
  1380. X    tmp_at(-1, -1);
  1381. X    /* blindfold keeps substances out of your eyes */
  1382. X    if (blindinc && !Blindfolded) {
  1383. X        u.ucreamed += blindinc;
  1384. X        make_blinded(Blinded + blindinc,FALSE);
  1385. X    }
  1386. X}
  1387. X
  1388. X/* Remove an item from the monster's inventory.
  1389. X */
  1390. Xvoid
  1391. Xm_useup(mon, obj)
  1392. Xstruct monst *mon;
  1393. Xstruct obj *obj;
  1394. X{
  1395. X    struct obj *otmp, *prev;
  1396. X
  1397. X    prev = ((struct obj *) 0);
  1398. X    for (otmp = mon->minvent; otmp; otmp = otmp->nobj) {
  1399. X        if (otmp == obj) {
  1400. X            if (prev)
  1401. X                prev->nobj = obj->nobj;
  1402. X            else
  1403. X                mon->minvent = obj->nobj;
  1404. X            free((genericptr_t) obj);
  1405. X            break;
  1406. X        }
  1407. X        prev = otmp;
  1408. X    }
  1409. X}
  1410. X
  1411. X/* Always returns 0??? -SAC */
  1412. Xint
  1413. Xthrwmu(mtmp)    /* monster throws item at you */
  1414. Xregister struct monst *mtmp;
  1415. X{
  1416. X    struct obj *otmp, *select_rwep();
  1417. X    register xchar x, y;
  1418. X
  1419. X    if(lined_up(mtmp)) {
  1420. X
  1421. X        if((otmp = select_rwep(mtmp))) {
  1422. X
  1423. X        /* If you are coming toward the monster, the monster
  1424. X         * should try to soften you up with missiles.  If you are
  1425. X         * going away, you are probably hurt or running.  Give
  1426. X         * chase, but if you are getting too far away, throw.
  1427. X         */
  1428. X        x = mtmp->mx;
  1429. X        y = mtmp->my;
  1430. X        if(!URETREATING(x,y) ||
  1431. X           !rn2(BOLT_LIM-movedist(x,mtmp->mux,y,mtmp->muy)))
  1432. X        {
  1433. X            m_throw(mtmp->mx, mtmp->my, sgn(tbx), sgn(tby), 
  1434. X            movedist(mtmp->mx,mtmp->mux,mtmp->my,mtmp->muy), otmp);
  1435. X            if (!otmp->quan) m_useup(mtmp, otmp);
  1436. X            nomul(0);
  1437. X            return 0;
  1438. X        }
  1439. X        }
  1440. X    }
  1441. X    return 0;
  1442. X}
  1443. X
  1444. Xint
  1445. Xspitmu(mtmp)            /* monster spits substance at you */
  1446. Xregister struct monst *mtmp;
  1447. X{
  1448. X    register struct obj *otmp;
  1449. X
  1450. X    if(mtmp->mcan) {
  1451. X
  1452. X        if(flags.soundok)
  1453. X        pline("A dry rattle comes from %s's throat", mon_nam(mtmp));
  1454. X        return 0;
  1455. X    }
  1456. X    if(lined_up(mtmp)) {
  1457. X        otmp = mksobj(mtmp->data==&mons[PM_COBRA] ?
  1458. X            BLINDING_VENOM : ACID_VENOM, FALSE);
  1459. X        /* really incorrect; should check the attack type; this might
  1460. X         * fail if someone introduces another monster with a venom
  1461. X         * attack...
  1462. X         */
  1463. X        if(!rn2(BOLT_LIM-movedist(mtmp->mx,mtmp->mux,mtmp->my,mtmp->muy))) {
  1464. X
  1465. X            m_throw(mtmp->mx, mtmp->my, sgn(tbx), sgn(tby), 
  1466. X            movedist(mtmp->mx,mtmp->mux,mtmp->my,mtmp->muy), otmp);
  1467. X            nomul(0);
  1468. X            return 0;
  1469. X        }
  1470. X    }
  1471. X    return 0;
  1472. X}
  1473. X
  1474. Xint
  1475. Xbreamu(mtmp, mattk)            /* monster breathes at you (ranged) */
  1476. X    register struct monst *mtmp;
  1477. X    register struct attack  *mattk;
  1478. X{
  1479. X    if(lined_up(mtmp)) {
  1480. X
  1481. X        if(mtmp->mcan) {
  1482. X        if(flags.soundok) {
  1483. X            if(canseemon(mtmp))
  1484. X            pline("%s coughs.", Monnam(mtmp));
  1485. X            else
  1486. X            You("hear a cough.");
  1487. X        }
  1488. X        return(0);
  1489. X        }
  1490. X        if(rn2(3)) {
  1491. X
  1492. X        if((mattk->adtyp >= 1) && (mattk->adtyp < 11)) {
  1493. X
  1494. X            if(canseemon(mtmp))
  1495. X            pline("%s breathes %s!", Monnam(mtmp),
  1496. X                  breathwep[mattk->adtyp-1]);
  1497. X            buzz((int) (-20 - (mattk->adtyp-1)), (int)mattk->damn,
  1498. X             mtmp->mx, mtmp->my, sgn(tbx), sgn(tby));
  1499. X            nomul(0);
  1500. X        } else impossible("Breath weapon %d used", mattk->adtyp-1);
  1501. X        }
  1502. X    }
  1503. X    return(1);
  1504. X}
  1505. X
  1506. Xboolean
  1507. Xlinedup(ax, ay, bx, by)
  1508. Xregister xchar ax, ay, bx, by;
  1509. X{
  1510. X    register xchar x, y;
  1511. X
  1512. X    tbx = ax - bx;    /* These two values are set for use */
  1513. X    tby = ay - by;    /* after successful return.        */
  1514. X
  1515. X    if((!tbx || !tby || abs(tbx) == abs(tby)) /* straight line or diagonal */
  1516. X       && movedist(tbx, 0,  tby, 0) < BOLT_LIM) {
  1517. X
  1518. X        /* Check if there are any dead squares between.  If so,
  1519. X         * it will not be possible to shoot.
  1520. X         */
  1521. X        x = bx; y = by;
  1522. X        while(x != ax || y != ay) {
  1523. X
  1524. X            if (!ACCESSIBLE(levl[x][y].typ) ||
  1525. X              (IS_DOOR(levl[x][y].typ) && 
  1526. X                (levl[x][y].doormask & (D_LOCKED | D_CLOSED)))) 
  1527. X            return FALSE;
  1528. X            x += sgn(tbx), y += sgn(tby);
  1529. X        }
  1530. X        return TRUE;
  1531. X    }
  1532. X    return FALSE;
  1533. X}
  1534. X
  1535. Xboolean
  1536. Xlined_up(mtmp)        /* is mtmp in position to use ranged attack? */
  1537. X    register struct monst *mtmp;
  1538. X{
  1539. X    return(linedup(mtmp->mux,mtmp->muy,mtmp->mx,mtmp->my));
  1540. X}
  1541. X
  1542. X/* Check if a monster is carrying a particular item.
  1543. X */
  1544. Xstruct obj *
  1545. Xm_carrying(mtmp, type)
  1546. Xstruct monst *mtmp;
  1547. Xint type;
  1548. X{
  1549. X    register struct obj *otmp;
  1550. X
  1551. X    for(otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
  1552. X        if(otmp->otyp == type)
  1553. X            return(otmp);
  1554. X    return((struct obj *) 0);
  1555. X}
  1556. X
  1557. Xstatic int
  1558. Xmovedist(x0, x1, y0, y1)
  1559. X{
  1560. X    register int absdx, absdy;
  1561. X
  1562. X    absdx = abs(x1 - x0);
  1563. X    absdy = abs(y1 - y0);
  1564. X
  1565. X    return (max(absdx,absdy));
  1566. X}
  1567. END_OF_FILE
  1568. if test 10474 -ne `wc -c <'src/mthrowu.c'`; then
  1569.     echo shar: \"'src/mthrowu.c'\" unpacked with wrong size!
  1570. fi
  1571. # end of 'src/mthrowu.c'
  1572. fi
  1573. if test -f 'src/spell.c' -a "${1}" != "-c" ; then 
  1574.   echo shar: Will not clobber existing file \"'src/spell.c'\"
  1575. else
  1576. echo shar: Extracting \"'src/spell.c'\" \(10739 characters\)
  1577. sed "s/^X//" >'src/spell.c' <<'END_OF_FILE'
  1578. X/*    SCCS Id: @(#)spell.c    3.0    88/09/18
  1579. X *
  1580. X *    Copyright (c) M. Stepheneon 1988
  1581. X */
  1582. X/* NetHack may be freely redistributed.  See license for details. */
  1583. X
  1584. X#include "hack.h"
  1585. X#ifdef SPELLS
  1586. Xstatic schar delay;        /* moves left for this spell */
  1587. Xstatic struct obj *book;    /* last/current book being xscribed */
  1588. X
  1589. X#ifdef HARD
  1590. X#define spelluses(spell)    spl_book[spell-1].sp_uses
  1591. X#define decrnuses(spell)    spl_book[spell-1].sp_uses--
  1592. X#endif /* HARD */
  1593. X#define spellev(spell)        spl_book[spell-1].sp_lev
  1594. X#define spellname(spell)    objects[spl_book[spell-1].sp_id].oc_name
  1595. X#define spellid(spell)        spl_book[spell-1].sp_id
  1596. X
  1597. Xstatic void
  1598. Xcursed_book(level)
  1599. X    register int    level;
  1600. X{
  1601. X    switch(rn2(level)) {
  1602. X    case 0:
  1603. X        You("feel a wrenching sensation.");
  1604. X        tele();        /* teleport him */
  1605. X        break;
  1606. X    case 1:
  1607. X        You("feel threatened.");
  1608. X        aggravate();
  1609. X        break;
  1610. X    case 2:
  1611. X        make_blinded(Blinded + rn1(100,250),TRUE);
  1612. X        break;
  1613. X    case 3:
  1614. X        take_gold();
  1615. X        break;
  1616. X    case 4:
  1617. X        pline("These runes were just too much to comprehend.");
  1618. X        make_confused(HConfusion + rn1(7,16),FALSE);
  1619. X        break;
  1620. X    case 5:
  1621. X        pline("The book was coated with contact poison!");
  1622. X        if (uarmg) {
  1623. X            if (uarmg->rustfree)
  1624. X            Your("gloves seem unaffected.");
  1625. X            else if (uarmg->spe > -6) {
  1626. X            Your("gloves corrode!");
  1627. X            uarmg->spe--;
  1628. X            } else
  1629. X            Your("gloves look quite corroded.");
  1630. X            break;
  1631. X        }
  1632. X        if(Poison_resistance) {
  1633. X            losestr(rn1(1,2));
  1634. X            losehp(rnd(6), "contact poison");
  1635. X        } else {
  1636. X            losestr(rn1(4,3));
  1637. X            losehp(rnd(10), "contact poison");
  1638. X        }
  1639. X        break;
  1640. X    case 6:
  1641. X        if(Antimagic) {
  1642. X            shieldeff(u.ux, u.uy);
  1643. X            pline("The book explodes, but you are unharmed!");
  1644. X        } else {
  1645. X            pline("As you read the book, it explodes in your %s!",
  1646. X            body_part(FACE));
  1647. X            losehp (2*rnd(10)+5, "exploding rune");
  1648. X        }
  1649. X        break;
  1650. X    default:
  1651. X        rndcurse();
  1652. X        break;
  1653. X    }
  1654. X    return;
  1655. X}
  1656. X
  1657. Xstatic int
  1658. Xlearn()
  1659. X{
  1660. X    register int    i;
  1661. X    register unsigned booktype;
  1662. X
  1663. X    if (delay) {    /* not if (delay++), so at end delay == 0 */
  1664. X        delay++;
  1665. X        return(1); /* still busy */
  1666. X    }
  1667. X
  1668. X    booktype = book->otyp;
  1669. X    for (i = 0; i < MAXSPELL; i++)  {
  1670. X        if (spl_book[i].sp_id == booktype)  {
  1671. X#ifdef HARD
  1672. X            Your("knowledge of that spell is keener.");
  1673. X            spl_book[i].sp_uses += rn1(3,8-spl_book[i].sp_lev);
  1674. X#else
  1675. X            pline("Oh, you already know that one!");
  1676. X#endif
  1677. X            break;
  1678. X        } else if (spl_book[i].sp_id == NO_SPELL)  {
  1679. X            spl_book[i].sp_id = booktype;
  1680. X            spl_book[i].sp_lev = objects[booktype].spl_lev;
  1681. X            spl_book[i].sp_flags = objects[booktype].bits;
  1682. X#ifdef HARD
  1683. X            /* spells have 2 .. 10-level uses. */
  1684. X            /* ie 2 or 3 uses w/ most potent */
  1685. X            spl_book[i].sp_uses = rn1(3,8-spl_book[i].sp_lev);
  1686. X#endif
  1687. X            You("add the spell to your repertoire.");
  1688. X            makeknown(booktype);
  1689. X            break;
  1690. X        }
  1691. X    }
  1692. X    if (i == MAXSPELL) impossible("Too many spells memorized!");
  1693. X
  1694. X    if (book->cursed) {    /* maybe a demon cursed it */
  1695. X        cursed_book(objects[booktype].spl_lev);
  1696. X    }
  1697. X
  1698. X    useup(book);
  1699. X    book = 0;
  1700. X    return(0);
  1701. X}
  1702. X
  1703. Xint
  1704. Xstudy_book(spellbook)
  1705. Xregister struct obj *spellbook;
  1706. X{
  1707. X    register int     booktype = spellbook->otyp;
  1708. X    register boolean oops      = !spellbook->blessed && (spellbook->cursed ||
  1709. Xrn2(20) > (ACURR(A_INT) + 4 + (int)(u.ulevel/2) - 2*objects[booktype].spl_lev));
  1710. X
  1711. X    if (delay && spellbook == book)
  1712. X        You("continue your efforts to memorize the spell.");
  1713. X    else {
  1714. X        switch(booktype)  {
  1715. X
  1716. X/* level 1 spells */
  1717. X    case SPE_HEALING:
  1718. X    case SPE_DETECT_MONSTERS:
  1719. X    case SPE_FORCE_BOLT:
  1720. X    case SPE_LIGHT:
  1721. X    case SPE_SLEEP:
  1722. X    case SPE_KNOCK:
  1723. X/* level 2 spells */
  1724. X    case SPE_MAGIC_MISSILE:
  1725. X    case SPE_CONFUSE_MONSTER:
  1726. X    case SPE_SLOW_MONSTER:
  1727. X    case SPE_CURE_BLINDNESS:
  1728. X    case SPE_CREATE_MONSTER:
  1729. X    case SPE_DETECT_FOOD:
  1730. X    case SPE_WIZARD_LOCK:
  1731. X        delay = -objects[booktype].oc_delay;
  1732. X        break;
  1733. X/* level 3 spells */
  1734. X    case SPE_HASTE_SELF:
  1735. X    case SPE_CAUSE_FEAR:
  1736. X    case SPE_CURE_SICKNESS:
  1737. X    case SPE_DETECT_UNSEEN:
  1738. X    case SPE_EXTRA_HEALING:
  1739. X    case SPE_CHARM_MONSTER:
  1740. X    case SPE_CLAIRVOYANCE:
  1741. X/* level 4 spells */
  1742. X    case SPE_LEVITATION:
  1743. X    case SPE_RESTORE_ABILITY:
  1744. X    case SPE_INVISIBILITY:
  1745. X    case SPE_FIREBALL:
  1746. X    case SPE_DETECT_TREASURE:
  1747. X        delay = -(objects[booktype].spl_lev - 1) * objects[booktype].oc_delay;
  1748. X        break;
  1749. X/* level 5 spells */
  1750. X    case SPE_REMOVE_CURSE:
  1751. X    case SPE_MAGIC_MAPPING:
  1752. X    case SPE_CONE_OF_COLD:
  1753. X    case SPE_IDENTIFY:
  1754. X    case SPE_DIG:
  1755. X/* level 6 spells */
  1756. X    case SPE_TURN_UNDEAD:
  1757. X    case SPE_POLYMORPH:
  1758. X    case SPE_CREATE_FAMILIAR:
  1759. X    case SPE_TELEPORT_AWAY:
  1760. X        delay = -objects[booktype].spl_lev * objects[booktype].oc_delay;
  1761. X        break;
  1762. X/* level 7 spells */
  1763. X    case SPE_CANCELLATION:
  1764. X    case SPE_FINGER_OF_DEATH:
  1765. X    case SPE_GENOCIDE:
  1766. X        delay = -8 * objects[booktype].oc_delay;
  1767. X        break;
  1768. X/* impossible */
  1769. X    default:
  1770. X        impossible("Unknown spellbook, %d;", booktype);
  1771. X        return(0);
  1772. X    }
  1773. X
  1774. X        if (oops) {
  1775. X            cursed_book(objects[booktype].spl_lev);
  1776. X            nomul(delay);            /* study time */
  1777. X            delay = 0;
  1778. X            useup(spellbook);
  1779. X            return(1);
  1780. X        }
  1781. X
  1782. X        You("begin to memorize the runes.");
  1783. X    }
  1784. X
  1785. X    book = spellbook;
  1786. X    set_occupation(learn, "studying", 0);
  1787. X    return(1);
  1788. X}
  1789. X
  1790. Xstatic int
  1791. Xgetspell()  {
  1792. X
  1793. X    register int    maxs, ilet, i;
  1794. X    char     lets[BUFSZ], buf[BUFSZ];
  1795. X
  1796. X    if (spl_book[0].sp_id == NO_SPELL)  {
  1797. X
  1798. X        You("don't know any spells right now.");
  1799. X        return(0);
  1800. X    } else  {
  1801. X
  1802. X        for(maxs = 1; (maxs < MAXSPELL) && (spl_book[maxs].sp_id != NO_SPELL); maxs++);
  1803. X        if (maxs >= MAXSPELL)  {
  1804. X
  1805. X        impossible("Too many spells memorized.");
  1806. X        return(0);
  1807. X        }
  1808. X
  1809. X        for(i = 0; (i < maxs) && (i < 26); buf[++i] = 0)  buf[i] = 'a' + i;
  1810. X        for(i = 26; (i < maxs) && (i < 52); buf[++i] = 0) buf[i] = 'A' + i - 26;
  1811. X
  1812. X        if (maxs == 1)  Strcpy(lets, "a");
  1813. X        else if (maxs < 27)  Sprintf(lets, "a-%c", 'a' + maxs - 1);
  1814. X        else if (maxs == 27)  Sprintf(lets, "a-z A");
  1815. X        else Sprintf(lets, "a-z A-%c", 'A' + maxs - 27);
  1816. X        for(;;)  {
  1817. X
  1818. X        pline("Cast which spell? [%s ?] ", lets);
  1819. X        if ((ilet = readchar()) == '?')  {
  1820. X            (void) dovspell();
  1821. X            continue;
  1822. X        } else if ((ilet == '\033')||(ilet == '\n')||(ilet == ' '))
  1823. X            return(0);
  1824. X        else for(i = 0; buf[i] != 0; i++)  if(ilet == buf[i])  return(++i);
  1825. X        You("don't know that spell.");
  1826. X        }
  1827. X    }
  1828. X}
  1829. X
  1830. Xint
  1831. Xdocast()
  1832. X{
  1833. X    register int     spell;
  1834. X
  1835. X    spell = getspell();
  1836. X    if (!spell) return(0);
  1837. X
  1838. X    return(spelleffects(spell,FALSE));
  1839. X}
  1840. X
  1841. Xint
  1842. Xspelleffects(spell,atme)
  1843. Xregister int spell;
  1844. Xboolean atme;
  1845. X{
  1846. X    register int energy, damage;
  1847. X#ifdef HARD
  1848. X    boolean confused = (Confusion != 0);
  1849. X#endif
  1850. X    struct obj *pseudo;
  1851. X
  1852. X#ifdef HARD
  1853. X    /* note that trying to cast it decrements the # of uses,    */
  1854. X    /* even if the mage does not have enough food/energy to use */
  1855. X    /* the spell */
  1856. X    switch (spelluses(spell)) {
  1857. X        case 0:
  1858. X            pline ("That spell is too hard to recall at the moment.");
  1859. X            return(0);
  1860. X        case 1:
  1861. X            pline ("You can barely remember the runes of this spell.");
  1862. X            break;
  1863. X        case 2:
  1864. X            pline ("This spell is starting to be over-used.");
  1865. X            break;
  1866. X        default:
  1867. X            break;
  1868. X    }
  1869. X    decrnuses(spell);
  1870. X#endif
  1871. X    energy = spellev(spell);
  1872. X    if (u.uhave_amulet) {
  1873. X        You("feel the amulet draining your energy away.");
  1874. X        energy *= rnd(6);
  1875. X    }
  1876. X    if(energy > u.uen)  {
  1877. X        You("are too weak to cast that spell.");
  1878. X        return(0);
  1879. X    } else    if ((u.uhunger <= 100 && spell != SPE_DETECT_FOOD) ||
  1880. X                        (ACURR(A_STR) < 6))  {
  1881. X        You("lack the strength for that spell.");
  1882. X        return(0);
  1883. X    } else    {
  1884. X        if (spell != SPE_DETECT_FOOD)
  1885. X            morehungry(energy * 10);
  1886. X        u.uen -= energy;
  1887. X    }
  1888. X    flags.botl = 1;
  1889. X
  1890. X#ifdef HARD
  1891. X    if (confused ||
  1892. X        ((int)(ACURR(A_INT) + u.uluck) - 3 * spellev(spell)) < 0) {
  1893. X
  1894. X        if (Hallucination)
  1895. X            pline("Far out... a light show!");
  1896. X        else    pline("The air around you crackles as you goof up.");
  1897. X        return(0);
  1898. X    }
  1899. X#endif
  1900. X
  1901. X/*    pseudo is a temporary "false" object containing the spell stats. */
  1902. X    pseudo = mksobj(spellid(spell),FALSE);
  1903. X    pseudo->blessed = pseudo->cursed = 0;
  1904. X    pseudo->quan = 20;            /* do not let useup get it */
  1905. X    switch(pseudo->otyp)  {
  1906. X
  1907. X/* These spells are all duplicates of wand effects */
  1908. X    case SPE_FORCE_BOLT:
  1909. X    case SPE_SLEEP:
  1910. X    case SPE_MAGIC_MISSILE:
  1911. X    case SPE_KNOCK:
  1912. X    case SPE_SLOW_MONSTER:
  1913. X    case SPE_WIZARD_LOCK:
  1914. X    case SPE_FIREBALL:
  1915. X    case SPE_CONE_OF_COLD:
  1916. X    case SPE_DIG:
  1917. X    case SPE_TURN_UNDEAD:
  1918. X    case SPE_POLYMORPH:
  1919. X    case SPE_TELEPORT_AWAY:
  1920. X    case SPE_CANCELLATION:
  1921. X    case SPE_FINGER_OF_DEATH:
  1922. X    case SPE_LIGHT:
  1923. X    case SPE_DETECT_UNSEEN:
  1924. X        if (!(objects[pseudo->otyp].bits & NODIR)) {
  1925. X            if (atme) u.dx = u.dy = u.dz = 0;
  1926. X            else (void) getdir(1);
  1927. X            if(!u.dx && !u.dy && !u.dz) {
  1928. X                if((damage = zapyourself(pseudo)))
  1929. X                losehp(damage, "self-inflicted injury");
  1930. X            } else    weffects(pseudo);
  1931. X        } else weffects(pseudo);
  1932. X        break;
  1933. X/* These are all duplicates of scroll effects */
  1934. X    case SPE_CONFUSE_MONSTER:
  1935. X    case SPE_DETECT_FOOD:
  1936. X    case SPE_CAUSE_FEAR:
  1937. X    case SPE_CHARM_MONSTER:
  1938. X    case SPE_REMOVE_CURSE:
  1939. X    case SPE_MAGIC_MAPPING:
  1940. X    case SPE_CREATE_MONSTER:
  1941. X    case SPE_IDENTIFY:
  1942. X    case SPE_GENOCIDE:
  1943. X        (void) seffects(pseudo);
  1944. X        break;
  1945. X    case SPE_HASTE_SELF:
  1946. X    case SPE_DETECT_TREASURE:
  1947. X    case SPE_DETECT_MONSTERS:
  1948. X    case SPE_LEVITATION:
  1949. X    case SPE_RESTORE_ABILITY:
  1950. X    case SPE_INVISIBILITY:
  1951. X        (void) peffects(pseudo);
  1952. X        break;
  1953. X    case SPE_HEALING:
  1954. X        You("feel a bit better.");
  1955. X        healup(rnd(8), 0, 0, 0);
  1956. X        break;
  1957. X    case SPE_CURE_BLINDNESS:
  1958. X        healup(0, 0, 0, 1);
  1959. X        break;
  1960. X    case SPE_CURE_SICKNESS:
  1961. X        You("are no longer ill.");
  1962. X        healup(0, 0, 1, 0);
  1963. X        break;
  1964. X    case SPE_EXTRA_HEALING:
  1965. X        You("feel a fair bit better.");
  1966. X        healup(d(2,8), 1, 0, 0);
  1967. X        break;
  1968. X    case SPE_CREATE_FAMILIAR:
  1969. X        make_familiar((struct obj *)0);
  1970. X        break;
  1971. X    case SPE_CLAIRVOYANCE:
  1972. X        do_vicinity_map();
  1973. X        break;
  1974. X    default:
  1975. X        impossible("Unknown spell %d attempted.", spell);
  1976. X        obfree(pseudo, (struct obj *)0);
  1977. X        return(0);
  1978. X    }
  1979. X    obfree(pseudo, (struct obj *)0);    /* now, get rid of it */
  1980. X    return(1);
  1981. X}
  1982. X
  1983. Xvoid
  1984. Xlosespells() {
  1985. X    register boolean confused = (Confusion != 0);
  1986. X    register int     n, nzap, i;
  1987. X
  1988. X    book = 0;
  1989. X    for(n = 0;(spl_book[n].sp_id != NO_SPELL) && (n < MAXSPELL); n++);
  1990. X    if (!n) return;
  1991. X    if (n < MAXSPELL) {
  1992. X        nzap = rnd(n);
  1993. X        if (nzap < n) nzap += confused;
  1994. X        for (i = 0; i < nzap; i++) spl_book[n-i-1].sp_id = NO_SPELL;
  1995. X    } else impossible("Too many spells memorized!");
  1996. X    return;
  1997. X}
  1998. X
  1999. Xstatic char
  2000. Xspellet(spl)
  2001. X{
  2002. X    return (spl < 27) ? ('a' + spl - 1) : ('A' + spl - 27);
  2003. X}
  2004. X
  2005. Xint
  2006. Xdovspell() {
  2007. X
  2008. X    register int maxs, i;
  2009. X    char     buf[BUFSZ], any[BUFSZ];
  2010. X
  2011. X    if (spl_book[0].sp_id == NO_SPELL)  {
  2012. X
  2013. X        You("don't know any spells right now.");
  2014. X        return 0;
  2015. X    }
  2016. X
  2017. X    for(maxs = 1; (maxs < MAXSPELL) && (spl_book[maxs].sp_id != NO_SPELL); maxs++);
  2018. X    if (maxs >= MAXSPELL)  {
  2019. X
  2020. X        impossible("Too many spells memorized.");
  2021. X        return 0;
  2022. X    }
  2023. X    morc = 0;        /* just to be sure */
  2024. X    cornline(0, "Currently known spells:");
  2025. X
  2026. X    for(i = 1; i <= maxs; i++) {
  2027. X
  2028. X#ifdef HARD
  2029. X        Sprintf(buf, "%c %c %s (%d)",
  2030. X            spellet(i), (spelluses(i)) ? '-' : '*',
  2031. X            spellname(i), spellev(i));
  2032. X#else
  2033. X        Sprintf(buf, "%c %s (%d)",
  2034. X            spellet(i),
  2035. X            spellname(i), spellev(i));
  2036. X#endif
  2037. X        cornline(1, buf);
  2038. X        any[i-1] = spellet(i);
  2039. X      }
  2040. X    any[i-1] = 0;
  2041. X    cornline(2, any);
  2042. X
  2043. X    return 0;
  2044. X}
  2045. X
  2046. X
  2047. X#endif /* SPELLS /**/
  2048. END_OF_FILE
  2049. if test 10739 -ne `wc -c <'src/spell.c'`; then
  2050.     echo shar: \"'src/spell.c'\" unpacked with wrong size!
  2051. fi
  2052. # end of 'src/spell.c'
  2053. fi
  2054. echo shar: End of archive 29 \(of 38\).
  2055. cp /dev/null ark29isdone
  2056. MISSING=""
  2057. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 ; do
  2058.     if test ! -f ark${I}isdone ; then
  2059.     MISSING="${MISSING} ${I}"
  2060.     fi
  2061. done
  2062. if test "${MISSING}" = "" ; then
  2063.     echo You have unpacked all 38 archives.
  2064.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2065. else
  2066.     echo You still need to unpack the following archives:
  2067.     echo "        " ${MISSING}
  2068. fi
  2069. ##  End of shell archive.
  2070. exit 0
  2071.