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

Comparing deliantra/server/random_maps/random_map.C (file contents):
Revision 1.14 by root, Sun Dec 31 20:46:17 2006 UTC vs.
Revision 1.30 by root, Sun Jul 1 05:00:19 2007 UTC

1
2/* 1/*
3 CrossFire, A Multiplayer game for X-windows 2 * This file is part of Crossfire TRT, the Roguelike Realtime MORPG.
4 3 *
4 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT 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 * Crossfire TRT 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. 20 *
21
22 The authors can be reached via e-mail at <crossfire@schmorp.de> 21 * The authors can be reached via e-mail to <crossfire@schmorp.de>
23*/ 22 */
24 23
25#include <time.h> 24#include <time.h>
26#include <stdio.h> 25#include <stdio.h>
27#include <global.h> 26#include <global.h>
28#include <maze_gen.h> 27#include <maze_gen.h>
29#include <room_gen.h> 28#include <room_gen.h>
30#include <random_map.h> 29#include <random_map.h>
31#include <rproto.h> 30#include <rproto.h>
32#include <sproto.h> 31#include <sproto.h>
32
33#define CEDE coroapi::cede_to_tick (); rndm.seed (RP->random_seed + __LINE__);
33 34
34void 35void
35dump_layout (char **layout, random_map_params *RP) 36dump_layout (char **layout, random_map_params *RP)
36{ 37{
37 { 38 {
51 } 52 }
52 } 53 }
53 printf ("\n"); 54 printf ("\n");
54} 55}
55 56
56maptile * 57bool
57generate_random_map (const char *OutFileName, random_map_params *RP) 58maptile::generate_random_map (random_map_params *RP)
58{ 59{
59 char **layout, buf[HUGE_BUF]; 60 char **layout, buf[16384];
60 maptile *theMap;
61 int i; 61 int i;
62 62
63 RP->Xsize = RP->xsize;
64 RP->Ysize = RP->ysize;
65
63 /* pick a random seed, or use the one from the input file */ 66 /* pick a random seed, or use the one from the input file */
64 SRANDOM (RP->random_seed ? RP->random_seed + RP->dungeon_level : time (0)); 67 RP->random_seed = RP->random_seed
68 ? RP->random_seed + RP->dungeon_level
69 : time (0);
70 CEDE;
65 71
66 write_map_parameters_to_string (buf, RP); 72 write_map_parameters_to_string (buf, RP);
67 73
68 if (RP->difficulty == 0) 74 if (RP->difficulty == 0)
69 { 75 {
77 } 83 }
78 else 84 else
79 RP->difficulty_given = 1; 85 RP->difficulty_given = 1;
80 86
81 if (RP->Xsize < MIN_RANDOM_MAP_SIZE) 87 if (RP->Xsize < MIN_RANDOM_MAP_SIZE)
82 RP->Xsize = MIN_RANDOM_MAP_SIZE + RANDOM () % 25 + 5; 88 RP->Xsize = MIN_RANDOM_MAP_SIZE + rndm (25) + 5;
83 89
84 if (RP->Ysize < MIN_RANDOM_MAP_SIZE) 90 if (RP->Ysize < MIN_RANDOM_MAP_SIZE)
85 RP->Ysize = MIN_RANDOM_MAP_SIZE + RANDOM () % 25 + 5; 91 RP->Ysize = MIN_RANDOM_MAP_SIZE + rndm (25) + 5;
92
93 if (RP->symmetry == SYMMETRY_RANDOM)
94 RP->symmetry_used = rndm (SYMMETRY_XY) + 1;
95 else
96 RP->symmetry_used = RP->symmetry;
97
98 if (RP->symmetry_used == SYMMETRY_Y || RP->symmetry_used == SYMMETRY_XY)
99 RP->Ysize = RP->Ysize / 2 + 1;
100
101 if (RP->symmetry_used == SYMMETRY_X || RP->symmetry_used == SYMMETRY_XY)
102 RP->Xsize = RP->Xsize / 2 + 1;
86 103
87 if (RP->expand2x > 0) 104 if (RP->expand2x > 0)
88 { 105 {
89 RP->Xsize /= 2; 106 RP->Xsize /= 2;
90 RP->Ysize /= 2; 107 RP->Ysize /= 2;
91 } 108 }
92 109
93 layout = layoutgen (RP);
94
95#ifdef RMAP_DEBUG
96 dump_layout (layout, RP);
97#endif
98
99 /* increment these for the current map */
100 RP->dungeon_level += 1;
101 /* allow constant-difficulty maps. */
102 /* difficulty+=1; */
103
104 /* rotate the layout randomly */
105 layout = rotate_layout (layout, RANDOM () % 4, RP);
106#ifdef RMAP_DEBUG
107 dump_layout (layout, RP);
108#endif
109
110 /* allocate the map and set the floor */
111 theMap = make_map_floor (layout, RP->floorstyle, RP);
112
113 /* set the name of the map. */
114 theMap->path = OutFileName;
115
116 /* set region */
117 theMap->region = RP->region;
118
119 coroapi.cede ();
120 /* create walls unless the wallstyle is "none" */
121 if (strcmp (RP->wallstyle, "none"))
122 {
123 make_map_walls (theMap, layout, RP->wallstyle, RP);
124
125 /* place doors unless doorstyle or wallstyle is "none" */
126 if (strcmp (RP->doorstyle, "none"))
127 put_doors (theMap, layout, RP->doorstyle, RP);
128
129 }
130
131 coroapi.cede ();
132 /* create exits unless the exitstyle is "none" */
133 if (strcmp (RP->exitstyle, "none"))
134 place_exits (theMap, layout, RP->exitstyle, RP->orientation, RP);
135
136 coroapi.cede ();
137 place_specials_in_map (theMap, layout, RP);
138
139 coroapi.cede ();
140 /* create monsters unless the monsterstyle is "none" */
141 if (strcmp (RP->monsterstyle, "none"))
142 place_monsters (theMap, RP->monsterstyle, RP->difficulty, RP);
143
144 coroapi.cede ();
145 /* treasures needs to have a proper difficulty set for the map. */
146 theMap->difficulty = theMap->estimate_difficulty ();
147
148 coroapi.cede ();
149 /* create treasure unless the treasurestyle is "none" */
150 if (strcmp (RP->treasurestyle, "none"))
151 place_treasure (theMap, layout, RP->treasurestyle, RP->treasureoptions, RP);
152
153 coroapi.cede ();
154 /* create decor unless the decorstyle is "none" */
155 if (strcmp (RP->decorstyle, "none"))
156 put_decor (theMap, layout, RP->decorstyle, RP->decoroptions, RP);
157
158 coroapi.cede ();
159 /* generate treasures, etc. */
160 theMap->fix_auto_apply ();
161
162 coroapi.cede ();
163 unblock_exits (theMap, layout, RP);
164
165 /* free the layout */
166 for (i = 0; i < RP->Xsize; i++)
167 free (layout[i]);
168
169 free (layout);
170
171 theMap->msg = strdup (buf);
172 theMap->in_memory = MAP_IN_MEMORY;
173
174 return theMap;
175}
176
177/* function selects the layout function and gives it whatever
178 arguments it needs. */
179char **
180layoutgen (random_map_params *RP)
181{
182 char **maze = 0;
183 int oxsize = RP->Xsize, oysize = RP->Ysize;
184
185 if (RP->symmetry == SYMMETRY_RANDOM)
186 RP->symmetry_used = (RANDOM () % (SYMMETRY_XY)) + 1;
187 else
188 RP->symmetry_used = RP->symmetry;
189
190 if (RP->symmetry_used == SYMMETRY_Y || RP->symmetry_used == SYMMETRY_XY)
191 RP->Ysize = RP->Ysize / 2 + 1;
192 if (RP->symmetry_used == SYMMETRY_X || RP->symmetry_used == SYMMETRY_XY)
193 RP->Xsize = RP->Xsize / 2 + 1;
194
195 if (RP->Xsize < MIN_RANDOM_MAP_SIZE)
196 RP->Xsize = MIN_RANDOM_MAP_SIZE + RANDOM () % 5;
197 if (RP->Ysize < MIN_RANDOM_MAP_SIZE)
198 RP->Ysize = MIN_RANDOM_MAP_SIZE + RANDOM () % 5;
199 RP->map_layout_style = 0; 110 RP->map_layout_style = LAYOUT_NONE;
200 111
201 /* Redo this - there was a lot of redundant code of checking for preset 112 /* Redo this - there was a lot of redundant code of checking for preset
202 * layout style and then random layout style. Instead, figure out 113 * layout style and then random layout style. Instead, figure out
203 * the numeric layoutstyle, so there is only one area that actually 114 * the numeric layoutstyle, so there is only one area that actually
204 * calls the code to make the maps. 115 * calls the code to make the maps.
219 RP->map_layout_style = LAYOUT_SNAKE; 130 RP->map_layout_style = LAYOUT_SNAKE;
220 131
221 if (strstr (RP->layoutstyle, "squarespiral")) 132 if (strstr (RP->layoutstyle, "squarespiral"))
222 RP->map_layout_style = LAYOUT_SQUARE_SPIRAL; 133 RP->map_layout_style = LAYOUT_SQUARE_SPIRAL;
223 134
224 /* No style found - choose one ranomdly */ 135 /* No style found - choose one randomly */
225 if (RP->map_layout_style == LAYOUT_NONE) 136 if (RP->map_layout_style == LAYOUT_NONE)
226 RP->map_layout_style = (RANDOM () % (NROFLAYOUTS - 1)) + 1; 137 RP->map_layout_style = rndm (NROFLAYOUTS - 1) + 1;
138
139 layout = layoutgen (RP);
140
141#ifdef RMAP_DEBUG
142 dump_layout (layout, RP);
143#endif
144
145 /* increment these for the current map */
146 RP->dungeon_level += 1;
147 /* allow constant-difficulty maps. */
148 /* difficulty+=1; */
149
150 /* rotate the layout randomly */
151 layout = rotate_layout (layout, rndm (4), RP);
152#ifdef RMAP_DEBUG
153 dump_layout (layout, RP);
154#endif
155
156 /* allocate the map and set the floor */
157 make_map_floor (layout, RP->floorstyle, RP);
158
159 /* set region */
160 default_region = RP->region;
161
162 CEDE;
163
164 /* create walls unless the wallstyle is "none" */
165 if (strcmp (RP->wallstyle, "none"))
166 {
167 make_map_walls (this, layout, RP->wallstyle, RP);
168
169 /* place doors unless doorstyle or wallstyle is "none" */
170 if (strcmp (RP->doorstyle, "none"))
171 put_doors (this, layout, RP->doorstyle, RP);
172 }
173
174 CEDE;
175
176 /* create exits unless the exitstyle is "none" */
177 if (strcmp (RP->exitstyle, "none"))
178 place_exits (this, layout, RP->exitstyle, RP->orientation, RP);
179
180 CEDE;
181
182 place_specials_in_map (this, layout, RP);
183
184 CEDE;
185
186 /* create monsters unless the monsterstyle is "none" */
187 if (strcmp (RP->monsterstyle, "none"))
188 place_monsters (this, RP->monsterstyle, RP->difficulty, RP);
189
190 CEDE;
191
192 /* treasures needs to have a proper difficulty set for the map. */
193 difficulty = estimate_difficulty ();
194
195 CEDE;
196
197 /* create treasure unless the treasurestyle is "none" */
198 if (strcmp (RP->treasurestyle, "none"))
199 place_treasure (this, layout, RP->treasurestyle, RP->treasureoptions, RP);
200
201 CEDE;
202
203 /* create decor unless the decorstyle is "none" */
204 if (strcmp (RP->decorstyle, "none"))
205 put_decor (this, layout, RP->decorstyle, RP->decoroptions, RP);
206
207 CEDE;
208
209 /* generate treasures, etc. */
210 fix_auto_apply ();
211
212 CEDE;
213
214 unblock_exits (this, layout, RP);
215
216 /* free the layout */
217 for (i = 0; i < RP->Xsize; i++)
218 free (layout[i]);
219
220 free (layout);
221
222 msg = strdup (buf);
223 in_memory = MAP_IN_MEMORY;
224
225 CEDE;
226
227 return 1;
228}
229
230/* function selects the layout function and gives it whatever
231 arguments it needs. */
232char **
233layoutgen (random_map_params *RP)
234{
235 char **maze = 0;
236 int oxsize = RP->Xsize, oysize = RP->Ysize;
227 237
228 switch (RP->map_layout_style) 238 switch (RP->map_layout_style)
229 { 239 {
230 case LAYOUT_ONION: 240 case LAYOUT_ONION:
231 maze = map_gen_onion (RP->Xsize, RP->Ysize, RP->layoutoptions1, RP->layoutoptions2); 241 maze = map_gen_onion (RP->Xsize, RP->Ysize, RP->layoutoptions1, RP->layoutoptions2);
232 if (!(RANDOM () % 3) && !(RP->layoutoptions1 & RMOPT_WALLS_ONLY)) 242 if (!(rndm (3)) && !(RP->layoutoptions1 & RMOPT_WALLS_ONLY))
233 roomify_layout (maze, RP); 243 roomify_layout (maze, RP);
234 break; 244 break;
235 245
236 case LAYOUT_MAZE: 246 case LAYOUT_MAZE:
237 maze = maze_gen (RP->Xsize, RP->Ysize, RANDOM () % 2); 247 maze = maze_gen (RP->Xsize, RP->Ysize, rndm (2));
238 if (!(RANDOM () % 2)) 248 if (!(rndm (2)))
239 doorify_layout (maze, RP); 249 doorify_layout (maze, RP);
240 break; 250 break;
241 251
242 case LAYOUT_SPIRAL: 252 case LAYOUT_SPIRAL:
243 maze = map_gen_spiral (RP->Xsize, RP->Ysize, RP->layoutoptions1); 253 maze = map_gen_spiral (RP->Xsize, RP->Ysize, RP->layoutoptions1);
244 if (!(RANDOM () % 2)) 254 if (!(rndm (2)))
245 doorify_layout (maze, RP); 255 doorify_layout (maze, RP);
246 break; 256 break;
247 257
248 case LAYOUT_ROGUELIKE: 258 case LAYOUT_ROGUELIKE:
249 /* Don't put symmetry in rogue maps. There isn't much reason to 259 /* Don't put symmetry in rogue maps. There isn't much reason to
260 /* no doorifying... done already */ 270 /* no doorifying... done already */
261 break; 271 break;
262 272
263 case LAYOUT_SNAKE: 273 case LAYOUT_SNAKE:
264 maze = make_snake_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1); 274 maze = make_snake_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1);
265 if (RANDOM () % 2) 275 if (rndm (2))
266 roomify_layout (maze, RP); 276 roomify_layout (maze, RP);
267 break; 277 break;
268 278
269 case LAYOUT_SQUARE_SPIRAL: 279 case LAYOUT_SQUARE_SPIRAL:
270 maze = make_square_spiral_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1); 280 maze = make_square_spiral_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1);
271 if (RANDOM () % 2) 281 if (rndm (2))
272 roomify_layout (maze, RP); 282 roomify_layout (maze, RP);
273 break; 283 break;
274 } 284 }
275 285
276 maze = symmetrize_layout (maze, RP->symmetry_used, RP); 286 maze = symmetrize_layout (maze, RP->symmetry_used, RP);
439 for (ti = 0; ti < tries; ti++) 449 for (ti = 0; ti < tries; ti++)
440 { 450 {
441 int dx, dy; /* starting location for looking at creating a door */ 451 int dx, dy; /* starting location for looking at creating a door */
442 int cx, cy; /* results of checking on creating walls. */ 452 int cx, cy; /* results of checking on creating walls. */
443 453
444 dx = RANDOM () % RP->Xsize; 454 dx = rndm (RP->Xsize);
445 dy = RANDOM () % RP->Ysize; 455 dy = rndm (RP->Ysize);
456
446 cx = can_make_wall (maze, dx, dy, 0, RP); /* horizontal */ 457 cx = can_make_wall (maze, dx, dy, 0, RP); /* horizontal */
447 cy = can_make_wall (maze, dx, dy, 1, RP); /* vertical */ 458 cy = can_make_wall (maze, dx, dy, 1, RP); /* vertical */
448 if (cx == -1) 459 if (cx == -1)
449 { 460 {
450 if (cy != -1) 461 if (cy != -1)
451 make_wall (maze, dx, dy, 1); 462 make_wall (maze, dx, dy, 1);
463
452 continue; 464 continue;
453 } 465 }
466
454 if (cy == -1) 467 if (cy == -1)
455 { 468 {
456 make_wall (maze, dx, dy, 0); 469 make_wall (maze, dx, dy, 0);
457 continue; 470 continue;
458 } 471 }
472
459 if (cx < cy) 473 if (cx < cy)
460 make_wall (maze, dx, dy, 0); 474 make_wall (maze, dx, dy, 0);
461 else 475 else
462 make_wall (maze, dx, dy, 1); 476 make_wall (maze, dx, dy, 1);
463 } 477 }
609 while (ndoors > 0 && doorlocs > 0) 623 while (ndoors > 0 && doorlocs > 0)
610 { 624 {
611 int di; 625 int di;
612 int sindex; 626 int sindex;
613 627
614 di = RANDOM () % doorlocs; 628 di = rndm (doorlocs);
615 i = doorlist_x[di]; 629 i = doorlist_x[di];
616 j = doorlist_y[di]; 630 j = doorlist_y[di];
617 sindex = surround_flag (maze, i, j, RP); 631 sindex = surround_flag (maze, i, j, RP);
632
618 if (sindex == 3 || sindex == 12) /* these are possible door sindex */ 633 if (sindex == 3 || sindex == 12) /* these are possible door sindex */
619 { 634 {
620 maze[i][j] = 'D'; 635 maze[i][j] = 'D';
621 ndoors--; 636 ndoors--;
622 } 637 }
638
623 /* reduce the size of the list */ 639 /* reduce the size of the list */
624 doorlocs--; 640 doorlocs--;
625 doorlist_x[di] = doorlist_x[doorlocs]; 641 doorlist_x[di] = doorlist_x[doorlocs];
626 doorlist_y[di] = doorlist_y[doorlocs]; 642 doorlist_y[di] = doorlist_y[doorlocs];
627 } 643 }
631} 647}
632 648
633void 649void
634write_map_parameters_to_string (char *buf, random_map_params *RP) 650write_map_parameters_to_string (char *buf, random_map_params *RP)
635{ 651{
636 char small_buf[2048]; 652 char small_buf[16384];
637 653
638 sprintf (buf, "xsize %d\nysize %d\n", RP->Xsize, RP->Ysize); 654 sprintf (buf, "xsize %d\nysize %d\n", RP->xsize, RP->ysize);
639 655
640 if (RP->wallstyle[0]) 656 if (RP->wallstyle[0])
641 { 657 {
642 sprintf (small_buf, "wallstyle %s\n", RP->wallstyle); 658 sprintf (small_buf, "wallstyle %s\n", RP->wallstyle);
643 strcat (buf, small_buf); 659 strcat (buf, small_buf);
776 { 792 {
777 sprintf (small_buf, "origin_y %d\n", RP->origin_y); 793 sprintf (small_buf, "origin_y %d\n", RP->origin_y);
778 strcat (buf, small_buf); 794 strcat (buf, small_buf);
779 } 795 }
780 796
797 if (RP->treasureoptions)
798 {
799 sprintf (small_buf, "treasureoptions %d\n", RP->treasureoptions);
800 strcat (buf, small_buf);
801 }
802
781 if (RP->random_seed) 803 if (RP->random_seed)
782 { 804 {
783 /* Add one so that the next map is a bit different */
784 sprintf (small_buf, "random_seed %d\n", RP->random_seed + 1);
785 strcat (buf, small_buf);
786 }
787
788 if (RP->treasureoptions)
789 {
790 sprintf (small_buf, "treasureoptions %d\n", RP->treasureoptions);
791 strcat (buf, small_buf);
792 }
793
794 if (RP->random_seed)
795 {
796 sprintf (small_buf, "random_seed %d\n", RP->random_seed); 805 sprintf (small_buf, "random_seed %u\n", RP->random_seed);
806 strcat (buf, small_buf);
807 }
808
809 if (RP->custom)
810 {
811 sprintf (small_buf, "custom %s\n", RP->custom);
797 strcat (buf, small_buf); 812 strcat (buf, small_buf);
798 } 813 }
799} 814}
800 815
801void 816void
802write_parameters_to_string (char *buf, 817write_parameters_to_string (char *buf,
803 int xsize_n, 818 int xsize_n,
804 int ysize_n, 819 int ysize_n,
805 char *wallstyle_n, 820 const char *wallstyle_n,
806 char *floorstyle_n, 821 const char *floorstyle_n,
807 char *monsterstyle_n, 822 const char *monsterstyle_n,
808 char *treasurestyle_n, 823 const char *treasurestyle_n,
809 char *layoutstyle_n, 824 const char *layoutstyle_n,
810 char *decorstyle_n, 825 const char *decorstyle_n,
811 char *doorstyle_n, 826 const char *doorstyle_n,
812 char *exitstyle_n, 827 const char *exitstyle_n,
813 char *final_map_n, 828 const char *final_map_n,
814 char *exit_on_final_map_n, 829 const char *exit_on_final_map_n,
815 char *this_map_n, 830 const char *this_map_n,
816 int layoutoptions1_n, 831 int layoutoptions1_n,
817 int layoutoptions2_n, 832 int layoutoptions2_n,
818 int layoutoptions3_n, 833 int layoutoptions3_n,
819 int symmetry_n, 834 int symmetry_n,
820 int dungeon_depth_n, 835 int dungeon_depth_n,
821 int dungeon_level_n, 836 int dungeon_level_n,
822 int difficulty_n, 837 int difficulty_n,
823 int difficulty_given_n, 838 int difficulty_given_n,
824 int decoroptions_n, 839 int decoroptions_n,
825 int orientation_n, 840 int orientation_n,
826 int origin_x_n, int origin_y_n, int random_seed_n, int treasureoptions_n, float difficulty_increase) 841 int origin_x_n,
842 int origin_y_n,
843 uint32_t random_seed_n,
844 int treasureoptions_n,
845 float difficulty_increase)
827{ 846{
828 char small_buf[2048]; 847 char small_buf[16384];
829 848
830 sprintf (buf, "xsize %d\nysize %d\n", xsize_n, ysize_n); 849 sprintf (buf, "xsize %d\nysize %d\n", xsize_n, ysize_n);
831 850
832 if (wallstyle_n && wallstyle_n[0]) 851 if (wallstyle_n && wallstyle_n[0])
833 { 852 {
967 } 986 }
968 987
969 if (random_seed_n) 988 if (random_seed_n)
970 { 989 {
971 /* Add one so that the next map is a bit different */ 990 /* Add one so that the next map is a bit different */
972 sprintf (small_buf, "random_seed %d\n", random_seed_n + 1); 991 sprintf (small_buf, "random_seed %u\n", random_seed_n + 1);
973 strcat (buf, small_buf); 992 strcat (buf, small_buf);
974 } 993 }
975 994
976 if (treasureoptions_n) 995 if (treasureoptions_n)
977 { 996 {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines