Monster random walk code optimized (fixes #208)
* 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
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user