Browse Source

Fixed Homunculus Amistr skills (#8556)

Daegaladh 8 months ago
parent
commit
ffead570b2
10 changed files with 86 additions and 60 deletions
  1. 0 5
      db/pre-re/skill_db.yml
  2. 7 0
      db/pre-re/status.yml
  3. 0 5
      db/re/skill_db.yml
  4. 7 0
      db/re/status.yml
  5. 10 7
      doc/status_change.txt
  6. 2 2
      src/map/battle.cpp
  7. 18 13
      src/map/skill.cpp
  8. 13 11
      src/map/status.cpp
  9. 27 15
      src/map/unit.cpp
  10. 2 2
      src/map/unit.hpp

+ 0 - 5
db/pre-re/skill_db.yml

@@ -30822,7 +30822,6 @@ Body:
     TargetType: Self
     TargetType: Self
     DamageFlags:
     DamageFlags:
       NoDamage: true
       NoDamage: true
-    Hit: Single
     AfterCastActDelay: 1000
     AfterCastActDelay: 1000
     AfterCastWalkDelay: 1000
     AfterCastWalkDelay: 1000
     Requires:
     Requires:
@@ -30834,7 +30833,6 @@ Body:
     TargetType: Self
     TargetType: Self
     DamageFlags:
     DamageFlags:
       NoDamage: true
       NoDamage: true
-    Hit: Single
     AfterCastActDelay: 30000
     AfterCastActDelay: 30000
     AfterCastWalkDelay: 1000
     AfterCastWalkDelay: 1000
     Duration1:
     Duration1:
@@ -30865,8 +30863,6 @@ Body:
     Name: HAMI_SKIN
     Name: HAMI_SKIN
     Description: Adamantium Skin
     Description: Adamantium Skin
     MaxLevel: 5
     MaxLevel: 5
-    DamageFlags:
-      NoDamage: true
   - Id: 8008
   - Id: 8008
     Name: HAMI_BLOODLUST
     Name: HAMI_BLOODLUST
     Description: Bloodlust
     Description: Bloodlust
@@ -30874,7 +30870,6 @@ Body:
     TargetType: Self
     TargetType: Self
     DamageFlags:
     DamageFlags:
       NoDamage: true
       NoDamage: true
-    Hit: Single
     AfterCastActDelay:
     AfterCastActDelay:
       - Level: 1
       - Level: 1
         Time: 300000
         Time: 300000

+ 7 - 0
db/pre-re/status.yml

@@ -2496,6 +2496,9 @@ Body:
     CalcFlags:
     CalcFlags:
       Batk: true
       Batk: true
       Watk: true
       Watk: true
+    Flags:
+      NoSave: true
+      RemoveFromHomOnWarp: true
   - Status: Fleet
   - Status: Fleet
     DurationLookup: HFLI_FLEET
     DurationLookup: HFLI_FLEET
     CalcFlags:
     CalcFlags:
@@ -2510,6 +2513,10 @@ Body:
     DurationLookup: HAMI_DEFENCE
     DurationLookup: HAMI_DEFENCE
     CalcFlags:
     CalcFlags:
       Def: true
       Def: true
+      Vit: true
+    Flags:
+      NoSave: true
+      RemoveFromHomOnWarp: true
   - Status: Incaspdrate
   - Status: Incaspdrate
     CalcFlags:
     CalcFlags:
       Aspd: true
       Aspd: true

+ 0 - 5
db/re/skill_db.yml

@@ -43106,7 +43106,6 @@ Body:
     TargetType: Self
     TargetType: Self
     DamageFlags:
     DamageFlags:
       NoDamage: true
       NoDamage: true
-    Hit: Single
     AfterCastWalkDelay: 1000
     AfterCastWalkDelay: 1000
     Cooldown: 1000
     Cooldown: 1000
     Requires:
     Requires:
@@ -43118,7 +43117,6 @@ Body:
     TargetType: Self
     TargetType: Self
     DamageFlags:
     DamageFlags:
       NoDamage: true
       NoDamage: true
-    Hit: Single
     AfterCastWalkDelay: 1000
     AfterCastWalkDelay: 1000
     Duration1:
     Duration1:
       - Level: 1
       - Level: 1
@@ -43149,8 +43147,6 @@ Body:
     Name: HAMI_SKIN
     Name: HAMI_SKIN
     Description: Adamantium Skin
     Description: Adamantium Skin
     MaxLevel: 5
     MaxLevel: 5
-    DamageFlags:
-      NoDamage: true
   - Id: 8008
   - Id: 8008
     Name: HAMI_BLOODLUST
     Name: HAMI_BLOODLUST
     Description: Bloodlust
     Description: Bloodlust
@@ -43158,7 +43154,6 @@ Body:
     TargetType: Self
     TargetType: Self
     DamageFlags:
     DamageFlags:
       NoDamage: true
       NoDamage: true
-    Hit: Single
     AfterCastWalkDelay: 1000
     AfterCastWalkDelay: 1000
     Duration1:
     Duration1:
       - Level: 1
       - Level: 1

+ 7 - 0
db/re/status.yml

@@ -2618,6 +2618,9 @@ Body:
     CalcFlags:
     CalcFlags:
       Batk: true
       Batk: true
       Watk: true
       Watk: true
+    Flags:
+      NoSave: true
+      RemoveFromHomOnMapWarp: true
   - Status: Fleet
   - Status: Fleet
     DurationLookup: HFLI_FLEET
     DurationLookup: HFLI_FLEET
     CalcFlags:
     CalcFlags:
@@ -2631,7 +2634,11 @@ Body:
   - Status: Defence
   - Status: Defence
     DurationLookup: HAMI_DEFENCE
     DurationLookup: HAMI_DEFENCE
     CalcFlags:
     CalcFlags:
+      Def: true
       Vit: true
       Vit: true
+    Flags:
+      NoSave: true
+      RemoveFromHomOnMapWarp: true
   - Status: Incaspdrate
   - Status: Incaspdrate
     CalcFlags:
     CalcFlags:
       Aspd: true
       Aspd: true

+ 10 - 7
doc/status_change.txt

@@ -1012,9 +1012,12 @@ SC_CHANGE	(EFST_HLIF_CHANGE)
 	val2: VIT increase (20 * val1)
 	val2: VIT increase (20 * val1)
 	val3: INT increase (30 * val1)
 	val3: INT increase (30 * val1)
 
 
-SC_BLOODLUST	()
-	desc:
-	val1:
+SC_BLOODLUST	(EFST_HAMI_BLOODLUST)
+	desc: Increase the homunculus ATK and has a chance to leech HP from the target
+	val1: Skill Level
+	val2: ATK increase (20 + (10 * val1))
+	val3: Chance to leech HP (9 * val1)%
+	val4: Leeched HP percentage 20%
 
 
 SC_FLEET	()
 SC_FLEET	()
 	desc:
 	desc:
@@ -1024,10 +1027,10 @@ SC_SPEED	()
 	desc:
 	desc:
 	val1:
 	val1:
 
 
-SC_DEFENCE	()
-	desc: Increase Defense, HAMI_DEFENCE effect
-	val1: (none)
-	val2: + Def(Pre-renewal) or VIT (Renewal)
+SC_DEFENCE	(EFST_HAMI_DEFENCE)
+	desc: Increase VIT and as result VIT-based DEF of the Player and plain VIT of the Homunculus
+	val1: Skill Level
+	val2: VIT increase for players, DEF increase for homunculus (5 + (5 * val1)) [Renewal], (2 * val1) [Pre-Renewal]
 
 
 SC_INCASPDRATE	()
 SC_INCASPDRATE	()
 	desc: Increase ASPD
 	desc: Increase ASPD

+ 2 - 2
src/map/battle.cpp

@@ -1900,8 +1900,8 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 			}
 			}
 		}
 		}
 
 
-		if ((sce = sc->getSCE(SC_BLOODLUST)) && flag&BF_WEAPON && damage > 0 && rnd()%100 < sce->val3)
-			status_heal(src, damage * sce->val4 / 100, 0, 3);
+		if ((sce = sc->getSCE(SC_BLOODLUST)) && flag & BF_WEAPON && damage > 0 && rnd_chance(sce->val3, 100))
+			status_heal(src, damage * sce->val4 / 100, 0, 1);
 
 
 		if ((sce = sc->getSCE(SC_BLOODSUCKER)) && flag & BF_WEAPON && damage > 0 && rnd() % 100 < (2 * sce->val1 - 1))
 		if ((sce = sc->getSCE(SC_BLOODSUCKER)) && flag & BF_WEAPON && damage > 0 && rnd() % 100 < (2 * sce->val1 - 1))
 			status_heal(src, damage * sce->val1 / 100, 0, 3);
 			status_heal(src, damage * sce->val1 / 100, 0, 3);

+ 18 - 13
src/map/skill.cpp

@@ -8236,8 +8236,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 		break;
 		break;
 	case HLIF_AVOID:
 	case HLIF_AVOID:
 	case HAMI_DEFENCE:
 	case HAMI_DEFENCE:
-		sc_start(src,bl,type,100,skill_lv,skill_get_time(skill_id,skill_lv)); // Master
-		clif_skill_nodamage(src,src,skill_id,skill_lv,sc_start(src,src,type,100,skill_lv,skill_get_time(skill_id,skill_lv))); // Homunc
+		// Master
+		sc_start(src, bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv));
+		// Homunculus
+		clif_skill_nodamage(src, src, skill_id, skill_lv, sc_start(src, src, type, 100, skill_lv, skill_get_time(skill_id, skill_lv)));
 		break;
 		break;
 	case NJ_BUNSINJYUTSU:
 	case NJ_BUNSINJYUTSU:
 		status_change_end(bl, SC_BUNSINJYUTSU); // on official recasting cancels existing mirror image [helvetica]
 		status_change_end(bl, SC_BUNSINJYUTSU); // on official recasting cancels existing mirror image [helvetica]
@@ -10670,23 +10672,26 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 
 
 	case HAMI_CASTLE:	//[orn]
 	case HAMI_CASTLE:	//[orn]
 		if (src != bl && rnd_chance(20 * skill_lv, 100)) {
 		if (src != bl && rnd_chance(20 * skill_lv, 100)) {
-			int x = src->x, y = src->y;
+			// Get one of the monsters targeting the player and set the homunculus as its new target
+			if (block_list* tbl = battle_getenemy(bl, BL_MOB, AREA_SIZE); tbl != nullptr) {
+				if (unit_data* ud = unit_bl2ud(tbl); ud != nullptr)
+					unit_changetarget_sub(*ud, *src);
+			}
 
 
-			// Move source
-			if (unit_movepos(src,bl->x,bl->y,0,0)) {
-				clif_skill_nodamage(src,src,skill_id,skill_lv,1); // Homunc
+			int16 x = src->x, y = src->y;
+			// Move homunculus
+			if (unit_movepos(src, bl->x, bl->y, 0, false)) {
 				clif_blown(src);
 				clif_blown(src);
-				// Move target
-				if (unit_movepos(bl,x,y,0,0)) {
-					clif_skill_nodamage(bl,bl,skill_id,skill_lv,1);
+				// Move player
+				if (unit_movepos(bl, x, y, 0, false))
 					clif_blown(bl);
 					clif_blown(bl);
-				}
-				map_foreachinallrange(unit_changetarget,src,AREA_SIZE,BL_MOB,bl,src);
+				// Show the animation on the homunculus only
+				clif_skill_nodamage(src, src, skill_id, skill_lv, 1);
 			}
 			}
 		}
 		}
-		else if (hd && hd->master) // Failed
+		else if (hd != nullptr && hd->master != nullptr)
 			clif_skill_fail( *hd->master, skill_id );
 			clif_skill_fail( *hd->master, skill_id );
-		else if (sd)
+		else if (sd != nullptr)
 			clif_skill_fail( *sd, skill_id );
 			clif_skill_fail( *sd, skill_id );
 		break;
 		break;
 	case HVAN_CHAOTIC:	//[orn]
 	case HVAN_CHAOTIC:	//[orn]

+ 13 - 11
src/map/status.cpp

@@ -6686,10 +6686,8 @@ static unsigned short status_calc_vit(struct block_list *bl, status_change *sc,
 		vit -= vit * sc->getSCE(SC_STRIPARMOR)->val2/100;
 		vit -= vit * sc->getSCE(SC_STRIPARMOR)->val2/100;
 	if(sc->getSCE(SC_FULL_THROTTLE))
 	if(sc->getSCE(SC_FULL_THROTTLE))
 		vit += vit * sc->getSCE(SC_FULL_THROTTLE)->val3 / 100;
 		vit += vit * sc->getSCE(SC_FULL_THROTTLE)->val3 / 100;
-#ifdef RENEWAL
-	if(sc->getSCE(SC_DEFENCE))
+	if(bl->type == BL_PC && sc->getSCE(SC_DEFENCE))
 		vit += sc->getSCE(SC_DEFENCE)->val2;
 		vit += sc->getSCE(SC_DEFENCE)->val2;
-#endif
 	if(sc->getSCE(SC_CHEERUP))
 	if(sc->getSCE(SC_CHEERUP))
 		vit += 3;
 		vit += 3;
 	if(sc->getSCE(SC_GLASTHEIM_STATE))
 	if(sc->getSCE(SC_GLASTHEIM_STATE))
@@ -7707,10 +7705,9 @@ static defType status_calc_def(struct block_list *bl, status_change *sc, int def
 #ifdef RENEWAL
 #ifdef RENEWAL
 	if (sc->getSCE(SC_ASSUMPTIO))
 	if (sc->getSCE(SC_ASSUMPTIO))
 		def += sc->getSCE(SC_ASSUMPTIO)->val1 * 50;
 		def += sc->getSCE(SC_ASSUMPTIO)->val1 * 50;
-#else
-	if(sc->getSCE(SC_DEFENCE))
-		def += sc->getSCE(SC_DEFENCE)->val2;
 #endif
 #endif
+	if (bl->type == BL_HOM && sc->getSCE(SC_DEFENCE))
+		def += sc->getSCE(SC_DEFENCE)->val2;
 	if(sc->getSCE(SC_INCDEFRATE))
 	if(sc->getSCE(SC_INCDEFRATE))
 		def += def * sc->getSCE(SC_INCDEFRATE)->val1/100;
 		def += def * sc->getSCE(SC_INCDEFRATE)->val1/100;
 	if(sc->getSCE(SC_EARTH_INSIGNIA) && sc->getSCE(SC_EARTH_INSIGNIA)->val1 == 2)
 	if(sc->getSCE(SC_EARTH_INSIGNIA) && sc->getSCE(SC_EARTH_INSIGNIA)->val1 == 2)
@@ -11506,16 +11503,21 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 				val2 = 10 * val1;
 				val2 = 10 * val1;
 			break;
 			break;
 		case SC_DEFENCE:
 		case SC_DEFENCE:
+			// Vit bonus for players / Def bonus for homunculus
 #ifdef RENEWAL
 #ifdef RENEWAL
-			val2 = 5 + (val1 * 5); // Vit bonus
+			val2 = 5 + (5 * val1);
 #else
 #else
-			val2 = 2*val1; // Def bonus
+			val2 = 2 * val1;
 #endif
 #endif
 			break;
 			break;
 		case SC_BLOODLUST:
 		case SC_BLOODLUST:
-			val2 = 20+10*val1; // Atk rate change.
-			val3 = 3*val1; // Leech chance
-			val4 = 20; // Leech percent
+			// Atk rate change
+			val2 = 20 + (10 * val1);
+			// Leech chance
+			// It's actually 9 * level on both pre-re and renewal, despite the description
+			val3 = 9 * val1;
+			// Leech percent
+			val4 = 20;
 			break;
 			break;
 		case SC_FLEET:
 		case SC_FLEET:
 			val2 = 30*val1; // Aspd change
 			val2 = 30*val1; // Aspd change

+ 27 - 15
src/map/unit.cpp

@@ -3130,32 +3130,44 @@ int unit_counttargeted(struct block_list* bl)
  * @param src Current target
  * @param src Current target
  * @param target New target
  * @param target New target
  **/
  **/
-int unit_changetarget(struct block_list *bl, va_list ap) {
-	struct unit_data *ud = unit_bl2ud(bl);
-	struct block_list *src = va_arg(ap,struct block_list *);
-	struct block_list *target = va_arg(ap,struct block_list *);
+int unit_changetarget(block_list *bl, va_list ap) {
+	if (bl == nullptr)
+		return 1;
+	unit_data *ud = unit_bl2ud(bl);
+	block_list *src = va_arg(ap, block_list *);
+	block_list *target = va_arg(ap, block_list *);
 
 
-	if (!ud || !target || ud->target == target->id)
+	if (ud == nullptr || src == nullptr || target == nullptr || ud->target == target->id)
 		return 1;
 		return 1;
-	if (!ud->target && !ud->target_to)
+	if (ud->target <= 0 && ud->target_to <= 0)
 		return 1;
 		return 1;
 	if (ud->target != src->id && ud->target_to != src->id)
 	if (ud->target != src->id && ud->target_to != src->id)
 		return 1;
 		return 1;
 
 
-	if (bl->type == BL_MOB)
-		(BL_CAST(BL_MOB,bl))->target_id = target->id;
-	if (ud->target_to)
-		ud->target_to = target->id;
-	else
-		ud->target_to = 0;
-	if (ud->skilltarget)
-		ud->skilltarget = target->id;
-	unit_set_target(ud, target->id);
+	unit_changetarget_sub(*ud, *target);
 
 
 	//unit_attack(bl, target->id, ud->state.attack_continue);
 	//unit_attack(bl, target->id, ud->state.attack_continue);
 	return 0;
 	return 0;
 }
 }
 
 
+/**
+ * Changes the target of a unit
+ * @param ud: Unit data
+ * @param target: New target data
+ **/
+void unit_changetarget_sub(unit_data& ud, block_list& target) {
+	if (status_isdead(target))
+		return;
+
+	if (ud.bl->type == BL_MOB)
+		reinterpret_cast<mob_data*>(ud.bl)->target_id = target.id;
+	if (ud.target_to > 0)
+		ud.target_to = target.id;
+	if (ud.skilltarget > 0)
+		ud.skilltarget = target.id;
+	unit_set_target(&ud, target.id);
+}
+
 /**
 /**
  * Removes a bl/ud from the map
  * Removes a bl/ud from the map
  * On kill specifics are not performed here, check status_damage()
  * On kill specifics are not performed here, check status_damage()

+ 2 - 2
src/map/unit.hpp

@@ -172,8 +172,8 @@ void unit_free_pc(map_session_data *sd);
 #define unit_remove_map(bl,clrtype) unit_remove_map_(bl,clrtype,__FILE__,__LINE__,__func__)
 #define unit_remove_map(bl,clrtype) unit_remove_map_(bl,clrtype,__FILE__,__LINE__,__func__)
 int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file, int line, const char* func);
 int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file, int line, const char* func);
 int unit_free(struct block_list *bl, clr_type clrtype);
 int unit_free(struct block_list *bl, clr_type clrtype);
-int unit_changeviewsize(struct block_list *bl,short size);
-int unit_changetarget(struct block_list *bl,va_list ap);
+int unit_changetarget(block_list *bl,va_list ap);
+void unit_changetarget_sub(unit_data& ud, block_list& target);
 
 
 // Shadow Scar
 // Shadow Scar
 void unit_addshadowscar(unit_data &ud, int interval);
 void unit_addshadowscar(unit_data &ud, int interval);