home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!news.tek.com!master!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v16i079: nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part71/108
- Message-ID: <4442@master.CNA.TEK.COM>
- Date: 5 Feb 93 19:19:36 GMT
- Sender: news@master.CNA.TEK.COM
- Lines: 2040
- Approved: billr@saab.CNA.TEK.COM
- Xref: uunet comp.sources.games:1630
-
- Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
- Posting-number: Volume 16, Issue 79
- Archive-name: nethack31/Part71
- Supersedes: nethack3p9: Volume 10, Issue 46-102
- Environment: Amiga, Atari, Mac, MS-DOS, OS2, Unix, VMS, X11
-
-
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 71 (of 108)."
- # Contents: doc/tmac.n src/mkmaze.c
- # Wrapped by billr@saab on Wed Jan 27 16:09:15 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'doc/tmac.n' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'doc/tmac.n'\"
- else
- echo shar: Extracting \"'doc/tmac.n'\" \(25079 characters\)
- sed "s/^X//" >'doc/tmac.n' <<'END_OF_FILE'
- X\" @(#)$Id: tmac.n,v 3.0 89/06/21 21:44:28 syd Exp $
- X.\" The News macro package
- X.\"
- X.\" This is the macro package that is used to format news documents. It
- X.\" was written because many sites do not have one of the -mm or -ms pack-
- X.\" ages that the documents use. This is NOT compatible with EITHER, but
- X.\" (I hope) will become the standard for all news documents (man pages
- X.\" excepted, since everyone seems to have -man.)
- X.\"
- X.\" This package was written using only the "NROFF/TROFF Users' Guide",
- X.\" and therefore if you can run NROFF/TROFF, you can legitimately use
- X.\" this package. However, because NROFF/TROFF are proprietary programs,
- X.\" I cannot place this package in the public domain. This should not
- X.\" matter, because if you legitimately have NROFF/TROFF, you have the
- X.\" documentation; if not, you can't run off the documentation anyway.
- X.\"
- X.\" This package may be circulated freely with the news documentation; it
- X.\" may not be sold, but is to be distributed with the unformatted news
- X.\" documents. However, the name of the author and the place at which it
- X.\" was written (in the author's own time, of course) are not to be
- X.\" removed from the package regardless of how it is modified or altered.
- X.\" Further, please do not distribute this package if you make any changes
- X.\" because I don't want to get bug reports of macros I haven't written;
- X.\" if you have a goodie you want me to add, send it to me and we'll talk.
- X.\" (I really do like feedback!) I'd really appreciate your cooperation.
- X.\"
- X.\" Author: Matt Bishop
- X.\" Research Institute for Advanced Computer Science
- X.\" Mail Stop 230-5
- X.\" NASA Ames Research Center
- X.\" Moffett Field, CA 94035
- X.\"
- X.\" version 1.0 September 28, 1985 mab@riacs.arpa
- X.\" initial version
- X.\" version 1.1 October 25, 1985 mab@riacs.arpa
- X.\" fixed an incredibly obscure footnote bug (that occurred twice in
- X.\" the news documentation!) which put footnoted words on one page
- X.\" and the footnote on the next if the word was in the next-to-last
- X.\" or last line; commented it, and generally cleaned up
- X.\" Version 1.2 October 27, 1985 mab@riacs.arpa
- X.\" Added a few more comments and a check to keep footnotes lined up
- X.\" with the bottom margin.
- X.\" Version 1.3 February 12, 1986 mab@riacs.arpa
- X.\" Added an error check to catch unmatched ef's and ed's
- X.\" Version 1.4 December 29, 1986 mab@riacs.edu
- X.\" Changed footnote for ux, pd, and vx macros and added a string
- X.\" for rg ("Registered Trademark")
- X.\" Version 1.5 January 2, 1989 Matt.Bishop@dartmouth.edu
- X.\" Minor modifications for nroff compatibility
- X.\" Version 1.6 March 15, 1989 Matt.Bishop@dartmouth.edu
- X.\" ..!bear.dartmouth.edu!bishop
- X.\" Fixed a bug in footnote handling (again, sigh ...) This one
- X.\" occurred when the the "fo" trap position was reset just beneath
- X.\" the current line; the footnote overflow trap would kick in and
- X.\" never be closed.
- X.\"
- X.\"
- X.\" **********
- X.\" these preserve and restore various things
- X.\" they are used to shorten other macros
- X.de yf \" restore fonts
- X.ft \\n(f2 \" previous font
- X.ft \\n(f1 \" current font
- X..
- X.de yi \" restore indents
- X'in \\n(i2u \" previous indent
- X'in \\n(i1u \" current indent
- X..
- X.de ys \" restore point sizes
- X.ps \\n(s2 \" previous point size
- X.ps \\n(s1 \" current point size
- X..
- X.de yv \" restore vertical spacings
- X.vs \\n(v2u \" previous vertical spacing
- X.vs \\n(v1u \" current vertical spacing
- X..
- X.de ya \" restore everything
- X.yf \" restore fonts
- X.yi \" restore indents
- X.ys \" restore point sizes
- X.yv \" restore vertical spacing
- X..
- X.de zf \" preserve fonts
- X.nr f1 \\n(.f \" current font
- X.ft \" switch to previous font
- X.nr f2 \\n(.f \" previous font
- X.ft \" back to current font
- X..
- X.de zi \" preserve indents
- X.nr i1 \\n(.iu \" current indent
- X'in \" switch to previous indent
- X.nr i2 \\n(.iu \" previous indent
- X'in \" back to current indent
- X..
- X.de zs \" preserve point sizes
- X.nr s1 \\n(.su \" current point size
- X.ps \" switch to previous point size
- X.nr s2 \\n(.su \" previous point size
- X.ps \" back to current point size
- X..
- X.de zv \" preserve vertical spacings
- X.nr v1 \\n(.vu \" current vertical spacing
- X.vs \" switch to previous vertical spacing
- X.nr v2 \\n(.vu \" previous vertical spacing
- X.vs \" back to current vertical spacing
- X..
- X.de za \" save everything
- X.zf \" save fonts
- X.zi \" save indents
- X.zs \" save point sizes
- X.zv \" save vertical spacings
- X..
- X.\" **********
- X.\" these actually print the header and footer titles
- X.\" they are defined separately from the "hd" and "fo" macros
- X.\" to make user redefinition easy
- X.de pt \" print header title
- X. \" omit header on first page
- X.if \\n%>1 \{\
- X' sp |\\$1u \" move to proper position
- X. ft 1 \" change to default font
- X. ps \\n(ps \" change to default point size
- X. vs \\n(vs \" change to default spacing
- X. tl '\\*(h0'\\*(h1'\\*(h2' \" center title
- X. vs \" restore current vertical spacing
- X. ps \" restore current point size
- X. ft \" restore current font
- X.\}
- X..
- X.de pf \" print footer title
- X.ft 1 \" change to default font
- X.ps \\n(ps \" change to default point size
- X.vs \\n(vs \" change to default spacing
- X.ie \\n%=1 .tl '\\*(h0'\\*(h1'\\*(h2' \" on first page, print the header here
- X.el .tl '\\*(f0'\\*(f1'\\*(f2' \" on other pages, print the footer
- X.vs \" restore current vertical spacing
- X.ps \" restore current point size
- X.ft \" restore current font
- X..
- X.\" **********
- X.\" these are the top of page (header) and bottom of page (footer) macros
- X.\" they don't actually print anything, just call the right macros
- X.de hd \" header -- do top of page processing
- X.if t .if \\n(cm .tl '\(rn''' \" drop cut mark if needed
- X.pt \\n(ttu \" print header
- X.nr fc 0 1 \" init footnote count
- X.nr fs \\n(.pu-\\n(bmu-1u \" if any footnotes, start print here
- X.nr fp 0-\\n(bmu \" reset current footer place
- X.ch fo -\\n(bmu \" reset footer trap
- X.if \\n(dn .fz \" put leftover footnotes st bottom
- X.ya \" restore font, etc.
- X'sp |\\n(tmu \" move to top of body
- X.ns \" don't allow any more space
- X..
- X.de fo \" footer -- do bottom of page processing
- X.za \" save font, etc.
- X.rs \" you want motions here
- X.nr dn 0 \" clobber diversion size register
- X.if \\n(fc .fd \" now print the footnotes, if any
- X'bp \" force out page
- X..
- X.\" **********
- X.\" these are the footnote macros
- X.\" here's an overview:
- X.\" Footnotes are processed in environment #1, which is initialized
- X.\" at the bottom of this package. When "fn" is called, nroff/troff
- X.\" switches to this environment. The body of the footnote is saved
- X.\" in the diversion "tf" (for "temporary footnote"), so you will
- X.\" NEVER spring a trap during the first reading of a footnote. When
- X.\" "ef" ("end footnote") is called, the diversion is closed. If
- X.\" this is the first footnote on the page (ie, the number register
- X.\" "fc" is 1), and the footnote height (plus the height of 1 line)
- X.\" crosses the bottom margin, you get the footnoted word on one
- X.\" page and the footnote on the other. In this case we just call
- X.\" "fo" manually (taking case it cannot be re-invoked on the same
- X.\" page!) If this situation does not occur, we just adjust the
- X.\" footer trap's position upwards (we'll get to how far in a min-
- X.\" ute); if this puts the trap above the current line, we reposi-
- X.\" tion the trap just beneath the current line to be sure of trig-
- X.\" triggering it once the current line is forced out.
- X.\" To reposition the footer trap, we proceed as follows. Because
- X.\" the trap may be sprung in the middle of a line, it is possible
- X.\" that the footnote will not fit on the page (regardless of where
- X.\" on the page the footnoted word occurs -- really!) if we move the
- X.\" trap up by the size of the footnote diversion "tf". So, we
- X.\" fudge things a little bit -- for the first footnote on each page
- X.\" we move the footer trap up 1 extra line ("line" being 1v in env-
- X.\" ironment #0). Unless the point size and vertical spacing are
- X.\" increased between the first footnote and the footer trap's being
- X.\" sprung, this will keep the footnotes on the same page as the
- X.\" footnoted word. But as there may be now as much as 1v of space
- X.\" between the footnote and the bottom margin, which looks HIDEOUS,
- X.\" we use the number register "fs" to mark where the footer trap
- X.\" would REALLY go, and just space to it when it comes time to put
- X.\" out the footnotes.
- X.de fd \" dump footnotes
- X.nr gs 1v \" get a measure of 1 line in env #0
- X.ev 1 \" switch to footnote environment
- X.nr gs +2v \" min of 2 lines of footnotes
- X. \" if the number register ns > 0,
- X. \" the last text line may contain a
- X. \" footnote that is too big to fit;
- X. \" this checks for such a note and
- X. \" if so, forces the footnote into
- X. \" the "fy" diversion that carries
- X. \" it onto the next text page
- X.ie (\\n(nsu>0)&(\\n(gsu>=\\n(.tu) 'sp \\n(gsu \" be sure you can get it down
- X.el .if \\n(fsu>\\n(nlu 'sp \\n(fsu-\\n(nlu \" move to footnote start position
- X'nf \" don't reprocess footnotes
- X'in 0 \" don't indent them any more either
- X.tf \" drop text of footnotes
- X.rm tf
- X.if '\\n(.z'fy' .di \" end overflow diversion, if any
- X.nr fc 0 \" re-init footnote count
- X.ev \" return to usual environment
- X..
- X.de fn \" start footnote
- X. \" look for nested footnotes -- ILLEGAL
- X.ie \\n(if>0 .er "footnote within footnote"
- X.el .da tf \" append footnote to footnote diversion
- X.nr if +1 \" increment level of footnoting
- X.nr fc +1 \" one more footnote on this page
- X.if \\n(fc=1 .nr fp -1v \" The reason for this "fudge factor"
- X. \" is that there is no way to force
- X. \" NROFF/TROFF to invoke a macro at
- X. \" the end of each line. At times,
- X. \" the trap boundary will not match up
- X. \" with the bottom of a line, so the
- X. \" "fo" trap which is set at 2320 may
- X. \" not be triggered until 2340 -- and
- X. \" then the footnote won't fit. This
- X. \" gives some slack so the footnote is
- X. \" more likely to fit. *sigh*
- X.ev 1 \" enter footnote environment
- X.if \\n(fc=1 .fs \" drop separator if first footnote
- X.br \" flush out any previous line in footnote
- X.fi \" process footnote in fill mode
- X..
- X.de ef \" end footnote
- X.br \" flush out the line in footnote
- X.ie \\n(if<=0 .er "end footnote has no corresponding begin footnote"
- X.el \{\
- X. nr if -1 \" decrement level of footnoting
- X. nr fg 2v \" remember this for repositioning fo
- X. ev \" back to usual environment
- X. if \\n(if=0 \{\
- X. di \" end of footnote proper
- X. nr fp -\\n(dnu \" "fo" will be moved at least up this far
- X. nr fs -\\n(dnu \" increase size of footnote
- X. ch fo \\n(fpu \" reposition "fo" trap (first guess)
- X. \" the first part of the "ie" clause
- X. \" is taken in the special case
- X. \" described above
- X. ie (\\n(fc=1)&((\\n(nlu+1v+\\n(fgu)>=(\\n(.pu-\\n(bmu)) \{\
- X. nr ns \\n(dnu \" suppress footnote separator
- X. \" since this footnote contains it
- X. \" keep "fo" from being invoked twice
- X. ch fo \\n(.pu+1i
- X. fo \" force the page out AT ONCE
- X. nr ns 0 \" re-enable footnote separator
- X. \}
- X. \" footnote won't fit completely
- X. \" invoke the footer trap but
- X. \" don't worry about the footnote
- X. \" separator (it's already there)
- X. el .if (\\n(nlu+1v)>=(\\n(.pu+\\n(fpu) \{\
- X. \" as before we must reposition the
- X. \" "fo" trap to prevent "fo" from
- X. \" being invoked twice
- X. ch fo \\n(.pu+1i
- X. fo \" force the page out AT ONCE
- X. \}
- X. \}
- X.\}
- X..
- X.de fs \" drop footnote separator
- X. \" only if not already dropped
- X.if \\n(ns=0 \l'1i'
- X.nr ns 0 \" in case footnotes are over 1 page long
- X..
- X.de fx \" process footnote overflow
- X.if \\n(fc .di fy \" stuff them in the right place
- X..
- X.de fz \" deposit footnote overflow
- X.fn \" treat it as a footnote
- X.nf \" it's already been processed
- X.in 0 \" and indented
- X.fy \" "fx" put it here
- X.ef \" end the footnote
- X..
- X.\" **********
- X.\" the ones after here are user-invoked (like "fn" and "ef" above)
- X.\" title, author, etc.
- X.de mt \" main title
- X\&
- X.sp |\\n(mtu \" space
- X.ft 3 \" in bold
- X.ps \\n(ps+2p \" large point size and
- X.vs \\n(vs+2p \" vertical spacing
- X.ce 1000 \" center the title
- X.nr t2 1 \" space it
- X..
- X.de au \" author
- X.nr t2 0 \" spacing here
- X.sp 2v \" space
- X.ft 2 \" in italics
- X.ps \\n(ps \" usual point size and
- X.vs \\n(vs \" vertical spacing
- X.ce 1000 \" center the name(s)
- X..
- X.de ai \" author's institution
- X.if \\n(t2 .sp 2v \" space after a title
- X.nr t2 0 \" institution
- X.ft 2 \" in italics
- X.ps \\n(ps \" usual point size and
- X.vs \\n(vs \" vertical spacing
- X.ce 1000 \" center the name(s)
- X..
- X.de bt \" begin text macro
- X.nr t2 0 \" hold it here
- X.nr it +1 \" mark as called
- X.ce 0 \" end any centering
- X.sn 3v \" a little bit of space
- X..
- X.\" paragraph
- X.de si \" start indented section
- X.nr lo \\n(lm \" remember the current level
- X.nr lm +1 \" go to the next level
- X.ie '\\$1'' .nr l\\n(lm \\n(l\\n(lo+5n \" if no arg, indent 5n
- X.el .nr l\\n(lm \\$1n \" otherwise, indent that much
- X..
- X.de ei \" end indent
- X.nr lm -1 \" down one level
- X.if \\n(lm<0 .nr lm 0 \" make sure you don't go too far
- X..
- X.de pg \" plain old paragraph
- X.if !\\n(it .bt \" end the title and such
- X.sn \\n(pdu \" inter-paragraph spacing
- X.ft 1 \" reset a few things (paranoia)
- X. \" these ONLY if not in footnote
- X.ie \\n(if=0 \{\
- X. ps \\n(ps \" reset point size
- X. vs \\n(vs \" reset vertical spacing
- X. ne 1v+\\n(.Vu \" slightly more than 1 line
- X.\}
- X.el \{\
- X. ps \\n(ps-2p \" reset point size
- X. vs \\n(vs-2p \" reset vertical spacing
- X.\}
- X.in \\n(l\\n(lmu \" stop any indenting
- X.ce 0 \" stop any centering
- X.if !'\\$1'L' .if !'\\$1'l' .ti +\\n(piu \" indent the sucker
- X..
- X.de lp \" labelled paragraph
- X.pg l \" reset paragraph
- X.if \\n(.$>1 .nr li \\$2n \" if indent given use it
- X.in +\\n(liu \" indent for paragraph
- X.ti -\\n(liu \" force first line NOT to indent
- X.ta +\\n(liu \" for the label
- X\&\\$1\t\c
- X.if \\w'\\$1'u>=(\\n(l\\n(lmu+\\n(liu) .br \" don't overwrite
- X..
- X.\" The following two macros (hu & hn) have been modified for ELM usage.
- X.\" If the macros have text as part of the macro call, the text will be
- X.\" increased in size by two points. After printing the text, the font
- X.\" will be returned to normal, otherwise the font will be left bold.
- X.\"
- X.\" section
- X.de hu \" header, unnumbered
- X. \" format: .hu [text]
- X.if !\\n(it .bt \" end the title and such
- X.br \" force out previous line
- X.b
- X.ie \\n(hP .ps \\n(hP
- X.el .ps \\n(ps
- X.ie \\n(hv .vs \\n(hv
- X.el .vs \\n(vs
- X.in \\n(l\\n(lmu \" stop any indenting
- X.sn \\n(hsu \" inter-section spacing
- X.ne 3v+\\n(.Vu \" slightly more than 3 lines
- X.fi \" process the text, too
- X.if \\n(.$>=1 \{\
- X.ps +2
- X\\$1
- X.\}
- X.if \\n(.$>=2 \\$2
- X.if \\n(.$>=3 \\$3
- X.if \\n(.$>=4 \\$4
- X.if \\n(.$>=5 \\$5
- X.if \\n(.$>=6 \\$6
- X.if \\n(.$>=7 \\$7
- X.if \\n(.$>=8 \\$8
- X.if \\n(.$=9 \\$9
- X.if \\n(.$>=1 \{\
- X.ps -2
- X.br
- X.ft 1
- X.\}
- X..
- X.de hn \" header, numbered
- X. \" format: .hn [level] [text]
- X.if !\\n(it .bt \" end the title and such
- X.br \" force out previous line
- X.b
- X.ie \\n(hP .ps \\n(hP
- X.el .ps \\n(ps
- X.ie \\n(hv .vs \\n(hv
- X.el .vs \\n(vs
- X.in \\n(l\\n(lmu \" stop any indenting
- X.sn \\n(hsu \" inter-section spacing
- X.ne 3v+\\n(.Vu \" slightly more than 3 lines
- X.fi \" process the text, too
- X.ie !'\\$1'' .nr hn \\$1
- X.el .nr hn 1
- X.ie \\n(hn>0 .nr hn -1
- X.el .nr hn 0
- X.ie \\n(hn=0 \{\
- X. nr h0 +1 \" add 1 to main section header
- X. nr h1 0 \" zap remaining section numbers
- X. nr h2 0 \" zap remaining section numbers
- X. nr h3 0 \" zap remaining section numbers
- X.ie \\n(.$>=2 \{\
- X.ps +2
- X\\n(h0.
- X.ps -2
- X.\}
- X.el \\n(h0.
- X.\}
- X.el .ie \\n(hn=1 \{\
- X. nr h1 +1 \" add 1 to the section header
- X. nr h2 0 \" zap remaining section numbers
- X. nr h3 0 \" zap remaining section numbers
- X.ie \\n(.$>=2 \{\
- X.ps +2
- X\\n(h0.\\n(h1.
- X.ps -2
- X.\}
- X.el \\n(h0.\\n(h1.
- X.\}
- X.el .ie \\n(hn=2 \{\
- X. nr h2 +1 \" add 1 to the section header
- X. nr h3 0 \" zap remaining section numbers
- X.ie \\n(.$>=2 \{\
- X.ps +2
- X\\n(h0.\\n(h1.\\n(h2.
- X.ps -2
- X.\}
- X.el \\n(h0.\\n(h1.\\n(h2.
- X.\}
- X.el \{\
- X. nr h3 +1 \" add 1 to the section number
- X.ie \\n(.$>=2 \{\
- X.ps +2
- X\\n(h0.\\n(h1.\\n(h2.\\n(h3.
- X.ps -2
- X.\}
- X.el \\n(h0.\\n(h1.\\n(h2.\\n(h3.
- X.\}
- X.if \\n(.$>=2 \{\
- X.ps +2
- X\\$2
- X.\}
- X.if \\n(.$>=3 \\$3
- X.if \\n(.$>=4 \\$4
- X.if \\n(.$>=5 \\$5
- X.if \\n(.$>=6 \\$6
- X.if \\n(.$>=7 \\$7
- X.if \\n(.$>=8 \\$8
- X.if \\n(.$>=9 \\$9
- X.if \\n(.$>=2 \{\
- X.br
- X.ft 1
- X.ps -2
- X.\}
- X..
- X.\" displays (no floats, thank God!)
- X.de sd \" start display
- X. \" look for nested displays -- ILLEGAL
- X.ie \\n(id>0 .er "display within display"
- X.el \{\
- X. ie '\\$1'c' .nr sf 1 \" center the sucker
- X. el .nr sf 0 \" don't center it
- X.\}
- X.sn \\n(pdu \" a little bit of space
- X.ev 2 \" switch to display environment
- X.nf \" what you type is what you get
- X.if \\n(id=0 .di dd \" start saving text
- X.rs \" don't eat leading space
- X.nr id +1 \" increment level of display
- X..
- X.de ed \" end display
- X.br \" flush line
- X.ie \\n(id<=0 .er "end display has no corresponding begin display"
- X.el \{\
- X. nr id -1 \" decrement level of display
- X. if \\n(id=0 \{\
- X. di \" end diversion
- X. fi \" resume filling
- X. in -\\n(piu \" dedent
- X. ev \" pop environment
- X. ne \\n(dnu \" be sure you have room
- X. nf \" don't reprocess display
- X. rs \" don't eat leading space
- X. zi \" save indents
- X. ie \\n(sf .in (\\n(llu-\\n(dlu)/2u \" center on the line length
- X. el .in +\\n(piu \" indent the sucker
- X. dd \" drop display
- X. yi \" restore indents
- X. \}
- X.\}
- X.fi \" resume filling
- X.sn \\n(pdu \" a little bit of space
- X..
- X.\" **********
- X.\" fonts -- if argument(s), apply only to first
- X.de b \" bold (font 3)
- X.ie \\n(.$>0 \\&\\$3\\f3\\$1\\fP\\$2
- X.el .ft 3
- X..
- X.de i \" italics (font 2)
- X.ie \\n(.$>0 \\&\\$3\\f2\\$1\\fP\\$2
- X.el .ft 2
- X..
- X.de r \" roman (font 1)
- X.ft 1 \" just restore it
- X..
- X.de bi \" bold italics (embolden font 2)
- X\\&\\$3\c
- X\\kb\\f2\\$1\\fP\\h'|\\nbu+2u'\\f2\\$1\\fP\\$2
- X..
- X.\" **********
- X.\" point sizes -- if argument(s), apply only to first
- X.de sm \" reduce point size by 2
- X.ie \\n(.$>0 \\&\\$3\\s-2\\$1\\s0\\$2
- X.el .ps -2
- X..
- X.de is \" increase point size by 2
- X.ie \\n(.$>0 \\&\\$3\\s+2\\$1\\s0\\$2
- X.el .ps +2
- X..
- X.de nl \" return to normal size
- X.ps \\n(ps \" just reset the point size
- X..
- X.\" **********
- X.\" handy force space/inhibit more space macros
- X.de sn \" space, then turn on nospace mode
- X.sp \\$1 \" space
- X.ns \" ignore any more space requests
- X..
- X.de sr \" force out space
- X.rs \" turn on spacing mode
- X.sp \\$1 \" space
- X..
- X.\" **********
- X.\" end of text and error macros
- X.de et \" end of text macro
- X. \" this: (1) flushes rest of line
- X. \" (2) trips the footer, taking
- X. \" care of footnotes
- X.sp \\n(.pu
- X. \" check for open displays or footnotes
- X.if \\n(id>0 .er "unfinished display"
- X.if \\n(if>0 .er "unfinished footnote"
- X. \" this one means an -mn bug (*sigh*)
- X.if !'\\n(.z'' .er "diversion \\n(.z not closed"
- X..
- X.de er \" print error message
- X. \" flag it as an error
- X.ds ws "** ERROR **
- X. \" if you have it, give the file name
- X.if !'\\*(.f'' .as ws " file \\*(.f,
- X. \" put out the line number
- X.as ws " line \\n(.c
- X. \" and finally the error message
- X.tm \\*(ws: \\$1
- X..
- X.\" **********
- X.\" macros in this section are VERY specific to the news documentation
- X.de pa \" protocol appellation (darn names!)
- X\\&\\$3\\f2\\$1\\fP\\$2
- X..
- X.de ng \" news group name
- X\\&\\$3\\f3\\$1\\fP\\$2
- X..
- X.de cn \" computer name
- X\\&\\$3\\f2\\$1\\fP\\$2
- X..
- X.de hf \" header field
- X\\&\\$3\\*(lq\\$1\\*(rq\\$2
- X..
- X.de cf \" contents of field
- X\\&\\$3\\*(lq\\$1\\*(rq\\$2
- X..
- X.de qc \" quote control char (command)
- X\\&\\$3\\f3<\\s-2\\$1\\s0>\\fP\\$2
- X..
- X.de qp \" quote printing char (command)
- X\\&\\$3\\f3\\$1\\fP\\$2
- X..
- X.de op \" option
- X\\&\\$3\\f3\\$1\\fP\\$2
- X..
- X.\" **********
- X.\" trademarked names
- X.de pd \" print "PDP-11"
- X.ie \\n(p1 \\&\\$2\\s-1PDP\\s0-11\\$1
- X.el \{\
- X. nr p1 +1 \" mark footnote as dropped
- X\\&\\$2\\s-1PDP\\s0-11\\*(rg\\$1
- X. fn \" put out the footnote
- X\\&\\*(rgPDP-11 is a registered trademark of Digital Equipment Corporation.
- X. ef \" short and sweet ...
- X.\}
- X..
- X.de ux \" print "UNIX"
- X.ie \\n(ux \\&\\$2\\s-1UNIX\\s0\\$1
- X.el \{\
- X. nr ux +1 \" mark footnote as dropped
- X\\&\\$2\\s-1UNIX\\s0\\*(rg\\$1
- X. fn \" put out the footnote
- X\\&\\*(rgUNIX is a registered trademark of AT&T.
- X. ef \" short and sweet ...
- X.\}
- X..
- X.de vx \" print "VAX"
- X.ie \\n(vx \\&\\$2\\s-1VAX\\s0\\$1
- X.el \{\
- X. nr vx +1 \" mark footnote as dropped
- X\\&\\$2\\s-1VAX\\s0\\*(rg\\$1
- X. fn \" put out the footnote
- X\\&\\*(rgVAX is a trademark of Digital Equipment Corporation.
- X. ef \" short and sweet ...
- X.\}
- X..
- X.\" **********
- X.\" set up string and number registers
- X. \" set up for the date
- X.if \n(mo=1 .ds mo January
- X.if \n(mo=2 .ds mo February
- X.if \n(mo=3 .ds mo March
- X.if \n(mo=4 .ds mo April
- X.if \n(mo=5 .ds mo May
- X.if \n(mo=6 .ds mo June
- X.if \n(mo=7 .ds mo July
- X.if \n(mo=8 .ds mo August
- X.if \n(mo=9 .ds mo September
- X.if \n(mo=10 .ds mo October
- X.if \n(mo=11 .ds mo November
- X.if \n(mo=12 .ds mo December
- X.ds dy "\*(mo \n(dy, 19\n(yr
- X.if \n(dw=1 .ds dw Sunday
- X.if \n(dw=2 .ds dw Monday
- X.if \n(dw=3 .ds dw Tuesday
- X.if \n(dw=4 .ds dw Wednesday
- X.if \n(dw=5 .ds dw Thursday
- X.if \n(dw=6 .ds dw Friday
- X.if \n(dw=7 .ds dw Saturday
- X. \" NROFF dependencies
- X.if n \{\
- X. \" string registers
- X. ds rg (R)
- X. ds lq ""
- X. ds rq ""
- X. ds f1 "\*(dy
- X. \" number registers
- X. nr hs 1v \" space before section header
- X. nr pd 1v \" inter-paragraph spacing
- X. nr bm 1.0i \" height of bottom margin
- X.\}
- X. \" NROFF dependencies
- X.if t \{\
- X. \" string registers
- X. ds rg \\u\\s-2\\(rg\\s0\\d
- X. ds lq ``
- X. ds rq ''
- X. \" number registers
- X. nr hs 1v \" space before section header
- X. nr pd 0.3v \" inter-paragraph spacing
- X. nr bm 1.0i+1v \" height of bottom margin (wacky laser)
- X.\}
- X. \" these are the same for [NT]ROFF
- X.ds dg \(dg
- X.ds vr "News Version B2.11
- X.ds pv "News macros 1.5
- X.ds h1 - % -
- X.nr bt 0.5i+1v \" bottom of page to footer
- X.nr cm 0 \" no cut marks
- X.nr fc 0 1 \" init footnote count
- X.nr fl 5.5i \" footnote line length
- X.nr fp 0-\n(bmu \" fo macro trap location
- X.nr h0 0 \" init section header level 0
- X.nr h1 0 \" init section header level 1
- X.nr h2 0 \" init section header level 2
- X.nr h3 0 \" init section header level 3
- X.nr id 0 \" 1 in display
- X.nr if 0 \" 1 in keep
- X.nr it 0 \" 1 when beyond title, etc.
- X.nr li 5n \" indent for labelled paragraph
- X.nr ll 6.5i \" line length
- X.nr lm 0 \" left margin
- X.nr l0 0 \" first indent level
- X.nr mt 1.5i+1v \" title goes down this far
- X.nr pi 5n \" regular paragraph indent
- X.nr po 1.0i \" page offset
- X.nr ps 10 \" point size
- X.nr tm 1.0i \" height of top margin
- X.nr tt 0.5i-0.5v \" top of page to header
- X.nr p1 0 \" no PDP-TM message yet
- X.nr ux 0 \" no UNIX-TM message yet
- X.nr vx 0 \" no VAX-TM message yet
- X.nr vs 12 \" vertical spacing
- X.\" set things up
- X.\" DSINC changes for XROFF
- X.nr f1 1
- X.nr f2 1
- X.nr s1 10
- X.nr s2 10
- X.nr v1 12
- X.nr v2 12
- X.ps 10
- X.vs 12
- X.\" DSINC end changes for XROFF
- X.po \n(pou \" set page offset
- X.ps \n(ps \" set previous, current
- X.ps \n(ps \" point sizes
- X.vs \n(vs \" set previous, current
- X.vs \n(vs \" vertical spacings
- X.ll \n(llu \" set line length
- X.lt \n(llu \" set title line length
- X.ev 1 \" *** footnote environment
- X.ps \n(ps-2p \" set previous, current
- X.ps \n(ps-2p \" point sizes
- X.vs \n(vs-2p \" set previous, current
- X.vs \n(vs-2p \" vertical spacings
- X.ll \n(flu \" set line length
- X.lt \n(flu \" set title line length
- X.ev \" *** pop environment
- X.ev 2 \" *** footnote environment
- X.ps \n(ps \" set previous, current
- X.ps \n(ps \" point sizes
- X.vs \n(vs \" set previous, current
- X.vs \n(vs \" vertical spacings
- X.ll \n(llu \" set line length
- X.lt \n(llu \" set title line length
- X.ev \" *** pop environment
- X.\" now set internal registers (for the first header section)
- X.nr f1 \n(.f \" saved font #1
- X.nr f2 \n(.f \" saved font #2
- X.nr s1 \n(.s \" saved point size #1
- X.nr s2 \n(.s \" saved point size #2
- X.nr v1 \n(.v \" saved vertical spacing #1
- X.nr v2 \n(.v \" saved vertical spacing #2
- X.\" install traps
- X.wh 0i hd \" position header trap
- X.wh -\n(bmu fo \" position footer trap
- X.wh \n(.pu+1i fx \" put footnote overflow trap here
- X.ch fx -\n(bmu \" move it over fo
- X.wh -\n(btu pf \" print the bottom margin here
- X.em et \" at end of file, call et
- X.\" couple of miscellaneous requests
- X.bd S 3 3 \" embolden special font chars if B
- X.hy 2 \" don't hyphenate last lines
- X
- END_OF_FILE
- if test 25079 -ne `wc -c <'doc/tmac.n'`; then
- echo shar: \"'doc/tmac.n'\" unpacked with wrong size!
- fi
- # end of 'doc/tmac.n'
- fi
- if test -f 'src/mkmaze.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/mkmaze.c'\"
- else
- echo shar: Extracting \"'src/mkmaze.c'\" \(29353 characters\)
- sed "s/^X//" >'src/mkmaze.c' <<'END_OF_FILE'
- X/* SCCS Id: @(#)mkmaze.c 3.1 93/01/17 */
- X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
- X/* NetHack may be freely redistributed. See license for details. */
- X
- X#include "hack.h"
- X#include "sp_lev.h"
- X
- X#define UP 1
- X#define DOWN 0
- X
- X/* from sp_lev.c, for fixup_special() */
- Xextern char *lev_message;
- Xextern lev_region *lregions;
- Xextern int num_lregions;
- X
- Xstatic int FDECL(iswall,(int,int));
- Xstatic boolean FDECL(okay,(int,int,int));
- Xstatic void FDECL(maze0xy,(coord *));
- Xstatic boolean FDECL(put_lregion_here,(XCHAR_P,XCHAR_P,XCHAR_P,
- X XCHAR_P,XCHAR_P,XCHAR_P,XCHAR_P,BOOLEAN_P,d_level *));
- Xstatic void NDECL(fixup_special);
- Xstatic void NDECL(setup_waterlevel);
- Xstatic void NDECL(unsetup_waterlevel);
- X
- Xstatic int
- Xiswall(x,y)
- Xint x,y;
- X{
- X if (x<=0 || y<0 || x>COLNO-1 || y>ROWNO-1)
- X return 0;
- X return (IS_WALL(levl[x][y].typ) || IS_DOOR(levl[x][y].typ)
- X || levl[x][y].typ == SDOOR);
- X}
- X
- Xvoid
- Xwallification(x1, y1, x2, y2)
- Xint x1, y1, x2, y2;
- X{
- X uchar type;
- X short x,y;
- X register struct rm *lev;
- X
- X if (x1 < 0) x1 = 0;
- X if (x2 < x1) x2 = x1;
- X if (x2 > COLNO-1) x2 = COLNO-1;
- X if (x1 > x2) x1 = x2;
- X if (y1 < 0) y1 = 0;
- X if (y2 < y1) y2 = y1;
- X if (y2 > ROWNO-1) y2 = ROWNO-1;
- X if (y1 > y2) y1 = y2;
- X for(x = x1; x <= x2; x++)
- X for(y = y1; y <= y2; y++) {
- X lev = &levl[x][y];
- X type = lev->typ;
- X if (iswall(x,y)) {
- X if (IS_DOOR(type) || type == SDOOR || type == DBWALL)
- X continue;
- X else
- X if (iswall(x,y-1))
- X if (iswall(x,y+1))
- X if (iswall(x-1,y))
- X if (iswall(x+1,y))
- X lev->typ = CROSSWALL;
- X else
- X lev->typ = TLWALL;
- X else
- X if (iswall(x+1,y))
- X lev->typ = TRWALL;
- X else
- X lev->typ = VWALL;
- X else
- X if (iswall(x-1,y))
- X if (iswall(x+1,y))
- X lev->typ = TUWALL;
- X else
- X lev->typ = BRCORNER;
- X else
- X if (iswall(x+1,y))
- X lev->typ = BLCORNER;
- X else
- X lev->typ = VWALL;
- X else
- X if (iswall(x,y+1))
- X if (iswall(x-1,y))
- X if (iswall(x+1,y))
- X lev->typ = TDWALL;
- X else
- X lev->typ = TRCORNER;
- X else
- X if (iswall(x+1,y))
- X lev->typ = TLCORNER;
- X else
- X lev->typ = VWALL;
- X else
- X lev->typ = HWALL;
- X }
- X }
- X}
- X
- Xstatic boolean
- Xokay(x,y,dir)
- Xint x,y;
- Xregister int dir;
- X{
- X move(&x,&y,dir);
- X move(&x,&y,dir);
- X if(x<3 || y<3 || x>x_maze_max || y>y_maze_max || levl[x][y].typ != 0)
- X return(FALSE);
- X return(TRUE);
- X}
- X
- Xstatic void
- Xmaze0xy(cc) /* find random starting point for maze generation */
- X coord *cc;
- X{
- X cc->x = 3 + 2*rn2((x_maze_max>>1) - 1);
- X cc->y = 3 + 2*rn2((y_maze_max>>1) - 1);
- X return;
- X}
- X
- X/*
- X * Bad if:
- X * pos is occupied OR
- X * pos is inside restricted region (lx,ly,hx,hy) OR
- X * NOT (pos is corridor and a maze level OR pos is a room OR pos is air)
- X */
- Xboolean
- Xbad_location(x, y, lx, ly, hx, hy)
- X xchar x, y;
- X xchar lx, ly, hx, hy;
- X{
- X return(occupied(x, y) ||
- X ((x >= lx) && (x <= hx) && (y >= ly) && (y <= hy)) ||
- X !((levl[x][y].typ == CORR && level.flags.is_maze_lev) ||
- X levl[x][y].typ == ROOM || levl[x][y].typ == AIR));
- X}
- X
- X/* pick a location in area (lx, ly, hx, hy) but not in (nlx, nly, nhx, nhy) */
- X/* and place something (based on rtype) in that region */
- Xvoid
- Xplace_lregion(lx, ly, hx, hy, nlx, nly, nhx, nhy, rtype, lev)
- X xchar lx, ly, hx, hy;
- X xchar nlx, nly, nhx, nhy;
- X xchar rtype;
- X d_level *lev;
- X{
- X int trycnt;
- X boolean oneshot;
- X xchar x, y;
- X
- X if(!lx) { /* default to whole level */
- X /*
- X * if there are rooms and this a branch, let place_branch choose
- X * the branch location (to avoid putting branches in corridors).
- X */
- X if(rtype == LR_BRANCH && nroom) {
- X place_branch(Is_branchlev(&u.uz), 0, 0);
- X return;
- X }
- X
- X lx = 1; hx = COLNO-1;
- X ly = 1; hy = ROWNO-1;
- X }
- X
- X /* first a probabilistic approach */
- X
- X oneshot = (lx == hx && ly == hy);
- X for(trycnt = 0; trycnt < 100; trycnt ++) {
- X
- X x = rn1((hx - lx) + 1, lx);
- X y = rn1((hy - ly) + 1, ly);
- X
- X if (put_lregion_here(x,y,nlx,nly,nhx,nhy,rtype,oneshot,lev))
- X return;
- X }
- X
- X /* then a deterministic one */
- X
- X oneshot = TRUE;
- X for (x = lx; x <= hx; x++)
- X for (y = ly; y <= hy; y++)
- X if (put_lregion_here(x,y,nlx,nly,nhx,nhy,rtype,oneshot,lev))
- X return;
- X
- X impossible("Couldn't place lregion type %d!", rtype);
- X}
- X
- Xstatic boolean
- Xput_lregion_here(x,y,nlx,nly,nhx,nhy,rtype,oneshot,lev)
- Xxchar x, y;
- Xxchar nlx, nly, nhx, nhy;
- Xxchar rtype;
- Xboolean oneshot;
- Xd_level *lev;
- X{
- X if(oneshot) {
- X /* must make due with the only location possible */
- X /* avoid failure due to a misplaced trap */
- X /* it might still fail if there's a dungeon feature here */
- X struct trap *t = t_at(x,y);
- X if (t) deltrap(t);
- X }
- X if(bad_location(x, y, nlx, nly, nhx, nhy)) return(FALSE);
- X switch (rtype) {
- X case LR_TELE:
- X case LR_UPTELE:
- X case LR_DOWNTELE:
- X /* "something" means the player in this case */
- X if(MON_AT(x, y)) {
- X /* move the monster if no choice, or just try again */
- X if(oneshot) rloc(m_at(x,y));
- X else return(FALSE);
- X }
- X u.ux = x; u.uy = y;
- X break;
- X case LR_PORTAL:
- X mkportal(x, y, lev->dnum, lev->dlevel);
- X break;
- X case LR_DOWNSTAIR:
- X case LR_UPSTAIR:
- X mkstairs(x, y, (char)rtype, (struct mkroom *)0);
- X break;
- X case LR_BRANCH:
- X place_branch(Is_branchlev(&u.uz), x, y);
- X break;
- X }
- X return(TRUE);
- X}
- X
- Xstatic boolean was_waterlevel; /* ugh... this shouldn't be needed */
- X
- X/* this is special stuff that the level compiler cannot (yet) handle */
- Xstatic void
- Xfixup_special()
- X{
- X register lev_region *r = lregions;
- X struct d_level lev;
- X register int x, y;
- X struct mkroom *croom;
- X boolean added_branch = FALSE;
- X
- X if (was_waterlevel) {
- X was_waterlevel = FALSE;
- X u.uinwater = 0;
- X unsetup_waterlevel();
- X } else if (Is_waterlevel(&u.uz)) {
- X level.flags.hero_memory = 0;
- X was_waterlevel = TRUE;
- X /* water level is an odd beast - it has to be set up
- X before calling place_lregions etc. */
- X setup_waterlevel();
- X }
- X for(x = 0; x < num_lregions; x++, r++) {
- X switch(r->rtype) {
- X case LR_BRANCH:
- X added_branch = TRUE;
- X goto place_it;
- X
- X case LR_PORTAL:
- X if(*r->rname >= '0' && *r->rname <= '9') {
- X /* "chutes and ladders" */
- X lev = u.uz;
- X lev.dlevel = atoi(r->rname);
- X } else
- X lev = find_level(r->rname)->dlevel;
- X /* fall into... */
- X
- X case LR_UPSTAIR:
- X case LR_DOWNSTAIR:
- X place_it:
- X place_lregion(r->inarea.x1, r->inarea.y1,
- X r->inarea.x2, r->inarea.y2,
- X r->delarea.x1, r->delarea.y1,
- X r->delarea.x2, r->delarea.y2,
- X r->rtype, &lev);
- X break;
- X
- X case LR_TELE:
- X case LR_UPTELE:
- X case LR_DOWNTELE:
- X /* save the region outlines for goto_level() */
- X if(r->rtype == LR_TELE || r->rtype == LR_UPTELE) {
- X updest.lx = r->inarea.x1; updest.ly = r->inarea.y1;
- X updest.hx = r->inarea.x2; updest.hy = r->inarea.y2;
- X updest.nlx = r->delarea.x1; updest.nly = r->delarea.y1;
- X updest.nhx = r->delarea.x2; updest.nhy = r->delarea.y2;
- X }
- X if(r->rtype == LR_TELE || r->rtype == LR_DOWNTELE) {
- X dndest.lx = r->inarea.x1; dndest.ly = r->inarea.y1;
- X dndest.hx = r->inarea.x2; dndest.hy = r->inarea.y2;
- X dndest.nlx = r->delarea.x1; dndest.nly = r->delarea.y1;
- X dndest.nhx = r->delarea.x2; dndest.nhy = r->delarea.y2;
- X }
- X /* place_lregion gets called from goto_level() */
- X break;
- X }
- X }
- X
- X /* place dungeon branch if not placed above */
- X if (!added_branch && Is_branchlev(&u.uz)) {
- X place_lregion(0,0,0,0,0,0,0,0,LR_BRANCH,(d_level *)0);
- X }
- X
- X /* Still need to add some stuff to level file */
- X if (Is_medusa_level(&u.uz)) {
- X struct obj *otmp;
- X int tryct;
- X
- X croom = &rooms[0]; /* only one room on the medusa level */
- X for (tryct = rn1(1,3); tryct; tryct--) {
- X x = somex(croom); y = somey(croom);
- X if (goodpos(x, y, (struct monst *)0, (struct permonst *)0)) {
- X otmp = mk_tt_object(STATUE, x, y);
- X while (otmp && (poly_when_stoned(&mons[otmp->corpsenm]) ||
- X resists_ston(&mons[otmp->corpsenm]))) {
- X otmp->corpsenm = rndmonnum();
- X otmp->owt = weight(otmp);
- X }
- X }
- X }
- X
- X if (rn2(2))
- X otmp = mk_tt_object(STATUE, somex(croom), somey(croom));
- X else /* Medusa statues don't contain books */
- X otmp = mkcorpstat(STATUE, (struct permonst *)0,
- X somex(croom), somey(croom), FALSE);
- X if (otmp) {
- X while (resists_ston(&mons[otmp->corpsenm])
- X || poly_when_stoned(&mons[otmp->corpsenm])) {
- X otmp->corpsenm = rndmonnum();
- X otmp->owt = weight(otmp);
- X }
- X }
- X } else if(Is_wiz1_level(&u.uz)) {
- X croom = search_special(MORGUE);
- X
- X create_secret_door(croom, W_SOUTH|W_EAST|W_WEST);
- X#ifdef MULDGN
- X } else if(Is_knox(&u.uz)) {
- X /* using an unfilled morgue for rm id */
- X croom = search_special(MORGUE);
- X /* stock the main vault */
- X for(x = croom->lx; x <= croom->hx; x++)
- X for(y = croom->ly; y <= croom->hy; y++) {
- X mkgold((long) rn1(300, 600), x, y);
- X if(!rn2(3) && !is_pool(x,y)) (void)maketrap(x, y, LANDMINE);
- X }
- X#endif
- X } else if(Is_sanctum(&u.uz)) {
- X croom = search_special(TEMPLE);
- X
- X create_secret_door(croom, W_ANY);
- X } else if(on_level(&u.uz, &orcus_level)) {
- X register struct monst *mtmp, *mtmp2;
- X
- X /* it's a ghost town, get rid of shopkeepers */
- X for(mtmp = fmon; mtmp; mtmp = mtmp2) {
- X mtmp2 = mtmp->nmon;
- X if(mtmp->isshk) mongone(mtmp);
- X }
- X }
- X
- X if(lev_message) {
- X char *str, *nl;
- X for(str = lev_message; (nl = index(str, '\n')) != 0; str = nl+1) {
- X *nl = '\0';
- X pline("%s", str);
- X }
- X if(*str)
- X pline("%s", str);
- X free((genericptr_t)lev_message);
- X lev_message = 0;
- X }
- X}
- X
- Xvoid
- Xmakemaz(s)
- Xregister const char *s;
- X{
- X int x,y;
- X char protofile[20];
- X s_level *sp = Is_special(&u.uz);
- X coord mm;
- X
- X if(*s) {
- X if(sp && sp->rndlevs) Sprintf(protofile, "%s-%d", s,
- X rnd((int) sp->rndlevs));
- X else Strcpy(protofile, s);
- X } else if(*(dungeons[u.uz.dnum].proto)) {
- X if(dunlevs_in_dungeon(&u.uz) > 1) {
- X if(sp && sp->rndlevs)
- X Sprintf(protofile, "%s%d-%d", dungeons[u.uz.dnum].proto,
- X dunlev(&u.uz),
- X rnd((int) sp->rndlevs));
- X else Sprintf(protofile, "%s%d", dungeons[u.uz.dnum].proto,
- X dunlev(&u.uz));
- X } else if(sp && sp->rndlevs) {
- X Sprintf(protofile, "%s-%d", dungeons[u.uz.dnum].proto,
- X rnd((int) sp->rndlevs));
- X } else Strcpy(protofile, dungeons[u.uz.dnum].proto);
- X
- X } else Strcpy(protofile, "");
- X
- X if(*protofile) {
- X Strcat(protofile, LEV_EXT);
- X if(load_special(protofile)) {
- X fixup_special();
- X return; /* no mazification right now */
- X }
- X impossible("Couldn't load '%s' - making a maze.", protofile);
- X }
- X
- X level.flags.is_maze_lev = TRUE;
- X
- X#ifndef WALLIFIED_MAZE
- X for(x = 2; x < x_maze_max; x++)
- X for(y = 2; y < y_maze_max; y++)
- X levl[x][y].typ = STONE;
- X#else
- X for(x = 2; x <= x_maze_max; x++)
- X for(y = 2; y <= y_maze_max; y++)
- X levl[x][y].typ = ((x % 2) && (y % 2)) ? STONE : HWALL;
- X#endif
- X
- X maze0xy(&mm);
- X walkfrom((int) mm.x, (int) mm.y);
- X /* put a boulder at the maze center */
- X (void) mksobj_at(BOULDER, (int) mm.x, (int) mm.y, TRUE);
- X
- X#ifdef WALLIFIED_MAZE
- X wallification(2, 2, x_maze_max, y_maze_max);
- X#else
- X for(x = 2; x < x_maze_max; x++)
- X for(y = 2; y < y_maze_max; y++)
- X levl[x][y].seen = 1; /* start out seen */
- X#endif
- X if(Invocation_lev(&u.uz)) {
- X place_lregion(0,0,0,0, 30, 0, 46, ROWNO, UP, (d_level *)0);
- X do {
- X if(xupstair < 30)
- X x = rn1(COLNO-16-xupstair, xupstair+7);
- X else
- X x = rn1(xupstair-16, 9);
- X y = rn1(7, 8);
- X } while((levl[x][y].typ != CORR && levl[x][y].typ != ROOM)
- X || occupied(x,y));
- X inv_pos.x = x;
- X inv_pos.y = y;
- X } else {
- X /* no regular up stairs on the first level of a dungeon) */
- X if(u.uz.dlevel != 1) {
- X mazexy(&mm);
- X mkstairs(mm.x, mm.y, UP, (struct mkroom *)0);
- X }
- X
- X /* no regular down stairs on the last level of a dungeon */
- X if(dunlev(&u.uz) != dunlevs_in_dungeon(&u.uz)) {
- X mazexy(&mm);
- X mkstairs(mm.x, mm.y, DOWN, (struct mkroom *)0);
- X }
- X }
- X
- X /* place branch stair or portal */
- X place_branch(Is_branchlev(&u.uz), 0, 0);
- X
- X for(x = rn1(8,11); x; x--) {
- X mazexy(&mm);
- X (void) mkobj_at(rn2(2) ? GEM_CLASS : 0, mm.x, mm.y, TRUE);
- X }
- X for(x = rn1(10,2); x; x--) {
- X mazexy(&mm);
- X (void) mksobj_at(BOULDER, mm.x, mm.y, TRUE);
- X }
- X mazexy(&mm);
- X (void) makemon(&mons[PM_MINOTAUR], mm.x, mm.y);
- X for(x = rn1(5,7); x; x--) {
- X mazexy(&mm);
- X (void) makemon((struct permonst *) 0, mm.x, mm.y);
- X }
- X for(x = rn1(6,7); x; x--) {
- X mazexy(&mm);
- X mkgold(0L,mm.x,mm.y);
- X }
- X for(x = rn1(6,7); x; x--)
- X mktrap(0,1,(struct mkroom *) 0, (coord*) 0);
- X}
- X
- X#ifdef MICRO
- X/* Make the mazewalk iterative by faking a stack. This is needed to
- X * ensure the mazewalk is successful in the limited stack space of
- X * the program. This iterative version uses the minimum amount of stack
- X * that is totally safe.
- X */
- Xvoid
- Xwalkfrom(x,y)
- Xint x,y;
- X{
- X#define CELLS (ROWNO * COLNO) / 4 /* a maze cell is 4 squares */
- X char mazex[CELLS + 1], mazey[CELLS + 1]; /* char's are OK */
- X int q, a, dir, pos;
- X int dirs[4];
- X
- X pos = 1;
- X mazex[pos] = (char) x;
- X mazey[pos] = (char) y;
- X while (pos) {
- X x = (int) mazex[pos];
- X y = (int) mazey[pos];
- X if(!IS_DOOR(levl[x][y].typ)) {
- X /* might still be on edge of MAP, so don't overwrite */
- X#ifndef WALLIFIED_MAZE
- X levl[x][y].typ = CORR;
- X#else
- X levl[x][y].typ = ROOM;
- X#endif
- X levl[x][y].flags = 0;
- X }
- X q = 0;
- X for (a = 0; a < 4; a++)
- X if(okay(x, y, a)) dirs[q++]= a;
- X if (!q)
- X pos--;
- X else {
- X dir = dirs[rn2(q)];
- X move(&x, &y, dir);
- X#ifndef WALLIFIED_MAZE
- X levl[x][y].typ = CORR;
- X#else
- X levl[x][y].typ = ROOM;
- X#endif
- X move(&x, &y, dir);
- X pos++;
- X if (pos > CELLS)
- X panic("Overflow in walkfrom");
- X mazex[pos] = (char) x;
- X mazey[pos] = (char) y;
- X }
- X }
- X}
- X#else
- X
- Xvoid
- Xwalkfrom(x,y)
- Xint x,y;
- X{
- X register int q,a,dir;
- X int dirs[4];
- X
- X if(!IS_DOOR(levl[x][y].typ)) {
- X /* might still be on edge of MAP, so don't overwrite */
- X#ifndef WALLIFIED_MAZE
- X levl[x][y].typ = CORR;
- X#else
- X levl[x][y].typ = ROOM;
- X#endif
- X levl[x][y].flags = 0;
- X }
- X
- X while(1) {
- X q = 0;
- X for(a = 0; a < 4; a++)
- X if(okay(x,y,a)) dirs[q++]= a;
- X if(!q) return;
- X dir = dirs[rn2(q)];
- X move(&x,&y,dir);
- X#ifndef WALLIFIED_MAZE
- X levl[x][y].typ = CORR;
- X#else
- X levl[x][y].typ = ROOM;
- X#endif
- X move(&x,&y,dir);
- X walkfrom(x,y);
- X }
- X}
- X#endif /* MICRO */
- X
- Xvoid
- Xmove(x,y,dir)
- Xregister int *x, *y;
- Xregister int dir;
- X{
- X switch(dir){
- X case 0: --(*y); break;
- X case 1: (*x)++; break;
- X case 2: (*y)++; break;
- X case 3: --(*x); break;
- X }
- X}
- X
- Xvoid
- Xmazexy(cc) /* find random point in generated corridors,
- X so we don't create items in moats, bunkers, or walls */
- X coord *cc;
- X{
- X int cpt=0;
- X
- X do {
- X cc->x = 3 + 2*rn2((x_maze_max>>1) - 1);
- X cc->y = 3 + 2*rn2((y_maze_max>>1) - 1);
- X cpt++;
- X } while (cpt < 100 && levl[cc->x][cc->y].typ !=
- X#ifndef WALLIFIED_MAZE
- X CORR
- X#else
- X ROOM
- X#endif
- X );
- X if (cpt >= 100) {
- X register int x, y;
- X /* last try */
- X for (x = 0; x < (x_maze_max>>1) - 1; x++)
- X for (y = 0; y < (y_maze_max>>1) - 1; y++) {
- X cc->x = 3 + 2 * x;
- X cc->y = 3 + 2 * y;
- X if (levl[cc->x][cc->y].typ ==
- X#ifndef WALLIFIED_MAZE
- X CORR
- X#else
- X ROOM
- X#endif
- X ) return;
- X }
- X panic("mazexy: can't find a place!");
- X }
- X return;
- X}
- X
- Xvoid
- Xbound_digging()
- X/* put a non-diggable boundary around the initial portion of a level map.
- X * assumes that no level will initially put things beyond the isok() range.
- X *
- X * we can't bound unconditionally on the last line with something in it,
- X * because that something might be a niche which was already reachable,
- X * so the boundary would be breached
- X *
- X * we can't bound unconditionally on one beyond the last line, because
- X * that provides a window of abuse for WALLIFIED_MAZE special levels
- X */
- X{
- X register int x,y;
- X register unsigned typ;
- X register struct rm *lev;
- X boolean found, nonwall;
- X int xmin,xmax,ymin,ymax;
- X
- X if(Is_earthlevel(&u.uz)) return; /* everything diggable here */
- X
- X found = nonwall = FALSE;
- X for(xmin=0; !found; xmin++) {
- X lev = &levl[xmin][0];
- X for(y=0; y<=ROWNO-1; y++, lev++) {
- X typ = lev->typ;
- X if(typ != STONE) {
- X found = TRUE;
- X if(!IS_WALL(typ)) nonwall = TRUE;
- X }
- X }
- X }
- X xmin -= (nonwall || !level.flags.is_maze_lev) ? 2 : 1;
- X if (xmin < 0) xmin = 0;
- X
- X found = nonwall = FALSE;
- X for(xmax=COLNO-1; !found; xmax--) {
- X lev = &levl[xmax][0];
- X for(y=0; y<=ROWNO-1; y++, lev++) {
- X typ = lev->typ;
- X if(typ != STONE) {
- X found = TRUE;
- X if(!IS_WALL(typ)) nonwall = TRUE;
- X }
- X }
- X }
- X xmax += (nonwall || !level.flags.is_maze_lev) ? 2 : 1;
- X if (xmax >= COLNO) xmax = COLNO-1;
- X
- X found = nonwall = FALSE;
- X for(ymin=0; !found; ymin++) {
- X lev = &levl[xmin][ymin];
- X for(x=xmin; x<=xmax; x++, lev += ROWNO) {
- X typ = lev->typ;
- X if(typ != STONE) {
- X found = TRUE;
- X if(!IS_WALL(typ)) nonwall = TRUE;
- X }
- X }
- X }
- X ymin -= (nonwall || !level.flags.is_maze_lev) ? 2 : 1;
- X
- X found = nonwall = FALSE;
- X for(ymax=ROWNO-1; !found; ymax--) {
- X lev = &levl[xmin][ymax];
- X for(x=xmin; x<=xmax; x++, lev += ROWNO) {
- X typ = lev->typ;
- X if(typ != STONE) {
- X found = TRUE;
- X if(!IS_WALL(typ)) nonwall = TRUE;
- X }
- X }
- X }
- X ymax += (nonwall || !level.flags.is_maze_lev) ? 2 : 1;
- X
- X if(ymin >= 0)
- X for(x=xmin; x<=xmax; x++) levl[x][ymin].diggable = W_NONDIGGABLE;
- X if(ymax < ROWNO)
- X for(x=xmin; x<=xmax; x++) levl[x][ymax].diggable = W_NONDIGGABLE;
- X
- X /* Don't bound these until _after_ the previous loops to avoid "ice" */
- X /* Normal rooms become ice by setting W_NONDIGGABLE -dlc */
- X if (ymin < 0) ymin = 0;
- X if (ymax >= ROWNO) ymax = ROWNO-1;
- X
- X for(y=ymin; y<=ymax; y++) {
- X levl[xmin][y].diggable = W_NONDIGGABLE;
- X levl[xmax][y].diggable = W_NONDIGGABLE;
- X }
- X}
- X
- Xvoid
- Xmkportal(x, y, todnum, todlevel)
- Xregister xchar x, y, todnum, todlevel;
- X{
- X /* a portal "trap" must be matched by a */
- X /* portal in the destination dungeon/dlevel */
- X register struct trap *ttmp = maketrap(x, y, MAGIC_PORTAL);
- X
- X#ifdef DEBUG
- X pline("mkportal: at (%d,%d), to %s, level %d",
- X x, y, dungeons[todnum].dname, todlevel);
- X#endif
- X ttmp->dst.dnum = todnum;
- X ttmp->dst.dlevel = todlevel;
- X return;
- X}
- X
- X/*
- X * Special waterlevel stuff in endgame (TH).
- X *
- X * Some of these functions would probably logically belong to some
- X * other source files, but they are all so nicely encapsulated here.
- X */
- X
- X/* to ease the work of debuggers at this stage */
- X#define register
- X
- Xstruct container {
- X struct container *next;
- X xchar x, y;
- X short what;
- X genericptr_t list;
- X};
- X#define CONS_OBJ 0
- X#define CONS_MON 1
- X#define CONS_HERO 2
- X#define CONS_TRAP 3
- X
- Xstatic struct bubble {
- X xchar x, y; /* coordinates of the upper left corner */
- X schar dx, dy; /* the general direction of the bubble's movement */
- X uchar *bm; /* pointer to the bubble bit mask */
- X struct bubble *prev, *next; /* need to traverse the list up and down */
- X struct container *cons;
- X} *bbubbles, *ebubbles;
- X
- Xstatic struct trap *wportal;
- Xstatic int xmin, ymin, xmax, ymax; /* level boundaries */
- X/* bubble movement boundaries */
- X#define bxmin (xmin + 1)
- X#define bymin (ymin + 1)
- X#define bxmax (xmax - 1)
- X#define bymax (ymax - 1)
- X
- Xstatic void NDECL(set_wportal);
- Xstatic void FDECL(mk_bubble, (int,int,int));
- Xstatic void FDECL(mv_bubble, (struct bubble *,int,int,BOOLEAN_P));
- X
- Xvoid
- Xmovebubbles()
- X{
- X static boolean up;
- X register struct bubble *b;
- X register int x, y, i, j;
- X struct trap *btrap;
- X static const struct rm water_pos =
- X { cmap_to_glyph(S_water), WATER, 0, 0, 0, 0, 0, 0, 0 };
- X
- X /* set up the portal the first time bubbles are moved */
- X if (!wportal) set_wportal();
- X
- X vision_recalc(2);
- X
- X /*
- X * Pick up everything inside of a bubble then fill all bubble
- X * locations.
- X */
- X
- X for (b = up ? bbubbles : ebubbles; b; b = up ? b->next : b->prev) {
- X if (b->cons) panic("movebubbles: cons != null");
- X for (i = 0, x = b->x; i < (int) b->bm[0]; i++, x++)
- X for (j = 0, y = b->y; j < (int) b->bm[1]; j++, y++)
- X if (b->bm[j + 2] & (1 << i)) {
- X if (!isok(x,y)) {
- X impossible("movebubbles: bad pos (%d,%d)", x,y);
- X continue;
- X }
- X
- X /* pick up objects, monsters, hero, and traps */
- X if (OBJ_AT(x,y)) {
- X struct obj *olist = (struct obj *) 0, *otmp;
- X struct container *cons = (struct container *)
- X alloc(sizeof(struct container));
- X
- X while ((otmp = level.objects[x][y]) != 0) {
- X remove_object(otmp);
- X otmp->ox = otmp->oy = 0;
- X otmp->nexthere = olist;
- X olist = otmp;
- X }
- X
- X cons->x = x;
- X cons->y = y;
- X cons->what = CONS_OBJ;
- X cons->list = (genericptr_t) olist;
- X cons->next = b->cons;
- X b->cons = cons;
- X }
- X if (MON_AT(x,y)) {
- X struct monst *mon = m_at(x,y);
- X struct container *cons = (struct container *)
- X alloc(sizeof(struct container));
- X
- X cons->x = x;
- X cons->y = y;
- X cons->what = CONS_MON;
- X cons->list = (genericptr_t) mon;
- X
- X cons->next = b->cons;
- X b->cons = cons;
- X
- X if(mon->wormno)
- X remove_worm(mon);
- X else
- X remove_monster(x, y);
- X
- X newsym(x,y); /* clean up old position */
- X mon->mx = mon->my = 0;
- X }
- X if (!u.uswallow && x == u.ux && y == u.uy) {
- X struct container *cons = (struct container *)
- X alloc(sizeof(struct container));
- X
- X cons->x = x;
- X cons->y = y;
- X cons->what = CONS_HERO;
- X cons->list = (genericptr_t) 0;
- X
- X cons->next = b->cons;
- X b->cons = cons;
- X }
- X if ((btrap = t_at(x,y)) != 0) {
- X struct container *cons = (struct container *)
- X alloc(sizeof(struct container));
- X
- X cons->x = x;
- X cons->y = y;
- X cons->what = CONS_TRAP;
- X cons->list = (genericptr_t) btrap;
- X
- X cons->next = b->cons;
- X b->cons = cons;
- X }
- X
- X levl[x][y] = water_pos;
- X block_point(x,y);
- X }
- X }
- X
- X /*
- X * Every second time traverse down. This is because otherwise
- X * all the junk that changes owners when bubbles overlap
- X * would eventually end up in the last bubble in the chain.
- X */
- X
- X up = !up;
- X for (b = up ? bbubbles : ebubbles; b; b = up ? b->next : b->prev) {
- X register int rx = rn2(3), ry = rn2(3);
- X
- X mv_bubble(b,b->dx + 1 - (!b->dx ? rx : (rx ? 1 : 0)),
- X b->dy + 1 - (!b->dy ? ry : (ry ? 1 : 0)),
- X FALSE);
- X }
- X
- X vision_full_recalc = 1;
- X}
- X
- Xvoid
- Xwater_friction()
- X{
- X register boolean eff = FALSE;
- X
- X if (u.dx && !rn2(3)) {
- X eff = TRUE;
- X u.dx = 0;
- X }
- X if (u.dy && !rn2(3)) {
- X eff = TRUE;
- X u.dy = 0;
- X }
- X if (eff) pline("Water turbulence affects your movements.");
- X}
- X
- Xvoid
- Xsave_waterlevel(fd)
- Xregister int fd;
- X{
- X register struct bubble *b;
- X int n;
- X
- X if (!Is_waterlevel(&u.uz)) return;
- X
- X for (b = bbubbles, n = 0; b; b = b->next, n++) ;
- X bwrite(fd,(genericptr_t)&n,sizeof(int));
- X bwrite(fd,(genericptr_t)&xmin,sizeof(int));
- X bwrite(fd,(genericptr_t)&ymin,sizeof(int));
- X bwrite(fd,(genericptr_t)&xmax,sizeof(int));
- X bwrite(fd,(genericptr_t)&ymax,sizeof(int));
- X for (b = bbubbles; b; b = b->next)
- X bwrite(fd,(genericptr_t)b,sizeof(struct bubble));
- X}
- X
- Xvoid
- Xrestore_waterlevel(fd)
- Xregister int fd;
- X{
- X register struct bubble *b = (struct bubble *)0, *btmp;
- X register int i;
- X int n;
- X
- X if (!Is_waterlevel(&u.uz)) return;
- X
- X set_wportal();
- X mread(fd,(genericptr_t)&n,sizeof(int));
- X mread(fd,(genericptr_t)&xmin,sizeof(int));
- X mread(fd,(genericptr_t)&ymin,sizeof(int));
- X mread(fd,(genericptr_t)&xmax,sizeof(int));
- X mread(fd,(genericptr_t)&ymax,sizeof(int));
- X for (i = 0; i < n; i++) {
- X btmp = b;
- X b = (struct bubble *)alloc(sizeof(struct bubble));
- X mread(fd,(genericptr_t)b,sizeof(struct bubble));
- X if (bbubbles) {
- X btmp->next = b;
- X b->prev = btmp;
- X } else {
- X bbubbles = b;
- X b->prev = (struct bubble *)0;
- X }
- X mv_bubble(b,0,0,TRUE);
- X }
- X ebubbles = b;
- X b->next = (struct bubble *)0;
- X was_waterlevel = TRUE;
- X}
- X
- Xstatic void
- Xset_wportal()
- X{
- X /* there better be only one magic portal on water level... */
- X for (wportal = ftrap; wportal; wportal = wportal->ntrap)
- X if (wportal->ttyp == MAGIC_PORTAL) return;
- X impossible("set_wportal(): no portal!");
- X}
- X
- Xstatic void
- Xsetup_waterlevel()
- X{
- X register int x, y;
- X register int xskip, yskip;
- X register int water_glyph = cmap_to_glyph(S_water);
- X
- X /* ouch, hardcoded... */
- X
- X xmin = 3;
- X ymin = 1;
- X xmax = 78;
- X ymax = 20;
- X
- X /* set hero's memory to water */
- X
- X for (x = xmin; x <= xmax; x++)
- X for (y = ymin; y <= ymax; y++)
- X levl[x][y].glyph = water_glyph;
- X
- X /* make bubbles */
- X
- X xskip = 10 + rn2(10);
- X yskip = 4 + rn2(4);
- X for (x = bxmin; x <= bxmax; x += xskip)
- X for (y = bymin; y <= bymax; y += yskip)
- X mk_bubble(x,y,rn2(7));
- X}
- X
- Xstatic void
- Xunsetup_waterlevel()
- X{
- X register struct bubble *b, *bb;
- X
- X /* free bubbles */
- X
- X for (b = bbubbles; b; b = bb) {
- X bb = b->next;
- X free((genericptr_t)b);
- X }
- X bbubbles = ebubbles = (struct bubble *)0;
- X}
- X
- Xstatic void
- Xmk_bubble(x,y,n)
- Xregister int x, y, n;
- X{
- X /*
- X * These bit masks make visually pleasing bubbles on a normal aspect
- X * 25x80 terminal, which naturally results in them being mathematically
- X * anything but symmetric. For this reason they cannot be computed
- X * in situ, either. The first two elements tell the dimensions of
- X * the bubble's bounding box.
- X */
- X static uchar
- X bm2[] = {2,1,0x3},
- X bm3[] = {3,2,0x7,0x7},
- X bm4[] = {4,3,0x6,0xf,0x6},
- X bm5[] = {5,3,0xe,0x1f,0xe},
- X bm6[] = {6,4,0x1e,0x3f,0x3f,0x1e},
- X bm7[] = {7,4,0x3e,0x7f,0x7f,0x3e},
- X bm8[] = {8,4,0x7e,0xff,0xff,0x7e},
- X *bmask[] = {bm2,bm3,bm4,bm5,bm6,bm7,bm8};
- X
- X register struct bubble *b;
- X
- X if (x >= bxmax || y >= bymax) return;
- X if (n >= SIZE(bmask)) {
- X impossible("n too large (mk_bubble)");
- X n = SIZE(bmask) - 1;
- X }
- X b = (struct bubble *)alloc(sizeof(struct bubble));
- X if ((x + (int) bmask[n][0] - 1) > bxmax) x = bxmax - bmask[n][0] + 1;
- X if ((y + (int) bmask[n][1] - 1) > bymax) y = bymax - bmask[n][1] + 1;
- X b->x = x;
- X b->y = y;
- X b->dx = 1 - rn2(3);
- X b->dy = 1 - rn2(3);
- X b->bm = bmask[n];
- X b->cons = 0;
- X if (!bbubbles) bbubbles = b;
- X if (ebubbles) {
- X ebubbles->next = b;
- X b->prev = ebubbles;
- X }
- X else
- X b->prev = (struct bubble *)0;
- X b->next = (struct bubble *)0;
- X ebubbles = b;
- X mv_bubble(b,0,0,TRUE);
- X}
- X
- X/*
- X * The player, the portal and all other objects and monsters
- X * float along with their associated bubbles. Bubbles may overlap
- X * freely, and the contents may get associated with other bubbles in
- X * the process. Bubbles are "sticky", meaning that if the player is
- X * in the immediate neighborhood of one, he/she may get sucked inside.
- X * This property also makes leaving a bubble slightly difficult.
- X */
- Xstatic void
- Xmv_bubble(b,dx,dy,ini)
- Xregister struct bubble *b;
- Xregister int dx, dy;
- Xregister boolean ini;
- X{
- X register int x, y, i, j, colli = 0;
- X struct bubble ob;
- X struct container *cons, *ctemp;
- X
- X /* some old data for reference */
- X
- X ob.x = b->x;
- X ob.y = b->y;
- X ob.bm = b->bm;
- X
- X /* move bubble */
- X if (dx < -1 || dx > 1 || dy < -1 || dy > 1) {
- X /* pline("mv_bubble: dx = %d, dy = %d", dx, dy); */
- X dx = sgn(dx);
- X dy = sgn(dy);
- X }
- X
- X /*
- X * collision with level borders?
- X * 1 = horizontal border, 2 = vertical, 3 = corner
- X */
- X if (b->x <= bxmin) colli |= 2;
- X if (b->y <= bymin) colli |= 1;
- X if ((int) (b->x + b->bm[0] - 1) >= bxmax) colli |= 2;
- X if ((int) (b->y + b->bm[1] - 1) >= bymax) colli |= 1;
- X
- X if (b->x < bxmin) {
- X pline("bubble xmin: x = %d, xmin = %d", b->x, bxmin);
- X b->x = bxmin;
- X }
- X if (b->y < bymin) {
- X pline("bubble ymin: y = %d, ymin = %d", b->y, bymin);
- X b->y = bymin;
- X }
- X if ((int) (b->x + b->bm[0] - 1) > bxmax) {
- X pline("bubble xmax: x = %d, xmax = %d",
- X b->x + b->bm[0] - 1, bxmax);
- X b->x = bxmax - b->bm[0] + 1;
- X }
- X if ((int) (b->y + b->bm[1] - 1) > bymax) {
- X pline("bubble ymax: y = %d, ymax = %d",
- X b->y + b->bm[1] - 1, bymax);
- X b->y = bymax - b->bm[1] + 1;
- X }
- X
- X /* bounce if we're trying to move off the border */
- X if (b->x == bxmin && dx < 0) dx = -dx;
- X if (b->x + b->bm[0] - 1 == bxmax && dx > 0) dx = -dx;
- X if (b->y == bymin && dy < 0) dy = -dy;
- X if (b->y + b->bm[1] - 1 == bymax && dy > 0) dy = -dy;
- X
- X b->x += dx;
- X b->y += dy;
- X
- X /* void positions inside bubble */
- X
- X for (i = 0, x = b->x; i < (int) b->bm[0]; i++, x++)
- X for (j = 0, y = b->y; j < (int) b->bm[1]; j++, y++)
- X if (b->bm[j + 2] & (1 << i)) {
- X levl[x][y].typ = AIR;
- X levl[x][y].lit = 1;
- X unblock_point(x,y);
- X }
- X
- X /* replace contents of bubble */
- X for (cons = b->cons; cons; cons = ctemp) {
- X ctemp = cons->next;
- X cons->x += dx;
- X cons->y += dy;
- X
- X switch(cons->what) {
- X case CONS_OBJ: {
- X struct obj *olist, *otmp;
- X
- X for (olist=(struct obj *)cons->list; olist; olist=otmp) {
- X otmp = olist->nexthere;
- X place_object(olist, cons->x, cons->y);
- X }
- X break;
- X }
- X
- X case CONS_MON: {
- X struct monst *mon = (struct monst *) cons->list;
- X (void) mnearto(mon, cons->x, cons->y, TRUE);
- X break;
- X }
- X
- X case CONS_HERO: {
- X int ux0 = u.ux, uy0 = u.uy;
- X
- X /* change u.ux0 and u.uy0? */
- X u.ux = cons->x;
- X u.uy = cons->y;
- X newsym(ux0, uy0); /* clean up old position */
- X
- X if (MON_AT(cons->x, cons->y)) {
- X mnexto(m_at(cons->x,cons->y));
- X }
- X if (Punished) placebc(); /* do this for now */
- X break;
- X }
- X
- X case CONS_TRAP: {
- X struct trap *btrap = (struct trap *) cons->list;
- X btrap->tx = cons->x;
- X btrap->ty = cons->y;
- X break;
- X }
- X
- X default:
- X impossible("mv_bubble: unknown bubble contents");
- X break;
- X }
- X free((genericptr_t)cons);
- X }
- X b->cons = 0;
- X
- X /* boing? */
- X
- X switch (colli) {
- X case 1: b->dy = -b->dy; break;
- X case 3: b->dy = -b->dy; /* fall through */
- X case 2: b->dx = -b->dx; break;
- X default:
- X /* sometimes alter direction for fun anyway
- X (higher probability for stationary bubbles) */
- X if (!ini && ((b->dx || b->dy) ? !rn2(20) : !rn2(5))) {
- X b->dx = 1 - rn2(3);
- X b->dy = 1 - rn2(3);
- X }
- X }
- X}
- X
- X
- X/*mkmaze.c*/
- END_OF_FILE
- if test 29353 -ne `wc -c <'src/mkmaze.c'`; then
- echo shar: \"'src/mkmaze.c'\" unpacked with wrong size!
- fi
- # end of 'src/mkmaze.c'
- fi
- echo shar: End of archive 71 \(of 108\).
- cp /dev/null ark71isdone
- MISSING=""
- 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 39 40 \
- 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
- 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
- 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
- 101 102 103 104 105 106 107 108 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 108 archives.
- echo "Now execute 'rebuild.sh'"
- rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-