Files
2026-06-01 12:46:52 +02:00

1207 lines
44 KiB
C++

#pragma once
#include <windows.h>
#include <mmo/ArType.h>
#include "ItemBase.h"
#include "CreatureBase.h"
#include "GameRule.h"
//#include <string>
#ifdef max
#undef max
#undef min
#endif // max
#pragma pack( push, 1 )
// sonador 10.4.1 스킬 툴팁 리뉴얼
struct SkillBase
{
enum
{
MAX_SKILL_LEVEL = 50,
MAX_TOGGLE_GROUP = 20,
MAX_SKILL_VALUE = 20,
TOGGLE_REFRESH_TIME = 700, ///< 토글형 스킬은 7초마다 다시 걸어줌
TOGGLE_LIVE_TIME = 1000, ///< 토글형 스킬로 발동된 지속효과는 10초간 유지됨
};
enum
{
ST_INVALID = 0,
ST_VALID = 1,
ST_SYSTEM = 2,
};
/// 분산 타입
enum
{
DISTRIBUTION_TYPE_NO_LIMIT = 0,
DISTRIBUTION_TYPE_DISTRIBUTE = 1,
DISTRIBUTION_TYPE_RANDOM = 2,
DISTRIBUTION_TYPE_SEQUENTIAL_TARGET = 3,
DISTRIBUTION_TYPE_SEQUENTIAL_CASTER = 4,
};
/// 대상 제한
enum
{
SKILL_EFFECT_TARGET_LIMIT_ANY_BODY = 0,
SKILL_EFFECT_TARGET_LIMIT_NOT_ENEMY = 1,
SKILL_EFFECT_TARGET_LIMIT_ONLY_ALLY = 2,
};
enum
{
REGION_TYPE_DIRECTION = 0, ///< 일자형
REGION_TYPE_ARC_CIRCLE = 1, ///< 부채꼴형
REGION_TYPE_CROSS = 2, ///< 십자가형
};
/// effect type
enum
{
EF_MISC = 0,
// 2010.05.17 - prodongi
EF_PASSIVE_PARAMETER_INCREASE = 3,
EF_PASSIVE_PARAMETER_AMPLIFY = 4,
EF_PHYSICAL_SINGLE_DAMAGE_T1 = 101,
EF_PHYSICAL_MULTIPLE_DAMAGE_T1 = 102,
EF_PHYSICAL_SINGLE_DAMAGE_T2 = 103,
EF_PHYSICAL_MULTIPLE_DAMAGE_T2 = 104,
EF_PHYSICAL_DIRECTIONAL_DAMAGE = 105,
EF_PHYSICAL_SINGLE_DAMAGE_T3 = 106,
EF_PHYSICAL_MULTIPLE_DAMAGE_T3 = 107,
EF_PHYSICAL_MULTIPLE_DAMAGE_TRIPLE_ATTACK = 108,
EF_PHYSICAL_SINGLE_REGION_DAMAGE = 111,
EF_PHYSICAL_MULTIPLE_REGION_DAMAGE = 112,
EF_PHYSICAL_SPECIAL_REGION_DAMAGE = 113,
EF_PHYSICAL_IGNORE_POWER_SHIELD_ATTACK = 117,
EF_PHYSICAL_ABSORB_DAMAGE = 121,
EF_PHYSICAL_SINGLE_DAMAGE_KNOCK_BACK = 131,
EF_PHYSICAL_SINGLE_REGION_DAMAGE_KNOCK_BACK = 132,
EF_PHYSICAL_MULTIPLE_DAMAGE_KNOCK_BACK = 133,
EF_PHYSICAL_MULTIPLE_REGION_DAMAGE_KNOCK_BACK = 134,
EF_PHYSICAL_SINGLE_DAMAGE_WITHOUT_WEAPON_RUSH_KNOCK_BACK = 151,
EF_PHYSICAL_SINGLE_DAMAGE_RUSH_KNOCK_BACK = 152,
EF_MAGIC_IMPROVED_SINGLE_DAMAGE_T1 = 201,
// EF_MAGIC_MULTIPLE_DAMAGE_T1 = 202,
// EF_MAGIC_SINGLE_DAMAGE_T2 = 203,
// EF_MAGIC_MULTIPLE_DAMAGE_T2 = 204,
// EF_MAGIC_MULTIPLE_DAMAGE_T3 = 205,
// EF_MAGIC_MULTIPLE_DAMAGE_T1_DEAL_SUMMON_HP = 206,
EF_MAGIC_IMPROVED_SINGLE_REGION_DAMAGE = 211,
// EF_MAGIC_MULTIPLE_REGION_DAMAGE = 212,
// EF_MAGIC_SPECIAL_REGION_DAMAGE = 213,
// EF_MAGIC_MULTIPLE_REGION_DAMAGE_T2 = 214,
// EF_MAGIC_ABSORB_DAMAGE = 221,
EF_MAGIC_SINGLE_DAMAGE_T1 = 231, ///< 구 201, 203
EF_MAGIC_MULTIPLE_DAMAGE_T1 = 232, ///< 구 202, 204
EF_MAGIC_MULTIPLE_DAMAGE_T1_DEAL_SUMMON_HP = 233, ///< 구 206
EF_MAGIC_SINGLE_DAMAGE_DEAD = 234,
EF_MAGIC_SINGLE_ABSORPTION_DAMAGE = 235, ///< 구 221
EF_MAGIC_SINGLE_HPRATE_DAMAGE = 236,
EF_MAGIC_SINGLE_MP_HP_DAMAGE = 237,
EF_MAGIC_REGION_DAMAGE = 261, ///< 구 211
EF_MAGIC_SPECIAL_REGION_DAMAGE = 262, ///< 구 213
EF_MAGIC_MULTIPLE_REGION_DAMAGE = 263, ///< 구 212
EF_MAGIC_MULTIPLE_SINGLE_HPRATE_DAMAGE = 264,
EF_MAGIC_CORPSE_EXPLOSION = 265,
EF_MAGIC_CREATURE_SUICIDAL_EXPLOSION = 267,
EF_MAGIC_SINGLE_WORLD_REGION_DAMAGE = 271,
EF_MAGIC_SINGLE_WORLD_REGION_DAMAGE_RECOVERY= 272,
EF_MAGIC_SINGLE_WORLD_REGION_DAMAGE_RECOVERY_T2 = 273,
EF_ADD_STATE = 301,
EF_ADD_STATE_REGION = 302,
EF_ADD_STATE_WHEN_CASTING_CANCELED = 304,
EF_ADD_STATE_WHEN_RACE_IS_FIT = 307,
// 2010.06.03 이름을 어떻게 해야 될지 몰라서 임시로 표시- prodongi
EF_ADD_STATE_308 = 308,
EF_ADD_STATE_309 = 309,
EF_PHYSICAL_SINGLE_DAMAGE_AND_ADD_STATE = 311,
EF_PHYSICAL_MULTIPLE_DAMAGE_AND_ADD_STATE = 312,
EF_MAGICAL_SINGLE_DAMAGE_AND_ADD_STATE = 321,
EF_MAGICAL_MULTIPLE_DAMAGE_AND_ADD_STATE = 322,
// EF_AREA_EFFECT_MAGIC_DAMAGE = 352,
EF_AREA_EFFECT_HEAL = 353,
EF_TRAP_PHYSICAL_DAMAGE_ADD_STATE = 381,
EF_TRAP_MAGICAL_DAMAGE_ADD_STATE = 382,
EF_TRAP_MAGICAL_CONTINUOUS_DAMAGE_ADD_STATE = 384,
EF_REMOVE_BAD_STATE = 401,
EF_REMOVE_GOOD_STATE = 402,
EF_ADD_HP = 501,
EF_ADD_MP = 502,
EF_ADD_SP = 503,
EF_RESURRECTION = 504,
EF_ADD_HP_MP = 505,
EF_ADD_HP_MP_BY_SUMMON_DAMAGE = 506,
EF_ADD_HP_MP_BY_SUMMON_DEAD = 507,
EF_ADD_HP_MP_REGION = 508,
EF_ADD_HP_BY_ITEM = 509,
EF_ADD_MP_BY_ITEM = 510,
EF_CORPSE_ABSORB = 511,
EF_ADD_HP_MP_BY_STEAL_SUMMON_HP_MP = 512,
EF_ADD_HP_TARGET_REGION = 521,
EF_SUMMON = 601,
EF_UNSUMMON = 602,
EF_TAMING = 603,
EF_RECALL_CREATURE_WITH_STATE = 605,
EF_TOGGLE_AURA = 701,
EF_TOGGLE_DISTRIBUTIVE_AURA = 702,
EF_ADD_HATE = 900,
EF_REDUCE_HATE = 903,
// 2010.05.12 순차적 지속효과 부여 - prodongi
EF_ADD_SEQ_STATE = 904,
EF_CORPSE_EXPLOSION = 1001,
EF_CREATE_ITEM = 9001,
// passive
EF_WEAPON_MASTERY = 10001,
EF_BATTLE_PARAMTER_INCREASE = 10002,
EF_BLOCK_INCREASE = 10003,
EF_ATTACK_RANGE_INCREASE = 10004,
EF_RESISTANCE_INCREASE = 10005,
EF_MAGIC_REGISTANCE_INCREASE = 10006,
EF_SPECIALIZE_ARMOR = 10007,
EF_BASIC_MASTERY = 10008,
EF_EXTENDED_MASTERY = 10009,
EF_FIT_ARMOR_MASTERY = 10010,
EF_AMPLIFY_BASIC_MASTERY = 10011,
EF_MAGIC_TRAINING = 10012,
EF_HUNTING_TRAINING = 10013,
EF_BOW_TRAINING = 10014,
EF_IMPROVE_STAT = 10015,
EF_PARAMETER_INCREASE = 10021,
EF_PARAMETER_AMPLIFY = 10022,
EF_HEALING_AMPLIFY = 10023,
EF_SUMMON_PARAMETER_INCREASE = 10031,
EF_SUMMON_PARAMETER_AMPLIFY = 10032,
EF_CREATURE_ASSIGNMENT_INCREASE = 10033,
EF_CREATURE_ACQUIREMENT_INCREASE = 10034,
EF_BELT_ON_PARAMETER_INC = 10035,
EF_CREATURE_CARD_AMPLIFY_STAT_WHEN_EQUIPPED = 10042,
EF_CREATURE_CARD_AMPLIFY_BASIC_STAT_WHEN_EQUIPPED = 10043,
EF_CREATURE_CARD_AMPLIFY_EXPAN_STAT_WHEN_EQUIPPED = 10044,
EF_CREATURE_CARD_AMPLIFY_HP_MP_WHEN_EQUIPPED = 10045,
/// 2011.04.13 네이밍이 힘들다,, - prodongi
EF_ADD_STATE_10048 = 10048,
EF_ADD_STATE_10049 = 10049,
EF_ADD_STATE_10050 = 10050,
EF_ADD_STATE_10051 = 10051,
EF_ADD_STATE_10052 = 10052,
EF_ADD_STATE_10053 = 10053,
EF_ADD_STATE_10054 = 10054,
EF_ADD_STATE_10055 = 10055,
EF_ADD_STATE_10056 = 10056,
EF_ADD_STATE_10057 = 10057,
EF_ADD_STATE_10058 = 10058,
EF_ADD_STATE_10059 = 10059,
EF_ADD_STATE_10060 = 10060,
EF_ADD_STATE_10061 = 10061,
EF_ADD_STATE_10062 = 10062,
EF_PHYSICAL_ATTACK = 30001,
EF_PHYSICAL_ATTACK_WITH_ABSORB_HP_AND_MP = 30002,
EF_PHYSICAL_ATTACK_RUSH = 30004,
EF_PHYSICAL_ATTACK_KNOCK_BACK = 30006,
EF_PHYSICAL_ATTACK_KNOCK_BACK_REGION = 30008,
EF_PHYSICAL_ATTACK_MULTI_STEP_HIT = 30009,
EF_PHYSICAL_ATTACK_REGION_AROUND_TARGET = 30011,
EF_PHYSICAL_ATTACK_MULTI_STEP_HIT_REGION_AROUND_TARGET = 30012,
EF_PHYSICAL_ATTACK_PARTICULAR_REGION = 30013,
EF_PHYSICAL_ATTACK_MULTI_STEP_HIT_PARTICULAR_REGION_AROUND_TARGET = 30014,
EF_PHYSICAL_ATTACK_MULTI_STEP_HIT_IGNORE_DELAY = 30016,
EF_PHYSICAL_ATTACK_MULTI_STEP_HIT_WITH_KNOCK_BACK = 30017,
EF_RESURRECTION_ANEW = 30501,
EF_REMOVE_STATE_BY_GROUP = 30601,
EF_AMPLIFY_WEAPON_MASTERY = 31001,
EF_AMPLIFY_EXTENDED_MASTERY = 31003,
EF_AMPLIFY_CREATURE_EXP = 32001,
};
/// interrupt type
enum
{
IT_ABSOLUTE = 0, ///< 방해, 캔슬을 당하지 않는 스킬
IT_DELAY = 1, ///< 캐스팅 방해를 받는 스킬
IT_CANCEL = 2, ///< 캐스팅캔슬을 당하는 스킬
};
/// interrupt level
enum
{
IL_LOW = 0, ///< 낮음 : 0.2초의 캐스팅 감소 혹은 20%의 확률로 캐스팅이 캔슬됨
IL_MEDIUM = 1, ///< 보통 : 0.5초의 캐스팅 감소 혹은 50%의 확률로 캐스팅이 캔슬됨
IL_HIGH = 2, ///< 높음 : 1초의 캐스팅 감소 혹은 100%의 확률로 캐스팅이 캔슬됨
};
enum
{
TF_ADD_STATE = 1 << 1,
};
enum
{
TARGET_MISC = 0,
TARGET_TARGET = 1,
TARGET_REGION = 2,
TARGET_REGION_WITH_TARGET = 3,
TARGET_REGION_WITHOUT_TARGET = 4,
TARGET_PARTY = 21,
TARGET_GUILD = 22,
TARGET_CREATURE = 31,
TARGET_PARTY_CREATURE = 32,
TARGET_MASTER = 101,
TARGET_CREATURE_TYPE_NONE = 201,
TARGET_CREATURE_TYPE_FIRE = 202,
TARGET_CREATURE_TYPE_WATER = 203,
TARGET_CREATURE_TYPE_WIND = 204,
TARGET_CREATURE_TYPE_EARTH = 205,
TARGET_CREATURE_TYPE_LIGHT = 206,
TARGET_CREATURE_TYPE_DARK = 207,
};
/// 사용가능/불가/강제 공격 처리
enum
{
USE_SELF = 0, ///< 자신
USE_PARTY, ///< 파티원
USE_GUILD, ///< 길드원
USE_NEUTRAL, ///< 중립
USE_PURPLE, ///< 보라
USE_ENEMY, ///< 적
};
/// 2010.10.13 - prodongi
enum
{
SKILL_TARGET_NONE, /// 불필요
SKILL_TARGET_PLAYER, /// 플레이어
SKILL_TARGET_POSITION, /// 위치
};
int GetID() const { return uid; }
int GetNameID() const { return name_id; }
/// 구현 여부
bool IsValid() const { return is_valid != ST_INVALID; }
/// 귀환 스킬등, 존재하지만 스킬창에 보여지면 안 되는 것
bool IsSystemSkill() const { return is_valid == ST_SYSTEM; }
/// 패시브, 액티브 인가?
bool IsPassive() const { return !is_active; }
/// 물리스킬, 마법 인가?
bool IsPhysicalSkill() const { return !is_spell_act; }
bool IsHarmful() const { return !!is_harmful; }
/// 타겟이 필요한가?
/// 2010.10.13 지면 타겟이 추가‰榮?- prodongi
bool IsNeedTarget() const { return (target_type == SKILL_TARGET_PLAYER); }
char getTargetType() const { return target_type; }
/// 시체가 필요한가?
bool IsValidToCorpse() const { return !!is_corpse; }
/// 토글형 인가?
bool IsToggle() const { return !!is_toggle; }
int GetCastRange() const { return cast_range; }
int GetValidRange() const { return valid_range; }
int GetCastCancelType() const { return cancel_type; }
int GetCastCancelLevel() const { return cancel_level; }
int GetToggleGroup() const { return toggle_group; }
int GetSkillTargetType() const { return target; }
int GetSkillEffectType() const { return effect_type; }
int GetElementalType() const { return elemental; }
bool CheckEffectType( int nFlag ) const { return !!(effect_flag & nFlag); }
bool IsNeedShield() const { return !!vf_shield_only; }
bool IsNeedWeapon() const { return !vf_is_not_need_weapon; }
bool IsUseableWeapon( ItemBase::ItemClass c ) const
{
switch( c )
{
case ItemBase::CLASS_ONEHAND_SWORD : if( vf_one_hand_sword ) return true; break;
case ItemBase::CLASS_TWOHAND_SWORD : if( vf_two_hand_sword ) return true; break;
case ItemBase::CLASS_DOUBLE_DAGGER : if( vf_double_dagger ) return true; break;
case ItemBase::CLASS_DOUBLE_SWORD : if( vf_double_sword ) return true; break;
case ItemBase::CLASS_DAGGER : if( vf_dagger ) return true; break;
case ItemBase::CLASS_TWOHAND_SPEAR : if( vf_spear ) return true; break;
case ItemBase::CLASS_TWOHAND_AXE : if( vf_axe ) return true; break;
case ItemBase::CLASS_ONEHAND_MACE : if( vf_one_hand_mace ) return true; break;
case ItemBase::CLASS_TWOHAND_MACE : if( vf_two_hand_mace ) return true; break;
case ItemBase::CLASS_LIGHT_BOW : if( vf_lightbow ) return true; break;
case ItemBase::CLASS_HEAVY_BOW : if( vf_heavybow ) return true; break;
case ItemBase::CLASS_CROSSBOW : if( vf_crossbow ) return true; break;
<<<<<<< HEAD
case ItemBase::CLASS_ONEHAND_STAFF : if( vf_one_hand_staff ) return true; break;
case ItemBase::CLASS_TWOHAND_STAFF : if( vf_two_hand_staff ) return true; break;
case ItemBase::CLASS_SHIELD : if( vf_shield_only ) return true; break;
case ItemBase::CLASS_ONEHAND_AXE : if( vf_onehand_axe ) return true; break;
case ItemBase::CLASS_DOUBLE_AXE : if( vf_double_axe ) return true; break;
case ItemBase::CLASS_DOUBLE_CROSSBOW: if(vf_crossbow ) return true; break; //Double Crossbow
=======
// AziaMafia Double Crossbow
//case ItemBase::CLASS_DOUBLE_CROSSBOW: if (vf_crossbow) return true; break;
case ItemBase::CLASS_ONEHAND_STAFF : if( vf_one_hand_staff ) return true; break;
case ItemBase::CLASS_TWOHAND_STAFF : if( vf_two_hand_staff ) return true; break;
case ItemBase::CLASS_SHIELD : if( vf_shield_only ) return true; break;
case ItemBase::CLASS_ONEHAND_AXE : if( vf_onehand_axe ) return true; break;
case ItemBase::CLASS_DOUBLE_AXE : if( vf_double_axe ) return true; break;
case ItemBase::CLASS_DOUBLE_CROSSBOW: if( vf_crossbow ) return true; break; // From ZONE source; dual crossbows
>>>>>>> a34328224e914a577b99c79ec6e8ffbcea554a05
default: return false;
}
return false;
}
bool IsUseableOnAvatar() const { return !!tf_avatar; }
bool IsUseableOnMonster() const { return !!tf_monster; }
bool IsUseableOnSummon() const { return !!tf_summon; }
int GetProbabilityOnHit() const { return probability_on_hit; }
int GetProbabilityIncBySLV() const { return probability_inc_by_slv; }
int GetStateId() const { return state_id; }
int GetStateLevel( int skill_lv ) const { return state_level_base+(int)(state_level_per_skl*skill_lv); }
int GetStateSecond( int skill_lv ) const { return (int)( state_second+state_second_per_skl*(skill_lv) ); }
int GetStateEnhanceLv( int Enhance ) const { return state_level_per_enhance*Enhance; }
AR_TIME GetStateEnhanceTime( int Enhance ) const { return state_second_per_enhance*Enhance; }
int GetCostHP( int skill_lv ) const { return cost_hp + cost_hp_per_skl*(skill_lv); }
int GetCostMP( int skill_lv ) const { return cost_mp + cost_mp_per_skl*(skill_lv); }
int GetCostEnergy( int skill_lv ) const { return cost_energy + cost_energy_per_skl*(skill_lv); }
int GetCostItem( int skill_lv ) const { return cost_item + item_count*(skill_lv); }
int GetNeedHP() const { return need_hp; }
int GetNeedMP() const { return need_mp; }
int GetCoolTimeGroup() const { return cool_time_group_id; }
AR_UNIT GetFireRange() const { return valid_range * GameRule::DEFAULT_UNIT_SIZE; }
long GetCoolTime() const { return delay_cooltime; } /// 2011.05.27 AR_TIME -> long - prodongi
long GetCoolTimePerSkill() const { return delay_cooltime_per_skl; }
long GetCommonDelay() const { return delay_common; }
long GetCastDelay( int skill_lv ) const { return delay_cast + delay_cast_per_skl * (skill_lv); } /// 2011.05.27 AR_TIME -> long - prodongi
long GetDelay( int skill_lv ) const { return GetCastDelay( skill_lv ) + GetCommonDelay(); }
int GetPercentage() const { return percentage; }
int GetHitBonus( int enhance ) const { return hit_bonus + enhance * hit_bonus_enhace; }
float GetVar( int idx ) const { return var[idx]; }
float GetVar1() const { return var[0]; }
float GetVar2() const { return var[1]; }
float GetVar3() const { return var[2]; }
float GetVar4() const { return var[3]; }
float GetLvVar(int idx, int lv) const { return var[idx] + var[idx+1]*lv; }
int GetCriticalBonus( int skill_lv ) const { return critical_bonus + critical_bonus_per_skl * skill_lv; }
//스킬효과에 따른 벨류값 얻기 -N4- ==========================================================================================
int GetPower( int nUseLevel ) const { return static_cast<int>( var[0] + nUseLevel * var[1] ); }; ///< 공격력 증가(물리)
int GetPowerRate( int nUseLevel ) const { return static_cast<int>( std::min(var[0] + nUseLevel * var[1], var[2] + nUseLevel * var[3]) * 100 ); }; ///< 공격력 증가율(물리)
int GetRealTimePowerRate( int nUseLevel ) const { return static_cast<int>( (var[0] + nUseLevel * var[1]) * 100 ); }; ///< 실시간연타 공격 공격력증가율(물리)
int GetOneAttackPower( int nUseLevel ) const { return static_cast<int>( var[0] + nUseLevel * var[1] ); }; ///< 공격력 증가(물리 1타)
// int GetPowerDirectByEnhance( int nUseLevel ) const { return static_cast<int>( nEnhance * var[5] ); }; ///< 공격력 증가(물리 방향)
int GetMagicPower( int nUseLevel ) const { return static_cast<int>( var[3] + nUseLevel * var[4] ); }; ///<마력 증가
int GetMagicPowerRate( int nUseLevel ) const { return static_cast<int>( var[0] + nUseLevel * var[1] ); }; ///<마력 증폭
int GetOneAttackMagic( int nUseLevel ) const { return static_cast<int>( var[0] + nUseLevel * var[1] ); }; ///< 공격력 증가(마법 1타)
// int GetMagicAreaByEnhance( int nUseLevel ) const { return static_cast<int>( nEnhance * var[4] ); }; // 공격력 증가(마법 방향)
int DemagePer() const { return static_cast<int>( var[2] ); };
int AddAttackDemage() const { return static_cast<int>( var[2] ); };
int GetPerAbsorptionHP() const { return static_cast<int>( var[2]*100 ); }; ///< 흡수율 HP
int GetPerAbsorptionMP() const { return static_cast<int>( var[3]*100 ); }; ///< 흡수율 MP
int GetPerMagicAbsorptionHP() const { return static_cast<int>( var[2]*100 ); }; ///< 마법 흡수율 HP
int GetPerMagicAbsorptionMP() const { return static_cast<int>( var[3]*100 ); }; ///< 마법 흡수율 MP
int GetAmountAbsorptionHP( int nUseLevel ) const { return static_cast<int>( var[0]+var[1]*nUseLevel ); }; ///< 흡수양 HP
int GetAmountAbsorptionMP( int nUseLevel ) const { return static_cast<int>( var[2]+var[3]*nUseLevel ); }; ///< 흡수양 MP
int GetAmountAbsorptionRate() const { return static_cast<int>( var[6] ); }; ///< 흡수한 값에 대한 회복률
int GetIncreasePower( int nUseLevel ) const { return static_cast<int>( var[0] + nUseLevel * var[1] ); }; ///< 공격력 증폭(물리)
int GetIncreaseOneAttack( int nUseLevel ) const { return static_cast<int>( var[0] + nUseLevel * var[1] ); }; ///< 공격력 증폭(물리 1타)
int GetStateSuccess( int nUseLevel ) const { return probability_on_hit + probability_inc_by_slv * nUseLevel; }; ///< 지속효과 성공률(물리 저주 계열)
AR_TIME GetStateTime( int nUseLevel ) const { return state_second + state_second_per_skl * nUseLevel; }; ///< 지속효과 성공률(물리 저주 계열)
int GetRecovery( int nUseLevel ) const { return static_cast<int>( var[2] + nUseLevel * var[3] ); }; ///< 획복량/회복률
int GetRecoveryStat( int nUseLevel ) const { return static_cast<int>( var[0] + nUseLevel * var[1] * 100 ); }; ///< 획복량/회복률
int GetRecoveryPer( int nUseLevel ) const { return static_cast<int>( var[4] + nUseLevel * var[5] * 100 ); }; ///< 획복량/회복률
int GetRecoveryHP( int nUseLevel ) const { return static_cast<int>( var[2] * nUseLevel ); }; ///< 획복량/회복률
int GetRecoveryStatHP( int nUseLevel ) const { return static_cast<int>( var[0] + nUseLevel * var[1] * 100 ); }; ///< 획복량/회복률
int GetRecoveryPerHP( int nUseLevel ) const { float result(var[3] * nUseLevel * 100.0f); return static_cast<int>( result ); }; ///< 획복량/회복률
int GetRecoveryMP( int nUseLevel ) const { return static_cast<int>( var[7] * nUseLevel ); }; ///< 획복량/회복률
int GetRecoveryStatMP( int nUseLevel ) const { return static_cast<int>( var[5] + nUseLevel * var[6] * 100 ); }; ///< 획복량/회복률
int GetRecoveryPerMP( int nUseLevel ) const { return static_cast<int>( var[8] * nUseLevel * 100 ); }; ///< 획복량/회복률
int GetRecoveryAllHP( int nUseLevel ) const { return static_cast<int>( var[0] + var[1] * nUseLevel ); }; ///< 획복량/회복률
int GetRecoveryAllMP( int nUseLevel ) const { return static_cast<int>( var[2] + var[3] * nUseLevel ); }; ///< 획복량/회복률
int GetRecoveryAllSP( int nUseLevel ) const { return static_cast<int>( var[4] + var[5] * nUseLevel ); }; ///< 획복량/회복률
int GetRecoveryAllRange() const { return static_cast<int>( var[9] ); };
int GetAttackCount( int nUseLevel ) const { return static_cast<int>( var[2] + nUseLevel * var[3] ); }; ///< 연타횟수
int GetSkillLv( int nUseLevel ) const { if( var[2]<nUseLevel ) return 1; if( var[2]*2<nUseLevel ) return 2; else return 3; }; ///< 연타횟수
int GetRealtimeAttackCount( int nUseLevel ) const { return static_cast<int>( var[ GetSkillLv(nUseLevel)+5 ] ); }; ///< 연타횟수
int GetAttackRange() const { return static_cast<int>( var[2] ); }; ///< 범위
int GetMultiAttackRange() const { return static_cast<int>( var[5] ); }; ///< 멀티어택범위
int GetSpecialAttackRange() const { return static_cast<int>( var[8] ); }; ///< 멀티어택범위
int GetMultiAttackKnockBackRange() const { return static_cast<int>( var[6] ); }; ///< 멀티어택범위
int GetTargetCount() const { return static_cast<int>( var[11] ); }; ///< 범위
int GetMultiAttackTargetCount() const { return static_cast<int>( var[7] ); }; ///< 멀티어택범위
int GetSpecialMultiAttackTargetCount() const { return static_cast<int>( var[3] ); }; ///< 특수멀티어택범위
int GetRangeMagicTargetCount() const { return static_cast<int>( var[4] ); }; ///< 범위마법어택가능 몹수
int GetKnockBack( int nUseLevel) const { return static_cast<int>( var[5] + nUseLevel * var[6] ); }; ///< 넉다운거리
int GetMultiAttackKnockBack( int nUseLevel) const { return static_cast<int>( var[10] + nUseLevel * var[11] ); }; ///< 넉다운거리
int GetTamingSuccess( int nUseLevel ) const { return static_cast<int>( var[0] * 100.f ) * nUseLevel; }; ///< 테이밍 성공률
int ResurrectionHP( int nUseLevel ) const { return static_cast<int>( var[0] * 100.f ) * nUseLevel; }; ///< 부활시 MP복구
int ResurrectionMP( int nUseLevel ) const { return static_cast<int>( var[1] * 100.f ) * nUseLevel; }; ///< 부활시 MP복구
int ResurrectionEXP( int nUseLevel ) const { return static_cast<int>( var[2] * 100.f ) * nUseLevel; }; ///< 부활시 EXP복구
int GetAggro( int nUseLevel ) const { return static_cast<int>( var[0] + var[1] * nUseLevel ); }; ///< 헤이트
int GetSuccessRate( int nUseLevel ) const { return static_cast<int>( var[5] + var[6] * nUseLevel ); }; ///< 스킬 성공률
int RemoveStateLv( int nUseLevel ) const{ return static_cast<int>( var[1] * nUseLevel ); }
int RemoveStateID1() const{ return static_cast<int>( var[0] ); }
int RemoveStateID2() const{ return static_cast<int>( var[3] ); }
int RemoveStateID3() const{ return static_cast<int>( var[4] ); }
int RemoveStateID4() const{ return static_cast<int>( var[5] ); }
int RemoveStateID5() const{ return static_cast<int>( var[6] ); }
int RemoveStateID6() const{ return static_cast<int>( var[7] ); }
int AddStateID1() const{ return static_cast<int>( var[0] ); }
int AddStateID2() const{ return static_cast<int>( var[1] ); }
int AddStateID3() const{ return static_cast<int>( var[2] ); }
int AddStateID4() const{ return static_cast<int>( var[3] ); }
int AddStateID5() const{ return static_cast<int>( var[4] ); }
int GetConsumptionMP( int nUseLevel ) const{ return static_cast<int>( var[0] + var[1]*nUseLevel ); }
int GetHate( int nUseLevel ) const{ return hate_basic + nUseLevel * hate_slv; }
// 지속효과 연타 공격력 강화
// int GetStatePowerOneByEnhance( int nUseLevel ) const { return static_cast<int>( nEnhance * var[7] ); };
// 지속효과 마법 공격력 강화
// int GetStateMagicPowerByEnhance( int nUseLevel ) const { return static_cast<int>( nEnhance * var[2] ); };
// 버프/디버프 성능
// int GetStatePowerByEnhance( int nUseLevel ) const { return static_cast<int>( nEnhance * var[2] ); };
// 부활시 EXP 복구률
// int GetExpIncreaseByRevival( int nUseLevel ) const { return static_cast<int>( var[3] * 100.f ) * nEnhance; };
// HP 흡수량
// int GetAbsorptionHPPointByEnhance( int nUseLevel ) const { return static_cast<int>( nEnhance * var[4] ); };
// MP 흡수량
// int GetAbsorptionMPPointByEnhance( int nUseLevel ) const { return static_cast<int>( nEnhance * var[5] ); };
// 테이밍 성공률
// int GetTamingSuccessByEnhance( int nUseLevel ) const { return static_cast<int>( var[1] * 100.f ) * nEnhance; };
// 초당 mp 소모
// int GetCostMPPerSecondByEnhance( int nUseLevel ) const { return static_cast<int>( nEnhance * var[2] ); };
// ===============================================================================================================================
// 강화 단계에 따른 수치 ========================
// 카드/스킬 공통
/// MP 소모
int GetCostMPByEnhance( int nEnhance ) const { return cost_mp_per_enhance * nEnhance; }
/// 캐스팅 증가율
int GetCastDelayByEnhancePer( int nEnhance ) const { return static_cast<int>( delay_cast_mod_per_enhance * 100.f ) * nEnhance; }
float GetCastDelayByEnhance( int nEnhance ) const { return delay_cast_mod_per_enhance * nEnhance; }
/// 쿨타임 증가율
int GetCoolTimeByEnhancePer( int nEnhance ) const { return static_cast<int>( delay_cooltime_mod_per_enhance * 100.f ) * nEnhance; }
float GetCoolTimeByEnhance( int nEnhance ) const { return delay_cooltime_mod_per_enhance * nEnhance; }
/// 지속효과 레벨
int GetStateLevelByEnhance( int nEnhance )const { return static_cast<int>( state_level_per_enhance * nEnhance ); }
/// 명중 보너스
int GetHitBonusByEnhance( int nEnhance ) const { return hit_bonus_enhace * nEnhance; };
/// 지속효과 시간
AR_TIME GetStateSecondByEnhance( int nEnhance )const{ return state_second_per_enhance * nEnhance; }
/// 헤이트 수치
int GetHateByEnhance( int nEnhance )const{ return nEnhance * hate_enhance; }
// ===================
/// 공격력 증가(물리)
int GetPowerByEnhance( int nEnhance ) const { return static_cast<int>( nEnhance * var[4] ); };
/// 공격력 증가율(물리)
int GetPowerLimitRateByEnhance( int nEnhance ) const { return static_cast<int>( std::min(var[5],nEnhance * var[4]) * 100 ); };
/// 실시간 연타 공격 공격력 증가율(물리)
int GetPowerRateByEnhance( int nEnhance ) const { return static_cast<int>( var[5] * 100 ); };
/// 공격력 증가(물리 1타)
int GetPowerOneByEnhance( int nEnhance ) const { return static_cast<int>( nEnhance * var[5] ); };
/// 공격력 증가(물리 방향)
int GetPowerDirectByEnhance( int nEnhance ) const { return static_cast<int>( nEnhance * var[5] ); };
/// 공격력 증가(타겟 중심 범위 연타)
int GetPowerMultipleRange( int nEnhance ) const { return static_cast<int>( nEnhance * var[8] ); };
/// 공격력 증가(마법)
int GetMagicByEnhance( int nEnhance ) const { return static_cast<int>( nEnhance * var[5] ); };
/// 공격력 증폭(마법)
int GetMagicRateByEnhance( int nEnhance ) const { return static_cast<int>( nEnhance * var[3] ); };
/// 공격력 증가(마법)
int GetSpecialMagicByEnhance( int nEnhance ) const { return static_cast<int>( nEnhance * var[4] ); };
/// 공격력 증가(마법 1타)
int GetMagicOneByEnhance( int nEnhance ) const { return static_cast<int>( nEnhance * var[5] ); };
/// 실시간 연타 공격 공격력 증가율(마법)
int GetMagicMultiRateByEnhance( int nEnhance ) const { return static_cast<int>( var[5] * 100 ); };
/// 공격력 증가(실시간 연타 타겟 중심 범위)
int GetMagicMultipleRange( int nEnhance ) const { return static_cast<int>( nEnhance * var[8] ); };
/// 공격력 증가(마법)
int GetMagicRangeStateDemageByEnhance( int nEnhance ) const { return static_cast<int>( nEnhance * var[7] ); };
// 공격력 증가율(마법)
// int GetMagicRateByEnhance( int nEnhance ) const { return static_cast<int>( std::min(var[5],nEnhance * var[4]) ) * 100; };
/// 공격력 증가(마법 방향)
int GetMagicAreaByEnhance( int nEnhance ) const { return static_cast<int>( nEnhance * var[4] ); };
/// 데미지율 증가
int GetDemagePerByEnhance( int nEnhance ) const { return static_cast<int>( nEnhance * var[8] ); };
/// 흡수율 HP
int GetAbsorptionHPByEnhance( int nEnhance ) const { return static_cast<int>( var[4] * 100.f ) * nEnhance; };
/// 흡수율 MP
int GetAbsorptionMPByEnhance( int nEnhance ) const { return static_cast<int>( var[5] * 100.f ) * nEnhance; };
/// 마법 흡수율 HP
int GetMagicAbsorptionHPByEnhance( int nEnhance ) const { return static_cast<int>( var[4] * 100.f ) * nEnhance; };
/// 마법 흡수율 MP
int GetMagicAbsorptionMPByEnhance( int nEnhance ) const { return static_cast<int>( var[5] * 100.f ) * nEnhance; };
/// 공격력 증폭(물리)
int GetIncreaseByEnhance( int nEnhance ) const { return static_cast<int>( var[4] * 100.f ) * nEnhance; };
/// 공격력 증폭(물리 1타)
int GetIncreaseOneByEnhance( int nEnhance ) const { return static_cast<int>( var[5] * 100.f ) * nEnhance; };
int GetIncreaseAttackRange( int nEnhance ) const { return static_cast<int>( var[7]*nEnhance ); }; // 범위
int GetIncreaseMultiAttackRange( int nEnhance ) const { return static_cast<int>( var[9]*nEnhance ); }; // 멀티어택범위
int GetIncreaseKnockBack( int nEnhance ) const { return static_cast<int>( nEnhance * var[7] ); }; // 범위
/// 지속효과 성공률(물리 저주 계열)
int GetStateSuccessByEnhance( int nEnhance ) const { return static_cast<int>( nEnhance * var[5] ); };
/// 지속효과 연타 공격력 강화
int GetStatePowerOneByEnhance( int nEnhance ) const { return static_cast<int>( nEnhance * var[7] ); };
/// 지속효과 마법 공격력 강화
int GetStateMagicPowerByEnhance( int nEnhance ) const { return static_cast<int>( nEnhance * var[2] ); };
/// 버프/디버프 성능
int GetStatePowerByEnhance( int nEnhance ) const { return static_cast<int>( nEnhance * var[2] ); };
/// 획복량/회복률
int GetRecoveryByEnhance( int nEnhance ) const { return static_cast<int>( nEnhance * var[6] ); };
int GetRecoveryPerByEnhance( int nEnhance ) const { return static_cast<int>( var[7] * 100.f ) * nEnhance; };
int GetRecoveryHPByEnhance( int nEnhance ) const { return static_cast<int>( nEnhance * var[4] ); };
int GetRecoveryMPByEnhance( int nEnhance ) const { return static_cast<int>( nEnhance * var[9] ); };
/// 획복량/회복률
int GetRecoveryAllPerByEnhance( int nEnhance ) const { return static_cast<int>( var[11] * nEnhance * 100 ); };
/// 회복률
int GetAmountAbsorptionRateByEnhance( int nEnhance ) const { return static_cast<int>( var[7] * nEnhance ); };
/// 부활시 EXP 복구률
int GetExpIncreaseByRevival( int nEnhance ) const { return static_cast<int>( var[3] * 100.f ) * nEnhance; };
/// 지속효과 제거 레벨
int GetRemoveStateLvByEnhance( int nEnhance ) const { return static_cast<int>( var[2]* nEnhance ); };
/// MP소모량
int GetConsumptionMPByEnhance( int nUseLevel ) const{ return static_cast<int>( var[2]*nUseLevel ); }
/// HP 흡수량
int GetAbsorptionHPPointByEnhance( int nEnhance ) const { return static_cast<int>( nEnhance * var[4] ); };
/// MP 흡수량
int GetAbsorptionMPPointByEnhance( int nEnhance ) const { return static_cast<int>( nEnhance * var[5] ); };
/// 테이밍 성공률
int GetTamingSuccessByEnhance( int nEnhance ) const { return static_cast<int>( var[1] * 100.f ) * nEnhance; };
/// 초당 mp 소모
int GetCostMPPerSecondByEnhance( int nEnhance ) const { return static_cast<int>( nEnhance * var[2] ); };
/// 헤이트
int GetAggroByEnhance( int nEnhance ) const { return static_cast<int>( var[7] * nEnhance ); };
/// 스킬 성공률
int GetSuccessRateByEnhance( int nEnhance ) const { return static_cast<int>( var[9] * nEnhance * 100 ); };
// ==============================================
int GetNeedJopPoint( int skill_lv ) const
{
if( skill_lv >= MAX_SKILL_LEVEL ) return need_jp[ MAX_SKILL_LEVEL - 1 ];
return need_jp[ skill_lv - 1 ];
}
void SetNeedJopPoint( int skill_lv, int jp )
{
if( skill_lv >= MAX_SKILL_LEVEL ) return;
need_jp[ skill_lv - 1 ] = jp;
}
/// 사용가능/불가/강제 공격 처리 - 가져다 쓰는게 애매하다..
char GetUseAble( char nUseIndex )
{
switch( nUseIndex )
{
case USE_SELF : return uf_self; ///< 자신
case USE_PARTY : return uf_party; ///< 파티원
case USE_GUILD : return uf_guild; ///< 길드원
case USE_NEUTRAL : return uf_neutral; ///< 중립
case USE_PURPLE : return uf_purple; ///< 보라
case USE_ENEMY : return uf_enemy; ///< 적
}
return 0; //사용 원천 불가
}
/// 효과 타입
int GetEffectType() const { return effect_type; }
/** 헤이트 비율
-1 : 데미지와 무관하게 일정값이 적용 ([헤이트], [SLv:헤이트] 수치로 적용)
0 : 헤이트 부가 안함
0 : 데미지, 힐량과 비례하여 값을 비율로 적용 (부가할 헤이트 = 데미지 * [헤이트비율]) (옆의 두 값은 무시한다) */
int GetHatePoint( int lv, int point, int enhance ) const
{
if( hate_mod == 0 ) return 0;
if( hate_mod < 0 ) return (int)( hate_basic + lv * hate_slv + enhance * hate_enhance );
return (int)( hate_basic + point * hate_mod );
}
int uid; ///< id
int name_id;
char is_valid; ///< 구현 여부
char elemental; ///< 무속성 0 화속성 1 수속성 2 풍속성 3 토속성 4 명속성 5 암속성 6
char is_active; ///< 액티브 스킬이면 1
char is_spell_act; ///< 전투기술이면 0, 마법이면 1
char is_harmful; ///< 피해를 주는 스킬이면 1
/// 2010.10.13 지면 타겟이 추가되서 변수 명이 안맞아 수정함 - prodongi
char target_type; ///< 타겟팅 타입
char is_corpse; ///< 시체에게 사용가능?
char is_toggle; ///< 토글형 스킬?
char cancel_type; ///< 캐스팅 캔슬 타입
char cancel_level; ///< 캐스팅 캔슬 위험도
int toggle_group; ///< 토글 그룹
int cast_range; ///< 캐스트 가능 거리
int valid_range; ///< 유효 적용 거리, 캐스트 시전중 타겟과의 거리가 valid_range 보다 커지면, 시전 취소
int cost_hp;
int cost_hp_per_skl;
int cost_mp; ///< mp
int cost_mp_per_skl; ///< 스킬레벨당 mp
int cost_mp_per_enhance; ///< 스킬레벨당 mp
float cost_hp_per; ///< DECIMAL(10, 2) -- 23
float cost_hp_per_skl_per; ///< DECIMAL(10, 2) -- 24
float cost_mp_per; ///< DECIMAL(10, 2) -- 25
float cost_mp_per_skl_per; ///< DECIMAL(10, 2) -- 26
int cost_havoc; // 사용하지 않음
int cost_havoc_per_skl; // 사용하지 않음
int cost_energy;
int cost_energy_per_skl;
int cost_exp;
int cost_exp_per_enhance;
int cost_jp;
int cost_jp_per_enhance;
int cost_item;
int item_count;
int cost_item_count_per_skl;
int need_level;
int need_hp;
int need_mp;
int need_havoc; // 사용하지 않음
int need_havoc_burst; // 사용하지 않음
int need_state_id;
char need_state_level;
char need_state_exhaust;
char vf_one_hand_sword;
char vf_two_hand_sword;
char vf_double_sword;
char vf_dagger;
char vf_double_dagger;
char vf_spear;
char vf_axe;
char vf_onehand_axe; ///< CHAR NOT NULL, -- 53
char vf_double_axe; ///< CHAR NOT NULL, -- 54
char vf_one_hand_mace;
char vf_two_hand_mace;
char vf_lightbow;
char vf_heavybow;
char vf_crossbow;
char vf_one_hand_staff;
char vf_two_hand_staff;
char vf_shield_only;
char vf_is_not_need_weapon;
long delay_cast; /// 2011.05.27 AR_TIME -> long - prodongi
long delay_cast_per_skl;
float delay_cast_mod_per_enhance;
long delay_common; /// 2011.05.27 AR_TIME -> long - prodongi
long delay_cooltime; /// 2011.04.27 AR_TIME -> long - prodongi
long delay_cooltime_per_skl; /// 2011.01.12 - prodongi
float delay_cooltime_mod_per_enhance;
int cool_time_group_id;
// 자신 파티원 길드원 중립 보라 적 아바타 소환수 몬스터
char uf_self;
char uf_party;
char uf_guild;
char uf_neutral;
char uf_purple;
char uf_enemy;
char tf_avatar;
char tf_summon;
char tf_monster;
int skill_lvup_limit; //스킬 레벨 증가 적용 제한
short target; /// 효과 대상
short effect_type; ///< 효과 타임, 스킬 유형
int skill_enchant_link_id; /// 2011.04.15 강화스킬 대상 스킬 ID - prodongi
int state_id; /// 지속 효과 id
int state_level_base; ///< INT NOT NULL, -- 83, 기본 지속 효과
float state_level_per_skl;
float state_level_per_enhance;
AR_TIME state_second;
AR_TIME state_second_per_skl;
AR_TIME state_second_per_enhance;
int probability_on_hit;
int probability_inc_by_slv;
short hit_bonus;
short hit_bonus_enhace;
short percentage;
float hate_mod;
int hate_basic;
float hate_slv;
float hate_enhance;
int critical_bonus; ///< 크리율 증가
int critical_bonus_per_skl; ///< 레벨당 크리율 증가
float var[MAX_SKILL_VALUE];
int need_jp[ MAX_SKILL_LEVEL ];
char effect_flag;
};
#pragma pack( pop )
//------------------------------------------------------------------------------------------------------
// 소환수 (크리쳐) 랜덤 스킬
//------------------------------------------------------------------------------------------------------
struct SummonRandomSkillBase
{
int skill_group_id; // 스킬 그룹 ID ( Unique ID ) 1
int skill_count; // 스킬 개수 ( 최대 4개 ) 2
// int skill_id[4]; // 스킬 ID - 1번 ~ 4번 3
int skill_id[15]; // 스킬 ID - 1번 ~ 15번 3
SummonRandomSkillBase()
: skill_group_id( NULL )
, skill_count( NULL )
{
ZeroMemory( skill_id, sizeof( skill_id ) );
}
};
//------------------------------------------------------------------------------------------------------
// 스킬 트리 (DB 로부터 읽어드리는 데이터)
//------------------------------------------------------------------------------------------------------
struct SkillTree
{
int skill_tree_id ; // 스킬트리아이디 1
int skill_id ; // 스킬아이디 2
int skill_group_id ; // 스킬 그룹 ID 3
int min_skill_lv ; // 스킬 최소 레벨 4
int max_skill_lv ; // 스킬 최대 레벨 5
int lv ; // 스킬 학습 레벨 6
int jop_lv ; // 스킬 학습 직업 레벨 7
float jp_ratio ; // 스킬 JP 소모 비율 8
int need_skill_id[3] ; // 필요 스킬 아이디 9 ~ 11
int need_skill_lv[3] ; // 필요 스킬 레벨 12 ~ 14
int cenhance_min ; // 크리쳐 강화 최소값 15
int cenhance_max ; // 크리쳐 강화 최대값 16
SkillTree()
: skill_tree_id( NULL )
, skill_id( NULL )
, skill_group_id( NULL )
, min_skill_lv( NULL )
, max_skill_lv( NULL )
, lv( NULL )
, jop_lv( NULL )
, jp_ratio( 0.0f )
, cenhance_min( NULL )
, cenhance_max( NULL )
{
ZeroMemory( need_skill_id, sizeof( need_skill_id ) );
ZeroMemory( need_skill_lv, sizeof( need_skill_lv ) );
}
};
//------------------------------------------------------------------------------------------------------
// 스킬 트리 확장 (클라이언트에서 추가 필요한 데이터)
//------------------------------------------------------------------------------------------------------
struct SkillTreeEx : public SkillTree
{
bool bIsRandomSkill; // 랜덤 스킬인가?
int nChangedSkillID; // 랜덤 스킬로 부터 변경 된 스킬 아이디
SkillTreeEx()
: bIsRandomSkill( false )
, nChangedSkillID( NULL )
{
}
SkillTreeEx( SkillTree& stSkillTree )
: bIsRandomSkill( false )
, nChangedSkillID( NULL )
{
skill_tree_id = stSkillTree.skill_tree_id;
skill_id = stSkillTree.skill_id;
skill_group_id = stSkillTree.skill_group_id;
min_skill_lv = stSkillTree.min_skill_lv;
max_skill_lv = stSkillTree.max_skill_lv;
lv = stSkillTree.lv;
jop_lv = stSkillTree.jop_lv;
jp_ratio = stSkillTree.jp_ratio;
cenhance_min = stSkillTree.cenhance_min;
cenhance_max = stSkillTree.cenhance_max;
memcpy( need_skill_id, stSkillTree.need_skill_id, sizeof(need_skill_id) ); //gmpbigsun( 20130404, #26732 )
memcpy( need_skill_lv, stSkillTree.need_skill_lv, sizeof(need_skill_lv) );
}
};
//------------------------------------------------------------------------------------------------------
// 스킬 트리 ( Display )
//------------------------------------------------------------------------------------------------------
struct SkillTreeDisplay
{
int job_id; // 잡 ID
int slot_v; // 슬롯 위치1~9
int skill1_id; // 스킬 ID
int skill2_id; // 스킬 ID
int skill3_id; // 스킬 ID
int skill4_id; // 스킬 ID
int skill5_id; // 스킬 ID
SkillTreeDisplay()
: job_id( NULL )
, slot_v( NULL )
, skill1_id( NULL )
, skill2_id( NULL )
, skill3_id( NULL )
, skill4_id( NULL )
, skill5_id( NULL )
{
}
};
#pragma pack( 1 )
/// 스킬 사용 결과
struct SkillResult
{
enum
{
// type
DAMAGE = 0,
MAGIC_DAMAGE = 1,
DAMAGE_WITH_KNOCK_BACK = 2,
RESULT = 10,
ADD_HP = 20, ///< HP가 소모될 때도 사용
ADD_MP = 21, ///< MP가 소모될 때도 사용
ADD_HP_MP_SP = 22,
REBIRTH = 23,
RUSH = 30,
/// 2011.03.22 - prodongi
CHAIN_DAMAGE = 40,
CHAIN_MAGIC_DAMAGE = 41,
CHAIN_HEAL = 42,
NOT_USE = 100,
};
enum
{
// ResultType의 SuccessType
ADD_STATE = 10,
REMOVE_STATE = 11,
ADD_HATE = 12,
TURN_ON = 21,
TURN_OFF = 22,
SUMMON_DEAD = 30,
TARGET_DEAD = 31,
CREATE_ITEM = 40,
};
enum
{
// Damage Type의 flag
CRITICAL = ( 1 << 0 ),
MISS = ( 1 << 1 ),
BLOCK = ( 1 << 2 ),
PERFECT_BLOCK = ( 1 << 3 ),
};
int GetType() const { return damage.type; }
AR_HANDLE GetTargetHandle() const { return damage.hTarget; }
int GetDamage() const { return damage.damage; }
struct DamageType
{
unsigned char type;
AR_HANDLE hTarget;
int target_hp;
char damage_type;
int damage;
int flag;
unsigned short elemental_damage[ CreatureElemental::ElementalCount ];
};
struct DamageWithKnockBackType
{
unsigned char type;
AR_HANDLE hTarget;
int target_hp;
char damage_type;
int damage;
int flag;
unsigned short elemental_damage[ CreatureElemental::ElementalCount ];
AR_UNIT x, y;
unsigned char speed;
AR_TIME knock_back_time;
};
struct ResultType
{
unsigned char type;
AR_HANDLE hTarget;
bool bResult;
int success_type;
};
/// Add MP 도 동일하게 사용
struct AddHPType
{
unsigned char type;
AR_HANDLE hTarget;
int target_hp;
int nIncHP;
};
struct AddHPMPSPType
{
unsigned char type;
AR_HANDLE hTarget;
int target_hp;
int nIncHP;
int nIncMP;
int nIncSP;
int target_mp;
};
struct RushType
{
unsigned char type;
AR_HANDLE hTarget;
bool bResult;
AR_UNIT x, y;
float face;
unsigned char speed;
};
struct RebirthType
{
unsigned char type;
AR_HANDLE hTarget;
int target_hp;
int nIncHP;
int nIncMP;
int nRecoveryEXP;
short target_mp;
};
/// 2011.03.22 - prodongi
struct ChainDamageType
{
unsigned char type;
AR_HANDLE hTarget;
int target_hp;
char damage_type;
int damage;
int flag;
unsigned short elemental_damage[ CreatureElemental::ElementalCount ];
AR_HANDLE hFrom;
};
struct ChainHealType
{
unsigned char type;
AR_HANDLE hTarget;
int target_hp;
int nIncHP;
AR_HANDLE hFrom;
};
/// 서버에서 공용으로 사용하기 위한 데이터
union
{
DamageType damage;
DamageWithKnockBackType damage_kb;
ResultType result;
AddHPType add_hp;
AddHPMPSPType add_hp_mp_sp;
RushType rush;
RebirthType rebirth;
/// 2011.03.22 - prodongi
ChainDamageType chain_damage;
ChainHealType chain_heal;
};
SkillResult()
{
damage.damage = 0;
damage.target_hp = 0;
damage_kb.damage = 0;
damage_kb.target_hp = 0;
add_hp.hTarget = 0;
add_hp.nIncHP = 0;
add_hp.target_hp = 0;
add_hp_mp_sp.hTarget = 0;
add_hp_mp_sp.nIncHP = 0;
add_hp_mp_sp.nIncMP = 0;
add_hp_mp_sp.nIncSP = 0;
add_hp_mp_sp.target_hp = 0;
add_hp_mp_sp.target_mp = 0;
rebirth.target_hp = 0;
rebirth.target_mp = 0;
// 2010.08.30 - prodongi
memset(damage.elemental_damage, 0, sizeof( damage.elemental_damage));
memset(damage_kb.elemental_damage, 0, sizeof (damage_kb.elemental_damage));
}
};
struct ATTACK_INFO
{
int damage; ///< -1 이면 MISS, -2 면 failed, -3이면 너무 멀리 떨어져 있음, -4면 너무 빨리 공격했음 (스핵?)
int mp_damage;
unsigned char flag;
int elemental_damage[ CreatureElemental::COUNT ]; ///< 추가데미지
int target_hp;
int target_mp;
int attacker_damage;
int attacker_mp_damage;
int attacker_hp;
int attacker_mp;
ATTACK_INFO()
{
damage = 0;
mp_damage = 0;
flag = 0;
memset( elemental_damage, 0, sizeof( elemental_damage ) );
target_hp = 0;
target_mp = 0;
attacker_damage = 0;
attacker_mp_damage = 0;
attacker_hp = 0;
attacker_mp = 0;
}
};
#pragma pack()