[Here's the latest and greatest version of umoria. I compiled and
ran this with no problems on a Sun SS-2. Be sure the run the
"bldfiles.sh" script when after parts are unpacked to rebuild
some large files that were split for posting. Also read the
INSTALL file for building and installation instructions. -br]
#! /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 1 (of 39)."
# Contents: README MANIFEST INSTALL amiga atari_st atari_st/atarist.c
# atari_st/curscomp doc files ibmpc ibmpc/make mac mac/dumpres
# mac/scrnmgr misc source source/moria3.c unix util util/mc
# util/printit util/scores util/weapons vms
# amiga/README amiga/timer.c
# Wrapped by billr@saab on Thu Aug 20 09:11:25 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(2160 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X
XThis is the source for Umoria 5.5, a dungeon exploration game. This is my
Xsecond major release of the game. These sources have been compiled
Xsuccessfully at least once in the following environments: UNIX (4.2 BSD,
X4.3 BSD, SYS V, Xenix, and many similar systems), IBM-PC (MSC 5.0,
XTurbo C 2.0), Mac (MPW 3.0, Think C 4.0), Atari ST (MWC, GCC, TC 2.0),
XAmiga (Aztec C 5.0), and VMS.
X
XI consider these to be production sources. They should work without trouble
Xon all of the systems mentioned above. Some minor bugs must surely remain,
Xbut there should be no major program bugs encountered.
X
XPeople who are accustomed to Umoria 4.87 MUST read the file doc/FEATURES.NEW
Xwhich documents many of the user visible features. Don't send me bug reports
Xunless you have read the file.
X
XUmoria 5.x does not understand Umoria 4.87 savefiles. The changes to the
Xgame are so great, that supporting the old savefile format is not worth
Xthe effort. Implementing a savefile conversion program will be an almost
Ximpossible task, and at least two people have tried and not succeeded.
X
XYou may distribute modified copies of this game. However, you must clearly
Xindicate the extent and purpose of the changes. Also, if the changes are
Xextensive, I request that you call your sources something other than
X`umoria' so that they won't be confused with my version of the game.
XI would also appreciate receiving a copy of your changes, so that good ideas
Xcan be added back into my version.
X
XDavid Grabiner
XDepartment of Mathematics
XHarvard University
XCambridge, MA 02138
X
XInternet electronic mail addess: grab...@math.harvard.edu
X
XJim Wilson
X856 University Ave.
XPalo Alto, CA 94301
XUSA
X
Xinternet electronic mail address: wil...@kithrup.com
X
XIf the above addresses fail, then try contacting the alumni
Xorganizations of Princeton University for David Grabiner, or Case
XWestern Reserve Univ (Cleveland, OH) or Univ California at Berkeley for
XJim Wilson, for current addresses. These addresses are expected to
Xremain valid for an unknown length of time.
X
XFirst revision (alpha): February 28, 1990
XSecond revision (beta): May 4, 1990
XThird revision (production): March 25, 1991
END_OF_FILE
if test 2160 -ne `wc -c <'README'`; then
echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'MANIFEST' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(7127 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
X File Name Archive # Description
X-----------------------------------------------------------
X CHANGES 13
X ERRORS 12
X INSTALL 1
X MANIFEST 1 This shipping list
X OChanges 3
X OOChanges.1 29
X OOChanges.2 26
X README 1
X amiga 1
X amiga/ERRORS 9
X amiga/README 1
X amiga/amiga.c 39
X amiga/makefile 37
X amiga/timer.c 1
X atari_st 1
X atari_st/Makefile 37
X atari_st/Makefile.bam 38
X atari_st/Makefile.roe 38
X atari_st/Makefile.tc 20
X atari_st/README 39
X atari_st/atarist.c 1
X atari_st/curscomp 1
X atari_st/curscomp/curses.c 9
X atari_st/curscomp/curses.h 35
X atari_st/curscomp/curses.txt 4
X atari_st/curscomp/cursinc.h 37
X atari_st/moria.lnk 39
X atari_st/moria.prj 38
X atari_st/porting.txt 37
X atari_st/st-stuff.c 38
X atari_st/string.h 39
X bldfiles.sh 38
X doc 1
X doc/ERRORS 33
X doc/FEATURES.NEW 28
X doc/README 39
X doc/dragon.inf 38
X doc/exp.doc 35
X doc/faq 19
X doc/history 34
X doc/moria.6 37
X doc/moria.man 37
X doc/moria1.ms.1 24
X doc/moria1.ms.2 23
X doc/moria1.txt 5
X doc/moria2.ms 27
X doc/moria2.txt.1 19
X doc/moria2.txt.2 25
X doc/pronounc 38
X doc/spells.doc 31
X doc/where.inf 38
X files 1
X files/hours 39
X files/news 39
X files/origcmds.hlp 38
X files/owizcmds.hlp 39
X files/roglcmds.hlp 38
X files/rwizcmds.hlp 34
X files/scores 2
X files/version.hlp 38
X files/welcome.hlp 39
X ibmpc 1
X ibmpc/CONFIG.DOC 31
X ibmpc/ERRORS 39
X ibmpc/MAKE.BAT 39
X ibmpc/MLINK.LNK 39
X ibmpc/MORIA.CNF 38
X ibmpc/Makefile.tc 39
X ibmpc/README 39
X ibmpc/TCCONFIG.TCU 32
X ibmpc/TCPICK.TCU 39
X ibmpc/TERMCAP 16
X ibmpc/make 1
X ibmpc/make/ccthru.bat 39
X ibmpc/make/makefile.ibm 39
X ibmpc/make/makefile.src 39
X ibmpc/make/makefile.top 13
X ibmpc/ms_ansi.c 34
X ibmpc/ms_ansi.h 38
X ibmpc/ms_misc.c 31
X ibmpc/tcio.c 33
X ibmpc/turbo_c.inf 39
X ibmpc/umoria.prj 39
X mac 1
X mac/ERRORS 39
X mac/Install.doc 38
X mac/Install.hqx 35
X mac/MakeFile.hqx 33
X mac/README 39
X mac/dumpres 1
X mac/dumpres/DumpRes.c 35
X mac/dumpres/DumpRes.h 39
X mac/dumpres/MakeFile.hqx 39
X mac/dumpres/TestDR.c 30
X mac/mac.c 16
X mac/macconf.c 36
X mac/macdata.c 38
X mac/machelp.c 35
X mac/macio.c 30
X mac/macrsrc.c 34
X mac/macrsrc.h 38
X mac/macscore.c 32
X mac/miscrsrc.hqx 33
X mac/moria.r 20
X mac/moria.ro 34
X mac/scrnmgr 1
X mac/scrnmgr/ERRORS 39
X mac/scrnmgr/MakeFile.hqx 38
X mac/scrnmgr/README 39
X mac/scrnmgr/ScrnMgr.c.1 11
X mac/scrnmgr/ScrnMgr.c.2 17
X mac/scrnmgr/ScrnMgr.doc 17
X mac/scrnmgr/ScrnMgr.h 34
X mac/scrnmgr/ScrnMgr.r 33
X mac/scrnmgr/ScrnMgr.ro 36
X mac/scrnmgr/ScrnTest.c 34
X mac/scrnmgr/ScrnTest.r 36
X mac/scrnmgr/ScrnTest.ro 39
X misc 1
X misc/README 15
X misc/damage.chg 32
X misc/funckeys.c 37
X misc/funckeys.h 39
X misc/haggle.sug 37
X misc/mabbrev 39
X misc/mail.msg 15
X misc/moria.msg 35
X misc/rick.msg 28
X misc/shading 31
X misc/wex.msg 32
X shortnam.sed 9
X source 1
X source/config.h 32
X source/constant.h 16
X source/create.c 30
X source/creature.c 6
X source/death.c 22
X source/desc.c 23
X source/dungeon.c 4
X source/eat.c 36
X source/externs.h 22
X source/files.c 12
X source/generate.c 14
X source/help.c 35
X source/io.c 13
X source/magic.c 36
X source/main.c 30
X source/misc1.c 26
X source/misc2.c 27
X source/misc3.c.1 24
X source/misc3.c.2 21
X source/misc4.c 3
X source/monsters.c 10
X source/moria1.c 7
X source/moria2.c 21
X source/moria3.c 1
X source/moria4.c 15
X source/player.c 18
X source/potions.c 33
X source/prayer.c 5
X source/recall.c 14
X source/rnd.c 37
X source/save.c 8
X source/scrolls.c 29
X source/sets.c 36
X source/signals.c 34
X source/spells.c.1 18
X source/spells.c.2 25
X source/staffs.c 37
X source/store1.c 10
X source/store2.c 20
X source/tables.c 8
X source/treasure.c 2
X source/types.h 30
X source/variable.c 37
X source/wands.c 36
X source/wizard.c 32
X unix 1
X unix/Makefile 21
X unix/unix.c 33
X util 1
X util/README 39
X util/map.c 37
X util/mc 1
X util/mc/ERRORS 39
X util/mc/Makefile 39
X util/mc/attribut.txt 39
X util/mc/creature.y 28
X util/mc/generic.h 39
X util/mc/mon.inf 7
X util/mc/st.h 18
X util/mc/symtab.c 11
X util/mcheck.inf 36
X util/monster.cng 37
X util/printit 1
X util/printit/Makefile 39
X util/printit/pr_items.c 35
X util/printit/pr_monst.c 6
X util/scores 1
X util/scores/Makefile 39
X util/scores/README 17
X util/scores/delete.c 23
X util/scores/print.c 36
X util/showmon.c 29
X util/weapons 1
X util/weapons/ERRORS 39
X util/weapons/Makefile 39
X util/weapons/README 31
X util/weapons/calchits.c 35
X util/weapons/highchar.in 39
X util/weapons/lowchar.in 39
X util/weapons/medchar.in 39
X util/weapons/mkallwpn 39
X util/weapons/mkallwpn.lst 37
X util/weapons/weapon.lst 37
X vms 1
X vms/ERRORS 39
X vms/Makefile 36
X vms/README 39
X vms/debug.mms 38
X vms/descrip.mms 38
X vms/getch.c 36
X vms/make.com 39
X vms/moria.opt 26
X vms/scores.fdl 39
X vms/uexit.c 39
END_OF_FILE
if test 7127 -ne `wc -c <'MANIFEST'`; then
echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test -f 'INSTALL' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'INSTALL'\"
else
echo shar: Extracting \"'INSTALL'\" \(1835 characters\)
sed "s/^X//" >'INSTALL' <<'END_OF_FILE'
X
XFirst, you have to put every file in the 'source' directory, and every file
Xin your machine/OS specific directory into a common directory. If you are on
Xa UNIX machine and running csh, the following works nicely if typed from this
Xdirectory.
X******
Xforeach i (source/* unix/*)
Xln -s $i $i:t
Xend
X******
X(If you wish to build the program in a temporary directory, the same command
Xwill work, but you will have to give full pathnames for the source and
Xunix directories. If you build the program in a different filesystem than
Xthe one containing the sources, then 'ln -s' will only work if you have
XBSD or SYSVR4. If the 'ln -s' fails, you can use 'ln' or 'cp' instead.)
X
XTo compile the program, edit the config.h file to change the
Xnames of the files the game uses. Also, uncomment the appropriate
Xline for the system you are compiling on. Type make (or build
Xor whatever) to compile the game. You may want to edit the 'files/hours' file
Xto indicate during what hours people are allowed to play the game. (The
Xmicro versions don't use this file.)
X
XThe game needs to be installed setuid on UNIX systems for the scoreboard
Xto work. Use the command 'chmod 4511 moria' to do this.
XThe file scores should be mode 644 with the same owner as moria.
XThe files hours and news must be publicly readable with mode 444.
X(Or just type 'make install' after setting BINDIR and LIBDIR in the
XMakefile to appropriate values.)
X
XThere are two choices for the key bindings, the original style and
Xa rogue-like style. You can choose which one is to be the default
Xby changing the value of ROGUE_LIKE in config.h.
X
XMoria only has partial support for SYS III. It probably won't
Xcompile and run under this system without a bit of work.
X
XIf your compiler has a seven character identifier limit, the shortnam.sed
Xfile should solve the problem nicely.
END_OF_FILE
if test 1835 -ne `wc -c <'INSTALL'`; then
echo shar: \"'INSTALL'\" unpacked with wrong size!
fi
# end of 'INSTALL'
fi
if test ! -d 'amiga' ; then
echo shar: Creating directory \"'amiga'\"
mkdir 'amiga'
fi
if test ! -d 'atari_st' ; then
echo shar: Creating directory \"'atari_st'\"
mkdir 'atari_st'
fi
if test -f 'atari_st/atarist.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'atari_st/atarist.c'\"
else
echo shar: Extracting \"'atari_st/atarist.c'\" \(1611 characters\)
sed "s/^X//" >'atari_st/atarist.c' <<'END_OF_FILE'
X/* atari_st/atarist.c: Atari ST support code for MWC or TC
X
X Copyright (c) 1990-92 Stephen A. Jacobs, James E. Wilson
X
X This software may be copied and distributed for educational, research, and
X not for profit purposes provided that this copyright and statement are
X included in all such copies. */
X
X#include <stdio.h>
X#include "config.h"
X#include "constant.h"
X#include "types.h"
X#include "externs.h"
X
X#if defined(GEMDOS) && (__STDC__ == 0) || defined(ATARIST_TC)
X#include <time.h>
X#ifdef ATARIST_TC
X#include <tos.h>
X#else /* ATARIST_MWC */
X#include <osbind.h>
X#include <bios.h>
X#endif
X
X#include "curses.h"
X
X#ifdef ATARIST_TC
X/* Include this to get prototypes for standard library functions. */
X#include <stdlib.h>
X#endif
X
X/* check_input does a non blocking read (consuming the input if any) and
X returns 1 if there was input pending */
Xint check_input(microsec)
Xint microsec;
X{
X time_t start;
X
X if(microsec != 0 && (turn & (unsigned long)0x3f) == 0){
X start = clock();
X while ((clock() <= (start + 100)));/* half second pause */
X }
X if (Bconstat(2) != 0L)
X {
X (void) getch();
X return 1;
X }
X else
X return 0;
X}
X
Xvoid user_name(buf)
Xchar *buf;
X{
X extern char *getenv();
X register char *p;
X
X if(p=getenv("NAME")) strcpy(buf, p);
X else if(p=getenv("USER")) strcpy(buf, p);
X else strcpy(buf, "X");
X}
X
X#ifdef ATARIST_TC
Xint access(name, dum)
Xchar *name;
Xint dum;
X{
X int fd;
X
X fd = open(name, O_RDWR);
X if (fd < 0)
X return(-1);
X else
X {
X close(fd);
X return(0);
X }
X}
X
Xvoid chmod(name, mode)
Xchar *name;
Xint mode;
X{
X/* does not exist, dummy function */
X}
X#endif
X#endif
END_OF_FILE
if test 1611 -ne `wc -c <'atari_st/atarist.c'`; then
echo shar: \"'atari_st/atarist.c'\" unpacked with wrong size!
fi
# end of 'atari_st/atarist.c'
fi
if test ! -d 'atari_st/curscomp' ; then
echo shar: Creating directory \"'atari_st/curscomp'\"
mkdir 'atari_st/curscomp'
fi
if test ! -d 'doc' ; then
echo shar: Creating directory \"'doc'\"
mkdir 'doc'
fi
if test ! -d 'files' ; then
echo shar: Creating directory \"'files'\"
mkdir 'files'
fi
if test ! -d 'ibmpc' ; then
echo shar: Creating directory \"'ibmpc'\"
mkdir 'ibmpc'
fi
if test ! -d 'ibmpc/make' ; then
echo shar: Creating directory \"'ibmpc/make'\"
mkdir 'ibmpc/make'
fi
if test ! -d 'mac' ; then
echo shar: Creating directory \"'mac'\"
mkdir 'mac'
fi
if test ! -d 'mac/dumpres' ; then
echo shar: Creating directory \"'mac/dumpres'\"
mkdir 'mac/dumpres'
fi
if test ! -d 'mac/scrnmgr' ; then
echo shar: Creating directory \"'mac/scrnmgr'\"
mkdir 'mac/scrnmgr'
fi
if test ! -d 'misc' ; then
echo shar: Creating directory \"'misc'\"
mkdir 'misc'
fi
if test ! -d 'source' ; then
echo shar: Creating directory \"'source'\"
mkdir 'source'
fi
if test -f 'source/moria3.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'source/moria3.c'\"
else
echo shar: Extracting \"'source/moria3.c'\" \(31365 characters\)
sed "s/^X//" >'source/moria3.c' <<'END_OF_FILE'
X/* source/moria3.c: misc code, mainly to handle player commands
X
X Copyright (c) 1989-92 James E. Wilson, Robert A. Koeneke
X
X This software may be copied and distributed for educational, research, and
X not for profit purposes provided that this copyright and statement are
X included in all such copies. */
X
X#ifdef __TURBOC__
X#include <stdio.h>
X#endif
X
X#include "config.h"
X#include "constant.h"
X#include "types.h"
X#include "externs.h"
X
X#ifdef USG
X#ifndef ATARIST_MWC
X#include <string.h>
X#endif
X#else
X#include <strings.h>
X#endif
X
X#if defined(LINT_ARGS)
Xstatic void hit_trap(int, int);
Xstatic void carry(int, int, int);
Xstatic int summon_object(int, int, int, int);
X#endif
X
X
X/* Player hit a trap. (Chuckle) -RAK- */
Xstatic void hit_trap(y, x)
Xint y, x;
X{
X int i, ty, tx, num, dam;
X register cave_type *c_ptr;
X register struct misc *p_ptr;
X register inven_type *t_ptr;
X bigvtype tmp;
X
X end_find();
X change_trap(y, x);
X c_ptr = &cave[y][x];
X p_ptr = &py.misc;
X t_ptr = &t_list[c_ptr->tptr];
X dam = pdamroll(t_ptr->damage);
X switch(t_ptr->subval)
X {
X case 1: /* Open pit*/
X msg_print("You fell into a pit!");
X if (py.flags.ffall)
X msg_print("You gently float down.");
X else
X {
X objdes(tmp, t_ptr, TRUE);
X take_hit(dam, tmp);
X }
X break;
X case 2: /* Arrow trap*/
X if (test_hit(125, 0, 0, p_ptr->pac+p_ptr->ptoac, CLA_MISC_HIT))
X {
X objdes(tmp, t_ptr, TRUE);
X take_hit(dam, tmp);
X msg_print("An arrow hits you.");
X }
X else
X msg_print("An arrow barely misses you.");
X break;
X case 3: /* Covered pit*/
X msg_print("You fell into a covered pit.");
X if (py.flags.ffall)
X msg_print("You gently float down.");
X else
X {
X objdes(tmp, t_ptr, TRUE);
X take_hit(dam, tmp);
X }
X place_trap(y, x, 0);
X break;
X case 4: /* Trap door*/
X msg_print("You fell through a trap door!");
X new_level_flag = TRUE;
X dun_level++;
X if (py.flags.ffall)
X msg_print("You gently float down.");
X else
X {
X objdes(tmp, t_ptr, TRUE);
X take_hit(dam, tmp);
X }
X /* Force the messages to display before starting to generate the
X next level. */
X msg_print (CNIL);
X break;
X case 5: /* Sleep gas*/
X if (py.flags.paralysis == 0)
X {
X msg_print("A strange white mist surrounds you!");
X if (py.flags.free_act)
X msg_print("You are unaffected.");
X else
X {
X msg_print("You fall asleep.");
X py.flags.paralysis += randint(10) + 4;
X }
X }
X break;
X case 6: /* Hid Obj*/
X (void) delete_object(y, x);
X place_object(y, x);
X msg_print("Hmmm, there was something under this rock.");
X break;
X case 7: /* STR Dart*/
X if (test_hit(125, 0, 0, p_ptr->pac+p_ptr->ptoac, CLA_MISC_HIT))
X {
X if (!py.flags.sustain_str)
X {
X (void) dec_stat(A_STR);
X objdes(tmp, t_ptr, TRUE);
X take_hit(dam, tmp);
X msg_print("A small dart weakens you!");
X }
X else
X msg_print("A small dart hits you.");
X }
X else
X msg_print("A small dart barely misses you.");
X break;
X case 8: /* Teleport*/
X teleport_flag = TRUE;
X msg_print("You hit a teleport trap!");
X /* Light up the teleport trap, before we teleport away. */
X move_light (y, x, y, x);
X break;
X case 9: /* Rockfall*/
X take_hit(dam, "a falling rock");
X (void) delete_object(y, x);
X place_rubble(y, x);
X msg_print("You are hit by falling rock.");
X break;
X case 10: /* Corrode gas*/
X /* Makes more sense to print the message first, then damage an
X object. */
X msg_print("A strange red gas surrounds you.");
X corrode_gas("corrosion gas");
X break;
X case 11: /* Summon mon*/
X (void) delete_object(y, x); /* Rune disappears. */
X num = 2 + randint (3);
X for (i = 0; i < num; i++)
X {
X ty = y;
X tx = x;
X (void) summon_monster(&ty, &tx, FALSE);
X }
X break;
X case 12: /* Fire trap*/
X msg_print("You are enveloped in flames!");
X fire_dam(dam, "a fire trap");
X break;
X case 13: /* Acid trap*/
X msg_print("You are splashed with acid!");
X acid_dam(dam, "an acid trap");
X break;
X case 14: /* Poison gas*/
X msg_print("A pungent green gas surrounds you!");
X poison_gas(dam, "a poison gas trap");
X break;
X case 15: /* Blind Gas */
X msg_print("A black gas surrounds you!");
X py.flags.blind += randint(50) + 50;
X break;
X case 16: /* Confuse Gas*/
X msg_print("A gas of scintillating colors surrounds you!");
X py.flags.confused += randint(15) + 15;
X break;
X case 17: /* Slow Dart*/
X if (test_hit(125, 0, 0, p_ptr->pac+p_ptr->ptoac, CLA_MISC_HIT))
X {
X objdes(tmp, t_ptr, TRUE);
X take_hit(dam, tmp);
X msg_print("A small dart hits you!");
X if (py.flags.free_act)
X msg_print("You are unaffected.");
X else
X py.flags.slow += randint(20) + 10;
X }
X else
X msg_print("A small dart barely misses you.");
X break;
X case 18: /* CON Dart*/
X if (test_hit(125, 0, 0, p_ptr->pac+p_ptr->ptoac, CLA_MISC_HIT))
X {
X if (!py.flags.sustain_con)
X {
X (void) dec_stat(A_CON);
X objdes(tmp, t_ptr, TRUE);
X take_hit(dam, tmp);
X msg_print("A small dart saps your health!");
X }
X else
X msg_print("A small dart hits you.");
X }
X else
X msg_print("A small dart barely misses you.");
X break;
X case 19: /*Secret Door*/
X break;
X case 99: /* Scare Mon*/
X break;
X
X /* Town level traps are special, the stores. */
X case 101: /* General */
X enter_store(0);
X break;
X case 102: /* Armory */
X enter_store(1);
X break;
X case 103: /* Weaponsmith*/
X enter_store(2);
X break;
X case 104: /* Temple */
X enter_store(3);
X break;
X case 105: /* Alchemy */
X enter_store(4);
X break;
X case 106: /* Magic-User */
X enter_store(5);
X break;
X
X default:
X msg_print("Unknown trap value.");
X break;
X }
X}
X
X
X/* Return spell number and failure chance -RAK- */
X/* returns -1 if no spells in book
X returns 1 if choose a spell in book to cast
X returns 0 if don't choose a spell, i.e. exit with an escape */
Xint cast_spell(prompt, item_val, sn, sc)
Xchar *prompt;
Xint item_val;
Xint *sn, *sc;
X{
X int32u j;
X register int i, k;
X int spell[31], result, first_spell;
X register spell_type *s_ptr;
X
X result = -1;
X i = 0;
X j = inventory[item_val].flags;
X first_spell = bit_pos(&j);
X /* set j again, since bit_pos modified it */
X j = inventory[item_val].flags & spell_learned;
X s_ptr = magic_spell[py.misc.pclass-1];
X while (j)
X {
X k = bit_pos(&j);
X if (s_ptr[k].slevel <= py.misc.lev)
X {
X spell[i] = k;
X i++;
X }
X }
X if (i > 0)
X {
X result = get_spell(spell, i, sn, sc, prompt, first_spell);
X if (result && magic_spell[py.misc.pclass-1][*sn].smana > py.misc.cmana)
X {
X if (class[py.misc.pclass].spell == MAGE)
X result = get_check("You summon your limited strength to cast \
Xthis one! Confirm?");
X else
X result = get_check("The gods may think you presumptuous for \
Xthis! Confirm?");
X }
X }
X return(result);
X}
X
X
X/* Player is on an object. Many things can happen based -RAK- */
X/* on the TVAL of the object. Traps are set off, money and most */
X/* objects are picked up. Some objects, such as open doors, just*/
X/* sit there. */
Xstatic void carry(y, x, pickup)
Xint y, x;
Xint pickup;
X{
X register int locn, i;
X bigvtype out_val, tmp_str;
X register cave_type *c_ptr;
X register inven_type *i_ptr;
X
X c_ptr = &cave[y][x];
X i_ptr = &t_list[c_ptr->tptr];
X i = t_list[c_ptr->tptr].tval;
X if (i <= TV_MAX_PICK_UP)
X {
X end_find();
X /* There's GOLD in them thar hills! */
X if (i == TV_GOLD)
X {
X py.misc.au += i_ptr->cost;
X objdes(tmp_str, i_ptr, TRUE);
X (void) sprintf(out_val,
X "You have found %ld gold pieces worth of %s",
X i_ptr->cost, tmp_str);
X prt_gold();
X (void) delete_object(y, x);
X msg_print(out_val);
X }
X else
X {
X if (inven_check_num(i_ptr)) /* Too many objects? */
X { /* Okay, pick it up */
X if (pickup && prompt_carry_flag)
X {
X objdes(tmp_str, i_ptr, TRUE);
X /* change the period to a question mark */
X tmp_str[strlen(tmp_str)-1] = '?';
X (void) sprintf(out_val, "Pick up %s", tmp_str);
X pickup = get_check(out_val);
X }
X /* Check to see if it will change the players speed. */
X if (pickup && !inven_check_weight(i_ptr))
X {
X objdes(tmp_str, i_ptr, TRUE);
X /* change the period to a question mark */
X tmp_str[strlen(tmp_str)-1] = '?';
X (void) sprintf(out_val,
X "Exceed your weight limit to pick up %s",
X tmp_str);
X pickup = get_check(out_val);
X }
X /* Attempt to pick up an object. */
X if (pickup)
X {
X locn = inven_carry(i_ptr);
X objdes(tmp_str, &inventory[locn], TRUE);
X (void) sprintf(out_val, "You have %s (%c)",tmp_str,locn+'a');
X msg_print(out_val);
X (void) delete_object(y, x);
X }
X }
X else
X {
X objdes(tmp_str, i_ptr, TRUE);
X (void) sprintf(out_val, "You can't carry %s", tmp_str);
X msg_print(out_val);
X }
X }
X }
X /* OPPS! */
X else if (i == TV_INVIS_TRAP || i == TV_VIS_TRAP || i == TV_STORE_DOOR)
X hit_trap(y, x);
X}
X
X
X/* Deletes a monster entry from the level -RAK- */
Xvoid delete_monster(j)
Xint j;
X{
X register monster_type *m_ptr;
X
X m_ptr = &m_list[j];
X cave[m_ptr->fy][m_ptr->fx].cptr = 0;
X if (m_ptr->ml)
X lite_spot((int)m_ptr->fy, (int)m_ptr->fx);
X if (j != mfptr - 1)
X {
X m_ptr = &m_list[mfptr - 1];
X cave[m_ptr->fy][m_ptr->fx].cptr = j;
X m_list[j] = m_list[mfptr - 1];
X }
X mfptr--;
X m_list[mfptr] = blank_monster;
X if (mon_tot_mult > 0)
X mon_tot_mult--;
X}
X
X/* The following two procedures implement the same function as delete monster.
X However, they are used within creatures(), because deleting a monster
X while scanning the m_list causes two problems, monsters might get two
X turns, and m_ptr/monptr might be invalid after the delete_monster.
X Hence the delete is done in two steps. */
X/* fix1_delete_monster does everything delete_monster does except delete
X the monster record and reduce mfptr, this is called in breathe, and
X a couple of places in creatures.c */
Xvoid fix1_delete_monster(j)
Xint j;
X{
X register monster_type *m_ptr;
X
X m_ptr = &m_list[j];
X /* force the hp negative to ensure that the monster is dead, for example,
X if the monster was just eaten by another, it will still have positive
X hit points */
X m_ptr->hp = -1;
X cave[m_ptr->fy][m_ptr->fx].cptr = 0;
X if (m_ptr->ml)
X lite_spot((int)m_ptr->fy, (int)m_ptr->fx);
X if (mon_tot_mult > 0)
X mon_tot_mult--;
X}
X
X/* fix2_delete_monster does everything in delete_monster that wasn't done
X by fix1_monster_delete above, this is only called in creatures() */
Xvoid fix2_delete_monster(j)
Xint j;
X{
X register monster_type *m_ptr;
X
X if (j != mfptr - 1)
X {
X m_ptr = &m_list[mfptr - 1];
X cave[m_ptr->fy][m_ptr->fx].cptr = j;
X m_list[j] = m_list[mfptr - 1];
X }
X m_list[mfptr - 1] = blank_monster;
X mfptr--;
X}
X
X
X/* Creates objects nearby the coordinates given -RAK- */
Xstatic int summon_object(y, x, num, typ)
Xint y, x, num, typ;
X{
X register int i, j, k;
X register cave_type *c_ptr;
X int real_typ, res;
X
X if (typ == 1)
X real_typ = 1; /* typ == 1 -> objects */
X else
X real_typ = 256; /* typ == 2 -> gold */
X res = 0;
X do
X {
X i = 0;
X do
X {
X j = y - 3 + randint(5);
X k = x - 3 + randint(5);
X if (in_bounds(j, k) && los(y, x, j, k))
X {
X c_ptr = &cave[j][k];
X if (c_ptr->fval <= MAX_OPEN_SPACE && (c_ptr->tptr == 0))
X {
X if (typ == 3) /* typ == 3 -> 50% objects, 50% gold */
X {
X if (randint(100) < 50)
X real_typ = 1;
X else
X real_typ = 256;
X }
X if (real_typ == 1)
X place_object(j, k);
X else
X place_gold(j, k);
X lite_spot(j, k);
X if (test_light(j, k))
X res += real_typ;
X i = 20;
X }
X }
X i++;
X }
X while (i <= 20);
X num--;
X }
X while (num != 0);
X return res;
X}
X
X
X/* Deletes object from given location -RAK- */
Xint delete_object(y, x)
Xint y, x;
X{
X register int delete;
X register cave_type *c_ptr;
X
X c_ptr = &cave[y][x];
X if (c_ptr->fval == BLOCKED_FLOOR)
X c_ptr->fval = CORR_FLOOR;
X pusht(c_ptr->tptr);
X c_ptr->tptr = 0;
X c_ptr->fm = FALSE;
X lite_spot(y, x);
X if (test_light(y, x))
X delete = TRUE;
X else
X delete = FALSE;
X return(delete);
X}
X
X
X/* Allocates objects upon a creatures death -RAK- */
X/* Oh well, another creature bites the dust. Reward the victor*/
X/* based on flags set in the main creature record */
X/* Returns a mask of bits from the given flags which indicates what the
X monster is seen to have dropped. This may be added to monster memory. */
Xint32u monster_death(y, x, flags)
Xint y, x;
Xregister int32u flags;
X{
X register int i, number;
X int32u dump, res;
X#if defined(ATARIST_MWC)
X int32u holder; /* avoid a compiler bug */
X#endif
X
X#if !defined(ATARIST_MWC)
X if (flags & CM_CARRY_OBJ)
X i = 1;
X else
X i = 0;
X if (flags & CM_CARRY_GOLD)
X i += 2;
X
X number = 0;
X if ((flags & CM_60_RANDOM) && (randint(100) < 60))
X number++;
X if ((flags & CM_90_RANDOM) && (randint(100) < 90))
X number++;
X if (flags & CM_1D2_OBJ)
X number += randint(2);
X if (flags & CM_2D2_OBJ)
X number += damroll(2, 2);
X if (flags & CM_4D2_OBJ)
X number += damroll(4, 2);
X if (number > 0)
X dump = summon_object(y, x, number, i);
X else
X dump = 0;
X#else
X holder = CM_CARRY_OBJ;
X if (flags & holder)
X i = 1;
X else
X i = 0;
X holder = CM_CARRY_GOLD;
X if (flags & holder)
X i += 2;
X
X number = 0;
X holder = CM_60_RANDOM;
X if ((flags & holder) && (randint(100) < 60))
X number++;
X holder = CM_90_RANDOM;
X if ((flags & holder) && (randint(100) < 90))
X number++;
X holder = CM_1D2_OBJ;
X if (flags & holder)
X number += randint(2);
X holder = CM_2D2_OBJ;
X if (flags & holder)
X number += damroll(2, 2);
X holder = CM_4D2_OBJ;
X if (flags & holder)
X number += damroll(4, 2);
X if (number > 0)
X dump = summon_object(y, x, number, i);
X else
X dump = 0;
X
X
X#endif
X
X#if defined(ATARIST_MWC)
X holder = CM_WIN;
X if (flags & holder)
X#else
X if (flags & CM_WIN)
X#endif
X {
X total_winner = TRUE;
X prt_winner();
X msg_print("*** CONGRATULATIONS *** You have won the game.");
X msg_print("You cannot save this game, but you may retire when ready.");
X }
X
X if (dump)
X {
X res = 0;
X if (dump & 255)
X#ifdef ATARIST_MWC
X {
X holder = CM_CARRY_OBJ;
X res |= holder;
X }
X#else
X res |= CM_CARRY_OBJ;
X#endif
X if (dump >= 256)
X#ifdef ATARIST_MWC
X {
X holder = CM_CARRY_GOLD;
X res |= holder;
X }
X#else
X res |= CM_CARRY_GOLD;
X#endif
X dump = (dump % 256) + (dump / 256); /* number of items */
X res |= dump << CM_TR_SHIFT;
X }
X else
X res = 0;
X
X return res;
X}
X
X
X/* Decreases monsters hit points and deletes monster if needed. */
X/* (Picking on my babies.) -RAK- */
Xint mon_take_hit(monptr, dam)
Xint monptr, dam;
X{
X register int32u i;
X int32 new_exp, new_exp_frac;
X register monster_type *m_ptr;
X register struct misc *p_ptr;
X register creature_type *c_ptr;
X int m_take_hit;
X int32u tmp;
X#ifdef ATARIST_MWC
X int32u holder;
X#endif
X
X m_ptr = &m_list[monptr];
X m_ptr->hp -= dam;
X m_ptr->csleep = 0;
X if (m_ptr->hp < 0)
X {
X i = monster_death((int)m_ptr->fy, (int)m_ptr->fx,
X c_list[m_ptr->mptr].cmove);
X if ((py.flags.blind < 1 && m_ptr->ml)
X#ifdef ATARIST_MWC
X || (c_list[m_ptr->mptr].cmove & (holder = CM_WIN)))
X#else
X || (c_list[m_ptr->mptr].cmove & CM_WIN))
X#endif
X {
X#ifdef ATARIST_MWC
X holder = CM_TREASURE;
X tmp = (c_recall[m_ptr->mptr].r_cmove & holder) >> CM_TR_SHIFT;
X if (tmp > ((i & holder) >> CM_TR_SHIFT))
X i = (i & ~holder) | (tmp << CM_TR_SHIFT);
X c_recall[m_ptr->mptr].r_cmove =
X (c_recall[m_ptr->mptr].r_cmove & ~holder) | i;
X#else
X tmp = (c_recall[m_ptr->mptr].r_cmove & CM_TREASURE) >> CM_TR_SHIFT;
X if (tmp > ((i & CM_TREASURE) >> CM_TR_SHIFT))
X i = (i & ~CM_TREASURE) | (tmp << CM_TR_SHIFT);
X c_recall[m_ptr->mptr].r_cmove =
X (c_recall[m_ptr->mptr].r_cmove & ~CM_TREASURE) | i;
X#endif
X if (c_recall[m_ptr->mptr].r_kills < MAX_SHORT)
X c_recall[m_ptr->mptr].r_kills++;
X }
X c_ptr = &c_list[m_ptr->mptr];
X p_ptr = &py.misc;
X
X new_exp = ((long)c_ptr->mexp * c_ptr->level) / p_ptr->lev;
X new_exp_frac = ((((long)c_ptr->mexp * c_ptr->level) % p_ptr->lev)
X * 0x10000L / p_ptr->lev) + p_ptr->exp_frac;
X if (new_exp_frac >= 0x10000L)
X {
X new_exp++;
X p_ptr->exp_frac = new_exp_frac - 0x10000L;
X }
X else
X p_ptr->exp_frac = new_exp_frac;
X
X p_ptr->exp += new_exp;
X /* can't call prt_experience() here, as that would result in "new level"
X message appearing before "monster dies" message */
X m_take_hit = m_ptr->mptr;
X /* in case this is called from within creatures(), this is a
X horrible hack, the m_list/creatures() code needs to be
X rewritten */
X if (hack_monptr < monptr)
X delete_monster(monptr);
X else
X fix1_delete_monster(monptr);
X }
X else
X m_take_hit = -1;
X return(m_take_hit);
X}
X
X
X/* Player attacks a (poor, defenseless) creature -RAK- */
Xvoid py_attack(y, x)
Xint y, x;
X{
X register int k, blows;
X int crptr, monptr, tot_tohit, base_tohit;
X vtype m_name, out_val;
X register inven_type *i_ptr;
X register struct misc *p_ptr;
X#ifdef ATARIST_MWC
X int32u holder;
X#endif
X
X crptr = cave[y][x].cptr;
X monptr = m_list[crptr].mptr;
X m_list[crptr].csleep = 0;
X i_ptr = &inventory[INVEN_WIELD];
X /* Does the player know what he's fighting? */
X if (!m_list[crptr].ml)
X (void) strcpy(m_name, "it");
X else
X (void) sprintf(m_name, "the %s", c_list[monptr].name);
X if (i_ptr->tval != TV_NOTHING) /* Proper weapon */
X blows = attack_blows((int)i_ptr->weight, &tot_tohit);
X else /* Bare hands? */
X {
X blows = 2;
X tot_tohit = -3;
X }
X if ((i_ptr->tval >= TV_SLING_AMMO) && (i_ptr->tval <= TV_SPIKE))
X /* Fix for arrows */
X blows = 1;
X p_ptr = &py.misc;
X tot_tohit += p_ptr->ptohit;
X /* if creature not lit, make it more difficult to hit */
X if (m_list[crptr].ml)
X base_tohit = p_ptr->bth;
X else
X base_tohit = (p_ptr->bth / 2) - (tot_tohit * (BTH_PLUS_ADJ-1))
X - (p_ptr->lev * class_level_adj[p_ptr->pclass][CLA_BTH] / 2);
X
X /* Loop for number of blows, trying to hit the critter. */
X do
X {
X if (test_hit(base_tohit, (int)p_ptr->lev, tot_tohit,
X (int)c_list[monptr].ac, CLA_BTH))
X {
X (void) sprintf(out_val, "You hit %s.", m_name);
X msg_print(out_val);
X if (i_ptr->tval != TV_NOTHING)
X {
X k = pdamroll(i_ptr->damage);
X k = tot_dam(i_ptr, k, monptr);
X k = critical_blow((int)i_ptr->weight, tot_tohit, k, CLA_BTH);
X }
X else /* Bare hands!? */
X {
X k = damroll(1, 1);
X k = critical_blow(1, 0, k, CLA_BTH);
X }
X k += p_ptr->ptodam;
X if (k < 0) k = 0;
X
X if (py.flags.confuse_monster)
X {
X py.flags.confuse_monster = FALSE;
X msg_print("Your hands stop glowing.");
X if ((c_list[monptr].cdefense & CD_NO_SLEEP)
X || (randint(MAX_MONS_LEVEL) < c_list[monptr].level))
X (void) sprintf(out_val, "%s is unaffected.", m_name);
X else
X {
X (void) sprintf(out_val, "%s appears confused.", m_name);
X m_list[crptr].confused = TRUE;
X }
X msg_print(out_val);
X if (m_list[crptr].ml && randint(4) == 1)
X c_recall[monptr].r_cdefense |=
X c_list[monptr].cdefense & CD_NO_SLEEP;
X }
X
X /* See if we done it in. */
X if (mon_take_hit(crptr, k) >= 0)
X {
X (void) sprintf(out_val, "You have slain %s.", m_name);
X msg_print(out_val);
X prt_experience();
X blows = 0;
X }
X
X if ((i_ptr->tval >= TV_SLING_AMMO)
X && (i_ptr->tval <= TV_SPIKE)) /* Use missiles up*/
X {
X i_ptr->number--;
X inven_weight -= i_ptr->weight;
X#ifdef ATARIST_MWC
X py.flags.status |= (holder = PY_STR_WGT);
X#else
X py.flags.status |= PY_STR_WGT;
X#endif
X if (i_ptr->number == 0)
X {
X equip_ctr--;
X py_bonuses(i_ptr, -1);
X invcopy(i_ptr, OBJ_NOTHING);
X calc_bonuses();
X }
X }
X }
X else
X {
X (void) sprintf(out_val, "You miss %s.", m_name);
X msg_print(out_val);
X }
X blows--;
X }
X while (blows >= 1);
X}
X
X
X/* Moves player from one space to another. -RAK- */
X/* Note: This routine has been pre-declared; see that for argument*/
Xvoid move_char(dir, do_pickup)
Xint dir, do_pickup;
X{
X int old_row, old_col, old_find_flag;
X int y, x;
X register int i, j;
X register cave_type *c_ptr, *d_ptr;
X
X if ((py.flags.confused > 0) && /* Confused? */
X (randint(4) > 1) && /* 75% random movement */
X (dir != 5)) /* Never random if sitting*/
X {
X dir = randint(9);
X end_find();
X }
X y = char_row;
X x = char_col;
X if (mmove(dir, &y, &x)) /* Legal move? */
X {
X c_ptr = &cave[y][x];
X /* if there is no creature, or an unlit creature in the walls then... */
X /* disallow attacks against unlit creatures in walls because moving into
X a wall is a free turn normally, hence don't give player free turns
X attacking each wall in an attempt to locate the invisible creature,
X instead force player to tunnel into walls which always takes a turn */
X if ((c_ptr->cptr < 2)
X || (!m_list[c_ptr->cptr].ml && c_ptr->fval >= MIN_CLOSED_SPACE))
X {
X if (c_ptr->fval <= MAX_OPEN_SPACE) /* Open floor spot */
X {
X /* Make final assignments of char co-ords */
X old_row = char_row;
X old_col = char_col;
X char_row = y;
X char_col = x;
X /* Move character record (-1) */
X move_rec(old_row, old_col, char_row, char_col);
X /* Check for new panel */
X if (get_panel(char_row, char_col, FALSE))
X prt_map();
X /* Check to see if he should stop */
X if (find_flag)
X area_affect(dir, char_row, char_col);
X /* Check to see if he notices something */
X /* fos may be negative if have good rings of searching */
X if ((py.misc.fos <= 1) || (randint(py.misc.fos) == 1) ||
X (py.flags.status & PY_SEARCH))
X search(char_row, char_col, py.misc.srh);
X /* A room of light should be lit. */
X if (c_ptr->fval == LIGHT_FLOOR)
X {
X if (!c_ptr->pl && !py.flags.blind)
X light_room(char_row, char_col);
X }
X /* In doorway of light-room? */
X else if (c_ptr->lr && (py.flags.blind < 1))
X for (i = (char_row - 1); i <= (char_row + 1); i++)
X for (j = (char_col - 1); j <= (char_col + 1); j++)
X {
X d_ptr = &cave[i][j];
X if ((d_ptr->fval == LIGHT_FLOOR) && (!d_ptr->pl))
X light_room(i, j);
X }
X /* Move the light source */
X move_light(old_row, old_col, char_row, char_col);
X /* An object is beneath him. */
X if (c_ptr->tptr != 0)
X {
X carry(char_row, char_col, do_pickup);
X /* if stepped on falling rock trap, and space contains
X rubble, then step back into a clear area */
X if (t_list[c_ptr->tptr].tval == TV_RUBBLE)
X {
X move_rec(char_row, char_col, old_row, old_col);
X move_light(char_row, char_col, old_row, old_col);
X char_row = old_row;
X char_col = old_col;
X /* check to see if we have stepped back onto another
X trap, if so, set it off */
X c_ptr = &cave[char_row][char_col];
X if (c_ptr->tptr != 0)
X {
X i = t_list[c_ptr->tptr].tval;
X if (i == TV_INVIS_TRAP || i == TV_VIS_TRAP
X || i == TV_STORE_DOOR)
X hit_trap(char_row, char_col);
X }
X }
X }
X }
X else /*Can't move onto floor space*/
X {
X if (!find_flag && (c_ptr->tptr != 0))
X {
X if (t_list[c_ptr->tptr].tval == TV_RUBBLE)
X msg_print("There is rubble blocking your way.");
X else if (t_list[c_ptr->tptr].tval == TV_CLOSED_DOOR)
X msg_print("There is a closed door blocking your way.");
X }
X else
X end_find();
X free_turn_flag = TRUE;
X }
X }
X else /* Attacking a creature! */
X {
X old_find_flag = find_flag;
X end_find();
X /* if player can see monster, and was in find mode, then nothing */
X if (m_list[c_ptr->cptr].ml && old_find_flag)
X {
X /* did not do anything this turn */
X free_turn_flag = TRUE;
X }
X else
X {
X if (py.flags.afraid < 1) /* Coward? */
X py_attack(y, x);
X else /* Coward! */
X msg_print("You are too afraid!");
X }
X }
X }
X}
X
X
X/* Chests have traps too. -RAK- */
X/* Note: Chest traps are based on the FLAGS value */
Xvoid chest_trap(y, x)
Xint y, x;
X{
X register int i;
X int j, k;
X register inven_type *t_ptr;
X
X t_ptr = &t_list[cave[y][x].tptr];
X if (CH_LOSE_STR & t_ptr->flags)
X {
X msg_print("A small needle has pricked you!");
X if (!py.flags.sustain_str)
X {
X (void) dec_stat(A_STR);
X take_hit(damroll(1, 4), "a poison needle");
X msg_print("You feel weakened!");
X }
X else
X msg_print("You are unaffected.");
X }
X if (CH_POISON & t_ptr->flags)
X {
X msg_print("A small needle has pricked you!");
X take_hit(damroll(1, 6), "a poison needle");
X py.flags.poisoned += 10 + randint(20);
X }
X if (CH_PARALYSED & t_ptr->flags)
X {
X msg_print("A puff of yellow gas surrounds you!");
X if (py.flags.free_act)
X msg_print("You are unaffected.");
X else
X {
X msg_print("You choke and pass out.");
X py.flags.paralysis = 10 + randint(20);
X }
X }
X if (CH_SUMMON & t_ptr->flags)
X {
X for (i = 0; i < 3; i++)
X {
X j = y;
X k = x;
X (void) summon_monster(&j, &k, FALSE);
X }
X }
X if (CH_EXPLODE & t_ptr->flags)
X {
X msg_print("There is a sudden explosion!");
X (void) delete_object(y, x);
X take_hit(damroll(5, 8), "an exploding chest");
X }
X}
X
X
X/* Opens a closed door or closed chest. -RAK- */
Xvoid openobject()
X{
X int y, x, i, dir;
X int flag, no_object;
X register cave_type *c_ptr;
X register inven_type *t_ptr;
X register struct misc *p_ptr;
X register monster_type *m_ptr;
X vtype m_name, out_val;
X#ifdef ATARIST_MWC
X int32u holder;
X#endif
X
X y = char_row;
X x = char_col;
X if (get_dir(CNIL, &dir))
X {
X (void) mmove(dir, &y, &x);
X c_ptr = &cave[y][x];
X no_object = FALSE;
X if (c_ptr->cptr > 1 && c_ptr->tptr != 0 &&
X (t_list[c_ptr->tptr].tval == TV_CLOSED_DOOR
X || t_list[c_ptr->tptr].tval == TV_CHEST))
X {
X m_ptr = &m_list[c_ptr->cptr];
X if (m_ptr->ml)
X (void) sprintf (m_name, "The %s", c_list[m_ptr->mptr].name);
X else
X (void) strcpy (m_name, "Something");
X (void) sprintf(out_val, "%s is in your way!", m_name);
X msg_print(out_val);
X }
X else if (c_ptr->tptr != 0)
X /* Closed door */
X if (t_list[c_ptr->tptr].tval == TV_CLOSED_DOOR)
X {
X t_ptr = &t_list[c_ptr->tptr];
X if (t_ptr->p1 > 0) /* It's locked. */
X {
X p_ptr = &py.misc;
X i = p_ptr->disarm + 2*todis_adj() + stat_adj(A_INT)
X + (class_level_adj[p_ptr->pclass][CLA_DISARM]
X * p_ptr->lev / 3);
X if (py.flags.confused > 0)
X msg_print("You are too confused to pick the lock.");
X else if ((i-t_ptr->p1) > randint(100))
X {
X msg_print("You have picked the lock.");
X py.misc.exp++;
X prt_experience();
X t_ptr->p1 = 0;
X }
X else
X count_msg_print("You failed to pick the lock.");
X }
X else if (t_ptr->p1 < 0) /* It's stuck */
X msg_print("It appears to be stuck.");
X if (t_ptr->p1 == 0)
X {
X invcopy(&t_list[c_ptr->tptr], OBJ_OPEN_DOOR);
X c_ptr->fval = CORR_FLOOR;
X lite_spot(y, x);
X command_count = 0;
X }
X }
X /* Open a closed chest. */
X else if (t_list[c_ptr->tptr].tval == TV_CHEST)
X {
X p_ptr = &py.misc;
X i = p_ptr->disarm + 2*todis_adj() + stat_adj(A_INT)
X + (class_level_adj[p_ptr->pclass][CLA_DISARM] * p_ptr->lev / 3);
X t_ptr = &t_list[c_ptr->tptr];
X flag = FALSE;
X if (CH_LOCKED & t_ptr->flags)
X if (py.flags.confused > 0)
X msg_print("You are too confused to pick the lock.");
X else if ((i-(int)t_ptr->level) > randint(100))
X {
X msg_print("You have picked the lock.");
X flag = TRUE;
X py.misc.exp += t_ptr->level;
X prt_experience();
X }
X else
X count_msg_print("You failed to pick the lock.");
X else
X flag = TRUE;
X if (flag)
X {
X t_ptr->flags &= ~CH_LOCKED;
X t_ptr->name2 = SN_EMPTY;
X known2(t_ptr);
X t_ptr->cost = 0;
X }
X flag = FALSE;
X /* Was chest still trapped? (Snicker) */
X if ((CH_LOCKED & t_ptr->flags) == 0)
X {
X chest_trap(y, x);
X if (c_ptr->tptr != 0)
X flag = TRUE;
X }
X /* Chest treasure is allocated as if a creature */
X /* had been killed. */
X if (flag)
X {
X /* clear the cursed chest/monster win flag, so that people
X can not win by opening a cursed chest */
X#ifdef ATARIST_MWC
X t_list[c_ptr->tptr].flags &= ~(holder = TR_CURSED);
X#else
X t_list[c_ptr->tptr].flags &= ~TR_CURSED;
X#endif
X (void) monster_death(y, x, t_list[c_ptr->tptr].flags);
X t_list[c_ptr->tptr].flags = 0;
X }
X }
X else
X no_object = TRUE;
X else
X no_object = TRUE;
X
X if (no_object)
X {
X msg_print("I do not see anything you can open there.");
X free_turn_flag = TRUE;
X }
X }
X}
X
X
X/* Closes an open door. -RAK- */
Xvoid closeobject()
X{
X int y, x, dir, no_object;
X vtype out_val, m_name;
X register cave_type *c_ptr;
X register monster_type *m_ptr;
X
X y = char_row;
X x = char_col;
X if (get_dir(CNIL, &dir))
X {
X (void) mmove(dir, &y, &x);
X c_ptr = &cave[y][x];
X no_object = FALSE;
X if (c_ptr->tptr != 0)
X if (t_list[c_ptr->tptr].tval == TV_OPEN_DOOR)
X if (c_ptr->cptr == 0)
X if (t_list[c_ptr->tptr].p1 == 0)
X {
X invcopy(&t_list[c_ptr->tptr], OBJ_CLOSED_DOOR);
X c_ptr->fval = BLOCKED_FLOOR;
X lite_spot(y, x);
X }
X else
X msg_print("The door appears to be broken.");
X else
X {
X m_ptr = &m_list[c_ptr->cptr];
X if (m_ptr->ml)
X (void) sprintf (m_name, "The %s", c_list[m_ptr->mptr].name);
X else
X (void) strcpy (m_name, "Something");
X (void) sprintf(out_val, "%s is in your way!", m_name);
X msg_print(out_val);
X }
X else
X no_object = TRUE;
X else
X no_object = TRUE;
X
X if (no_object)
X {
X msg_print("I do not see anything you can close there.");
X free_turn_flag = TRUE;
X }
X }
X}
X
X
X/* Tunneling through real wall: 10, 11, 12 -RAK- */
X/* Used by TUNNEL and WALL_TO_MUD */
Xint twall(y, x, t1, t2)
Xint y, x, t1, t2;
X{
X register int i, j;
X register cave_type *c_ptr;
X int res, found;
X
X res = FALSE;
X if (t1 > t2)
X {
X c_ptr = &cave[y][x];
X if (c_ptr->lr)
X {
X /* should become a room space, check to see whether it should be
X LIGHT_FLOOR or DARK_FLOOR */
X found = FALSE;
X for (i = y-1; i <= y+1; i++)
X for (j = x-1; j <= x+1; j++)
X if (cave[i][j].fval <= MAX_CAVE_ROOM)
X {
X c_ptr->fval = cave[i][j].fval;
X c_ptr->pl = cave[i][j].pl;
X found = TRUE;
X break;
X }
X if (!found)
X {
X c_ptr->fval = CORR_FLOOR;
X c_ptr->pl = FALSE;
X }
X }
X else
X {
X /* should become a corridor space */
X c_ptr->fval = CORR_FLOOR;
X c_ptr->pl = FALSE;
X }
X c_ptr->fm = FALSE;
X if (panel_contains(y, x))
X if ((c_ptr->tl || c_ptr->pl) && c_ptr->tptr != 0)
X msg_print("You have found something!");
X lite_spot(y, x);
X res = TRUE;
X }
X return(res);
X}
END_OF_FILE
if test 31365 -ne `wc -c <'source/moria3.c'`; then
echo shar: \"'source/moria3.c'\" unpacked with wrong size!
fi
# end of 'source/moria3.c'
fi
if test ! -d 'unix' ; then
echo shar: Creating directory \"'unix'\"
mkdir 'unix'
fi
if test ! -d 'util' ; then
echo shar: Creating directory \"'util'\"
mkdir 'util'
fi
if test ! -d 'util/mc' ; then
echo shar: Creating directory \"'util/mc'\"
mkdir 'util/mc'
fi
if test ! -d 'util/printit' ; then
echo shar: Creating directory \"'util/printit'\"
mkdir 'util/printit'
fi
if test ! -d 'util/scores' ; then
echo shar: Creating directory \"'util/scores'\"
mkdir 'util/scores'
fi
if test ! -d 'util/weapons' ; then
echo shar: Creating directory \"'util/weapons'\"
mkdir 'util/weapons'
fi
if test ! -d 'vms' ; then
echo shar: Creating directory \"'vms'\"
mkdir 'vms'
fi
if test -f 'amiga/README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'amiga/README'\"
else
echo shar: Extracting \"'amiga/README'\" \(1784 characters\)
sed "s/^X//" >'amiga/README' <<'END_OF_FILE'
XThis is the readme file for the Amiga port of Umoria. Please keep this file
Xwith any distribution of Umoria for the Amiga.
X
XVersion 5.3.1: changed display to use Simon John Raybould's curses. The
X version of the curses that was used in the binary distribution was 1.22
X with some modifications. Because of this some of the bugs may be fixed
X and new bugs may have been created. Please send any bug reports to me
X at (cge...@hubcap.clemson.edu) or post on usenet in rec.games.moria.
X
XThe game detachs from the cli. This was done so that the program can set
Xits own stack size. You no longer have to set the stack higher. I have
Xcompiled the binary distribution with stack depth checking, if anyone
XEVER gets the error "stack overflow!" tell me and I'll increase the stack
Xsize. As far as I can tell the program only uses about 20000 bytes and
XI have set the stack to 30000, so it should be fine.
X
XThis game will work on 1 MB amigas with one disk drive.
X
XFor the game to work properly you must:
X
X1) The game looks for the amiga environment variables. If you don't have
X env: set, you'll get a requester asking for it.
X
X2) If umoria is install on a hard disk, assign moria: to the directory where
X the binary and all of the support files are. If the files are in
X "dh1:games/moria" type "assign moria: dh1:games/moria".
X
X
XTo compile the game:
X
X1) You must have Aztec C 5.0d.
X
X2) Copy all of the files in the subdirectories "amiga" & "source" together
X and type "make". You must have the environment setup so that Aztec will
X find the include files and the large code libraries (cl.lib & ml.lib).
X
X3) If you do not want to use the assignment "moria:" to find the game, then
X you will have to change variables in "config.h" and "makefile".
END_OF_FILE
if test 1784 -ne `wc -c <'amiga/README'`; then
echo shar: \"'amiga/README'\" unpacked with wrong size!
fi
# end of 'amiga/README'
fi
if test -f 'amiga/timer.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'amiga/timer.c'\"
else
echo shar: Extracting \"'amiga/timer.c'\" \(2271 characters\)
sed "s/^X//" >'amiga/timer.c' <<'END_OF_FILE'
X/* amiga/timer.c: high level io commands for the timer.device
X
X Copyright (c) 1990-92 Corey Gehman, James E. Wilson
X
X This software may be copied and distributed for educational, research, and
X not for profit purposes provided that this copyright and statement are
X included in all such copies. */
X
X#include <exec/memory.h>
X#include <devices/timer.h>
X#include <functions.h>
X
Xextern UBYTE *malloc();
X
Xstruct mydevice {
X struct IORequest *readreq;
X struct MsgPort *readport;
X unsigned short size;
X} *currentdevice;
X
Xvoid clean(i)
Xint i;
X{
X switch (i){
X case 6: if (currentdevice->readreq)
X CloseDevice(currentdevice->readreq);
X case 5: if (currentdevice->readreq)
X DeleteExtIO(currentdevice->readreq);
X case 4: if (currentdevice->readport)
X DeletePort(currentdevice->readport);
X case 1: free(currentdevice);
X }
X}
X
Xint openreadports(size) /* 0=error,-1=ok */
Xint size;
X{
X currentdevice->size=size;
X currentdevice->readport=CreatePort("Read Port",0);
X if (currentdevice->readport==0L) {
X printf("The Read message port did not open\n");
X clean(1);
X return(0);
X }
X currentdevice->readreq=CreateExtIO(currentdevice->readport,size);
X if (currentdevice->readreq==0L) {
X printf("Read Standard IO Did Not Open\n");
X clean(4);
X return(0);
X }
X return(-1);
X}
X
Xint opentimer() /* 0=error,-1=ok */
X{
X currentdevice=(struct mydevice *)malloc(sizeof(struct mydevice));
X if (currentdevice==0) {
X printf("Not enough memory\n");
X return(0);
X }
X setmem(currentdevice,sizeof(struct mydevice),0);
X openreadports(sizeof(struct timerequest));
X if (OpenDevice("timer.device",UNIT_VBLANK,currentdevice->readreq,0)) {
X printf("New Timer OpenDevice Failed\n");
X clean(5);
X return(0);
X }
X currentdevice->readreq->io_Command=TR_ADDREQUEST;
X return(-1);
X}
X
Xvoid closetimer()
X{
X clean(6);
X}
X
Xvoid sendtimer(microsec)
Xint microsec;
X{
Xstruct timerequest *tr;
X tr=(struct timerequest *)currentdevice->readreq;
X tr->tr_time.tv_secs=microsec/1000000;
X tr->tr_time.tv_micro=microsec%1000000;
X SendIO((struct IORequest *)tr);
X}
X
Xvoid waittimer()
X{
X Wait(1<<(currentdevice->readport->mp_SigBit));
X GetMsg(currentdevice->readport);
X}
X
END_OF_FILE
if test 2271 -ne `wc -c <'amiga/timer.c'`; then
echo shar: \"'amiga/timer.c'\" unpacked with wrong size!
fi
# end of 'amiga/timer.c'
fi
echo shar: End of archive 1 \(of 39\).
cp /dev/null ark1isdone
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