- Added state.running to unit_data to make it easier to check for running characters (saves having to get the sc data and check for the corresponding timer all the time)
- removed pc_run, pc_walktodir, replaced with unit_run. - moved the code that makes you walk that extra cell to unit_stop_walking, which is now invoked before resetting the walk-target. - Flag &2 in unit_stop_walking is now to make the character force-move that extra tile if the walkpath pos is 0 at hit time. - Added variable walk_count to unit_data to be use as a counter for cells walked for walk-triggered skills (walk path_pos is not good enough since it keeps resetting each time the walk path is updated) - Increased WALK_SKILL_INTERVAL to 5 (it is the closest value that makes the average mob trigger a chase skill every second) git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@6137 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
c9112b1fd8
commit
3a2c267be6
@ -4,6 +4,13 @@ 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/17
|
||||
* Some cleanup in the TK_RUN related code. [Skotlex]
|
||||
* Added variable walk_count to unit_data to be use as a counter for cells
|
||||
walked for walk-triggered skills, on-chase skill triggers are now done
|
||||
every 5 cells (it is the closest value that makes the average mob trigger a
|
||||
chase skill every second). [Skotlex]
|
||||
* mob_skill_db needs updating since it's current use rates for chase-skills
|
||||
assume the trigger is every 100ms rather than every second.
|
||||
* Fixed TK_RUN having a cast-bar when attempting to stop-running and
|
||||
generating timer_delete errors when halting as well. [Skotlex]
|
||||
* Clearing the dummy npc after fooling the client. [Lance]
|
||||
|
@ -365,11 +365,13 @@ struct unit_data {
|
||||
unsigned int canact_tick;
|
||||
unsigned int canmove_tick;
|
||||
unsigned char dir;
|
||||
unsigned char walk_count;
|
||||
struct {
|
||||
unsigned change_walk_target : 1 ;
|
||||
unsigned skillcastcancel : 1 ;
|
||||
unsigned attack_continue : 1 ;
|
||||
unsigned walk_easy : 1 ;
|
||||
unsigned running : 1;
|
||||
} state;
|
||||
};
|
||||
|
||||
|
@ -1049,7 +1049,7 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
|
||||
return 0;
|
||||
|
||||
if( md->ud.walktimer != -1 && md->ud.walkpath.path_pos <= 3)
|
||||
return 0; //Prevent ai when it just started walking.
|
||||
return 0;
|
||||
|
||||
// Abnormalities
|
||||
if((md->sc.opt1 > 0 && md->sc.opt1 != OPT1_STONEWAIT) || md->sc.data[SC_BLADESTOP].timer != -1)
|
||||
@ -1077,7 +1077,7 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
|
||||
((struct map_session_data*)tbl)->state.gangsterparadise
|
||||
)) { //Unlock current target.
|
||||
if (battle_config.mob_ai&8) //Inmediately stop chasing.
|
||||
mob_stop_walking(md,2);
|
||||
mob_stop_walking(md,1);
|
||||
mob_unlocktarget(md, tick-(battle_config.mob_ai&8?3000:0)); //Imediately do random walk.
|
||||
tbl = NULL;
|
||||
}
|
||||
|
70
src/map/pc.c
70
src/map/pc.c
@ -52,9 +52,6 @@ struct skill_tree_entry skill_tree[MAX_PC_CLASS][MAX_SKILL_TREE];
|
||||
int day_timer_tid;
|
||||
int night_timer_tid;
|
||||
|
||||
static int dirx[8]={0,-1,-1,-1,0,1,1,1};
|
||||
static int diry[8]={1,1,0,-1,-1,-1,0,1};
|
||||
|
||||
struct fame_list smith_fame_list[MAX_FAME_LIST];
|
||||
struct fame_list chemist_fame_list[MAX_FAME_LIST];
|
||||
struct fame_list taekwon_fame_list[MAX_FAME_LIST];
|
||||
@ -3177,73 +3174,6 @@ int pc_memo(struct map_session_data *sd, int i) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* pc駆け足要求
|
||||
*------------------------------------------
|
||||
*/
|
||||
int pc_run(struct map_session_data *sd, int skilllv, int dir)
|
||||
{
|
||||
int i,to_x,to_y,dir_x,dir_y;
|
||||
|
||||
nullpo_retr(0, sd);
|
||||
|
||||
if (!unit_can_move(&sd->bl)) {
|
||||
if(sd->sc.data[SC_RUN].timer!=-1)
|
||||
status_change_end(&sd->bl,SC_RUN,-1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
to_x = sd->bl.x;
|
||||
to_y = sd->bl.y;
|
||||
dir_x = dirx[dir];
|
||||
dir_y = diry[dir];
|
||||
|
||||
for(i=0;i<AREA_SIZE;i++)
|
||||
{
|
||||
if(!map_getcell(sd->bl.m,to_x+dir_x,to_y+dir_y,CELL_CHKPASS))
|
||||
break;
|
||||
|
||||
to_x += dir_x;
|
||||
to_y += dir_y;
|
||||
}
|
||||
|
||||
//進めない場合 駆け足終了 障害物で止まった場合スパート状態解除
|
||||
if(to_x == sd->bl.x && to_y == sd->bl.y){
|
||||
if(sd->sc.data[SC_RUN].timer!=-1)
|
||||
status_change_end(&sd->bl,SC_RUN,-1);
|
||||
return 0;
|
||||
}
|
||||
unit_walktoxy(&sd->bl, to_x, to_y, 1);
|
||||
return 1;
|
||||
}
|
||||
/*==========================================
|
||||
* PCの向居ているほうにstep分歩く
|
||||
*------------------------------------------
|
||||
*/
|
||||
int pc_walktodir(struct map_session_data *sd,int step)
|
||||
{
|
||||
int i,to_x,to_y,dir_x,dir_y;
|
||||
|
||||
nullpo_retr(0, sd);
|
||||
|
||||
to_x = sd->bl.x;
|
||||
to_y = sd->bl.y;
|
||||
dir_x = dirx[(int)sd->ud.dir];
|
||||
dir_y = diry[(int)sd->ud.dir];
|
||||
|
||||
for(i=0;i<step;i++)
|
||||
{
|
||||
if(map_getcell(sd->bl.m,to_x+dir_x,to_y+dir_y,CELL_CHKNOPASS))
|
||||
break;
|
||||
|
||||
to_x += dir_x;
|
||||
to_y += dir_y;
|
||||
}
|
||||
unit_walktoxy(&sd->bl, to_x, to_y, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// •<>Ší??
|
||||
//
|
||||
|
@ -245,8 +245,6 @@ void pc_addfame(struct map_session_data *sd,int count);
|
||||
int pc_istop10fame(int char_id, int job);
|
||||
int pc_eventtimer(int tid,unsigned int tick,int id,int data); // for npc_dequeue
|
||||
|
||||
int pc_run(struct map_session_data *sd, int skilllv, int dir);
|
||||
|
||||
extern struct fame_list smith_fame_list[MAX_FAME_LIST];
|
||||
extern struct fame_list chemist_fame_list[MAX_FAME_LIST];
|
||||
extern struct fame_list taekwon_fame_list[MAX_FAME_LIST];
|
||||
|
@ -42,7 +42,7 @@
|
||||
#define INF2_GUILD_ONLY 2048
|
||||
|
||||
//Walk intervals at which chase-skills are attempted to be triggered.
|
||||
#define WALK_SKILL_INTERVAL 2
|
||||
#define WALK_SKILL_INTERVAL 5
|
||||
|
||||
// スキルデ?タベ?ス
|
||||
struct skill_db {
|
||||
|
@ -4758,8 +4758,12 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
|
||||
clif_updatestatus(sd,updateflag); /* ステ?タスをクライアントに送る */
|
||||
if (sd->pd)
|
||||
pet_sc_check(sd, type); //Skotlex: Pet Status Effect Healing
|
||||
if (type==SC_RUN)
|
||||
pc_run(sd,val1,val2);
|
||||
}
|
||||
|
||||
if (type==SC_RUN) {
|
||||
struct unit_data *ud = unit_bl2ud(bl);
|
||||
if (ud)
|
||||
ud->state.running = unit_run(bl);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -4961,13 +4965,20 @@ int status_change_end( struct block_list* bl , int type,int tid )
|
||||
}
|
||||
break;
|
||||
case SC_RUN://駆け足
|
||||
unit_stop_walking(bl,1);
|
||||
{
|
||||
struct unit_data *ud = unit_bl2ud(bl);
|
||||
if (ud) {
|
||||
ud->state.running = 0;
|
||||
if (ud->walktimer != -1)
|
||||
unit_stop_walking(bl,1);
|
||||
}
|
||||
if (sc->data[type].val1 >= 7 &&
|
||||
DIFF_TICK(gettick(), sc->data[type].val4) <= 1000 &&
|
||||
(!sd || (sd->weapontype1 == 0 && sd->weapontype2 == 0))
|
||||
)
|
||||
sc_start(bl,SC_SPURT,100,sc->data[type].val1,skill_get_time2(StatusSkillChangeTable[type], sc->data[type].val1));
|
||||
calc_flag = 1;
|
||||
}
|
||||
break;
|
||||
case SC_AUTOBERSERK:
|
||||
if (sc->data[SC_PROVOKE].timer != -1 && sc->data[SC_PROVOKE].val2 == 1)
|
||||
|
115
src/map/unit.c
115
src/map/unit.c
@ -85,8 +85,8 @@ int unit_walktoxy_sub(struct block_list *bl)
|
||||
i = status_get_speed(bl)*14/10;
|
||||
else
|
||||
i = status_get_speed(bl);
|
||||
if( i > 0) //First time data is sent as 0 to always enable moving one tile when hit.
|
||||
ud->walktimer = add_timer(gettick()+i,unit_walktoxy_timer,bl->id,0);
|
||||
if( i > 0)
|
||||
ud->walktimer = add_timer(gettick()+i,unit_walktoxy_timer,bl->id,i);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -153,6 +153,7 @@ static int unit_walktoxy_timer(int tid,unsigned int tick,int id,int data)
|
||||
x += dx;
|
||||
y += dy;
|
||||
map_moveblock(bl, x, y, tick);
|
||||
ud->walk_count++; //walked cell counter, to be used for walk-triggered skills. [Skotlex]
|
||||
|
||||
ud->walktimer = 1;
|
||||
map_foreachinmovearea(clif_insight,bl->m,
|
||||
@ -182,7 +183,7 @@ static int unit_walktoxy_timer(int tid,unsigned int tick,int id,int data)
|
||||
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 &&
|
||||
!(ud->walk_count%WALK_SKILL_INTERVAL) &&
|
||||
rand()%10000 < battle_config.sg_miracle_skill_ratio
|
||||
) { //SG_MIRACLE [Komurka]
|
||||
clif_displaymessage(sd->fd,"[Miracle of the Sun, Moon and Stars]");
|
||||
@ -191,7 +192,7 @@ static int unit_walktoxy_timer(int tid,unsigned int tick,int id,int data)
|
||||
} 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 &&
|
||||
if(!(ud->walk_count%WALK_SKILL_INTERVAL) &&
|
||||
mobskill_use(md, tick, -1))
|
||||
return 0;
|
||||
}
|
||||
@ -210,9 +211,11 @@ static int unit_walktoxy_timer(int tid,unsigned int tick,int id,int data)
|
||||
|
||||
if(i > 0)
|
||||
ud->walktimer = add_timer(tick+i,unit_walktoxy_timer,id,i);
|
||||
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->target) {
|
||||
else if(ud->state.running) {
|
||||
//Keep trying to run.
|
||||
if (!unit_run(bl))
|
||||
ud->state.running = 0;
|
||||
} else if (ud->target) {
|
||||
//Update target trajectory.
|
||||
struct block_list *tbl = map_id2bl(ud->target);
|
||||
if (!tbl) { //Cancel chase.
|
||||
@ -329,6 +332,41 @@ int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, int
|
||||
return unit_walktoxy_sub(bl);
|
||||
}
|
||||
|
||||
int unit_run(struct block_list *bl)
|
||||
{
|
||||
struct status_change *sc = status_get_sc(bl);
|
||||
int i,to_x,to_y,dir_x,dir_y;
|
||||
|
||||
if (!sc || !sc->count || sc->data[SC_RUN].timer == -1)
|
||||
return 0;
|
||||
|
||||
if (!unit_can_move(bl)) {
|
||||
if(sc->data[SC_RUN].timer!=-1)
|
||||
status_change_end(bl,SC_RUN,-1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
to_x = bl->x;
|
||||
to_y = bl->y;
|
||||
dir_x = dirx[sc->data[SC_RUN].val2];
|
||||
dir_y = diry[sc->data[SC_RUN].val2];
|
||||
|
||||
for(i=0;i<AREA_SIZE;i++)
|
||||
{
|
||||
if(!map_getcell(bl->m,to_x+dir_x,to_y+dir_y,CELL_CHKPASS))
|
||||
break;
|
||||
to_x += dir_x;
|
||||
to_y += dir_y;
|
||||
}
|
||||
|
||||
if(to_x == bl->x && to_y == bl->y) {
|
||||
status_change_end(bl,SC_RUN,-1);
|
||||
return 0;
|
||||
}
|
||||
unit_walktoxy(bl, to_x, to_y, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//Instant warp function.
|
||||
int unit_movepos(struct block_list *bl,int dst_x,int dst_y, int easy, int checkpath)
|
||||
{
|
||||
@ -495,42 +533,42 @@ int unit_warp(struct block_list *bl,int m,short x,short y,int type)
|
||||
*/
|
||||
int unit_stop_walking(struct block_list *bl,int type)
|
||||
{
|
||||
struct unit_data *ud;
|
||||
struct status_change *sc;
|
||||
struct unit_data *ud;
|
||||
struct TimerData *data;
|
||||
unsigned int tick;
|
||||
nullpo_retr(0, bl);
|
||||
|
||||
ud = unit_bl2ud(bl);
|
||||
if(!ud || ud->walktimer == -1)
|
||||
return 0;
|
||||
|
||||
// if(md) { md->state.skillstate = MSS_IDLE; }
|
||||
if(type&0x01) // ˆÊ’u•â<E280A2>³‘—<E28098>M‚ª•K—v
|
||||
clif_fixpos(bl);
|
||||
|
||||
if(type&0x02 && unit_can_move(bl)) {
|
||||
int dx=ud->to_x-bl->x;
|
||||
int dy=ud->to_y-bl->y;
|
||||
if(dx<0) dx=-1; else if(dx>0) dx=1;
|
||||
if(dy<0) dy=-1; else if(dy>0) dy=1;
|
||||
if(dx || dy) {
|
||||
return unit_walktoxy( bl, bl->x+dx, bl->y+dy, 1);
|
||||
}
|
||||
//NOTE: We are using timer data after deleting it because we know the
|
||||
//delete_timer function does not messes with it. If the function's
|
||||
//behaviour changes in the future, this code could break!
|
||||
data = get_timer(ud->walktimer);
|
||||
delete_timer(ud->walktimer, unit_walktoxy_timer);
|
||||
ud->walktimer = -1;
|
||||
ud->state.change_walk_target = 0;
|
||||
tick = gettick();
|
||||
if ((type&0x02 && !ud->walkpath.path_pos) //Force moving at least one cell.
|
||||
|| (data && DIFF_TICK(data->tick, tick) <= data->data/2)) //Enough time has passed to cover half-cell
|
||||
{
|
||||
ud->walkpath.path_len = ud->walkpath.path_pos+1;
|
||||
unit_walktoxy_timer(-1, tick, bl->id, ud->walkpath.path_pos);
|
||||
}
|
||||
|
||||
// if(md) { md->state.skillstate = MSS_IDLE; }
|
||||
if(type&0x01)
|
||||
clif_fixpos(bl);
|
||||
|
||||
ud->walkpath.path_len = 0;
|
||||
ud->walkpath.path_pos = 0;
|
||||
ud->to_x = bl->x;
|
||||
ud->to_y = bl->y;
|
||||
delete_timer(ud->walktimer, unit_walktoxy_timer);
|
||||
ud->walktimer = -1;
|
||||
if(bl->type == BL_PET) {
|
||||
if(type&~0xff)
|
||||
ud->canmove_tick = gettick() + (type>>8);
|
||||
}
|
||||
sc = status_get_sc(bl);
|
||||
if (sc && sc->count && sc->data[SC_RUN].timer != -1)
|
||||
status_change_end(bl, SC_RUN, -1);
|
||||
if(bl->type == BL_PET && type&~0xff)
|
||||
ud->canmove_tick = gettick() + (type>>8);
|
||||
|
||||
if (ud->state.running)
|
||||
status_change_end(bl, SC_RUN, -1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -631,20 +669,7 @@ int unit_set_walkdelay(struct block_list *bl, unsigned int tick, int delay, int
|
||||
ud->canmove_tick = tick + delay;
|
||||
if (ud->walktimer != -1)
|
||||
{ //Stop walking, if chasing, readjust timers.
|
||||
struct TimerData *data = get_timer(ud->walktimer);
|
||||
//NOTE: We are using timer data after deleting it because we know the
|
||||
//delete_timer function does not messes with it. If the function's
|
||||
//behaviour changes in the future, this code could break!
|
||||
delete_timer(ud->walktimer, unit_walktoxy_timer);
|
||||
ud->walktimer = -1;
|
||||
ud->state.change_walk_target = 0;
|
||||
if (data && (!data->data || DIFF_TICK(data->tick, tick) <= data->data/2))
|
||||
{ //Enough time has elapsed to allow for one more tile,
|
||||
//Or this is the first iteration of the walk
|
||||
ud->walkpath.path_len = ud->walkpath.path_pos+1;
|
||||
unit_walktoxy_timer(-1, tick, bl->id, ud->walkpath.path_pos);
|
||||
}
|
||||
clif_fixpos(bl);
|
||||
unit_stop_walking(bl,3);
|
||||
if(ud->target)
|
||||
add_timer(ud->canmove_tick+1, unit_walktobl_sub, bl->id, ud->target);
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
// 戻り値は、0 ( 成功 ), 1 ( 失敗 )
|
||||
int unit_walktoxy( struct block_list *bl, int x, int y, int easy);
|
||||
int unit_walktobl( struct block_list *bl, struct block_list *target, int range, int easy);
|
||||
int unit_run(struct block_list *bl);
|
||||
|
||||
// 歩行停止
|
||||
// typeは以下の組み合わせ :
|
||||
|
Loading…
x
Reference in New Issue
Block a user