- Multiple optimizations to the unit_data auto-chase upgrade, also simplified the mob and pet ai routines.

- Simplified the walk routines to half the number of timers required for walking.


git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@5982 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
skotlex 2006-04-11 04:10:41 +00:00
parent 3acdfa691b
commit 42c6f89d86
8 changed files with 138 additions and 162 deletions

View File

@ -4,6 +4,10 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
2006/04/10
* Multiple optimizations to the unit_data auto-chase upgrade, also
simplified the mob and pet ai routines. [Skotlex]
* Simplified the walk routines to half the number of timers required for
walking. [Skotlex]
* Finished fixing the unit_data auto-chase update. Still need to do some
optimizations... but the current code-base should be usable. [Skotlex]
* Fixes to the unit_data update that lets characters auto-chase while

View File

@ -69,7 +69,7 @@ static int battle_gettargeted_sub(struct block_list *bl, va_list ap)
ud = unit_bl2ud(bl);
if (!ud) return 0;
if (ud->attacktarget == target_id || ud->skilltarget == target_id) {
if (ud->target == target_id || ud->skilltarget == target_id) {
bl_list[(*c)++] = bl;
return 1;
}
@ -96,7 +96,7 @@ int battle_gettarget(struct block_list *bl)
switch (bl->type)
{
case BL_PC:
return ((struct map_session_data*)bl)->ud.attacktarget;
return ((struct map_session_data*)bl)->ud.target;
case BL_MOB:
return ((struct mob_data*)bl)->target_id;
case BL_PET:

View File

@ -357,9 +357,8 @@ struct unit_data {
short skillid,skilllv;
int skilltarget;
int skilltimer;
int attacktarget;
int target;
int attacktimer;
int walktarget;
int walktimer;
int chaserange;
unsigned int attackabletime;

View File

@ -935,8 +935,8 @@ static int mob_ai_sub_hard_slavemob(struct mob_data *md,unsigned int tick)
if (ud) {
struct block_list *tbl=NULL;
if (ud->attacktarget && ud->attacktimer != -1)
tbl=map_id2bl(ud->attacktarget);
if (ud->target && ud->attacktimer != -1)
tbl=map_id2bl(ud->target);
else if (ud->skilltarget) {
tbl = map_id2bl(ud->skilltarget);
//Required check as skilltarget is not always an enemy. [Skotlex]
@ -967,7 +967,6 @@ int mob_unlocktarget(struct mob_data *md,int tick)
md->state.skillstate=MSS_IDLE;
md->next_walktime=tick+rand()%3000+3000;
mob_stop_attack(md);
md->ud.attacktarget = md->ud.walktarget = 0;
return 0;
}
/*==========================================
@ -1068,7 +1067,9 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
{ //Check validity of current target. [Skotlex]
tbl = map_id2bl(md->target_id);
if (!tbl || tbl->m != md->bl.m ||
(md->ud.attacktimer == -1 && !status_check_skilluse(&md->bl, tbl, 0, 0)) || (
(md->ud.attacktimer == -1 && !status_check_skilluse(&md->bl, tbl, 0, 0)) ||
(md->ud.walktimer != -1 && !check_distance_bl(&md->bl, tbl, md->min_chase)) ||
(
tbl->type == BL_PC && !(mode&MD_BOSS) &&
((struct map_session_data*)tbl)->state.gangsterparadise
)) { //Unlock current target.
@ -1137,9 +1138,6 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
md->attacked_id = 0;
}
if (md->ud.attacktimer != -1 && tbl && md->ud.attacktarget == tbl->id)
return 0; //Already attacking the current target.
// Processing of slave monster, is it needed when there's a target to deal with?
if (md->master_id > 0 && !tbl)
mob_ai_sub_hard_slavemob(md, tick);
@ -1167,47 +1165,48 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
if (tbl->type != BL_ITEM)
{ //Attempt to attack.
//At this point we know the target is attackable, we just gotta check if the range matches.
if (md->ud.target == tbl->id && md->ud.attacktimer != -1)
return 0; //Already locked.
if (!battle_check_range (&md->bl, tbl, md->db->range))
{ //Out of range...
mob_stop_attack(md);
if (!(mode&MD_CANMOVE))
{ //Can't chase. Attempt to use a ranged skill at least?
mobskill_use(md, tick, MSC_LONGRANGEATTACKED);
mob_unlocktarget(md,tick);
return 0;
}
//Follow up
if (!mob_can_reach(md, tbl, md->min_chase, MSS_RUSH))
{ //Give up.
mob_unlocktarget(md,tick);
return 0;
}
md->state.skillstate = md->state.aggressive?MSS_FOLLOW:MSS_RUSH;
if (md->ud.walktimer != -1 && md->ud.walktarget == tbl->id &&
if (md->ud.walktimer != -1 && md->ud.target == tbl->id &&
(
!battle_config.mob_ai&1 ||
check_distance_blxy(tbl, md->ud.to_x, md->ud.to_y, md->db->range)
)) //Current target tile is still within attack range.
return 0;
//Target reachable. Locate suitable spot to move to.
unit_walktobl(&md->bl, tbl, md->db->range, 2|(!battle_config.mob_ai&1));
//Follow up
if (!mob_can_reach(md, tbl, md->min_chase, MSS_RUSH) ||
!unit_walktobl(&md->bl, tbl, md->db->range, 2|(!battle_config.mob_ai&1)))
//Give up.
mob_unlocktarget(md,tick);
return 0;
}
//Target within range, engage
mob_stop_walking(md,1);
md->state.skillstate = md->state.aggressive?MSS_ANGRY:MSS_BERSERK;
unit_attack(&md->bl,tbl->id,1);
return 0;
} else { //Target is BL_ITEM, attempt loot.
struct flooritem_data *fitem;
int i;
if (md->ud.target == tbl->id && md->ud.walktimer != -1)
return 0; //Already locked.
if (md->lootitem == NULL)
{ //Can't loot...
mob_unlocktarget (md, tick);
mob_stop_walking(md,0);
return 0;
}
if (!check_distance_bl(&md->bl, tbl, 1))
{ //Still not within loot range.
if (!(mode&MD_CANMOVE))
@ -1218,9 +1217,6 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
if (!can_move) // 動けない状態にある
return 0;
md->state.skillstate = MSS_LOOT; // ルート時スキル使用
if (md->ud.walktimer != -1 && md->ud.walktarget == tbl->id)
//Already on the way to looting.
return 0;
if (!unit_walktobl(&md->bl, tbl, 0, 1))
mob_unlocktarget(md, tick); //Can't loot...
return 0;
@ -1228,7 +1224,6 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
//Within looting range.
if (md->ud.attacktimer != -1)
return 0; //Busy attacking?
mob_stop_walking(md,0);
fitem = (struct flooritem_data *)tbl;
if (md->lootitem_count < LOOTITEM_SIZE) {

View File

@ -123,7 +123,7 @@ int pet_unlocktarget(struct pet_data *pd)
pd->target_id=0;
pet_stop_attack(pd);
pd->ud.attacktarget = pd->ud.walktarget = 0;
pet_stop_walking(pd,1);
return 0;
}
@ -960,7 +960,7 @@ static int pet_ai_sub_hard(struct pet_data *pd,unsigned int tick)
//Master too far, chase.
if(pd->target_id)
pet_unlocktarget(pd);
if(pd->ud.walktimer != -1 && pd->ud.walktarget == sd->bl.id)
if(pd->ud.walktimer != -1 && pd->ud.target == sd->bl.id)
return 0; //Already walking to him
pd->speed = (sd->speed>>1);
@ -1007,36 +1007,28 @@ static int pet_ai_sub_hard(struct pet_data *pd,unsigned int tick)
return 0;
}
if(pd->ud.target == target->id &&
(pd->ud.attacktimer != -1 || pd->ud.walktimer != -1))
return 0; //Target already locked.
if (target->type != BL_ITEM)
{ //enemy targetted
if(!battle_check_range(&pd->bl,target,pd->db->range))
{ //Chase
if(pd->ud.walktimer != -1 && check_distance_blxy(target, pd->ud.to_x,pd->ud.to_y, pd->db->range))
return 0;
if(!unit_walktobl(&pd->bl, target, pd->db->range, 2))
{ //Unreachable target.
pet_unlocktarget(pd);
}
pet_unlocktarget(pd); //Unreachable target.
return 0;
} //End Chase
pet_stop_walking(pd,1);
if (pd->ud.attacktimer != -1 && pd->ud.attacktarget == pd->target_id)
return 0; //Already attacking.
}
//Continuous attack.
unit_attack(&pd->bl, pd->target_id, 1);
} else { //Item Targeted, attempt loot
if (!check_distance_bl(&pd->bl, target, 1))
{ //Out of range
if(pd->ud.walktimer != -1 && pd->ud.walktarget == pd->target_id)
return 0;
if(!unit_walktobl(&pd->bl, target, 0, 1)) //Unreachable target.
pet_unlocktarget(pd);
return 0;
} else{ // アイテムまでたどり着いた
} else{
struct flooritem_data *fitem = (struct flooritem_data *)target;
pet_stop_walking(pd,1);
if(pd->loot->count < pd->loot->max){
memcpy(&pd->loot->item[pd->loot->count++],&fitem->item_data,sizeof(pd->loot->item[0]));
pd->loot->weight += itemdb_search(fitem->item_data.nameid)->weight*fitem->item_data.amount;

View File

@ -10405,8 +10405,8 @@ int buildin_mobassist(struct script_state *st) {
ud = unit_bl2ud(bl);
md->master_id = bl->id;
if (ud) {
if (ud->attacktarget)
md->target_id = ud->attacktarget;
if (ud->target)
md->target_id = ud->target;
else if (ud->skilltarget)
md->target_id = ud->skilltarget;
md->min_chase = distance_bl(&md->bl,map_id2bl(md->target_id)) + md->db->range2;

View File

@ -3418,8 +3418,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
if (!bl) bl = src;
unit_skilluse_id(src, bl->id, abra_skillid, abra_skilllv);
} else { //Assume offensive skills
if (ud->attacktarget)
target_id = ud->attacktarget;
if (ud->target)
target_id = ud->target;
else switch (src->type) {
case BL_MOB:
target_id = ((TBL_MOB*)src)->target_id;

View File

@ -57,7 +57,7 @@ int unit_walktoxy_sub(struct block_list *bl)
memcpy(&ud->walkpath,&wpd,sizeof(wpd));
if (ud->walktarget && ud->chaserange >0) {
if (ud->target && ud->chaserange >0) {
//Trim the last part of the path to account for range.
for (i = ud->chaserange*10; i > 0 && ud->walkpath.path_len>0;) {
int dir;
@ -72,8 +72,8 @@ int unit_walktoxy_sub(struct block_list *bl)
}
if (!ud->walkpath.path_len) {
//Already within requested range.
if (ud->attacktarget == ud->walktarget)
unit_attack(bl, ud->attacktarget, ud->state.attack_continue);
if (ud->target && ud->state.attack_continue)
unit_attack(bl, ud->target, 1);
return 0;
}
}
@ -134,84 +134,80 @@ static int unit_walktoxy_timer(int tid,unsigned int tick,int id,int data)
sd->inchealspirithptick = 0;
sd->inchealspiritsptick = 0;
}
ud->walkpath.path_half ^= 1;
if(ud->walkpath.path_half==0){ // マス目中心へ到着
ud->walkpath.path_pos++;
if(ud->state.change_walk_target) {
unit_walktoxy_sub(bl);
return 0;
if(ud->walkpath.path[ud->walkpath.path_pos]>=8)
return 1;
x = bl->x;
y = bl->y;
dir = ud->walkpath.path[ud->walkpath.path_pos];
ud->dir = dir;
if (sd)
sd->head_dir = dir;
dx = dirx[(int)dir];
dy = diry[(int)dir];
if(map_getcell(bl->m,x+dx,y+dy,CELL_CHKNOPASS))
return unit_walktoxy_sub(bl);
// ƒoƒVƒŠƒJ”»è
map_foreachinmovearea(clif_outsight,bl->m,
x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,
dx,dy,sd?BL_ALL:BL_PC,bl);
x += dx;
y += dy;
map_moveblock(bl, x, y, tick);
ud->walktimer = 1;
map_foreachinmovearea(clif_insight,bl->m,
x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,
-dx,-dy,sd?BL_ALL:BL_PC,bl);
ud->walktimer = -1;
if(sd) {
if(map_getcell(bl->m,x,y,CELL_CHKNPC)) {
npc_touch_areanpc(sd,bl->m,x,y);
if (bl->prev == NULL) //Script could have warped char, abort remaining of the function.
return 0;
} else
sd->areanpc_id=0;
if (sd->state.gmaster_flag)
{ //Guild Aura: Likely needs to be recoded, this method seems inefficient.
struct guild *g = sd->state.gmaster_flag;
int skill, guildflag = 0;
if ((skill = guild_checkskill(g, GD_LEADERSHIP)) > 0) guildflag |= skill<<12;
if ((skill = guild_checkskill(g, GD_GLORYWOUNDS)) > 0) guildflag |= skill<<8;
if ((skill = guild_checkskill(g, GD_SOULCOLD)) > 0) guildflag |= skill<<4;
if ((skill = guild_checkskill(g, GD_HAWKEYES)) > 0) guildflag |= skill;
if (guildflag)
map_foreachinrange(skill_guildaura_sub, bl,2, BL_PC,
bl->id, sd->status.guild_id, &guildflag);
}
} else {
if(ud->walkpath.path[ud->walkpath.path_pos]>=8)
return 1;
x = bl->x;
y = bl->y;
dir = ud->walkpath.path[ud->walkpath.path_pos];
ud->dir = dir;
if (sd)
sd->head_dir = dir;
dx = dirx[(int)dir];
dy = diry[(int)dir];
if(map_getcell(bl->m,x+dx,y+dy,CELL_CHKNOPASS))
return unit_walktoxy_sub(bl);
// バシリカ判定
map_foreachinmovearea(clif_outsight,bl->m,
x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,
dx,dy,sd?BL_ALL:BL_PC,bl);
x += dx;
y += dy;
map_moveblock(bl, x, y, tick);
ud->walktimer = 1;
map_foreachinmovearea(clif_insight,bl->m,
x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,
-dx,-dy,sd?BL_ALL:BL_PC,bl);
ud->walktimer = -1;
if(sd) {
if(map_getcell(bl->m,x,y,CELL_CHKNPC)) {
npc_touch_areanpc(sd,bl->m,x,y);
if (bl->prev == NULL) //Script could have warped char, abort remaining of the function.
return 0;
} else
sd->areanpc_id=0;
if (sd->state.gmaster_flag)
{ //Guild Aura: Likely needs to be recoded, this method seems inefficient.
struct guild *g = sd->state.gmaster_flag;
int skill, guildflag = 0;
if ((skill = guild_checkskill(g, GD_LEADERSHIP)) > 0) guildflag |= skill<<12;
if ((skill = guild_checkskill(g, GD_GLORYWOUNDS)) > 0) guildflag |= skill<<8;
if ((skill = guild_checkskill(g, GD_SOULCOLD)) > 0) guildflag |= skill<<4;
if ((skill = guild_checkskill(g, GD_HAWKEYES)) > 0) guildflag |= skill;
if (guildflag)
map_foreachinrange(skill_guildaura_sub, bl,2, BL_PC,
bl->id, sd->status.guild_id, &guildflag);
}
if (
(sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR &&
sd->sc.data[SC_MIRACLE].timer==-1 &&
ud->walkpath.path_pos && ud->walkpath.path_pos%WALK_SKILL_INTERVAL == 0 &&
rand()%10000 < battle_config.sg_miracle_skill_ratio
) { //SG_MIRACLE [Komurka]
clif_displaymessage(sd->fd,"[Miracle of the Sun, Moon and Stars]");
sc_start(&sd->bl,SC_MIRACLE,100,1,battle_config.sg_miracle_skill_duration);
}
} else if (md) {
if (ud->attacktarget) {
if(md->min_chase > md->db->range2) md->min_chase--;
if(ud->walkpath.path_pos && ud->walkpath.path_pos%WALK_SKILL_INTERVAL == 0 &&
mobskill_use(md, tick, -1))
return 0;
}
if (
(sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR &&
sd->sc.data[SC_MIRACLE].timer==-1 &&
ud->walkpath.path_pos && ud->walkpath.path_pos%WALK_SKILL_INTERVAL == 0 &&
rand()%10000 < battle_config.sg_miracle_skill_ratio
) { //SG_MIRACLE [Komurka]
clif_displaymessage(sd->fd,"[Miracle of the Sun, Moon and Stars]");
sc_start(&sd->bl,SC_MIRACLE,100,1,battle_config.sg_miracle_skill_duration);
}
} else if (md) {
if (ud->target && ud->state.attack_continue) {
if(md->min_chase > md->db->range2) md->min_chase--;
if(ud->walkpath.path_pos && ud->walkpath.path_pos%WALK_SKILL_INTERVAL == 0 &&
mobskill_use(md, tick, -1))
return 0;
}
}
if(ud->state.change_walk_target)
return unit_walktoxy_sub(bl);
ud->walkpath.path_pos++;
if(ud->walkpath.path_pos>=ud->walkpath.path_len)
i = -1;
else if(ud->walkpath.path[ud->walkpath.path_pos]&1)
@ -219,16 +215,13 @@ static int unit_walktoxy_timer(int tid,unsigned int tick,int id,int data)
else
i = status_get_speed(bl);
if(i > 0) {
i = i>>1;
// if(i < 1 && ud->walkpath.path_half == 0)
// i = 1;
if(i > 0)
ud->walktimer = add_timer(tick+i,unit_walktoxy_timer,id,ud->walkpath.path_pos);
} else if(sd && sd->sc.count && sd->sc.data[SC_RUN].timer!=-1) //Keep trying to run.
else if(sd && sd->sc.count && sd->sc.data[SC_RUN].timer!=-1) //Keep trying to run.
pc_run(sd, sd->sc.data[SC_RUN].val1, sd->sc.data[SC_RUN].val2);
else if (ud->walktarget) {
else if (ud->target) {
//Update target trajectory.
struct block_list *tbl = map_id2bl(ud->walktarget);
struct block_list *tbl = map_id2bl(ud->target);
if (!tbl) { //Cancel chase.
ud->to_x = bl->x;
ud->to_y = bl->y;
@ -236,10 +229,10 @@ static int unit_walktoxy_timer(int tid,unsigned int tick,int id,int data)
}
if (tbl->m == bl->m && check_distance_bl(bl, tbl, ud->chaserange))
{ //Reached destination.
if (ud->attacktarget == tbl->id)
if (ud->state.attack_continue)
unit_attack(bl, tbl->id, ud->state.attack_continue);
} else { //Update chase-path
unit_walktobl(bl, tbl, ud->chaserange, ud->state.walk_easy);
unit_walktobl(bl, tbl, ud->chaserange, ud->state.walk_easy|(ud->state.attack_continue?2:0));
return 0;
}
} else { //Stopped walking. Update to_x and to_y to current location [Skotlex]
@ -266,7 +259,7 @@ int unit_walktoxy( struct block_list *bl, int x, int y, int easy) {
return 0;
ud->state.walk_easy = easy;
ud->walktarget = 0;
ud->target = 0;
ud->to_x = x;
ud->to_y = y;
@ -289,7 +282,7 @@ static int unit_walktobl_sub(int tid,unsigned int tick,int id,int data)
struct block_list *bl = map_id2bl(id);
struct unit_data *ud = bl?unit_bl2ud(bl):NULL;
if (ud && ud->walktimer == -1 && ud->walktarget == data)
if (ud && ud->walktimer == -1 && ud->target == data)
{
if (DIFF_TICK(ud->canmove_tick, tick) > 0) //Keep waiting?
add_timer(ud->canmove_tick+1, unit_walktobl_sub, id, data);
@ -300,7 +293,7 @@ static int unit_walktobl_sub(int tid,unsigned int tick,int id,int data)
}
// Chases a tbl. If the flag&1, use hard-path seek,
// if flag&2, start attacking upon arrival within range.
// if flag&2, start attacking upon arrival within range, otherwise just walk to that character.
int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, int flag) {
struct unit_data *ud = NULL;
struct status_change *sc = NULL;
@ -320,17 +313,14 @@ int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, int
}
ud->state.walk_easy = flag&1;
ud->walktarget = tbl->id;
ud->target = tbl->id;
ud->chaserange = range;
ud->state.attack_continue = flag&2?1:0; //Chase to attack.
sc = status_get_sc(bl);
if (sc && sc->count && sc->data[SC_CONFUSION].timer != -1) //Randomize the target position
map_random_dir(bl, &ud->to_x, &ud->to_y);
if (flag&2) { //Chase to attack.
ud->attacktarget = tbl->id;
ud->state.attack_continue = 1;
}
if(ud->walktimer != -1) {
ud->state.change_walk_target = 1;
@ -338,7 +328,7 @@ int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, int
}
if (DIFF_TICK(ud->canmove_tick, gettick()) > 0)
{ //Can't move, wait a bit before invoking the movement.
add_timer(ud->canmove_tick+1, unit_walktobl_sub, bl->id, ud->walktarget);
add_timer(ud->canmove_tick+1, unit_walktobl_sub, bl->id, ud->target);
return 1;
} else if (!unit_can_move(bl))
return 0;
@ -651,8 +641,8 @@ int unit_set_walkdelay(struct block_list *bl, unsigned int tick, int delay, int
delete_timer(ud->walktimer, unit_walktoxy_timer);
ud->walktimer = -1;
clif_fixpos(bl);
if(ud->walktarget)
add_timer(ud->canmove_tick+1, unit_walktobl_sub, bl->id, ud->walktarget);
if(ud->target)
add_timer(ud->canmove_tick+1, unit_walktobl_sub, bl->id, ud->target);
}
return 1;
}
@ -722,8 +712,8 @@ int unit_skilluse_id2(struct block_list *src, int target_id, int skill_num, int
temp = (target_id == src->id && !(sd && sd->state.skill_flag)
&& skill_get_inf(skill_num)&INF_SELF_SKILL
&& skill_get_inf2(skill_num)&INF2_NO_TARGET_SELF);
if (temp)
target_id = ud->attacktarget; //Auto-select skills. [Skotlex]
if (temp)
target_id = ud->target; //Auto-select skills. [Skotlex]
if (sd) {
//Target_id checking.
@ -1064,8 +1054,8 @@ int unit_stop_attack(struct block_list *bl)
int unit_unattackable(struct block_list *bl) {
struct unit_data *ud = unit_bl2ud(bl);
if (ud) {
ud->attacktarget = 0;
ud->walktarget = 0;
ud->target = 0;
ud->state.attack_continue = 0;
}
if(bl->type == BL_MOB)
@ -1106,12 +1096,10 @@ int unit_attack(struct block_list *src,int target_id,int type)
return 1;
}
ud->attacktarget = target_id;
ud->target = target_id;
ud->state.attack_continue = type;
if (type) { //If you re to attack continously, set to auto-case character
ud->walktarget = target_id;
if (type) //If you re to attack continously, set to auto-case character
ud->chaserange = status_get_range(src);
}
//Just change target/type. [Skotlex]
if(ud->attacktimer != -1)
@ -1222,7 +1210,7 @@ static int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int t
BL_CAST( BL_PC , src, sd);
BL_CAST( BL_MOB, src, md);
ud->attacktimer=-1;
target=map_id2bl(ud->attacktarget);
target=map_id2bl(ud->target);
if(src->prev == NULL || target==NULL || target->prev == NULL)
return 0;
@ -1252,26 +1240,24 @@ static int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int t
range = status_get_range(src);
if(ud->walktimer != -1) range++; //Extra range when walking.
if(!sd || sd->status.weapon != 11) range++; //Dunno why everyone but bows gets this extra range...
if(unit_is_walking(target)) range++; //Extra range when chasing
if(!check_distance_bl(src,target,range) ) {
//Chase if required.
if(ud->state.attack_continue && ud->walktarget == target->id) {
if(ud->state.attack_continue) {
if(sd)
clif_movetoattack(sd,target);
else
unit_walktobl(src,target,ud->chaserange,ud->state.walk_easy);
unit_walktobl(src,target,ud->chaserange,ud->state.walk_easy|2);
}
return 1;
}
if(!battle_check_range(src,target,range)) {
//Within range, but no direct line of attack
if(ud->state.attack_continue && ud->walktarget == target->id) {
if(ud->state.attack_continue) {
if(ud->chaserange > 2) ud->chaserange-=2;
unit_walktobl(src,target,ud->chaserange,ud->state.walk_easy);
ud->attacktimer = add_timer(tick + status_get_adelay(src),unit_attack_timer,src->id,0);
unit_walktobl(src,target,ud->chaserange,ud->state.walk_easy|2);
}
return 1;
}
@ -1422,7 +1408,7 @@ static int unit_counttargeted_sub(struct block_list *bl, va_list ap)
ud = unit_bl2ud(bl);
if (ud && ud->attacktarget == id && ud->attacktimer != -1 && ud->attacktarget_lv >= target_lv)
if (ud && ud->target == id && ud->attacktimer != -1 && ud->attacktarget_lv >= target_lv)
return 1;
return 0;
@ -1463,7 +1449,7 @@ int unit_counttargeted(struct block_list *bl,int target_lv)
int unit_mobstopattacked(struct map_session_data *sd,va_list ap)
{
int id=va_arg(ap,int);
if(sd->ud.attacktarget==id)
if(sd->ud.target==id)
unit_stop_attack(&sd->bl);
return 0;
}