#pragma once // 전반적인 게임 공식/상수들. // 헤더에는 아무것도 include 하지 말것. // // percentage 는 0 ~ 1 사이의 값 // // 2004/05/21 by Testors #pragma warning( disable : 4244 ) #include "GameType.h" #include #include #include struct QuestBase; namespace GameRule { const int MAX_CHARACTER_NAME_SIZE = 18; ///< sonador #2.1.24 const int MAX_STATE_LEVEL = 125; ///< 최대 지속효과 레벨 const float DEFAULT_HUMAN_SIZE = 1.0f; ///< 표준 생물체(인간)의 지름 const float DEFAULT_ATTACK_RANGE = 0.5f; ///< 기본 사거리 (50센티 정도) const int DEFAULT_UNIT_SIZE = 12; ///< 1미터가 좌표상으로 얼마인지를 정의 const float SKILL_CAST_COST = 0.2f; ///< 스킬 시전시 20% 소비 const float SKILL_FIRE_COST = 0.8f; ///< 스킬 발사시 80% 소비 const float SKILL_CANCEL_RATE = 0.03f; ///< 캐스팅 캔슬이 일어나기 위한 데미지 비율 (MAXHP 대비) const int MAX_LEVEL = 300; ///< 최대 레벨 const int NORMAL_SUMMON_MAX_LEVEL = 70; ///< 소환수 기본형 최대 레벨 const int GROWTH_SUMMON_MAX_LEVEL = 100; ///< 소환수 성장형 최대 레벨 const int EVOLVE_SUMMON_MAX_LEVEL = 100; ///< 소환수 진화형 최대 레벨 const int ATTACK_RANGE_UNIT = 100; ///< 사정거리 단위. ( 내부적으로는 기획 DB 에서 ATTACK_RANGE_UNIT 를 곱한 값으로 처리된다 ) const AR_TIME TAMING_INTERVAL = 30000; ///< 테이밍 유지시간은 5분임 const int MAX_GOLD_DROP = 1000000; ///< 최대 골드 드랍양 const int MAX_FIRST_ATTACK_BONUS_TIME = 6000; ///< 선공 보너스 적용 시간 const float MAX_TAKE_ITEM_RANGE = 20.0f; /// 2010.10.14 최대 줍기 거리 - prodongi const short DEFAULT_RUSH_SPEED = 140; ///< 러쉬일때 속도오~ const short DEFAULT_KNOCK_BACK_SPEED = 140; ///< 넉백일때 속도오~ const float UNMOUNT_PENALTY = 0.05f; ///< 말에서 떨어지면 체력 5% 감소 const int DEFAULT_UNMOUNT_PROBABILITY_ON_DAMAGE = 30; const int DEFAULT_UNMOUNT_PROBABILITY_ON_CRITICAL_DAMAGE = 75; const AR_TIME CASTING_DELAY_LOW = 20; ///< 캐스팅 딜레이 const AR_TIME CASTING_DELAY_MEDIUM = 50; const AR_TIME CASTING_DELAY_HIGH = 100; const AR_TIME DEFAULT_MP_DEC_TIME = 1000; ///< 오오라 시전시 MP 소진 시간 const int CASTING_CANCEL_LOW = 20; ///< 캐스팅 캔슬 확률 (%) const int CASTING_CANCEL_MEDIUM = 50; ///< 캐스팅 캔슬 확률 (%) const int CASTING_CANCEL_HIGH = 100; ///< 캐스팅 캔슬 확률 (%) // 피로도 시스템 관련 const int DEFAULT_MAX_STAMINA = 475200; const AR_TIME STAMINA_UPDATE_TIME = 6000; const int STAMINA_REGEN_ON_GOOD = 110; const int STAMINA_REGEN_ON_AVERAGE = 100; const int STAMINA_REGEN_ON_BAD = 90; const int STAMINA_REGEN_ON_LOGOUT_IN_FIELD = 30; const int BAD_CONDITION_LIMIT = 158400 * 0.15f; const int AVERAGE_CONDITION_LIMIT = 158400 * 0.85f; const int GOOD_CONDITION_LIMIT = 158400; // 기공 const int ENERGY_MAX = 10; // PK 관련 const AR_TIME PK_ON_TIME = 100; // 1000 const AR_TIME PK_OFF_TIME = 100; // 3000 extern float fEXPRate; ///< 경치 비율 extern float fGoldDropRate; ///< 돈 드랍 비율 extern float fItemDropRate; ///< 아이템 드랍 비율 extern float fPartyEXPRate; ///< 파티 경치 보너스 extern float fChaosDropRate; ///< 혼돈 드랍 비율 extern bool bMonsterWandering; ///< 몬스터 방황 여부.-_- const int nMaxCharactersPerAccount = 8; const float MORAL_LIMIT = 100; ///< 블러디 캐릭터가 되기 위한 IP 수치 const float CRIME_LIMIT = 1000; ///< 데모니악 캐릭터가 되기 위한 IP 수치 const float BOW_AIMING_TIME_RATIO = 0.8f; const AR_TIME DEFAULT_HEAVY_BOW_INTERVAL = 200; ///< 기본 활 휴지기 const AR_TIME DEFAULT_LIGHT_BOW_INTERVAL = 300; ///< 기본 활 휴지기 const AR_TIME DEFAULT_DOUBLE_SUMMON_TIME = 1000; ///< 기본 동시 소환 가능 시간 const AR_TIME BIND_SUMMON_UPDATE_TIME = 1000; ///< 소환 안된 크리쳐 업데이트 타임. const AR_UNIT CHANGE_LOCATION_ERROR_RANGE = 10 * DEFAULT_UNIT_SIZE; ///< 위치 바꿀 때 오차범위 const AR_UNIT AGGRESIVE_MONSTER_REACTION_RANGE = 8 * DEFAULT_UNIT_SIZE; ///< 선공몹 어그로 범위 const AR_UNIT MONSTER_TRACKING_RANGE = 30 * DEFAULT_UNIT_SIZE; ///< 추적 범위 ( 이 이상 거리가 멀어지면 다른 타겟을 찾아갑니다~ ) const AR_UNIT MONSTER_COME_BACK_HOME_RANGE = 500 * DEFAULT_UNIT_SIZE; ///< 집-ㅅ-에서 너무 멀리 떨어져나와, 향수를 느껴 집으로 다시 돌아가게 되는 거리. const int MONSTER_FIND_ATTACK_POS_RATIO = 10; ///< 공격 중 다른 몬스터와 겹칠때 적절한 위치를 찾을 확률 const int AUCTION_INFO_COUNT_PER_PAGE = 40; ///< { [sonador][3.1.2]경매장 구현 // // 헌터홀릭 시스템 관련 상수 정의 // const int HUNTAHOLIC_MAX_INSTANCE_NAME_LENGTH = 30; const int HUNTAHOLIC_MAX_INSTANCE_PASSWORD_LENGTH = 16; const int HUNTAHOLIC_MAX_INSTANCE_SLOT_ON_GUI = 8; // #2.1.2.12 // 스킬 툴팁 관련 스트링 DB 오프셋 const int SKILL_EFFECT_TOOLTIP_STRING_OFFSET = 2000000000; ///< 효과+강화 const int SKILL_ENHANCE_TOOLTIP_STRING_OFFSET = 2100000000; ///< 강화 // #2.1.12 const unsigned int MAX_ACCOUNT_LEN = 60; const unsigned int MAX_CRYPTO_BLOCK_LEN = 16; // 2010.09.02. bintitle. 에테리얼스톤 최대 충전량. const int MAX_ETHEREAL_STONE_DURABILITY = 100000000; // 최대 에테리얼 스톤 충전 가능량 // Monster Creature 관련 const char MAX_MONSTER_CREATURE_COUNT = 10; int GetSummonEXPLimit( int depth, int level ); int GetPlayerEXPLimit( int level ); float GetSummonLevelPenalty( int master_level, int summon_level ); float GetSummonStatPenalty( int master_level, int summon_level ); float GetOverBreedLevelPenalty( int master_level, int overbreed_level, int summon_level ); float GetOverBreedStatPenalty( int master_level, int overbreed_level, int summon_level ); /// 먹자 방지 시간 inline int GetPickupOrderTime( int idx ) { return 3000 + idx * 1000; } /// 시체 유지시간 inline int GetCorpseHoldTime() { return 3000; } // 10초 inline int GetCritical( int luck ) { return luck * 0.1f; } inline int GetItemChance( int luck ) { return luck * 0.2f; } /// 공격력 inline int GetAttackPoint( int strength, float level, float fCM ) { return ( 1 + ( level * 0.02f ) ) * ( strength * ( 0.3f + fCM * 0.3f ) ) + level; } /// 마법 공격력 inline int GetMagicPoint( int intelligence, float level, float fCM ) { return ( 1 + ( level * 0.02f ) ) * ( intelligence * ( 0.3f + fCM * 0.3f) ) + level; } /// 방어력 inline int GetDefence( float lv, int vital, float fCM ) { return ( vital * fCM + lv ) * 0.15f; } /// 마법 방어력 inline int GetMagicDefence( float lv, int men, float fCM ) { return ( ( men * fCM ) + lv ) * 0.6f; } /// 명중수치 inline int GetAccuracy( int dexterity, float level, float fCM ) { return level + ( dexterity * 0.5f ) * ( 0.8f + fCM * 0.2f ); } /// 마법명중수치 inline int GetMagicAccuracy( int mental, int dexterity, float level, float fCM ) { return level + ( ( mental * 0.4f ) + ( dexterity * 0.1f ) ) * ( 0.7f + fCM * 0.3f ); } /// 마법저항수치 inline int GetMagicAvoid( int mental, int agility, float level, float fCM ) { return level + ( ( mental * 0.4f ) + ( agility * 0.1f ) ) * ( 0.7f + fCM * 0.3f ); } /// 회피수치 inline int GetAvoid( int agility, float level, float fCM ) { return level + ( agility * 0.5f ) * ( 0.8f + fCM * 0.2f ) + 30; } /// 공격확률 inline float GetHitPercentage( int hit_value, int avoid_value ) { return ( 90 + hit_value - avoid_value ) / 100.0f; } /// 시전속도 inline int GetCastingTime( int dexterity, int men, float level ) { return ( (dexterity * 8) + (men * 2) ) * 0.25 + (level * 0.2f); } /// 이동속도 inline int GetBaseMoveSpeed() { return 100; } /// 최대 HP inline int GetMaxHP( int vital, float level, float fCM ) { return vital * fCM * level * 0.8f + 150; } /// 최대 MP inline int GetMaxMP( int intelligence, int level, float fCM ) { return intelligence * fCM * level * 0.8f + 20; } inline int GetIntValueByRandom( float fValue ) { float fmod = (int)fValue + (float) ( XFastRandom() % 100 ) / 100; if( fmod < fValue ) { return (int) fValue + 1; } return (int) fValue; } /// 공격속도 inline int GetAttackSpeed( int agility, int strength, float fCM ) { int agi_speed = 0; if( agility <= 300 ) agi_speed = agility * ( 0.7f + ( 300 - agility ) / 300.0f ) * 0.5f; else agi_speed = agility * 0.35f; int str_speed = 0; if( strength <= 300 ) str_speed = strength * ( 0.7f + ( 300 - strength ) / 300.0f ) * 0.1f; else str_speed = strength * 0.07f; return ( 50 + ( agi_speed + str_speed ) * ( 0.8f + ( fCM * 0.2f ) ) ) - 20; } /// HP 리젠율% (100초당) inline int GetHPRegenPercentage( int vitality, float fCM ) { return (vitality * fCM * 0.2); } /// HP 리젠율+ (100초당) inline int GetHPRegenPoint( float level, int max_hp ) { return ( (1 + (level * 0.2f)) * 35 ); } /// MP 리젠율% (100초당) inline int GetMPRegenPercentage( int mentality, float fCM ) { return (mentality * fCM * 0.2); } /// MP 리젠율 (100초당) inline int GetMPRegenPoint( float level, int max_mp ) { return ( (1 + (level * 0.1f)) * 35 ); } float GetStaminaRatio( int level ); /// 플레이어가 최대로 들 수 있는 무게 int GetMaxWeight( int strength ); /// 물건을 주울 수 있는 거리 int GetPickableRange(); /// 등급에 따른 아이템 레벨 제한 int GetItemLevelLimit( int item_rank ); /// 아이템 레벨에 따른 페널티 float GetItemLevelPenalty( int creature_level, int item_min_level,int item_rank, int item_level, int item_limit_level ); /// 등급별 아이템 권장레벨 조정 테이블 int GetItemRecommendModTable( int item_rank ); /// 아이템 권장 레벨 int GetItemRecommendLevel( int item_min_level, int item_rank, int item_level ); /// 내구도에 따른 페널티 비율 float GetItemEndurancePenalty( float item_endurance_percentage ); /// 수리 비용 int GetRepairCost( int item_price, float item_endurance_percentage ); /// 각 레벨에 따른 성능 조정 (데미지, 방어구 동일) int GetItemValue( float item_current_value, float item_endurance_percentage, int item_rank_value, int creature_level, int item_min_level, int item_rank, int item_level, int item_limit_level = -1 ); int GetItemSellPrice( int price, int rank, int lv, bool isEquipment ); bool IsValidName( const char* name, int nBufferSize, int nLimitMin, int nLimitMax ); // Integration of country-specific local bitsets and separation of Europe // enum LOCAL_BITSET { KR = ( 1 << 0 ), // South Korea 1 HK = ( 1 << 1 ), // Hong Kong 2 US = ( 1 << 2 ), // North America 4 DE = ( 1 << 3 ), // Germany 8 JP = ( 1 << 4 ), // Japan 16 TW = ( 1 << 5 ), // Taiwan 32 CN = ( 1 << 6 ), // China 64 FR = ( 1 << 7 ), // France 128 RU = ( 1 << 8 ), // Russia 256 MASG= ( 1 << 9 ), // Malaysia(Singapore) 512 PH = ( 1 << 10 ), // Philippines 1024 VN = ( 1 << 11 ), // Vietnam 2048 TL = ( 1 << 12 ), // Thailand 4096 ME = ( 1 << 13 ), // Middle East 8192 TR = ( 1 << 14 ), // Turkey 16384 PL = ( 1 << 15 ), // Poland 32768 IT = ( 1 << 16 ), // Italy 65536 BR = ( 1 << 17 ), // Brazil 131072 ES = ( 1 << 18 ), // Spain 262144 ID = ( 1 << 19 ), // Indonesia 524288 EXCLUDE_TEST_SERV = ( 1 << 29 ), // Test server excluded NPCs EXCLUDE_SERVICE_SERV = ( 1 << 30 ) // Main server excluded NPCs }; int GetCurrentLocalBitSet(); // 2010.07.12 prodongi bool isSoutheastAsia(); /// 2011.10.07 - prodongi bool isEurope(); // } // #2.3.1.8 sonador c_fixed10 GetQuestRewardFactor( QuestBase* questBase ); // #2.1.2.6.1 enum SETPART_COMPOSITION_FLAG { SETPART_NONE = 0, SETPART_ARMO = 1 << 0, SETPART_WEAPON1 = 1 << 1, SETPART_WEAPON2 = 1 << 2, SETPART_WEAPON3 = 1 << 3, SETPART_WEAPON4 = 1 << 4, SETPART_TWOHAND_WEAPON1 = 1 << 5, SETPART_TWOHAND_WEAPON2 = 1 << 6, SETPART_SHEILD = 1 << 7, SETPART_HELM = 1 << 8, }; const char* GetSetPartCompositionSlotOnEmoticonByPartId( int partId ); const char* GetSetPartCompositionSlotOffEmoticonByPartId( int partId ); };