Skip to content

Commit

Permalink
Monster random walk code optimized (fixes #208)
Browse files Browse the repository at this point in the history
* Monsters will now always find a cell to walk to on first attempt as long as there is at least one cell available
* Performance for searching a cell improved, a monster no longer tries the same cell twice
* Removed the "MOB can't move" warning by default; the warning could appear with legit behavior like using Icewall and actually made the monster re-spawn
* Added a config option to monster.conf, where you can re-enable the warning and the re-spawning again
  • Loading branch information
Playtester committed Jan 30, 2016
1 parent 92bf61c commit 78419ba
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 18 deletions.
4 changes: 4 additions & 0 deletions conf/battle/monster.conf
Original file line number Diff line number Diff line change
Expand Up @@ -251,3 +251,7 @@ boss_icewall_walk_block: 0
// 2012-04-04aRagexeRE or higher client required.
monster_hp_bars_info: yes

// Should a monster respawn and a warning printed to the map server when a monster couldn't move for a long time?
// This can be legit gameplay (e.g. players keeping an MVP stuck inside icewall), but if you want to prevent any
// exploits and be notified about them, you can set this to yes.
monster_stuck_warning: no
1 change: 1 addition & 0 deletions src/map/battle.c
Original file line number Diff line number Diff line change
Expand Up @@ -8195,6 +8195,7 @@ static const struct _battle_data {
{ "max_body_style", &battle_config.max_body_style, 4, 0, SHRT_MAX, },
{ "save_body_style", &battle_config.save_body_style, 0, 0, 1, },
{ "monster_eye_range_bonus", &battle_config.mob_eye_range_bonus, 0, 0, 10, },
{ "monster_stuck_warning", &battle_config.mob_stuck_warning, 0, 0, 1, },
};

#ifndef STATS_OPT_OUT
Expand Down
1 change: 1 addition & 0 deletions src/map/battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,7 @@ extern struct Battle_Config
int max_body_style;
int save_body_style;
int mob_eye_range_bonus; //Vulture's Eye and Snake's Eye range bonus
int mob_stuck_warning; //Show warning if a monster is stuck too long
} battle_config;

void do_init_battle(void);
Expand Down
42 changes: 24 additions & 18 deletions src/map/mob.c
Original file line number Diff line number Diff line change
Expand Up @@ -1385,8 +1385,8 @@ int mob_unlocktarget(struct mob_data *md, unsigned int tick)
*------------------------------------------*/
int mob_randomwalk(struct mob_data *md,unsigned int tick)
{
const int retrycount=20;
int i,c,d;
const int d=7;
int i,c,r,dx,dy;
int speed;

nullpo_ret(md);
Expand All @@ -1397,26 +1397,32 @@ int mob_randomwalk(struct mob_data *md,unsigned int tick)
!(status_get_mode(&md->bl)&MD_CANMOVE))
return 0;

d =12-md->move_fail_count;
if(d<5) d=5;
if(d>7) d=7;
for(i=0;i<retrycount;i++){ // Search of a movable place
int r=rnd();
int x=r%(d*2+1)-d;
int y=r/(d*2+1)%(d*2+1)-d;
x+=md->bl.x;
y+=md->bl.y;

r=rnd();
dx=r%(d*2+1)-d;
dy=r/(d*2+1)%(d*2+1)-d;
for(i=0;i<d*d;i++){ // Search of a movable place
int x = dx + md->bl.x;
int y = dy + md->bl.y;
if(((x != md->bl.x) || (y != md->bl.y)) && map_getcell(md->bl.m,x,y,CELL_CHKPASS) && unit_walktoxy(&md->bl,x,y,8)){
break;
}
// Could not move to cell, try the next one
if (++dx>d) {
dx=-d;
if (++dy>d) {
dy=-d;
}
}
}
if(i==retrycount){
md->move_fail_count++;
if(md->move_fail_count>1000){
ShowWarning("MOB can't move. random spawn %d, class = %d, at %s (%d,%d)\n",md->bl.id,md->mob_id,map[md->bl.m].name, md->bl.x, md->bl.y);
md->move_fail_count=0;
mob_spawn(md);
if(i==d*d){
// None of the available cells worked, try again next interval
if(battle_config.mob_stuck_warning) {
md->move_fail_count++;
if(md->move_fail_count>1000){
ShowWarning("MOB can't move. random spawn %d, class = %d, at %s (%d,%d)\n",md->bl.id,md->mob_id,map[md->bl.m].name, md->bl.x, md->bl.y);
md->move_fail_count=0;
mob_spawn(md);
}
}
return 0;
}
Expand Down

0 comments on commit 78419ba

Please sign in to comment.