diff options
-rw-r--r-- | src/map/map.c | 118 | ||||
-rw-r--r-- | src/map/map.h | 9 |
2 files changed, 74 insertions, 53 deletions
diff --git a/src/map/map.c b/src/map/map.c index b45863b11..838a88f01 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -76,6 +76,22 @@ int map_getusers(void) { return map->users; } +/** + * Expands map->bl_list on demand + **/ +static inline void map_bl_list_expand(void) { + map->bl_list_size += 250; + RECREATE(map->bl_list, struct block_list *, map->bl_list_size); +} + +/** + * Expands map->block_free on demand + **/ +static inline void map_block_free_expand(void) { + map->block_free_list_size += 100; + RECREATE(map->block_free, struct block_list *, map->block_free_list_size); +} + /*========================================== * server player count (this mapserver only) *------------------------------------------*/ @@ -88,17 +104,20 @@ int map_usercount(void) { *------------------------------------------*/ int map_freeblock (struct block_list *bl) { nullpo_retr(map->block_free_lock, bl); - - if (map->block_free_lock == 0 || map->block_free_count >= block_free_max) { + + if (map->block_free_lock == 0) { if( bl->type == BL_ITEM ) ers_free(map->flooritem_ers, bl); else aFree(bl); bl = NULL; - if (map->block_free_count >= block_free_max) - ShowWarning("map_freeblock: too many free block! %d %d\n", map->block_free_count, map->block_free_lock); - } else + } else { + + if( map->block_free_count >= map->block_free_list_size ) + map_block_free_expand(); + map->block_free[map->block_free_count++] = bl; + } return map->block_free_lock; } @@ -483,23 +502,22 @@ static int map_vforeachinmap(int (*func)(struct block_list*, va_list), int16 m, for (i = 0; i < bsize; i++) { if (type&~BL_MOB) { for (bl = map->list[m].block[i]; bl != NULL; bl = bl->next) { - if (bl->type&type && map->bl_list_count < BL_LIST_MAX) { + if (bl->type&type) { + if( map->bl_list_count >= map->bl_list_size ) + map_bl_list_expand(); map->bl_list[map->bl_list_count++] = bl; } } } if (type&BL_MOB) { for (bl = map->list[m].block_mob[i]; bl != NULL; bl = bl->next) { - if (map->bl_list_count < BL_LIST_MAX) { - map->bl_list[map->bl_list_count++] = bl; - } + if( map->bl_list_count >= map->bl_list_size ) + map_bl_list_expand(); + map->bl_list[map->bl_list_count++] = bl; } } } - if (map->bl_list_count >= BL_LIST_MAX) - ShowError("map.c:map_vforeachinmap: bl_list size (%d) exceeded\n", BL_LIST_MAX); - va_copy(argscopy, args); returnCount = bl_vforeach(func, blockcount, INT_MAX, argscopy); va_end(argscopy); @@ -607,52 +625,45 @@ static int bl_getall_area(int type, int m, int x0, int y0, int x1, int y1, int ( for (bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++) { if (type&~BL_MOB) { for (bl = map->list[m].block[bx + by * map->list[m].bxs]; bl != NULL; bl = bl->next) { - if (map->bl_list_count < BL_LIST_MAX - && bl->type&type - && bl->x >= x0 && bl->x <= x1 - && bl->y >= y0 && bl->y <= y1) { - if (func) { - va_start(args, func); - if (func(bl, args)) { - map->bl_list[map->bl_list_count++] = bl; - found++; - } - va_end(args); - } - else { + if (bl->type&type && bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1) { + if( map->bl_list_count >= map->bl_list_size ) + map_bl_list_expand(); + if (func) { + va_start(args, func); + if (func(bl, args)) { map->bl_list[map->bl_list_count++] = bl; found++; } + va_end(args); + } else { + map->bl_list[map->bl_list_count++] = bl; + found++; + } } } } if (type&BL_MOB) { // TODO: fix this code duplication for (bl = map->list[m].block_mob[bx + by * map->list[m].bxs]; bl != NULL; bl = bl->next) { - if (map->bl_list_count < BL_LIST_MAX - //&& bl->type&type // block_mob contains BL_MOBs only - && bl->x >= x0 && bl->x <= x1 - && bl->y >= y0 && bl->y <= y1) { - if (func) { - va_start(args, func); - if (func(bl, args)) { - map->bl_list[map->bl_list_count++] = bl; - found++; - } - va_end(args); - } - else { + if (bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1) { + if( map->bl_list_count >= map->bl_list_size ) + map_bl_list_expand(); + if (func) { + va_start(args, func); + if (func(bl, args)) { map->bl_list[map->bl_list_count++] = bl; found++; } + va_end(args); + } else { + map->bl_list[map->bl_list_count++] = bl; + found++; + } } } } } } - if (map->bl_list_count >= BL_LIST_MAX) - ShowError("map.c:bl_getall_area: bl_list size (%d) exceeded\n", BL_LIST_MAX); - return found; } @@ -5281,6 +5292,12 @@ void do_final(void) aFree(map->list); + if( map->block_free ) + aFree(map->block_free); + if( map->bl_list ) + aFree(map->bl_list); + + if( !map->enable_grf ) aFree(map->cache_buffer); @@ -5863,17 +5880,20 @@ void map_defaults(void) { map->zone_db = NULL; map->iwall_db = NULL; + map->block_free = NULL; + map->block_free_count = 0; + map->block_free_lock = 0; + map->block_free_list_size = 0; + map->bl_list = NULL; + map->bl_list_count = 0; + map->bl_list_size = 0; + //all in a big chunk, respects order - memset(map->block_free,0,sizeof(map->block_free) - + sizeof(map->block_free_count) - + sizeof(map->block_free_lock) - + sizeof(map->bl_list) - + sizeof(map->bl_list_count) - + sizeof(map->bl_head) + memset(&map->bl_head,0,sizeof(map->bl_head) + sizeof(map->zone_all) + sizeof(map->zone_pk) ); - + map->cpsd = NULL; map->list = NULL; @@ -6056,7 +6076,7 @@ void map_defaults(void) { map->remove_questinfo = map_remove_questinfo; map->merge_zone = map_merge_zone; - + /** * mapit interface **/ diff --git a/src/map/map.h b/src/map/map.h index aed506992..270931689 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -875,13 +875,14 @@ struct map_interface { DBMap* iwall_db; /* order respected by map_defaults() in order to zero */ /* from block_free until zone_pk */ - struct block_list *block_free[block_free_max]; - int block_free_count, block_free_lock; - struct block_list *bl_list[BL_LIST_MAX]; - int bl_list_count; + struct block_list **block_free; + int block_free_count, block_free_lock, block_free_list_size; + struct block_list **bl_list; + int bl_list_count, bl_list_size; struct block_list bl_head; struct map_zone_data zone_all;/* used as a base on all maps */ struct map_zone_data zone_pk;/* used for (pk_mode) */ + /* */ struct map_session_data *cpsd; struct map_data *list; /* [Ind/Hercules] */ |