Переглянути джерело

Fixed homunculus cooldown and aftercast delays (#8508)

Co-authored-by: Lemongrass3110 <lemongrass@kstp.at>
Daegaladh 9 місяців тому
батько
коміт
3908b0e9ee

+ 10 - 2
conf/battle/homunc.conf

@@ -17,10 +17,18 @@
 // 0x10: They display luk/3+1 instead of their actual critical in the
 //       stat window (by default they don't crit)
 // 0x20: Their Min-Matk is always the same as their max
-// 0x40: Skill re-use delay is reset when they are vaporized.
-// 0x80: Skill re-use delay is reset when they are warped (by skill or item) with player.
 hom_setting: 0x3D
 
+// Should the cooldown or aftercast delay of homunculi skills be reset when
+// the homunculus is vaporized?
+// Default on official servers: yes for Pre-renewal, no for Renewal
+//hom_delay_reset_vaporize: no
+
+// Should the cooldown or aftercast delay of homunculi skills be reset when
+// warping or changing maps?
+// Default on official servers: yes for Pre-renewal, no for Renewal
+//hom_delay_reset_warp: no
+
 // The rate a homunculus will get friendly by feeding it. (Note 2)
 homunculus_friendly_rate: 100
 

+ 44 - 51
db/pre-re/skill_db.yml

@@ -30730,6 +30730,7 @@ Body:
     Hit: Single
     HitCount: 1
     AfterCastActDelay: 2000
+    AfterCastWalkDelay: 1000
     Requires:
       SpCost:
         - Level: 1
@@ -30757,6 +30758,7 @@ Body:
     HitCount: 1
     SplashArea: -1
     AfterCastActDelay: 35000
+    AfterCastWalkDelay: 1000
     Duration1:
       - Level: 1
         Time: 40000
@@ -30794,6 +30796,14 @@ Body:
     DamageFlags:
       NoDamage: true
     Hit: Single
+    AfterCastActDelay:
+      - Level: 1
+        Time: 600000
+      - Level: 2
+        Time: 900000
+      - Level: 3
+        Time: 1200000
+    AfterCastWalkDelay: 1000
     Duration1:
       - Level: 1
         Time: 60000
@@ -30801,13 +30811,6 @@ Body:
         Time: 180000
       - Level: 3
         Time: 300000
-    Duration2:
-      - Level: 1
-        Time: 600000
-      - Level: 2
-        Time: 900000
-      - Level: 3
-        Time: 1200000
     Requires:
       SpCost: 100
     Status: Change
@@ -30819,7 +30822,8 @@ Body:
     DamageFlags:
       NoDamage: true
     Hit: Single
-    Duration2: 1000
+    AfterCastActDelay: 1000
+    AfterCastWalkDelay: 1000
     Requires:
       SpCost: 10
   - Id: 8006
@@ -30831,6 +30835,7 @@ Body:
       NoDamage: true
     Hit: Single
     AfterCastActDelay: 30000
+    AfterCastWalkDelay: 1000
     Duration1:
       - Level: 1
         Time: 40000
@@ -30869,6 +30874,14 @@ Body:
     DamageFlags:
       NoDamage: true
     Hit: Single
+    AfterCastActDelay:
+      - Level: 1
+        Time: 300000
+      - Level: 2
+        Time: 600000
+      - Level: 3
+        Time: 900000
+    AfterCastWalkDelay: 1000
     Duration1:
       - Level: 1
         Time: 60000
@@ -30876,13 +30889,6 @@ Body:
         Time: 180000
       - Level: 3
         Time: 300000
-    Duration2:
-      - Level: 1
-        Time: 300000
-      - Level: 2
-        Time: 600000
-      - Level: 3
-        Time: 900000
     Requires:
       SpCost: 120
     Status: Bloodlust
@@ -30905,7 +30911,6 @@ Body:
         Count: -2
       - Level: 5
         Count: -3
-    AfterCastWalkDelay: 2000
     Requires:
       SpCost:
         - Level: 1
@@ -30926,28 +30931,29 @@ Body:
     DamageFlags:
       NoDamage: true
     Hit: Single
-    Duration1:
+    AfterCastActDelay:
       - Level: 1
         Time: 60000
       - Level: 2
-        Time: 55000
+        Time: 70000
       - Level: 3
-        Time: 50000
+        Time: 80000
       - Level: 4
-        Time: 45000
+        Time: 90000
       - Level: 5
-        Time: 40000
-    Duration2:
+        Time: 120000
+    AfterCastWalkDelay: 1000
+    Duration1:
       - Level: 1
         Time: 60000
       - Level: 2
-        Time: 70000
+        Time: 55000
       - Level: 3
-        Time: 80000
+        Time: 50000
       - Level: 4
-        Time: 90000
+        Time: 45000
       - Level: 5
-        Time: 120000
+        Time: 40000
     Requires:
       SpCost:
         - Level: 1
@@ -30971,28 +30977,29 @@ Body:
       NoDamage: true
     Hit: Single
     CastCancel: true
-    Duration1:
+    AfterCastActDelay:
       - Level: 1
         Time: 60000
       - Level: 2
-        Time: 55000
+        Time: 70000
       - Level: 3
-        Time: 50000
+        Time: 80000
       - Level: 4
-        Time: 45000
+        Time: 90000
       - Level: 5
-        Time: 40000
-    Duration2:
+        Time: 120000
+    AfterCastWalkDelay: 1000
+    Duration1:
       - Level: 1
         Time: 60000
       - Level: 2
-        Time: 70000
+        Time: 55000
       - Level: 3
-        Time: 80000
+        Time: 50000
       - Level: 4
-        Time: 90000
+        Time: 45000
       - Level: 5
-        Time: 120000
+        Time: 40000
     Requires:
       SpCost:
         - Level: 1
@@ -31015,7 +31022,6 @@ Body:
     Range: 15
     Hit: Single
     HitCount: 1
-    AfterCastActDelay: 1000
     Requires:
       SpCost: 1
   - Id: 8013
@@ -31037,17 +31043,6 @@ Body:
         Count: 4
       - Level: 5
         Count: 5
-    AfterCastActDelay:
-      - Level: 1
-        Time: 2000
-      - Level: 2
-        Time: 2200
-      - Level: 3
-        Time: 2400
-      - Level: 4
-        Time: 2600
-      - Level: 5
-        Time: 2800
     Requires:
       SpCost:
         - Level: 1
@@ -31068,8 +31063,7 @@ Body:
     DamageFlags:
       NoDamage: true
     Hit: Single
-    AfterCastActDelay: 3000
-    AfterCastWalkDelay: 3000
+    AfterCastWalkDelay: 1500
     Requires:
       SpCost: 40
   - Id: 8015
@@ -31093,7 +31087,6 @@ Body:
     HitCount: 1
     Element: Weapon
     SplashArea: 4
-    AfterCastWalkDelay: 1000
     Requires:
       SpCost: 1
   - Id: 8018

+ 23 - 14
db/re/skill_db.yml

@@ -43021,7 +43021,8 @@ Body:
     Range: 9
     Hit: Single
     HitCount: 1
-    AfterCastActDelay: 2000
+    AfterCastWalkDelay: 1000
+    Cooldown: 20000
     Requires:
       SpCost:
         - Level: 1
@@ -43048,7 +43049,7 @@ Body:
     Hit: Single
     HitCount: 1
     SplashArea: -1
-    AfterCastActDelay: 35000
+    AfterCastWalkDelay: 1000
     Duration1:
       - Level: 1
         Time: 40000
@@ -43060,6 +43061,7 @@ Body:
         Time: 25000
       - Level: 5
         Time: 20000
+    Cooldown: 35000
     Requires:
       SpCost:
         - Level: 1
@@ -43086,6 +43088,7 @@ Body:
     DamageFlags:
       NoDamage: true
     Hit: Single
+    AfterCastWalkDelay: 1000
     Duration1:
       - Level: 1
         Time: 60000
@@ -43093,7 +43096,7 @@ Body:
         Time: 180000
       - Level: 3
         Time: 300000
-    Duration2:
+    Cooldown:
       - Level: 1
         Time: 600000
       - Level: 2
@@ -43111,7 +43114,8 @@ Body:
     DamageFlags:
       NoDamage: true
     Hit: Single
-    Duration2: 1000
+    AfterCastWalkDelay: 1000
+    Cooldown: 1000
     Requires:
       SpCost: 10
   - Id: 8006
@@ -43122,7 +43126,7 @@ Body:
     DamageFlags:
       NoDamage: true
     Hit: Single
-    AfterCastActDelay: 30000
+    AfterCastWalkDelay: 1000
     Duration1:
       - Level: 1
         Time: 40000
@@ -43134,6 +43138,7 @@ Body:
         Time: 25000
       - Level: 5
         Time: 20000
+    Cooldown: 30000
     Requires:
       SpCost:
         - Level: 1
@@ -43161,6 +43166,7 @@ Body:
     DamageFlags:
       NoDamage: true
     Hit: Single
+    AfterCastWalkDelay: 1000
     Duration1:
       - Level: 1
         Time: 60000
@@ -43168,7 +43174,7 @@ Body:
         Time: 180000
       - Level: 3
         Time: 300000
-    Duration2:
+    Cooldown:
       - Level: 1
         Time: 300000
       - Level: 2
@@ -43197,7 +43203,7 @@ Body:
         Count: -2
       - Level: 5
         Count: -3
-    AfterCastWalkDelay: 2000
+    Cooldown: 2000
     Requires:
       SpCost:
         - Level: 1
@@ -43218,6 +43224,7 @@ Body:
     DamageFlags:
       NoDamage: true
     Hit: Single
+    AfterCastWalkDelay: 1000
     Duration1:
       - Level: 1
         Time: 60000
@@ -43229,7 +43236,7 @@ Body:
         Time: 45000
       - Level: 5
         Time: 40000
-    Duration2:
+    Cooldown:
       - Level: 1
         Time: 60000
       - Level: 2
@@ -43263,6 +43270,7 @@ Body:
       NoDamage: true
     Hit: Single
     CastCancel: true
+    AfterCastWalkDelay: 1000
     Duration1:
       - Level: 1
         Time: 60000
@@ -43274,7 +43282,7 @@ Body:
         Time: 45000
       - Level: 5
         Time: 40000
-    Duration2:
+    Cooldown:
       - Level: 1
         Time: 60000
       - Level: 2
@@ -43307,7 +43315,7 @@ Body:
     Range: 15
     Hit: Single
     HitCount: 1
-    AfterCastActDelay: 1000
+    Cooldown: 1000
     Requires:
       SpCost: 1
   - Id: 8013
@@ -43329,7 +43337,7 @@ Body:
         Count: 4
       - Level: 5
         Count: 5
-    AfterCastActDelay:
+    Cooldown:
       - Level: 1
         Time: 2000
       - Level: 2
@@ -43360,8 +43368,8 @@ Body:
     DamageFlags:
       NoDamage: true
     Hit: Single
-    AfterCastActDelay: 3000
-    AfterCastWalkDelay: 3000
+    AfterCastWalkDelay: 1500
+    Cooldown: 3000
     Requires:
       SpCost: 40
   - Id: 8015
@@ -43385,7 +43393,8 @@ Body:
     HitCount: 1
     Element: Weapon
     SplashArea: 4
-    AfterCastWalkDelay: 1000
+    AfterCastActDelay: 5000
+    CoolDown: 1000
     Requires:
       SpCost: 1
   - Id: 8018

+ 7 - 0
src/map/battle.cpp

@@ -11529,6 +11529,13 @@ static const struct _battle_data {
 #endif
 	{ "synchronize_damage",                 &battle_config.synchronize_damage,              0,      0,      1,              },
 	{ "item_stacking",                      &battle_config.item_stacking,                   1,      0,      1,              },
+#ifdef RENEWAL
+	{ "hom_delay_reset_vaporize",           &battle_config.hom_delay_reset_vaporize,        0,      0,      1,              },
+	{ "hom_delay_reset_warp",               &battle_config.hom_delay_reset_warp,            0,      0,      1,              },
+#else
+	{ "hom_delay_reset_vaporize",           &battle_config.hom_delay_reset_vaporize,        1,      0,      1,              },
+	{ "hom_delay_reset_warp",               &battle_config.hom_delay_reset_warp,            1,      0,      1,              },
+#endif
 
 #include <custom/battle_config_init.inc>
 };

+ 2 - 0
src/map/battle.hpp

@@ -762,6 +762,8 @@ struct Battle_Config
 	int instance_allow_reconnect;
 	int synchronize_damage;
 	int item_stacking;
+	int hom_delay_reset_vaporize;
+	int hom_delay_reset_warp;
 
 #include <custom/battle_config_struct.inc>
 };

+ 1 - 1
src/map/homunculus.cpp

@@ -289,7 +289,7 @@ int hom_vaporize(map_session_data *sd, int flag)
 	//Delete timers when vaporized.
 	hom_hungry_timer_delete(hd);
 	hd->homunculus.vaporize = flag ? flag : HOM_ST_REST;
-	if (battle_config.hom_setting&HOMSET_RESET_REUSESKILL_VAPORIZED) {
+	if (battle_config.hom_delay_reset_vaporize) {
 		hd->blockskill.clear();
 		hd->blockskill.shrink_to_fit();
 	}

+ 0 - 2
src/map/homunculus.hpp

@@ -168,8 +168,6 @@ enum homun_setting : uint8 {
 	HOMSET_COPY_SPEED					= 0x08, /// Copy their master's speed on spawn/map-change
 	HOMSET_DISPLAY_LUK					= 0x10, /// They display luk/3+1 instead of their actual critical in the stat window, by default they don't crit
 	HOMSET_SAME_MATK					= 0x20, /// Their Min-Matk is always the same as their max
-	HOMSET_RESET_REUSESKILL_VAPORIZED	= 0x40, /// Skill re-use delay is reset when they are vaporized.
-	HOMSET_RESET_REUSESKILL_TELEPORTED	= 0x80, /// Skill re-use delay is reset when they are warped (by skill or item) with player.
 };
 
 enum e_homun_grade : uint8 {

+ 5 - 0
src/map/pc.cpp

@@ -7008,6 +7008,11 @@ enum e_setpos pc_setpos(map_session_data* sd, unsigned short mapindex, int x, in
 
 	if( hom_is_active(sd->hd) )
 	{
+		if (battle_config.hom_delay_reset_warp) {
+			sd->hd->blockskill.clear();
+			sd->hd->blockskill.shrink_to_fit();
+		}
+
 		sd->hd->bl.m = m;
 		sd->hd->bl.x = sd->hd->ud.to_x = x;
 		sd->hd->bl.y = sd->hd->ud.to_y = y;

+ 36 - 30
src/map/skill.cpp

@@ -1014,8 +1014,10 @@ bool skill_isNotOk_hom(struct homun_data *hd, uint16 skill_id, uint16 skill_lv)
 	if (sc && !sc->count)
 		sc = nullptr;
 
-	if (util::vector_exists(hd->blockskill, skill_id))
+	if (util::vector_exists(hd->blockskill, skill_id)) {
+		clif_skill_fail(*sd, skill_id, USESKILL_FAIL_SKILLINTERVAL);
 		return true;
+	}
 
 	switch(skill_id) {
 		case HFLI_SBR44:
@@ -1120,9 +1122,16 @@ bool skill_isNotOk_hom(struct homun_data *hd, uint16 skill_id, uint16 skill_lv)
  * @return true: Skill cannot be used, false: otherwise
  */
 bool skill_isNotOk_mercenary( uint16 skill_id, s_mercenary_data& md ){
-	if (util::vector_exists(md.blockskill, skill_id))
+	map_session_data* sd = md.master;
+
+	if (sd == nullptr)
 		return true;
 
+	if (util::vector_exists(md.blockskill, skill_id)) {
+		clif_skill_fail(*sd, skill_id, USESKILL_FAIL_SKILLINTERVAL);
+		return true;
+	}
+
 	if( md.master != nullptr ){
 		return skill_isNotOk( skill_id, *md.master );
 	}else{
@@ -7342,8 +7351,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 			    ret = skill_castend_pos2(src,src->x,src->y,skill_id,skill_lv,tick,flag); //cast on homon
 			if(s_src && !skill_check_unit_range(s_src, s_src->x, s_src->y, skill_id, skill_lv))
 			    ret |= skill_castend_pos2(s_src,s_src->x,s_src->y,skill_id,skill_lv,tick,flag); //cast on master
-			if (hd)
-			    skill_blockhomun_start(hd, skill_id, skill_get_cooldown(skill_id, skill_lv));
 			return ret;
 		    }
 		    break;
@@ -9330,10 +9337,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 				break;
 			}
 
-			if (sd->hd && battle_config.hom_setting&HOMSET_RESET_REUSESKILL_TELEPORTED) {
-				sd->hd->blockskill.clear();
-				sd->hd->blockskill.shrink_to_fit();
-			}
 
 			if( sd->state.autocast || ( (sd->skillitem == AL_TELEPORT || battle_config.skip_teleport_lv1_menu) && skill_lv == 1 ) || skill_lv == 3 )
 			{
@@ -10675,11 +10678,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 		break;
 
 	case HAMI_CASTLE:	//[orn]
-		if (src != bl && rnd()%100 < 20 * skill_lv) {
+		if (src != bl && rnd_chance(20 * skill_lv, 100)) {
 			int x = src->x, y = src->y;
 
-			if (hd)
-				skill_blockhomun_start(hd,skill_id,skill_get_time2(skill_id,skill_lv));
 			// Move source
 			if (unit_movepos(src,bl->x,bl->y,0,0)) {
 				clif_skill_nodamage(src,src,skill_id,skill_lv,1); // Homunc
@@ -10726,8 +10727,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 	case MH_GOLDENE_FERSE:
 		clif_skill_nodamage(src,bl,skill_id,skill_lv,
 			sc_start(src,bl,type,100,skill_lv,skill_get_time(skill_id,skill_lv)));
-		if (hd)
-			skill_blockhomun_start(hd, skill_id, skill_get_time2(skill_id,skill_lv));
 		break;
 
 	case NPC_DRAGONFEAR:
@@ -12356,15 +12355,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 				for (i = 0; i < ARRAYLENGTH(scs); i++)
 					if (tsc->getSCE(scs[i])) status_change_end(bl, scs[i]);
 			}
-			if (hd)
-				skill_blockhomun_start(hd, skill_id, skill_get_cooldown(skill_id, skill_lv));
 		}
 		break;
 	case MH_OVERED_BOOST:
 		if (hd && battle_get_master(src)) {
 			sc_start(src, battle_get_master(src), type, 100, skill_lv, skill_get_time(skill_id, skill_lv));
 			sc_start(src, bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv));
-			skill_blockhomun_start(hd, skill_id, skill_get_cooldown(skill_id, skill_lv));
 		}
 		break;
 	case MH_GRANITIC_ARMOR:
@@ -12373,7 +12369,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 			struct block_list *s_bl = battle_get_master(src);
 			if(s_bl) sc_start2(src, s_bl, type, 100, skill_lv, hd->homunculus.level, skill_get_time(skill_id, skill_lv)); //start on master
 			sc_start2(src, bl, type, 100, skill_lv, hd->homunculus.level, skill_get_time(skill_id, skill_lv));
-			skill_blockhomun_start(hd, skill_id, skill_get_cooldown(skill_id, skill_lv));
 	     }
 	     break;
 	case MH_LIGHT_OF_REGENE: //self
@@ -12381,7 +12376,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 			struct block_list *s_bl = battle_get_master(src);
 			if(s_bl) sc_start(src, s_bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv));
 			sc_start2(src, src, type, 100, skill_lv, hd->homunculus.level, skill_get_time(skill_id, skill_lv));
-			skill_blockhomun_start(hd, skill_id, skill_get_cooldown(skill_id, skill_lv));
 		}
 		break;
 	case MH_STYLE_CHANGE:
@@ -12407,21 +12401,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 			clif_skill_nodamage(src,master_bl,skill_id,skill_lv,1);
 			sc_start(src, master_bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv));
 		}
-		
-		if (hd)
-			skill_blockhomun_start(hd, skill_id, skill_get_cooldown(skill_id, skill_lv));
 		} break;
 	case MH_PAIN_KILLER:
 		bl = battle_get_master(src);
 		if (bl != nullptr)
 			sc_start(src, bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv));
-		if (hd)
-			skill_blockhomun_start(hd, skill_id, skill_get_cooldown(skill_id, skill_lv));
 		break;
 	case MH_MAGMA_FLOW:
 	   sc_start(src,bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv));
-	   if (hd)
-		   skill_blockhomun_start(hd, skill_id, skill_get_cooldown(skill_id, skill_lv));
 	   break;
 	case MH_SUMMON_LEGION: {
 		int summons[5] = {MOBID_S_HORNET, MOBID_S_GIANT_HORNET, MOBID_S_GIANT_HORNET, MOBID_S_LUCIOLA_VESPA, MOBID_S_LUCIOLA_VESPA};
@@ -12448,8 +12435,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 				sc_start4(&sum_md->bl,&sum_md->bl, SC_MODECHANGE, 100, 1, 0, MD_CANATTACK|MD_AGGRESSIVE, 0, 60000);
 			}
 		}
-		if (hd)
-			skill_blockhomun_start(hd, skill_id, skill_get_cooldown(skill_id, skill_lv));
 		}
 		break;
 
@@ -13398,10 +13383,25 @@ TIMER_FUNC(skill_castend_id){
 
 		if (!sd || sd->skillitem != ud->skill_id || skill_get_delay(ud->skill_id, ud->skill_lv))
 			ud->canact_tick = i64max(tick + skill_delayfix(src, ud->skill_id, ud->skill_lv), ud->canact_tick - SECURITY_CASTTIME);
-		if (sd) { //Cooldown application
-			int cooldown = pc_get_skillcooldown(sd,ud->skill_id, ud->skill_lv); // Increases/Decreases cooldown of a skill by item/card bonuses.
-			if(cooldown) skill_blockpc_start(sd, ud->skill_id, cooldown);
+
+		// Cooldown application
+		switch (src->type) {
+		case BL_PC:{
+			// Increases/Decreases cooldown of a skill by item/card bonuses.
+			int cooldown = pc_get_skillcooldown(sd, ud->skill_id, ud->skill_lv);
+			if (cooldown > 0)
+				skill_blockpc_start(sd, ud->skill_id, cooldown);
+		} break;
+		case BL_HOM:{
+			homun_data& hd = reinterpret_cast<homun_data&>(*src);
+#ifdef RENEWAL
+			skill_blockhomun_start(&hd, ud->skill_id, skill_get_cooldown(ud->skill_id, ud->skill_lv));
+#else
+			skill_blockhomun_start(&hd, ud->skill_id, skill_get_delay(ud->skill_id, ud->skill_lv));
+#endif
+		} break;
 		}
+
 		if( battle_config.display_status_timers && sd )
 			clif_status_change(src, EFST_POSTDELAY, 1, skill_delayfix(src, ud->skill_id, ud->skill_lv), 0, 0, 0);
 		if( sd )
@@ -23069,6 +23069,9 @@ int skill_blockhomun_start(struct homun_data *hd, uint16 skill_id, int tick)	//[
 
 	hd->blockskill.push_back(skill_id);
 
+	if (battle_config.display_status_timers)
+		clif_skill_cooldown(*hd->master, skill_id, tick);
+
 	return add_timer(gettick() + tick, skill_blockhomun_end, hd->bl.id, skill_id);
 }
 
@@ -23101,6 +23104,9 @@ int skill_blockmerc_start(s_mercenary_data *md, uint16 skill_id, int tick)
 
 	md->blockskill.push_back(skill_id);
 
+	if (battle_config.display_status_timers)
+		clif_skill_cooldown(*md->master, skill_id, tick);
+
 	return add_timer(gettick() + tick, skill_blockmerc_end, md->bl.id, skill_id);
 }
 /**