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

Comparing deliantra/server/random_maps/exit.C (file contents):
Revision 1.15 by root, Sun Dec 31 17:17:23 2006 UTC vs.
Revision 1.18 by root, Sun Dec 31 20:46:27 2006 UTC

1
1/* 2/*
2 CrossFire, A Multiplayer game for X-windows 3 CrossFire, A Multiplayer game for X-windows
3 4
4 Copyright (C) 2001 Mark Wedel & Crossfire Development Team 5 Copyright (C) 2001 Mark Wedel & Crossfire Development Team
5 Copyright (C) 1992 Frank Tore Johansen 6 Copyright (C) 1992 Frank Tore Johansen
27#include <rproto.h> 28#include <rproto.h>
28 29
29/* find a character in the layout. fx and fy are pointers to 30/* find a character in the layout. fx and fy are pointers to
30 where to find the char. fx,fy = -1 if not found. */ 31 where to find the char. fx,fy = -1 if not found. */
31void 32void
32find_in_layout (int mode, char target, int *fx, int *fy, char **layout, random_map_params * RP) 33find_in_layout (int mode, char target, int *fx, int *fy, char **layout, random_map_params *RP)
33{ 34{
34 int M; 35 int M;
35 int i, j; 36 int i, j;
36 37
37 *fx = -1; 38 *fx = -1;
46 /* four different search starting points and methods so that 47 /* four different search starting points and methods so that
47 we can do something different for symmetrical maps instead of 48 we can do something different for symmetrical maps instead of
48 the same damned thing every time. */ 49 the same damned thing every time. */
49 switch (M) 50 switch (M)
50 { 51 {
51 case 1: 52 case 1:
52 { /* search from top left down/right */ 53 { /* search from top left down/right */
53 for (i = 1; i < RP->Xsize; i++) 54 for (i = 1; i < RP->Xsize; i++)
54 for (j = 1; j < RP->Ysize; j++) 55 for (j = 1; j < RP->Ysize; j++)
55 { 56 {
56 if (layout[i][j] == target) 57 if (layout[i][j] == target)
57 { 58 {
58 *fx = i; 59 *fx = i;
59 *fy = j; 60 *fy = j;
60 return; 61 return;
61 } 62 }
62 } 63 }
63 break; 64 break;
64 } 65 }
65 case 2: 66 case 2:
66 { /* Search from top right down/left */ 67 { /* Search from top right down/left */
67 for (i = RP->Xsize - 2; i > 0; i--) 68 for (i = RP->Xsize - 2; i > 0; i--)
68 for (j = 1; j < RP->Ysize - 1; j++) 69 for (j = 1; j < RP->Ysize - 1; j++)
69 { 70 {
70 if (layout[i][j] == target) 71 if (layout[i][j] == target)
71 { 72 {
72 *fx = i; 73 *fx = i;
73 *fy = j; 74 *fy = j;
74 return; 75 return;
75 } 76 }
76 } 77 }
77 break; 78 break;
78 } 79 }
79 case 3: 80 case 3:
80 { /* search from bottom-left up-right */ 81 { /* search from bottom-left up-right */
81 for (i = 1; i < RP->Xsize - 1; i++) 82 for (i = 1; i < RP->Xsize - 1; i++)
82 for (j = RP->Ysize - 2; j > 0; j--) 83 for (j = RP->Ysize - 2; j > 0; j--)
83 { 84 {
84 if (layout[i][j] == target) 85 if (layout[i][j] == target)
85 { 86 {
86 *fx = i; 87 *fx = i;
87 *fy = j; 88 *fy = j;
88 return; 89 return;
89 } 90 }
90 } 91 }
91 break; 92 break;
92 } 93 }
93 case 4: 94 case 4:
94 { /* search from bottom-right up-left */ 95 { /* search from bottom-right up-left */
95 for (i = RP->Xsize - 2; i > 0; i--) 96 for (i = RP->Xsize - 2; i > 0; i--)
96 for (j = RP->Ysize - 2; j > 0; j--) 97 for (j = RP->Ysize - 2; j > 0; j--)
97 { 98 {
98 if (layout[i][j] == target) 99 if (layout[i][j] == target)
99 { 100 {
100 *fx = i; 101 *fx = i;
101 *fy = j; 102 *fy = j;
102 return; 103 return;
103 } 104 }
104 } 105 }
105 break; 106 break;
106 } 107 }
107 } 108 }
108} 109}
109 110
110/* orientation: 0 means random, 111/* orientation: 0 means random,
111 1 means descending dungeon 112 1 means descending dungeon
116 6 means southward 117 6 means southward
117*/ 118*/
118void 119void
119place_exits (maptile *map, char **maze, char *exitstyle, int orientation, random_map_params *RP) 120place_exits (maptile *map, char **maze, char *exitstyle, int orientation, random_map_params *RP)
120{ 121{
121 char styledirname[256]; 122 char styledirname[1024];
122 maptile *style_map_down = 0; /* harder maze */ 123 maptile *style_map_down = 0; /* harder maze */
123 maptile *style_map_up = 0; /* easier maze */ 124 maptile *style_map_up = 0; /* easier maze */
124 object *the_exit_down; /* harder maze */ 125 object *the_exit_down; /* harder maze */
125 object *the_exit_up; /* easier maze */ 126 object *the_exit_up; /* easier maze */
126 object *random_sign; /* magic mouth saying this is a random map. */ 127 object *random_sign; /* magic mouth saying this is a random map. */
127 char buf[512];
128 int cx = -1, cy = -1; /* location of a map center */ 128 int cx = -1, cy = -1; /* location of a map center */
129 int upx = -1, upy = -1; /* location of up exit */ 129 int upx = -1, upy = -1; /* location of up exit */
130 int downx = -1, downy = -1; 130 int downx = -1, downy = -1;
131 int final_map_exit = 1; 131 int final_map_exit = 1;
132 132
133 if (RP->exit_on_final_map) 133 if (RP->exit_on_final_map)
134 {
135 if (strstr (RP->exit_on_final_map, "no")) 134 if (strstr (RP->exit_on_final_map, "no"))
136 final_map_exit = 0; 135 final_map_exit = 0;
137 }
138 136
139 if (orientation == 0) 137 if (!orientation)
140 orientation = RANDOM () % 6 + 1; 138 orientation = RANDOM () % 6 + 1;
141 139
142 switch (orientation) 140 switch (orientation)
143 { 141 {
144 case 1: 142 case 1:
168 } 166 }
169 } 167 }
170 168
171 if (style_map_up == 0) 169 if (style_map_up == 0)
172 the_exit_up = arch_to_object (archetype::find ("exit")); 170 the_exit_up = arch_to_object (archetype::find ("exit"));
171
173 else 172 else
174 { 173 {
175 object *tmp; 174 object *tmp;
176 175
177 tmp = pick_random_object (style_map_up); 176 tmp = pick_random_object (style_map_up);
180 179
181 /* we need a down exit only if we're recursing. */ 180 /* we need a down exit only if we're recursing. */
182 if (RP->dungeon_level < RP->dungeon_depth || RP->final_map[0] != 0) 181 if (RP->dungeon_level < RP->dungeon_depth || RP->final_map[0] != 0)
183 if (style_map_down == 0) 182 if (style_map_down == 0)
184 the_exit_down = arch_to_object (archetype::find ("exit")); 183 the_exit_down = arch_to_object (archetype::find ("exit"));
184
185 else 185 else
186 { 186 {
187 object *tmp; 187 object *tmp;
188 188
189 tmp = pick_random_object (style_map_down); 189 tmp = pick_random_object (style_map_down);
198 the_exit_up->slaying = RP->origin_map; 198 the_exit_up->slaying = RP->origin_map;
199 199
200 /* figure out where to put the entrance */ 200 /* figure out where to put the entrance */
201 /* begin a logical block */ 201 /* begin a logical block */
202 { 202 {
203 int i, j;
204
205 /* First, look for a '<' char */ 203 /* First, look for a '<' char */
206 find_in_layout (0, '<', &upx, &upy, maze, RP); 204 find_in_layout (0, '<', &upx, &upy, maze, RP);
207 205
208 /* next, look for a C, the map center. */ 206 /* next, look for a C, the map center. */
209 find_in_layout (0, 'C', &cx, &cy, maze, RP); 207 find_in_layout (0, 'C', &cx, &cy, maze, RP);
210 208
211
212 /* if we didn't find an up, find an empty place far from the center */ 209 /* if we didn't find an up, find an empty place far from the center */
213 if (upx == -1 && cx != -1) 210 if (upx == -1 && cx != -1)
214 { 211 {
215 if (cx > RP->Xsize / 2) 212 if (cx > RP->Xsize / 2)
216 upx = 1; 213 upx = 1;
217 else 214 else
218 upx = RP->Xsize - 2; 215 upx = RP->Xsize - 2;
216
219 if (cy > RP->Ysize / 2) 217 if (cy > RP->Ysize / 2)
220 upy = 1; 218 upy = 1;
221 else 219 else
222 upy = RP->Ysize - 2; 220 upy = RP->Ysize - 2;
221
223 /* find an empty place far from the center */ 222 /* find an empty place far from the center */
224 if (upx == 1 && upy == 1) 223 if (upx == 1 && upy == 1)
225 find_in_layout (1, 0, &upx, &upy, maze, RP); 224 find_in_layout (1, 0, &upx, &upy, maze, RP);
226 else if (upx == 1 && upy > 1) 225 else if (upx == 1 && upy > 1)
227 find_in_layout (3, 0, &upx, &upy, maze, RP); 226 find_in_layout (3, 0, &upx, &upy, maze, RP);
237 236
238 the_exit_up->x = upx; 237 the_exit_up->x = upx;
239 the_exit_up->y = upy; 238 the_exit_up->y = upy;
240 239
241 /* surround the exits with notices that this is a random map. */ 240 /* surround the exits with notices that this is a random map. */
242 for (j = 1; j < 9; j++) 241 for (int j = 1; j < 9; j++)
243 { 242 {
244 if (!wall_blocked (map, the_exit_up->x + freearr_x[j], the_exit_up->y + freearr_y[j])) 243 if (!wall_blocked (map, the_exit_up->x + freearr_x[j], the_exit_up->y + freearr_y[j]))
245 { 244 {
246 random_sign = get_archetype ("sign"); 245 random_sign = get_archetype ("sign");
247 random_sign->x = the_exit_up->x + freearr_x[j]; 246 random_sign->x = the_exit_up->x + freearr_x[j];
248 random_sign->y = the_exit_up->y + freearr_y[j]; 247 random_sign->y = the_exit_up->y + freearr_y[j];
249 248
249 char buf[8192];
250 sprintf (buf, "This is a random map.\nLevel: %d\n", (RP->dungeon_level) - 1); 250 sprintf (buf, "This is a random map.\nLevel: %d\n", (RP->dungeon_level) - 1);
251 251
252 random_sign->msg = buf; 252 random_sign->msg = buf;
253 insert_ob_in_map (random_sign, map, NULL, 0); 253 insert_ob_in_map (random_sign, map, NULL, 0);
254 } 254 }
255 } 255 }
256
256 /* Block the exit so things don't get dumped on top of it. */ 257 /* Block the exit so things don't get dumped on top of it. */
257 the_exit_up->move_block = MOVE_ALL; 258 the_exit_up->move_block = MOVE_ALL;
258 259
259 insert_ob_in_map (the_exit_up, map, NULL, 0); 260 insert_ob_in_map (the_exit_up, map, NULL, 0);
260 maze[the_exit_up->x][the_exit_up->y] = '<'; 261 maze[the_exit_up->x][the_exit_up->y] = '<';
278 { 279 {
279 if (upx > RP->Xsize / 2) 280 if (upx > RP->Xsize / 2)
280 downx = 1; 281 downx = 1;
281 else 282 else
282 downx = RP->Xsize - 2; 283 downx = RP->Xsize - 2;
284
283 if (upy > RP->Ysize / 2) 285 if (upy > RP->Ysize / 2)
284 downy = 1; 286 downy = 1;
285 else 287 else
286 downy = RP->Ysize - 2; 288 downy = RP->Ysize - 2;
289
287 /* find an empty place far from the entrance */ 290 /* find an empty place far from the entrance */
288 if (downx == 1 && downy == 1) 291 if (downx == 1 && downy == 1)
289 find_in_layout (1, 0, &downx, &downy, maze, RP); 292 find_in_layout (1, 0, &downx, &downy, maze, RP);
290 else if (downx == 1 && downy > 1) 293 else if (downx == 1 && downy > 1)
291 find_in_layout (3, 0, &downx, &downy, maze, RP); 294 find_in_layout (3, 0, &downx, &downy, maze, RP);
292 else if (downx > 1 && downy == 1) 295 else if (downx > 1 && downy == 1)
293 find_in_layout (2, 0, &downx, &downy, maze, RP); 296 find_in_layout (2, 0, &downx, &downy, maze, RP);
294 else if (downx > 1 && downy > 1) 297 else if (downx > 1 && downy > 1)
295 find_in_layout (4, 0, &downx, &downy, maze, RP); 298 find_in_layout (4, 0, &downx, &downy, maze, RP);
296
297 } 299 }
300
298 /* no indication of where to place the down exit, so just place it */ 301 /* no indication of where to place the down exit, so just place it */
299 if (downx == -1) 302 if (downx == -1)
300 find_in_layout (0, 0, &downx, &downy, maze, RP); 303 find_in_layout (0, 0, &downx, &downy, maze, RP);
304
301 if (the_exit_down) 305 if (the_exit_down)
302 { 306 {
303 char buf[2048]; 307 char buf[8192];
304 308
305 i = find_first_free_spot (the_exit_down, map, downx, downy); 309 int i = find_first_free_spot (the_exit_down, map, downx, downy);
306 the_exit_down->x = downx + freearr_x[i]; 310 the_exit_down->x = downx + freearr_x[i];
307 the_exit_down->y = downy + freearr_y[i]; 311 the_exit_down->y = downy + freearr_y[i];
308 RP->origin_x = the_exit_down->x; 312 RP->origin_x = the_exit_down->x;
309 RP->origin_y = the_exit_down->y; 313 RP->origin_y = the_exit_down->y;
310 write_map_parameters_to_string (buf, RP); 314 write_map_parameters_to_string (buf, RP);
311 the_exit_down->msg = buf; 315 the_exit_down->msg = buf;
316
312 /* the identifier for making a random map. */ 317 /* the identifier for making a random map. */
313 if (RP->dungeon_level >= RP->dungeon_depth && RP->final_map[0] != 0) 318 if (RP->dungeon_level >= RP->dungeon_depth && *RP->final_map)
314 { 319 {
315 maptile *new_map; 320 maptile *new_map;
316 object *the_exit_back = arch_to_object (the_exit_up->arch), *tmp; 321 object *the_exit_back = arch_to_object (the_exit_up->arch);
317 322
318#if 0
319 /* I'm not sure if there was any reason to change the path to the
320 * map other than to maybe make it more descriptive in the 'maps'
321 * command. But changing the map name makes life more complicated,
322 * (has_been_loaded needs to use the new name)
323 */
324
325 char new_map_name[MAX_BUF];
326
327 /* give the final map a name */
328 sprintf (new_map_name, "%sfinal_map", RP->final_map);
329 /* set the exit down. */
330#endif
331 /* load it */ 323 /* load it */
332 if (!(new_map = maptile::load_map_sync (RP->final_map))) 324 if (!(new_map = maptile::load_map_sync (RP->final_map)))
333 return; 325 return;
334 326
335 the_exit_down->slaying = RP->final_map; 327 the_exit_down->slaying = RP->final_map;
336 328
337 for (tmp = new_map->at (new_map->enter_x, new_map->enter_y).bot; tmp; tmp = tmp->above) 329 for (object *tmp = new_map->at (new_map->enter_x, new_map->enter_y).bot; tmp; tmp = tmp->above)
338 /* Remove exit back to previous random map. There should only be one 330 /* Remove exit back to previous random map. There should only be one
339 * which is why we break out. To try to process more than one 331 * which is why we break out. To try to process more than one
340 * would require keeping a 'next' pointer, ad free_object kills tmp, which 332 * would require keeping a 'next' pointer, ad free_object kills tmp, which
341 * breaks the for loop. 333 * breaks the for loop.
342 */ 334 */
343 if (tmp->type == EXIT && EXIT_PATH (tmp) && !strncmp (EXIT_PATH (tmp), "/random/", 8)) 335 if (tmp->type == EXIT && EXIT_PATH (tmp) && !strncmp (EXIT_PATH (tmp), "?random/", 8))
344 { 336 {
345 tmp->destroy (); 337 tmp->destroy ();
346 break; 338 break;
347 } 339 }
348 340
365 the_exit_down->move_block = MOVE_ALL; 357 the_exit_down->move_block = MOVE_ALL;
366 insert_ob_in_map (the_exit_down, map, NULL, 0); 358 insert_ob_in_map (the_exit_down, map, NULL, 0);
367 maze[the_exit_down->x][the_exit_down->y] = '>'; 359 maze[the_exit_down->x][the_exit_down->y] = '>';
368 } 360 }
369 } 361 }
370
371} 362}
372 363
373/* this function unblocks the exits. We blocked them to 364/* this function unblocks the exits. We blocked them to
374 keep things from being dumped on them during the other 365 keep things from being dumped on them during the other
375 phases of random map generation. */ 366 phases of random map generation. */
376void 367void
377unblock_exits (maptile *map, char **maze, random_map_params * RP) 368unblock_exits (maptile *map, char **maze, random_map_params *RP)
378{ 369{
379 int i = 0, j = 0; 370 int i = 0, j = 0;
380 object *walk; 371 object *walk;
381 372
382 for (i = 0; i < RP->Xsize; i++) 373 for (i = 0; i < RP->Xsize; i++)
391 update_object (walk, UP_OBJ_CHANGE); 382 update_object (walk, UP_OBJ_CHANGE);
392 } 383 }
393 } 384 }
394 } 385 }
395} 386}
387

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines