1 | /* |
1 | /* |
2 | * static char *rcsid_special_c = |
2 | * static char *rcsid_special_c = |
3 | * "$Id: special.C,v 1.1 2006/08/13 17:16:03 elmex Exp $"; |
3 | * "$Id: special.C,v 1.3 2006/09/03 00:18:41 root Exp $"; |
4 | */ |
4 | */ |
5 | |
5 | |
6 | /* |
6 | /* |
7 | CrossFire, A Multiplayer game for X-windows |
7 | CrossFire, A Multiplayer game for X-windows |
8 | |
8 | |
… | |
… | |
25 | |
25 | |
26 | The authors can be reached via e-mail at crossfire-devel@real-time.com |
26 | The authors can be reached via e-mail at crossfire-devel@real-time.com |
27 | */ |
27 | */ |
28 | |
28 | |
29 | /* Specials in this file: |
29 | /* Specials in this file: |
30 | included maps */ |
30 | included maps */ |
31 | |
31 | |
32 | #include <global.h> |
32 | #include <global.h> |
33 | #include <random_map.h> |
33 | #include <random_map.h> |
34 | #include <rproto.h> |
34 | #include <rproto.h> |
35 | |
35 | |
… | |
… | |
74 | object *tmp; |
74 | object *tmp; |
75 | object *new_ob; |
75 | object *new_ob; |
76 | |
76 | |
77 | /* First, splatter everything in the dest map at the location */ |
77 | /* 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)); |
78 | nuke_map_region(dest_map,x,y,MAP_WIDTH(in_map),MAP_HEIGHT(in_map)); |
79 | |
79 | |
80 | for(i=0;i<MAP_WIDTH(in_map);i++) |
80 | for(i=0;i<MAP_WIDTH(in_map);i++) |
81 | for(j=0;j<MAP_HEIGHT(in_map);j++) { |
81 | for(j=0;j<MAP_HEIGHT(in_map);j++) { |
82 | for(tmp=get_map_ob(in_map,i,j);tmp!=NULL;tmp=tmp->above) { |
82 | for(tmp=get_map_ob(in_map,i,j);tmp!=NULL;tmp=tmp->above) { |
83 | /* don't copy things with multiple squares: must be dealt with |
83 | /* don't copy things with multiple squares: must be dealt with |
84 | specially. */ |
84 | specially. */ |
… | |
… | |
113 | for(m=j;m<j + ysize;m++) |
113 | for(m=j;m<j + ysize;m++) |
114 | is_occupied|=layout[l][m]; |
114 | is_occupied|=layout[l][m]; |
115 | if(!is_occupied) break; |
115 | if(!is_occupied) break; |
116 | } |
116 | } |
117 | |
117 | |
118 | |
118 | |
119 | /* if we failed, relax the restrictions */ |
119 | /* if we failed, relax the restrictions */ |
120 | |
120 | |
121 | if(is_occupied) { /* failure, try a relaxed placer. */ |
121 | if(is_occupied) { /* failure, try a relaxed placer. */ |
122 | /* pick a random location in the layout */ |
122 | /* pick a random location in the layout */ |
123 | for(tries=0;tries<10;tries++) { |
123 | for(tries=0;tries<10;tries++) { |
… | |
… | |
157 | ix += freearr_x[i]; |
157 | ix += freearr_x[i]; |
158 | iy += freearr_y[i]; |
158 | iy += freearr_y[i]; |
159 | potion->face=fountain->face; |
159 | potion->face=fountain->face; |
160 | SET_FLAG(potion,FLAG_NO_PICK); |
160 | SET_FLAG(potion,FLAG_NO_PICK); |
161 | SET_FLAG(potion,FLAG_IDENTIFIED); |
161 | SET_FLAG(potion,FLAG_IDENTIFIED); |
162 | potion->name=add_string("fountain"); |
162 | potion->name = potion->name_pl = "fountain"; |
163 | potion->name_pl=add_string("fountain"); |
|
|
164 | potion->x = ix; |
163 | potion->x = ix; |
165 | potion->y = iy; |
164 | potion->y = iy; |
166 | potion->material=M_ADAMANT; |
165 | potion->material=M_ADAMANT; |
167 | fountain->x = ix; |
166 | fountain->x = ix; |
168 | fountain->y = iy; |
167 | fountain->y = iy; |
… | |
… | |
181 | if(!exit_style) return; |
180 | if(!exit_style) return; |
182 | |
181 | |
183 | copy_object(pick_random_object(exit_style),the_exit); |
182 | copy_object(pick_random_object(exit_style),the_exit); |
184 | |
183 | |
185 | while(i<0) { |
184 | while(i<0) { |
186 | ix = RANDOM() % (MAP_WIDTH(map) -2) +1; |
185 | ix = RANDOM() % (MAP_WIDTH(map) -2) +1; |
187 | iy = RANDOM() % (MAP_HEIGHT(map) -2) +1; |
186 | iy = RANDOM() % (MAP_HEIGHT(map) -2) +1; |
188 | i = find_first_free_spot(the_exit,map,ix,iy); |
187 | i = find_first_free_spot(the_exit,map,ix,iy); |
189 | } |
188 | } |
190 | |
189 | |
191 | ix += freearr_x[i]; |
190 | ix += freearr_x[i]; |
192 | iy += freearr_y[i]; |
191 | iy += freearr_y[i]; |
193 | the_exit->x = ix; |
192 | the_exit->x = ix; |
194 | the_exit->y = iy; |
193 | the_exit->y = iy; |
195 | |
194 | |
196 | if(!hole_type) hole_type = RANDOM() % NR_OF_HOLE_TYPES + 1 ; |
195 | if(!hole_type) hole_type = RANDOM() % NR_OF_HOLE_TYPES + 1 ; |
197 | |
196 | |
198 | switch(hole_type) { |
197 | switch(hole_type) { |
199 | case GLORY_HOLE: /* treasures */ |
198 | case GLORY_HOLE: /* treasures */ |
200 | { |
199 | { |
201 | g_xsize = RANDOM() %3 + 4 + RP->difficulty/4; |
200 | g_xsize = RANDOM() %3 + 4 + RP->difficulty/4; |
202 | g_ysize = RANDOM() %3 + 4 + RP->difficulty/4; |
201 | g_ysize = RANDOM() %3 + 4 + RP->difficulty/4; |
203 | style = "onion"; |
202 | style = "onion"; |
204 | decor = "wealth2"; |
203 | decor = "wealth2"; |
205 | mon = "none"; |
204 | mon = "none"; |
206 | break; |
205 | break; |
207 | } |
206 | } |
208 | |
207 | |
209 | case ORC_ZONE: /* hole with orcs in it. */ |
208 | case ORC_ZONE: /* hole with orcs in it. */ |
210 | { |
209 | { |
211 | g_xsize = RANDOM() %3 + 4 + RP->difficulty/4; |
210 | g_xsize = RANDOM() %3 + 4 + RP->difficulty/4; |
212 | g_ysize = RANDOM() %3 + 4 + RP->difficulty/4; |
211 | g_ysize = RANDOM() %3 + 4 + RP->difficulty/4; |
213 | style = "onion"; |
212 | style = "onion"; |
214 | decor = "wealth2"; |
213 | decor = "wealth2"; |
215 | mon = "orc"; |
214 | mon = "orc"; |
216 | break; |
215 | break; |
217 | } |
216 | } |
218 | |
217 | |
219 | case MINING_ZONE: /* hole with orcs in it. */ |
218 | case MINING_ZONE: /* hole with orcs in it. */ |
220 | { |
219 | { |
221 | g_xsize = RANDOM() %9 + 4 + RP->difficulty/4; |
220 | g_xsize = RANDOM() %9 + 4 + RP->difficulty/4; |
222 | g_ysize = RANDOM() %9 + 4 + RP->difficulty/4; |
221 | g_ysize = RANDOM() %9 + 4 + RP->difficulty/4; |
223 | style = "maze"; |
222 | style = "maze"; |
224 | decor = "minerals2"; |
223 | decor = "minerals2"; |
225 | mon = "none"; |
224 | mon = "none"; |
226 | break; |
225 | break; |
227 | } |
226 | } |
228 | |
227 | |
229 | default: /* undefined */ |
228 | default: /* undefined */ |
230 | LOG(llevError, "place_special_exit: undefined hole type %d\n", hole_type); |
229 | LOG(llevError, "place_special_exit: undefined hole type %d\n", hole_type); |
231 | return; |
230 | return; |
232 | break; |
231 | break; |
233 | } |
232 | } |
234 | |
233 | |
235 | /* Need to be at least this size, otherwise the load |
234 | /* Need to be at least this size, otherwise the load |
236 | * code will generate new size values which are too large. |
235 | * code will generate new size values which are too large. |
237 | */ |
236 | */ |
… | |
… | |
240 | |
239 | |
241 | write_parameters_to_string(buf, g_xsize, g_ysize,RP->wallstyle,RP->floorstyle,mon, |
240 | write_parameters_to_string(buf, g_xsize, g_ysize,RP->wallstyle,RP->floorstyle,mon, |
242 | "none",style,decor,"none",RP->exitstyle,0,0,0, |
241 | "none",style,decor,"none",RP->exitstyle,0,0,0, |
243 | OPT_WALLS_ONLY,0,0,1,RP->dungeon_level,RP->dungeon_level, |
242 | OPT_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); |
243 | RP->difficulty,RP->difficulty,-1,1,0,0,0,0, RP->difficulty_increase); |
245 | the_exit->slaying = add_string("/!"); |
244 | the_exit->slaying = "/!"; |
246 | the_exit->msg = add_string(buf); |
245 | the_exit->msg = buf; |
247 | |
246 | |
248 | insert_ob_in_map(the_exit,map,NULL,0); |
247 | insert_ob_in_map(the_exit,map,NULL,0); |
249 | } |
248 | } |
250 | |
249 | |
251 | |
250 | |
252 | void place_specials_in_map(mapstruct *map, char **layout,RMParms *RP) { |
251 | void place_specials_in_map(mapstruct *map, char **layout,RMParms *RP) { |
253 | mapstruct *special_map; |
252 | mapstruct *special_map; |
254 | int ix,iy; /* map insertion locatons */ |
253 | int ix,iy; /* map insertion locatons */ |
255 | int special_type; /* type of special to make */ |
254 | int special_type; /* type of special to make */ |
256 | |
255 | |
… | |
… | |
260 | |
259 | |
261 | /* includes a special map into the random map being made. */ |
260 | /* includes a special map into the random map being made. */ |
262 | case SPECIAL_SUBMAP: { |
261 | case SPECIAL_SUBMAP: { |
263 | special_map = find_style("/styles/specialmaps",0,RP->difficulty); |
262 | special_map = find_style("/styles/specialmaps",0,RP->difficulty); |
264 | if(special_map==NULL) return; |
263 | if(special_map==NULL) return; |
265 | |
264 | |
266 | if(find_spot_for_submap(map,layout,&ix,&iy,MAP_WIDTH(special_map),MAP_HEIGHT(special_map))) |
265 | if(find_spot_for_submap(map,layout,&ix,&iy,MAP_WIDTH(special_map),MAP_HEIGHT(special_map))) |
267 | include_map_in_map(map,special_map,ix,iy); |
266 | include_map_in_map(map,special_map,ix,iy); |
268 | break; |
267 | break; |
269 | } |
268 | } |
270 | |
269 | |