- Moved the idle state random walk and idle skill triggering to mob_unlock_target, since our current AI has some execution paths where these would never be triggered.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@10240 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
skotlex 2007-04-12 18:41:55 +00:00
parent ef10fe3a04
commit aa0e780bd5

View File

@ -990,6 +990,9 @@ static int mob_ai_sub_hard_slavemob(struct mob_data *md,unsigned int tick)
/*========================================== /*==========================================
* A lock of target is stopped and mob moves to a standby state. * A lock of target is stopped and mob moves to a standby state.
* This also triggers idle skill/movement since the AI can get stuck
* when trying to pick new targets when the current chosen target is
* unreachable.
*------------------------------------------ *------------------------------------------
*/ */
int mob_unlocktarget(struct mob_data *md,int tick) int mob_unlocktarget(struct mob_data *md,int tick)
@ -999,11 +1002,31 @@ int mob_unlocktarget(struct mob_data *md,int tick)
if(md->nd) if(md->nd)
mob_script_callback(md, map_id2bl(md->target_id), CALLBACK_UNLOCK); mob_script_callback(md, map_id2bl(md->target_id), CALLBACK_UNLOCK);
md->target_id=0; switch (md->state.skillstate) {
md->state.skillstate=MSS_IDLE; case MSS_IDLE:
md->next_walktime=tick+rand()%3000+3000; // Idle skill.
mob_stop_attack(md); if (!(++md->ud.walk_count%IDLE_SKILL_INTERVAL) &&
md->ud.target = 0; mobskill_use(md, tick, -1))
break;
//Random walk.
if (!md->master_id &&
DIFF_TICK(md->next_walktime, tick) <= 0 &&
!mob_randomwalk(md,tick))
//Delay next random walk when this one failed.
md->next_walktime=tick+rand()%3000;
break;
case MSS_WALK:
break;
default:
mob_stop_attack(md);
if (battle_config.mob_ai&0x8)
mob_stop_walking(md,1); //Inmediately stop chasing.
md->state.skillstate = MSS_IDLE;
md->target_id=0;
md->ud.target = 0;
md->next_walktime=tick+rand()%3000+3000;
break;
}
return 0; return 0;
} }
/*========================================== /*==========================================
@ -1119,8 +1142,7 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
map_foreachinrange (mob_ai_sub_hard_warpsearch, &md->bl, map_foreachinrange (mob_ai_sub_hard_warpsearch, &md->bl,
view_range, BL_NPC, md, &tbl); view_range, BL_NPC, md, &tbl);
if (tbl) unit_walktobl(&md->bl, tbl, 0, 1); if (tbl) unit_walktobl(&md->bl, tbl, 0, 1);
} else if (battle_config.mob_ai&0x8) //Inmediately stop chasing. }
mob_stop_walking(md,1);
mob_unlocktarget(md, tick-(battle_config.mob_ai&0x8?3000:0)); //Imediately do random walk. mob_unlocktarget(md, tick-(battle_config.mob_ai&0x8?3000:0)); //Imediately do random walk.
tbl = NULL; tbl = NULL;
} }
@ -1214,16 +1236,8 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
if (!tbl) { //No targets available. if (!tbl) { //No targets available.
if (mode&MD_ANGRY && !md->state.aggressive) if (mode&MD_ANGRY && !md->state.aggressive)
md->state.aggressive = 1; //Restore angry state when no targets are available. md->state.aggressive = 1; //Restore angry state when no targets are available.
//This handles triggering idle walk/skill.
if(md->ud.walktimer == -1) { mob_unlocktarget(md, tick);
// Idle skill.
md->state.skillstate = MSS_IDLE;
if (!(++md->ud.walk_count%IDLE_SKILL_INTERVAL) && mobskill_use(md, tick, -1))
return 0;
}
// Random walk.
if (can_move && !md->master_id && DIFF_TICK(md->next_walktime, tick) <= 0)
mob_randomwalk(md,tick);
return 0; return 0;
} }
@ -1236,7 +1250,6 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
if (md->lootitem == NULL) if (md->lootitem == NULL)
{ //Can't loot... { //Can't loot...
mob_unlocktarget (md, tick); mob_unlocktarget (md, tick);
mob_stop_walking(md,0);
return 0; return 0;
} }
if (!check_distance_bl(&md->bl, tbl, 1)) if (!check_distance_bl(&md->bl, tbl, 1))
@ -1316,19 +1329,10 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
return 0; return 0;
//Follow up if possible. //Follow up if possible.
if (mob_can_reach(md, tbl, md->min_chase, MSS_RUSH) && if(!mob_can_reach(md, tbl, md->min_chase, MSS_RUSH) ||
unit_walktobl(&md->bl, tbl, md->status.rhw.range, 2)) !unit_walktobl(&md->bl, tbl, md->status.rhw.range, 2))
return 0; //Chasing.
//Can't chase locked target. Return to IDLE.
if(md->state.skillstate == MSS_IDLE ||
md->state.skillstate == MSS_WALK)
{ //Mob is already idle, try a idle skill before giving up.
if (!(++md->ud.walk_count%IDLE_SKILL_INTERVAL))
mobskill_use(md, tick, -1);
md->target_id=0;
} else
mob_unlocktarget(md,tick); mob_unlocktarget(md,tick);
return 0; return 0;
} }