#ifndef _SKILL_TABLE_H_ #define _SKILL_TABLE_H_ #pragma once #include #include #include #include #include #include #include #include #include "SkillMgr.h" namespace Skill { enum PassiveType { ActivatePassive = 1, DeactivatePassive = 2 }; enum MasteryType { NONE_MASTERY = 0, SWORD_MASTERY = 1, AXE_MASTERY = 2, BLUNT_MASTERY = 3, DAGGER_MASTERY = 4, CRUSH_WEAPON = 5, BLADE = 6, CLAW_MASTERY = 7 }; typedef unsigned short (*FnProcess)(const Skill::ProtoType& ProtoType, AtType attackType, CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, unsigned char &cOffencerJudge, unsigned char &cDefenserJudge, unsigned short& wOffencerMPHeal, unsigned short& wDefenserMPHeal, unsigned short &wError); class CProcessTable : public CSingleton { public: struct ProcessInfo { unsigned short m_usSkill_ID; Skill::FnProcess m_fnProcess; Skill::ProtoType* m_lpProtoType; static Skill::ProtoType m_NullProtoType; ProcessInfo() : m_usSkill_ID(0), m_fnProcess(NULL), m_lpProtoType(&m_NullProtoType) { } ProcessInfo(unsigned short usSkill_ID, Skill::FnProcess fnProcess, Skill::ProtoType* lpProtoType) : m_usSkill_ID(usSkill_ID), m_fnProcess(fnProcess), m_lpProtoType(lpProtoType) { } inline bool operator < (const ProcessInfo& rhs) const { return (m_usSkill_ID < rhs.m_usSkill_ID); } }; typedef std::vector ProcessVector; bool Initialize(); bool InsertSkill(Skill::CProcessTable::ProcessVector& processVector, unsigned short usSkill_ID, FnProcess fnProcess); const ProcessInfo* GetProcessInfo(unsigned short usSkill_ID); inline unsigned short UseSkill(AtType attackType, CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, unsigned char &cOffencerJudge, unsigned char &cDefenserJudge, unsigned short& wOffencerMPHeal, unsigned short& wDefenserMPHeal, unsigned short &wError) { const ProcessInfo* lpProcessInfo = GetProcessInfo(attackType.m_wType); if (NULL == lpProcessInfo) return 0; char cLockCount = CSkillMgr::MAX_SKILL_LOCKCOUNT; if(lpProcessInfo->m_lpProtoType->m_eSkillType == Skill::Type::ITEM) cLockCount = 7; if (attackType.m_cSkillLockCount >= cLockCount || attackType.m_cSkillLevel > CSkillMgr::MAX_SKILL_LEVEL) { unsigned long dwCID = (NULL != lpSkillUser) ? lpSkillUser->GetCID() : 0; ERRLOG3(g_Log, "CID:0x%08x À߸øµÈ ¶ôÄ«¿îÆ®/·¹º§ÀÇ ½ºÅ³À» »ç¿ëÇÏ·Á ÇÕ´Ï´Ù. LockCount:%d, Level:%d", dwCID, attackType.m_cSkillLockCount, attackType.m_cSkillLevel); } else { return lpProcessInfo->m_fnProcess(lpProcessInfo->m_lpProtoType[attackType.m_cSkillLockCount], attackType, lpSkillUser, lpVictim, cOffencerJudge, cDefenserJudge, wOffencerMPHeal, wDefenserMPHeal, wError); } return 0; } private: CProcessTable(); ~CProcessTable(); unsigned short m_usProcessInfo; ProcessInfo* m_fnProcessTable; static CProcessTable ms_this; }; class CFunctions { public: static short ConsumeMP(AtType attackType, CAggresiveCreature* lpSkillUser, unsigned char cOffencerJudge); protected: // ÇÔ¼ö Å×À̺íÀ» ÅëÇØ¼­¸¸ È£ÃâÇÒ ¼ö ÀÖµµ·Ï ÇÑ´Ù. enum Const { VarCastMeeleEnchantLevelMultiplier = 4 }; friend class CProcessTable; // ÆÐ½Ãºê ½ºÅ³ : ¸®Åϰª - ÀÏ´ÜÀº 0; // ÀνºÅϽº ½ºÅ³ : ¸®Åϰª - Victim¿¡°Ô ÀÔÈù ´ë¹ÌÁö // ij½ºÆ® ½ºÅ³ : ¸®Åϰª - Victim¿¡°Ô ÀÔÈù ´ë¹ÌÁö static inline bool CheckChantOff(unsigned char cSkillLockCount, unsigned char cSkillLevel); static inline bool SlowlySkillAttack(const Skill::ProtoType& ProtoType, AtType attackType, CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim); // ------------------------------------------------------------------------------------------------------------ // ±âȹ Ãø¿¡¼­ »ç¿ëÇÏ´Â ¿ë¾î/¼ö½ÄÀ» ±¸ÇöÇÑ ÇÔ¼öµé // ¶ôÄ«¿îÆ® static inline const unsigned short GetSkillLockCount(CAggresiveCreature* lpSkillUser, AtType attackType); // ¿¤¸®Æ®, ·¹º§°¸ static inline const float LevelFactor(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim); // ¼º°ø È®·ü static inline const unsigned short SuccessHitRate(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, float fFactor); // ¼º°ø È®·ü static inline const unsigned short SuccessRate(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, float fFactor); // ÀνºÅϽº ¸¶¹ý µ¥¹ÌÁö static inline const unsigned short InstanceMagicDamage(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, AtType attackType, unsigned char cFactor); // ÀνºÅϽº Àû´ë ÀÎæƮ static inline const unsigned long InstanceEnemyEnchantTick(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, AtType attackType, float fFactor); // ÀνºÅϽº ¸¶¹ý ȸº¹ static inline const unsigned short InstanceMagicRegen(CAggresiveCreature* lpSkillUser, AtType attackType, unsigned char cFactor); // ij½ºÆ® ¸¶¹ý µ¥¹ÌÁö static inline const unsigned short CastMagicDamage(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, AtType attackType, unsigned char cFactor); // ±×¸®½º ÀÎæƮ static inline const unsigned long CastEnchantTick(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, AtType attackType, float fFactor); // ij½ºÆ® ÀÎæƮ static inline const unsigned short CastEnchantLevel(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, AtType attackType, float fFactor); // ¹Ð¸® ÄɽºÆ® ÀÎæƮ static inline const unsigned short CastMeelsEnchantLevel(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, AtType attackType, float fFactor); // ij½ºÆ® ¸¶¹ý ȸº¹ static inline const unsigned short CastMagicRegen(CAggresiveCreature* lpSkillUser, AtType attackType, unsigned char cFactor); // æƮ °ø½Ä static inline const unsigned short ChantLevel(CAggresiveCreature* lpSkillUser, AtType attackType, unsigned char cFactor); // ȸº¹·ù ¾ÆÀÌÅÛÀÇ HP, MP Àý´ë°ª ¸®ÅÏ ÇÔ¼ö static inline const unsigned short PotionHPValue(unsigned char cPercent); static inline const unsigned short PotionMPValue(unsigned char cPercent); // ------------------------------------------------------------------------------------------------------------ // 3Â÷ ¹ë·±½º ÆÐÄ¡ °ü·Ã ÇÔ¼ö // ÀνºÅϽº ¹Ð¸® ȸº¹ static inline const unsigned short InstanceMeleeRegen(CAggresiveCreature* lpSkillUser, AtType attackType, unsigned char cFactor); // ij½ºÆ® ¹Ð¸® ȸº¹ static inline const unsigned short CastMeleeRegen(CAggresiveCreature* lpSkillUser, AtType attackType, unsigned char cFactor); // ¹Ð¸® æƮ °ø½Ä static inline const unsigned short MeleeChantLevel(CAggresiveCreature* lpSkillUser, AtType attackType, unsigned char cFactor); // ij½ºÆ® ÀÎæƮ ½ºÅ³ ·¹º§ static inline const unsigned short CastEnchantSkillLevel(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, AtType attackType, float fFactor1, float fFactor2 = 1.0f, float fFactor3 = 0.0f); // ------------------------------------------------------------------------------------------------------------ #define DECLARE_SKILL(SpellName) \ static unsigned short SpellName(const Skill::ProtoType& ProtoType, AtType attackType, CAggresiveCreature* lpSkillUser, \ CAggresiveCreature* lpVictim, unsigned char &cOffencerJudge, unsigned char &cDefenserJudge, \ unsigned short& wOffencerMPHeal, unsigned short& wDefenserMPHeal, unsigned short &wError) #define DEFINE_SKILL(SpellName) \ unsigned short Skill::CFunctions::##SpellName(const Skill::ProtoType& ProtoType, AtType attackType, \ CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, \ unsigned char &cOffencerJudge, unsigned char &cDefenserJudge, \ unsigned short& wOffencerMPHeal, unsigned short& wDefenserMPHeal, unsigned short &wError) // ¼Ò¼³¸ð¼Ç DECLARE_SKILL(SocialMotion); // ÆÄÀÌÅÍ DECLARE_SKILL(Net); DECLARE_SKILL(SwordMastery); DECLARE_SKILL(AxeMastery); DECLARE_SKILL(HardHit); DECLARE_SKILL(BluntMastery); DECLARE_SKILL(WillPower); DECLARE_SKILL(Toughness); // ·Î±× DECLARE_SKILL(Detection); DECLARE_SKILL(ImprovedCritical); DECLARE_SKILL(Evasion); DECLARE_SKILL(NeedleSpit); // ¸ÞÀÌÁö DECLARE_SKILL(BloodyMana); DECLARE_SKILL(VampiricTouch); DECLARE_SKILL(ManaShell); DECLARE_SKILL(Grease); DECLARE_SKILL(Serenity); // ¾îÄݶóÀÌÆ® DECLARE_SKILL(Purification); DECLARE_SKILL(Faith); DECLARE_SKILL(Encourage); DECLARE_SKILL(FirstAid); DECLARE_SKILL(HammerOfLight); // µðÆæ´õ DECLARE_SKILL(Charging); DECLARE_SKILL(SharedPain); DECLARE_SKILL(FullSwing); // ¿ö¸®¾î DECLARE_SKILL(Blaze); DECLARE_SKILL(BattleSong); DECLARE_SKILL(ChainAction); DECLARE_SKILL(DualWieldMastery); DECLARE_SKILL(CounterAttack); DECLARE_SKILL(CounterAttackMotion); // ¾î½Ø½Å DECLARE_SKILL(BackStab); DECLARE_SKILL(Stealth); DECLARE_SKILL(DaggerMastery); DECLARE_SKILL(BombSet); DECLARE_SKILL(Explosion); DECLARE_SKILL(StealHand); // ¾ÆÃ³ DECLARE_SKILL(AimedShot); DECLARE_SKILL(DualShot); DECLARE_SKILL(Camouflage); DECLARE_SKILL(Accuracy); // ¼Ò¼­·¯ DECLARE_SKILL(Recall); DECLARE_SKILL(FireBolt); DECLARE_SKILL(LightningArrow); DECLARE_SKILL(FrostBolt); DECLARE_SKILL(DeathRay); DECLARE_SKILL(FreshToStone); // ¿£ÂùÅÍ DECLARE_SKILL(Disenchant); DECLARE_SKILL(Entangle); DECLARE_SKILL(LowerStrength); DECLARE_SKILL(EnchantWeapon); DECLARE_SKILL(Shatter); // ÇÁ¸®½ºÆ® DECLARE_SKILL(Resurrection); DECLARE_SKILL(MaintenanceChant); DECLARE_SKILL(AccelerationChant); DECLARE_SKILL(BrightArmor); DECLARE_SKILL(ManaFlow); DECLARE_SKILL(ManaBurn); // Ŭ·¹¸¯ DECLARE_SKILL(Dazzle); DECLARE_SKILL(CureWounds); DECLARE_SKILL(WoundsCrafting); DECLARE_SKILL(CureLight); DECLARE_SKILL(WoundsMake); DECLARE_SKILL(Regeneration); // ÄĹèÅÏÆ® DECLARE_SKILL(CrusherMastery); DECLARE_SKILL(BladeMastery); DECLARE_SKILL(SplitLife); DECLARE_SKILL(ExtraLife); // ¿ÀÇǼ¼ÀÌÅÍ DECLARE_SKILL(Dispel); DECLARE_SKILL(MagicMissile); DECLARE_SKILL(Flexibility); DECLARE_SKILL(ClawMastery); DECLARE_SKILL(LifeAura); DECLARE_SKILL(InnerSight); // ÅÛÇ÷¯ DECLARE_SKILL(Guard); DECLARE_SKILL(HardenSkin); DECLARE_SKILL(FastHit); DECLARE_SKILL(ManaConvert); // ¾îÅÂÄ¿ DECLARE_SKILL(PowerDrain); DECLARE_SKILL(SkillArmFight); DECLARE_SKILL(RingGeyser); // °Å³Ê DECLARE_SKILL(FireRing); DECLARE_SKILL(Blast); // ·é¿ÀÇÁ DECLARE_SKILL(Rot); DECLARE_SKILL(Shock); DECLARE_SKILL(Shackle); DECLARE_SKILL(Crevice); DECLARE_SKILL(SummonKindling); // ¶óÀÌÇÁ¿ÀÇÁ DECLARE_SKILL(Flash); // ½¦µµ¿ì¿ÀÇÁ DECLARE_SKILL(WoundsBlast); DECLARE_SKILL(DaggerFire); DECLARE_SKILL(Envenom); // ȸº¹ ¾ÆÀÌÅÛ DECLARE_SKILL(UseFood); // DECLARE_SKILL(UseFoodPer); DECLARE_SKILL(UseDrink); // DECLARE_SKILL(UseDrinkPer); DECLARE_SKILL(UseFusionFood); // DECLARE_SKILL(UseFusionFoodPer); // DECLARE_SKILL(UseHealPotion); DECLARE_SKILL(UseHealPotionPer); // DECLARE_SKILL(UseManaPotion); DECLARE_SKILL(UseManaPotionPer); // DECLARE_SKILL(UseRefreshPotion); DECLARE_SKILL(UseRefreshPotionPer); // ¹öÇÁÆ÷¼Ç // DECLARE_SKILL(DemagePotion); DECLARE_SKILL(DemagePotionPer); // DECLARE_SKILL(ArmorPotion); DECLARE_SKILL(ArmorPotionPer); // DECLARE_SKILL(HitRatePotion); DECLARE_SKILL(HitRatePotionPer); // DECLARE_SKILL(EvadePotion); DECLARE_SKILL(EvadePotionPer); // DECLARE_SKILL(MaxHPPotion); DECLARE_SKILL(MaxHPPotionPer); // DECLARE_SKILL(MaxMPPotion); DECLARE_SKILL(MaxMPPotionPer); // DECLARE_SKILL(HPRegenPotion); // DECLARE_SKILL(HPRegenPotionPer); // DECLARE_SKILL(MPRegenPotion); // DECLARE_SKILL(MPRegenPotionPer); // DECLARE_SKILL(CriticalPotion); DECLARE_SKILL(CriticalPotionPer); // DECLARE_SKILL(BlockPotion); DECLARE_SKILL(BlockPotionPer); // DECLARE_SKILL(SpeedPotion); DECLARE_SKILL(SpeedPotionPer); // DECLARE_SKILL(DeCoolDownPotion); DECLARE_SKILL(DeCoolDownPotionPer); // DECLARE_SKILL(MagicPowerPotion); DECLARE_SKILL(MagicPowerPotionPer); // DECLARE_SKILL(MagicResistPotion); DECLARE_SKILL(MagicResistPotionPer); DECLARE_SKILL(ConcentrationPotionPer); DECLARE_SKILL(FireCracker); DECLARE_SKILL(ChinaFireCracker); DECLARE_SKILL(Drunk); DECLARE_SKILL(LuckyExpOrb); DECLARE_SKILL(MichaelBless); DECLARE_SKILL(ExpOrb); DECLARE_SKILL(LuckyOrb); DECLARE_SKILL(AntidotePotion); DECLARE_SKILL(AntiFreeze); DECLARE_SKILL(AntiFire); DECLARE_SKILL(Gather); // °ø¼º ¿ÀºêÁ§Æ® ½ºÅ³ DECLARE_SKILL(SRSAAttack); DECLARE_SKILL(LRSAAttack); DECLARE_SKILL(SRCAAttack); DECLARE_SKILL(LRCAAttack); DECLARE_SKILL(GuardAttack); DECLARE_SKILL(EmblemAttack); DECLARE_SKILL(CampAttack); DECLARE_SKILL(EmblemNewAttack); }; // ½ºÅÚ½º ½ÃųÀΰ¡? static inline bool IsStealthSkill(unsigned short wSkillID); }; inline const float Skill::CFunctions::LevelFactor(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim) { return lpSkillUser->CalculateLevelGapAffect(lpVictim); } inline const unsigned short Skill::CFunctions::SuccessHitRate(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, float fFactor) { return static_cast((lpSkillUser->GetStatus().m_StatusInfo.m_wHitRate * fFactor / (lpSkillUser->GetStatus().m_StatusInfo.m_wHitRate * fFactor + lpVictim->GetStatus().m_StatusInfo.m_wEvade)) * 100); } inline const unsigned short Skill::CFunctions::SuccessRate(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, float fFactor) { return static_cast((lpSkillUser->GetStatus().m_StatusInfo.m_wMagicPower * fFactor / (lpSkillUser->GetStatus().m_StatusInfo.m_wMagicPower * fFactor + lpVictim->GetStatus().m_StatusInfo.m_fMagicResistRate)) * 100); } inline const unsigned short Skill::CFunctions::InstanceMagicDamage(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, AtType attackType, unsigned char cFactor) { long lDamage = static_cast((attackType.m_cSkillLevel + attackType.m_cSkillLockCount * 6) * cFactor * (75 + Math::Random::ComplexRandom(75) + lpSkillUser->GetStatus().m_StatusInfo.m_wMagicPower) / 100.0f * (100 - lpVictim->GetStatus().m_StatusInfo.m_fMagicResistRate) / 100.0f * LevelFactor(lpSkillUser, lpVictim)); return static_cast(min(lDamage, USHRT_MAX)); } inline const unsigned long Skill::CFunctions::InstanceEnemyEnchantTick(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, AtType attackType, float fFactor) { return static_cast((attackType.m_cSkillLevel + attackType.m_cSkillLockCount * 6) * fFactor * LevelFactor(lpSkillUser, lpVictim)); } inline const unsigned short Skill::CFunctions::InstanceMagicRegen(CAggresiveCreature* lpSkillUser, AtType attackType, unsigned char cFactor) { return static_cast((attackType.m_cSkillLevel + attackType.m_cSkillLockCount * 6) * cFactor * (50 + Math::Random::ComplexRandom(50) + lpSkillUser->GetStatus().m_StatusInfo.m_wMagicPower) / 100.0f); } inline const unsigned short Skill::CFunctions::CastMagicDamage(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, AtType attackType, unsigned char cFactor) { const unsigned short wLockCount = GetSkillLockCount(lpSkillUser, attackType); long lDamage = static_cast(((wLockCount + 1) * attackType.m_cSkillLevel + 1 + attackType.m_cSkillLockCount * wLockCount * 5) * cFactor * (75 + Math::Random::ComplexRandom(75) + lpSkillUser->GetStatus().m_StatusInfo.m_wMagicPower) / 100.0f * (100 - lpVictim->GetStatus().m_StatusInfo.m_fMagicResistRate) / 100.0f * LevelFactor(lpSkillUser, lpVictim)); return static_cast(min(lDamage, USHRT_MAX)); } inline const unsigned long Skill::CFunctions::CastEnchantTick(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, AtType attackType, float fFactor) { return static_cast((GetSkillLockCount(lpSkillUser, attackType) + attackType.m_cSkillLevel + attackType.m_cSkillLockCount * 2) * fFactor * LevelFactor(lpSkillUser, lpVictim)); } inline const unsigned short Skill::CFunctions::CastEnchantLevel(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, AtType attackType, float fFactor) { unsigned short wFirstCase = static_cast(((GetSkillLockCount(lpSkillUser, attackType) + 1) * attackType.m_cSkillLevel + attackType.m_cSkillLockCount * GetSkillLockCount(lpSkillUser, attackType)) * fFactor * (100 + lpSkillUser->GetStatus().m_StatusInfo.m_wMagicPower) / 100.0f); unsigned short wSecondCase = static_cast(lpVictim->GetStatus().m_nLevel * 3 * fFactor); return min(wFirstCase, wSecondCase); } inline const unsigned short Skill::CFunctions::CastMeelsEnchantLevel(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, AtType attackType, float fFactor) { unsigned short wFirstCase = static_cast(((GetSkillLockCount(lpSkillUser, attackType) + 1) * attackType.m_cSkillLevel + attackType.m_cSkillLockCount * GetSkillLockCount(lpSkillUser, attackType)) * fFactor * (VarCastMeeleEnchantLevelMultiplier + GetSkillLockCount(lpSkillUser, attackType))); unsigned short wSecondCase = static_cast(lpVictim->GetStatus().m_nLevel * 3 * fFactor); return min(wFirstCase, wSecondCase); } inline const unsigned short Skill::CFunctions::CastMagicRegen(CAggresiveCreature* lpSkillUser, AtType attackType, unsigned char cFactor) { return static_cast(((GetSkillLockCount(lpSkillUser, attackType) + 1) * attackType.m_cSkillLevel + 1 + attackType.m_cSkillLockCount * GetSkillLockCount(lpSkillUser, attackType) * 5) * cFactor * (50 + Math::Random::ComplexRandom(50) + lpSkillUser->GetStatus().m_StatusInfo.m_wMagicPower) / 100.0f); } inline const unsigned short Skill::CFunctions::PotionHPValue(unsigned char cPercent) { switch (cPercent) { case 10: return 1000; case 20: return 3000; case 30: return 5000; case 40: return 6000; case 50: return 7000; case 60: return 8000; case 80: return 10000; } return 0; } inline const unsigned short Skill::CFunctions::PotionMPValue(unsigned char cPercent) { switch (cPercent) { case 5: return 500; case 10: return 1000; case 15: return 2000; case 20: return 3000; case 30: return 4000; case 45: return 6000; case 60: return 8000; } return 0; } inline const unsigned short Skill::CFunctions::ChantLevel(CAggresiveCreature* lpSkillUser, AtType attackType, unsigned char cFactor) { return static_cast((attackType.m_cSkillLevel + attackType.m_cSkillLockCount * 6) * cFactor * (100 + lpSkillUser->GetStatus().m_StatusInfo.m_wMagicPower) / 100.0f); } inline const unsigned short Skill::CFunctions::GetSkillLockCount(CAggresiveCreature* lpSkillUser, AtType attackType) { unsigned short wLockCount = 0; Creature::CreatureType eCreatureType = Creature::GetCreatureType(lpSkillUser->GetCID()); if (Creature::CT_MONSTER == eCreatureType || Creature::CT_SUMMON == eCreatureType || Creature::CT_STRUCT == eCreatureType) { wLockCount = attackType.m_cSkillLockCount; } else { wLockCount = lpSkillUser->GetSkillLockCount(attackType.m_wType); } if (wLockCount < 0 || wLockCount >= CSkillMgr::MAX_SKILL_LOCKCOUNT) { ERRLOG3(g_Log, "CID:0x%08x ¾²·Á´Â ½ºÅ³ÀÇ ¶ôÄ«¿îÆ®°¡ ÀÌ»óÇÕ´Ï´Ù. SkillType : 0x%04x, LockCount : %d", lpSkillUser->GetCID(), attackType.m_wType, wLockCount); return 0; } return wLockCount; } inline bool Skill::CFunctions::CheckChantOff(unsigned char cSkillLockCount, unsigned char cSkillLevel) { return (0 == cSkillLockCount && 0 == cSkillLevel) ? true : false; } inline bool Skill::CFunctions::SlowlySkillAttack(const Skill::ProtoType& ProtoType, AtType attackType, CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim) { unsigned short wLockCount = GetSkillLockCount(lpSkillUser, attackType); unsigned short wEnchantLevel = attackType.m_cSkillLevel + wLockCount * 6; unsigned long dwDurationSec = static_cast( (attackType.m_cSkillLevel + wLockCount * 6) * 0.5f * LevelFactor(lpSkillUser, lpVictim)); unsigned short wResult = CAddSpell(CSpell::Spell_Info(ProtoType, lpSkillUser, SpellType::MAGICAL_SPELL, SpellID::Slow, wEnchantLevel, dwDurationSec))(lpVictim); return (wResult == CSpell::ENCHANT_FAIL_BY_ENEMY_ENCHANT) ? false : true; } inline bool Skill::IsStealthSkill(unsigned short wSkillID) { switch (wSkillID) { case 0x8704: // ½ºÅÚ½º (¾î½Ø) case 0x9804: // ½ºÅÚ½º (½¦¿É) case 0x8805: // ij¸ðÇöóÁã (¾ÆÃ³) case 0x9504: // ij¸ðÇöóÁã (°Å³Ê) return true; } return false; } // ------------------------------------------------------------------------------------------------------------ // 3Â÷ ¹ë·±½º ÆÐÄ¡ °ü·Ã ÇÔ¼ö inline const unsigned short Skill::CFunctions::InstanceMeleeRegen(CAggresiveCreature* lpSkillUser, AtType attackType, unsigned char cFactor) { return static_cast((attackType.m_cSkillLevel + attackType.m_cSkillLockCount * 6) * cFactor * (50 + Math::Random::ComplexRandom(50) + (attackType.m_cSkillLevel + attackType.m_cSkillLockCount * 6) * 25) / 100.0f); } inline const unsigned short Skill::CFunctions::CastMeleeRegen(CAggresiveCreature* lpSkillUser, AtType attackType, unsigned char cFactor) { return static_cast(((GetSkillLockCount(lpSkillUser, attackType) + 1) * attackType.m_cSkillLevel + 1 + attackType.m_cSkillLockCount * GetSkillLockCount(lpSkillUser, attackType) * 5) * cFactor * (50 + Math::Random::ComplexRandom(50) + GetSkillLockCount(lpSkillUser, attackType) * 100) / 100.0f); } inline const unsigned short Skill::CFunctions::MeleeChantLevel(CAggresiveCreature* lpSkillUser, AtType attackType, unsigned char cFactor) { return static_cast((attackType.m_cSkillLevel + attackType.m_cSkillLockCount * 6) * cFactor * (100 + (attackType.m_cSkillLevel + attackType.m_cSkillLockCount * 6) * 31) / 100.0f); } inline const unsigned short Skill::CFunctions::CastEnchantSkillLevel(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, AtType attackType, float fFactor1, float fFactor2, float fFactor3) { unsigned short wFirstCase = static_cast((((GetSkillLockCount(lpSkillUser, attackType) + 1) * attackType.m_cSkillLevel + attackType.m_cSkillLockCount * GetSkillLockCount(lpSkillUser, attackType)) * fFactor1 * (GetSkillLockCount(lpSkillUser, attackType) + 4) * fFactor2) + fFactor3); unsigned short wSecondCase = static_cast(lpVictim->GetStatus().m_nLevel * 3 * fFactor1); return min(wFirstCase, wSecondCase); } #endif