--- deliantra/server/random_maps/random_map.C 2006/12/31 19:02:24 1.13 +++ deliantra/server/random_maps/random_map.C 2007/04/17 10:06:34 1.29 @@ -1,26 +1,26 @@ - /* - CrossFire, A Multiplayer game for X-windows - - Copyright (C) 2001 Mark Wedel & Crossfire Development Team - Copyright (C) 1992 Frank Tore Johansen - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - The authors can be reached via e-mail at -*/ + * CrossFire, A Multiplayer game for X-windows + * + * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team + * Copyright (C) 2001 Mark Wedel & Crossfire Development Team + * Copyright (C) 1992 Frank Tore Johansen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * The authors can be reached via e-mail at + */ #include #include @@ -31,6 +31,8 @@ #include #include +#define CEDE coroapi::cede_to_tick (); rndm.seed (RP->random_seed + __LINE__); + void dump_layout (char **layout, random_map_params *RP) { @@ -53,20 +55,20 @@ printf ("\n"); } -extern FILE *logfile; - -maptile * -generate_random_map (const char *OutFileName, random_map_params *RP) +bool +maptile::generate_random_map (random_map_params *RP) { - char **layout, buf[HUGE_BUF]; - maptile *theMap; + char **layout, buf[16384]; int i; - /* pick a random seed, or use the one from the input file */ - if (RP->random_seed == 0) - RP->random_seed = time (0); + RP->Xsize = RP->xsize; + RP->Ysize = RP->ysize; - SRANDOM (RP->random_seed); + /* pick a random seed, or use the one from the input file */ + RP->random_seed = RP->random_seed + ? RP->random_seed + RP->dungeon_level + : time (0); + CEDE; write_map_parameters_to_string (buf, RP); @@ -84,10 +86,21 @@ RP->difficulty_given = 1; if (RP->Xsize < MIN_RANDOM_MAP_SIZE) - RP->Xsize = MIN_RANDOM_MAP_SIZE + RANDOM () % 25 + 5; + RP->Xsize = MIN_RANDOM_MAP_SIZE + rndm (25) + 5; if (RP->Ysize < MIN_RANDOM_MAP_SIZE) - RP->Ysize = MIN_RANDOM_MAP_SIZE + RANDOM () % 25 + 5; + RP->Ysize = MIN_RANDOM_MAP_SIZE + rndm (25) + 5; + + if (RP->symmetry == SYMMETRY_RANDOM) + RP->symmetry_used = rndm (SYMMETRY_XY) + 1; + else + RP->symmetry_used = RP->symmetry; + + if (RP->symmetry_used == SYMMETRY_Y || RP->symmetry_used == SYMMETRY_XY) + RP->Ysize = RP->Ysize / 2 + 1; + + if (RP->symmetry_used == SYMMETRY_X || RP->symmetry_used == SYMMETRY_XY) + RP->Xsize = RP->Xsize / 2 + 1; if (RP->expand2x > 0) { @@ -95,6 +108,35 @@ RP->Ysize /= 2; } + RP->map_layout_style = LAYOUT_NONE; + + /* Redo this - there was a lot of redundant code of checking for preset + * layout style and then random layout style. Instead, figure out + * the numeric layoutstyle, so there is only one area that actually + * calls the code to make the maps. + */ + if (strstr (RP->layoutstyle, "onion")) + RP->map_layout_style = LAYOUT_ONION; + + if (strstr (RP->layoutstyle, "maze")) + RP->map_layout_style = LAYOUT_MAZE; + + if (strstr (RP->layoutstyle, "spiral")) + RP->map_layout_style = LAYOUT_SPIRAL; + + if (strstr (RP->layoutstyle, "rogue")) + RP->map_layout_style = LAYOUT_ROGUELIKE; + + if (strstr (RP->layoutstyle, "snake")) + RP->map_layout_style = LAYOUT_SNAKE; + + if (strstr (RP->layoutstyle, "squarespiral")) + RP->map_layout_style = LAYOUT_SQUARE_SPIRAL; + + /* No style found - choose one randomly */ + if (RP->map_layout_style == LAYOUT_NONE) + RP->map_layout_style = rndm (NROFLAYOUTS - 1) + 1; + layout = layoutgen (RP); #ifdef RMAP_DEBUG @@ -107,56 +149,70 @@ /* difficulty+=1; */ /* rotate the layout randomly */ - layout = rotate_layout (layout, RANDOM () % 4, RP); + layout = rotate_layout (layout, rndm (4), RP); #ifdef RMAP_DEBUG dump_layout (layout, RP); #endif /* allocate the map and set the floor */ - theMap = make_map_floor (layout, RP->floorstyle, RP); - - /* set the name of the map. */ - theMap->path = OutFileName; + make_map_floor (layout, RP->floorstyle, RP); /* set region */ - theMap->region = RP->region; + default_region = RP->region; + + CEDE; /* create walls unless the wallstyle is "none" */ if (strcmp (RP->wallstyle, "none")) { - make_map_walls (theMap, layout, RP->wallstyle, RP); + make_map_walls (this, layout, RP->wallstyle, RP); /* place doors unless doorstyle or wallstyle is "none" */ if (strcmp (RP->doorstyle, "none")) - put_doors (theMap, layout, RP->doorstyle, RP); - + put_doors (this, layout, RP->doorstyle, RP); } + CEDE; + /* create exits unless the exitstyle is "none" */ if (strcmp (RP->exitstyle, "none")) - place_exits (theMap, layout, RP->exitstyle, RP->orientation, RP); + place_exits (this, layout, RP->exitstyle, RP->orientation, RP); + + CEDE; + + place_specials_in_map (this, layout, RP); - place_specials_in_map (theMap, layout, RP); + CEDE; /* create monsters unless the monsterstyle is "none" */ if (strcmp (RP->monsterstyle, "none")) - place_monsters (theMap, RP->monsterstyle, RP->difficulty, RP); + place_monsters (this, RP->monsterstyle, RP->difficulty, RP); + + CEDE; /* treasures needs to have a proper difficulty set for the map. */ - theMap->difficulty = theMap->estimate_difficulty (); + difficulty = estimate_difficulty (); + + CEDE; /* create treasure unless the treasurestyle is "none" */ if (strcmp (RP->treasurestyle, "none")) - place_treasure (theMap, layout, RP->treasurestyle, RP->treasureoptions, RP); + place_treasure (this, layout, RP->treasurestyle, RP->treasureoptions, RP); + + CEDE; /* create decor unless the decorstyle is "none" */ if (strcmp (RP->decorstyle, "none")) - put_decor (theMap, layout, RP->decorstyle, RP->decoroptions, RP); + put_decor (this, layout, RP->decorstyle, RP->decoroptions, RP); + + CEDE; /* generate treasures, etc. */ - theMap->fix_auto_apply (); + fix_auto_apply (); - unblock_exits (theMap, layout, RP); + CEDE; + + unblock_exits (this, layout, RP); /* free the layout */ for (i = 0; i < RP->Xsize; i++) @@ -164,10 +220,12 @@ free (layout); - theMap->msg = strdup (buf); - theMap->in_memory = MAP_IN_MEMORY; + msg = strdup (buf); + in_memory = MAP_IN_MEMORY; + + CEDE; - return theMap; + return 1; } /* function selects the layout function and gives it whatever @@ -178,66 +236,23 @@ char **maze = 0; int oxsize = RP->Xsize, oysize = RP->Ysize; - if (RP->symmetry == SYMMETRY_RANDOM) - RP->symmetry_used = (RANDOM () % (SYMMETRY_XY)) + 1; - else - RP->symmetry_used = RP->symmetry; - - if (RP->symmetry_used == SYMMETRY_Y || RP->symmetry_used == SYMMETRY_XY) - RP->Ysize = RP->Ysize / 2 + 1; - if (RP->symmetry_used == SYMMETRY_X || RP->symmetry_used == SYMMETRY_XY) - RP->Xsize = RP->Xsize / 2 + 1; - - if (RP->Xsize < MIN_RANDOM_MAP_SIZE) - RP->Xsize = MIN_RANDOM_MAP_SIZE + RANDOM () % 5; - if (RP->Ysize < MIN_RANDOM_MAP_SIZE) - RP->Ysize = MIN_RANDOM_MAP_SIZE + RANDOM () % 5; - RP->map_layout_style = 0; - - /* Redo this - there was a lot of redundant code of checking for preset - * layout style and then random layout style. Instead, figure out - * the numeric layoutstyle, so there is only one area that actually - * calls the code to make the maps. - */ - if (strstr (RP->layoutstyle, "onion")) - RP->map_layout_style = LAYOUT_ONION; - - if (strstr (RP->layoutstyle, "maze")) - RP->map_layout_style = LAYOUT_MAZE; - - if (strstr (RP->layoutstyle, "spiral")) - RP->map_layout_style = LAYOUT_SPIRAL; - - if (strstr (RP->layoutstyle, "rogue")) - RP->map_layout_style = LAYOUT_ROGUELIKE; - - if (strstr (RP->layoutstyle, "snake")) - RP->map_layout_style = LAYOUT_SNAKE; - - if (strstr (RP->layoutstyle, "squarespiral")) - RP->map_layout_style = LAYOUT_SQUARE_SPIRAL; - - /* No style found - choose one ranomdly */ - if (RP->map_layout_style == LAYOUT_NONE) - RP->map_layout_style = (RANDOM () % (NROFLAYOUTS - 1)) + 1; - switch (RP->map_layout_style) { case LAYOUT_ONION: maze = map_gen_onion (RP->Xsize, RP->Ysize, RP->layoutoptions1, RP->layoutoptions2); - if (!(RANDOM () % 3) && !(RP->layoutoptions1 & RMOPT_WALLS_ONLY)) + if (!(rndm (3)) && !(RP->layoutoptions1 & RMOPT_WALLS_ONLY)) roomify_layout (maze, RP); break; case LAYOUT_MAZE: - maze = maze_gen (RP->Xsize, RP->Ysize, RANDOM () % 2); - if (!(RANDOM () % 2)) + maze = maze_gen (RP->Xsize, RP->Ysize, rndm (2)); + if (!(rndm (2))) doorify_layout (maze, RP); break; case LAYOUT_SPIRAL: maze = map_gen_spiral (RP->Xsize, RP->Ysize, RP->layoutoptions1); - if (!(RANDOM () % 2)) + if (!(rndm (2))) doorify_layout (maze, RP); break; @@ -258,13 +273,13 @@ case LAYOUT_SNAKE: maze = make_snake_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1); - if (RANDOM () % 2) + if (rndm (2)) roomify_layout (maze, RP); break; case LAYOUT_SQUARE_SPIRAL: maze = make_square_spiral_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1); - if (RANDOM () % 2) + if (rndm (2)) roomify_layout (maze, RP); break; } @@ -437,21 +452,25 @@ int dx, dy; /* starting location for looking at creating a door */ int cx, cy; /* results of checking on creating walls. */ - dx = RANDOM () % RP->Xsize; - dy = RANDOM () % RP->Ysize; + dx = rndm (RP->Xsize); + dy = rndm (RP->Ysize); + cx = can_make_wall (maze, dx, dy, 0, RP); /* horizontal */ cy = can_make_wall (maze, dx, dy, 1, RP); /* vertical */ if (cx == -1) { if (cy != -1) make_wall (maze, dx, dy, 1); + continue; } + if (cy == -1) { make_wall (maze, dx, dy, 0); continue; } + if (cx < cy) make_wall (maze, dx, dy, 0); else @@ -607,15 +626,17 @@ int di; int sindex; - di = RANDOM () % doorlocs; + di = rndm (doorlocs); i = doorlist_x[di]; j = doorlist_y[di]; sindex = surround_flag (maze, i, j, RP); + if (sindex == 3 || sindex == 12) /* these are possible door sindex */ { maze[i][j] = 'D'; ndoors--; } + /* reduce the size of the list */ doorlocs--; doorlist_x[di] = doorlist_x[doorlocs]; @@ -629,9 +650,9 @@ void write_map_parameters_to_string (char *buf, random_map_params *RP) { - char small_buf[256]; + char small_buf[16384]; - sprintf (buf, "xsize %d\nysize %d\n", RP->Xsize, RP->Ysize); + sprintf (buf, "xsize %d\nysize %d\n", RP->xsize, RP->ysize); if (RP->wallstyle[0]) { @@ -681,9 +702,9 @@ strcat (buf, small_buf); } - if (RP->final_map[0]) + if (RP->final_map.length ()) { - sprintf (small_buf, "final_map %s\n", RP->final_map); + sprintf (small_buf, "final_map %s\n", &RP->final_map); strcat (buf, small_buf); } @@ -693,9 +714,9 @@ strcat (buf, small_buf); } - if (RP->this_map[0]) + if (RP->this_map.length ()) { - sprintf (small_buf, "origin_map %s\n", RP->this_map); + sprintf (small_buf, "origin_map %s\n", &RP->this_map); strcat (buf, small_buf); } @@ -711,14 +732,12 @@ strcat (buf, small_buf); } - if (RP->layoutoptions2) { sprintf (small_buf, "layoutoptions2 %d\n", RP->layoutoptions2); strcat (buf, small_buf); } - if (RP->layoutoptions3) { sprintf (small_buf, "layoutoptions3 %d\n", RP->layoutoptions3); @@ -731,7 +750,6 @@ strcat (buf, small_buf); } - if (RP->difficulty && RP->difficulty_given) { sprintf (small_buf, "difficulty %d\n", RP->difficulty); @@ -777,16 +795,21 @@ strcat (buf, small_buf); } + if (RP->treasureoptions) + { + sprintf (small_buf, "treasureoptions %d\n", RP->treasureoptions); + strcat (buf, small_buf); + } + if (RP->random_seed) { - /* Add one so that the next map is a bit different */ - sprintf (small_buf, "random_seed %d\n", RP->random_seed + 1); + sprintf (small_buf, "random_seed %u\n", RP->random_seed); strcat (buf, small_buf); } - if (RP->treasureoptions) + if (RP->custom) { - sprintf (small_buf, "treasureoptions %d\n", RP->treasureoptions); + sprintf (small_buf, "custom %s\n", RP->custom); strcat (buf, small_buf); } } @@ -795,17 +818,17 @@ write_parameters_to_string (char *buf, int xsize_n, int ysize_n, - char *wallstyle_n, - char *floorstyle_n, - char *monsterstyle_n, - char *treasurestyle_n, - char *layoutstyle_n, - char *decorstyle_n, - char *doorstyle_n, - char *exitstyle_n, - char *final_map_n, - char *exit_on_final_map_n, - char *this_map_n, + const char *wallstyle_n, + const char *floorstyle_n, + const char *monsterstyle_n, + const char *treasurestyle_n, + const char *layoutstyle_n, + const char *decorstyle_n, + const char *doorstyle_n, + const char *exitstyle_n, + const char *final_map_n, + const char *exit_on_final_map_n, + const char *this_map_n, int layoutoptions1_n, int layoutoptions2_n, int layoutoptions3_n, @@ -816,10 +839,13 @@ int difficulty_given_n, int decoroptions_n, int orientation_n, - int origin_x_n, int origin_y_n, int random_seed_n, int treasureoptions_n, float difficulty_increase) + int origin_x_n, + int origin_y_n, + uint32_t random_seed_n, + int treasureoptions_n, + float difficulty_increase) { - - char small_buf[256]; + char small_buf[16384]; sprintf (buf, "xsize %d\nysize %d\n", xsize_n, ysize_n); @@ -963,7 +989,7 @@ if (random_seed_n) { /* Add one so that the next map is a bit different */ - sprintf (small_buf, "random_seed %d\n", random_seed_n + 1); + sprintf (small_buf, "random_seed %u\n", random_seed_n + 1); strcat (buf, small_buf); } @@ -972,8 +998,6 @@ sprintf (small_buf, "treasureoptions %d\n", treasureoptions_n); strcat (buf, small_buf); } - - } /* copy an object with an inventory... i.e., duplicate the inv too. */ @@ -984,7 +1008,7 @@ src_ob->copy_to (dest_ob); - for (walk = src_ob->inv; walk != NULL; walk = walk->below) + for (walk = src_ob->inv; walk; walk = walk->below) { tmp = object::create ();