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: v14i060: umoria4 - single player dungeon simulation (ver. 5.5), Part28/39
- Message-ID: <3424@master.CNA.TEK.COM>
- Date: 22 Aug 92 22:13:51 GMT
- Sender: news@master.CNA.TEK.COM
- Lines: 1959
- Approved: billr@saab.CNA.TEK.COM
-
- Submitted-by: grabiner@math.harvard.edu (David Grabiner)
- Posting-number: Volume 14, Issue 60
- Archive-name: umoria4/Part28
- 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 28 (of 39)."
- # Contents: doc/FEATURES.NEW misc/rick.msg util/mc/creature.y
- # Wrapped by billr@saab on Thu Aug 20 09:11:33 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'doc/FEATURES.NEW' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'doc/FEATURES.NEW'\"
- else
- echo shar: Extracting \"'doc/FEATURES.NEW'\" \(11714 characters\)
- sed "s/^X//" >'doc/FEATURES.NEW' <<'END_OF_FILE'
- X
- XYou get a warning for spells or prayers beyond your strength.
- X
- XInventory commands (wear, wield, exchange, take off, drop) now always
- Xtake one move each. If anything significant happens during that move,
- Xsuch as a monster moving somewhere, the screen will be redisplayed.
- XInventories are displayed in the top-right corner of the screen, to minimize
- Xthe number of characters that must be redrawn afterwards, this makes the game
- Xmuch more playable on slow speed modems.
- X
- XWhen selecting items or spells, you can select with a capital letter to
- Xprint a description and confirm you really want that one.
- X
- XYou can now associate counts with commands. The '?' command shows you
- Xthe possibilities. In rogue command mode, simply type in the number.
- XIn this mode, numbers are no longer simple commands.
- XIn original moria command mode, enter a '#' to start a count.
- X
- XThere are options (set with the = command) to display weights in
- Xan inventory, to highlight mineral seams, to ignore open doors
- Xwhile running, etc.
- X
- XMonster memory: use the / command to access info about a monster after you
- Xhave seen/killed at least one of them. This can also be accessed from
- Xthe look 'l' command.
- X
- XCan enter control characters with two keystrokes using ^ key, useful for
- Xnoisy phone lines? or stupid terminals?
- X
- X'M'ap command shows reduced size map. 'L' allows you to scroll around entire
- Xmap. The 'L' command also will now center the character on the screen.
- X
- XLook 'l' views all objects in an arc in the specified direction, or specify
- X'5' and it will look in every direction.
- X
- XCan change your speed in wizard mode.
- X
- XNew field in status line, used for rest/paralysed/searching/repeat counts.
- X
- XNew field in status line shows speed.
- X
- XCan die of starvation.
- X
- XIf carrying too much weight, you will be slowed immediately, the amount slowed
- Xdepends on how much over the weight limit you are.
- X
- XCan not circle monsters (moving at the same speed as yourself)
- Xby moving around them in a diamond pattern.
- X
- XHigh level monsters have a chance of ignoring your bash, and they also have
- Xa chance of recovering immediately even if stunned. You can not bash the
- XBalrog.
- X
- XCan abort rest/repeated command by hitting any character.
- X
- XEvery duration affect prints a command when it wears off previously
- Xresist heat and resist cold, and perhaps others did not.
- X
- XNew find/run algorithm which is much better than the old one. Also,
- Xbetter handling of dangerous conditions that occur during repeat commands/runs.
- XAn attack will always stop a repeated command and find/run mode.
- X
- XCan inscribe names onto objects. Some inscriptions are automatic:
- Xan empty wand/staff is inscribed 'empty'. An object which is used, but its
- Xuse does not identify it is inscribed 'tried'. Cursed objects are inscribed
- X'damned' when identified as cursed. If you detect an object is enchanted,
- Xit is inscribed 'magik'.
- X
- XScrolls have their titles removed after being identified. Scrolls/potions
- Xfrom the store/dungeon can stack after the dungeon item is identified.
- X
- XIf you curse/damage a special object, such as a Holy Avenger sword, it
- Xwill lose its special property.
- X
- XWill automatically save the game correctly if a HANGUP signal is received,
- Xi.e. dropped dialup connection, the network crashes, etc. The save file
- Xis not a panic save, instead the program plays the game for you (i.e.
- Xpretends that you are hitting ESCAPE) until it is safe to save the game.
- X
- XBetter handling of inventory/equipment lists, i.e. you can drop items
- Xin the equipment list, can identify items in the equipment list, etc.
- X
- XMore consistent monster definitions, i.e. creatures with frost attacks
- Xalways take extra damage from fire (except those that also have fire
- Xattacks), and many other fixes.
- X
- XOne source for the UNIX/IBM/Atari ST/Amiga/Mac/VMS versions, should make
- Xkeeping the micro versions up-to-date much easier. The game is smaller and
- Xhopefully faster. Savefiles are now relatively machine independent, they
- Xshould transport from one mini/micro to another without any problems.
- X
- XIf you are hallucinating, ^R won't help.
- X
- XBows can have a pluses to damage. These pluses only apply if you are
- Xusing the bow to fire the appropriate type of missile (arrow/bolt/etc).
- X
- XCan haggle incrementally in the stores, i.e. can increase bid by 10
- Xby typing +10, similarly -10 will decrease bid by 10.
- X
- XBeeps if invalid character entered at most prompts.
- X
- XCan type ^R at any time to refresh the screen.
- X
- XArmor/weapons show their base AC/hit/dam values in their name.
- X
- XAny of RETURN (^M), LF (^J), SPACE, or ESCAPE can be typed at -more- prompts.
- X
- XWhen droping a group of items, you have the choice of dropping only one,
- Xor all of them.
- X
- XThere is a small chance that a player will notice that there are unidentified
- Xmagic items in the inventory. The chance is larger if the item is in the
- Xequipment list.
- X
- XObject distribution has been changed so that when you are deep in the dungeon,
- Xthere are many more high level objects created than low level objects.
- X
- XMonster distribution changed so that when you are deep in the dungeon,
- Xyou will meet many more high level monsters than low level monsters.
- X
- XAdditional spikes make a door harder to open, in a progressively decreasing
- Xsequence, that is, the more spikes you add, the less effect each additional
- Xspike has.
- X
- XWhen a stat changes, all abilities/etc that depend on the stat will immediately
- Xchange. For example, if you CON increases, then your hit points will increase,
- Xif your INT/WIS increases then your mana will immediately increase and you
- Xwill immediately learn new spells/prayers. This makes the Grape Jelly trick
- Xcompletely unnecessary, and, in fact, it will has no effect.
- X
- XSpell/prayer letters never change, i.e. if you know the second spell of a book,
- Xit will not be referred to as spell 'a' if you do not know the first spell.
- X
- XWhen haggling, if you have reach the final offer much more often than you
- Xhaven't, then the store will give you the benefit of the doubt and go
- Xdirectly to the final price. The exact formula is (good > 3*bad + 20).
- XTwo sets of numbers are kept for every store, one for buying and one for
- Xselling.
- X
- XWhen wielding a weapon that is too heavy, the to hit penalty will be shown
- Xby the 'C' command.
- X
- XIt is harder to hit monsters when you can't see them.
- X
- XPerfect stealth is impossible now.
- X
- XSave files are now encrypted.
- X
- XSlay monster items are now slay animal. The previous slay monster item
- Xdid not work as stated by the documentation, fixing it to work reasonably
- Xwould have made it too powerful.
- X
- XIf picking up an item will slow you down, you are asked if you really want
- Xto pick it up.
- X
- XSpells work differently now. You no longer learn them automatically when
- Xyou gain a level. Instead, 'Study' appears in the status line when are
- Xcapable of learning new spells. Use the 'G' command to actually learn
- Xthe spells. The 'G' command can be used anytime that you are eligible to
- Xlearn new spells, as for example, after quaffing a restore intelligence/wisdom
- Xpotion.
- X
- XThe object naming routines are completely rewritten. This makes the program
- Xmuch smaller. Also, too long names will no longer cause a crash or error,
- Xthey will be silently truncated as necessary.
- X
- XYou can not attack an invisible/unlit monster in a wall by merely moving
- Xinto the wall, instead you must tunnel into the wall. Since moving into
- Xa wall is a free turn, people could take advantage of this while fighting
- Xinvis monsters by checking all of the walls first.
- X
- XTo change the default moria save file name, define the environment variable
- X"MORIA_SAV" to be the full pathname for where you want your save files.
- X
- X"moria -n" will start a new game, and will ignore "moria.save" if it exists
- X
- XJellies and molds never carry treasure.
- X
- XRecharging a high level wand, or a wand which already has many charges, is
- Xmuch more likely to fail.
- X
- XElves and half-elves have infravision now.
- X
- XThere is no longer a distinction between wizard and god mode; only wizard mode
- Xexists now. Also, wizard mode no longer requires a password, and anyone
- X(not just the installer) can enter wizard mode. Hence, wizard now works the
- Xsame no matter whether you are playing on a micro or a mini. Enter wizard
- Xmode by using the ^W command, help is ^H. (Or for the rogue-like option,
- X^W and \).
- X
- XMissile weapons are much more powerful when used with the proper weapon.
- XFor example, firing a bolt from a heavy crossbow multiplies its damage by 4.
- Xrounded pebble, iron shot: sling = 2x
- Xarrow: short bow = 2x, long bow = 3x, composite bow = 4x
- Xbolt: light crossbow = 3x, heavy crossbow = 4x
- XArrows and bolts appear more often deep in the dungeon.
- XMagical missile weapon prices are more reasonable.
- X
- XThe miscellaneous abilities 'fighting', 'bows/throw', 'saving throw', 'disarm',
- Xand 'magical device' are all level dependent, i.e. they improve as you gain
- Xlevels. Formerly, the rate of improvement was independent of class, now,
- Xhowever, the learning rate is clas dependent. For example, warriors gain
- Xproficiency at fighting twice as fast as mages/priests now. As a result,
- Xhigh level warriors are better fighters than before, and high level
- Xmages/priests do not fight as well as they used to. The complete table is:
- X Magic Saving
- X Fighting Bows Devices Disarm Throw
- XWarrior 4 4 2 2 3
- XMage 2 2 4 3 3
- XPriest 2 2 4 3 3
- XRogue 3 4 3 4 3
- XRanger 3 4 3 3 3
- XPaladin 3 3 3 2 3
- XIn all cases, three is equivalent to the old rate.
- X
- Xumoria now understands tilde (~) characters at the start of a file name.
- X
- XTo resurrect a dead character, use "moria -w filename".
- X
- XNew status line shows "Is wizard" if in wizard mode, "Was wizard" if
- Xpreviously was in wizard mode, "Resurrected" if character was resurrected,
- Xand "Duplicate" if character is already on the scoreboard.
- X
- XMoved see invisible from slay animal to slay undead, since this makes a lot
- Xmore sense.
- X
- XDragon lightning breath attacks can now damage items in your inventory,
- Xjust like all other dragon breath attacks.
- X
- XNew scoreboard code added. It will hold 1000 scores by default, scores for
- Xsaved characters are listed, can see all scores or just your scores.
- XOn multiuser OS's, each user can only have one entry in the scoreboard for
- Xeach legal race/sex/class combination. The score file format is portable,
- Xand should be able to move from one machine to another with no problems.
- X
- XThe '-s' option will show all scores in the scoreboard. The '-S' option
- Xwill show only your scores. The 'V' command will show all scores in the
- Xscoreboard. A second 'V' command typed immediately afterwards will show
- Xonly your scores.
- X
- XTyping '*' for the rest count will make you rest until you reach max mana
- Xand max hp.
- X
- XSpikes can now be wielded as a weapon for completeness. Note however that
- Xthey make terrible weapons.
- X
- XThe damage multiplier for bows is now displayed as part of their name.
- X
- XTwo new '=' command options: can turn off sound, and can turn off the rest/
- Xrepeat counts displayed on the bottom line. The last is useful for those
- Xplaying at 2400 baud or less, or on very slow machines.
- X
- XMany items are now added to the inventory in a sorted position, e.g.
- Xthe spell books will always end up in the inventory sorted by their level.
- XThis automatic sorting does not work for objects which have a 'color',
- Xe.g. potions, wands, staffs, scrolls.
- X
- XTyping RETURN while haggling will default to the last increment/decrement
- Xamount used.
- X
- XUmoria 5.4:
- X
- XPrints multiple sentences on the message line if they are short enough.
- X
- XUmoria 5.5:
- X
- XThe maximum damage enchantment for a weapon is now equal to its maximum
- Xdamage, instead of being fixed at 10 (there is a slight chance of
- Xenchantment beyond this level); thus daggers are no longer the best
- Xweapons for mid-level characters.
- X
- Xlast modified 8/12/92
- END_OF_FILE
- if test 11714 -ne `wc -c <'doc/FEATURES.NEW'`; then
- echo shar: \"'doc/FEATURES.NEW'\" unpacked with wrong size!
- fi
- # end of 'doc/FEATURES.NEW'
- fi
- if test -f 'misc/rick.msg' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'misc/rick.msg'\"
- else
- echo shar: Extracting \"'misc/rick.msg'\" \(14612 characters\)
- sed "s/^X//" >'misc/rick.msg' <<'END_OF_FILE'
- XFrom 18862246%VUVAXCOM.BITNET@lilac.berkeley.edu Thu Aug 24 13:11:19 1989
- XReceived: from lilac.Berkeley.EDU by ernie.Berkeley.EDU (5.61/1.36)
- X id AA06320; Thu, 24 Aug 89 13:11:14 -0700
- XReceived: by lilac.berkeley.edu (5.61.1/1.16.22)
- X id AA05399; Thu, 24 Aug 89 12:47:05 PDT
- XMessage-Id: <8908241947.AA05399@lilac.berkeley.edu>
- XDate: Thu, 24 Aug 89 15:41 EST
- XFrom: "Computers and you, living life a bit at a time"
- X <188622462%VUVAXCOM.bitnet@lilac.berkeley.edu>
- XSubject: Here is the UPDATE.TXT file
- XTo: wilson@ernie.Berkeley.EDU
- XOriginal_To: BITNET%"wilson@ucbernie"
- XStatus: RO
- X
- X
- XHere are the changes incorporated to date in the upgrade from V5.0 to V6.0:
- X
- X o The source code has been converted from a %INCLUDE format to modular
- X programs. Due to low system memory quotas set on student accounts at my
- X university, compiling the %INCLUDE form was not possible. By converting
- X to modular form, anyone with enough disk space can compile the program,
- X by compiling each module separately, and then linking all the files
- X together. Along with this, I also changed all the indentation in the
- X code so that it is uniform throughout, something that was not there from
- X having four or more different people work on it before.
- X
- X o Creation of a new high score list. Early in Moria's time at my node,
- X many people had found out the Wizard mode password (this was for version
- X 4.3 and then 4.8), so I have created a Wizard Mode Top Twenty list. Part
- X of this has been creating 2 new fields in the player character record to
- X enable Moria to remember if your character ever entered Wizard or God
- X modes. If you used Wizard mode at any point, you are eligible for the
- X Wizard mode list, if you used God mode, you can't get on any list. If
- X you die and aren't allowed to go to either of the lists, the game does
- X tell you what score you earned.
- X
- X o A second effect of everyone here knowing the Wizard password was the
- X continual resurrection of characters by copying the save file and re-
- X storing the character. This lead to multiple copies of the same
- X character appearing on the high score lists. I have solved this problem
- X by adding two more new fields to the character record, to keep track of
- X the birthdate and birthtime of the character, taken from the system time
- X at the same point that the stats are rolled. When a character dies, his
- X birthdate/time is recorded in the highscore file, and whenever that same
- X userid kills another character, it checks to see if the birthdate/times
- X match, if so, then it assumes a clone, and doesn't post the score to the
- X list. The game does tell you what you had earned in this case.
- X
- X o The game now saves the userid of the character's creator in the
- X save file. This prevents one person making a strong character, then
- X giving it to someone else to use to finish off the Balrog.
- X
- X o The increase of stats via special items (ie: HA increasing strength) and
- X via Gain potions has been re-worked. Increase stat items (weapons,
- X rings, crowns, amulets, armor) now affects only the current value of the
- X stat, not the max value. Gain potions affect the max and the current,
- X based on the max value. If you are close to 18/100 and the item would
- X increase you past that, you will see a drop in the current value of the
- X stat when you take it off, but a Restore potion will return you to what
- X it was before you wielded/wore the item.
- X
- X o The changing of the cost of an item has been repaired where an increase
- X to the tohit and todam values are concerned. Also, changes have been
- X implemented wherever items are damaged, so that the shops will know of
- X their decreased value.
- X
- X o The Vampire Bites attack has been modified. Originally, you lost the
- X same amount (or close to it) of hit points as you did experience points
- X (which could be from 18d8 to 32d8, depending on the type of Vampire).
- X The Vampire Bite now takes off 1d6 hit points (logic: you bleed a bit).
- X
- X o The stats area (left side of screen) has been fixed in regards to field
- X widths. All fields, when re-printed, wipe out any extra digits from the
- X previous value. If you have more than 9,999,999 in gold, the string
- X "$$$$$$$" is printed. If more than 9,999,999 experience points are
- X earned, the string "*******" is printed. If you have more than 999 mana
- X then the string "###/###" will be printed.
- X
- X o The God mode function ^C (Make Nice Character) now checks to see if the
- X character is a Magic-using type (ie: not Warrior or Rogue) before upping
- X the mana score. The God function ^E (Change Character) does the same.
- X
- X o A new wizard function: Describe Object. This will give you information
- X about the item specified, including Damage, Tohit and ToDam adjustments,
- X weight, and others. This will not identify an unidentified item, only
- X help you in figuring out if one item is better than another (ie: which
- X sword does more damage?). The hex flags for the item in question will
- X be translated to show what special magic is inherit in the item.
- X
- X o A new God Mode function, ^X, Examine Character. This prints out all the
- X values of the Flags section of the player character record. Useful in
- X debugging purposes.
- X
- X o A bug with Search mode and going up/down stairs has been fixed. When
- X using stairs, Search mode is turned off (if it was on) and the relevant
- X reduction in speed is removed.
- X
- X o All code referring to the "Consultant" classes and the "Extra" spells
- X group have been removed, since a) they were written, but no character
- X race was allowed to be one and b) they were simply slight modifications
- X on the mage class.
- X
- X o In the source, there were two people who used their initials as parts of
- X variable names. These have all been changed to more descriptive names.
- X
- X o The Town generation code has been fixed so that any store could appear
- X at any of the locations, instead of the Black Market always appearing in
- X the upper right-hand corner. The code there has also been fixed so that
- X adding in additional stores should not be difficult.
- X
- X o The various spell books have been fixed so that multiple copies will be
- X listed as "a) 2 Books of <whatever>" in the inventory list.
- X
- X o The running of the Black Market has been fixed up so that it works more
- X like the other stores, except store inventory turn-around is still as
- X as fast as it was before. The inventory will now flucuate in size, just
- X as the other stores do.
- X
- X o A bug involving the Wizard Mode Light Dungeon function and using a torch
- X has been repaired so that the tunnel floors remain lit after passing
- X over them.
- X
- X o Caps/Helms of Intelligence/Wisdom bought in the Black Market now
- X correctly increase the relevant stat.
- X
- X o A bug involving certain area-affect spells (Light Area, any Ball-type
- X spell, etc) and the right-hand and bottom edges of the town level has
- X been fixed.
- X
- X o The magic translation case statements in SCROLLS.PAS and POTIONS.PAS
- X has been fixed to allow a full set of both to be used. Previously,
- X each one was coming up short of the 64 actual possible slots that are
- X available by using two Tval values.
- X
- X o The problem with the special Magic and Prayer books from the Black
- X Market has been fixed so that they appear as separate items in your
- X inventory and are not added with the normal books.
- X
- X o The bug concerning enchanting items bought from the Black Market and the
- X new values never being seen was been repaired, so that the name string
- X of the item will be displayed properly.
- X
- X o The Control-Y exit command has been changed so the user has to hit Q to
- X exit instead of Y. This is to make it more fool-proof and more accident
- X proof (but not totally).
- X
- X o Three new monster attacks: Lose Mana (different from the monster spell),
- X Slip, Trip, and Fall (you'll find out), and Eclipse attack. A number of
- X new attack descriptions have been added with this. A new function was
- X added, function DEX_ADJ, to determine the character's plus or minus to
- X his dexterity saving throw.
- X
- X o New monsters have found their way into the Dungeons of Moria. A list of
- X their names can be found in the file MONSTERS.NEW, included in the
- X distribution package (or from your local Moria Wizard).
- X
- X o The creatures "Mother & Baby" and "Small Girl" have been fixed to
- X correctly utilize the CDEFENSE flag of Lose Experience for killing that
- X creature.
- X
- X o The global constant store$turn_around has been changed to the global
- X array variable store_turnaround, allowing each store to have a different
- X inventory turn over rate. This was done partially to work the Black
- X Market in more properly.
- X
- X o A bug involving the running function ('.' and a direction) has been
- X fixed so that if you are attacked in any form, either via a physical
- X hit or a spell, you will stop running at that point.
- X
- X o New monster defense: cloning on death. A new value has been added to
- X the CDEFENSE flag so that certain monsters can try to clone themselves
- X when they have been dealt a mortal blow. There are four types of
- X cloning, each giving a different base chance to clone. The chance is
- X reduced based on how badly killed the creature is (if you "neutronize"
- X the critter, he isn't as likely to clone himself).
- X
- X o The \ function has been fixed up a bit, mainly in formatting control,
- X with an added piece to watch for the end of the screen and page it out
- X as needed. Also, it has been renamed to ^U, and is now a Wizard mode
- X function, just as creating the Monster Dictionary is.
- X
- X o The Create Food spell/scroll has been fixed. If an item is under you
- X when you cast/read this spell, it will not be deleted as it was doing
- X before. Make sure you have a open space of floor under or around you,
- X or you may go hungry...
- X
- X o The Medusa has been fixed so that it's gaze causes Turn to Stone, not
- X Vampire Bite.
- X
- X o Added a new flag to the monster's spell flags. A creature can now be
- X set up so that only a percentage of that type of creature will be spell
- X casters, assuming the type has any spell ability at all. For example,
- X the Young Blue Dragon could be set up so that only 1 in 10 Young Blue
- X Dragons can cast spells at all. This does not effect Dragon Breath
- X attacks, only spell ability. If a zero or one is in this position,
- X all members of that creature type can cast spells, if any are indicated.
- X
- X
- XFrom 18862246%VUVAXCOM.BITNET@lilac.berkeley.edu Thu Aug 31 06:10:59 1989
- XReceived: from lilac.Berkeley.EDU by ernie.Berkeley.EDU (5.61/1.36)
- X id AA14710; Thu, 31 Aug 89 06:10:54 -0700
- XReceived: by lilac.berkeley.edu (5.61.1/1.16.22)
- X id AA04291; Thu, 31 Aug 89 05:54:29 PDT
- XMessage-Id: <8908311254.AA04291@lilac.berkeley.edu>
- XDate: Thu, 31 Aug 89 08:51 EST
- XFrom: "Charon, the Ferryman on the River Styx"
- X <188622462%VUVAXCOM.bitnet@lilac.berkeley.edu>
- XSubject: what to put for a subject? I don't know...
- XTo: wilson@ernie.Berkeley.EDU
- XOriginal_To: BITNET%"wilson@ucbernie"
- XStatus: RO
- X
- X
- XJim-
- X
- XI see what you mean about the up/down and the search flag thing. What did
- Xyou add to the main dungeon procedure to fix this?
- X
- XAt the end of this letter, I've appended the dictionary descriptions of the
- X"Mother & Baby" and "Small Girl". I've also include the piece from the
- Xmon_take_hit function that checks the appropriate bit in the monster cdefense
- Xflag. I believe this was something written in for the 5.0 UB version, but
- XI'm not certain, so if you need more to be able to put it into yours, I can
- Xsend whatever you need.
- X
- XThat bug you mention could well be the result of someone diddling with the
- Xsources. Off hand, I can think of one or two reasons they'd do something to
- Xthe monster-array parts, to save on memory usage, but the file-access goes
- Xway up the minute you do anything other than the orginial form, so you lose
- Xout in the end. I'll keep my eye out, but I doubt if I'll ever see it happen
- Xhere.
- X
- XSounds like you and I, and the rest of the Usenet community, are in agreement
- Xthen. We'll keep our two separate "schools" of Moria, and just share thoughts
- Xback and forth.
- X
- XNow if only the VM/CMS Moria porter would respond to my letter...
- X
- XCatch you later,
- X
- XRick
- X
- X
- X---excerpt from function mon_take_hit. Insert within the section of if
- X statement that has determined the monster has died.
- X EXP is the player's current experience points. LEV is the player's level.
- X I1 is the amount of experience the creature is worth (I think it's a
- X calculated value)
- X
- X {Penalize player - subtract experience}
- X if (uand (cdefense, %X'00000400') <> 0) then
- X begin
- X exp := exp - 10*lev;
- X if (exp < 0) then exp := 0;
- X end
- X else
- X exp := exp + i1;
- X
- X
- X--------------------------------------------
- X 1 Mother and Baby (p)
- X Speed = 1 Level = 0 Exp = 0
- X AC = 1 Eye-sight = 4 HD = 1d1
- X Creature harmed by cold.
- X Creature harmed by fire.
- X Creature harmed by poison.
- X Creature harmed by acid.
- X Creature harmed by stone-to-mud.
- X Causes experience loss when killed
- X Creature seen with Infra-Vision.
- X Creature picks up objects.
- X--Spells/Dragon Breath =
- X--Movement =
- X Moves and attacks normally.
- X 20% random movement.
- X Can open doors.
- X--Creature attacks =
- X Touches you for normal damage. (0d0)
- X--------------------------------------------
- X 2 Small Girl (p)
- X Speed = 1 Level = 0 Exp = 0
- X AC = 1 Eye-sight = 4 HD = 1d1
- X Creature harmed by cold.
- X Creature harmed by fire.
- X Creature harmed by poison.
- X Creature harmed by acid.
- X Creature harmed by stone-to-mud.
- X Causes experience loss when killed
- X Creature seen with Infra-Vision.
- X Creature picks up objects.
- X--Spells/Dragon Breath =
- X--Movement =
- X Moves and attacks normally.
- X 20% random movement.
- X Can open doors.
- X--Creature attacks =
- X Touches you for normal damage. (0d0)
- X--------------------------------------------
- X
- X
- END_OF_FILE
- if test 14612 -ne `wc -c <'misc/rick.msg'`; then
- echo shar: \"'misc/rick.msg'\" unpacked with wrong size!
- fi
- # end of 'misc/rick.msg'
- fi
- if test -f 'util/mc/creature.y' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'util/mc/creature.y'\"
- else
- echo shar: Extracting \"'util/mc/creature.y'\" \(26665 characters\)
- sed "s/^X//" >'util/mc/creature.y' <<'END_OF_FILE'
- X/* util/mc/creature.y: a Moria creature definition compiler
- X *
- X * Copyright 1989 by Joseph Hall.
- X * All rights reserved except as stated below.
- X * This program may contain portions excerpted from Moria which are
- X * copyrighted by others.
- X *
- X * Jim Wilson and any other holders of copyright on substantial portions
- X * of Moria are granted rights to use, modify, and distribute this program
- X * as they see fit, so long as the terms of its use, modification and/or
- X * distribution are no less restrictive than those applying to Moria,
- X * version 5.0 or later, itself, and so long as this use is related to
- X * the further development of Moria.
- X *
- X * Anyone having any other use in mind for this code should contact the
- X * author at 4116 Brewster Dr., Raleigh NC 27606 (jnh@ecemwl.ncsu.edu).
- X */
- X
- X%{
- X#include <stdio.h>
- X#include <string.h>
- X#include <ctype.h>
- X#include <math.h>
- X
- X#ifdef ANSI_LIBS
- X#include <stdlib.h>
- X#else
- Xextern double atof();
- Xextern char *malloc();
- Xextern char *calloc();
- Xextern void free();
- X#endif
- X
- X#include "st.h"
- X
- X#ifndef TRUE
- X#define TRUE 1
- X#endif
- X
- X#ifndef FALSE
- X#define FALSE 0
- X#endif
- X
- X#define VERBOSE /* to turn on debugging output */
- X
- Xtypedef unsigned long int32u;
- Xtypedef long int32;
- Xtypedef unsigned short int16u;
- Xtypedef short int16;
- Xtypedef unsigned char int8u;
- X
- Xtypedef struct creature_type
- X{
- X char *name; /* Descrip of creature */
- X int32u cmove; /* Bit field */
- X int32u spells; /* Creature spells */
- X int16u cdefense; /* Bit field */
- X int16u mexp; /* Exp value for kill */
- X int8u sleep; /* Inactive counter/10 */
- X int8u aaf; /* Area affect radius */
- X int8u ac; /* AC */
- X int8u speed; /* Movement speed+10 */
- X int8u cchar; /* Character rep. */
- X int8u hd[2]; /* Creatures hit die */
- X int8u damage[4]; /* Type attack and damage*/
- X int8u level; /* Level of creature */
- X
- X int32u general; /* general characteristics; not present in usual */
- X /* moria creature_type */
- X} creature_type;
- X
- X
- X
- X/*
- X * defined_t is used to indicate whether all fields have been defined
- X */
- X
- Xtypedef struct {
- X unsigned move: 1,
- X special: 1,
- X treasure: 1,
- X spell: 1,
- X breath: 1,
- X defense: 1,
- X mexp: 1,
- X sleep: 1,
- X aaf: 1,
- X ac: 1,
- X speed: 1,
- X cchar: 1,
- X hd: 1,
- X damage: 1,
- X level: 1;
- X} defined_t;
- X
- X
- X
- X/*
- X * template_t contains creature definition & flags
- X */
- X
- Xtypedef struct {
- X creature_type val;
- X defined_t def;
- X} template_t;
- X
- X
- X
- X/*
- X * attack_t describes a monster attack
- X */
- X
- Xtypedef struct {
- X int8u type,
- X desc,
- X dice,
- X sides;
- X} attack_t;
- X
- X
- X
- X/*
- X * symInit_t is used to initialize symbol tables with integer values
- X */
- X
- Xtypedef struct {
- X char *name;
- X int32u val;
- X} symInit_t;
- X
- X
- X
- Xstatic symInit_t defenseInit[] = {
- X { "dragon", 0 },
- X { "animal", 1 },
- X { "evil", 2 },
- X { "undead", 3 },
- X { "frost", 4 },
- X { "fire", 5 },
- X { "poison", 6 },
- X { "acid", 7 },
- X { "light", 8 },
- X { "stone", 9 },
- X { "bit_9", 10 },
- X { "bit_10", 11 },
- X { "no_sleep", 12 },
- X { "infra", 13 },
- X { "max_hp", 14 },
- X { "bit_15", 15 },
- X { NULL, 0 }
- X};
- X
- Xstatic symInit_t moveInit[] = {
- X { "attack_only", 0 },
- X { "move_normal", 1 },
- X { "bit_2", 2 },
- X { "random_20", 3 },
- X { "random_40", 4 },
- X { "random_75", 5 },
- X { NULL, 0 }
- X};
- X
- Xstatic symInit_t specialInit[] = {
- X { "invisible", 16 },
- X { "open_door", 17 },
- X { "phase", 18 },
- X { "eats_other", 19 },
- X { "picks_up", 20 },
- X { "multiply", 21 },
- X { "win_creature", 31 },
- X { NULL, 0 }
- X};
- X
- Xstatic symInit_t treasureInit[] = {
- X { "carry_obj", 24 },
- X { "carry_gold", 25 },
- X { "has_random_60", 26 },
- X { "has_random_90", 27 },
- X { "has_1d2_obj", 28 },
- X { "has_2d2_obj", 29 },
- X { "has_4d2_obj", 30 },
- X { NULL, 0 }
- X};
- X
- Xstatic symInit_t spellInit[] = {
- X { "tel_short", 4 },
- X { "tel_long", 5 },
- X { "tel_to", 6 },
- X { "lght_wnd", 7 },
- X { "ser_wnd", 8 },
- X { "hold_per", 9 },
- X { "blind", 10 },
- X { "confuse", 11 },
- X { "fear", 12 },
- X { "summon_mon", 13 },
- X { "summon_und", 14 },
- X { "slow_per", 15 },
- X { "drain_mana", 16 },
- X { "bit_17", 17 },
- X { "bit_18", 18 },
- X { NULL, 0 }
- X};
- X
- Xstatic symInit_t breathInit[] = {
- X { "light", 19 },
- X { "gas", 20 },
- X { "acid", 21 },
- X { "frost", 22 },
- X { "fire", 23 },
- X { NULL, 0 }
- X};
- X
- Xstatic symInit_t attackTypeInit[] = {
- X { "normal_damage", 1 },
- X { "lose_str", 2 },
- X { "confusion", 3 },
- X { "cause_fear", 4 },
- X { "fire_damage", 5 },
- X { "acid_damage", 6 },
- X { "cold_damage", 7 },
- X { "lightning_damage", 8 },
- X { "corrosion", 9 },
- X { "cause_blindness", 10 },
- X { "cause_paralysis", 11 },
- X { "steal_money", 12 },
- X { "steal_obj", 13 },
- X { "poison", 14 },
- X { "lose_dex", 15 },
- X { "lose_con", 16 },
- X { "lose_int", 17 },
- X { "lose_wis", 18 },
- X { "lose_exp", 19 },
- X { "aggravation", 20 },
- X { "disenchant", 21 },
- X { "eat_food", 22 },
- X { "eat_light", 23 },
- X { "eat_charges", 24 },
- X { "blank", 99 },
- X { NULL, 0 }
- X};
- X
- Xstatic symInit_t attackDescInit[] = {
- X { "hits", 1 },
- X { "bites", 2 },
- X { "claws", 3 },
- X { "stings", 4 },
- X { "touches", 5 },
- X { "kicks", 6 },
- X { "gazes", 7 },
- X { "breathes", 8 },
- X { "spits", 9 },
- X { "wails", 10 },
- X { "embraces", 11 },
- X { "crawls_on", 12 },
- X { "releases_spores", 13 },
- X { "begs_for_money", 14 },
- X { "slimes", 15 },
- X { "crushes", 16 },
- X { "tramples", 17 },
- X { "drools_on", 18 },
- X { "insults", 19 },
- X { "is_repelled", 99 },
- X { NULL, 0 }
- X};
- X
- X
- X
- X
- X/*
- X * Maximum token length = maximum string constant length
- X * Also, trim the stack to an "acceptable" size.
- X */
- X
- X#define MAX_TOK_LEN 64 /* maximum acceptable token length */
- X#define YYSTACKSIZE 128
- X
- X#define GEN_TYPE_TMPL 256 /* type of a template for st */
- X
- X/*
- X * Globals used by the tokenizer (lexical analyzer)
- X */
- X
- X#define INPUT_BUF_SIZE 256
- Xstatic char inputBuf[INPUT_BUF_SIZE] = { 0 };
- X /* input line buffer */
- Xstatic char *inputBufp = inputBuf; /* position in input line buffer */
- Xstatic int lineNo = 0; /* number of current line */
- Xstatic FILE *input_F;
- Xstatic char tokStr[MAX_TOK_LEN]; /* text of current token */
- Xstatic int tokType; /* type of current token */
- Xstatic double tokVal; /* numeric value of current token, */
- X /* if applicable */
- X
- Xstatic template_t blankTemplate = { 0 }; /* blank template for init-ing */
- Xstatic template_t tmpTemplate; /* working template for current */
- X /* class or creature */
- X
- X#define MAX_ATTACK 250
- Xstatic attack_t attackList[MAX_ATTACK] = { 0 };
- Xstatic int attackCt = 1, creatureAttacks = 0;
- Xstatic int maxCreatureLevel = 0;
- X
- X/*
- X * Global symbol tables
- X */
- X
- Xstatic st_Table_Pt keywordT_P, /* parser's keywords */
- X defenseT_P, /* defense flags */
- X moveT_P, /* movement flags */
- X specialT_P, /* special flags */
- X treasureT_P, /* treasure flags */
- X spellT_P, /* spell flags */
- X breathT_P, /* breath flags */
- X attackTypeT_P, /* attack type flags */
- X attackDescT_P, /* attack desc flags */
- X classT_P, /* class templates */
- X creatureT_P; /* creature definitions */
- X
- X/*
- X * Function declarations
- X */
- X
- Xextern void AddDefense();
- Xextern void NegDefense();
- Xextern void AddMove();
- Xextern void NegMove();
- Xextern void AddTreasure();
- Xextern void NegTreasure();
- Xextern void AddSpecial();
- Xextern void NegSpecial();
- Xextern void AddSpell();
- Xextern void NegSpell();
- Xextern void AddBreath();
- Xextern void NegBreath();
- Xextern void AddAttack();
- Xextern void WriteCreature();
- Xextern void PutClassTemplate();
- Xextern template_t GetClassTemplate();
- Xextern void PutCreature();
- X
- X%}
- X
- X
- X/*
- X * YACC DEFINITIONS
- X */
- X
- X/*
- X * The parser's stack can hold ints, doubles, and strings.
- X */
- X
- X%union {
- X int ival;
- X double dval;
- X char sval[MAX_TOK_LEN];
- X }
- X
- X/*
- X * Reserved words
- X */
- X
- X%token CLASS CREATURE NAMED HD D MOVE SPELL BREATH DEFENSE XP CCHAR SLEEP
- X%token RADIUS SPEED ATTACK FOR AC LEVEL TREASURE SPECIAL OF IN
- X
- X/*
- X * Entities
- X */
- X
- X%token <sval> IDENTIFIER /* identifier, not a keyword */
- X%token <dval> FLOAT_LIT /* floating-pt literal */
- X%token <ival> INT_LIT /* integer literal */
- X%token <sval> STRING_LIT /* string literal */
- X%token <ival> BOOL_LIT /* boolean literal */
- X
- X/*
- X * ASCII chars are their own tokens
- X */
- X
- X%start creatures
- X
- X
- X/*
- X * THE PARSER
- X */
- X
- X%%
- X
- Xcreatures : class_def ';' creatures
- X | creature_def ';' creatures
- X | /* empty */
- X ;
- X
- Xclass_def : CLASS IDENTIFIER parent_class '{' features '}'
- X { PutClassTemplate($<sval>2, &tmpTemplate); }
- X ;
- X
- Xparent_class : ':' IDENTIFIER
- X { tmpTemplate = GetClassTemplate($<sval>2);
- X creatureAttacks = 0; }
- X | /* empty */
- X { tmpTemplate = blankTemplate;
- X creatureAttacks = 0; }
- X ;
- X
- Xcreature_def : CREATURE STRING_LIT parent_class
- X '{' features '}'
- X { tmpTemplate.val.name =
- X (char *) malloc(strlen($<sval>2) + 1);
- X strcpy(tmpTemplate.val.name, $<sval>2);
- X PutCreature($<sval>2, &tmpTemplate);
- X }
- X ;
- X
- Xfeatures : feature ';' features
- X | /* empty */
- X ;
- X
- Xfeature : LEVEL ':' INT_LIT
- X { tmpTemplate.val.level = $<ival>3;
- X tmpTemplate.def.level = TRUE; }
- X | HD ':' INT_LIT D INT_LIT
- X { tmpTemplate.val.hd[0] = $<ival>3;
- X tmpTemplate.val.hd[1] = $<ival>5;
- X tmpTemplate.def.hd = TRUE; }
- X | XP ':' INT_LIT
- X { tmpTemplate.val.mexp = $<ival>3;
- X tmpTemplate.def.mexp = TRUE; }
- X | CCHAR ':' STRING_LIT
- X { tmpTemplate.val.cchar = $<sval>3[0];
- X tmpTemplate.def.cchar = TRUE; }
- X | AC ':' INT_LIT
- X { tmpTemplate.val.ac = $<ival>3;
- X tmpTemplate.def.ac = TRUE; }
- X | SLEEP ':' INT_LIT
- X { tmpTemplate.val.sleep = $<ival>3;
- X tmpTemplate.def.sleep = TRUE; }
- X | RADIUS ':' INT_LIT
- X { tmpTemplate.val.aaf = $<ival>3;
- X tmpTemplate.def.aaf = TRUE; }
- X | SPEED ':' INT_LIT
- X { tmpTemplate.val.speed = $<ival>3 + 10;
- X tmpTemplate.def.speed = TRUE; }
- X | ATTACK ':' attacks
- X | MOVE ':' moves
- X | SPELL ':' spells
- X | SPELL INT_LIT '%' ':' spells
- X { float chance = 100.0 / $<ival>2;
- X if (chance > 15.0)
- X chance = 0.0;
- X if (chance < 0.0)
- X chance = 0.0;
- X tmpTemplate.val.spells &= ~0xf;
- X tmpTemplate.val.spells |=
- X (int) ceil(chance);
- X tmpTemplate.def.spell = TRUE; }
- X | BREATH ':' breaths
- X | BREATH INT_LIT '%' ':' breaths
- X { float chance = 100.0 / $<ival>2;
- X if (chance > 15.0)
- X chance = 0.0;
- X if (chance < 0.0)
- X chance = 0.0;
- X tmpTemplate.val.spells &= ~0xf;
- X tmpTemplate.val.spells |=
- X (int) ceil(chance);
- X tmpTemplate.def.spell = TRUE; }
- X | DEFENSE ':' defenses
- X | TREASURE ':' carries
- X | SPECIAL ':' specials
- X ;
- X
- Xattacks : attack more_attacks
- X ;
- X
- Xattack : IDENTIFIER FOR INT_LIT D INT_LIT OF IDENTIFIER
- X { AddAttack($<sval>1, $<ival>3,
- X $<ival>5, $<sval>7); }
- X ;
- X
- Xmore_attacks : ',' attack more_attacks
- X | /* empty */
- X ;
- X
- Xmoves : move more_moves
- X ;
- X
- Xmove : IDENTIFIER { AddMove($<sval>1); }
- X | '~' IDENTIFIER { NegMove($<sval>2); }
- X ;
- X
- Xmore_moves : ',' move more_moves
- X | /* empty */
- X ;
- X
- Xspells : spell more_spells
- X | /* empty */
- X ;
- X
- Xspell : IDENTIFIER { AddSpell($<sval>1); }
- X | '~' IDENTIFIER { NegSpell($<sval>2); }
- X ;
- X
- Xmore_spells : ',' spell more_spells
- X | /* empty */
- X ;
- X
- Xbreaths : breath more_breaths
- X ;
- X
- Xbreath : IDENTIFIER { AddBreath($<sval>1); }
- X | '~' IDENTIFIER { NegBreath($<sval>2); }
- X ;
- X
- Xmore_breaths : ',' breath more_breaths
- X | /* empty */
- X ;
- X
- Xdefenses : defense more_defenses
- X ;
- X
- Xdefense : IDENTIFIER { AddDefense($<sval>1); }
- X | '~' IDENTIFIER { NegDefense($<sval>2); }
- X ;
- X
- Xmore_defenses : ',' defense more_defenses
- X | /* empty */
- X ;
- X
- Xcarries : carry more_carries
- X ;
- X
- Xcarry : IDENTIFIER { AddTreasure($<sval>1); }
- X | '~' IDENTIFIER { NegTreasure($<sval>2); }
- X ;
- X
- Xmore_carries : ',' carry more_carries
- X | /* empty */
- X ;
- X
- Xspecials : special more_specials
- X ;
- X
- Xspecial : IDENTIFIER { AddSpecial($<sval>1); }
- X | '~' IDENTIFIER { NegSpecial($<sval>2); }
- X ;
- X
- Xmore_specials : ',' special more_specials
- X | /* empty */
- X ;
- X
- X
- X%%
- X
- Xstatic symInit_t keywordInit[] = {
- X { "class", CLASS },
- X { "creature", CREATURE },
- X { "named", NAMED },
- X { "hd", HD },
- X { "d", D },
- X { "move", MOVE },
- X { "spell", SPELL },
- X { "breath", BREATH },
- X { "defense", DEFENSE },
- X { "xp", XP },
- X { "cchar", CCHAR },
- X { "sleep", SLEEP },
- X { "radius", RADIUS },
- X { "speed", SPEED },
- X { "attack", ATTACK },
- X { "for", FOR },
- X { "ac", AC },
- X { "level", LEVEL },
- X { "treasure", TREASURE },
- X { "special", SPECIAL },
- X { "of", OF },
- X { "in", IN },
- X { NULL, 0 }
- X};
- X
- X
- X
- X/*
- X * MyFGetC--
- X * fgetc with support for comments
- X *
- X * # is the comment character. comment lasts till end of line.
- X * Spews out an extra char of whitespace at EOF since something seems to
- X * need it. I'll figure this out eventually...
- X */
- Xstatic int MyFGetC(input_F)
- XFILE *input_F;
- X{
- X static int atEof = FALSE;
- X while (!*inputBufp || (*inputBufp == '#')) {
- X fgets(inputBuf, INPUT_BUF_SIZE, input_F);
- X if (feof(input_F))
- X return EOF;
- X lineNo++;
- X inputBufp = inputBuf;
- X }
- X return *inputBufp++;
- X}
- X
- X
- X
- X/*
- X * Advance--
- X * Advance to the next token in the input stream and set tokStr,
- X * tokType, tokVal as appropriate.
- X *
- X * On error, tokType is set to a negative value.
- X */
- Xstatic void Advance(input_F)
- XFILE *input_F;
- X{
- X
- X register char
- X *tok = tokStr; /* accumulating token string */
- X register int
- X len = 0; /* length of current token */
- X static int c = 32; /* current character; ' ' is harmless init */
- X
- X
- X /*
- X * Skip whitespace in the stream
- X */
- X while ((c != EOF) && isspace(c))
- X c = MyFGetC(input_F);
- X
- X /*
- X * At end of file?
- X */
- X if (c == EOF) {
- X tokType = EOF;
- X strcpy(tokStr, "[EOF]");
- X return;
- X }
- X
- X /*
- X * Recognize a number [+|-][dddd][.][dddd][{e|E}[+|-]dddd]
- X */
- X if (isdigit(c) || (c == '.') || (c == '+') || (c == '-')) {
- X
- X register int
- X decPt = FALSE, /* seen a decimal point yet? */
- X hasExp = FALSE; /* has an exponent? */
- X
- X if ((c == '-') || (c == '+')) {
- X *tok++ = c;
- X c = MyFGetC(input_F);
- X }
- X
- X while ((len < MAX_TOK_LEN - 1) && (isdigit(c) || (c == '.'))) {
- X if (c == '.') {
- X if (decPt)
- X break;
- X else
- X decPt = TRUE;
- X }
- X
- X *tok++ = c;
- X c = MyFGetC(input_F);
- X len++;
- X }
- X
- X if ((c == 'e') || (c == 'E')) {
- X hasExp = TRUE;
- X *tok++ = c;
- X c = MyFGetC(input_F);
- X len++;
- X
- X if ((c == '-') || (c == '+')) {
- X *tok++ = c;
- X c = MyFGetC(input_F);
- X len++;
- X }
- X
- X while ((len < MAX_TOK_LEN - 1) && isdigit(c)) {
- X *tok++ = c;
- X c = MyFGetC(input_F);
- X len++;
- X }
- X }
- X
- X *tok = 0;
- X
- X if (decPt || hasExp) {
- X tokType = FLOAT_LIT;
- X yylval.dval = atof(tokStr);
- X } else {
- X tokType = INT_LIT;
- X yylval.ival = atoi(tokStr);
- X }
- X
- X return;
- X
- X }
- X
- X /*
- X * Recognize a quoted string
- X */
- X if (c == '\"') {
- X
- X c = MyFGetC(input_F);
- X
- X while ((len < MAX_TOK_LEN - 1) &&
- X (c != EOF) && (c != '\n') && (c != '\"')) {
- X *tok++ = c;
- X c = MyFGetC(input_F);
- X }
- X
- X *tok = 0;
- X
- X c = MyFGetC(input_F);
- X
- X tokType = STRING_LIT;
- X strncpy(yylval.sval, tokStr, MAX_TOK_LEN - 1);
- X yylval.sval[MAX_TOK_LEN - 1] = 0;
- X
- X return;
- X
- X }
- X
- X /*
- X * Recognize an identifier and try to match it with a keyword.
- X * Identifiers begin with a letter and continue in letters and/or
- X * digits. Convert it to lowercase.
- X */
- X if (isalpha(c) || (c == '_') || (c == '$')) {
- X
- X if (isupper(c))
- X c = tolower(c);
- X *tok++ = c;
- X c = MyFGetC(input_F);
- X len++;
- X
- X while ((len < MAX_TOK_LEN - 1) && (isalpha(c) || isdigit(c) ||
- X (c == '_') || (c == '$'))) {
- X if (isupper(c))
- X c = tolower(c);
- X *tok++ = c;
- X c = MyFGetC(input_F);
- X len++;
- X }
- X
- X *tok = 0;
- X
- X /*
- X * We've got the identifier; see if it matches any keywords.
- X */
- X
- X {
- X generic_t gval;
- X int type;
- X if (St_GetSym(keywordT_P, tokStr, &type, &gval) ==
- X ST_SYM_FOUND) {
- X tokType = gval.i;
- X strncpy(yylval.sval, tokStr, MAX_TOK_LEN - 1);
- X yylval.sval[MAX_TOK_LEN - 1] = 0;
- X } else if (!strcmp(tokStr, "true")) {
- X tokType = BOOL_LIT;
- X yylval.ival = 1;
- X } else if (!strcmp(tokStr, "false")) {
- X tokType = BOOL_LIT;
- X yylval.ival = 0;
- X } else {
- X tokType = IDENTIFIER;
- X strncpy(yylval.sval, tokStr, MAX_TOK_LEN - 1);
- X yylval.sval[MAX_TOK_LEN - 1] = 0;
- X }
- X }
- X
- X return;
- X
- X }
- X
- X /*
- X * Recognize punctuation
- X */
- X
- X tokType = c;
- X *tok++ = c;
- X *tok = 0;
- X c = MyFGetC(input_F);
- X return;
- X
- X}
- X
- Xvoid ErrMsg(s)
- Xchar *s;
- X{
- X int i;
- X
- X fprintf(stderr, "Error: %s at line %d\n", s, lineNo);
- X fprintf(stderr, "%s", inputBuf);
- X for (i = 0; i < inputBufp - inputBuf; i++) {
- X fputc((inputBuf[i] == '\t' ? '\t' : ' '), stderr);
- X }
- X fprintf(stderr, "^ before here\n\n");
- X}
- X
- Xint yyerror(s)
- Xchar *s;
- X{
- X ErrMsg(s);
- X}
- X
- X
- Xint yylex()
- X{
- X Advance(input_F);
- X return(tokType);
- X}
- X
- Xvoid AddSpell(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(spellT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "unknown spell '%s'", s);
- X ErrMsg(s1);
- X } else {
- X tmpTemplate.val.spells |= (1 << gval.i);
- X tmpTemplate.def.spell = TRUE;
- X }
- X}
- X
- X
- Xvoid NegSpell(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(spellT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "unknown spell '%s'", s);
- X ErrMsg(s1);
- X } else {
- X tmpTemplate.val.spells &= ~(1 << gval.i);
- X tmpTemplate.def.spell = TRUE;
- X }
- X}
- X
- X
- Xvoid AddBreath(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(breathT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "unknown breath '%s'", s);
- X ErrMsg(s1);
- X } else {
- X tmpTemplate.val.spells |= (1 << gval.i);
- X tmpTemplate.def.breath = TRUE;
- X }
- X}
- X
- X
- Xvoid NegBreath(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(breathT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "unknown breath '%s'", s);
- X ErrMsg(s1);
- X } else {
- X tmpTemplate.val.spells &= ~(1 << gval.i);
- X tmpTemplate.def.breath = TRUE;
- X }
- X}
- X
- X
- Xvoid AddSpecial(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(specialT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "unknown special '%s'", s);
- X ErrMsg(s1);
- X } else {
- X tmpTemplate.val.cmove |= (1 << gval.i);
- X tmpTemplate.def.special = TRUE;
- X }
- X}
- X
- X
- Xvoid NegSpecial(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(specialT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "unknown special '%s'", s);
- X ErrMsg(s1);
- X } else {
- X tmpTemplate.val.cmove &= ~(1 << gval.i);
- X tmpTemplate.def.special = TRUE;
- X }
- X}
- X
- X
- Xvoid AddMove(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(moveT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "unknown move '%s'", s);
- X ErrMsg(s1);
- X } else {
- X tmpTemplate.val.cmove |= (1 << gval.i);
- X tmpTemplate.def.move = TRUE;
- X }
- X}
- X
- X
- Xvoid NegMove(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(moveT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "unknown move '%s'", s);
- X ErrMsg(s1);
- X } else {
- X tmpTemplate.val.cmove &= ~(1 << gval.i);
- X tmpTemplate.def.move = TRUE;
- X }
- X}
- X
- X
- Xvoid AddTreasure(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(treasureT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "unknown treasure '%s'", s);
- X ErrMsg(s1);
- X } else {
- X tmpTemplate.val.cmove |= (1 << gval.i);
- X tmpTemplate.def.treasure = TRUE;
- X }
- X}
- X
- X
- Xvoid NegTreasure(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(treasureT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "unknown treasure '%s'", s);
- X ErrMsg(s1);
- X } else {
- X tmpTemplate.val.cmove &= ~(1 << gval.i);
- X tmpTemplate.def.treasure = TRUE;
- X }
- X}
- X
- X
- Xvoid AddDefense(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(defenseT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "unknown defense '%s'", s);
- X ErrMsg(s1);
- X } else {
- X tmpTemplate.val.cdefense |= (1 << gval.i);
- X tmpTemplate.def.defense = TRUE;
- X }
- X}
- X
- X
- Xvoid NegDefense(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(defenseT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "unknown defense '%s'", s);
- X ErrMsg(s1);
- X } else {
- X tmpTemplate.val.cdefense &= ~(1 << gval.i);
- X tmpTemplate.def.defense = TRUE;
- X }
- X}
- X
- X
- Xint PutAttack(attack)
- Xattack_t attack;
- X{
- X register int i;
- X
- X for (i = 0; i < attackCt; i++) {
- X if ((attack.type == attackList[i].type) &&
- X (attack.desc == attackList[i].desc) &&
- X (attack.dice == attackList[i].dice) &&
- X (attack.sides == attackList[i].sides)) {
- X return(i);
- X }
- X }
- X
- X if (attackCt == MAX_ATTACK) {
- X fprintf(stderr, "fatal error: too many different attacks.\n");
- X fprintf(stderr, "increase MAX_ATTACK.\n");
- X exit(1);
- X }
- X
- X attackList[attackCt].type = attack.type;
- X attackList[attackCt].desc = attack.desc;
- X attackList[attackCt].dice = attack.dice;
- X attackList[attackCt].sides = attack.sides;
- X
- X return attackCt++;
- X}
- X
- Xvoid AddAttack(s1, dice, sides, s2)
- Xchar *s1, *s2;
- Xint dice, sides;
- X{
- X generic_t gval;
- X int type, aDesc;
- X attack_t attack;
- X char s[256];
- X
- X if (St_GetSym(attackDescT_P, s1, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s, "unknown attack description '%s'", s1);
- X ErrMsg(s);
- X return;
- X } else {
- X aDesc = gval.i;
- X }
- X
- X if (St_GetSym(attackTypeT_P, s2, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s, "unknown attack type '%s'", s2);
- X ErrMsg(s);
- X } else {
- X if (creatureAttacks > 3) {
- X sprintf(s, "creature limited to 4 attacks");
- X ErrMsg(s);
- X return;
- X }
- X attack.type = gval.i;
- X attack.dice = dice;
- X attack.desc = aDesc;
- X attack.sides = sides;
- X tmpTemplate.val.damage[creatureAttacks++] =
- X PutAttack(attack);
- X tmpTemplate.def.damage = TRUE;
- X }
- X}
- X
- Xst_Table_Pt InitTable(name, init)
- Xchar *name;
- XsymInit_t *init;
- X{
- X int i;
- X st_Table_Pt table_P;
- X generic_t gval;
- X
- X table_P = St_NewTable(name, 20);
- X for (i = 0; init[i].name; i++) {
- X gval.i = init[i].val;
- X St_DefSym(table_P, init[i].name, GEN_TYPE_INT, gval);
- X }
- X
- X return table_P;
- X}
- X
- X
- Xvoid InitTables()
- X{
- X int i;
- X generic_t gval;
- X
- X keywordT_P = InitTable("keyword", keywordInit);
- X defenseT_P = InitTable("defense", defenseInit);
- X spellT_P = InitTable("spell", spellInit);
- X moveT_P = InitTable("move", moveInit);
- X specialT_P = InitTable("special", specialInit);
- X breathT_P = InitTable("breath", breathInit);
- X treasureT_P = InitTable("treasure", treasureInit);
- X attackTypeT_P = InitTable("attackType", attackTypeInit);
- X attackDescT_P = InitTable("attackDesc", attackDescInit);
- X
- X classT_P = St_NewTable("class", 40);
- X creatureT_P = St_NewTable("creature", 200);
- X}
- X
- Xvoid WriteCreature(tmpl_P)
- Xtemplate_t *tmpl_P;
- X{
- X char s[256];
- X strcpy(s, "\"");
- X strcat(s, tmpl_P->val.name);
- X strcat(s, "\"");
- X printf("{%-28s, 0x%08x,0x%06x,0x%04x,%5d,%3d,\n",
- X s, tmpl_P->val.cmove, tmpl_P->val.spells,
- X tmpl_P->val.cdefense, tmpl_P->val.mexp, tmpl_P->val.sleep);
- X printf(" %2d, %3d, %2d, '%c', {%3d,%2d}, {%3d,%3d,%3d,%3d}, %3d},\n",
- X tmpl_P->val.aaf, tmpl_P->val.ac, tmpl_P->val.speed,
- X tmpl_P->val.cchar,
- X tmpl_P->val.hd[0], tmpl_P->val.hd[1],
- X tmpl_P->val.damage[0], tmpl_P->val.damage[1],
- X tmpl_P->val.damage[2], tmpl_P->val.damage[3],
- X tmpl_P->val.level);
- X}
- X
- Xvoid WriteCreatures()
- X{
- X char **s_A, **sp;
- X int level, type;
- X generic_t gval;
- X
- X s_A = St_SListTable(creatureT_P);
- X
- X printf("creature_type c_list[MAX_CREATURES] = {\n");
- X
- X for (level = 0; level <= maxCreatureLevel; level++) {
- X for (sp = s_A; *sp; sp++) {
- X if (St_GetSym(creatureT_P, *sp, &type, &gval) !=
- X ST_SYM_FOUND) {
- X fprintf(stderr, "internal err. in WriteCreatures\n");
- X exit(1);
- X }
- X if ((*(template_t *) gval.v).val.level == level) {
- X WriteCreature((template_t *) gval.v);
- X }
- X }
- X }
- X
- X printf("};\n\n");
- X
- X St_SListTable(NULL);
- X}
- X
- Xvoid PutClassTemplate(s, tmpl_P)
- Xchar *s;
- Xtemplate_t *tmpl_P;
- X{
- X generic_t gval;
- X char s1[256];
- X
- X gval.v = malloc(sizeof(template_t));
- X *(template_t *) gval.v = *tmpl_P;
- X
- X if (St_DefSym(classT_P, s, GEN_TYPE_TMPL, gval) == ST_SYM_FOUND) {
- X sprintf(s1, "attempt to redefine class '%s'", s);
- X ErrMsg(s1);
- X free(gval.v);
- X return;
- X }
- X}
- X
- X
- Xtemplate_t GetClassTemplate(s)
- Xchar *s;
- X{
- X generic_t gval;
- X int type;
- X char s1[256];
- X
- X if (St_GetSym(classT_P, s, &type, &gval) != ST_SYM_FOUND) {
- X sprintf(s1, "class '%s' undefined\n", s);
- X ErrMsg(s1);
- X return blankTemplate;
- X } else {
- X return *(template_t *) gval.v;
- X }
- X}
- X
- X
- X
- X
- Xvoid NotDefined(name, s)
- Xchar *name, *s;
- X{
- X printf("Warning: %s not defined for \"%s\", line %d\n",
- X s, name, lineNo);
- X}
- X
- X
- Xvoid PutCreature(s, tmpl_P)
- Xchar *s;
- Xtemplate_t *tmpl_P;
- X{
- X generic_t gval;
- X char s1[256];
- X
- X gval.v = malloc(sizeof(template_t));
- X *(template_t *) gval.v = *tmpl_P;
- X
- X if (!tmpl_P->def.move)
- X NotDefined(tmpl_P->val.name, "MOVE");
- X if (!tmpl_P->def.treasure)
- X NotDefined(tmpl_P->val.name, "TREASURE");
- X if (!tmpl_P->def.defense)
- X NotDefined(tmpl_P->val.name, "DEFENSE");
- X if (!tmpl_P->def.mexp)
- X NotDefined(tmpl_P->val.name, "XP");
- X if (!tmpl_P->def.sleep)
- X NotDefined(tmpl_P->val.name, "SLEEP");
- X if (!tmpl_P->def.aaf)
- X NotDefined(tmpl_P->val.name, "RADIUS");
- X if (!tmpl_P->def.ac)
- X NotDefined(tmpl_P->val.name, "AC");
- X if (!tmpl_P->def.speed)
- X NotDefined(tmpl_P->val.name, "SPEED");
- X if (!tmpl_P->def.cchar)
- X NotDefined(tmpl_P->val.name, "CCHAR");
- X if (!tmpl_P->def.hd)
- X NotDefined(tmpl_P->val.name, "HD");
- X if (!tmpl_P->def.damage)
- X NotDefined(tmpl_P->val.name, "ATTACK");
- X if (!tmpl_P->def.level)
- X NotDefined(tmpl_P->val.name, "LEVEL");
- X
- X if (St_DefSym(creatureT_P, s, GEN_TYPE_TMPL, gval) == ST_SYM_FOUND) {
- X sprintf(s1, "attempt to redefine creature '%s'\n", s);
- X ErrMsg(s1);
- X free(gval.v);
- X return;
- X }
- X
- X if (tmpl_P->val.level > maxCreatureLevel)
- X maxCreatureLevel = tmpl_P->val.level;
- X
- X}
- X
- Xvoid WriteAttacks()
- X{
- X int i;
- X
- X printf("struct m_attack_type monster_attacks[N_MONS_ATTS] = {\n");
- X for (i = 0; i < attackCt; i++) {
- X printf("/* %3d */ { %2d, %2d, %2d, %2d },\n",
- X i, attackList[i].type, attackList[i].desc,
- X attackList[i].dice, attackList[i].sides);
- X };
- X printf("};\n");
- X}
- X
- Xvoid WriteConstants()
- X{
- X printf("/* These values should match the values defined in constant.h. */");
- X printf("\n#define MAX_CREATURES\t%d\n", St_TableSize(creatureT_P));
- X printf("#define N_MON_ATTS\t%d\n\n", attackCt);
- X}
- X
- Xvoid WriteMonsterHdr()
- X{
- X printf("/* The following code belongs in the file monster.c. */\n\n");
- X printf("/* The following data was generated by the program in util/mc.");
- X printf("*/\n\n");
- X}
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X char inputFilename[256];
- X
- X InitTables();
- X
- X if (argc > 1) {
- X strncpy(inputFilename, argv[1], 255);
- X inputFilename[255] = 0;
- X } else {
- X fprintf(stderr, "input file: ");
- X scanf("%255s", inputFilename);
- X }
- X
- X input_F = fopen(inputFilename, "r");
- X if (!input_F) {
- X printf("Error: couldn't open file.\n");
- X exit(1);
- X }
- X
- X if (yyparse()) {
- X printf("Errors prevent continuation.\n");
- X exit(1);
- X }
- X
- X WriteConstants();
- X WriteMonsterHdr();
- X WriteCreatures();
- X WriteAttacks();
- X}
- END_OF_FILE
- if test 26665 -ne `wc -c <'util/mc/creature.y'`; then
- echo shar: \"'util/mc/creature.y'\" unpacked with wrong size!
- fi
- # end of 'util/mc/creature.y'
- fi
- echo shar: End of archive 28 \(of 39\).
- cp /dev/null ark28isdone
- 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
-