--- deliantra/server/common/map.C 2006/08/27 16:15:11 1.9 +++ deliantra/server/common/map.C 2006/09/07 09:37:12 1.26 @@ -1,6 +1,6 @@ /* * static char *rcsid_map_c = - * "$Id: map.C,v 1.9 2006/08/27 16:15:11 root Exp $"; + * "$Id: map.C,v 1.26 2006/09/07 09:37:12 pippijn Exp $"; */ /* @@ -49,10 +49,10 @@ mapstruct *map; if (!name || !*name) - return 0; + return 0; for (map = first_map; map; map = map->next) - if (!strcmp (name, map->path)) - break; + if (!strcmp (name, map->path)) + break; return (map); } @@ -157,15 +157,15 @@ #ifndef WIN32 char *endbuf; struct stat statbuf; - int mode = 0, i; + int mode = 0; #endif if (prepend_dir) - strcpy (buf, create_pathname(name)); + strcpy (buf, create_pathname(name)); else - strcpy(buf, name); + strcpy(buf, name); #ifdef WIN32 /* ***win32: check this sucker in windows style. */ - return(_access(buf,0)); + return(_access(buf,0)); #else /* old method (strchr(buf, '\0')) seemd very odd to me - @@ -175,28 +175,20 @@ */ endbuf = buf + strlen(buf); - for (i = 0; i < NROF_COMPRESS_METHODS; i++) { - if (uncomp[i][0]) - strcpy(endbuf, uncomp[i][0]); - else - *endbuf = '\0'; - if (!stat (buf, &statbuf)) - break; - } - if (i == NROF_COMPRESS_METHODS) - return (-1); + if (stat (buf, &statbuf)) + return -1; if (!S_ISREG (statbuf.st_mode)) - return (-1); + return (-1); if (((statbuf.st_mode & S_IRGRP) && getegid() == statbuf.st_gid) || - ((statbuf.st_mode & S_IRUSR) && geteuid() == statbuf.st_uid) || - (statbuf.st_mode & S_IROTH)) - mode |= 4; + ((statbuf.st_mode & S_IRUSR) && geteuid() == statbuf.st_uid) || + (statbuf.st_mode & S_IROTH)) + mode |= 4; if ((statbuf.st_mode & S_IWGRP && getegid() == statbuf.st_gid) || - (statbuf.st_mode & S_IWUSR && geteuid() == statbuf.st_uid) || - (statbuf.st_mode & S_IWOTH)) - mode |= 2; + (statbuf.st_mode & S_IWUSR && geteuid() == statbuf.st_uid) || + (statbuf.st_mode & S_IWOTH)) + mode |= 2; return (mode); #endif @@ -211,17 +203,17 @@ void dump_map(const mapstruct *m) { LOG(llevError,"Map %s status: %d.\n",m->path,m->in_memory); LOG(llevError,"Size: %dx%d Start: %d,%d\n", - MAP_WIDTH(m), MAP_HEIGHT(m), - MAP_ENTER_X(m), MAP_ENTER_Y(m)); + MAP_WIDTH(m), MAP_HEIGHT(m), + MAP_ENTER_X(m), MAP_ENTER_Y(m)); if(m->msg!=NULL) - LOG(llevError,"Message:\n%s",m->msg); + LOG(llevError,"Message:\n%s",m->msg); if(m->maplore!=NULL) - LOG(llevError,"Lore:\n%s",m->maplore); + LOG(llevError,"Lore:\n%s",m->maplore); if(m->tmpname!=NULL) - LOG(llevError,"Tmpname: %s\n",m->tmpname); + LOG(llevError,"Tmpname: %s\n",m->tmpname); LOG(llevError,"Difficulty: %d\n",m->difficulty); LOG(llevError,"Darkness: %d\n",m->darkness); @@ -236,7 +228,7 @@ void dump_all_maps(void) { mapstruct *m; for(m=first_map;m!=NULL;m=m->next) { - dump_map(m); + dump_map(m); } } @@ -261,7 +253,7 @@ newy = y; mp = get_map_from_coord(oldmap, &newx, &newy); if (mp != oldmap) - retval |= P_NEW_MAP; + retval |= P_NEW_MAP; if (newmap) *newmap = mp; if (nx) *nx = newx; if (ny) *ny = newy; @@ -295,8 +287,8 @@ * have already checked this. */ if (OUT_OF_REAL_MAP(m, sx, sy)) { - LOG(llevError,"blocked_link: Passed map, x, y coordinates outside of map\n"); - return 1; + LOG(llevError,"blocked_link: Passed map, x, y coordinates outside of map\n"); + return 1; } /* Save some cycles - instead of calling get_map_flags(), just get the value @@ -322,7 +314,7 @@ if (!(mflags & P_IS_ALIVE) && !OB_TYPE_MOVE_BLOCK(ob, blocked)) return 0; if(ob->head != NULL) - ob=ob->head; + ob=ob->head; /* We basically go through the stack of objects, and if there is * some other object that has NO_PASS or FLAG_ALIVE set, return @@ -331,39 +323,39 @@ */ for(tmp = GET_MAP_OB(m,sx,sy); tmp!= NULL; tmp = tmp->above) { - /* This must be before the checks below. Code for inventory checkers. */ - if (tmp->type==CHECK_INV && OB_MOVE_BLOCK(ob, tmp)) { - /* If last_sp is set, the player/monster needs an object, - * so we check for it. If they don't have it, they can't - * pass through this space. - */ - if (tmp->last_sp) { - if (check_inv_recursive(ob,tmp)==NULL) - return 1; - else - continue; - } else { - /* In this case, the player must not have the object - - * if they do, they can't pass through. - */ - if (check_inv_recursive(ob,tmp)!=NULL) /* player has object */ - return 1; - else - continue; - } - } /* if check_inv */ - else { - /* Broke apart a big nasty if into several here to make - * this more readable. first check - if the space blocks - * movement, can't move here. - * second - if a monster, can't move there, unles it is a - * hidden dm - */ - if (OB_MOVE_BLOCK(ob, tmp)) return 1; - if (QUERY_FLAG(tmp,FLAG_ALIVE) && tmp->head != ob && tmp != ob && - tmp->type != DOOR && !(QUERY_FLAG(tmp,FLAG_WIZ) && tmp->contr->hidden)) - return 1; - } + /* This must be before the checks below. Code for inventory checkers. */ + if (tmp->type==CHECK_INV && OB_MOVE_BLOCK(ob, tmp)) { + /* If last_sp is set, the player/monster needs an object, + * so we check for it. If they don't have it, they can't + * pass through this space. + */ + if (tmp->last_sp) { + if (check_inv_recursive(ob,tmp)==NULL) + return 1; + else + continue; + } else { + /* In this case, the player must not have the object - + * if they do, they can't pass through. + */ + if (check_inv_recursive(ob,tmp)!=NULL) /* player has object */ + return 1; + else + continue; + } + } /* if check_inv */ + else { + /* Broke apart a big nasty if into several here to make + * this more readable. first check - if the space blocks + * movement, can't move here. + * second - if a monster, can't move there, unles it is a + * hidden dm + */ + if (OB_MOVE_BLOCK(ob, tmp)) return 1; + if (QUERY_FLAG(tmp,FLAG_ALIVE) && tmp->head != ob && tmp != ob && + tmp->type != DOOR && !(QUERY_FLAG(tmp,FLAG_WIZ) && tmp->contr->hidden)) + return 1; + } } return 0; @@ -404,31 +396,31 @@ sint16 sx, sy; if(ob==NULL) { - flag= get_map_flags(m,&m1, x,y, &sx, &sy); - if (flag & P_OUT_OF_MAP) return P_OUT_OF_MAP; + flag= get_map_flags(m,&m1, x,y, &sx, &sy); + if (flag & P_OUT_OF_MAP) return P_OUT_OF_MAP; - /* don't have object, so don't know what types would block */ - return(GET_MAP_MOVE_BLOCK(m1, sx, sy)); + /* don't have object, so don't know what types would block */ + return(GET_MAP_MOVE_BLOCK(m1, sx, sy)); } for(tmp=ob->arch; tmp!=NULL;tmp=tmp->more) { - flag = get_map_flags(m, &m1, x+tmp->clone.x,y+tmp->clone.y, &sx, &sy); + flag = get_map_flags(m, &m1, x+tmp->clone.x,y+tmp->clone.y, &sx, &sy); - if (flag & P_OUT_OF_MAP) return P_OUT_OF_MAP; - if (flag & P_IS_ALIVE) return P_IS_ALIVE; + if (flag & P_OUT_OF_MAP) return P_OUT_OF_MAP; + if (flag & P_IS_ALIVE) return P_IS_ALIVE; - /* find_first_free_spot() calls this function. However, often - * ob doesn't have any move type (when used to place exits) + /* find_first_free_spot() calls this function. However, often + * ob doesn't have any move type (when used to place exits) * so the AND operation in OB_TYPE_MOVE_BLOCK doesn't work. - */ + */ - if (ob->move_type == 0 && GET_MAP_MOVE_BLOCK(m1, sx, sy) != MOVE_ALL) continue; + if (ob->move_type == 0 && GET_MAP_MOVE_BLOCK(m1, sx, sy) != MOVE_ALL) continue; - /* Note it is intentional that we check ob - the movement type of the - * head of the object should correspond for the entire object. - */ - if (OB_TYPE_MOVE_BLOCK(ob, GET_MAP_MOVE_BLOCK(m1, sx, sy))) - return AB_NO_PASS; + /* Note it is intentional that we check ob - the movement type of the + * head of the object should correspond for the entire object. + */ + if (OB_TYPE_MOVE_BLOCK(ob, GET_MAP_MOVE_BLOCK(m1, sx, sy))) + return AB_NO_PASS; } return 0; @@ -447,11 +439,11 @@ container->inv=NULL; while (tmp!=NULL) { - next = tmp->below; - if (tmp->inv) - fix_container(tmp); - (void) insert_ob_in_ob(tmp,container); - tmp = next; + next = tmp->below; + if (tmp->inv) + fix_container(tmp); + (void) insert_ob_in_ob(tmp,container); + tmp = next; } /* sum_weight will go through and calculate what all the containers are * carrying. @@ -470,119 +462,123 @@ { int x,y; object *tmp, *op, *last, *above; - archetype *at; + archetype *at; for(x=0;xabove; - - /* already multipart - don't do anything more */ - if (tmp->head || tmp->more) continue; - - /* If there is nothing more to this object, this for loop - * won't do anything. - */ - for (at = tmp->arch->more, last=tmp; at != NULL; at=at->more, last=op) { - op = arch_to_object(at); - - /* update x,y coordinates */ - op->x += tmp->x; - op->y += tmp->y; - op->head = tmp; - op->map = m; - last->more = op; - if (tmp->name != op->name) { - if (op->name) free_string(op->name); - op->name = add_string(tmp->name); - } - if (tmp->title != op->title) { - if (op->title) free_string(op->title); - op->title = add_string(tmp->title); - } - /* we could link all the parts onto tmp, and then just - * call insert_ob_in_map once, but the effect is the same, - * as insert_ob_in_map will call itself with each part, and - * the coding is simpler to just to it here with each part. - */ - insert_ob_in_map(op, op->map, tmp,INS_NO_MERGE|INS_ABOVE_FLOOR_ONLY|INS_NO_WALK_ON); - } /* for at = tmp->arch->more */ - } /* for objects on this space */ + for(y=0;yabove; + + /* already multipart - don't do anything more */ + if (tmp->head || tmp->more) continue; + + /* If there is nothing more to this object, this for loop + * won't do anything. + */ + for (at = tmp->arch->more, last=tmp; at != NULL; at=at->more, last=op) { + op = arch_to_object(at); + + /* update x,y coordinates */ + op->x += tmp->x; + op->y += tmp->y; + op->head = tmp; + op->map = m; + last->more = op; + op->name = tmp->name; + op->title = tmp->title; + /* we could link all the parts onto tmp, and then just + * call insert_ob_in_map once, but the effect is the same, + * as insert_ob_in_map will call itself with each part, and + * the coding is simpler to just to it here with each part. + */ + insert_ob_in_map(op, op->map, tmp,INS_NO_MERGE|INS_ABOVE_FLOOR_ONLY|INS_NO_WALK_ON); + } /* for at = tmp->arch->more */ + } /* for objects on this space */ } - - - + /* * Loads (ands parses) the objects into a given map from the specified * file pointer. * mapflags is the same as we get with load_original_map */ +void +load_objects (mapstruct *m, object_thawer &fp, int mapflags) +{ + int i, j; + int unique; + object *op, *prev = NULL, *last_more = NULL, *otmp; + + op = get_object (); + op->map = m; /* To handle buttons correctly */ + + while ((i = load_object (fp, op, mapflags))) + { + /* if the archetype for the object is null, means that we + * got an invalid object. Don't do anything with it - the game + * or editor will not be able to do anything with it either. + */ + if (op->arch == NULL) + { + LOG (llevDebug, "Discarding object without arch: %s\n", + op->name ? (const char *) op->name : "(null)"); + continue; + } + + + switch (i) + { + case LL_NORMAL: + /* if we are loading an overlay, put the floors on the bottom */ + if ((QUERY_FLAG (op, FLAG_IS_FLOOR) || + QUERY_FLAG (op, FLAG_OVERLAY_FLOOR)) && mapflags & MAP_OVERLAY) + insert_ob_in_map (op, m, op, + INS_NO_MERGE | INS_NO_WALK_ON | + INS_ABOVE_FLOOR_ONLY | INS_MAP_LOAD); + else + insert_ob_in_map (op, m, op, + INS_NO_MERGE | INS_NO_WALK_ON | INS_ON_TOP | + INS_MAP_LOAD); + + if (op->inv) + sum_weight (op); + + prev = op, last_more = op; + break; + + case LL_MORE: + insert_ob_in_map (op, m, op, + INS_NO_MERGE | INS_NO_WALK_ON | + INS_ABOVE_FLOOR_ONLY); + op->head = prev, last_more->more = op, last_more = op; + break; + } -void load_objects (mapstruct *m, FILE *fp, object_thawer &thawer, int mapflags) { - int i,j,bufstate=LO_NEWFILE; - int unique; - object *op, *prev=NULL,*last_more=NULL, *otmp; - - op=get_object(); - op->map = m; /* To handle buttons correctly */ - - while((i = load_object (fp, thawer, op, bufstate, mapflags))) { - /* Since the loading of the map header does not load an object - * anymore, we need to pass LO_NEWFILE for the first object loaded, - * and then switch to LO_REPEAT for faster loading. - */ - bufstate = LO_REPEAT; - - /* if the archetype for the object is null, means that we - * got an invalid object. Don't do anything with it - the game - * or editor will not be able to do anything with it either. - */ - if (op->arch==NULL) { - LOG(llevDebug,"Discarding object without arch: %s\n", op->name?op->name:"(null)"); - continue; - } - - - switch(i) { - case LL_NORMAL: - /* if we are loading an overlay, put the floors on the bottom */ - if ((QUERY_FLAG(op, FLAG_IS_FLOOR) || - QUERY_FLAG(op, FLAG_OVERLAY_FLOOR)) && mapflags & MAP_OVERLAY) - insert_ob_in_map(op,m,op,INS_NO_MERGE | INS_NO_WALK_ON | INS_ABOVE_FLOOR_ONLY | INS_MAP_LOAD); - else - insert_ob_in_map(op,m,op,INS_NO_MERGE | INS_NO_WALK_ON | INS_ON_TOP | INS_MAP_LOAD); - - if (op->inv) - sum_weight(op); - - prev=op,last_more=op; - break; - - case LL_MORE: - insert_ob_in_map(op,m, op, INS_NO_MERGE | INS_NO_WALK_ON | INS_ABOVE_FLOOR_ONLY); - op->head=prev,last_more->more=op,last_more=op; - break; - } - if (mapflags & MAP_STYLE) { - remove_from_active_list(op); - } - op=get_object(); - op->map = m; - } - for (i=0;iwidth;i++){ - for (j=0;jheight;j++){ - unique =0; - /* check for unique items, or unique squares */ - for (otmp = get_map_ob(m, i, j); otmp; otmp = otmp->above) { - if (QUERY_FLAG(otmp, FLAG_UNIQUE) || QUERY_FLAG(otmp, FLAG_OBJ_SAVE_ON_OVL)) - unique = 1; - if (!(mapflags & (MAP_OVERLAY|MAP_PLAYER_UNIQUE) || unique)) - SET_FLAG(otmp, FLAG_OBJ_ORIGINAL); - } - } + if (mapflags & MAP_STYLE) + remove_from_active_list (op); + + op = get_object (); + op->map = m; } - free_object(op); - link_multipart_objects(m); + + for (i = 0; i < m->width; i++) + { + for (j = 0; j < m->height; j++) + { + unique = 0; + /* check for unique items, or unique squares */ + for (otmp = get_map_ob (m, i, j); otmp; otmp = otmp->above) + { + if (QUERY_FLAG (otmp, FLAG_UNIQUE) + || QUERY_FLAG (otmp, FLAG_OBJ_SAVE_ON_OVL)) + unique = 1; + if (!(mapflags & (MAP_OVERLAY | MAP_PLAYER_UNIQUE) || unique)) + SET_FLAG (otmp, FLAG_OBJ_ORIGINAL); + } + } + } + + free_object (op); + link_multipart_objects (m); } /* This saves all the objects on the map in a non destructive fashion. @@ -590,35 +586,35 @@ * and we only save the head of multi part objects - this is needed * in order to do map tiling properly. */ -void save_objects (mapstruct *m, FILE *fp, object_freezer &freezer, FILE *fp2, object_freezer &freezer2, int flag) { +void save_objects (mapstruct *m, object_freezer &fp, object_freezer &fp2, int flag) { int i, j = 0,unique=0; object *op; /* first pass - save one-part objects */ for(i = 0; i < MAP_WIDTH(m); i++) - for (j = 0; j < MAP_HEIGHT(m); j++) { - unique=0; - for(op = get_map_ob (m, i, j); op; op = op->above) { - if (QUERY_FLAG(op,FLAG_IS_FLOOR) && QUERY_FLAG(op, FLAG_UNIQUE)) - unique=1; - - if(op->type == PLAYER) { - LOG(llevDebug, "Player on map that is being saved\n"); - continue; - } - - if (op->head || op->owner) - continue; - - if (unique || QUERY_FLAG(op, FLAG_UNIQUE)) - save_object( fp2 , freezer2, op, 3); - else - if (flag == 0 || - (flag == 2 && (!QUERY_FLAG(op, FLAG_OBJ_ORIGINAL) && - !QUERY_FLAG(op, FLAG_UNPAID)))) - save_object(fp, freezer, op, 3); + for (j = 0; j < MAP_HEIGHT(m); j++) { + unique=0; + for(op = get_map_ob (m, i, j); op; op = op->above) { + if (QUERY_FLAG(op,FLAG_IS_FLOOR) && QUERY_FLAG(op, FLAG_UNIQUE)) + unique=1; + + if(op->type == PLAYER) { + LOG(llevDebug, "Player on map that is being saved\n"); + continue; + } + + if (op->head || op->owner) + continue; + + if (unique || QUERY_FLAG(op, FLAG_UNIQUE)) + save_object (fp2, op, 3); + else + if (flag == 0 || + (flag == 2 && (!QUERY_FLAG(op, FLAG_OBJ_ORIGINAL) && + !QUERY_FLAG(op, FLAG_UNPAID)))) + save_object(fp, op, 3); - } /* for this space */ - } /* for this j */ + } /* for this space */ + } /* for this j */ } /* @@ -628,17 +624,14 @@ */ mapstruct *get_linked_map(void) { - mapstruct *map=(mapstruct *) calloc(1,sizeof(mapstruct)); + mapstruct *map = new mapstruct; mapstruct *mp; - if(map==NULL) - fatal(OUT_OF_MEMORY); - for(mp=first_map;mp!=NULL&&mp->next!=NULL;mp=mp->next); if(mp==NULL) - first_map=map; + first_map=map; else - mp->next=map; + mp->next=map; map->in_memory=MAP_SWAPPED; /* The maps used to pick up default x and y values from the @@ -650,9 +643,9 @@ MAP_TIMEOUT(map)=300; MAP_ENTER_X(map)=0; MAP_ENTER_Y(map)=0; - /*set part to -1 indicating conversion to weather map not yet done*/ - MAP_WORLDPARTX(map)=-1; - MAP_WORLDPARTY(map)=-1; + /*set part to -1 indicating conversion to weather map not yet done*/ + MAP_WORLDPARTX(map)=-1; + MAP_WORLDPARTY(map)=-1; return map; } @@ -669,14 +662,14 @@ * that is their poor assumption. */ if (m->spaces) { - LOG(llevError,"allocate_map called with already allocated map (%s)\n", m->path); - free(m->spaces); + LOG(llevError,"allocate_map called with already allocated map (%s)\n", m->path); + free(m->spaces); } m->spaces = (MapSpace *) calloc(1, MAP_WIDTH(m) * MAP_HEIGHT(m) * sizeof(MapSpace)); if(m->spaces==NULL) - fatal(OUT_OF_MEMORY); + fatal(OUT_OF_MEMORY); } /* Create and returns a map of the specific size. Used @@ -707,53 +700,53 @@ p=shop_string; /* first we'll count the entries, we'll need that for allocating the array shortly */ while (p) { - p=strchr(p, ';'); - number_of_entries++; - if (p) p++; + p=strchr(p, ';'); + number_of_entries++; + if (p) p++; } p=shop_string; strip_endline(p); items=(shopitems *) CALLOC(number_of_entries+1, sizeof(shopitems)); memset(items, 0, (sizeof(shopitems) * number_of_entries+1)); for (i=0; iname; - items[i].name_pl=current_type->name_pl; - } - } - else { /*we have a named type, let's figure out what it is */ - q=strpbrk(p,";:"); - if (q) *q='\0'; - - current_type=get_typedata_by_name(p); - if (current_type) { - items[i].name=current_type->name; - items[i].typenum=current_type->number; - items[i].name_pl=current_type->name_pl; - } - else { /* oh uh, something's wrong, let's free up this one, and try - * the next entry while we're at it, better print a warning - */ - LOG(llevError, "invalid type %s defined in shopitems in string %s\n", - p, input_string); - } - } - items[i].index=number_of_entries; - if (next_semicolon) p=++next_semicolon; - else p=NULL; + if (!p) { + LOG(llevError, "parse_shop_string: I seem to have run out of string, that shouldn't happen.\n"); + break; + } + next_semicolon=strchr(p, ';'); + next_colon=strchr(p, ':'); + /* if there is a stregth specified, figure out what it is, we'll need it soon. */ + if (next_colon &&( !next_semicolon || next_colonname; + items[i].name_pl=current_type->name_pl; + } + } + else { /*we have a named type, let's figure out what it is */ + q=strpbrk(p,";:"); + if (q) *q='\0'; + + current_type=get_typedata_by_name(p); + if (current_type) { + items[i].name=current_type->name; + items[i].typenum=current_type->number; + items[i].name_pl=current_type->name_pl; + } + else { /* oh uh, something's wrong, let's free up this one, and try + * the next entry while we're at it, better print a warning + */ + LOG(llevError, "invalid type %s defined in shopitems in string %s\n", + p, input_string); + } + } + items[i].index=number_of_entries; + if (next_semicolon) p=++next_semicolon; + else p=NULL; } free(shop_string); return items; @@ -766,19 +759,19 @@ char tmp[MAX_BUF]; strcpy(output_string, ""); for (i=0; i< m->shopitems[0].index; i++) { - if (m->shopitems[i].typenum) { - if (m->shopitems[i].strength) { - sprintf(tmp, "%s:%d;", m->shopitems[i].name, m->shopitems[i].strength); - } - else sprintf(tmp, "%s;", m->shopitems[i].name); - } - else { - if (m->shopitems[i].strength) { - sprintf(tmp, "*:%d;", m->shopitems[i].strength); - } - else sprintf(tmp, "*"); - } - strcat(output_string, tmp); + if (m->shopitems[i].typenum) { + if (m->shopitems[i].strength) { + sprintf(tmp, "%s:%d;", m->shopitems[i].name, m->shopitems[i].strength); + } + else sprintf(tmp, "%s;", m->shopitems[i].name); + } + else { + if (m->shopitems[i].strength) { + sprintf(tmp, "*:%d;", m->shopitems[i].strength); + } + else sprintf(tmp, "*"); + } + strcat(output_string, tmp); } } @@ -795,209 +788,211 @@ * return 0 on success, 1 on failure. */ -static int load_map_header(FILE *fp, mapstruct *m) +static int load_map_header(object_thawer &fp, mapstruct *m) { char buf[HUGE_BUF], msgbuf[HUGE_BUF], maplorebuf[HUGE_BUF], *key=NULL, *value, *end; int msgpos=0; int maplorepos=0; while (fgets(buf, HUGE_BUF-1, fp)!=NULL) { - buf[HUGE_BUF-1] = 0; - key = buf; - while (isspace(*key)) key++; - if (*key == 0) continue; /* empty line */ - value = strchr(key, ' '); - if (!value) { - end = strchr(key, '\n'); - if (end != NULL) { - *end = 0; - } - } else { - *value = 0; - value++; - end = strchr(value, '\n'); - while (isspace(*value)) { - value++; - if (*value == '\0' || value == end) { - /* Nothing but spaces. */ - value = NULL; - break; - } - } - } - if (!end) { - LOG(llevError, "Error loading map header - did not find a newline - perhaps file is truncated? Buf=%s\n", - buf); - return 1; - } - - - /* key is the field name, value is what it should be set - * to. We've already done the work to null terminate key, - * and strip off any leading spaces for both of these. - * We have not touched the newline at the end of the line - - * these are needed for some values. the end pointer - * points to the first of the newlines. - * value could be NULL! It would be easy enough to just point - * this to "" to prevent cores, but that would let more errors slide - * through. - * - * First check for entries that do not use the value parameter, then - * validate that value is given and check for the remaining entries - * that use the parameter. - */ - - if (!strcmp(key,"msg")) { - while (fgets(buf, HUGE_BUF-1, fp)!=NULL) { - if (!strcmp(buf,"endmsg\n")) break; - else { - /* slightly more efficient than strcat */ - strcpy(msgbuf+msgpos, buf); - msgpos += strlen(buf); - } - } - /* There are lots of maps that have empty messages (eg, msg/endmsg - * with nothing between). There is no reason in those cases to + buf[HUGE_BUF-1] = 0; + key = buf; + while (isspace(*key)) key++; + if (*key == 0) continue; /* empty line */ + value = strchr(key, ' '); + if (!value) { + end = strchr(key, '\n'); + if (end != NULL) { + *end = 0; + } + } else { + *value = 0; + value++; + end = strchr(value, '\n'); + while (isspace(*value)) { + value++; + if (*value == '\0' || value == end) { + /* Nothing but spaces. */ + value = NULL; + break; + } + } + } + + if (!end) { + LOG(llevError, "Error loading map header - did not find a newline - perhaps file is truncated? Buf=%s\n", + buf); + return 1; + } + + /* key is the field name, value is what it should be set + * to. We've already done the work to null terminate key, + * and strip off any leading spaces for both of these. + * We have not touched the newline at the end of the line - + * these are needed for some values. the end pointer + * points to the first of the newlines. + * value could be NULL! It would be easy enough to just point + * this to "" to prevent cores, but that would let more errors slide + * through. + * + * First check for entries that do not use the value parameter, then + * validate that value is given and check for the remaining entries + * that use the parameter. + */ + + if (!strcmp(key,"msg")) { + while (fgets(buf, HUGE_BUF-1, fp)!=NULL) { + if (!strcmp(buf,"endmsg\n")) break; + else { + /* slightly more efficient than strcat */ + strcpy(msgbuf+msgpos, buf); + msgpos += strlen(buf); + } + } + /* There are lots of maps that have empty messages (eg, msg/endmsg + * with nothing between). There is no reason in those cases to * keep the empty message. Also, msgbuf contains garbage data - * when msgpos is zero, so copying it results in crashes - */ - if (msgpos != 0) - m->msg = strdup_local(msgbuf); - } - else if (!strcmp(key,"maplore")) { - while (fgets(buf, HUGE_BUF-1, fp)!=NULL) { - if (!strcmp(buf,"endmaplore\n")) break; - else { - /* slightly more efficient than strcat */ - strcpy(maplorebuf+maplorepos, buf); - maplorepos += strlen(buf); - } - } - if (maplorepos != 0) - m->maplore = strdup_local(maplorebuf); - } - else if (!strcmp(key,"end")) { - break; - } - else if (value == NULL) { - LOG(llevError, "Got '%s' line without parameter in map header\n", key); - } - else if (!strcmp(key, "arch")) { - /* This is an oddity, but not something we care about much. */ - if (strcmp(value,"map\n")) - LOG(llevError,"loading map and got a non 'arch map' line(%s %s)?\n",key,value); - } - else if (!strcmp(key,"name")) { - *end=0; - m->name = strdup_local(value); - } - /* first strcmp value on these are old names supported - * for compatibility reasons. The new values (second) are - * what really should be used. - */ - else if (!strcmp(key,"hp") || !strcmp(key, "enter_x")) { - m->enter_x = atoi(value); - } else if (!strcmp(key,"sp") || !strcmp(key, "enter_y")) { - m->enter_y = atoi(value); - } else if (!strcmp(key,"x") || !strcmp(key, "width")) { - m->width = atoi(value); - } else if (!strcmp(key,"y") || !strcmp(key, "height")) { - m->height = atoi(value); - } else if (!strcmp(key,"weight") || !strcmp(key, "reset_timeout")) { - m->reset_timeout = atoi(value); - } else if (!strcmp(key,"value") || !strcmp(key, "swap_time")) { - m->timeout = atoi(value); - } else if (!strcmp(key,"level") || !strcmp(key, "difficulty")) { - m->difficulty = atoi(value); - } else if (!strcmp(key,"invisible") || !strcmp(key, "darkness")) { - m->darkness = atoi(value); - } else if (!strcmp(key,"stand_still") || !strcmp(key, "fixed_resettime")) { - m->fixed_resettime = atoi(value); - } else if (!strcmp(key,"unique")) { - m->unique = atoi(value); - } else if (!strcmp(key,"template")) { - m->templatemap = atoi(value); - } else if (!strcmp(key,"region")) { - m->region = get_region_by_name(value); - } else if (!strcmp(key,"shopitems")) { - *end=0; - m->shopitems = parse_shop_string(value); - } else if (!strcmp(key,"shopgreed")) { - m->shopgreed = atof(value); - } else if (!strcmp(key,"shopmin")) { - m->shopmin = atol(value); - } else if (!strcmp(key,"shopmax")) { - m->shopmax = atol(value); - } else if (!strcmp(key,"shoprace")) { - *end=0; - m->shoprace = strdup_local(value); - } else if (!strcmp(key,"outdoor")) { - m->outdoor = atoi(value); - } else if (!strcmp(key, "temp")) { - m->temp = atoi(value); - } else if (!strcmp(key, "pressure")) { - m->pressure = atoi(value); - } else if (!strcmp(key, "humid")) { - m->humid = atoi(value); - } else if (!strcmp(key, "windspeed")) { - m->windspeed = atoi(value); - } else if (!strcmp(key, "winddir")) { - m->winddir = atoi(value); - } else if (!strcmp(key, "sky")) { - m->sky = atoi(value); - } else if (!strcmp(key, "nosmooth")) { - m->nosmooth = atoi(value); - } else if (!strcmp(key, "safe_map")) { - m->safe_map = atoi(value); - } - else if (!strncmp(key,"tile_path_", 10)) { - int tile=atoi(key+10); - - if (tile<1 || tile>4) { - LOG(llevError,"load_map_header: tile location %d out of bounds (%s)\n", - tile, m->path); - } else { - char *path; - - *end = 0; - - if (m->tile_path[tile-1]) { - LOG(llevError,"load_map_header: tile location %d duplicated (%s)\n", - tile, m->path); - free(m->tile_path[tile-1]); - m->tile_path[tile-1] = NULL; - } - - if (check_path(value, 1) != -1) { - /* The unadorned path works. */ - path = value; - } else { - /* Try again; it could be a relative exit. */ + * when msgpos is zero, so copying it results in crashes + */ + if (msgpos != 0) + m->msg = strdup_local(msgbuf); + } + else if (!strcmp(key,"maplore")) { + while (fgets(buf, HUGE_BUF-1, fp)!=NULL) { + if (!strcmp(buf,"endmaplore\n")) break; + else { + /* slightly more efficient than strcat */ + strcpy(maplorebuf+maplorepos, buf); + maplorepos += strlen(buf); + } + } + if (maplorepos != 0) + m->maplore = strdup_local(maplorebuf); + } + else if (!strcmp(key,"end")) { + break; + } + else if (value == NULL) { + LOG(llevError, "Got '%s' line without parameter in map header\n", key); + } + else if (!strcmp(key, "arch")) { + /* This is an oddity, but not something we care about much. */ + if (strcmp(value,"map\n")) + LOG(llevError,"loading map and got a non 'arch map' line(%s %s)?\n",key,value); + } + else if (!strcmp(key,"name")) { + *end=0; + m->name = strdup_local(value); + } + /* first strcmp value on these are old names supported + * for compatibility reasons. The new values (second) are + * what really should be used. + */ + else if (!strcmp(key,"oid")) { + fp.get (m, atoi(value)); + } else if (!strcmp(key, "attach")) { + m->attach = value; + } else if (!strcmp(key,"hp") || !strcmp(key, "enter_x")) { + m->enter_x = atoi(value); + } else if (!strcmp(key,"sp") || !strcmp(key, "enter_y")) { + m->enter_y = atoi(value); + } else if (!strcmp(key,"x") || !strcmp(key, "width")) { + m->width = atoi(value); + } else if (!strcmp(key,"y") || !strcmp(key, "height")) { + m->height = atoi(value); + } else if (!strcmp(key,"weight") || !strcmp(key, "reset_timeout")) { + m->reset_timeout = atoi(value); + } else if (!strcmp(key,"value") || !strcmp(key, "swap_time")) { + m->timeout = atoi(value); + } else if (!strcmp(key,"level") || !strcmp(key, "difficulty")) { + m->difficulty = atoi(value); + } else if (!strcmp(key,"invisible") || !strcmp(key, "darkness")) { + m->darkness = atoi(value); + } else if (!strcmp(key,"stand_still") || !strcmp(key, "fixed_resettime")) { + m->fixed_resettime = atoi(value); + } else if (!strcmp(key,"unique")) { + m->unique = atoi(value); + } else if (!strcmp(key,"template")) { + m->templatemap = atoi(value); + } else if (!strcmp(key,"region")) { + m->region = get_region_by_name(value); + } else if (!strcmp(key,"shopitems")) { + *end=0; + m->shopitems = parse_shop_string(value); + } else if (!strcmp(key,"shopgreed")) { + m->shopgreed = atof(value); + } else if (!strcmp(key,"shopmin")) { + m->shopmin = atol(value); + } else if (!strcmp(key,"shopmax")) { + m->shopmax = atol(value); + } else if (!strcmp(key,"shoprace")) { + *end=0; + m->shoprace = strdup_local(value); + } else if (!strcmp(key,"outdoor")) { + m->outdoor = atoi(value); + } else if (!strcmp(key, "temp")) { + m->temp = atoi(value); + } else if (!strcmp(key, "pressure")) { + m->pressure = atoi(value); + } else if (!strcmp(key, "humid")) { + m->humid = atoi(value); + } else if (!strcmp(key, "windspeed")) { + m->windspeed = atoi(value); + } else if (!strcmp(key, "winddir")) { + m->winddir = atoi(value); + } else if (!strcmp(key, "sky")) { + m->sky = atoi(value); + } else if (!strcmp(key, "nosmooth")) { + m->nosmooth = atoi(value); + } + else if (!strncmp(key,"tile_path_", 10)) { + int tile=atoi(key+10); - path = path_combine_and_normalize(m->path, value); + if (tile<1 || tile>4) { + LOG(llevError,"load_map_header: tile location %d out of bounds (%s)\n", + tile, m->path); + } else { + char *path; + + *end = 0; + + if (m->tile_path[tile-1]) { + LOG(llevError,"load_map_header: tile location %d duplicated (%s)\n", + tile, m->path); + free(m->tile_path[tile-1]); + m->tile_path[tile-1] = NULL; + } + + if (check_path(value, 1) != -1) { + /* The unadorned path works. */ + path = value; + } else { + /* Try again; it could be a relative exit. */ + + path = path_combine_and_normalize(m->path, value); if (check_path(path, 1) == -1) { LOG(llevError, "get_map_header: Bad tile path %s %s\n", m->path, value); path = NULL; - } - } + } + } - if (editor) { - /* Use the value as in the file. */ - m->tile_path[tile-1] = strdup_local(value); - } else if (path != NULL) { - /* Use the normalized value. */ - m->tile_path[tile-1] = strdup_local(path); - } - } /* end if tile direction (in)valid */ - } - else { - LOG(llevError,"Got unknown value in map header: %s %s\n", key, value); - } + if (editor) { + /* Use the value as in the file. */ + m->tile_path[tile-1] = strdup_local(value); + } else if (path != NULL) { + /* Use the normalized value. */ + m->tile_path[tile-1] = strdup_local(path); + } + } /* end if tile direction (in)valid */ + } + else { + LOG(llevError,"Got unknown value in map header: %s %s\n", key, value); + } } if (!key || strcmp(key,"end")) { - LOG(llevError,"Got premature eof on map header!\n"); - return 1; + LOG(llevError,"Got premature eof on map header!\n"); + return 1; } return 0; } @@ -1011,51 +1006,47 @@ * MAP_BLOCK, in which case we block on this load. This happens in all * cases, no matter if this flag is set or not. * MAP_STYLE: style map - don't add active objects, don't add to server - * managed map list. + * managed map list. */ mapstruct *load_original_map(const char *filename, int flags) { - FILE *fp; mapstruct *m; - int comp; char pathname[MAX_BUF]; - LOG(llevDebug, "load_original_map: %s (%x)\n", filename,flags); if (flags & MAP_PLAYER_UNIQUE) - strcpy(pathname, filename); + strcpy(pathname, filename); else if (flags & MAP_OVERLAY) - strcpy(pathname, create_overlay_pathname(filename)); + strcpy(pathname, create_overlay_pathname(filename)); else - strcpy(pathname, create_pathname(filename)); + strcpy(pathname, create_pathname(filename)); - if((fp=open_and_uncompress(pathname, 0, &comp))==NULL) { - LOG(llevError, "Can't open %s: %s\n", pathname, strerror_local(errno)); - return (NULL); - } + LOG(llevDebug, "load_original_map(%x): %s (%s)\n", flags, filename, pathname); - object_thawer thawer (filename); + object_thawer thawer (pathname); + + if (!thawer) + return 0; m = get_linked_map(); strcpy (m->path, filename); - if (load_map_header(fp, m)) { - LOG(llevError,"Error loading map header for %s, flags=%d\n", - filename, flags); - delete_map(m); - return NULL; + if (load_map_header(thawer, m)) { + LOG(llevError,"Error loading map header for %s, flags=%d\n", + filename, flags); + delete_map(m); + return NULL; } allocate_map(m); - m->compressed = comp; m->in_memory=MAP_LOADING; - load_objects (m, fp, thawer, flags & (MAP_BLOCK|MAP_STYLE)); - close_and_delete(fp, comp); + load_objects (m, thawer, flags & (MAP_BLOCK|MAP_STYLE)); + m->in_memory=MAP_IN_MEMORY; if (!MAP_DIFFICULTY(m)) - MAP_DIFFICULTY(m)=calculate_difficulty(m); + MAP_DIFFICULTY(m)=calculate_difficulty(m); set_map_reset_time(m); - INVOKE_MAP (LOAD, m); + m->instantiate (); return (m); } @@ -1066,45 +1057,42 @@ */ static mapstruct *load_temporary_map(mapstruct *m) { - FILE *fp; - int comp; char buf[MAX_BUF]; if (!m->tmpname) { - LOG(llevError, "No temporary filename for map %s\n", m->path); - strcpy(buf, m->path); - delete_map(m); + LOG(llevError, "No temporary filename for map %s\n", m->path); + strcpy(buf, m->path); + delete_map(m); m = load_original_map(buf, 0); - if(m==NULL) return NULL; - fix_auto_apply(m); /* Chests which open as default */ - return m; - } - - if((fp=open_and_uncompress(m->tmpname,0, &comp))==NULL) { - LOG(llevError, "Cannot open %s: %s\n",m->tmpname, strerror_local(errno)); - strcpy(buf, m->path); - delete_map(m); - m = load_original_map(buf, 0); - if(m==NULL) return NULL; - fix_auto_apply(m); /* Chests which open as default */ - return m; + if(m==NULL) return NULL; + fix_auto_apply(m); /* Chests which open as default */ + return m; } object_thawer thawer (m->tmpname); - if (load_map_header(fp, m)) { - LOG(llevError,"Error loading map header for %s (%s)\n", - m->path, m->tmpname); - delete_map(m); + if (!thawer) + { + strcpy (buf, m->path); + delete_map (m); + m = load_original_map (buf, 0); + if (!m) return NULL; + fix_auto_apply (m); /* Chests which open as default */ + return m; + } + + if (load_map_header(thawer, m)) { + LOG(llevError,"Error loading map header for %s (%s)\n", + m->path, m->tmpname); + delete_map(m); m = load_original_map(m->path, 0); - return NULL; + return NULL; } - m->compressed = comp; allocate_map(m); m->in_memory=MAP_LOADING; - load_objects (m, fp, thawer, 0); - close_and_delete(fp, comp); + load_objects (m, thawer, 0); + m->in_memory=MAP_IN_MEMORY; INVOKE_MAP (SWAPIN, m); return m; @@ -1117,32 +1105,27 @@ */ mapstruct *load_overlay_map(const char *filename, mapstruct *m) { - FILE *fp; - int comp; char pathname[MAX_BUF]; strcpy(pathname, create_overlay_pathname(filename)); - if((fp=open_and_uncompress(pathname, 0, &comp))==NULL) { -/* LOG(llevDebug,"Can't open overlay %s\n", pathname);*/ - return m; - } - object_thawer thawer (pathname); + + if (!thawer) + return m; - if (load_map_header(fp, m)) { - LOG(llevError,"Error loading map header for overlay %s (%s)\n", - m->path, pathname); - delete_map(m); + if (load_map_header(thawer, m)) { + LOG(llevError,"Error loading map header for overlay %s (%s)\n", + m->path, pathname); + delete_map(m); m = load_original_map(m->path, 0); - return NULL; + return NULL; } - m->compressed = comp; /*allocate_map(m);*/ m->in_memory=MAP_LOADING; - load_objects (m, fp, thawer, MAP_OVERLAY); - close_and_delete(fp, comp); + load_objects (m, thawer, MAP_OVERLAY); + m->in_memory=MAP_IN_MEMORY; return m; } @@ -1158,21 +1141,21 @@ object *op, *next; for(i=0; iabove; - if (QUERY_FLAG(op, FLAG_IS_FLOOR) && QUERY_FLAG(op, FLAG_UNIQUE)) - unique=1; - if(op->head == NULL && (QUERY_FLAG(op, FLAG_UNIQUE) || unique)) { - clean_object(op); - if (QUERY_FLAG(op, FLAG_IS_LINKED)) - remove_button_link(op); - remove_ob(op); - free_object(op); - } - } - } + for(j=0; jabove; + if (QUERY_FLAG(op, FLAG_IS_FLOOR) && QUERY_FLAG(op, FLAG_UNIQUE)) + unique=1; + if(op->head == NULL && (QUERY_FLAG(op, FLAG_UNIQUE) || unique)) { + clean_object(op); + if (QUERY_FLAG(op, FLAG_IS_LINKED)) + remove_button_link(op); + remove_ob(op); + free_object(op); + } + } + } } @@ -1181,33 +1164,26 @@ * m is the map to load unique items into. */ static void load_unique_objects(mapstruct *m) { - FILE *fp; - int comp,count; + int count; char firstname[MAX_BUF]; for (count=0; count<10; count++) { - sprintf(firstname, "%s.v%02d", create_items_path(m->path), count); - if (!access(firstname, R_OK)) break; + sprintf(firstname, "%s.v%02d", create_items_path(m->path), count); + if (!access(firstname, R_OK)) break; } /* If we get here, we did not find any map */ if (count==10) return; - if ((fp=open_and_uncompress(firstname, 0, &comp))==NULL) { - /* There is no expectation that every map will have unique items, but this - * is debug output, so leave it in. - */ - LOG(llevDebug, "Can't open unique items file for %s\n", create_items_path(m->path)); - return; - } - object_thawer thawer (firstname); + if (!thawer) + return; + m->in_memory=MAP_LOADING; if (m->tmpname == NULL) /* if we have loaded unique items from */ delete_unique_items(m); /* original map before, don't duplicate them */ - load_object(fp, thawer, NULL, LO_NOREAD,0); - load_objects (m, fp, thawer, 0); - close_and_delete(fp, comp); + load_objects (m, thawer, 0); + m->in_memory=MAP_IN_MEMORY; } @@ -1221,155 +1197,152 @@ * (this should have been updated when first loaded) */ -int new_save_map(mapstruct *m, int flag) { - FILE *fp, *fp2; - char filename[MAX_BUF],buf[MAX_BUF], buf_s[MAX_BUF], - shop[MAX_BUF], filename_s[MAX_BUF]; - int i; - - if (flag && !*m->path) { - LOG(llevError,"Tried to save map without path.\n"); - return -1; +int +new_save_map (mapstruct * m, int flag) +{ + char filename[MAX_BUF], buf[MAX_BUF], shop[MAX_BUF]; + int i; + + if (flag && !*m->path) + { + LOG (llevError, "Tried to save map without path.\n"); + return -1; } - - if (flag || (m->unique) || (m->templatemap)) { - if (!m->unique && !m->templatemap) { /* flag is set */ - if (flag == 2) - strcpy(filename, create_overlay_pathname(m->path)); - else - strcpy (filename, create_pathname (m->path)); - } else - strcpy (filename, m->path); - - /* If the compression suffix already exists on the filename, don't - * put it on again. This nasty looking strcmp checks to see if the - * compression suffix is at the end of the filename already. - */ - if (m->compressed && - strcmp((filename + strlen(filename)-strlen(uncomp[m->compressed][0])), - uncomp[m->compressed][0])) - strcat(filename, uncomp[m->compressed][0]); - make_path_to_file(filename); - } else { - if (!m->tmpname) - m->tmpname = tempnam_local(settings.tmpdir,NULL); - strcpy(filename, m->tmpname); - } - LOG(llevDebug,"Saving map %s to %s\n", m->path, filename); - m->in_memory = MAP_SAVING; - - sprintf (filename_s, "%s~", filename); - - /* Compress if it isn't a temporary save. Do compress if unique */ - if (m->compressed && (m->unique || m->templatemap || flag)) { - char buf[MAX_BUF]; - strcpy(buf, uncomp[m->compressed][2]); - strcat(buf, " > "); - strcat(buf, filename_s); - fp = popen(buf, "w"); - } else - fp = fopen(filename_s, "w"); - - if(fp == NULL) { - LOG(llevError, "Cannot write %s: %s\n", filename_s, strerror_local(errno)); - return -1; + + if (flag || (m->unique) || (m->templatemap)) + { + if (!m->unique && !m->templatemap) + { /* flag is set */ + if (flag == 2) + strcpy (filename, create_overlay_pathname (m->path)); + else + strcpy (filename, create_pathname (m->path)); + } + else + strcpy (filename, m->path); + + make_path_to_file (filename); } + else + { + if (!m->tmpname) + m->tmpname = tempnam_local (settings.tmpdir, NULL); - object_freezer freezer (filename); - - /* legacy */ - fprintf(fp,"arch map\n"); - if (m->name) fprintf(fp,"name %s\n", m->name); - if (!flag) fprintf(fp,"swap_time %d\n", m->swap_time); - if (m->reset_timeout) fprintf(fp,"reset_timeout %d\n", m->reset_timeout); - if (m->fixed_resettime) fprintf(fp,"fixed_resettime %d\n", m->fixed_resettime); - /* we unfortunately have no idea if this is a value the creator set - * or a difficulty value we generated when the map was first loaded - */ - if (m->difficulty) fprintf(fp,"difficulty %d\n", m->difficulty); - if (m->region) fprintf(fp,"region %s\n", m->region->name); - if (m->shopitems) { - print_shop_string(m, shop); - fprintf(fp,"shopitems %s\n", shop); + strcpy (filename, m->tmpname); + } + + LOG (llevDebug, "Saving map %s to %s\n", m->path, filename); + m->in_memory = MAP_SAVING; + + object_freezer freezer; + + /* legacy */ + fprintf (freezer, "arch map\n"); + if (m->name) + fprintf (freezer, "name %s\n", m->name); + if (!flag) + fprintf (freezer, "swap_time %d\n", m->swap_time); + if (m->reset_timeout) + fprintf (freezer, "reset_timeout %d\n", m->reset_timeout); + if (m->fixed_resettime) + fprintf (freezer, "fixed_resettime %d\n", m->fixed_resettime); + /* we unfortunately have no idea if this is a value the creator set + * or a difficulty value we generated when the map was first loaded + */ + if (m->difficulty) + fprintf (freezer, "difficulty %d\n", m->difficulty); + if (m->region) + fprintf (freezer, "region %s\n", m->region->name); + if (m->shopitems) + { + print_shop_string (m, shop); + fprintf (freezer, "shopitems %s\n", shop); } - if (m->shopgreed) fprintf(fp,"shopgreed %f\n", m->shopgreed); + if (m->shopgreed) + fprintf (freezer, "shopgreed %f\n", m->shopgreed); #ifndef WIN32 - if (m->shopmin) fprintf(fp,"shopmin %llu\n", m->shopmin); - if (m->shopmax) fprintf(fp,"shopmax %llu\n", m->shopmax); + if (m->shopmin) + fprintf (freezer, "shopmin %llu\n", m->shopmin); + if (m->shopmax) + fprintf (freezer, "shopmax %llu\n", m->shopmax); #else - if (m->shopmin) fprintf(fp,"shopmin %I64u\n", m->shopmin); - if (m->shopmax) fprintf(fp,"shopmax %I64u\n", m->shopmax); + if (m->shopmin) + fprintf (freezer, "shopmin %I64u\n", m->shopmin); + if (m->shopmax) + fprintf (freezer, "shopmax %I64u\n", m->shopmax); #endif - if (m->shoprace) fprintf(fp,"shoprace %s\n", m->shoprace); - if (m->darkness) fprintf(fp,"darkness %d\n", m->darkness); - if (m->width) fprintf(fp,"width %d\n", m->width); - if (m->height) fprintf(fp,"height %d\n", m->height); - if (m->enter_x) fprintf(fp,"enter_x %d\n", m->enter_x); - if (m->enter_y) fprintf(fp,"enter_y %d\n", m->enter_y); - if (m->msg) fprintf(fp,"msg\n%sendmsg\n", m->msg); - if (m->maplore) fprintf(fp,"maplore\n%sendmaplore\n", m->maplore); - if (m->unique) fprintf(fp,"unique %d\n", m->unique); - if (m->templatemap) fprintf(fp,"template %d\n", m->templatemap); - if (m->outdoor) fprintf(fp,"outdoor %d\n", m->outdoor); - if (m->temp) fprintf(fp, "temp %d\n", m->temp); - if (m->pressure) fprintf(fp, "pressure %d\n", m->pressure); - if (m->humid) fprintf(fp, "humid %d\n", m->humid); - if (m->windspeed) fprintf(fp, "windspeed %d\n", m->windspeed); - if (m->winddir) fprintf(fp, "winddir %d\n", m->winddir); - if (m->sky) fprintf(fp, "sky %d\n", m->sky); - if (m->nosmooth) fprintf(fp, "nosmooth %d\n", m->nosmooth); - if (m->safe_map) fprintf(fp, "safe_map %d\n", m->safe_map); - - /* Save any tiling information, except on overlays */ - if (flag != 2) - for (i=0; i<4; i++) - if (m->tile_path[i]) - fprintf(fp,"tile_path_%d %s\n", i+1, m->tile_path[i]); - - fprintf(fp,"end\n"); - - /* In the game save unique items in the different file, but - * in the editor save them to the normal map file. - * If unique map, save files in the proper destination (set by - * player) - */ - if ((flag == 0 || flag == 2) && !m->unique && !m->templatemap) { - sprintf (buf,"%s.v00",create_items_path (m->path)); - sprintf (buf_s, "%s~", buf); - if ((fp2 = fopen (buf_s, "w")) == NULL) { - LOG(llevError, "Can't open unique items file %s\n", buf_s); - } - - object_freezer freezer2 (buf); - - if (flag == 2) - save_objects(m, fp, freezer, fp2, freezer2, 2); - else - save_objects (m, fp,freezer, fp2, freezer2, 0); - if (fp2 != NULL) { - if (ftell (fp2) == 0) { - fclose (fp2); - rename (buf_s, buf); - unlink (buf); - } else { - fclose (fp2); - rename (buf_s, buf); - chmod (buf, SAVE_MODE); - } - } - } else { /* save same file when not playing, like in editor */ - save_objects(m, fp, freezer, fp, freezer, 0); - } + if (m->shoprace) + fprintf (freezer, "shoprace %s\n", m->shoprace); + if (m->darkness) + fprintf (freezer, "darkness %d\n", m->darkness); + if (m->width) + fprintf (freezer, "width %d\n", m->width); + if (m->height) + fprintf (freezer, "height %d\n", m->height); + if (m->enter_x) + fprintf (freezer, "enter_x %d\n", m->enter_x); + if (m->enter_y) + fprintf (freezer, "enter_y %d\n", m->enter_y); + if (m->msg) + fprintf (freezer, "msg\n%sendmsg\n", m->msg); + if (m->maplore) + fprintf (freezer, "maplore\n%sendmaplore\n", m->maplore); + if (m->unique) + fprintf (freezer, "unique %d\n", m->unique); + if (m->templatemap) + fprintf (freezer, "template %d\n", m->templatemap); + if (m->outdoor) + fprintf (freezer, "outdoor %d\n", m->outdoor); + if (m->temp) + fprintf (freezer, "temp %d\n", m->temp); + if (m->pressure) + fprintf (freezer, "pressure %d\n", m->pressure); + if (m->humid) + fprintf (freezer, "humid %d\n", m->humid); + if (m->windspeed) + fprintf (freezer, "windspeed %d\n", m->windspeed); + if (m->winddir) + fprintf (freezer, "winddir %d\n", m->winddir); + if (m->sky) + fprintf (freezer, "sky %d\n", m->sky); + if (m->nosmooth) + fprintf (freezer, "nosmooth %d\n", m->nosmooth); + + /* Save any tiling information, except on overlays */ + if (flag != 2) + for (i = 0; i < 4; i++) + if (m->tile_path[i]) + fprintf (freezer, "tile_path_%d %s\n", i + 1, m->tile_path[i]); + + freezer.put (m); + fprintf (freezer, "end\n"); + + /* In the game save unique items in the different file, but + * in the editor save them to the normal map file. + * If unique map, save files in the proper destination (set by + * player) + */ + if ((flag == 0 || flag == 2) && !m->unique && !m->templatemap) + { + object_freezer unique; - if (m->compressed && (m->unique || m->templatemap || flag)) - pclose(fp); - else - fclose(fp); + if (flag == 2) + save_objects (m, freezer, unique, 2); + else + save_objects (m, freezer, unique, 0); - rename (filename_s, filename); + sprintf (buf, "%s.v00", create_items_path (m->path)); - chmod (filename, SAVE_MODE); - return 0; + unique.save (buf); + } + else + { /* save same file when not playing, like in editor */ + save_objects (m, freezer, freezer, 0); + } + + freezer.save (filename); + + return 0; } @@ -1384,12 +1357,12 @@ for(tmp = op->inv; tmp; tmp = next) { - next = tmp->below; - clean_object(tmp); - if (QUERY_FLAG(tmp, FLAG_IS_LINKED)) - remove_button_link(tmp); - remove_ob(tmp); - free_object(tmp); + next = tmp->below; + clean_object(tmp); + if (QUERY_FLAG(tmp, FLAG_IS_LINKED)) + remove_button_link(tmp); + remove_ob(tmp); + free_object(tmp); } } @@ -1402,38 +1375,26 @@ object *op; for(i=0;ihead!=NULL) - op = op->head; - - /* If the map isn't in memory, free_object will remove and - * free objects in op's inventory. So let it do the job. - */ - if (m->in_memory==MAP_IN_MEMORY) - clean_object(op); - remove_ob(op); - free_object(op); - } - } -#ifdef MANY_CORES - /* I see periodic cores on metalforge where a map has been swapped out, but apparantly - * an item on that map was not saved - look for that condition and die as appropriate - - * this leaves more of the map data intact for better debugging. - */ - for (op=objects; op!=NULL; op=op->next) { - if (!QUERY_FLAG(op, FLAG_REMOVED) && op->map == m) { - LOG(llevDebug,"free_all_objects: object %s still on map after it should have been freed\n", op->name); - abort(); - } - } -#endif + for(j=0;jhead!=NULL) + op = op->head; + + /* If the map isn't in memory, free_object will remove and + * free objects in op's inventory. So let it do the job. + */ + if (m->in_memory==MAP_IN_MEMORY) + clean_object(op); + remove_ob(op); + free_object(op); + } + } } /* @@ -1445,8 +1406,8 @@ int i; if (!m->in_memory) { - LOG(llevError,"Trying to free freed map.\n"); - return; + LOG(llevError,"Trying to free freed map.\n"); + return; } if (flag && m->spaces) free_all_objects(m); if (m->name) FREE_AND_CLEAR(m->name); @@ -1456,11 +1417,11 @@ if (m->shopitems) FREE_AND_CLEAR(m->shopitems); if (m->shoprace) FREE_AND_CLEAR(m->shoprace); if (m->buttons) - free_objectlinkpt(m->buttons); + free_objectlinkpt(m->buttons); m->buttons = NULL; for (i=0; i<4; i++) { - if (m->tile_path[i]) FREE_AND_CLEAR(m->tile_path[i]); - m->tile_map[i] = NULL; + if (m->tile_path[i]) FREE_AND_CLEAR(m->tile_path[i]); + m->tile_map[i] = NULL; } m->in_memory = MAP_SWAPPED; } @@ -1478,19 +1439,22 @@ if (!m) return; + + m->clear (); + if (m->in_memory == MAP_IN_MEMORY) { - /* change to MAP_SAVING, even though we are not, - * so that remove_ob doesn't do as much work. - */ - m->in_memory = MAP_SAVING; - free_map (m, 1); + /* change to MAP_SAVING, even though we are not, + * so that remove_ob doesn't do as much work. + */ + m->in_memory = MAP_SAVING; + free_map (m, 1); } /* move this out of free_map, since tmpname can still be needed if * the map is swapped out. */ if (m->tmpname) { - free(m->tmpname); - m->tmpname=NULL; + free(m->tmpname); + m->tmpname=NULL; } last = NULL; /* We need to look through all the maps and see if any maps @@ -1499,28 +1463,28 @@ * maps this map tiles with and clears those. */ for (tmp = first_map; tmp != NULL; tmp = tmp->next) { - if (tmp->next == m) last = tmp; + if (tmp->next == m) last = tmp; - /* This should hopefully get unrolled on a decent compiler */ - for (i=0; i<4; i++) - if (tmp->tile_map[i] == m) tmp->tile_map[i]=NULL; + /* This should hopefully get unrolled on a decent compiler */ + for (i=0; i<4; i++) + if (tmp->tile_map[i] == m) tmp->tile_map[i]=NULL; } /* If last is null, then this should be the first map in the list */ if (!last) { - if (m == first_map) - first_map = m->next; - else - /* m->path is a static char, so should hopefully still have - * some useful data in it. - */ - LOG(llevError,"delete_map: Unable to find map %s in list\n", - m->path); + if (m == first_map) + first_map = m->next; + else + /* m->path is a static char, so should hopefully still have + * some useful data in it. + */ + LOG(llevError,"delete_map: Unable to find map %s in list\n", + m->path); } else - last->next = m->next; + last->next = m->next; - free (m); + delete m; } @@ -1548,7 +1512,7 @@ /* Map is good to go, so just return it */ if (m && (m->in_memory == MAP_LOADING || m->in_memory == MAP_IN_MEMORY)) { - return m; + return m; } /* unique maps always get loaded from their original location, and never @@ -1561,53 +1525,58 @@ */ if ((flags & (MAP_FLUSH|MAP_PLAYER_UNIQUE)) || !m) { - /* first visit or time to reset */ - if (m) { - clean_tmp_map(m); /* Doesn't make much difference */ - delete_map(m); - } - - /* create and load a map */ - if (flags & MAP_PLAYER_UNIQUE) - LOG(llevDebug, "Trying to load map %s.\n", name); - else - LOG(llevDebug, "Trying to load map %s.\n", create_pathname(name)); - - if (!(m = load_original_map(name, (flags & MAP_PLAYER_UNIQUE)))) - return (NULL); - - fix_auto_apply(m); /* Chests which open as default */ - - /* If a player unique map, no extra unique object file to load. - * if from the editor, likewise. - */ - if (! (flags & (MAP_FLUSH|MAP_PLAYER_UNIQUE))) - load_unique_objects(m); - - if (! (flags & (MAP_FLUSH|MAP_PLAYER_UNIQUE|MAP_OVERLAY))) { - m=load_overlay_map(name, m); - if (m==NULL) - return NULL; - } + /* first visit or time to reset */ + if (m) { + clean_tmp_map(m); /* Doesn't make much difference */ + delete_map(m); + } + + /* create and load a map */ + if (flags & MAP_PLAYER_UNIQUE) + LOG(llevDebug, "Trying to load map %s.\n", name); + else + LOG(llevDebug, "Trying to load map %s.\n", create_pathname(name)); + + //eval_pv ("$x = Event::time", 1);//D + if (!(m = load_original_map(name, (flags & MAP_PLAYER_UNIQUE)))) + return (NULL); + //eval_pv ("warn \"LOAD \", Event::time - $x", 1);//D + + fix_auto_apply(m); /* Chests which open as default */ + + /* If a player unique map, no extra unique object file to load. + * if from the editor, likewise. + */ + if (!(flags & (MAP_FLUSH|MAP_PLAYER_UNIQUE))) + load_unique_objects(m); + + if (! (flags & (MAP_FLUSH|MAP_PLAYER_UNIQUE|MAP_OVERLAY))) { + m=load_overlay_map(name, m); + if (m==NULL) + return NULL; + } + + if (flags & MAP_PLAYER_UNIQUE) + INVOKE_MAP (SWAPIN, m); } else { - /* If in this loop, we found a temporary map, so load it up. */ + /* If in this loop, we found a temporary map, so load it up. */ - m=load_temporary_map (m); + m=load_temporary_map (m); if(m==NULL) return NULL; - load_unique_objects(m); + load_unique_objects(m); - clean_tmp_map(m); - m->in_memory = MAP_IN_MEMORY; - /* tempnam() on sun systems (probably others) uses malloc - * to allocated space for the string. Free it here. - * In some cases, load_temporary_map above won't find the - * temporary map, and so has reloaded a new map. If that - * is the case, tmpname is now null - */ - if (m->tmpname) free(m->tmpname); - m->tmpname = NULL; - /* It's going to be saved anew anyway */ + clean_tmp_map(m); + m->in_memory = MAP_IN_MEMORY; + /* tempnam() on sun systems (probably others) uses malloc + * to allocated space for the string. Free it here. + * In some cases, load_temporary_map above won't find the + * temporary map, and so has reloaded a new map. If that + * is the case, tmpname is now null + */ + if (m->tmpname) free(m->tmpname); + m->tmpname = NULL; + /* It's going to be saved anew anyway */ } /* Below here is stuff common to both first time loaded maps and @@ -1618,7 +1587,7 @@ /* In case other objects press some buttons down */ update_buttons(m); if (m->outdoor) - set_darkness_map(m); + set_darkness_map(m); /* run the weather over this map */ weather_effect(name); return m; @@ -1639,7 +1608,7 @@ int calculate_difficulty(mapstruct *m) { object *op; archetype *at; - int x, y, i, diff; + int x, y, i; long monster_cnt = 0; double avgexp = 0; sint64 total_exp = 0; @@ -1688,7 +1657,7 @@ void clean_tmp_map(mapstruct *m) { if(m->tmpname == NULL) - return; + return; INVOKE_MAP (CLEAN, m); (void) unlink(m->tmpname); } @@ -1698,12 +1667,12 @@ int real_maps=0; while (first_map) { - /* I think some of the callers above before it gets here set this to be - * saving, but we still want to free this data - */ - if (first_map->in_memory == MAP_SAVING) first_map->in_memory = MAP_IN_MEMORY; - delete_map(first_map); - real_maps++; + /* I think some of the callers above before it gets here set this to be + * saving, but we still want to free this data + */ + if (first_map->in_memory == MAP_SAVING) first_map->in_memory = MAP_IN_MEMORY; + delete_map(first_map); + real_maps++; } LOG(llevDebug,"free_all_maps: Freed %d maps\n", real_maps); } @@ -1727,9 +1696,9 @@ /* inform all players on the map */ if (change>0) - new_info_map(NDI_BLACK|NDI_UNIQUE, m,"It becomes darker."); + new_info_map(NDI_BLACK|NDI_UNIQUE, m,"It becomes darker."); else - new_info_map(NDI_BLACK|NDI_UNIQUE, m,"It becomes brighter."); + new_info_map(NDI_BLACK|NDI_UNIQUE, m,"It becomes brighter."); /* Do extra checking. since m->darkness is a unsigned value, * we need to be extra careful about negative values. @@ -1757,13 +1726,13 @@ uint8 flags = 0, oldflags, light=0, anywhere=0; New_Face *top,*floor, *middle; object *top_obj, *floor_obj, *middle_obj; - MoveType move_block=0, move_slow=0, move_on=0, move_off=0, move_allow=0; + MoveType move_block=0, move_slow=0, move_on=0, move_off=0, move_allow=0; oldflags = GET_MAP_FLAGS(m,x,y); if (!(oldflags & P_NEED_UPDATE)) { - LOG(llevDebug,"update_position called with P_NEED_UPDATE not set: %s (%d, %d)\n", - m->path, x, y); - return; + LOG(llevDebug,"update_position called with P_NEED_UPDATE not set: %s (%d, %d)\n", + m->path, x, y); + return; } middle=blank_face; @@ -1776,73 +1745,73 @@ for (tmp = get_map_ob (m, x, y); tmp; last = tmp, tmp = tmp->above) { - /* This could be made additive I guess (two lights better than - * one). But if so, it shouldn't be a simple additive - 2 - * light bulbs do not illuminate twice as far as once since - * it is a disapation factor that is squared (or is it cubed?) - */ - if (tmp->glow_radius > light) light = tmp->glow_radius; - - /* This call is needed in order to update objects the player - * is standing in that have animations (ie, grass, fire, etc). - * However, it also causes the look window to be re-drawn - * 3 times each time the player moves, because many of the - * functions the move_player calls eventualy call this. - * - * Always put the player down for drawing. - */ - if (!tmp->invisible) { - if ((tmp->type==PLAYER || QUERY_FLAG(tmp, FLAG_MONSTER))) { - top = tmp->face; - top_obj = tmp; - } - else if (QUERY_FLAG(tmp,FLAG_IS_FLOOR)) { - /* If we got a floor, that means middle and top were below it, - * so should not be visible, so we clear them. - */ - middle=blank_face; - top=blank_face; - floor = tmp->face; - floor_obj = tmp; - } - /* Flag anywhere have high priority */ - else if (QUERY_FLAG(tmp, FLAG_SEE_ANYWHERE)) { - middle = tmp->face; - - middle_obj = tmp; - anywhere =1; - } - /* Find the highest visible face around. If equal - * visibilities, we still want the one nearer to the - * top - */ - else if (middle == blank_face || (tmp->face->visibility > middle->visibility && !anywhere)) { - middle = tmp->face; - middle_obj = tmp; - } - } - if (tmp==tmp->above) { - LOG(llevError, "Error in structure of map\n"); - exit (-1); - } + /* This could be made additive I guess (two lights better than + * one). But if so, it shouldn't be a simple additive - 2 + * light bulbs do not illuminate twice as far as once since + * it is a disapation factor that is squared (or is it cubed?) + */ + if (tmp->glow_radius > light) light = tmp->glow_radius; + + /* This call is needed in order to update objects the player + * is standing in that have animations (ie, grass, fire, etc). + * However, it also causes the look window to be re-drawn + * 3 times each time the player moves, because many of the + * functions the move_player calls eventualy call this. + * + * Always put the player down for drawing. + */ + if (!tmp->invisible) { + if ((tmp->type==PLAYER || QUERY_FLAG(tmp, FLAG_MONSTER))) { + top = tmp->face; + top_obj = tmp; + } + else if (QUERY_FLAG(tmp,FLAG_IS_FLOOR)) { + /* If we got a floor, that means middle and top were below it, + * so should not be visible, so we clear them. + */ + middle=blank_face; + top=blank_face; + floor = tmp->face; + floor_obj = tmp; + } + /* Flag anywhere have high priority */ + else if (QUERY_FLAG(tmp, FLAG_SEE_ANYWHERE)) { + middle = tmp->face; + + middle_obj = tmp; + anywhere =1; + } + /* Find the highest visible face around. If equal + * visibilities, we still want the one nearer to the + * top + */ + else if (middle == blank_face || (tmp->face->visibility > middle->visibility && !anywhere)) { + middle = tmp->face; + middle_obj = tmp; + } + } + if (tmp==tmp->above) { + LOG(llevError, "Error in structure of map\n"); + exit (-1); + } - move_slow |= tmp->move_slow; - move_block |= tmp->move_block; - move_on |= tmp->move_on; - move_off |= tmp->move_off; - move_allow |= tmp->move_allow; - - if (QUERY_FLAG(tmp,FLAG_ALIVE)) - flags |= P_IS_ALIVE; - if (QUERY_FLAG(tmp,FLAG_NO_MAGIC)) - flags |= P_NO_MAGIC; - if (QUERY_FLAG(tmp,FLAG_DAMNED)) - flags |= P_NO_CLERIC; + move_slow |= tmp->move_slow; + move_block |= tmp->move_block; + move_on |= tmp->move_on; + move_off |= tmp->move_off; + move_allow |= tmp->move_allow; + + if (QUERY_FLAG(tmp,FLAG_ALIVE)) + flags |= P_IS_ALIVE; + if (QUERY_FLAG(tmp,FLAG_NO_MAGIC)) + flags |= P_NO_MAGIC; + if (QUERY_FLAG(tmp,FLAG_DAMNED)) + flags |= P_NO_CLERIC; if (tmp->type == SAFE_GROUND) flags |= P_SAFE | P_NO_CLERIC | P_NO_MAGIC; - if (QUERY_FLAG(tmp,FLAG_BLOCKSVIEW)) - flags |= P_BLOCKSVIEW; + if (QUERY_FLAG(tmp,FLAG_BLOCKSVIEW)) + flags |= P_BLOCKSVIEW; } /* for stack of objects */ /* we don't want to rely on this function to have accurate flags, but @@ -1852,7 +1821,7 @@ if (((oldflags & ~(P_NEED_UPDATE|P_NO_ERROR)) != flags) && (!(oldflags & P_NO_ERROR))) { LOG(llevDebug,"update_position: updated flags do not match old flags: %s (old=%d,new=%d) %x != %x\n", - m->path, x, y, + m->path, x, y, (oldflags & ~P_NEED_UPDATE), flags); } SET_MAP_FLAGS(m, x, y, flags); @@ -1884,34 +1853,34 @@ */ for (tmp=last; tmp; tmp=tmp->below) { - /* Once we get to a floor, stop, since we already have a floor object */ - if (QUERY_FLAG(tmp,FLAG_IS_FLOOR)) break; + /* Once we get to a floor, stop, since we already have a floor object */ + if (QUERY_FLAG(tmp,FLAG_IS_FLOOR)) break; - /* If two top faces are already set, quit processing */ - if ((top != blank_face) && (middle != blank_face)) break; + /* If two top faces are already set, quit processing */ + if ((top != blank_face) && (middle != blank_face)) break; - /* Only show visible faces, unless its the editor - show all */ - if (!tmp->invisible || editor) { - /* Fill in top if needed */ - if (top == blank_face) { - top = tmp->face; - top_obj = tmp; - if (top == middle) middle=blank_face; - } else { - /* top is already set - we should only get here if - * middle is not set - * - * Set the middle face and break out, since there is nothing - * more to fill in. We don't check visiblity here, since - * - */ - if (tmp->face != top ) { - middle = tmp->face; - middle_obj = tmp; - break; - } - } - } + /* Only show visible faces, unless its the editor - show all */ + if (!tmp->invisible || editor) { + /* Fill in top if needed */ + if (top == blank_face) { + top = tmp->face; + top_obj = tmp; + if (top == middle) middle=blank_face; + } else { + /* top is already set - we should only get here if + * middle is not set + * + * Set the middle face and break out, since there is nothing + * more to fill in. We don't check visiblity here, since + * + */ + if (tmp->face != top ) { + middle = tmp->face; + middle_obj = tmp; + break; + } + } + } } if (middle == floor) middle = blank_face; if (top == middle) middle = blank_face; @@ -1961,8 +1930,8 @@ /* need to do a strcmp here as the orig_map->path is not a shared string */ if (orig_map->tile_map[tile_num]->tile_path[dest_tile] && - !strcmp(orig_map->tile_map[tile_num]->tile_path[dest_tile], orig_map->path)) - orig_map->tile_map[tile_num]->tile_map[dest_tile] = orig_map; + !strcmp(orig_map->tile_map[tile_num]->tile_path[dest_tile], orig_map->path)) + orig_map->tile_map[tile_num]->tile_map[dest_tile] = orig_map; return orig_map->tile_map[tile_num]; } @@ -1987,32 +1956,32 @@ if (!m) return 0; if (x<0) { - if (!m->tile_path[3]) return 1; - if (!m->tile_map[3] || m->tile_map[3]->in_memory != MAP_IN_MEMORY) { - load_and_link_tiled_map(m, 3); - } - return (out_of_map(m->tile_map[3], x + MAP_WIDTH(m->tile_map[3]), y)); + if (!m->tile_path[3]) return 1; + if (!m->tile_map[3] || m->tile_map[3]->in_memory != MAP_IN_MEMORY) { + load_and_link_tiled_map(m, 3); + } + return (out_of_map(m->tile_map[3], x + MAP_WIDTH(m->tile_map[3]), y)); } if (x>=MAP_WIDTH(m)) { - if (!m->tile_path[1]) return 1; - if (!m->tile_map[1] || m->tile_map[1]->in_memory != MAP_IN_MEMORY) { - load_and_link_tiled_map(m, 1); - } - return (out_of_map(m->tile_map[1], x - MAP_WIDTH(m), y)); + if (!m->tile_path[1]) return 1; + if (!m->tile_map[1] || m->tile_map[1]->in_memory != MAP_IN_MEMORY) { + load_and_link_tiled_map(m, 1); + } + return (out_of_map(m->tile_map[1], x - MAP_WIDTH(m), y)); } if (y<0) { - if (!m->tile_path[0]) return 1; - if (!m->tile_map[0] || m->tile_map[0]->in_memory != MAP_IN_MEMORY) { - load_and_link_tiled_map(m, 0); - } - return (out_of_map(m->tile_map[0], x, y + MAP_HEIGHT(m->tile_map[0]))); + if (!m->tile_path[0]) return 1; + if (!m->tile_map[0] || m->tile_map[0]->in_memory != MAP_IN_MEMORY) { + load_and_link_tiled_map(m, 0); + } + return (out_of_map(m->tile_map[0], x, y + MAP_HEIGHT(m->tile_map[0]))); } if (y>=MAP_HEIGHT(m)) { - if (!m->tile_path[2]) return 1; - if (!m->tile_map[2] || m->tile_map[2]->in_memory != MAP_IN_MEMORY) { - load_and_link_tiled_map(m, 2); - } - return (out_of_map(m->tile_map[2], x, y - MAP_HEIGHT(m))); + if (!m->tile_path[2]) return 1; + if (!m->tile_map[2] || m->tile_map[2]->in_memory != MAP_IN_MEMORY) { + load_and_link_tiled_map(m, 2); + } + return (out_of_map(m->tile_map[2], x, y - MAP_HEIGHT(m))); } /* Simple case - coordinates are within this local @@ -2033,36 +2002,36 @@ { if (*x<0) { - if (!m->tile_path[3]) return NULL; - if (!m->tile_map[3] || m->tile_map[3]->in_memory != MAP_IN_MEMORY) - load_and_link_tiled_map(m, 3); + if (!m->tile_path[3]) return NULL; + if (!m->tile_map[3] || m->tile_map[3]->in_memory != MAP_IN_MEMORY) + load_and_link_tiled_map(m, 3); - *x += MAP_WIDTH(m->tile_map[3]); - return (get_map_from_coord(m->tile_map[3], x, y)); + *x += MAP_WIDTH(m->tile_map[3]); + return (get_map_from_coord(m->tile_map[3], x, y)); } if (*x>=MAP_WIDTH(m)) { - if (!m->tile_path[1]) return NULL; - if (!m->tile_map[1] || m->tile_map[1]->in_memory != MAP_IN_MEMORY) - load_and_link_tiled_map(m, 1); + if (!m->tile_path[1]) return NULL; + if (!m->tile_map[1] || m->tile_map[1]->in_memory != MAP_IN_MEMORY) + load_and_link_tiled_map(m, 1); - *x -= MAP_WIDTH(m); - return (get_map_from_coord(m->tile_map[1], x, y)); + *x -= MAP_WIDTH(m); + return (get_map_from_coord(m->tile_map[1], x, y)); } if (*y<0) { - if (!m->tile_path[0]) return NULL; - if (!m->tile_map[0] || m->tile_map[0]->in_memory != MAP_IN_MEMORY) - load_and_link_tiled_map(m, 0); + if (!m->tile_path[0]) return NULL; + if (!m->tile_map[0] || m->tile_map[0]->in_memory != MAP_IN_MEMORY) + load_and_link_tiled_map(m, 0); - *y += MAP_HEIGHT(m->tile_map[0]); - return (get_map_from_coord(m->tile_map[0], x, y)); + *y += MAP_HEIGHT(m->tile_map[0]); + return (get_map_from_coord(m->tile_map[0], x, y)); } if (*y>=MAP_HEIGHT(m)) { - if (!m->tile_path[2]) return NULL; - if (!m->tile_map[2] || m->tile_map[2]->in_memory != MAP_IN_MEMORY) - load_and_link_tiled_map(m, 2); + if (!m->tile_path[2]) return NULL; + if (!m->tile_map[2] || m->tile_map[2]->in_memory != MAP_IN_MEMORY) + load_and_link_tiled_map(m, 2); - *y -= MAP_HEIGHT(m); - return (get_map_from_coord(m->tile_map[2], x, y)); + *y -= MAP_HEIGHT(m); + return (get_map_from_coord(m->tile_map[2], x, y)); } /* Simple case - coordinates are within this local @@ -2216,8 +2185,8 @@ retval->direction = 0; retval->part = 0; } else { - retval->distance_x += op2->x-x; - retval->distance_y += op2->y-y; + retval->distance_x += op2->x-x; + retval->distance_y += op2->y-y; retval->part = NULL; retval->distance = isqrt(retval->distance_x*retval->distance_x+retval->distance_y*retval->distance_y);