Atrinik Server 2.5
random_maps/wall.c
Go to the documentation of this file.
00001 /************************************************************************
00002 *            Atrinik, a Multiplayer Online Role Playing Game            *
00003 *                                                                       *
00004 *    Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team    *
00005 *                                                                       *
00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game)     *
00007 * and Crossfire (Multiplayer game for X-windows).                       *
00008 *                                                                       *
00009 * This program is free software; you can redistribute it and/or modify  *
00010 * it under the terms of the GNU General Public License as published by  *
00011 * the Free Software Foundation; either version 2 of the License, or     *
00012 * (at your option) any later version.                                   *
00013 *                                                                       *
00014 * This program is distributed in the hope that it will be useful,       *
00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00017 * GNU General Public License for more details.                          *
00018 *                                                                       *
00019 * You should have received a copy of the GNU General Public License     *
00020 * along with this program; if not, write to the Free Software           *
00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.             *
00022 *                                                                       *
00023 * The author can be reached at admin@atrinik.org                        *
00024 ************************************************************************/
00025 
00030 #include <global.h>
00031 
00041 int surround_flag(char **layout, int i, int j, RMParms *RP)
00042 {
00043     int surround_index = 0;
00044 
00045     if ((i > 0) && layout[i - 1][j] != '\0')
00046     {
00047         surround_index |= 1;
00048     }
00049 
00050     if ((i < RP->Xsize - 1) && layout[i + 1][j] != '\0')
00051     {
00052         surround_index |= 2;
00053     }
00054 
00055     if ((j > 0) && layout[i][j - 1] != '\0')
00056     {
00057         surround_index |= 4;
00058     }
00059 
00060     if ((j < RP->Ysize - 1) && layout[i][j + 1] != '\0')
00061     {
00062         surround_index |= 8;
00063     }
00064 
00065     return surround_index;
00066 }
00067 
00077 int surround_flag2(char **layout, int i, int j, RMParms *RP)
00078 {
00079     int surround_index = 0;
00080 
00081     if ((i > 0) && (layout[i - 1][j] == '#' || layout[i - 1][j] == 'D'))
00082     {
00083         surround_index |= 1;
00084     }
00085 
00086     if ((i < RP->Xsize - 1) && (layout[i + 1][j] == '#' || layout[i + 1][j] == 'D'))
00087     {
00088         surround_index |= 2;
00089     }
00090 
00091     if ((j > 0) && (layout[i][j - 1] == '#' || layout[i][j - 1] == 'D'))
00092     {
00093         surround_index |= 4;
00094     }
00095 
00096     if ((j < RP->Ysize - 1) && (layout[i][j + 1] == '#' || layout[i][j + 1] == 'D'))
00097     {
00098         surround_index |= 8;
00099     }
00100 
00101     return surround_index;
00102 }
00103 
00117 int surround_flag3(mapstruct *map, int i, int j, RMParms *RP)
00118 {
00119     int surround_index = 0;
00120 
00121     if ((i > 0) && blocked(NULL, map, i -1, j, TERRAIN_ALL))
00122     {
00123         surround_index |= 1;
00124     }
00125 
00126     if ((i < RP->Xsize - 1) && blocked(NULL, map, i + 1, j, TERRAIN_ALL))
00127     {
00128         surround_index |= 2;
00129     }
00130 
00131     if ((j > 0) && blocked(NULL, map, i, j - 1, TERRAIN_ALL))
00132     {
00133         surround_index |= 4;
00134     }
00135 
00136     if ((j < RP->Ysize - 1) && blocked(NULL, map, i, j + 1, TERRAIN_ALL))
00137     {
00138         surround_index |= 8;
00139     }
00140 
00141     return surround_index;
00142 }
00143 
00157 int surround_flag4(mapstruct *map, int i, int j, RMParms *RP)
00158 {
00159     int surround_index = 0;
00160 
00161     if ((i > 0) && wall_blocked(map, i - 1, j))
00162     {
00163         surround_index |= 1;
00164     }
00165 
00166     if ((i < RP->Xsize - 1) && wall_blocked(map, i + 1, j))
00167     {
00168         surround_index |= 2;
00169     }
00170 
00171     if ((j > 0) && wall_blocked(map, i, j- 1))
00172     {
00173         surround_index |= 4;
00174     }
00175 
00176     if ((j < RP->Ysize - 1) && wall_blocked(map, i, j + 1))
00177     {
00178         surround_index |= 8;
00179     }
00180 
00181     return surround_index;
00182 }
00183 
00191 void make_map_walls(mapstruct *map, char **layout, char *w_style, RMParms *RP)
00192 {
00193     char styledirname[256], stylefilepath[256];
00194     mapstruct *style_map = NULL;
00195     object *the_wall;
00196 
00197     /* get the style map */
00198     if (!strcmp(w_style, "none"))
00199     {
00200         return;
00201     }
00202 
00203     strncpy(styledirname, "/styles/wallstyles", sizeof(styledirname) - 1);
00204 
00205     snprintf(stylefilepath, sizeof(stylefilepath), "%s/%s", styledirname, w_style);
00206     style_map = find_style(styledirname, w_style, -1);
00207 
00208     if (style_map == 0)
00209     {
00210         return;
00211     }
00212 
00213     /* Fill up the map with the given wall style */
00214     if ((the_wall = pick_random_object(style_map)) != NULL)
00215     {
00216         int i, j;
00217         char *cp;
00218 
00219         snprintf(RP->wall_name, sizeof(RP->wall_name), "%s", the_wall->arch->name);
00220 
00221         if ((cp = strchr(RP->wall_name, '_')) != NULL)
00222         {
00223             *cp = '\0';
00224         }
00225 
00226         for (i = 0; i < RP->Xsize; i++)
00227         {
00228             for (j = 0; j < RP->Ysize; j++)
00229             {
00230                 if (layout[i][j] == '#')
00231                 {
00232                     object *thiswall = pick_joined_wall(the_wall, layout, i, j, RP);
00233 
00234                     thiswall->x = i;
00235                     thiswall->y = j;
00236 
00237                     /* Make SURE it's a wall */
00238                     SET_FLAG(thiswall, FLAG_NO_PASS);
00239 
00240                     wall(map, i, j);
00241                     insert_ob_in_map(thiswall, map, thiswall, INS_NO_MERGE | INS_NO_WALK_ON);
00242                 }
00243             }
00244         }
00245     }
00246 }
00247 
00256 object *pick_joined_wall(object *the_wall, char **layout, int i, int j, RMParms *RP)
00257 {
00258     int surround_index = 0, l;
00259     char wall_name[MAX_BUF];
00260     archetype *wall_arch = 0;
00261 
00262     strncpy(wall_name, the_wall->arch->name, sizeof(wall_name) - 1);
00263 
00264     /* conventionally, walls are named like this:
00265         wallname_wallcode, where wallcode indicates
00266         a joinedness, and wallname is the wall.
00267         this code depends on the convention for
00268         finding the right wall. */
00269 
00270     /* extract the wall name, which is the text up to the leading _ */
00271     for (l = sizeof(wall_name); l >= 0; l--)
00272     {
00273         if (wall_name[l] == '_')
00274         {
00275             wall_name[l] = '\0';
00276             break;
00277         }
00278     }
00279 
00280     surround_index = surround_flag2(layout, i, j, RP);
00281 
00282     switch (surround_index)
00283     {
00284         case 0:
00285             strcat(wall_name, "_0");
00286             break;
00287 
00288         case 10:
00289         case 8:
00290         case 2:
00291             strcat(wall_name, "_8");
00292             break;
00293 
00294         case 11:
00295         case 9:
00296         case 3:
00297             strcat(wall_name, "_1");
00298             break;
00299 
00300         case 12:
00301         case 4:
00302         case 14:
00303         case 6:
00304             strcat(wall_name, "_3");
00305             break;
00306 
00307         case 1:
00308         case 5:
00309         case 7:
00310         case 13:
00311         case 15:
00312             strcat(wall_name, "_4");
00313             break;
00314     }
00315 
00316     wall_arch = find_archetype(wall_name);
00317 
00318     if (wall_arch)
00319     {
00320         return arch_to_object(wall_arch);
00321     }
00322     else
00323     {
00324         return arch_to_object(the_wall->arch);
00325     }
00326 }
00327 
00336 object * retrofit_joined_wall(mapstruct *the_map, int i, int j, int insert_flag, RMParms *RP)
00337 {
00338     int surround_index = 0, l;
00339     object *the_wall = NULL, *new_wall = NULL;
00340     archetype *wall_arch = NULL;
00341 
00342     /* First find the wall */
00343     for (the_wall = get_map_ob(the_map, i, j); the_wall != NULL; the_wall = the_wall->above)
00344     {
00345         if (QUERY_FLAG(the_wall, FLAG_NO_PASS) && the_wall->type != EXIT && the_wall->type != TELEPORTER)
00346         {
00347             break;
00348         }
00349     }
00350 
00351 
00352     /* if what we found is a door, don't remove it, set the_wall to NULL to
00353         signal that later. */
00354     if (the_wall && the_wall->type == DOOR)
00355     {
00356         the_wall = NULL;
00357 
00358         /* if we're not supposed to insert a new wall where there wasn't one,
00359             we've gotta leave. */
00360         if (insert_flag == 0)
00361         {
00362             return NULL;
00363         }
00364     }
00365     else if (the_wall == NULL)
00366     {
00367         return NULL;
00368     }
00369 
00370     /* Canonicalize the wall name */
00371     for (l = 0; l < 64; l++)
00372     {
00373         if (RP->wall_name[l] == '_')
00374         {
00375             RP->wall_name[l] = 0;
00376             break;
00377         }
00378     }
00379 
00380     surround_index = surround_flag4(the_map, i, j, RP);
00381 
00382     switch (surround_index)
00383     {
00384         case 0:
00385             strcat(RP->wall_name, "_0");
00386             break;
00387 
00388         case 10:
00389         case 8:
00390         case 2:
00391             strcat(RP->wall_name, "_8");
00392             break;
00393 
00394         case 11:
00395         case 9:
00396         case 3:
00397             strcat(RP->wall_name, "_1");
00398             break;
00399 
00400         case 12:
00401         case 4:
00402         case 14:
00403         case 6:
00404             strcat(RP->wall_name, "_3");
00405             break;
00406 
00407         case 1:
00408         case 5:
00409         case 7:
00410         case 13:
00411         case 15:
00412             strcat(RP->wall_name, "_4");
00413             break;
00414     }
00415 
00416     wall_arch = find_archetype(RP->wall_name);
00417 
00418     if (wall_arch != NULL)
00419     {
00420         new_wall = arch_to_object(wall_arch);
00421         new_wall->x = i;
00422         new_wall->y = j;
00423 
00424         if (the_wall && the_wall->map)
00425         {
00426             remove_ob(the_wall);
00427         }
00428 
00429         /* Make SURE it's a wall */
00430         SET_FLAG(new_wall, FLAG_NO_PASS);
00431         insert_ob_in_map(new_wall, the_map, new_wall, INS_NO_MERGE | INS_NO_WALK_ON);
00432     }
00433 
00434     return new_wall;
00435 }