-+-+-+-+-+-+-+-+ START OF PART 27 -+-+-+-+-+-+-+-+ X/*`09`09`09`09`09`09`09`09`09 */ X/*`09`09`09`09`09`09`09`09`09 */ X/*`09 Designer and Programmer : Robert Alan Koeneke`09`09`09 */ X/*`09`09`09`09 University of Oklahoma`09`09 */ X/*`09`09`09`09`09`09`09`09`09 */ X/*`09 Assistant Programmers`09 : Jimmey Wayne Todd`09`09`09 */ X/*`09`09`09`09 University of Oklahoma`09`09 */ X/*`09`09`09`09`09`09`09`09`09 */ X/*`09`09`09`09 Gary D. McAdoo`09`09`09 */ X/*`09`09`09`09 University of Oklahoma`09`09 */ X/*`09`09`09`09`09`09`09`09`09 */ X/*`09 UNIX Port`09`09 : James E. Wilson`09`09`09 */ X/*`09`09`09`09 UC Berkeley`09`09`09`09 */ X/*`09`09`09`09 wilson@kithrup.com`09`09`09 */ X/*`09`09`09`09`09`09`09`09`09 */ X/*`09 MSDOS Port`09`09 : Don Kneller`09`09`09`09 */ X/*`09`09`09`09 1349 - 10th ave`09`09`09 */ X/*`09`09`09`09 San Francisco, CA 94122`09`09 */ X/*`09`09`09`09 kneller@cgl.ucsf.EDU`09`09`09 */ X/*`09`09`09`09 ...ucbvax!ucsfcgl!kneller`09`09 */ X/*`09`09`09`09 kneller@ucsf-cgl.BITNET`09`09 */ X/*`09`09`09`09`09`09`09`09`09 */ X/*`09 BRUCE Moria`09`09 : Christopher Stuart`09`09`09 */ X/*`09`09`09`09 Monash University`09`09`09 */ X/*`09`09`09`09 Melbourne, Victoria, AUSTRALIA`09 */ X/*`09`09`09`09 cjs@moncsbruce.oz`09`09`09 */ X/*`09`09`09`09`09`09`09`09`09 */ X/* Amiga Port : Corey Gehman */ X/* Clemson University */ X/* cg377170@eng.clemson.edu */ X/*`09`09`09`09`09`09`09`09`09 */ X/*`09 Version 5.5`09`09 : David Grabiner`09`09`09 */ X/*`09`09`09`09 Harvard University`09`09`09 */ X/*`09`09`09`09 grabiner@math.harvard.edu`09`09 */ X/* */ X/*`09 Moria may be copied and modified freely as long as the above`09 */ X/*`09 credits are retained.`09No one who-so-ever may sell or market`09 */ X/*`09 this software in any form without the expressed written consent */ X/*`09 of the author Robert Alan Koeneke.`09`09`09`09 */ X/*`09`09`09`09`09`09`09`09`09 */ X X#ifdef __TURBOC__ X#include`09 X#include`09 X#include`09 X#endif /* __TURBOC__ */ X`20 X#include "config.h" X#include "constant.h" X#include "types.h" X#include "externs.h" X X#ifndef USG X#include X#include X#endif X X#ifdef USG X#ifndef ATARIST_MWC X#include X#else X#include "string.h" X#endif X#else X#include X#endif X X#include X X#ifdef Pyramid X#include X#else X#include X#endif X X#ifndef VMS X#ifndef MAC X#ifndef GEMDOS X#ifndef AMIGA Xlong time(); X#endif X#endif Xchar *getenv(); X#endif X#endif X X#ifndef MAC X#ifndef AMIGA X#ifdef USG X#if !defined(MSDOS) && !defined(ATARIST_TC) Xunsigned short getuid(), getgid(); X#endif X#else X#ifndef SECURE X#ifdef BSD4_3 Xuid_t getuid(), getgid(); X#else /* other BSD versions */ Xint getuid(), getgid(); X#endif X#endif X#endif X#endif X#endif X X#ifndef VMS X#ifndef MAC X#if defined(ultrix) `7C`7C defined(USG) Xvoid perror(); X#endif X#endif X#endif X X#ifndef VMS X#ifndef MAC X#ifdef USG Xvoid exit(); X#endif X#endif X#endif X X/* X#if defined(atarist) && defined(__GNUC__) Xlong _stksize = 64*1024; X#endif X*/ X X#ifdef ATARIST_MWC Xlong _stksize = 18000;`09`09/*(SAJ) for MWC`09*/ X#endif X X#ifdef __TURBOC__ Xunsigned _stklen = 0x3fff;`09/* increase stack from 4K to 16K */ X#endif X X#if defined(LINT_ARGS) Xstatic void char_inven_init(void); Xstatic void init_m_level(void); Xstatic void init_t_level(void); X#if (COST_ADJ != 100) Xstatic void price_adjust(void); X#endif X#else Xstatic void char_inven_init(); Xstatic void init_m_level(); Xstatic void init_t_level(); X#if (COST_ADJ != 100) Xstatic void price_adjust(); X#endif X#endif X X/* Initialize, restore, and get the ball rolling.`09-RAK-`09*/ X#ifdef MAC X/* This is just a subroutine for the Mac version */ X/* only options passed in are -orn */ X/* save file name is never passed */ Xint moria_main(argc, argv) Xint argc; Xchar *argv`5B`5D; X#else Xint main(argc, argv) Xint argc; Xchar *argv`5B`5D; X#endif X`7B X int32u seed; X int generate; X int result; X#ifndef MAC X char *p; X#endif X int new_game = FALSE; X int force_rogue_like = FALSE; X int force_keys_to; X X /* default command set defined in config.h file */ X rogue_like_commands = ROGUE_LIKE; X X#ifdef SECURE X Authenticate(); X#endif X X#ifdef MSDOS X msdos_init();`09`09/* find out where everything is */ X#endif X X /* call this routine to grab a file pointer to the highscore file */ X /* and prepare things to relinquish setuid privileges */ X init_scorefile(); X X#ifndef SECURE X#if !defined(MSDOS) && !defined(ATARIST_MWC) && !defined(MAC) X#if !defined(AMIGA) && !defined(ATARIST_TC) X#if !defined(atarist) X if (0 != setuid(getuid())) X `7B X perror("Can't set permissions correctly! Setuid call failed.\n"); X exit(0); X `7D X if (0 != setgid(getgid())) X `7B X perror("Can't set permissions correctly! Setgid call failed.\n"); X exit(0); X `7D X#endif X#endif X#endif X#endif X X /* use curses */ X init_curses(); X X#ifdef VMS X /* Bizarre, but yes this really is needed to make moria work correctly X under VMS. */ X restore_screen (); X#endif X X /* catch those nasty signals */ X /* must come after init_curses as some of the signal handlers use curses * V/ X init_signals(); X X seed = 0; /* let wizard specify rng seed */ X /* check for user interface option */ X for (--argc, ++argv; argc > 0 && argv`5B0`5D`5B0`5D == '-'; --argc, ++argv V) X switch (argv`5B0`5D`5B1`5D) X `7B X case 'N': X case 'n': new_game = TRUE; break; X case 'O': X case 'o': X`09/* rogue_like_commands may be set in get_char(), so delay this X`09 until after read savefile if any */ X`09force_rogue_like = TRUE; X`09force_keys_to = FALSE; X`09break; X case 'R': X case 'r': X`09force_rogue_like = TRUE; X`09force_keys_to = TRUE; X`09break; X#ifndef MAC X case 'S': display_scores(TRUE); exit_game(); X case 's': display_scores(FALSE); exit_game(); X case 'W': X case 'w': X`09to_be_wizard = TRUE; X X`09if (isdigit((int)argv`5B0`5D`5B2`5D)) X`09 seed = atoi(&argv`5B0`5D`5B2`5D); X`09break; X default: (void) printf("Usage: moria `5B-norsw`5D `5Bsavefile`5D\n"); X`09exit_game(); X#endif X `7D X X#ifndef MAC X /* Check operating hours`09`09`09*/ X /* If not wizard No_Control_Y`09 */ X read_times(); X#endif X X /* Some necessary initializations`09`09*/ X /* all made into constants or initialized in variables.c */ X X#if (COST_ADJ != 100) X price_adjust(); X#endif X X /* Grab a random seed from the clock`09`09*/ X init_seeds(seed); X X /* Init monster and treasure levels for allocate */ X init_m_level(); X init_t_level(); X X /* Init the store inventories`09`09`09*/ X store_init(); X X#ifndef MAC X /* On Mac, if -n is passed, no savefile is used */ X /* If -n is not passed, the calling routine will know savefile name, X hence, this code is not necessary */ X X /* Auto-restart of saved file */ X if (argv`5B0`5D != CNIL) X (void) strcpy (savefile, argv`5B0`5D); X else if ((p = getenv("MORIA_SAV")) != CNIL) X (void) strcpy(savefile, p); X else if ((p = getenv("HOME")) != CNIL) X#if defined(ATARIST_MWC) `7C`7C defined(ATARIST_TC) X (void) sprintf(savefile, "%s\\%s", p, MORIA_SAV); X#else X#ifdef VMS X (void) sprintf(savefile, "%s%s", p, MORIA_SAV); X#else X (void) sprintf(savefile, "%s/%s", p, MORIA_SAV); X#endif X#endif X else X (void) strcpy(savefile, MORIA_SAV); X#endif X X/* This restoration of a saved character may get ONLY the monster memory. In X this case, get_char returns false. It may also resurrect a dead character X (if you are the wizard). In this case, it returns true, but also sets the X parameter "generate" to true, as it does not recover any cave details. */ X X result = FALSE; X#ifdef MAC X if ((new_game == FALSE) && get_char(&generate)) X#else X if ((new_game == FALSE) && !access(savefile, 0) && get_char(&generate)) X#endif X result = TRUE; X X /* enter wizard mode before showing the character display, but must wait X until after get_char in case it was just a resurrection */ X if (to_be_wizard) X if (!enter_wiz_mode()) X exit_game(); X X if (result) X `7B X change_name(); X X /* could be restoring a dead character after a signal or HANGUP */ X if (py.misc.chp < 0) X`09death = TRUE; X `7D X else X `7B`09 /* Create character`09 */ X create_character(); X#ifdef MAC X birth_date = time ((time_t *)0); X#else X birth_date = time ((long *)0); X#endif X char_inven_init(); X py.flags.food = 7500; X py.flags.food_digested = 2; X if (class`5Bpy.misc.pclass`5D.spell == MAGE) X`09`7B`09 /* Magic realm */ X`09 clear_screen(); /* makes spell list easier to read */ X`09 calc_spells(A_INT); X`09 calc_mana(A_INT); X`09`7D X else if (class`5Bpy.misc.pclass`5D.spell == PRIEST) X`09`7B`09 /* Clerical realm*/ X`09 calc_spells(A_WIS); X`09 clear_screen(); /* force out the 'learn prayer' message */ X`09 calc_mana(A_WIS); X`09`7D X /* prevent `5Ec quit from entering score into scoreboard, X`09 and prevent signal from creating panic save until this point, X`09 all info needed for save file is now valid */ X character_generated = 1; X generate = TRUE; X `7D X X if (force_rogue_like) X rogue_like_commands = force_keys_to; X X magic_init(); X X /* Begin the game`09`09`09`09*/ X clear_screen(); X prt_stat_block(); X if (generate) X generate_cave(); X X /* Loop till dead, or exit`09`09`09*/ X while(!death) X `7B X dungeon();`09`09`09`09 /* Dungeon logic */ X X#ifndef MAC X /* check for eof here, see inkey() in io.c */ X /* eof can occur if the process gets a HANGUP signal */ X if (eof_flag) X`09`7B X`09 (void) strcpy(died_from, "(end of input: saved)"); X`09 if (!save_char()) X`09 `7B X`09 (void) strcpy(died_from, "unexpected eof"); X`09 `7D X`09 /* should not reach here, by if we do, this guarantees exit */ X`09 death = TRUE; X`09`7D X#endif X X if (!death) generate_cave();`09 /* New level`09*/ X `7D X X exit_game();`09`09/* Character gets buried. */ X /* should never reach here, but just in case */ X return (0); X`7D X X/* Init players with some belongings`09`09`09-RAK-`09*/ Xstatic void char_inven_init() X`7B X register int i, j; X inven_type inven_init; X X /* this is needed for bash to work right, it can't hurt anyway */ X for (i = 0; i < INVEN_ARRAY_SIZE; i++) X invcopy(&inventory`5Bi`5D, OBJ_NOTHING); X X for (i = 0; i < 5; i++) X `7B X j = player_init`5Bpy.misc.pclass`5D`5Bi`5D; X invcopy(&inven_init, j); X /* this makes it known2 and known1 */ X store_bought(&inven_init); X /* must set this bit to display tohit/todam for stiletto */ X if (inven_init.tval == TV_SWORD) X`09inven_init.ident `7C= ID_SHOW_HITDAM; X (void) inven_carry(&inven_init); X `7D X X /* wierd place for it, but why not? */ X for (i = 0; i < 32; i++) X spell_order`5Bi`5D = 99; X`7D X X X/* Initializes M_LEVEL array for use with PLACE_MONSTER`09-RAK-`09*/ Xstatic void init_m_level() X`7B X register int i, k; X X for (i = 0; i <= MAX_MONS_LEVEL; i++) X m_level`5Bi`5D = 0; X X k = MAX_CREATURES - WIN_MON_TOT; X for (i = 0; i < k; i++) X m_level`5Bc_list`5Bi`5D.level`5D++; X X for (i = 1; i <= MAX_MONS_LEVEL; i++) X#ifdef AMIGA /* fix a stupid MANX Aztec C 5.0 bug again */ X m_level`5Bi`5D = m_level`5Bi`5D + m_level`5Bi-1`5D; X#else X m_level`5Bi`5D += m_level`5Bi-1`5D; X#endif X`7D X X X/* Initializes T_LEVEL array for use with PLACE_OBJECT`09-RAK-`09*/ Xstatic void init_t_level() X`7B X register int i, l; X int tmp`5BMAX_OBJ_LEVEL+1`5D; X X for (i = 0; i <= MAX_OBJ_LEVEL; i++) X t_level`5Bi`5D = 0; X for (i = 0; i < MAX_DUNGEON_OBJ; i++) X t_level`5Bobject_list`5Bi`5D.level`5D++; X for (i = 1; i <= MAX_OBJ_LEVEL; i++) X#ifdef AMIGA /* fix a stupid MANX Aztec C 5.0 bug again */ X t_level`5Bi`5D = t_level`5Bi`5D + t_level`5Bi-1`5D; X#else X t_level`5Bi`5D += t_level`5Bi-1`5D; X#endif X X /* now produce an array with object indexes sorted by level, by using X the info in t_level, this is an O(n) sort! */ X /* this is not a stable sort, but that does not matter */ X for (i = 0; i <= MAX_OBJ_LEVEL; i++) X tmp`5Bi`5D = 1; X for (i = 0; i < MAX_DUNGEON_OBJ; i++) X `7B X l = object_list`5Bi`5D.level; X sorted_objects`5Bt_level`5Bl`5D - tmp`5Bl`5D`5D = i; X tmp`5Bl`5D++; X `7D X`7D X X X#if (COST_ADJ != 100) X/* Adjust prices of objects`09`09`09`09-RAK-`09*/ Xstatic void price_adjust() X`7B X register int i; X X /* round half-way cases up */ X for (i = 0; i < MAX_OBJECTS; i++) X object_list`5Bi`5D.cost = ((object_list`5Bi`5D.cost * COST_ADJ) + 50) / V 100; X`7D X#endif $ CALL UNPACK MAIN.C;1 1327695199 $ create 'f' X$ set verify X$ cc create.c /obj=create.obj X$ cc creature.c /obj=creature.obj X$ cc death.c /obj=death.obj X$ cc desc.c /obj=desc.obj X$ cc dungeon.c /obj=dungeon.obj X$ cc eat.c /obj=eat.obj X$ cc files.c /obj=files.obj X$ cc generate.c /obj=generate.obj X$ cc help.c /obj=help.obj X$ cc io.c /obj=io.obj X$ cc magic.c /obj=magic.obj X$ cc main.c /obj=main.obj X$ cc misc1.c /obj=misc1.obj X$ cc misc2.c /obj=misc2.obj X$ cc misc3.c /obj=misc3.obj X$ cc misc4.c /obj=misc4.obj X$ cc monsters.c /obj=monsters.obj X$ cc moria1.c /obj=moria1.obj X$ cc moria2.c /obj=moria2.obj X$ cc moria3.c /obj=moria3.obj X$ cc moria4.c /obj=moria4.obj X$ cc potions.c /obj=potions.obj X$ cc player.c /obj=player.obj X$ cc prayer.c /obj=prayer.obj X$ cc recall.c /obj=recall.obj X$ cc rnd.c /obj=rnd.obj X$ cc save.c /obj=save.obj X$ cc scrolls.c /obj=scrolls.obj X$ cc sets.c /obj=sets.obj X$ cc signals.c /obj=signals.obj X$ cc spells.c /obj=spells.obj X$ cc staffs.c /obj=staffs.obj X$ cc store1.c /obj=store1.obj X$ cc store2.c /obj=store2.obj X$ cc tables.c /obj=tables.obj +-+-+-+-+-+-+-+- END OF PART 27 +-+-+-+-+-+-+-+-