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.41 by root, Sat Apr 10 01:54:07 2010 UTC vs.
Revision 1.48 by root, Sun Jul 4 22:12:26 2010 UTC

25#include <global.h> 25#include <global.h>
26#include <random_map.h> 26#include <random_map.h>
27#include <sproto.h> 27#include <sproto.h>
28#include <rproto.h> 28#include <rproto.h>
29 29
30/* find a character in the layout. fx and fy are pointers to 30/* find a character in the maze. fx and fy are pointers to
31 where to find the char. fx,fy = -1 if not found. */ 31 where to find the char. fx,fy = -1 if not found. */
32static void 32static void
33find_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, layout &maze)
34{ 34{
35 int M; 35 int M;
36 int i, j; 36 int i, j;
37 37
38 *fx = -1; 38 fx = -1;
39 *fy = -1; 39 fy = -1;
40 40
41 /* if a starting point isn't given, pick one */ 41 /* if a starting point isn't given, pick one */
42 if (mode < 1 || mode > 4) 42 if (mode < 1 || mode > 4)
43 M = rmg_rndm (4) + 1; 43 M = rmg_rndm (4) + 1;
44 else 44 else
49 the same damned thing every time. */ 49 the same damned thing every time. */
50 switch (M) 50 switch (M)
51 { 51 {
52 case 1: 52 case 1:
53 /* search from top left down/right */ 53 /* search from top left down/right */
54 for (i = 1; i < RP->Xsize; i++) 54 for (i = 1; i < maze.w; i++)
55 for (j = 1; j < RP->Ysize; j++) 55 for (j = 1; j < maze.h; j++)
56 { 56 {
57 if (layout[i][j] == target) 57 if (maze[i][j] == target)
58 { 58 {
59 *fx = i; 59 fx = i;
60 *fy = j; 60 fy = j;
61 return; 61 return;
62 } 62 }
63 } 63 }
64 break; 64 break;
65 65
66 case 2: 66 case 2:
67 /* Search from top right down/left */ 67 /* Search from top right down/left */
68 for (i = RP->Xsize - 2; i > 0; i--) 68 for (i = maze.w - 2; i > 0; i--)
69 for (j = 1; j < RP->Ysize - 1; j++) 69 for (j = 1; j < maze.h - 1; j++)
70 { 70 {
71 if (layout[i][j] == target) 71 if (maze[i][j] == target)
72 { 72 {
73 *fx = i; 73 fx = i;
74 *fy = j; 74 fy = j;
75 return; 75 return;
76 } 76 }
77 } 77 }
78 break; 78 break;
79 79
80 case 3: 80 case 3:
81 /* search from bottom-left up-right */ 81 /* search from bottom-left up-right */
82 for (i = 1; i < RP->Xsize - 1; i++) 82 for (i = 1; i < maze.w - 1; i++)
83 for (j = RP->Ysize - 2; j > 0; j--) 83 for (j = maze.h - 2; j > 0; j--)
84 { 84 {
85 if (layout[i][j] == target) 85 if (maze[i][j] == target)
86 { 86 {
87 *fx = i; 87 fx = i;
88 *fy = j; 88 fy = j;
89 return; 89 return;
90 } 90 }
91 } 91 }
92 break; 92 break;
93 93
94 case 4: 94 case 4:
95 /* search from bottom-right up-left */ 95 /* search from bottom-right up-left */
96 for (i = RP->Xsize - 2; i > 0; i--) 96 for (i = maze.w - 2; i > 0; i--)
97 for (j = RP->Ysize - 2; j > 0; j--) 97 for (j = maze.h - 2; j > 0; j--)
98 { 98 {
99 if (layout[i][j] == target) 99 if (maze[i][j] == target)
100 { 100 {
101 *fx = i; 101 fx = i;
102 *fy = j; 102 fy = j;
103 return; 103 return;
104 } 104 }
105 } 105 }
106 break; 106 break;
107
108 } 107 }
109} 108}
110 109
111/* orientation: 0 means random, 110/* orientation: 0 means random,
112 1 means descending dungeon 111 1 means descending dungeon
115 4 means leftward 114 4 means leftward
116 5 means northward 115 5 means northward
117 6 means southward 116 6 means southward
118*/ 117*/
119void 118void
120place_exits (maptile *map, char **maze, char *exitstyle, int orientation, random_map_params *RP) 119place_exits (maptile *map, layout &maze, const char *exitstyle, int orientation, random_map_params *RP)
121{ 120{
122 maptile *style_map_down = 0; /* harder maze */ 121 maptile *style_map_down = 0; /* harder maze */
123 maptile *style_map_up = 0; /* easier maze */ 122 maptile *style_map_up = 0; /* easier maze */
124 object *the_exit_down; /* harder maze */ 123 object *the_exit_down; /* harder maze */
125 object *the_exit_up; /* easier maze */ 124 object *the_exit_up; /* easier maze */
126 int cx = -1, cy = -1; /* location of a map center */ 125 int cx = -1, cy = -1; /* location of a map center */
127 int upx = -1, upy = -1; /* location of up exit */ 126 int upx = -1, upy = -1; /* location of up exit */
128 int downx = -1, downy = -1; 127 int downx = -1, downy = -1;
129 int final_map_exit = 1; 128 int final_map_exit = 1;
130 129
131 if (RP->exit_on_final_map) 130 if (const char *eofm = RP->get_str ("exit_on_final_map", 0))
132 if (strstr (RP->exit_on_final_map, "no")) 131 if (strstr (eofm, "no"))
133 final_map_exit = 0; 132 final_map_exit = 0;
134 133
135 if (!orientation) 134 if (!orientation)
136 orientation = rmg_rndm (6) + 1; 135 orientation = rmg_rndm (6) + 1;
137 136
161 160
162 the_exit_up = style_map_up 161 the_exit_up = style_map_up
163 ? style_map_up->pick_random_object (rmg_rndm)->clone () 162 ? style_map_up->pick_random_object (rmg_rndm)->clone ()
164 : archetype::get (shstr_exit); 163 : archetype::get (shstr_exit);
165 164
165 const char *final_map = RP->get_str ("final_map", 0);
166
166 /* we need a down exit only if we're recursing. */ 167 /* we need a down exit only if we're recursing. */
167 if (RP->dungeon_level < RP->dungeon_depth || *RP->final_map) 168 if (RP->dungeon_level < RP->dungeon_depth || final_map)
168 the_exit_down = style_map_down 169 the_exit_down = style_map_down
169 ? style_map_down->pick_random_object (rmg_rndm)->clone () 170 ? style_map_down->pick_random_object (rmg_rndm)->clone ()
170 : archetype::get (shstr_exit); 171 : archetype::get (shstr_exit);
171 else 172 else
172 the_exit_down = 0; 173 the_exit_down = 0;
173 174
174 /* set up the up exit */ 175 /* set up the up exit */
175 the_exit_up->stats.hp = RP->origin_x; 176 the_exit_up->stats.hp = RP->get_iv ("origin_x", -1);
176 the_exit_up->stats.sp = RP->origin_y; 177 the_exit_up->stats.sp = RP->get_iv ("origin_y", -1);
177 the_exit_up->slaying = RP->origin_map; 178 the_exit_up->slaying = RP->get_str ("origin_map", 0);
178 179
179 /* figure out where to put the entrance */ 180 /* figure out where to put the entrance */
180 /* begin a logical block */ 181 /* begin a logical block */
181 { 182 {
182 /* First, look for a '<' char */ 183 /* First, look for a '<' char */
183 find_in_layout (0, '<', &upx, &upy, maze, RP); 184 find_in_layout (0, '<', upx, upy, maze);
184 185
185 /* next, look for a C, the map center. */ 186 /* next, look for a C, the map center. */
186 find_in_layout (0, 'C', &cx, &cy, maze, RP); 187 find_in_layout (0, 'C', cx, cy, maze);
187 188
188 /* if we didn't find an up, find an empty place far from the center */ 189 /* if we didn't find an up, find an empty place far from the center */
189 if (upx == -1 && cx != -1) 190 if (upx == -1 && cx != -1)
190 { 191 {
191 if (cx > RP->Xsize / 2) 192 if (cx > RP->Xsize / 2)
198 else 199 else
199 upy = RP->Ysize - 2; 200 upy = RP->Ysize - 2;
200 201
201 /* find an empty place far from the center */ 202 /* find an empty place far from the center */
202 if (upx == 1 && upy == 1) 203 if (upx == 1 && upy == 1)
203 find_in_layout (1, 0, &upx, &upy, maze, RP); 204 find_in_layout (1, 0, upx, upy, maze);
204 else if (upx == 1 && upy > 1) 205 else if (upx == 1 && upy > 1)
205 find_in_layout (3, 0, &upx, &upy, maze, RP); 206 find_in_layout (3, 0, upx, upy, maze);
206 else if (upx > 1 && upy == 1) 207 else if (upx > 1 && upy == 1)
207 find_in_layout (2, 0, &upx, &upy, maze, RP); 208 find_in_layout (2, 0, upx, upy, maze);
208 else if (upx > 1 && upy > 1) 209 else if (upx > 1 && upy > 1)
209 find_in_layout (4, 0, &upx, &upy, maze, RP); 210 find_in_layout (4, 0, upx, upy, maze);
210 } 211 }
211 212
212 /* no indication of where to place the exit, so just place it. */ 213 /* no indication of where to place the exit, so just place it. */
213 if (upx == -1) 214 if (upx == -1)
214 find_in_layout (0, 0, &upx, &upy, maze, RP); 215 find_in_layout (0, 0, upx, upy, maze);
215 216
216 the_exit_up->x = upx; 217 the_exit_up->x = upx;
217 the_exit_up->y = upy; 218 the_exit_up->y = upy;
218 219
219 /* surround the exits with notices that this is a random map. */ 220 /* surround the exits with notices that this is a random map. */
220 for (int j = 1; j < 9; j++) 221 for (int j = 1; j < 9; j++)
221 {
222 if (!wall_blocked (map, the_exit_up->x + freearr_x[j], the_exit_up->y + freearr_y[j])) 222 if (!wall_blocked (map, the_exit_up->x + freearr_x[j], the_exit_up->y + freearr_y[j]))
223 { 223 {
224 object *random_sign = archetype::get (shstr_sign); 224 object *random_sign = archetype::get (shstr_sign);
225 random_sign->msg = format ("This is a random map.\nLevel: %d\n", RP->dungeon_level - 1); 225 random_sign->msg = format ("This is a random map.\nLevel: %d of %d.\n", RP->dungeon_level - 1, RP->dungeon_depth);
226 map->insert (random_sign, the_exit_up->x + freearr_x[j], the_exit_up->y + freearr_y[j], 0, 0); 226 map->insert (random_sign, the_exit_up->x + freearr_x[j], the_exit_up->y + freearr_y[j], 0, 0);
227 } 227 }
228 }
229 228
230 /* Block the exit so things don't get dumped on top of it. */ 229 /* Block the exit so things don't get dumped on top of it. */
231 the_exit_up->move_block = MOVE_ALL; 230 the_exit_up->move_block = MOVE_ALL;
232 231
233 insert_ob_in_map (the_exit_up, map, NULL, 0); 232 insert_ob_in_map (the_exit_up, map, NULL, 0);
236 /* set the starting x,y for this map */ 235 /* set the starting x,y for this map */
237 map->enter_x = the_exit_up->x; 236 map->enter_x = the_exit_up->x;
238 map->enter_y = the_exit_up->y; 237 map->enter_y = the_exit_up->y;
239 238
240 /* first, look for a '>' character */ 239 /* first, look for a '>' character */
241 find_in_layout (0, '>', &downx, &downy, maze, RP); 240 find_in_layout (0, '>', downx, downy, maze);
242 241
243 /* if no > is found use C */ 242 /* if no > is found use C */
244 if (downx == -1) 243 if (downx == -1)
245 { 244 {
246 downx = cx; 245 downx = cx;
261 else 260 else
262 downy = RP->Ysize - 2; 261 downy = RP->Ysize - 2;
263 262
264 /* find an empty place far from the entrance */ 263 /* find an empty place far from the entrance */
265 if (downx == 1 && downy == 1) 264 if (downx == 1 && downy == 1)
266 find_in_layout (1, 0, &downx, &downy, maze, RP); 265 find_in_layout (1, 0, downx, downy, maze);
267 else if (downx == 1 && downy > 1) 266 else if (downx == 1 && downy > 1)
268 find_in_layout (3, 0, &downx, &downy, maze, RP); 267 find_in_layout (3, 0, downx, downy, maze);
269 else if (downx > 1 && downy == 1) 268 else if (downx > 1 && downy == 1)
270 find_in_layout (2, 0, &downx, &downy, maze, RP); 269 find_in_layout (2, 0, downx, downy, maze);
271 else if (downx > 1 && downy > 1) 270 else if (downx > 1 && downy > 1)
272 find_in_layout (4, 0, &downx, &downy, maze, RP); 271 find_in_layout (4, 0, downx, downy, maze);
273 } 272 }
274 273
275 /* no indication of where to place the down exit, so just place it */ 274 /* no indication of where to place the down exit, so just place it */
276 if (downx == -1) 275 if (downx == -1)
277 find_in_layout (0, 0, &downx, &downy, maze, RP); 276 find_in_layout (0, 0, downx, downy, maze);
278 277
279 if (the_exit_down) 278 if (the_exit_down)
280 { 279 {
281 char buf[16384];
282
283 int i = find_free_spot (the_exit_down, map, downx, downy, 1, SIZEOFFREE1 + 1); 280 int i = rmg_find_free_spot (the_exit_down, map, downx, downy, 1, SIZEOFFREE1 + 1);
284 the_exit_down->x = downx + freearr_x[i]; 281 the_exit_down->x = downx + freearr_x[i];
285 the_exit_down->y = downy + freearr_y[i]; 282 the_exit_down->y = downy + freearr_y[i];
286 RP->origin_x = the_exit_down->x; 283 RP->set ("origin_x", (IV)the_exit_down->x);
287 RP->origin_y = the_exit_down->y; 284 RP->set ("origin_y", (IV)the_exit_down->y);
288 write_map_parameters_to_string (buf, RP); 285
289 the_exit_down->msg = buf; 286 the_exit_down->msg = RP->as_shstr ();
290 287
291 /* the identifier for making a random map. */ 288 /* the identifier for making a random map. */
292 if (RP->dungeon_level >= RP->dungeon_depth && *RP->final_map) 289 if (RP->dungeon_level >= RP->dungeon_depth && final_map)
293 { 290 {
294 maptile *new_map; 291 maptile *new_map;
295 object *the_exit_back = the_exit_up->arch->instance (); 292 object *the_exit_back = the_exit_up->arch->instance ();
296 293
297 /* load it */ 294 /* load it */
298 if (!(new_map = maptile::find_sync (RP->final_map))) 295 if (!(new_map = maptile::find_sync (final_map)))
299 return; 296 return;
300 297
301 new_map->load_sync (); 298 new_map->load_sync ();
302 299
303 the_exit_down->slaying = RP->final_map; 300 the_exit_down->slaying = final_map;
304 301
305 for (object *tmp = new_map->at (new_map->enter_x, new_map->enter_y).bot; tmp; tmp = tmp->above) 302 for (object *tmp = new_map->at (new_map->enter_x, new_map->enter_y).bot; tmp; tmp = tmp->above)
306 /* Remove exit back to previous random map. There should only be one 303 /* Remove exit back to previous random map. There should only be one
307 * which is why we break out. To try to process more than one 304 * which is why we break out. To try to process more than one
308 * would require keeping a 'next' pointer, ad free_object kills tmp, which 305 * would require keeping a 'next' pointer, ad free_object kills tmp, which
312 { 309 {
313 tmp->destroy (); 310 tmp->destroy ();
314 break; 311 break;
315 } 312 }
316 313
317 if (final_map_exit == 1) 314 if (final_map_exit)
318 { 315 {
319 /* setup the exit back */ 316 /* setup the exit back */
320 the_exit_back->slaying = map->path; 317 the_exit_back->slaying = map->path;
321 the_exit_back->stats.hp = the_exit_down->x; 318 the_exit_back->stats.hp = the_exit_down->x;
322 the_exit_back->stats.sp = the_exit_down->y; 319 the_exit_back->stats.sp = the_exit_down->y;
339 336
340/* this function unblocks the exits. We blocked them to 337/* this function unblocks the exits. We blocked them to
341 keep things from being dumped on them during the other 338 keep things from being dumped on them during the other
342 phases of random map generation. */ 339 phases of random map generation. */
343void 340void
344unblock_exits (maptile *map, char **maze, random_map_params *RP) 341unblock_exits (maptile *map, layout &maze)
345{ 342{
346 int i = 0, j = 0; 343 int i = 0, j = 0;
347 object *walk; 344 object *walk;
348 345
349 for (i = 0; i < RP->Xsize; i++) 346 for (i = 0; i < maze.w; i++)
350 for (j = 0; j < RP->Ysize; j++) 347 for (j = 0; j < maze.h; j++)
351 if (maze[i][j] == '>' || maze[i][j] == '<') 348 if (maze[i][j] == '>' || maze[i][j] == '<')
352 { 349 {
353 for (walk = GET_MAP_OB (map, i, j); walk != NULL; walk = walk->above) 350 for (walk = GET_MAP_OB (map, i, j); walk != NULL; walk = walk->above)
354 { 351 {
355 if (walk->move_block == MOVE_ALL && walk->type != LOCKED_DOOR) 352 if (walk->move_block == MOVE_ALL && walk->type != LOCKED_DOOR)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines