#include "stdafx.h" #include "./CommonCharacterFormula.h" #include #include "NumericValues.h" //================================================================================================== namespace ns_formula { ; // internal interfaces static float CalcHPRatioNum(DWORD partymemberNum); static float CalcAdditionalHPRatio(DWORD partymemberNum); // //================================================================================================== static ns_formula::SkillAttackPowerBalanceConstants kSkillAttackPowerConstants = { // ratio_of_conversion #ifdef _NA_008486_20150914_TOTAL_BALANCE { 0.0f, // eCHAR_NONE 90.0f, // eCHAR_BERSERKER 90.0f, // eCHAR_DRAGON 90.0f, // eCHAR_SHADOW 90.0f, // eCHAR_VALKYRIE 90.0f, // eCHAR_ELEMENTALIST 90.0f, // eCHAR_MYSTIC 90.0f, // eCHAR_HELLROID 90.0f, // eCHAR_WITCHBLADE }, #else { 0.0f, // eCHAR_NONE 90.0f, // eCHAR_BERSERKER 80.0f, // eCHAR_DRAGON 70.0f, // eCHAR_SHADOW 60.0f, // eCHAR_VALKYRIE 50.0f, // eCHAR_ELEMENTALIST 80.0f, // eCHAR_MYSTIC 90.0f, // eCHAR_HELLROID 90.0f, // eCHAR_WITCHBLADE }, #endif //_NA_008486_20150914_TOTAL_BALANCE }; static ns_formula::CriticalBalanceConstants kCriticalChanceConstants = { #ifdef _NA_008486_20150914_TOTAL_BALANCE 60.0f, // kNumberatorWeight #else 5.0f, // kNumberatorWeight #endif //_NA_008486_20150914_TOTAL_BALANCE 100.0f, // kDenominatorWeight // base_probabilies { 0.0f, // eCHAR_NONE 0.8f, // eCHAR_BERSERKER 1.7f, // eCHAR_DRAGON 1.2f, // eCHAR_SHADOW 1.0f, // eCHAR_VALKYRIE 0.2f, // eCHAR_ELEMENTALIST 1.5f, // eCHAR_MYSTIC 0.8f, // eCHAR_HELLROID 1.0f, // eCHAR_WITCHBLADE }, }; static ns_formula::AttackRateConstants kAttackRateConstants = { 1.0f, #ifdef _NA_008486_20150914_TOTAL_BALANCE { 6.0f, // eCHAR_NONE 6.0f, // eCHAR_BERSERKER 6.0f, // eCHAR_DRAGON 6.0f, // eCHAR_SHADOW 6.0f, // eCHAR_VALKYRIE 6.0f, // eCHAR_ELEMENTALIST 6.0f, // eCHAR_MYSTIC 6.0f, // eCHAR_HELLROID 6.0f, // eCHAR_WITCHBLADE }, #else { 4.0f, // eCHAR_NONE 4.0f, // eCHAR_BERSERKER 4.0f, // eCHAR_DRAGON 4.0f, // eCHAR_SHADOW 4.0f, // eCHAR_VALKYRIE 4.0f, // eCHAR_ELEMENTALIST 4.0f, // eCHAR_MYSTIC 4.0f, // eCHAR_HELLROID 4.0f, // eCHAR_WITCHBLADE }, #endif //_NA_008486_20150914_TOTAL_BALANCE }; static ns_formula::AttackAvoidRateConstants kAttackAvoidRateConstants = { 0.2f, #ifdef _NA_008486_20150914_TOTAL_BALANCE { 0.0f, // eCHAR_NONE 5.0f, // eCHAR_BERSERKER 5.0f, // eCHAR_DRAGON 5.0f, // eCHAR_SHADOW 5.0f, // eCHAR_VALKYRIE 5.0f, // eCHAR_ELEMENTALIST 5.0f, // eCHAR_MYSTIC 5.0f, // eCHAR_HELLROID 5.0f, // eCHAR_WITCHBLADE }, #else { 0.0f, // eCHAR_NONE 8.0f, // eCHAR_BERSERKER 8.0f, // eCHAR_DRAGON 8.0f, // eCHAR_SHADOW 5.0f, // eCHAR_VALKYRIE 5.0f, // eCHAR_ELEMENTALIST 6.0f, // eCHAR_MYSTIC 8.0f, // eCHAR_HELLROID 6.0f, // eCHAR_WITCHBLADE }, #endif //_NA_008486_20150914_TOTAL_BALANCE }; extern const double& AttackRateConstants_EquipmentWeight = kAttackRateConstants.kEquipmentWeight; extern const double& AttackAvoidRateConstants_EquipmentWeight = kAttackAvoidRateConstants.kEquipmentWeight; //================================================================================================== void ns_formula::BalanceConstantsChangerInProgramCommon::GetSkillAttackPower( SkillAttackPowerBalanceConstants* const constants) { *constants = ns_formula::kSkillAttackPowerConstants; } void ns_formula::BalanceConstantsChangerInProgramCommon::ModifySkillAttackPower( const SkillAttackPowerBalanceConstants& constants) { SkillAttackPowerBalanceConstants modified = constants; modified.ratio_of_conversion[eCHAR_NONE] = 0.0f; // > 0.0f if (modified.ratio_of_conversion[eCHAR_BERSERKER] < 0.0f) { modified.ratio_of_conversion[eCHAR_BERSERKER] = 90.0f; }; if (modified.ratio_of_conversion[eCHAR_DRAGON] < 0.0f) { modified.ratio_of_conversion[eCHAR_DRAGON] = 80.0f; }; if (modified.ratio_of_conversion[eCHAR_SHADOW] < 0.0f) { modified.ratio_of_conversion[eCHAR_SHADOW] = 70.0f; }; if (modified.ratio_of_conversion[eCHAR_VALKYRIE] < 0.0f) { modified.ratio_of_conversion[eCHAR_VALKYRIE] = 60.0f; }; if (modified.ratio_of_conversion[eCHAR_ELEMENTALIST] < 0.0f) { modified.ratio_of_conversion[eCHAR_ELEMENTALIST] = 50.0f; }; // _NA_004965_20120613_NEW_CHARACTER_MYSTIC if (modified.ratio_of_conversion[eCHAR_MYSTIC] < 0.0f) { modified.ratio_of_conversion[eCHAR_MYSTIC] = 70.0f; } // _NA_000000_20130812_NEW_CHARACTER_HELLROID if (modified.ratio_of_conversion[eCHAR_HELLROID] < 0.0f) { modified.ratio_of_conversion[eCHAR_HELLROID] = 90.0f; } //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE if (modified.ratio_of_conversion[eCHAR_WITCHBLADE] < 0.0f) { modified.ratio_of_conversion[eCHAR_WITCHBLADE] = 80.0f; } ns_formula::kSkillAttackPowerConstants = modified; return; } void ns_formula::BalanceConstantsChangerInProgramCommon::GetCriticalChance( CriticalBalanceConstants* const constants) { *constants = ns_formula::kCriticalChanceConstants; } void ns_formula::BalanceConstantsChangerInProgramCommon::ModifyCriticalChance( const CriticalBalanceConstants& constants) { CriticalBalanceConstants modified = constants; // > 0.0f /* NOTE: it's dangerous if the below code was opened. if (modified.kNumberatorWeight <= 0.0f) { modified.kNumberatorWeight = 3.0f; }; if (modified.kDenominatorWeight <= 0.0f) { modified.kDenominatorWeight = 5.0f; }; */ modified.base_probabilies[eCHAR_NONE] = 0.0f; if (modified.base_probabilies[eCHAR_BERSERKER] < 0.0f) { modified.base_probabilies[eCHAR_BERSERKER] = 1.7f; }; if (modified.base_probabilies[eCHAR_DRAGON] < 0.0f) { modified.base_probabilies[eCHAR_DRAGON] = 3.3f; }; if (modified.base_probabilies[eCHAR_SHADOW] < 0.0f) { modified.base_probabilies[eCHAR_SHADOW] = 2.3f; }; if (modified.base_probabilies[eCHAR_VALKYRIE] < 0.0f) { modified.base_probabilies[eCHAR_VALKYRIE] = 2.0f; }; if (modified.base_probabilies[eCHAR_ELEMENTALIST] < 0.0f) { modified.base_probabilies[eCHAR_ELEMENTALIST] = 0.3f; }; // _NA_004965_20120613_NEW_CHARACTER_MYSTIC if (modified.base_probabilies[eCHAR_MYSTIC] < 0.0f) { modified.base_probabilies[eCHAR_MYSTIC] = 2.3f; }; // _NA_000000_20130812_NEW_CHARACTER_HELLROID if (modified.base_probabilies[eCHAR_HELLROID] < 0.0f) { modified.base_probabilies[eCHAR_HELLROID] = 0.8f; }; //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE if (modified.base_probabilies[eCHAR_WITCHBLADE] < 0.0f) { modified.base_probabilies[eCHAR_WITCHBLADE] = 1.0f; }; ns_formula::kCriticalChanceConstants = modified; return; } void ns_formula::BalanceConstantsChangerInProgramCommon::GetAttackRate( AttackRateConstants* const constants) { *constants = ns_formula::kAttackRateConstants; } void ns_formula::BalanceConstantsChangerInProgramCommon::ModifyAttackRate( const AttackRateConstants& constants) { AttackRateConstants modified = constants; if (modified.kEquipmentWeight < 0.0f) { modified.kEquipmentWeight = 1.0f; } modified.ratio_of_conversion[eCHAR_NONE] = 0.0f; if (modified.ratio_of_conversion[eCHAR_BERSERKER] < 0.0f) { modified.ratio_of_conversion[eCHAR_BERSERKER] = 4.0f; }; if (modified.ratio_of_conversion[eCHAR_DRAGON] < 0.0f) { modified.ratio_of_conversion[eCHAR_DRAGON] = 4.0f; }; if (modified.ratio_of_conversion[eCHAR_SHADOW] < 0.0f) { modified.ratio_of_conversion[eCHAR_SHADOW] = 4.0f; }; if (modified.ratio_of_conversion[eCHAR_VALKYRIE] < 0.0f) { modified.ratio_of_conversion[eCHAR_VALKYRIE] = 4.0f; }; if (modified.ratio_of_conversion[eCHAR_ELEMENTALIST] < 0.0f) { modified.ratio_of_conversion[eCHAR_ELEMENTALIST] = 4.0f; }; // _NA_004965_20120613_NEW_CHARACTER_MYSTIC if (modified.ratio_of_conversion[eCHAR_MYSTIC] < 0.0f) { modified.ratio_of_conversion[eCHAR_MYSTIC] = 4.0f; }; //_NA_000000_20130812_NEW_CHARACTER_HELLROID if (modified.ratio_of_conversion[eCHAR_HELLROID] < 0.0f) { modified.ratio_of_conversion[eCHAR_HELLROID] = 4.0f; }; //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE if (modified.ratio_of_conversion[eCHAR_WITCHBLADE] < 0.0f) { modified.ratio_of_conversion[eCHAR_WITCHBLADE] = 4.0f; }; ns_formula::kAttackRateConstants = modified; return; } void ns_formula::BalanceConstantsChangerInProgramCommon::GetAttackAvoidRate( AttackAvoidRateConstants* const constants) { *constants = ns_formula::kAttackAvoidRateConstants; } void ns_formula::BalanceConstantsChangerInProgramCommon::ModifyAttackAvoidRate( const AttackAvoidRateConstants& constants) { AttackAvoidRateConstants modified = constants; if (modified.kEquipmentWeight < 0.0f) { modified.kEquipmentWeight = 0.2f; } modified.ratio_of_conversion[eCHAR_NONE] = 0.0f; if (modified.ratio_of_conversion[eCHAR_BERSERKER] < 0.0f) { modified.ratio_of_conversion[eCHAR_BERSERKER] = 8.0f; }; if (modified.ratio_of_conversion[eCHAR_DRAGON] < 0.0f) { modified.ratio_of_conversion[eCHAR_DRAGON] = 8.0f; }; if (modified.ratio_of_conversion[eCHAR_SHADOW] < 0.0f) { modified.ratio_of_conversion[eCHAR_SHADOW] = 8.0f; }; if (modified.ratio_of_conversion[eCHAR_VALKYRIE] < 0.0f) { modified.ratio_of_conversion[eCHAR_VALKYRIE] = 3.5f; }; if (modified.ratio_of_conversion[eCHAR_ELEMENTALIST] < 0.0f) { modified.ratio_of_conversion[eCHAR_ELEMENTALIST] = 16.0f; }; // _NA_004965_20120613_NEW_CHARACTER_MYSTIC if (modified.ratio_of_conversion[eCHAR_MYSTIC] < 0.0f) { modified.ratio_of_conversion[eCHAR_MYSTIC] = 8.0f; } // _NA_000000_20130812_NEW_CHARACTER_HELLROID if (modified.ratio_of_conversion[eCHAR_HELLROID] < 0.0f) { modified.ratio_of_conversion[eCHAR_HELLROID] = 8.0f; } //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE if (modified.ratio_of_conversion[eCHAR_WITCHBLADE] < 0.0f) { modified.ratio_of_conversion[eCHAR_WITCHBLADE] = 7.0f; } ns_formula::kAttackAvoidRateConstants = modified; return; } //================================================================================================== //================================================================================================== //================================================================================================== //================================================================================================== /* #if defined(_NA001605_EP2_ATTRIBUTES_RENEWAL_) && USE_DAMAGE_EXTENTION int ns_formula::DamageEncoder::Fix(int origin_damage) { // 0x0000 // 2bit : 0, 1, 2, 3 // gap : 0 1 4 8 int fixed_damage = origin_damage; if (fixed_damage < 0) { fixed_damage = 0; } else if (fixed_damage > kMaxDamage) { fixed_damage = kMaxDamage; }; // fixed_damage // 4096 - 1 = (fixed_damage < 0x00001000) ? ((fixed_damage)) // 16384 - 1 : (fixed_damage < 0x00004000) ? ((fixed_damage & ~0x1)) // 65536 - 1 : (fixed_damage < 0x00010000) ? ((fixed_damage & ~0x3)) // 262144 - 1 : ((fixed_damage & ~0xF)); return fixed_damage; } DAMAGETYPE ns_formula::DamageEncoder::Encode(int fixed_damage) { assert(fixed_damage >= 0 && fixed_damage <= kMaxDamage); int encode_damage // 4096 - 1 = (fixed_damage < 0x00001000) ? ((fixed_damage)) // 16384 - 1 : (fixed_damage < 0x00004000) ? ((fixed_damage >> 1) | (0x4000)) // 65536 - 1 : (fixed_damage < 0x00010000) ? ((fixed_damage >> 2) | (0x8000)) // 262144 - 1 //(damage < 0x00040000) ? ((fixed_damage >> 4) | (0xC000)) : ((fixed_damage >> 4) | (0xC000)); return static_cast(encode_damage); } int ns_formula::DamageEncoder::Decode(DAMAGETYPE encoded_damage) { int decode_damage // 262144 - 1 = ((encoded_damage & 0xC000) == 0xC000) ? ((encoded_damage & ~0xC000) << 4) // 65536 - 1 : ((encoded_damage & 0x8000) == 0x8000) ? ((encoded_damage & ~0x8000) << 2) // 16384 - 1 : ((encoded_damage & 0x4000) == 0x4000) ? ((encoded_damage & ~0x4000) << 1) // 4096 - 1 : ((encoded_damage)); assert(decode_damage >= 0 && decode_damage <= kMaxDamage); return decode_damage; } #else //if !(defined(_NA001605_EP2_ATTRIBUTES_RENEWAL_) && USE_DAMAGE_EXTENTION) int ns_formula::DamageEncoder::Fix(int origin_damage) { int fixed_damage = origin_damage; if (fixed_damage < 0) { fixed_damage = 0; } else if (fixed_damage > kMaxDamage) { fixed_damage = kMaxDamage; } return fixed_damage; } DAMAGETYPE ns_formula::DamageEncoder::Encode(int fixed_damage) { assert(fixed_damage >= 0 && fixed_damage <= kMaxDamage); return static_cast(fixed_damage); } int ns_formula::DamageEncoder::Decode(DAMAGETYPE encoded_damage) { assert(encoded_damage >= 0 && encoded_damage <= kMaxDamage); return encoded_damage; } #endif */ //================================================================================================== DWORD ns_formula::GetStatPointPerLevel() { return 5; } DWORD ns_formula::GetSkillPoint(LEVELTYPE level) { #ifdef _NA_0_20100901_SKILLTREE_SYSTEM uint temp = level % CHARACTER_SKILL_LEVEL_RATIO; return ((temp == 0) && (level != 0)) ? 1 : 0; #else __UNUSED(level); // current (100221) // i. 1~50LV½Ã »ç¿ë °ø½Ä = (·¹º§/10)+1 (¼Ò¼ö´Â ³»¸²Ã³¸®ÇÑ´Ù.) // ii. 51~135LV½Ã »ç¿ë °ø½Ä = (·¹º§/15)+3 (¼Ò¼ö´Â ³»¸²Ã³¸®ÇÑ´Ù.) // iii. 136~200LV½Ã »ç¿ë °ø½Ä = (·¹º§/20)+5 (¼Ò¼ö´Â ³»¸²Ã³¸®ÇÑ´Ù.) /* if (level<=50) { return level/10 + 1; } else if (level<=135) { return level/15 + 3; } else if (level<=200) { return level/20 + 5; } */ // ·¹º§¾÷½Ã ¹«Á¶°Ç ½ºÅ³Æ÷ÀÎÆ® 1¾¿ ȹµæÇÏ´Â °ÍÀ¸·Î ¼öÁ¤µÊ return 1; #endif } DWORD ns_formula::CalcHP(const eCHAR_TYPE char_type, const LEVELTYPE level, const short in_vitality) { short vitality = in_vitality; if (vitality < 0) { vitality = 0; } #ifdef _NA001605_EP2_ATTRIBUTES_RENEWAL_ switch (char_type) { case eCHAR_BERSERKER: return (DWORD)(200 + (level - 1) * 39.0f + (vitality - 27) * 11.0f); case eCHAR_DRAGON: return (DWORD)(180 + (level - 1) * 26.0f + (vitality - 20) * 9.0f); case eCHAR_SHADOW: return (DWORD)(160 + (level - 1) * 25.0f + (vitality - 16) * 9.0f); case eCHAR_VALKYRIE: return (DWORD)(160 + (level - 1) * 25.0f + (vitality - 15) * 9.0f); case eCHAR_ELEMENTALIST: return (DWORD)(150 + (level - 1) * 23.0f + (vitality - 13) * 7.0f); case eCHAR_MYSTIC: // _NA_004965_20120613_NEW_CHARACTER_MYSTIC return (DWORD)(160 + (level - 1) * 25.0f + (vitality - 15) * 9.0f); case eCHAR_HELLROID: // _NA_000000_20130812_NEW_CHARACTER_HELLROID return (DWORD)(200 + (level - 1) * 39.0f + (vitality - 27) * 12.0f); case eCHAR_WITCHBLADE: // _NA_007514_20140828_NEW_CHARACTER_WITCHBLADE return (DWORD)(180 + (level - 1) * 25.0f + (vitality - 24) * 9.0f); } #else switch (char_type) { case eCHAR_BERSERKER: return (DWORD)(200 + (level - 1) * 30.0f + (vitality - 27) * 10.0f); case eCHAR_DRAGON: return (DWORD)(180 + (level - 1) * 22.0f + (vitality - 20) * 7.0f); case eCHAR_SHADOW: return (DWORD)(160 + (level - 1) * 19.0f + (vitality - 15) * 7.0f); case eCHAR_VALKYRIE: return (DWORD)(160 + (level - 1) * 19.0f + (vitality - 15) * 5.0f); case eCHAR_ELEMENTALIST: return (DWORD)(150 + (level - 1) * 18.0f + (vitality - 13) * 5.0f); case eCHAR_MYSTIC: // _NA_004965_20120613_NEW_CHARACTER_MYSTIC return (DWORD)(160 + (level - 1) * 19.0f + (vitality - 15) * 7.0f); #ifdef _NA_000000_20130812_NEW_CHARACTER_HELLROID case eCHAR_HELLROID: return (DWORD)(200 + (level - 1) * 39.0f + (vitality - 27) * 12.0f); #endif //_NA_000000_20130812_NEW_CHARACTER_HELLROID #ifdef _NA_007514_20140828_NEW_CHARACTER_WITCHBLADE case eCHAR_WITCHBLADE: return (DWORD)(180 + (level - 1) * 25.0f + (vitality - 24) * 9.0f); #endif //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE } #endif SASSERT(false, "Wrong Char_Type in CalcHP()"); return 1; } DWORD ns_formula::CalcMP(const eCHAR_TYPE char_type, const LEVELTYPE level, const short in_spirit) { short spirit = in_spirit; if (spirit < 0) { spirit = 0; } switch (char_type) { case eCHAR_BERSERKER: return (DWORD)( 20 + (level - 1) * 5.0f + (spirit-10) * 2.0f); case eCHAR_DRAGON: return (DWORD)( 25 + (level - 1) * 7.0f + (spirit-12) * 4.0f); case eCHAR_SHADOW: return (DWORD)( 40 + (level - 1) * 8.5f + (spirit-10) * 6.0f); case eCHAR_VALKYRIE: return (DWORD)( 32 + (level - 1) * 8.0f + (spirit-19) * 5.0f); case eCHAR_ELEMENTALIST: return (DWORD)(100 + (level - 1) * 25.0f + spirit * 6.0f); case eCHAR_MYSTIC: // _NA_004965_20120613_NEW_CHARACTER_MYSTIC return (DWORD)(40 + (level - 1) * 8.5f + (spirit - 10) * 6.0f); case eCHAR_HELLROID: //_NA_000000_20130812_NEW_CHARACTER_HELLROID return (DWORD)(100 + (level - 1) * 20.0f + (spirit * 6.0f)); case eCHAR_WITCHBLADE: //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE return (DWORD)(30 + (level - 1) * 7.0f + ((spirit-10) * 4.0f)); } SASSERT(false, "Wrong Char_Type in CalcMP()"); return 1; } // °¢ Äɸ¯ÅÍ SD Point °ø½Ä DWORD ns_formula::CalcSD(eCHAR_TYPE char_type, LEVELTYPE level) { __UNUSED(char_type); float calc = static_cast(level); #ifdef _NA_004010_20120102_1201_SD_FORMULA calc = 200.0f + pow(calc, 3) / (calc * 2); #else calc = 200.0f + (pow(calc, 3) / SDINCREASE_RATIO / calc); #endif if (calc < 0) { return 0; } return static_cast(util::LL_Round(calc)); } // ÃÖ¼Ò °ø°Ý·Â(±Ù°Å¸®) DWORD ns_formula::CalcMinMeleeAttackPower( const eCHAR_TYPE char_type, const short in_strength, const short in_dexterity) { short dexterity = in_dexterity; if (dexterity < 0) { dexterity = 0; } short strength = in_strength; if (strength < 0) { strength = 0; } #ifdef _NA_008486_20150914_TOTAL_BALANCE switch (char_type) { case eCHAR_DRAGON: return (DWORD)(strength / 5); case eCHAR_BERSERKER: return (DWORD)(strength / 6); case eCHAR_SHADOW: return (DWORD)(strength / 8); case eCHAR_VALKYRIE: return (DWORD)(strength / 8); case eCHAR_ELEMENTALIST: return (DWORD)(strength / 9); case eCHAR_MYSTIC: // _NA_004965_20120613_NEW_CHARACTER_MYSTIC return (DWORD)(strength / 9); case eCHAR_HELLROID: //_NA_000000_20130812_NEW_CHARACTER_HELLROID return (DWORD)(strength / 8); case eCHAR_WITCHBLADE: //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE return (DWORD)(strength / 8); } #else switch (char_type) { case eCHAR_DRAGON: return (DWORD)(strength / 5); case eCHAR_BERSERKER: return (DWORD)(strength / 6); case eCHAR_SHADOW: return (DWORD)(strength / 9 + dexterity / 12); case eCHAR_VALKYRIE: return (DWORD)(strength / 8 + dexterity / 10); case eCHAR_ELEMENTALIST: return (DWORD)(strength / 9); case eCHAR_MYSTIC: // _NA_004965_20120613_NEW_CHARACTER_MYSTIC return (DWORD)(strength / 9 + dexterity / 12); case eCHAR_HELLROID: //_NA_000000_20130812_NEW_CHARACTER_HELLROID return (DWORD)(strength / 8); case eCHAR_WITCHBLADE: //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE return (DWORD)(strength / 8 + dexterity / 12); } #endif //_NA_008486_20150914_TOTAL_BALANCE SASSERT(false, "Wrong Char_Type in CalcMP()"); return 1; } #ifdef _NA_007514_20140828_NEW_CHARACTER_WITCHBLADE extern PLAYERFP CalcFP( const eCHAR_TYPE char_type ) { switch (char_type) { case eCHAR_WITCHBLADE: return 10; } return 0; } #endif //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE // ÃÖ¼Ò °ø°Ý·Â(¿ø°Å¸®) DWORD ns_formula::CalcMinRangeAttackPower( const eCHAR_TYPE char_type, const short in_strength, const short in_dexterity) { short dexterity = in_dexterity; if (dexterity < 0) { dexterity = 0; } short strength = in_strength; if (strength < 0) { strength = 0; } switch (char_type) { case eCHAR_DRAGON: case eCHAR_BERSERKER: case eCHAR_ELEMENTALIST: return CalcMinMeleeAttackPower(char_type, strength, dexterity); case eCHAR_SHADOW: return (DWORD)(strength / 8); case eCHAR_VALKYRIE: #ifdef _NA_008486_20150914_TOTAL_BALANCE return (DWORD)(strength / 8); #else return (DWORD)(strength / 8 + dexterity / 10); #endif //_NA_008486_20150914_TOTAL_BALANCE case eCHAR_MYSTIC: // _NA_004965_20120613_NEW_CHARACTER_MYSTIC return (DWORD)(strength / 8); case eCHAR_HELLROID: // _NA_000000_20130812_NEW_CHARACTER_HELLROID return (DWORD)(strength / 8); case eCHAR_WITCHBLADE: // _NA_007514_20140828_NEW_CHARACTER_WITCHBLADE return (DWORD)(strength / 8); } return 1; } // ÃÖ´ë °ø°Ý·Â(±Ù°Å¸®) DWORD ns_formula::CalcMaxMeleeAttackPower( const eCHAR_TYPE char_type, const short in_strength, const short in_dexterity) { short dexterity = in_dexterity; if (dexterity < 0) { dexterity = 0; } short strength = in_strength; if (strength < 0) { strength = 0; } #ifdef _NA_008486_20150914_TOTAL_BALANCE switch (char_type) { case eCHAR_DRAGON: return (DWORD)(strength / 3); case eCHAR_BERSERKER: return (DWORD)(strength / 2); case eCHAR_SHADOW: return (DWORD)(strength / 4); case eCHAR_VALKYRIE: return (DWORD)(strength / 4); case eCHAR_ELEMENTALIST: return (DWORD)(strength / 4); case eCHAR_MYSTIC: // _NA_004965_20120613_NEW_CHARACTER_MYSTIC return (DWORD)(strength / 6); case eCHAR_HELLROID: // _NA_000000_20130812_NEW_CHARACTER_HELLROID return (DWORD)(strength / 3); case eCHAR_WITCHBLADE: // _NA_007514_20140828_NEW_CHARACTER_WITCHBLADE return (DWORD)(strength / 4); } #else switch (char_type) { case eCHAR_DRAGON: return (DWORD)(strength / 3); case eCHAR_BERSERKER: return (DWORD)(strength / 2); case eCHAR_SHADOW: return (DWORD)(strength / 6 + dexterity / 8); case eCHAR_VALKYRIE: return (DWORD)(strength / 4 + dexterity / 5); case eCHAR_ELEMENTALIST: return (DWORD)(strength / 4); case eCHAR_MYSTIC: // _NA_004965_20120613_NEW_CHARACTER_MYSTIC return (DWORD)(strength / 6 + dexterity / 8); case eCHAR_HELLROID: // _NA_000000_20130812_NEW_CHARACTER_HELLROID return (DWORD)(strength / 3); case eCHAR_WITCHBLADE: // _NA_007514_20140828_NEW_CHARACTER_WITCHBLADE return (DWORD)(strength / 4 + dexterity / 7); } #endif //_NA_008486_20150914_TOTAL_BALANCE SASSERT(false, "Wrong Char_Type in CalcMaxMeleeAttackPower()"); return 1; } // ÃÖ´ë °ø°Ý·Â(¿ø°Å¸®) DWORD ns_formula::CalcMaxRangeAttackPower( const eCHAR_TYPE char_type, const short in_strength, const short in_dexterity) { short dexterity = in_dexterity; if (dexterity < 0) { dexterity = 0; } short strength = in_strength; if (strength < 0) { strength = 0; } switch (char_type) { case eCHAR_DRAGON: case eCHAR_BERSERKER: case eCHAR_ELEMENTALIST: return CalcMaxMeleeAttackPower(char_type, strength, dexterity); case eCHAR_SHADOW: return (DWORD)(strength / 4); case eCHAR_VALKYRIE: #ifdef _NA_008486_20150914_TOTAL_BALANCE return (DWORD)(strength / 4); #else return (DWORD)(strength / 4 + dexterity / 5); #endif //_NA_008486_20150914_TOTAL_BALANCE case eCHAR_MYSTIC: // _NA_004965_20120613_NEW_CHARACTER_MYSTIC return (DWORD)(strength / 4); case eCHAR_HELLROID: // _NA_000000_20130812_NEW_CHARACTER_HELLROID return (DWORD)(strength / 3); case eCHAR_WITCHBLADE: // _NA_007514_20140828_NEW_CHARACTER_WITCHBLADE return (DWORD)(strength / 4); } SASSERT(false, "Wrong Char_Type in CalcMaxRangeAttackPower()"); return 1; } // EP2:unused, old comment, ±âº» °ø°Ý·Â(¸¶¹ý) DWORD ns_formula::CalcMagicAttackPower(BOOL bMin, short intelligence) { if (intelligence < 0) { intelligence = 0; } if (bMin) return intelligence / 3; else return intelligence / 2; } // CHANGES: f110103.4L, changes concept of a CalcMagicAttackPower. // added by _NA001605_EP2_ATTRIBUTES_RENEWAL_ // ±âº» ½ºÅ³ °ø°Ý·Â DWORD CalcSkillAttackPower(const eCHAR_TYPE char_type, const short in_intelligence) { // _NA001605_EP2_ATTRIBUTES_RENEWAL_ short intelligence = in_intelligence; if (intelligence < 0) { intelligence = 0; // NOTE: set dummy penalty value if an invalid attributes value. } if (char_type < eCHAR_BERSERKER || char_type >= eCHAR_TYPE_MAX) { return 0; } double ratio_of_intelligence_to_skill_attack_power = \ ns_formula::kSkillAttackPowerConstants.ratio_of_conversion[char_type]; // // formula // ratio_of_intelligence_to_skill_attack_power // BaseSkillAttackPower = _____________________________________________ * intelligence // 40 #ifdef _NA_008486_20150914_TOTAL_BALANCE double skill_attack_power = ratio_of_intelligence_to_skill_attack_power / 40 * intelligence; #else double skill_attack_power = ratio_of_intelligence_to_skill_attack_power / 100 * intelligence; #endif //_NA_008486_20150914_TOTAL_BALANCE return util::LL_Round(skill_attack_power); } DWORD ns_formula::CalcPhyBaseDef(const eCHAR_TYPE char_type, const short in_vitality) { short vitality = in_vitality; if (vitality < 0) { vitality = 0; } switch (char_type) { case eCHAR_DRAGON: return (DWORD)(vitality / 5 + 29); case eCHAR_BERSERKER: return (DWORD)(vitality / 5 + 29); case eCHAR_SHADOW: return (DWORD)(vitality / 7 + 29); case eCHAR_VALKYRIE: return (DWORD)(vitality / 6 + 29); case eCHAR_ELEMENTALIST: return (DWORD)(vitality / 10 +29); case eCHAR_MYSTIC: // _NA_004965_20120613_NEW_CHARACTER_MYSTIC return (DWORD)(vitality / 7 + 29); case eCHAR_HELLROID: // _NA_000000_20130812_NEW_CHARACTER_HELLROID return (DWORD)((vitality / 5) + 29); case eCHAR_WITCHBLADE: // _NA_007514_20140828_NEW_CHARACTER_WITCHBLADE return (DWORD)((vitality / 7) + 29); } SASSERT(false, "Wrong Char_Type in CalcPhyDef()"); return 1; } // EP2:unused, °¢ ¼Ó¼º º°·Î ºÐ¸®ÇØ¾ß ÇÑ´Ù. DWORD ns_formula::CalcMagicBaseDef(const eCHAR_TYPE char_type, const short in_spirit) { short spirit = in_spirit; if (spirit < 0) { spirit = 0; } switch (char_type) { case eCHAR_DRAGON: return (DWORD)(spirit / 9); case eCHAR_BERSERKER: return (DWORD)(spirit / 9); case eCHAR_SHADOW: return (DWORD)(spirit / 8); case eCHAR_VALKYRIE: return (DWORD)(spirit / 8); case eCHAR_ELEMENTALIST: return (DWORD)(spirit / 7); case eCHAR_MYSTIC: // _NA_004965_20120613_NEW_CHARACTER_MYSTIC return (DWORD)(spirit / 8); case eCHAR_HELLROID: // _NA_000000_20130812_NEW_CHARACTER_HELLROID return (DWORD)(spirit / 8); case eCHAR_WITCHBLADE: // _NA_007514_20140828_NEW_CHARACTER_WITCHBLADE return (DWORD)(spirit / 8); } SASSERT(false, "Wrong Char_Type in CalcMagicDef()"); return 1; } #ifdef _NA_008486_20150914_TOTAL_BALANCE int ns_formula::CalcMoveSpeedRatio(int item_move_speed, int skill_move_speed, LEVELTYPE char_level) { return internal::CalcMoveSpeedRatio(item_move_speed, skill_move_speed, char_level); } #else int ns_formula::CalcMoveSpeedRatio(short dexterity, int item_move_speed, int skill_move_speed) { return internal::CalcMoveSpeedRatio(dexterity, item_move_speed, skill_move_speed); } #endif //_NA_008486_20150914_TOTAL_BALANCE DWORD ns_formula::CalcPhyCriticalBaseRatio( const eCHAR_TYPE char_type, const LEVELTYPE level, const short in_dexterity) { // CHANGES: f110103.2L, change critical occurrence probability #ifdef _NA001605_EP2_ATTRIBUTES_RENEWAL_ // __UNUSED(level); if (char_type < eCHAR_BERSERKER || char_type >= eCHAR_TYPE_MAX) { return 0; } // change boundary short dexterity = in_dexterity; if (dexterity <= 0) { return 0; }; typedef BalanceConstantsChangerInProgramCommon Constants; double default_critical_probability = \ ns_formula::kCriticalChanceConstants.base_probabilies[char_type]; double dex = static_cast(dexterity); const double kNumberatorWeight = ns_formula::kCriticalChanceConstants.kNumberatorWeight; const double kDenominatorWeight = ns_formula::kCriticalChanceConstants.kDenominatorWeight; // formula // (Dex * kNumberatorWeight) // critical chance = ______________________________ + default_critical_probability // sqrt(Dex) * kDenominatorWeight double result = (dex * kNumberatorWeight) / (sqrt(dex) * kDenominatorWeight); ; result += default_critical_probability; return util::LL_Round(result); #else float phyValue = 0; if (dexterity < 0) { dexterity = 0; } switch (char_type) { case eCHAR_DRAGON: phyValue = 2.0f; break; case eCHAR_BERSERKER: phyValue = 2.0f; break; case eCHAR_SHADOW: phyValue = 3.0f; break; case eCHAR_VALKYRIE: phyValue = 3.0f; break; case eCHAR_ELEMENTALIST: phyValue = 4.0f; break; case eCHAR_MYSTIC: // _NA_004965_20120613_NEW_CHARACTER_MYSTIC phyValue = 3.0f; break; case eCHAR_HELLROID: // _NA_000000_20130812_NEW_CHARACTER_HELLROID phyValue = 3.0f; break; case eCHAR_WITCHBLADE: // _NA_007514_20140828_NEW_CHARACTER_WITCHBLADE phyValue = 3.0f; break; default: return 0; } return (DWORD)(level / 4 + dexterity / phyValue); #endif } DWORD ns_formula::CalcMagicCriticalBaseRatio( const eCHAR_TYPE char_type, const LEVELTYPE level, const short in_spirit) { DWORD phyValue = 0; short spirit = in_spirit; if (spirit < 0) { spirit = 0; } switch (char_type) { case eCHAR_DRAGON: phyValue = 2; break; case eCHAR_BERSERKER: phyValue = 2; break; case eCHAR_SHADOW: phyValue = 2; break; case eCHAR_VALKYRIE: phyValue = 2; break; case eCHAR_ELEMENTALIST: phyValue = 2; break; case eCHAR_MYSTIC: // _NA_004965_20120613_NEW_CHARACTER_MYSTIC phyValue = 2; break; case eCHAR_HELLROID: //_NA_000000_20130812_NEW_CHARACTER_HELLROID phyValue = 2; break; case eCHAR_WITCHBLADE: //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE phyValue = 2; break; default: return 0; } return (level / 4 + spirit / phyValue); } // °ø°Ý ¼º°ø·ü DWORD ns_formula::CalcPhysicalAttackRateBase( const eCHAR_TYPE char_type, const LEVELTYPE level, const short in_dexterity) { #ifdef _NA001605_EP2_ATTRIBUTES_RENEWAL_ __UNUSED(level); if (char_type < eCHAR_BERSERKER || char_type >= eCHAR_TYPE_MAX) { return 0; } short dexterity = in_dexterity; if (dexterity < 0) { dexterity = 0; }; // [Items...] + [Constant] * [Dex] // [Constant] = 0.0004 * 100 -> 4% // percentage base = 1000 * 4.0(x10000) * [Dex] / 10 double calc = static_cast(dexterity); ; calc *= ns_formula::kAttackRateConstants.ratio_of_conversion[char_type]; ; calc /= 100.0f; // make to percentage return util::LL_Round(calc); #else float rateValue = 0; short dexterity = in_dexterity; if (dexterity < 0) { dexterity = 0; } switch (char_type) { case eCHAR_DRAGON : rateValue = 2.0f; break; case eCHAR_BERSERKER : rateValue = 1.0f; break; case eCHAR_SHADOW : rateValue = 3.0f; break; case eCHAR_VALKYRIE : rateValue = 5.0f; break; case eCHAR_ELEMENTALIST : rateValue = 1.0f; break; case eCHAR_MYSTIC : rateValue = 3.0f; break; // _NA_004965_20120613_NEW_CHARACTER_MYSTIC case eCHAR_HELLROID : rateValue = 3.0f; break; //_NA_000000_20130812_NEW_CHARACTER_HELLROID case eCHAR_WITCHBLADE : rateValue = 3.0f; break; //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE default: { SASSERT(false, "Wrong Char_Type in CalcPhysicalAttackRateBase()"); rateValue = 1.0f; } break; } return (DWORD)(50 + level * 10 + dexterity * rateValue); #endif } int ns_formula::CalcAttackSpeedRatio(eCHAR_TYPE char_type, DWORD weapon_kind, short dexterity, int item_attr_speed, int skill_attr_speed) { return internal::CalcAttackSpeedRatio(char_type, weapon_kind, dexterity, item_attr_speed, skill_attr_speed); } // HP ¹èÀ²¼ö static float ns_formula::CalcHPRatioNum(DWORD partymemberNum) { #ifdef _NA001605_EP2_ATTRIBUTES_RENEWAL_ if (partymemberNum == 0) return 0; else return 0.032f; // 0.4f -> 0.032f #else if (partymemberNum == 0) return 0; else return 0.7f; #endif } // HP Ãß°¡ºñÀ² static float ns_formula::CalcAdditionalHPRatio(DWORD partymemberNum) { #ifdef _NA001605_EP2_ATTRIBUTES_RENEWAL_ const float kAdditionalRatioOfRatio = 0.072f; // 0.09f -> 0.072f float additional_ratio = 0.0f; if (partymemberNum != 0) { additional_ratio = (partymemberNum - 1) * kAdditionalRatioOfRatio; } return additional_ratio; #else float fAdditionalRatio = 0.0f; const float kAdditionalRatioOfRatio = 0.10f; if (partymemberNum == 0) { fAdditionalRatio = 0; } else if (partymemberNum <= 5) { fAdditionalRatio = (partymemberNum - 1) * kAdditionalRatioOfRatio; } else { fAdditionalRatio = CalcAdditionalHPRatio(partymemberNum - 1) + (partymemberNum - 4) * kAdditionalRatioOfRatio; } return fAdditionalRatio; #endif } // ÆÄƼ¿ø ¼ö¿¡ µû¸¥ NPC HP Áõ°¡À² float ns_formula::CalcHPIncreaseRatioAsParty(DWORD partymemberNum) { #ifdef _NA001605_EP2_ATTRIBUTES_RENEWAL_ float result_ratio = 1.0f; ; result_ratio += (partymemberNum - 1) * CalcHPRatioNum(partymemberNum); ; result_ratio += CalcAdditionalHPRatio(partymemberNum); return result_ratio; #else float fResultRatio = 1 + (float)(partymemberNum - 1) * CalcHPRatioNum(partymemberNum) + CalcAdditionalHPRatio(partymemberNum); return fResultRatio; #endif } // ÆÄƼ¿ø ¼ö¿¡ µû¸¥ NPC °ø°Ý·Â Áõ°¡¼öÄ¡ int ns_formula::CalcAttackPowerIncreaseAsParty(DWORD partymemberNum, int iAttackPower) { int iIncreaseAttackPower = 0; iIncreaseAttackPower = (int)(GetBonusAttackPower(partymemberNum) + iAttackPower * (partymemberNum - 1) * GetBonusAttPowerRatio(partymemberNum)); return iIncreaseAttackPower; } // °ø°ÝȸÇÇÀ²(¹°¸®) #ifdef _NA_008486_20150914_TOTAL_BALANCE//--------------------------------------------------- DWORD ns_formula::CalcPhysicalAvoidRateBase( const eCHAR_TYPE char_type, const LEVELTYPE level, const short in_vitality) { __UNUSED(level); if (char_type < eCHAR_BERSERKER || char_type >= eCHAR_TYPE_MAX) { return 0; } short vitality = in_vitality; if (vitality < 0) { vitality = 0; }; // [Items...] + [Constant] * [vital] // [Constant] = 0.0008 * 100 -> 4% // percentage base = 1000 * 8.0(x10000) * [Dex] / 10 double calc = static_cast(vitality); ; calc *= ns_formula::kAttackAvoidRateConstants.ratio_of_conversion[char_type]; ; calc /= 100.0f; // make to percentage return util::LL_Round(calc); } // µð¹öÇÁ Áö¼Ó½Ã°£ INT ns_formula::CalcDebuffDuration(const short in_spirit) { short spirit = in_spirit; if (spirit < 0) { spirit = 0; } //ÀüÁ÷¾÷ °øÅë //Á¤½Å·Â 1´ç 0.0012ÃÊ(2¹Ð¸®¼¼ÄÁµå) double calc = static_cast(spirit); calc *= 1.2f; return util::LL_Round(calc); } #else //-------------------------------------------------------------------------------------------- DWORD ns_formula::CalcPhysicalAvoidRateBase( const eCHAR_TYPE char_type, const LEVELTYPE level, const short in_dexterity) { #ifdef _NA001605_EP2_ATTRIBUTES_RENEWAL_ __UNUSED(level); if (char_type < eCHAR_BERSERKER || char_type >= eCHAR_TYPE_MAX) { return 0; } short dexterity = in_dexterity; if (dexterity < 0) { dexterity = 0; }; // [Items...] + [Constant] * [Dex] // [Constant] = 0.0008 * 100 -> 4% // percentage base = 1000 * 8.0(x10000) * [Dex] / 10 double calc = static_cast(dexterity); ; calc *= ns_formula::kAttackAvoidRateConstants.ratio_of_conversion[char_type]; ; calc /= 100.0f; // make to percentage return util::LL_Round(calc); #else float fRateValue = 1; short dexterity = in_dexterity; if (dexterity < 0) { dexterity = 0; } switch (char_type) { case eCHAR_DRAGON : fRateValue = 1.0f; break; case eCHAR_BERSERKER : fRateValue = 1.0f; break; case eCHAR_SHADOW : fRateValue = 1.0f; break; case eCHAR_VALKYRIE : fRateValue = 1.0f; break; case eCHAR_ELEMENTALIST : fRateValue = 1.0f; break; case eCHAR_MYSTIC : fRateValue = 1.0f; break; // _NA_004965_20120613_NEW_CHARACTER_MYSTIC case eCHAR_HELLROID : fRateValue = 1.0f; break; //_NA_000000_20130812_NEW_CHARACTER_HELLROID case eCHAR_WITCHBLADE : fRateValue = 1.0f; break; //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE default: { SASSERT(false, "Wrong Char_Type in CalcPhysicalAvoidRateBase()"); fRateValue = 1.0f; } break; } return (DWORD)(level + dexterity); #endif } #endif //_NA_008486_20150914_TOTAL_BALANCE }; //end of namespace 'ns_formula' //==================================================================================================