diff options
Diffstat (limited to 'src/map/map.c')
-rw-r--r-- | src/map/map.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/map/map.c b/src/map/map.c index 493a243ff..9515e8233 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -652,6 +652,95 @@ void map_foreachincell(int (*func)(struct block_list*,va_list),int m,int x,int y bl_list_count = blockcount; } +/*============================================================ +* For checking a path between two points (x0, y0) and (x1, y1) +*------------------------------------------------------------ + */ +void map_foreachinpath(int (*func)(struct block_list*,va_list),int m,int x0,int y0,int x1,int y1,int range,int length,int type,...) { + va_list ap; + int bx,by; + struct block_list *bl=NULL; + int blockcount=bl_list_count,i,c; + double s; + int in; // slope, interception + + if(m < 0) + return; + va_start(ap,type); + if (x0 < 0) x0 = 0; + if (y0 < 0) y0 = 0; + if (x1 >= map[m].xs) x1 = map[m].xs-1; + if (y1 >= map[m].ys) y1 = map[m].ys-1; + +// y = ax + c // ugh, algebra! xp +// x = (y - c) / a + if (x0 == x1) { + s = 999; in = 0; + } else if (y0 == y1) { + s = 0; in = y0; + } else { + s = (double)(y1 - y0)/(double)(x1 - x0); + in = y0 - s * x0; + } + //printf ("%lf %d\n", s, in); + + if (type == 0 || type != BL_MOB) + for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++) { + for(bx=x0/BLOCK_SIZE;bx<=x1/BLOCK_SIZE;bx++){ + bl = map[m].block[bx+by*map[m].bxs]; + c = map[m].block_count[bx+by*map[m].bxs]; + for(i=0;i<c && bl;i++,bl=bl->next){ + if(bl && type && bl->type!=type) + continue; + if(bl) { + printf ("%lf %lf\n", s * bl->x + in - bl->y, (in - bl->y)/s - bl->x); + + if (((s == 999 && bl->x == x0) || + (s == 0 && in == y0 && bl->y == y0) || + abs(s * bl->x + in - bl->y) <= range || + abs((bl->y - in)/s - bl->x) <= range) && + bl_list_count<BL_LIST_MAX) + bl_list[bl_list_count++]=bl; + } + } + } + } + if(type==0 || type==BL_MOB) + for(by=y0/BLOCK_SIZE;by<=y1/BLOCK_SIZE;by++){ + for(bx=x0/BLOCK_SIZE;bx<=x1/BLOCK_SIZE;bx++){ + bl = map[m].block_mob[bx+by*map[m].bxs]; + c = map[m].block_mob_count[bx+by*map[m].bxs]; + for(i=0;i<c && bl;i++,bl=bl->next){ + if(bl) { + printf ("%lf %lf\n", s * bl->x + in - bl->y, (bl->y - in)/s - bl->x); + if (((s == 999 && bl->x == x0) || + (s == 0 && in == y0 && bl->y == y0) || + abs(s * bl->x + in - bl->y) <= range || + abs((bl->y - in)/s - bl->x) <= range) && + bl_list_count<BL_LIST_MAX) + bl_list[bl_list_count++]=bl; + } + } + } + } + + if(bl_list_count>=BL_LIST_MAX) { + if(battle_config.error_log) + printf("map_foreachinarea: *WARNING* block count too many!\n"); + } + + map_freeblock_lock(); // メモリからの解放を禁止する + + for(i=blockcount;i<bl_list_count;i++) + if(bl_list[i]->prev) // 有?かどうかチェック + func(bl_list[i],ap); + + map_freeblock_unlock(); // 解放を許可する + + va_end(ap); + bl_list_count = blockcount; +} + /*========================================== * 床アイテムやエフェクト用の一時obj割り?て * object[]への保存とid_db登?まで |