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.6 by root, Thu Sep 14 22:34:03 2006 UTC vs.
Revision 1.12 by root, Sun Dec 31 19:02:24 2006 UTC

1
1/* 2/*
2 CrossFire, A Multiplayer game for X-windows 3 CrossFire, A Multiplayer game for X-windows
3 4
4 Copyright (C) 2001 Mark Wedel & Crossfire Development Team 5 Copyright (C) 2001 Mark Wedel & Crossfire Development Team
5 Copyright (C) 1992 Frank Tore Johansen 6 Copyright (C) 1992 Frank Tore Johansen
49 * and doors but not monsters. 50 * and doors but not monsters.
50 * This function is not map tile aware. 51 * This function is not map tile aware.
51 */ 52 */
52 53
53int 54int
54wall_blocked (mapstruct *m, int x, int y) 55wall_blocked (maptile *m, int x, int y)
55{ 56{
56 int r; 57 int r;
57 58
58 if (OUT_OF_REAL_MAP (m, x, y)) 59 if (OUT_OF_REAL_MAP (m, x, y))
59 return 1; 60 return 1;
67treasure style (may be empty or NULL, or "none" to cause no treasure.) 68treasure style (may be empty or NULL, or "none" to cause no treasure.)
68treasureoptions (may be 0 for random choices or positive) 69treasureoptions (may be 0 for random choices or positive)
69*/ 70*/
70 71
71void 72void
72place_treasure (mapstruct *map, char **layout, char *treasure_style, int treasureoptions, RMParms * RP) 73place_treasure (maptile *map, char **layout, char *treasure_style, int treasureoptions, random_map_params *RP)
73{ 74{
74 char styledirname[256]; 75 char styledirname[256];
75 char stylefilepath[256]; 76 char stylefilepath[256];
76 mapstruct *style_map = 0; 77 maptile *style_map = 0;
77 int num_treasures; 78 int num_treasures;
78 79
79 /* bail out if treasure isn't wanted. */ 80 /* bail out if treasure isn't wanted. */
80 if (treasure_style) 81 if (treasure_style)
81 if (!strcmp (treasure_style, "none")) 82 if (!strcmp (treasure_style, "none"))
113 { 114 {
114 115
115 /* map_layout_style global, and is previously set */ 116 /* map_layout_style global, and is previously set */
116 switch (RP->map_layout_style) 117 switch (RP->map_layout_style)
117 { 118 {
118 case ONION_LAYOUT: 119 case LAYOUT_ONION:
119 case SPIRAL_LAYOUT: 120 case LAYOUT_SPIRAL:
120 case SQUARE_SPIRAL_LAYOUT: 121 case LAYOUT_SQUARE_SPIRAL:
121 { 122 {
122 int i, j; 123 int i, j;
123 124
124 /* search the onion for C's or '>', and put treasure there. */ 125 /* search the onion for C's or '>', and put treasure there. */
125 for (i = 0; i < RP->Xsize; i++) 126 for (i = 0; i < RP->Xsize; i++)
126 { 127 {
127 for (j = 0; j < RP->Ysize; j++) 128 for (j = 0; j < RP->Ysize; j++)
128 { 129 {
129 if (layout[i][j] == 'C' || layout[i][j] == '>') 130 if (layout[i][j] == 'C' || layout[i][j] == '>')
130 { 131 {
131 int tdiv = RP->symmetry_used; 132 int tdiv = RP->symmetry_used;
132 object **doorlist; 133 object **doorlist;
133 object *chest; 134 object *chest;
134 135
135 if (tdiv == 3) 136 if (tdiv == 3)
136 tdiv = 2; /* this symmetry uses a divisor of 2 */ 137 tdiv = 2; /* this symmetry uses a divisor of 2 */
137 /* don't put a chest on an exit. */ 138 /* don't put a chest on an exit. */
138 chest = place_chest (treasureoptions, i, j, map, style_map, num_treasures / tdiv, RP); 139 chest = place_chest (treasureoptions, i, j, map, style_map, num_treasures / tdiv, RP);
139 if (!chest) 140 if (!chest)
140 continue; /* if no chest was placed NEXT */ 141 continue; /* if no chest was placed NEXT */
141 if (treasureoptions & (DOORED | HIDDEN)) 142 if (treasureoptions & (DOORED | HIDDEN))
142 { 143 {
143 doorlist = find_doors_in_room (map, i, j, RP); 144 doorlist = find_doors_in_room (map, i, j, RP);
144 lock_and_hide_doors (doorlist, map, treasureoptions, RP); 145 lock_and_hide_doors (doorlist, map, treasureoptions, RP);
145 free (doorlist); 146 free (doorlist);
146 } 147 }
147 } 148 }
148 } 149 }
149 } 150 }
150 break; 151 break;
151 } 152 }
152 default: 153 default:
153 { 154 {
154 int i, j, tries; 155 int i, j, tries;
155 object *chest; 156 object *chest;
156 object **doorlist; 157 object **doorlist;
157 158
158 i = j = -1; 159 i = j = -1;
159 tries = 0; 160 tries = 0;
160 while (i == -1 && tries < 100) 161 while (i == -1 && tries < 100)
161 { 162 {
162 i = RANDOM () % (RP->Xsize - 2) + 1; 163 i = RANDOM () % (RP->Xsize - 2) + 1;
163 j = RANDOM () % (RP->Ysize - 2) + 1; 164 j = RANDOM () % (RP->Ysize - 2) + 1;
164 find_enclosed_spot (map, &i, &j, RP); 165 find_enclosed_spot (map, &i, &j, RP);
165 if (wall_blocked (map, i, j)) 166 if (wall_blocked (map, i, j))
166 i = -1; 167 i = -1;
167 tries++; 168 tries++;
168 } 169 }
169 chest = place_chest (treasureoptions, i, j, map, style_map, num_treasures, RP); 170 chest = place_chest (treasureoptions, i, j, map, style_map, num_treasures, RP);
170 if (!chest) 171 if (!chest)
171 return; 172 return;
172 i = chest->x; 173 i = chest->x;
173 j = chest->y; 174 j = chest->y;
174 if (treasureoptions & (DOORED | HIDDEN)) 175 if (treasureoptions & (DOORED | HIDDEN))
175 { 176 {
176 doorlist = surround_by_doors (map, layout, i, j, treasureoptions); 177 doorlist = surround_by_doors (map, layout, i, j, treasureoptions);
177 lock_and_hide_doors (doorlist, map, treasureoptions, RP); 178 lock_and_hide_doors (doorlist, map, treasureoptions, RP);
178 free (doorlist); 179 free (doorlist);
179 } 180 }
180 } 181 }
181 } 182 }
182 } 183 }
183 else 184 else
184 { /* DIFFUSE treasure layout */ 185 { /* DIFFUSE treasure layout */
185 int ti, i, j; 186 int ti, i, j;
191 place_chest (treasureoptions, i, j, map, style_map, 1, RP); 192 place_chest (treasureoptions, i, j, map, style_map, 1, RP);
192 } 193 }
193 } 194 }
194} 195}
195 196
196
197
198/* put a chest into the map, near x and y, with the treasure style 197/* put a chest into the map, near x and y, with the treasure style
199 determined (may be null, or may be a treasure list from lib/treasures, 198 determined (may be null, or may be a treasure list from lib/treasures,
200 if the global variable "treasurestyle" is set to that treasure list's name */ 199 if the global variable "treasurestyle" is set to that treasure list's name */
201 200
202object * 201object *
203place_chest (int treasureoptions, int x, int y, mapstruct *map, mapstruct *style_map, int n_treasures, RMParms * RP) 202place_chest (int treasureoptions, int x, int y, maptile *map, maptile *style_map, int n_treasures, random_map_params *RP)
204{ 203{
205 object *the_chest; 204 object *the_chest;
206 int i, xl, yl; 205 int i, xl, yl;
207 206
208 the_chest = get_archetype ("chest"); /* was "chest_2" */ 207 the_chest = get_archetype ("chest"); /* was "chest_2" */
209 208
210 /* first, find a place to put the chest. */ 209 /* first, find a place to put the chest. */
211 i = find_first_free_spot (the_chest, map, x, y); 210 i = find_first_free_spot (the_chest, map, x, y);
212 if (i == -1) 211 if (i == -1)
213 { 212 {
214 free_object (the_chest); 213 the_chest->destroy ();
215 return NULL; 214 return NULL;
216 } 215 }
217 xl = x + freearr_x[i]; 216 xl = x + freearr_x[i];
218 yl = y + freearr_y[i]; 217 yl = y + freearr_y[i];
219 218
220 /* if the placement is blocked, return a fail. */ 219 /* if the placement is blocked, return a fail. */
221 if (wall_blocked (map, xl, yl)) 220 if (wall_blocked (map, xl, yl))
222 return 0; 221 return 0;
223
224 222
225 /* put the treasures in the chest. */ 223 /* put the treasures in the chest. */
226 /* if(style_map) { */ 224 /* if(style_map) { */
227#if 0 /* don't use treasure style maps for now! */ 225#if 0 /* don't use treasure style maps for now! */
228 int ti; 226 int ti;
241 { /* use the style map */ 239 { /* use the style map */
242 the_chest->randomitems = tlist; 240 the_chest->randomitems = tlist;
243 the_chest->stats.hp = n_treasures; 241 the_chest->stats.hp = n_treasures;
244 } 242 }
245#endif 243#endif
246 else
247 { /* neither style_map no treasure list given */ 244 { /* neither style_map no treasure list given */
248 treasurelist *tlist = find_treasurelist ("chest"); 245 treasurelist *tlist = find_treasurelist ("chest");
249 246
250 the_chest->randomitems = tlist; 247 the_chest->randomitems = tlist;
251 the_chest->stats.hp = n_treasures; 248 the_chest->stats.hp = n_treasures;
252 } 249 }
253 250
254 /* stick a trap in the chest if required */ 251 /* stick a trap in the chest if required */
255 if (treasureoptions & TRAPPED) 252 if (treasureoptions & TRAPPED)
256 { 253 {
257 mapstruct *trap_map = find_style ("/styles/trapstyles", "traps", -1); 254 maptile *trap_map = find_style ("/styles/trapstyles", "traps", -1);
258 object *the_trap; 255 object *the_trap;
259 256
260 if (trap_map) 257 if (trap_map)
261 { 258 {
262 the_trap = pick_random_object (trap_map); 259 the_trap = pick_random_object (trap_map);
265 if (the_trap) 262 if (the_trap)
266 { 263 {
267 object *new_trap; 264 object *new_trap;
268 265
269 new_trap = arch_to_object (the_trap->arch); 266 new_trap = arch_to_object (the_trap->arch);
270 copy_object (new_trap, the_trap); 267 new_trap->copy_to (the_trap);
271 new_trap->x = x; 268 new_trap->x = x;
272 new_trap->y = y; 269 new_trap->y = y;
273 insert_ob_in_ob (new_trap, the_chest); 270 insert_ob_in_ob (new_trap, the_chest);
274 } 271 }
275 } 272 }
297 294
298 295
299/* finds the closest monster and returns him, regardless of doors 296/* finds the closest monster and returns him, regardless of doors
300 or walls */ 297 or walls */
301object * 298object *
302find_closest_monster (mapstruct *map, int x, int y, RMParms * RP) 299find_closest_monster (maptile *map, int x, int y, random_map_params *RP)
303{ 300{
304 int i; 301 int i;
305 302
306 for (i = 0; i < SIZEOFFREE; i++) 303 for (i = 0; i < SIZEOFFREE; i++)
307 { 304 {
312 /* boundscheck */ 309 /* boundscheck */
313 if (lx >= 0 && ly >= 0 && lx < RP->Xsize && ly < RP->Ysize) 310 if (lx >= 0 && ly >= 0 && lx < RP->Xsize && ly < RP->Ysize)
314 /* don't bother searching this square unless the map says life exists. */ 311 /* don't bother searching this square unless the map says life exists. */
315 if (GET_MAP_FLAGS (map, lx, ly) & P_IS_ALIVE) 312 if (GET_MAP_FLAGS (map, lx, ly) & P_IS_ALIVE)
316 { 313 {
317 object *the_monster = get_map_ob (map, lx, ly); 314 object *the_monster = GET_MAP_OB (map, lx, ly);
318 315
319 for (; the_monster != NULL && (!QUERY_FLAG (the_monster, FLAG_MONSTER)); the_monster = the_monster->above); 316 for (; the_monster != NULL && (!QUERY_FLAG (the_monster, FLAG_MONSTER)); the_monster = the_monster->above);
320 if (the_monster && QUERY_FLAG (the_monster, FLAG_MONSTER)) 317 if (the_monster && QUERY_FLAG (the_monster, FLAG_MONSTER))
321 return the_monster; 318 return the_monster;
322 } 319 }
336 The idea is that you call keyplace on x,y where a door is, and it'll make 333 The idea is that you call keyplace on x,y where a door is, and it'll make
337 sure a key is placed on both sides of the door. 334 sure a key is placed on both sides of the door.
338*/ 335*/
339 336
340int 337int
341keyplace (mapstruct *map, int x, int y, char *keycode, int door_flag, int n_keys, RMParms * RP) 338keyplace (maptile *map, int x, int y, char *keycode, int door_flag, int n_keys, random_map_params *RP)
342{ 339{
343 int i, j; 340 int i, j;
344 int kx, ky; 341 int kx, ky;
345 object *the_keymaster; /* the monster that gets the key. */ 342 object *the_keymaster; /* the monster that gets the key. */
346 object *the_key; 343 object *the_key;
432 429
433/* a recursive routine which will return a monster, eventually,if there is one. 430/* a recursive routine which will return a monster, eventually,if there is one.
434 it does a check-off on the layout, converting 0's to 1's */ 431 it does a check-off on the layout, converting 0's to 1's */
435 432
436object * 433object *
437find_monster_in_room_recursive (char **layout, mapstruct *map, int x, int y, RMParms * RP) 434find_monster_in_room_recursive (char **layout, maptile *map, int x, int y, random_map_params *RP)
438{ 435{
439 int i, j; 436 int i, j;
440 437
441 /* if we've found a monster already, leave */ 438 /* if we've found a monster already, leave */
442 if (theMonsterToFind != NULL) 439 if (theMonsterToFind != NULL)
453 /* check the current square for a monster. If there is one, 450 /* check the current square for a monster. If there is one,
454 set theMonsterToFind and return it. */ 451 set theMonsterToFind and return it. */
455 layout[x][y] = 1; 452 layout[x][y] = 1;
456 if (GET_MAP_FLAGS (map, x, y) & P_IS_ALIVE) 453 if (GET_MAP_FLAGS (map, x, y) & P_IS_ALIVE)
457 { 454 {
458 object *the_monster = get_map_ob (map, x, y); 455 object *the_monster = GET_MAP_OB (map, x, y);
459 456
460 /* check off this point */ 457 /* check off this point */
461 for (; the_monster != NULL && (!QUERY_FLAG (the_monster, FLAG_ALIVE)); the_monster = the_monster->above); 458 for (; the_monster != NULL && (!QUERY_FLAG (the_monster, FLAG_ALIVE)); the_monster = the_monster->above);
462 if (the_monster && QUERY_FLAG (the_monster, FLAG_ALIVE)) 459 if (the_monster && QUERY_FLAG (the_monster, FLAG_ALIVE))
463 { 460 {
479 476
480/* sets up some data structures: the _recursive form does the 477/* sets up some data structures: the _recursive form does the
481 real work. */ 478 real work. */
482 479
483object * 480object *
484find_monster_in_room (mapstruct *map, int x, int y, RMParms * RP) 481find_monster_in_room (maptile *map, int x, int y, random_map_params *RP)
485{ 482{
486 char **layout2; 483 char **layout2;
487 int i, j; 484 int i, j;
488 485
489 theMonsterToFind = 0; 486 theMonsterToFind = 0;
521/* the workhorse routine, which finds the free spots in a room: 518/* the workhorse routine, which finds the free spots in a room:
522a datastructure of free points is set up, and a position chosen from 519a datastructure of free points is set up, and a position chosen from
523that datastructure. */ 520that datastructure. */
524 521
525void 522void
526find_spot_in_room_recursive (char **layout, int x, int y, RMParms * RP) 523find_spot_in_room_recursive (char **layout, int x, int y, random_map_params *RP)
527{ 524{
528 int i, j; 525 int i, j;
529 526
530 /* bounds check x and y */ 527 /* bounds check x and y */
531 if (!(x >= 0 && y >= 0 && x < RP->Xsize && y < RP->Ysize)) 528 if (!(x >= 0 && y >= 0 && x < RP->Xsize && y < RP->Ysize))
550 547
551} 548}
552 549
553/* find a random non-blocked spot in this room to drop a key. */ 550/* find a random non-blocked spot in this room to drop a key. */
554void 551void
555find_spot_in_room (mapstruct *map, int x, int y, int *kx, int *ky, RMParms * RP) 552find_spot_in_room (maptile *map, int x, int y, int *kx, int *ky, random_map_params *RP)
556{ 553{
557 char **layout2; 554 char **layout2;
558 int i, j; 555 int i, j;
559 556
560 number_of_free_spots_in_room = 0; 557 number_of_free_spots_in_room = 0;
597/* searches the map for a spot with walls around it. The more 594/* searches the map for a spot with walls around it. The more
598 walls the better, but it'll settle for 1 wall, or even 0, but 595 walls the better, but it'll settle for 1 wall, or even 0, but
599 it'll return 0 if no FREE spots are found.*/ 596 it'll return 0 if no FREE spots are found.*/
600 597
601void 598void
602find_enclosed_spot (mapstruct *map, int *cx, int *cy, RMParms * RP) 599find_enclosed_spot (maptile *map, int *cx, int *cy, random_map_params *RP)
603{ 600{
604 int x, y; 601 int x, y;
605 int i; 602 int i;
606 603
607 x = *cx; 604 x = *cx;
669 *cx = *cy = -1; 666 *cx = *cy = -1;
670} 667}
671 668
672 669
673void 670void
674remove_monsters (int x, int y, mapstruct *map) 671remove_monsters (int x, int y, maptile *map)
675{ 672{
676 object *tmp; 673 object *tmp;
677 674
678 for (tmp = get_map_ob (map, x, y); tmp != NULL; tmp = tmp->above) 675 for (tmp = GET_MAP_OB (map, x, y); tmp != NULL; tmp = tmp->above)
679 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 676 if (QUERY_FLAG (tmp, FLAG_ALIVE))
680 { 677 {
681 if (tmp->head) 678 if (tmp->head)
682 tmp = tmp->head; 679 tmp = tmp->head;
683 remove_ob (tmp); 680 tmp->remove ();
684 free_object (tmp); 681 tmp->destroy ();
685 tmp = get_map_ob (map, x, y); 682 tmp = GET_MAP_OB (map, x, y);
686 if (tmp == NULL) 683 if (tmp == NULL)
687 break; 684 break;
688 }; 685 };
689} 686}
690 687
692/* surrounds the point x,y by doors, so as to enclose something, like 689/* surrounds the point x,y by doors, so as to enclose something, like
693 a chest. It only goes as far as the 8 squares surrounding, and 690 a chest. It only goes as far as the 8 squares surrounding, and
694 it'll remove any monsters it finds.*/ 691 it'll remove any monsters it finds.*/
695 692
696object ** 693object **
697surround_by_doors (mapstruct *map, char **layout, int x, int y, int opts) 694surround_by_doors (maptile *map, char **layout, int x, int y, int opts)
698{ 695{
699 int i; 696 int i;
700 char *doors[2]; 697 char *doors[2];
701 object **doorlist; 698 object **doorlist;
702 int ndoors_made = 0; 699 int ndoors_made = 0;
735} 732}
736 733
737 734
738/* returns the first door in this square, or NULL if there isn't a door. */ 735/* returns the first door in this square, or NULL if there isn't a door. */
739object * 736object *
740door_in_square (mapstruct *map, int x, int y) 737door_in_square (maptile *map, int x, int y)
741{ 738{
742 object *tmp; 739 object *tmp;
743 740
744 for (tmp = get_map_ob (map, x, y); tmp != NULL; tmp = tmp->above) 741 for (tmp = GET_MAP_OB (map, x, y); tmp != NULL; tmp = tmp->above)
745 if (tmp->type == DOOR || tmp->type == LOCKED_DOOR) 742 if (tmp->type == DOOR || tmp->type == LOCKED_DOOR)
746 return tmp; 743 return tmp;
747 return NULL; 744 return NULL;
748} 745}
749 746
750 747
751/* the workhorse routine, which finds the doors in a room */ 748/* the workhorse routine, which finds the doors in a room */
752void 749void
753find_doors_in_room_recursive (char **layout, mapstruct *map, int x, int y, object **doorlist, int *ndoors, RMParms * RP) 750find_doors_in_room_recursive (char **layout, maptile *map, int x, int y, object **doorlist, int *ndoors, random_map_params *RP)
754{ 751{
755 int i, j; 752 int i, j;
756 object *door; 753 object *door;
757 754
758 /* bounds check x and y */ 755 /* bounds check x and y */
790 } 787 }
791} 788}
792 789
793/* find a random non-blocked spot in this room to drop a key. */ 790/* find a random non-blocked spot in this room to drop a key. */
794object ** 791object **
795find_doors_in_room (mapstruct *map, int x, int y, RMParms * RP) 792find_doors_in_room (maptile *map, int x, int y, random_map_params *RP)
796{ 793{
797 char **layout2; 794 char **layout2;
798 object **doorlist; 795 object **doorlist;
799 int i, j; 796 int i, j;
800 int ndoors = 0; 797 int ndoors = 0;
830 827
831/* locks and/or hides all the doors in doorlist, or does nothing if 828/* locks and/or hides all the doors in doorlist, or does nothing if
832 opts doesn't say to lock/hide doors. */ 829 opts doesn't say to lock/hide doors. */
833 830
834void 831void
835lock_and_hide_doors (object **doorlist, mapstruct *map, int opts, RMParms * RP) 832lock_and_hide_doors (object **doorlist, maptile *map, int opts, random_map_params *RP)
836{ 833{
837 object *door; 834 object *door;
838 int i; 835 int i;
839 836
840 /* lock the doors and hide the keys. */ 837 /* lock the doors and hide the keys. */
848 845
849 door = doorlist[i]; 846 door = doorlist[i];
850 new_door->face = door->face; 847 new_door->face = door->face;
851 new_door->x = door->x; 848 new_door->x = door->x;
852 new_door->y = door->y; 849 new_door->y = door->y;
853 remove_ob (door); 850 door->remove ();
854 free_object (door); 851 door->destroy ();
855 doorlist[i] = new_door; 852 doorlist[i] = new_door;
856 insert_ob_in_map (new_door, map, NULL, 0); 853 insert_ob_in_map (new_door, map, NULL, 0);
857 sprintf (keybuf, "%d", (int) RANDOM ()); 854 sprintf (keybuf, "%d", (int) RANDOM ());
858 new_door->slaying = keybuf; 855 new_door->slaying = keybuf;
859 keyplace (map, new_door->x, new_door->y, keybuf, NO_PASS_DOORS, 2, RP); 856 keyplace (map, new_door->x, new_door->y, keybuf, NO_PASS_DOORS, 2, RP);
875 retrofit_joined_wall (map, door->x + 1, door->y, 0, RP); 872 retrofit_joined_wall (map, door->x + 1, door->y, 0, RP);
876 retrofit_joined_wall (map, door->x, door->y - 1, 0, RP); 873 retrofit_joined_wall (map, door->x, door->y - 1, 0, RP);
877 retrofit_joined_wall (map, door->x, door->y + 1, 0, RP); 874 retrofit_joined_wall (map, door->x, door->y + 1, 0, RP);
878 door->face = wallface->face; 875 door->face = wallface->face;
879 if (!QUERY_FLAG (wallface, FLAG_REMOVED)) 876 if (!QUERY_FLAG (wallface, FLAG_REMOVED))
880 remove_ob (wallface); 877 wallface->remove ();
881 free_object (wallface); 878 wallface->destroy ();
882 } 879 }
883 } 880 }
884 } 881 }
885} 882}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines