From b8cecabe98a2d0762d945a08d52f6a37587ce83d Mon Sep 17 00:00:00 2001 From: skotlex Date: Thu, 2 Mar 2006 20:11:07 +0000 Subject: - Some cleanup on mob_can_reach code to prevent unnecessary path-searching - Optimized the path-searching ai for mobs to try target cells around the target in order rather than randomly picked cells. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@5434 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 4 +++ src/map/mob.c | 97 ++++++++++++++++++++++++++++++----------------------- src/map/skill.c | 1 - src/map/skill.h | 1 + 4 files changed, 60 insertions(+), 43 deletions(-) diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index f6fffb1d0..b8b818b28 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -5,6 +5,10 @@ IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. EV GOES INTO TRUNK AND WILL BE MERGED INTO STABLE BY VALARIS AND WIZPUTER. -- VALARIS 2006/03/02 + * Some cleanup on mob_can_reach code to prevent unnecessary path-searching + [Skotlex] + * Optimized the path-searching ai for mobs to try target cells around the + target in order rather than randomly picked cells. [Skotlex] * Applied Snufkin's patch to fix compilation on FreeBSD. [Skotlex] * Fixed mobs targetting themselves after using a support skill. [Skotlex] * Gospel no longer blocks item usage of whoever is in the area of effect, diff --git a/src/map/mob.c b/src/map/mob.c index d164275fd..11774bad9 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -622,16 +622,22 @@ int mob_can_reach(struct mob_data *md,struct block_list *bl,int range, int state return 1; // It judges whether it can adjoin or not. - dx=abs(bl->x - md->bl.x); - dy=abs(bl->y - md->bl.y); + dx=bl->x - md->bl.x; + dy=bl->y - md->bl.y; dx=(dx>0)?1:((dx<0)?-1:0); dy=(dy>0)?1:((dy<0)?-1:0); + if (map_getcell(md->bl.m,bl->x+dx,bl->y+dy,CELL_CHKNOREACH)) + { //Look for a suitable cell to place in. + for(i=0;i<9 && map_getcell(md->bl.m,bl->x-1+i/3,bl->y-1+i%3,CELL_CHKNOREACH);i++); + if (i<9) { + dx = 1-i/3; + dy = 1-i%3; + } + } + if(path_search_real(&wpd,md->bl.m,md->bl.x,md->bl.y,bl->x-dx,bl->y-dy,easy,CELL_CHKNOREACH)!=-1) return 1; - for(i=0;i<9;i++){ - if(path_search_real(&wpd,md->bl.m,md->bl.x,md->bl.y,bl->x-1+i/3,bl->y-1+i%3,easy, CELL_CHKNOREACH)!=-1) - return 1; - } + return 0; } @@ -1563,7 +1569,7 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap) struct mob_data *md; struct block_list *tbl = NULL, *abl = NULL; unsigned int tick; - int i, dx, dy, dist; + int i, j, dx, dy, dist; int attack_type = 0; int mode; int search_size = AREA_SIZE*2; @@ -1747,51 +1753,58 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap) return 0; } //Target reachable. Locate suitable spot to move to. - i = 0; + i = j = 0; dx = tbl->x - md->bl.x; dy = tbl->y - md->bl.y; - if (dx < 0) dx++; - else if (dx > 0) dx--; - if (dy < 0) dy++; - else if (dy > 0) dy--; + if (dx < 0) dx=-1; + else if (dx > 0) dx=1; + if (dy < 0) dy=-1; + else if (dy > 0) dy=1; + if(mob_walktoxy(md, tbl->x -dx, tbl->y -dy, 0)) { + j = (dy+1) + 3*(dx+1); + for (i = j+1; i%9 != j; i++) { + dx = -1+(i%9)/3; + dy = -1+(i%3); +#ifdef CELL_NOSTACK + if (map_getcell(md->bl.m, tbl->x-dx, tbl->y-dy, CELL_CHKSTACK)) + continue; +#endif + if (!mob_walktoxy(md, tbl->x-dx, tbl->y-dy, 0)) + break; + } #ifdef CELL_NOSTACK - while (mob_walktoxy(md, md->bl.x + dx, md->bl.y + dy, 0)) - { //Attempt to chase to nearby blocks - do { - if (i < 5) { - dx = tbl->x - md->bl.x + rand()%3 - 1; - dy = tbl->y - md->bl.y + rand()%3 - 1; - } else { //Try some more... - dx = tbl->x - md->bl.x + rand()%5 - 2; - dy = tbl->y - md->bl.y + rand()%5 - 2; + if (i%9 == j) + { //All adjacent cells are taken. Try roaming around on 5x5 + for (i = j+1; i%9 != j; i++) { + dx = 2*(-1+(i%9)/3); + dy = 2*(-1+(i%3)); + if (map_getcell(md->bl.m, tbl->x-dx, tbl->y-dy, CELL_CHKSTACK)) + continue; + if (!mob_walktoxy(md, tbl->x-dx, tbl->y-dy, 0)) { + md->next_walktime = tick + 1000; + break; + } } - i++; - } while (i < 15 && map_getcell(md->bl.m, md->bl.x+dx, md->bl.y+dy, CELL_CHKSTACK)); - if (i >= 15) { + } + if (i%9 == j) + { //On stacked mode, it is much more likely that you just can't reach the target. So unlock it mob_unlocktarget(md, tick); - //Make it give up for 1 second to avoid unnecessary server load in case the target is already mobbed to death. - mob_changestate(md,MS_DELAY,1000); + md->next_walktime = tick + 1000; return 0; } - } #else - while (i < 5 && mob_walktoxy(md, md->bl.x + dx, md->bl.y + dy, 0)) - { //Attempt to chase to nearby blocks - dx = tbl->x - md->bl.x + rand()%3 - 1; - dy = tbl->y - md->bl.y + rand()%3 - 1; - i++; - } - if (i==5) - { //Failed? Try going away from the target before retrying. - if (dx < 0) dx = 2; - else if (dx > 0) dx = -2; - if (dy < 0) dy = 2; - else if (dy > 0) dy = -2; - } + if (i%9 == j) + { //Failed? Try going away from the target before retrying. + if (dx < 0) dx = 2; + else if (dx > 0) dx = -2; + if (dy < 0) dy = 2; + else if (dy > 0) dy = -2; + mob_walktoxy (md, tbl->x+dx, tbl->y+dy, 0); + md->next_walktime = tick + 500; + } #endif - md->next_walktime = tick + 500; - mob_walktoxy (md, md->bl.x+dx, md->bl.y+dy, 0); + } return 0; } //Target within range, engage diff --git a/src/map/skill.c b/src/map/skill.c index 4c1a7dd57..213d56415 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -637,7 +637,6 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s int skill_frostjoke_scream(struct block_list *bl,va_list ap); int status_change_timer_sub(struct block_list *bl, va_list ap); int skill_attack_area(struct block_list *bl,va_list ap); -int skill_clear_element_field(struct block_list *bl); struct skill_unit_group *skill_locate_element_field(struct block_list *bl); // [Skotlex] int skill_graffitiremover(struct block_list *bl, va_list ap); // [Valaris] int skill_greed(struct block_list *bl, va_list ap); diff --git a/src/map/skill.h b/src/map/skill.h index 9c38744db..24ff74066 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -187,6 +187,7 @@ struct skill_unit_group *skill_initunitgroup(struct block_list *src, int count,int skillid,int skilllv,int unit_id); int skill_delunitgroup(struct skill_unit_group *group); int skill_clear_unitgroup(struct block_list *src); +int skill_clear_element_field(struct block_list *bl); int skill_unit_ondamaged(struct skill_unit *src,struct block_list *bl, int damage,unsigned int tick); -- cgit v1.2.3-70-g09d2