-+-+-+-+-+-+-+-+ START OF PART 28 -+-+-+-+-+-+-+-+ X$ cc treasure.c /obj=treasure.obj X$ cc variable.c /obj=variable.obj X$ cc wands.c /obj=wands.obj X$ cc wizard.c /obj=wizard.obj X$ cc getch.c /obj=getch.obj X$ cc uexit.c /obj=uexit.obj X$ link moria/opt $ CALL UNPACK MAKE.COM;1 1163257088 $ create 'f' X# COPTS = /nowarning XCOPTS = X XOBJS1 = create.obj creature.obj death.obj desc.obj dungeon.obj eat.obj \ X`09files.obj generate.obj getch.obj help.obj io.obj magic.obj main.obj \ X`09misc1.obj misc2.obj misc3.obj misc4.obj monsters.obj XOBJS2 = moria1.obj moria2.obj moria3.obj moria4.obj player.obj potions.obj \ X`09prayer.obj recall.obj rnd.obj save.obj scrolls.obj sets.obj \ X`09signals.obj spells.obj staffs.obj store1.obj store2.obj tables.obj XOBJS3 = treasure.obj uexit.obj variable.obj wands.obj wizard.obj X Xmoria : $(OBJS1) $(OBJS2) $(OBJS3) X`09link moria/opt X Xcreate.obj : create.c constant.h types.h externs.h config.h X`09cc $(COPTS) create.c /obj=create.obj X Xcreature.obj : creature.c constant.h types.h externs.h config.h X`09cc $(COPTS) creature.c /obj=creature.obj X Xdeath.obj : death.c constant.h types.h externs.h config.h X`09cc $(COPTS) death.c /obj=death.obj X Xdesc.obj : desc.c constant.h types.h externs.h config.h X`09cc $(COPTS) desc.c /obj=desc.obj X Xdungeon.obj : dungeon.c constant.h types.h externs.h config.h X`09cc $(COPTS) dungeon.c /obj=dungeon.obj X Xeat.obj : eat.c constant.h types.h externs.h config.h X`09cc $(COPTS) eat.c /obj=eat.obj X Xfiles.obj : files.c constant.h types.h externs.h config.h X`09cc $(COPTS) files.c /obj=files.obj X Xgenerate.obj : generate.c constant.h types.h externs.h config.h X`09cc $(COPTS) generate.c /obj=generate.obj X Xgetch.obj : getch.c X`09cc $(COPTS) getch.c /obj=getch.obj X Xhelp.obj : help.c constant.h types.h externs.h config.h X`09cc $(COPTS) help.c /obj=help.obj X Xio.obj : io.c constant.h types.h externs.h config.h X`09cc $(COPTS) io.c /obj=io.obj X Xmagic.obj : magic.c constant.h types.h externs.h config.h X`09cc $(COPTS) magic.c /obj=magic.obj X Xmain.obj : main.c constant.h types.h externs.h config.h X`09cc $(COPTS) main.c /obj=main.obj X Xmisc1.obj : misc1.c constant.h types.h externs.h config.h X`09cc $(COPTS) misc1.c /obj=misc1.obj X Xmisc2.obj : misc2.c constant.h types.h externs.h config.h X`09cc $(COPTS) misc2.c /obj=misc2.obj X Xmisc3.obj : misc3.c constant.h types.h externs.h config.h X`09cc $(COPTS) misc3.c /obj=misc3.obj X Xmisc4.obj : misc4.c constant.h types.h externs.h config.h X`09cc $(COPTS) misc4.c /obj=misc4.obj X Xmonsters.obj : monsters.c constant.h types.h config.h X`09cc $(COPTS) monsters.c /obj=monsters.obj X Xmoria1.obj : moria1.c constant.h types.h externs.h config.h X`09cc $(COPTS) moria1.c /obj=moria1.obj X Xmoria2.obj : moria2.c constant.h types.h externs.h config.h X`09cc $(COPTS) moria2.c /obj=moria2.obj X Xmoria3.obj : moria3.c constant.h types.h externs.h config.h X`09cc $(COPTS) moria3.c /obj=moria3.obj X Xmoria4.obj : moria4.c constant.h types.h externs.h config.h X`09cc $(COPTS) moria4.c /obj=moria4.obj X Xplayer.obj : player.c constant.h types.h config.h X`09cc $(COPTS) player.c /obj=player.obj X Xpotions.obj : potions.c constant.h types.h externs.h config.h X`09cc $(COPTS) potions.c /obj=potions.obj X Xprayer.obj : prayer.c constant.h types.h externs.h config.h X`09cc $(COPTS) prayer.c /obj=prayer.obj X Xrecall.obj : recall.c constant.h types.h externs.h config.h X`09cc $(COPTS) recall.c /obj=recall.obj X Xrnd.obj : rnd.c constant.h types.h X`09cc $(COPTS) rnd.c /obj=rnd.obj X Xsave.obj : save.c constant.h types.h externs.h config.h X`09cc $(COPTS) save.c /obj=save.obj X Xscrolls.obj : scrolls.c constant.h types.h externs.h config.h X`09cc $(COPTS) scrolls.c /obj=scrolls.obj X Xsets.obj : sets.c constant.h config.h X`09cc $(COPTS) sets.c /obj=sets.obj X Xsignals.obj : signals.c constant.h types.h externs.h config.h X`09cc $(COPTS) signals.c /obj=signals.obj X Xspells.obj : spells.c constant.h types.h externs.h config.h X`09cc $(COPTS) spells.c /obj=spells.obj X Xstaffs.obj : staffs.c constant.h types.h externs.h config.h X`09cc $(COPTS) staffs.c /obj=staffs.obj X Xstore1.obj : store1.c constant.h types.h externs.h config.h X`09cc $(COPTS) store1.c /obj=store1.obj X Xstore2.obj : store2.c constant.h types.h externs.h config.h X`09cc $(COPTS) store2.c /obj=store2.obj X Xtables.obj : tables.c constant.h types.h config.h X`09cc $(COPTS) tables.c /obj=tables.obj X Xtreasure.obj : treasure.c constant.h types.h config.h X`09cc $(COPTS) treasure.c /obj=treasure.obj X Xuexit.obj : uexit.c constant.h types.h config.h X`09cc $(COPTS) uexit.c /obj=uexit.obj X Xvariable.obj : variable.c constant.h types.h externs.h config.h X`09cc $(COPTS) variable.c /obj=variable.obj X Xwands.obj : wands.c constant.h types.h externs.h config.h X`09cc $(COPTS) wands.c /obj=wands.obj X Xwizard.obj : wizard.c constant.h types.h externs.h config.h X`09cc $(COPTS) wizard.c /obj=wizard.obj X X $ CALL UNPACK MAKEFILE.;1 926634558 $ create 'f' X/* source/misc1.c: misc utility and initialization code, magic objects code X X Copyright (c) 1989-92 James E. Wilson, Robert A. Koeneke X X This software may be copied and distributed for educational, research, an Vd X not for profit purposes provided that this copyright and statement are X included in all such copies. */ X X#include "config.h" X#include "constant.h" X#include "types.h" X#include "externs.h" X X#ifdef __TURBOC__ X#include`09 X#endif X X#ifdef Pyramid X#include X#else X#include X#endif X#if !defined(GEMDOS) && !defined(MAC) && !defined(AMIGA) X#ifndef VMS X#include X#else X#include X#endif X#endif X X#if !defined(ATARIST_MWC) && !defined(MAC) && !defined(VMS) && !defined(AMIG VA) Xlong time(); X#endif Xstruct tm *localtime(); X X#if defined(LINT_ARGS) Xstatic void compact_objects(void); X#endif X X X/* gets a new random seed for the random number generator */ Xvoid init_seeds(seed) Xint32u seed; X`7B X register int32u clock_var; X X if (seed == 0) X#ifdef MAC X clock_var = time((time_t *)0); X#else X clock_var = time((long *)0); X#endif X else X clock_var = seed; X randes_seed = (int32) clock_var; X X clock_var += 8762; X town_seed = (int32) clock_var; X X clock_var += 113452L; X set_rnd_seed(clock_var); X /* make it a little more random */ X for (clock_var = randint(100); clock_var != 0; clock_var--) X (void) rnd(); X`7D X X/* holds the previous rnd state */ Xstatic int32u old_seed; X X/* change to different random number generator state */ Xvoid set_seed(seed) Xint32u seed; X`7B X old_seed = get_rnd_seed (); X X /* want reproducible state here */ X set_rnd_seed (seed); X`7D X X X/* restore the normal random generator state */ Xvoid reset_seed() X`7B X set_rnd_seed (old_seed); X`7D X X X/* Check the day-time strings to see if open`09`09-RAK-`09*/ Xint check_time() X`7B X#ifdef MORIA_HOU X long clock_var; X register struct tm *tp; X X#ifdef MAC X clock_var = time((time_t *)0); X#else X clock_var = time((long *)0); X#endif X tp = localtime(&clock_var); X if (days`5Btp->tm_wday`5D`5Btp->tm_hour+4`5D == 'X') X return TRUE; X else X return FALSE; X#else X return TRUE; X#endif X`7D X X X/* Generates a random integer x where 1<=X<=MAXVAL`09-RAK-`09*/ Xint randint(maxval) Xint maxval; X`7B X register long randval; X X randval = rnd (); X return ((int)(randval % maxval) + 1); X`7D X X/* Generates a random integer number of NORMAL distribution -RAK-*/ Xint randnor(mean, stand) Xint mean, stand; X`7B X register int tmp, offset, low, iindex, high; X X#if 0 X /* alternate randnor code, slower but much smaller since no table */ X /* 2 per 1,000,000 will be > 4*SD, max is 5*SD */ X tmp = damroll(8, 99);`09 /* mean 400, SD 81 */ X tmp = (tmp - 400) * stand / 81; X return tmp + mean; X#endif X X tmp = randint(MAX_SHORT); X X /* off scale, assign random value between 4 and 5 times SD */ X if (tmp == MAX_SHORT) X `7B X offset = 4 * stand + randint(stand); X X /* one half are negative */ X if (randint(2) == 1) X`09offset = -offset; X X return mean + offset; X `7D X X /* binary search normal normal_table to get index that matches tmp */ X /* this takes up to 8 iterations */ X low = 0; X iindex = NORMAL_TABLE_SIZE >> 1; X high = NORMAL_TABLE_SIZE; X while (TRUE) X `7B X if ((normal_table`5Biindex`5D == tmp) `7C`7C (high == (low+1))) X`09break; X if (normal_table`5Biindex`5D > tmp) X`09`7B X`09 high = iindex; X`09 iindex = low + ((iindex - low) >> 1); X`09`7D X else X`09`7B X`09 low = iindex; X`09 iindex = iindex + ((high - iindex) >> 1); X`09`7D X `7D X X /* might end up one below target, check that here */ X if (normal_table`5Biindex`5D < tmp) X iindex = iindex + 1; X X /* normal_table is based on SD of 64, so adjust the index value here, X round the half way case up */ X offset = ((stand * iindex) + (NORMAL_TABLE_SD >> 1)) / NORMAL_TABLE_SD; X X /* one half should be negative */ X if (randint(2) == 1) X offset = -offset; X X return mean + offset; X`7D X X X/* Returns position of first set bit`09`09`09-RAK-`09*/ X/* and clears that bit */ Xint bit_pos(test) Xint32u *test; X`7B X register int i; X register int32u mask = 0x1; X X for (i = 0; i < sizeof(*test)*8; i++) `7B X if (*test & mask) `7B X *test &= `7Emask; X return(i); X `7D X mask <<= 1; X `7D X X /* no one bits found */ X return(-1); X`7D X X/* Checks a co-ordinate for in bounds status`09`09-RAK-`09*/ Xint in_bounds(y, x) Xint y, x; X`7B X if ((y > 0) && (y < cur_height-1) && (x > 0) && (x < cur_width-1)) X return(TRUE); X else X return(FALSE); X`7D X X X/* Calculates current boundaries`09`09`09`09-RAK-`09*/ Xvoid panel_bounds() X`7B X panel_row_min = panel_row*(SCREEN_HEIGHT/2); X panel_row_max = panel_row_min + SCREEN_HEIGHT - 1; X panel_row_prt = panel_row_min - 1; X panel_col_min = panel_col*(SCREEN_WIDTH/2); X panel_col_max = panel_col_min + SCREEN_WIDTH - 1; X panel_col_prt = panel_col_min - 13; X`7D X X X/* Given an row (y) and col (x), this routine detects -RAK-`09*/ X/* when a move off the screen has occurred and figures new borders. X Force forcses the panel bounds to be recalculated, useful for 'W'here. */ Xint get_panel(y, x, force) Xint y, x, force; X`7B X register int prow, pcol; X register int panel; X X prow = panel_row; X pcol = panel_col; X if (force `7C`7C (y < panel_row_min + 2) `7C`7C (y > panel_row_max - 2)) X `7B X prow = ((y - SCREEN_HEIGHT/4)/(SCREEN_HEIGHT/2)); X if (prow > max_panel_rows) X`09prow = max_panel_rows; X else if (prow < 0) X`09prow = 0; X `7D X if (force `7C`7C (x < panel_col_min + 3) `7C`7C (x > panel_col_max - 3)) X `7B X pcol = ((x - SCREEN_WIDTH/4)/(SCREEN_WIDTH/2)); X if (pcol > max_panel_cols) X`09pcol = max_panel_cols; X else if (pcol < 0) X`09pcol = 0; X `7D X if ((prow != panel_row) `7C`7C (pcol != panel_col)) X `7B X panel_row = prow; X panel_col = pcol; X panel_bounds(); X panel = TRUE; X /* stop movement if any */ X if (find_bound) X`09end_find(); X `7D X else X panel = FALSE; X return(panel); X`7D X X X/* Tests a given point to see if it is within the screen -RAK-`09*/ X/* boundaries.`09`09`09`09`09`09`09 */ Xint panel_contains(y, x) Xregister int y, x; X`7B X if ((y >= panel_row_min) && (y <= panel_row_max) && X (x >= panel_col_min) && (x <= panel_col_max)) X return (TRUE); X else X return (FALSE); X`7D X X X/* Distance between two points`09`09`09`09-RAK-`09*/ Xint distance(y1, x1, y2, x2) Xint y1, x1, y2, x2; X`7B X register int dy, dx; X X dy = y1 - y2; X if (dy < 0) X dy = -dy; X dx = x1 - x2; X if (dx < 0) X dx = -dx; X X return ((((dy + dx) << 1) - (dy > dx ? dx : dy)) >> 1); X`7D X X/* Checks points north, south, east, and west for a wall -RAK-`09*/ X/* note that y,x is always in_bounds(), i.e. 0 < y < cur_height-1, and X 0 < x < cur_width-1`09*/ Xint next_to_walls(y, x) Xregister int y, x; X`7B X register int i; X register cave_type *c_ptr; X X i = 0; X c_ptr = &cave`5By-1`5D`5Bx`5D; X if (c_ptr->fval >= MIN_CAVE_WALL) X i++; X c_ptr = &cave`5By+1`5D`5Bx`5D; X if (c_ptr->fval >= MIN_CAVE_WALL) X i++; X c_ptr = &cave`5By`5D`5Bx-1`5D; X if (c_ptr->fval >= MIN_CAVE_WALL) X i++; X c_ptr = &cave`5By`5D`5Bx+1`5D; X if (c_ptr->fval >= MIN_CAVE_WALL) X i++; X X return(i); X`7D X X X/* Checks all adjacent spots for corridors`09`09-RAK-`09*/ X/* note that y, x is always in_bounds(), hence no need to check that X j, k are in_bounds(), even if they are 0 or cur_x-1 is still works */ Xint next_to_corr(y, x) Xregister int y, x; X`7B X register int k, j, i; X register cave_type *c_ptr; X X i = 0; X for (j = y - 1; j <= (y + 1); j++) X for (k = x - 1; k <= (x + 1); k++) X `7B X`09c_ptr = &cave`5Bj`5D`5Bk`5D; X`09/* should fail if there is already a door present */ X`09if (c_ptr->fval == CORR_FLOOR X`09 && (c_ptr->tptr == 0 `7C`7C t_list`5Bc_ptr->tptr`5D.tval < TV_MIN_DOO VRS)) X`09 i++; X `7D X return(i); X`7D X X X/* generates damage for 2d6 style dice rolls */ Xint damroll(num, sides) Xint num, sides; X`7B X register int i, sum = 0; X X for (i = 0; i < num; i++) X sum += randint(sides); X return(sum); X`7D X Xint pdamroll(array) Xint8u *array; X`7B X return damroll((int)array`5B0`5D, (int)array`5B1`5D); X`7D X X X/* A simple, fast, integer-based line-of-sight algorithm. By Joseph Hall, X 4116 Brewster Drive, Raleigh NC 27606. Email to jnh@ecemwl.ncsu.edu. X X Returns TRUE if a line of sight can be traced from x0, y0 to x1, y1. X X The LOS begins at the center of the tile `5Bx0, y0`5D and ends at X the center of the tile `5Bx1, y1`5D. If los() is to return TRUE, all of X the tiles this line passes through must be transparent, WITH THE X EXCEPTIONS of the starting and ending tiles. X X We don't consider the line to be "passing through" a tile if X it only passes across one corner of that tile. */ X X/* Because this function uses (short) ints for all calculations, overflow +-+-+-+-+-+-+-+- END OF PART 28 +-+-+-+-+-+-+-+-