*** old/src/generate.c	Thu Dec 21 08:38:36 1995
--- src/generate.c	Thu Jan 04 20:36:50 1996
***************
*** 3639,3645 ****
--- 3639,4220 ----
      }
  }
  
+ /*
+  * Find a position suitable for placing something (stairs, obstacles) -EK-
+  *
+  * It's a bit away from the outer walls and it's inside a 3x3 grid
+  * of emptiness. 
+  *
+  * If "part" is greater than 1, then the position
+  * is further restricted to fit into the lower (or the left) 
+  * "1/part"th part of the dungen. This is used for pillars that leave
+  * open a large free space in the middle of the level.
+  *
+  * Returns FALSE if no position could be found to prevent infitive loops.
+  */
+ static bool ek_level_gen_aux(int *x,int *y,int part)
+ {
+     int dx,dy,count;
+ 
+     count=100;
+ 
+     if (part<1) part=1;
+ 
+     while (count--) 
+     {
+         /* Pick a location at least "three" from the outer walls */
+         if (rand_int(2))
+         {
+             *y = rand_range(3, cur_hgt - 4);
+             *x = rand_range(3, cur_wid/part - 4);
+         }
+         else 
+         {
+             *y = rand_range(3, cur_hgt/part - 4);
+             *x = rand_range(3, cur_wid - 4);
+         }
+     
+         /* Require a "naked" floor grid inside of 3x3 naked floor grids */
+         for (dx=-1; dx<=1; dx++)
+             for (dy=-1; dy<=1; dy++)
+                 if (!naked_grid_bold(dy+*y, dx+*x)) break;
+ 
+         if (dx>1 && dy>1) break;
+     }
+ 
+     if (count) return TRUE;
+ 
+     return FALSE;
+ }
+ 
+ /*
+  * Place 4 pieces of granite, checking for validity        -EK-
+  */
+ static void ek_level_gen_aux2(int x,int y)
+ {
+     cave_type *c_ptr;
+ 
+     if (x<0 || x>=cur_wid || y<0 || y>=cur_hgt) return;
+ 
+     c_ptr = &cave[y][x];                            
+     c_ptr->feat = ((c_ptr->feat & ~0x3f) | 0x38);   /* Clear, add perma-wall */
+ 
+     c_ptr = &cave[cur_hgt-y][x];                            
+     c_ptr->feat = ((c_ptr->feat & ~0x3f) | 0x38);   /* Clear, add perma-wall */
+ 
+     c_ptr = &cave[y][cur_wid-x];                            
+     c_ptr->feat = ((c_ptr->feat & ~0x3f) | 0x38);   /* Clear, add perma-wall */
+ 
+     c_ptr = &cave[cur_hgt-y][cur_wid-x];                            
+     c_ptr->feat = ((c_ptr->feat & ~0x3f) | 0x38);   /* Clear, add perma-wall */
+ }
+ 
+ /*
+  * Reject breaders                                       -EK- 
+  */
+ 
+ static bool ek_level_gen_monster_hook(int r_idx) 
+ {
+     monster_race *r_ptr = &r_info[r_idx];
+ 
+     if (r_ptr->flags2 & RF2_MULTIPLY) return FALSE;
+ 
+     return TRUE;
+ }
+ 
+ /*
+  * Choose monster for camp fire                          -EK- 
+  */
+ 
+ static bool ek_level_gen_monster_hook2(int r_idx) 
+ {
+     monster_race *r_ptr = &r_info[r_idx];
+ 
+     /* Hack -- Require "o" monsters */
+     if (!strchr("o", r_ptr->r_char) &&
+         !strchr("O", r_ptr->r_char) &&
+         !strchr("P", r_ptr->r_char) &&
+         !strchr("h", r_ptr->r_char) &&
+         !strchr("T", r_ptr->r_char)) return (FALSE);
+ 
+     /* Hack -- do not allow "BLINK" monsters */
+     if (r_ptr->flags6 & RF6_BLINK) return (FALSE);
+     
+     /* Hack -- do not allow "INVISIBLE" monsters */
+     if (r_ptr->flags2 & RF2_INVISIBLE) return (FALSE); 
+ 
+     /* Hack -- Skip unique monsters */
+     if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
+ 
+     /* Hack -- Skip multiplying monsters */
+     if (r_ptr->flags2 & RF2_MULTIPLY) return (FALSE);
+ 
+     /* Okay */
+     return (TRUE);
+ }
+ 
+ /*
+  * Reject monsters less than monster_level               -EK- 
+  */
+ 
+ static bool ek_level_gen_monster_hook3(int r_idx) 
+ {
+     monster_race *r_ptr = &r_info[r_idx];
+ 
+     if (r_ptr->level<monster_level) return FALSE;
+ 
+     if (r_ptr->flags2 & RF2_MULTIPLY) return FALSE;
+ 
+     return TRUE;
+ }
+ 
+ #define EK_BASE_MONSTER_DEPTH   4       /* Depth of all monsters */
+ #define EK_CAMP_MONSTER_DEPTH   3       /* Depth of camp-fire monsters */
+ #define EK_DEEP_MONSTER_DEPTH  15       /* Depth of "deep" monster */
+ #define EK_ARTIFACT_DEPTH       5       /* Depth of artifact */
+ #define EK_GREAT_ITEM_DEPTH     2       /* Depth of the great items */
+ 
+ #define EK_NUM_MONS            25       /* Number of monsters, when no camp-fire */        
+ #define EK_NUM_MONS_CAMP       15       /* Number of monsters, when camp-fire */
+ #define EK_NUM_MONS_ROUND       2       /* Avg. num of mons. around camp fire, +-1 */
+ #define EK_NUM_GREAT_ITEMS      4       /* Number of great items */
+ 
+ /*
+  *  Generate a special "ek" level                         -EK-
+  */
+ static void ek_level_gen(void)
+ {
+     int         i, y, x, len, t, r, sqr, dx, dy, i2, r_idx, glows;
+     int         type;
+     cave_type  *c_ptr;
+     inven_type *i_ptr;
+ 
+     /*
+     **
+     **    INITIALISATION
+     **
+     */
+ 
+     /*
+      * 0 - Wholly lit and marked, like town at day (perhaps boring)
+      *
+      * 1 - Wholly lit (most probable)
+      *
+      * 2 - With camp fires (very difficult)
+      */
+ 
+     type=rand_int(100);
+ 
+     if (type<30) type=0;
+     else if (type<80) type=1;
+     else type=3;
+ 
+     /* Make level glowing or not */
+     if (type==0 || type==1) glows=CAVE_GLOW;
+     else glows=0;
+ 
+     /* Never allocate new monsters during playtime */
+     dont_alloc_new_monsters = TRUE;
+ 
+     /* Hack -- Start with basic floors */
+     for (y = 0; y < cur_hgt; y++) {
+         for (x = 0; x < cur_wid; x++) {
+ 
+             cave_type *c_ptr = &cave[y][x];
+ 
+             /* Clear all features, set to "empty floor" */
+             c_ptr->feat = 0x01 | glows;
+         }
+     }
+ 
+     /*
+     **
+     **    OUTER WALLS
+     **
+     */
+ 
+     /* Perma-walls -- North/South */
+     for (x = 0; x < cur_wid; x++) {
+ 
+         /* North wall */
+         c_ptr = &cave[0][x];
+ 
+         /* Clear previous contents, add "solid" perma-wall */
+         c_ptr->feat = ((c_ptr->feat & ~0x3F) | 0x3F);
+ 
+         /* South wall */
+         c_ptr = &cave[cur_hgt-1][x];
+ 
+         /* Clear previous contents, add "solid" perma-wall */
+         c_ptr->feat = ((c_ptr->feat & ~0x3F) | 0x3F);
+     }
+ 
+     /* Perma-walls -- West/East */
+     for (y = 0; y < cur_hgt; y++) {
+ 
+         /* West wall */
+         c_ptr = &cave[y][0];
+ 
+         /* Clear previous contents, add "solid" perma-wall */
+         c_ptr->feat = ((c_ptr->feat & ~0x3F) | 0x3F);
+ 
+         /* East wall */
+         c_ptr = &cave[y][cur_wid-1];
+ 
+         /* Clear previous contents, add "solid" perma-wall */
+         c_ptr->feat = ((c_ptr->feat & ~0x3F) | 0x3F);
+     }
+ 
+     /*
+     **
+     **    RANDOM SHORT WALLS
+     **
+     */
+ 
+     /* Place i*4 short walls */
+     i=rand_range(3,9);
+ 
+     while (i--)
+     {
+         switch (rand_int(2))
+         {
+             case 0:
+                 /* Short horizontal wall */
+ 
+                 /* Find position */
+                 if (!ek_level_gen_aux(&x,&y,2)) 
+                     continue;
+                 
+                 /* Get length of wall */
+                 len=rand_range(3,6);
+ 
+                 /* Shorten it if it goes beyond the outer wall */
+                 if (len+x>cur_wid) len=cur_wid-x;
+ 
+                 /* Place 4 walls */
+                 for (t=0; t<len; t++)
+                     ek_level_gen_aux2(x+t,y);
+                 
+ 
+                 break;
+ 
+             case 1:
+                 /* Short vertical wall */
+                 
+                 /* Find position */
+                 if (!ek_level_gen_aux(&x,&y,2)) 
+                     continue;
+                 
+                 /* Get length of wall */
+                 len=rand_range(3,6);
+ 
+                 /* Shorten it if it goes beyond the outer wall */
+                 if (len+y>cur_hgt) len=cur_hgt-y;
+ 
+                 /* Place 4 walls */
+                 for (t=0; t<len; t++)
+                     ek_level_gen_aux2(x,y+t);
+                 
+                 break;
+         }
+     }
+ 
+     /*
+     **
+     **    RANDOM PILLARS
+     **
+     */
+ 
+     /* Place i*4 pillars */
+     i=rand_range(2,14);
+ 
+     while (i--)
+     {
+         /* Find position */
+         if (!ek_level_gen_aux(&x,&y,3)) 
+             continue;
+         
+         /* Place 4 pillars */
+         ek_level_gen_aux2(x,y);
+     }
+ 
+     /*
+     **
+     **    UP STAIRS
+     **
+     */
+ 
+     /* Place the up stairs */
+     ek_level_gen_aux(&x,&y,3);
+ 
+     /* Hack -- the player starts on the stairs */
+     py = y;
+     px = x;
+ 
+     /* Put walls around the stair */
+     /* XXX may be possible to "lock in" the player */
+     for (dy=-2; dy<=2; dy++)
+     {
+         for (dx=-2; dx<=2; dx++)
+         {
+             if (!in_bounds(y+dy,x+dx)) continue;
+ 
+             c_ptr = &cave[y+dy][x+dx];
+             
+             /* Clear previous contents */
+             c_ptr->feat = 0x01 | glows;
+ 
+             /* Add granite-wall */
+             if (dy>=-1 && dy<=1 && dx>=-1 && dx<=1 && (dx || dy))
+                 c_ptr->feat |= 0x38 | CAVE_MARK;
+             
+             else
+ 
+             /* Add stairway */
+             if (!dx && !dy) 
+                 place_up_stairs(y+dy,x+dx);
+         }
+     }
  
+     /* Carve out one space around the door */
+     do
+     {
+         dx=rand_range(-1,1);
+         dy=rand_range(-1,1);
+     } while ((dx && dy) || (!dx && !dy));
+ 
+     c_ptr = &cave[y+dy][x+dx];
+ 
+     /* Clear previous contents */
+     c_ptr->feat = 0x01 | glows;
+ 
+     /*
+     **
+     **    LIGHTNING and CAMP FIRE MONSTERS
+     **
+     */
+ 
+     if (type==0)
+     {
+         /* Mark up everything (already lit up) */
+      
+         for (y = 0; y < cur_hgt; y++) {
+             for (x = 0; x < cur_wid; x++) {
+             
+                 c_ptr = &cave[y][x];
+             
+                 /* Memorize */
+                 if (view_perma_grids) c_ptr->feat |= CAVE_MARK; 
+             }
+         }
+     }
+     else if (type==2)
+     {
+         /* Place i little fire places all over the place */
+ 
+         i=rand_range(3,5);
+ 
+         while (i--)
+         {
+             /* Locate a location */
+             if (!ek_level_gen_aux(&x,&y,1)) continue;
+ 
+             /* Place the "camp fire" at (x,y) */
+             /* XXX */
+ 
+             /* Place i2 monsters around the location */
+             i2=rand_range(EK_NUM_MONS_ROUND-1,EK_NUM_MONS_ROUND+1);
+ 
+             /* Initialize the monster hook */
+             get_mon_num_hook=ek_level_gen_monster_hook2;
+             
+             /* Choose the monster */
+             r_idx=get_mon_num(monster_level+EK_CAMP_MONSTER_DEPTH);
+ 
+             /* Restore monster hook */
+             get_mon_num_hook=NULL;
+ 
+             while (i2--)
+             {
+                 /* There *are* 8 free spaces around the fire! */
+                 while (1)
+                 {
+                     /* Choose a location */
+                     dx=rand_range(-1,1);
+                     dy=rand_range(-1,1);
+                     
+                     /* Monsters like it hot... NOT <g> */
+                     if (!dx && !dy) continue;
+ 
+                     if (!empty_grid_bold(y+dy,x+dx)) continue;
+ 
+                     break;
+                 }
+ 
+                 /* Place a monster, most probably sleeping, no group */
+                 place_monster_aux(y+dy,x+dx,r_idx,rand_int(5),0);
+             }
+ 
+             /* Choose the radius of the light */
+             r=rand_range(1,3);
+ 
+             sqr=r*r;
+ 
+             /* Light up a circle with radius r at (x,y) */
+             for (dy=-r; dy<=r; dy++)
+             {
+                 if (dy+y>=cur_hgt) break;
+                 if (dy+y<0) continue;
+                 
+                 for (dx=-r; dx<=r; dx++)
+                 {
+                     if (dx+x>=cur_wid) break;
+                     if (dx+x<0) continue;
+ 
+                     /* Is the point in range? */
+                     if (((dx*dx)/3 + dy*dy) > sqr) continue;
+ 
+                     /* Check los from middle of fire place */
+                     if (!los(y,x,y+dy,x+dx)) continue;
+                     
+                     c_ptr = &cave[y+dy][x+dx];
+ 
+                     /* Perma-Lite */
+                     c_ptr->feat |= CAVE_GLOW; 
+                     
+                     /* Memorize */
+                     if (view_perma_grids) c_ptr->feat |= CAVE_MARK; 
+                 }
+             }
+         }
+     }
+ 
+     /*
+     **
+     **    THE ARTIFACT
+     */
+ 
+     /* Find location at least 20 spaces away from the player */
+     i=100;
+     do
+     {
+         ek_level_gen_aux(&x,&y,1);
+ 
+         if (!i--) break;
+     } while (((x-px)*(x-px) + (y-py)*(y-py)) < 400);
+ 
+     if (i<0)
+     {
+         /* Find location at least 15 spaces away from the player */
+         i=100;
+         do
+         {
+             ek_level_gen_aux(&x,&y,1);
+             
+             if (!i--) break;
+         } while (((x-px)*(x-px) + (y-py)*(y-py)) < 225);
+ 
+         /* If i<0, then we'll take *any* location */
+     }
+ 
+     /* Increase object level */
+     object_level+=EK_ARTIFACT_DEPTH;
+ 
+     i=1000;
+     while (i--)
+     {
+         /* Place great object */
+         place_object(y,x,TRUE,TRUE);
+ 
+         /* Check if it is an artifact */
+         c_ptr=&cave[y][x];
+ 
+         /* Access the object */
+         i_ptr=&i_list[c_ptr->i_idx];
+ 
+         /* Is it an artifact? */
+         if (i_ptr->name1) break;
+ 
+         /* No. Remove it. */
+         delete_object(y,x);
+     }
+ 
+     /* Decrease object level */
+     object_level-=EK_ARTIFACT_DEPTH;
+ 
+     /*
+     **
+     **    SOME GREAT ITEMS
+     */
+ 
+     /* Increase object level */
+     object_level+=EK_GREAT_ITEM_DEPTH;
+ 
+     i=EK_NUM_GREAT_ITEMS;
+     while (i--)
+     {
+         /* Find location at least 20 spaces away from the player */
+         i2=100;
+         do
+         {
+             ek_level_gen_aux(&x,&y,1);
+             
+             if (!i2--) break;
+         } while (((x-px)*(x-px) + (y-py)*(y-py)) < 400);
+ 
+         /* Place object */
+         place_object(y,x,TRUE,TRUE);
+     }
+ 
+     /* Decrease object level */
+     object_level-=EK_GREAT_ITEM_DEPTH;
+ 
+     /*
+     **
+     **    VERY DEEP MONSTER on artifact
+     **
+     */
+ 
+     /* Initialize the monster hook - reject monsters less than monster_level */
+     get_mon_num_hook=ek_level_gen_monster_hook3;
+ 
+     /* Adjust monster level for the one *deep* level monster */
+     monster_level+=EK_DEEP_MONSTER_DEPTH;
+ 
+     /* Make sure it really is created */
+     i=100;
+     while (i-- && !place_monster(y,x,rand_int(3),TRUE));
+ 
+     /* Adjust monster level */
+     monster_level -=EK_DEEP_MONSTER_DEPTH;
+ 
+     /*
+     **
+     **    FINAL MONSTERS
+     **
+     */
+ 
+     /* Initialize the monster hook - no breeders */
+ /*    get_mon_num_hook=ek_level_gen_monster_hook;*/
+ 
+     /* Adjust monster level */
+     monster_level+=EK_BASE_MONSTER_DEPTH;
+ 
+     /* Make some "residents" far away from the player*/
+ 
+     /* If no camp fires, then more monsters */
+     if (type!=2) i=EK_NUM_MONS;
+     else i=EK_NUM_MONS_CAMP;
+ 
+     for (i = 0; i < 10; i++) alloc_monster(7, TRUE);
+ 
+     /* Adjust monster level */
+     monster_level-=EK_BASE_MONSTER_DEPTH;
+ 
+     get_mon_num_hook=NULL;
+ }
+ 
+ 
  /*
   * Generates a random dungeon level			-RAK-	
   *
***************
*** 3651,3656 ****
--- 4226,4233 ----
  {
      int i, num;
      
+     /* Hack - reset flag */
+     dont_alloc_new_monsters = FALSE;                        /* -EK- */
  
      /* No dungeon yet */
      character_dungeon = FALSE;
***************
*** 3716,3721 ****
--- 4293,4317 ----
  
              /* Make a town */
              town_gen();
+         }
+ 
+         /* Build a EK level */
+         else if (1)
+         {
+             /* Small level */
+             cur_hgt = SCREEN_HGT;
+             cur_wid = SCREEN_WID;
+ 
+             /* Determine number of panels */
+             max_panel_rows = (cur_hgt / SCREEN_HGT) * 2 - 2;
+             max_panel_cols = (cur_wid / SCREEN_WID) * 2 - 2;
+ 
+             /* Assume illegal panel */
+             panel_row = max_panel_rows;
+             panel_col = max_panel_cols;
+ 
+             /* Make a level */
+             ek_level_gen();
          }
  
          /* Build a real level */
