home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!zephyr.ens.tek.com!master!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v14i047: umoria4 - single player dungeon simulation (ver. 5.5), Part15/39
- Message-ID: <3405@master.CNA.TEK.COM>
- Date: 20 Aug 92 18:04:57 GMT
- Sender: news@master.CNA.TEK.COM
- Lines: 1703
- Approved: billr@saab.CNA.TEK.COM
-
- Submitted-by: grabiner@math.harvard.edu (David Grabiner)
- Posting-number: Volume 14, Issue 47
- Archive-name: umoria4/Part15
- Supersedes: umoria3: Volume 9, Issue 55-97; Volume 10, Issue 15-17
- Environment: Curses, Unix, Mac, MS-DOS, Atari-ST, Amiga, VMS
-
-
-
- #! /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 15 (of 39)."
- # Contents: misc/README misc/mail.msg source/moria4.c
- # Wrapped by billr@saab on Thu Aug 20 09:11:29 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'misc/README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'misc/README'\"
- else
- echo shar: Extracting \"'misc/README'\" \(489 characters\)
- sed "s/^X//" >'misc/README' <<'END_OF_FILE'
- Xstuff that isn't part of Umoria, but would be nice if it was
- X
- Xfunckeys.h, funckeys.c, mabbrev are (mama) Liz's code for handling SUN keypads
- X
- Xshading is joseph n hall's ideas on how to efficiently calculate multiple
- Xlines of sight
- X
- Xhaggle.sug, moria.msg, and mail.msg are some interesting mail messages
- Xabout moria which suggest changes or additions
- X
- Xrick.msg is a mail message from the author of VMS Moria 6.0, which lists
- Xthe changes he was working on, VMS Moria 6.0 seems to be defunct
- END_OF_FILE
- if test 489 -ne `wc -c <'misc/README'`; then
- echo shar: \"'misc/README'\" unpacked with wrong size!
- fi
- # end of 'misc/README'
- fi
- if test -f 'misc/mail.msg' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'misc/mail.msg'\"
- else
- echo shar: Extracting \"'misc/mail.msg'\" \(21386 characters\)
- sed "s/^X//" >'misc/mail.msg' <<'END_OF_FILE'
- XFrom afc@klaatu.cc.purdue.edu Tue Jan 16 13:33:16 1990
- XReceived: from klaatu.cc.purdue.edu by ernie.Berkeley.EDU (5.61/1.36)
- X id AA09793; Tue, 16 Jan 90 13:33:09 -0800
- XReceived: by klaatu.cc.purdue.edu (5.61/1.14)
- X id AA01432; Tue, 16 Jan 90 16:32:51 -0500
- XDate: Tue, 16 Jan 90 16:32:51 -0500
- XFrom: afc@klaatu.cc.purdue.edu (Greg Flint)
- XMessage-Id: <9001162132.AA01432@klaatu.cc.purdue.edu>
- XTo: wilson@ernie.Berkeley.EDU
- XSubject: Some comments about PC Moria 4.873 aimed toward your Moria 5.0
- XStatus: RO
- X
- XYou comment that Umoria 5.0 will have good balance because it will be
- Xplayer tested before its release. I'd be willing to volunteer to do
- Xsome of this beta testing. I don't have lots of time to play but I find
- Xmoria to be a good way to unwind after a long day fighting more mundane
- Xmosters such as Vaxes, Cybers and Suns.
- X
- XA few opinions about PC Moria 4.873 that might influence Umoria 5.0:
- X
- X STATS
- X -----
- X * Once stats get to the 18/xx stage, I find that I can deal with almost
- X anything non-hastened (except for MHD's and Green d/D's) because by then
- X my HP's are usually quite high. I can just hack away and usually come
- X out on top. If I have sufficient haste self, I tackle V's and L's. If
- X I don't, I phase door, teleport away or run for the stairs. (The method
- X depends on my character type, distance from the monster and equipment at
- X hand.)
- X
- X * After I reach the 18/xx stage, the game degenerates in to a sequence of
- X 1) attack until I loose life levels,
- X 2) WOR to store level,
- X 3) buy more WOR and RLL, if available,
- X 4) kill time on level 1 if no RLL, then back to #3
- X 5) WOR back to deepest level,
- X 6) go to #1".
- X until I'm finally ready to go to level 50 of the dungeon.
- X
- X
- X MONSTERS
- X --------
- X
- X * It seems to take "forever" to go up the levels of 32+ because there is a
- X big disparity between the value of monsters and the amount of points needed
- X to rise to the next level. I find myself looking for D's (and L's if I've
- X the proper abilities and/or tools) and being bored by almost anything else
- X -- and yet I'm not yet ready for Iggy or the big "B".
- X
- X
- X MAGIC
- X -----
- X * Maybe I've been lucky, but I've always been able to find some "see
- X invisible" item early (about Banshee dungeon level). This makes G's, L's,
- X etc a lot easier (see the earlier comment on my playing sequence.)
- X
- X * When playing as a mage and reaching about level 29 where I gain fire ball,
- X I find that I've reached the peak in spells. Of the two spells after that,
- X I've never used WOD and find Genocide so powerful that it seems like
- X cheating.
- X
- X
- X STORES and MONEY
- X ----------------
- X
- X * Money is an issue early, but once I get to about 10,000, I never need to
- X worry about money again -- for two reasons. The scrolls, potions, staves
- X and the like are cheap (relative to 10K gold). The weapons that are HA,
- X DF, etc almost never appear so even though they are expensive, I never
- X seem to need the money.
- X
- X * It would be nice to know how may of a given item are in a store. This
- X would help with questions such as "should I buy now or wait and chance
- X that it (they?) are gone next time?" or "can I buy him out in the hopes
- X of getting better stock next time?".
- X
- X
- X MAGE SPELLS
- X -----------
- X
- X * The two recharge and the three sleep spells seem redundant (especially
- X the latter). I usually ignore the Level I recharge and Levels I and II
- X sleep spells because I need more offensive weaponry (spells). By the time
- X I get around to learning these low level spells (because I've moved up
- X a mage level and you've got to pick something), I really don't need them.
- X
- X * I don't know what I'd suggest, but I'd like to see some other spells in
- X place of the ones listed above -- especially some after level 29.
- X
- X * How about spells being fixed in terms of there letter? Nothing is more
- X painful than forgetting that I've added spell "b" thereby making spell "e"
- X spell "f" and wasting a bunch of mana and maybe allowing a monster a free
- X hit.
- X
- X
- X MAP
- X ---
- X
- X * I find the reduced map a help in speeding up the game. I favor anything
- X that speeds up the game at no penalty me. (For example, using "H" to
- X "run" in place of lots of h's is a no cost plus. I would not want to be
- X penalized for "running" since all I'm doing is speeding up the game, not
- X trying to "tire out" the character.)
- X
- X------------------------------------------------------------------------------
- XGreg Flint Math G-169 (317) 494-1787 UUCP: purdue!klaatu.cc!afc
- X Purdue Univ. Purdue University INTERNET: afc@klaatu.cc.purdue.edu
- X Computing Ctr. West Lafayette, IN 47907 BITNET: flint@purccvm.bitnet
- X
- XFrom qqc@h.cc.purdue.edu Thu Jan 18 13:54:52 1990
- XReceived: from h.cc.purdue.edu by ernie.Berkeley.EDU (5.61/1.36)
- X id AA09437; Thu, 18 Jan 90 13:54:47 -0800
- XReceived: by h.cc.purdue.edu (5.61/1.14)
- X id AA15380; Thu, 18 Jan 90 16:54:08 -0500
- XDate: Thu, 18 Jan 90 16:54:08 -0500
- XFrom: qqc@h.cc.purdue.edu (Dale Forsyth)
- XMessage-Id: <9001182154.AA15380@h.cc.purdue.edu>
- XTo: wilson@ernie.Berkeley.EDU
- XSubject: program comments
- XStatus: RO
- X
- X
- XJim Wilson: As I perceive you as the author/programmer now associated
- Xwith moria, I have several comments to make, in light of messages you have
- Xposted in the past about the program. I use the ibm-pc version 4.873, but
- Xexpect my comments apply universally. All the following is, of course, only
- Xone person's opinion.
- X I'm almost ashamed to admit how much I've used the program -- suffice to
- Xsay I consider myself VERY experienced. I think I could win with ANY
- Xcharacter, but I would not have the patience to do so.
- X I consider the ONLY reason to use the program is for my own enjoyment.
- XAny cheating I do is only to myself, for myself, and affects no one else; of
- Xcourse mine isn't a multi-user machine, for which you are concerned.
- X In my opinion, a mage is a reasonable and fun character. I don't think it
- Xshould be necessary to change it's balance. A priest (current character) is
- Xok EXCEPT that it needs an identify spell. Either that or the shops MUST keep
- Xidentify spells stocked. Since they do not in my version, I would quit this
- Xcharacter as NOT FUN anymore, except that I use wizard mode and cheat on this
- Xpoint.
- X I do NOT consider the 'triangle dance' around monsters a bad thing. I think
- Xthere SHOULD be a way to outdo monsters that are bigger and badder than you,
- Xif you have patience.
- X The shops is an area that needs improvement; they should contain better and
- Xbetter things as one's level increases. After a while there becomes NO REASON
- Xto return topside and accumulation of gold becomes moot. It would stay more
- XFUN if you could BUY that HA weapon, even at 300,000 gp, when you have only
- X175,000 gp. But really good stuff never appears in MY shops.
- X Endless repetition of mundane tactics that you know, waiting for something
- Xyou NEED, is NOT FUN. A little is ok, month's of my life that way is NOT FUN.
- X Characters beyond the BALROG would be possible, as for example Mordred from
- XMordor (Lord of the Rings), the Ring Wraiths, etc. I think reincarnation,
- Xperhaps with some penalty, would be I think reasonable. (Me, I cheat with
- Xbackups, to learn, try things that if I knew I couldn't get back I just
- Xwouldn't do, and therefore wouldn't have that particular fun, etc).
- X If one thing is over-powerful, it's perhaps bashing for good characters.
- XWhen I am REALLY ready to take on the balrog, (not try it for FUN with a worse
- Xcharacter), I accomplish his demise, fully loaded with mana, equipment, etc,
- Xnone of which I need or use, and he dies without ever touching me. Of course
- Xthis takes searching for months for enough speed, but bashing is the secret
- X(as I know you know) and reduces the game to trivial at that point. (3 AMHD's
- Xat one time, all always stunned, none ever hurting you; that's an example).
- X
- X My main points in this letter are Priests and others need Identify or stores
- Xmust keep scrolls, to be fun, and stores should stock better, more expensive
- Xthings as one progresses.
- X Thanks for maintaining such a good program, one of the most
- X addictive I know.
- XDale Forsyth (45 yr-old game addict) qqc@h.cc.purdue.edu
- X
- XFrom ucbvax!tut.cis.ohio-state.edu!cs.utexas.edu!yale!cs.yale.edu
- XStatus: RO
- X
- XArticle 4187 of rec.games.moria:
- XPath: ucbvax!tut.cis.ohio-state.edu!cs.utexas.edu!yale!cs.yale.edu!
- X>From: berman-andrew@CS.Yale.EDU (Andrew Berman)
- XNewsgroups: rec.games.moria
- XSubject: Possible Enhancements
- XMessage-ID: <12615@cs.yale.edu>
- XDate: 24 Jan 90 03:52:46 GMT
- XSender: news@cs.yale.edu
- XReply-To: berman-andrew@CS.Yale.EDU (Andrew Berman)
- XOrganization: Yale University Computer Science Dept, New Haven CT 06520-2158
- XLines: 47
- X
- X
- XI've been playing moria off and on for several years, only recently with
- Xversion 4.87. I have some suggestions which I'd like input on. Most of
- Xthem would make the game *harder*, but would also increase the power
- Xand attractiveness of some classes, like the fighter, which don't get
- Xused as often.
- X
- XThe first suggestion is to give fighters limited poison
- Ximmunity. Let them take a % damage which diminishes with their level,
- Xup to, say 1/2 damage for a level 39 character. So they won't get
- Xblown away like other characters by AMHD. They have enough problems
- Xas it is. And it's somewhat consistent- a fighters training may
- Xinclude ducking blasts, holding their breath, keeping their skin from
- Xbeing exposed, etc...
- X
- XThe second suggestion is to limit the power of the "cure poison" *spell*
- Xof the mages and priests. Right now, you can fight a black mamba and
- Xkill it without looking at your stats, because a simple relatively low
- Xlevel spell will eliminate any future problems. Keep the potion as
- Xcurrently powered, though.
- X
- X
- X
- XThe third suggestion is to limit weapons and Armor based on character class,
- Xlike in D & D. I see no reason to allow a Priest full use of an Executioner's
- Xsword, no matter what his/her strength/dex. If a Priest uses an edged
- Xweapon, have some sort of minus. If a Mage tries to cast a spell through
- XPlate Armor, decrease chance of success. If a Rogue uses a dagger, give
- Xa +3 to hit bonus. Fighters and Paladins can use anything. Rangers get
- Xdouble damage with bows. Something like that.
- X
- XMy fourth suggestion is to limit max stats based on character race and
- Xmaybe on character class.
- X
- XThe point of the previous two suggestions is to eliminate the
- Xdemigodlike character, a 250 hitpoint, 4-hits-per-round-with-a-Beaked-Axe,
- Xarmor class of 58 character elven mage.
- X
- XMy fifth suggestion is to allow "disenchanting" creatures to occasionally
- Xzap an ego weapon, low probability, but maybe "you hear your longsword scream
- Xin agony" as it goes from an HA to zip.
- X
- XMy sixth suggestion is to give critical hits to monsters. Let a Bezerker
- Xoccasionally get a good one in for triple damage. Let a touch have
- Xa 5% chance of being a grasp for double drain..
- X
- XAny comments?
- X
- X
- XFrom ucbvax!decwrl!lll-winken!uwm.edu!cs.utexas.edu!tut.cis.ohio-state.edu
- XStatus: RO
- X
- XArticle 4188 of rec.games.moria:
- XPath: ucbvax!decwrl!lll-winken!uwm.edu!cs.utexas.edu!tut.cis.ohio-state.edu
- X>From: mf2t+@andrew.cmu.edu (Matthew David Fletcher)
- XNewsgroups: rec.games.moria
- XSubject: Re: Possible Enhancements
- XMessage-ID: <YZjHVGi00XM101NVNs@andrew.cmu.edu>
- XDate: 24 Jan 90 05:08:34 GMT
- XReferences: <12615@cs.yale.edu>
- XOrganization: Carnegie Mellon, Pittsburgh, PA
- XLines: 35
- XIn-Reply-To: <12615@cs.yale.edu>
- X
- Xberman-andrew@CS.Yale.EDU (Andrew Berman) writes:
- X
- X>The first suggestion is to give fighters limited poison
- X>immunity. Let them take a % damage which diminishes with their level,
- X>up to, say 1/2 damage for a level 39 character. So they won't get
- X>blown away like other characters by AMHD. They have enough problems
- X>as it is. And it's somewhat consistent- a fighters training may
- X>include ducking blasts, holding their breath, keeping their skin from
- X>being exposed, etc...
- X>
- X>The second suggestion is to limit the power of the "cure poison" *spell*
- X>of the mages and priests. Right now, you can fight a black mamba and
- X>kill it without looking at your stats, because a simple relatively low
- X>level spell will eliminate any future problems. Keep the potion as
- X>currently powered, though.
- X
- XMy current character is a twenty third level half-troll warrior. The
- Xonly time I've come close to dying while being poisoned was when the
- XStone Giant came up and started pounding me half way through. Certain
- Xraces are naturally suited to certain classes by virtue of their
- Xbeginning stats.
- X
- XAre mages capable of casting spells while afraid. If so, a natural
- Xresistance to fear would make it more even. A ghost almost killed me a
- Xwhile ago, because I couldn't attack it.
- X
- X>My fifth suggestion is to allow "disenchanting" creatures to occasionally
- X>zap an ego weapon, low probability, but maybe "you hear your longsword scream
- X>in agony" as it goes from an HA to zip.
- X
- XThis could be rather expensive, considering the cost of all the computer
- Xequipment that would be destroyed when a person's dagger (HA) (+8,+8)
- Xgets zapped.
- X
- X Fletch
- X
- X
- XFrom ucbvax!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!unix.cis.p
- XStatus: RO
- X
- XArticle 4193 of rec.games.moria:
- XPath: ucbvax!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!unix.cis.
- X>From: dtate@unix.cis.pitt.edu (David M Tate)
- XNewsgroups: rec.games.moria
- XSubject: Re: Possible Enhancements
- XMessage-ID: <21833@unix.cis.pitt.edu>
- XDate: 24 Jan 90 17:00:57 GMT
- XReferences: <12615@cs.yale.edu>
- XReply-To: dtate@unix.cis.pitt.edu (David M Tate)
- XOrganization: Univ. of Pittsburgh, Comp & Info Services
- XLines: 35
- X
- XAndrew Berman lists a number of possible enhancements for later versions of
- XMoria. Some of them, I think, bear serious consideration.
- X
- XIn particular, I think that the idea of distinguishing various character
- Xclasses even more sharply is a good one. I agree wholeheartedly that the only
- Xweapons usable by a priest should be mace/morningstar/hammer/club/flail types.
- XNo one but a fighter, paladin, or ranger should be able to wield a 2-handed
- Xsword or Executioner's Sword. No matter how strong a mage gets, he should not
- Xbe able to fight effectively with anything heavy, nor able to cast spells
- Xeffectively while wearing heavy armor.
- X
- XOne way to reduce the mage/ranger advantage would be to implement a "setup
- Xcost" for the switch between magic mode and fighting mode: you can't cast a
- Xspell in the round immediately following a slash/fire move. This makes some
- Xsense, as one would in general have to "prepare" a spell before casting it.
- XSimilarly, one would expect the act of praying to take some finite time.
- X(For that matter,eating should take some time--a character interrupted while
- Xeating would have the option of finishing the meal (while getting stomped) or
- Xabandoning it (in which case the remainder is lost--trampled in battle, or
- Xsome such).
- X
- XOne touch of realism that I would like to see is more more NPC's to pick up
- Xthings. I know this can be done, because ghosts do it already. Can you
- Xreally imagine a hobgoblin coming into a room and *not* picking up the gold
- Xand gems? This would add the challenge of preserving items to the character.
- X
- XSimilarly, why can't you get your stolen gold back from a dead rogue? What
- Xdid he do with it? Hide it? If you're a rogue yourself, you should be able
- Xto (a) keep him from picking your pocket, and (b) find where he hid it.
- X
- XJust a few ramblings...
- X
- X--
- X==============================================================================
- X David M. Tate | "I do not know which to prefer: the beauty
- X dtate@unix.cis.pitt.edu | of inflections, or the beauty of innuendoes;
- X | the blackbird whistling, or just after..."
- X
- X
- XFrom 73230.224@compuserve.com Tue Jan 30 11:46:30 1990
- XReceived: from saqqara.cis.ohio-state.edu by ernie.Berkeley.EDU (5.61/1.36)
- X id AA23367; Tue, 30 Jan 90 11:46:14 -0800
- XReceived: by saqqara.cis.ohio-state.edu (5.61/4.891221)
- X id AA09041; Tue, 30 Jan 90 14:45:48 -0500
- XDate: 30 Jan 90 12:41:49 EST
- XFrom: Curtis McCauley <73230.224@CompuServe.COM>
- XTo: <wilson@ernie.Berkeley.EDU>
- XSubject: Umoria 5.0.13 disks mailed
- XMessage-Id: <"900130174148 73230.224 EHA20-1"@CompuServe.COM>
- XStatus: RO
- X
- XTo: >INTERNET:wilson@ernie.Berkeley.EDU
- XI mailed you the sources either Monday or Tuesday of last week. I can't
- Xremember which day for sure. I used regular mail, so it may take some time.
- XThe mailing required two diskettes, one for the source, the other for a
- Xcompiled version of the game. Do you have access to MPW 3.0? You will need
- Xit to compile. I don't think that THINK C could be used very easily in place
- Xof MPW. I rely pretty heavily on the MPW environment to make the program.
- X
- XWhile I'm thinking about it, there are a couple of principles which, if
- Xobserved in all parts of the code, would make the mac port easier and less
- Xof a hack:
- X
- X1) Don't modify a variable which is initialized in its declaration (e.g.,
- X"int foo_flag = TRUE"). I had to try to find all of these in order to make
- Xthe game restartable.
- X
- X2) Don't rely on the value of a variable which is not initialized in its
- Xdeclaration being zero. For example, get_panel() forces the panel to be
- Xredrawn the first time it is called in the course of a game because
- Xpanel_[row/col]_[min/max] are all zero. In the mac version, when the game is
- Xrestarted, these variables have the values left over from the previous game.
- XI do with them what I do with the variables which fall under 1 above: I keep
- Xtheir "initialized" value in a resource and restore them each time a game is
- Xrestarted.
- X
- X3) (This follows a fortiori from 1 above.) Don't modify a private variable
- Xwhich is initialized in its declaration. These I had to move from the source
- Xfiles in which they were declared to variables.c and externs.h in order to
- Xmake them accessible for the routines which build the restart resource and
- Xcopy the saved data when a new game is started.
- X
- XAdmittedly, there is some inconvience involved in following these rules. It's
- Xa judgement call.
- X
- XThe version I have given you "hilights" the veins instead of using '%'. I
- Xdidn't discover that you had given up on hilighting until after I had ported
- Xio.c to allow it. So I figured I'd leave it in. I discovered after I had
- Xsent you the game that this causes the map command to screw up because it
- Xdoesn't know how to handle -'#'. What do you think? Remove the hilighting
- Xcapability or fix the map command to handle it?
- X
- XYou might want to consider the possibility of having two mac file types for
- Xsave files: one for living characters, another for dead characters' memories.
- XThis way the two files will be distinguishable by their icons. (Perhaps a
- Xtombstone as the latter type of icon.)
- X
- XDo we want to get a new application signature from Apple? I'd prefer not to,
- Xbut there likely will be problems for people who try to keep the old version
- Xaround on their disks. For example, I am not certain which program will come
- Xup if the user double clicks on a save file from the finder when he has both
- Xcopies of the game on his disk. Maybe this can be handled by simply telling
- Xthe player to throw away his old version in the mac help text.
- X
- XI do not like the way the game "flows" at the end, particularly the standard
- Xfile dialog which prompts for saving the player's memories. It seems kind of
- Xintrusive. I do not know how things will change when the top ten is added.
- XAlso, there is a problem with the prompt in this dialog box. In save_char() I
- Xtry to say "Save your memories as:" instead of "Save the game as:" when I
- Xthink the player has died or quit. This doesn't always work right. Sometimes
- Xit says "memories" when it should say "game". This always happens when ^X is
- Xused to save the game. I have fixed that problem since I sent you the source.
- XAnother problem remains: I rely upon the variable death to decide which
- Xprompt to choose. This will not work when the player quits the character.
- XDeath is not set, yet only the memories will get saved, right? In the version
- Xyou have, I have the two prompts switched in save_char(). So, you get the
- X"memories" prompt when you quit and the "game" prompt when you are killed.
- X
- XFinally, do female dwarves really have beards? Ugh.
- X
- X-Curtis (73230.224@compuserve.com)
- X
- X
- XFrom chinet!saj@gargoyle.uchicago.edu Mon Feb 5 23:29:25 1990
- XReceived: from gargoyle.uchicago.edu by ernie.Berkeley.EDU (5.61/1.36)
- X id AA00727; Mon, 5 Feb 90 23:29:21 -0800
- XReceived: by gargoyle.uchicago.edu (5.59/1.14)
- X id AA06383; Tue, 6 Feb 90 01:28:53 199
- XReceived: by chinet.chi.il.us (/\=-/\ Smail3.1.18.1 #18.65)
- X id <m0gvOff-0002kbC@chinet.chi.il.us>; Tue, 6 Feb 90 00:27 CST
- XMessage-Id: <m0gvOff-0002kbC@chinet.chi.il.us>
- XFrom: saj@chinet.chi.il.us (Stephen Jacobs)
- XSubject: Source arrived today
- XTo: ernie.Berkeley.EDU!wilson@gargoyle.uchicago.edu (James E. Wilson)
- XDate: Tue, 6 Feb 90 0:27:26 CST
- XIn-Reply-To: <9002020111.AA22413@ernie.Berkeley.EDU>; from "James E. Wilson"
- XX-Mailer: ELM [version 2.2 PL16]
- XStatus: RO
- X
- XThe source arrived today. Thanks. I've barely begun to scan it, but I'd
- Xguess that there shouldn't be any special problems bringing it up on the
- XST. One immediate suggestion: the Mark Williams C compiler defines the
- Xmacro GEMDOS, and defines the macro __STDC__ to be 0. Using those as
- Xconditions could make recognition of the situation automatic.
- X
- X Steve J.
- X
- X
- END_OF_FILE
- if test 21386 -ne `wc -c <'misc/mail.msg'`; then
- echo shar: \"'misc/mail.msg'\" unpacked with wrong size!
- fi
- # end of 'misc/mail.msg'
- fi
- if test -f 'source/moria4.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'source/moria4.c'\"
- else
- echo shar: Extracting \"'source/moria4.c'\" \(31210 characters\)
- sed "s/^X//" >'source/moria4.c' <<'END_OF_FILE'
- X/* source/moria4.c: misc code, mainly to handle player commands
- X
- X Copyright (c) 1989-92 James E. Wilson, Robert A. Koeneke
- X
- X This software may be copied and distributed for educational, research, and
- X not for profit purposes provided that this copyright and statement are
- X included in all such copies. */
- X
- X#ifdef __TURBOC__
- X#include <stdio.h>
- X#include <stdlib.h>
- X#endif
- X
- X#include "config.h"
- X#include "constant.h"
- X#include "types.h"
- X#include "externs.h"
- X
- X#ifdef USG
- X#ifndef ATARIST_MWC
- X#include <string.h>
- X#endif
- X#else
- X#include <strings.h>
- X#endif
- X
- X#include <ctype.h>
- X
- X
- X#if defined(LINT_ARGS)
- Xstatic int look_ray(int, int, int);
- Xstatic int look_see(int, int, int *);
- Xstatic void inven_throw(int, struct inven_type *);
- Xstatic void facts(struct inven_type *, int *, int *, int *, int *);
- Xstatic void drop_throw(int, int, struct inven_type *);
- Xstatic void py_bash(int, int);
- X#else
- Xstatic int look_ray();
- Xstatic int look_see();
- X#endif
- X
- X
- X/* Tunnels through rubble and walls -RAK- */
- X/* Must take into account: secret doors, special tools */
- Xvoid tunnel(dir)
- Xint dir;
- X{
- X register int i, tabil;
- X register cave_type *c_ptr;
- X register inven_type *i_ptr;
- X int y, x;
- X monster_type *m_ptr;
- X vtype out_val, m_name;
- X#ifdef ATARIST_MWC
- X int32u holder;
- X#endif
- X
- X if ((py.flags.confused > 0) && /* Confused? */
- X (randint(4) > 1)) /* 75% random movement */
- X dir = randint(9);
- X y = char_row;
- X x = char_col;
- X (void) mmove(dir, &y, &x);
- X
- X c_ptr = &cave[y][x];
- X /* Compute the digging ability of player; based on */
- X /* strength, and type of tool used */
- X tabil = py.stats.use_stat[A_STR];
- X i_ptr = &inventory[INVEN_WIELD];
- X
- X /* Don't let the player tunnel somewhere illegal, this is necessary to
- X prevent the player from getting a free attack by trying to tunnel
- X somewhere where it has no effect. */
- X if (c_ptr->fval < MIN_CAVE_WALL
- X && (c_ptr->tptr == 0 || (t_list[c_ptr->tptr].tval != TV_RUBBLE
- X && t_list[c_ptr->tptr].tval != TV_SECRET_DOOR)))
- X {
- X if (c_ptr->tptr == 0)
- X {
- X msg_print ("Tunnel through what? Empty air?!?");
- X free_turn_flag = TRUE;
- X }
- X else
- X {
- X msg_print("You can't tunnel through that.");
- X free_turn_flag = TRUE;
- X }
- X return;
- X }
- X
- X if (c_ptr->cptr > 1)
- X {
- X m_ptr = &m_list[c_ptr->cptr];
- X if (m_ptr->ml)
- X (void) sprintf (m_name, "The %s", c_list[m_ptr->mptr].name);
- X else
- X (void) strcpy (m_name, "Something");
- X (void) sprintf(out_val, "%s is in your way!", m_name);
- X msg_print(out_val);
- X
- X /* let the player attack the creature */
- X if (py.flags.afraid < 1)
- X py_attack(y, x);
- X else
- X msg_print("You are too afraid!");
- X }
- X else if (i_ptr->tval != TV_NOTHING)
- X {
- X#ifdef ATARIST_MWC
- X if ((holder = TR_TUNNEL) & i_ptr->flags)
- X#else
- X if (TR_TUNNEL & i_ptr->flags)
- X#endif
- X tabil += 25 + i_ptr->p1*50;
- X else
- X {
- X tabil += (i_ptr->damage[0]*i_ptr->damage[1]) + i_ptr->tohit
- X + i_ptr->todam;
- X /* divide by two so that digging without shovel isn't too easy */
- X tabil >>= 1;
- X }
- X
- X /* If this weapon is too heavy for the player to wield properly, then
- X also make it harder to dig with it. */
- X
- X if (weapon_heavy)
- X {
- X tabil += (py.stats.use_stat[A_STR] * 15) - i_ptr->weight;
- X if (tabil < 0)
- X tabil = 0;
- X }
- X
- X /* Regular walls; Granite, magma intrusion, quartz vein */
- X /* Don't forget the boundary walls, made of titanium (255)*/
- X switch(c_ptr->fval)
- X {
- X case GRANITE_WALL:
- X i = randint(1200) + 80;
- X if (twall(y, x, tabil, i))
- X msg_print("You have finished the tunnel.");
- X else
- X count_msg_print("You tunnel into the granite wall.");
- X break;
- X case MAGMA_WALL:
- X i = randint(600) + 10;
- X if (twall(y, x, tabil, i))
- X msg_print("You have finished the tunnel.");
- X else
- X count_msg_print("You tunnel into the magma intrusion.");
- X break;
- X case QUARTZ_WALL:
- X i = randint(400) + 10;
- X if (twall(y, x, tabil, i))
- X msg_print("You have finished the tunnel.");
- X else
- X count_msg_print("You tunnel into the quartz vein.");
- X break;
- X case BOUNDARY_WALL:
- X msg_print("This seems to be permanent rock.");
- X break;
- X default:
- X /* Is there an object in the way? (Rubble and secret doors)*/
- X if (c_ptr->tptr != 0)
- X {
- X /* Rubble. */
- X if (t_list[c_ptr->tptr].tval == TV_RUBBLE)
- X {
- X if (tabil > randint(180))
- X {
- X (void) delete_object(y, x);
- X msg_print("You have removed the rubble.");
- X if (randint(10) == 1)
- X {
- X place_object(y, x);
- X if (test_light(y, x))
- X msg_print("You have found something!");
- X }
- X lite_spot(y, x);
- X }
- X else
- X count_msg_print("You dig in the rubble.");
- X }
- X /* Secret doors.*/
- X else if (t_list[c_ptr->tptr].tval == TV_SECRET_DOOR)
- X {
- X count_msg_print("You tunnel into the granite wall.");
- X search(char_row, char_col, py.misc.srh);
- X }
- X else
- X abort ();
- X }
- X else
- X abort ();
- X break;
- X }
- X }
- X else
- X msg_print("You dig with your hands, making no progress.");
- X}
- X
- X
- X/* Disarms a trap -RAK- */
- Xvoid disarm_trap()
- X{
- X int y, x, level, tmp, dir, no_disarm;
- X register int tot, i;
- X register cave_type *c_ptr;
- X register inven_type *i_ptr;
- X monster_type *m_ptr;
- X vtype m_name, out_val;
- X
- X y = char_row;
- X x = char_col;
- X if (get_dir(CNIL, &dir))
- X {
- X (void) mmove(dir, &y, &x);
- X c_ptr = &cave[y][x];
- X no_disarm = FALSE;
- X if (c_ptr->cptr > 1 && c_ptr->tptr != 0 &&
- X (t_list[c_ptr->tptr].tval == TV_VIS_TRAP
- X || t_list[c_ptr->tptr].tval == TV_CHEST))
- X {
- X m_ptr = &m_list[c_ptr->cptr];
- X if (m_ptr->ml)
- X (void) sprintf (m_name, "The %s", c_list[m_ptr->mptr].name);
- X else
- X (void) strcpy (m_name, "Something");
- X (void) sprintf(out_val, "%s is in your way!", m_name);
- X msg_print(out_val);
- X }
- X else if (c_ptr->tptr != 0)
- X {
- X tot = py.misc.disarm + 2*todis_adj() + stat_adj(A_INT)
- X + (class_level_adj[py.misc.pclass][CLA_DISARM] * py.misc.lev / 3);
- X if ((py.flags.blind > 0) || (no_light()))
- X tot = tot / 10;
- X if (py.flags.confused > 0)
- X tot = tot / 10;
- X if (py.flags.image > 0)
- X tot = tot / 10;
- X i_ptr = &t_list[c_ptr->tptr];
- X i = i_ptr->tval;
- X level = i_ptr->level;
- X if (i == TV_VIS_TRAP) /* Floor trap */
- X {
- X if ((tot + 100 - level) > randint(100))
- X {
- X msg_print("You have disarmed the trap.");
- X py.misc.exp += i_ptr->p1;
- X (void) delete_object(y, x);
- X /* make sure we move onto the trap even if confused */
- X tmp = py.flags.confused;
- X py.flags.confused = 0;
- X move_char(dir, FALSE);
- X py.flags.confused = tmp;
- X prt_experience();
- X }
- X /* avoid randint(0) call */
- X else if ((tot > 5) && (randint(tot) > 5))
- X count_msg_print("You failed to disarm the trap.");
- X else
- X {
- X msg_print("You set the trap off!");
- X /* make sure we move onto the trap even if confused */
- X tmp = py.flags.confused;
- X py.flags.confused = 0;
- X move_char(dir, FALSE);
- X py.flags.confused += tmp;
- X }
- X }
- X else if (i == TV_CHEST)
- X {
- X if (!known2_p(i_ptr))
- X {
- X msg_print("I don't see a trap.");
- X free_turn_flag = TRUE;
- X }
- X else if (CH_TRAPPED & i_ptr->flags)
- X {
- X if ((tot - level) > randint(100))
- X {
- X i_ptr->flags &= ~CH_TRAPPED;
- X if (CH_LOCKED & i_ptr->flags)
- X i_ptr->name2 = SN_LOCKED;
- X else
- X i_ptr->name2 = SN_DISARMED;
- X msg_print("You have disarmed the chest.");
- X known2(i_ptr);
- X py.misc.exp += level;
- X prt_experience();
- X }
- X else if ((tot > 5) && (randint(tot) > 5))
- X count_msg_print("You failed to disarm the chest.");
- X else
- X {
- X msg_print("You set a trap off!");
- X known2(i_ptr);
- X chest_trap(y, x);
- X }
- X }
- X else
- X {
- X msg_print("The chest was not trapped.");
- X free_turn_flag = TRUE;
- X }
- X }
- X else
- X no_disarm = TRUE;
- X }
- X else
- X no_disarm = TRUE;
- X
- X if (no_disarm)
- X {
- X msg_print("I do not see anything to disarm there.");
- X free_turn_flag = TRUE;
- X }
- X }
- X}
- X
- X
- X/* An enhanced look, with peripheral vision. Looking all 8 -CJS-
- X directions will see everything which ought to be visible. Can
- X specify direction 5, which looks in all directions.
- X
- X For the purpose of hindering vision, each place is regarded as
- X a diamond just touching its four immediate neighbours. A
- X diamond is opaque if it is a wall, or shut door, or something
- X like that. A place is visible if any part of its diamond is
- X visible: i.e. there is a line from the view point to part of
- X the diamond which does not pass through any opaque diamonds.
- X
- X Consider the following situation:
- X
- X @.... X X X X X
- X .##.. / \ / \ / \ / \ / \
- X ..... X @ X . X . X 1 X . X
- X \ / \ / \ / \ / \ /
- X X X X X X
- X Expanded view, with / \ / \ / \ / \ / \
- X diamonds inscribed X . X # X # X 2 X . X
- X about each point, \ / \ / \ / \ / \ /
- X and some locations X X X X X
- X numbered. / \ / \ / \ / \ / \
- X X . X . X . X 3 X 4 X
- X \ / \ / \ / \ / \ /
- X X X X X X
- X - Location 1 is fully visible.
- X - Location 2 is visible, even though partially obscured.
- X - Location 3 is invisible, but if either # were
- X transparent, it would be visible.
- X - Location 4 is completely obscured by a single #.
- X
- X The function which does the work is look_ray. It sets up its
- X own co-ordinate frame (global variables map back to the
- X dungeon frame) and looks for everything between two angles
- X specified from a central line. It is recursive, and each call
- X looks at stuff visible along a line parallel to the center
- X line, and a set distance away from it. A diagonal look uses
- X more extreme peripheral vision from the closest horizontal and
- X vertical directions; horizontal or vertical looks take a call
- X for each side of the central line. */
- X
- X/* Globally accessed variables: gl_nseen counts the number of places where
- X something is seen. gl_rock indicates a look for rock or objects.
- X
- X The others map co-ords in the ray frame to dungeon co-ords.
- X
- X dungeon y = char_row + gl_fyx * (ray x) + gl_fyy * (ray y)
- X dungeon x = char_col + gl_fxx * (ray x) + gl_fxy * (ray y) */
- Xstatic int gl_fxx, gl_fxy, gl_fyx, gl_fyy;
- Xstatic int gl_nseen, gl_noquery;
- Xstatic int gl_rock;
- X/* Intended to be indexed by dir/2, since is only relevant to horizontal or
- X vertical directions. */
- Xstatic int set_fxy[] = { 0, 1, 0, 0, -1 };
- Xstatic int set_fxx[] = { 0, 0, -1, 1, 0 };
- Xstatic int set_fyy[] = { 0, 0, 1, -1, 0 };
- Xstatic int set_fyx[] = { 0, 1, 0, 0, -1 };
- X/* Map diagonal-dir/2 to a normal-dir/2. */
- Xstatic int map_diag1[] = { 1, 3, 0, 2, 4 };
- Xstatic int map_diag2[] = { 2, 1, 0, 4, 3 };
- X
- X#define GRADF 10000 /* Any sufficiently big number will do */
- X
- X/* Look at what we can see. This is a free move.
- X
- X Prompts for a direction, and then looks at every object in
- X turn within a cone of vision in that direction. For each
- X object, the cursor is moved over the object, a description is
- X given, and we wait for the user to type something. Typing
- X ESCAPE will abort the entire look.
- X
- X Looks first at real objects and monsters, and looks at rock
- X types only after all other things have been seen. Only looks at rock
- X types if the highlight_seams option is set. */
- X
- Xvoid look()
- X{
- X register int i, abort;
- X int dir, dummy;
- X
- X if (py.flags.blind > 0)
- X msg_print("You can't see a damn thing!");
- X else if (py.flags.image > 0)
- X msg_print("You can't believe what you are seeing! It's like a dream!");
- X else if (get_alldir("Look which direction?", &dir))
- X {
- X abort = FALSE;
- X gl_nseen = 0;
- X gl_rock = 0;
- X gl_noquery = FALSE; /* Have to set this up for the look_see */
- X if (look_see(0, 0, &dummy))
- X abort = TRUE;
- X else
- X {
- X do
- X {
- X abort = FALSE;
- X if (dir == 5)
- X {
- X for (i = 1; i <= 4; i++)
- X {
- X gl_fxx = set_fxx[i]; gl_fyx = set_fyx[i];
- X gl_fxy = set_fxy[i]; gl_fyy = set_fyy[i];
- X if (look_ray(0, 2*GRADF-1, 1))
- X {
- X abort = TRUE;
- X break;
- X }
- X gl_fxy = -gl_fxy;
- X gl_fyy = -gl_fyy;
- X if (look_ray(0, 2*GRADF, 2))
- X {
- X abort = TRUE;
- X break;
- X }
- X }
- X }
- X else if ((dir & 1) == 0) /* Straight directions */
- X {
- X i = dir >> 1;
- X gl_fxx = set_fxx[i]; gl_fyx = set_fyx[i];
- X gl_fxy = set_fxy[i]; gl_fyy = set_fyy[i];
- X if (look_ray(0, GRADF, 1))
- X abort = TRUE;
- X else
- X {
- X gl_fxy = -gl_fxy;
- X gl_fyy = -gl_fyy;
- X abort = look_ray(0, GRADF, 2);
- X }
- X }
- X else
- X {
- X i = map_diag1[dir >> 1];
- X gl_fxx = set_fxx[i]; gl_fyx = set_fyx[i];
- X gl_fxy = -set_fxy[i]; gl_fyy = -set_fyy[i];
- X if (look_ray(1, 2*GRADF, GRADF))
- X abort = TRUE;
- X else
- X {
- X i = map_diag2[dir >> 1];
- X gl_fxx = set_fxx[i]; gl_fyx = set_fyx[i];
- X gl_fxy = set_fxy[i]; gl_fyy = set_fyy[i];
- X abort = look_ray(1, 2*GRADF-1, GRADF);
- X }
- X }
- X }
- X while (abort == FALSE && highlight_seams && (++gl_rock < 2));
- X if (abort)
- X msg_print("--Aborting look--");
- X else
- X {
- X if (gl_nseen)
- X {
- X if (dir == 5)
- X msg_print("That's all you see.");
- X else
- X msg_print("That's all you see in that direction.");
- X }
- X else if (dir == 5)
- X msg_print("You see nothing of interest.");
- X else
- X msg_print("You see nothing of interest in that direction.");
- X }
- X }
- X }
- X}
- X
- X/* Look at everything within a cone of vision between two ray
- X lines emanating from the player, and y or more places away
- X from the direct line of view. This is recursive.
- X
- X Rays are specified by gradients, y over x, multiplied by
- X 2*GRADF. This is ONLY called with gradients between 2*GRADF
- X (45 degrees) and 1 (almost horizontal).
- X
- X (y axis)/ angle from
- X ^ / ___ angle to
- X | / ___
- X ...|../.....___.................... parameter y (look at things in the
- X | / ___ cone, and on or above this line)
- X |/ ___
- X @--------------------> direction in which you are looking. (x axis)
- X |
- X | */
- Xstatic int look_ray(y, from, to)
- Xint y, from, to;
- X{
- X register int max_x, x;
- X int transparent;
- X
- X /* from is the larger angle of the ray, since we scan towards the
- X center line. If from is smaller, then the ray does not exist. */
- X if (from <= to || y > MAX_SIGHT)
- X return FALSE;
- X /* Find first visible location along this line. Minimum x such
- X that (2x-1)/x < from/GRADF <=> x > GRADF(2x-1)/from. This may
- X be called with y=0 whence x will be set to 0. Thus we need a
- X special fix. */
- X x = (int)((long)GRADF * (2 * y - 1) / from + 1);
- X if (x <= 0)
- X x = 1;
- X
- X /* Find last visible location along this line.
- X Maximum x such that (2x+1)/x > to/GRADF <=> x < GRADF(2x+1)/to */
- X max_x = (int)(((long)GRADF * (2 * y + 1) - 1) / to);
- X if (max_x > MAX_SIGHT)
- X max_x = MAX_SIGHT;
- X if (max_x < x)
- X return FALSE;
- X
- X /* gl_noquery is a HACK to prevent doubling up on direct lines of
- X sight. If 'to' is greater than 1, we do not really look at
- X stuff along the direct line of sight, but we do have to see
- X what is opaque for the purposes of obscuring other objects. */
- X if (y == 0 && to > 1 || y == x && from < GRADF*2)
- X gl_noquery = TRUE;
- X else
- X gl_noquery = FALSE;
- X if (look_see(x, y, &transparent))
- X return TRUE;
- X if (y == x)
- X gl_noquery = FALSE;
- X if (transparent)
- X goto init_transparent;
- X
- X for (;;)
- X {
- X /* Look down the window we've found. */
- X if (look_ray(y+1, from, (int)((2 * y + 1) * (long)GRADF / x)))
- X return TRUE;
- X /* Find the start of next window. */
- X do
- X {
- X if (x == max_x)
- X return FALSE;
- X /* See if this seals off the scan. (If y is zero, then it will.) */
- X from = (int)((2 * y - 1) * (long)GRADF / x);
- X if (from <= to)
- X return FALSE;
- X x++;
- X if (look_see(x, y, &transparent))
- X return TRUE;
- X }
- X while(!transparent);
- X init_transparent:
- X /* Find the end of this window of visibility. */
- X do
- X {
- X if (x == max_x)
- X /* The window is trimmed by an earlier limit. */
- X return look_ray(y+1, from, to);
- X x++;
- X if (look_see(x, y, &transparent))
- X return TRUE;
- X }
- X while(transparent);
- X }
- X}
- X
- Xstatic int look_see(x, y, transparent)
- Xregister int x, y;
- Xint *transparent;
- X{
- X char *dstring, *string, query;
- X register cave_type *c_ptr;
- X register int j;
- X bigvtype out_val, tmp_str;
- X
- X if (x < 0 || y < 0 || y > x)
- X {
- X (void) sprintf(tmp_str, "Illegal call to look_see(%d, %d)", x, y);
- X msg_print(tmp_str);
- X }
- X if (x == 0 && y == 0)
- X dstring = "You are on";
- X else
- X dstring = "You see";
- X j = char_col + gl_fxx * x + gl_fxy * y;
- X y = char_row + gl_fyx * x + gl_fyy * y;
- X x = j;
- X if (!panel_contains(y, x))
- X {
- X *transparent = FALSE;
- X return FALSE;
- X }
- X c_ptr = &cave[y][x];
- X *transparent = c_ptr->fval <= MAX_OPEN_SPACE;
- X if (gl_noquery)
- X return FALSE; /* Don't look at a direct line of sight. A hack. */
- X out_val[0] = 0;
- X if (gl_rock == 0 && c_ptr->cptr > 1 && m_list[c_ptr->cptr].ml)
- X {
- X j = m_list[c_ptr->cptr].mptr;
- X (void) sprintf(out_val, "%s %s %s. [(r)ecall]",
- X dstring,
- X is_a_vowel( c_list[j].name[0] ) ? "an" : "a",
- X c_list[j].name);
- X dstring = "It is on";
- X prt(out_val, 0, 0);
- X move_cursor_relative(y, x);
- X query = inkey();
- X if (query == 'r' || query == 'R')
- X {
- X save_screen();
- X query = roff_recall(j);
- X restore_screen();
- X }
- X }
- X if (c_ptr->tl || c_ptr->pl || c_ptr->fm)
- X {
- X if (c_ptr->tptr != 0)
- X {
- X if (t_list[c_ptr->tptr].tval == TV_SECRET_DOOR)
- X goto granite;
- X if (gl_rock ==0 && t_list[c_ptr->tptr].tval != TV_INVIS_TRAP)
- X {
- X objdes(tmp_str, &t_list[c_ptr->tptr], TRUE);
- X (void) sprintf(out_val, "%s %s ---pause---", dstring, tmp_str);
- X dstring = "It is in";
- X prt(out_val, 0, 0);
- X move_cursor_relative(y, x);
- X query = inkey();
- X }
- X }
- X if ((gl_rock || out_val[0]) && c_ptr->fval >= MIN_CLOSED_SPACE)
- X {
- X switch(c_ptr->fval)
- X {
- X case BOUNDARY_WALL:
- X case GRANITE_WALL:
- X granite:
- X /* Granite is only interesting if it contains something. */
- X if(out_val[0])
- X string = "a granite wall";
- X else
- X string = CNIL; /* In case we jump here */
- X break;
- X case MAGMA_WALL: string = "some dark rock";
- X break;
- X case QUARTZ_WALL: string = "a quartz vein";
- X break;
- X default: string = CNIL;
- X break;
- X }
- X if (string)
- X {
- X (void) sprintf(out_val, "%s %s ---pause---", dstring, string);
- X prt(out_val, 0, 0);
- X move_cursor_relative(y, x);
- X query = inkey();
- X }
- X }
- X }
- X if (out_val[0])
- X {
- X gl_nseen++;
- X if (query == ESCAPE)
- X return TRUE;
- X }
- X
- X return FALSE;
- X}
- X
- X
- Xstatic void inven_throw(item_val, t_ptr)
- Xint item_val;
- Xinven_type *t_ptr;
- X{
- X register inven_type *i_ptr;
- X#ifdef ATARIST_MWC
- X int32u holder;
- X#endif
- X
- X i_ptr = &inventory[item_val];
- X *t_ptr = *i_ptr;
- X if (i_ptr->number > 1)
- X {
- X t_ptr->number = 1;
- X i_ptr->number--;
- X inven_weight -= i_ptr->weight;
- X#ifdef ATARIST_MWC
- X py.flags.status |= (holder = PY_STR_WGT);
- X#else
- X py.flags.status |= PY_STR_WGT;
- X#endif
- X }
- X else
- X inven_destroy(item_val);
- X}
- X
- X
- X/* Obtain the hit and damage bonuses and the maximum distance for a
- X thrown missile. */
- Xstatic void facts(i_ptr, tbth, tpth, tdam, tdis)
- Xregister inven_type *i_ptr;
- Xint *tbth, *tpth, *tdam, *tdis;
- X{
- X register int tmp_weight;
- X
- X if (i_ptr->weight < 1)
- X tmp_weight = 1;
- X else
- X tmp_weight = i_ptr->weight;
- X
- X /* Throwing objects */
- X *tdam = pdamroll(i_ptr->damage) + i_ptr->todam;
- X *tbth = py.misc.bthb * 75 / 100;
- X *tpth = py.misc.ptohit + i_ptr->tohit;
- X
- X /* Add this back later if the correct throwing device. -CJS- */
- X if (inventory[INVEN_WIELD].tval != TV_NOTHING)
- X *tpth -= inventory[INVEN_WIELD].tohit;
- X
- X *tdis = (((py.stats.use_stat[A_STR]+20)*10)/tmp_weight);
- X if (*tdis > 10) *tdis = 10;
- X
- X /* multiply damage bonuses instead of adding, when have proper
- X missile/weapon combo, this makes them much more useful */
- X
- X /* Using Bows, slings, or crossbows */
- X if (inventory[INVEN_WIELD].tval == TV_BOW)
- X switch(inventory[INVEN_WIELD].p1)
- X {
- X case 1:
- X if (i_ptr->tval == TV_SLING_AMMO) /* Sling and ammo */
- X {
- X *tbth = py.misc.bthb;
- X *tpth += 2 * inventory[INVEN_WIELD].tohit;
- X *tdam += inventory[INVEN_WIELD].todam;
- X *tdam = *tdam * 2;
- X *tdis = 20;
- X }
- X break;
- X case 2:
- X if (i_ptr->tval == TV_ARROW) /* Short Bow and Arrow */
- X {
- X *tbth = py.misc.bthb;
- X *tpth += 2 * inventory[INVEN_WIELD].tohit;
- X *tdam += inventory[INVEN_WIELD].todam;
- X *tdam = *tdam * 2;
- X *tdis = 25;
- X }
- X break;
- X case 3:
- X if (i_ptr->tval == TV_ARROW) /* Long Bow and Arrow */
- X {
- X *tbth = py.misc.bthb;
- X *tpth += 2 * inventory[INVEN_WIELD].tohit;
- X *tdam += inventory[INVEN_WIELD].todam;
- X *tdam = *tdam * 3;
- X *tdis = 30;
- X }
- X break;
- X case 4:
- X if (i_ptr->tval == TV_ARROW) /* Composite Bow and Arrow*/
- X {
- X *tbth = py.misc.bthb;
- X *tpth += 2 * inventory[INVEN_WIELD].tohit;
- X *tdam += inventory[INVEN_WIELD].todam;
- X *tdam = *tdam * 4;
- X *tdis = 35;
- X }
- X break;
- X case 5:
- X if (i_ptr->tval == TV_BOLT) /* Light Crossbow and Bolt*/
- X {
- X *tbth = py.misc.bthb;
- X *tpth += 2 * inventory[INVEN_WIELD].tohit;
- X *tdam += inventory[INVEN_WIELD].todam;
- X *tdam = *tdam * 3;
- X *tdis = 25;
- X }
- X break;
- X case 6:
- X if (i_ptr->tval == TV_BOLT) /* Heavy Crossbow and Bolt*/
- X {
- X *tbth = py.misc.bthb;
- X *tpth += 2 * inventory[INVEN_WIELD].tohit;
- X *tdam += inventory[INVEN_WIELD].todam;
- X *tdam = *tdam * 4;
- X *tdis = 35;
- X }
- X break;
- X }
- X}
- X
- X
- Xstatic void drop_throw(y, x, t_ptr)
- Xint y, x;
- Xinven_type *t_ptr;
- X{
- X register int i, j, k;
- X int flag, cur_pos;
- X bigvtype out_val, tmp_str;
- X register cave_type *c_ptr;
- X
- X flag = FALSE;
- X i = y;
- X j = x;
- X k = 0;
- X if (randint(10) > 1)
- X {
- X do
- X {
- X if (in_bounds(i, j))
- X {
- X c_ptr = &cave[i][j];
- X if (c_ptr->fval <= MAX_OPEN_SPACE && c_ptr->tptr == 0)
- X flag = TRUE;
- X }
- X if (!flag)
- X {
- X i = y + randint(3) - 2;
- X j = x + randint(3) - 2;
- X k++;
- X }
- X }
- X while ((!flag) && (k <= 9));
- X }
- X if (flag)
- X {
- X cur_pos = popt();
- X cave[i][j].tptr = cur_pos;
- X t_list[cur_pos] = *t_ptr;
- X lite_spot(i, j);
- X }
- X else
- X {
- X objdes(tmp_str, t_ptr, FALSE);
- X (void) sprintf(out_val, "The %s disappears.", tmp_str);
- X msg_print(out_val);
- X }
- X}
- X
- X/* Throw an object across the dungeon. -RAK- */
- X/* Note: Flasks of oil do fire damage */
- X/* Note: Extra damage and chance of hitting when missiles are used*/
- X/* with correct weapon. I.E. wield bow and throw arrow. */
- Xvoid throw_object()
- X{
- X int item_val, tbth, tpth, tdam, tdis;
- X int y, x, oldy, oldx, cur_dis, dir;
- X int flag, visible;
- X bigvtype out_val, tmp_str;
- X inven_type throw_obj;
- X register cave_type *c_ptr;
- X register monster_type *m_ptr;
- X register int i;
- X char tchar;
- X
- X if (inven_ctr == 0)
- X {
- X msg_print("But you are not carrying anything.");
- X free_turn_flag = TRUE;
- X }
- X else if (get_item(&item_val, "Fire/Throw which one?", 0, inven_ctr-1, CNIL,
- X CNIL))
- X {
- X if (get_dir(CNIL, &dir))
- X {
- X desc_remain(item_val);
- X if (py.flags.confused > 0)
- X {
- X msg_print("You are confused.");
- X do
- X {
- X dir = randint(9);
- X }
- X while (dir == 5);
- X }
- X inven_throw(item_val, &throw_obj);
- X facts(&throw_obj, &tbth, &tpth, &tdam, &tdis);
- X tchar = throw_obj.tchar;
- X flag = FALSE;
- X y = char_row;
- X x = char_col;
- X oldy = char_row;
- X oldx = char_col;
- X cur_dis = 0;
- X do
- X {
- X (void) mmove(dir, &y, &x);
- X cur_dis++;
- X lite_spot(oldy, oldx);
- X if (cur_dis > tdis) flag = TRUE;
- X c_ptr = &cave[y][x];
- X if ((c_ptr->fval <= MAX_OPEN_SPACE) && (!flag))
- X {
- X if (c_ptr->cptr > 1)
- X {
- X flag = TRUE;
- X m_ptr = &m_list[c_ptr->cptr];
- X tbth = tbth - cur_dis;
- X /* if monster not lit, make it much more difficult to
- X hit, subtract off most bonuses, and reduce bthb
- X depending on distance */
- X if (!m_ptr->ml)
- X tbth = (tbth / (cur_dis+2))
- X - (py.misc.lev *
- X class_level_adj[py.misc.pclass][CLA_BTHB] / 2)
- X - (tpth * (BTH_PLUS_ADJ-1));
- X if (test_hit(tbth, (int)py.misc.lev, tpth,
- X (int)c_list[m_ptr->mptr].ac, CLA_BTHB))
- X {
- X i = m_ptr->mptr;
- X objdes(tmp_str, &throw_obj, FALSE);
- X /* Does the player know what he's fighting? */
- X if (!m_ptr->ml)
- X {
- X (void) sprintf(out_val,
- X "You hear a cry as the %s finds a mark.", tmp_str);
- X visible = FALSE;
- X }
- X else
- X {
- X (void) sprintf(out_val, "The %s hits the %s.",
- X tmp_str, c_list[i].name);
- X visible = TRUE;
- X }
- X msg_print(out_val);
- X tdam = tot_dam(&throw_obj, tdam, i);
- X tdam = critical_blow((int)throw_obj.weight,
- X tpth, tdam, CLA_BTHB);
- X if (tdam < 0) tdam = 0;
- X i = mon_take_hit((int)c_ptr->cptr, tdam);
- X if (i >= 0)
- X {
- X if (!visible)
- X msg_print("You have killed something!");
- X else
- X {
- X (void) sprintf(out_val,"You have killed the %s.",
- X c_list[i].name);
- X msg_print(out_val);
- X }
- X prt_experience();
- X }
- X }
- X else
- X drop_throw(oldy, oldx, &throw_obj);
- X }
- X else
- X { /* do not test c_ptr->fm here */
- X if (panel_contains(y, x) && (py.flags.blind < 1)
- X && (c_ptr->tl || c_ptr->pl))
- X {
- X print(tchar, y, x);
- X put_qio(); /* show object moving */
- X }
- X }
- X }
- X else
- X {
- X flag = TRUE;
- X drop_throw(oldy, oldx, &throw_obj);
- X }
- X oldy = y;
- X oldx = x;
- X }
- X while (!flag);
- X }
- X }
- X}
- X
- X
- X/* Make a bash attack on someone. -CJS-
- X Used to be part of bash above. */
- Xstatic void py_bash(y, x)
- Xint y, x;
- X{
- X int monster, k, avg_max_hp, base_tohit;
- X register creature_type *c_ptr;
- X register monster_type *m_ptr;
- X vtype m_name, out_val;
- X
- X monster = cave[y][x].cptr;
- X m_ptr = &m_list[monster];
- X c_ptr = &c_list[m_ptr->mptr];
- X m_ptr->csleep = 0;
- X /* Does the player know what he's fighting? */
- X if (!m_ptr->ml)
- X (void) strcpy(m_name, "it");
- X else
- X (void) sprintf(m_name, "the %s", c_ptr->name);
- X base_tohit = py.stats.use_stat[A_STR] + inventory[INVEN_ARM].weight/2
- X + py.misc.wt/10;
- X if (!m_ptr->ml)
- X base_tohit = (base_tohit / 2)
- X - (py.stats.use_stat[A_DEX]*(BTH_PLUS_ADJ-1))
- X - (py.misc.lev * class_level_adj[py.misc.pclass][CLA_BTH] / 2);
- X
- X if (test_hit(base_tohit, (int)py.misc.lev,
- X (int)py.stats.use_stat[A_DEX], (int)c_ptr->ac, CLA_BTH))
- X {
- X (void) sprintf(out_val, "You hit %s.", m_name);
- X msg_print(out_val);
- X k = pdamroll(inventory[INVEN_ARM].damage);
- X k = critical_blow((int)(inventory[INVEN_ARM].weight / 4
- X + py.stats.use_stat[A_STR]), 0, k, CLA_BTH);
- X k += py.misc.wt/60 + 3;
- X if (k < 0) k = 0;
- X
- X /* See if we done it in. */
- X if (mon_take_hit(monster, k) >= 0)
- X {
- X (void) sprintf(out_val, "You have slain %s.", m_name);
- X msg_print(out_val);
- X prt_experience();
- X }
- X else
- X {
- X m_name[0] = toupper((int)m_name[0]); /* Capitalize */
- X /* Can not stun Balrog */
- X avg_max_hp = (c_ptr->cdefense & CD_MAX_HP ?
- X c_ptr->hd[0] * c_ptr->hd[1] :
- X (c_ptr->hd[0] * (c_ptr->hd[1] + 1)) >> 1);
- X if ((100 + randint(400) + randint(400))
- X > (m_ptr->hp + avg_max_hp))
- X {
- X m_ptr->stunned += randint(3) + 1;
- X if (m_ptr->stunned > 24) m_ptr->stunned = 24;
- X (void) sprintf(out_val, "%s appears stunned!", m_name);
- X }
- X else
- X (void) sprintf(out_val, "%s ignores your bash!", m_name);
- X msg_print(out_val);
- X }
- X }
- X else
- X {
- X (void) sprintf(out_val, "You miss %s.", m_name);
- X msg_print(out_val);
- X }
- X if (randint(150) > py.stats.use_stat[A_DEX])
- X {
- X msg_print("You are off balance.");
- X py.flags.paralysis = 1 + randint(2);
- X }
- X}
- X
- X
- X/* Bash open a door or chest -RAK- */
- X/* Note: Affected by strength and weight of character
- X
- X For a closed door, p1 is positive if locked; negative if
- X stuck. A disarm spell unlocks and unjams doors!
- X
- X For an open door, p1 is positive for a broken door.
- X
- X A closed door can be opened - harder if locked. Any door might
- X be bashed open (and thereby broken). Bashing a door is
- X (potentially) faster! You move into the door way. To open a
- X stuck door, it must be bashed. A closed door can be jammed
- X (which makes it stuck if previously locked).
- X
- X Creatures can also open doors. A creature with open door
- X ability will (if not in the line of sight) move though a
- X closed or secret door with no changes. If in the line of
- X sight, closed door are openned, & secret door revealed.
- X Whether in the line of sight or not, such a creature may
- X unlock or unstick a door.
- X
- X A creature with no such ability will attempt to bash a
- X non-secret door. */
- Xvoid bash()
- X{
- X int y, x, dir, tmp;
- X register cave_type *c_ptr;
- X register inven_type *t_ptr;
- X
- X y = char_row;
- X x = char_col;
- X if (get_dir(CNIL, &dir))
- X {
- X if (py.flags.confused > 0)
- X {
- X msg_print("You are confused.");
- X do
- X {
- X dir = randint(9);
- X }
- X while (dir == 5);
- X }
- X (void) mmove(dir, &y, &x);
- X c_ptr = &cave[y][x];
- X if (c_ptr->cptr > 1)
- X {
- X if (py.flags.afraid > 0)
- X msg_print("You are afraid!");
- X else
- X py_bash(y, x);
- X }
- X else if (c_ptr->tptr != 0)
- X {
- X t_ptr = &t_list[c_ptr->tptr];
- X if (t_ptr->tval == TV_CLOSED_DOOR)
- X {
- X count_msg_print("You smash into the door!");
- X tmp = py.stats.use_stat[A_STR] + py.misc.wt / 2;
- X /* Use (roughly) similar method as for monsters. */
- X if (randint(tmp*(20+abs(t_ptr->p1))) < 10*(tmp-abs(t_ptr->p1)))
- X {
- X msg_print("The door crashes open!");
- X invcopy(&t_list[c_ptr->tptr], OBJ_OPEN_DOOR);
- X t_ptr->p1 = 1 - randint(2); /* 50% chance of breaking door */
- X c_ptr->fval = CORR_FLOOR;
- X if (py.flags.confused == 0)
- X move_char(dir, FALSE);
- X else
- X lite_spot(y, x);
- X }
- X else if (randint(150) > py.stats.use_stat[A_DEX])
- X {
- X msg_print("You are off-balance.");
- X py.flags.paralysis = 1 + randint(2);
- X }
- X else if (command_count == 0)
- X msg_print("The door holds firm.");
- X }
- X else if (t_ptr->tval == TV_CHEST)
- X {
- X if (randint(10) == 1)
- X {
- X msg_print("You have destroyed the chest.");
- X msg_print("and its contents!");
- X t_ptr->index = OBJ_RUINED_CHEST;
- X t_ptr->flags = 0;
- X }
- X else if ((CH_LOCKED & t_ptr->flags) && (randint(10) == 1))
- X {
- X msg_print("The lock breaks open!");
- X t_ptr->flags &= ~CH_LOCKED;
- X }
- X else
- X count_msg_print("The chest holds firm.");
- X }
- X else
- X /* Can't give free turn, or else player could try directions
- X until he found invisible creature */
- X msg_print("You bash it, but nothing interesting happens.");
- X }
- X else
- X {
- X if (c_ptr->fval < MIN_CAVE_WALL)
- X msg_print("You bash at empty space.");
- X else
- X /* same message for wall as for secret door */
- X msg_print("You bash it, but nothing interesting happens.");
- X }
- X }
- X}
- END_OF_FILE
- if test 31210 -ne `wc -c <'source/moria4.c'`; then
- echo shar: \"'source/moria4.c'\" unpacked with wrong size!
- fi
- # end of 'source/moria4.c'
- fi
- echo shar: End of archive 15 \(of 39\).
- cp /dev/null ark15isdone
- 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 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 39 archives.
- echo "Now run "bldfiles.sh" to build split files"
- rm -f 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
-