/// Executes 'func' for each party member on the same map and in range (0:whole map) int party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_session_data *sd,int range,...) { struct party_data *p = NULL; struct battleground_data *bg = NULL; struct map_session_data *psd; int i,x0,y0,x1,y1; struct block_list *list[MAX_BG_MEMBERS]; int blockcount=0; int total = 0; //Return value. nullpo_retr(0,sd); if( map[sd->bl.m].flag.battleground && (bg = bg_team_search(sd->state.bg_id)) == NULL ) return 0; else if( !map[sd->bl.m].flag.battleground && (p = party_search(sd->status.party_id)) == NULL ) return 0; x0 = sd->bl.x-range; y0 = sd->bl.y-range; x1 = sd->bl.x+range; y1 = sd->bl.y+range; if( bg ) { for( i = 0; i < MAX_BG_MEMBERS; i++ ) { if( (psd = bg->members[i].sd) == NULL ) continue; if( psd->bl.m != sd->bl.m || !psd->bl.prev ) continue; if( range && (psd->bl.x < x0 || psd->bl.y < y0 || psd->bl.x > x1 || psd->bl.y > y1) ) continue; list[blockcount++] = &psd->bl; } } else if( p ) { for( i = 0; i < MAX_PARTY; i++ ) { if( (psd = p->data[i].sd) == NULL ) continue; if( psd->bl.m != sd->bl.m || !psd->bl.prev ) continue; if( range && (psd->bl.x < x0 || psd->bl.y < y0 || psd->bl.x > x1 || psd->bl.y > y1) ) continue; list[blockcount++] = &psd->bl; } } else return 0; map_freeblock_lock(); for( i = 0; i < blockcount; i++ ) { va_list ap; va_start(ap, range); total += func(list[i], ap); va_end(ap); } map_freeblock_unlock(); return total; }
/*========================================== * 全一時obj相手にfuncを呼ぶ * *------------------------------------------ */ void map_foreachobject(int (*func)(struct block_list*,va_list),int type,...) { int i; int blockcount=bl_list_count; va_list ap; va_start(ap,type); for(i=2;i<=last_object_id;i++){ if(object[i]){ if(type && object[i]->type!=type) continue; if(bl_list_count>=BL_LIST_MAX) { if(battle_config.error_log) printf("map_foreachobject: too many block !\n"); } else bl_list[bl_list_count++]=object[i]; } } map_freeblock_lock(); for(i=blockcount;i<bl_list_count;i++) if( bl_list[i]->prev || bl_list[i]->next ) func(bl_list[i],ap); map_freeblock_unlock(); va_end(ap); bl_list_count = blockcount; }
/*========================================== * map m (x0,y0)-(x1,y1)内の全objに対して * funcを呼ぶ * type!=0 ならその種類のみ *------------------------------------------ */ void map_foreachinarea(int (*func)(struct block_list*,va_list),int m,int x0,int y0,int x1,int y1,int type,...) { int bx,by; struct block_list *bl; va_list ap; int blockcount=bl_list_count,i,c; 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; 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(type && bl->type!=type) continue; if(bl->x>=x0 && bl->x<=x1 && bl->y>=y0 && bl->y<=y1 && 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->x>=x0 && bl->x<=x1 && bl->y>=y0 && bl->y<=y1 && 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; }
/// Executes 'func' for each party member on the same map and in range (0:whole map) int party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_session_data *sd,int range,...) { struct party_data *p; int i; int x0,y0,x1,y1; struct block_list *list[MAX_PARTY]; int blockcount=0; int total = 0; //Return value. nullpo_ret(sd); if((p = party_search(sd->status.party_id)) == NULL) return 0; x0 = sd->bl.x-range; y0 = sd->bl.y-range; x1 = sd->bl.x+range; y1 = sd->bl.y+range; for(i = 0; i < MAX_PARTY; i++) { struct map_session_data *psd = p->data[i].sd; if(!psd) continue; if(psd->bl.m!=sd->bl.m || !psd->bl.prev) continue; if(range && (psd->bl.x<x0 || psd->bl.y<y0 || psd->bl.x>x1 || psd->bl.y>y1 ) ) continue; list[blockcount++]=&psd->bl; } map_freeblock_lock(); for(i = 0; i < blockcount; i++) { va_list ap; va_start(ap, range); total += func(list[i], ap); va_end(ap); } map_freeblock_unlock(); return total; }
// 同じマップのパーティメンバー全体に処理をかける // type==0 同じマップ // !=0 画面内 int party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_session_data *sd,int range,...) { struct party *p; va_list ap; int i; int x0,y0,x1,y1; struct block_list *list[MAX_PARTY]; int blockcount=0; int total = 0; //Return value. nullpo_retr(0,sd); if((p=party_search(sd->status.party_id))==NULL) return 0; x0=sd->bl.x-range; y0=sd->bl.y-range; x1=sd->bl.x+range; y1=sd->bl.y+range; va_start(ap,range); for(i=0;i<MAX_PARTY;i++){ struct party_member *m=&p->member[i]; if(m->sd!=NULL){ if(sd->bl.m!=m->sd->bl.m) continue; if(range && (m->sd->bl.x<x0 || m->sd->bl.y<y0 || m->sd->bl.x>x1 || m->sd->bl.y>y1 ) ) continue; list[blockcount++]=&m->sd->bl; } } map_freeblock_lock(); // メモリからの解放を禁止する for(i=0;i<blockcount;i++) if(list[i]->prev) // 有効かどうかチェック total += func(list[i],ap); map_freeblock_unlock(); // 解放を許可する va_end(ap); return total; }
// 同じマップのパーティメンバー全体に処理をかける // type==0 同じマップ // !=0 画面内 void party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_session_data *sd,int type,...) { struct party *p; va_list ap; int i; int x0,y0,x1,y1; struct block_list *list[MAX_PARTY]; int blockcount=0; nullpo_retv(sd); if((p=party_search(sd->status.party_id))==NULL) return; x0=sd->bl.x-AREA_SIZE; y0=sd->bl.y-AREA_SIZE; x1=sd->bl.x+AREA_SIZE; y1=sd->bl.y+AREA_SIZE; va_start(ap,type); for(i=0;i<MAX_PARTY;i++){ struct party_member *m=&p->member[i]; if(m->sd!=NULL){ if(sd->bl.m!=m->sd->bl.m) continue; if(type!=0 && (m->sd->bl.x<x0 || m->sd->bl.y<y0 || m->sd->bl.x>x1 || m->sd->bl.y>y1 ) ) continue; list[blockcount++]=&m->sd->bl; } } map_freeblock_lock(); // メモリからの解放を禁止する for(i=0;i<blockcount;i++) if(list[i]->prev) // 有効かどうかチェック func(list[i],ap); map_freeblock_unlock(); // 解放を許可する va_end(ap); }
/*========================================== * 矩形(x0,y0)-(x1,y1)が(dx,dy)移動した時の * 領域外になる領域(矩形かL字形)内のobjに * 対してfuncを呼ぶ * * dx,dyは-1,0,1のみとする(どんな値でもいいっぽい?) *------------------------------------------ */ void map_foreachinmovearea(int (*func)(struct block_list*,va_list),int m,int x0,int y0,int x1,int y1,int dx,int dy,int type,...) { int bx,by; struct block_list *bl; va_list ap; int blockcount=bl_list_count,i,c; va_start(ap,type); if(dx==0 || dy==0){ // 矩形領域の場合 if(dx==0){ if(dy<0){ y0=y1+dy+1; } else { y1=y0+dy-1; } } else if(dy==0){ if(dx<0){ x0=x1+dx+1; } else { x1=x0+dx-1; } } 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; 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(type && bl->type!=type) continue; if(bl->x>=x0 && bl->x<=x1 && bl->y>=y0 && bl->y<=y1 && bl_list_count<BL_LIST_MAX) bl_list[bl_list_count++]=bl; } 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(type && bl->type!=type) continue; if(bl->x>=x0 && bl->x<=x1 && bl->y>=y0 && bl->y<=y1 && bl_list_count<BL_LIST_MAX) bl_list[bl_list_count++]=bl; } } } }else{ // L字領域の場合 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; 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(type && bl->type!=type) continue; if(!(bl->x>=x0 && bl->x<=x1 && bl->y>=y0 && bl->y<=y1)) continue; if(((dx>0 && bl->x<x0+dx) || (dx<0 && bl->x>x1+dx) || (dy>0 && bl->y<y0+dy) || (dy<0 && bl->y>y1+dy)) && bl_list_count<BL_LIST_MAX) bl_list[bl_list_count++]=bl; } 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(type && bl->type!=type) continue; if(!(bl->x>=x0 && bl->x<=x1 && bl->y>=y0 && bl->y<=y1)) continue; if(((dx>0 && bl->x<x0+dx) || (dx<0 && bl->x>x1+dx) || (dy>0 && bl->y<y0+dy) || (dy<0 && bl->y>y1+dy)) && 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; }