summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt4
-rw-r--r--src/map/mob.c97
-rw-r--r--src/map/skill.c1
-rw-r--r--src/map/skill.h1
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);