summaryrefslogtreecommitdiff
path: root/src/map/mob.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/mob.c')
-rw-r--r--src/map/mob.c78
1 files changed, 42 insertions, 36 deletions
diff --git a/src/map/mob.c b/src/map/mob.c
index cdd842075..122cc91aa 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -52,7 +52,9 @@ struct mob_interface mob_s;
#define IDLE_SKILL_INTERVAL 10 //Active idle skills should be triggered every 1 second (1000/MIN_MOBTHINKTIME)
-#define MOB_LAZYSKILLPERC 0 // Probability for mobs far from players from doing their IDLE skill. (rate of 1000 minute)
+// Probability for mobs far from players from doing their IDLE skill. (rate of 1000 minute)
+// in Aegis, this is 100% for mobs that have been activated by players and none otherwise.
+#define MOB_LAZYSKILLPERC(md) (md->state.spotted?1000:0)
// Move probability for mobs away from players (rate of 1000 minute)
// in Aegis, this is 100% for mobs that have been activated by players and none otherwise.
#define MOB_LAZYMOVEPERC(md) ((md)->state.spotted?1000:0)
@@ -946,7 +948,7 @@ int mob_spawn (struct mob_data *md)
md->state.aggressive = md->status.mode&MD_ANGRY?1:0;
md->state.skillstate = MSS_IDLE;
- md->next_walktime = tick+rnd()%5000+1000;
+ md->next_walktime = tick+rnd()%1000+MIN_RANDOMWALKTIME;
md->last_linktime = tick;
md->dmgtick = tick - 5000;
md->last_pcneartime = 0;
@@ -1294,13 +1296,16 @@ int mob_unlocktarget(struct mob_data *md, int64 tick) {
DIFF_TICK(md->next_walktime, tick) <= 0 &&
!mob->randomwalk(md,tick))
//Delay next random walk when this one failed.
- md->next_walktime=tick+rnd()%3000;
+ md->next_walktime = tick+rnd()%1000;
break;
default:
mob_stop_attack(md);
mob_stop_walking(md,1); //Stop chasing.
md->state.skillstate = MSS_IDLE;
- md->next_walktime=tick+rnd()%3000+3000;
+ if(battle_config.mob_ai&0x8) //Walk instantly after dropping target
+ md->next_walktime = tick+rnd()%1000;
+ else
+ md->next_walktime = tick+rnd()%1000+MIN_RANDOMWALKTIME;
break;
}
if (md->target_id) {
@@ -1327,6 +1332,7 @@ int mob_randomwalk(struct mob_data *md, int64 tick) {
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();
x=r%(d*2+1)-d;
@@ -1334,7 +1340,7 @@ int mob_randomwalk(struct mob_data *md, int64 tick) {
x+=md->bl.x;
y+=md->bl.y;
- if((map->getcell(md->bl.m,x,y,CELL_CHKPASS)) && unit->walktoxy(&md->bl,x,y,1)){
+ if(((x != md->bl.x) || (y != md->bl.y)) && map->getcell(md->bl.m,x,y,CELL_CHKPASS) && unit->walktoxy(&md->bl,x,y,0)){
break;
}
}
@@ -1357,7 +1363,7 @@ int mob_randomwalk(struct mob_data *md, int64 tick) {
}
md->state.skillstate=MSS_WALK;
md->move_fail_count=0;
- md->next_walktime = tick+rnd()%3000+3000+c;
+ md->next_walktime = tick+rnd()%1000+MIN_RANDOMWALKTIME+c;
return 1;
}
@@ -1435,7 +1441,7 @@ bool mob_ai_sub_hard(struct mob_data *md, int64 tick) {
return true; //Chasing this target.
if(md->ud.walktimer != INVALID_TIMER && md->ud.walkpath.path_pos <= battle_config.mob_chase_refresh)
return true; //Walk at least "mob_chase_refresh" cells before dropping the target
- mob_unlocktarget(md, tick-(battle_config.mob_ai&0x8?3000:0)); //Immediately do random walk.
+ mob_unlocktarget(md, tick); //Unlock target
tbl = NULL;
}
}
@@ -1627,26 +1633,24 @@ bool mob_ai_sub_hard(struct mob_data *md, int64 tick) {
}
//Out of range...
- if (!(mode&MD_CANMOVE))
- { //Can't chase. Attempt an idle skill before unlocking.
- if (md->ud.target != tbl->id || md->ud.attacktimer == INVALID_TIMER)
- { //Only use skill if no more attack delay left
- md->state.skillstate = MSS_IDLE;
- if (!mob->skill_use(md, tick, -1))
- mob->unlocktarget(md,tick);
+ if (!(mode&MD_CANMOVE) || (!can_move && DIFF_TICK(tick, md->ud.canmove_tick) > 0))
+ { //Can't chase. Immobile and trapped mobs should unlock target and use an idle skill on next interval.
+ if ((md->ud.target != tbl->id || md->ud.attacktimer == INVALID_TIMER))
+ { //Only unlock target to use idle skill if no more attack left
+ md->ud.walk_count = (md->ud.walk_count+1)%250;
+ if (!(md->ud.walk_count%IDLE_SKILL_INTERVAL))
+ mob_unlocktarget(md,tick);
}
return true;
- }
+ }
- if (!can_move)
- { //Stuck. Attempt an idle skill
- if (md->ud.target != tbl->id || md->ud.attacktimer == INVALID_TIMER)
- { //Only use skill if no more attack delay left
- md->state.skillstate = MSS_IDLE;
- if (!(++md->ud.walk_count%IDLE_SKILL_INTERVAL))
+ //Before a monster starts to chase a target, it will check if it has a ranged "attack" skill to use on it.
+ if(md->ud.walktimer == INVALID_TIMER && (md->state.skillstate == MSS_BERSERK || md->state.skillstate == MSS_ANGRY))
+ {
+ if (DIFF_TICK(md->ud.canmove_tick, tick) <= MIN_MOBTHINKTIME && DIFF_TICK(md->ud.canact_tick, tick) < -MIN_MOBTHINKTIME*IDLE_SKILL_INTERVAL)
+ { //Only use skill if able to walk on next tick and not used a skill the last second
mob->skill_use(md, tick, -1);
}
- return true;
}
if (md->ud.walktimer != INVALID_TIMER && md->ud.target == tbl->id &&
@@ -1661,6 +1665,7 @@ bool mob_ai_sub_hard(struct mob_data *md, int64 tick) {
return true;
//Follow up if possible.
+ //Hint: Chase skills are handled in the walktobl routine
if(!mob->can_reach(md, tbl, md->min_chase, MSS_RUSH) ||
!unit->walktobl(&md->bl, tbl, md->status.rhw.range, 2))
mob->unlocktarget(md,tick);
@@ -1741,20 +1746,17 @@ int mob_ai_sub_lazy(struct mob_data *md, va_list args) {
}
if( DIFF_TICK(md->next_walktime,tick) < 0 && (status_get_mode(&md->bl)&MD_CANMOVE) && unit->can_move(&md->bl) ) {
- if( map->list[md->bl.m].users > 0 )
- {
- if( rnd()%1000 < MOB_LAZYMOVEPERC(md) )
- mob->randomwalk(md, tick);
- else
- if( rnd()%1000 < MOB_LAZYSKILLPERC ) //Chance to do a mob's idle skill.
- mob->skill_use(md, tick, -1);
- }
- else
- {
- if( rnd()%1000 < MOB_LAZYMOVEPERC(md) )
- mob->randomwalk(md, tick);
- }
+ if( rnd()%1000 < MOB_LAZYMOVEPERC(md) )
+ mob_randomwalk(md, tick);
+ }
+ else if( md->ud.walktimer == INVALID_TIMER )
+ {
+ //Because it is not unset when the mob finishes walking.
+ md->state.skillstate = MSS_IDLE;
+ if( rnd()%1000 < MOB_LAZYSKILLPERC(md) ) //Chance to do a mob's idle skill.
+ mob->skill_use(md, tick, -1);
}
+
return 0;
}
@@ -2647,7 +2649,7 @@ void mob_revive(struct mob_data *md, unsigned int hp)
int64 tick = timer->gettick();
md->state.skillstate = MSS_IDLE;
md->last_thinktime = tick;
- md->next_walktime = tick+rnd()%50+5000;
+ md->next_walktime = tick+rnd()%1000+MIN_RANDOMWALKTIME;
md->last_linktime = tick;
md->last_pcneartime = 0;
memset(md->dmglog, 0, sizeof(md->dmglog)); // Reset the damage done on the rebirthed monster, otherwise will grant full exp + damage done. [Valaris]
@@ -3717,6 +3719,10 @@ bool mob_parse_dbrow(char** str) {
if (mstatus->dex < 1) mstatus->dex = 1;
if (mstatus->luk < 1) mstatus->luk = 1;
+ //Tests showed that chase range is effectively 2 cells larger than expected [Playtester]
+ if (db->range3 > 0)
+ db->range3 += 2;
+
db->range2 = atoi(str[20]);
db->range3 = atoi(str[21]);
if (battle_config.view_range_rate != 100) {