diff --git a/src/map/battle.cpp b/src/map/battle.cpp index 4e5e2ed2990..44fbb23a7da 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -4862,22 +4862,7 @@ static int32 battle_calc_attack_skill_ratio(struct Damage* wd, block_list *src,b skillratio += 100 + 100 * skill_lv; #endif break; - case LK_HEADCRUSH: - skillratio += 40 * skill_lv; - break; - case LK_JOINTBEAT: - skillratio += 10 * skill_lv - 50; - if (wd->miscflag & BREAK_NECK || (tsc && tsc->getSCE(SC_JOINTBEAT) && tsc->getSCE(SC_JOINTBEAT)->val2 & BREAK_NECK)) // The 2x damage is only for the BREAK_NECK ailment. - skillratio *= 2; - break; #ifdef RENEWAL - // Renewal: skill ratio applies to entire damage [helvetica] - case LK_SPIRALPIERCE: - skillratio += 50 + 50 * skill_lv; - RE_LVL_DMOD(100); - if (sc && sc->getSCE(SC_CHARGINGPIERCE_COUNT) && sc->getSCE(SC_CHARGINGPIERCE_COUNT)->val1 >= 10) - skillratio *= 2; - break; case ML_SPIRALPIERCE: skillratio += 50 + 50 * skill_lv; RE_LVL_DMOD(100); diff --git a/src/map/map-server-generator.vcxproj b/src/map/map-server-generator.vcxproj index 4ae7d0f04e1..d6c13fc8fef 100644 --- a/src/map/map-server-generator.vcxproj +++ b/src/map/map-server-generator.vcxproj @@ -382,6 +382,7 @@ + @@ -391,6 +392,9 @@ + + + @@ -651,6 +655,7 @@ + @@ -660,6 +665,9 @@ + + + diff --git a/src/map/map-server-generator.vcxproj.filters b/src/map/map-server-generator.vcxproj.filters index 969354b7a90..3d941dcbe3d 100644 --- a/src/map/map-server-generator.vcxproj.filters +++ b/src/map/map-server-generator.vcxproj.filters @@ -795,6 +795,9 @@ Header Files\Skills\Swordman + + Header Files\Skills\Swordman + Header Files\Skills\Swordman @@ -822,6 +825,15 @@ Header Files\Skills\Swordman + + Header Files\Skills\Swordman + + + Header Files\Skills\Swordman + + + Header Files\Skills\Swordman + Header Files\Skills\Taekwon @@ -1460,6 +1472,9 @@ Source Files\Skills\Swordman + + Source Files\Skills\Swordman + Source Files\Skills\Swordman @@ -1487,6 +1502,15 @@ Source Files\Skills\Swordman + + Source Files\Skills\Swordman + + + Source Files\Skills\Swordman + + + Source Files\Skills\Swordman + Source Files\Skills\Taekwon diff --git a/src/map/map-server.vcxproj b/src/map/map-server.vcxproj index ce700fa94ca..277a27aa7ad 100644 --- a/src/map/map-server.vcxproj +++ b/src/map/map-server.vcxproj @@ -382,6 +382,7 @@ + @@ -391,6 +392,9 @@ + + + @@ -651,6 +655,7 @@ + @@ -660,6 +665,9 @@ + + + diff --git a/src/map/map-server.vcxproj.filters b/src/map/map-server.vcxproj.filters index 969354b7a90..3d941dcbe3d 100644 --- a/src/map/map-server.vcxproj.filters +++ b/src/map/map-server.vcxproj.filters @@ -795,6 +795,9 @@ Header Files\Skills\Swordman + + Header Files\Skills\Swordman + Header Files\Skills\Swordman @@ -822,6 +825,15 @@ Header Files\Skills\Swordman + + Header Files\Skills\Swordman + + + Header Files\Skills\Swordman + + + Header Files\Skills\Swordman + Header Files\Skills\Taekwon @@ -1460,6 +1472,9 @@ Source Files\Skills\Swordman + + Source Files\Skills\Swordman + Source Files\Skills\Swordman @@ -1487,6 +1502,15 @@ Source Files\Skills\Swordman + + Source Files\Skills\Swordman + + + Source Files\Skills\Swordman + + + Source Files\Skills\Swordman + Source Files\Skills\Taekwon diff --git a/src/map/skill.cpp b/src/map/skill.cpp index fcfd420a55b..fdb31654988 100755 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -1572,7 +1572,6 @@ int32 skill_additional_effect( block_list* src, block_list *bl, uint16 skill_id, } break; - case LK_SPIRALPIERCE: case ML_SPIRALPIERCE: case HN_SPIRAL_PIERCE_MAX: if( dstsd || ( dstmd && !status_bl_has_mode(bl,MD_STATUSIMMUNE) ) ) //Does not work on status immune @@ -1584,11 +1583,6 @@ int32 skill_additional_effect( block_list* src, block_list *bl, uint16 skill_id, sc_start(src,bl,SC_BLIND,100,skill_lv,skill_get_time2(skill_id,skill_lv)); break; - case LK_HEADCRUSH: //Headcrush has chance of causing Bleeding status, except on demon and undead element - if (!(battle_check_undead(tstatus->race, tstatus->def_ele) || tstatus->race == RC_DEMON)) - sc_start2(src,bl, SC_BLEEDING,50, skill_lv, src->id, skill_get_time2(skill_id,skill_lv)); - break; - case HW_NAPALMVULCAN: case HN_NAPALM_VULCAN_STRIKE: sc_start(src,bl,SC_CURSE,5*skill_lv,skill_lv,skill_get_time2(skill_id,skill_lv)); @@ -5120,23 +5114,6 @@ int32 skill_castend_damage_id (block_list* src, block_list *bl, uint16 skill_id, skill_attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag|SD_ANIMATION); break; - case LK_HEADCRUSH: - if (status_get_class_(bl) == CLASS_BOSS) { - if (sd) - clif_skill_fail( *sd, skill_id ); - break; - } - skill_attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag); - break; - - case LK_JOINTBEAT: - flag = 1 << rnd() % 6; - if (flag != BREAK_NECK && tsc && tsc->getSCE(SC_JOINTBEAT) && tsc->getSCE(SC_JOINTBEAT)->val2 & BREAK_NECK) - flag = BREAK_NECK; // Target should always receive double damage if neck is already broken - if (skill_attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag)) - status_change_start(src, bl, SC_JOINTBEAT, (50 * (skill_lv + 1) - (270 * tstatus->str) / 100) * 10, skill_lv, flag & BREAK_FLAGS, src->id, 0, skill_get_time2(skill_id, skill_lv), SCSTART_NONE); - break; - case MO_COMBOFINISH: if (!(flag&1) && sc && sc->getSCE(SC_SPIRIT) && sc->getSCE(SC_SPIRIT)->val2 == SL_MONK) { //Becomes a splash attack when Soul Linked. @@ -8040,12 +8017,6 @@ int32 skill_castend_nodamage_id (block_list *src, block_list *bl, uint16 skill_i break; */ - case LK_TENSIONRELAX: - clif_skill_nodamage(src,*bl,skill_id,skill_lv, - sc_start4(src,bl,type,100,skill_lv,0,0,skill_get_time2(skill_id,skill_lv), - skill_get_time(skill_id,skill_lv))); - break; - case MER_PROVOKE: if( status_has_mode(tstatus,MD_STATUSIMMUNE) || battle_check_undead(tstatus->race,tstatus->def_ele) ) { return 1; diff --git a/src/map/skills/swordman/relax.cpp b/src/map/skills/swordman/relax.cpp new file mode 100644 index 00000000000..efab2545fde --- /dev/null +++ b/src/map/skills/swordman/relax.cpp @@ -0,0 +1,18 @@ +// Copyright (c) rAthena Dev Teams - Licensed under GNU GPL +// For more information, see LICENCE in the main folder + +#include "relax.hpp" + +#include "map/clif.hpp" +#include "map/status.hpp" + +SkillRelax::SkillRelax() : SkillImpl(LK_TENSIONRELAX) { +} + +void SkillRelax::castendNoDamageId(block_list *src, block_list *target, uint16 skill_lv, t_tick tick, int32& flag) const { + sc_type type = skill_get_sc(getSkillId()); + + clif_skill_nodamage(src,*target,getSkillId(),skill_lv, + sc_start4(src,target,type,100,skill_lv,0,0,skill_get_time2(getSkillId(),skill_lv), + skill_get_time(getSkillId(),skill_lv))); +} diff --git a/src/map/skills/swordman/relax.hpp b/src/map/skills/swordman/relax.hpp new file mode 100644 index 00000000000..e0edd3869c3 --- /dev/null +++ b/src/map/skills/swordman/relax.hpp @@ -0,0 +1,13 @@ +// Copyright (c) rAthena Dev Teams - Licensed under GNU GPL +// For more information, see LICENCE in the main folder + +#pragma once + +#include "../skill_impl.hpp" + +class SkillRelax : public SkillImpl { +public: + SkillRelax(); + + void castendNoDamageId(block_list *src, block_list *target, uint16 skill_lv, t_tick tick, int32& flag) const override; +}; diff --git a/src/map/skills/swordman/skill_factory_swordman.cpp b/src/map/skills/swordman/skill_factory_swordman.cpp index 7ae68c084a0..e901f59c271 100644 --- a/src/map/skills/swordman/skill_factory_swordman.cpp +++ b/src/map/skills/swordman/skill_factory_swordman.cpp @@ -16,6 +16,7 @@ #include "magnum.hpp" #include "pierce.hpp" #include "provoke.hpp" +#include "relax.hpp" #include "resistantsouls.hpp" #include "sacrifice.hpp" #include "selfprovoke.hpp" @@ -24,6 +25,9 @@ #include "smite.hpp" #include "spearboomerang.hpp" #include "spearstab.hpp" +#include "spiralpierce.hpp" +#include "traumaticblow.hpp" +#include "vitalstrike.hpp" std::unique_ptr SkillFactorySwordman::create(const e_skill skill_id) const { switch( skill_id ){ @@ -99,10 +103,16 @@ std::unique_ptr SkillFactorySwordman::create(const e_skill skil return std::make_unique(skill_id); case LK_CONCENTRATION: return std::make_unique(skill_id); + case LK_HEADCRUSH: + return std::make_unique(); + case LK_JOINTBEAT: + return std::make_unique(); case LK_PARRYING: return std::make_unique(skill_id); case LK_SPIRALPIERCE: - return std::make_unique(skill_id); + return std::make_unique(); + case LK_TENSIONRELAX: + return std::make_unique(); case PA_SACRIFICE: return std::make_unique(skill_id); case PA_SHIELDCHAIN: diff --git a/src/map/skills/swordman/spiralpierce.cpp b/src/map/skills/swordman/spiralpierce.cpp new file mode 100644 index 00000000000..d7c69f0ee40 --- /dev/null +++ b/src/map/skills/swordman/spiralpierce.cpp @@ -0,0 +1,33 @@ +// Copyright (c) rAthena Dev Teams - Licensed under GNU GPL +// For more information, see LICENCE in the main folder + +#include "spiralpierce.hpp" + +#include +#include + +#include "map/mob.hpp" +#include "map/pc.hpp" +#include "map/status.hpp" + +SkillSpiralPierce::SkillSpiralPierce() : WeaponSkillImpl(LK_SPIRALPIERCE) { +} + +void SkillSpiralPierce::calculateSkillRatio(const Damage *wd, const block_list *src, const block_list *target, uint16 skill_lv, int32 &skillratio, int32 mflag) const { +#ifdef RENEWAL + const status_change *sc = status_get_sc(src); + + skillratio += 50 + 50 * skill_lv; + RE_LVL_DMOD(100); + if (sc && sc->getSCE(SC_CHARGINGPIERCE_COUNT) && sc->getSCE(SC_CHARGINGPIERCE_COUNT)->val1 >= 10) + skillratio *= 2; +#endif +} + +void SkillSpiralPierce::applyAdditionalEffects(block_list *src, block_list *target, uint16 skill_lv, t_tick tick, int32 attack_type, enum damage_lv dmg_lv) const { + map_session_data *dstsd = BL_CAST(BL_PC, target); + mob_data* dstmd = BL_CAST(BL_MOB, target); + + 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)); +} diff --git a/src/map/skills/swordman/spiralpierce.hpp b/src/map/skills/swordman/spiralpierce.hpp new file mode 100644 index 00000000000..dafb0bdb19a --- /dev/null +++ b/src/map/skills/swordman/spiralpierce.hpp @@ -0,0 +1,14 @@ +// Copyright (c) rAthena Dev Teams - Licensed under GNU GPL +// For more information, see LICENCE in the main folder + +#pragma once + +#include "../weapon_skill_impl.hpp" + +class SkillSpiralPierce : public WeaponSkillImpl { +public: + SkillSpiralPierce(); + + 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; +}; diff --git a/src/map/skills/swordman/traumaticblow.cpp b/src/map/skills/swordman/traumaticblow.cpp new file mode 100644 index 00000000000..6d1e1c0ecc4 --- /dev/null +++ b/src/map/skills/swordman/traumaticblow.cpp @@ -0,0 +1,35 @@ +// Copyright (c) rAthena Dev Teams - Licensed under GNU GPL +// For more information, see LICENCE in the main folder + +#include "traumaticblow.hpp" + +#include "map/clif.hpp" +#include "map/pc.hpp" +#include "map/status.hpp" + +SkillTraumaticBlow::SkillTraumaticBlow() : WeaponSkillImpl(LK_HEADCRUSH) { +} + +void SkillTraumaticBlow::calculateSkillRatio(const Damage *wd, const block_list *src, const block_list *target, uint16 skill_lv, int32 &base_skillratio, int32 mflag) const { + base_skillratio += 40 * skill_lv; +} + +void SkillTraumaticBlow::castendDamageId(block_list *src, block_list *target, uint16 skill_lv, t_tick tick, int32& flag) const { + map_session_data* sd = BL_CAST( BL_PC, src ); + + if (status_get_class_(target) == CLASS_BOSS) { + if (sd) + clif_skill_fail( *sd, getSkillId() ); + return; + } + + WeaponSkillImpl::castendDamageId(src, target, skill_lv, tick, flag); +} + +void SkillTraumaticBlow::applyAdditionalEffects(block_list *src, block_list *target, uint16 skill_lv, t_tick tick, int32 attack_type, enum damage_lv dmg_lv) const { + status_data* tstatus = status_get_status_data(*target); + + // Headcrush has chance of causing Bleeding status, except on demon and undead element + if (!(battle_check_undead(tstatus->race, tstatus->def_ele) || tstatus->race == RC_DEMON)) + sc_start2(src,target, SC_BLEEDING,50, skill_lv, src->id, skill_get_time2(getSkillId(),skill_lv)); +} diff --git a/src/map/skills/swordman/traumaticblow.hpp b/src/map/skills/swordman/traumaticblow.hpp new file mode 100644 index 00000000000..3f153346ab7 --- /dev/null +++ b/src/map/skills/swordman/traumaticblow.hpp @@ -0,0 +1,15 @@ +// Copyright (c) rAthena Dev Teams - Licensed under GNU GPL +// For more information, see LICENCE in the main folder + +#pragma once + +#include "../weapon_skill_impl.hpp" + +class SkillTraumaticBlow : public WeaponSkillImpl { +public: + SkillTraumaticBlow(); + + 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 &base_skillratio, int32 mflag) const override; + void castendDamageId(block_list *src, block_list *target, uint16 skill_lv, t_tick tick, int32& flag) const override; +}; diff --git a/src/map/skills/swordman/vitalstrike.cpp b/src/map/skills/swordman/vitalstrike.cpp new file mode 100644 index 00000000000..93f67e1886d --- /dev/null +++ b/src/map/skills/swordman/vitalstrike.cpp @@ -0,0 +1,30 @@ +// Copyright (c) rAthena Dev Teams - Licensed under GNU GPL +// For more information, see LICENCE in the main folder + +#include "vitalstrike.hpp" + +#include "map/status.hpp" + +SkillVitalStrike::SkillVitalStrike() : SkillImpl(LK_JOINTBEAT) { +} + +void SkillVitalStrike::calculateSkillRatio(const Damage *wd, const block_list *src, const block_list *target, uint16 skill_lv, int32 &base_skillratio, int32 mflag) const { + const status_change *tsc = status_get_sc(target); + + base_skillratio += 10 * skill_lv - 50; + + // The 2x damage is only for the BREAK_NECK ailment. + if (wd->miscflag & BREAK_NECK || (tsc && tsc->getSCE(SC_JOINTBEAT) && tsc->getSCE(SC_JOINTBEAT)->val2 & BREAK_NECK)) + base_skillratio *= 2; +} + +void SkillVitalStrike::castendDamageId(block_list *src, block_list *target, uint16 skill_lv, t_tick tick, int32& flag) const { + status_data* tstatus = status_get_status_data(*target); + status_change *tsc = status_get_sc(target); + + flag = 1 << rnd() % 6; + if (flag != BREAK_NECK && tsc && tsc->getSCE(SC_JOINTBEAT) && tsc->getSCE(SC_JOINTBEAT)->val2 & BREAK_NECK) + flag = BREAK_NECK; // Target should always receive double damage if neck is already broken + if (skill_attack(BF_WEAPON, src, src, target, getSkillId(), skill_lv, tick, flag)) + status_change_start(src, target, SC_JOINTBEAT, (50 * (skill_lv + 1) - (270 * tstatus->str) / 100) * 10, skill_lv, flag & BREAK_FLAGS, src->id, 0, skill_get_time2(getSkillId(), skill_lv), SCSTART_NONE); +} diff --git a/src/map/skills/swordman/vitalstrike.hpp b/src/map/skills/swordman/vitalstrike.hpp new file mode 100644 index 00000000000..ab7d0761d33 --- /dev/null +++ b/src/map/skills/swordman/vitalstrike.hpp @@ -0,0 +1,14 @@ +// Copyright (c) rAthena Dev Teams - Licensed under GNU GPL +// For more information, see LICENCE in the main folder + +#pragma once + +#include "../skill_impl.hpp" + +class SkillVitalStrike : public SkillImpl { +public: + SkillVitalStrike(); + + void calculateSkillRatio(const Damage *wd, const block_list *src, const block_list *target, uint16 skill_lv, int32 &base_skillratio, int32 mflag) const override; + void castendDamageId(block_list *src, block_list *target, uint16 skill_lv, t_tick tick, int32& flag) const override; +};