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

Comparing deliantra/server/random_maps/special.C (file contents):
Revision 1.4 by root, Sun Sep 10 16:06:37 2006 UTC vs.
Revision 1.15 by root, Mon Jan 15 15:54:19 2007 UTC

1
2/*
3 * static char *rcsid_special_c =
4 * "$Id: special.C,v 1.4 2006/09/10 16:06:37 root Exp $";
5 */
6 1
7/* 2/*
8 CrossFire, A Multiplayer game for X-windows 3 CrossFire, A Multiplayer game for X-windows
9 4
5 Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
10 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 6 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen 7 Copyright (C) 1992 Frank Tore Johansen
12 8
13 This program is free software; you can redistribute it and/or modify 9 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by 10 it under the terms of the GNU General Public License as published by
22 18
23 You should have received a copy of the GNU General Public License 19 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software 20 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 22
27 The authors can be reached via e-mail at crossfire-devel@real-time.com 23 The authors can be reached via e-mail at <crossfire@schmorp.de>
28*/ 24*/
29 25
30/* Specials in this file: 26/* Specials in this file:
31 included maps */ 27 included maps */
32 28
47 43
48/* clear map completely of all objects: a rectangular area of xsize, ysize 44/* clear map completely of all objects: a rectangular area of xsize, ysize
49is cleared with the top left corner at xstart, ystart */ 45is cleared with the top left corner at xstart, ystart */
50 46
51void 47void
52nuke_map_region (mapstruct *map, int xstart, int ystart, int xsize, int ysize) 48nuke_map_region (maptile *map, int xstart, int ystart, int xsize, int ysize)
53{ 49{
54 int i, j; 50 int i, j;
55 object *tmp; 51 object *tmp;
56 52
57 for (i = xstart; i < xstart + xsize; i++) 53 for (i = xstart; i < xstart + xsize; i++)
58 for (j = ystart; j < ystart + ysize; j++) 54 for (j = ystart; j < ystart + ysize; j++)
59 { 55 {
60 for (tmp = get_map_ob (map, i, j); tmp != NULL; tmp = tmp->above) 56 for (tmp = GET_MAP_OB (map, i, j); tmp != NULL; tmp = tmp->above)
61 { 57 {
62 if (!QUERY_FLAG (tmp, FLAG_IS_FLOOR)) 58 if (!QUERY_FLAG (tmp, FLAG_IS_FLOOR))
63 { 59 {
64 if (tmp->head) 60 if (tmp->head)
65 tmp = tmp->head; 61 tmp = tmp->head;
66 remove_ob (tmp); 62 tmp->remove ();
67 free_object (tmp); 63 tmp->destroy ();
68 tmp = get_map_ob (map, i, j); 64 tmp = GET_MAP_OB (map, i, j);
69 } 65 }
70 if (tmp == NULL) 66 if (tmp == NULL)
71 break; 67 break;
72 } 68 }
73 } 69 }
77 73
78/* copy in_map into dest_map at point x,y */ 74/* copy in_map into dest_map at point x,y */
79 75
80 76
81void 77void
82include_map_in_map (mapstruct *dest_map, mapstruct *in_map, int x, int y) 78include_map_in_map (maptile *dest_map, maptile *in_map, int x, int y)
83{ 79{
84 int i, j; 80 int i, j;
85 object *tmp; 81 object *tmp;
86 object *new_ob; 82 object *new_ob;
87 83
88 /* First, splatter everything in the dest map at the location */ 84 /* First, splatter everything in the dest map at the location */
89 nuke_map_region (dest_map, x, y, MAP_WIDTH (in_map), MAP_HEIGHT (in_map)); 85 nuke_map_region (dest_map, x, y, in_map->width, in_map->height);
90 86
91 for (i = 0; i < MAP_WIDTH (in_map); i++) 87 for (i = 0; i < in_map->width; i++)
92 for (j = 0; j < MAP_HEIGHT (in_map); j++) 88 for (j = 0; j < in_map->height; j++)
93 { 89 {
94 for (tmp = get_map_ob (in_map, i, j); tmp != NULL; tmp = tmp->above) 90 for (tmp = GET_MAP_OB (in_map, i, j); tmp != NULL; tmp = tmp->above)
95 { 91 {
96 /* don't copy things with multiple squares: must be dealt with 92 /* don't copy things with multiple squares: must be dealt with
97 specially. */ 93 specially. */
98 if (tmp->head != NULL) 94 if (tmp->head != NULL)
99 continue; 95 continue;
107 } 103 }
108 } 104 }
109} 105}
110 106
111int 107int
112find_spot_for_submap (mapstruct *map, char **layout, int *ix, int *iy, int xsize, int ysize) 108find_spot_for_submap (maptile *map, char **layout, int *ix, int *iy, int xsize, int ysize)
113{ 109{
114 int tries; 110 int tries;
115 int i = 0, j = 0; /* initialization may not be needed but prevents compiler warnings */ 111 int i = 0, j = 0; /* initialization may not be needed but prevents compiler warnings */
116 int is_occupied = 0; 112 int is_occupied = 0;
117 int l, m; 113 int l, m;
118 114
119 /* don't even try to place a submap into a map if the big map isn't 115 /* don't even try to place a submap into a map if the big map isn't
120 sufficiently large. */ 116 sufficiently large. */
121 if (2 * xsize > MAP_WIDTH (map) || 2 * ysize > MAP_HEIGHT (map)) 117 if (2 * xsize > map->width || 2 * ysize > map->height)
122 return 0; 118 return 0;
123 119
124 /* search a bit for a completely free spot. */ 120 /* search a bit for a completely free spot. */
125 for (tries = 0; tries < 20; tries++) 121 for (tries = 0; tries < 20; tries++)
126 { 122 {
127 /* pick a random location in the layout */ 123 /* pick a random location in the layout */
128 i = RANDOM () % (MAP_WIDTH (map) - xsize - 2) + 1; 124 i = RANDOM () % (map->width - xsize - 2) + 1;
129 j = RANDOM () % (MAP_HEIGHT (map) - ysize - 2) + 1; 125 j = RANDOM () % (map->height - ysize - 2) + 1;
130 is_occupied = 0; 126 is_occupied = 0;
131 for (l = i; l < i + xsize; l++) 127 for (l = i; l < i + xsize; l++)
132 for (m = j; m < j + ysize; m++) 128 for (m = j; m < j + ysize; m++)
133 is_occupied |= layout[l][m]; 129 is_occupied |= layout[l][m];
134 if (!is_occupied) 130 if (!is_occupied)
141 if (is_occupied) 137 if (is_occupied)
142 { /* failure, try a relaxed placer. */ 138 { /* failure, try a relaxed placer. */
143 /* pick a random location in the layout */ 139 /* pick a random location in the layout */
144 for (tries = 0; tries < 10; tries++) 140 for (tries = 0; tries < 10; tries++)
145 { 141 {
146 i = RANDOM () % (MAP_WIDTH (map) - xsize - 2) + 1; 142 i = RANDOM () % (map->width - xsize - 2) + 1;
147 j = RANDOM () % (MAP_HEIGHT (map) - ysize - 2) + 1; 143 j = RANDOM () % (map->height - ysize - 2) + 1;
148 is_occupied = 0; 144 is_occupied = 0;
149 for (l = i; l < i + xsize; l++) 145 for (l = i; l < i + xsize; l++)
150 for (m = j; m < j + ysize; m++) 146 for (m = j; m < j + ysize; m++)
151 if (layout[l][m] == 'C' || layout[l][m] == '>' || layout[l][m] == '<') 147 if (layout[l][m] == 'C' || layout[l][m] == '>' || layout[l][m] == '<')
152 is_occupied |= 1; 148 is_occupied |= 1;
159 return 1; 155 return 1;
160} 156}
161 157
162 158
163void 159void
164place_fountain_with_specials (mapstruct *map) 160place_fountain_with_specials (maptile *map)
165{ 161{
166 int ix, iy, i = -1, tries = 0; 162 int ix, iy, i = -1, tries = 0;
167 mapstruct *fountain_style = find_style ("/styles/misc", "fountains", -1); 163 maptile *fountain_style = find_style ("/styles/misc", "fountains", -1);
168 object *fountain = get_archetype ("fountain"); 164 object *fountain = get_archetype ("fountain");
169 object *potion = get_object (); 165 object *potion = object::create ();
170 166
171 copy_object (pick_random_object (fountain_style), potion); 167 pick_random_object (fountain_style)->copy_to (potion);
168
172 while (i < 0 && tries < 10) 169 while (i < 0 && tries < 10)
173 { 170 {
174 ix = RANDOM () % (MAP_WIDTH (map) - 2) + 1; 171 ix = RANDOM () % (map->width - 2) + 1;
175 iy = RANDOM () % (MAP_HEIGHT (map) - 2) + 1; 172 iy = RANDOM () % (map->height - 2) + 1;
176 i = find_first_free_spot (fountain, map, ix, iy); 173 i = find_free_spot (fountain, map, ix, iy, 1, SIZEOFFREE1 + 1);
177 tries++; 174 tries++;
178 }; 175 }
176
179 if (i == -1) 177 if (i == -1)
180 { /* can't place fountain */ 178 { /* can't place fountain */
181 free_object (fountain); 179 fountain->destroy ();
182 free_object (potion); 180 potion->destroy ();
183 return; 181 return;
184 } 182 }
183
185 ix += freearr_x[i]; 184 ix += freearr_x[i];
186 iy += freearr_y[i]; 185 iy += freearr_y[i];
187 potion->face = fountain->face; 186 potion->face = fountain->face;
188 SET_FLAG (potion, FLAG_NO_PICK); 187 SET_FLAG (potion, FLAG_NO_PICK);
189 SET_FLAG (potion, FLAG_IDENTIFIED); 188 SET_FLAG (potion, FLAG_IDENTIFIED);
193 potion->material = M_ADAMANT; 192 potion->material = M_ADAMANT;
194 fountain->x = ix; 193 fountain->x = ix;
195 fountain->y = iy; 194 fountain->y = iy;
196 insert_ob_in_map (fountain, map, NULL, 0); 195 insert_ob_in_map (fountain, map, NULL, 0);
197 insert_ob_in_map (potion, map, NULL, 0); 196 insert_ob_in_map (potion, map, NULL, 0);
198
199} 197}
200 198
201void 199void
202place_special_exit (mapstruct *map, int hole_type, RMParms * RP) 200place_special_exit (maptile *map, int hole_type, random_map_params *RP)
203{ 201{
204 int ix, iy, i = -1; 202 int ix, iy, i = -1;
205 char buf[HUGE_BUF], *style, *decor, *mon; 203 char buf[16384], *style, *decor, *mon;
206 mapstruct *exit_style = find_style ("/styles/misc", "obscure_exits", -1); 204 maptile *exit_style = find_style ("/styles/misc", "obscure_exits", -1);
207 int g_xsize, g_ysize; 205 int g_xsize, g_ysize;
208 206
209 object *the_exit = get_object (); 207 object *the_exit = object::create ();
210 208
211 if (!exit_style) 209 if (!exit_style)
212 return; 210 return;
213 211
214 copy_object (pick_random_object (exit_style), the_exit); 212 pick_random_object (exit_style)->copy_to (the_exit);
215 213
216 while (i < 0) 214 while (i < 0)
217 { 215 {
218 ix = RANDOM () % (MAP_WIDTH (map) - 2) + 1; 216 ix = RANDOM () % (map->width - 2) + 1;
219 iy = RANDOM () % (MAP_HEIGHT (map) - 2) + 1; 217 iy = RANDOM () % (map->height - 2) + 1;
220 i = find_first_free_spot (the_exit, map, ix, iy); 218 i = find_free_spot (the_exit, map, ix, iy, 1, SIZEOFFREE1 + 1);
221 } 219 }
222 220
223 ix += freearr_x[i]; 221 ix += freearr_x[i];
224 iy += freearr_y[i]; 222 iy += freearr_y[i];
225 the_exit->x = ix; 223 the_exit->x = ix;
228 if (!hole_type) 226 if (!hole_type)
229 hole_type = RANDOM () % NR_OF_HOLE_TYPES + 1; 227 hole_type = RANDOM () % NR_OF_HOLE_TYPES + 1;
230 228
231 switch (hole_type) 229 switch (hole_type)
232 { 230 {
233 case GLORY_HOLE: /* treasures */ 231 case GLORY_HOLE: /* treasures */
234 { 232 {
235 g_xsize = RANDOM () % 3 + 4 + RP->difficulty / 4; 233 g_xsize = RANDOM () % 3 + 4 + RP->difficulty / 4;
236 g_ysize = RANDOM () % 3 + 4 + RP->difficulty / 4; 234 g_ysize = RANDOM () % 3 + 4 + RP->difficulty / 4;
237 style = "onion"; 235 style = "onion";
238 decor = "wealth2"; 236 decor = "wealth2";
239 mon = "none"; 237 mon = "none";
240 break; 238 break;
241 } 239 }
242 240
243 case ORC_ZONE: /* hole with orcs in it. */ 241 case ORC_ZONE: /* hole with orcs in it. */
244 { 242 {
245 g_xsize = RANDOM () % 3 + 4 + RP->difficulty / 4; 243 g_xsize = RANDOM () % 3 + 4 + RP->difficulty / 4;
246 g_ysize = RANDOM () % 3 + 4 + RP->difficulty / 4; 244 g_ysize = RANDOM () % 3 + 4 + RP->difficulty / 4;
247 style = "onion"; 245 style = "onion";
248 decor = "wealth2"; 246 decor = "wealth2";
249 mon = "orc"; 247 mon = "orc";
250 break; 248 break;
251 } 249 }
252 250
253 case MINING_ZONE: /* hole with orcs in it. */ 251 case MINING_ZONE: /* hole with orcs in it. */
254 { 252 {
255 g_xsize = RANDOM () % 9 + 4 + RP->difficulty / 4; 253 g_xsize = RANDOM () % 9 + 4 + RP->difficulty / 4;
256 g_ysize = RANDOM () % 9 + 4 + RP->difficulty / 4; 254 g_ysize = RANDOM () % 9 + 4 + RP->difficulty / 4;
257 style = "maze"; 255 style = "maze";
258 decor = "minerals2"; 256 decor = "minerals2";
259 mon = "none"; 257 mon = "none";
260 break; 258 break;
261 } 259 }
262 260
263 default: /* undefined */ 261 default: /* undefined */
264 LOG (llevError, "place_special_exit: undefined hole type %d\n", hole_type); 262 LOG (llevError, "place_special_exit: undefined hole type %d\n", hole_type);
265 return; 263 return;
266 break; 264 break;
267 } 265 }
268 266
269 /* Need to be at least this size, otherwise the load 267 /* Need to be at least this size, otherwise the load
270 * code will generate new size values which are too large. 268 * code will generate new size values which are too large.
271 */ 269 */
274 if (g_ysize < MIN_RANDOM_MAP_SIZE) 272 if (g_ysize < MIN_RANDOM_MAP_SIZE)
275 g_ysize = MIN_RANDOM_MAP_SIZE; 273 g_ysize = MIN_RANDOM_MAP_SIZE;
276 274
277 write_parameters_to_string (buf, g_xsize, g_ysize, RP->wallstyle, RP->floorstyle, mon, 275 write_parameters_to_string (buf, g_xsize, g_ysize, RP->wallstyle, RP->floorstyle, mon,
278 "none", style, decor, "none", RP->exitstyle, 0, 0, 0, 276 "none", style, decor, "none", RP->exitstyle, 0, 0, 0,
279 OPT_WALLS_ONLY, 0, 0, 1, RP->dungeon_level, RP->dungeon_level, 277 RMOPT_WALLS_ONLY, 0, 0, 1, RP->dungeon_level, RP->dungeon_level,
280 RP->difficulty, RP->difficulty, -1, 1, 0, 0, 0, 0, RP->difficulty_increase); 278 RP->difficulty, RP->difficulty, -1, 1, 0, 0, 0, 0, RP->difficulty_increase);
281 the_exit->slaying = "/!"; 279 the_exit->slaying = "/!";
282 the_exit->msg = buf; 280 the_exit->msg = buf;
283 281
284 insert_ob_in_map (the_exit, map, NULL, 0); 282 insert_ob_in_map (the_exit, map, NULL, 0);
285} 283}
286 284
287 285
288void 286void
289place_specials_in_map (mapstruct *map, char **layout, RMParms * RP) 287place_specials_in_map (maptile *map, char **layout, random_map_params *RP)
290{ 288{
291 mapstruct *special_map; 289 maptile *special_map;
292 int ix, iy; /* map insertion locatons */ 290 int ix, iy; /* map insertion locatons */
293 int special_type; /* type of special to make */ 291 int special_type; /* type of special to make */
294 292
295 293
296 special_type = RANDOM () % NUM_OF_SPECIAL_TYPES; 294 special_type = RANDOM () % NUM_OF_SPECIAL_TYPES;
297 switch (special_type) 295 switch (special_type)
298 { 296 {
299 297
300 /* includes a special map into the random map being made. */ 298 /* includes a special map into the random map being made. */
301 case SPECIAL_SUBMAP: 299 case SPECIAL_SUBMAP:
302 { 300 {
303 special_map = find_style ("/styles/specialmaps", 0, RP->difficulty); 301 special_map = find_style ("/styles/specialmaps", 0, RP->difficulty);
304 if (special_map == NULL) 302 if (special_map == NULL)
305 return; 303 return;
306 304
307 if (find_spot_for_submap (map, layout, &ix, &iy, MAP_WIDTH (special_map), MAP_HEIGHT (special_map))) 305 if (find_spot_for_submap (map, layout, &ix, &iy, special_map->width, special_map->height))
308 include_map_in_map (map, special_map, ix, iy); 306 include_map_in_map (map, special_map, ix, iy);
309 break; 307 break;
310 } 308 }
311 309
312 /* Make a special fountain: an unpickable potion disguised as 310 /* Make a special fountain: an unpickable potion disguised as
313 a fountain, or rather, colocated with a fountain. */ 311 a fountain, or rather, colocated with a fountain. */
314 case SPECIAL_FOUNTAIN: 312 case SPECIAL_FOUNTAIN:
315 { 313 {
316 place_fountain_with_specials (map); 314 place_fountain_with_specials (map);
317 break; 315 break;
318 } 316 }
319 317
320 /* Make an exit to another random map, e.g. a gloryhole. */ 318 /* Make an exit to another random map, e.g. a gloryhole. */
321 case SPECIAL_EXIT: 319 case SPECIAL_EXIT:
322 { 320 {
323 place_special_exit (map, 0, RP); 321 place_special_exit (map, 0, RP);
324 break; 322 break;
325 } 323 }
326 } 324 }
327 325
328} 326}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines