瀏覽代碼

Improved solution to sync position after endure hit (#9228)

- Replaced the monster-specific solution to fix position lag after an endure hit with a common one
  * It remembers the time of the last damage and updates the position every cell for a certain time span
  * This is needed because sometimes an Endure hit still stops a unit on the client (e.g. firewall on undead)
  * Works for all BL types now and can even sync position on the current client of a player
  * Reduced the duration from 3000ms to 1000ms (max move time per cell)
  * Code optimizations such as using a constant for the duration
Playtester 1 月之前
父節點
當前提交
b7b6812fcf
共有 5 個文件被更改,包括 22 次插入7 次删除
  1. 0 2
      src/map/mob.cpp
  2. 1 1
      src/map/mob.hpp
  3. 6 0
      src/map/status.cpp
  4. 14 4
      src/map/unit.cpp
  5. 1 0
      src/map/unit.hpp

+ 0 - 2
src/map/mob.cpp

@@ -1191,7 +1191,6 @@ int32 mob_spawn (struct mob_data *md)
 	md->ud.state.blockedmove = false;
 	md->next_walktime = tick+rnd()%1000+MIN_RANDOMWALKTIME;
 	md->last_linktime = 0;
-	md->dmgtick = tick - 5000;
 	md->last_pcneartime = 0;
 	md->last_canmove = tick;
 	md->last_skillcheck = tick;
@@ -2701,7 +2700,6 @@ void mob_damage(struct mob_data *md, struct block_list *src, int32 damage)
 			md->state.aggressive = 0;
 		//Log damage
 		mob_log_damage(md, src, static_cast<int64>(damage));
-		md->dmgtick = gettick();
 	}
 
 	if (battle_config.show_mob_info&3)

+ 1 - 1
src/map/mob.hpp

@@ -373,7 +373,7 @@ struct mob_data {
 	int32 areanpc_id; //Required in OnTouchNPC (to avoid multiple area touchs)
 	int32 bg_id; // BattleGround System
 
-	t_tick next_walktime,next_thinktime,last_linktime,last_pcneartime,dmgtick,last_canmove,last_skillcheck;
+	t_tick next_walktime,next_thinktime,last_linktime,last_pcneartime,last_canmove,last_skillcheck;
 	t_tick trickcasting; // Special state where you show a fake castbar while moving
 	int16 move_fail_count;
 	int16 lootitem_count;

+ 6 - 0
src/map/status.cpp

@@ -1572,6 +1572,12 @@ int32 status_damage(struct block_list *src,struct block_list *target,int64 dhp,
 		if (target->type == BL_PC)
 			pc_bonus_script_clear(BL_CAST(BL_PC,target),BSF_REM_ON_DAMAGED);
 		unit_skillcastcancel(target, 2);
+
+		// Remember last time the unit was hit by a source
+		if (src != nullptr) {
+			if (unit_data* ud = unit_bl2ud(target); ud != nullptr)
+				ud->dmg_tick = gettick();
+		}
 	}
 
 	// We need to log the real damage on exp_calc_type 1

+ 14 - 4
src/map/unit.cpp

@@ -56,6 +56,12 @@ using namespace rathena;
 	#define MIN_DELAY_SLAVE MAX_ASPD_NOPC * 2
 #endif
 
+// Time frame during which we will send move packets each cell moved after being hit
+// This is needed because damage packets prevent the client from displaying movement for a while
+#ifndef MOVE_REFRESH_TIME
+	#define MOVE_REFRESH_TIME MAX_WALK_SPEED
+#endif
+
 // Directions values
 // 1 0 7
 // 2 . 6
@@ -212,8 +218,13 @@ bool unit_walktoxy_nextcell(block_list& bl, bool sendMove, t_tick tick) {
 		ud->walktimer = INVALID_TIMER;
 	}
 	ud->walktimer = add_timer(tick + speed, unit_walktoxy_timer, bl.id, speed);
-	if (sendMove)
+
+	// Resend move packet when unit was damaged recently
+	if (sendMove || DIFF_TICK(tick, ud->dmg_tick) < MOVE_REFRESH_TIME) {
 		clif_move(*ud);
+		if (bl.type == BL_PC)
+			clif_walkok(reinterpret_cast<map_session_data&>(bl));
+	}
 	return true;
 }
 
@@ -269,9 +280,7 @@ int32 unit_walktoxy_sub(struct block_list *bl)
 
 	if (bl->type == BL_PC) {
 		map_session_data *sd = BL_CAST(BL_PC, bl);
-
 		sd->head_dir = DIR_NORTH;
-		clif_walkok(*sd);
 	}
 #if PACKETVER >= 20170726
 	// If this is a walking NPC and it will use a player sprite
@@ -722,7 +731,7 @@ static TIMER_FUNC(unit_walktoxy_timer)
 
 	ud->walkpath.path_pos++;
 
-	if(unit_walktoxy_nextcell(*bl, (md != nullptr && DIFF_TICK(tick, md->dmgtick) < 3000), tick)) {
+	if(unit_walktoxy_nextcell(*bl, false, tick)) {
 		// Nothing else needs to be done
 	} else if(ud->state.running) { // Keep trying to run.
 		if (!(unit_run(bl, nullptr, SC_RUN) || unit_run(bl, sd, SC_WUGDASH)) )
@@ -3424,6 +3433,7 @@ void unit_dataset(struct block_list *bl)
 	ud->canact_tick = tick;
 	ud->canmove_tick = tick;
 	ud->endure_tick = tick;
+	ud->dmg_tick = 0;
 	ud->sx = 8;
 	ud->sy = 8;
 }

+ 1 - 0
src/map/unit.hpp

@@ -44,6 +44,7 @@ struct unit_data {
 	t_tick canact_tick;
 	t_tick canmove_tick;
 	t_tick endure_tick; // Time until which unit cannot be stopped
+	t_tick dmg_tick; // Last time the unit was damaged by a source
 	bool immune_attack; ///< Whether the unit is immune to attacks
 	uint8 dir;
 	unsigned char target_count;