1 | /* |
1 | /* |
2 | * static char *rcsid_wall_c = |
2 | * static char *rcsid_wall_c = |
3 | * "$Id: wall.C,v 1.1 2006/08/13 17:16:03 elmex Exp $"; |
3 | * "$Id: wall.C,v 1.2 2006/08/29 08:01:36 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 | |
… | |
… | |
32 | |
32 | |
33 | /* Put in the walls and autojoin them. */ |
33 | /* Put in the walls and autojoin them. */ |
34 | |
34 | |
35 | |
35 | |
36 | /* given a layout and a coordinate, tell me which squares up/down/right/left |
36 | /* given a layout and a coordinate, tell me which squares up/down/right/left |
37 | are occupied. */ |
37 | are occupied. */ |
38 | |
38 | |
39 | int surround_flag(char **layout,int i,int j,RMParms *RP){ |
39 | int surround_flag(char **layout,int i,int j,RMParms *RP){ |
40 | /* 1 = wall to left, |
40 | /* 1 = wall to left, |
41 | 2 = wall to right, |
41 | 2 = wall to right, |
42 | 4 = wall above |
42 | 4 = wall above |
43 | 8 = wall below */ |
43 | 8 = wall below */ |
44 | int surround_index = 0; |
44 | int surround_index = 0; |
45 | if((i > 0) && layout[i-1][j]!=0) surround_index |=1; |
45 | if((i > 0) && layout[i-1][j]!=0) surround_index |=1; |
46 | if((i < RP->Xsize-1) && layout[i+1][j]!=0) surround_index |=2; |
46 | if((i < RP->Xsize-1) && layout[i+1][j]!=0) surround_index |=2; |
47 | if((j > 0) && layout[i][j-1]!=0) surround_index |=4; |
47 | if((j > 0) && layout[i][j-1]!=0) surround_index |=4; |
48 | if((j < RP->Ysize-1) && layout[i][j+1]!=0) surround_index |=8; |
48 | if((j < RP->Ysize-1) && layout[i][j+1]!=0) surround_index |=8; |
49 | return surround_index; |
49 | return surround_index; |
50 | } |
50 | } |
51 | |
51 | |
52 | |
52 | |
53 | /* like surround_flag, but only walls count. |
53 | /* like surround_flag, but only walls count. |
54 | */ |
54 | */ |
55 | |
55 | |
56 | int surround_flag2(char **layout,int i,int j,RMParms *RP){ |
56 | int surround_flag2(char **layout,int i,int j,RMParms *RP){ |
57 | /* 1 = wall to left, |
57 | /* 1 = wall to left, |
58 | 2 = wall to right, |
58 | 2 = wall to right, |
59 | 4 = wall above |
59 | 4 = wall above |
60 | 8 = wall below */ |
60 | 8 = wall below */ |
61 | int surround_index = 0; |
61 | int surround_index = 0; |
62 | if((i > 0) && layout[i-1][j]=='#') surround_index |=1; |
62 | if((i > 0) && layout[i-1][j]=='#') surround_index |=1; |
63 | if((i < RP->Xsize-1) && layout[i+1][j]=='#') surround_index |=2; |
63 | if((i < RP->Xsize-1) && layout[i+1][j]=='#') surround_index |=2; |
64 | if((j > 0) && layout[i][j-1]=='#') surround_index |=4; |
64 | if((j > 0) && layout[i][j-1]=='#') surround_index |=4; |
65 | if((j < RP->Ysize-1) && layout[i][j+1]=='#') surround_index |=8; |
65 | if((j < RP->Ysize-1) && layout[i][j+1]=='#') surround_index |=8; |
… | |
… | |
81 | */ |
81 | */ |
82 | |
82 | |
83 | int surround_index = 0; |
83 | int surround_index = 0; |
84 | |
84 | |
85 | if((i > 0) && (GET_MAP_MOVE_BLOCK(map, i-1,j) & ~MOVE_BLOCK_DEFAULT)) |
85 | if((i > 0) && (GET_MAP_MOVE_BLOCK(map, i-1,j) & ~MOVE_BLOCK_DEFAULT)) |
86 | surround_index |=1; |
86 | surround_index |=1; |
87 | if((i < RP->Xsize-1) && (GET_MAP_MOVE_BLOCK(map, i+1,j) & ~MOVE_BLOCK_DEFAULT)) |
87 | if((i < RP->Xsize-1) && (GET_MAP_MOVE_BLOCK(map, i+1,j) & ~MOVE_BLOCK_DEFAULT)) |
88 | surround_index |=2; |
88 | surround_index |=2; |
89 | if((j > 0) && (GET_MAP_MOVE_BLOCK(map, i,j-1) & ~MOVE_BLOCK_DEFAULT)) |
89 | if((j > 0) && (GET_MAP_MOVE_BLOCK(map, i,j-1) & ~MOVE_BLOCK_DEFAULT)) |
90 | surround_index |=4; |
90 | surround_index |=4; |
91 | if((j < RP->Ysize-1) && (GET_MAP_MOVE_BLOCK(map,i,j+1) & ~MOVE_BLOCK_DEFAULT)) |
91 | if((j < RP->Ysize-1) && (GET_MAP_MOVE_BLOCK(map,i,j+1) & ~MOVE_BLOCK_DEFAULT)) |
92 | surround_index |=8; |
92 | surround_index |=8; |
93 | |
93 | |
94 | return surround_index; |
94 | return surround_index; |
95 | } |
95 | } |
96 | |
96 | |
97 | /* like surround_flag2, except it checks a map, not a layout. */ |
97 | /* like surround_flag2, except it checks a map, not a layout. */ |
98 | |
98 | |
99 | int surround_flag4(mapstruct *map,int i,int j,RMParms *RP){ |
99 | int surround_flag4(mapstruct *map,int i,int j,RMParms *RP){ |
100 | /* 1 = blocked to left, |
100 | /* 1 = blocked to left, |
101 | 2 = blocked to right, |
101 | 2 = blocked to right, |
102 | 4 = blocked above |
102 | 4 = blocked above |
103 | 8 = blocked below */ |
103 | 8 = blocked below */ |
104 | int surround_index = 0; |
104 | int surround_index = 0; |
105 | |
105 | |
106 | if((i > 0) && wall_blocked(map,i-1,j)) surround_index |=1; |
106 | if((i > 0) && wall_blocked(map,i-1,j)) surround_index |=1; |
107 | if((i < RP->Xsize-1) && wall_blocked(map,i+1,j)) surround_index |=2; |
107 | if((i < RP->Xsize-1) && wall_blocked(map,i+1,j)) surround_index |=2; |
108 | if((j > 0) && wall_blocked(map,i,j-1)) surround_index |=4; |
108 | if((j > 0) && wall_blocked(map,i,j-1)) surround_index |=4; |
… | |
… | |
110 | |
110 | |
111 | return surround_index; |
111 | return surround_index; |
112 | } |
112 | } |
113 | |
113 | |
114 | /* takes a map and a layout, and puts walls in the map (picked from |
114 | /* takes a map and a layout, and puts walls in the map (picked from |
115 | w_style) at '#' marks. */ |
115 | w_style) at '#' marks. */ |
116 | |
116 | |
117 | void make_map_walls(mapstruct *map,char **layout, char *w_style,RMParms *RP) { |
117 | void make_map_walls(mapstruct *map,char **layout, char *w_style,RMParms *RP) { |
118 | char styledirname[256]; |
118 | char styledirname[256]; |
119 | char stylefilepath[256]; |
119 | char stylefilepath[256]; |
120 | mapstruct *style_map=0; |
120 | mapstruct *style_map=0; |
… | |
… | |
127 | style_map = find_style(styledirname,w_style,-1); |
127 | style_map = find_style(styledirname,w_style,-1); |
128 | if(style_map == 0) return; |
128 | if(style_map == 0) return; |
129 | |
129 | |
130 | /* fill up the map with the given floor style */ |
130 | /* fill up the map with the given floor style */ |
131 | if((the_wall=pick_random_object(style_map))!=NULL) { |
131 | if((the_wall=pick_random_object(style_map))!=NULL) { |
132 | int i,j; |
132 | int i,j; |
133 | char *cp; |
133 | char *cp; |
134 | int joinedwalls=0; |
134 | int joinedwalls=0; |
135 | object *thiswall; |
135 | object *thiswall; |
136 | |
136 | |
137 | sprintf(RP->wall_name,"%s",the_wall->arch->name); |
137 | sprintf(RP->wall_name,"%s",the_wall->arch->name); |
138 | if ((cp=strchr(RP->wall_name,'_'))!=NULL) { |
138 | if ((cp=strchr(RP->wall_name,'_'))!=NULL) { |
139 | *cp=0; |
139 | *cp=0; |
140 | joinedwalls=1; |
140 | joinedwalls=1; |
141 | } |
141 | } |
142 | |
142 | |
143 | for(i=0;i<RP->Xsize;i++) |
143 | for(i=0;i<RP->Xsize;i++) |
144 | for(j=0;j<RP->Ysize;j++) { |
144 | for(j=0;j<RP->Ysize;j++) { |
145 | if(layout[i][j]=='#') { |
145 | if(layout[i][j]=='#') { |
146 | if(joinedwalls) |
146 | if(joinedwalls) |
147 | thiswall=pick_joined_wall(the_wall,layout,i,j,RP); |
147 | thiswall=pick_joined_wall(the_wall,layout,i,j,RP); |
148 | else |
148 | else |
149 | thiswall=arch_to_object(the_wall->arch); |
149 | thiswall=arch_to_object(the_wall->arch); |
150 | thiswall->x = i; |
150 | thiswall->x = i; |
151 | thiswall->y = j; |
151 | thiswall->y = j; |
152 | thiswall->move_block = MOVE_ALL; |
152 | thiswall->move_block = MOVE_ALL; |
153 | insert_ob_in_map(thiswall,map,thiswall,INS_NO_MERGE | INS_NO_WALK_ON); |
153 | insert_ob_in_map(thiswall,map,thiswall,INS_NO_MERGE | INS_NO_WALK_ON); |
154 | } |
154 | } |
155 | } |
155 | } |
156 | } |
156 | } |
157 | } |
157 | } |
158 | |
158 | |
159 | |
159 | |
160 | /* picks the right wall type for this square, to make it look nice, |
160 | /* picks the right wall type for this square, to make it look nice, |
161 | and have everything nicely joined. It uses the layout. */ |
161 | and have everything nicely joined. It uses the layout. */ |
162 | |
162 | |
163 | object *pick_joined_wall(object *the_wall,char **layout,int i,int j,RMParms *RP) { |
163 | object *pick_joined_wall(object *the_wall,char **layout,int i,int j,RMParms *RP) { |
164 | /* 1 = wall to left, |
164 | /* 1 = wall to left, |
165 | 2 = wall to right, |
165 | 2 = wall to right, |
166 | 4 = wall above |
166 | 4 = wall above |
167 | 8 = wall below */ |
167 | 8 = wall below */ |
168 | int surround_index=0; |
168 | int surround_index=0; |
169 | int l; |
169 | int l; |
170 | char wall_name[64]; |
170 | char wall_name[64]; |
171 | archetype *wall_arch=0; |
171 | archetype *wall_arch=0; |
172 | |
172 | |
173 | strcpy(wall_name,the_wall->arch->name); |
173 | strcpy(wall_name,the_wall->arch->name); |
174 | |
174 | |
175 | /* conventionally, walls are named like this: |
175 | /* conventionally, walls are named like this: |
176 | wallname_wallcode, where wallcode indicates |
176 | wallname_wallcode, where wallcode indicates |
177 | a joinedness, and wallname is the wall. |
177 | a joinedness, and wallname is the wall. |
178 | this code depends on the convention for |
178 | this code depends on the convention for |
179 | finding the right wall. */ |
179 | finding the right wall. */ |
180 | |
180 | |
181 | /* extract the wall name, which is the text up to the leading _ */ |
181 | /* extract the wall name, which is the text up to the leading _ */ |
182 | for(l=0;l<64;l++) { |
182 | for(l=0;l<64;l++) { |
183 | if(wall_name[l]=='_') { |
183 | if(wall_name[l]=='_') { |
184 | wall_name[l] = 0; |
184 | wall_name[l] = 0; |
185 | break; |
185 | break; |
186 | } |
186 | } |
187 | } |
187 | } |
188 | |
188 | |
189 | surround_index = surround_flag2(layout,i,j,RP); |
189 | surround_index = surround_flag2(layout,i,j,RP); |
190 | |
190 | |
191 | switch(surround_index) { |
191 | switch(surround_index) { |
192 | case 0: |
192 | case 0: |
193 | strcat(wall_name,"_0"); |
193 | strcat(wall_name,"_0"); |
194 | break; |
194 | break; |
195 | case 1: |
195 | case 1: |
196 | strcat(wall_name,"_1_3"); |
196 | strcat(wall_name,"_1_3"); |
197 | break; |
197 | break; |
198 | case 2: |
198 | case 2: |
199 | strcat(wall_name,"_1_4"); |
199 | strcat(wall_name,"_1_4"); |
200 | break; |
200 | break; |
201 | case 3: |
201 | case 3: |
202 | strcat(wall_name,"_2_1_2"); |
202 | strcat(wall_name,"_2_1_2"); |
203 | break; |
203 | break; |
204 | case 4: |
204 | case 4: |
205 | strcat(wall_name,"_1_2"); |
205 | strcat(wall_name,"_1_2"); |
206 | break; |
206 | break; |
207 | case 5: |
207 | case 5: |
208 | strcat(wall_name,"_2_2_4"); |
208 | strcat(wall_name,"_2_2_4"); |
209 | break; |
209 | break; |
210 | case 6: |
210 | case 6: |
211 | strcat(wall_name,"_2_2_1"); |
211 | strcat(wall_name,"_2_2_1"); |
212 | break; |
212 | break; |
213 | case 7: |
213 | case 7: |
214 | strcat(wall_name,"_3_1"); |
214 | strcat(wall_name,"_3_1"); |
215 | break; |
215 | break; |
216 | case 8: |
216 | case 8: |
217 | strcat(wall_name,"_1_1"); |
217 | strcat(wall_name,"_1_1"); |
218 | break; |
218 | break; |
219 | case 9: |
219 | case 9: |
220 | strcat(wall_name,"_2_2_3"); |
220 | strcat(wall_name,"_2_2_3"); |
221 | break; |
221 | break; |
222 | case 10: |
222 | case 10: |
223 | strcat(wall_name,"_2_2_2"); |
223 | strcat(wall_name,"_2_2_2"); |
224 | break; |
224 | break; |
225 | case 11: |
225 | case 11: |
226 | strcat(wall_name,"_3_3"); |
226 | strcat(wall_name,"_3_3"); |
227 | break; |
227 | break; |
228 | case 12: |
228 | case 12: |
229 | strcat(wall_name,"_2_1_1"); |
229 | strcat(wall_name,"_2_1_1"); |
230 | break; |
230 | break; |
231 | case 13: |
231 | case 13: |
232 | strcat(wall_name,"_3_4"); |
232 | strcat(wall_name,"_3_4"); |
233 | break; |
233 | break; |
234 | case 14: |
234 | case 14: |
235 | strcat(wall_name,"_3_2"); |
235 | strcat(wall_name,"_3_2"); |
236 | break; |
236 | break; |
237 | case 15: |
237 | case 15: |
238 | strcat(wall_name,"_4"); |
238 | strcat(wall_name,"_4"); |
239 | break; |
239 | break; |
240 | } |
240 | } |
241 | wall_arch = find_archetype(wall_name); |
241 | wall_arch = find_archetype(wall_name); |
242 | if(wall_arch) return arch_to_object(wall_arch); |
242 | if(wall_arch) return arch_to_object(wall_arch); |
243 | else { |
243 | else { |
244 | nroferrors--; |
244 | nroferrors--; |
… | |
… | |
269 | object *new_wall=0; |
269 | object *new_wall=0; |
270 | archetype * wall_arch=0; |
270 | archetype * wall_arch=0; |
271 | |
271 | |
272 | /* first find the wall */ |
272 | /* first find the wall */ |
273 | for(the_wall = get_map_ob(the_map,i,j);the_wall!=NULL;the_wall=the_wall->above) |
273 | for(the_wall = get_map_ob(the_map,i,j);the_wall!=NULL;the_wall=the_wall->above) |
274 | if ((the_wall->move_type & MOVE_WALK) && the_wall->type!=EXIT && the_wall->type!=TELEPORTER) |
274 | if ((the_wall->move_type & MOVE_WALK) && the_wall->type!=EXIT && the_wall->type!=TELEPORTER) |
275 | break; |
275 | break; |
276 | |
276 | |
277 | |
277 | |
278 | /* if what we found is a door, don't remove it, set the_wall to NULL to |
278 | /* if what we found is a door, don't remove it, set the_wall to NULL to |
279 | * signal that later. |
279 | * signal that later. |
280 | */ |
280 | */ |
281 | if(the_wall && (the_wall->type==DOOR || the_wall->type==LOCKED_DOOR) ) { |
281 | if(the_wall && (the_wall->type==DOOR || the_wall->type==LOCKED_DOOR) ) { |
282 | the_wall=NULL; |
282 | the_wall=NULL; |
283 | /* if we're not supposed to insert a new wall where there wasn't one, |
283 | /* if we're not supposed to insert a new wall where there wasn't one, |
284 | * we've gotta leave. |
284 | * we've gotta leave. |
285 | */ |
285 | */ |
286 | if(insert_flag==0) return 0; |
286 | if(insert_flag==0) return 0; |
287 | } |
287 | } |
288 | else if(the_wall==NULL) return NULL; |
288 | else if(the_wall==NULL) return NULL; |
289 | |
289 | |
290 | /* canonicalize the wall name */ |
290 | /* canonicalize the wall name */ |
291 | for(l=0;l<64;l++) { |
291 | for(l=0;l<64;l++) { |
292 | if(RP->wall_name[l]=='_') { |
292 | if(RP->wall_name[l]=='_') { |
293 | RP->wall_name[l] = 0; |
293 | RP->wall_name[l] = 0; |
294 | break; |
294 | break; |
295 | } |
295 | } |
296 | } |
296 | } |
297 | |
297 | |
298 | surround_index = surround_flag4(the_map,i,j,RP); |
298 | surround_index = surround_flag4(the_map,i,j,RP); |
299 | /* This would be a lot cleaner to just us a lookup table, |
299 | /* This would be a lot cleaner to just us a lookup table, |
300 | * eg, wall_suffix[surround_index] |
300 | * eg, wall_suffix[surround_index] |
301 | */ |
301 | */ |
302 | switch(surround_index) { |
302 | switch(surround_index) { |
303 | case 0: |
303 | case 0: |
304 | strcat(RP->wall_name,"_0"); |
304 | strcat(RP->wall_name,"_0"); |
305 | break; |
305 | break; |
306 | case 1: |
306 | case 1: |
307 | strcat(RP->wall_name,"_1_3"); |
307 | strcat(RP->wall_name,"_1_3"); |
308 | break; |
308 | break; |
309 | case 2: |
309 | case 2: |
310 | strcat(RP->wall_name,"_1_4"); |
310 | strcat(RP->wall_name,"_1_4"); |
311 | break; |
311 | break; |
312 | case 3: |
312 | case 3: |
313 | strcat(RP->wall_name,"_2_1_2"); |
313 | strcat(RP->wall_name,"_2_1_2"); |
314 | break; |
314 | break; |
315 | case 4: |
315 | case 4: |
316 | strcat(RP->wall_name,"_1_2"); |
316 | strcat(RP->wall_name,"_1_2"); |
317 | break; |
317 | break; |
318 | case 5: |
318 | case 5: |
319 | strcat(RP->wall_name,"_2_2_4"); |
319 | strcat(RP->wall_name,"_2_2_4"); |
320 | break; |
320 | break; |
321 | case 6: |
321 | case 6: |
322 | strcat(RP->wall_name,"_2_2_1"); |
322 | strcat(RP->wall_name,"_2_2_1"); |
323 | break; |
323 | break; |
324 | case 7: |
324 | case 7: |
325 | strcat(RP->wall_name,"_3_1"); |
325 | strcat(RP->wall_name,"_3_1"); |
326 | break; |
326 | break; |
327 | case 8: |
327 | case 8: |
328 | strcat(RP->wall_name,"_1_1"); |
328 | strcat(RP->wall_name,"_1_1"); |
329 | break; |
329 | break; |
330 | case 9: |
330 | case 9: |
331 | strcat(RP->wall_name,"_2_2_3"); |
331 | strcat(RP->wall_name,"_2_2_3"); |
332 | break; |
332 | break; |
333 | case 10: |
333 | case 10: |
334 | strcat(RP->wall_name,"_2_2_2"); |
334 | strcat(RP->wall_name,"_2_2_2"); |
335 | break; |
335 | break; |
336 | case 11: |
336 | case 11: |
337 | strcat(RP->wall_name,"_3_3"); |
337 | strcat(RP->wall_name,"_3_3"); |
338 | break; |
338 | break; |
339 | case 12: |
339 | case 12: |
340 | strcat(RP->wall_name,"_2_1_1"); |
340 | strcat(RP->wall_name,"_2_1_1"); |
341 | break; |
341 | break; |
342 | case 13: |
342 | case 13: |
343 | strcat(RP->wall_name,"_3_4"); |
343 | strcat(RP->wall_name,"_3_4"); |
344 | break; |
344 | break; |
345 | case 14: |
345 | case 14: |
346 | strcat(RP->wall_name,"_3_2"); |
346 | strcat(RP->wall_name,"_3_2"); |
347 | break; |
347 | break; |
348 | case 15: |
348 | case 15: |
349 | strcat(RP->wall_name,"_4"); |
349 | strcat(RP->wall_name,"_4"); |
350 | break; |
350 | break; |
351 | } |
351 | } |
352 | wall_arch = find_archetype(RP->wall_name); |
352 | wall_arch = find_archetype(RP->wall_name); |
353 | if(wall_arch!=NULL) { |
353 | if(wall_arch!=NULL) { |
354 | new_wall=arch_to_object(wall_arch); |
354 | new_wall=arch_to_object(wall_arch); |
355 | new_wall->x = i; |
355 | new_wall->x = i; |
356 | new_wall->y = j; |
356 | new_wall->y = j; |
357 | if(the_wall && the_wall->map) { |
357 | if(the_wall && the_wall->map) { |
358 | remove_ob(the_wall); |
358 | remove_ob(the_wall); |
359 | free_object(the_wall); |
359 | free_object(the_wall); |
360 | } |
360 | } |
361 | the_wall->move_block = MOVE_ALL; |
361 | the_wall->move_block = MOVE_ALL; |
362 | insert_ob_in_map(new_wall,the_map,new_wall,INS_NO_MERGE | INS_NO_WALK_ON); |
362 | insert_ob_in_map(new_wall,the_map,new_wall,INS_NO_MERGE | INS_NO_WALK_ON); |
363 | } |
363 | } |
364 | else |
364 | else |
365 | nroferrors--; /* it's OK not to find an arch. */ |
365 | nroferrors--; /* it's OK not to find an arch. */ |
366 | return new_wall; |
366 | return new_wall; |
367 | } |
367 | } |
368 | |
368 | |
369 | |
369 | |