1 | /* |
1 | /* |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
3 | * |
3 | * |
4 | * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
4 | * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 | * Copyright (©) 2001,2007 Mark Wedel & Crossfire Development Team |
5 | * Copyright (©) 2001,2007 Mark Wedel & Crossfire Development Team |
6 | * Copyright (©) 1992,2007 Frank Tore Johansen |
6 | * Copyright (©) 1992,2007 Frank Tore Johansen |
7 | * |
7 | * |
8 | * Deliantra is free software: you can redistribute it and/or modify |
8 | * Deliantra 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 |
… | |
… | |
136 | for (j = 0; j < RP->Ysize; j++) |
136 | for (j = 0; j < RP->Ysize; j++) |
137 | { |
137 | { |
138 | if (layout[i][j] == 'C' || layout[i][j] == '>') |
138 | if (layout[i][j] == 'C' || layout[i][j] == '>') |
139 | { |
139 | { |
140 | int tdiv = RP->symmetry_used; |
140 | int tdiv = RP->symmetry_used; |
141 | object **doorlist; |
|
|
142 | object *chest; |
141 | object *chest; |
143 | |
142 | |
144 | if (tdiv == 3) |
143 | if (tdiv == 3) |
145 | tdiv = 2; /* this symmetry uses a divisor of 2 */ |
144 | tdiv = 2; /* this symmetry uses a divisor of 2 */ |
146 | /* don't put a chest on an exit. */ |
145 | /* don't put a chest on an exit. */ |
147 | chest = place_chest (treasureoptions, i, j, map, style_map, num_treasures / tdiv, RP); |
146 | chest = place_chest (treasureoptions, i, j, map, style_map, num_treasures / tdiv, RP); |
|
|
147 | |
148 | if (!chest) |
148 | if (!chest) |
149 | continue; /* if no chest was placed NEXT */ |
149 | continue; /* if no chest was placed NEXT */ |
|
|
150 | |
150 | if (treasureoptions & (DOORED | HIDDEN)) |
151 | if (treasureoptions & (DOORED | HIDDEN)) |
151 | { |
152 | { |
152 | doorlist = find_doors_in_room (map, i, j, RP); |
153 | object **doorlist = find_doors_in_room (map, i, j, RP); |
153 | lock_and_hide_doors (doorlist, map, treasureoptions, RP); |
154 | lock_and_hide_doors (doorlist, map, treasureoptions, RP); |
154 | free (doorlist); |
155 | free (doorlist); |
155 | } |
156 | } |
156 | } |
157 | } |
157 | } |
158 | } |
… | |
… | |
501 | /* allocate and copy the layout, converting C to 0. */ |
502 | /* allocate and copy the layout, converting C to 0. */ |
502 | for (i = 0; i < RP->Xsize; i++) |
503 | for (i = 0; i < RP->Xsize; i++) |
503 | { |
504 | { |
504 | layout2[i] = (char *) calloc (sizeof (char), RP->Ysize); |
505 | layout2[i] = (char *) calloc (sizeof (char), RP->Ysize); |
505 | for (j = 0; j < RP->Ysize; j++) |
506 | for (j = 0; j < RP->Ysize; j++) |
506 | { |
|
|
507 | if (wall_blocked (map, i, j)) |
507 | if (wall_blocked (map, i, j)) |
508 | layout2[i][j] = '#'; |
508 | layout2[i][j] = '#'; |
509 | } |
|
|
510 | } |
509 | } |
|
|
510 | |
511 | theMonsterToFind = find_monster_in_room_recursive (layout2, map, x, y, RP); |
511 | theMonsterToFind = find_monster_in_room_recursive (layout2, map, x, y, RP); |
512 | |
512 | |
513 | /* deallocate the temp. layout */ |
513 | /* deallocate the temp. layout */ |
514 | for (i = 0; i < RP->Xsize; i++) |
514 | for (i = 0; i < RP->Xsize; i++) |
515 | { |
|
|
516 | free (layout2[i]); |
515 | free (layout2[i]); |
517 | } |
516 | |
518 | free (layout2); |
517 | free (layout2); |
519 | |
518 | |
520 | return theMonsterToFind; |
519 | return theMonsterToFind; |
521 | } |
520 | } |
522 | |
521 | |
… | |
… | |
746 | if (tmp->type == DOOR || tmp->type == LOCKED_DOOR) |
745 | if (tmp->type == DOOR || tmp->type == LOCKED_DOOR) |
747 | return tmp; |
746 | return tmp; |
748 | return NULL; |
747 | return NULL; |
749 | } |
748 | } |
750 | |
749 | |
751 | |
|
|
752 | /* the workhorse routine, which finds the doors in a room */ |
750 | /* the workhorse routine, which finds the doors in a room */ |
753 | void |
751 | void |
754 | find_doors_in_room_recursive (char **layout, maptile *map, int x, int y, object **doorlist, int *ndoors, random_map_params *RP) |
752 | find_doors_in_room_recursive (char **layout, maptile *map, int x, int y, object **doorlist, int *ndoors, random_map_params *RP) |
755 | { |
753 | { |
756 | int i, j; |
754 | int i, j; |
… | |
… | |
770 | layout[x][y] = 1; |
768 | layout[x][y] = 1; |
771 | door = door_in_square (map, x, y); |
769 | door = door_in_square (map, x, y); |
772 | if (door) |
770 | if (door) |
773 | { |
771 | { |
774 | doorlist[*ndoors] = door; |
772 | doorlist[*ndoors] = door; |
|
|
773 | |
775 | if (*ndoors > 1022) /* eek! out of memory */ |
774 | if (*ndoors > 1022) /* eek! out of memory */ |
776 | { |
775 | { |
777 | LOG (llevError, "find_doors_in_room_recursive:Too many doors for memory allocated!\n"); |
776 | LOG (llevError, "find_doors_in_room_recursive:Too many doors for memory allocated!\n"); |
778 | return; |
777 | return; |
779 | } |
778 | } |
… | |
… | |
795 | |
794 | |
796 | /* find a random non-blocked spot in this room to drop a key. */ |
795 | /* find a random non-blocked spot in this room to drop a key. */ |
797 | object ** |
796 | object ** |
798 | find_doors_in_room (maptile *map, int x, int y, random_map_params *RP) |
797 | find_doors_in_room (maptile *map, int x, int y, random_map_params *RP) |
799 | { |
798 | { |
800 | char **layout2; |
|
|
801 | object **doorlist; |
|
|
802 | int i, j; |
799 | int i, j; |
803 | int ndoors = 0; |
800 | int ndoors = 0; |
804 | |
801 | |
805 | doorlist = (object **) calloc (sizeof (int), 1024); |
802 | object **doorlist = (object **) calloc (sizeof (int), 1024); |
806 | |
803 | |
807 | layout2 = (char **) calloc (sizeof (char *), RP->Xsize); |
804 | MazeData layout2 (RP->Xsize, RP->Ysize); |
|
|
805 | |
808 | /* allocate and copy the layout, converting C to 0. */ |
806 | /* allocate and copy the layout, converting C to 0. */ |
809 | for (i = 0; i < RP->Xsize; i++) |
807 | for (i = 0; i < RP->Xsize; i++) |
810 | { |
|
|
811 | layout2[i] = (char *) calloc (sizeof (char), RP->Ysize); |
|
|
812 | for (j = 0; j < RP->Ysize; j++) |
808 | for (j = 0; j < RP->Ysize; j++) |
813 | { |
|
|
814 | if (wall_blocked (map, i, j)) |
809 | if (wall_blocked (map, i, j)) |
815 | layout2[i][j] = '#'; |
810 | layout2[i][j] = '#'; |
816 | } |
|
|
817 | } |
|
|
818 | |
811 | |
819 | /* setup num_free_spots and room_free_spots */ |
812 | /* setup num_free_spots and room_free_spots */ |
820 | find_doors_in_room_recursive (layout2, map, x, y, doorlist, &ndoors, RP); |
813 | find_doors_in_room_recursive (layout2, map, x, y, doorlist, &ndoors, RP); |
821 | |
814 | |
822 | /* deallocate the temp. layout */ |
|
|
823 | for (i = 0; i < RP->Xsize; i++) |
|
|
824 | free (layout2[i]); |
|
|
825 | |
|
|
826 | free (layout2); |
|
|
827 | return doorlist; |
815 | return doorlist; |
828 | } |
816 | } |
829 | |
|
|
830 | |
|
|
831 | |
817 | |
832 | /* locks and/or hides all the doors in doorlist, or does nothing if |
818 | /* locks and/or hides all the doors in doorlist, or does nothing if |
833 | opts doesn't say to lock/hide doors. */ |
819 | opts doesn't say to lock/hide doors. */ |
834 | |
|
|
835 | void |
820 | void |
836 | lock_and_hide_doors (object **doorlist, maptile *map, int opts, random_map_params *RP) |
821 | lock_and_hide_doors (object **doorlist, maptile *map, int opts, random_map_params *RP) |
837 | { |
822 | { |
838 | object *door; |
823 | object *door; |
839 | int i; |
824 | int i; |