home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
games
/
volume7
/
nethack3
/
part20
< prev
next >
Wrap
Internet Message Format
|
1989-07-31
|
56KB
Path: uunet!zephyr.ens.tek.com!tektronix!tekgen!tekred!saab!billr
From: billr@saab.CNA.TEK.COM (Bill Randle)
Newsgroups: comp.sources.games
Subject: v07i075: NetHack3 - display oriented dungeons & dragons (Ver. 3.0), Part20/38
Message-ID: <4332@tekred.CNA.TEK.COM>
Date: 24 Jul 89 19:03:03 GMT
Sender: nobody@tekred.CNA.TEK.COM
Lines: 2375
Approved: billr@saab.CNA.TEK.COM
Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
Posting-number: Volume 7, Issue 75
Archive-name: NetHack3/Part20
#! /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 20 (of 38)."
# Contents: include/attrib.h src/lev_comp.y src/mklev.c
# Wrapped by billr@saab on Sun Jul 23 21:33:03 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'include/attrib.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'include/attrib.h'\"
else
echo shar: Extracting \"'include/attrib.h'\" \(786 characters\)
sed "s/^X//" >'include/attrib.h' <<'END_OF_FILE'
X/*
X * attrib.h - Header file for character class processing.
X *
X * Copyright 1988, M. Stephenson
X */
X/* NetHack may be freely redistributed. See license for details. */
X
X#ifndef ATTRIB_H
X#define ATTRIB_H
X
X#define A_STR 0
X#define A_INT 1
X#define A_WIS 2
X#define A_DEX 3
X#define A_CON 4
X#define A_CHA 5
X
X#define A_MAX 6 /* used in rn2() selection of attrib */
X
X#define ABASE(x) (u.acurr.a[x])
X#define ABON(x) (u.abon.a[x])
X#define ACURR(x) (schar) acurr(x)
X/* should be: */
X/* #define ACURR(x) (ABON(x) + ATEMP(x) + (u.umonnum == -1) ? ABASE(x) : MBASE(x)) */
X#define MCURR(x) (u.macurr.a[x])
X#define AMAX(x) (u.amax.a[x])
X#define MMAX(x) (u.mamax.a[x])
X
X#define ATEMP(x) (u.atemp.a[x])
X#define ATIME(x) (u.atime.a[x])
X
Xstruct attribs {
X
X schar a[A_MAX];
X};
X
X#endif /* ATTRIB_H /* */
END_OF_FILE
if test 786 -ne `wc -c <'include/attrib.h'`; then
echo shar: \"'include/attrib.h'\" unpacked with wrong size!
fi
# end of 'include/attrib.h'
fi
if test -f 'src/lev_comp.y' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/lev_comp.y'\"
else
echo shar: Extracting \"'src/lev_comp.y'\" \(23359 characters\)
sed "s/^X//" >'src/lev_comp.y' <<'END_OF_FILE'
X%{
X/* SCCS Id: @(#)lev_comp.c 3.0 89/07/02
X/* Copyright (c) 1989 by Jean-Christophe Collet */
X/* NetHack may be freely redistributed. See license for details. */
X
X/*
X * This file contains the Level Compiler code
X * It may handle special mazes & special room-levels
X */
X
X/* block some unused #defines to avoid overloading some cpp's */
X#define MONDATA_H
X#include "hack.h"
X#include "sp_lev.h"
X#include <fcntl.h>
X
X#ifdef AMIGA
Xchar *fgets();
X# define alloc malloc
X# undef fopen
X# undef printf
X# undef Printf
X# define Printf printf
X# define memset(addr,val,len) setmem(addr,len,val)
X#endif
X
X#ifdef MSDOS
X# undef exit
X#endif
X
X#define MAX_REGISTERS 10
X#define ERR (-1)
X
Xstruct reg {
X int x1, y1;
X int x2, y2;
X} current_region;
X
Xstruct coord {
X int x;
X int y;
X} current_coord;
X
Xstruct {
X char *name;
X short type;
X} trap_types[TRAPNUM-1] = {
X "monster", MONST_TRAP,
X "statue", STATUE_TRAP,
X "bear", BEAR_TRAP,
X "arrow", ARROW_TRAP,
X "dart", DART_TRAP,
X "trapdoor", TRAPDOOR,
X "teleport", TELEP_TRAP,
X "pit", PIT,
X "sleeping gas", SLP_GAS_TRAP,
X "magic", MGTRP,
X "board", SQBRD,
X "web", WEB,
X "spiked pit", SPIKED_PIT,
X "level teleport",LEVEL_TELEP,
X#ifdef SPELLS
X "anti magic", ANTI_MAGIC,
X#endif
X "rust", RUST_TRAP
X#ifdef POLYSELF
X , "polymorph", POLY_TRAP
X#endif
X#ifdef ARMY
X , "land mine", LANDMINE
X#endif
X };
X
Xstruct {
X char *name;
X int type;
X} room_types[SHOPBASE-1] = {
X /* for historical reasons, room types are not contiguous numbers */
X /* (type 1 is skipped) */
X "ordinary", OROOM,
X#ifdef THRONES
X "throne", COURT,
X#endif
X "swamp", SWAMP,
X "vault", VAULT,
X "beehive", BEEHIVE,
X "morgue", MORGUE,
X#ifdef ARMY
X "barracks", BARRACKS,
X#endif
X "zoo", ZOO,
X "temple", TEMPLE,
X "shop", SHOPBASE,
X};
X
Xshort db_dirs[4] = {
X DB_NORTH,
X DB_EAST,
X DB_SOUTH,
X DB_WEST
X};
X
X#ifdef ALTARS
Xstatic altar *tmpaltar[256];
X#endif /* ALTARS /**/
Xstatic lad *tmplad[256];
Xstatic dig *tmpdig[256];
Xstatic char *tmpmap[ROWNO];
Xstatic region *tmpreg[16];
Xstatic door *tmpdoor[256];
Xstatic trap *tmptrap[256];
Xstatic monster *tmpmonst[256];
Xstatic object *tmpobj[256];
Xstatic drawbridge *tmpdb[256];
Xstatic walk *tmpwalk[256];
Xstatic mazepart *tmppart[10];
Xstatic room *tmproom[MAXNROFROOMS];
Xstatic specialmaze maze;
X
Xstatic char olist[MAX_REGISTERS], mlist[MAX_REGISTERS];
Xstatic struct coord plist[MAX_REGISTERS];
Xstatic int n_olist = 0, n_mlist = 0, n_plist = 0;
X
Xunsigned int nreg = 0, ndoor = 0, ntrap = 0, nmons = 0, nobj = 0;
Xunsigned int ndb = 0, nwalk = 0, npart = 0, ndig = 0, nlad = 0;
X#ifdef ALTARS
Xunsigned int naltar = 0;
X#endif /* ALTARS /*/
X
Xunsigned int max_x_map, max_y_map;
X
Xextern int fatal_error;
Xextern char* fname;
X
Xboolean check_monster_char(), check_object_char();
Xvoid scan_map(), store_part(), write_maze();
X
X%}
X
X%union
X{
X int i;
X char* map;
X}
X
X
X%token <i> CHAR INTEGER
X%token <i> MAZE_ID LEVEL_ID GEOMETRY_ID
X%token <i> OBJECT_ID MONSTER_ID TRAP_ID DOOR_ID DRAWBRIDGE_ID MAZEWALK_ID
X%token <i> REGION_ID RANDOM_OBJECTS_ID RANDOM_MONSTERS_ID RANDOM_PLACES_ID
X%token <i> ALTAR_ID LADDER_ID NON_DIGGABLE_ID ROOM_ID
X%token <i> DOOR_STATE LIGHT_STATE
X%token <i> DIRECTION RANDOM_TYPE O_REGISTER M_REGISTER P_REGISTER A_REGISTER
X%token <i> ALIGNMENT LEFT_OR_RIGHT CENTER TOP_OR_BOT ALTAR_TYPE UP_OR_DOWN
X%token <i> ',' ':' '(' ')' '[' ']'
X%token <map> STRING MAP_ID
X%type <map> string maze_def m_name o_name
X%start file
X
X%%
Xfile : /* notthing */
X | levels ;
X
Xlevels : level
X | levels level ;
X
Xlevel : maze_level ;
X
Xmaze_level : maze_def regions
X {
X int fout, i;
X
X if (fatal_error > 0)
X fprintf(stderr,"%s : %d errors detected. No output created!\n", fname, fatal_error);
X else {
X fout = open($1, O_WRONLY | O_CREAT
X#ifdef MSDOS
X | O_BINARY
X#endif /* MSDOS */
X , 0644);
X if (fout < 0) {
X yyerror("Can't open output file!!");
X exit(1);
X }
X maze.numpart = npart;
X maze.parts = (mazepart**) alloc(sizeof(mazepart*)*npart);
X for(i=0;i<npart;i++)
X maze.parts[i] = tmppart[i];
X write_maze(fout, &maze);
X (void) close(fout);
X npart = 0;
X }
X }
X
Xmaze_def : MAZE_ID ':' string
X {
X $$ = $3;
X }
X
Xregions : aregion
X | regions aregion;
X
Xaregion : map_definition reg_init map_details
X {
X store_part();
X }
X
Xmap_definition : map_geometry MAP_ID
X {
X tmppart[npart] = (mazepart *) alloc(sizeof(mazepart));
X tmppart[npart]->halign = $<i>1 % 10;
X tmppart[npart]->valign = $<i>1 / 10;
X tmppart[npart]->nrobjects = 0;
X tmppart[npart]->nloc = 0;
X tmppart[npart]->nrmonst = 0;
X scan_map($2);
X }
X
Xmap_geometry : GEOMETRY_ID ':' h_justif ',' v_justif
X {
X $<i>$ = $<i>3 + ( $<i>5 * 10 );
X }
X
Xh_justif : LEFT_OR_RIGHT
X | CENTER ;
X
Xv_justif : TOP_OR_BOT
X | CENTER ;
X
Xreg_init : /* nothing */
X | reg_init init_reg ;
X
Xinit_reg : RANDOM_OBJECTS_ID ':' object_list
X {
X if (tmppart[npart]->nrobjects)
X yyerror("Object registers already initialized!");
X else {
X tmppart[npart]->robjects = (char *) alloc(n_olist);
X memcpy(tmppart[npart]->robjects, olist, n_olist);
X tmppart[npart]->nrobjects = n_olist;
X }
X }
X | RANDOM_PLACES_ID ':' place_list
X {
X if (tmppart[npart]->nloc)
X yyerror("Location registers already initialized!");
X else {
X register int i;
X tmppart[npart]->rloc_x = (char *) alloc(n_plist);
X tmppart[npart]->rloc_y = (char *) alloc(n_plist);
X for(i=0;i<n_plist;i++) {
X tmppart[npart]->rloc_x[i] = plist[i].x;
X tmppart[npart]->rloc_y[i] = plist[i].y;
X }
X tmppart[npart]->nloc = n_plist;
X }
X }
X | RANDOM_MONSTERS_ID ':' monster_list
X {
X if (tmppart[npart]->nrmonst)
X yyerror("Monster registers already initialized!");
X else {
X tmppart[npart]->rmonst = (char *) alloc(n_mlist);
X memcpy(tmppart[npart]->rmonst, mlist, n_mlist);
X tmppart[npart]->nrmonst = n_mlist;
X }
X }
X
Xobject_list : object
X {
X if (n_olist < MAX_REGISTERS)
X olist[n_olist++] = $<i>1;
X else
X yyerror("Object list too long!");
X }
X | object_list ',' object
X {
X if (n_olist < MAX_REGISTERS)
X olist[n_olist++] = $<i>3;
X else
X yyerror("Object list too long!");
X }
X
Xmonster_list : monster
X {
X if (n_mlist < MAX_REGISTERS)
X mlist[n_mlist++] = $<i>1;
X else
X yyerror("Monster list too long!");
X }
X | monster_list ',' monster
X {
X if (n_mlist < MAX_REGISTERS)
X mlist[n_mlist++] = $<i>3;
X else
X yyerror("Monster list too long!");
X }
X
Xplace_list : place
X {
X if (n_plist < MAX_REGISTERS)
X plist[n_plist++] = current_coord;
X else
X yyerror("Location list too long!");
X }
X | place_list ',' place
X {
X if (n_plist < MAX_REGISTERS)
X plist[n_plist++] = current_coord;
X else
X yyerror("Location list too long!");
X }
X
Xmap_details : /* nothing */
X | map_details map_detail ;
X
Xmap_detail : monster_detail
X | object_detail
X | door_detail
X | trap_detail
X | drawbridge_detail
X | region_detail
X | altar_detail
X | mazewalk_detail
X | ladder_detail
X | diggable_detail ;
X
Xmonster_detail : MONSTER_ID ':' monster_c ',' m_name ',' coordinate
X {
X int token;
X
X tmpmonst[nmons] = (monster *) alloc(sizeof(monster));
X tmpmonst[nmons]->x = current_coord.x;
X tmpmonst[nmons]->y = current_coord.y;
X tmpmonst[nmons]->class = $<i>3;
X if (!$5)
X tmpmonst[nmons]->id = -1;
X else {
X token = get_monster_id($5, (char) $<i>3);
X if (token == ERR) {
X yywarning("Illegal monster name! Making random monster.");
X tmpmonst[nmons]->id = -1;
X } else
X tmpmonst[nmons]->id = token;
X }
X nmons++;
X }
X
Xobject_detail : OBJECT_ID ':' object_c ',' o_name ',' coordinate
X {
X int token;
X
X tmpobj[nobj] = (object *) alloc(sizeof(object));
X tmpobj[nobj]->x = current_coord.x;
X tmpobj[nobj]->y = current_coord.y;
X tmpobj[nobj]->class = $<i>3;
X if (!$5)
X tmpobj[nobj]->id = -1;
X else {
X token = get_object_id($5, (char) $<i>3);
X if (token == ERR) {
X yywarning("Illegal object name! Making random object.");
X tmpobj[nobj]->id = -1;
X } else
X tmpobj[nobj]->id = token;
X }
X nobj++;
X }
X
Xdoor_detail : DOOR_ID ':' door_state ',' coordinate
X {
X tmpdoor[ndoor] = (door *) alloc(sizeof(door));
X tmpdoor[ndoor]->x = current_coord.x;
X tmpdoor[ndoor]->y = current_coord.y;
X tmpdoor[ndoor]->mask = $<i>3;
X ndoor++;
X }
X
Xtrap_detail : TRAP_ID ':' trap_name ',' coordinate
X {
X tmptrap[ntrap] = (trap *) alloc(sizeof(trap));
X tmptrap[ntrap]->x = current_coord.x;
X tmptrap[ntrap]->y = current_coord.y;
X tmptrap[ntrap]->type = $<i>3;
X ntrap++;
X }
X
Xdrawbridge_detail: DRAWBRIDGE_ID ':' coordinate ',' DIRECTION ',' door_state
X {
X tmpdb[ndb] = (drawbridge *) alloc(sizeof(drawbridge));
X tmpdb[ndb]->x = current_coord.x;
X tmpdb[ndb]->y = current_coord.y;
X tmpdb[ndb]->dir = db_dirs[$5];
X if ( $<i>7 == D_ISOPEN )
X tmpdb[ndb]->open = 1;
X else if ( $<i>7 == D_CLOSED )
X tmpdb[ndb]->open = 0;
X else
X yyerror("A drawbridge can only be open or closed!");
X ndb++;
X }
X
Xmazewalk_detail : MAZEWALK_ID ':' coordinate ',' DIRECTION
X {
X tmpwalk[nwalk] = (walk *) alloc(sizeof(walk));
X tmpwalk[nwalk]->x = current_coord.x;
X tmpwalk[nwalk]->y = current_coord.y;
X tmpwalk[nwalk]->dir = $5;
X nwalk++;
X }
X
Xladder_detail : LADDER_ID ':' coordinate ',' UP_OR_DOWN
X {
X tmplad[nlad] = (lad *) alloc(sizeof(lad));
X tmplad[nlad]->x = current_coord.x;
X tmplad[nlad]->y = current_coord.y;
X tmplad[nlad]->up = $<i>5;
X nlad++;
X }
X
Xdiggable_detail : NON_DIGGABLE_ID ':' region
X {
X tmpdig[ndig] = (dig *) alloc(sizeof(dig));
X tmpdig[ndig]->x1 = current_region.x1;
X tmpdig[ndig]->y1 = current_region.y1;
X tmpdig[ndig]->x2 = current_region.x2;
X tmpdig[ndig]->y2 = current_region.y2;
X ndig++;
X }
X
Xregion_detail : REGION_ID ':' region ',' light_state ',' room_type
X {
X tmpreg[nreg] = (region *) alloc(sizeof(region));
X tmpreg[nreg]->x1 = current_region.x1;
X tmpreg[nreg]->y1 = current_region.y1;
X tmpreg[nreg]->x2 = current_region.x2;
X tmpreg[nreg]->y2 = current_region.y2;
X tmpreg[nreg]->rlit = $<i>5;
X tmpreg[nreg]->rtype = $<i>7;
X nreg++;
X }
X
Xaltar_detail : ALTAR_ID ':' coordinate ',' alignment ',' altar_type
X {
X#ifndef ALTARS
X yywarning("Altars are not allowed in this version! Ignoring...");
X#else
X tmpaltar[naltar] = (altar *) alloc(sizeof(altar));
X tmpaltar[naltar]->x = current_coord.x;
X tmpaltar[naltar]->y = current_coord.y;
X tmpaltar[naltar]->align = $<i>5;
X tmpaltar[naltar]->shrine = $<i>7;
X naltar++;
X#endif /* ALTARS */
X }
X
Xmonster_c : monster
X | RANDOM_TYPE
X {
X $<i>$ = - MAX_REGISTERS - 1;
X }
X | m_register ;
X
Xobject_c : object
X | RANDOM_TYPE
X {
X $<i>$ = - MAX_REGISTERS - 1;
X }
X | o_register;
X
Xm_name : string
X | RANDOM_TYPE
X {
X $$ = (char *) 0;
X }
X
Xo_name : string
X | RANDOM_TYPE
X {
X $$ = (char *) 0;
X }
X
Xtrap_name : string
X {
X int token = get_trap_type($1);
X if (token == ERR)
X yyerror("unknown trap type!");
X $<i>$ = token;
X }
X | RANDOM_TYPE
X
Xroom_type : string
X {
X int token = get_room_type($1);
X if (token == ERR) {
X yywarning("Unknown room type! Making ordinary room...");
X $<i>$ = OROOM;
X } else
X $<i>$ = token;
X }
X | RANDOM_TYPE
X
Xcoordinate : coord
X | p_register
X | RANDOM_TYPE
X {
X current_coord.x = current_coord.y = -MAX_REGISTERS-1;
X }
X
Xdoor_state : DOOR_STATE
X | RANDOM_TYPE
X
Xlight_state : LIGHT_STATE
X | RANDOM_TYPE
X
Xalignment : ALIGNMENT
X | a_register
X | RANDOM_TYPE
X {
X $<i>$ = - MAX_REGISTERS - 1;
X }
X
Xaltar_type : ALTAR_TYPE
X | RANDOM_TYPE
X
Xp_register : P_REGISTER '[' INTEGER ']'
X {
X if ( $3 >= MAX_REGISTERS ) {
X yyerror("Register Index overflow!");
X } else {
X current_coord.x = current_coord.y = - $3 - 1;
X }
X }
X
Xo_register : O_REGISTER '[' INTEGER ']'
X {
X if ( $3 >= MAX_REGISTERS ) {
X yyerror("Register Index overflow!");
X } else {
X $<i>$ = - $3 - 1;
X }
X }
X
Xm_register : M_REGISTER '[' INTEGER ']'
X {
X if ( $3 >= MAX_REGISTERS ) {
X yyerror("Register Index overflow!");
X } else {
X $<i>$ = - $3 - 1;
X }
X }
X
Xa_register : A_REGISTER '[' INTEGER ']'
X {
X if ( $3 >= 3 ) {
X yyerror("Register Index overflow!");
X } else {
X $<i>$ = - $3 - 1;
X }
X }
X
Xplace : coord
X
Xmonster : CHAR
X {
X if (check_monster_char($1))
X $<i>$ = $1 ;
X else {
X yyerror("unknown monster class!");
X $<i>$ = ERR;
X }
X }
X
Xobject : CHAR
X {
X char c;
X
X c = $1;
X#ifndef SPELLS
X if ( c == '+') {
X c = '?';
X yywarning("Spellbooks are not allowed in this version! (converted into scroll)");
X }
X#endif
X if (check_object_char(c))
X $<i>$ = c;
X else {
X yyerror("Unknown char class!");
X $<i>$ = ERR;
X }
X }
Xstring : STRING
X
Xcoord : '(' INTEGER ',' INTEGER ')'
X {
X if ($2 < 0 || $2 > max_x_map ||
X $4 < 0 || $4 > max_y_map)
X yyerror("Coordinates out of map range!");
X current_coord.x = $2;
X current_coord.y = $4;
X }
X
Xregion : '(' INTEGER ',' INTEGER ',' INTEGER ',' INTEGER ')'
X {
X if ($2 < 0 || $2 > max_x_map ||
X $4 < 0 || $4 > max_y_map ||
X $6 < 0 || $6 > max_x_map ||
X $8 < 0 || $8 > max_y_map)
X yyerror("Region out of map range!");
X current_region.x1 = $2;
X current_region.y1 = $4;
X current_region.x2 = $6;
X current_region.y2 = $8;
X }
X
X
X%%
X
X/*
X * Find the type of a room in the table, knowing its name.
X */
X
Xint
Xget_room_type(s)
Xchar *s;
X{
X register int i;
X
X for(i=0; i < SHOPBASE -1; i++)
X if (!strcmp(s, room_types[i].name))
X return room_types[i].type;
X return ERR;
X}
X
X/*
X * Find the type of a trap in the table, knowing its name.
X */
X
Xint
Xget_trap_type(s)
Xchar *s;
X{
X register int i;
X
X for(i=0; i < TRAPNUM - 1; i++)
X if(!strcmp(s,trap_types[i].name))
X return(trap_types[i].type);
X return ERR;
X}
X
X/*
X * Find the index of a monster in the table, knowing its name.
X */
X
Xint
Xget_monster_id(s, c)
Xchar *s;
Xchar c;
X{
X register int i;
X
X for(i=0; mons[i].mname[0]; i++)
X if(!strncmp(s, mons[i].mname, strlen(mons[i].mname))
X && c == mons[i].mlet)
X return i;
X return ERR;
X}
X
X/*
X * Find the index of an object in the table, knowing its name.
X */
X
Xint
Xget_object_id(s, c)
Xchar *s;
Xchar c;
X{
X register int i;
X
X for(i=0; i<=NROFOBJECTS;i++)
X if(objects[i].oc_name &&
X !strncmp(s, objects[i].oc_name, strlen(objects[i].oc_name))
X && c == objects[i].oc_olet)
X return i;
X return ERR;
X}
X
X/*
X * Is the character 'c' a valid monster class ?
X */
X
Xboolean
Xcheck_monster_char(c)
Xchar c;
X{
X register int i;
X
X for(i=0; mons[i].mname[0]; i++)
X if( c == mons[i].mlet)
X return 1;
X return(0);
X}
X
X/*
X * Is the character 'c' a valid object class ?
X */
X
Xboolean
Xcheck_object_char(c)
Xchar c;
X{
X register int i;
X
X for(i=0; i<=NROFOBJECTS;i++)
X if( c == objects[i].oc_olet)
X return 1;
X return 0;
X}
X
X/*
X * Yep! LEX gives us the map in a raw mode.
X * Just analyze it here.
X */
X
Xvoid scan_map(map)
Xchar *map;
X{
X register int i, len;
X register char *s1, *s2;
X int max_len = 0;
X int max_hig = 0;
X
X /* First : find the max width of the map */
X
X s1 = map;
X while (s1 && *s1) {
X s2 = index(s1, '\n');
X if (s2) {
X if (s2-s1 > max_len)
X max_len = s2-s1;
X s1 = s2 + 1;
X } else {
X if (strlen(s1) > max_len)
X max_len = strlen(s1);
X s1 = (char *) 0;
X }
X }
X
X /* Then parse it now */
X
X while (map && *map) {
X tmpmap[max_hig] = (char *) alloc(max_len);
X s1 = index(map, '\n');
X if (s1) {
X len = s1 - map;
X s1++;
X } else {
X len = strlen(map);
X s1 = map + len;
X }
X for(i=0; i<len; i++)
X switch(map[i]) {
X case '-' : tmpmap[max_hig][i] = HWALL; break;
X case '|' : tmpmap[max_hig][i] = VWALL; break;
X case '+' : tmpmap[max_hig][i] = DOOR; break;
X case 'S' : tmpmap[max_hig][i] = SDOOR; break;
X case '{' :
X#ifdef FOUNTAINS
X tmpmap[max_hig][i] = FOUNTAIN;
X#else
X tmpmap[max_hig][i] = ROOM;
X yywarning("Fountains are not allowed in this version! Ignoring...");
X#endif
X break;
X case '\\' :
X#ifdef THRONES
X tmpmap[max_hig][i] = THRONE;
X#else
X tmpmap[max_hig][i] = ROOM;
X yywarning("Thrones are not allowed in this version! Ignoring...");
X#endif
X break;
X case 'K' :
X#ifdef SINKS
X tmpmap[max_hig][i] = SINK;
X#else
X tmpmap[max_hig][i] = ROOM;
X yywarning("Sinks are not allowed in this version! Ignoring...");
X#endif
X break;
X case '}' : tmpmap[max_hig][i] = MOAT; break;
X case '#' : tmpmap[max_hig][i] = CORR; break;
X default : tmpmap[max_hig][i] = ROOM; break;
X }
X while(i < max_len)
X tmpmap[max_hig][i++] = ROOM;
X map = s1;
X max_hig++;
X }
X
X /* Memorize boundaries */
X
X max_x_map = max_len - 1;
X max_y_map = max_hig - 1;
X
X /* Store the map into the mazepart structure */
X
X tmppart[npart]->xsize = max_len;
X tmppart[npart]->ysize = max_hig;
X tmppart[npart]->map = (char **) alloc(max_hig*sizeof(char *));
X for(i = 0; i< max_hig; i++)
X tmppart[npart]->map[i] = tmpmap[i];
X}
X
X/*
X * Here we want to store the maze part we just got.
X */
X
Xvoid
Xstore_part()
X{
X register int i;
X
X /* Ok, We got the whole part, now we store it. */
X
X /* The Regions */
X
X if(tmppart[npart]->nreg = nreg) {
X tmppart[npart]->regions = (region**)alloc(sizeof(region*) * nreg);
X for(i=0;i<nreg;i++)
X tmppart[npart]->regions[i] = tmpreg[i];
X }
X nreg = 0;
X
X /* the doors */
X
X if(tmppart[npart]->ndoor = ndoor) {
X tmppart[npart]->doors = (door **)alloc(sizeof(door *) * ndoor);
X for(i=0;i<ndoor;i++)
X tmppart[npart]->doors[i] = tmpdoor[i];
X }
X ndoor = 0;
X
X /* the traps */
X
X if(tmppart[npart]->ntraps = ntrap) {
X tmppart[npart]->traps = (trap **)alloc(sizeof(trap*) * ntrap);
X for(i=0;i<ntrap;i++)
X tmppart[npart]->traps[i] = tmptrap[i];
X }
X ntrap = 0;
X
X /* the monsters */
X
X if(tmppart[npart]->nmonster = nmons) {
X tmppart[npart]->monsters = (monster**)alloc(sizeof(monster*)*nmons);
X for(i=0;i<nmons;i++)
X tmppart[npart]->monsters[i] = tmpmonst[i];
X }
X nmons = 0;
X
X /* the objects */
X
X if(tmppart[npart]->nobjects = nobj) {
X tmppart[npart]->objects = (object**)alloc(sizeof(object*)*nobj);
X for(i=0;i<nobj;i++)
X tmppart[npart]->objects[i] = tmpobj[i];
X }
X nobj = 0;
X
X /* the drawbridges */
X
X if(tmppart[npart]->ndrawbridge = ndb) {
X tmppart[npart]->drawbridges = (drawbridge**)alloc(sizeof(drawbridge*)*ndb);
X for(i=0;i<ndb;i++)
X tmppart[npart]->drawbridges[i] = tmpdb[i];
X }
X ndb = 0;
X
X /* The walkmaze directives */
X
X if(tmppart[npart]->nwalk = nwalk) {
X tmppart[npart]->walks = (walk**)alloc(sizeof(walk*)*nwalk);
X for(i=0;i<nwalk;i++)
X tmppart[npart]->walks[i] = tmpwalk[i];
X }
X nwalk = 0;
X
X /* The non_diggable directives */
X
X if(tmppart[npart]->ndig = ndig) {
X tmppart[npart]->digs = (dig **) alloc(sizeof(dig*) * ndig);
X for(i=0;i<ndig;i++)
X tmppart[npart]->digs[i] = tmpdig[i];
X }
X ndig = 0;
X
X /* The ladders */
X
X if(tmppart[npart]->nlad = nlad) {
X tmppart[npart]->lads = (lad **) alloc(sizeof(lad*) * nlad);
X for(i=0;i<nlad;i++)
X tmppart[npart]->lads[i] = tmplad[i];
X }
X nlad = 0;
X#ifdef ALTARS
X /* The altars */
X
X if(tmppart[npart]->naltar = naltar) {
X tmppart[npart]->altars = (altar**)alloc(sizeof(altar*) * naltar);
X for(i=0;i<naltar;i++)
X tmppart[npart]->altars[i] = tmpaltar[i];
X }
X naltar = 0;
X#endif /* ALTARS /**/
X npart++;
X n_plist = n_mlist = n_olist = 0;
X}
X
X/*
X * Here we write the structure of the maze in the specified file (fd).
X * Also, we have to free the memory allocated via alloc()
X */
X
Xvoid
Xwrite_maze(fd, maze)
Xint fd;
Xspecialmaze *maze;
X{
X char c;
X short i,j;
X mazepart *pt;
X
X c = 2;
X (void) write(fd, &c, 1); /* Header for special mazes */
X (void) write(fd, &(maze->numpart), 1); /* Number of parts */
X for(i=0;i<maze->numpart;i++) {
X pt = maze->parts[i];
X
X /* First, write the map */
X
X (void) write(fd, &(pt->halign), 1);
X (void) write(fd, &(pt->valign), 1);
X (void) write(fd, &(pt->xsize), 1);
X (void) write(fd, &(pt->ysize), 1);
X for(j=0;j<pt->ysize;j++) {
X (void) write(fd, pt->map[j], pt->xsize);
X free(pt->map[j]);
X }
X free(pt->map);
X
X /* The random registers */
X (void) write(fd, &(pt->nrobjects), 1);
X if(pt->nrobjects) {
X (void) write(fd, pt->robjects, pt->nrobjects);
X free(pt->robjects);
X }
X (void) write(fd, &(pt->nloc), 1);
X if(pt->nloc) {
X (void) write(fd,pt->rloc_x, pt->nloc);
X (void) write(fd,pt->rloc_y, pt->nloc);
X free(pt->rloc_x);
X free(pt->rloc_y);
X }
X (void) write(fd,&(pt->nrmonst), 1);
X if(pt->nrmonst) {
X (void) write(fd, pt->rmonst, pt->nrmonst);
X free(pt->rmonst);
X }
X
X /* subrooms */
X (void) write(fd, &(pt->nreg), 1);
X for(j=0;j<pt->nreg;j++) {
X (void) write(fd,(genericptr_t) pt->regions[j], sizeof(region));
X free(pt->regions[j]);
X }
X if(pt->nreg > 0)
X free(pt->regions);
X
X /* the doors */
X (void) write(fd,&(pt->ndoor),1);
X for(j=0;j<pt->ndoor;j++) {
X (void) write(fd,(genericptr_t) pt->doors[j], sizeof(door));
X free(pt->doors[j]);
X }
X if (pt->ndoor > 0)
X free(pt->doors);
X
X /* The traps */
X (void) write(fd,&(pt->ntraps), 1);
X for(j=0;j<pt->ntraps;j++) {
X (void) write(fd,(genericptr_t) pt->traps[j], sizeof(trap));
X free(pt->traps[j]);
X }
X if (pt->ntraps)
X free(pt->traps);
X
X /* The monsters */
X (void) write(fd, &(pt->nmonster), 1);
X for(j=0;j<pt->nmonster;j++) {
X (void) write(fd,(genericptr_t) pt->monsters[j], sizeof(monster));
X free(pt->monsters[j]);
X }
X if (pt->nmonster > 0)
X free(pt->monsters);
X
X /* The objects */
X (void) write(fd, &(pt->nobjects), 1);
X for(j=0;j<pt->nobjects;j++) {
X (void) write(fd,(genericptr_t) pt->objects[j], sizeof(object));
X free(pt->objects[j]);
X }
X if(pt->nobjects > 0)
X free(pt->objects);
X
X /* The drawbridges */
X (void) write(fd, &(pt->ndrawbridge),1);
X for(j=0;j<pt->ndrawbridge;j++) {
X (void) write(fd,(genericptr_t) pt->drawbridges[j], sizeof(drawbridge));
X free(pt->drawbridges[j]);
X }
X if(pt->ndrawbridge > 0)
X free(pt->drawbridges);
X
X /* The mazewalk directives */
X (void) write(fd, &(pt->nwalk), 1);
X for(j=0; j<pt->nwalk; j++) {
X (void) write(fd,(genericptr_t) pt->walks[j], sizeof(walk));
X free(pt->walks[j]);
X }
X if (pt->nwalk > 0)
X free(pt->walks);
X
X /* The non_diggable directives */
X (void) write(fd, &(pt->ndig), 1);
X for(j=0;j<pt->ndig;j++) {
X (void) write(fd,(genericptr_t) pt->digs[j], sizeof(dig));
X free(pt->digs[j]);
X }
X if (pt->ndig > 0)
X free(pt->digs);
X
X /* The ladders */
X (void) write(fd, &(pt->nlad), 1);
X for(j=0;j<pt->nlad;j++) {
X (void) write(fd,(genericptr_t) pt->lads[j], sizeof(lad));
X free(pt->lads[j]);
X }
X if (pt->nlad > 0)
X free(pt->lads);
X#ifdef ALTARS
X /* The altars */
X (void) write(fd, &(pt->naltar), 1);
X for(j=0;j<pt->naltar;j++) {
X (void) write(fd,(genericptr_t) pt->altars[j], sizeof(altar));
X free(pt->altars[j]);
X }
X if (pt->naltar > 0)
X free(pt->altars);
X#endif /* ALTARS /**/
X free(pt);
X }
X}
END_OF_FILE
if test 23359 -ne `wc -c <'src/lev_comp.y'`; then
echo shar: \"'src/lev_comp.y'\" unpacked with wrong size!
fi
# end of 'src/lev_comp.y'
fi
if test -f 'src/mklev.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/mklev.c'\"
else
echo shar: Extracting \"'src/mklev.c'\" \(27014 characters\)
sed "s/^X//" >'src/mklev.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)mklev.c 3.0 88/11/24
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed. See license for details. */
X
X#include "hack.h"
X
X/* for UNIX, Rand #def'd to (long)lrand48() or (long)random() */
X/* croom->lx etc are schar (width <= int), so % arith ensures that */
X/* conversion of result to int is reasonable */
X
X#ifdef SINKS
Xstatic void mksink();
X#endif
X#ifdef ALTARS
Xstatic void mkaltar();
X#endif
X
Xint
Xsomex(croom)
Xregister struct mkroom *croom;
X{
X return rn2(croom->hx-croom->lx+1) + croom->lx;
X}
X
Xint
Xsomey(croom)
Xregister struct mkroom *croom;
X{
X return rn2(croom->hy-croom->ly+1) + croom->ly;
X}
X
X#define XLIM 4 /* define minimum required space around a room */
X#define YLIM 3
Xboolean secret; /* TRUE while making a vault: increase [XY]LIM */
Xstruct rm zerorm;
Xschar nxcor;
Xboolean goldseen;
X
X/* Definitions used by makerooms() and addrs() */
X#define MAXRS 50 /* max lth of temp rectangle table - arbitrary */
Xstruct rectangle {
X xchar rlx,rly,rhx,rhy;
X} rs[MAXRS+1];
Xint rscnt,rsmax; /* 0..rscnt-1: currently under consideration */
X /* rscnt..rsmax: discarded */
X
Xstatic void
Xaddrsx(lx,ly,hx,hy,discarded)
Xregister int lx,ly,hx,hy;
Xboolean discarded; /* piece of a discarded area */
X{
X register struct rectangle *rsp;
X
X /* check inclusions */
X for(rsp = rs; rsp < &rs[rsmax]; rsp++) {
X if(lx >= rsp->rlx && hx <= rsp->rhx &&
X ly >= rsp->rly && hy <= rsp->rhy)
X return;
X }
X
X /* make a new entry */
X if(rsmax >= MAXRS) {
X#ifdef WIZARD
X if(wizard) pline("MAXRS may be too small.");
X#endif
X return;
X }
X rsmax++;
X if(!discarded) {
X *rsp = rs[rscnt];
X rsp = &rs[rscnt];
X rscnt++;
X }
X rsp->rlx = lx;
X rsp->rly = ly;
X rsp->rhx = hx;
X rsp->rhy = hy;
X}
X
Xstatic void
Xaddrs(lowx,lowy,hix,hiy)
Xregister int lowx,lowy,hix,hiy;
X{
X register struct rectangle *rsp;
X register int lx,ly,hx,hy,xlim,ylim;
X boolean discarded;
X
X xlim = XLIM + secret;
X ylim = YLIM + secret;
X
X /* walk down since rscnt and rsmax change */
X for(rsp = &rs[rsmax-1]; rsp >= rs; rsp--) {
X
X if((lx = rsp->rlx) > hix || (ly = rsp->rly) > hiy ||
X (hx = rsp->rhx) < lowx || (hy = rsp->rhy) < lowy)
X continue;
X if((discarded = (rsp >= &rs[rscnt]))) {
X *rsp = rs[--rsmax];
X } else {
X rsmax--;
X rscnt--;
X *rsp = rs[rscnt];
X if(rscnt != rsmax)
X rs[rscnt] = rs[rsmax];
X }
X if(lowy - ly > 2*ylim + 4)
X addrsx(lx,ly,hx,lowy-2,discarded);
X if(lowx - lx > 2*xlim + 4)
X addrsx(lx,ly,lowx-2,hy,discarded);
X if(hy - hiy > 2*ylim + 4)
X addrsx(lx,hiy+2,hx,hy,discarded);
X if(hx - hix > 2*xlim + 4)
X addrsx(hix+2,ly,hx,hy,discarded);
X }
X}
X
Xstatic int
Xcomp(x,y)
Xregister struct mkroom *x,*y;
X{
X if(x->lx < y->lx) return(-1);
X return(x->lx > y->lx);
X}
X
Xstatic void
Xfinddpos(cc, xl,yl,xh,yh)
Xcoord *cc;
Xxchar xl,yl,xh,yh;
X{
X register xchar x, y;
X
X x = (xl == xh) ? xl : (xl + rn2(xh-xl+1));
X y = (yl == yh) ? yl : (yl + rn2(yh-yl+1));
X if(okdoor(x, y))
X goto gotit;
X
X for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
X if(okdoor(x, y))
X goto gotit;
X
X for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
X if(IS_DOOR(levl[x][y].typ) || levl[x][y].typ == SDOOR)
X goto gotit;
X /* cannot find something reasonable -- strange */
X x = xl;
X y = yh;
Xgotit:
X cc->x = x;
X cc->y = y;
X return;
X}
X
X/* Only called from makerooms() and makebigroom() */
Xstatic int
Xmaker(lowx,ddx,lowy,ddy,lit)
Xschar lowx,ddx,lowy,ddy;
Xboolean lit;
X{
X register struct mkroom *croom;
X register int x, y, hix = lowx+ddx, hiy = lowy+ddy;
X register int xlim = XLIM + secret, ylim = YLIM + secret;
X
X if(nroom >= MAXNROFROOMS) return(0);
X if(lowx < XLIM) lowx = XLIM;
X if(lowy < YLIM) lowy = YLIM;
X if(hix > COLNO-XLIM-1) hix = COLNO-XLIM-1;
X if(hiy > ROWNO-YLIM-1) hiy = ROWNO-YLIM-1;
Xchk:
X if(hix <= lowx || hiy <= lowy) return(0);
X
X /* check area around room (and make room smaller if necessary) */
X for(x = lowx - xlim; x <= hix + xlim; x++) {
X for(y = lowy - ylim; y <= hiy + ylim; y++) {
X if(levl[x][y].typ) {
X#ifdef WIZARD
X if(wizard && !secret)
X pline("Strange area [%d,%d] in maker().",x,y);
X#endif
X if(!rn2(3)) return(0);
X if(x < lowx)
X lowx = x+xlim+1;
X else
X hix = x-xlim-1;
X if(y < lowy)
X lowy = y+ylim+1;
X else
X hiy = y-ylim-1;
X goto chk;
X }
X }
X }
X
X croom = &rooms[nroom];
X
X /* on low levels the room is lit (usually) */
X /* secret vaults are always lit */
X /* some other rooms may require lighting */
X if((rnd(dlevel) < 10 && rn2(77)) || secret || lit) {
X for(x = lowx-1; x <= hix+1; x++)
X for(y = lowy-1; y <= hiy+1; y++)
X levl[x][y].lit = 1;
X croom->rlit = 1;
X } else
X croom->rlit = 0;
X croom->lx = lowx;
X croom->hx = hix;
X croom->ly = lowy;
X croom->hy = hiy;
X croom->rtype = OROOM;
X croom->doorct = 0;
X /* if we're not making a vault, doorindex will still be 0
X * if we are, we'll have problems adding niches to the previous room
X * unless fdoor is at least doorindex
X */
X croom->fdoor = doorindex;
X
X for(x = lowx-1; x <= hix+1; x++)
X for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) {
X levl[x][y].typ = HWALL;
X levl[x][y].scrsym = HWALL_SYM;
X }
X for(x = lowx-1; x <= hix+1; x += (hix-lowx+2))
X for(y = lowy; y <= hiy; y++) {
X levl[x][y].typ = VWALL;
X levl[x][y].scrsym = VWALL_SYM;
X }
X for(x = lowx; x <= hix; x++)
X for(y = lowy; y <= hiy; y++) {
X levl[x][y].typ = ROOM;
X levl[x][y].scrsym = ROOM_SYM;
X }
X levl[lowx-1][lowy-1].typ = TLCORNER;
X levl[hix+1][lowy-1].typ = TRCORNER;
X levl[lowx-1][hiy+1].typ = BLCORNER;
X levl[hix+1][hiy+1].typ = BRCORNER;
X levl[lowx-1][lowy-1].scrsym = TLCORN_SYM;
X levl[hix+1][lowy-1].scrsym = TRCORN_SYM;
X levl[lowx-1][hiy+1].scrsym = BLCORN_SYM;
X levl[hix+1][hiy+1].scrsym = BRCORN_SYM;
X
X smeq[nroom] = nroom;
X croom++;
X croom->hx = -1;
X nroom++;
X return(1);
X}
X
Xstatic int
Xmakerooms() {
Xregister struct rectangle *rsp;
Xregister int lx, ly, hx, hy, lowx, lowy, hix, hiy, dx, dy;
Xint tryct = 0, xlim, ylim;
X
X /* init */
X xlim = XLIM + secret;
X ylim = YLIM + secret;
X if(nroom == 0) {
X rsp = rs;
X rsp->rlx = rsp->rly = 0;
X rsp->rhx = COLNO-1;
X rsp->rhy = ROWNO-1;
X rsmax = 1;
X }
X rscnt = rsmax;
X
X /* make rooms until satisfied */
X while(rscnt > 0 && nroom < MAXNROFROOMS-1) {
X if(!secret && nroom > (MAXNROFROOMS/4) &&
X !rn2((MAXNROFROOMS-nroom)*(MAXNROFROOMS-nroom)))
X return 0;
X
X /* pick a rectangle */
X rsp = &rs[rn2(rscnt)];
X hx = rsp->rhx;
X hy = rsp->rhy;
X lx = rsp->rlx;
X ly = rsp->rly;
X
X /* find size of room */
X if(secret)
X dx = dy = 1;
X else {
X dx = 2 + rn2((hx-lx-8 > 20) ? 12 : 8);
X dy = 2 + rn2(4);
X if(dx*dy > 50)
X dy = 50/dx;
X }
X
X /* look whether our room will fit */
X if(hx-lx < dx + (dx>>1) + 2*xlim ||
X hy-ly < dy + dy/3 + 2*ylim) {
X /* no, too small */
X /* maybe we throw this area out */
X if(secret || !rn2(MAXNROFROOMS+1-nroom-tryct)) {
X rscnt--;
X rs[rsmax] = *rsp;
X *rsp = rs[rscnt];
X rs[rscnt] = rs[rsmax];
X tryct = 0;
X } else
X tryct++;
X continue;
X }
X
X lowx = lx + xlim + rn2(hx - lx - dx - 2*xlim + 1);
X lowy = ly + ylim + rn2(hy - ly - dy - 2*ylim + 1);
X hix = lowx + dx;
X hiy = lowy + dy;
X
X if(maker(lowx, dx, lowy, dy, FALSE)) {
X if(secret) return(1);
X addrs(lowx-1, lowy-1, hix+1, hiy+1);
X tryct = 0;
X } else
X if(tryct++ > 100)
X break;
X }
X return(0); /* failed to make vault - very strange */
X}
X
Xstatic void
Xjoin(a,b)
Xregister int a, b;
X{
X coord cc,tt;
X register int tx, ty, xx, yy;
X register struct rm *crm;
X register struct mkroom *croom, *troom;
X register int dx, dy, dix, diy, cct;
X
X croom = &rooms[a];
X troom = &rooms[b];
X
X /* find positions cc and tt for doors in croom and troom
X and direction for a corridor between them */
X
X if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return;
X if(troom->lx > croom->hx) {
X dx = 1;
X dy = 0;
X xx = croom->hx+1;
X tx = troom->lx-1;
X finddpos(&cc, xx, croom->ly, xx, croom->hy);
X finddpos(&tt, tx, troom->ly, tx, troom->hy);
X } else if(troom->hy < croom->ly) {
X dy = -1;
X dx = 0;
X yy = croom->ly-1;
X finddpos(&cc, croom->lx, yy, croom->hx, yy);
X ty = troom->hy+1;
X finddpos(&tt, troom->lx, ty, troom->hx, ty);
X } else if(troom->hx < croom->lx) {
X dx = -1;
X dy = 0;
X xx = croom->lx-1;
X tx = troom->hx+1;
X finddpos(&cc, xx, croom->ly, xx, croom->hy);
X finddpos(&tt, tx, troom->ly, tx, troom->hy);
X } else {
X dy = 1;
X dx = 0;
X yy = croom->hy+1;
X ty = troom->ly-1;
X finddpos(&cc, croom->lx, yy, croom->hx, yy);
X finddpos(&tt, troom->lx, ty, troom->hx, ty);
X }
X xx = cc.x;
X yy = cc.y;
X tx = tt.x - dx;
X ty = tt.y - dy;
X if(nxcor && levl[xx+dx][yy+dy].typ)
X return;
X dodoor(xx,yy,croom);
X
X cct = 0;
X while(xx != tx || yy != ty) {
X xx += dx;
X yy += dy;
X
X /* loop: dig corridor at [xx,yy] and find new [xx,yy] */
X if(cct++ > 500 || (nxcor && !rn2(35)))
X return;
X
X if(xx == COLNO-1 || xx == 0 || yy == 0 || yy == ROWNO-1)
X return; /* impossible */
X
X crm = &levl[xx][yy];
X if(!(crm->typ)) {
X if(rn2(100)) {
X crm->typ = CORR;
X crm->scrsym = CORR_SYM;
X if(nxcor && !rn2(50))
X (void) mksobj_at(BOULDER, xx, yy);
X } else {
X crm->typ = SCORR;
X crm->scrsym = STONE_SYM;
X }
X } else
X if(crm->typ != CORR && crm->typ != SCORR) {
X /* strange ... */
X return;
X }
X
X /* find next corridor position */
X dix = abs(xx-tx);
X diy = abs(yy-ty);
X
X /* do we have to change direction ? */
X if(dy && dix > diy) {
X register int ddx = (xx > tx) ? -1 : 1;
X
X crm = &levl[xx+ddx][yy];
X if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) {
X dx = ddx;
X dy = 0;
X continue;
X }
X } else if(dx && diy > dix) {
X register int ddy = (yy > ty) ? -1 : 1;
X
X crm = &levl[xx][yy+ddy];
X if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) {
X dy = ddy;
X dx = 0;
X continue;
X }
X }
X
X /* continue straight on? */
X crm = &levl[xx+dx][yy+dy];
X if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
X continue;
X
X /* no, what must we do now?? */
X if(dx) {
X dx = 0;
X dy = (ty < yy) ? -1 : 1;
X crm = &levl[xx+dx][yy+dy];
X if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
X continue;
X dy = -dy;
X continue;
X } else {
X dy = 0;
X dx = (tx < xx) ? -1 : 1;
X crm = &levl[xx+dx][yy+dy];
X if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
X continue;
X dx = -dx;
X continue;
X }
X }
X
X /* we succeeded in digging the corridor */
X dodoor(tt.x, tt.y, troom);
X
X if(smeq[a] < smeq[b])
X smeq[b] = smeq[a];
X else
X smeq[a] = smeq[b];
X}
X
Xstatic void
Xmakecorridors() {
X register int a, b;
X
X nxcor = 0;
X for(a = 0; a < nroom-1; a++)
X join(a, a+1);
X for(a = 0; a < nroom-2; a++)
X if(smeq[a] != smeq[a+2])
X join(a, a+2);
X for(a = 0; a < nroom; a++)
X for(b = 0; b < nroom; b++)
X if(smeq[a] != smeq[b])
X join(a, b);
X if(nroom > 2)
X for(nxcor = rn2(nroom) + 4; nxcor; nxcor--) {
X a = rn2(nroom);
X b = rn2(nroom-2);
X if(b >= a) b += 2;
X join(a, b);
X }
X}
X
Xstatic void
Xdosdoor(x,y,aroom,type)
Xregister int x, y;
Xregister struct mkroom *aroom;
Xregister int type;
X{
X register struct mkroom *broom;
X register int tmp;
X boolean shdoor = in_shop(x, y);
X
X if(!IS_WALL(levl[x][y].typ)) /* avoid SDOORs with DOOR_SYM as scrsym */
X type = DOOR;
X levl[x][y].typ = type;
X if(type == DOOR) {
X levl[x][y].scrsym = DOOR_SYM;
X if(!rn2(3)) { /* is it a locked door, closed, or a doorway? */
X if(!rn2(5))
X levl[x][y].doormask = D_ISOPEN;
X else if(!rn2(4))
X levl[x][y].doormask = D_LOCKED;
X else
X levl[x][y].doormask = D_CLOSED;
X
X if (levl[x][y].doormask != D_ISOPEN && !shdoor && !rn2(25))
X levl[x][y].doormask |= D_TRAPPED;
X } else {
X if(shdoor) levl[x][y].doormask = D_ISOPEN;
X else levl[x][y].doormask = D_NODOOR;
X }
X } else { /* SDOOR */
X if(shdoor || !rn2(5)) levl[x][y].doormask = D_LOCKED;
X else levl[x][y].doormask = D_CLOSED;
X
X if(!shdoor && !rn2(20)) levl[x][y].doormask |= D_TRAPPED;
X }
X aroom->doorct++;
X broom = aroom+1;
X if(broom->hx < 0) tmp = doorindex; else
X for(tmp = doorindex; tmp > broom->fdoor; tmp--)
X doors[tmp] = doors[tmp-1];
X doorindex++;
X doors[tmp].x = x;
X doors[tmp].y = y;
X for( ; broom->hx >= 0; broom++) broom->fdoor++;
X}
X
Xstatic boolean
Xplace_niche(aroom,dy,xx,yy)
Xregister struct mkroom *aroom;
Xint *dy, *xx, *yy;
X{
X coord dd;
X
X if(rn2(2)) {
X *dy = 1;
X finddpos(&dd, aroom->lx, aroom->hy+1, aroom->hx, aroom->hy+1);
X } else {
X *dy = -1;
X finddpos(&dd, aroom->lx, aroom->ly-1, aroom->hx, aroom->ly-1);
X }
X *xx = dd.x;
X *yy = dd.y;
X return(levl[*xx][(*yy)+(*dy)].typ == STONE);
X}
X
X#ifdef ORACLE
Xboolean
Xplace_oracle(aroom,dy,xx,yy)
Xregister struct mkroom *aroom;
Xint *dy, *xx, *yy;
X{
X if(!place_niche(aroom,dy,xx,yy)) return FALSE;
X
X dosdoor(*xx,*yy,aroom,DOOR);
X levl[*xx][*yy].doormask = D_NODOOR;
X return TRUE;
X}
X#endif
X
X/* there should be one of these per trap */
Xconst char *engravings[] = { "", "", "", "", "", "",
X "?la? ?as ?er?", "ad ae?ar um",
X "", "", "", "" ,""
X , "", "ad ae?ar um"
X#ifdef SPELLS
X ,""
X#endif
X ,""
X#ifdef POLYSELF
X ,""
X#endif
X ,""
X };
X
Xstatic void
Xmakeniche(trap_type)
Xint trap_type;
X{
X register struct mkroom *aroom;
X register struct rm *rm;
X register int vct = 8;
X int dy, xx, yy;
X register struct trap *ttmp;
X
X if(doorindex < DOORMAX)
X while(vct--) {
X aroom = &rooms[rn2(nroom)];
X if(aroom->rtype != OROOM) continue; /* not an ordinary room */
X if(aroom->doorct == 1 && rn2(5)) continue;
X if(!place_niche(aroom,&dy,&xx,&yy)) continue;
X
X rm = &levl[xx][yy+dy];
X if(trap_type || !rn2(4)) {
X
X rm->typ = SCORR;
X rm->scrsym = STONE_SYM;
X if(trap_type) {
X ttmp = maketrap(xx, yy+dy, trap_type);
X ttmp->once = 1;
X if (strlen(engravings[trap_type]) > 0)
X make_engr_at(xx, yy-dy, engravings[trap_type]);
X }
X dosdoor(xx, yy, aroom, SDOOR);
X } else {
X rm->typ = CORR;
X rm->scrsym = CORR_SYM;
X if(rn2(7))
X dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR);
X else {
X (void) mksobj_at(SCR_TELEPORTATION, xx, yy+dy);
X if(!rn2(3)) (void) mkobj_at(0, xx, yy+dy);
X }
X }
X return;
X }
X}
X
Xstatic void
Xmake_niches()
X{
X register int ct = rnd((nroom>>1) + 1);
X boolean ltptr = TRUE,
X vamp = TRUE;
X
X while(ct--) {
X
X if(dlevel > 15 && !rn2(6) && ltptr) {
X
X ltptr = FALSE;
X makeniche(LEVEL_TELEP);
X } else if (dlevel > 5 && dlevel < 25
X && !rn2(6) && vamp) {
X
X vamp = FALSE;
X makeniche(TRAPDOOR);
X } else makeniche(NO_TRAP);
X }
X}
X
Xstatic void
Xmakebigroom()
X{
X register int x,y,n;
X register struct mkroom *croom;
X register struct monst *tmonst;
X
X /* make biggest possible room; make sure it's lit */
X (void) maker(XLIM, COLNO - 2*XLIM - 1, YLIM, ROWNO - 2*YLIM - 1, TRUE);
X croom = &rooms[0];
X
X /* add extra monsters and goodies */
X n = 10 + rn2(15);
X while (n--) {
X x = somex(croom);
X y = somey(croom);
X tmonst = makemon((struct permonst *) 0,x,y);
X if (tmonst && tmonst->data==&mons[PM_GIANT_SPIDER])
X (void) maketrap(x,y,WEB);
X if (tmonst && rn2(2))
X tmonst->msleep = 1;
X }
X n = 6 + rn2(10);
X while (n--)
X (void) mkobj_at(0,somex(croom),somey(croom));
X}
X
Xstatic void
Xmakevtele()
X{
X makeniche(TELEP_TRAP);
X}
X
X#define rntwixt(L1,L2) rn1((L2)-(L1),L1)
X
Xstatic void
Xinit_levels()
X{
X#if defined(STRONGHOLD) && defined(MUSIC)
X register int x;
X#endif
X
X#ifdef LINT /* handle constant in conditional context */
X medusa_level = 0;
X#else
X medusa_level = rn1(3, HELLLEVEL - 5);
X#endif /* LINT */
X#ifdef STRONGHOLD
X stronghold_level = rn1(5, medusa_level)+1;
X# ifdef MUSIC
X for (x=0; x<5; x++)
X tune[x] = 'A' + rn2(7);
X tune[5] = 0;
X# endif
X /* The tower will be on 3 levels */
X tower_level = rntwixt(stronghold_level, MAXLEVEL-2)+1;
X /* We don't want the wizard in Vlad's tower */
X do
X wiz_level = rntwixt(stronghold_level, MAXLEVEL)+1;
X while (wiz_level >= tower_level && wiz_level <= tower_level + 2);
X#else
X wiz_level = rntwixt(medusa_level, MAXLEVEL)+1;
X#endif /* STRONGHOLD /**/
X#ifdef WIZARD
X if (!rn2(15) || wizard)
X#else
X if (!rn2(15))
X#endif
X /* between the middle of the dungeon and the medusa level */
X bigroom_level = rntwixt(HELLLEVEL>>1, medusa_level);
X#ifdef REINCARNATION
X# ifdef WIZARD
X if (!rn2(3) || wizard)
X# else
X if (!rn2(3))
X# endif
X rogue_level = rn1(5,10);
X#endif
X#ifdef ORACLE
X oracle_level = rn1(4,5);
X#endif
X}
X
X#undef rntwixt
X
Xstatic void
Xmakelevel() {
X register struct mkroom *croom, *troom;
X register unsigned int tryct;
X register int x,y;
X struct monst *tmonst; /* always put a web with a spider */
X
X nroom = 0;
X doorindex = 0;
X rooms[0].hx = -1; /* in case we are in a maze */
X
X for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++)
X levl[x][y] = zerorm;
X
X oinit(); /* assign level dependent obj probabilities */
X fountsound = 0;
X sinksound = 0;
X
X if (wiz_level == 0)
X init_levels();
X if (
X#ifndef STRONGHOLD
X Inhell
X#else
X dlevel >= stronghold_level || dlevel < 0
X#endif
X || (dlevel > medusa_level && rn2(5))
X ) {
X makemaz();
X return;
X }
X
X /* construct the rooms */
X nroom = 0;
X secret = FALSE;
X
X#ifdef REINCARNATION
X if (dlevel == rogue_level) {
X makeroguerooms();
X makerogueghost();
X } else
X#endif
X if (dlevel == bigroom_level)
X makebigroom();
X else
X (void) makerooms();
X
X /* construct stairs (up and down in different rooms if possible) */
X croom = &rooms[rn2(nroom)];
X xdnstair = somex(croom);
X ydnstair = somey(croom);
X levl[xdnstair][ydnstair].scrsym = DN_SYM;
X levl[xdnstair][ydnstair].typ = STAIRS;
X#ifdef MEDUSA
X if (dlevel == medusa_level) {
X struct monst *mtmp;
X
X if (mtmp = makemon(&mons[PM_MEDUSA], xdnstair, ydnstair))
X mtmp->msleep = 1;
X for (tryct = rn1(1,3); tryct; tryct--) {
X x = somex(croom); y = somey(croom);
X if (goodpos(x,y))
X (void) mk_tt_statue(x, y);
X }
X }
X#endif
X if(nroom > 1) {
X troom = croom;
X croom = &rooms[rn2(nroom-1)];
X if(croom >= troom) croom++;
X }
X xupstair = somex(croom); /* %% < and > might be in the same place */
X yupstair = somey(croom);
X levl[xupstair][yupstair].scrsym = UP_SYM;
X levl[xupstair][yupstair].typ = STAIRS;
X#ifdef STRONGHOLD
X xdnladder = ydnladder = xupladder = yupladder = 0;
X#endif
X is_maze_lev = FALSE;
X
X#ifdef SYSV
X qsort((genericptr_t) rooms, (unsigned)nroom, sizeof(struct mkroom), comp);
X#else
X qsort((genericptr_t) rooms, nroom, sizeof(struct mkroom), comp);
X#endif
X#ifdef REINCARNATION
X if (dlevel == rogue_level) {
X You("feel as though you were here in a previous lifetime.");
X return;
X }
X#endif
X makecorridors();
X make_niches();
X
X /* make a secret treasure vault, not connected to the rest */
X if(nroom <= (MAXNROFROOMS/2)) if(rn2(3)) {
X
X troom = &rooms[nroom];
X secret = TRUE;
X if(makerooms()) {
X troom->rtype = VAULT; /* treasure vault */
X for(x = troom->lx; x <= troom->hx; x++)
X for(y = troom->ly; y <= troom->hy; y++)
X mkgold((long)(rnd(dlevel*100) + 50), x, y);
X if(!rn2(3))
X makevtele();
X }
X }
X
X#ifdef WIZARD
X if(wizard && getenv("SHOPTYPE")) mkroom(SHOPBASE); else
X#endif
X#ifdef ORACLE
X if(dlevel == oracle_level) mkroom(DELPHI);
X /* It is possible that we find no good place to set up Delphi.
X * It is also possible to get more than one Delphi using bones levels.
X * The first is not a problem; the second is a minor nuisance.
X */
X else
X#endif
X if(dlevel > 1 && dlevel < medusa_level && rn2(dlevel) < 3) mkroom(SHOPBASE);
X else
X#ifdef THRONES
X if(dlevel > 4 && !rn2(6)) mkroom(COURT);
X else
X#endif
X if(dlevel > 6 && !rn2(7)) mkroom(ZOO);
X else
X#ifdef ALTARS
X if(dlevel > 8 && !rn2(5)) mkroom(TEMPLE);
X else
X#endif
X if(dlevel > 9 && !rn2(5) && !(mons[PM_KILLER_BEE].geno & G_GENOD))
X mkroom(BEEHIVE);
X else
X if(dlevel > 11 && !rn2(6)) mkroom(MORGUE);
X else
X#ifdef ARMY
X if(dlevel > 14 && !rn2(4) && !(mons[PM_SOLDIER].geno & G_GENOD))
X mkroom(BARRACKS);
X else
X#endif
X if(dlevel > 18 && !rn2(6)) mkroom(SWAMP);
X
X
X /* for each room: put things inside */
X for(croom = rooms; croom->hx > 0; croom++) {
X register boolean boxinlev = FALSE;
X
X if(croom->rtype != OROOM) continue;
X
X /* put a sleeping monster inside */
X /* Note: monster may be on the stairs. This cannot be
X avoided: maybe the player fell through a trapdoor
X while a monster was on the stairs. Conclusion:
X we have to check for monsters on the stairs anyway. */
X
X if(u.uhave_amulet || !rn2(3)) {
X x = somex(croom); y = somey(croom);
X#ifdef REINCARNATION
X if (dlevel == rogue_level)
X tmonst = makemon(roguemon(), x, y);
X else
X#endif
X tmonst = makemon((struct permonst *) 0, x,y);
X if (tmonst && tmonst->data == &mons[PM_GIANT_SPIDER])
X (void) maketrap (x,y,WEB);
X }
X /* put traps and mimics inside */
X goldseen = FALSE;
X while(!rn2(8-(dlevel/6))) mktrap(0,0,croom);
X if(!goldseen && !rn2(3)) mkgold(0L, somex(croom), somey(croom));
X#ifdef REINCARNATION
X if (dlevel == rogue_level) goto skip_nonrogue;
X#endif
X#ifdef FOUNTAINS
X if(!rn2(10)) mkfount(0,croom);
X#endif
X#ifdef SINKS
X if(!rn2(60)) mksink(croom);
X#endif
X#ifdef ALTARS
X if(!rn2(60)) mkaltar(croom);
X#endif
X /* put statues inside */
X#ifdef MEDUSA
X if(!rn2(dlevel == medusa_level ? 1 : 20)) {
X if (!rn2(dlevel == medusa_level ? 2 : 50))
X (void) mk_tt_statue(somex(croom), somey(croom));
X else {
X struct obj *otmp =
X mkstatue((struct permonst *)0,
X somex(croom), somey(croom));
X if (dlevel == medusa_level && otmp)
X otmp->spe = 0;
X /* Medusa statues don't contain books */
X }
X }
X#else
X if(!rn2(20))
X (void) mkstatue((struct permonst *)0,
X somex(croom), somey(croom));
X#endif
X
X /* put box/chest inside */
X if(!rn2(20) && !boxinlev) {
X
X boxinlev = TRUE;
X (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST,
X somex(croom), somey(croom));
X }
X
X#ifdef REINCARNATION
X skip_nonrogue:
X#endif
X if(!rn2(3)) {
X (void) mkobj_at(0, somex(croom), somey(croom));
X tryct = 0;
X while(!rn2(5)) {
X if(++tryct > 100){
X Printf("tryct overflow4\n");
X break;
X }
X (void) mkobj_at(0, somex(croom), somey(croom));
X }
X }
X }
X}
X
Xvoid
Xmklev()
X{
X if(getbones()) return;
X
X in_mklev = TRUE;
X makelevel();
X bound_digging();
X in_mklev = FALSE;
X}
X
Xstatic boolean
Xbydoor(x, y)
Xregister xchar x, y;
X{
X register boolean tmp1, tmp2;
X
X /* break up large expression to help some compilers */
X tmp1 = (IS_DOOR(levl[x+1][y].typ) || levl[x+1][y].typ == SDOOR ||
X IS_DOOR(levl[x-1][y].typ) || levl[x-1][y].typ == SDOOR);
X tmp2 = (IS_DOOR(levl[x][y+1].typ) || levl[x][y+1].typ == SDOOR ||
X IS_DOOR(levl[x][y-1].typ) || levl[x][y-1].typ == SDOOR);
X return(tmp1 || tmp2);
X}
X
X/* see whether it is allowable to create a door at [x,y] */
Xint
Xokdoor(x,y)
Xregister xchar x, y;
X{
X register boolean near_door = bydoor(x, y);
X
X return((levl[x][y].typ == HWALL || levl[x][y].typ == VWALL) &&
X doorindex < DOORMAX && !near_door);
X}
X
Xvoid
Xdodoor(x,y,aroom)
Xregister int x, y;
Xregister struct mkroom *aroom;
X{
X if(doorindex >= DOORMAX) {
X impossible("DOORMAX exceeded?");
X return;
X }
X if(!okdoor(x,y) && nxcor)
X return;
X dosdoor(x,y,aroom,rn2(8) ? DOOR : SDOOR);
X}
X
Xstatic boolean
Xoccupied(x, y)
Xregister xchar x, y;
X{
X return(t_at(x, y) || levl[x][y].typ == STAIRS
X#ifdef FOUNTAINS
X || IS_FOUNTAIN(levl[x][y].typ)
X#endif
X#ifdef THRONES
X || IS_THRONE(levl[x][y].typ)
X#endif
X#ifdef SINKS
X || IS_SINK(levl[x][y].typ)
X#endif
X#ifdef ALTARS
X || levl[x][y].typ == ALTAR
X#endif
X );
X}
X
X/* make a trap somewhere (in croom if mazeflag = 0) */
Xvoid
Xmktrap(num, mazeflag, croom)
Xregister int num, mazeflag;
Xregister struct mkroom *croom;
X{
X register struct trap *ttmp;
X register int kind,nomonst,nomimic,nospider,
X#ifdef POLYSELF
X nopoly,
X#endif
X nospikes, nolevltp,
X nolandmine,
X tryct = 0;
X
X xchar mx,my;
X
X if(!num || num >= TRAPNUM) {
X nomonst = (dlevel < 4) ? 1 : 0;
X nolevltp = (dlevel < 5) ? 1 : 0;
X nospikes = (dlevel < 6) ? 1 : 0;
X nospider = (dlevel < 7) ? 1 : 0;
X#ifdef POLYSELF
X nopoly = (dlevel < 6) ? 1 : 0;
X#endif
X nolandmine = (dlevel < 5) ? 1 : 0;
X nomimic = (dlevel < 9 || goldseen ) ? 1 : 0;
X if((mons[PM_SMALL_MIMIC].geno & G_GENOD) &&
X (mons[PM_LARGE_MIMIC].geno & G_GENOD) &&
X (mons[PM_GIANT_MIMIC].geno & G_GENOD))
X nomimic = 1;
X if(mons[PM_GIANT_SPIDER].geno & G_GENOD)
X nospider = 1;
X
X do {
X#ifdef REINCARNATION
X if (dlevel==rogue_level) {
X switch(rn2(7)) {
X case 0: kind = BEAR_TRAP; break;
X case 1: kind = ARROW_TRAP; break;
X case 2: kind = DART_TRAP; break;
X case 3: kind = TRAPDOOR; break;
X case 4: kind = PIT; break;
X case 5: kind = SLP_GAS_TRAP; break;
X case 6: kind = RUST_TRAP; break;
X }
X } else
X#endif
X kind = rnd(TRAPNUM-1);
X if((kind == MONST_TRAP && (nomonst && nomimic))
X || ((kind == WEB) && nospider)
X || (kind == SPIKED_PIT && nospikes)
X || (kind == LEVEL_TELEP && nolevltp)
X#ifdef POLYSELF
X || (kind == POLY_TRAP && nopoly)
X#endif
X || (kind == LANDMINE && nolandmine)
X ) kind = NO_TRAP;
X } while(kind == NO_TRAP);
X } else kind = num;
X
X if(kind == MONST_TRAP && !nomimic && !rn2(4) && !mazeflag) {
X register struct monst *mtmp;
X
X do {
X if(++tryct > 200) return;
X /* note: fakedoor maybe on actual door */
X if(rn2(2)){
X if(rn2(2)) mx = croom->hx+1;
X else mx = croom->lx-1;
X my = somey(croom);
X } else {
X if(rn2(2)) my = croom->hy+1;
X else my = croom->ly-1;
X mx = somex(croom);
X }
X } while(levl[mx][my].mmask);
X
X if((mtmp = makemon(mkclass(S_MIMIC), mx, my))) {
X mtmp->mimic = 1;
X mtmp->mappearance = DOOR_SYM;
X }
X return;
X }
X
X do {
X if(++tryct > 200)
X return;
X if(mazeflag){
X coord mm;
X mazexy(&mm);
X mx = mm.x;
X my = mm.y;
X } else {
X mx = somex(croom);
X my = somey(croom);
X }
X } while(occupied(mx, my));
X
X ttmp = maketrap(mx, my, kind);
X if (kind == WEB) (void) makemon(&mons[PM_GIANT_SPIDER], mx, my);
X if(mazeflag && !rn2(10) && ttmp->ttyp < MONST_TRAP)
X ttmp->tseen = 1;
X}
X
X#ifdef FOUNTAINS
Xvoid
Xmkfount(mazeflag,croom)
Xregister struct mkroom *croom;
Xregister int mazeflag;
X{
X register xchar mx,my;
X register int tryct = 0;
X
X do {
X if(++tryct > 200) return;
X if(mazeflag) {
X coord mm;
X mazexy(&mm);
X mx = mm.x;
X my = mm.y;
X } else {
X mx = somex(croom);
X my = somey(croom);
X }
X } while(occupied(mx, my) || bydoor(mx, my));
X
X /* Put a fountain at mx, my */
X levl[mx][my].typ = FOUNTAIN;
X levl[mx][my].scrsym = FOUNTAIN_SYM;
X
X fountsound++;
X}
X#endif /* FOUNTAINS /**/
X
X#ifdef SINKS
Xstatic void
Xmksink(croom)
Xregister struct mkroom *croom;
X{
X register xchar mx,my;
X register int tryct = 0;
X
X do {
X if(++tryct > 200) return;
X mx = somex(croom);
X my = somey(croom);
X } while(occupied(mx, my) || bydoor(mx, my));
X
X /* Put a sink at mx, my */
X levl[mx][my].typ = SINK;
X levl[mx][my].scrsym = SINK_SYM;
X
X sinksound++;
X}
X#endif /* SINKS /**/
X
X
X#ifdef ALTARS
Xstatic void
Xmkaltar(croom)
Xregister struct mkroom *croom;
X{
X register xchar mx,my;
X register int tryct = 0;
X
X if(croom->rtype != OROOM) return;
X
X do {
X if(++tryct > 200) return;
X mx = somex(croom);
X my = somey(croom);
X } while(occupied(mx, my) || bydoor(mx, my));
X
X /* Put an altar at mx, my */
X levl[mx][my].typ = ALTAR;
X levl[mx][my].scrsym = ALTAR_SYM;
X /* 0 - A_CHAOS, 1 - A_NEUTRAL, 2 - A_LAW */
X levl[mx][my].altarmask = rn2((int)A_LAW+1);
X}
X#endif /* ALTARS /**/
END_OF_FILE
if test 27014 -ne `wc -c <'src/mklev.c'`; then
echo shar: \"'src/mklev.c'\" unpacked with wrong size!
fi
# end of 'src/mklev.c'
fi
echo shar: End of archive 20 \(of 38\).
cp /dev/null ark20isdone
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 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 38 archives.
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