- 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:
parent
3acdfa691b
commit
42c6f89d86
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
214
src/map/unit.c
214
src/map/unit.c
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user