Parcourir la source

Fix NPC_DAMAGE_HEAL heal calculation (#7660)

Fix NPC_DAMAGE_HEAL heal amount not being applied from some SC bonuses
eppc0330 il y a 2 ans
Parent
commit
8a4b34ef6a
1 fichiers modifiés avec 63 ajouts et 62 suppressions
  1. 63 62
      src/map/battle.cpp

+ 63 - 62
src/map/battle.cpp

@@ -1506,7 +1506,6 @@ bool battle_status_block_damage(struct block_list *src, struct block_list *targe
 int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damage *d,int64 damage,uint16 skill_id,uint16 skill_lv)
 {
 	map_session_data *sd = NULL, *tsd = BL_CAST(BL_PC, src);
-	status_change *sc;
 	struct status_change_entry *sce;
 	int div_ = d->div_, flag = d->flag;
 
@@ -1537,9 +1536,9 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 			return 0;
 	}
 
-	sc = status_get_sc(bl); //check target status
+	status_change* tsc = status_get_sc(bl); //check target status
 
-	if( sc && sc->getSCE(SC_INVINCIBLE) && !sc->getSCE(SC_INVINCIBLEOFF) )
+	if( tsc && tsc->getSCE(SC_INVINCIBLE) && !tsc->getSCE(SC_INVINCIBLEOFF) )
 		return 1;
 
 	switch (skill_id) {
@@ -1557,7 +1556,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 
 	// Nothing can reduce the damage, but Safety Wall and Millennium Shield can block it completely.
 	// So can defense sphere's but what the heck is that??? [Rytech]
-	if (skill_id == SJ_NOVAEXPLOSING && !(sc && (sc->getSCE(SC_SAFETYWALL) || sc->getSCE(SC_MILLENNIUMSHIELD)))) {
+	if (skill_id == SJ_NOVAEXPLOSING && !(tsc && (tsc->getSCE(SC_SAFETYWALL) || tsc->getSCE(SC_MILLENNIUMSHIELD)))) {
 		// Adjust this based on any possible PK damage rates.
 		if (battle_config.pk_mode == 1 && map_getmapflag(bl->m, MF_PVP) > 0)
 			damage = battle_calc_pk_damage(*src, *bl, damage, skill_id, flag);
@@ -1565,17 +1564,14 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 		return damage;
 	}
 
-	if( sc && sc->count ) {
-		if (!battle_status_block_damage(src, bl, sc, d, damage, skill_id, skill_lv)) // Statuses that reduce damage to 0.
-			return 0;
-
+	if( tsc && tsc->count ) {
 		// Damage increasing effects
 #ifdef RENEWAL // Flat +400% damage from melee
-		if (sc->getSCE(SC_KAITE) && (flag&(BF_SHORT|BF_MAGIC)) == BF_SHORT)
+		if (tsc->getSCE(SC_KAITE) && (flag&(BF_SHORT|BF_MAGIC)) == BF_SHORT)
 			damage *= 4;
 #endif
 
-		if (sc->getSCE(SC_AETERNA) && skill_id != PF_SOULBURN) {
+		if (tsc->getSCE(SC_AETERNA) && skill_id != PF_SOULBURN) {
 			if (src->type != BL_MER || !skill_id)
 				damage *= 2; // Lex Aeterna only doubles damage of regular attacks from mercenaries
 
@@ -1586,7 +1582,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 		}
 
 #ifdef RENEWAL
-		if( sc->getSCE(SC_RAID) ) {
+		if( tsc->getSCE(SC_RAID) ) {
 			if (status_get_class_(bl) == CLASS_BOSS)
 				damage += damage * 15 / 100;
 			else
@@ -1595,11 +1591,11 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 #endif
 
 		if( damage ) {
-			if( sc->getSCE(SC_DEEPSLEEP) ) {
+			if( tsc->getSCE(SC_DEEPSLEEP) ) {
 				damage += damage / 2; // 1.5 times more damage while in Deep Sleep.
 				status_change_end(bl,SC_DEEPSLEEP);
 			}
-			if( tsd && sd && sc->getSCE(SC_CRYSTALIZE) && flag&BF_WEAPON ) {
+			if( tsd && sd && tsc->getSCE(SC_CRYSTALIZE) && flag&BF_WEAPON ) {
 				switch(tsd->status.weapon) {
 					case W_MACE:
 					case W_2HMACE:
@@ -1624,15 +1620,15 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 						break;
 				}
 			}
-			if( sc->getSCE(SC_VOICEOFSIREN) )
+			if( tsc->getSCE(SC_VOICEOFSIREN) )
 				status_change_end(bl,SC_VOICEOFSIREN);
 		}
 
-		if (sc->getSCE(SC_SOUNDOFDESTRUCTION))
+		if (tsc->getSCE(SC_SOUNDOFDESTRUCTION))
 			damage *= 2;
-		if (sc->getSCE(SC_DARKCROW) && (flag&(BF_SHORT|BF_MAGIC)) == BF_SHORT) {
-			int bonus = sc->getSCE(SC_DARKCROW)->val2;
-		if( sc->getSCE(SC_BURNT) && status_get_element(src) == ELE_FIRE )
+		if (tsc->getSCE(SC_DARKCROW) && (flag&(BF_SHORT|BF_MAGIC)) == BF_SHORT) {
+			int bonus = tsc->getSCE(SC_DARKCROW)->val2;
+		if( tsc->getSCE(SC_BURNT) && status_get_element(src) == ELE_FIRE )
 			damage += damage * 666 / 100; //Custom value
 
 			if (status_get_class_(bl) == CLASS_BOSS)
@@ -1640,15 +1636,15 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 
 			damage += damage * bonus / 100;
 		}
-		if (sc->getSCE(SC_HOLY_OIL) && (flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
+		if (tsc->getSCE(SC_HOLY_OIL) && (flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
 			damage += damage * 50 / 100;// Need official adjustment. [Rytech]
-		if (sc->getSCE(SC_SHADOW_SCAR)) // !TODO: Need official adjustment for this too.
-			damage += damage * (3 * sc->getSCE(SC_SHADOW_SCAR)->val1) / 100;
+		if (tsc->getSCE(SC_SHADOW_SCAR)) // !TODO: Need official adjustment for this too.
+			damage += damage * (3 * tsc->getSCE(SC_SHADOW_SCAR)->val1) / 100;
 
 		// Damage reductions
 		// Assumptio increases DEF on RE mode, otherwise gives a reduction on the final damage. [Igniz]
 #ifndef RENEWAL
-		if( sc->getSCE(SC_ASSUMPTIO) ) {
+		if( tsc->getSCE(SC_ASSUMPTIO) ) {
 			if( map_flag_vs(bl->m) )
 				damage = (int64)damage*2/3; //Receive 66% damage
 			else
@@ -1656,47 +1652,47 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 		}
 #endif
 
-		if (sc->getSCE(SC_DEFENDER) &&
+		if (tsc->getSCE(SC_DEFENDER) &&
 			skill_id != NJ_ZENYNAGE && skill_id != KO_MUCHANAGE &&
 #ifdef RENEWAL
 			((flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON) || skill_id == GN_FIRE_EXPANSION_ACID))
 #else
 			(flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
 #endif
-			damage -= damage * sc->getSCE(SC_DEFENDER)->val2 / 100;
+			damage -= damage * tsc->getSCE(SC_DEFENDER)->val2 / 100;
 
-		if(sc->getSCE(SC_ADJUSTMENT) && (flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
+		if(tsc->getSCE(SC_ADJUSTMENT) && (flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
 			damage -= damage * 20 / 100;
 
-		if(sc->getSCE(SC_FOGWALL) && skill_id != RK_DRAGONBREATH && skill_id != RK_DRAGONBREATH_WATER && skill_id != NPC_DRAGONBREATH) {
+		if(tsc->getSCE(SC_FOGWALL) && skill_id != RK_DRAGONBREATH && skill_id != RK_DRAGONBREATH_WATER && skill_id != NPC_DRAGONBREATH) {
 			if(flag&BF_SKILL) //25% reduction
 				damage -= damage * 25 / 100;
 			else if ((flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
 				damage /= 4; //75% reduction
 		}
 
-		if (sc->getSCE(SC_SPORE_EXPLOSION) && (flag & BF_LONG) == BF_LONG)
+		if (tsc->getSCE(SC_SPORE_EXPLOSION) && (flag & BF_LONG) == BF_LONG)
 			damage += damage * (status_get_class(bl) == CLASS_BOSS ? 5 : 10) / 100;
 
-		if(sc->getSCE(SC_ARMORCHANGE)) {
+		if(tsc->getSCE(SC_ARMORCHANGE)) {
 			//On official servers, SC_ARMORCHANGE does not change DEF/MDEF but rather increases/decreases the damage
 			if(flag&BF_WEAPON)
-				damage -= damage * sc->getSCE(SC_ARMORCHANGE)->val2 / 100;
+				damage -= damage * tsc->getSCE(SC_ARMORCHANGE)->val2 / 100;
 			else if(flag&BF_MAGIC)
-				damage -= damage * sc->getSCE(SC_ARMORCHANGE)->val3 / 100;
+				damage -= damage * tsc->getSCE(SC_ARMORCHANGE)->val3 / 100;
 		}
 
-		if(sc->getSCE(SC_SMOKEPOWDER)) {
+		if(tsc->getSCE(SC_SMOKEPOWDER)) {
 			if( (flag&(BF_SHORT|BF_WEAPON)) == (BF_SHORT|BF_WEAPON) )
 				damage -= damage * 15 / 100; // 15% reduction to physical melee attacks
 			else if( (flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON) )
 				damage -= damage * 50 / 100; // 50% reduction to physical ranged attacks
 		}
 
-		if (sc->getSCE(SC_WATER_BARRIER))
+		if (tsc->getSCE(SC_WATER_BARRIER))
 			damage = damage * 80 / 100; // 20% reduction to all type attacks
 
-		if (sc->getSCE(SC_SU_STOOP))
+		if (tsc->getSCE(SC_SU_STOOP))
 			damage -= damage * 90 / 100;
 
 		// Compressed code, fixed by map.hpp [Epoque]
@@ -1706,46 +1702,46 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 			for (const auto &raceit : race2) {
 				switch (raceit) {
 					case RC2_MANUK:
-						if (sce = sc->getSCE(SC_MANU_DEF))
+						if (sce = tsc->getSCE(SC_MANU_DEF))
 							damage -= damage * sce->val1 / 100;
 						break;
 					case RC2_SPLENDIDE:
-						if (sce = sc->getSCE(SC_SPL_DEF))
+						if (sce = tsc->getSCE(SC_SPL_DEF))
 							damage -= damage * sce->val1 / 100;
 						break;
 					case RC2_OGH_ATK_DEF:
-						if (sc->getSCE(SC_GLASTHEIM_DEF))
+						if (tsc->getSCE(SC_GLASTHEIM_DEF))
 							return 0;
 						break;
 					case RC2_OGH_HIDDEN:
-						if (sce = sc->getSCE(SC_GLASTHEIM_HIDDEN))
+						if (sce = tsc->getSCE(SC_GLASTHEIM_HIDDEN))
 							damage -= damage * sce->val1 / 100;
 						break;
 					case RC2_BIO5_ACOLYTE_MERCHANT:
-						if (sce = sc->getSCE(SC_LHZ_DUN_N1))
+						if (sce = tsc->getSCE(SC_LHZ_DUN_N1))
 							damage -= damage * sce->val2 / 100;
 						break;
 					case RC2_BIO5_MAGE_ARCHER:
-						if (sce = sc->getSCE(SC_LHZ_DUN_N2))
+						if (sce = tsc->getSCE(SC_LHZ_DUN_N2))
 							damage -= damage * sce->val2 / 100;
 						break;
 					case RC2_BIO5_SWORDMAN_THIEF:
-						if (sce = sc->getSCE(SC_LHZ_DUN_N3))
+						if (sce = tsc->getSCE(SC_LHZ_DUN_N3))
 							damage -= damage * sce->val2 / 100;
 						break;
 					case RC2_BIO5_MVP:
-						if (sce = sc->getSCE(SC_LHZ_DUN_N4))
+						if (sce = tsc->getSCE(SC_LHZ_DUN_N4))
 							damage -= damage * sce->val2 / 100;
 						break;
 				}
 			}
 		}
 
-		if((sce=sc->getSCE(SC_ARMOR)) && //NPC_DEFENDER
+		if((sce=tsc->getSCE(SC_ARMOR)) && //NPC_DEFENDER
 			sce->val3&flag && sce->val4&flag)
-			damage -= damage * sc->getSCE(SC_ARMOR)->val2 / 100;
+			damage -= damage * tsc->getSCE(SC_ARMOR)->val2 / 100;
 
-		if( sc->getSCE(SC_ENERGYCOAT) && (skill_id == GN_HELLS_PLANT_ATK ||
+		if( tsc->getSCE(SC_ENERGYCOAT) && (skill_id == GN_HELLS_PLANT_ATK ||
 #ifdef RENEWAL
 			((flag&BF_WEAPON || flag&BF_MAGIC) && skill_id != WS_CARTTERMINATION)
 #else
@@ -1762,39 +1758,39 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 			damage -= damage * 6 * (1 + per) / 100; //Reduction: 6% + 6% every 20%
 		}
 
-		if(sc->getSCE(SC_GRANITIC_ARMOR))
-			damage -= damage * sc->getSCE(SC_GRANITIC_ARMOR)->val2 / 100;
+		if(tsc->getSCE(SC_GRANITIC_ARMOR))
+			damage -= damage * tsc->getSCE(SC_GRANITIC_ARMOR)->val2 / 100;
 
-		if(sc->getSCE(SC_PAIN_KILLER)) {
-			damage -= sc->getSCE(SC_PAIN_KILLER)->val2;
+		if(tsc->getSCE(SC_PAIN_KILLER)) {
+			damage -= tsc->getSCE(SC_PAIN_KILLER)->val2;
 			damage = i64max(damage, 1);
 		}
 
-		if( (sce=sc->getSCE(SC_MAGMA_FLOW)) && (rnd()%100 <= sce->val2) )
+		if( (sce=tsc->getSCE(SC_MAGMA_FLOW)) && (rnd()%100 <= sce->val2) )
 			skill_castend_damage_id(bl,src,MH_MAGMA_FLOW,sce->val1,gettick(),0);
 
-		if( damage > 0 && (sce = sc->getSCE(SC_STONEHARDSKIN)) ) {
+		if( damage > 0 && (sce = tsc->getSCE(SC_STONEHARDSKIN)) ) {
 			if( src->type == BL_MOB ) //using explicit call instead break_equip for duration
 				sc_start(src,src, SC_STRIPWEAPON, 30, 0, skill_get_time2(RK_STONEHARDSKIN, sce->val1));
 			else if (flag&(BF_WEAPON|BF_SHORT))
 				skill_break_equip(src,src, EQP_WEAPON, 3000, BCT_SELF);
 		}
 
-		if (src->type == BL_PC && sc->getSCE(SC_GVG_GOLEM)) {
+		if (src->type == BL_PC && tsc->getSCE(SC_GVG_GOLEM)) {
 			if (flag&BF_WEAPON)
-				damage -= damage * sc->getSCE(SC_GVG_GOLEM)->val3 / 100;
+				damage -= damage * tsc->getSCE(SC_GVG_GOLEM)->val3 / 100;
 			if (flag&BF_MAGIC)
-				damage -= damage * sc->getSCE(SC_GVG_GOLEM)->val4 / 100;
+				damage -= damage * tsc->getSCE(SC_GVG_GOLEM)->val4 / 100;
 		}
 
 #ifdef RENEWAL
 		// Renewal: steel body reduces all incoming damage to 1/10 [helvetica]
-		if( sc->getSCE(SC_STEELBODY) )
+		if( tsc->getSCE(SC_STEELBODY) )
 			damage = damage > 10 ? damage / 10 : 1;
 #endif
 
 		//Finally added to remove the status of immobile when Aimed Bolt is used. [Jobbie]
-		if( skill_id == RA_AIMEDBOLT && (sc->getSCE(SC_BITE) || sc->getSCE(SC_ANKLE) || sc->getSCE(SC_ELECTRICSHOCKER)) ) {
+		if( skill_id == RA_AIMEDBOLT && (tsc->getSCE(SC_BITE) || tsc->getSCE(SC_ANKLE) || tsc->getSCE(SC_ELECTRICSHOCKER)) ) {
 			status_change_end(bl, SC_BITE);
 			status_change_end(bl, SC_ANKLE);
 			status_change_end(bl, SC_ELECTRICSHOCKER);
@@ -1803,32 +1799,32 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 		if (!damage)
 			return 0;
 
-		if( sd && (sce = sc->getSCE(SC_FORCEOFVANGUARD)) && flag&BF_WEAPON && rnd()%100 < sce->val2 )
+		if( sd && (sce = tsc->getSCE(SC_FORCEOFVANGUARD)) && flag&BF_WEAPON && rnd()%100 < sce->val2 )
 			pc_addspiritball(sd,skill_get_time(LG_FORCEOFVANGUARD,sce->val1),sce->val3);
 
-		if( sd && (sce = sc->getSCE(SC_GT_ENERGYGAIN)) && flag&BF_WEAPON && rnd()%100 < sce->val2 ) {
+		if( sd && (sce = tsc->getSCE(SC_GT_ENERGYGAIN)) && flag&BF_WEAPON && rnd()%100 < sce->val2 ) {
 			int spheres = 5;
 
-			if( sc->getSCE(SC_RAISINGDRAGON) )
-				spheres += sc->getSCE(SC_RAISINGDRAGON)->val1;
+			if( tsc->getSCE(SC_RAISINGDRAGON) )
+				spheres += tsc->getSCE(SC_RAISINGDRAGON)->val1;
 
 			pc_addspiritball(sd, skill_get_time2(SR_GENTLETOUCH_ENERGYGAIN, sce->val1), spheres);
 		}
 
-		if (sc->getSCE(SC_STYLE_CHANGE) && sc->getSCE(SC_STYLE_CHANGE)->val1 == MH_MD_GRAPPLING) {
+		if (tsc->getSCE(SC_STYLE_CHANGE) && tsc->getSCE(SC_STYLE_CHANGE)->val1 == MH_MD_GRAPPLING) {
 			TBL_HOM *hd = BL_CAST(BL_HOM,bl); // We add a sphere for when the Homunculus is being hit
 
 			if (hd && (rnd()%100<50) ) // According to WarpPortal, this is a flat 50% chance
 				hom_addspiritball(hd, 10);
 		}
 
-		if( sc->getSCE(SC__DEADLYINFECT) && (flag&(BF_SHORT|BF_MAGIC)) == BF_SHORT && damage > 0 && rnd()%100 < 30 + 10 * sc->getSCE(SC__DEADLYINFECT)->val1 )
+		if( tsc->getSCE(SC__DEADLYINFECT) && (flag&(BF_SHORT|BF_MAGIC)) == BF_SHORT && damage > 0 && rnd()%100 < 30 + 10 * tsc->getSCE(SC__DEADLYINFECT)->val1 )
 			status_change_spread(bl, src);
 
 	} //End of target SC_ check
 
 	//SC effects from caster side.
-	sc = status_get_sc(src);
+	status_change* sc = status_get_sc(src);
 
 	if (sc && sc->count) {
 		if( sc->getSCE(SC_INVINCIBLE) && !sc->getSCE(SC_INVINCIBLEOFF) )
@@ -1946,6 +1942,11 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 		if (md && md->damagetaken != 100)
 			damage = i64max(damage * md->damagetaken / 100, 1);
 	}
+	
+	if (tsc && tsc->count) {
+		if (!battle_status_block_damage(src, bl, tsc, d, damage, skill_id, skill_lv)) // Statuses that reduce damage to 0.
+			return 0;
+	}
 
 	return damage;
 }