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.1 by elmex, Sun Aug 13 17:16:03 2006 UTC vs.
Revision 1.13 by pippijn, Sat Jan 6 14:42:30 2007 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines