From 14eabce08792bbf83b2f8001d3b341a6fe9dfb67 Mon Sep 17 00:00:00 2001 From: skotlex Date: Mon, 17 Apr 2006 18:12:06 +0000 Subject: - 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://rathena.svn.sourceforge.net/svnroot/rathena/trunk@6137 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/map.h | 2 + src/map/mob.c | 4 +- src/map/pc.c | 70 ----------------------------------- src/map/pc.h | 2 - src/map/skill.h | 2 +- src/map/status.c | 17 +++++++-- src/map/unit.c | 111 ++++++++++++++++++++++++++++++++++--------------------- src/map/unit.h | 1 + 8 files changed, 88 insertions(+), 121 deletions(-) (limited to 'src') diff --git a/src/map/map.h b/src/map/map.h index 83c3f3cdb..b2e194fc4 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -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; }; diff --git a/src/map/mob.c b/src/map/mob.c index 8e28ff6bf..5889903ed 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -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; } diff --git a/src/map/pc.c b/src/map/pc.c index 2dcb11a63..c8195eec5 100644 --- a/src/map/pc.c +++ b/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;ibl.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;ibl.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; -} - // // 武器?? // diff --git a/src/map/pc.h b/src/map/pc.h index 72a3a1f18..33e8eaef0 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -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]; diff --git a/src/map/skill.h b/src/map/skill.h index 2ba25b937..054cd1c71 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -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 { diff --git a/src/map/status.c b/src/map/status.c index 9b7ed47f0..2cfbbaf89 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -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) diff --git a/src/map/unit.c b/src/map/unit.c index f1c61c934..c8e3738b6 100644 --- a/src/map/unit.c +++ b/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;im,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; + //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) // 位置補正送信が必要 + if(type&0x01) 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); - } - } - 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); } diff --git a/src/map/unit.h b/src/map/unit.h index 5c4466351..8fc0343bc 100644 --- a/src/map/unit.h +++ b/src/map/unit.h @@ -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は以下の組み合わせ : -- cgit v1.2.3-70-g09d2