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.3 by root, Sun Sep 3 00:18:41 2006 UTC vs.
Revision 1.15 by root, Mon Jan 15 15:54:19 2007 UTC

1/*
2 * static char *rcsid_special_c =
3 * "$Id: special.C,v 1.3 2006/09/03 00:18:41 root 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
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;
149 i = find_first_free_spot(fountain,map,ix,iy); 172 iy = RANDOM () % (map->height - 2) + 1;
173 i = find_free_spot (fountain, map, ix, iy, 1, SIZEOFFREE1 + 1);
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 = potion->name_pl = "fountain"; 189 potion->name = potion->name_pl = "fountain";
163 potion->x = ix; 190 potion->x = ix;
164 potion->y = iy; 191 potion->y = iy;
165 potion->material=M_ADAMANT; 192 potion->material = M_ADAMANT;
166 fountain->x = ix; 193 fountain->x = ix;
167 fountain->y = iy; 194 fountain->y = iy;
168 insert_ob_in_map(fountain,map,NULL,0); 195 insert_ob_in_map (fountain, map, NULL, 0);
169 insert_ob_in_map(potion,map,NULL,0); 196 insert_ob_in_map (potion, map, NULL, 0);
170
171} 197}
172 198
199void
173void place_special_exit(mapstruct * map, int hole_type,RMParms *RP) { 200place_special_exit (maptile *map, int hole_type, random_map_params *RP)
201{
174 int ix,iy,i=-1; 202 int ix, iy, i = -1;
175 char buf[HUGE_BUF], *style, *decor, *mon; 203 char buf[16384], *style, *decor, *mon;
176 mapstruct *exit_style=find_style("/styles/misc","obscure_exits",-1); 204 maptile *exit_style = find_style ("/styles/misc", "obscure_exits", -1);
177 int g_xsize,g_ysize; 205 int g_xsize, g_ysize;
178 206
179 object *the_exit=get_object(); 207 object *the_exit = object::create ();
208
180 if(!exit_style) return; 209 if (!exit_style)
181 210 return;
211
182 copy_object(pick_random_object(exit_style),the_exit); 212 pick_random_object (exit_style)->copy_to (the_exit);
183 213
184 while(i<0) { 214 while (i < 0)
185 ix = RANDOM() % (MAP_WIDTH(map) -2) +1;
186 iy = RANDOM() % (MAP_HEIGHT(map) -2) +1;
187 i = find_first_free_spot(the_exit,map,ix,iy);
188 } 215 {
189 216 ix = RANDOM () % (map->width - 2) + 1;
217 iy = RANDOM () % (map->height - 2) + 1;
218 i = find_free_spot (the_exit, map, ix, iy, 1, SIZEOFFREE1 + 1);
219 }
220
190 ix += freearr_x[i]; 221 ix += freearr_x[i];
191 iy += freearr_y[i]; 222 iy += freearr_y[i];
192 the_exit->x = ix; 223 the_exit->x = ix;
193 the_exit->y = iy; 224 the_exit->y = iy;
194 225
226 if (!hole_type)
195 if(!hole_type) hole_type = RANDOM() % NR_OF_HOLE_TYPES + 1 ; 227 hole_type = RANDOM () % NR_OF_HOLE_TYPES + 1;
196 228
197 switch(hole_type) { 229 switch (hole_type)
230 {
198 case GLORY_HOLE: /* treasures */ 231 case GLORY_HOLE: /* treasures */
199 { 232 {
200 g_xsize = RANDOM() %3 + 4 + RP->difficulty/4; 233 g_xsize = RANDOM () % 3 + 4 + RP->difficulty / 4;
201 g_ysize = RANDOM() %3 + 4 + RP->difficulty/4; 234 g_ysize = RANDOM () % 3 + 4 + RP->difficulty / 4;
202 style = "onion"; 235 style = "onion";
203 decor = "wealth2"; 236 decor = "wealth2";
204 mon = "none"; 237 mon = "none";
205 break; 238 break;
206 } 239 }
207 240
208 case ORC_ZONE: /* hole with orcs in it. */ 241 case ORC_ZONE: /* hole with orcs in it. */
209 { 242 {
210 g_xsize = RANDOM() %3 + 4 + RP->difficulty/4; 243 g_xsize = RANDOM () % 3 + 4 + RP->difficulty / 4;
211 g_ysize = RANDOM() %3 + 4 + RP->difficulty/4; 244 g_ysize = RANDOM () % 3 + 4 + RP->difficulty / 4;
212 style = "onion"; 245 style = "onion";
213 decor = "wealth2"; 246 decor = "wealth2";
214 mon = "orc"; 247 mon = "orc";
215 break; 248 break;
216 } 249 }
217 250
218 case MINING_ZONE: /* hole with orcs in it. */ 251 case MINING_ZONE: /* hole with orcs in it. */
219 { 252 {
220 g_xsize = RANDOM() %9 + 4 + RP->difficulty/4; 253 g_xsize = RANDOM () % 9 + 4 + RP->difficulty / 4;
221 g_ysize = RANDOM() %9 + 4 + RP->difficulty/4; 254 g_ysize = RANDOM () % 9 + 4 + RP->difficulty / 4;
222 style = "maze"; 255 style = "maze";
223 decor = "minerals2"; 256 decor = "minerals2";
224 mon = "none"; 257 mon = "none";
225 break; 258 break;
226 } 259 }
227 260
228 default: /* undefined */ 261 default: /* undefined */
229 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);
263 return;
264 break;
265 }
266
267 /* Need to be at least this size, otherwise the load
268 * code will generate new size values which are too large.
269 */
270 if (g_xsize < MIN_RANDOM_MAP_SIZE)
271 g_xsize = MIN_RANDOM_MAP_SIZE;
272 if (g_ysize < MIN_RANDOM_MAP_SIZE)
273 g_ysize = MIN_RANDOM_MAP_SIZE;
274
275 write_parameters_to_string (buf, g_xsize, g_ysize, RP->wallstyle, RP->floorstyle, mon,
276 "none", style, decor, "none", RP->exitstyle, 0, 0, 0,
277 RMOPT_WALLS_ONLY, 0, 0, 1, RP->dungeon_level, RP->dungeon_level,
278 RP->difficulty, RP->difficulty, -1, 1, 0, 0, 0, 0, RP->difficulty_increase);
279 the_exit->slaying = "/!";
280 the_exit->msg = buf;
281
282 insert_ob_in_map (the_exit, map, NULL, 0);
283}
284
285
286void
287place_specials_in_map (maptile *map, char **layout, random_map_params *RP)
288{
289 maptile *special_map;
290 int ix, iy; /* map insertion locatons */
291 int special_type; /* type of special to make */
292
293
294 special_type = RANDOM () % NUM_OF_SPECIAL_TYPES;
295 switch (special_type)
296 {
297
298 /* includes a special map into the random map being made. */
299 case SPECIAL_SUBMAP:
300 {
301 special_map = find_style ("/styles/specialmaps", 0, RP->difficulty);
302 if (special_map == NULL)
230 return; 303 return;
304
305 if (find_spot_for_submap (map, layout, &ix, &iy, special_map->width, special_map->height))
306 include_map_in_map (map, special_map, ix, iy);
231 break; 307 break;
232 }
233
234 /* Need to be at least this size, otherwise the load
235 * code will generate new size values which are too large.
236 */
237 if (g_xsize < MIN_RANDOM_MAP_SIZE) g_xsize = MIN_RANDOM_MAP_SIZE;
238 if (g_ysize < MIN_RANDOM_MAP_SIZE) g_ysize = MIN_RANDOM_MAP_SIZE;
239
240 write_parameters_to_string(buf, g_xsize, g_ysize,RP->wallstyle,RP->floorstyle,mon,
241 "none",style,decor,"none",RP->exitstyle,0,0,0,
242 OPT_WALLS_ONLY,0,0,1,RP->dungeon_level,RP->dungeon_level,
243 RP->difficulty,RP->difficulty,-1,1,0,0,0,0, RP->difficulty_increase);
244 the_exit->slaying = "/!";
245 the_exit->msg = buf;
246
247 insert_ob_in_map(the_exit,map,NULL,0);
248}
249
250
251void place_specials_in_map(mapstruct *map, char **layout,RMParms *RP) {
252 mapstruct *special_map;
253 int ix,iy; /* map insertion locatons */
254 int special_type; /* type of special to make */
255
256
257 special_type = RANDOM() % NUM_OF_SPECIAL_TYPES;
258 switch(special_type) {
259
260 /* includes a special map into the random map being made. */
261 case SPECIAL_SUBMAP: {
262 special_map = find_style("/styles/specialmaps",0,RP->difficulty);
263 if(special_map==NULL) return;
264 308 }
265 if(find_spot_for_submap(map,layout,&ix,&iy,MAP_WIDTH(special_map),MAP_HEIGHT(special_map)))
266 include_map_in_map(map,special_map,ix,iy);
267 break;
268 }
269 309
270 /* Make a special fountain: an unpickable potion disguised as 310 /* Make a special fountain: an unpickable potion disguised as
271 a fountain, or rather, colocated with a fountain. */ 311 a fountain, or rather, colocated with a fountain. */
272 case SPECIAL_FOUNTAIN: { 312 case SPECIAL_FOUNTAIN:
313 {
273 place_fountain_with_specials(map); 314 place_fountain_with_specials (map);
274 break; 315 break;
275 } 316 }
276 317
277 /* Make an exit to another random map, e.g. a gloryhole. */ 318 /* Make an exit to another random map, e.g. a gloryhole. */
278 case SPECIAL_EXIT: { 319 case SPECIAL_EXIT:
320 {
279 place_special_exit(map,0,RP); 321 place_special_exit (map, 0, RP);
280 break; 322 break;
323 }
281 } 324 }
282 } 325
283
284} 326}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines