diff options
Diffstat (limited to 'src/map/map.c')
-rw-r--r-- | src/map/map.c | 188 |
1 files changed, 94 insertions, 94 deletions
diff --git a/src/map/map.c b/src/map/map.c index b3efe7c57..5c0f5d65e 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -395,7 +395,7 @@ int map_moveblock(struct block_list *bl, int x1, int y1, int64 tick) { /*========================================== * Counts specified number of objects on given cell. - * flag:
+ * flag: * 0x1 - only count standing units * TODO: merge with bl_getall_area *------------------------------------------*/ @@ -412,26 +412,26 @@ int map_count_oncell(int16 m, int16 x, int16 y, int type, int flag) { if (type&~BL_MOB) for( bl = map->list[m].block[bx+by*map->list[m].bxs] ; bl != NULL ; bl = bl->next ) - if(bl->x == x && bl->y == y && bl->type&type) {
- if(flag&1) {
- struct unit_data *ud = unit->bl2ud(bl);
- if(!ud || ud->walktimer == INVALID_TIMER)
- count++;
- } else {
- count++;
- }
+ if(bl->x == x && bl->y == y && bl->type&type) { + if(flag&1) { + struct unit_data *ud = unit->bl2ud(bl); + if(!ud || ud->walktimer == INVALID_TIMER) + count++; + } else { + count++; + } } if (type&BL_MOB) for( bl = map->list[m].block_mob[bx+by*map->list[m].bxs] ; bl != NULL ; bl = bl->next ) - if(bl->x == x && bl->y == y) {
- if(flag&1) {
- struct unit_data *ud = unit->bl2ud(bl);
- if(!ud || ud->walktimer == INVALID_TIMER)
- count++;
- } else {
- count++;
- }
+ if(bl->x == x && bl->y == y) { + if(flag&1) { + struct unit_data *ud = unit->bl2ud(bl); + if(!ud || ud->walktimer == INVALID_TIMER) + count++; + } else { + count++; + } } return count; @@ -1488,83 +1488,83 @@ int map_search_freecell(struct block_list *src, int16 m, int16 *x,int16 *y, int1 return 0; } -/*==========================================
- * Locates the closest, walkable cell with no blocks of a certain type on it
- * Returns true on success and sets x and y to cell found.
- * Otherwise returns false and x and y are not changed.
- * type: Types of block to count
- * flag:
- * 0x1 - only count standing units
- *------------------------------------------*/
-bool map_closest_freecell(int16 m, int16 *x, int16 *y, int type, int flag)
-{
- uint8 dir = 6;
- int16 tx = *x;
- int16 ty = *y;
- int costrange = 10;
-
- if(!map->count_oncell(m, tx, ty, type, flag))
- return true; //Current cell is free
-
- //Algorithm only works up to costrange of 34
- while(costrange <= 34) {
- short dx = dirx[dir];
- short dy = diry[dir];
-
- //Linear search
- if(dir%2 == 0 && costrange%MOVE_COST == 0) {
- tx = *x+dx*(costrange/MOVE_COST);
- ty = *y+dy*(costrange/MOVE_COST);
- if(!map->count_oncell(m, tx, ty, type, flag) && map->getcell(m,tx,ty,CELL_CHKPASS)) {
- *x = tx;
- *y = ty;
- return true;
- }
- }
- //Full diagonal search
- else if(dir%2 == 1 && costrange%MOVE_DIAGONAL_COST == 0) {
- tx = *x+dx*(costrange/MOVE_DIAGONAL_COST);
- ty = *y+dy*(costrange/MOVE_DIAGONAL_COST);
- if(!map->count_oncell(m, tx, ty, type, flag) && map->getcell(m,tx,ty,CELL_CHKPASS)) {
- *x = tx;
- *y = ty;
- return true;
- }
- }
- //One cell diagonal, rest linear (TODO: Find a better algorithm for this)
- else if(dir%2 == 1 && costrange%MOVE_COST == 4) {
- tx = *x+dx*((dir%4==3)?(costrange/MOVE_COST):1);
- ty = *y+dy*((dir%4==1)?(costrange/MOVE_COST):1);
- if(!map->count_oncell(m, tx, ty, type, flag) && map->getcell(m,tx,ty,CELL_CHKPASS)) {
- *x = tx;
- *y = ty;
- return true;
- }
- tx = *x+dx*((dir%4==1)?(costrange/MOVE_COST):1);
- ty = *y+dy*((dir%4==3)?(costrange/MOVE_COST):1);
- if(!map->count_oncell(m, tx, ty, type, flag) && map->getcell(m,tx,ty,CELL_CHKPASS)) {
- *x = tx;
- *y = ty;
- return true;
- }
- }
-
- //Get next direction
- if (dir == 5) {
- //Diagonal search complete, repeat with higher cost range
- if(costrange == 14) costrange += 6;
- else if(costrange == 28 || costrange >= 38) costrange += 2;
- else costrange += 4;
- dir = 6;
- } else if (dir == 4) {
- //Linear search complete, switch to diagonal directions
- dir = 7;
- } else {
- dir = (dir+2)%8;
- }
- }
-
- return false;
+/*========================================== + * Locates the closest, walkable cell with no blocks of a certain type on it + * Returns true on success and sets x and y to cell found. + * Otherwise returns false and x and y are not changed. + * type: Types of block to count + * flag: + * 0x1 - only count standing units + *------------------------------------------*/ +bool map_closest_freecell(int16 m, int16 *x, int16 *y, int type, int flag) +{ + uint8 dir = 6; + int16 tx = *x; + int16 ty = *y; + int costrange = 10; + + if(!map->count_oncell(m, tx, ty, type, flag)) + return true; //Current cell is free + + //Algorithm only works up to costrange of 34 + while(costrange <= 34) { + short dx = dirx[dir]; + short dy = diry[dir]; + + //Linear search + if(dir%2 == 0 && costrange%MOVE_COST == 0) { + tx = *x+dx*(costrange/MOVE_COST); + ty = *y+dy*(costrange/MOVE_COST); + if(!map->count_oncell(m, tx, ty, type, flag) && map->getcell(m,tx,ty,CELL_CHKPASS)) { + *x = tx; + *y = ty; + return true; + } + } + //Full diagonal search + else if(dir%2 == 1 && costrange%MOVE_DIAGONAL_COST == 0) { + tx = *x+dx*(costrange/MOVE_DIAGONAL_COST); + ty = *y+dy*(costrange/MOVE_DIAGONAL_COST); + if(!map->count_oncell(m, tx, ty, type, flag) && map->getcell(m,tx,ty,CELL_CHKPASS)) { + *x = tx; + *y = ty; + return true; + } + } + //One cell diagonal, rest linear (TODO: Find a better algorithm for this) + else if(dir%2 == 1 && costrange%MOVE_COST == 4) { + tx = *x+dx*((dir%4==3)?(costrange/MOVE_COST):1); + ty = *y+dy*((dir%4==1)?(costrange/MOVE_COST):1); + if(!map->count_oncell(m, tx, ty, type, flag) && map->getcell(m,tx,ty,CELL_CHKPASS)) { + *x = tx; + *y = ty; + return true; + } + tx = *x+dx*((dir%4==1)?(costrange/MOVE_COST):1); + ty = *y+dy*((dir%4==3)?(costrange/MOVE_COST):1); + if(!map->count_oncell(m, tx, ty, type, flag) && map->getcell(m,tx,ty,CELL_CHKPASS)) { + *x = tx; + *y = ty; + return true; + } + } + + //Get next direction + if (dir == 5) { + //Diagonal search complete, repeat with higher cost range + if(costrange == 14) costrange += 6; + else if(costrange == 28 || costrange >= 38) costrange += 2; + else costrange += 4; + dir = 6; + } else if (dir == 4) { + //Linear search complete, switch to diagonal directions + dir = 7; + } else { + dir = (dir+2)%8; + } + } + + return false; } /*========================================== |