[comp.sources.games] v05i048: umoria2 - single player dungeon simulation

games@tekred.TEK.COM (07/29/88)

Submitted by: "James E. Wilson" <wilson@ji.berkeley.edu>
Comp.sources.games: Volume 5, Issue 48
Archive-name: umoria2/Part14



#! /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 14 (of 18)."
# Contents:  generate.c store2.c
# Wrapped by billr@saab on Wed Jul 13 11:16:33 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'generate.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'generate.c'\"
else
echo shar: Extracting \"'generate.c'\" \(26802 characters\)
sed "s/^X//" >'generate.c' <<'END_OF_FILE'
X#include "constants.h"
X#include "config.h"
X#include "types.h"
X#include "externs.h"
X
Xtypedef struct coords {
X  int x, y;
X} coords;
X
Xcoords doorstk[100];
Xint doorptr;
X
X
X/* Always picks a correct direction		*/
Xcorrect_dir(rdir, cdir, y1, x1, y2, x2)
Xint *rdir, *cdir;
Xregister int y1, x1, y2, x2;
X{
X  if (y1 < y2)
X    *rdir =  1;
X  else if (y1 == y2)
X    *rdir =  0;
X  else
X    *rdir = -1;
X  if (x1 < x2)
X    *cdir =  1;
X  else if (x1 == x2)
X    *cdir =  0;
X  else
X    *cdir = -1;
X  if ((*rdir != 0) && (*cdir != 0))
X    switch(randint(2))
X      {
X      case 1:
X	*rdir = 0;
X	break;
X      case 2:
X	*cdir = 0;
X	break;
X      }
X}
X
X
X/* Chance of wandering direction			*/
Xrand_dir(rdir, cdir, y1, x1, y2, x2, chance)
Xint *rdir, *cdir;
Xint y1, x1, y2, x2;
Xint chance;
X{
X  switch(randint(chance))
X    {
X    case 1:
X      *rdir = -1;
X      *cdir =  0;
X      break;
X    case 2:
X      *rdir =  1;
X      *cdir =  0;
X      break;
X    case 3:
X      *rdir =  0;
X      *cdir = -1;
X      break;
X    case 4:
X      *rdir =  0;
X      *cdir =  1;
X      break;
X    default:
X      correct_dir(rdir, cdir, y1, x1, y2, x2);
X      break;
X    }
X}
X
X
X/* Blanks out entire cave				-RAK-	*/
Xblank_cave()
X{
X  register int i, j;
X  register cave_type *c_ptr;
X
X  c_ptr = &cave[0][0];
X  for (i = 0; i < MAX_HEIGHT; i++)
X    for (j = 0; j < MAX_WIDTH; j++)
X      *c_ptr++ = blank_floor;
X}
X
X
X/* Fills in empty spots with desired rock		-RAK-	*/
X/* Note: 9 is a temporary value.				*/
Xfill_cave(fill)
Xfloor_type fill;
X{
X  register int i, j;
X  register cave_type *c_ptr;
X
X  for (i = 1; i < cur_height-1; i++)
X    for (j = 1; j < cur_width-1; j++)
X      {
X	c_ptr = &cave[i][j];
X	if ((c_ptr->fval == 0) || (c_ptr->fval == 8) || (c_ptr->fval == 9))
X	  {
X	    c_ptr->fval = fill.ftval;
X	    c_ptr->fopen = fill.ftopen;
X	  }
X      }
X}
X
X
X/* Places indestructible rock around edges of dungeon	-RAK-	*/
Xplace_boundary()
X{
X  register int i;
X
X  for (i = 0; i < cur_height; i++)
X    {
X      cave[i][0].fval            = boundary_wall.ftval;
X      cave[i][0].fopen           = boundary_wall.ftopen;
X      cave[i][cur_width-1].fval  = boundary_wall.ftval;
X      cave[i][cur_width-1].fopen = boundary_wall.ftopen;
X    }
X  for (i = 0; i < cur_width; i++)
X    {
X      cave[0][i].fval             = boundary_wall.ftval;
X      cave[0][i].fopen            = boundary_wall.ftopen;
X      cave[cur_height-1][i].fval  = boundary_wall.ftval;
X      cave[cur_height-1][i].fopen = boundary_wall.ftopen;
X    }
X}
X
X
X/* Places "streamers" of rock through dungeon		-RAK-	*/
Xplace_streamer(rock, treas_chance)
Xfloor_type rock;
Xint treas_chance;
X{
X  register int i, tx, ty;
X  int y, x, dir, t1, t2;
X  int flag;
X  register cave_type *c_ptr;
X
X  /* Choose starting point and direction		*/
X  y = (cur_height/2.0) + 11 - randint(23);
X  x = (cur_width/2.0)  + 16 - randint(33);
X
X  dir = randint(8);	/* Number 1-4, 6-9	*/
X  if (dir > 4)
X    dir = dir + 1;
X
X  /* Place streamer into dungeon			*/
X  flag = FALSE;	/* Set to true when y, x are out-of-bounds*/
X  t1 = 2*DUN_STR_RNG + 1;	/* Constants	*/
X  t2 =   DUN_STR_RNG + 1;
X  do
X    {
X      for (i = 0; i < DUN_STR_DEN; i++)
X	{
X	  ty = y + randint(t1) - t2;
X	  tx = x + randint(t1) - t2;
X	  if (in_bounds(ty, tx))
X	    {
X	      c_ptr = &cave[ty][tx];
X	      if (c_ptr->fval == rock_wall1.ftval)
X		{
X		  c_ptr->fval = rock.ftval;
X		  c_ptr->fopen = rock.ftopen;
X		  if (randint(treas_chance) == 1)
X		    place_gold(ty, tx);
X		}
X	    }
X	}
X      if (!move(dir, &y, &x))
X	flag = TRUE;
X    }
X  while (!flag);
X}
X
X
X/* Place a trap with a given displacement of point	-RAK-	*/
Xvault_trap(y, x, yd, xd, num)
Xint y, x, yd, xd, num;
X{
X  register int count, y1, x1;
X  int i, flag;
X  register cave_type *c_ptr;
X
X  for (i = 0; i < num; i++)
X    {
X      flag = FALSE;
X      count = 0;
X      do
X	{
X	  y1 = y - yd - 1 + randint(2*yd+1);
X	  x1 = x - xd - 1 + randint(2*xd+1);
X	  c_ptr = &cave[y1][x1];
X	  if ((c_ptr->fval > 0) && (c_ptr->fval < 8) && (c_ptr->fval != 3))
X	    if (c_ptr->tptr == 0)
X	      {
X		place_trap(y1, x1, 1, randint(MAX_TRAPA)-1);
X		flag = TRUE;
X	      }
X	  count++;
X	}
X      while ((!flag) && (count <= 5));
X    }
X}
X
X
X/* Place a trap with a given displacement of point	-RAK-	*/
Xvault_monster(y, x, num)
Xint y, x, num;
X{
X  register int i;
X  int y1, x1;
X
X  for (i = 0; i < num; i++)
X    {
X      y1 = y;
X      x1 = x;
X      (void) summon_monster(&y1, &x1, TRUE);
X    }
X}
X
X
X/* Builds a room at a row, column coordinate		-RAK-	*/
Xbuild_room(yval, xval)
Xint yval, xval;
X{
X  register int i, j;
X  register int y_height, y_depth;
X  register int x_left, x_right;
X  floor_type cur_floor;
X
X  if (dun_level <= randint(25))
X    cur_floor = lopen_floor;	/* Floor with light	*/
X  else
X    cur_floor = dopen_floor;	/* Dark floor		*/
X  y_height = yval - randint(4);
X  y_depth  = yval + randint(3);
X  x_left   = xval - randint(11);
X  x_right  = xval + randint(11);
X  for (i = y_height; i <= y_depth; i++)
X    for (j = x_left; j <= x_right; j++)
X      {
X	cave[i][j].fval  = cur_floor.ftval;
X	cave[i][j].fopen = cur_floor.ftopen;
X      }
X  for (i = (y_height - 1); i <= (y_depth + 1); i++)
X    {
X      cave[i][x_left-1].fval   = rock_wall1.ftval;
X      cave[i][x_left-1].fopen  = rock_wall1.ftopen;
X      cave[i][x_right+1].fval  = rock_wall1.ftval;
X      cave[i][x_right+1].fopen = rock_wall1.ftopen;
X    }
X  for (i = x_left; i <= x_right; i++)
X    {
X      cave[y_height-1][i].fval  = rock_wall1.ftval;
X      cave[y_height-1][i].fopen = rock_wall1.ftopen;
X      cave[y_depth+1][i].fval   = rock_wall1.ftval;
X      cave[y_depth+1][i].fopen  = rock_wall1.ftopen;
X    }
X}
X
X
X/* Builds a room at a row, column coordinate		-RAK-	*/
X/* Type 1 unusual rooms are several overlapping rectangular ones	*/
Xbuild_type1(yval, xval)
Xint yval, xval;
X{
X  int y_height, y_depth;
X  int x_left, x_right;
X  register int i0, i, j;
X  floor_type cur_floor;
X  register cave_type *c_ptr;
X
X  if (dun_level <= randint(25))
X    cur_floor = lopen_floor;	/* Floor with light	*/
X  else
X    cur_floor = dopen_floor;	/* Dark floor		*/
X  for (i0 = 0; i0 < (1 + randint(2)); i0++)
X    {
X      y_height = yval - randint(4);
X      y_depth  = yval + randint(3);
X      x_left   = xval - randint(11);
X      x_right  = xval + randint(11);
X      for (i = y_height; i <= y_depth; i++)
X	for (j = x_left; j <= x_right; j++)
X	  {
X	    cave[i][j].fval  = cur_floor.ftval;
X	    cave[i][j].fopen = cur_floor.ftopen;
X	  }
X      for (i = (y_height - 1); i <= (y_depth + 1); i++)
X	{
X	  c_ptr = &cave[i][x_left-1];
X	  if (c_ptr->fval != cur_floor.ftval)
X	    {
X	      c_ptr->fval  = rock_wall1.ftval;
X	      c_ptr->fopen = rock_wall1.ftopen;
X	    }
X	  c_ptr = &cave[i][x_right+1];
X	    if (c_ptr->fval != cur_floor.ftval)
X	      {
X		c_ptr->fval  = rock_wall1.ftval;
X		c_ptr->fopen = rock_wall1.ftopen;
X	      }
X	}
X      for (i = x_left; i <= x_right; i++)
X	{
X	  c_ptr = &cave[y_height-1][i];
X	  if (c_ptr->fval != cur_floor.ftval)
X	    {
X	      c_ptr->fval  = rock_wall1.ftval;
X	      c_ptr->fopen = rock_wall1.ftopen;
X	    }
X	  c_ptr = &cave[y_depth+1][i];
X	    if (c_ptr->fval != cur_floor.ftval)
X	      {
X		c_ptr->fval  = rock_wall1.ftval;
X		c_ptr->fopen = rock_wall1.ftopen;
X	      }
X	}
X    }
X}
X
X
X/* Builds an unusual room at a row, column coordinate	-RAK-	*/
X/* Type 2 unusual rooms all have an inner room:			*/
X/*   1 - Just an inner room with one door			*/
X/*   2 - An inner room within an inner room			*/
X/*   3 - An inner room with pillar(s)				*/
X/*   4 - Inner room has a maze					*/
X/*   5 - A set of four inner rooms				*/
Xbuild_type2(yval, xval)
Xint yval, xval;
X{
X  register int i, j;
X  register int y_height, y_depth;
X  register int x_left, x_right;
X  floor_type cur_floor;
X
X  if (dun_level <= randint(30))
X    cur_floor = lopen_floor;	/* Floor with light	*/
X  else
X    cur_floor = dopen_floor;	/* Dark floor		*/
X  y_height = yval - 4;
X  y_depth  = yval + 4;
X  x_left   = xval - 11;
X  x_right  = xval + 11;
X  for (i = y_height; i <= y_depth; i++)
X    for (j = x_left; j <= x_right; j++)
X      {
X	cave[i][j].fval  = cur_floor.ftval;
X	cave[i][j].fopen = cur_floor.ftopen;
X      }
X  for (i = (y_height - 1); i <= (y_depth + 1); i++)
X    {
X      cave[i][x_left-1].fval   = rock_wall1.ftval;
X      cave[i][x_left-1].fopen  = rock_wall1.ftopen;
X      cave[i][x_right+1].fval  = rock_wall1.ftval;
X      cave[i][x_right+1].fopen = rock_wall1.ftopen;
X    }
X  for (i = x_left; i <= x_right; i++)
X    {
X      cave[y_height-1][i].fval  = rock_wall1.ftval;
X      cave[y_height-1][i].fopen = rock_wall1.ftopen;
X      cave[y_depth+1][i].fval   = rock_wall1.ftval;
X      cave[y_depth+1][i].fopen  = rock_wall1.ftopen;
X    }
X  /* The inner room		*/
X  y_height = y_height + 2;
X  y_depth  = y_depth  - 2;
X  x_left   = x_left   + 2;
X  x_right  = x_right  - 2;
X  for (i = (y_height - 1); i <= (y_depth + 1); i++)
X    {
X      cave[i][x_left-1].fval   = 8;
X      cave[i][x_right+1].fval  = 8;
X    }
X  for (i = x_left; i <= x_right; i++)
X    {
X      cave[y_height-1][i].fval  = 8;
X      cave[y_depth+1][i].fval   = 8;
X    }
X  /* Inner room variations		*/
X  switch(randint(5))
X    {
X    case 1:	/* Just an inner room...	*/
X      switch(randint(4)) 	/* Place a door	*/
X	{
X	case 1:	place_secret_door(y_height-1, xval); break;
X	case 2:	place_secret_door(y_depth+1, xval); break;
X	case 3:	place_secret_door(yval, x_left-1); break;
X	case 4:	place_secret_door(yval, x_right+1); break;
X	}
X      vault_monster(yval, xval, 1);
X      break;
X    case 2:	/* Treasure Vault	*/
X      switch(randint(4))	/* Place a door	*/
X	{
X	case 1:	place_secret_door(y_height-1, xval); break;
X	case 2:	place_secret_door(y_depth+1, xval); break;
X	case 3:	place_secret_door(yval, x_left-1); break;
X	case 4:	place_secret_door(yval, x_right+1); break;
X	}
X      for (i = yval-1; i <= yval+1; i++)
X	{
X	  cave[i][xval-1].fval   = 8;
X	  cave[i][xval+1].fval   = 8;
X	}
X      cave[yval-1][xval].fval  = 8;
X      cave[yval+1][xval].fval  = 8;
X      switch(randint(4))	/* Place a door	*/
X	{
X	case 1:	place_locked_door(yval-1, xval); break;
X	case 2:	place_locked_door(yval+1, xval); break;
X	case 3:	place_locked_door(yval, xval-1); break;
X	case 4:	place_locked_door(yval, xval+1); break;
X	}
X      /* Place an object in the treasure vault	*/
X      switch(randint(10))
X	{
X	case 1: place_up_stairs(yval, xval); break;
X	case 2: place_down_stairs(yval, xval); break;
X	default: place_object(yval, xval); break;
X	}
X      /* Guard the treasure well		*/
X      vault_monster(yval, xval, 2+randint(3));
X      /* If the monsters don't get 'em...	*/
X      vault_trap(yval, xval, 4, 10, 2+randint(3));
X      break;
X    case 3:	/* Inner pillar(s)...	*/
X      switch(randint(4))  /* Place a door	*/
X	{
X	case 1:	place_secret_door(y_height-1, xval); break;
X	case 2:	place_secret_door(y_depth+1, xval); break;
X	case 3:	place_secret_door(yval, x_left-1); break;
X	case 4:	place_secret_door(yval, x_right+1); break;
X	}
X      for (i = yval-1; i <= yval+1; i++)
X	for (j = xval-1; j <= xval+1; j++)
X	  cave[i][j].fval   = 8;
X      if (randint(2) == 1)
X	{
X	  switch(randint(2))
X	    {
X	    case 1:
X	      for (i = yval-1; i <= yval+1; i++)
X		for (j = xval-6; j <= xval-4; j++)
X		  cave[i][j].fval   = 8;
X	      for (i = yval-1; i <= yval+1; i++)
X		for (j = xval+4; j <= xval+6; j++)
X		  cave[i][j].fval   = 8;
X	      break;
X	    case 2:
X	      for (i = yval-1; i <= yval+1; i++)
X		for (j = xval-7; j <= xval-5; j++)
X		  cave[i][j].fval   = 8;
X	      for (i = yval-1; i <= yval+1; i++)
X		for (j = xval+5; j <= xval+7; j++)
X		  cave[i][j].fval   = 8;
X	      break;
X	    }
X	}
X      if (randint(3) == 1) 	/* Inner rooms	*/
X	{
X	  for (i = xval-5; i <= xval+5; i++)
X	    {
X	      cave[yval-1][i].fval = 8;
X	      cave[yval+1][i].fval = 8;
X	    }
X	  cave[yval][xval-5].fval = 8;
X	  cave[yval][xval+5].fval = 8;
X	  switch(randint(2))
X	    {
X	    case 1: place_secret_door(yval+1, xval-3); break;
X	    case 2: place_secret_door(yval-1, xval-3); break;
X	    }
X	  switch(randint(2))
X	    {
X	    case 1: place_secret_door(yval+1, xval+3); break;
X	    case 2: place_secret_door(yval-1, xval+3); break;
X	    }
X	  if (randint(3) == 1)  place_object(yval, xval-2);
X	  if (randint(3) == 1)  place_object(yval, xval+2);
X	  vault_monster(yval, xval-2, randint(2));
X	  vault_monster(yval, xval+2, randint(2));
X	}
X      break;
X    case 4:	/* Maze inside...	*/
X      switch(randint(4))	/* Place a door	*/
X	{
X	case 1:	place_secret_door(y_height-1, xval); break;
X	case 2:	place_secret_door(y_depth+1, xval); break;
X	case 3:	place_secret_door(yval, x_left-1); break;
X	case 4:	place_secret_door(yval, x_right+1); break;
X	}
X      for (i = y_height; i <= y_depth; i++)
X	for (j = x_left; j <= x_right; j++)
X	  if (0x1 & (j+i))
X	    cave[i][j].fval = 8;
X      /* Monsters just love mazes...		*/
X      vault_monster(yval, xval-5, randint(3));
X      vault_monster(yval, xval+5, randint(3));
X      /* Traps make them entertaining...	*/
X      vault_trap(yval, xval-3, 2, 8, randint(3));
X      vault_trap(yval, xval+3, 2, 8, randint(3));
X      /* Mazes should have some treasure too..	*/
X      for (i = 0; i < 3; i++)
X	random_object(yval, xval, 1);
X      break;
X    case 5:	/* Four small rooms...	*/
X      for (i = y_height; i <= y_depth; i++)
X	cave[i][xval].fval = 8;
X      for (i = x_left; i <= x_right; i++)
X	cave[yval][i].fval = 8;
X      switch(randint(2))
X	{
X	case 1:
X	  i = randint(10);
X	  place_secret_door(y_height-1, xval-i);
X	  place_secret_door(y_height-1, xval+i);
X	  place_secret_door(y_depth+1, xval-i);
X	  place_secret_door(y_depth+1, xval+i);
X	  break;
X	case 2:
X	  i = randint(3);
X	  place_secret_door(yval+i, x_left-1);
X	  place_secret_door(yval-i, x_left-1);
X	  place_secret_door(yval+i, x_right+1);
X	  place_secret_door(yval-i, x_right+1);
X	  break;
X	}
X      /* Treasure in each one...		*/
X      random_object(yval, xval, 2+randint(2));
X      /* Gotta have some monsters...		*/
X      vault_monster(yval+2, xval-4, randint(2));
X      vault_monster(yval+2, xval+4, randint(2));
X      vault_monster(yval-2, xval-4, randint(2));
X      vault_monster(yval-2, xval+4, randint(2));
X      break;
X    }
X}
X
X
X/* Builds a room at a row, column coordinate		-RAK-	*/
X/* Type 3 unusual rooms are cross shaped				*/
Xbuild_type3(yval, xval)
Xint yval, xval;
X{
X  int y_height, y_depth;
X  int x_left, x_right;
X  register int i0, i, j;
X  floor_type cur_floor;
X  register cave_type *c_ptr;
X
X  if (dun_level <= randint(25))
X    cur_floor = lopen_floor;	/* Floor with light	*/
X  else
X    cur_floor = dopen_floor;	/* Dark floor		*/
X  i0 = 2 + randint(2);
X  y_height = yval - i0;
X  y_depth  = yval + i0;
X  x_left   = xval - 1;
X  x_right  = xval + 1;
X  for (i = y_height; i <= y_depth; i++)
X    for (j = x_left; j <= x_right; j++)
X      {
X	cave[i][j].fval  = cur_floor.ftval;
X	cave[i][j].fopen = cur_floor.ftopen;
X      }
X  for (i = (y_height - 1); i <= (y_depth + 1); i++)
X    {
X      c_ptr = &cave[i][x_left-1];
X      c_ptr->fval  = rock_wall1.ftval;
X      c_ptr->fopen = rock_wall1.ftopen;
X      c_ptr = &cave[i][x_right+1];
X      c_ptr->fval  = rock_wall1.ftval;
X      c_ptr->fopen = rock_wall1.ftopen;
X    }
X  for (i = x_left; i <= x_right; i++)
X    {
X      c_ptr = &cave[y_height-1][i];
X      c_ptr->fval  = rock_wall1.ftval;
X      c_ptr->fopen = rock_wall1.ftopen;
X      c_ptr = &cave[y_depth+1][i];
X      c_ptr->fval  = rock_wall1.ftval;
X      c_ptr->fopen = rock_wall1.ftopen;
X    }
X  i0 = 2 + randint(9);
X  y_height = yval - 1;
X  y_depth  = yval + 1;
X  x_left   = xval - i0;
X  x_right  = xval + i0;
X  for (i = y_height; i <= y_depth; i++)
X    for (j = x_left; j <= x_right; j++)
X      {
X	cave[i][j].fval  = cur_floor.ftval;
X	cave[i][j].fopen = cur_floor.ftopen;
X      }
X  for (i = (y_height - 1); i <= (y_depth + 1); i++)
X    {
X      c_ptr = &cave[i][x_left-1];
X      if (c_ptr->fval != cur_floor.ftval)
X	{
X	  c_ptr->fval  = rock_wall1.ftval;
X	  c_ptr->fopen = rock_wall1.ftopen;
X	}
X      c_ptr = &cave[i][x_right+1];
X      if (c_ptr->fval != cur_floor.ftval)
X	{
X	  c_ptr->fval  = rock_wall1.ftval;
X	  c_ptr->fopen = rock_wall1.ftopen;
X	}
X    }
X  for (i = x_left; i <= x_right; i++)
X    {
X      c_ptr = &cave[y_height-1][i];
X      if (c_ptr->fval != cur_floor.ftval)
X	{
X	  c_ptr->fval  = rock_wall1.ftval;
X	  c_ptr->fopen = rock_wall1.ftopen;
X	}
X      c_ptr = &cave[y_depth+1][i];
X      if (c_ptr->fval != cur_floor.ftval)
X	{
X	  c_ptr->fval  = rock_wall1.ftval;
X	  c_ptr->fopen = rock_wall1.ftopen;
X	}
X    }
X  /* Special features...			*/
X  switch(randint(4))
X    {
X    case 1:	/* Large middle pillar		*/
X      for (i = yval-1; i <= yval+1; i++)
X	for (j = xval-1; j <= xval+1; j++)
X	  cave[i][j].fval = 8;
X      break;
X    case 2:	/* Inner treasure vault		*/
X      for (i = yval-1; i <= yval+1; i++)
X	{
X	  cave[i][xval-1].fval   = 8;
X	  cave[i][xval+1].fval   = 8;
X	}
X      cave[yval-1][xval].fval  = 8;
X      cave[yval+1][xval].fval  = 8;
X      switch(randint(4))	/* Place a door	*/
X	{
X	case 1:	place_secret_door(yval-1, xval); break;
X	case 2:	place_secret_door(yval+1, xval); break;
X	case 3:	place_secret_door(yval, xval-1); break;
X	case 4:	place_secret_door(yval, xval+1); break;
X	}
X      /* Place a treasure in the vault		*/
X      place_object(yval, xval);
X      /* Let's guard the treasure well...	*/
X      vault_monster(yval, xval, 2+randint(2));
X      /* Traps naturally			*/
X      vault_trap(yval, xval, 4, 4, 1+randint(3));
X      break;
X    case 3:
X      if (randint(3) == 1)
X	{
X	  cave[yval-1][xval-2].fval = 8;
X	  cave[yval+1][xval-2].fval = 8;
X	  cave[yval-1][xval+2].fval = 8;
X	  cave[yval-1][xval+2].fval = 8;
X	  cave[yval-2][xval-1].fval = 8;
X	  cave[yval-2][xval+1].fval = 8;
X	  cave[yval+2][xval-1].fval = 8;
X	  cave[yval+2][xval+1].fval = 8;
X	  if (randint(3) == 1)
X	    {
X	      place_secret_door(yval, xval-2);
X	      place_secret_door(yval, xval+2);
X	      place_secret_door(yval-2, xval);
X	      place_secret_door(yval+2, xval);
X	    }
X	}
X      else if (randint(3) == 1)
X	{
X	  cave[yval][xval].fval = 8;
X	  cave[yval-1][xval].fval = 8;
X	  cave[yval+1][xval].fval = 8;
X	  cave[yval][xval-1].fval = 8;
X	  cave[yval][xval+1].fval = 8;
X	}
X      else if (randint(3) == 1)
X	cave[yval][xval].fval = 8;
X      break;
X    case 4:
X      break;
X    }
X}
X
X
X/* Constructs a tunnel between two points		*/
Xbuild_tunnel(row1, col1, row2, col2)
Xint row1, col1, row2, col2;
X{
X  register int tmp_row, tmp_col;
X  int row_dir, col_dir;
X  register int i, j;
X  coords tunstk[1000];
X  coords wallstk[1000];
X  int tunptr;
X  int wallptr;
X  int stop_flag, door_flag;
X  cave_type *c_ptr, *d_ptr;
X
X  /* Main procedure for Tunnel			*/
X  /* Note: 9 is a temporary value		*/
X  stop_flag = FALSE;
X  door_flag = FALSE;
X  tunptr    = 0;
X  wallptr   = 0;
X  correct_dir(&row_dir, &col_dir, row1, col1, row2, col2);
X  do
X    {
X      if (randint(100) > DUN_TUN_CHG)
X	rand_dir(&row_dir, &col_dir, row1, col1, row2, col2, DUN_TUN_RND);
X      tmp_row = row1 + row_dir;
X      tmp_col = col1 + col_dir;
X      while (!in_bounds(tmp_row, tmp_col))
X	{
X	  rand_dir(&row_dir, &col_dir, row1, col1, row2, col2, DUN_TUN_RND);
X	  tmp_row = row1 + row_dir;
X	  tmp_col = col1 + col_dir;
X	}
X      c_ptr = &cave[tmp_row][tmp_col];
X      if (c_ptr->fval == rock_wall1.ftval)
X	{
X	  row1 = tmp_row;
X	  col1 = tmp_col;
X	  wallstk[wallptr].y = row1;
X	  wallstk[wallptr].x = col1;
X	  if (wallptr < 1000)
X	    wallptr++;
X	  for (i = row1-1; i <= row1+1; i++)
X	    for (j = col1-1; j <= col1+1; j++)
X	      if (in_bounds(i, j))
X		{
X		  d_ptr = &cave[i][j];
X		  if ((d_ptr->fval >= 10) && (d_ptr->fval <= 12))
X		    d_ptr->fval = 9;
X		}
X	}
X      else if (c_ptr->fval == corr_floor1.ftval)
X	{
X	  row1 = tmp_row;
X	  col1 = tmp_col;
X	  if (!door_flag)
X	    {
X	      if (doorptr < 100)
X		{
X		  doorstk[doorptr].y = row1;
X		  doorstk[doorptr].x = col1;
X		  doorptr++;
X		}
X	      door_flag = TRUE;
X	    }
X	  if (randint(100) > DUN_TUN_CON)
X	    stop_flag = TRUE;
X	}
X      else if (c_ptr->fval == 0)
X	{
X	  row1 = tmp_row;
X	  col1 = tmp_col;
X	  tunstk[tunptr].y = row1;
X	  tunstk[tunptr].x = col1;
X	  if (tunptr < 1000)
X	    tunptr++;
X	  door_flag = FALSE;
X	}
X      else if (c_ptr->fval != 9)
X	{
X	  row1 = tmp_row;
X	  col1 = tmp_col;
X	}
X    }
X  while (((row1 != row2) || (col1 != col2)) && (!stop_flag));
X  for (i = 0; i < tunptr; i++)
X    {
X      cave[tunstk[i].y][tunstk[i].x].fval  = corr_floor1.ftval;
X      cave[tunstk[i].y][tunstk[i].x].fopen = corr_floor1.ftopen;
X    }
X  for (i = 0; i < wallptr; i++)
X    {
X      c_ptr = &cave[wallstk[i].y][wallstk[i].x];
X      if (c_ptr->fval == 9)
X	{
X	  if (randint(100) < DUN_TUN_PEN)
X	    place_door(wallstk[i].y, wallstk[i].x);
X	  else
X	    {
X	      c_ptr->fval  = corr_floor2.ftval;
X	      c_ptr->fopen = corr_floor2.ftopen;
X	    }
X	}
X    }
X}
X
X
Xint next_to(y, x)
Xregister int y, x;
X{
X  int next;
X
X  if (next_to8(y, x, 4, 5, 6) > 2)
X    if (((cave[y-1][x].fval >= 10) && (cave[y-1][x].fval <= 12)) &&
X	((cave[y+1][x].fval >= 10) && (cave[y+1][x].fval <= 12)))
X      next = TRUE;
X    else if (((cave[y][x-1].fval >= 10) && (cave[y][x-1].fval <= 12)) &&
X	     ((cave[y][x+1].fval >= 10) && (cave[y][x+1].fval <= 12)))
X      next = TRUE;
X    else
X      next = FALSE;
X  else
X    next = FALSE;
X  return(next);
X}
X
X/* Places door at y, x position if at least 2 walls found	*/
Xtry_door(y, x)
Xregister int y, x;
X{
X  if (randint(100) > DUN_TUN_JCT)
X    if (cave[y][x].fval == corr_floor1.ftval)
X      if (next_to(y, x))
X	place_door(y, x);
X}
X
X
X/* Cave logic flow for generation of new dungeon		*/
Xcave_gen()
X{
X  struct spot_type
X    {
X      int endx;
X      int endy;
X    };
X  int room_map[20][20];
X  register int i, j, k;
X  int y1, x1, y2, x2;
X  int pick1, pick2;
X  int row_rooms, col_rooms;
X  int alloc_level;
X  worlint yloc[400];
X  worlint xloc[400];
X
X  int set_1_2();
X  int set_1_2_4();
X  int set_4();
X
X  row_rooms = 2*(cur_height/SCREEN_HEIGHT);
X  col_rooms = 2*(cur_width /SCREEN_WIDTH);
X  for (i = 0; i < row_rooms; i++)
X    for (j = 0; j < col_rooms; j++)
X      room_map[i][j] = FALSE;
X  for (i = 0; i < randnor(DUN_ROO_MEA, 2); i++)
X    room_map[randint(row_rooms)-1][randint(col_rooms)-1] = TRUE;
X  k = 0;
X  for (i = 0; i < row_rooms; i++)
X    for (j = 0; j < col_rooms; j++)
X      if (room_map[i][j] == TRUE)
X	{
X	  yloc[k] = i * (QUART_HEIGHT * 2 + 1) + QUART_HEIGHT;
X	  xloc[k] = j * (QUART_WIDTH * 2 + 1) + QUART_WIDTH;
X	  if (dun_level > randint(DUN_UNUSUAL))
X	    switch(randint(3))
X	      {
X	      case 1: build_type1(yloc[k], xloc[k]); break;
X	      case 2: build_type2(yloc[k], xloc[k]); break;
X	      case 3: build_type3(yloc[k], xloc[k]); break;
X	      }
X	  else
X	    build_room(yloc[k], xloc[k]);
X	  k++;
X	}
X  for (i = 0; i < k; i++)
X    {
X      pick1 = randint(k) - 1;
X      pick2 = randint(k) - 1;
X      y1 = yloc[pick1];
X      x1 = xloc[pick1];
X      yloc[pick1] = yloc[pick2];
X      xloc[pick1] = xloc[pick2];
X      yloc[pick2] = y1;
X      xloc[pick2] = x1;
X      }
X  doorptr = 0;
X  for (i = 0; i < k-1; i++)
X    {
X      y1 = yloc[i];
X      x1 = xloc[i];
X      y2 = yloc[i+1];
X      x2 = xloc[i+1];
X      build_tunnel(y2, x2, y1, x1);
X      }
X  fill_cave(rock_wall1);
X  for (i = 0; i < DUN_STR_MAG; i++)
X    place_streamer(rock_wall2, DUN_STR_MC);
X  for (i = 0; i < DUN_STR_QUA; i++)
X    place_streamer(rock_wall3, DUN_STR_QC);
X  place_boundary();
X  /* Place intersection doors	*/
X  for (i = 0; i < doorptr; i++)
X    {
X      try_door(doorstk[i].y, doorstk[i].x-1);
X      try_door(doorstk[i].y, doorstk[i].x+1);
X      try_door(doorstk[i].y-1, doorstk[i].x);
X      try_door(doorstk[i].y+1, doorstk[i].x);
X    }
X  alloc_level = (dun_level/3);
X  if (alloc_level < 2)
X    alloc_level = 2;
X  else if (alloc_level > 10)
X    alloc_level = 10;
X  place_stairs(2, randint(2)+2, 3);
X  place_stairs(1, randint(2), 3);
X  alloc_monster(set_1_2, (randint(8)+MIN_MALLOC_LEVEL+alloc_level), 0, TRUE);
X  alloc_object(set_4, 3, randint(alloc_level));
X  alloc_object(set_1_2, 5, randnor(TREAS_ROOM_ALLOC, 3));
X  alloc_object(set_1_2_4, 5, randnor(TREAS_ANY_ALLOC, 3));
X  alloc_object(set_1_2_4, 4, randnor(TREAS_GOLD_ALLOC, 3));
X  alloc_object(set_1_2_4, 1, randint(alloc_level));
X  if (dun_level >= WIN_MON_APPEAR)  place_win_monster();
X}
X
X
X/* Builds a store at a row, column coordinate			*/
Xbuild_store(store_num, y, x)
Xint store_num, y, x;
X{
X  int yval, y_height, y_depth;
X  int xval, x_left, x_right;
X  register int i, j;
X  int cur_pos;
X  register cave_type *c_ptr;
X
X  yval	   = y*10 + 5;
X  xval     = x*16 + 16;
X  y_height = yval - randint(3);
X  y_depth  = yval + randint(4);
X  x_left   = xval - randint(6);
X  x_right  = xval + randint(6);
X  for (i = y_height; i <= y_depth; i++)
X    for (j = x_left; j <= x_right; j++)
X      {
X	cave[i][j].fval  = boundary_wall.ftval;
X	cave[i][j].fopen = boundary_wall.ftopen;
X      }
X  switch(randint(4))
X    {
X    case 1:
X      i = randint(y_depth-y_height) + y_height - 1;
X      j = x_left;
X      break;
X    case 2:
X      i = randint(y_depth-y_height) + y_height - 1;
X      j = x_right;
X      break;
X    case 3:
X      i = y_depth;
X      j = randint(x_right-x_left) + x_left - 1;
X      break;
X    case 4:
X      i = y_height;
X      j = randint(x_right-x_left) + x_left - 1;
X      break;
X    }
X  c_ptr = &cave[i][j];
X  c_ptr->fval  = corr_floor3.ftval;
X  c_ptr->fopen = corr_floor3.ftopen;
X  popt(&cur_pos);
X  c_ptr->tptr = cur_pos;
X  t_list[cur_pos] = store_door[store_num];
X}
X
X
X/* Town logic flow for generation of new town		*/
Xtown_gen()
X{
X  register int i, j, k, l, m;
X  int rooms[6];
X
X  int set_1_2();
X
X  set_seed(town_state, town_seed);
X  for (i = 0; i < 6; i++)
X    rooms[i] = i;
X  l = 6;
X  for (i = 0; i < 2; i++)
X    for (j = 0; j < 3; j++)
X      {
X	k = randint(l) - 1;
X	build_store(rooms[k], i, j);
X	for (m = k; m < l-1; m++)
X	  rooms[m] = rooms[m+1];
X	l--;
X      }
X  fill_cave(dopen_floor);
X  /* make stairs before reset_seed, so that they don't move around */
X  place_stairs(2, 1, 0);
X  place_boundary();
X  reset_seed();
X  if (0x1 & (turn / 5000))
X    {		/* Night	*/
X      for (i = 0; i < cur_height; i++)
X	for (j = 0; j < cur_width; j++)
X	  if (cave[i][j].fval != dopen_floor.ftval)
X	    cave[i][j].pl = TRUE;
X      alloc_monster(set_1_2, MIN_MALLOC_TN, 3, TRUE);
X    }
X  else
X    {		/* Day	*/
X      for (i = 0; i < cur_height; i++)
X	for (j = 0; j < cur_width; j++)
X	  cave[i][j].pl = TRUE;
X      alloc_monster(set_1_2, MIN_MALLOC_TD, 3, TRUE);
X    }
X  store_maint();
X}
X
X
X/* Generates a random dungeon level			-RAK-	*/
Xgenerate_cave()
X{
X  panel_row_min	= 0;
X  panel_row_max	= 0;
X  panel_col_min	= 0;
X  panel_col_max	= 0;
X  char_row		= -1;
X  char_col		= -1;
X
X  tlink();
X  mlink();
X  blank_cave();
X
X  if (dun_level == 0)
X    {
X      cur_height = SCREEN_HEIGHT;
X      cur_width  = SCREEN_WIDTH;
X      max_panel_rows = (cur_height/SCREEN_HEIGHT)*2 - 2;
X      max_panel_cols = (cur_width /SCREEN_WIDTH )*2 - 2;
X      panel_row = max_panel_rows;
X      panel_col = max_panel_cols;
X      town_gen();
X    }
X  else
X    {
X      cur_height = MAX_HEIGHT;
X      cur_width  = MAX_WIDTH;
X      max_panel_rows = (cur_height/SCREEN_HEIGHT)*2 - 2;
X      max_panel_cols = (cur_width /SCREEN_WIDTH )*2 - 2;
X      panel_row = max_panel_rows;
X      panel_col = max_panel_cols;
X      cave_gen();
X    }
X}
X
END_OF_FILE
if test 26802 -ne `wc -c <'generate.c'`; then
    echo shar: \"'generate.c'\" unpacked with wrong size!
fi
# end of 'generate.c'
fi
if test -f 'store2.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'store2.c'\"
else
echo shar: Extracting \"'store2.c'\" \(25318 characters\)
sed "s/^X//" >'store2.c' <<'END_OF_FILE'
X#include <stdio.h>
X
X#include "constants.h"
X#include "config.h"
X#include "types.h"
X#include "externs.h"
X
X#ifdef USG
X#include <string.h>
X#else
X#include <strings.h>
X#endif
X
X#ifdef sun   /* correct SUN stupidity in the stdio.h file */
Xchar *sprintf();
X#endif
X
Xdouble chr_adj();
X
X/* Comments vary...					-RAK-	*/
X/* Comment one : Finished haggling				*/
Xprt_comment1()
X{
X  msg_flag = FALSE;
X  switch(randint(14))
X    {
X    case 1: msg_print("Done!"); break;
X    case 2: msg_print("Accepted!"); break;
X    case 3: msg_print("Fine..."); break;
X    case 4: msg_print("Agreed!"); break;
X    case 5: msg_print("Okay..."); break;
X    case 6: msg_print("Taken!"); break;
X    case 7: msg_print("You drive a hard bargain, but taken..."); break;
X    case 8: msg_print("You'll force me bankrupt, but it's a deal..."); break;
X    case 9: msg_print("Sigh...  I'll take it..."); break;
X    case 10: msg_print("My poor sick children may starve, but done!"); break;
X    case 11: msg_print("Finally!  I accept..."); break;
X    case 12: msg_print("Robbed again..."); break;
X    case 13: msg_print("A pleasure to do business with you!"); break;
X    case 14: msg_print("My spouse will skin me, but accepted."); break;
X    }
X}
X
X
X/* %A1 is offer, %A2 is asking...		*/
Xprt_comment2(offer, asking, final)
Xint offer, asking, final;
X{
X  vtype comment;
X
X  if (final > 0)
X    switch(randint(3))
X      {
X      case 1:
X	(void) strcpy(comment,"%A2 is my final offer; take it or leave it...");
X	break;
X      case 2:
X	(void) strcpy(comment, "I'll give you no more than %A2.");
X	break;
X      case 3:
X	(void) strcpy(comment, "My patience grows thin...  %A2 is final.");
X	break;
X      }
X  else
X    switch(randint(16))
X      {
X      case 1:
X	(void) strcpy(comment,
X		      "%A1 for such a fine item?  HAH!  No less than %A2.");
X	break;
X      case 2:
X	(void) strcpy(comment, "%A1 is an insult!  Try %A2 gold pieces...");
X	break;
X      case 3:
X	(void) strcpy(comment,
X		      "%A1???  Thou wouldst rob my poor starving children?");
X	break;
X      case 4:
X	(void) strcpy(comment, "Why, I'll take no less than %A2 gold pieces.");
X	break;
X      case 5:
X	(void) strcpy(comment, "Ha!  No less than %A2 gold pieces.");
X	break;
X      case 6:
X	(void) strcpy(comment,
X		      "Thou knave!  No less than %A2 gold pieces.");
X	break;
X      case 7:
X	(void) strcpy(comment, "%A1 is far too little; how about %A2?");
X	break;
X      case 8:
X	(void) strcpy(comment, "I paid more than %A1 for it myself, try %A2.");
X	break;
X      case 9:
X	(void) strcpy(comment,
X		      "%A1?  Are you mad???  How about %A2 gold pieces?");
X	break;
X      case 10:
X	(void) strcpy(comment,
X		      "As scrap this would bring %A1.  Try %A2 in gold.");
X	break;
X      case 11:
X	(void) strcpy(comment,
X		      "May the fleas of 1000 orcs molest you.  I want %A2.");
X	break;
X      case 12:
X	(void) strcpy(comment,
X		      "My mother you can get for %A1, this costs %A2.");
X	break;
X      case 13:
X	(void) strcpy(comment,
X		      "May your chickens grow lips.  I want %A2 in gold!");
X	break;
X      case 14:
X	(void) strcpy(comment,
X		      "Sell this for such a pittance?  Give me %A2 gold.");
X	break;
X      case 15:
X	(void) strcpy(comment,
X		      "May the Balrog find you tasty!  %A2 gold pieces?");
X	break;
X      case 16:
X	(void) strcpy(comment,"Your mother was a Troll!  %A2 or I'll tell...");
X	break;
X      }
X  insert_num(comment, "%A1", offer, FALSE);
X  insert_num(comment, "%A2", asking, FALSE);
X  msg_print(comment);
X}
X
X
Xprt_comment3(offer, asking, final)
X     int offer, asking, final;
X{
X  vtype comment;
X
X  if (final > 0)
X    switch(randint(3))
X      {
X      case 1:
X	(void) strcpy(comment,
X		      "I'll pay no more than %A1; take it or leave it.");
X	break;
X      case 2:
X	(void) strcpy(comment, "You'll get no more than %A1 from me...");
X	break;
X      case 3:
X	(void) strcpy(comment, "%A1 and that's final.");
X	break;
X      }
X  else
X    switch(randint(15))
X      {
X      case 1:
X	(void) strcpy(comment,"%A2 for that piece of junk?  No more than %A1");
X	break;
X      case 2:
X	(void) strcpy(comment, "For %A2 I could own ten of those.  Try %A1.");
X	break;
X      case 3:
X	(void) strcpy(comment, "%A2?  NEVER!  %A1 is more like it...");
X	break;
X      case 4:
X	(void) strcpy(comment,
X		      "Let's be reasonable... How about %A1 gold pieces?");
X	break;
X      case 5:
X	(void) strcpy(comment, "%A1 gold for that junk, no more...");
X	break;
X      case 6:
X	(void) strcpy(comment, "%A1 gold pieces and be thankful for it!");
X	break;
X      case 7:
X	(void) strcpy(comment, "%A1 gold pieces and not a copper more...");
X	break;
X      case 8:
X	(void) strcpy(comment, "%A2 gold?  HA!  %A1 is more like it...");
X	break;
X      case 9:
X	(void) strcpy(comment, "Try about %A1 gold...");
X	break;
X      case 10:
X	(void) strcpy(comment,
X		      "I wouldn't pay %A2 for your children, try %A1.");
X	break;
X      case 11:
X	(void) strcpy(comment, "*CHOKE* For that!?  Let's say %A1.");
X	break;
X      case 12:
X	(void) strcpy(comment, "How about %A1?");
X	break;
X      case 13:
X	(void) strcpy(comment, "That looks war surplus!  Say %A1 gold.");
X	break;
X      case 14:
X	(void) strcpy(comment, "I'll buy it as scrap for %A1.");
X	break;
X      case 15:
X	(void) strcpy(comment, "%A2 is too much; let us say %A1 gold.");
X	break;
X      }
X  insert_num(comment, "%A1", offer, FALSE);
X  insert_num(comment, "%A2", asking, FALSE);
X  msg_print(comment);
X}
X
X
X/* Kick 'da bum out...					-RAK-	*/
Xprt_comment4()
X{
X  msg_flag = FALSE;
X  switch(randint(5))
X    {
X    case 1:
X      msg_print("ENOUGH!  Thou hast abused me once too often!");
X      msg_print("Out of my place!");
X      break;
X    case 2:
X      msg_print("THAT DOES IT!  You shall waste my time no more!");
X      msg_print("out... Out... OUT!!!");
X      break;
X    case 3:
X      msg_print("This is getting nowhere...  I'm going home!");
X      msg_print("Come back tomorrow...");
X      break;
X    case 4:
X      msg_print("BAH!  No more shall you insult me!");
X      msg_print("Leave my place...  Begone!");
X      break;
X    case 5:
X      msg_print("Begone!  I have had enough abuse for one day.");
X      msg_print("Come back when thou art richer...");
X      break;
X    }
X  /* make sure player sees last message, before he is kicked out of store */
X  msg_print(" ");
X  msg_flag = FALSE;
X}
X
X
Xprt_comment5()
X{
X  switch(randint(10))
X    {
X    case 1: msg_print("You will have to do better than that!"); break;
X    case 2: msg_print("That's an insult!"); break;
X    case 3: msg_print("Do you wish to do business or not?"); break;
X    case 4: msg_print("Hah!  Try again..."); break;
X    case 5: msg_print("Ridiculous!"); break;
X    case 6: msg_print("You've got to be kidding!"); break;
X    case 7: msg_print("You'd better be kidding!!"); break;
X    case 8: msg_print("You try my patience."); break;
X    case 9: msg_print("I don't hear you."); break;
X    case 10: msg_print("Hmmm, nice weather we're having..."); break;
X    }
X}
X
X
Xprt_comment6()
X{
X  switch(randint(5))
X    {
X    case 1: msg_print("I must have heard you wrong..."); break;
X    case 2: msg_print("What was that?"); break;
X    case 3: msg_print("I'm sorry, say that again..."); break;
X    case 4: msg_print("What did you say?"); break;
X    case 5: msg_print("Sorry, what was that again?"); break;
X    }
X}
X
X
X/* Displays the set of commands				-RAK-	*/
Xdisplay_commands()
X{
X  prt("You may:", 20, 0);
X  prt(" p) Purchase an item.           b) Browse store's inventory.", 21, 0);
X  prt(" s) Sell an item.               i) Inventory and Equipment Lists.",
X      22, 0);
X  prt("ESC) Exit from Building.       ^R) Redraw the screen.", 23, 0);
X}
X
X
X/* Displays the set of commands				-RAK-	*/
Xhaggle_commands(typ)
Xint typ;
X{
X  if (typ == -1)
X    prt("Specify an asking-price in gold pieces.", 21, 0);
X  else
X    prt("Specify an offer in gold pieces.", 21, 0);
X  prt("ESC) Quit Haggling.", 22, 0);
X  prt("", 23, 0);  /* clear last line */
X}
X
X
X/* Displays a store's inventory				-RAK-	*/
Xdisplay_inventory(store_num, start)
Xint store_num, start;
X{
X  register store_type *s_ptr;
X  register treasure_type *i_ptr;
X  register int i, j, stop;
X  vtype out_val1, out_val2;
X
X  s_ptr = &store[store_num];
X  i = (start % 12);
X  stop = ((start / 12) + 1) * 12;
X  if (stop > s_ptr->store_ctr)  stop = s_ptr->store_ctr;
X  while (start < stop)
X    {
X      inventory[INVEN_MAX] = s_ptr->store_inven[start].sitem;
X      i_ptr = &inventory[INVEN_MAX];
X      if ((i_ptr->subval > 255) && (i_ptr->subval < 512))
X	i_ptr->number = 1;
X      objdes(out_val1, INVEN_MAX, TRUE);
X      (void) sprintf(out_val2, "%c) %s", 97+i, out_val1);
X      prt(out_val2, i+5, 0);
X      if (s_ptr->store_inven[start].scost <= 0)
X	{
X	  j = abs(s_ptr->store_inven[start].scost);
X	  j += (j * chr_adj());
X	  if (j <= 0)
X	    j = 1;
X	  (void) sprintf(out_val2, "%9d", j);
X	}
X      else
X	(void) sprintf(out_val2,"%9d [Fixed]",s_ptr->store_inven[start].scost);
X      prt(out_val2, i+5, 59);
X      i++;
X      start++;
X    }
X  if (i < 12)
X    for (j = 0; j < (11 - i + 1); j++)
X      prt("", j+i+5, 0);  /* clear remaining lines */
X  if (s_ptr->store_ctr > 12)
X    prt("- cont. -", 17, 60);
X  else
X    prt("", 17, 60);  /* clear the line */
X}
X
X
X/* Re-displays only a single cost			-RAK-	*/
Xdisplay_cost(store_num, pos)
Xint store_num, pos;
X{
X  register int i, j;
X  vtype out_val;
X  register store_type *s_ptr;
X
X  s_ptr = &store[store_num];
X  i = (pos % 12);
X  if (s_ptr->store_inven[pos].scost < 0)
X    {
X      j = abs(s_ptr->store_inven[pos].scost);
X      j += (j*chr_adj());
X      (void) sprintf(out_val, "%d", j);
X    }
X  else
X    (void) sprintf(out_val, "%9d [Fixed]", s_ptr->store_inven[pos].scost);
X  prt(out_val, i+5, 59);
X}
X
X
X/* Displays players gold					-RAK-	*/
Xstore_prt_gold()
X{
X  vtype out_val;
X
X  (void) sprintf(out_val, "Gold Remaining : %d", py.misc.au);
X  prt(out_val, 18, 17);
X}
X
X
X/* Displays store					-RAK-	*/
Xdisplay_store(store_num, cur_top)
Xint store_num, cur_top;
X{
X  register store_type *s_ptr;
X
X  s_ptr = &store[store_num];
X  really_clear_screen();
X  prt(owners[s_ptr->owner].owner_name, 3, 9);
X  prt("   Item", 4, 0);
X  prt("Asking Price", 4, 60);
X  store_prt_gold();
X  display_commands();
X  display_inventory(store_num, cur_top);
X}
X
X
X/* Get the ID of a store item and return it's value	-RAK-	*/
Xint get_store_item(com_val, pmt, i, j)
Xint *com_val;
Xchar *pmt;
Xregister int i, j;
X{
X  char command;
X  vtype out_val;
X  register int flag;
X
X  *com_val = -1;
X  flag = TRUE;
X  (void) sprintf(out_val, "(Items %c-%c, ESC to exit) %s", i+97, j+97, pmt);
X  while (((*com_val < i) || (*com_val > j)) && (flag))
X    {
X      prt(out_val, 0, 0);
X      inkey(&command);
X      *com_val = (command);
X      switch(*com_val)
X	{
X	case 0: case 27: flag = FALSE; break;
X	default: *com_val = *com_val - 97; break;
X	}
X    }
X  msg_flag = FALSE;
X  erase_line(MSG_LINE, 0);
X  return(flag);
X}
X
X
X/* Increase the insult counter and get pissed if too many -RAK-	*/
Xint increase_insults(store_num)
Xint store_num;
X{
X  register int increase;
X  register store_type *s_ptr;
X
X  increase = FALSE;
X  s_ptr = &store[store_num];
X  s_ptr->insult_cur++;
X  if (s_ptr->insult_cur > owners[s_ptr->owner].insult_max)
X    {
X      prt_comment4();
X      s_ptr->insult_cur = 0;
X      s_ptr->store_open = turn + 2500 + randint(2500);
X      increase = TRUE;
X    }
X  return(increase);
X}
X
X
X/* Decrease insults					-RAK-	*/
Xdecrease_insults(store_num)
Xint store_num;
X{
X  register store_type *s_ptr;
X
X  s_ptr = &store[store_num];
X  s_ptr->insult_cur -= 2;
X  if (s_ptr->insult_cur < 0)  s_ptr->insult_cur = 0;
X}
X
X
X/* Have insulted while haggling				-RAK-	*/
Xint haggle_insults(store_num)
Xint store_num;
X{
X  register int haggle;
X
X  haggle = FALSE;
X  if (increase_insults(store_num))
X    haggle = TRUE;
X  else
X    prt_comment5();
X  return(haggle);
X}
X
X
Xint get_haggle(comment, num)
Xchar *comment;
Xint *num;
X{
X  int i;
X  vtype out_val;
X  register int flag, clen;
X
X  flag = TRUE;
X  i = 0;
X  clen = strlen(comment);
X  do
X    {
X      msg_print(comment);
X      msg_flag = FALSE;
X      if (!get_string(out_val, 0, clen, 40))
X	{
X	  flag = FALSE;
X	  erase_line(MSG_LINE, 0);
X	}
X      (void) sscanf(out_val, "%d", &i);
X    }
X  while ((i <= 0) && (flag));
X  if (flag)  *num = i;
X  return(flag);
X}
X
X
Xint receive_offer(store_num, comment, new_offer, last_offer, factor)
Xint store_num;
Xchar *comment;
Xint *new_offer;
Xint last_offer, factor;
X{
X  register int flag;
X  register int receive;
X
X  receive = 0;
X  flag = FALSE;
X  do
X    {
X      if (get_haggle(comment, new_offer))
X	{
X	  if (*new_offer*factor >= last_offer*factor)
X	    flag = TRUE;
X	  else if (haggle_insults(store_num))
X	    {
X	      receive = 2;
X	      flag = TRUE;
X	    }
X	}
X      else
X	{
X	  receive = 1;
X	  flag = TRUE;
X	}
X    }
X  while (!flag);
X  return(receive);
X}
X
X
X/* Haggling routine					-RAK-	*/
Xint purchase_haggle(store_num, price, item)
Xint store_num;
Xint *price;
Xtreasure_type item;
X{
X  int max_sell, min_sell, max_buy;
X  int cost, cur_ask, final_ask, min_offer;
X  int last_offer, new_offer, final_flag, x3;
X  double x1, x2;
X  double min_per, max_per;
X  register int flag, loop_flag;
X  vtype out_val, comment;
X  int purchase;
X  register store_type *s_ptr;
X  register owner_type *o_ptr;
X
X  flag = FALSE;
X  purchase = 0;
X  *price = 0;
X  final_flag = 0;
X  msg_flag = FALSE;
X  s_ptr = &store[store_num];
X  o_ptr = &owners[s_ptr->owner];
X  cost = sell_price(store_num, &max_sell, &min_sell, item);
X  max_sell = max_sell + (max_sell*chr_adj());
X  if (max_sell <= 0)  max_sell = 1;
X  min_sell = min_sell + (min_sell*chr_adj());
X  if (min_sell <= 0)  min_sell = 1;
X  max_buy  = (cost*(1-o_ptr->max_inflate));
X  min_per  = o_ptr->haggle_per;
X  max_per  = min_per*3.0;
X  haggle_commands(1);
X  cur_ask   = max_sell;
X  final_ask = min_sell;
X  min_offer = max_buy;
X  last_offer = min_offer;
X  (void) strcpy(comment, "Asking : ");
X  do
X    {
X      do
X	{
X	  loop_flag = TRUE;
X	  (void) sprintf(out_val, "%s %d", comment, cur_ask);
X	  put_buffer(out_val, 1, 0);
X	  switch(receive_offer(store_num, "What do you offer? ",
X			     &new_offer, last_offer, 1))
X	    {
X	    case 1:
X	      purchase = 1;
X	      flag   = TRUE;
X	      break;
X	    case 2:
X	      purchase = 2;
X	      flag   = TRUE;
X	      break;
X	    default:
X	      if (new_offer > cur_ask)
X		{
X		  prt_comment6();
X		}
X	      else if (new_offer == cur_ask)
X		{
X		  flag = TRUE;
X		  *price = new_offer;
X		}
X	      else
X		loop_flag = FALSE;
X	    }
X	}
X      while (!flag && loop_flag);
X      if (!flag)
X	{
X	  x1 = (double)(new_offer - last_offer)/(double)(cur_ask - last_offer);
X	  if (x1 < min_per)
X	    {
X	      flag = haggle_insults(store_num);
X	      if (flag)  purchase = 2;
X	    }
X	  else
X	    {
X	      if (x1 > max_per)
X		{
X		  x1 = x1*0.75;
X		  if (x1 < max_per)  x1 = max_per;
X		}
X	    }
X	  x2 = (x1 + (randint(5) - 3)/100.0);
X	  x3 = ((cur_ask-new_offer)*x2) + 1;
X	  /* don't let the price go up */
X	  if (x3 < 0)
X	    x3 = 0;
X	  cur_ask -= x3;
X	  if (cur_ask < final_ask)
X	    {
X	      cur_ask = final_ask;
X	      (void) strcpy(comment, "Final Offer : ");
X	      final_flag++;
X	      if (final_flag > 3)
X		{
X		  if (increase_insults(store_num))
X		    purchase = 2;
X		  else
X		    purchase = 1;
X		  flag = TRUE;
X		}
X	    }
X	  else if (new_offer >= cur_ask)
X	    {
X	      flag = TRUE;
X	      *price = new_offer;
X	    }
X	  if (!flag)
X	    {
X	      last_offer = new_offer;
X	      prt("", 1, 0);  /* clear the line */
X	      (void) sprintf(out_val, "Your last offer : %d", last_offer);
X	      put_buffer(out_val, 1, 39);
X	      prt_comment2(last_offer, cur_ask, final_flag);
X	    }
X	}
X    }
X  while (!flag);
X  prt("", 1, 0);  /* clear the line */
X  display_commands();
X  return(purchase);
X}
X
X
X/* Haggling routine					-RAK-	*/
Xint sell_haggle(store_num, price, item)
Xint store_num;
Xint *price;
Xtreasure_type item;
X{
X  int max_sell, max_buy, min_buy;
X  int cost, cur_ask, final_ask, min_offer;
X  int last_offer, new_offer, final_flag, x3;
X  int max_gold;
X  double x1, x2;
X  double min_per, max_per;
X  register int flag, loop_flag;
X  vtype comment, out_val;
X  register store_type *s_ptr;
X  register owner_type *o_ptr;
X  int sell;
X
X  flag = FALSE;
X  sell = 0;
X  *price = 0;
X  final_flag = 0;
X  msg_flag = FALSE;
X  s_ptr = &store[store_num];
X  cost = item_value(item);
X  if (cost < 1)
X    {
X      sell = 3;
X      flag = TRUE;
X    }
X  else
X    {
X      o_ptr = &owners[s_ptr->owner];
X      cost += -(cost*chr_adj()) -
X	       (cost*rgold_adj[o_ptr->owner_race][py.misc.prace]);
X      if (cost < 1)  cost = 1;
X      max_sell = (cost*(1+o_ptr->max_inflate));
X      max_buy  = (cost*(1-o_ptr->max_inflate));
X      min_buy  = (cost*(1-o_ptr->min_inflate));
X      if (min_buy < 1) min_buy = 1;
X      if (max_buy < 1) max_buy = 1;
X      if (min_buy < max_buy)  min_buy = max_buy;
X      min_per  = o_ptr->haggle_per;
X      max_per  = min_per*3.0;
X      max_gold = o_ptr->max_cost;
X    }
X  if (!flag)
X    {
X      haggle_commands(-1);
X      if (max_buy > max_gold)
X	{
X	  final_flag= 1;
X	  (void) strcpy(comment, "Final offer : ");
X	  cur_ask   = max_gold;
X	  final_ask = max_gold;
X msg_print("I am sorry, but I have not the money to afford such a fine item.");
X	  /* make sure player see the message */
X	  msg_print(" ");
X	}
X      else
X	{
X	  cur_ask   = max_buy;
X	  final_ask = min_buy;
X	  if (final_ask > max_gold)
X	    final_ask = max_gold;
X	  (void) strcpy(comment, "Offer : ");
X	}
X      min_offer = max_sell;
X      last_offer = min_offer;
X      if (cur_ask < 1)  cur_ask = 1;
X      do
X	{
X	  do
X	    {
X	      loop_flag = TRUE;
X	      (void) sprintf(out_val, "%s %d", comment, cur_ask);
X	      put_buffer(out_val, 1, 0);
X	      switch(receive_offer(store_num, "What price do you ask? ",
X				 &new_offer, last_offer, -1))
X		{
X		case 1:
X		  sell = 1;
X		  flag   = TRUE;
X		  break;
X		case 2:
X		  sell = 2;
X		  flag   = TRUE;
X		  break;
X		default:
X		  if (new_offer < cur_ask)
X		    {
X		      prt_comment6();
X		    }
X		  else if (new_offer == cur_ask)
X		    {
X		      flag = TRUE;
X		      *price = new_offer;
X		    }
X		  else
X		    loop_flag = FALSE;
X	        }
X	    }
X	  while (!flag && loop_flag);
X	  if (!flag)
X	    {
X	      msg_flag = FALSE;
X	      x1 = (double)(last_offer - new_offer)/
X		(double)(last_offer - cur_ask);
X	      if (x1 < min_per)
X		{
X		  flag = haggle_insults(store_num);
X		  if (flag)  sell = 2;
X		}
X	      else
X		{
X		  if (x1 > max_per)
X		    {
X		      x1 = x1 * 0.75;
X		      if (x1 < max_per)  x1 = max_per;
X		    }
X		}
X	      x2 = (x1 + (randint(5) - 3)/100.0);
X	      x3 = ((new_offer-cur_ask)*x2) + 1;
X	      /* don't let the price go down */
X	      if (x3 < 0)
X		x3 = 0;
X	      cur_ask += x3;
X	      if (cur_ask > final_ask)
X		{
X		  cur_ask = final_ask;
X		  (void) strcpy(comment, "Final Offer : ");
X		  final_flag++;
X		  if (final_flag > 3)
X		    {
X		      if (increase_insults(store_num))
X			sell = 2;
X		      else
X			sell = 1;
X		      flag = TRUE;
X		    }
X		}
X	      else if (new_offer <= cur_ask)
X		{
X		  flag = TRUE;
X		  *price = new_offer;
X		}
X	      if (!flag)
X		{
X		  last_offer = new_offer;
X		  prt("", 1, 0);  /* clear the line */
X		  (void) sprintf(out_val, "Your last bid %d", last_offer);
X		  put_buffer(out_val, 1, 39);
X		  prt_comment3(cur_ask, last_offer, final_flag);
X		}
X	    }
X	}
X      while (!flag);
X      prt("", 1, 0);  /* clear the line */
X      display_commands();
X    }
X  return(sell);
X}
X
X
X/* Buy an item from a store				-RAK-	*/
Xint store_purchase(store_num, cur_top)
Xint store_num;
Xint *cur_top;
X{
X  int i, item_val, price;
X  int item_new, choice;
X  int save_number;
X  vtype out_val, tmp_str;
X  register store_type *s_ptr;
X  register treasure_type *i_ptr;
X  register inven_record *r_ptr;
X  int purchase;
X
X  purchase = FALSE;
X  s_ptr = &store[store_num];
X  /* i == number of objects shown on screen	*/
X  if (*cur_top == 12)
X    i = s_ptr->store_ctr - 1 - 12;
X  else if (s_ptr->store_ctr > 11)
X    i = 11;
X  else
X    i = s_ptr->store_ctr - 1;
X  if (s_ptr->store_ctr < 1)
X    msg_print("I am currently out of stock.");
X      /* Get the item number to be bought		*/
X  else if (get_store_item(&item_val,
X			  "Which item are you interested in? ", 0, i))
X    {
X      item_val = item_val + *cur_top;	/* TRUE item_val	*/
X      inventory[INVEN_MAX] = s_ptr->store_inven[item_val].sitem;
X      i_ptr = &inventory[INVEN_MAX];
X      if ((i_ptr->subval > 255) && (i_ptr->subval < 512))
X	{
X	  save_number = i_ptr->number;
X	  i_ptr->number = 1;
X	}
X      else
X	save_number = 1;
X      if (inven_check_weight())
X	if (inven_check_num())
X	  {
X	    if (s_ptr->store_inven[item_val].scost > 0)
X	      {
X		price = s_ptr->store_inven[item_val].scost;
X		choice = 0;
X	      }
X	    else
X	      choice = purchase_haggle(store_num, &price,
X				       inventory[INVEN_MAX]);
X	    switch(choice)
X	      {
X	      case 0:
X		if (py.misc.au >= price)
X		  {
X		    prt_comment1();
X		    decrease_insults(store_num);
X		    py.misc.au -= price;
X		    store_destroy(store_num, item_val, TRUE);
X		    inven_carry(&item_new);
X		    objdes(tmp_str, item_new, TRUE);
X		    (void) sprintf(out_val, "You have %s (%c)",
X				   tmp_str, item_new+97);
X		    msg_print(out_val);
X		    if (*cur_top >= s_ptr->store_ctr)
X		      {
X			*cur_top = 0;
X			display_inventory(store_num, *cur_top);
X		      }
X		    else
X		      {
X			r_ptr = &s_ptr->store_inven[item_val];
X			if (save_number > 1)
X			  {
X			    if (r_ptr->scost < 0)
X			      {
X				r_ptr->scost = price;
X				display_cost(store_num, item_val);
X			      }
X			  }
X			else
X			  display_inventory(store_num, item_val);
X			store_prt_gold();
X		      }
X		  }
X		else
X		  {
X		    if (increase_insults(store_num))
X		      purchase = TRUE;
X		    else
X		      {
X			prt_comment1();
X			msg_print("Liar!  You have not the gold!");
X		      }
X		  }
X		break;
X	      case 2:
X		purchase = TRUE;
X		break;
X	      default:
X		break;
X	      }
X	    prt("", 1, 0);  /* clear the line */
X	  }
X	else
X	  prt("You cannot carry that many different items.", 0, 0);
X      else
X	prt("You can not carry that much weight.", 0, 0);
X    }
X  return(purchase);
X}
X
X
X/* Sell an item to the store				-RAK-	*/
Xint store_sell(store_num, cur_top)
Xint store_num, cur_top;
X{
X  int item_val;
X  int item_pos, price;
X  int redraw;
X  vtype out_val, tmp_str;
X  register treasure_type *i_ptr;
X  register int sell;
X
X  sell = FALSE;
X  redraw = FALSE;
X  if (get_item(&item_val, "Which one? ", &redraw, 0, inven_ctr-1))
X    {
X      if (redraw)  display_store(store_num, cur_top);
X      inventory[INVEN_MAX] = inventory[item_val];
X      i_ptr = &inventory[INVEN_MAX];
X      if ((i_ptr->subval > 255) && (i_ptr->subval < 512))
X	i_ptr->number = 1;
X      objdes(tmp_str, INVEN_MAX, TRUE);
X      (void) sprintf(out_val, "Selling %s (%c)", tmp_str, item_val+97);
X      msg_print(out_val);
X      /* make sure player sees the message */
X      msg_print(" ");
X      if ((store_buy[store_num])(inventory[INVEN_MAX].tval))
X	if (store_check_num(store_num))
X	  switch(sell_haggle(store_num, &price, inventory[INVEN_MAX]))
X	    {
X	    case 0:
X	      prt_comment1();
X	      py.misc.au += price;
X	      inven_destroy(item_val);
X	      store_carry(store_num, &item_pos);
X	      if (item_pos >= 0)
X		if (item_pos < 12)
X		  if (cur_top < 12)
X		    display_inventory(store_num, item_pos);
X		  else
X		    display_inventory(store_num, cur_top);
X		else if (cur_top > 11)
X		  display_inventory(store_num, item_pos);
X	      store_prt_gold();
X	      break;
X	    case 2:
X	      sell = TRUE;
X	      break;
X	    case 3:
X	      msg_print("How dare you!");
X	      msg_print("I will not buy that!");
X	      sell = increase_insults(store_num);
X	      break;
X	    default:
X	      break;
X	    }
X	else
X	  prt("I have not the room in my store to keep it...", 0, 0);
X      else
X	prt("I do not buy such items.", 0, 0);
X    }
X  else if (redraw)
X    display_store(store_num, cur_top);
X  return(sell);
X}
X
X
X/* Entering a store					-RAK-	*/
Xenter_store(store_num)
Xint store_num;
X{
X  int com_val, cur_top;
X  char command;
X  register int exit_flag;
X  register store_type *s_ptr;
X
X  s_ptr = &store[store_num];
X  if (s_ptr->store_open < turn)
X    {
X      exit_flag = FALSE;
X      cur_top = 0;
X      display_store(store_num, cur_top);
X      do
X	{
X	  if (get_com("", &command))
X	    {
X	      msg_flag = FALSE;
X	      com_val = (command);
X	      switch(com_val)
X		{
X		case 18:
X		  display_store(store_num, cur_top);
X		  break;
X		case 98:
X		  if (cur_top == 0)
X		    if (s_ptr->store_ctr > 12)
X		      {
X			cur_top = 12;
X			display_inventory(store_num, cur_top);
X		      }
X		    else
X		      prt("Entire inventory is shown.", 0, 0);
X		  else
X		    {
X		      cur_top = 0;
X		      display_inventory(store_num, cur_top);
X		    }
X		  break;
X		case 101:      /* Equipment List	*/
X		  if (inven_command('e', 0, 0))
X		    display_store(store_num, cur_top);
X		  break;
X		case 105:      /* Inventory		*/
X		  if (inven_command('i', 0, 0))
X		    display_store(store_num, cur_top);
X		  break;
X		case 116:      /* Take off		*/
X		  if (inven_command('t', 0, 0))
X		    display_store(store_num, cur_top);
X		  break;
X		case 119:	/* Wear			*/
X		  if (inven_command('w', 0, 0))
X		    display_store(store_num, cur_top);
X		  break;
X		case 120:     /* Switch weapon		*/
X		  if (inven_command('x', 0, 0))
X		    display_store(store_num, cur_top);
X		  break;
X		case 112:
X		  exit_flag = store_purchase(store_num, &cur_top);
X		  break;
X		case 115:
X		  exit_flag = store_sell(store_num, cur_top);
X		  break;
X		default:
X		  prt("Invalid Command.", 0, 0);
X		  break;
X		}
X	    }
X	  else
X	    exit_flag = TRUE;
X	}
X      while (!exit_flag);
X      draw_cave();
X    }
X  else
X    msg_print("The doors are locked.");
X}
END_OF_FILE
if test 25318 -ne `wc -c <'store2.c'`; then
    echo shar: \"'store2.c'\" unpacked with wrong size!
fi
# end of 'store2.c'
fi
echo shar: End of archive 14 \(of 18\).
cp /dev/null ark14isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 18 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