diff --git a/src/map/battle.cpp b/src/map/battle.cpp index 2243c31e4d6..4b83c3e65da 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -45,9 +45,9 @@ static struct eri *delay_damage_ers; //For battle delay damage structures. #endif // Early declaration -int32 battle_get_weapon_element( const Damage *wd, const block_list* src, const block_list* target, uint16 skill_id, uint16 skill_lv, int16 weapon_position, bool calc_for_damage_only ); -int32 battle_get_magic_element( const block_list* src, const block_list* target, uint16 skill_id, uint16 skill_lv, int32 mflag ); -int32 battle_get_misc_element( const block_list* src, const block_list* target, uint16 skill_id, uint16 skill_lv, int32 mflag ); +int32 battle_get_weapon_element(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_id, uint16 skill_lv, equip_index weapon_position, bool calc_for_damage_only); +int32 battle_get_magic_element(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_id, uint16 skill_lv); +int32 battle_get_misc_element(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_id, uint16 skill_lv); static void battle_calc_defense_reduction( Damage* wd, block_list* src, block_list* target, uint16 skill_id, uint16 skill_lv ); /** @@ -1306,13 +1306,13 @@ bool battle_status_block_damage(block_list *src, block_list *target, status_chan if (flag & BF_WEAPON) { status_data* sstatus = status_get_status_data(*src); if(sstatus->rhw.ele == ELE_NEUTRAL && sstatus->lhw.ele > sstatus->rhw.ele) - element = battle_get_weapon_element(d, src, target, skill_id, skill_lv, EQI_HAND_L, false); + element = battle_get_weapon_element(*d, *src, *target, skill_id, skill_lv, EQI_HAND_L, false); else - element = battle_get_weapon_element(d, src, target, skill_id, skill_lv, EQI_HAND_R, false); + element = battle_get_weapon_element(*d, *src, *target, skill_id, skill_lv, EQI_HAND_R, false); } else if(flag & BF_MAGIC) - element = battle_get_magic_element(src, target, skill_id, skill_lv, d->miscflag); + element = battle_get_magic_element(*d, *src, *target, skill_id, skill_lv); else - element = battle_get_misc_element(src, target, skill_id, skill_lv, d->miscflag); + element = battle_get_misc_element(*d, *src, *target, skill_id, skill_lv); switch( element ){ case ELE_NEUTRAL: @@ -2031,7 +2031,7 @@ int64 battle_calc_damage(block_list *src,block_list *bl,struct Damage *d,int64 d } if (sd && pc_ismadogear(sd)) { - pc_overheat(*sd, (battle_get_weapon_element(d, src, bl, skill_id, skill_lv, EQI_HAND_R, false) == ELE_FIRE ? 3 : 1)); + pc_overheat(*sd, (battle_get_weapon_element(*d, *src, *bl, skill_id, skill_lv, EQI_HAND_R, false) == ELE_FIRE ? 3 : 1)); } // Target status (again), required for RELIEVE @@ -3453,221 +3453,92 @@ static int32 battle_calc_equip_attack(block_list *src, int32 skill_id) * Initial refactoring by Baalberith * Refined and optimized by helvetica */ -int32 battle_get_weapon_element( const Damage* wd, const block_list* src, const block_list* target, uint16 skill_id, uint16 skill_lv, int16 weapon_position, bool calc_for_damage_only ){ - const map_session_data* sd = BL_CAST(BL_PC,src); - const status_change* sc = status_get_sc(src); - const status_data* sstatus = status_get_status_data(*src); +int32 battle_get_weapon_element(const Damage& wd, const block_list& src, const block_list& target, uint16 skill_id, uint16 skill_lv, equip_index weapon_position, bool calc_for_damage_only) { int32 element = skill_get_ele(skill_id, skill_lv); + const map_session_data* sd = BL_CAST(BL_PC, &src); + const status_change* sc = status_get_sc(&src); + const status_data* sstatus = status_get_status_data(src); + //Take weapon's element if( !skill_id || element == ELE_WEAPON ) { - if (weapon_position == EQI_HAND_R) - element = sstatus->rhw.ele; - else - element = sstatus->lhw.ele; - if(is_skill_using_arrow(src, skill_id) && sd && sd->bonus.arrow_ele && weapon_position == EQI_HAND_R) + if (sstatus != nullptr) { + if (weapon_position == EQI_HAND_R) + element = sstatus->rhw.ele; + else + element = sstatus->lhw.ele; + } + + if(is_skill_using_arrow(&src, skill_id) && sd && sd->bonus.arrow_ele && weapon_position == EQI_HAND_R) element = sd->bonus.arrow_ele; if(sd && sd->spiritcharm_type != CHARM_TYPE_NONE && sd->spiritcharm >= MAX_SPIRITCHARM) element = sd->spiritcharm_type; // Summoning 10 spiritcharm will endow your weapon - // on official endows override all other elements [helvetica] - if(sc && sc->getSCE(SC_ENCHANTARMS)) // Check for endows - element = sc->getSCE(SC_ENCHANTARMS)->val1; + + if (sc != nullptr) { + // on official endows override all other elements [helvetica] + if (sc->hasSCE(SC_ENCHANTARMS)) // Check for endows + element = sc->getSCE(SC_ENCHANTARMS)->val1; + + if (skill_id == 0 && sc->hasSCE(SC_GOLDENE_FERSE) && (rnd() % 100 < sc->getSCE(SC_GOLDENE_FERSE)->val4)) + element = ELE_HOLY; + } } else if( element == ELE_ENDOWED ) //Use enchantment's element - element = status_get_attack_sc_element(src,sc); + element = status_get_attack_sc_element(&src, sc); else if( element == ELE_RANDOM ) //Use random element element = rnd()%ELE_ALL; - switch( skill_id ) { - case GS_GROUNDDRIFT: - element = wd->miscflag; //element comes in flag. - break; - case LK_SPIRALPIERCE: - if (!sd) - element = ELE_NEUTRAL; //forced neutral for monsters - break; - case RK_DRAGONBREATH: - if (sc) { - if (sc->getSCE(SC_LUXANIMA)) // Lux Anima has priority over Giant Growth - element = ELE_DARK; - else if (sc->getSCE(SC_GIANTGROWTH)) - element = ELE_HOLY; - } - break; - case RK_DRAGONBREATH_WATER: - if (sc) { - if (sc->getSCE(SC_LUXANIMA)) // Lux Anima has priority over Fighting Spirit - element = ELE_NEUTRAL; - else if (sc->getSCE(SC_FIGHTINGSPIRIT)) - element = ELE_GHOST; - } - break; - case LG_HESPERUSLIT: - if (sc && sc->getSCE(SC_BANDING) && sc->getSCE(SC_BANDING)->val2 > 4) - element = ELE_HOLY; - break; - case GN_CARTCANNON: - case NC_ARMSCANNON: - if (sd && sd->state.arrow_atk > 0) - element = sd->bonus.arrow_ele; - break; - case SJ_PROMINENCEKICK: - element = ELE_FIRE; - break; - case RL_H_MINE: - if (sd && sd->flicker) //Force RL_H_MINE deals fire damage if activated by RL_FLICKER - element = ELE_FIRE; - break; - case NW_BASIC_GRENADE: - case NW_HASTY_FIRE_IN_THE_HOLE: - case NW_GRENADES_DROPPING: - case NW_MISSION_BOMBARD: - // Night Watch Grenade Fragment elementals affecting those skills. - if( sc != nullptr ){ - if( sc->getSCE( SC_GRENADE_FRAGMENT_1 ) != nullptr ){ - element = ELE_WATER; - }else if( sc->getSCE( SC_GRENADE_FRAGMENT_2 ) != nullptr ){ - element = ELE_WIND; - }else if( sc->getSCE( SC_GRENADE_FRAGMENT_3 ) != nullptr ){ - element = ELE_EARTH; - }else if( sc->getSCE( SC_GRENADE_FRAGMENT_4 ) != nullptr ){ - element = ELE_FIRE; - }else if( sc->getSCE( SC_GRENADE_FRAGMENT_5 ) != nullptr ){ - element = ELE_DARK; - }else if( sc->getSCE( SC_GRENADE_FRAGMENT_6 ) != nullptr ){ - element = ELE_HOLY; - } - } - break; - case SS_FUUMASHOUAKU: - case SS_FUUMAKOUCHIKU: - if( sd != nullptr ){ - element = sd->bonus.arrow_ele; - } - break; + // Modify the element type of skill attack + if (std::shared_ptr skill = skill_db.find(skill_id); skill != nullptr && skill->impl != nullptr) { + skill->impl->modifyElement(wd, src, target, skill_lv, element, calc_for_damage_only); } - if (sc && sc->getSCE(SC_GOLDENE_FERSE) && ((!skill_id && (rnd() % 100 < sc->getSCE(SC_GOLDENE_FERSE)->val4)) || skill_id == MH_STAHL_HORN)) - element = ELE_HOLY; - -// calc_flag means the element should be calculated for damage only - if (calc_for_damage_only) - return element; - -#ifdef RENEWAL - if (skill_id == CR_SHIELDBOOMERANG) - element = ELE_NEUTRAL; -#endif - return element; } -int32 battle_get_magic_element(const block_list* src, const block_list* target, uint16 skill_id, uint16 skill_lv, int32 mflag) { +int32 battle_get_magic_element(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_id, uint16 skill_lv) { int32 element = skill_get_ele(skill_id, skill_lv); - const map_session_data* sd = BL_CAST(BL_PC,src); - const status_change *sc = status_get_sc(src); - const status_data* sstatus = status_get_status_data(*src); - - if (element == ELE_WEAPON) { // pl=-1 : the skill takes the weapon's element - element = sstatus->rhw.ele; - if(sd && sd->spiritcharm_type != CHARM_TYPE_NONE && sd->spiritcharm >= MAX_SPIRITCHARM) - element = sd->spiritcharm_type; // Summoning 10 spiritcharm will endow your weapon - } else if (element == ELE_ENDOWED) //Use status element - element = status_get_attack_sc_element(src,status_get_sc(src)); - else if (element == ELE_RANDOM) //Use random element - element = rnd()%ELE_ALL; - switch(skill_id) { - case NPC_EARTHQUAKE: - element = ELE_NEUTRAL; - break; - case WL_HELLINFERNO: - if (mflag & 2) { // ELE_DARK - element = ELE_DARK; - } - break; - case NPC_PSYCHIC_WAVE: - case SO_PSYCHIC_WAVE: - if( sc != nullptr && !sc->empty() ) { - static const std::vector types = { - SC_HEATER_OPTION, - SC_COOLER_OPTION, - SC_BLAST_OPTION, - SC_CURSED_SOIL_OPTION, - SC_FLAMETECHNIC_OPTION, - SC_COLD_FORCE_OPTION, - SC_GRACE_BREEZE_OPTION, - SC_EARTH_CARE_OPTION, - SC_DEEP_POISONING_OPTION - }; - for( sc_type type : types ){ - if( sc->getSCE( type ) ){ - element = sc->getSCE( type )->val3; - break; - } - } - } - break; - case KO_KAIHOU: - if(sd && sd->spiritcharm_type != CHARM_TYPE_NONE && sd->spiritcharm > 0) - element = sd->spiritcharm_type; - break; - case CD_DIVINUS_FLOS: - case AB_ADORAMUS: - if (sc != nullptr && sc->hasSCE(SC_ANCILLA)) - element = ELE_NEUTRAL; - break; - case LG_RAYOFGENESIS: - if (sc && sc->getSCE(SC_INSPIRATION)) - element = ELE_NEUTRAL; - break; - case IG_IMPERIAL_PRESSURE: - if (sc != nullptr && sc->hasSCE(SC_GUARD_STANCE)) - element = ELE_HOLY; - break; - case WM_REVERBERATION: - case TR_METALIC_FURY: - case TR_SOUNDBLEND: - case TR_RHYTHMICAL_WAVE: - if (sd) - element = sd->bonus.arrow_ele; + switch (element) { + case ELE_WEAPON: // pl = -1 : the skill takes the weapon's element + if (const status_data* sstatus = status_get_status_data(src); sstatus != nullptr) + element = sstatus->rhw.ele; + + if (const map_session_data* sd = BL_CAST(BL_PC, &src); sd != nullptr && sd->spiritcharm_type != CHARM_TYPE_NONE && sd->spiritcharm >= MAX_SPIRITCHARM) + element = sd->spiritcharm_type; // Summoning 10 spiritcharm will endow your weapon break; - case SU_CN_METEOR: - case SU_CN_METEOR2: - case SH_HYUN_ROKS_BREEZE: - case SH_HYUN_ROK_CANNON: - case SH_HYUN_ROK_SPIRIT_POWER: - if( sc != nullptr && !sc->empty() ){ - if( sc->getSCE( SC_COLORS_OF_HYUN_ROK_1 ) != nullptr ){ - element = ELE_WATER; - }else if( sc->getSCE( SC_COLORS_OF_HYUN_ROK_2 ) != nullptr ){ - element = ELE_WIND; - }else if( sc->getSCE( SC_COLORS_OF_HYUN_ROK_3 ) != nullptr ){ - element = ELE_EARTH; - }else if( sc->getSCE( SC_COLORS_OF_HYUN_ROK_4 ) != nullptr ){ - element = ELE_FIRE; - }else if( sc->getSCE( SC_COLORS_OF_HYUN_ROK_5 ) != nullptr ){ - element = ELE_DARK; - }else if( sc->getSCE( SC_COLORS_OF_HYUN_ROK_6 ) != nullptr ){ - element = ELE_HOLY; - } - } + case ELE_ENDOWED: // Use status element + element = status_get_attack_sc_element(&src, status_get_sc(&src)); break; - case SS_ANKOKURYUUAKUMU: - if (mflag & SKILL_ALTDMG_FLAG) - element = ELE_FIRE; + case ELE_RANDOM: // Use random element + element = rnd() % ELE_ALL; break; } + // Modify the element type of skill attack + if (std::shared_ptr skill = skill_db.find(skill_id); skill != nullptr && skill->impl != nullptr) { + skill->impl->modifyElement(dmg, src, target, skill_lv, element, 0); + } + return element; } -int32 battle_get_misc_element( const block_list* src, const block_list* target, uint16 skill_id, uint16 skill_lv, int32 mflag ) { +int32 battle_get_misc_element(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_id, uint16 skill_lv) { int32 element = skill_get_ele(skill_id, skill_lv); - - if (element == ELE_WEAPON || element == ELE_ENDOWED) //Attack that takes weapon's element for misc attacks? Make it neutral [Skotlex] - element = ELE_NEUTRAL; - else if (element == ELE_RANDOM) //Use random element - element = rnd()%ELE_ALL; + + switch (element) { + case ELE_WEAPON: + case ELE_ENDOWED: // Attack that takes weapon's element for misc attacks? Make it neutral [Skotlex] + element = ELE_NEUTRAL; + break; + case ELE_RANDOM: // Use random element + element = rnd() % ELE_ALL; + break; + } + + // Modify the element type of skill attack + if (std::shared_ptr skill = skill_db.find(skill_id); skill != nullptr && skill->impl != nullptr) { + skill->impl->modifyElement(dmg, src, target, skill_lv, element, 0); + } return element; } @@ -3774,11 +3645,11 @@ static void battle_calc_element_damage(struct Damage* wd, block_list *src, block status_change* sc = status_get_sc(src); status_data* sstatus = status_get_status_data(*src); status_data* tstatus = status_get_status_data(*target); - int32 right_element = battle_get_weapon_element(wd, src, target, skill_id, skill_lv, EQI_HAND_R, true); + int32 right_element = battle_get_weapon_element(*wd, *src, *target, skill_id, skill_lv, EQI_HAND_R, true); // Elemental attribute fix if(!nk[NK_IGNOREELEMENT] && (wd->damage > 0 || wd->damage2 > 0)) { - int32 left_element = battle_get_weapon_element(wd, src, target, skill_id, skill_lv, EQI_HAND_L, true); + int32 left_element = battle_get_weapon_element(*wd, *src, *target, skill_id, skill_lv, EQI_HAND_L, true); switch (skill_id) { case PA_SACRIFICE: @@ -4018,8 +3889,8 @@ static void battle_calc_damage_parts(struct Damage* wd, block_list *src,block_li map_session_data *sd = BL_CAST(BL_PC, src); bool critical = false; - int32 right_element = battle_get_weapon_element(wd, src, target, skill_id, skill_lv, EQI_HAND_R, false); - int32 left_element = battle_get_weapon_element(wd, src, target, skill_id, skill_lv, EQI_HAND_L, false); + int32 right_element = battle_get_weapon_element(*wd, *src, *target, skill_id, skill_lv, EQI_HAND_R, false); + int32 left_element = battle_get_weapon_element(*wd, *src, *target, skill_id, skill_lv, EQI_HAND_L, false); wd->statusAtk += sstatus->batk; wd->statusAtk2 += sstatus->batk; @@ -5109,8 +4980,8 @@ static void battle_calc_attack_plant(struct Damage* wd, block_list *src,block_li return; } - const int32 right_element = battle_get_weapon_element(wd, src, target, skill_id, skill_lv, EQI_HAND_R, false); - const int32 left_element = battle_get_weapon_element(wd, src, target, skill_id, skill_lv, EQI_HAND_L, false); + const int32 right_element = battle_get_weapon_element(*wd, *src, *target, skill_id, skill_lv, EQI_HAND_R, false); + const int32 left_element = battle_get_weapon_element(*wd, *src, *target, skill_id, skill_lv, EQI_HAND_L, false); if (wd->damage > 0) { wd->damage = battle_attr_fix(src, target, wd->damage, right_element, tstatus->def_ele, tstatus->ele_lv); @@ -5534,8 +5405,8 @@ static struct Damage battle_calc_weapon_attack(block_list *src, block_list *targ skill->impl->modifyDamageData(wd, *src, *target, skill_lv); } - right_element = battle_get_weapon_element(&wd, src, target, skill_id, skill_lv, EQI_HAND_R, false); - left_element = battle_get_weapon_element(&wd, src, target, skill_id, skill_lv, EQI_HAND_L, false); + right_element = battle_get_weapon_element(wd, *src, *target, skill_id, skill_lv, EQI_HAND_R, false); + left_element = battle_get_weapon_element(wd, *src, *target, skill_id, skill_lv, EQI_HAND_L, false); if (sc != nullptr && sc->empty()) sc = nullptr; //Skip checking as there are no status changes active. @@ -5974,7 +5845,7 @@ struct Damage battle_calc_magic_attack(block_list *src,block_list *target,uint16 tsc = status_get_sc(target); //Initialize variables that will be used afterwards - s_ele = battle_get_magic_element(src, target, skill_id, skill_lv, mflag); + s_ele = battle_get_magic_element(ad, *src, *target, skill_id, skill_lv); //Set miscellaneous data that needs be filled if(sd) { @@ -6454,7 +6325,7 @@ struct Damage battle_calc_misc_attack(block_list *src,block_list *target,uint16 md.blewcount += battle_blewcount_bonus(sd, skill_id); } - s_ele = battle_get_misc_element(src, target, skill_id, skill_lv, mflag); + s_ele = battle_get_misc_element(md, *src, *target, skill_id, skill_lv); //Skill Range Criteria md.flag |= battle_range_type(src, target, skill_id, skill_lv); diff --git a/src/map/skills/acolyte/adoramus.cpp b/src/map/skills/acolyte/adoramus.cpp index 6a7206394a0..a031bc76c10 100644 --- a/src/map/skills/acolyte/adoramus.cpp +++ b/src/map/skills/acolyte/adoramus.cpp @@ -29,3 +29,10 @@ int64 SkillAdoramus::splashDamage(block_list* src, block_list* target, uint16 sk return SkillImplRecursiveDamageSplash::splashDamage(src, target, skill_lv, tick, flag); } + +void SkillAdoramus::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const status_change* sc = status_get_sc(&src); + + if (sc != nullptr && sc->hasSCE(SC_ANCILLA)) + element = ELE_NEUTRAL; +} diff --git a/src/map/skills/acolyte/adoramus.hpp b/src/map/skills/acolyte/adoramus.hpp index c9c4f04d3b9..99e20029af0 100644 --- a/src/map/skills/acolyte/adoramus.hpp +++ b/src/map/skills/acolyte/adoramus.hpp @@ -12,4 +12,5 @@ class SkillAdoramus : public SkillImplRecursiveDamageSplash { void applyAdditionalEffects(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32 attack_type, enum damage_lv dmg_lv) const override; void calculateSkillRatio(const Damage *wd, const block_list *src, const block_list *target, uint16 skill_lv, int32 &skillratio, int32 mflag) const override; int64 splashDamage(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32 flag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/acolyte/divinusflos.cpp b/src/map/skills/acolyte/divinusflos.cpp index 80833f52d6c..480a58b7e02 100644 --- a/src/map/skills/acolyte/divinusflos.cpp +++ b/src/map/skills/acolyte/divinusflos.cpp @@ -27,3 +27,10 @@ void SkillDivinusFlos::splashSearch(block_list* src, block_list* target, uint16 SkillImplRecursiveDamageSplash::splashSearch(src, target, skill_lv, tick, flag); } + +void SkillDivinusFlos::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const status_change* sc = status_get_sc(&src); + + if (sc != nullptr && sc->hasSCE(SC_ANCILLA)) + element = ELE_NEUTRAL; +} diff --git a/src/map/skills/acolyte/divinusflos.hpp b/src/map/skills/acolyte/divinusflos.hpp index 0c3404ad32c..a15512918f2 100644 --- a/src/map/skills/acolyte/divinusflos.hpp +++ b/src/map/skills/acolyte/divinusflos.hpp @@ -11,4 +11,5 @@ class SkillDivinusFlos : public SkillImplRecursiveDamageSplash { void calculateSkillRatio(const Damage* wd, const block_list* src, const block_list* target, uint16 skill_lv, int32& base_skillratio, int32 mflag) const override; void splashSearch(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32 flag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/archer/metallicfury.cpp b/src/map/skills/archer/metallicfury.cpp index e498c561b6c..915844aa8ef 100644 --- a/src/map/skills/archer/metallicfury.cpp +++ b/src/map/skills/archer/metallicfury.cpp @@ -24,3 +24,10 @@ void SkillMetallicFury::calculateSkillRatio(const Damage* wd, const block_list* } RE_LVL_DMOD(100); } + +void SkillMetallicFury::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const map_session_data* sd = BL_CAST(BL_PC, &src); + + if (sd != nullptr) + element = sd->bonus.arrow_ele; +} diff --git a/src/map/skills/archer/metallicfury.hpp b/src/map/skills/archer/metallicfury.hpp index 8f5365cd9f7..40cb2f5d431 100644 --- a/src/map/skills/archer/metallicfury.hpp +++ b/src/map/skills/archer/metallicfury.hpp @@ -10,4 +10,5 @@ class SkillMetallicFury : public SkillImplRecursiveDamageSplash { SkillMetallicFury(); void calculateSkillRatio(const Damage* wd, const block_list* src, const block_list* target, uint16 skill_lv, int32& base_skillratio, int32 mflag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/archer/reverberation.cpp b/src/map/skills/archer/reverberation.cpp index 8579d2635ab..cbb177938a4 100644 --- a/src/map/skills/archer/reverberation.cpp +++ b/src/map/skills/archer/reverberation.cpp @@ -39,3 +39,10 @@ void SkillReverberation::castendDamageId(block_list *src, block_list *target, ui battle_consume_ammo(sd, getSkillId(), skill_lv); // Consume here since Magic/Misc attacks reset arrow_atk } } + +void SkillReverberation::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const map_session_data* sd = BL_CAST(BL_PC, &src); + + if (sd != nullptr) + element = sd->bonus.arrow_ele; +} diff --git a/src/map/skills/archer/reverberation.hpp b/src/map/skills/archer/reverberation.hpp index 241d2f7a4fc..21632ce8117 100644 --- a/src/map/skills/archer/reverberation.hpp +++ b/src/map/skills/archer/reverberation.hpp @@ -12,4 +12,5 @@ class SkillReverberation : public SkillImpl { void applyAdditionalEffects(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32 attack_type, enum damage_lv dmg_lv) const override; void calculateSkillRatio(const Damage *wd, const block_list *src, const block_list *target, uint16 skill_lv, int32 &skillratio, int32 mflag) const override; void castendDamageId(block_list *src, block_list *target, uint16 skill_lv, t_tick tick, int32& flag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/archer/rhythmicalwave.cpp b/src/map/skills/archer/rhythmicalwave.cpp index d973eccd79d..879d19fa624 100644 --- a/src/map/skills/archer/rhythmicalwave.cpp +++ b/src/map/skills/archer/rhythmicalwave.cpp @@ -40,3 +40,10 @@ void SkillRhythmicalWave::calculateSkillRatio(const Damage* wd, const block_list RE_LVL_DMOD(100); } + +void SkillRhythmicalWave::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const map_session_data* sd = BL_CAST(BL_PC, &src); + + if (sd != nullptr) + element = sd->bonus.arrow_ele; +} diff --git a/src/map/skills/archer/rhythmicalwave.hpp b/src/map/skills/archer/rhythmicalwave.hpp index 61371e456ad..32b40bf01f9 100644 --- a/src/map/skills/archer/rhythmicalwave.hpp +++ b/src/map/skills/archer/rhythmicalwave.hpp @@ -11,4 +11,5 @@ class SkillRhythmicalWave : public SkillImpl { void castendDamageId(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32& flag) const override; void calculateSkillRatio(const Damage* wd, const block_list* src, const block_list* target, uint16 skill_lv, int32& base_skillratio, int32 mflag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/archer/soundblend.cpp b/src/map/skills/archer/soundblend.cpp index ff23417a7ba..1022248526a 100644 --- a/src/map/skills/archer/soundblend.cpp +++ b/src/map/skills/archer/soundblend.cpp @@ -35,3 +35,10 @@ void SkillSoundBlend::calculateSkillRatio(const Damage* wd, const block_list* sr skillratio += skillratio * 50 / 100; } } + +void SkillSoundBlend::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const map_session_data* sd = BL_CAST(BL_PC, &src); + + if (sd != nullptr) + element = sd->bonus.arrow_ele; +} diff --git a/src/map/skills/archer/soundblend.hpp b/src/map/skills/archer/soundblend.hpp index a88b13e04b2..a043e2c723e 100644 --- a/src/map/skills/archer/soundblend.hpp +++ b/src/map/skills/archer/soundblend.hpp @@ -12,4 +12,5 @@ class SkillSoundBlend : public SkillImpl { void castendNoDamageId(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32& flag) const override; void castendDamageId(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32& flag) const override; void calculateSkillRatio(const Damage* wd, const block_list* src, const block_list* target, uint16 skill_lv, int32& base_skillratio, int32 mflag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/gunslinger/basicgrenade.cpp b/src/map/skills/gunslinger/basicgrenade.cpp index ddedf07f5c2..b4bf9184ffe 100644 --- a/src/map/skills/gunslinger/basicgrenade.cpp +++ b/src/map/skills/gunslinger/basicgrenade.cpp @@ -26,3 +26,24 @@ void SkillBasicGrenade::calculateSkillRatio(const Damage* wd, const block_list* skillratio += 5 * sstatus->con; RE_LVL_DMOD(100); } + +void SkillBasicGrenade::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const status_change* sc = status_get_sc(&src); + + // Night Watch Grenade Fragment elementals + if( sc != nullptr ){ + if( sc->hasSCE( SC_GRENADE_FRAGMENT_1 ) ){ + element = ELE_WATER; + }else if( sc->hasSCE( SC_GRENADE_FRAGMENT_2 ) ){ + element = ELE_WIND; + }else if( sc->hasSCE( SC_GRENADE_FRAGMENT_3 ) ){ + element = ELE_EARTH; + }else if( sc->hasSCE( SC_GRENADE_FRAGMENT_4 ) ){ + element = ELE_FIRE; + }else if( sc->hasSCE( SC_GRENADE_FRAGMENT_5 ) ){ + element = ELE_DARK; + }else if( sc->hasSCE( SC_GRENADE_FRAGMENT_6 ) ){ + element = ELE_HOLY; + } + } +} diff --git a/src/map/skills/gunslinger/basicgrenade.hpp b/src/map/skills/gunslinger/basicgrenade.hpp index 975ea044023..3c57298ccec 100644 --- a/src/map/skills/gunslinger/basicgrenade.hpp +++ b/src/map/skills/gunslinger/basicgrenade.hpp @@ -11,4 +11,5 @@ class SkillBasicGrenade : public WeaponSkillImpl { void castendPos2(block_list* src, int32 x, int32 y, uint16 skill_lv, t_tick tick, int32& flag) const override; void calculateSkillRatio(const Damage* wd, const block_list* src, const block_list* target, uint16 skill_lv, int32& base_skillratio, int32 mflag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/gunslinger/grenadesdropping.cpp b/src/map/skills/gunslinger/grenadesdropping.cpp index 98a94d8921d..77db3324444 100644 --- a/src/map/skills/gunslinger/grenadesdropping.cpp +++ b/src/map/skills/gunslinger/grenadesdropping.cpp @@ -30,3 +30,24 @@ void SkillGrenadesDropping::calculateSkillRatio(const Damage* wd, const block_li skillratio += 5 * sstatus->con; RE_LVL_DMOD(100); } + +void SkillGrenadesDropping::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const status_change* sc = status_get_sc(&src); + + // Night Watch Grenade Fragment elementals + if( sc != nullptr ){ + if( sc->hasSCE( SC_GRENADE_FRAGMENT_1 ) ){ + element = ELE_WATER; + }else if( sc->hasSCE( SC_GRENADE_FRAGMENT_2 ) ){ + element = ELE_WIND; + }else if( sc->hasSCE( SC_GRENADE_FRAGMENT_3 ) ){ + element = ELE_EARTH; + }else if( sc->hasSCE( SC_GRENADE_FRAGMENT_4 ) ){ + element = ELE_FIRE; + }else if( sc->hasSCE( SC_GRENADE_FRAGMENT_5 ) ){ + element = ELE_DARK; + }else if( sc->hasSCE( SC_GRENADE_FRAGMENT_6 ) ){ + element = ELE_HOLY; + } + } +} diff --git a/src/map/skills/gunslinger/grenadesdropping.hpp b/src/map/skills/gunslinger/grenadesdropping.hpp index b038e74d798..262b7f29c3d 100644 --- a/src/map/skills/gunslinger/grenadesdropping.hpp +++ b/src/map/skills/gunslinger/grenadesdropping.hpp @@ -11,4 +11,5 @@ class SkillGrenadesDropping : public SkillImpl { void castendPos2(block_list* src, int32 x, int32 y, uint16 skill_lv, t_tick tick, int32& flag) const override; void calculateSkillRatio(const Damage* wd, const block_list* src, const block_list* target, uint16 skill_lv, int32& base_skillratio, int32 mflag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/gunslinger/grounddrift.cpp b/src/map/skills/gunslinger/grounddrift.cpp index fd3ff95289c..c1986ddefe7 100644 --- a/src/map/skills/gunslinger/grounddrift.cpp +++ b/src/map/skills/gunslinger/grounddrift.cpp @@ -27,3 +27,7 @@ void SkillGroundDrift::castendPos2(block_list* src, int32 x, int32 y, uint16 ski // Ammo should be deleted right away. skill_unitsetting(src, getSkillId(), skill_lv, x, y, 0); } + +void SkillGroundDrift::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + element = dmg.miscflag; // element comes in flag. +} diff --git a/src/map/skills/gunslinger/grounddrift.hpp b/src/map/skills/gunslinger/grounddrift.hpp index f012f47ef0c..6cb6a0397b9 100644 --- a/src/map/skills/gunslinger/grounddrift.hpp +++ b/src/map/skills/gunslinger/grounddrift.hpp @@ -14,4 +14,5 @@ class SkillGroundDrift : public SkillImpl { void modifyDamageData(Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv) const override; void calculateSkillRatio(const Damage *wd, const block_list *src, const block_list *target, uint16 skill_lv, int32 &base_skillratio, int32 mflag) const override; void castendPos2(block_list* src, int32 x, int32 y, uint16 skill_lv, t_tick tick, int32& flag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/gunslinger/hastyfireinthehole.cpp b/src/map/skills/gunslinger/hastyfireinthehole.cpp index 89064bb6b4d..fc943fc906f 100644 --- a/src/map/skills/gunslinger/hastyfireinthehole.cpp +++ b/src/map/skills/gunslinger/hastyfireinthehole.cpp @@ -39,3 +39,24 @@ void SkillHastyFireInTheHole::calculateSkillRatio(const Damage* wd, const block_ skillratio += 5 * sstatus->con; RE_LVL_DMOD(100); } + +void SkillHastyFireInTheHole::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const status_change* sc = status_get_sc(&src); + + // Night Watch Grenade Fragment elementals + if( sc != nullptr ){ + if( sc->hasSCE( SC_GRENADE_FRAGMENT_1 ) ){ + element = ELE_WATER; + }else if( sc->hasSCE( SC_GRENADE_FRAGMENT_2 ) ){ + element = ELE_WIND; + }else if( sc->hasSCE( SC_GRENADE_FRAGMENT_3 ) ){ + element = ELE_EARTH; + }else if( sc->hasSCE( SC_GRENADE_FRAGMENT_4 ) ){ + element = ELE_FIRE; + }else if( sc->hasSCE( SC_GRENADE_FRAGMENT_5 ) ){ + element = ELE_DARK; + }else if( sc->hasSCE( SC_GRENADE_FRAGMENT_6 ) ){ + element = ELE_HOLY; + } + } +} diff --git a/src/map/skills/gunslinger/hastyfireinthehole.hpp b/src/map/skills/gunslinger/hastyfireinthehole.hpp index 96f839df94e..000837297d9 100644 --- a/src/map/skills/gunslinger/hastyfireinthehole.hpp +++ b/src/map/skills/gunslinger/hastyfireinthehole.hpp @@ -11,4 +11,5 @@ class SkillHastyFireInTheHole : public WeaponSkillImpl { void castendPos2(block_list* src, int32 x, int32 y, uint16 skill_lv, t_tick tick, int32& flag) const override; void calculateSkillRatio(const Damage* wd, const block_list* src, const block_list* target, uint16 skill_lv, int32& base_skillratio, int32 mflag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/gunslinger/howlingmine.cpp b/src/map/skills/gunslinger/howlingmine.cpp index e39b9eddd31..9b64bf1e269 100644 --- a/src/map/skills/gunslinger/howlingmine.cpp +++ b/src/map/skills/gunslinger/howlingmine.cpp @@ -53,3 +53,10 @@ void SkillHowlingMine::calculateSkillRatio(const Damage* wd, const block_list* s skillratio += -100 + 200 + 200 * skill_lv; } } + +void SkillHowlingMine::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const map_session_data* sd = BL_CAST(BL_PC, &src); + + if (sd != nullptr && sd->flicker) //Force RL_H_MINE deals fire damage if activated by RL_FLICKER + element = ELE_FIRE; +} diff --git a/src/map/skills/gunslinger/howlingmine.hpp b/src/map/skills/gunslinger/howlingmine.hpp index 1049049513e..e728916c93b 100644 --- a/src/map/skills/gunslinger/howlingmine.hpp +++ b/src/map/skills/gunslinger/howlingmine.hpp @@ -11,4 +11,5 @@ class SkillHowlingMine : public SkillImpl { void castendDamageId(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32& flag) const override; void calculateSkillRatio(const Damage* wd, const block_list* src, const block_list* target, uint16 skill_lv, int32& base_skillratio, int32 mflag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/gunslinger/missionbombard.cpp b/src/map/skills/gunslinger/missionbombard.cpp index e1a7fe97fc6..4dc6ab1cabf 100644 --- a/src/map/skills/gunslinger/missionbombard.cpp +++ b/src/map/skills/gunslinger/missionbombard.cpp @@ -37,3 +37,24 @@ void SkillMissionBombard::calculateSkillRatio(const Damage* wd, const block_list skillratio += 5 * sstatus->con; RE_LVL_DMOD(100); } + +void SkillMissionBombard::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const status_change* sc = status_get_sc(&src); + + // Night Watch Grenade Fragment elementals + if( sc != nullptr ){ + if( sc->hasSCE( SC_GRENADE_FRAGMENT_1 ) ){ + element = ELE_WATER; + }else if( sc->hasSCE( SC_GRENADE_FRAGMENT_2 ) ){ + element = ELE_WIND; + }else if( sc->hasSCE( SC_GRENADE_FRAGMENT_3 ) ){ + element = ELE_EARTH; + }else if( sc->hasSCE( SC_GRENADE_FRAGMENT_4 ) ){ + element = ELE_FIRE; + }else if( sc->hasSCE( SC_GRENADE_FRAGMENT_5 ) ){ + element = ELE_DARK; + }else if( sc->hasSCE( SC_GRENADE_FRAGMENT_6 ) ){ + element = ELE_HOLY; + } + } +} diff --git a/src/map/skills/gunslinger/missionbombard.hpp b/src/map/skills/gunslinger/missionbombard.hpp index 07c016d5324..9e18d70dfb3 100644 --- a/src/map/skills/gunslinger/missionbombard.hpp +++ b/src/map/skills/gunslinger/missionbombard.hpp @@ -11,4 +11,5 @@ class SkillMissionBombard : public WeaponSkillImpl { void castendPos2(block_list* src, int32 x, int32 y, uint16 skill_lv, t_tick tick, int32& flag) const override; void calculateSkillRatio(const Damage* wd, const block_list* src, const block_list* target, uint16 skill_lv, int32& base_skillratio, int32 mflag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/homunculus/homunculus_steelhorn.cpp b/src/map/skills/homunculus/homunculus_steelhorn.cpp index 15a2c88751f..2be02a0b25b 100644 --- a/src/map/skills/homunculus/homunculus_steelhorn.cpp +++ b/src/map/skills/homunculus/homunculus_steelhorn.cpp @@ -21,3 +21,10 @@ void SkillSteelHorn::calculateSkillRatio(const Damage* wd, const block_list* src void SkillSteelHorn::applyAdditionalEffects(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32 attack_type, enum damage_lv dmg_lv) const { sc_start(src, target, SC_STUN, 20 + 2 * skill_lv, skill_lv, skill_get_time(getSkillId(), skill_lv)); } + +void SkillSteelHorn::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const status_change* sc = status_get_sc(&src); + + if (sc != nullptr && sc->hasSCE(SC_GOLDENE_FERSE)) + element = ELE_HOLY; +} diff --git a/src/map/skills/homunculus/homunculus_steelhorn.hpp b/src/map/skills/homunculus/homunculus_steelhorn.hpp index 1af8878f851..c0312932ad0 100644 --- a/src/map/skills/homunculus/homunculus_steelhorn.hpp +++ b/src/map/skills/homunculus/homunculus_steelhorn.hpp @@ -12,4 +12,5 @@ class SkillSteelHorn : public SkillImpl { void castendDamageId(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32& flag) const override; void calculateSkillRatio(const Damage* wd, const block_list* src, const block_list* target, uint16 skill_lv, int32& base_skillratio, int32 mflag) const override; void applyAdditionalEffects(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32 attack_type, enum damage_lv dmg_lv) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/mage/hellinferno.cpp b/src/map/skills/mage/hellinferno.cpp index 2b178a84c03..48dfd54a709 100644 --- a/src/map/skills/mage/hellinferno.cpp +++ b/src/map/skills/mage/hellinferno.cpp @@ -34,3 +34,9 @@ void SkillHellInferno::castendDamageId(block_list *src, block_list *target, uint map_foreachinrange(skill_area_sub, target, skill_get_splash(getSkillId(), skill_lv), BL_CHAR, src, getSkillId(), skill_lv, tick, flag | BCT_ENEMY | SD_SPLASH | 1, skill_castend_damage_id); } } + +void SkillHellInferno::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + if (dmg.miscflag & 2) { + element = ELE_DARK; + } +} diff --git a/src/map/skills/mage/hellinferno.hpp b/src/map/skills/mage/hellinferno.hpp index e243bebef40..b5df6eeaff4 100644 --- a/src/map/skills/mage/hellinferno.hpp +++ b/src/map/skills/mage/hellinferno.hpp @@ -12,4 +12,5 @@ class SkillHellInferno : public SkillImpl { void modifyDamageData(Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv) const override; void calculateSkillRatio(const Damage *wd, const block_list *src, const block_list *target, uint16 skill_lv, int32 &skillratio, int32 mflag) const override; void castendDamageId(block_list *src, block_list *target, uint16 skill_lv, t_tick tick, int32& flag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/mage/psychicwave.cpp b/src/map/skills/mage/psychicwave.cpp index c5de68c357d..76d6d78aee9 100644 --- a/src/map/skills/mage/psychicwave.cpp +++ b/src/map/skills/mage/psychicwave.cpp @@ -31,3 +31,27 @@ void SkillPsychicWave::castendPos2(block_list* src, int32 x, int32 y, uint16 ski flag|=1; // Set flag to 1 to prevent deleting ammo (it will be deleted on group-delete). skill_unitsetting(src,getSkillId(),skill_lv,x,y,0); } + +void SkillPsychicWave::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const status_change* sc = status_get_sc(&src); + + if( sc != nullptr && !sc->empty() ) { + static const std::vector types = { + SC_HEATER_OPTION, + SC_COOLER_OPTION, + SC_BLAST_OPTION, + SC_CURSED_SOIL_OPTION, + SC_FLAMETECHNIC_OPTION, + SC_COLD_FORCE_OPTION, + SC_GRACE_BREEZE_OPTION, + SC_EARTH_CARE_OPTION, + SC_DEEP_POISONING_OPTION + }; + for( sc_type type : types ){ + if( sc->hasSCE( type ) ){ + element = sc->getSCE( type )->val3; + break; + } + } + } +} diff --git a/src/map/skills/mage/psychicwave.hpp b/src/map/skills/mage/psychicwave.hpp index a93141533e7..837e8352dcf 100644 --- a/src/map/skills/mage/psychicwave.hpp +++ b/src/map/skills/mage/psychicwave.hpp @@ -12,4 +12,5 @@ class SkillPsychicWave : public SkillImpl { void modifyDamageData(Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv) const override; void calculateSkillRatio(const Damage *wd, const block_list *src, const block_list *target, uint16 skill_lv, int32 &skillratio, int32 mflag) const override; void castendPos2(block_list* src, int32 x, int32 y, uint16 skill_lv, t_tick tick, int32& flag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/merchant/armcannon.cpp b/src/map/skills/merchant/armcannon.cpp index 05548819be1..d37dc74a33c 100644 --- a/src/map/skills/merchant/armcannon.cpp +++ b/src/map/skills/merchant/armcannon.cpp @@ -5,6 +5,7 @@ #include +#include "map/pc.hpp" #include "map/status.hpp" SkillArmCannon::SkillArmCannon() : SkillImplRecursiveDamageSplash(NC_ARMSCANNON) { @@ -31,3 +32,10 @@ void SkillArmCannon::splashSearch(block_list* src, block_list* target, uint16 sk SkillImplRecursiveDamageSplash::splashSearch(src, target, skill_lv, tick, flag); } + +void SkillArmCannon::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const map_session_data* sd = BL_CAST(BL_PC, &src); + + if (sd != nullptr && sd->state.arrow_atk > 0) + element = sd->bonus.arrow_ele; +} diff --git a/src/map/skills/merchant/armcannon.hpp b/src/map/skills/merchant/armcannon.hpp index 6224d9d7fe7..13904c4a916 100644 --- a/src/map/skills/merchant/armcannon.hpp +++ b/src/map/skills/merchant/armcannon.hpp @@ -13,4 +13,5 @@ class SkillArmCannon : public SkillImplRecursiveDamageSplash { void calculateSkillRatio(const Damage* wd, const block_list* src, const block_list* target, uint16 skill_lv, int32& base_skillratio, int32 mflag) const override; int32 getSplashTarget(block_list* src) const override; void splashSearch(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32 flag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/merchant/cartcannon.cpp b/src/map/skills/merchant/cartcannon.cpp index 4ba8f77775c..93331b693f7 100644 --- a/src/map/skills/merchant/cartcannon.cpp +++ b/src/map/skills/merchant/cartcannon.cpp @@ -39,3 +39,10 @@ void SkillCartCannon::splashSearch(block_list* src, block_list* target, uint16 s SkillImplRecursiveDamageSplash::splashSearch(src, target, skill_lv, tick, flag); } + +void SkillCartCannon::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const map_session_data* sd = BL_CAST(BL_PC, &src); + + if (sd != nullptr && sd->state.arrow_atk > 0) + element = sd->bonus.arrow_ele; +} diff --git a/src/map/skills/merchant/cartcannon.hpp b/src/map/skills/merchant/cartcannon.hpp index cbb4501f012..7eb55b08d6e 100644 --- a/src/map/skills/merchant/cartcannon.hpp +++ b/src/map/skills/merchant/cartcannon.hpp @@ -13,4 +13,5 @@ class SkillCartCannon : public SkillImplRecursiveDamageSplash { void calculateSkillRatio(const Damage *wd, const block_list *src, const block_list *target, uint16 skill_lv, int32 &skillratio, int32 mflag) const override; void modifyHitRate(int16& hit_rate, const block_list* src, const block_list* target, uint16 skill_lv) const override; void splashSearch(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32 flag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/ninja/darkdragonnightmare.cpp b/src/map/skills/ninja/darkdragonnightmare.cpp index bbb71bc3eb1..4df5f5479a9 100644 --- a/src/map/skills/ninja/darkdragonnightmare.cpp +++ b/src/map/skills/ninja/darkdragonnightmare.cpp @@ -43,3 +43,8 @@ void SkillDarkDragonNightmare::castendNoDamageId(block_list *src, block_list *ta map_foreachinrange( skill_area_sub, target, range, BL_CHAR, src, getSkillId(), skill_lv, tick, flag | BCT_ENEMY | SD_SPLASH | 1, skill_castend_damage_id ); } + +void SkillDarkDragonNightmare::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + if (dmg.miscflag & SKILL_ALTDMG_FLAG) + element = ELE_FIRE; +} diff --git a/src/map/skills/ninja/darkdragonnightmare.hpp b/src/map/skills/ninja/darkdragonnightmare.hpp index f91f1c2de45..934b15bff2b 100644 --- a/src/map/skills/ninja/darkdragonnightmare.hpp +++ b/src/map/skills/ninja/darkdragonnightmare.hpp @@ -13,4 +13,5 @@ class SkillDarkDragonNightmare : public SkillImpl { void calculateSkillRatio(const Damage *wd, const block_list *src, const block_list *target, uint16 skill_lv, int32 &skillratio, int32 mflag) const override; void castendDamageId(block_list *src, block_list *target, uint16 skill_lv, t_tick tick, int32& flag) const override; void castendNoDamageId(block_list *src, block_list *target, uint16 skill_lv, t_tick tick, int32& flag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/ninja/huumashurikenconstruct.cpp b/src/map/skills/ninja/huumashurikenconstruct.cpp index 4aaf4c845de..50b065af1bc 100644 --- a/src/map/skills/ninja/huumashurikenconstruct.cpp +++ b/src/map/skills/ninja/huumashurikenconstruct.cpp @@ -40,3 +40,11 @@ void SkillHuumaShurikenConstruct::castendPos2(block_list* src, int32 x, int32 y, skill_get_type(getSkillId()), src, src, getSkillId(), skill_lv, tick, flag, BCT_ENEMY); } } + +void SkillHuumaShurikenConstruct::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const map_session_data* sd = BL_CAST(BL_PC, &src); + + if( sd != nullptr ){ + element = sd->bonus.arrow_ele; + } +} diff --git a/src/map/skills/ninja/huumashurikenconstruct.hpp b/src/map/skills/ninja/huumashurikenconstruct.hpp index 1dadff3f118..e138ab532c8 100644 --- a/src/map/skills/ninja/huumashurikenconstruct.hpp +++ b/src/map/skills/ninja/huumashurikenconstruct.hpp @@ -11,4 +11,5 @@ class SkillHuumaShurikenConstruct : public WeaponSkillImpl { void calculateSkillRatio(const Damage *wd, const block_list *src, const block_list *target, uint16 skill_lv, int32 &skillratio, int32 mflag) const override; void castendPos2(block_list* src, int32 x, int32 y, uint16 skill_lv, t_tick tick, int32& flag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/ninja/huumashurikengrasp.cpp b/src/map/skills/ninja/huumashurikengrasp.cpp index 4ba5557fda9..7b1379f2535 100644 --- a/src/map/skills/ninja/huumashurikengrasp.cpp +++ b/src/map/skills/ninja/huumashurikengrasp.cpp @@ -29,3 +29,11 @@ void SkillHuumaShurikenGrasp::castendPos2(block_list* src, int32 x, int32 y, uin // Ammo should be deleted right away. skill_unitsetting(src,getSkillId(),skill_lv,x,y,0); } + +void SkillHuumaShurikenGrasp::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const map_session_data* sd = BL_CAST(BL_PC, &src); + + if( sd != nullptr ){ + element = sd->bonus.arrow_ele; + } +} diff --git a/src/map/skills/ninja/huumashurikengrasp.hpp b/src/map/skills/ninja/huumashurikengrasp.hpp index 98287e793dc..494ea100feb 100644 --- a/src/map/skills/ninja/huumashurikengrasp.hpp +++ b/src/map/skills/ninja/huumashurikengrasp.hpp @@ -12,4 +12,5 @@ class SkillHuumaShurikenGrasp : public SkillImpl { void applyAdditionalEffects(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32 attack_type, enum damage_lv dmg_lv) const override; void calculateSkillRatio(const Damage *wd, const block_list *src, const block_list *target, uint16 skill_lv, int32 &skillratio, int32 mflag) const override; void castendPos2(block_list* src, int32 x, int32 y, uint16 skill_lv, t_tick tick, int32& flag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/ninja/releaseninjaspell.cpp b/src/map/skills/ninja/releaseninjaspell.cpp index a46a86d9701..5819ffb2452 100644 --- a/src/map/skills/ninja/releaseninjaspell.cpp +++ b/src/map/skills/ninja/releaseninjaspell.cpp @@ -25,3 +25,10 @@ void SkillReleaseNinjaSpell::calculateSkillRatio(const Damage *wd, const block_l void SkillReleaseNinjaSpell::castendDamageId(block_list *src, block_list *target, uint16 skill_lv, t_tick tick, int32& flag) const { skill_attack(BF_MAGIC, src, src, target, getSkillId(), skill_lv, tick, flag); } + +void SkillReleaseNinjaSpell::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const map_session_data* sd = BL_CAST(BL_PC, &src); + + if (sd != nullptr && sd->spiritcharm_type != CHARM_TYPE_NONE && sd->spiritcharm > 0) + element = sd->spiritcharm_type; +} diff --git a/src/map/skills/ninja/releaseninjaspell.hpp b/src/map/skills/ninja/releaseninjaspell.hpp index da7a3d5a831..0057c77a12b 100644 --- a/src/map/skills/ninja/releaseninjaspell.hpp +++ b/src/map/skills/ninja/releaseninjaspell.hpp @@ -11,4 +11,5 @@ class SkillReleaseNinjaSpell : public SkillImpl { void calculateSkillRatio(const Damage *wd, const block_list *src, const block_list *target, uint16 skill_lv, int32 &skillratio, int32 mflag) const override; void castendDamageId(block_list *src, block_list *target, uint16 skill_lv, t_tick tick, int32& flag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/npc/earthquake.cpp b/src/map/skills/npc/earthquake.cpp index 7b49b25f73f..c07d6d992df 100644 --- a/src/map/skills/npc/earthquake.cpp +++ b/src/map/skills/npc/earthquake.cpp @@ -13,3 +13,7 @@ void SkillEarthquake::castendPos2(block_list* src, int32 x, int32 y, uint16 skil clif_skill_damage( *src, *src, tick, status_get_amotion(src), 0, DMGVAL_IGNORE, 1, getSkillId(), -1, DMG_SINGLE ); skill_unitsetting(src, getSkillId(), skill_lv, x, y, 0); } + +void SkillEarthquake::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + element = ELE_NEUTRAL; +} diff --git a/src/map/skills/npc/earthquake.hpp b/src/map/skills/npc/earthquake.hpp index 9b5f588df6b..9237ac84c1a 100644 --- a/src/map/skills/npc/earthquake.hpp +++ b/src/map/skills/npc/earthquake.hpp @@ -10,4 +10,5 @@ class SkillEarthquake : public SkillImpl { SkillEarthquake(); void castendPos2(block_list* src, int32 x, int32 y, uint16 skill_lv, t_tick tick, int32& flag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/npc/npcpsychicwave.cpp b/src/map/skills/npc/npcpsychicwave.cpp index 7a9cd5eb009..58ba801c9d1 100644 --- a/src/map/skills/npc/npcpsychicwave.cpp +++ b/src/map/skills/npc/npcpsychicwave.cpp @@ -14,3 +14,27 @@ void SkillNpcPsychicWave::castendPos2(block_list* src, int32 x, int32 y, uint16 flag|=1; // Set flag to 1 to prevent deleting ammo (it will be deleted on group-delete). skill_unitsetting(src,getSkillId(),skill_lv,x,y,0); } + +void SkillNpcPsychicWave::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const status_change* sc = status_get_sc(&src); + + if( sc != nullptr && !sc->empty() ) { + static const std::vector types = { + SC_HEATER_OPTION, + SC_COOLER_OPTION, + SC_BLAST_OPTION, + SC_CURSED_SOIL_OPTION, + SC_FLAMETECHNIC_OPTION, + SC_COLD_FORCE_OPTION, + SC_GRACE_BREEZE_OPTION, + SC_EARTH_CARE_OPTION, + SC_DEEP_POISONING_OPTION + }; + for( sc_type type : types ){ + if( sc->hasSCE( type ) ){ + element = sc->getSCE( type )->val3; + break; + } + } + } +} diff --git a/src/map/skills/npc/npcpsychicwave.hpp b/src/map/skills/npc/npcpsychicwave.hpp index f27fd17ce8e..2e4054dddce 100644 --- a/src/map/skills/npc/npcpsychicwave.hpp +++ b/src/map/skills/npc/npcpsychicwave.hpp @@ -11,4 +11,5 @@ class SkillNpcPsychicWave : public SkillImpl { void calculateSkillRatio(const Damage *wd, const block_list *src, const block_list *target, uint16 skill_lv, int32 &base_skillratio, int32 mflag) const override; void castendPos2(block_list* src, int32 x, int32 y, uint16 skill_lv, t_tick tick, int32& flag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/skill_impl.cpp b/src/map/skills/skill_impl.cpp index 597786d9d5a..d6cc6222ce8 100644 --- a/src/map/skills/skill_impl.cpp +++ b/src/map/skills/skill_impl.cpp @@ -46,6 +46,10 @@ void SkillImpl::modifyDamageData(Damage&, const block_list&, const block_list&, // no-op } +void SkillImpl::modifyElement(const Damage&, const block_list&, const block_list&, uint16, int32&, int32) const { + // no-op +} + StatusSkillImpl::StatusSkillImpl(e_skill skillId, bool end_if_running) : SkillImpl(skillId) { this->end_if_running = end_if_running; }; diff --git a/src/map/skills/skill_impl.hpp b/src/map/skills/skill_impl.hpp index 321fec436a1..abfde916d8a 100644 --- a/src/map/skills/skill_impl.hpp +++ b/src/map/skills/skill_impl.hpp @@ -52,6 +52,11 @@ class SkillImpl { */ virtual void modifyDamageData(Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv) const; + /** + * Allows modifying the element type of attack. + */ + virtual void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const; + protected: e_skill skill_id_; }; diff --git a/src/map/skills/summoner/catnipmeteor.cpp b/src/map/skills/summoner/catnipmeteor.cpp index cfaff633781..50a8aef8dd1 100644 --- a/src/map/skills/summoner/catnipmeteor.cpp +++ b/src/map/skills/summoner/catnipmeteor.cpp @@ -45,6 +45,26 @@ void SkillCatnipMeteor::castendPos2(block_list* src, int32 x, int32 y, uint16 sk } } +void SkillCatnipMeteor::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const status_change* sc = status_get_sc(&src); + + if( sc != nullptr && !sc->empty() ){ + if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_1 ) ){ + element = ELE_WATER; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_2 ) ){ + element = ELE_WIND; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_3 ) ){ + element = ELE_EARTH; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_4 ) ){ + element = ELE_FIRE; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_5 ) ){ + element = ELE_DARK; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_6 ) ){ + element = ELE_HOLY; + } + } +} + // SU_CN_METEOR2 SkillCatnipMeteor2::SkillCatnipMeteor2() : SkillImpl(SU_CN_METEOR2) { @@ -63,3 +83,23 @@ void SkillCatnipMeteor2::calculateSkillRatio(const Damage *wd, const block_list } RE_LVL_DMOD(100); } + +void SkillCatnipMeteor2::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const status_change* sc = status_get_sc(&src); + + if( sc != nullptr && !sc->empty() ){ + if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_1 ) ){ + element = ELE_WATER; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_2 ) ){ + element = ELE_WIND; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_3 ) ){ + element = ELE_EARTH; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_4 ) ){ + element = ELE_FIRE; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_5 ) ){ + element = ELE_DARK; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_6 ) ){ + element = ELE_HOLY; + } + } +} diff --git a/src/map/skills/summoner/catnipmeteor.hpp b/src/map/skills/summoner/catnipmeteor.hpp index 8e14acbf4a4..494aaeb0099 100644 --- a/src/map/skills/summoner/catnipmeteor.hpp +++ b/src/map/skills/summoner/catnipmeteor.hpp @@ -12,6 +12,7 @@ class SkillCatnipMeteor : public SkillImpl { void calculateSkillRatio(const Damage *wd, const block_list *src, const block_list *target, uint16 skill_lv, int32 &skillratio, int32 mflag) const override; void castendPos2(block_list* src, int32 x, int32 y, uint16 skill_lv, t_tick tick, int32& flag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; @@ -22,4 +23,5 @@ class SkillCatnipMeteor2 : public SkillImpl { void applyAdditionalEffects(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32 attack_type, enum damage_lv dmg_lv) const override; void calculateSkillRatio(const Damage *wd, const block_list *src, const block_list *target, uint16 skill_lv, int32 &skillratio, int32 mflag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/summoner/hyunrokbreeze.cpp b/src/map/skills/summoner/hyunrokbreeze.cpp index 2f5c010171b..0775280c11e 100644 --- a/src/map/skills/summoner/hyunrokbreeze.cpp +++ b/src/map/skills/summoner/hyunrokbreeze.cpp @@ -31,3 +31,23 @@ void SkillHyunrokBreeze::castendPos2(block_list* src, int32 x, int32 y, uint16 s flag|=1;//Set flag to 1 to prevent deleting ammo (it will be deleted on group-delete). skill_unitsetting(src,getSkillId(),skill_lv,x,y,0); } + +void SkillHyunrokBreeze::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const status_change* sc = status_get_sc(&src); + + if( sc != nullptr && !sc->empty() ){ + if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_1 ) ){ + element = ELE_WATER; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_2 ) ){ + element = ELE_WIND; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_3 ) ){ + element = ELE_EARTH; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_4 ) ){ + element = ELE_FIRE; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_5 ) ){ + element = ELE_DARK; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_6 ) ){ + element = ELE_HOLY; + } + } +} diff --git a/src/map/skills/summoner/hyunrokbreeze.hpp b/src/map/skills/summoner/hyunrokbreeze.hpp index bab2e41528e..97a00d23090 100644 --- a/src/map/skills/summoner/hyunrokbreeze.hpp +++ b/src/map/skills/summoner/hyunrokbreeze.hpp @@ -11,4 +11,5 @@ class SkillHyunrokBreeze : public SkillImpl { void calculateSkillRatio(const Damage *wd, const block_list *src, const block_list *target, uint16 skill_lv, int32 &skillratio, int32 mflag) const override; void castendPos2(block_list* src, int32 x, int32 y, uint16 skill_lv, t_tick tick, int32& flag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/summoner/hyunrokcannon.cpp b/src/map/skills/summoner/hyunrokcannon.cpp index a86ebbebc38..76c57f62d18 100644 --- a/src/map/skills/summoner/hyunrokcannon.cpp +++ b/src/map/skills/summoner/hyunrokcannon.cpp @@ -32,3 +32,23 @@ void SkillHyunrokCannon::castendDamageId(block_list *src, block_list *target, ui clif_skill_nodamage(src, *target, getSkillId(), skill_lv); skill_attack(skill_get_type(getSkillId()), src, src, target, getSkillId(), skill_lv, tick, flag); } + +void SkillHyunrokCannon::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const status_change* sc = status_get_sc(&src); + + if( sc != nullptr && !sc->empty() ){ + if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_1 ) ){ + element = ELE_WATER; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_2 ) ){ + element = ELE_WIND; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_3 ) ){ + element = ELE_EARTH; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_4 ) ){ + element = ELE_FIRE; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_5 ) ){ + element = ELE_DARK; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_6 ) ){ + element = ELE_HOLY; + } + } +} diff --git a/src/map/skills/summoner/hyunrokcannon.hpp b/src/map/skills/summoner/hyunrokcannon.hpp index 5d545f64454..5d45636fcc6 100644 --- a/src/map/skills/summoner/hyunrokcannon.hpp +++ b/src/map/skills/summoner/hyunrokcannon.hpp @@ -11,4 +11,5 @@ class SkillHyunrokCannon : public SkillImpl { void calculateSkillRatio(const Damage *wd, const block_list *src, const block_list *target, uint16 skill_lv, int32 &skillratio, int32 mflag) const override; void castendDamageId(block_list *src, block_list *target, uint16 skill_lv, t_tick tick, int32& flag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/summoner/hyunrokspiritpower.cpp b/src/map/skills/summoner/hyunrokspiritpower.cpp index 51814db79d4..29ce782584f 100644 --- a/src/map/skills/summoner/hyunrokspiritpower.cpp +++ b/src/map/skills/summoner/hyunrokspiritpower.cpp @@ -27,3 +27,23 @@ void SkillHyunrokSpiritPower::splashSearch(block_list* src, block_list* target, SkillImplRecursiveDamageSplash::splashSearch(src, target, skill_lv, tick, flag); } + +void SkillHyunrokSpiritPower::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const status_change* sc = status_get_sc(&src); + + if( sc != nullptr && !sc->empty() ){ + if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_1 ) ){ + element = ELE_WATER; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_2 ) ){ + element = ELE_WIND; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_3 ) ){ + element = ELE_EARTH; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_4 ) ){ + element = ELE_FIRE; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_5 ) ){ + element = ELE_DARK; + }else if( sc->hasSCE( SC_COLORS_OF_HYUN_ROK_6 ) ){ + element = ELE_HOLY; + } + } +} diff --git a/src/map/skills/summoner/hyunrokspiritpower.hpp b/src/map/skills/summoner/hyunrokspiritpower.hpp index 07eb2378fad..02d02410047 100644 --- a/src/map/skills/summoner/hyunrokspiritpower.hpp +++ b/src/map/skills/summoner/hyunrokspiritpower.hpp @@ -11,4 +11,5 @@ class SkillHyunrokSpiritPower : public SkillImplRecursiveDamageSplash { void calculateSkillRatio(const Damage *wd, const block_list *src, const block_list *target, uint16 skill_lv, int32 &skillratio, int32 mflag) const override; void splashSearch(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32 flag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/swordman/dragonbreath.cpp b/src/map/skills/swordman/dragonbreath.cpp index a35f91a9652..1c57ceac50c 100644 --- a/src/map/skills/swordman/dragonbreath.cpp +++ b/src/map/skills/swordman/dragonbreath.cpp @@ -24,6 +24,17 @@ void SkillDragonBreath::castendDamageId(block_list *src, block_list *target, uin } } +void SkillDragonBreath::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const status_change* sc = status_get_sc(&src); + + if (sc != nullptr) { + if (sc->hasSCE(SC_LUXANIMA)) // Lux Anima has priority over Giant Growth + element = ELE_DARK; + else if (sc->hasSCE(SC_GIANTGROWTH)) + element = ELE_HOLY; + } +} + // RK_DRAGONBREATH_WATER SkillDragonBreathWater::SkillDragonBreathWater() : SkillImplRecursiveDamageSplash(RK_DRAGONBREATH_WATER) { @@ -42,3 +53,14 @@ void SkillDragonBreathWater::castendDamageId(block_list *src, block_list *target skill_attack(BF_WEAPON, src, src, target, getSkillId(), skill_lv, tick, flag); } } + +void SkillDragonBreathWater::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const status_change* sc = status_get_sc(&src); + + if (sc != nullptr) { + if (sc->hasSCE(SC_LUXANIMA)) // Lux Anima has priority over Fighting Spirit + element = ELE_NEUTRAL; + else if (sc->hasSCE(SC_FIGHTINGSPIRIT)) + element = ELE_GHOST; + } +} diff --git a/src/map/skills/swordman/dragonbreath.hpp b/src/map/skills/swordman/dragonbreath.hpp index 88b7a311723..b459e156a9e 100644 --- a/src/map/skills/swordman/dragonbreath.hpp +++ b/src/map/skills/swordman/dragonbreath.hpp @@ -12,6 +12,7 @@ class SkillDragonBreath : public SkillImplRecursiveDamageSplash { void applyAdditionalEffects(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32 attack_type, enum damage_lv dmg_lv) const override; void castendDamageId(block_list *src, block_list *target, uint16 skill_lv, t_tick tick, int32& flag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; @@ -22,4 +23,5 @@ class SkillDragonBreathWater : public SkillImplRecursiveDamageSplash { void applyAdditionalEffects(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32 attack_type, enum damage_lv dmg_lv) const override; void castendDamageId(block_list *src, block_list *target, uint16 skill_lv, t_tick tick, int32& flag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/swordman/hesperuslit.cpp b/src/map/skills/swordman/hesperuslit.cpp index 54f2bc35ec2..8bf23ca1445 100644 --- a/src/map/skills/swordman/hesperuslit.cpp +++ b/src/map/skills/swordman/hesperuslit.cpp @@ -50,3 +50,10 @@ void SkillHesperusLit::applyAdditionalEffects(block_list* src, block_list* targe if( pc_checkskill(sd,LG_PINPOINTATTACK) > 0 && sc && sc->getSCE(SC_BANDING) && sc->getSCE(SC_BANDING)->val2 > 5 ) skill_castend_damage_id(src,target,LG_PINPOINTATTACK, rnd_value(1, pc_checkskill(sd,LG_PINPOINTATTACK)),tick,0); } + +void SkillHesperusLit::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const status_change* sc = status_get_sc(&src); + + if (sc != nullptr && sc->hasSCE(SC_BANDING) && sc->getSCE(SC_BANDING)->val2 > 4) + element = ELE_HOLY; +} diff --git a/src/map/skills/swordman/hesperuslit.hpp b/src/map/skills/swordman/hesperuslit.hpp index f706d92f8b8..45111ae4207 100644 --- a/src/map/skills/swordman/hesperuslit.hpp +++ b/src/map/skills/swordman/hesperuslit.hpp @@ -12,4 +12,5 @@ class SkillHesperusLit : public WeaponSkillImpl { void applyCounterAdditionalEffects(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32& attack_type) const override; void calculateSkillRatio(const Damage* wd, const block_list* src, const block_list* target, uint16 skill_lv, int32& base_skillratio, int32 mflag) const override; void applyAdditionalEffects(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32 attack_type, enum damage_lv dmg_lv) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/swordman/imperialpressure.cpp b/src/map/skills/swordman/imperialpressure.cpp index 2b93a36016e..11b49ce95f4 100644 --- a/src/map/skills/swordman/imperialpressure.cpp +++ b/src/map/skills/swordman/imperialpressure.cpp @@ -27,3 +27,10 @@ void SkillImperialPressure::splashSearch(block_list* src, block_list* target, ui SkillImplRecursiveDamageSplash::splashSearch(src, target, skill_lv, tick, flag); } + +void SkillImperialPressure::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const status_change* sc = status_get_sc(&src); + + if (sc != nullptr && sc->hasSCE(SC_GUARD_STANCE)) + element = ELE_HOLY; +} diff --git a/src/map/skills/swordman/imperialpressure.hpp b/src/map/skills/swordman/imperialpressure.hpp index 530dbf14990..86261546a96 100644 --- a/src/map/skills/swordman/imperialpressure.hpp +++ b/src/map/skills/swordman/imperialpressure.hpp @@ -11,4 +11,5 @@ class SkillImperialPressure : public SkillImplRecursiveDamageSplash { void calculateSkillRatio(const Damage* wd, const block_list* src, const block_list* target, uint16 skill_lv, int32& base_skillratio, int32 mflag) const override; void splashSearch(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32 flag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/swordman/rayofgenesis.cpp b/src/map/skills/swordman/rayofgenesis.cpp index 2a96c658094..f90c143054b 100644 --- a/src/map/skills/swordman/rayofgenesis.cpp +++ b/src/map/skills/swordman/rayofgenesis.cpp @@ -32,3 +32,10 @@ void SkillRayOfGenesis::applyAdditionalEffects(block_list* src, block_list* targ if ( battle_check_undead(tstatus->race, tstatus->def_ele) || tstatus->race == RC_DEMON ) sc_start(src,target, SC_BLIND, 50, skill_lv, skill_get_time(getSkillId(),skill_lv)); } + +void SkillRayOfGenesis::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + const status_change* sc = status_get_sc(&src); + + if (sc != nullptr && sc->hasSCE(SC_INSPIRATION)) + element = ELE_NEUTRAL; +} diff --git a/src/map/skills/swordman/rayofgenesis.hpp b/src/map/skills/swordman/rayofgenesis.hpp index 2dab6f63498..58df1a61fc6 100644 --- a/src/map/skills/swordman/rayofgenesis.hpp +++ b/src/map/skills/swordman/rayofgenesis.hpp @@ -12,4 +12,5 @@ class SkillRayOfGenesis : public SkillImplRecursiveDamageSplash { void castendNoDamageId(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32& flag) const override; void calculateSkillRatio(const Damage* wd, const block_list* src, const block_list* target, uint16 skill_lv, int32& base_skillratio, int32 mflag) const override; void applyAdditionalEffects(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32 attack_type, enum damage_lv dmg_lv) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/swordman/shieldboomerang.cpp b/src/map/skills/swordman/shieldboomerang.cpp index bf7162a55c6..4338ddf907c 100644 --- a/src/map/skills/swordman/shieldboomerang.cpp +++ b/src/map/skills/swordman/shieldboomerang.cpp @@ -15,3 +15,11 @@ void SkillShieldBoomerang::calculateSkillRatio(const Damage* wd, const block_lis base_skillratio += 30 * skill_lv; #endif } + +void SkillShieldBoomerang::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { +#ifdef RENEWAL + // flag 1 means the element should be calculated for damage only + if (flag & 1) + element = ELE_NEUTRAL; +#endif +} diff --git a/src/map/skills/swordman/shieldboomerang.hpp b/src/map/skills/swordman/shieldboomerang.hpp index b6223ab9bb4..0d2f5a6fb02 100644 --- a/src/map/skills/swordman/shieldboomerang.hpp +++ b/src/map/skills/swordman/shieldboomerang.hpp @@ -10,4 +10,5 @@ class SkillShieldBoomerang : public WeaponSkillImpl { SkillShieldBoomerang(); void calculateSkillRatio(const Damage* wd, const block_list* src, const block_list* target, uint16 skill_lv, int32& base_skillratio, int32 mflag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/swordman/spiralpierce.cpp b/src/map/skills/swordman/spiralpierce.cpp index e441e0ebba3..b52cae8d4ac 100644 --- a/src/map/skills/swordman/spiralpierce.cpp +++ b/src/map/skills/swordman/spiralpierce.cpp @@ -37,3 +37,8 @@ void SkillSpiralPierce::applyAdditionalEffects(block_list *src, block_list *targ if( dstsd || ( dstmd && !status_bl_has_mode(target,MD_STATUSIMMUNE) ) ) //Does not work on status immune sc_start(src,target,SC_ANKLE,100,0,skill_get_time2(getSkillId(),skill_lv)); } + +void SkillSpiralPierce::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + if (src.type != BL_PC) + element = ELE_NEUTRAL; // forced neutral for monsters +} diff --git a/src/map/skills/swordman/spiralpierce.hpp b/src/map/skills/swordman/spiralpierce.hpp index a1f3773517d..b1c4fdb69ce 100644 --- a/src/map/skills/swordman/spiralpierce.hpp +++ b/src/map/skills/swordman/spiralpierce.hpp @@ -12,4 +12,5 @@ class SkillSpiralPierce : public WeaponSkillImpl { void modifyDamageData(Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv) const override; void applyAdditionalEffects(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32 attack_type, enum damage_lv dmg_lv) const override; void calculateSkillRatio(const Damage *wd, const block_list *src, const block_list *target, uint16 skill_lv, int32 &skillratio, int32 mflag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; }; diff --git a/src/map/skills/taekwon/prominencekick.cpp b/src/map/skills/taekwon/prominencekick.cpp index f9b0d3cbf0c..149a6c8c21b 100644 --- a/src/map/skills/taekwon/prominencekick.cpp +++ b/src/map/skills/taekwon/prominencekick.cpp @@ -18,3 +18,7 @@ int64 SkillProminenceKick::splashDamage(block_list* src, block_list* target, uin return dmg; } + +void SkillProminenceKick::modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const { + element = ELE_FIRE; +} diff --git a/src/map/skills/taekwon/prominencekick.hpp b/src/map/skills/taekwon/prominencekick.hpp index 9178b386563..33c26c93887 100644 --- a/src/map/skills/taekwon/prominencekick.hpp +++ b/src/map/skills/taekwon/prominencekick.hpp @@ -11,4 +11,5 @@ class SkillProminenceKick : public SkillImplRecursiveDamageSplash { void calculateSkillRatio(const Damage *wd, const block_list *src, const block_list *target, uint16 skill_lv, int32 &base_skillratio, int32 mflag) const override; int64 splashDamage(block_list* src, block_list* target, uint16 skill_lv, t_tick tick, int32 flag) const override; + void modifyElement(const Damage& dmg, const block_list& src, const block_list& target, uint16 skill_lv, int32& element, int32 flag) const override; };