Просмотр исходного кода

- 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

skotlex 19 лет назад
Родитель
Сommit
3a2c267be6
9 измененных файлов с 95 добавлено и 121 удалено
  1. 7 0
      Changelog-Trunk.txt
  2. 2 0
      src/map/map.h
  3. 2 2
      src/map/mob.c
  4. 0 70
      src/map/pc.c
  5. 0 2
      src/map/pc.h
  6. 1 1
      src/map/skill.h
  7. 14 3
      src/map/status.c
  8. 68 43
      src/map/unit.c
  9. 1 0
      src/map/unit.h

+ 7 - 0
Changelog-Trunk.txt

@@ -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]

+ 2 - 0
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;
 };
 

+ 2 - 2
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;
 		}

+ 0 - 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;
-}
-
 //
 // 武器??
 //

+ 0 - 2
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];

+ 1 - 1
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
 
 // ƒXƒLƒ‹ƒf?ƒ^ƒx?ƒX
 struct skill_db {

+ 14 - 3
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)

+ 68 - 43
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;
+	//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) // ˆÊ’u•â�³‘—�M‚ª•K—v
+	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);
 	}

+ 1 - 0
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は以下の組み合わせ :