diff --git a/src/map/battle.cpp b/src/map/battle.cpp index 51732d8ff8..e7e2e9d7d0 100644 --- a/src/map/battle.cpp +++ b/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; }