ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/random_maps/random_map.C
(Generate patch)

Comparing deliantra/server/random_maps/random_map.C (file contents):
Revision 1.21 by root, Thu Jan 18 19:42:10 2007 UTC vs.
Revision 1.30 by root, Sun Jul 1 05:00:19 2007 UTC

1/* 1/*
2 * CrossFire, A Multiplayer game for X-windows 2 * This file is part of Crossfire TRT, the Roguelike Realtime MORPG.
3 * 3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team 4 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team
5 * Copyright (C) 2001 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2001,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * Crossfire TRT is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version. 11 * (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * 20 *
22 * The authors can be reached via e-mail at <crossfire@schmorp.de> 21 * The authors can be reached via e-mail to <crossfire@schmorp.de>
23 */ 22 */
24 23
25#include <time.h> 24#include <time.h>
26#include <stdio.h> 25#include <stdio.h>
27#include <global.h> 26#include <global.h>
28#include <maze_gen.h> 27#include <maze_gen.h>
29#include <room_gen.h> 28#include <room_gen.h>
30#include <random_map.h> 29#include <random_map.h>
31#include <rproto.h> 30#include <rproto.h>
32#include <sproto.h> 31#include <sproto.h>
32
33#define CEDE coroapi::cede_to_tick (); rndm.seed (RP->random_seed + __LINE__);
33 34
34void 35void
35dump_layout (char **layout, random_map_params *RP) 36dump_layout (char **layout, random_map_params *RP)
36{ 37{
37 { 38 {
57maptile::generate_random_map (random_map_params *RP) 58maptile::generate_random_map (random_map_params *RP)
58{ 59{
59 char **layout, buf[16384]; 60 char **layout, buf[16384];
60 int i; 61 int i;
61 62
63 RP->Xsize = RP->xsize;
64 RP->Ysize = RP->ysize;
65
62 /* pick a random seed, or use the one from the input file */ 66 /* pick a random seed, or use the one from the input file */
63 SRANDOM (RP->random_seed ? RP->random_seed + RP->dungeon_level : time (0)); 67 RP->random_seed = RP->random_seed
68 ? RP->random_seed + RP->dungeon_level
69 : time (0);
70 CEDE;
64 71
65 write_map_parameters_to_string (buf, RP); 72 write_map_parameters_to_string (buf, RP);
66 73
67 if (RP->difficulty == 0) 74 if (RP->difficulty == 0)
68 { 75 {
81 RP->Xsize = MIN_RANDOM_MAP_SIZE + rndm (25) + 5; 88 RP->Xsize = MIN_RANDOM_MAP_SIZE + rndm (25) + 5;
82 89
83 if (RP->Ysize < MIN_RANDOM_MAP_SIZE) 90 if (RP->Ysize < MIN_RANDOM_MAP_SIZE)
84 RP->Ysize = MIN_RANDOM_MAP_SIZE + rndm (25) + 5; 91 RP->Ysize = MIN_RANDOM_MAP_SIZE + rndm (25) + 5;
85 92
93 if (RP->symmetry == SYMMETRY_RANDOM)
94 RP->symmetry_used = rndm (SYMMETRY_XY) + 1;
95 else
96 RP->symmetry_used = RP->symmetry;
97
98 if (RP->symmetry_used == SYMMETRY_Y || RP->symmetry_used == SYMMETRY_XY)
99 RP->Ysize = RP->Ysize / 2 + 1;
100
101 if (RP->symmetry_used == SYMMETRY_X || RP->symmetry_used == SYMMETRY_XY)
102 RP->Xsize = RP->Xsize / 2 + 1;
103
86 if (RP->expand2x > 0) 104 if (RP->expand2x > 0)
87 { 105 {
88 RP->Xsize /= 2; 106 RP->Xsize /= 2;
89 RP->Ysize /= 2; 107 RP->Ysize /= 2;
90 } 108 }
91 109
92 layout = layoutgen (RP);
93
94#ifdef RMAP_DEBUG
95 dump_layout (layout, RP);
96#endif
97
98 /* increment these for the current map */
99 RP->dungeon_level += 1;
100 /* allow constant-difficulty maps. */
101 /* difficulty+=1; */
102
103 /* rotate the layout randomly */
104 layout = rotate_layout (layout, rndm (4), RP);
105#ifdef RMAP_DEBUG
106 dump_layout (layout, RP);
107#endif
108
109 /* allocate the map and set the floor */
110 make_map_floor (layout, RP->floorstyle, RP);
111
112 /* set region */
113 region = RP->region;
114
115 coroapi::cede ();
116
117 /* create walls unless the wallstyle is "none" */
118 if (strcmp (RP->wallstyle, "none"))
119 {
120 make_map_walls (this, layout, RP->wallstyle, RP);
121
122 /* place doors unless doorstyle or wallstyle is "none" */
123 if (strcmp (RP->doorstyle, "none"))
124 put_doors (this, layout, RP->doorstyle, RP);
125
126 }
127
128 coroapi::cede ();
129
130 /* create exits unless the exitstyle is "none" */
131 if (strcmp (RP->exitstyle, "none"))
132 place_exits (this, layout, RP->exitstyle, RP->orientation, RP);
133
134 coroapi::cede ();
135
136 place_specials_in_map (this, layout, RP);
137
138 coroapi::cede ();
139
140 /* create monsters unless the monsterstyle is "none" */
141 if (strcmp (RP->monsterstyle, "none"))
142 place_monsters (this, RP->monsterstyle, RP->difficulty, RP);
143
144 coroapi::cede ();
145
146 /* treasures needs to have a proper difficulty set for the map. */
147 difficulty = estimate_difficulty ();
148
149 coroapi::cede ();
150
151 /* create treasure unless the treasurestyle is "none" */
152 if (strcmp (RP->treasurestyle, "none"))
153 place_treasure (this, layout, RP->treasurestyle, RP->treasureoptions, RP);
154
155 coroapi::cede ();
156
157 /* create decor unless the decorstyle is "none" */
158 if (strcmp (RP->decorstyle, "none"))
159 put_decor (this, layout, RP->decorstyle, RP->decoroptions, RP);
160
161 coroapi::cede ();
162
163 /* generate treasures, etc. */
164 fix_auto_apply ();
165
166 coroapi::cede ();
167 unblock_exits (this, layout, RP);
168
169 /* free the layout */
170 for (i = 0; i < RP->Xsize; i++)
171 free (layout[i]);
172
173 free (layout);
174
175 msg = strdup (buf);
176 in_memory = MAP_IN_MEMORY;
177
178 return 1;
179}
180
181/* function selects the layout function and gives it whatever
182 arguments it needs. */
183char **
184layoutgen (random_map_params *RP)
185{
186 char **maze = 0;
187 int oxsize = RP->Xsize, oysize = RP->Ysize;
188
189 if (RP->symmetry == SYMMETRY_RANDOM)
190 RP->symmetry_used = (RANDOM () % (SYMMETRY_XY)) + 1;
191 else
192 RP->symmetry_used = RP->symmetry;
193
194 if (RP->symmetry_used == SYMMETRY_Y || RP->symmetry_used == SYMMETRY_XY)
195 RP->Ysize = RP->Ysize / 2 + 1;
196 if (RP->symmetry_used == SYMMETRY_X || RP->symmetry_used == SYMMETRY_XY)
197 RP->Xsize = RP->Xsize / 2 + 1;
198
199 if (RP->Xsize < MIN_RANDOM_MAP_SIZE)
200 RP->Xsize = MIN_RANDOM_MAP_SIZE + rndm (5);
201 if (RP->Ysize < MIN_RANDOM_MAP_SIZE)
202 RP->Ysize = MIN_RANDOM_MAP_SIZE + rndm (5);
203 RP->map_layout_style = 0; 110 RP->map_layout_style = LAYOUT_NONE;
204 111
205 /* Redo this - there was a lot of redundant code of checking for preset 112 /* Redo this - there was a lot of redundant code of checking for preset
206 * layout style and then random layout style. Instead, figure out 113 * layout style and then random layout style. Instead, figure out
207 * the numeric layoutstyle, so there is only one area that actually 114 * the numeric layoutstyle, so there is only one area that actually
208 * calls the code to make the maps. 115 * calls the code to make the maps.
223 RP->map_layout_style = LAYOUT_SNAKE; 130 RP->map_layout_style = LAYOUT_SNAKE;
224 131
225 if (strstr (RP->layoutstyle, "squarespiral")) 132 if (strstr (RP->layoutstyle, "squarespiral"))
226 RP->map_layout_style = LAYOUT_SQUARE_SPIRAL; 133 RP->map_layout_style = LAYOUT_SQUARE_SPIRAL;
227 134
228 /* No style found - choose one ranomdly */ 135 /* No style found - choose one randomly */
229 if (RP->map_layout_style == LAYOUT_NONE) 136 if (RP->map_layout_style == LAYOUT_NONE)
230 RP->map_layout_style = (RANDOM () % (NROFLAYOUTS - 1)) + 1; 137 RP->map_layout_style = rndm (NROFLAYOUTS - 1) + 1;
138
139 layout = layoutgen (RP);
140
141#ifdef RMAP_DEBUG
142 dump_layout (layout, RP);
143#endif
144
145 /* increment these for the current map */
146 RP->dungeon_level += 1;
147 /* allow constant-difficulty maps. */
148 /* difficulty+=1; */
149
150 /* rotate the layout randomly */
151 layout = rotate_layout (layout, rndm (4), RP);
152#ifdef RMAP_DEBUG
153 dump_layout (layout, RP);
154#endif
155
156 /* allocate the map and set the floor */
157 make_map_floor (layout, RP->floorstyle, RP);
158
159 /* set region */
160 default_region = RP->region;
161
162 CEDE;
163
164 /* create walls unless the wallstyle is "none" */
165 if (strcmp (RP->wallstyle, "none"))
166 {
167 make_map_walls (this, layout, RP->wallstyle, RP);
168
169 /* place doors unless doorstyle or wallstyle is "none" */
170 if (strcmp (RP->doorstyle, "none"))
171 put_doors (this, layout, RP->doorstyle, RP);
172 }
173
174 CEDE;
175
176 /* create exits unless the exitstyle is "none" */
177 if (strcmp (RP->exitstyle, "none"))
178 place_exits (this, layout, RP->exitstyle, RP->orientation, RP);
179
180 CEDE;
181
182 place_specials_in_map (this, layout, RP);
183
184 CEDE;
185
186 /* create monsters unless the monsterstyle is "none" */
187 if (strcmp (RP->monsterstyle, "none"))
188 place_monsters (this, RP->monsterstyle, RP->difficulty, RP);
189
190 CEDE;
191
192 /* treasures needs to have a proper difficulty set for the map. */
193 difficulty = estimate_difficulty ();
194
195 CEDE;
196
197 /* create treasure unless the treasurestyle is "none" */
198 if (strcmp (RP->treasurestyle, "none"))
199 place_treasure (this, layout, RP->treasurestyle, RP->treasureoptions, RP);
200
201 CEDE;
202
203 /* create decor unless the decorstyle is "none" */
204 if (strcmp (RP->decorstyle, "none"))
205 put_decor (this, layout, RP->decorstyle, RP->decoroptions, RP);
206
207 CEDE;
208
209 /* generate treasures, etc. */
210 fix_auto_apply ();
211
212 CEDE;
213
214 unblock_exits (this, layout, RP);
215
216 /* free the layout */
217 for (i = 0; i < RP->Xsize; i++)
218 free (layout[i]);
219
220 free (layout);
221
222 msg = strdup (buf);
223 in_memory = MAP_IN_MEMORY;
224
225 CEDE;
226
227 return 1;
228}
229
230/* function selects the layout function and gives it whatever
231 arguments it needs. */
232char **
233layoutgen (random_map_params *RP)
234{
235 char **maze = 0;
236 int oxsize = RP->Xsize, oysize = RP->Ysize;
231 237
232 switch (RP->map_layout_style) 238 switch (RP->map_layout_style)
233 { 239 {
234 case LAYOUT_ONION: 240 case LAYOUT_ONION:
235 maze = map_gen_onion (RP->Xsize, RP->Ysize, RP->layoutoptions1, RP->layoutoptions2); 241 maze = map_gen_onion (RP->Xsize, RP->Ysize, RP->layoutoptions1, RP->layoutoptions2);
443 for (ti = 0; ti < tries; ti++) 449 for (ti = 0; ti < tries; ti++)
444 { 450 {
445 int dx, dy; /* starting location for looking at creating a door */ 451 int dx, dy; /* starting location for looking at creating a door */
446 int cx, cy; /* results of checking on creating walls. */ 452 int cx, cy; /* results of checking on creating walls. */
447 453
448 dx = RANDOM () % RP->Xsize; 454 dx = rndm (RP->Xsize);
449 dy = RANDOM () % RP->Ysize; 455 dy = rndm (RP->Ysize);
456
450 cx = can_make_wall (maze, dx, dy, 0, RP); /* horizontal */ 457 cx = can_make_wall (maze, dx, dy, 0, RP); /* horizontal */
451 cy = can_make_wall (maze, dx, dy, 1, RP); /* vertical */ 458 cy = can_make_wall (maze, dx, dy, 1, RP); /* vertical */
452 if (cx == -1) 459 if (cx == -1)
453 { 460 {
454 if (cy != -1) 461 if (cy != -1)
455 make_wall (maze, dx, dy, 1); 462 make_wall (maze, dx, dy, 1);
463
456 continue; 464 continue;
457 } 465 }
466
458 if (cy == -1) 467 if (cy == -1)
459 { 468 {
460 make_wall (maze, dx, dy, 0); 469 make_wall (maze, dx, dy, 0);
461 continue; 470 continue;
462 } 471 }
472
463 if (cx < cy) 473 if (cx < cy)
464 make_wall (maze, dx, dy, 0); 474 make_wall (maze, dx, dy, 0);
465 else 475 else
466 make_wall (maze, dx, dy, 1); 476 make_wall (maze, dx, dy, 1);
467 } 477 }
613 while (ndoors > 0 && doorlocs > 0) 623 while (ndoors > 0 && doorlocs > 0)
614 { 624 {
615 int di; 625 int di;
616 int sindex; 626 int sindex;
617 627
618 di = RANDOM () % doorlocs; 628 di = rndm (doorlocs);
619 i = doorlist_x[di]; 629 i = doorlist_x[di];
620 j = doorlist_y[di]; 630 j = doorlist_y[di];
621 sindex = surround_flag (maze, i, j, RP); 631 sindex = surround_flag (maze, i, j, RP);
632
622 if (sindex == 3 || sindex == 12) /* these are possible door sindex */ 633 if (sindex == 3 || sindex == 12) /* these are possible door sindex */
623 { 634 {
624 maze[i][j] = 'D'; 635 maze[i][j] = 'D';
625 ndoors--; 636 ndoors--;
626 } 637 }
638
627 /* reduce the size of the list */ 639 /* reduce the size of the list */
628 doorlocs--; 640 doorlocs--;
629 doorlist_x[di] = doorlist_x[doorlocs]; 641 doorlist_x[di] = doorlist_x[doorlocs];
630 doorlist_y[di] = doorlist_y[doorlocs]; 642 doorlist_y[di] = doorlist_y[doorlocs];
631 } 643 }
637void 649void
638write_map_parameters_to_string (char *buf, random_map_params *RP) 650write_map_parameters_to_string (char *buf, random_map_params *RP)
639{ 651{
640 char small_buf[16384]; 652 char small_buf[16384];
641 653
642 sprintf (buf, "xsize %d\nysize %d\n", RP->Xsize, RP->Ysize); 654 sprintf (buf, "xsize %d\nysize %d\n", RP->xsize, RP->ysize);
643 655
644 if (RP->wallstyle[0]) 656 if (RP->wallstyle[0])
645 { 657 {
646 sprintf (small_buf, "wallstyle %s\n", RP->wallstyle); 658 sprintf (small_buf, "wallstyle %s\n", RP->wallstyle);
647 strcat (buf, small_buf); 659 strcat (buf, small_buf);
788 strcat (buf, small_buf); 800 strcat (buf, small_buf);
789 } 801 }
790 802
791 if (RP->random_seed) 803 if (RP->random_seed)
792 { 804 {
793 sprintf (small_buf, "random_seed %d\n", RP->random_seed); 805 sprintf (small_buf, "random_seed %u\n", RP->random_seed);
794 strcat (buf, small_buf); 806 strcat (buf, small_buf);
795 } 807 }
796 808
797 if (RP->custom) 809 if (RP->custom)
798 { 810 {
803 815
804void 816void
805write_parameters_to_string (char *buf, 817write_parameters_to_string (char *buf,
806 int xsize_n, 818 int xsize_n,
807 int ysize_n, 819 int ysize_n,
808 char *wallstyle_n, 820 const char *wallstyle_n,
809 char *floorstyle_n, 821 const char *floorstyle_n,
810 char *monsterstyle_n, 822 const char *monsterstyle_n,
811 char *treasurestyle_n, 823 const char *treasurestyle_n,
812 char *layoutstyle_n, 824 const char *layoutstyle_n,
813 char *decorstyle_n, 825 const char *decorstyle_n,
814 char *doorstyle_n, 826 const char *doorstyle_n,
815 char *exitstyle_n, 827 const char *exitstyle_n,
816 char *final_map_n, 828 const char *final_map_n,
817 char *exit_on_final_map_n, 829 const char *exit_on_final_map_n,
818 char *this_map_n, 830 const char *this_map_n,
819 int layoutoptions1_n, 831 int layoutoptions1_n,
820 int layoutoptions2_n, 832 int layoutoptions2_n,
821 int layoutoptions3_n, 833 int layoutoptions3_n,
822 int symmetry_n, 834 int symmetry_n,
823 int dungeon_depth_n, 835 int dungeon_depth_n,
824 int dungeon_level_n, 836 int dungeon_level_n,
825 int difficulty_n, 837 int difficulty_n,
826 int difficulty_given_n, 838 int difficulty_given_n,
827 int decoroptions_n, 839 int decoroptions_n,
828 int orientation_n, 840 int orientation_n,
829 int origin_x_n, int origin_y_n, int random_seed_n, int treasureoptions_n, float difficulty_increase) 841 int origin_x_n,
842 int origin_y_n,
843 uint32_t random_seed_n,
844 int treasureoptions_n,
845 float difficulty_increase)
830{ 846{
831 char small_buf[16384]; 847 char small_buf[16384];
832 848
833 sprintf (buf, "xsize %d\nysize %d\n", xsize_n, ysize_n); 849 sprintf (buf, "xsize %d\nysize %d\n", xsize_n, ysize_n);
834 850
970 } 986 }
971 987
972 if (random_seed_n) 988 if (random_seed_n)
973 { 989 {
974 /* Add one so that the next map is a bit different */ 990 /* Add one so that the next map is a bit different */
975 sprintf (small_buf, "random_seed %d\n", random_seed_n + 1); 991 sprintf (small_buf, "random_seed %u\n", random_seed_n + 1);
976 strcat (buf, small_buf); 992 strcat (buf, small_buf);
977 } 993 }
978 994
979 if (treasureoptions_n) 995 if (treasureoptions_n)
980 { 996 {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines