diff --git a/src/map/battle.c b/src/map/battle.c index 302ed3cbc6..2982e65067 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -809,19 +809,19 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam //uint16 skill_id = sc->data[SC_SAFETYWALL]->val2; (safetywall or steinwand) if (group) { //in RE, SW possesses a lifetime equal to group val2, (3x caster hp, or homon formula) - #ifdef RENEWAL +#ifdef RENEWAL d->dmg_lv = ATK_BLOCK; if ( ( group->val2 - damage) > 0 ) { group->val2 -= (int)cap_value(damage,INT_MIN,INT_MAX); } else skill_delunitgroup(group); return 0; - #else +#else if (--group->val2<=0) skill_delunitgroup(group); d->dmg_lv = ATK_BLOCK; return 0; - #endif +#endif } status_change_end(bl, SC_SAFETYWALL, INVALID_TIMER); } @@ -4131,63 +4131,21 @@ struct Damage battle_calc_attack_left_right_hands(struct Damage wd, struct block struct Damage battle_calc_attack_gvg_bg(struct Damage wd, struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv) { if( wd.damage + wd.damage2 ) { //There is a total damage value - if( src != target && - (!skill_id || skill_id || - ( src->type == BL_SKILL && ( skill_id == SG_SUN_WARM || skill_id == SG_MOON_WARM || skill_id == SG_STAR_WARM ) )) ){ - int64 damage = wd.damage + wd.damage2, rdamage = 0; - struct map_session_data *tsd = BL_CAST(BL_PC, target); - struct status_change *tsc = status_get_sc(target); - struct status_data *sstatus = status_get_status_data(src); - int tick = gettick(), rdelay = 0; - - rdamage = battle_calc_return_damage(target, src, &damage, wd.flag, skill_id, 0); - - // Item reflect gets calculated first - if( rdamage > 0 ) { - //Use Reflect Shield to signal this kind of skill trigger. [Skotlex] - rdelay = clif_damage(src, src, tick, wd.amotion, sstatus->dmotion, rdamage, 1, 4, 0); - if( tsd && src != target ) - battle_drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src)); - battle_delay_damage(tick, wd.amotion,target,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,rdelay,true); - skill_additional_effect(target, src, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick); - } - - // Calculate skill reflect damage separately - if( tsc ) { - struct status_data *tstatus = status_get_status_data(target); - rdamage = battle_calc_return_damage(target, src, &damage, wd.flag, skill_id, 1); - if( rdamage > 0 ) { - if( tsc->data[SC_REFLECTDAMAGE] && src != target ) // Don't reflect your own damage (Grand Cross) - map_foreachinshootrange(battle_damage_area,target,skill_get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,tick,target,wd.amotion,sstatus->dmotion,rdamage,tstatus->race); - else { - rdelay = clif_damage(src, src, tick, wd.amotion, sstatus->dmotion, rdamage, 1, 4, 0); - if( tsd && src != target ) - battle_drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src)); - // It appears that official servers give skill reflect damage a longer delay - battle_delay_damage(tick, wd.amotion,target,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,rdelay,true); - skill_additional_effect(target, src, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick); - } - } - } - } - if(!wd.damage2) - { + if(!wd.damage2) { wd.damage = battle_calc_damage(src,target,&wd,wd.damage,skill_id,skill_lv); if( map_flag_gvg2(target->m) ) wd.damage=battle_calc_gvg_damage(src,target,wd.damage,wd.div_,skill_id,skill_lv,wd.flag); else if( map[target->m].flag.battleground ) wd.damage=battle_calc_bg_damage(src,target,wd.damage,wd.div_,skill_id,skill_lv,wd.flag); } - else if(!wd.damage) - { + else if(!wd.damage) { wd.damage2 = battle_calc_damage(src,target,&wd,wd.damage2,skill_id,skill_lv); if( map_flag_gvg2(target->m) ) wd.damage2 = battle_calc_gvg_damage(src,target,wd.damage2,wd.div_,skill_id,skill_lv,wd.flag); else if( map[target->m].flag.battleground ) wd.damage2 = battle_calc_bg_damage(src,target,wd.damage2,wd.div_,skill_id,skill_lv,wd.flag); } - else - { + else { int64 d1 = wd.damage + wd.damage2,d2 = wd.damage2; wd.damage = battle_calc_damage(src,target,&wd,d1,skill_id,skill_lv); if( map_flag_gvg2(target->m) ) @@ -4277,16 +4235,22 @@ struct Damage battle_calc_weapon_final_atk_modifiers(struct Damage wd, struct bl } status_change_end(src,SC_CAMOUFLAGE, INVALID_TIMER); } - if( skill_id == LG_RAYOFGENESIS ) { - struct Damage md = battle_calc_magic_attack(src, target, skill_id, skill_lv, wd.miscflag); - wd.damage += md.damage; - } + switch (skill_id) { + case LG_RAYOFGENESIS: + { + struct Damage md = battle_calc_magic_attack(src, target, skill_id, skill_lv, wd.miscflag); + wd.damage += md.damage; + } + break; #ifndef RENEWAL - else if(skill_id == ASC_BREAKER) { //Breaker's int-based damage (a misc attack?) - struct Damage md = battle_calc_misc_attack(src, target, skill_id, skill_lv, wd.miscflag); - wd.damage += md.damage; - } + case ASC_BREAKER: + { //Breaker's int-based damage (a misc attack?) + struct Damage md = battle_calc_misc_attack(src, target, skill_id, skill_lv, wd.miscflag); + wd.damage += md.damage; + } + break; #endif + } return wd; } @@ -4538,16 +4502,19 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl wd.damage2 += battle_calc_cardfix(BF_WEAPON, src, target, battle_skill_get_damage_properties(skill_id, wd.miscflag), right_element, left_element, wd.damage2, 3, wd.flag); #endif } - + if(tsd) { // Card Fix for target (tsd), 2 is not added to the "left" flag meaning "target cards only" switch(skill_id) { // These skills will do a card fix later - case CR_ACIDDEMONSTRATION: +#ifdef RENEWAL case NJ_ISSEN: case ASC_BREAKER: +#endif + case CR_ACIDDEMONSTRATION: case KO_HAPPOKUNAI: break; default: wd.damage += battle_calc_cardfix(BF_WEAPON, src, target, battle_skill_get_damage_properties(skill_id, wd.miscflag), right_element, left_element, wd.damage, is_attack_left_handed(src, skill_id), wd.flag); + break; } } @@ -4577,17 +4544,19 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl return battle_calc_attack_plant(wd, src, target, skill_id, skill_lv); wd = battle_calc_attack_left_right_hands(wd, src, target, skill_id, skill_lv); - wd = battle_calc_weapon_final_atk_modifiers(wd, src, target, skill_id, skill_lv); - switch(skill_id) { // These skills will do a GVG fix later - case CR_ACIDDEMONSTRATION: + switch (skill_id) { // These skills will do a GVG fix later +#ifdef RENEWAL case NJ_ISSEN: case ASC_BREAKER: +#endif + case CR_ACIDDEMONSTRATION: case KO_HAPPOKUNAI: return wd; default: wd = battle_calc_attack_gvg_bg(wd, src, target, skill_id, skill_lv); + break; } /* Skill damage adjustment */ @@ -4595,6 +4564,48 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl if ((skill_damage = battle_skill_damage(src, target, skill_id)) != 0) ATK_ADDRATE(wd.damage, wd.damage2, skill_damage); #endif + + // Do reflect calculation after all atk modifier + if( wd.damage + wd.damage2 && src != target && + (src->type != BL_SKILL || + (src->type == BL_SKILL && ( skill_id == SG_SUN_WARM || skill_id == SG_MOON_WARM || skill_id == SG_STAR_WARM ))) ) + { + int64 damage = wd.damage + wd.damage2, rdamage = 0; + struct map_session_data *tsd = BL_CAST(BL_PC, target); + struct status_change *tsc = status_get_sc(target); + struct status_data *sstatus = status_get_status_data(src); + int tick = gettick(), rdelay = 0; + + rdamage = battle_calc_return_damage(target, src, &damage, wd.flag, skill_id, 0); + + // Item reflect gets calculated first + if( rdamage > 0 ) { + //Use Reflect Shield to signal this kind of skill trigger. [Skotlex] + rdelay = clif_damage(src, src, tick, wd.amotion, sstatus->dmotion, rdamage, 1, 4, 0); + if( tsd ) + battle_drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src)); + battle_delay_damage(tick, wd.amotion,target,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,rdelay,true); + skill_additional_effect(target, src, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick); + } + + // Calculate skill reflect damage separately + if( tsc ) { + struct status_data *tstatus = status_get_status_data(target); + rdamage = battle_calc_return_damage(target, src, &damage, wd.flag, skill_id, 1); + if( rdamage > 0 ) { + if( tsc->data[SC_REFLECTDAMAGE] ) // Don't reflect your own damage (Grand Cross) + map_foreachinshootrange(battle_damage_area,target,skill_get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,tick,target,wd.amotion,sstatus->dmotion,rdamage,tstatus->race); + else { + rdelay = clif_damage(src, src, tick, wd.amotion, sstatus->dmotion, rdamage, 1, 4, 0); + if( tsd ) + battle_drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src)); + // It appears that official servers give skill reflect damage a longer delay + battle_delay_damage(tick, wd.amotion,target,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,rdelay,true); + skill_additional_effect(target, src, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick); + } + } + } + } return wd; } @@ -5256,8 +5267,10 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list ad.damage = ad.damage>0?1:-1; switch(skill_id) { // These skills will do a GVG fix later - case CR_ACIDDEMONSTRATION: +#ifdef RENEWAL case ASC_BREAKER: +#endif + case CR_ACIDDEMONSTRATION: return ad; default: ad.damage=battle_calc_damage(src,target,&ad,ad.damage,skill_id,skill_lv); @@ -5440,7 +5453,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * md.damage=md.damage/2; break; #ifdef RENEWAL - case NJ_ISSEN: + case NJ_ISSEN: // Official Renewal formula [helvetica] // base damage = currenthp + ((atk * currenthp * skill level) / maxhp) // final damage = base damage + ((mirror image count + 1) / 5 * base damage) - (edef + sdef) @@ -5461,7 +5474,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * md.damage -= totaldef; } break; -#endif +#endif case GS_FLING: md.damage = sd?sd->status.job_level:status_get_lv(src); break; @@ -5484,14 +5497,14 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * { short totaldef, totalmdef; struct Damage atk, matk; - + atk = battle_calc_weapon_attack(src, target, skill_id, skill_lv, 0); nk|=NK_NO_ELEFIX; // atk part takes on weapon element, matk part is non-elemental matk = battle_calc_magic_attack(src, target, skill_id, skill_lv, 0); - + // (atk + matk) * (3 + (.5 * skill level)) md.damage = ((30 + (5 * skill_lv)) * (atk.damage + matk.damage)) / 10; - + // modified def reduction, final damage = base damage - (edef + sdef + emdef + smdef) totaldef = tstatus->def2 + (short)status_get_def(target); totalmdef = tstatus->mdef + tstatus->mdef2; diff --git a/src/map/skill.c b/src/map/skill.c index 2bb533ca65..bc6bb6c408 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -452,6 +452,7 @@ static short skill_isCopyable (struct map_session_data *sd, uint16 skill_id, str return 0; // Added so plagarize can't copy agi/bless if you're undead since it damages you + // NOTE: Is this still needed since we use skill_copyable_db now? if (skill_get_inf3(skill_id)&INF3_DIS_PLAGIA) return 0;