|
Atrinik Server 2.5
|
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 00032 #include <global.h> 00033 00035 region *first_region = NULL; 00036 00037 static region *get_region_struct(); 00038 static void assign_region_parents(); 00039 00049 region *get_region_by_name(const char *region_name) 00050 { 00051 region *reg; 00052 00053 for (reg = first_region; reg; reg = reg->next) 00054 { 00055 if (!strcmp(reg->name, region_name)) 00056 { 00057 return reg; 00058 } 00059 } 00060 00061 LOG(llevDebug, "Got no region for region %s.\n", region_name); 00062 return NULL; 00063 } 00064 00073 char *get_region_longname(const region *r) 00074 { 00075 if (r->longname) 00076 { 00077 return r->longname; 00078 } 00079 else if (r->parent) 00080 { 00081 return get_region_longname(r->parent); 00082 } 00083 00084 LOG(llevDebug, "Region %s has no parent and no longname.\n", r->name); 00085 return "no region name"; 00086 } 00087 00093 char *get_region_msg(const region *r) 00094 { 00095 if (r->msg) 00096 { 00097 return r->msg; 00098 } 00099 else if (r->parent) 00100 { 00101 return get_region_msg(r->parent); 00102 } 00103 00104 LOG(llevDebug, "Region %s has no parent and no msg.\n", r->name); 00105 return "no region message"; 00106 } 00107 00114 object *get_jail_exit(object *op) 00115 { 00116 region *reg; 00117 object *exit_ob; 00118 00119 if (op->type != PLAYER) 00120 { 00121 LOG(llevBug, "get_jail_exit() called for non-player object.\n"); 00122 return NULL; 00123 } 00124 00125 if (!op->map->region) 00126 { 00127 return NULL; 00128 } 00129 00130 reg = op->map->region; 00131 00132 while (reg) 00133 { 00134 if (reg->jailmap) 00135 { 00136 exit_ob = get_object(); 00137 FREE_AND_COPY_HASH(EXIT_PATH(exit_ob), reg->jailmap); 00138 /* Damned exits reset savebed and remove teleports, so the prisoner can't escape */ 00139 SET_FLAG(exit_ob, FLAG_DAMNED); 00140 EXIT_X(exit_ob) = reg->jailx; 00141 EXIT_Y(exit_ob) = reg->jaily; 00142 return exit_ob; 00143 } 00144 else 00145 { 00146 reg = reg->parent; 00147 } 00148 } 00149 00150 LOG(llevDebug, "No suitable jailmap for region %s was found.\n", reg->name); 00151 return NULL; 00152 } 00153 00156 void init_regions() 00157 { 00158 FILE *fp; 00159 char filename[MAX_BUF]; 00160 int comp; 00161 region *new = NULL, *reg; 00162 char buf[HUGE_BUF * 4], msgbuf[HUGE_BUF], *key = NULL, *value, *end; 00163 int msgpos = 0; 00164 00165 /* Only do this once */ 00166 if (first_region) 00167 { 00168 return; 00169 } 00170 00171 snprintf(filename, sizeof(filename), "%s/regions.reg", settings.mapdir); 00172 LOG(llevDebug, "Reading regions from %s...\n", filename); 00173 00174 if ((fp = open_and_uncompress(filename, 0, &comp)) == NULL) 00175 { 00176 LOG(llevError, "init_regions(): Can't open regions file: %s.\n", filename); 00177 return; 00178 } 00179 00180 while (fgets(buf, sizeof(buf) - 1, fp)) 00181 { 00182 buf[sizeof(buf) - 1] = '\0'; 00183 key = buf; 00184 00185 while (isspace(*key)) 00186 { 00187 key++; 00188 } 00189 00190 /* Empty line or a comment */ 00191 if (*key == '\0' || *key == '#') 00192 { 00193 continue; 00194 } 00195 00196 value = strchr(key, ' '); 00197 00198 if (!value) 00199 { 00200 end = strchr(key, '\n'); 00201 *end = '\0'; 00202 } 00203 else 00204 { 00205 *value = '\0'; 00206 value++; 00207 00208 while (isspace(*value)) 00209 { 00210 value++; 00211 } 00212 00213 end = strchr(value, '\n'); 00214 } 00215 00216 if (!strcmp(key, "region")) 00217 { 00218 *end = '\0'; 00219 new = get_region_struct(); 00220 new->name = strdup_local(value); 00221 } 00222 else if (!strcmp(key, "parent")) 00223 { 00224 *end = '\0'; 00225 new->parent_name = strdup_local(value); 00226 } 00227 else if (!strcmp(key, "longname")) 00228 { 00229 *end = '\0'; 00230 new->longname = strdup_local(value); 00231 } 00232 else if (!strcmp(key, "map_first")) 00233 { 00234 *end = '\0'; 00235 new->map_first = strdup_local(value); 00236 } 00237 else if (!strcmp(key, "map_bg")) 00238 { 00239 *end = '\0'; 00240 new->map_bg = strdup_local(value); 00241 } 00242 /* Jail entries are of the form: /path/to/map x y */ 00243 else if (!strcmp(key, "jail")) 00244 { 00245 char path[MAX_BUF]; 00246 int x, y; 00247 00248 if (sscanf(value, "%[^ ] %d %d\n", path, &x, &y) != 3) 00249 { 00250 LOG(llevError, "init_regions(): Malformed regions entry: jail %s\n", value); 00251 continue; 00252 } 00253 00254 new->jailmap = strdup_local(path); 00255 new->jailx = x; 00256 new->jaily = y; 00257 } 00258 else if (!strcmp(key, "msg")) 00259 { 00260 while (fgets(buf, sizeof(buf) - 1, fp)) 00261 { 00262 if (!strcmp(buf, "endmsg\n")) 00263 { 00264 break; 00265 } 00266 00267 strcpy(msgbuf + msgpos, buf); 00268 msgpos += strlen(buf); 00269 } 00270 00271 if (msgpos != 0) 00272 { 00273 new->msg = strdup_local(msgbuf); 00274 } 00275 00276 /* we have to reset msgpos, or the next region will store both msg blocks. */ 00277 msgpos = 0; 00278 } 00279 else if (!strcmp(key, "end")) 00280 { 00281 /* Place this new region last on the list, if the list is empty put it first */ 00282 for (reg = first_region; reg != NULL && reg->next != NULL; reg = reg->next) 00283 { 00284 } 00285 00286 if (reg == NULL) 00287 { 00288 first_region = new; 00289 } 00290 else 00291 { 00292 reg->next = new; 00293 } 00294 00295 new = NULL; 00296 } 00297 else 00298 { 00299 /* We should never get here, if we have, then something is wrong */ 00300 LOG(llevError, "Got unknown value in region file: %s %s\n", key, value); 00301 } 00302 } 00303 00304 assign_region_parents(); 00305 LOG(llevDebug, " done\n"); 00306 00307 close_and_delete(fp, comp); 00308 } 00309 00313 static region *get_region_struct() 00314 { 00315 region *new = (region *) CALLOC(1, sizeof(region)); 00316 00317 if (new == NULL) 00318 { 00319 LOG(llevError, "get_region_struct(): Out of memory."); 00320 } 00321 00322 memset(new, 0, sizeof(region)); 00323 return new; 00324 } 00325 00328 static void assign_region_parents() 00329 { 00330 region *reg; 00331 uint32 parent_count = 0, region_count = 0; 00332 00333 for (reg = first_region; reg; reg = reg->next) 00334 { 00335 if (reg->parent_name) 00336 { 00337 reg->parent = get_region_by_name(reg->parent_name); 00338 parent_count++; 00339 } 00340 00341 region_count++; 00342 } 00343 00344 LOG(llevDebug, "Assigned %u regions with %u parents.\n", region_count, parent_count); 00345 } 00346 00349 void free_regions() 00350 { 00351 region *reg, *next; 00352 00353 LOG(llevDebug, "Freeing regions.\n"); 00354 00355 for (reg = first_region; reg; reg = next) 00356 { 00357 next = reg->next; 00358 00359 FREE_AND_NULL_PTR(reg->name); 00360 FREE_AND_NULL_PTR(reg->parent_name); 00361 FREE_AND_NULL_PTR(reg->longname); 00362 FREE_AND_NULL_PTR(reg->msg); 00363 FREE_AND_NULL_PTR(reg->jailmap); 00364 CFREE(reg); 00365 } 00366 }
1.7.4