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: v14i063: umoria4 - single player dungeon simulation (ver. 5.5), Part31/39
- Message-ID: <3427@master.CNA.TEK.COM>
- Date: 22 Aug 92 22:14:31 GMT
- Sender: news@master.CNA.TEK.COM
- Lines: 1654
- Approved: billr@saab.CNA.TEK.COM
-
- Submitted-by: grabiner@math.harvard.edu (David Grabiner)
- Posting-number: Volume 14, Issue 63
- Archive-name: umoria4/Part31
- 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 31 (of 39)."
- # Contents: doc/spells.doc ibmpc/CONFIG.DOC ibmpc/ms_misc.c
- # misc/shading util/weapons/README
- # Wrapped by billr@saab on Thu Aug 20 09:11:34 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'doc/spells.doc' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'doc/spells.doc'\"
- else
- echo shar: Extracting \"'doc/spells.doc'\" \(11474 characters\)
- sed "s/^X//" >'doc/spells.doc' <<'END_OF_FILE'
- XAddendum to the manual for Moria.
- X
- XProposed contribution written by Mike Marcelais
- X North Carolina School of
- X Science And Math
- X mrm@odin.ncssm.edu
- X games@odin.ncssm.edu
- X
- X1. Magic Spells
- X
- XAll player characters except Warriors are able to learn some form of
- Xmagic spells. There are two kinds of magic, Magic spells, which Mages,
- XRogues, and Rangers get, and prayers, which Priests and Paladins have.
- XEach spell has a minimum level required for learning it, a mana score,
- Xwhich is the mana points required to cast it, and a failure percentage.
- X
- XMana points are determined by your experience level, and the level of
- Xyour key stat. For Mages, Rogues, and Rangers, the key stat is intelligence,
- Xfor Priests and Paladins the key stat is wisdom. The effect of your key
- Xstat is shown by the following table.
- X
- X Stat Level Factor
- X 3-7 0
- X 8-17 1
- X 18-18/49 3/2
- X 18/50-18/69 2
- X 18/70-18/89 5/2
- X 18/90-18/99 3
- X 18/100 4
- X
- XYour Mana score is the Factor times your experience level plus 1.
- XIf your key stat is 7 or less, your Mana score will be zero (not one)
- Xand you will not be able to use any spells. If you attempt to cast a
- Xspell that calls for more Mana than you have, the rate of failure is much
- Xgreater than normal, you will faint for a few turns afterward, and you stand
- Xthe chance of damaging your health.
- X
- X1.1 Priest Spells
- X
- XPriest spells are received from the character's deity. When the 'G'
- Xcommand is issued to learn new spells, spells are chosen randomly from
- Xthe spells that you are able to cast. You need not
- Xhave the book the spell is in to learn it, because your God gave it to you,
- Xbut you do need the book to cast the spell. Failure percentages and spell
- Xeffectiveness are based on Wisdom for priests and paladins.
- X
- X1.1.1 Priest spell levels and Mana
- X
- XThis is a table of all the spells, with the mana and level of achievement
- Xfor Priests and Paladins.
- X Priest Paladin
- X(Beginner's Handbook) Lv Mana Lv Mana
- XA Detect Evil 1 1 1 1
- XB Cure Light Wounds 1 2 2 2
- XC Bless 1 2 3 3
- XD Remove Fear 1 2 5 3
- XE Call Light 3 2 5 4
- XF Find Traps 3 3 7 5
- XG Detect Doors/Stairs 3 3 7 5
- XH Slow Poison 3 3 9 7
- X
- X(Words of Wisdom)
- XA Blind Creature 5 4 9 7
- XB Portal 5 4 9 8
- XC Cure Medium Wounds 5 4 11 9
- XD Chant 5 5 11 10
- XE Sanctuary 7 5 11 10
- XF Create Food 7 5 13 10
- XG Remove Curse 7 6 13 11
- XH Resist Heat and Cold 7 7 15 13
- X
- X(Chants and Blessings)
- XA Neutralize Poison 9 6 15 15
- XB Orb of Draining 9 7 17 15
- XC Cure Serious Wounds 9 7 17 15
- XD Sense Invisible 11 8 19 15
- XE Protection from Evil 11 8 19 15
- XF Earthquake 11 9 21 17
- XG Sense Surroundings 13 10 23 17
- XH Cure Critical Wounds 13 11 25 20
- XI Turn Undead 15 12 27 21
- X
- X(Exorcisms and Dispellings)
- XA Prayer 15 14 29 22
- XB Dispel Undead 17 14 31 24
- XC Heal 21 16 33 28
- XD Dispel Evil 25 20 35 32
- XE Glyph of Warding 33 24 37 36
- XF Holy Word 39 32 39 38
- X
- X1.1.2 Priest Spell Descriptions
- X
- XThis is a short description of each of the spells, listed alphabetically.
- X
- XBless - Improves armor class and fighting ability for a short period of time.
- XBlind Creature - Blinds a creature for a short period of time.
- XCall Light - Lights up an area.
- XChant - Improves armor class and fighting ability for a medium period of time.
- XCreate Food - Causes a food item to be dropped at your feet.
- XCure Critical Wounds - Cures a very large number of hit points.
- XCure Light Wounds - Cures a small number of hit points.
- XCure Medium Wounds - Cures a medium number of hit points.
- XCure Serious Wounds - Cures a large number of hit points.
- XDetect Doors/Stairs - Finds all the doors and stairs on the screen.
- XDetect Evil - Finds all the evil creatures on the screen.
- XDispel Evil - Attempts to destroy the evil creature.
- XDispel Undead - Attempts to destroy the undead creature.
- XEarthquake - Randomly toggles corridors into walls and vice versa.
- XFind Traps - Locates all the traps on the screen.
- XGlyph of Warding - Leaves a 'Glyph' that monsters won't pass over.
- XHeal - Restores 200 Hit Points.
- XHoly Word - Dispels evil, removes fear, cures poison, and restores 1000 HPs.
- XNeutralize Poison - Cures you of poison.
- XOrb of Draining - Offensive spell that drains levels from monsters.
- XPortal - Teleports you a short distance away.
- XPrayer - Improves armor class and fighting ability for a long period of time.
- XProtection from Evil - Causes evil creatures to do less damage to you.
- XRemove Curse - Removes {damned} objects that you are welding.
- XRemove Fear - Negates the fear placed on you by an enemy.
- XResist Heat and Cold - Reduce damage you suffer from heat or cold attacks.
- XSanctuary - Causes neighboring monsters to fall asleep for a while.
- XSense Invisible - Finds all invisible creatures on the screen.
- XSense Surroundings - Maps the dungeon appearing on the screen.
- XSlow Poison - Reduces the rate HP are lost due to poison.
- XTurn Undead - Attempts to cause undead creatures to flee.
- X
- X1.2 Mage Spells
- X
- XMage Spells are more powerful and offensive in nature than Priest
- Xspells. This offsets the fact that magicians are generally weaker
- Xthan any other class. Because mage spells are learned though
- Xstudy, you must have the correct Magic book to learn and cast a
- Xspell. Learning spells can be banked up. For example: You are a
- Xsecond level Mage who had learned Magic Missile and can learn one
- Xmore spell. You do not wish to learn Detect Monsters, Phase Door
- Xor Light Area. You can wait until you are third level and learn
- Xboth the Cure Light Wounds and Stinking Cloud, both third level
- Xspells. Spell failure and effectiveness is based on intelligence
- Xfor Mages, Rangers, and Rogues. Rangers can learn all but the most
- Xpowerful offensive spell. Rogues can not learn any offensive spell.
- X
- X1.2.1 Mage Spell levels and Mana
- X
- X Mage Ranger Rogue
- X(Beginners-Magik) Lv Mana Lv Mana Lv Mana
- XA Magic Missile 1 1 3 1 -- --
- XB Detect Monsters 1 1 3 2 5 1
- XC Phase Door 1 2 3 2 7 2
- XD Light Area 1 2 5 3 9 3
- XE Cure Light Wounds 3 3 5 3 11 4
- XF Find Hidden Traps/Doors 3 3 5 4 13 5
- XG Stinking Cloud 3 3 7 5 -- --
- X
- X(Magik I)
- XA Confusion 3 4 7 6 15 6
- XB Lightning Bolt 5 4 9 7 -- --
- XC Trap/Door Destruction 5 5 9 8 17 7
- XD Sleep I 5 5 11 8 19 8
- XE Cure Poison 5 5 11 9 21 9
- XF Teleport Self 7 6 13 10 -- --
- XG Remove Curse 7 6 13 11 23 10
- XH Frost Bolt 7 6 15 12 -- --
- XI Turn Stone to Mud 9 7 15 13 -- --
- X
- X(Magik II)
- XA Create Food 9 7 17 17 25 12
- XB Recharge Item I 9 7 17 17 27 15
- XC Sleep II 9 7 21 17 -- --
- XD Polymorph Other 11 7 21 19 -- --
- XE Identify 11 7 23 25 29 18
- XF Sleep III 13 7 23 20 -- --
- XG Fire Bolt 15 9 25 20 -- --
- XH Slow Monster 17 9 25 21 -- --
- X
- X(Mages Guide to Power)
- XA Frost Ball 19 12 27 21 -- --
- XB Recharge Item II 21 12 29 23 -- --
- XC Teleport Other 23 12 31 25 -- --
- XD Haste Self 25 12 33 25 -- --
- XE Fire Ball 29 18 35 25 -- --
- XF Word of Destruction 33 21 37 30 -- --
- XG Genocide 37 25 -- -- -- --
- X
- XNote: Rangers don't get spells until 3'rd level, Rogues 5'th level.
- X
- X1.2.2 Mage Spell Descriptions
- X
- XConfusion - Confuses a monster for a short time.
- XCreate Food - Causes a food item to be dropped at your feet.
- XCure Light Wounds - Restores a small number of hit points.
- XCure Poison - Neutralizes the poison running through your veins.
- XDetect Monsters - Displays all the monsters on the screen.
- XFind Hidden Traps/Doors - Locates all the secret traps and doors.
- XFire Ball - Shoots a ball of flame toward a monster.
- XFire Bolt - Shoots a bolt of flame toward a monster.
- XFrost Ball - Shoots a ball of frost toward a monster.
- XFrost Bolt - Shoots a bolt of frost toward a monster.
- XGenocide - Destroys a particular monster on the level.
- XHaste Self - Causes you to move faster temporarily.
- XIdentify - Identifies an unknown object in your pack.
- XLight Area - Illuminates the area you are in with light.
- XLightning Bolt - Shoots a bolt of lightning at your enemy.
- XMagic Missile - Traditional bolt of magic used to damage enemies.
- XPhase Door - Teleports you a short distance.
- XPolymorph Other - Polymorphs a monster into a different creature.
- XRecharge Item I and II - Recharges a staff, rod, or wand.
- XRemove Curse - Allows you to unwield {damned} items.
- XSleep I - Causes a monster of your choosing to fall asleep.
- XSleep II - Causes neighboring monsters to fall asleep.
- XSleep III - Causes all monsters in range to fall asleep.
- XSlow Monster - Causes a monster to move slower.
- XStinking Cloud - Shoots a ball of noxious vapors to do damage.
- XTeleport Self - Teleports you to a new place on the level.
- XTeleport Other - Teleports an enemy to a new place on the level.
- XTrap/Door Destruction - Destroys all neighboring doors and traps.
- XTurn Stone to Mud - Causes a wall (or other stone object) to melt.
- XWord of Destruction - Destroys the entire screen.
- X
- XFor spells that come in numbered versions (Sleep I, II, III, etc), the
- Xhigher numbers have a higher effectiveness, but greater change
- Xof spell failure and greater Mana cost.
- X
- X1.3 Using Offensive Spells Against Monsters
- X
- XMonsters have a chance to save themselves from damage caused by
- Xoffensive spells, just like the player has a chanced to be saved from
- Xdamage by monster spells. This chance is greater for higher level
- Xmonsters than for lower level monsters. Also, some spells will never
- Xwork against monsters whose level is higher than the character's
- Xexperience level.
- X
- XMany monsters are immune to certain kinds of attack, and will suffer little
- Xor no damage from such attacks. For example, a fire breathing dragon will
- Xsuffer little damage from a fire ball, but will suffer greatly from a
- Xfrost ball. Also, Undead creatures will not be affected by sleep spells,
- Xsince they never sleep.
- X
- END_OF_FILE
- if test 11474 -ne `wc -c <'doc/spells.doc'`; then
- echo shar: \"'doc/spells.doc'\" unpacked with wrong size!
- fi
- # end of 'doc/spells.doc'
- fi
- if test -f 'ibmpc/CONFIG.DOC' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ibmpc/CONFIG.DOC'\"
- else
- echo shar: Extracting \"'ibmpc/CONFIG.DOC'\" \(10740 characters\)
- sed "s/^X//" >'ibmpc/CONFIG.DOC' <<'END_OF_FILE'
- X
- X The Dungeons of MORIA version 5.x
- X COPYRIGHT (c) Robert Alan Koeneke
- X
- X MSDOS port, v4.873, by D. G. Kneller
- X Nov 1, 1988
- X Updated for Umoria 5.x by James E. Wilson
- X Mar 24, 1991
- X
- X
- X
- X
- X
- XTable of contents
- X1. USAGE ............................................................. 1
- X2. REQUIREMENTS ...................................................... 1
- X3. INSTALLATION ...................................................... 1
- X3.1. Hard drive systems .............................................. 1
- X3.2. High-density floppy systems ..................................... 2
- X3.3. 2 - 360K floppy systems ......................................... 2
- X4. OPTIONS ........................................................... 2
- X4.1. SAVE ............................................................ 2
- X4.2. SCORE ........................................................... 3
- X4.3. KEYBOARD ........................................................ 3
- X4.4. GRAPHICS ........................................................ 3
- X4.5. RAWIO ........................................................... 3
- X4.6. IBMBIOS ......................................................... 3
- X4.7. ANSI ............................................................ 4
- X5. ENVIRONMENT VARIABLES ............................................. 5
- X6. BUGS .............................................................. 5
- X7. AUTHOR'S ADDRESS .................................................. 5
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X - i -
- X
- X
- X
- X
- XINTRODUCTION
- X
- XThis README file describes the requirements and setup necessary to get
- XMORIA running on your MSDOS computer. The actual game documentation is
- Xin MORIA.DOC.
- X
- X
- X1. USAGE
- X
- X Usage: moria [ -norsw ] [ savefile ]
- X
- X Where: -n starts a new game, ignoring any existing save files.
- X -o selects the original (VMS) command set.
- X -r selects the Rogue-like command set.
- X -s prints the score file and exits.
- X -w will try to resurrect a dead character
- X
- X2. REQUIREMENTS
- X
- X 640K ram (really!)
- X DOS 2.x or higher
- X 2 - 360K floppy disk drives or 1 high density drive or 1 hard drive
- X A 24 (or 25) line by 80 column monitor. MORIA uses either BIOS calls
- X or ANSI for video output so should work properly on most monitors.
- X It must use ANSI to work on DEC Rainbows. It won't work in 43-line mode
- X of an EGA.
- X
- X
- X3. INSTALLATION
- X
- XMORIA is very easy to configure. The biggest problem is that there is
- Xnot enough room on a single 360K floppy disk to hold the DOS system
- Xfiles, MORIA.EXE (about 340K) and a MORIA save file (about 20K or so).
- XTo install MORIA, some files must be copied and 2 options in MORIA.CNF
- Xmust be set. Options and the MORIA.CNF are described more fully in the
- Xsection entitled OPTIONS. Here are a few methods of configuration.
- XThese methods are also described in the MORIA.CNF file.
- X
- X
- X3.1. Hard drive systems
- X
- XCreate a c:\games subdirectory on your hard disk and put c:\games on
- Xyour PATH (see the DOS manual if you need help with PATH). Copy
- XMORIA.EXE and MORIA.CNF to c:\games. Edit MORIA.CNF and put in the
- Xoptions:
- X
- X SAVE c:\games\moria.sav;n
- X SCORE c:\games\moria.scr
- X
- X
- X
- X
- X
- X
- X - 1 -
- X
- X3.2. High-density floppy systems
- X
- XThis is about as easy as for a hard disk. Format a diskette and put the
- XDOS system files on it (use FORMAT A:/S). Copy MORIA.EXE and MORIA.CNF
- Xto that diskette. Edit MORIA.CNF and put in the options:
- X
- X SAVE a:\moria.sav
- X SCORE a:\moria.scr
- X
- X
- X
- X3.3. 2 - 360K floppy systems
- X
- XYou will need to use 2 floppy diskettes. Format a diskette and put the
- XDOS system files on it (use FORMAT A:/S). Copy MORIA.CNF to this
- Xdiskette. This diskette will go in drive A when you want to play MORIA.
- XFormat a second diskette (no /S) and copy MORIA.EXE to it. This
- Xdiskette will go in drive B. Edit MORIA.CNF and put in the options:
- X
- X SAVE a:moria.sav
- X SCORE a:moria.scr
- X
- X
- XWhen you want to play MORIA, put both diskettes in and type "B:MORIA"
- X
- X
- X
- X4. OPTIONS
- X
- XWhen MORIA starts up it looks along your PATH for the file "MORIA.CNF".
- XMORIA.CNF contains configuration information for MORIA in the form of
- Xoptions. Options have a name and perhaps a value. If the option
- Xdoesn't have a value, simply mentioning its name selects that option.
- XHere are the options.
- X
- X4.1. SAVE
- X
- XThe SAVE option has 1 argument, the name of a file where saved games
- Xwill be stored. Normally, when you start MORIA by typing "MORIA file",
- XMORIA will try to use "file" as the name of a saved game. The SAVE
- Xoption allows you to give the name of the save file so you don't have to
- Xtype it in each time you save or restore a game. A sample SAVE option
- Xis:
- X
- X SAVE c:\games\moria.sav;n
- X
- X
- XThe ";n" is optional. If given it means that MORIA should never prompt
- Xyou for the name of the save file. If the SAVE option isn't given,
- XMORIA defaults to the file MORIA.SAV in the same directory as MORIA.CNF.
- XAlso, the SAVE option can be just ";n", which means use the default name
- Xwithout prompting.
- X
- X
- X
- X
- X
- X - 2 -
- X
- X4.2. SCORE
- X
- XThe SCORE option has 1 argument, the name of the file where the top
- Xscores are kept. A sample SCORE option is:
- X
- X SCORE c:\games\moria.scr
- X
- X
- XIf the SCORE option isn't given, MORIA defaults to the file MORIA.SCR in
- Xthe same directory as MORIA.CNF.
- X
- X
- X4.3. KEYBOARD
- X
- XMORIA can be played with either of 2 styles of commands. There is the
- Xoriginal VMS-style commands and a Rogue-style set of commands. The
- Xchoice of command set affects the keyboard letters used for doing the
- Xvarious game commands. The KEYBOARD value can be either "ROGUE" or
- X"VMS". The default is to use the original VMS-style commands.
- X
- X
- X4.4. GRAPHICS
- X
- XThe GRAPHICS option takes 2 arguments, the ASCII number for the
- Xcharacter to be used for displaying the walls and floors. For example,
- Xto use '#' for the walls and '.' for the floors, the GRAPHICS option
- Xwould be:
- X
- X GRAPHICS 35 46
- X
- X
- XIncidentally, these also are the default characters that are used if the
- XGRAPHICS option is not specified.
- X
- X
- X4.5. RAWIO
- X
- XNormally DOS does some extra work whenever a character is input from the
- Xkeyboard. One of the tasks is to interpret the special characters ^S
- X(control-S, which does a scroll lock) ^C (control-C, which acts like
- Xcontrol-Break) and ^P (control-P, which acts like control-PrtSc,
- Xtoggling output to your printer or giving an error message if you don't
- Xhave one). The RAWIO option will be used to tell DOS to not do this
- Xextra work by making the input (and output) operate in "raw" mode. This
- Xis good because ^P (a MORIA command) will now work. As well, screen
- Xoutput will be somewhat faster.
- X
- XURGENT! RAWIO will not work on Dec Rainbows and will probably lock up
- Xthe computer.
- X
- X
- X4.6. IBMBIOS
- X
- XIBMBIOS enables the use of a BIOS call to read input from the keyboard.
- X
- X
- X
- X - 3 -
- X
- XThe advantage of this is that the numeric keypad will then be useable as
- Xdirection keys for moving around. With this option the keypad keys map
- Xto the directions:
- X
- X 7 up & left 8 up 9 up & right
- X 4 left 5 nothing 6 right
- X 1 down & left 2 down 3 down & right
- X
- X And other keypad keys map to:
- X
- X - rest
- X + previous message
- X Ins inventory Del rest
- X
- X
- XIf you are using the Rogue-style command set, the shift key and NumLock
- Xkey modify these commands. With the shift key down, 7 will be "run up
- Xand left", 8 will be "run up", etc. The NumLock key is used as a toggle
- Xbetween moving and tunneling. With NumLock enabled, 7 will be "tunnel up
- Xand left", etc.
- X
- X
- X4.7. ANSI
- X
- XThe ANSI option tells MORIA to use ANSI sequences rather than using BIOS
- Xcalls for doing output. You must use the ANSI option if you are playing
- XMORIA on a DEC Rainbow. On IBM PCs, ATs and clones there should be no
- Xneed to use this option and you can safely ignore the rest of this
- Xsection.
- X
- XThe ANSI option takes three optional arguments: check_ansi, move_opt and
- Xuse_tgoto. If no arguments aren't given, they are assumed to be Y (yes),
- XY and N (no), respectively. The usage is
- X
- X ANSI [ check_ansi [ move_opt [ use_tgoto ] ] ]
- X
- XAn example is:
- X
- X ANSI Y N
- X
- Xcheck_ansi tells MORIA to check for ANSI.SYS when starting up. You may have
- Xto disable this check if MORIA insists you don't have ANSI installed, but you
- Xknow you do. move_opt tries to reduce the amount of output being sent to the
- Xscreen. use_tgoto tells MORIA to use the actual TERMCAP tgoto() routine. The
- Xdefault is to use a faster routine which only works for ANSI-like terminals.
- X
- XWhen the ANSI option is chosen, MORIA looks for ANSI control strings in
- Xa file called TERMCAP, first in the current directory, then in directory
- XETC. A sample TERMCAP file is supplied. Basically, this file maps
- Xbetween logical cursor operations (eg. "cursor up") to ANSI sequences
- X(eg ESC [ A). In the file, ESC (escape) is represented as \E. MORIA
- Xuses the following logical operations:
- X
- X
- X
- X
- X
- X - 4 -
- X
- X ce clear to end of line
- X cl clear screen
- X cm cursor motion (only if use_tgoto is chosen)
- X nd cursor forward (non-destructive space)
- X le cursor back (left)
- X up cursor up
- X do cursor down
- X li number of lines on the screen
- X
- XMORIA can also use:
- X
- X ti terminal initialization string
- X te terminal end string
- X
- X
- X5. ENVIRONMENT VARIABLES
- X
- XMORIA uses the environment variable USER to determine your real name (as
- Xopposed to your role playing name in the game). The USER environment
- Xvariable can be set from DOS with:
- X
- X set USER = kneller
- X
- XIf the USER variable isn't set, MORIA just uses the name "player".
- X
- XIf the ANSI option is chosen, MORIA uses the variable TERM to determine
- Xthe terminal information to extract from the TERMCAP file. If the TERM
- Xvariable isn't set, MORIA assumes the value "ibmpc-mono".
- X
- X
- X
- X6. BUGS
- X
- XI have not played this game much so there may be bugs which I have not
- Xseen yet. Please report them to me so I can fix them.
- X
- X
- X7. AUTHOR'S ADDRESS
- X
- XIf you have any questions or bug reports please contact me at:
- X
- X David Grabiner
- X Department of Mathematics
- X Harvard University
- X Cambridge, MA 02138
- X
- X or by electronic mail: grabiner@math.harvard.edu
- X
- XThe original author can be reached at:
- X
- X James E. Wilson
- X 856 University Ave.
- X Palo Alto, CA 94301
- X USA
- X
- X or by electronic mail: wilson@kithrup.com
- X
- X - 5 -
- X
- END_OF_FILE
- if test 10740 -ne `wc -c <'ibmpc/CONFIG.DOC'`; then
- echo shar: \"'ibmpc/CONFIG.DOC'\" unpacked with wrong size!
- fi
- # end of 'ibmpc/CONFIG.DOC'
- fi
- if test -f 'ibmpc/ms_misc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ibmpc/ms_misc.c'\"
- else
- echo shar: Extracting \"'ibmpc/ms_misc.c'\" \(11297 characters\)
- sed "s/^X//" >'ibmpc/ms_misc.c' <<'END_OF_FILE'
- X/* ibmpc/ms_misc.c: MSDOS support code
- X
- X Copyright (c) 1989-92 James E. Wilson, Don Kneller
- 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 <conio.h>
- X#endif /* __TURBOC__ */
- X
- X#include <string.h>
- X#include <ctype.h>
- X#include <time.h>
- X#include <fcntl.h>
- X#include <stdio.h>
- X
- X#include "config.h"
- X#include "constant.h"
- X#include "types.h"
- X#include "externs.h"
- X
- X#ifdef MSDOS
- X#ifndef USING_TCIO
- X/* We don't want to include curses.h when using the tcio.c file. */
- X#include <curses.h>
- X#endif
- X#ifdef ANSI
- X#include "ms_ansi.h"
- X#endif
- X
- X#ifdef LINT_ARGS
- Xvoid exit(int);
- Xstatic FILE *fopenp(char *, char *, char *);
- Xstatic unsigned int ioctl(int ,int ,unsigned int );
- X#else
- Xvoid exit();
- Xstatic unsigned int ioctl();
- X#endif
- X
- Xextern char *getenv();
- X
- X#define PATHLEN 80
- Xchar moriatop[PATHLEN];
- Xchar moriasav[PATHLEN];
- Xint saveprompt = TRUE;
- Xint ibmbios;
- Xstatic int rawio;
- Xint8u floorsym = '.';
- Xint8u wallsym = '#';
- X
- X/* UNIX compatability routines */
- Xvoid user_name(buf)
- Xchar *buf;
- X{
- X strcpy(buf, getlogin());
- X}
- X
- Xchar *
- Xgetlogin()
- X{
- X char *cp;
- X
- X if ((cp = getenv("USER")) == NULL)
- X cp = "player";
- X return cp;
- X}
- X
- X#ifndef __TURBOC__
- Xunsigned int
- Xsleep(secs)
- Xint secs;
- X{
- X time_t finish_time;
- X
- X finish_time = time((long *) NULL) + secs;
- X while (time((long *) NULL) < finish_time)
- X /* nothing */;
- X return 0;
- X}
- X#endif
- X
- X#ifdef OLD
- X/* This is the old code. It is not strictly correct; it is retained in
- X case the correct code below is not portable. You will also have to
- X change the declarations for these functions in externs.h. */
- Xvoid
- Xerror(fmt, a1, a2, a3, a4)
- Xchar *fmt;
- Xint a1, a2, a3, a4;
- X{
- X fprintf(stderr, "MORIA error: ");
- X fprintf(stderr, fmt, a1, a2, a3, a4);
- X (void) sleep(2);
- X exit(1);
- X}
- X
- Xvoid
- Xwarn(fmt, a1, a2, a3, a4)
- Xchar *fmt;
- Xint a1, a2, a3, a4;
- X{
- X fprintf(stderr, "MORIA warning: ");
- X fprintf(stderr, fmt, a1, a2, a3, a4);
- X (void) sleep(2);
- X}
- X#else
- X
- X#include <stdarg.h>
- X
- Xvoid
- Xerror (char *fmt, ...)
- X{
- X va_list p_arg;
- X
- X va_start (p_arg, fmt);
- X fprintf (stderr, "Moria error: ");
- X vfprintf (stderr, fmt, p_arg);
- X sleep (2);
- X exit (1);
- X}
- X
- Xvoid
- Xwarn(char *fmt, ...)
- X{
- X va_list p_arg;
- X
- X va_start(p_arg, fmt);
- X fprintf(stderr, "MORIA warning: ");
- X vfprintf(stderr, fmt, p_arg);
- X sleep(2);
- X}
- X#endif
- X
- X/* Search the path for a file of name "name". The directory is
- X * filled in with the directory part of the path.
- X */
- Xstatic FILE *
- Xfopenp(name, mode, directory)
- Xchar *name, *mode, directory[];
- X{
- X char *dp, *pathp, *getenv(), lastch;
- X FILE *fp;
- X
- X /* Try the default directory first. If the file can't be opened,
- X * start looking along the path.
- X */
- X fp = fopen (name, mode);
- X if (fp) {
- X directory[0] = '\0';
- X return fp;
- X }
- X pathp = getenv("PATH");
- X while (pathp && *pathp) {
- X dp = directory;
- X while (*pathp && *pathp != ';')
- X lastch = *dp++ = *pathp++;
- X if (lastch != '\\' && lastch != '/' && lastch != ':')
- X *dp++ = '\\';
- X (void) strcpy(dp, name);
- X fp = fopen (directory, mode);
- X if (fp) {
- X *dp = '\0';
- X return fp;
- X }
- X if (*pathp)
- X pathp++;
- X }
- X directory[0] = '\0';
- X return NULL;
- X}
- X
- X/* Read the configuration.
- X */
- Xvoid
- Xmsdos_init()
- X{
- X char buf[BUFSIZ], *bp, opt[PATHLEN];
- X int arg1, arg2, cnt;
- X FILE *fp;
- X
- X buf[0] = '\0';
- X bp = MORIA_CNF_NAME;
- X fp = fopenp(bp, "r", buf);
- X (void) strcpy(moriatop, buf);
- X (void) strcat(moriatop, MORIA_TOP_NAME);
- X (void) strcpy(moriasav, buf);
- X (void) strcat(moriasav, MORIA_SAV_NAME);
- X if (fp == NULL) {
- X warn("Can't find configuration file `%s'\n", bp);
- X return;
- X }
- X printf("Reading configuration from %s%s\n", buf, bp);
- X (void) sleep(1);
- X while (fgets(buf, sizeof buf, fp)) {
- X if (*buf == '#')
- X continue;
- X
- X cnt = sscanf(buf, "%s", opt);
- X /* Turbo C will return EOF when reading an empty line,
- X MSC will correctly read a NULL character */
- X if (cnt == 0 ||
- X#ifdef __TURBOC__
- X cnt == EOF ||
- X#endif
- X opt[0] == '\0')
- X continue;
- X
- X /* Go through possible variables
- X */
- X if (strcmpi(opt, "GRAPHICS") == 0) {
- X cnt = sscanf(buf, "%*s%d %d\n", &arg1, &arg2);
- X if (cnt != 2)
- X warn("GRAPHICS did not contain 2 values\n");
- X else {
- X wallsym = (int8u) arg1;
- X floorsym = (int8u) arg2;
- X
- X /* Adjust lists that depend on '#' and '.' */
- X object_list[OBJ_SECRET_DOOR].tchar = wallsym;
- X }
- X }
- X else if (strcmpi(opt, "SAVE") == 0) {
- X cnt = sscanf(buf, "%*s%s", opt);
- X if (cnt == 0)
- X warn("SAVE option requires a filename\n");
- X else {
- X bp = strchr (opt, ';');
- X if (bp) {
- X *bp++ = '\0';
- X if (*bp == 'n' || *bp == 'N')
- X saveprompt = FALSE;
- X }
- X if (opt[0])
- X (void) strcpy(moriasav, opt);
- X }
- X }
- X else if (strcmpi(opt, "SCORE") == 0) {
- X cnt = sscanf(buf, "%*s%s", opt);
- X if (cnt == 0)
- X warn("SCORE option requires a filename\n");
- X else
- X (void) strcpy(moriatop, opt);
- X }
- X else if (strcmpi(opt, "KEYBOARD") == 0) {
- X cnt = sscanf(buf, "%*s%s", opt);
- X if (cnt == 0)
- X warn("KEYBOARD option requires a value\n");
- X else if (strcmpi(opt, "ROGUE") == 0)
- X rogue_like_commands = TRUE;
- X else if (strcmpi(opt, "VMS") == 0)
- X rogue_like_commands = FALSE;
- X }
- X else if (strcmpi(opt, "IBMBIOS") == 0)
- X ibmbios = TRUE;
- X else if (strcmpi(opt, "RAWIO") == 0)
- X rawio = TRUE;
- X#ifdef ANSI
- X /* Usage: ANSI [ check_ansi [ domoveopt [ tgoto ] ] ]
- X * where check_ansi and domoveopt are "Y"es unless explicitly
- X * set to "N"o. Tgoto is "N"o unless set to "Y"es.
- X */
- X else if (strcmpi(opt, "ANSI") == 0) {
- X cnt=sscanf(buf, "%*s%1s%1s%1s",&opt[0],&opt[1],&opt[2]);
- X ansi_prep(cnt < 1 || opt[0] == 'y' || opt[0] == 'Y',
- X cnt < 2 || opt[1] == 'y' || opt[1] == 'Y',
- X cnt >= 3 && (opt[2] == 'y' || opt[2] == 'Y'));
- X }
- X#endif
- X else
- X warn("Unknown configuration line: `%s'\n", buf);
- X }
- X fclose(fp);
- X
- X /* The only text file has been read. Switch to binary mode */
- X}
- X
- X#include <dos.h>
- X#define DEVICE 0x80
- X#define RAW 0x20
- X#define IOCTL 0x44
- X#define STDIN fileno(stdin)
- X#define STDOUT fileno(stdout)
- X#define GETBITS 0
- X#define SETBITS 1
- X
- Xstatic unsigned old_stdin, old_stdout, ioctl();
- X
- Xvoid
- Xmsdos_raw() {
- X if (!rawio)
- X return;
- X old_stdin = ioctl(STDIN, GETBITS, 0);
- X old_stdout = ioctl(STDOUT, GETBITS, 0);
- X if (old_stdin & DEVICE)
- X ioctl(STDIN, SETBITS, old_stdin | RAW);
- X if (old_stdout & DEVICE)
- X ioctl(STDOUT, SETBITS, old_stdout | RAW);
- X}
- X
- Xvoid
- Xmsdos_noraw() {
- X if (!rawio)
- X return;
- X if (old_stdin)
- X (void) ioctl(STDIN, SETBITS, old_stdin);
- X if (old_stdout)
- X (void) ioctl(STDOUT, SETBITS, old_stdout);
- X}
- X
- Xstatic unsigned int
- Xioctl(handle, mode, setvalue)
- Xunsigned int setvalue;
- X{
- X union REGS regs;
- X
- X regs.h.ah = IOCTL;
- X regs.h.al = (unsigned char) mode;
- X regs.x.bx = handle;
- X regs.h.dl = (unsigned char) setvalue;
- X regs.h.dh = 0; /* Zero out dh */
- X intdos(®s, ®s);
- X return (regs.x.dx);
- X}
- X
- X/* Normal characters are output when the shift key is not pushed.
- X * Shift characters are output when either shift key is pushed.
- X */
- X#define KEYPADHI 83
- X#define KEYPADLOW 71
- X#define ISKEYPAD(x) (KEYPADLOW <= (x) && (x) <= KEYPADHI)
- X#undef CTRL
- X#define CTRL(x) (x - '@')
- Xtypedef struct {
- X char normal, shift, numlock;
- X} KEY;
- Xstatic KEY roguekeypad[KEYPADHI - KEYPADLOW + 1] = {
- X {'y', 'Y', CTRL('Y')}, /* 7 */
- X {'k', 'K', CTRL('K')}, /* 8 */
- X {'u', 'U', CTRL('U')}, /* 9 */
- X {'.', '.', '.'}, /* - */
- X {'h', 'H', CTRL('H')}, /* 4 */
- X {'.', '.', '.'}, /* 5 */
- X {'l', 'L', CTRL('L')}, /* 6 */
- X {CTRL('P'), CTRL('P'), CTRL('P')}, /* + */
- X {'b', 'B', CTRL('B')}, /* 1 */
- X {'j', 'J', CTRL('J')}, /* 2 */
- X {'n', 'N', CTRL('N')}, /* 3 */
- X {'i', 'i', 'i'}, /* Ins */
- X {'.', '.', '.'} /* Del */
- X};
- Xstatic KEY originalkeypad[KEYPADHI - KEYPADLOW + 1] = {
- X {'7', '7', '7'}, /* 7 */
- X {'8', '8', '8'}, /* 8 */
- X {'9', '9', '9'}, /* 9 */
- X {'-', '-', '-'}, /* - */
- X {'4', '4', '4'}, /* 4 */
- X {'5', '5', '5'}, /* 5 - move */
- X {'6', '6', '6'}, /* 6 */
- X {CTRL('M'), CTRL('M'), CTRL('M')}, /* + */
- X {'1', '1', '1'}, /* 1 */
- X {'2', '2', '2'}, /* 2 */
- X {'3', '3', '3'}, /* 3 */
- X {'i', 'i', 'i'}, /* Ins */
- X {'.', '.', '.'} /* Del */
- X};
- X
- X/* bios_getch gets keys directly with a BIOS call.
- X */
- X#define SHIFT (0x1 | 0x2)
- X#define NUMLOCK 0x20
- X#define KEYBRD_BIOS 0x16
- X
- Xint
- Xbios_getch()
- X{
- X unsigned char scan, shift;
- X int ch;
- X KEY *kp;
- X union REGS regs;
- X
- X if (rogue_like_commands)
- X kp = roguekeypad;
- X else
- X kp = originalkeypad;
- X
- X /* Get scan code.
- X */
- X regs.h.ah = 0;
- X int86(KEYBRD_BIOS, ®s, ®s);
- X ch = regs.h.al;
- X scan = regs.h.ah;
- X
- X /* Get shift status.
- X */
- X regs.h.ah = 2;
- X int86(KEYBRD_BIOS, ®s, ®s);
- X shift = regs.h.al;
- X
- X /* If scan code is for the keypad, translate it.
- X */
- X if (ISKEYPAD(scan)) {
- X if (shift & NUMLOCK)
- X ch = kp[scan - KEYPADLOW].numlock;
- X else if (shift & SHIFT)
- X ch = kp[scan - KEYPADLOW].shift;
- X else
- X ch = kp[scan - KEYPADLOW].normal;
- X }
- X return ch;
- X}
- X
- Xint
- Xmsdos_getch()
- X{
- X int ch;
- X
- X if (ibmbios)
- X ch = bios_getch();
- X else {
- X ch = getch();
- X if (ch == 0)
- X ch = getch();
- X }
- X return ch;
- X}
- X
- X#if 0
- X/* This intro message deleted because it is obsolete. */
- X
- X/* Hardcode the introductory message in */
- Xvoid
- Xmsdos_intro()
- X{
- X char buf[80];
- X
- X clear_screen();
- X wmove(stdscr,0,0);
- X waddstr(stdscr," *********************");
- X wmove(stdscr,1,0);
- X sprintf(buf," ** Moria %d.%d **",
- X CUR_VERSION_MAJ, CUR_VERSION_MIN);
- X waddstr(stdscr,buf);
- X wmove(stdscr,2,0);
- X waddstr(stdscr," *********************");
- X wmove(stdscr,3,0);
- X waddstr(stdscr," COPYRIGHT (c) Robert Alan Koeneke");
- X wmove(stdscr,5,0);
- X waddstr(stdscr,"Programmers : Robert Alan Koeneke / University of Oklahoma");
- X wmove(stdscr,6,0);
- X waddstr(stdscr," Jimmey Wayne Todd / University of Oklahoma");
- X wmove(stdscr,8,0);
- X waddstr(stdscr,"UNIX Port : James E. Wilson / Cygnus Support");
- X wmove(stdscr,10,0);
- X waddstr(stdscr,"MSDOS Port : Don Kneller / 1349 - 10th ave");
- X wmove(stdscr,11,0);
- X waddstr(stdscr,
- X " / San Francisco, CA 94122");
- X wmove(stdscr,12,0);
- X waddstr(stdscr," / Dec 12, 1988");
- X pause_line(23);
- X}
- X#endif
- X
- X#ifdef PC_CURSES
- X/* Seems to be a bug in PCcurses whereby it won't really clear the screen
- X * if there are characters there it doesn't know about.
- X */
- X#define VIDEOINT 0x10
- Xvoid
- Xbios_clear()
- X{
- X union REGS regs;
- X unsigned char nocols, activepage;
- X
- X#ifdef ANSI
- X if (ansi)
- X return;
- X#endif
- X
- X /* get video attributes */
- X regs.h.ah = 15;
- X int86(VIDEOINT, ®s, ®s);
- X nocols = regs.h.ah;
- X activepage = regs.h.bh;
- X
- X /* Move to lower right corner */
- X regs.h.ah = 2;
- X regs.h.dh = (unsigned char) 24;
- X regs.h.dl = nocols - 1; /* lower right col */
- X regs.h.bh = activepage;
- X int86(VIDEOINT, ®s, ®s);
- X
- X /* get current attribute into bh */
- X regs.h.ah = 8;
- X regs.h.bh = activepage;
- X int86(VIDEOINT, ®s, ®s);
- X regs.h.bh = regs.h.ah;
- X
- X regs.h.cl = 0; /* upper left row */
- X regs.h.ch = 0; /* upper left col */
- X regs.h.dh = (unsigned char) 24; /* lower right row */
- X regs.h.dl = nocols - 1; /* lower right col */
- X regs.h.al = 0; /* clear window */
- X regs.h.ah = 7; /* scroll down */
- X int86(VIDEOINT, ®s, ®s);
- X}
- X#endif
- X
- X#endif
- END_OF_FILE
- if test 11297 -ne `wc -c <'ibmpc/ms_misc.c'`; then
- echo shar: \"'ibmpc/ms_misc.c'\" unpacked with wrong size!
- fi
- # end of 'ibmpc/ms_misc.c'
- fi
- if test -f 'misc/shading' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'misc/shading'\"
- else
- echo shar: Extracting \"'misc/shading'\" \(8888 characters\)
- sed "s/^X//" >'misc/shading' <<'END_OF_FILE'
- XFrom ucbvax!tut.cis.ohio-state.edu!mailrus!uflorida!gatech!ncsuvx!ecemwl!jnh
- XStatus: RO
- X
- XArticle 1484 of rec.games.programmer:
- XPath: ucbvax!tut.cis.ohio-state.edu!mailrus!uflorida!gatech!ncsuvx!ecemwl!jnh
- X>From: jnh@ecemwl.ncsu.edu (Joseph N. Hall)
- XNewsgroups: rec.games.programmer
- XSubject: Shading and line-of-sight calculation _en_masse_...
- XKeywords: very very fast
- XMessage-ID: <4036@ncsuvx.ncsu.edu>
- XDate: 25 Sep 89 17:10:09 GMT
- XSender: news@ncsuvx.ncsu.edu
- XReply-To: jnh@ecemwl.UUCP (Joseph N. Hall)
- XOrganization: North Carolina State University
- XLines: 192
- X
- XHere is a rough presentation of the technique for calculating shading and
- Xvisibility that I had mentioned earlier.
- X
- X...
- X
- X(summary)
- X
- XA Fast Algorithm for Calculating Shading and Visibility in a
- XTwo-Dimensional Field
- X
- XBy Joseph Hall
- XApplications Programmer, North Carolina State University
- X
- XThis document copyright 1989 by Joseph Hall. It may be reproduced in
- Xentirety for distribution for any purpose, so long as no fee whatsoever
- Xis charged for its distribution and no attempt is made to restrict its
- Xdistribution. No other use is allowed without permission from the author.
- XPermission from the author must be obtained if a substantial portion of
- Xthis document is to be included in another copyrighted work.
- X
- XAs the author of this document, I hereby release the ALGORITHMS described
- Xherein into the public domain. This release does not apply to the actual
- Xtext of this document.
- X
- X---
- X
- XInteractive terminal-based "rogue-like" games such as Hack, Moria, Omega,
- Xand, of course, the original Rogue, feature a player character traveling
- Xthrough a maze. The maze usually comprises several levels and is usually
- Xlaid out on a grid of squares or "tiles." Each tile contains one of several
- Xdistinct features, e.g., a piece of wall, floor, door, etc., and may also
- Xcontain objects and/or creatures, if it is not solid.
- X
- XHack and Rogue handle lighting and visibility quite simply. All corridors
- Xand walls are "visible" once they have been seen. Rooms are square and are
- Xeither "lit" or "dark." A player carrying a lamp can see with a radius of
- X1 tile if he is in a corridor (which is always dark) or in a dark room.
- XA player cannot see the occupants of a room until he steps into that room.
- XThese conditions eliminate the possible complexity of line-of-sight and
- Xshading computations, but detract somewhat from the "realism" of the game.
- X
- XMoria, on the other hand, allows for line-of-sight considerations. A player
- Xcan see whatever is standing or resting on a tile is it is both lit and
- Xcan be seen from his current location, i.e., if there are no "solid" tiles,
- Xsuch as walls or closed doors, intervening. Thus a player can see some of
- Xthe contents of a room as he approaches its entrance, and more as he gets
- Xcloser. Moria does not, however, allow for lights of radius greater than
- Xone tile, and only the player is allowed to carry a light. Again, all rooms
- Xare either lit or not lit, and corridors are dark, although certain player
- Xactions can permanently light portions of corridors and permanently light
- Xor darken portions of rooms.
- X
- XOne can see the desirability of a more complex scheme, where the player
- Xis allowed a lamp of variable radius, other creatures can carry lamps, and
- Xrooms are lit by lamps with finite radius. Such a scheme is not trivial to
- Ximplement, at least from the standpoint of the bookkeeping required, but the
- Xgreatest difficulty is the amount of calculation required, which can easily
- Xtake long enough on a microcomputer to remove the interactive feel of
- Xthe game.
- X
- XConsider:
- X
- XWhenever the player moves, and thus his viewpoint changes, the visibility
- Xof the entire area surrounding him must be recalculated. This area will be
- Xeither the visible area on the screen or the portion of it within a limited
- X"sight radius" of the player. A sight radius of at least 25 tiles is
- Xdesirable, and this could entail calculations for pi * 25 * 25 tiles, or
- Xabout 2000 tiles.
- X
- XAdditionally, whenever a light source moves (when carried by the player or
- Xby another creature), the lighting status of the area within the effective
- Xradius of the light source must be recalculated. Although a radius of 1-5
- Xtiles is probably optimum for players and other creatures, there may be a
- Xnumber of these light sources on screen at the same time, and larger radii
- Xalso have some application.
- X
- XFinally, considerable recalculation is required whenever the solidity of a
- Xvisible tile changes, e.g., when a door opens or closes.
- X
- XThe obvious approach to all of the above situations is to calculate both
- Xvisibility and lighting status on a tile-by-tile basis using an ordinary
- X"line-of-sight" routine. That is, for each light source on screen, calculate
- Xwhether it lights a tile within its radius by seeing whether a line of sight
- Xexists between it and the tile; similarly, once the lighting status of all
- Xtiles on screen is known, calculate whether the player can see them by
- Xchecking the line of sight from the player to each of the surrounding tiles.
- X
- XThe difficulty here is that the line-of-sight routine must check each of the
- Xtiles intervening between the player/light source and destination. This
- Xmakes the calculations described above roughly O(n^3), which is generally
- Xunsuitable.
- X
- XA previous posting on USENET suggested using "rays" emanating from the player
- Xor light source, one ray to each screen border tile or each tile of limiting
- Xcircumference. The algorithm involves checking the solidity of tiles along
- Xeach ray, beginning at the player or light source, and marking them visible
- Xuntil a solid object is encountered. While this is fast and efficient, it
- Xis incorrect. To wit:
- X
- X . | . | |
- X . . | . . | . |
- X . . . | . . . * * * * . . .
- X@ . x . | @ . x * * @ . x * * @ . . . . @ . .
- X
- X (1) (2) (3) (4) (5)
- X
- X
- XHere, @ is the center of a light source, x is a solid object, '*' represents
- Xa shaded tile, '.' is a lit tile, and '|' is a boundary. (1) shows the system
- Xwithout shading. (2) is the correct shading. (3) is the shading generated
- Xby the above algorithm. (4) and (5) are the lines of sight to the border that
- Xcause the incorrect shading to be generated. The correct shading will be
- Xgenerated only for the border tiles, and there will be some inaccuracies in
- Xthe remaining shading.
- X
- XThe author has, however, found an efficient technique that relies on
- Xtables of pre-calculated, rasterized shading.
- X
- XConsider this situation:
- X
- X . . . *
- X . . . . . . * *
- X . . . . . . . . * * * *
- X . 3 . . . . . . . . * * . 3 * .
- X . . 2 . . . . . . . . . 2 * * . . . . .
- X @ . . 1 . . @ . . 1 * * @ . . . . . @ . . . . .
- X
- X (6) (7) (8) (9)
- X
- X'1,' '2,' and '3' represent solid objects. (7), (8) and (9) are the shading
- Xgenerated by the individual objects. The total shading can be generated by
- Xoverlaying (7), (8) and (9):
- X
- X *
- X * *
- X * * *
- X . 3 * *
- X . . 2 * *
- X @ . . 1 * *
- X
- X (10)
- X
- XThus the problem of calculating shading for an area can be reduced to one of
- X"summing" the shadows that its individual tiles create. This procedure is
- Xstraightforward and won't be detailed in this short report.
- X
- XHOW TO STORE the pre-calculated shadows is a matter to consider, however.
- XOne might expect a full set of shadows, say, out to a radius of 32, to
- Xoccupy an inordinate amount of space, or, if tightly compressed, to present
- Xproblems in retrieval. But this turns out to be not nearly so bad.
- X
- XSymmetry considerations, first, reduce the number of shadows that must be
- Xstored by a factor of 8, since only one "octant" (45-degree slice), as
- Xshown above, need be calculated.
- X
- XThe shadows can be stored as a series of "rasters," using the following
- Xrepresentation for each shadow:
- X
- X byte
- X 1 # of rasters in this shadow
- X 2 #1 start
- X 3 #1 end
- X 4 #2 start
- X 5 #2 end
- X ...
- X
- X(7), (8) and (9) can be translated as follows:
- X
- X (7) 1 4-5
- X (8) 3 4-5 4-5 5-5
- X (9) 4 4-4 3-5 4-5 5-5
- X
- XThe full set of radius-32 shadows can, in fact, be stored in a readily-
- Xaccessible table of LESS THAN 9000 BYTES.
- X
- X...
- X
- XI have written a prototype that uses this shading technique. Missing
- Xcertain optimizations in its current version, it still calculates a 32 x 32
- Xarea in a relatively-constant 50 milliseconds on an 8MHz 68000. The
- Xmost efficient conventional LOS-based version that I have been able to write
- Xtakes about 800 milliseconds. (!)
- X
- XI am working on a cleaner version of the prototype and table generator and
- Xwill present them and a detailed report later (a couple of weeks?) in
- Xrec.games.programmer.
- X
- X
- Xv v sssss|| joseph hall || 4116 Brewster Drive
- X v v s s || jnh@ecemwl.ncsu.edu (Internet) || Raleigh, NC 27606
- X v sss || SP Software/CAD Tool Developer, Mac Hacker and Keyboardist
- X-----------|| Disclaimer: NCSU may not share my views, but is welcome to.
- X
- X
- END_OF_FILE
- if test 8888 -ne `wc -c <'misc/shading'`; then
- echo shar: \"'misc/shading'\" unpacked with wrong size!
- fi
- # end of 'misc/shading'
- fi
- if test -f 'util/weapons/README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'util/weapons/README'\"
- else
- echo shar: Extracting \"'util/weapons/README'\" \(10766 characters\)
- sed "s/^X//" >'util/weapons/README' <<'END_OF_FILE'
- X
- X>
- X> Here's a question for all of you who have had experiences with HA's. Is a
- X> dagger a better weapon than say, a war hammer or an axe? I've found a
- X> bodkin [+8,+8] and a war hammer [+7,+8], and found that the dagger sold
- X> for more in the stores. Why? Just because it is one up on To-Hit?? To me,
- X> it would seem like the war hammer is a way better weapon... Well, the
- X> difference between the prices is about 1000 gp.
- X>
- X
- X
- X
- Xok, here are some spoilers.
- X
- X
- X1) dont trust what the store will buy or sell things for as being a
- X good indicator of its true value. they basis it only on the base
- X value of a weapon, the to-hit and to-damage, and the special
- X abilities it has. these are _not_ always what makes a weapon
- X really good, and what might be good for one character may be bad
- X for another.
- X
- X2) when in doubt, keep the dagger. daggers are probably best for all
- X types of characters (mages, warriors etc) until you get your
- X strength and dexterity up real high.
- X
- X
- Xa detail explanation of how things work follows...
- X
- X
- Xthe amount of damage that a weapon will do is based on the following things:
- X
- X * the weight of the weapon. the lighter it is the more likely you
- X will get two hits in for each attack. on the other hand, the
- X heavier the weapon, the more likely you are to get a critical hit
- X (good, excellent, great hits).
- X
- X * the basic amount of damage the weapon does. most daggers do 1d4,
- X two handed swords (Zweihander) do 4d6.
- X
- X * your total to-hit. this includes the pluses that come with your
- X weapon, the minuses that your armor does, any rings of to-hit or
- X slaying, etc. the higher your total to-hit is, the more likely
- X you are to get a critical blow.
- X
- X * your total to-damage. like your total to-hit, this includes
- X everything. when you get a really good character, this will
- X usually dominate over the weapons basic damage.
- X
- X * your current strength. the stronger you are the easier it is for
- X you to get several hits per attack.
- X
- X * your current dexterity. the more dextrous you are the more hits
- X per attack you are capable of.
- X
- X * the level of your character. the more experience you have the
- X more likely you are to get a "good (x2)" or "excellent (x3)" hit.
- X
- X
- Xall of these things are mixed together in a rather complicated way. i
- Xhad to write a program that takes all of these factors into account
- Xand gives a true indication of which weapon is better. (i had two
- XHA's that i couldnt decide between. it turned out that depending on
- Xmy current strength and dex either one could be much better than the
- Xother. i ended up keeping both of them until both my str and dex were
- X18/100.)
- X
- X
- Xthe chance that you actually hit the monster is based on:
- X
- X * your "base to hit". this is based on what race your character is
- X and ranges from -10 for Halflings to 20 for Half-Trolls. it also
- X depends on what "class" your character is and these bonuses range
- X from 20 for mages to 70 for paladin's. (warriors arent much
- X behind with a bonus of 68). a human mage will have a "base to
- X hit" of 20, a half troll warrior will have a "base to hit" of 88.
- X
- X * your current level. the more experience you have, the more likely
- X you are to hit the monster. going up one level is equivalent to
- X enchanting your weapon's to-hit by one.
- X
- X * your total to-hit. the higher your total to-hit, the more likely
- X you are to hit the monster
- X
- X * the monsters ac (armor class). the higher the monster's ac, the
- X less likely you are to hit the monster. this varies a lot from
- X monster to monster. most worm masses, mushrooms, jellies and
- X stuff have ac's under 10. most of the ancient dragons have ac's
- X in the 80-100 range. the balrog has an ac of 125, the highest of
- X any monster. iron golems have an ac of 99, which can give you
- X some idea of how hard it would be to hit a ancient dragon without
- X taking too many risks. most of the other monsters seem to to be
- X in the 30-60 range.
- X
- X the formula for this is:
- X
- X val = bth + 3*level + 3*tohit
- X
- X if a random number between 1 and val is greater than the
- X monsters ac, then you hit, otherwise you miss.
- X
- X you will always hit one out of 20 times, even if your weapon is too
- X heavy for you to wield.
- X
- Xi dont have anything to calculate calculate your chances to hit
- Xmonsters because there are just too many different cases. a level 40
- Xhalf-troll warrior with a total to hit of 30 would have a two out of
- Xthree chance of hitting a AMHD. everyone else is going to going to be
- Xwell under 50-50.
- X
- X
- X
- XThe program "calc_hits" can help you figure out which weapon is better
- Xfor you now, and as your strength and dexterity goes up. it is based
- Xon the source code to moria so it should be basically correct.
- Xcalc_hits isnt a fancy program and it handles errors by stopping the
- Xprogram. it is designed to be used by the person who wrote it. :->
- X
- X
- Xprobably the best way to explain how to run the program is simply to
- Xgive you an example run comparing a bastard sword, a dagger (stiletto)
- Xand a two handed great flail. all of them will be (+3,+4) giving you
- Xa total to-hit of 2 and a total to-damage of 4.
- X
- Xthe results are given in a table form with the following field:
- X
- XMblow is the maximum number of blows you can get per attack. it is
- X based only on your dex.
- X
- XBlows is the number of plows you can get with your current strength
- X based on the Mblows, and strength/weight ratio.
- X
- Xwt ratio is your strength to weight of weapon ratio. a ratio above 10
- X doesnt do you any more good than a ratio of 10. if the ratio is
- X under 2, you can only get one blow no matter what your dex is.
- X
- Xdam is the amount of damage that you get, on the average if you hit
- X with every blow and dont get a critical hit.
- X
- Xw/ critical is the amount of damage you get on the average if you
- X include the possibilities of getting a critical hit. for low
- X level characters, this rarely makes a difference. for high
- X level characters, this can make a real difference.
- X
- X(wayne 6) % calc_hits
- XEnter level of your character: 12
- XEnter number of weapons: 3
- XEnter weight, weapon_dam, to_hit, to_dam for weapon #0: 140 3d4 2 4
- XEnter weight, weapon_dam, to_hit, to_dam for weapon #1: 12 1d4 2 4
- XEnter weight, weapon_dam, to_hit, to_dam for weapon #2: 280 3d6 2 4
- XEnter cstr, cdex: 11 14
- X| Weapon | Max blows | Blows | weight ratio | hp of dam | w/ critical |
- X| 0 | 2 | 1 | 0 | 11 | 12 |
- X| 1 | 2 | 2 | 9 | 13 | 13 |
- X| 2 | 0 | 0 | 0 | 0 | 0 |
- X
- XEnter cstr, cdex: 17 18
- X| Weapon | Max blows | Blows | weight ratio | hp of dam | w/ critical |
- X| 0 | 2 | 1 | 1 | 11 | 12 |
- X| 1 | 2 | 2 | 14 | 13 | 13 |
- X| 2 | 0 | 0 | 0 | 0 | 0 |
- X
- XEnter cstr, cdex: 18/20 18/10
- X| Weapon | Max blows | Blows | weight ratio | hp of dam | w/ critical |
- X| 0 | 3 | 2 | 2 | 23 | 25 |
- X| 1 | 3 | 3 | 31 | 19 | 19 |
- X| 2 | 3 | 1 | 1 | 14 | 17 |
- X
- XEnter cstr, cdex: 18/100 18/100
- X| Weapon | Max blows | Blows | weight ratio | hp of dam | w/ critical |
- X| 0 | 6 | 4 | 8 | 46 | 50 |
- X| 1 | 6 | 5 | 98 | 32 | 32 |
- X| 2 | 6 | 3 | 4 | 43 | 52 |
- X
- XEnter cstr, cdex:
- X(wayne 7) % exit
- X
- X
- X
- X
- X
- Xthere is a second program called "mk_all_weapon" that generates a list
- Xof how much damage all weapons will do given a certain character. it
- Xis useful for getting a feel of which weapons are good and why.
- X
- X
- Xfor low level characters, the following are the top 5 weapons:
- X
- Xcharacter level of 12
- Xtotal to-hit and to-damage of +7
- Xstrength of 11. these numbers wont change much until you get above 18
- Xdexterity of 17. these numbers will be the same unless your dex is
- X above 18/01 or below 10.
- X
- X Name | Mblow | Blows | wt ratio | dam | w/ critical |
- XDagger (Stiletto) | 2 | 2 | 9 | 19 | 19 |
- XDagger (Misercorde) | 2 | 2 | 7 | 19 | 19 |
- XDagger (Bodkin) | 2 | 2 | 5 | 19 | 19 |
- XMorningstar | 2 | 1 | 0 | 14 | 15 |
- XKatana | 2 | 1 | 0 | 14 | 15 |
- X
- Xthe bottom 5 for a low level character:
- X
- XFauchard | 0 | 0 | 0 | 0 | 0 |
- XExecutioner's Sword | 0 | 0 | 0 | 0 | 0 |
- XBeaked Axe | 0 | 0 | 0 | 0 | 0 |
- XBattle Axe (European) | 0 | 0 | 0 | 0 | 0 |
- XBattle Axe (Balestarius) | 0 | 0 | 0 | 0 | 0 |
- X
- X
- X
- Xfor high level characters, the following are the top 5 weapons:
- X
- Xcharacter level of 36
- Xtotal to-hit and to-damage of +20
- Xstrength of 18/100.
- Xdexterity of 18/100.
- X
- X Name | Mblow | Blows | wt ratio | dam | w/ critical |
- XKatana | 6 | 5 | 9 | 137 | 161 |
- XWar Hammer | 6 | 5 | 9 | 130 | 153 |
- XLucerne Hammer | 6 | 5 | 9 | 130 | 153 |
- XTwo Handed Sword (Claymore) | 6 | 4 | 5 | 122 | 151 |
- XTwo Handed Sword (No-Dachi) | 6 | 4 | 5 | 120 | 149 |
- X
- Xthe bottom 5
- X
- XTwo Handed Great Flail | 6 | 3 | 4 | 91 | 120 |
- XBall and Chain | 6 | 4 | 7 | 100 | 120 |
- XAwl-Pike | 6 | 4 | 7 | 98 | 118 |
- XLance | 6 | 3 | 3 | 87 | 117 |
- XFauchard | 6 | 4 | 6 | 84 | 102 |
- X
- X
- X
- Xthe katana tends to be at or near the top for all characters at all
- Xtimes. if you get even a poor katana (HA) or (DF), keep it and enchant
- Xit.
- X
- X
- Xone of the biggest mistakes people do is get rid of the weapon that
- Xthe start with and try to get a "bigger meaner" weapon. dont. just
- Xenchant your original weapon until you get something really good. i
- Xdont consider the (FT), (FB), (SD), (SE) and (SU) as "really good". i
- Xconsider the "(SM)" good, only if i dont already have something of see
- Xinvisible. (HA) and (DF)'s i keep if they are better than the ones i
- Xalready have.
- X
- X
- X-wayne
- END_OF_FILE
- if test 10766 -ne `wc -c <'util/weapons/README'`; then
- echo shar: \"'util/weapons/README'\" unpacked with wrong size!
- fi
- # end of 'util/weapons/README'
- fi
- echo shar: End of archive 31 \(of 39\).
- cp /dev/null ark31isdone
- 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
-