Crossfire Server, Branch 1.12
R12190
|
00001 /* 00002 * static char *rcsid_wall_c = 00003 * "$Id: wall.c 11578 2009-02-23 22:02:27Z lalo $"; 00004 */ 00005 00006 /* 00007 CrossFire, A Multiplayer game for X-windows 00008 00009 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 00010 Copyright (C) 1992 Frank Tore Johansen 00011 00012 This program is free software; you can redistribute it and/or modify 00013 it under the terms of the GNU General Public License as published by 00014 the Free Software Foundation; either version 2 of the License, or 00015 (at your option) any later version. 00016 00017 This program is distributed in the hope that it will be useful, 00018 but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 GNU General Public License for more details. 00021 00022 You should have received a copy of the GNU General Public License 00023 along with this program; if not, write to the Free Software 00024 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00025 00026 The authors can be reached via e-mail at crossfire-devel@real-time.com 00027 */ 00028 00034 #include <global.h> 00035 #include <random_map.h> 00036 #include <rproto.h> 00037 00056 int surround_flag(char **layout, int i, int j, RMParms *RP) { 00057 int surround_index = 0; 00058 00059 if ((i > 0) && layout[i-1][j] != 0) 00060 surround_index |= 1; 00061 if ((i < RP->Xsize-1) && layout[i+1][j] != 0) 00062 surround_index |= 2; 00063 if ((j > 0) && layout[i][j-1] != 0) 00064 surround_index |= 4; 00065 if ((j < RP->Ysize-1) && layout[i][j+1] != 0) 00066 surround_index |= 8; 00067 return surround_index; 00068 } 00069 00088 int surround_flag2(char **layout, int i, int j, RMParms *RP) { 00089 int surround_index = 0; 00090 00091 if ((i > 0) && layout[i-1][j] == '#') 00092 surround_index |= 1; 00093 if ((i < RP->Xsize-1) && layout[i+1][j] == '#') 00094 surround_index |= 2; 00095 if ((j > 0) && layout[i][j-1] == '#') 00096 surround_index |= 4; 00097 if ((j < RP->Ysize-1) && layout[i][j+1] == '#') 00098 surround_index |= 8; 00099 return surround_index; 00100 } 00101 00120 int surround_flag3(mapstruct *map, int i, int j, RMParms *RP) { 00121 int surround_index = 0; 00122 00123 if ((i > 0) && (GET_MAP_MOVE_BLOCK(map, i-1, j)&~MOVE_BLOCK_DEFAULT)) 00124 surround_index |= 1; 00125 if ((i < RP->Xsize-1) && (GET_MAP_MOVE_BLOCK(map, i+1, j)&~MOVE_BLOCK_DEFAULT)) 00126 surround_index |= 2; 00127 if ((j > 0) && (GET_MAP_MOVE_BLOCK(map, i, j-1)&~MOVE_BLOCK_DEFAULT)) 00128 surround_index |= 4; 00129 if ((j < RP->Ysize-1) && (GET_MAP_MOVE_BLOCK(map, i, j+1)&~MOVE_BLOCK_DEFAULT)) 00130 surround_index |= 8; 00131 00132 return surround_index; 00133 } 00134 00153 int surround_flag4(mapstruct *map, int i, int j, RMParms *RP) { 00154 int surround_index = 0; 00155 00156 if ((i > 0) && wall_blocked(map, i-1, j)) 00157 surround_index |= 1; 00158 if ((i < RP->Xsize-1) && wall_blocked(map, i+1, j)) 00159 surround_index |= 2; 00160 if ((j > 0) && wall_blocked(map, i, j-1)) 00161 surround_index |= 4; 00162 if ((j < RP->Ysize-1) && wall_blocked(map, i, j+1)) 00163 surround_index |= 8; 00164 00165 return surround_index; 00166 } 00167 00180 void make_map_walls(mapstruct *map, char **layout, char *w_style, RMParms *RP) { 00181 char styledirname[256]; 00182 char stylefilepath[256]; 00183 mapstruct *style_map = NULL; 00184 object *the_wall; 00185 00186 /* get the style map */ 00187 if (!strcmp(w_style, "none")) 00188 return; 00189 snprintf(styledirname, sizeof(styledirname), "%s", "/styles/wallstyles"); 00190 snprintf(stylefilepath, sizeof(stylefilepath), "%s/%s", styledirname, w_style); 00191 style_map = find_style(styledirname, w_style, -1); 00192 if (style_map == NULL) 00193 return; 00194 00195 /* fill up the map with the given floor style */ 00196 if ((the_wall = pick_random_object(style_map)) != NULL) { 00197 int i, j; 00198 char *cp; 00199 int joinedwalls = 0; 00200 object *thiswall; 00201 00202 snprintf(RP->wall_name, sizeof(RP->wall_name), "%s", the_wall->arch->name); 00203 if ((cp = strchr(RP->wall_name, '_')) != NULL) { 00204 *cp = 0; 00205 joinedwalls = 1; 00206 } 00207 00208 for (i = 0; i < RP->Xsize; i++) 00209 for (j = 0; j < RP->Ysize; j++) { 00210 if (layout[i][j] == '#') { 00211 if (joinedwalls) 00212 thiswall = pick_joined_wall(the_wall, layout, i, j, RP); 00213 else 00214 thiswall = arch_to_object(the_wall->arch); 00215 thiswall->x = i; 00216 thiswall->y = j; 00217 thiswall->move_block = MOVE_ALL; 00218 thiswall->move_allow = 0; 00219 insert_ob_in_map(thiswall, map, thiswall, INS_NO_MERGE|INS_NO_WALK_ON); 00220 } 00221 } 00222 } 00223 } 00224 00241 object *pick_joined_wall(object *the_wall, char **layout, int i, int j, RMParms *RP) { 00242 /* 1 = wall to left, 00243 2 = wall to right, 00244 4 = wall above 00245 8 = wall below */ 00246 int surround_index = 0; 00247 int l; 00248 char wall_name[64]; 00249 archetype *wall_arch = NULL; 00250 00251 strncpy(wall_name, the_wall->arch->name, sizeof(wall_name)); 00252 00253 /* conventionally, walls are named like this: 00254 wallname_wallcode, where wallcode indicates 00255 a joinedness, and wallname is the wall. 00256 this code depends on the convention for 00257 finding the right wall. */ 00258 00259 /* extract the wall name, which is the text up to the leading _ */ 00260 for (l = 0; l < 64; l++) { 00261 if (wall_name[l] == '_') { 00262 wall_name[l] = 0; 00263 break; 00264 } 00265 } 00266 00267 surround_index = surround_flag2(layout, i, j, RP); 00268 00269 switch (surround_index) { 00270 case 0: 00271 strcat(wall_name, "_0"); 00272 break; 00273 00274 case 1: 00275 strcat(wall_name, "_1_3"); 00276 break; 00277 00278 case 2: 00279 strcat(wall_name, "_1_4"); 00280 break; 00281 00282 case 3: 00283 strcat(wall_name, "_2_1_2"); 00284 break; 00285 00286 case 4: 00287 strcat(wall_name, "_1_2"); 00288 break; 00289 00290 case 5: 00291 strcat(wall_name, "_2_2_4"); 00292 break; 00293 00294 case 6: 00295 strcat(wall_name, "_2_2_1"); 00296 break; 00297 00298 case 7: 00299 strcat(wall_name, "_3_1"); 00300 break; 00301 00302 case 8: 00303 strcat(wall_name, "_1_1"); 00304 break; 00305 00306 case 9: 00307 strcat(wall_name, "_2_2_3"); 00308 break; 00309 00310 case 10: 00311 strcat(wall_name, "_2_2_2"); 00312 break; 00313 00314 case 11: 00315 strcat(wall_name, "_3_3"); 00316 break; 00317 00318 case 12: 00319 strcat(wall_name, "_2_1_1"); 00320 break; 00321 00322 case 13: 00323 strcat(wall_name, "_3_4"); 00324 break; 00325 00326 case 14: 00327 strcat(wall_name, "_3_2"); 00328 break; 00329 00330 case 15: 00331 strcat(wall_name, "_4"); 00332 break; 00333 } 00334 wall_arch = try_find_archetype(wall_name); 00335 if (wall_arch) 00336 return arch_to_object(wall_arch); 00337 else { 00338 return arch_to_object(the_wall->arch); 00339 } 00340 } 00341 00362 object *retrofit_joined_wall(mapstruct *the_map, int i, int j, int insert_flag, RMParms *RP) { 00363 /* 1 = wall to left, 00364 * 2 = wall to right, 00365 * 4 = wall above 00366 * 8 = wall below 00367 */ 00368 int surround_index = 0; 00369 int l; 00370 object *the_wall = NULL; 00371 object *new_wall = NULL; 00372 archetype *wall_arch = NULL; 00373 00374 /* first find the wall */ 00375 for (the_wall = GET_MAP_OB(the_map, i, j); the_wall != NULL; the_wall = the_wall->above) 00376 if ((the_wall->move_type&MOVE_WALK) && the_wall->type != EXIT && the_wall->type != TELEPORTER) 00377 break; 00378 00379 00380 /* if what we found is a door, don't remove it, set the_wall to NULL to 00381 * signal that later. 00382 */ 00383 if (the_wall && (the_wall->type == DOOR || the_wall->type == LOCKED_DOOR)) { 00384 the_wall = NULL; 00385 /* if we're not supposed to insert a new wall where there wasn't one, 00386 * we've gotta leave. 00387 */ 00388 if (insert_flag == 0) 00389 return NULL; 00390 } else if (the_wall == NULL) 00391 return NULL; 00392 00393 /* canonicalize the wall name */ 00394 for (l = 0; l < 64; l++) { 00395 if (RP->wall_name[l] == '_') { 00396 RP->wall_name[l] = 0; 00397 break; 00398 } 00399 } 00400 00401 surround_index = surround_flag4(the_map, i, j, RP); 00402 /* This would be a lot cleaner to just us a lookup table, 00403 * eg, wall_suffix[surround_index] 00404 */ 00405 switch (surround_index) { 00406 case 0: 00407 strcat(RP->wall_name, "_0"); 00408 break; 00409 00410 case 1: 00411 strcat(RP->wall_name, "_1_3"); 00412 break; 00413 00414 case 2: 00415 strcat(RP->wall_name, "_1_4"); 00416 break; 00417 00418 case 3: 00419 strcat(RP->wall_name, "_2_1_2"); 00420 break; 00421 00422 case 4: 00423 strcat(RP->wall_name, "_1_2"); 00424 break; 00425 00426 case 5: 00427 strcat(RP->wall_name, "_2_2_4"); 00428 break; 00429 00430 case 6: 00431 strcat(RP->wall_name, "_2_2_1"); 00432 break; 00433 00434 case 7: 00435 strcat(RP->wall_name, "_3_1"); 00436 break; 00437 00438 case 8: 00439 strcat(RP->wall_name, "_1_1"); 00440 break; 00441 00442 case 9: 00443 strcat(RP->wall_name, "_2_2_3"); 00444 break; 00445 00446 case 10: 00447 strcat(RP->wall_name, "_2_2_2"); 00448 break; 00449 00450 case 11: 00451 strcat(RP->wall_name, "_3_3"); 00452 break; 00453 00454 case 12: 00455 strcat(RP->wall_name, "_2_1_1"); 00456 break; 00457 00458 case 13: 00459 strcat(RP->wall_name, "_3_4"); 00460 break; 00461 00462 case 14: 00463 strcat(RP->wall_name, "_3_2"); 00464 break; 00465 00466 case 15: 00467 strcat(RP->wall_name, "_4"); 00468 break; 00469 } 00470 wall_arch = try_find_archetype(RP->wall_name); 00471 if (wall_arch != NULL) { 00472 new_wall = arch_to_object(wall_arch); 00473 new_wall->x = i; 00474 new_wall->y = j; 00475 if (the_wall && the_wall->map) { 00476 remove_ob(the_wall); 00477 free_object(the_wall); 00478 } 00479 the_wall->move_block = MOVE_ALL; 00480 insert_ob_in_map(new_wall, the_map, new_wall, INS_NO_MERGE|INS_NO_WALK_ON); 00481 } 00482 return new_wall; 00483 }