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
00030
00036 #include <global.h>
00037 #include <random_map.h>
00038 #include <rproto.h>
00039
00046 #define CONCENTRATED 1
00047 #define HIDDEN 2
00048 #define KEYREQUIRED 4
00049 #define DOORED 8
00050 #define TRAPPED 16
00051 #define SPARSE 32
00052 #define RICH 64
00053 #define FILLED 128
00054 #define LAST_OPTION 64
00055
00057 #define NO_PASS_DOORS 0
00058 #define PASS_DOORS 1
00059
00060 static object **surround_by_doors(mapstruct *map, char **layout, int x, int y, int opts);
00061
00073 int wall_blocked(mapstruct *m, int x, int y) {
00074 int r;
00075
00076 if (OUT_OF_REAL_MAP(m, x, y))
00077 return 1;
00078 r = GET_MAP_MOVE_BLOCK(m, x, y)&~MOVE_BLOCK_DEFAULT;
00079 return r;
00080 }
00081
00101 void place_treasure(mapstruct *map, char **layout, char *treasure_style, int treasureoptions, RMParms *RP) {
00102 char styledirname[256];
00103 char stylefilepath[256];
00104 mapstruct *style_map = NULL;
00105 int num_treasures;
00106
00107
00108 if (treasure_style)
00109 if (!strcmp(treasure_style, "none"))
00110 return;
00111 if (treasureoptions <= 0)
00112 treasureoptions = RANDOM()%(2*LAST_OPTION);
00113
00114
00115 if ((treasureoptions&RICH) && (treasureoptions&SPARSE)) {
00116 if (RANDOM()%2)
00117 treasureoptions -= 1;
00118 else
00119 treasureoptions -= 2;
00120 }
00121
00122
00123 if (treasureoptions&SPARSE)
00124 num_treasures = BC_RANDOM(RP->total_map_hp/600+RP->difficulty/2+1);
00125 else if (treasureoptions&RICH)
00126 num_treasures = BC_RANDOM(RP->total_map_hp/150+2*RP->difficulty+1);
00127 else
00128 num_treasures = BC_RANDOM(RP->total_map_hp/300+RP->difficulty+1);
00129
00130 if (num_treasures <= 0)
00131 return;
00132
00133
00134 snprintf(styledirname, sizeof(styledirname), "%s", "/styles/treasurestyles");
00135 snprintf(stylefilepath, sizeof(stylefilepath), "%s/%s", styledirname, treasure_style);
00136 style_map = find_style(styledirname, treasure_style, -1);
00137
00138
00139 if (treasureoptions&CONCENTRATED) {
00140
00141 switch (RP->map_layout_style) {
00142 case ONION_LAYOUT:
00143 case SPIRAL_LAYOUT:
00144 case SQUARE_SPIRAL_LAYOUT: {
00145 int i, j;
00146
00147
00148 for (i = 0; i < RP->Xsize; i++) {
00149 for (j = 0; j < RP->Ysize; j++) {
00150 if (layout[i][j] == 'C' || layout[i][j] == '>') {
00151 int tdiv = RP->symmetry_used;
00152 object **doorlist;
00153 object *chest;
00154
00155 if (tdiv == 3)
00156 tdiv = 2;
00157
00158 chest = place_chest(treasureoptions, i, j, map, style_map, num_treasures/tdiv, RP);
00159 if (!chest)
00160 continue;
00161 if (treasureoptions&(DOORED|HIDDEN)) {
00162 doorlist = find_doors_in_room(map, i, j, RP);
00163 lock_and_hide_doors(doorlist, map, treasureoptions, RP);
00164 free(doorlist);
00165 }
00166 }
00167 }
00168 }
00169 break;
00170 }
00171 default: {
00172 int i, j, tries;
00173 object *chest;
00174 object **doorlist;
00175
00176 i = j = -1;
00177 tries = 0;
00178 while (i == -1 && tries < 100) {
00179 i = RANDOM()%(RP->Xsize-2)+1;
00180 j = RANDOM()%(RP->Ysize-2)+1;
00181 find_enclosed_spot(map, &i, &j, RP);
00182 if (wall_blocked(map, i, j))
00183 i = -1;
00184 tries++;
00185 }
00186 chest = place_chest(treasureoptions, i, j, map, style_map, num_treasures, RP);
00187 if (!chest)
00188 return;
00189 i = chest->x;
00190 j = chest->y;
00191 if (treasureoptions&(DOORED|HIDDEN)) {
00192 doorlist = surround_by_doors(map, layout, i, j, treasureoptions);
00193 lock_and_hide_doors(doorlist, map, treasureoptions, RP);
00194 free(doorlist);
00195 }
00196 }
00197 }
00198 } else {
00199 int ti, i, j;
00200
00201 for (ti = 0; ti < num_treasures; ti++) {
00202 i = RANDOM()%(RP->Xsize-2)+1;
00203 j = RANDOM()%(RP->Ysize-2)+1;
00204 place_chest(treasureoptions, i, j, map, style_map, 1, RP);
00205 }
00206 }
00207 }
00208
00232 object *place_chest(int treasureoptions, int x, int y, mapstruct *map, mapstruct *style_map, int n_treasures, RMParms *RP) {
00233 object *the_chest;
00234 int i, xl, yl;
00235 treasurelist *tlist;
00236
00237 the_chest = create_archetype("chest");
00238
00239
00240 i = find_first_free_spot(the_chest, map, x, y);
00241 if (i == -1) {
00242 free_object(the_chest);
00243 return NULL;
00244 }
00245 xl = x+freearr_x[i];
00246 yl = y+freearr_y[i];
00247
00248
00249 if (wall_blocked(map, xl, yl)) {
00250 free_object(the_chest);
00251 return NULL;
00252 }
00253
00254 tlist = find_treasurelist("chest");
00255 the_chest->randomitems = tlist;
00256 the_chest->stats.hp = n_treasures;
00257
00258
00259 if (treasureoptions&TRAPPED) {
00260 mapstruct *trap_map = find_style("/styles/trapstyles", "traps", -1);
00261 object *the_trap;
00262
00263 if (trap_map) {
00264 the_trap = pick_random_object(trap_map);
00265 the_trap->stats.Cha = 10+RP->difficulty;
00266 the_trap->level = BC_RANDOM((3*RP->difficulty)/2);
00267 if (the_trap) {
00268 object *new_trap;
00269
00270 new_trap = arch_to_object(the_trap->arch);
00271 copy_object(new_trap, the_trap);
00272 new_trap->x = x;
00273 new_trap->y = y;
00274 insert_ob_in_ob(new_trap, the_chest);
00275 }
00276 }
00277 }
00278
00279
00280
00281
00282 if ((treasureoptions&KEYREQUIRED) && n_treasures > 1) {
00283 char keybuf[256];
00284
00285 snprintf(keybuf, sizeof(keybuf), "%d", (int)RANDOM());
00286 if (keyplace(map, x, y, keybuf, PASS_DOORS, 1, RP))
00287 the_chest->slaying = add_string(keybuf);
00288 }
00289
00290
00291 the_chest->x = xl;
00292 the_chest->y = yl;
00293 insert_ob_in_map(the_chest, map, NULL, 0);
00294 return the_chest;
00295 }
00296
00311 object *find_closest_monster(mapstruct *map, int x, int y, RMParms *RP) {
00312 int i;
00313
00314 for (i = 0; i < SIZEOFFREE; i++) {
00315 int lx, ly;
00316
00317 lx = x+freearr_x[i];
00318 ly = y+freearr_y[i];
00319
00320 if (lx >= 0 && ly >= 0 && lx < RP->Xsize && ly < RP->Ysize)
00321
00322 if (GET_MAP_FLAGS(map, lx, ly)&P_IS_ALIVE) {
00323 object *the_monster = GET_MAP_OB(map, lx, ly);
00324
00325 for (; the_monster != NULL && (!QUERY_FLAG(the_monster, FLAG_MONSTER)); the_monster = the_monster->above)
00326 ;
00327 if (the_monster && QUERY_FLAG(the_monster, FLAG_MONSTER))
00328 return the_monster;
00329 }
00330 }
00331 return NULL;
00332 }
00333
00361 int keyplace(mapstruct *map, int x, int y, char *keycode, int door_flag, int n_keys, RMParms *RP) {
00362 int i, j;
00363 int kx, ky;
00364 object *the_keymaster;
00365 object *the_key;
00366 char keybuf[256];
00367
00368
00369 the_key = create_archetype("key2");
00370 the_key->slaying = add_string(keycode);
00371 free_string(the_key->name);
00372 snprintf(keybuf, 256, "key from level %d of %s", RP->dungeon_level, RP->dungeon_name[0] != '\0' ? RP->dungeon_name : "a random map");
00373 the_key->name = add_string(keybuf);
00374
00375 if (door_flag == PASS_DOORS) {
00376 int tries = 0;
00377
00378 the_keymaster = NULL;
00379 while (tries < 15 && the_keymaster == NULL) {
00380 i = (RANDOM()%(RP->Xsize-2))+1;
00381 j = (RANDOM()%(RP->Ysize-2))+1;
00382 tries++;
00383 the_keymaster = find_closest_monster(map, i, j, RP);
00384 }
00385
00386 if (the_keymaster == NULL) {
00387 int freeindex;
00388
00389 freeindex = -1;
00390 for (tries = 0; tries < 15 && freeindex == -1; tries++) {
00391 kx = (RANDOM()%(RP->Xsize-2))+1;
00392 ky = (RANDOM()%(RP->Ysize-2))+1;
00393 freeindex = find_first_free_spot(the_key, map, kx, ky);
00394 }
00395 if (freeindex != -1) {
00396 kx += freearr_x[freeindex];
00397 ky += freearr_y[freeindex];
00398 }
00399 }
00400 } else {
00401
00402
00403
00404 if (n_keys == 1) {
00405 if (wall_blocked(map, x, y))
00406 return 0;
00407 the_keymaster = find_monster_in_room(map, x, y, RP);
00408 if (the_keymaster == NULL)
00409 if (!find_spot_in_room(map, x, y, &kx, &ky, RP))
00410 return 0;
00411 } else {
00412
00413
00414
00415 int sum = 0;
00416 int distance = 1;
00417
00418 while (distance < 5) {
00419
00420 sum += keyplace(map, x+distance, y, keycode, NO_PASS_DOORS, 1, RP);
00421 sum += keyplace(map, x, y+distance, keycode, NO_PASS_DOORS, 1, RP);
00422 sum += keyplace(map, x-distance, y, keycode, NO_PASS_DOORS, 1, RP);
00423 sum += keyplace(map, x, y-distance, keycode, NO_PASS_DOORS, 1, RP);
00424 if (sum < 2) {
00425
00426 keyplace(map, x+distance, y+distance, keycode, NO_PASS_DOORS, 1, RP);
00427 keyplace(map, x+distance, y-distance, keycode, NO_PASS_DOORS, 1, RP);
00428 keyplace(map, x-distance, y+distance, keycode, NO_PASS_DOORS, 1, RP);
00429 keyplace(map, x-distance, y-distance, keycode, NO_PASS_DOORS, 1, RP);
00430 }
00431 if (sum > 0)
00432 return 1;
00433 distance++;
00434 }
00435 return 0;
00436 }
00437 }
00438
00439 if (the_keymaster == NULL) {
00440 the_key->x = kx;
00441 the_key->y = ky;
00442 insert_ob_in_map(the_key, map, NULL, 0);
00443 return 1;
00444 }
00445
00446 insert_ob_in_ob(the_key, the_keymaster);
00447 return 1;
00448 }
00449
00465 object *find_monster_in_room_recursive(char **layout, mapstruct *map, int x, int y, RMParms *RP) {
00466 int i, j;
00467 object *the_monster;
00468
00469
00470 if (!(x >= 0 && y >= 0 && x < RP->Xsize && y < RP->Ysize))
00471 return NULL;
00472
00473
00474 if (layout[x][y] != 0)
00475 return NULL;
00476
00477
00478
00479 layout[x][y] = 1;
00480 if (GET_MAP_FLAGS(map, x, y)&P_IS_ALIVE) {
00481 the_monster = GET_MAP_OB(map, x, y);
00482
00483 for (; the_monster != NULL && (!QUERY_FLAG(the_monster, FLAG_ALIVE)); the_monster = the_monster->above)
00484 ;
00485 if (the_monster && QUERY_FLAG(the_monster, FLAG_ALIVE)) {
00486 return the_monster;
00487 }
00488 }
00489
00490
00491 for (i = RANDOM()%8, j = 0; j < 8; i++, j++) {
00492 the_monster = find_monster_in_room_recursive(layout, map, x+freearr_x[i%8+1], y+freearr_y[i%8+1], RP);
00493 if (the_monster != NULL)
00494 return the_monster;
00495 }
00496 return NULL;
00497 }
00498
00513 object *find_monster_in_room(mapstruct *map, int x, int y, RMParms *RP) {
00514 char **layout2;
00515 int i, j;
00516 object *theMonsterToFind;
00517
00518 layout2 = (char **)calloc(sizeof(char *), RP->Xsize);
00519
00520 for (i = 0; i < RP->Xsize; i++) {
00521 layout2[i] = (char *)calloc(sizeof(char), RP->Ysize);
00522 for (j = 0; j < RP->Ysize; j++) {
00523 if (wall_blocked(map, i, j))
00524 layout2[i][j] = '#';
00525 }
00526 }
00527 theMonsterToFind = find_monster_in_room_recursive(layout2, map, x, y, RP);
00528
00529
00530 for (i = 0; i < RP->Xsize; i++) {
00531 free(layout2[i]);
00532 }
00533 free(layout2);
00534
00535 return theMonsterToFind;
00536 }
00537
00539 typedef struct free_spots_struct {
00540 int *room_free_spots_x;
00541 int *room_free_spots_y;
00542 int number_of_free_spots_in_room;
00543 } free_spots_struct;
00544
00559 static void find_spot_in_room_recursive(char **layout, int x, int y, RMParms *RP, free_spots_struct *spots) {
00560 int i, j;
00561
00562
00563 if (!(x >= 0 && y >= 0 && x < RP->Xsize && y < RP->Ysize))
00564 return;
00565
00566
00567 if (layout[x][y] != 0)
00568 return;
00569
00570
00571
00572 layout[x][y] = 1;
00573 spots->room_free_spots_x[spots->number_of_free_spots_in_room] = x;
00574 spots->room_free_spots_y[spots->number_of_free_spots_in_room] = y;
00575 spots->number_of_free_spots_in_room++;
00576
00577 for (i = RANDOM()%8, j = 0; j < 8; i++, j++) {
00578 find_spot_in_room_recursive(layout, x+freearr_x[i%8+1], y+freearr_y[i%8+1], RP, spots);
00579 }
00580 }
00581
00600 int find_spot_in_room(mapstruct *map, int x, int y, int *kx, int *ky, RMParms *RP) {
00601 char **layout2;
00602 int i, j;
00603 free_spots_struct spots;
00604
00605 spots.number_of_free_spots_in_room = 0;
00606 spots.room_free_spots_x = (int *)calloc(sizeof(int), RP->Xsize*RP->Ysize);
00607 spots.room_free_spots_y = (int *)calloc(sizeof(int), RP->Xsize*RP->Ysize);
00608
00609 layout2 = (char **)calloc(sizeof(char *), RP->Xsize);
00610
00611 for (i = 0; i < RP->Xsize; i++) {
00612 layout2[i] = (char *)calloc(sizeof(char), RP->Ysize);
00613 for (j = 0; j < RP->Ysize; j++) {
00614 if (wall_blocked(map, i, j))
00615 layout2[i][j] = '#';
00616 }
00617 }
00618
00619
00620 find_spot_in_room_recursive(layout2, x, y, RP, &spots);
00621
00622 if (spots.number_of_free_spots_in_room > 0) {
00623 i = RANDOM()%spots.number_of_free_spots_in_room;
00624 *kx = spots.room_free_spots_x[i];
00625 *ky = spots.room_free_spots_y[i];
00626 }
00627
00628
00629 for (i = 0; i < RP->Xsize; i++) {
00630 free(layout2[i]);
00631 }
00632 free(layout2);
00633 free(spots.room_free_spots_x);
00634 free(spots.room_free_spots_y);
00635
00636 if (spots.number_of_free_spots_in_room > 0)
00637 return 1;
00638 return 0;
00639 }
00640
00653 void find_enclosed_spot(mapstruct *map, int *cx, int *cy, RMParms *RP) {
00654 int x, y;
00655 int i;
00656
00657 x = *cx;
00658 y = *cy;
00659
00660 for (i = 0; i <= SIZEOFFREE1; i++) {
00661 int lx, ly, sindex;
00662 lx = x+freearr_x[i];
00663 ly = y+freearr_y[i];
00664 sindex = surround_flag3(map, lx, ly, RP);
00665
00666 if (sindex == 7 || sindex == 11 || sindex == 13 || sindex == 14) {
00667 *cx = lx;
00668 *cy = ly;
00669 return;
00670 }
00671 }
00672
00673
00674
00675 for (i = 0; i <= SIZEOFFREE1; i++) {
00676 int lx, ly, sindex;
00677
00678 lx = x+freearr_x[i];
00679 ly = y+freearr_y[i];
00680 sindex = surround_flag3(map, lx, ly, RP);
00681
00682 if (sindex == 3 || sindex == 5 || sindex == 9 || sindex == 6 || sindex == 10 || sindex == 12) {
00683 *cx = lx;
00684 *cy = ly;
00685 return;
00686 }
00687 }
00688
00689
00690 for (i = 0; i <= SIZEOFFREE1; i++) {
00691 int lx, ly, sindex;
00692
00693 lx = x+freearr_x[i];
00694 ly = y+freearr_y[i];
00695 sindex = surround_flag3(map, lx, ly, RP);
00696
00697 if (sindex) {
00698 *cx = lx;
00699 *cy = ly;
00700 return;
00701 }
00702 }
00703
00704
00705 i = find_first_free_spot(&find_archetype("chest")->clone, map, x, y);
00706 if (i != -1 && i <= SIZEOFFREE1) {
00707 *cx = x+freearr_x[i];
00708 *cy = y+freearr_y[i];
00709 return;
00710 }
00711
00712 *cx = *cy = -1;
00713 }
00714
00722 void remove_monsters(int x, int y, mapstruct *map) {
00723 object *tmp;
00724
00725 for (tmp = GET_MAP_OB(map, x, y); tmp != NULL; tmp = tmp->above)
00726 if (QUERY_FLAG(tmp, FLAG_ALIVE)) {
00727 if (tmp->head)
00728 tmp = tmp->head;
00729 remove_ob(tmp);
00730 free_object(tmp);
00731 tmp = GET_MAP_OB(map, x, y);
00732 if (tmp == NULL)
00733 break;
00734 };
00735 }
00736
00755 static object **surround_by_doors(mapstruct *map, char **layout, int x, int y, int opts) {
00756 int i;
00757 const char *doors[2];
00758 object **doorlist;
00759 int ndoors_made = 0;
00760 doorlist = (object **)calloc(9, sizeof(object *));
00761
00762
00763 if (opts&DOORED) {
00764 doors[0] = "locked_door2";
00765 doors[1] = "locked_door1";
00766 } else {
00767 doors[0] = "door_1";
00768 doors[1] = "door_2";
00769 }
00770
00771
00772 for (i = 1; i < 9; i++) {
00773 int x1 = x+freearr_x[i], y1 = y+freearr_y[i];
00774
00775 if (!wall_blocked(map, x1, y1)
00776 || layout[x1][y1] == '>') {
00777 object *new_door = create_archetype((freearr_x[i] == 0) ? doors[1] : doors[0]);
00778
00779 new_door->x = x+freearr_x[i];
00780 new_door->y = y+freearr_y[i];
00781 remove_monsters(new_door->x, new_door->y, map);
00782 insert_ob_in_map(new_door, map, NULL, 0);
00783 doorlist[ndoors_made] = new_door;
00784 ndoors_made++;
00785 }
00786 }
00787 return doorlist;
00788 }
00789
00801 static object *door_in_square(mapstruct *map, int x, int y) {
00802 object *tmp;
00803
00804 for (tmp = GET_MAP_OB(map, x, y); tmp != NULL; tmp = tmp->above)
00805 if (tmp->type == DOOR || tmp->type == LOCKED_DOOR)
00806 return tmp;
00807 return NULL;
00808 }
00809
00824 void find_doors_in_room_recursive(char **layout, mapstruct *map, int x, int y, object **doorlist, int *ndoors, RMParms *RP) {
00825 int i, j;
00826 object *door;
00827
00828
00829 if (!(x >= 0 && y >= 0 && x < RP->Xsize && y < RP->Ysize))
00830 return;
00831
00832
00833 if (layout[x][y] == 1)
00834 return;
00835
00836
00837 if (layout[x][y] == '#') {
00838 layout[x][y] = 1;
00839 door = door_in_square(map, x, y);
00840 if (door != NULL) {
00841 doorlist[*ndoors] = door;
00842 if (*ndoors > 254) {
00843 LOG(llevError, "find_doors_in_room_recursive:Too many doors for memory allocated!\n");
00844 return;
00845 }
00846 *ndoors = *ndoors+1;
00847 }
00848 } else {
00849 layout[x][y] = 1;
00850
00851 for (i = RANDOM()%8, j = 0; j < 8; i++, j++) {
00852 find_doors_in_room_recursive(layout, map, x+freearr_x[i%8+1], y+freearr_y[i%8+1], doorlist, ndoors, RP);
00853 }
00854 }
00855 }
00856
00871 object **find_doors_in_room(mapstruct *map, int x, int y, RMParms *RP) {
00872 char **layout2;
00873 object **doorlist;
00874 int i, j;
00875 int ndoors = 0;
00876
00877 doorlist = (object **)calloc(sizeof(int), 256);
00878
00879
00880 layout2 = (char **)calloc(sizeof(char *), RP->Xsize);
00881
00882 for (i = 0; i < RP->Xsize; i++) {
00883 layout2[i] = (char *)calloc(sizeof(char), RP->Ysize);
00884 for (j = 0; j < RP->Ysize; j++) {
00885 if (wall_blocked(map, i, j))
00886 layout2[i][j] = '#';
00887 }
00888 }
00889
00890
00891 find_doors_in_room_recursive(layout2, map, x, y, doorlist, &ndoors, RP);
00892
00893
00894 for (i = 0; i < RP->Xsize; i++) {
00895 free(layout2[i]);
00896 }
00897 free(layout2);
00898 return doorlist;
00899 }
00900
00910 static void remove_adjacent_doors(object *door) {
00911 mapstruct *m = door->map;
00912 int x = door->x;
00913 int y = door->y;
00914 int i, flags;
00915 object *tmp;
00916
00917 for (i = 1; i <= 8; i++) {
00918 flags = get_map_flags(m, NULL, x+freearr_x[i], y+freearr_y[i], NULL, NULL);
00919 if (flags&P_OUT_OF_MAP)
00920 continue;
00921
00922
00923
00924
00925 if (flags&P_IS_ALIVE) {
00926 for (tmp = GET_MAP_OB(m, x+freearr_x[i], y+freearr_y[i]); tmp; tmp = tmp->above) {
00927 if (tmp->type == DOOR) {
00928 remove_ob(tmp);
00929 free_object(tmp);
00930 break;
00931 }
00932 }
00933 }
00934 }
00935 }
00936
00952 void lock_and_hide_doors(object **doorlist, mapstruct *map, int opts, RMParms *RP) {
00953 object *door;
00954 int i;
00955
00956
00957 if (opts&DOORED) {
00958 for (i = 0, door = doorlist[0]; doorlist[i] != NULL; i++) {
00959 object *new_door = create_archetype("locked_door1");
00960 char keybuf[256];
00961
00962 door = doorlist[i];
00963 new_door->face = door->face;
00964 new_door->x = door->x;
00965 new_door->y = door->y;
00966 remove_ob(door);
00967 free_object(door);
00968 doorlist[i] = new_door;
00969 insert_ob_in_map(new_door, map, NULL, 0);
00970
00971 snprintf(keybuf, 256, "%d", (int)RANDOM());
00972 if (keyplace(map, new_door->x, new_door->y, keybuf, NO_PASS_DOORS, 2, RP))
00973 new_door->slaying = add_string(keybuf);
00974 }
00975 for (i = 0; doorlist[i] != NULL; i++)
00976 remove_adjacent_doors(doorlist[i]);
00977 }
00978
00979
00980 if (opts&HIDDEN) {
00981 for (i = 0, door = doorlist[0]; doorlist[i] != NULL; i++) {
00982 object *wallface;
00983
00984 door = doorlist[i];
00985 wallface = retrofit_joined_wall(map, door->x, door->y, 1, RP);
00986 if (wallface != NULL) {
00987 retrofit_joined_wall(map, door->x-1, door->y, 0, RP);
00988 retrofit_joined_wall(map, door->x+1, door->y, 0, RP);
00989 retrofit_joined_wall(map, door->x, door->y-1, 0, RP);
00990 retrofit_joined_wall(map, door->x, door->y+1, 0, RP);
00991 door->face = wallface->face;
00992 if (!QUERY_FLAG(wallface, FLAG_REMOVED))
00993 remove_ob(wallface);
00994 free_object(wallface);
00995 }
00996 }
00997 }
00998 }