Grand Cross Damage and Trigger Rework (#8283)
- Grand Cross on target is now considered a full magic attack and no longer triggers drain and similar effects that only work with physical attacks * This problem as was introduced in d8a02e9 to fix Coma not working on Grand Cross, but the reason that Coma works on Grand Cross is because it can also trigger on Magic skills (this is already working) - Grand Cross damage on self is still considered as "physical damage received" for reactive cards (e.g. Alarm Card), but no longer as "magical damage received" (e.g. Platinum Shield does not trigger) - Grand Cross no longer channels through the whole "weapon attack" code and just calls the necessary parts directly (it only considers ATK, DEF/VIT_DEF and refine) - Damage parts of Grand Cross can now go below 1 and reduce the other part (e.g. -5 physical damage and 15 magical damage now results in 10 damage instead of 16) - Implemented the official renewal damage formula for Grand Cross: [((ATK+MATK)/2)*RATIO - DEF - VIT_DEF - MDEF - MDEF2] - Fixed the order of damage processing for Grand Cross for fully accurate damage (there were a lot of rounding issues before) - The attribute table is no longer applied twice on self damage (still applied twice on target) - Cards that increase magic damage now work with Grand Cross (e.g. Skeggiold Card) - Changed Grand Cross range to 9 as that's the official range (you never know when it matters) - Fixes #1140
This commit is contained in:
parent
2963e52fc6
commit
0e434aa73b
@ -6887,12 +6887,9 @@ Body:
|
||||
MaxLevel: 10
|
||||
Type: Magic
|
||||
TargetType: Self
|
||||
DamageFlags:
|
||||
IgnoreAtkCard: true
|
||||
IgnoreFlee: true
|
||||
Flags:
|
||||
TargetSelf: true
|
||||
Range: 5
|
||||
Range: 9
|
||||
Hit: Single
|
||||
HitCount: 1
|
||||
Element: Holy
|
||||
|
@ -7234,9 +7234,8 @@ Body:
|
||||
Type: Magic
|
||||
TargetType: Self
|
||||
DamageFlags:
|
||||
IgnoreAtkCard: true
|
||||
IgnoreFlee: true
|
||||
Range: 5
|
||||
IgnoreDefense: true
|
||||
Range: 9
|
||||
Hit: Single
|
||||
HitCount: 1
|
||||
Element: Holy
|
||||
|
@ -3378,12 +3378,6 @@ static bool battle_skill_stacks_masteries_vvs(uint16 skill_id, e_bonus_chk_flag
|
||||
case LG_EARTHDRIVE:
|
||||
case NPC_DRAGONBREATH:
|
||||
return false;
|
||||
case CR_GRANDCROSS:
|
||||
case NPC_GRANDDARKNESS:
|
||||
// Grand Cross is influenced by refine bonus but not by atkpercent / masteries / Star Crumbs / Spirit Spheres
|
||||
if (chk_flag != BCHK_REFINE)
|
||||
return false;
|
||||
break;
|
||||
case LK_SPIRALPIERCE:
|
||||
// Spiral Pierce is influenced only by refine bonus and Star Crumbs for players
|
||||
if (chk_flag != BCHK_REFINE && chk_flag != BCHK_STAR)
|
||||
@ -6627,7 +6621,9 @@ static void battle_calc_defense_reduction(struct Damage* wd, struct block_list *
|
||||
return;
|
||||
if (is_attack_piercing(wd, src, target, skill_id, skill_lv, EQI_HAND_R) || is_attack_piercing(wd, src, target, skill_id, skill_lv, EQI_HAND_L))
|
||||
return;
|
||||
|
||||
[[fallthrough]];
|
||||
case CR_GRANDCROSS: // Grand Cross is marked as "IgnoreDefense" in renewal as it's applied at the end after already combining ATK and MATK
|
||||
case NPC_GRANDDARKNESS:
|
||||
// Defense reduction by flat value.
|
||||
// This completely bypasses the normal RE DEF Reduction formula.
|
||||
wd->damage -= (def1 + vit_def);
|
||||
@ -7537,9 +7533,6 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl
|
||||
|
||||
battle_calc_element_damage(&wd, src, target, skill_id, skill_lv);
|
||||
|
||||
if(skill_id == CR_GRANDCROSS || skill_id == NPC_GRANDDARKNESS)
|
||||
return wd; //Enough, rest is not needed.
|
||||
|
||||
#ifdef RENEWAL
|
||||
if (is_attack_critical(&wd, src, target, skill_id, skill_lv, false)) {
|
||||
if (sd) { //Check for player so we don't crash out, monsters don't have bonus crit rates [helvetica]
|
||||
@ -8812,6 +8805,46 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
|
||||
ad.damage = ad.damage * (100-mdef)/100 - mdef2;
|
||||
#endif
|
||||
}
|
||||
|
||||
//Apply the physical part of the skill's damage. [Skotlex]
|
||||
switch (skill_id) {
|
||||
case CR_GRANDCROSS:
|
||||
case NPC_GRANDDARKNESS: {
|
||||
// Pre-re ATK = Take atk, apply def reduction and add refine bonus
|
||||
// Final Damage = (ATK+MATK)*RATIO
|
||||
// Renewal ATK = Take total atk
|
||||
// Final Damage = ((ATK+MATK)/2)*RATIO - (tDEF + tMDEF)
|
||||
// No need to go through the whole physical damage code
|
||||
struct Damage wd = initialize_weapon_data(src, target, skill_id, skill_lv, mflag);
|
||||
battle_calc_skill_base_damage(&wd, src, target, skill_id, skill_lv);
|
||||
// Calculate ATK
|
||||
#ifdef RENEWAL
|
||||
if (sd)
|
||||
wd.damage = wd.statusAtk + wd.weaponAtk + wd.equipAtk + wd.percentAtk;
|
||||
#else
|
||||
battle_calc_defense_reduction(&wd, src, target, skill_id, skill_lv);
|
||||
if (sd) {
|
||||
wd.damage += sstatus->rhw.atk2;
|
||||
}
|
||||
#endif
|
||||
// Combine ATK and MATK
|
||||
#ifdef RENEWAL
|
||||
ad.damage = (wd.damage + ad.damage) / 2;
|
||||
#else
|
||||
ad.damage = std::max((int64)1, wd.damage + ad.damage);
|
||||
#endif
|
||||
// Ratio
|
||||
skillratio += 40 * skill_lv;
|
||||
MATK_RATE(skillratio);
|
||||
#ifdef RENEWAL
|
||||
// Total defense reduction (renewal only)
|
||||
battle_calc_defense_reduction(&ad, src, target, skill_id, skill_lv);
|
||||
ad.damage -= (tstatus->mdef + tstatus->mdef2);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(ad.damage<1)
|
||||
ad.damage=1;
|
||||
else if(sc) { //only applies when hit
|
||||
@ -8842,26 +8875,26 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
|
||||
if (!nk[NK_IGNOREELEMENT])
|
||||
ad.damage = battle_attr_fix(src, target, ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
|
||||
|
||||
//Apply the physical part of the skill's damage. [Skotlex]
|
||||
switch(skill_id) {
|
||||
case CR_GRANDCROSS:
|
||||
case NPC_GRANDDARKNESS: {
|
||||
struct Damage wd = battle_calc_weapon_attack(src,target,skill_id,skill_lv,mflag);
|
||||
|
||||
ad.damage = battle_attr_fix(src, target, wd.damage + ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv) * (100 + 40 * skill_lv) / 100;
|
||||
if(src == target) {
|
||||
if(src->type == BL_PC)
|
||||
ad.damage = ad.damage / 2;
|
||||
else
|
||||
ad.damage = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef RENEWAL
|
||||
ad.damage += battle_calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, ad.damage, 0, ad.flag);
|
||||
#endif
|
||||
|
||||
switch (skill_id) {
|
||||
case CR_GRANDCROSS:
|
||||
case NPC_GRANDDARKNESS:
|
||||
if (src == target) {
|
||||
// Grand Cross on self first applies attr_fix, then cardfix and finally halves the damage
|
||||
if (src->type == BL_PC)
|
||||
ad.damage = ad.damage / 2;
|
||||
else
|
||||
ad.damage = 0;
|
||||
}
|
||||
else
|
||||
// Grand Cross on target applies attr_fix, then cardfix and then attr_fix a second time
|
||||
ad.damage = battle_attr_fix(src, target, ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
|
||||
break;
|
||||
}
|
||||
|
||||
} //Hint: Against plants damage will still be 1 at this point
|
||||
|
||||
//Apply DAMAGE_DIV_FIX and check for min damage
|
||||
|
@ -1540,14 +1540,12 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl, uint
|
||||
|
||||
case NPC_GRANDDARKNESS:
|
||||
sc_start(src, bl, SC_BLIND, 100, skill_lv, skill_get_time2(skill_id, skill_lv));
|
||||
attack_type |= BF_WEAPON;
|
||||
break;
|
||||
|
||||
case CR_GRANDCROSS:
|
||||
//Chance to cause blind status vs demon and undead element, but not against players
|
||||
if(!dstsd && (battle_check_undead(tstatus->race,tstatus->def_ele) || tstatus->race == RC_DEMON))
|
||||
sc_start(src,bl,SC_BLIND,100,skill_lv,skill_get_time2(skill_id,skill_lv));
|
||||
attack_type |= BF_WEAPON;
|
||||
break;
|
||||
|
||||
case AM_ACIDTERROR:
|
||||
@ -2626,8 +2624,11 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list *
|
||||
}
|
||||
break;
|
||||
case CR_GRANDCROSS:
|
||||
case NPC_GRANDDARKNESS:
|
||||
attack_type |= BF_WEAPON;
|
||||
if (src == bl) {
|
||||
// Grand Cross on self specifically only triggers "When hit by physical attack" autospells and ignores everything else
|
||||
attack_type |= BF_WEAPON;
|
||||
attack_type &= ~BF_MAGIC;
|
||||
}
|
||||
break;
|
||||
case LG_HESPERUSLIT:
|
||||
{
|
||||
@ -4111,9 +4112,6 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
|
||||
}
|
||||
}
|
||||
|
||||
if(skill_id == CR_GRANDCROSS || skill_id == NPC_GRANDDARKNESS)
|
||||
dmg.flag |= BF_WEAPON;
|
||||
|
||||
if( sd && src != bl && damage > 0 && ( dmg.flag&BF_WEAPON ||
|
||||
(dmg.flag&BF_MISC && (skill_id == RA_CLUSTERBOMB || skill_id == RA_FIRINGTRAP || skill_id == RA_ICEBOUNDTRAP)) ) )
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user