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

Comparing deliantra/server/random_maps/treasure.C (file contents):
Revision 1.25 by root, Sat Feb 17 23:32:11 2007 UTC vs.
Revision 1.36 by root, Tue Apr 15 03:00:24 2008 UTC

1/* 1/*
2 * CrossFire, A Multiplayer game 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * 3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team 4 * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (C) 2001 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2001,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 * 7 *
8 * This program 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
10 * the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version. 11 * (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * 20 *
22 * The authors can be reached via e-mail at <crossfire@schmorp.de> 21 * The authors can be reached via e-mail to <support@deliantra.net>
23 */ 22 */
24 23
25/* placing treasure in maps, where appropriate. */ 24/* placing treasure in maps, where appropriate. */
26 25
27#include <global.h> 26#include <global.h>
59wall_blocked (maptile *m, int x, int y) 58wall_blocked (maptile *m, int x, int y)
60{ 59{
61 if (OUT_OF_REAL_MAP (m, x, y)) 60 if (OUT_OF_REAL_MAP (m, x, y))
62 return 1; 61 return 1;
63 62
63 m->at (x, y).update ();
64 int r = GET_MAP_MOVE_BLOCK (m, x, y) & ~MOVE_BLOCK_DEFAULT; 64 return GET_MAP_MOVE_BLOCK (m, x, y) & MOVE_WALK;
65 return r;
66} 65}
67 66
68/* place treasures in the map, given the 67/* place treasures in the map, given the
69map, (required) 68map, (required)
70layout, (required) 69layout, (required)
119 } 118 }
120 119
121 /* all the treasure at one spot in the map. */ 120 /* all the treasure at one spot in the map. */
122 if (treasureoptions & CONCENTRATED) 121 if (treasureoptions & CONCENTRATED)
123 { 122 {
124
125 /* map_layout_style global, and is previously set */ 123 /* map_layout_style global, and is previously set */
126 switch (RP->map_layout_style) 124 switch (RP->map_layout_style)
127 { 125 {
128 case LAYOUT_ONION: 126 case LAYOUT_ONION:
129 case LAYOUT_SPIRAL: 127 case LAYOUT_SPIRAL:
137 for (j = 0; j < RP->Ysize; j++) 135 for (j = 0; j < RP->Ysize; j++)
138 { 136 {
139 if (layout[i][j] == 'C' || layout[i][j] == '>') 137 if (layout[i][j] == 'C' || layout[i][j] == '>')
140 { 138 {
141 int tdiv = RP->symmetry_used; 139 int tdiv = RP->symmetry_used;
142 object **doorlist;
143 object *chest; 140 object *chest;
144 141
145 if (tdiv == 3) 142 if (tdiv == 3)
146 tdiv = 2; /* this symmetry uses a divisor of 2 */ 143 tdiv = 2; /* this symmetry uses a divisor of 2 */
144
147 /* don't put a chest on an exit. */ 145 /* don't put a chest on an exit. */
148 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
149 if (!chest) 148 if (!chest)
150 continue; /* if no chest was placed NEXT */ 149 continue; /* if no chest was placed NEXT */
150
151 if (treasureoptions & (DOORED | HIDDEN)) 151 if (treasureoptions & (DOORED | HIDDEN))
152 { 152 {
153 doorlist = find_doors_in_room (map, i, j, RP); 153 object **doorlist = find_doors_in_room (map, i, j, RP);
154 lock_and_hide_doors (doorlist, map, treasureoptions, RP); 154 lock_and_hide_doors (doorlist, map, treasureoptions, RP);
155 free (doorlist); 155 free (doorlist);
156 } 156 }
157 } 157 }
158 } 158 }
170 while (i == -1 && tries < 100) 170 while (i == -1 && tries < 100)
171 { 171 {
172 i = rndm (RP->Xsize - 2) + 1; 172 i = rndm (RP->Xsize - 2) + 1;
173 j = rndm (RP->Ysize - 2) + 1; 173 j = rndm (RP->Ysize - 2) + 1;
174 find_enclosed_spot (map, &i, &j, RP); 174 find_enclosed_spot (map, &i, &j, RP);
175
175 if (wall_blocked (map, i, j)) 176 if (wall_blocked (map, i, j))
176 i = -1; 177 i = -1;
178
177 tries++; 179 tries++;
178 } 180 }
181
179 chest = place_chest (treasureoptions, i, j, map, style_map, num_treasures, RP); 182 chest = place_chest (treasureoptions, i, j, map, style_map, num_treasures, RP);
183
180 if (!chest) 184 if (!chest)
181 return; 185 return;
186
182 i = chest->x; 187 i = chest->x;
183 j = chest->y; 188 j = chest->y;
184 if (treasureoptions & (DOORED | HIDDEN)) 189 if (treasureoptions & (DOORED | HIDDEN))
185 { 190 {
186 doorlist = surround_by_doors (map, layout, i, j, treasureoptions); 191 doorlist = surround_by_doors (map, layout, i, j, treasureoptions);
204} 209}
205 210
206/* put a chest into the map, near x and y, with the treasure style 211/* put a chest into the map, near x and y, with the treasure style
207 determined (may be null, or may be a treasure list from lib/treasures, 212 determined (may be null, or may be a treasure list from lib/treasures,
208 if the global variable "treasurestyle" is set to that treasure list's name */ 213 if the global variable "treasurestyle" is set to that treasure list's name */
209
210object * 214object *
211place_chest (int treasureoptions, int x, int y, maptile *map, maptile *style_map, int n_treasures, random_map_params *RP) 215place_chest (int treasureoptions, int x, int y, maptile *map, maptile *style_map, int n_treasures, random_map_params *RP)
212{ 216{
213 object *the_chest; 217 object *the_chest;
214 int i, xl, yl; 218 int i, xl, yl;
250 the_chest->randomitems = tlist; 254 the_chest->randomitems = tlist;
251 the_chest->stats.hp = n_treasures; 255 the_chest->stats.hp = n_treasures;
252 } 256 }
253#endif 257#endif
254 { /* neither style_map no treasure list given */ 258 { /* neither style_map no treasure list given */
255 treasurelist *tlist = find_treasurelist ("chest"); 259 treasurelist *tlist = treasurelist::find ("chest");
256 260
257 the_chest->randomitems = tlist; 261 the_chest->randomitems = tlist;
258 the_chest->stats.hp = n_treasures; 262 the_chest->stats.hp = n_treasures;
259 } 263 }
260 264
429 the_key->y = ky; 433 the_key->y = ky;
430 insert_ob_in_map (the_key, map, NULL, 0); 434 insert_ob_in_map (the_key, map, NULL, 0);
431 return 1; 435 return 1;
432 } 436 }
433 437
434 insert_ob_in_ob (the_key, the_keymaster); 438 insert_ob_in_ob (the_key, the_keymaster->head_ ());
435 return 1; 439 return 1;
436} 440}
437 441
438 442
439 443
482 { 486 {
483 theMonsterToFind = find_monster_in_room_recursive (layout, map, x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1], RP); 487 theMonsterToFind = find_monster_in_room_recursive (layout, map, x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1], RP);
484 if (theMonsterToFind != NULL) 488 if (theMonsterToFind != NULL)
485 return theMonsterToFind; 489 return theMonsterToFind;
486 } 490 }
491
487 return theMonsterToFind; 492 return theMonsterToFind;
488} 493}
489
490 494
491/* sets up some data structures: the _recursive form does the 495/* sets up some data structures: the _recursive form does the
492 real work. */ 496 real work. */
493
494object * 497object *
495find_monster_in_room (maptile *map, int x, int y, random_map_params *RP) 498find_monster_in_room (maptile *map, int x, int y, random_map_params *RP)
496{ 499{
497 char **layout2; 500 Layout layout2 (RP);
498 int i, j; 501
502 layout2->clear ();
503
504 /* allocate and copy the layout, converting C to 0. */
505 for (int i = 0; i < layout2->w; i++)
506 for (int j = 0; j < layout2->h; j++)
507 if (wall_blocked (map, i, j))
508 layout2[i][j] = '#';
499 509
500 theMonsterToFind = 0; 510 theMonsterToFind = 0;
501 layout2 = (char **) calloc (sizeof (char *), RP->Xsize);
502 /* allocate and copy the layout, converting C to 0. */
503 for (i = 0; i < RP->Xsize; i++)
504 {
505 layout2[i] = (char *) calloc (sizeof (char), RP->Ysize);
506 for (j = 0; j < RP->Ysize; j++)
507 {
508 if (wall_blocked (map, i, j))
509 layout2[i][j] = '#';
510 }
511 }
512 theMonsterToFind = find_monster_in_room_recursive (layout2, map, x, y, RP); 511 theMonsterToFind = find_monster_in_room_recursive (layout2, map, x, y, RP);
513 512
514 /* deallocate the temp. layout */ 513 layout2.free ();
515 for (i = 0; i < RP->Xsize; i++)
516 {
517 free (layout2[i]);
518 }
519 free (layout2);
520 514
521 return theMonsterToFind; 515 return theMonsterToFind;
522} 516}
523 517
524/* a datastructure needed by find_spot_in_room and find_spot_in_room_recursive */ 518/* a datastructure needed by find_spot_in_room and find_spot_in_room_recursive */
658 *cy = ly; 652 *cy = ly;
659 return; 653 return;
660 } 654 }
661 } 655 }
662 /* give up and return the closest free spot. */ 656 /* give up and return the closest free spot. */
663 i = find_free_spot (&archetype::find ("chest")->clone, map, x, y, 1, SIZEOFFREE1 + 1); 657 i = find_free_spot (archetype::find ("chest"), map, x, y, 1, SIZEOFFREE1 + 1);
664 658
665 if (i != -1) 659 if (i != -1)
666 { 660 {
667 *cx = x + freearr_x[i]; 661 *cx = x + freearr_x[i];
668 *cy = y + freearr_y[i]; 662 *cy = y + freearr_y[i];
698 it'll remove any monsters it finds.*/ 692 it'll remove any monsters it finds.*/
699object ** 693object **
700surround_by_doors (maptile *map, char **layout, int x, int y, int opts) 694surround_by_doors (maptile *map, char **layout, int x, int y, int opts)
701{ 695{
702 int i; 696 int i;
703 char *doors[2]; 697 const char *doors[2];
704 object **doorlist; 698 object **doorlist;
705 int ndoors_made = 0; 699 int ndoors_made = 0;
706 doorlist = (object **) calloc (9, sizeof (object *)); /* 9 doors so we can hold termination null */ 700 doorlist = (object **) calloc (9, sizeof (object *)); /* 9 doors so we can hold termination null */
707 701
708 /* this is a list we pick from, for horizontal and vertical doors */ 702 /* this is a list we pick from, for horizontal and vertical doors */
746 for (tmp = GET_MAP_OB (map, x, y); tmp != NULL; tmp = tmp->above) 740 for (tmp = GET_MAP_OB (map, x, y); tmp != NULL; tmp = tmp->above)
747 if (tmp->type == DOOR || tmp->type == LOCKED_DOOR) 741 if (tmp->type == DOOR || tmp->type == LOCKED_DOOR)
748 return tmp; 742 return tmp;
749 return NULL; 743 return NULL;
750} 744}
751
752 745
753/* the workhorse routine, which finds the doors in a room */ 746/* the workhorse routine, which finds the doors in a room */
754void 747void
755find_doors_in_room_recursive (char **layout, maptile *map, int x, int y, object **doorlist, int *ndoors, random_map_params *RP) 748find_doors_in_room_recursive (char **layout, maptile *map, int x, int y, object **doorlist, int *ndoors, random_map_params *RP)
756{ 749{
771 layout[x][y] = 1; 764 layout[x][y] = 1;
772 door = door_in_square (map, x, y); 765 door = door_in_square (map, x, y);
773 if (door) 766 if (door)
774 { 767 {
775 doorlist[*ndoors] = door; 768 doorlist[*ndoors] = door;
769
776 if (*ndoors > 1022) /* eek! out of memory */ 770 if (*ndoors > 1022) /* eek! out of memory */
777 { 771 {
778 LOG (llevError, "find_doors_in_room_recursive:Too many doors for memory allocated!\n"); 772 LOG (llevError, "find_doors_in_room_recursive:Too many doors for memory allocated!\n");
779 return; 773 return;
780 } 774 }
796 790
797/* find a random non-blocked spot in this room to drop a key. */ 791/* find a random non-blocked spot in this room to drop a key. */
798object ** 792object **
799find_doors_in_room (maptile *map, int x, int y, random_map_params *RP) 793find_doors_in_room (maptile *map, int x, int y, random_map_params *RP)
800{ 794{
801 char **layout2;
802 object **doorlist;
803 int i, j; 795 int i, j;
804 int ndoors = 0; 796 int ndoors = 0;
805 797
806 doorlist = (object **) calloc (sizeof (int), 1024); 798 object **doorlist = (object **)calloc (sizeof (int), 1024);
807 799
808 layout2 = (char **) calloc (sizeof (char *), RP->Xsize); 800 LayoutData layout2 (RP->Xsize, RP->Ysize);
801 layout2.clear ();
802
809 /* allocate and copy the layout, converting C to 0. */ 803 /* allocate and copy the layout, converting C to 0. */
810 for (i = 0; i < RP->Xsize; i++) 804 for (i = 0; i < RP->Xsize; i++)
811 {
812 layout2[i] = (char *) calloc (sizeof (char), RP->Ysize);
813 for (j = 0; j < RP->Ysize; j++) 805 for (j = 0; j < RP->Ysize; j++)
814 { 806 layout2[i][j] = wall_blocked (map, i, j) ? '#' : 0;
815 if (wall_blocked (map, i, j))
816 layout2[i][j] = '#';
817 }
818 }
819 807
820 /* setup num_free_spots and room_free_spots */ 808 /* setup num_free_spots and room_free_spots */
821 find_doors_in_room_recursive (layout2, map, x, y, doorlist, &ndoors, RP); 809 find_doors_in_room_recursive (layout2, map, x, y, doorlist, &ndoors, RP);
822 810
823 /* deallocate the temp. layout */
824 for (i = 0; i < RP->Xsize; i++)
825 free (layout2[i]);
826
827 free (layout2);
828 return doorlist; 811 return doorlist;
829} 812}
830
831
832 813
833/* locks and/or hides all the doors in doorlist, or does nothing if 814/* locks and/or hides all the doors in doorlist, or does nothing if
834 opts doesn't say to lock/hide doors. */ 815 opts doesn't say to lock/hide doors. */
835
836void 816void
837lock_and_hide_doors (object **doorlist, maptile *map, int opts, random_map_params *RP) 817lock_and_hide_doors (object **doorlist, maptile *map, int opts, random_map_params *RP)
838{ 818{
839 object *door; 819 object *door;
840 int i; 820 int i;
875 { 855 {
876 retrofit_joined_wall (map, door->x - 1, door->y, 0, RP); 856 retrofit_joined_wall (map, door->x - 1, door->y, 0, RP);
877 retrofit_joined_wall (map, door->x + 1, door->y, 0, RP); 857 retrofit_joined_wall (map, door->x + 1, door->y, 0, RP);
878 retrofit_joined_wall (map, door->x, door->y - 1, 0, RP); 858 retrofit_joined_wall (map, door->x, door->y - 1, 0, RP);
879 retrofit_joined_wall (map, door->x, door->y + 1, 0, RP); 859 retrofit_joined_wall (map, door->x, door->y + 1, 0, RP);
860
880 door->face = wallface->face; 861 door->face = wallface->face;
862
881 if (!QUERY_FLAG (wallface, FLAG_REMOVED)) 863 if (!QUERY_FLAG (wallface, FLAG_REMOVED))
882 wallface->remove (); 864 wallface->remove ();
865
883 wallface->destroy (); 866 wallface->destroy ();
884 } 867 }
885 } 868 }
886 } 869 }
887} 870}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines