summaryrefslogtreecommitdiff
path: root/src/map/map.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/map.c')
-rw-r--r--src/map/map.c89
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登?まで