From grabiner@math.harvard.edu Tue Jan 26 18:06:30 1993
Received: from math.harvard.edu (boucher.harvard.edu) by diamond; Tue, 26 Jan 1993 18:05:41 GMT
Date: Tue, 26 Jan 93 13:04:14 EST
From: grabiner@math.harvard.edu (David Grabiner)
Message-Id: <9301261804.AA03249@math.harvard.edu>
To: smarsh@dcs.warwick.ac.uk
Subject: Re: *Read this* A New Moria hack...
References: <9301251810.AA15753@math.harvard.edu>
	<10937.199301260938@stone>
Reply-To: grabiner@math.harvard.edu
Status: OR

Here's the relevant section of creature.c:

/* Places creature adjacent to given location		-RAK-	*/
/* Rats and Flys are fun!					 */
int multiply_monster(y, x, cr_index, monptr)
int y, x, cr_index;
int monptr;
{
  register int i, j, k;
  register cave_type *c_ptr;
  int result;
#ifdef ATARIST_MWC
  int32u holder;
#endif

  i = 0;
  do
    {
      j = y - 2 + randint(3);
      k = x - 2 + randint(3);
      /* don't create a new creature on top of the old one, that causes
	 invincible/invisible creatures to appear */
      if (in_bounds(j, k) && (j != y || k != x))
	{
	  c_ptr = &cave[j][k];
	  if ((c_ptr->fval <= MAX_OPEN_SPACE) && (c_ptr->tptr == 0) &&
	      (c_ptr->cptr != 1))
	    {
	      if (c_ptr->cptr > 1)     /* Creature there already?	*/
		{
		  /* Some critters are cannibalistic!	    */
#ifdef ATARIST_MWC
		  holder = CM_EATS_OTHER;
		  if ((c_list[cr_index].cmove & holder)
#else
		  if ((c_list[cr_index].cmove & CM_EATS_OTHER)
#endif
		      /* Check the experience level -CJS- */
		     && c_list[cr_index].mexp >=
		      c_list[m_list[c_ptr->cptr].mptr].mexp)

This is one other major fix; if you haven't changed this, the game will
lock up if you spend too long in place on a level.  In your version, the
check of (cur_dis < mon_ptr->cdis) had a > sign by mistake, which made
it impossible to compact monsters more than 66 spaces away, but allowed
monsters near the player to disappear.

/* Compact monsters					-RAK-	*/
/* Return TRUE if any monsters were deleted, FALSE if could not delete any
   monsters.  */
int compact_monsters()
{
  register int i;
  int cur_dis, delete_any;
  register monster_type *mon_ptr;
#ifdef ATARIST_MWC
  int32 holder;
#endif

  msg_print("Compacting monsters...");

  cur_dis = 66;
  delete_any = FALSE;
  do
    {
      for (i = mfptr - 1; i >= MIN_MONIX; i--)
	{
	  mon_ptr = &m_list[i];
	  if ((cur_dis < mon_ptr->cdis) && (randint(3) == 1))
	    {
	      /* Never compact away the Balrog!! */
#ifdef ATARIST_MWC
	      if (c_list[mon_ptr->mptr].cmove & (holder = CM_WIN))
#else
	      if (c_list[mon_ptr->mptr].cmove & CM_WIN)
#endif
		/* Do nothing */
		;
	      /* in case this is called from within creatures(), this is a
		 horrible hack, the m_list/creatures() code needs to be
		 rewritten */
	      else if (hack_monptr < i)
		{
		  delete_monster(i);
		  delete_any = TRUE;
		}
	      else
		/* fix1_delete_monster() does not decrement mfptr, so
		   don't set delete_any if this was called */
		fix1_delete_monster(i);
	    }
	}
      if (!delete_any)
	{
	  cur_dis -= 6;
	  /* Can't delete any monsters, return failure.  */
	  if (cur_dis < 0)
	    return FALSE;
	}
    }
  while (!delete_any);
  return TRUE;
}


Here's a complete change log from 5.2.1 to the release of 5.5:

---------- 5/31
all: released umoria 5.2.1
ibmpc/ms_misc.c: corrected warn() function to use va_list, the old function
	was not strictly correct
---------- 6/4
misc2.c: prt_stat_block() must also call prt_study()
misc2.c: random_object() could create objects outside of map boudaries,
	added an in_bounds() call to fix
------------- 6/6
main.c: changed 'if (p = getenv(...))' to 'if ((p = getenv(...)) != NULL)'
	to avoid compiler warnings
moria1.c: rest_on(), add check to make sure rest_num fits in short
ibmpc/umoria.prj: new file, a project file for Turbo C 2.0
------------- 6/9
io.c: HP-UX does not have VEOL2, added #ifdef VEOL2 around its use
dungeon.c: clear message line after change_character(), since as ESCAPE
	exit does not
moria1.c: for 'x' and 'w' commands, clear heavy_weapon flag before calling
	check_strength, so that always get heavy message when wielding heavy
	weapon, and never get light message when wielding light weapon
scrolls.c: identify scroll can move arbitrarily far after ident_spell(),
	replace simple 'moved one down' check with loop to search until found
main.c: fixed starup code so that don't get 'savefile doesn't exist'
	message anymore when starting a new game
all: apply fix to all uses of long constant with & | << operators to avoid
	a Mark Williams C bug on the Atari ST
externs.h, files.c: removed MSDOS declaration of errno from files.c, and
	remove ifndef MSDOS from errno decl in externs.h
misc1.c: changed name of variable 'clock' to 'clock_var' to avoid problem
	with a mac compiler (not sure which one)
io.c: every io.c file, remove '\0' as alias for ESCAPE from get_com() and
	get_comdir() (MAC only function)
moria1.c: light_dam() calls inven_damage(set_lightning_destroy, 3) which
	gives it a small chance of destroying objects in player's pack,
	this makes it just like the other *_dam() functions
spells.c: teleport_to(), add call to in_bound() to make sure player will
	be teleported to somewhere inside the dungeon
------------- 6/10
config.h: add note about using GCC on an Atari ST
main.c, save.c, undef.c: eliminated the unused _new_log() function
death.c, dungeon.c, externs.h, save.c, undef.c, variable.c: eliminated the
	mostly unused log_index variable, the few uses of it were replaced
	with references to character_saved
externs.h, files.c, io.c, undef.c: init_scorefile() implemented, same as
	in umoria 4.87
main.c, undef.c: eliminate unused function init_files()
constant.h, moria.r, version.hlp: change version number to 5.2.2
----------- 6/11
ibmpc/ms_misc.c: added space to GRAPHICS scanf, to try to eliminate problem
	with Turco C
death.c, externs.h, files.c, save.c, variable.c: extensive changes to
	implement the scorefile, total_points(), highscores(), display_
	scores(), set_fileptr(), rd_highscore(), and wr_highscore() defined
	scorefile holds 1000 entries max, has one sex/race/class entry per
	non-zero uid, has live characters also
unix/Makefile: fix the treatment of score file, don't copy over old one,
	just use touch to create one if it doesn't exist
undef.c: finally eliminated
---------- 6/13
all: lint under 4.3 BSD and AIX 2.2.1 (SYS V)
scores: readd scores file, since it makes micro distributions much easier
death.c: modify savefile for single user machine, so that it tries to
	prevent a single character from appearing multiple times in the
	savefile, checks for identical names, and killed by = (saved)
player.c: eliminated the unused dsp_race[] array
death.c: added code to implement flock() for systems which don't have it,
	based on code written by CJS for BRUCE Moria
---------- 6/17
all: fixes for VMS, define USG for VMS, merge in fixes from Todd Pierzina
---------- 6/23
scrolls.c: for curse weapon, call py_bonuses(-1) before clear flags so
	that attributes will be turned off
moria1.c: calc_bonuses(), handle AC just like everything else, previously
	did not add in AC bonus if armor was cursed
creature.c, moria2.c: doors weren't being broken when bashed, change
	"randint(2) - 1" to "1 - randint(2)"
----------- 7/14
all: merge in some changes indiciated by warnings/prototypes generated by
	MSC 5.x
recall.c: compute monster kill exp in long, to avoid overflow of int
all: added AMIGA support
amiga/: new directory to hold support files for the amiga
main.c: variable result was not initialized to false
------------- 7/15
all: merge in more VMS patches
death.c, dungeon.c: fixed display_scores() and 'V' command problems
creature.c, dungeon.c, misc2.c, moria1.c: new feature '*' rest until
	reach max mana and hp, print error message for illegal rest count
all: removed improper define of NULL, new define CNIL for (char *)0, used
	instead of NULL where appropriate, eliminate strange include orders
	that the previous NULL define required
io.c: ifdefed out the include for termio.h, as this caused it to be included
	twice on some systems (curses.h includes it also) causing problems
macrsrc.h: changed MAX_RESTART from 37 to 36
--------- 7/21
ms_misc.c: fixed reading of empty lines from config file for Turbo C
-------- 7/22
io.c: fix Amiga code for flush()
types.h: reduce size of cave_type structure for Amiga/Aztec C 5.0
death.c: fix display_scores(), so that it only shows entries belonging to
	current player when show_player is true
--------- 8/29
misc2.c: deleted some redundant code in gain_spells() where it calculates
	which spells a player can learn
spells.c: recharge(), could call randint() with 0 or negative numbers, check
	for these cases before calling randint()
--------- 9/8
moria1.c: inven_command(), when drop/remove object and inven/equip are both
	empty, set inven weight to zero, just to be safe
dungeon.c: jamdoor(), when jam a door, decrement inven_weight by weight of
	one spike
moria1.c: inven_command(), make spikes wieldable objects, fight with them
	like missile weapons, i.e. they disappear after use
desc.c: objdes(), add damage multiplier of bows to their name
externs.h, io.c, misc1.c, save.c variable.c: new option sound_beep_flag, so
	that players can turn off bad character beep if desired
desc.c, misc2.c: modify known1_p() to return TRUE for objects which never
	have a color, modify objdes() to work with the new convention,
	modify inven_carry() so that objects are added to the inventory
	sorted by subval if they are known1_p()
---------- 9/9
misc1.c: add_food(), fix so that does not use f_ptr->slow to set f_ptr->food
	value, this makes it much less likely to overflow the food level
misc2.c: inven_carry(), yesterday's insert in order fix does not work for
	items which can be unknown1p, only insert items ordered by subval if
	they are always known1p, i.e. object_offset() returns -1
externs.h, misc1.c, misc2.c, save.c variable.c: new option display rest/repeat
	counts, since these counts make resting at 1200 baud or less
	unbearably slow, people need to be able to turn them off
store2.c: get_haggle(), let RET default to the last inc/dec amount when
	haggling
misc1.c: compact_monsters(), return FALSE if could not delete any monsters
	instead of aborting, popm() return -1 if could not allocate monster
	(i.e. compact_monsters() failed), place_win_monster() abort if popm()
	fails which should never happen, place_monster()
externs.h: place_monster() now int type not void,
creature.c, misc1.c, spells.c: fix users of place_monster() to check result,
	and fail if place_monster() failed, really only necessary for the
	calls in creature.c, these fixes fix the monster list overflow bug
dungeon.c, externs.h, misc1.c: change compact_monsters() from static to
	extern, call it from within main loop in dungeon.c if there are less
	than 10 spaces left in the monster list, compact_monsters() is much
	more likely to be successful when called here than when called from
	creatures()
----------- 9/11
signals.c: delete extra definition of error_sig for ATARIST_MWC
atari_st/README: update with GCC and Turbo C info
files.c: fix typo, filname1 -> filename1
--------------- 9/18
mac.c, ScrnMgr1.c: replace uses of KeyMapLM with GetKeys() call
------------- 9/19
misc1.c: m_bonus(), could overflow on 16 bit machines when level >= 263
	when calculating stand_dev
death.c, externs.h, save.c: store the encryption byte for each savefile record
	immediately before it in the scorefile, makes the scorefile more
	robust in the face of a system crash, rd_highscore(), wr_highscore()
	no longer pass the encryption byte
death.c: added version numbers to the savefile
death.c, externs.h, save.c, variable.c: add max_score to savefile, which is
	the maximum score the character has reached so far, total_points()
	modified to use the larger of the computed score, and the value of
	max_score, this prevents a "(saved)" message on the score file for
	a dead character, which died having fewer points than when it was
	last saved
----------- 9/26
death.c, externs.h, main.c, save.c, types.h, variable.c: new global variable
	birth_date, set to time when character created, saved in save files
	and scorefile, when loading character check to see if the a character
	in the scorefile has the same race/sex/class/uid/birth_date and
	its died_from is not "(saved)", in which case this character will not
	be scored
misc2.c: print "Duplicate" on screen for such duplicate characters
all: update all documentation, README, and other misc descriptive files
all: add fixes for Atari ST/Turbo C 2.0
all: lint on Sun3/uVAX/MIPS/RT_PC
recall.c: when printing out depth of monster, print Balrog as 50 not 100
----------- 10/3
all: fix all problems reported by maniscan/cshar, except for control-L
	characters on a line by themselves
----------- 10/7
creature.c: mon_move(), cast m_ptr->fy-1 to int, so that negative values
	will correctly compare to it, in the wall building code
spoilers: new file, lists spell damages
misc2.c: prt_experience(), always check whether exp is greater than max_exp,
	previously did not when player was at level 40
creature.c: mon_move(), set the recall CM_ATTACK_ONLY bit when a monster
	should have moved but did not, instead of the old method of setting it
	when a non-moving monster attacked
store2.c: get_haggle(), fix bugs in the automatic increment code, also, when
	reach final offer, set the automatic increment to the required diff,
	so that player need only hit return to bid the final amount
moria2.c: tunnel(), before checking for tunneling into a invisible monster,
	check to make sure player is tunneling somewhere which has an effect,
	otherwise, player can use this to 'detect' invisible monsters in
	open spaces by trying to tunnel there
moria1.c: calc_bonuses(), base AC should always be visible, as long as the
	item is not cursed
------- 10/8
spells.c: td_destroy2(), should not destroy chests, not disarms and unlocks
	them instead
misc2.c: put_misc3(), clear_from(14) not 13, was clearing the gold value
files.c: file_character(), add the "Max Exp" and "Exp to Adv" fields to
	the info written to a file, to match the on screen display
files.c: file_character(), set fd to -1, not NULL, code was closing stdin
	(== 0 == NULL) when could not open file
death.c: exit_game(), clear character_saved before calling highscores(),
	prevents inkey() from recursively calling exit_game() when eof on
	stdin has been detected
all: released 5.2.2 sources
----------- 10/23
death.c: highscores(), must do fseek() after reaching EOF before changing
	read/write mode, previously only did this for VMS, now do this for
	all systems
----------- 10/26
config.h, death.c, io.c: fix VMS errors, declare 'string' in death.c
	duplicate_character(), fix typos in other files
dungeon.c: for VMS, after calling kbhit(), must consume one character
vms/Makefile: fixed, mostly change constants.h to constant.h
------------ 10/30
death.c, externs.h, files.c, save.c: define STDIO_LOADED after including
	stdio.h, then use it to control declarations in externs.h
constant.h, death.c: define SCOREFILE_SIZE as 1000, and use it in death.c
moria2.c: cast_spell(), when don't have enough mana, use 'gods may think you
	presumptuous' message instead of 'summon your limited strength'
----------- 11/4
ibmpc/moria.cnf: add ^M, since otherwise MSDOS moria can't read file properly
io.c: include stdio.h explicitly, and define STDIO_LOADED, so savefile
	can be closed when shelling out
store2.c: get_haggle(), clear increment when invalid increment entered
store2.c, variables.c: last_store_inc contradictory declarations, changed both
	to int16
externs, misc2.c, sets.c, spells.c: set_*_destroy changed to take inven_type
	pointer instead of tval, modified so that (Rx) items won't be
	destroyed by attacks of type x
death.c: for single user systems, use birth_date instead of name when
	looking for matching characters in savefile
death.c: MSDOS setmode() needs file descriptor, not FILE pointer
files/*: removed all TABS, since some systems do not handle them properly,
	specifically, Turbo C on the Atari ST and IBM-PC
misc1.c: rings of searching cost was 100*p1, amulet of searching cost 20*p1,
	change both to 50*p1
mac/macio.c, ibmpc/tcio.c: modify beep() so that it uses the new option flag
desc.c: changed the (*2) string for bows to (x2)
spells.c: slow monster and confuse monster modified to wake up monster if
	the attacks fails
spells.c: wall_to_mud() and dispel_creature(), print messages even if
	monster not visible since the effects are visible/audible
moria2.c: for fire/acid/gas traps, print the trap message first, and then
	damage an item
treasure.c: change name of lose memories potion to lose experience, so it
	won't be confused with monster memories
spells.c: trap_creation(), don't create a trap under the player, to prevent
	strange occurances such as ending up under a falling rock
moria2.c: tunnel(), when wielding heavy weapon, make tunneling more difficult
----------- 11/6
vms/getch.c: New code for kb_hit(), which was tested and works under VMS 5.2
	the old code did not work for VMS 5.2
----------- 11/9
misc1.c: compact_monsters(), distance test was backwards!, now delete monsters
	farther away first,  allow a final pass with distance of 0,
	never delete the Balrog during compaction
---------- 11/21
doc/history: rewrote history file to bring it up-to-date
misc2.c: gain_spells(), don't need to be able to read spell books if learning
	priestly spells, don't fail if blind or no light
death.c: fix #ifdef typo around <time.h> include
----------- 12/1
store2.c: when good bargainer, change string to "final offer", and allow
	return to accept final offer
player.c: change rogue start inv from Soft Armor to Cloak, so that it is the
	same as the other non-Warrior classes
dungeon.c: decrement command count after do_command() instead of before,
	so that all counted commands will work right, this fixes 3^P
--------- 12/5
death.c: display_scores(), fix VMS bug, truncate uid to a short before
	comparing against the uid in the score file record, also move
	the uid computation outside the loop to speedup the procedure
io.c: put_buffer (), for Atari ST, was printing the untruncated out_str
	instead of tmp_str
--------- 12/14
atari_st/curscomp/curses.[ch], death.c, files.c, io.c, signals.c:
	add Atari ST TC fixes for the new (in 5.2.2) code
::::::: 1991 ::::::::
---------- 1/4
spells.c: light_area(), always light area immediately next to player even if
	in a room, could be standing on the edge of a room
monsters.c: Grave Wight, no longer has confusion spell, no other wight/wraith
	has it
misc2.c: get_spell(), when enter invalid character, print "You don't know
	that prayer." instead of "spell" for priests/etc.
creature.c: make_attack(), creatures which are repelled should not be confused
	because they did not hit the player
death.c: exit_game(), delete #ifndef TURBOC around the restore_term() call
io.c: restore_term(), delete the call to clear() in the MSDOS code, it was
	trying to use curses after curses had been exited
---------- 1/22
files.c: call pause_line(23) after printing hours file
constant.h, config.h: constant.h should always be included before config.h,
	because some systems redefine constants in config.h
rnd.c: include config.h after constant.h
main.c, misc2.c, save.c, signals.c: include constants.h before config.h
misc2.c, vms/getch.c: new function user_name() for VMS, fix get_name()
	in misc2.c to call it
------- 1/30
moria2.c: hit_trap(), add msg_print(CNIL) for the trap door case
-------- 2/4
io.c: for ATARIST_MWC, use 240 instead of '#' for walls
save.c: for ATARIST_MWC, convert 240 to '#' when saving, and '#' to 240
	when loading, to avoid conversion problems
--------- 2/8
create.c: monval(), cast i to int, otherwise some compilers do the arithmetic
	with unsigned characters
--------- 2/19
makefile: add new macro CURSES, define it for BSD/SYS V/and Xenix
config.h: add config info for XENIX, define SYS_V and unix, only undefine
	register for MSC versions less than 600 (6.00?)
creature.c: mon_move, comment out register decl for r_ptr for XENIX systems
	to avoid a compiler bug
misc2.c: place_gold, comment out register decl for t_ptr for XENIX systems
	to avoid a compiler bug
unix.c: ifdef out include of termio.h, for XENIX add include of sys/types.h
	and define bzero as memset, test for unix or M_XENIX at the top
Makefile: add optional commands to install target which chown/chgrp everythin
	to bin, and put pointer to it at the top
---------- 2/25
util/score: Two new utilities, prscore to print scorefiles, and delscore to
	delete one entry from a scorefile.
config.h: add MORIA_* macros for the Atari ST with GCC
death.c, externs.h, io.c, main.c, signals.c, variable.c: Apply Atari ST/GCC
	patches from Scott Kolodzieski.
-------- 3/1
death.c: Amiga must open/close scorefile like MSDOS&VMS
io.c: init_curses(),restore_term(), fix bugs in AMIGA code,
	add code to release resources
amiga/*: updated versions of amiga source files, from
	cg37717@lion.eng.clemson.edu, Corey Gehman
atari_st/curscomp: complete rewrite of the curses code by Hildo Biersma
store2.c: get_haggle(), do not accept an increment value of zero, turn off
	increment flag instead of accepting it
-------- 3/2
store2.c: store_purchase(), store_prt_gold call was inside `if' now after,
	did not update gold if store had 13 items and you bought the 13th
-------- 3/11
moria1.c: sub3_move_light(), don't print over old location if find_flag
	is true, unless find_prself is also true, this speeds up movement
	in find mode by eliminating unnecessary drawing of characters
moria2.c: hit_trap(), call move_light() for the teleport trap case, to light
	up the trap
misc1.c, save.c, treasure.c: change ATARIST_MWC ifdefs for using graphic
	character to ATARI_ST which is true for both MWC and TC
io.c: remove all ATARIST_MWC diffs which were needed for the old non-standard
	curses, change the rest to be ATARI_ST, since both MWC and TC need them
-------- 3/14
source/*: add Mac THINK C support
mac/dumpres/*: add Mac THINK C support
mac/scrnmgr/*: add Mac Think C support
moria1.c: find_init(), when !light_flag and !find_prself, must erase the
	player's '@', because sub3_move_light() won't, see 3/11 change above
------- 3/15
mac/*: add Mac THINK C support
*: put file name and 1991 copyrights in all source files
------- 3/23
save.c: prevent resurrection of a total winner character
constants.h, creature.c, monsters.c, recall.c: add new flag CM_ONLY_MAGIC,
	set this flag in creature.c, check the flag in recall.c, allows
	recall to print movement speed for Quylthulgs
creature.c: when a wand is drained of charges, inscribe it as {empty} if
	it is not known2
-------- 3/24
files.c, ibmpc/ms_misc.c: ifdefed out msdos_intro(), since that routine is
	obsolete now
doc/moria.6: add -S option to list at the top
ibmpc/CONFIG.DOC: update for Umoria 5.x, remove kneller's address, and put in
	my address
------- 3/25
config.h, constant.h, */*.c: move VMS definition for ESCAPE from config.h
	to constant.h, now all files include config.h before constant.h
*: linted all sources files, changed version numbers to 5.3
------- 3/30
vms/*, ibmpc/ms_misc.c, config.h, death.c, dungeon.c, externs.h, files.c,
io.c, save.c: merge in changes from Ralph Waters, which are needed to compile
	the sources under VMS and IBM-PC/Turbo C.
moria2.c, store2.c, *.c: get_item(), show_inven() take new parameter mask,
	if mask is non-zero, they only list items indicated by mask array,
	store_sell() calculates a mask based on what store will buy
store2.c: purchase_haggle(), sell_haggle(), if the auto increment is larger
	than the difference between the store's offer and the player's offer,
	then set the auto increment to the exact difference
dungeon.c, externs.h, moria1.c, moria2.c, variable.c: eliminate search_flag,
	it was redundant, replace all uses with (py.flags.status & PY_SEARCH)
tables.c: remove good armor items from armory, to force players to search for
	them in the dungeons, hard leather boots, iron helm, partial plate,
	full plate
misc1.c: alloc_monster(), always create dragons sleeping here, to give the
	player a sporting chance
moria1.c: inven_command(), when pack not empty and show_weights flag true,
	display capacity along with weigth carried on first line of inventory
spells.c: build_wall(), permanently light walls created within range of
	player's lamp
spells.c: earthquake(), fix it to act just like build_wall when a monster is
	trapped in a wall
creature.c, externs.h: movement_rate(), now static
*: release 5.3.1 sources
------- 4/27
ms_misc.c, externs.h: change declarations of warn() to match definition,
	change declaration and definition of error() to match warn(),
externs.h: fix declarations for sleep(), find_init(), show_inven(), get_item()
death.c: display_scores(), don't set player_uid for non UNIX/VMS system
	duplicate_character(), ifdef out code which is unreachable for non
	UNIX/VMS system, make all returns have a value
sets.c: set_null(), add a #pragma argused for TURBO C
ms_misc.c: fix three lines that had an assignment inside an if
externs.h: add prototypes/declarations for VMS files getch.c and uexit.c
moria1.c: see_wall(), change ATARIST_MWC ifdef to ATARI_ST
atari_st/curscomp/curses.c: winsch(), first loop ran in wrong direction
externs.h: add declarations for atari st functions
atari_st/moria.prj: new file, TC project file for Umoria
death.c: highscores (), change fseed to fseek, typing error
creature.c, death.c, desc.c, dungeon.c, files.c, io.c, moria1.c, moria2.c,
	store2.c, wizard.c, atarist.c: include stdlib.h if ATARIST_TC to get
	prototypes for standard library functions
generate.c: for ATARIST_TC, include <string.h>
atarist/curscomp/curses.h: change mvadd* macros from compound statements to
	conditional expressions, so that all returns values are error checked
io.c: for ATARIST_TC, include ext.h to properly define (?) sleep
config.h: for ATARIST_TC, define index strchr
save.c: sv_write()/get_char(), define t_ptr for both MSDOS and ATARI_ST;
	get_char(), change ATARIST_MWC ifdef around chmod call to ATARI_ST
	include time.h for ATARIST_TC
unix/Makefile: change ONWER to OWNER
creature.c: creatures(), give moves to monsters trapped in rock, so that they
	will die/dig out immediately, mon_move() if a monster in rock is
	already dead, don't kill it again
*: update address info in all files
io.c: change __GNU_C_ to __GNUC__
config.h: the test for undefining 'register' was wrong, it was undefing it
	for all non-MSC compilers
moria2.c: tunnel(), heavy weapon code wrong, eliminate >>2 of penalty, add
	penalty instead of subtracting it
help.c: ident_char(), add period after Giant Frog.
monsters.c: novice priest, change sleep from 10 to 5 to match other novice 'p'
moria1.c, store2.c, *.c: get_item() new parameter 'message', when invalid
	letter hit, print this message if non-zero instead of beeping,
	store_sell() pass message "I do not buy such items.", fix all other
	callers to pass CNIL
-------- 4/28
misc2.c, files.c: put_misc2(), file_character(), when player at max level,
	don't print a number for Exp to Adv, instead print ******
io.c: msg_print(), put multiple messages on the same line if they are short
	enough
------- 5/22
externs.h: ifdef out declaration of sprintf for NeXT
io.c (init_curses): correct atarist/GNUC code for signal call, ifdef was wrong
------- 7/6
spells.c (unlight_area): Unlight all floor spaces with `lr' set, instead of
	just the room floors spaces.  This darkens the doorways.
moria1.c (light_room): Add code to set the fm flag, necessary so that the
	above fix does not unlight doors that it shouldn't.
io.c (msg_print): Don't combine NULL messages with other messages.
save.c (get_char): Use msg_print when printing the `departed spirit' message.
-------- 7/26
store2.c (purchase_haggle, sell_haggle): If the automatic increment plus the
	last offer passes the shop keepers current ask, then clear the incr.
-------- 10/5
*: Add changes needed to prevent warnings from the IBM-PC TURBO C compiler.
misc[1234].c, moria[1234].c: misc[12].c and moria[12].c were each split into
	two files, because they were too large for TURBO C's integrated
	environment
*: adjust all makefiles, externs.h, etc to account for new moria/misc files
TCCONFIG.TCU, TCPICK.TCU: new files, uuencoded copies of Turbo C setup files
config.h, ms_misc.c: New define USING_TCIO, used to prevent including curses.h
	in ms_misc.c.  Defaults to defined if using TURBOC on an IBM-PC.
io.c: delete special purpose AMIGA code, it now uses curses
amiga/amiga.h: Deleted.
amiga/amiga.c: Delete all curses stubs.
-------- 10/6
macrsrc.h: change type of resType, ResID to long
macrsrc.c: eliminated search_flag from macrsrc.c (see 3/30 changes)
config.h: put back switches RSRC, RSRC_PART1 and RSRC_PART2
ScrnMgr.ro: changed def of MBAR #228 (fixes crash on Mac Plus) and INFO #1
	(Make default window be full screen)
ScrnMgr.c: check for reconfig flag enabled for THINK_C, add recognition
	of MacClassic (and LC?) keyboard, now assumes unknown keyboard type
	has control key, other misc cleanups
moria.ro: changes version string
macconf.c: config.h included for consistency
mac.c: added support for 8-column tabs
mac/Install.doc: new file, installation instructions for THINK C
macconf.c, machelp.c, macscore.c scrnmgr.c: covered up error in THINK C
	includes files OK/Cancel for ok/cancel
death.c, save.c: delete setmode calls for IBM-PC, instead open files in binary
	mode
--------- 10/12
*: Changed version number to 5.4.
save.c: change code to accept savefiles with version numbers greater than the
	version number of the game, savefile format frozen as of 5.2.2
externs.h: ifdef out the troublesome sprintf declaration
config.h: force `unix' to be defined for unix systems, since some stupid
	systems (e.g. AIX) don't already define it
--------- 10/15
externs.h, moria4.c, ms_misc.c: correct typos discovered under MSDOS
--------- 10/19
spells.doc, exp.doc: New documentation files.
--------- 10/26
vms/uexit.c, externs.h, io.c, signals.c: Define uexit as void, and ifdef out
	exit declarations when VMS.
vms/moria.opt: add misc[34].obj and moria[34].obj
ibmpc/ms_misc.c: correct typo in error()
pr_items.c, pr_monst.c: main now returns 0
CONFIG.DOC, TERMCAP, ms_ansi.c: use le/do instead of obsolete bc/xd
dragon.inf: moved from util/weapons to doc, and updated it to be accurate
spoilers: Update from USENET FAQ posting.
--------- 11/17
io.c: ifdef out code checking for 8 char TABS, because it assumes that the
	screen is exactly 80 characters wide
moria[12].[ms/txt]: Correct a few typos.
*: Fix all file permissions.
::::::: 1992 ::::::::
Maintenance taken over by David Grabiner
--------- 7/16
moria4.c: bash(), use random direction if player is confused
spells.c: fire_ball(), fire_bolt(), don't update recall if monster not lit;
	this can happen if bolt hits an invisible monster
spells.c: speed_monsters(), sleep_monsters2(), dispel_creature(), 
	turn_undead(), only affect creatures within MAX_SIGHT 
spells.c: mass_poly(), area of effect should be <= MAX_SIGHT, was <
spells.c: destroy_area(), remove light from player's spot
spells.c: enchant(), add new variable limit, chance of failure is now
	(plusses/limit), with very slight chance of success over limit
scrolls.c: when enchanting melee weapons to damage, set limit to weapon's
	maximum damage, otherwise use 10 to give behavior similar to old method
misc2.c: magic_treasure(), make standard deviation of damage bonus on a melee 
	weapon proportional to weapon's maximum damage; these changes mean
	that daggers can no longer become powerful weapons
treasure.c: the Zweihander has now become a great weapon, value increased from
	1000 to 1500
externs.h: fix declaration for enchant()
staffs.c, wands.c: give everyone a slight chance to use difficult wands and
	staffs, otherwise a warrior will never be able to use many items
--------- 7/23
death.c: print_tomb(), insert msg_print(CNIL) so that "You are using:" and
	"You are carrying:" don't get combined as one message; this made it
	impossible to see the equipment list
store2.c: haggle_insults(), insert msg_print(CNIL) so that insult is always
	recognizable
store2.c: purchase_haggle() and sell_haggle(), new variable didnt_haggle,
	don't call updatebargain if no haggle
store1.c: noneedtobargain(), changed to sliding scale, (good-3*bad) must
	be more than 5 + (price/50) to skip haggling, so that haggling for
	cheap items is over quickly, but can still eventually skip
	haggle for all items
store1.c: updatebargain(), now update for all items worth >9 gold, instead
	of just 10-999, since it is now possible to skip haggling for more
	valuable items as well
--------- 7/25
moria4.c: bash(), unsuccessful bash takes a turn; otherwise, you can
	attempt to bash in different directions while confused or to locate
	invisible monsters; eliminate variable no_bash
--------- 7/27
check all above changes
moria4.c: bash(), get "You bash at empty space" method when bashing a
	wall, corrected to "nothing interesting	happens"; this also
	prevents bashing from locating a secret door
--------- 8/9
merge in all changes from 5.4.0 to 5.4.1
creature.c: update attack information only if monster is visible; update
	death information even if monster is not visible, since
	information will be on tombstone
*: change version number to 5.5.0
--------- 8/12
spells.c: enchant(), guard against randint(0) if called with limit of 0
	(it shouldn't be).
moria4.c: throw_object(), py_bash(), don't do negative damage
shortnam.sed, spells.c: fire_ball(), fix spelling of "envelops"
doc/faq: remove old spoilers file, and put current FAQ here instead
*: put my name (DJG) in credits as contact
*: change copyright date in all source files to 1992
---------- 8/13
release umoria 5.5.0
---------- 10/26
doc/moria[12].[ms,txt]: correct some typos, and make changes for 5.5.0
---------- 10/31
misc4.c: scribe_object() allowed inscriptions longer than 12 characters
	if 13-24 characters availble for inscription, could overwrite
	other data

David Grabiner, grabiner@zariski.harvard.edu
"We are sorry, but the number you have dialed is imaginary."
"Please rotate your phone 90 degrees and try again."
Disclaimer: I speak for no one and no one speaks for me.

