فهرست منبع

Fixed Parry not applying any delays (#9138)

- When Parry activates, it will now apply delays to PCs
  * Cannot attack for AttackMotion*2 (AttackDelay) after activation
  * Cannot use skills for AttackMotion+[200-MaxASPD]*10 after activation
  * Non-PCs still don't receive any delays
- Follow-up to ca27c6d
  * Due to above commit no delays were applied at all as the skill_id check was always false
- Fixes #9128
Playtester 2 ماه پیش
والد
کامیت
59fc37b279
3فایلهای تغییر یافته به همراه36 افزوده شده و 7 حذف شده
  1. 1 7
      src/map/battle.cpp
  2. 32 0
      src/map/unit.cpp
  3. 3 0
      src/map/unit.hpp

+ 1 - 7
src/map/battle.cpp

@@ -1532,13 +1532,7 @@ bool battle_status_block_damage(struct block_list *src, struct block_list *targe
 
 	if ((sce = sc->getSCE(SC_PARRYING)) && flag&BF_WEAPON && skill_id != WS_CARTTERMINATION && rnd() % 100 < sce->val2) {
 		clif_skill_nodamage(target, *target, LK_PARRYING, sce->val1);
-
-		if (skill_id == LK_PARRYING) {
-			unit_data *ud = unit_bl2ud(target);
-
-			if (ud != nullptr) // Delay the next attack
-				ud->attackabletime = gettick() + status_get_adelay(target);
-		}
+		unit_set_attackdelay(*target, gettick());
 		return false;
 	}
 

+ 32 - 0
src/map/unit.cpp

@@ -1813,6 +1813,38 @@ TIMER_FUNC(unit_resume_running){
 	return 0;
 }
 
+/**
+ * Sets the delays that prevent attacks and skill usage considering the bl type
+ * Officially it just remembers the last attack time here and applies the delays during the comparison
+ * But we pre-calculate the delays instead and store them in attackabletime and canact_tick
+ * Currently these delays are only applied to PCs
+ * TODO: This function should also be called on attacks and cast begin
+ * @param bl Object to apply attack delay to
+ * @param tick Current tick
+ */
+void unit_set_attackdelay(block_list& bl, t_tick tick)
+{
+	unit_data* ud = unit_bl2ud(&bl);
+
+	if (ud == nullptr)
+		return;
+
+	switch (bl.type) {
+		case BL_PC:
+			ud->attackabletime = tick + status_get_adelay(&bl);
+			// A fixed delay is added here which is equal to the minimum attack motion you can get
+			// This ensures that at max ASPD attackabletime and canact_tick are equal
+			ud->canact_tick = tick + status_get_amotion(&bl) + (pc_maxaspd(reinterpret_cast<map_session_data*>(&bl)) / AMOTION_DIVIDER_PC);
+			break;
+		case BL_MER:
+			// TODO: Should set this, but only for ground skills
+			break;
+		default:
+			// Not applicable
+			break;
+	}
+}
+
 /**
  * Applies a walk delay to a unit
  * @param bl: Object to apply walk delay to

+ 3 - 0
src/map/unit.hpp

@@ -124,6 +124,9 @@ void unit_stop_walking_soon(struct block_list& bl, t_tick tick = gettick());
 bool unit_stop_walking( block_list* bl, int32 type, t_tick canmove_delay = 0 );
 bool unit_can_move(struct block_list *bl);
 int32 unit_is_walking(struct block_list *bl);
+
+// Delay functions
+void unit_set_attackdelay(block_list& bl, t_tick tick);
 int32 unit_set_walkdelay(struct block_list *bl, t_tick tick, t_tick delay, int32 type);
 
 t_tick unit_get_walkpath_time(struct block_list& bl);