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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines