* Fixed bugreport:8103, damage rate calculation should be before reflected damage calculation
* Fixed bugreport:8028, fixed NJ_ISSEN and ASC_BREAKER calculation for PRE-RE (thank @exneval)
This commit is contained in:
parent
f25ca39814
commit
a6f6679751
115
src/map/battle.c
115
src/map/battle.c
@ -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)
|
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( wd.damage + wd.damage2 ) { //There is a total damage value
|
||||||
if( src != target &&
|
if(!wd.damage2) {
|
||||||
(!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)
|
|
||||||
{
|
|
||||||
wd.damage = battle_calc_damage(src,target,&wd,wd.damage,skill_id,skill_lv);
|
wd.damage = battle_calc_damage(src,target,&wd,wd.damage,skill_id,skill_lv);
|
||||||
if( map_flag_gvg2(target->m) )
|
if( map_flag_gvg2(target->m) )
|
||||||
wd.damage=battle_calc_gvg_damage(src,target,wd.damage,wd.div_,skill_id,skill_lv,wd.flag);
|
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 )
|
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);
|
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);
|
wd.damage2 = battle_calc_damage(src,target,&wd,wd.damage2,skill_id,skill_lv);
|
||||||
if( map_flag_gvg2(target->m) )
|
if( map_flag_gvg2(target->m) )
|
||||||
wd.damage2 = battle_calc_gvg_damage(src,target,wd.damage2,wd.div_,skill_id,skill_lv,wd.flag);
|
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 )
|
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);
|
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;
|
int64 d1 = wd.damage + wd.damage2,d2 = wd.damage2;
|
||||||
wd.damage = battle_calc_damage(src,target,&wd,d1,skill_id,skill_lv);
|
wd.damage = battle_calc_damage(src,target,&wd,d1,skill_id,skill_lv);
|
||||||
if( map_flag_gvg2(target->m) )
|
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);
|
status_change_end(src,SC_CAMOUFLAGE, INVALID_TIMER);
|
||||||
}
|
}
|
||||||
if( skill_id == LG_RAYOFGENESIS ) {
|
switch (skill_id) {
|
||||||
|
case LG_RAYOFGENESIS:
|
||||||
|
{
|
||||||
struct Damage md = battle_calc_magic_attack(src, target, skill_id, skill_lv, wd.miscflag);
|
struct Damage md = battle_calc_magic_attack(src, target, skill_id, skill_lv, wd.miscflag);
|
||||||
wd.damage += md.damage;
|
wd.damage += md.damage;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
#ifndef RENEWAL
|
#ifndef RENEWAL
|
||||||
else if(skill_id == ASC_BREAKER) { //Breaker's int-based damage (a misc attack?)
|
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);
|
struct Damage md = battle_calc_misc_attack(src, target, skill_id, skill_lv, wd.miscflag);
|
||||||
wd.damage += md.damage;
|
wd.damage += md.damage;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
return wd;
|
return wd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4541,13 +4505,16 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl
|
|||||||
|
|
||||||
if(tsd) { // Card Fix for target (tsd), 2 is not added to the "left" flag meaning "target cards only"
|
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
|
switch(skill_id) { // These skills will do a card fix later
|
||||||
case CR_ACIDDEMONSTRATION:
|
#ifdef RENEWAL
|
||||||
case NJ_ISSEN:
|
case NJ_ISSEN:
|
||||||
case ASC_BREAKER:
|
case ASC_BREAKER:
|
||||||
|
#endif
|
||||||
|
case CR_ACIDDEMONSTRATION:
|
||||||
case KO_HAPPOKUNAI:
|
case KO_HAPPOKUNAI:
|
||||||
break;
|
break;
|
||||||
default:
|
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);
|
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);
|
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_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);
|
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
|
switch (skill_id) { // These skills will do a GVG fix later
|
||||||
case CR_ACIDDEMONSTRATION:
|
#ifdef RENEWAL
|
||||||
case NJ_ISSEN:
|
case NJ_ISSEN:
|
||||||
case ASC_BREAKER:
|
case ASC_BREAKER:
|
||||||
|
#endif
|
||||||
|
case CR_ACIDDEMONSTRATION:
|
||||||
case KO_HAPPOKUNAI:
|
case KO_HAPPOKUNAI:
|
||||||
return wd;
|
return wd;
|
||||||
default:
|
default:
|
||||||
wd = battle_calc_attack_gvg_bg(wd, src, target, skill_id, skill_lv);
|
wd = battle_calc_attack_gvg_bg(wd, src, target, skill_id, skill_lv);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skill damage adjustment */
|
/* Skill damage adjustment */
|
||||||
@ -4596,6 +4565,48 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl
|
|||||||
ATK_ADDRATE(wd.damage, wd.damage2, skill_damage);
|
ATK_ADDRATE(wd.damage, wd.damage2, skill_damage);
|
||||||
#endif
|
#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;
|
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;
|
ad.damage = ad.damage>0?1:-1;
|
||||||
|
|
||||||
switch(skill_id) { // These skills will do a GVG fix later
|
switch(skill_id) { // These skills will do a GVG fix later
|
||||||
case CR_ACIDDEMONSTRATION:
|
#ifdef RENEWAL
|
||||||
case ASC_BREAKER:
|
case ASC_BREAKER:
|
||||||
|
#endif
|
||||||
|
case CR_ACIDDEMONSTRATION:
|
||||||
return ad;
|
return ad;
|
||||||
default:
|
default:
|
||||||
ad.damage=battle_calc_damage(src,target,&ad,ad.damage,skill_id,skill_lv);
|
ad.damage=battle_calc_damage(src,target,&ad,ad.damage,skill_id,skill_lv);
|
||||||
|
@ -452,6 +452,7 @@ static short skill_isCopyable (struct map_session_data *sd, uint16 skill_id, str
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Added so plagarize can't copy agi/bless if you're undead since it damages you
|
// 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)
|
if (skill_get_inf3(skill_id)&INF3_DIS_PLAGIA)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user