Fix NPC_DAMAGE_HEAL heal calculation (#7660)
Fix NPC_DAMAGE_HEAL heal amount not being applied from some SC bonuses
This commit is contained in:
parent
cf0264be45
commit
8a4b34ef6a
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user