00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <global.h>
00030 #include <random_map.h>
00031 #include <sproto.h>
00032 #include <rproto.h>
00033
00058 void find_in_layout(int mode, char target, int *fx, int *fy, char **layout, RMParms *RP) {
00059 int M;
00060 int i, j;
00061
00062 *fx = -1;
00063 *fy = -1;
00064
00065
00066 if (mode < 1 || mode > 4)
00067 M = RANDOM()%4+1;
00068 else
00069 M = mode;
00070
00071
00072
00073
00074 switch (M) {
00075 case 1: {
00076 for (i = 1; i < RP->Xsize; i++)
00077 for (j = 1; j < RP->Ysize; j++) {
00078 if (layout[i][j] == target) {
00079 *fx = i;
00080 *fy = j;
00081 return;
00082 }
00083 }
00084 break;
00085 }
00086
00087 case 2: {
00088 for (i = RP->Xsize-2; i > 0; i--)
00089 for (j = 1; j < RP->Ysize-1; j++) {
00090 if (layout[i][j] == target) {
00091 *fx = i;
00092 *fy = j;
00093 return;
00094 }
00095 }
00096 break;
00097 }
00098
00099 case 3: {
00100 for (i = 1; i < RP->Xsize-1; i++)
00101 for (j = RP->Ysize-2; j > 0; j--) {
00102 if (layout[i][j] == target) {
00103 *fx = i;
00104 *fy = j;
00105 return;
00106 }
00107 }
00108 break;
00109 }
00110
00111 case 4: {
00112 for (i = RP->Xsize-2; i > 0; i--)
00113 for (j = RP->Ysize-2; j > 0; j--) {
00114 if (layout[i][j] == target) {
00115 *fx = i;
00116 *fy = j;
00117 return;
00118 }
00119 }
00120 break;
00121 }
00122 }
00123 }
00124
00125
00126
00127
00153 void place_exits(mapstruct *map, char **maze, char *exitstyle, int orientation, RMParms *RP) {
00154 char styledirname[256];
00155 mapstruct *style_map_down = NULL;
00156 mapstruct *style_map_up = NULL;
00157 object *the_exit_down;
00158 object *the_exit_up;
00159 object *random_sign;
00160 char buf[512];
00161 int cx = -1, cy = -1;
00162 int upx = -1, upy = -1;
00163 int downx = -1, downy = -1;
00164 int final_map_exit = 1;
00165 int i, j;
00166
00167 if (RP->exit_on_final_map) {
00168 if (strstr(RP->exit_on_final_map, "no"))
00169 final_map_exit = 0;
00170 }
00171
00172 if (orientation == 0)
00173 orientation = RANDOM()%6+1;
00174
00175 switch (orientation) {
00176 case 1: {
00177 snprintf(styledirname, sizeof(styledirname), "/styles/exitstyles/up");
00178 style_map_up = find_style(styledirname, exitstyle, -1);
00179 snprintf(styledirname, sizeof(styledirname), "/styles/exitstyles/down");
00180 style_map_down = find_style(styledirname, exitstyle, -1);
00181 break;
00182 }
00183
00184 case 2: {
00185 snprintf(styledirname, sizeof(styledirname), "/styles/exitstyles/down");
00186 style_map_up = find_style(styledirname, exitstyle, -1);
00187 snprintf(styledirname, sizeof(styledirname), "/styles/exitstyles/up");
00188 style_map_down = find_style(styledirname, exitstyle, -1);
00189 break;
00190 }
00191
00192 default: {
00193 snprintf(styledirname, sizeof(styledirname), "/styles/exitstyles/generic");
00194 style_map_up = find_style(styledirname, exitstyle, -1);
00195 style_map_down = style_map_up;
00196 break;
00197 }
00198 }
00199
00200 if (style_map_up == NULL)
00201 the_exit_up = arch_to_object(find_archetype("exit"));
00202 else {
00203 object *tmp;
00204
00205 tmp = pick_random_object(style_map_up);
00206 the_exit_up = arch_to_object(tmp->arch);
00207 }
00208
00209
00210 if (RP->dungeon_level < RP->dungeon_depth || RP->final_map[0] != 0)
00211 if (RP->dungeon_level >= RP->dungeon_depth && RP->final_exit_archetype[0] != 0)
00212 the_exit_down = arch_to_object(find_archetype(RP->final_exit_archetype));
00213 else if (style_map_down == NULL)
00214 the_exit_down = arch_to_object(find_archetype("exit"));
00215 else {
00216 object *tmp;
00217
00218 tmp = pick_random_object(style_map_down);
00219 the_exit_down = arch_to_object(tmp->arch);
00220 }
00221 else
00222 the_exit_down = NULL;
00223
00224
00225 the_exit_up->stats.hp = RP->origin_x;
00226 the_exit_up->stats.sp = RP->origin_y;
00227 the_exit_up->slaying = add_string(RP->origin_map);
00228
00229
00230
00231 find_in_layout(0, '<', &upx, &upy, maze, RP);
00232
00233
00234 find_in_layout(0, 'C', &cx, &cy, maze, RP);
00235
00236
00237 if (upx == -1 && cx != -1) {
00238 if (cx > RP->Xsize/2)
00239 upx = 1;
00240 else
00241 upx = RP->Xsize-2;
00242 if (cy > RP->Ysize/2)
00243 upy = 1;
00244 else
00245 upy = RP->Ysize-2;
00246
00247
00248 if (upx == 1 && upy == 1)
00249 find_in_layout(1, 0, &upx, &upy, maze, RP);
00250 else if (upx == 1 && upy > 1)
00251 find_in_layout(3, 0, &upx, &upy, maze, RP);
00252 else if (upx > 1 && upy == 1)
00253 find_in_layout(2, 0, &upx, &upy, maze, RP);
00254 else if (upx > 1 && upy > 1)
00255 find_in_layout(4, 0, &upx, &upy, maze, RP);
00256 }
00257
00258
00259 if (upx == -1)
00260 find_in_layout(0, 0, &upx, &upy, maze, RP);
00261
00262 the_exit_up->x = upx;
00263 the_exit_up->y = upy;
00264
00265
00266 for (j = 1; j < 9; j++) {
00267 if (!wall_blocked(map, the_exit_up->x+freearr_x[j], the_exit_up->y+freearr_y[j])) {
00268 random_sign = create_archetype("sign");
00269 random_sign->x = the_exit_up->x+freearr_x[j];
00270 random_sign->y = the_exit_up->y+freearr_y[j];
00271
00272 snprintf(buf, sizeof(buf), "This is a random map.\nLevel: %d\n", (RP->dungeon_level)-1);
00273
00274 random_sign->msg = add_string(buf);
00275 insert_ob_in_map(random_sign, map, NULL, 0);
00276 }
00277 }
00278
00279 the_exit_up->move_block = MOVE_ALL;
00280
00281 insert_ob_in_map(the_exit_up, map, NULL, 0);
00282 maze[the_exit_up->x][the_exit_up->y] = '<';
00283
00284
00285 MAP_ENTER_X(map) = the_exit_up->x;
00286 MAP_ENTER_Y(map) = the_exit_up->y;
00287
00288
00289 find_in_layout(0, '>', &downx, &downy, maze, RP);
00290
00291 if (downx == -1) {
00292 downx = cx;
00293 downy = cy;
00294 }
00295
00296
00297
00298 if (downx == -1) {
00299 if (upx > RP->Xsize/2)
00300 downx = 1;
00301 else
00302 downx = RP->Xsize-2;
00303 if (upy > RP->Ysize/2)
00304 downy = 1;
00305 else
00306 downy = RP->Ysize-2;
00307
00308
00309 if (downx == 1 && downy == 1)
00310 find_in_layout(1, 0, &downx, &downy, maze, RP);
00311 else if (downx == 1 && downy > 1)
00312 find_in_layout(3, 0, &downx, &downy, maze, RP);
00313 else if (downx > 1 && downy == 1)
00314 find_in_layout(2, 0, &downx, &downy, maze, RP);
00315 else if (downx > 1 && downy > 1)
00316 find_in_layout(4, 0, &downx, &downy, maze, RP);
00317
00318 }
00319
00320 if (downx == -1)
00321 find_in_layout(0, 0, &downx, &downy, maze, RP);
00322 if (the_exit_down) {
00323 char buf[2048];
00324
00325 i = find_first_free_spot(the_exit_down, map, downx, downy);
00326 the_exit_down->x = downx+freearr_x[i];
00327 the_exit_down->y = downy+freearr_y[i];
00328 RP->origin_x = the_exit_down->x;
00329 RP->origin_y = the_exit_down->y;
00330 write_map_parameters_to_string(RP, buf, sizeof(buf));
00331 the_exit_down->msg = add_string(buf);
00332
00333 if (RP->dungeon_level >= RP->dungeon_depth && RP->final_map[0] != 0) {
00334
00335 mapstruct *new_map;
00336 object *the_exit_back = arch_to_object(the_exit_up->arch), *tmp;
00337
00338
00339 if ((new_map = ready_map_name(RP->final_map, 0)) == NULL)
00340 return;
00341
00342 the_exit_down->slaying = add_string(RP->final_map);
00343 EXIT_X(the_exit_down) = MAP_ENTER_X(new_map);
00344 EXIT_Y(the_exit_down) = MAP_ENTER_Y(new_map);
00345 strncpy(new_map->path, RP->final_map, sizeof(new_map->path));
00346
00347 for (tmp = GET_MAP_OB(new_map, MAP_ENTER_X(new_map), MAP_ENTER_Y(new_map)); tmp; tmp = tmp->above)
00348
00349
00350
00351
00352
00353 if (tmp->type == EXIT && EXIT_PATH(tmp) && !strncmp(EXIT_PATH(tmp), "/random/", 8)) {
00354 remove_ob(tmp);
00355 free_object(tmp);
00356 break;
00357 }
00358
00359 if (final_map_exit == 1) {
00360
00361 the_exit_back->slaying = add_string(map->path);
00362 the_exit_back->stats.hp = the_exit_down->x;
00363 the_exit_back->stats.sp = the_exit_down->y;
00364 the_exit_back->x = MAP_ENTER_X(new_map);
00365 the_exit_back->y = MAP_ENTER_Y(new_map);
00366
00367 insert_ob_in_map(the_exit_back, new_map, NULL, 0);
00368 }
00369
00370 set_map_timeout(new_map);
00371 } else
00372 the_exit_down->slaying = add_string("/!");
00373
00374
00375 the_exit_down->move_block = MOVE_ALL;
00376 insert_ob_in_map(the_exit_down, map, NULL, 0);
00377 maze[the_exit_down->x][the_exit_down->y] = '>';
00378 }
00379 }
00380
00392 void unblock_exits(mapstruct *map, char **maze, RMParms *RP) {
00393 int i = 0, j = 0;
00394 object *walk;
00395
00396 for (i = 0; i < RP->Xsize; i++)
00397 for (j = 0; j < RP->Ysize; j++)
00398 if (maze[i][j] == '>' || maze[i][j] == '<') {
00399 for (walk = GET_MAP_OB(map, i, j); walk != NULL; walk = walk->above) {
00400 if (walk->move_block == MOVE_ALL && walk->type != LOCKED_DOOR) {
00401 walk->move_block = MOVE_BLOCK_DEFAULT;
00402 update_object(walk, UP_OBJ_CHANGE);
00403 }
00404 }
00405 }
00406 }