瀏覽代碼

Properly implements Soul Attack (#6126)

* Fixes #6095.
* Proper implementation of Soul Attack for Doram.
* Adds the missing client EFST when learning the skill.
* Fixes the behavior so that skills that block or reduce ranged attacks are properly taken into account.
Thanks to @Everade!
Aleos 3 年之前
父節點
當前提交
a93daa0c6f
共有 5 個文件被更改,包括 20 次插入2 次删除
  1. 5 1
      src/map/battle.cpp
  2. 4 0
      src/map/pc.cpp
  3. 1 0
      src/map/script_constants.hpp
  4. 8 1
      src/map/status.cpp
  5. 2 0
      src/map/status.hpp

+ 5 - 1
src/map/battle.cpp

@@ -5789,7 +5789,11 @@ static struct Damage initialize_weapon_data(struct block_list *src, struct block
 					wd.flag |= BF_LONG;
 		}
 	} else {
-		wd.flag |= is_skill_using_arrow(src, skill_id)?BF_LONG:BF_SHORT;
+		bool is_long = false;
+
+		if (is_skill_using_arrow(src, skill_id) || (sc && sc->data[SC_SOULATTACK]))
+			is_long = true;
+		wd.flag |= is_long ? BF_LONG : BF_SHORT;
 	}
 
 	return wd;

+ 4 - 0
src/map/pc.cpp

@@ -8079,6 +8079,8 @@ int pc_resetskill(struct map_session_data* sd, int flag)
 
 		if (sd->sc.data[SC_SPRITEMABLE] && pc_checkskill(sd, SU_SPRITEMABLE))
 			status_change_end(&sd->bl, SC_SPRITEMABLE, INVALID_TIMER);
+		if (sd->sc.data[SC_SOULATTACK] && pc_checkskill(sd, SU_SOULATTACK))
+			status_change_end(&sd->bl, SC_SOULATTACK, INVALID_TIMER);
 	}
 
 	for (const auto &skill : skill_db) {
@@ -9525,6 +9527,8 @@ bool pc_jobchange(struct map_session_data *sd,int job, char upper)
 
 	if (sd->sc.data[SC_SPRITEMABLE] && !pc_checkskill(sd, SU_SPRITEMABLE))
 		status_change_end(&sd->bl, SC_SPRITEMABLE, INVALID_TIMER);
+	if (sd->sc.data[SC_SOULATTACK] && !pc_checkskill(sd, SU_SOULATTACK))
+		status_change_end(&sd->bl, SC_SOULATTACK, INVALID_TIMER);
 
 	if(sd->status.manner < 0)
 		clif_changestatus(sd,SP_MANNER,sd->status.manner);

+ 1 - 0
src/map/script_constants.hpp

@@ -1627,6 +1627,7 @@
 	export_constant(SC_PACKING_ENVELOPE8);
 	export_constant(SC_PACKING_ENVELOPE9);
 	export_constant(SC_PACKING_ENVELOPE10);
+	export_constant(SC_SOULATTACK);
 #ifdef RENEWAL
 	export_constant(SC_EXTREMITYFIST2);
 #endif

+ 8 - 1
src/map/status.cpp

@@ -1661,6 +1661,7 @@ void initChangeTables(void)
 	StatusIconChangeTable[SC_SPRITEMABLE] = EFST_SPRITEMABLE;
 	StatusIconChangeTable[SC_DORAM_BUF_01] = EFST_DORAM_BUF_01;
 	StatusIconChangeTable[SC_DORAM_BUF_02] = EFST_DORAM_BUF_02;
+	StatusIconChangeTable[SC_SOULATTACK] = EFST_SOULATTACK;
 
 	// Item Reuse Limits
 	StatusIconChangeTable[SC_REUSE_REFRESH] = EFST_REUSE_REFRESH;
@@ -1994,6 +1995,7 @@ void initChangeTables(void)
 	StatusDisplayType[SC_MISTY_FROST]     = BL_PC;
 	StatusDisplayType[SC_MAGIC_POISON]    = BL_PC;
 	StatusDisplayType[SC_MADOGEAR]        = BL_PC;
+	StatusDisplayType[SC_SOULATTACK]      = BL_PC;
 
 	// Costumes
 	StatusDisplayType[SC_MOONSTAR] = BL_PC;
@@ -5067,8 +5069,10 @@ int status_calc_pc_sub(struct map_session_data* sd, enum e_status_calc_opt opt)
 		clif_skillinfoblock(sd);
 
 	// If the skill is learned, the status is infinite.
-	if( (skill = pc_checkskill(sd,SU_SPRITEMABLE)) > 0 && !sd->sc.data[SC_SPRITEMABLE] )
+	if (pc_checkskill(sd, SU_SPRITEMABLE) > 0 && !sd->sc.data[SC_SPRITEMABLE])
 		sc_start(&sd->bl, &sd->bl, SC_SPRITEMABLE, 100, 1, INFINITE_TICK);
+	if (pc_checkskill(sd, SU_SOULATTACK) > 0 && !sd->sc.data[SC_SOULATTACK])
+		sc_start(&sd->bl, &sd->bl, SC_SOULATTACK, 100, 1, INFINITE_TICK);
 
 	calculating = 0;
 
@@ -10606,6 +10610,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 		case SC_SPRITEMABLE:
 		case SC_CLAN_INFO:
 		case SC_DAILYSENDMAILCNT:
+		case SC_SOULATTACK:
 			tick = INFINITE_TICK;
 			break;
 
@@ -13293,6 +13298,7 @@ int status_change_clear(struct block_list* bl, int type)
 			case SC_PACKING_ENVELOPE8:
 			case SC_PACKING_ENVELOPE9:
 			case SC_PACKING_ENVELOPE10:
+			case SC_SOULATTACK:
 			// Costumes
 			case SC_MOONSTAR:
 			case SC_SUPER_STAR:
@@ -15441,6 +15447,7 @@ void status_change_clear_buffs(struct block_list* bl, uint8 type)
 			case SC_EP16_2_BUFF_SC:
 			case SC_EP16_2_BUFF_AC:
 			case SC_HOMUN_TIME:
+			case SC_SOULATTACK:
 			// Clans
 			case SC_CLAN_INFO:
 			case SC_SWORDCLAN:

+ 2 - 0
src/map/status.hpp

@@ -999,6 +999,8 @@ enum sc_type : int16 {
 	SC_PACKING_ENVELOPE9,
 	SC_PACKING_ENVELOPE10,
 
+	SC_SOULATTACK,
+
 #ifdef RENEWAL
 	SC_EXTREMITYFIST2, //! NOTE: This SC should be right before SC_MAX, so it doesn't disturb if RENEWAL is disabled
 #endif