#pragma once #include #include #include "ItemBase.h" #include "CreatureBase.h" #include "GameRule.h" //#include #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( var[0] + nUseLevel * var[1] ); }; ///< 공격력 증가(물리) int GetPowerRate( int nUseLevel ) const { return static_cast( std::min(var[0] + nUseLevel * var[1], var[2] + nUseLevel * var[3]) * 100 ); }; ///< 공격력 증가율(물리) int GetRealTimePowerRate( int nUseLevel ) const { return static_cast( (var[0] + nUseLevel * var[1]) * 100 ); }; ///< 실시간연타 공격 공격력증가율(물리) int GetOneAttackPower( int nUseLevel ) const { return static_cast( var[0] + nUseLevel * var[1] ); }; ///< 공격력 증가(물리 1타) // int GetPowerDirectByEnhance( int nUseLevel ) const { return static_cast( nEnhance * var[5] ); }; ///< 공격력 증가(물리 방향) int GetMagicPower( int nUseLevel ) const { return static_cast( var[3] + nUseLevel * var[4] ); }; ///<마력 증가 int GetMagicPowerRate( int nUseLevel ) const { return static_cast( var[0] + nUseLevel * var[1] ); }; ///<마력 증폭 int GetOneAttackMagic( int nUseLevel ) const { return static_cast( var[0] + nUseLevel * var[1] ); }; ///< 공격력 증가(마법 1타) // int GetMagicAreaByEnhance( int nUseLevel ) const { return static_cast( nEnhance * var[4] ); }; // 공격력 증가(마법 방향) int DemagePer() const { return static_cast( var[2] ); }; int AddAttackDemage() const { return static_cast( var[2] ); }; int GetPerAbsorptionHP() const { return static_cast( var[2]*100 ); }; ///< 흡수율 HP int GetPerAbsorptionMP() const { return static_cast( var[3]*100 ); }; ///< 흡수율 MP int GetPerMagicAbsorptionHP() const { return static_cast( var[2]*100 ); }; ///< 마법 흡수율 HP int GetPerMagicAbsorptionMP() const { return static_cast( var[3]*100 ); }; ///< 마법 흡수율 MP int GetAmountAbsorptionHP( int nUseLevel ) const { return static_cast( var[0]+var[1]*nUseLevel ); }; ///< 흡수양 HP int GetAmountAbsorptionMP( int nUseLevel ) const { return static_cast( var[2]+var[3]*nUseLevel ); }; ///< 흡수양 MP int GetAmountAbsorptionRate() const { return static_cast( var[6] ); }; ///< 흡수한 값에 대한 회복률 int GetIncreasePower( int nUseLevel ) const { return static_cast( var[0] + nUseLevel * var[1] ); }; ///< 공격력 증폭(물리) int GetIncreaseOneAttack( int nUseLevel ) const { return static_cast( 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( var[2] + nUseLevel * var[3] ); }; ///< 획복량/회복률 int GetRecoveryStat( int nUseLevel ) const { return static_cast( var[0] + nUseLevel * var[1] * 100 ); }; ///< 획복량/회복률 int GetRecoveryPer( int nUseLevel ) const { return static_cast( var[4] + nUseLevel * var[5] * 100 ); }; ///< 획복량/회복률 int GetRecoveryHP( int nUseLevel ) const { return static_cast( var[2] * nUseLevel ); }; ///< 획복량/회복률 int GetRecoveryStatHP( int nUseLevel ) const { return static_cast( var[0] + nUseLevel * var[1] * 100 ); }; ///< 획복량/회복률 int GetRecoveryPerHP( int nUseLevel ) const { float result(var[3] * nUseLevel * 100.0f); return static_cast( result ); }; ///< 획복량/회복률 int GetRecoveryMP( int nUseLevel ) const { return static_cast( var[7] * nUseLevel ); }; ///< 획복량/회복률 int GetRecoveryStatMP( int nUseLevel ) const { return static_cast( var[5] + nUseLevel * var[6] * 100 ); }; ///< 획복량/회복률 int GetRecoveryPerMP( int nUseLevel ) const { return static_cast( var[8] * nUseLevel * 100 ); }; ///< 획복량/회복률 int GetRecoveryAllHP( int nUseLevel ) const { return static_cast( var[0] + var[1] * nUseLevel ); }; ///< 획복량/회복률 int GetRecoveryAllMP( int nUseLevel ) const { return static_cast( var[2] + var[3] * nUseLevel ); }; ///< 획복량/회복률 int GetRecoveryAllSP( int nUseLevel ) const { return static_cast( var[4] + var[5] * nUseLevel ); }; ///< 획복량/회복률 int GetRecoveryAllRange() const { return static_cast( var[9] ); }; int GetAttackCount( int nUseLevel ) const { return static_cast( var[2] + nUseLevel * var[3] ); }; ///< 연타횟수 int GetSkillLv( int nUseLevel ) const { if( var[2]( var[ GetSkillLv(nUseLevel)+5 ] ); }; ///< 연타횟수 int GetAttackRange() const { return static_cast( var[2] ); }; ///< 범위 int GetMultiAttackRange() const { return static_cast( var[5] ); }; ///< 멀티어택범위 int GetSpecialAttackRange() const { return static_cast( var[8] ); }; ///< 멀티어택범위 int GetMultiAttackKnockBackRange() const { return static_cast( var[6] ); }; ///< 멀티어택범위 int GetTargetCount() const { return static_cast( var[11] ); }; ///< 범위 int GetMultiAttackTargetCount() const { return static_cast( var[7] ); }; ///< 멀티어택범위 int GetSpecialMultiAttackTargetCount() const { return static_cast( var[3] ); }; ///< 특수멀티어택범위 int GetRangeMagicTargetCount() const { return static_cast( var[4] ); }; ///< 범위마법어택가능 몹수 int GetKnockBack( int nUseLevel) const { return static_cast( var[5] + nUseLevel * var[6] ); }; ///< 넉다운거리 int GetMultiAttackKnockBack( int nUseLevel) const { return static_cast( var[10] + nUseLevel * var[11] ); }; ///< 넉다운거리 int GetTamingSuccess( int nUseLevel ) const { return static_cast( var[0] * 100.f ) * nUseLevel; }; ///< 테이밍 성공률 int ResurrectionHP( int nUseLevel ) const { return static_cast( var[0] * 100.f ) * nUseLevel; }; ///< 부활시 MP복구 int ResurrectionMP( int nUseLevel ) const { return static_cast( var[1] * 100.f ) * nUseLevel; }; ///< 부활시 MP복구 int ResurrectionEXP( int nUseLevel ) const { return static_cast( var[2] * 100.f ) * nUseLevel; }; ///< 부활시 EXP복구 int GetAggro( int nUseLevel ) const { return static_cast( var[0] + var[1] * nUseLevel ); }; ///< 헤이트 int GetSuccessRate( int nUseLevel ) const { return static_cast( var[5] + var[6] * nUseLevel ); }; ///< 스킬 성공률 int RemoveStateLv( int nUseLevel ) const{ return static_cast( var[1] * nUseLevel ); } int RemoveStateID1() const{ return static_cast( var[0] ); } int RemoveStateID2() const{ return static_cast( var[3] ); } int RemoveStateID3() const{ return static_cast( var[4] ); } int RemoveStateID4() const{ return static_cast( var[5] ); } int RemoveStateID5() const{ return static_cast( var[6] ); } int RemoveStateID6() const{ return static_cast( var[7] ); } int AddStateID1() const{ return static_cast( var[0] ); } int AddStateID2() const{ return static_cast( var[1] ); } int AddStateID3() const{ return static_cast( var[2] ); } int AddStateID4() const{ return static_cast( var[3] ); } int AddStateID5() const{ return static_cast( var[4] ); } int GetConsumptionMP( int nUseLevel ) const{ return static_cast( var[0] + var[1]*nUseLevel ); } int GetHate( int nUseLevel ) const{ return hate_basic + nUseLevel * hate_slv; } // 지속효과 연타 공격력 강화 // int GetStatePowerOneByEnhance( int nUseLevel ) const { return static_cast( nEnhance * var[7] ); }; // 지속효과 마법 공격력 강화 // int GetStateMagicPowerByEnhance( int nUseLevel ) const { return static_cast( nEnhance * var[2] ); }; // 버프/디버프 성능 // int GetStatePowerByEnhance( int nUseLevel ) const { return static_cast( nEnhance * var[2] ); }; // 부활시 EXP 복구률 // int GetExpIncreaseByRevival( int nUseLevel ) const { return static_cast( var[3] * 100.f ) * nEnhance; }; // HP 흡수량 // int GetAbsorptionHPPointByEnhance( int nUseLevel ) const { return static_cast( nEnhance * var[4] ); }; // MP 흡수량 // int GetAbsorptionMPPointByEnhance( int nUseLevel ) const { return static_cast( nEnhance * var[5] ); }; // 테이밍 성공률 // int GetTamingSuccessByEnhance( int nUseLevel ) const { return static_cast( var[1] * 100.f ) * nEnhance; }; // 초당 mp 소모 // int GetCostMPPerSecondByEnhance( int nUseLevel ) const { return static_cast( nEnhance * var[2] ); }; // =============================================================================================================================== // 강화 단계에 따른 수치 ======================== // 카드/스킬 공통 /// MP 소모 int GetCostMPByEnhance( int nEnhance ) const { return cost_mp_per_enhance * nEnhance; } /// 캐스팅 증가율 int GetCastDelayByEnhancePer( int nEnhance ) const { return static_cast( 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( 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( 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( nEnhance * var[4] ); }; /// 공격력 증가율(물리) int GetPowerLimitRateByEnhance( int nEnhance ) const { return static_cast( std::min(var[5],nEnhance * var[4]) * 100 ); }; /// 실시간 연타 공격 공격력 증가율(물리) int GetPowerRateByEnhance( int nEnhance ) const { return static_cast( var[5] * 100 ); }; /// 공격력 증가(물리 1타) int GetPowerOneByEnhance( int nEnhance ) const { return static_cast( nEnhance * var[5] ); }; /// 공격력 증가(물리 방향) int GetPowerDirectByEnhance( int nEnhance ) const { return static_cast( nEnhance * var[5] ); }; /// 공격력 증가(타겟 중심 범위 연타) int GetPowerMultipleRange( int nEnhance ) const { return static_cast( nEnhance * var[8] ); }; /// 공격력 증가(마법) int GetMagicByEnhance( int nEnhance ) const { return static_cast( nEnhance * var[5] ); }; /// 공격력 증폭(마법) int GetMagicRateByEnhance( int nEnhance ) const { return static_cast( nEnhance * var[3] ); }; /// 공격력 증가(마법) int GetSpecialMagicByEnhance( int nEnhance ) const { return static_cast( nEnhance * var[4] ); }; /// 공격력 증가(마법 1타) int GetMagicOneByEnhance( int nEnhance ) const { return static_cast( nEnhance * var[5] ); }; /// 실시간 연타 공격 공격력 증가율(마법) int GetMagicMultiRateByEnhance( int nEnhance ) const { return static_cast( var[5] * 100 ); }; /// 공격력 증가(실시간 연타 타겟 중심 범위) int GetMagicMultipleRange( int nEnhance ) const { return static_cast( nEnhance * var[8] ); }; /// 공격력 증가(마법) int GetMagicRangeStateDemageByEnhance( int nEnhance ) const { return static_cast( nEnhance * var[7] ); }; // 공격력 증가율(마법) // int GetMagicRateByEnhance( int nEnhance ) const { return static_cast( std::min(var[5],nEnhance * var[4]) ) * 100; }; /// 공격력 증가(마법 방향) int GetMagicAreaByEnhance( int nEnhance ) const { return static_cast( nEnhance * var[4] ); }; /// 데미지율 증가 int GetDemagePerByEnhance( int nEnhance ) const { return static_cast( nEnhance * var[8] ); }; /// 흡수율 HP int GetAbsorptionHPByEnhance( int nEnhance ) const { return static_cast( var[4] * 100.f ) * nEnhance; }; /// 흡수율 MP int GetAbsorptionMPByEnhance( int nEnhance ) const { return static_cast( var[5] * 100.f ) * nEnhance; }; /// 마법 흡수율 HP int GetMagicAbsorptionHPByEnhance( int nEnhance ) const { return static_cast( var[4] * 100.f ) * nEnhance; }; /// 마법 흡수율 MP int GetMagicAbsorptionMPByEnhance( int nEnhance ) const { return static_cast( var[5] * 100.f ) * nEnhance; }; /// 공격력 증폭(물리) int GetIncreaseByEnhance( int nEnhance ) const { return static_cast( var[4] * 100.f ) * nEnhance; }; /// 공격력 증폭(물리 1타) int GetIncreaseOneByEnhance( int nEnhance ) const { return static_cast( var[5] * 100.f ) * nEnhance; }; int GetIncreaseAttackRange( int nEnhance ) const { return static_cast( var[7]*nEnhance ); }; // 범위 int GetIncreaseMultiAttackRange( int nEnhance ) const { return static_cast( var[9]*nEnhance ); }; // 멀티어택범위 int GetIncreaseKnockBack( int nEnhance ) const { return static_cast( nEnhance * var[7] ); }; // 범위 /// 지속효과 성공률(물리 저주 계열) int GetStateSuccessByEnhance( int nEnhance ) const { return static_cast( nEnhance * var[5] ); }; /// 지속효과 연타 공격력 강화 int GetStatePowerOneByEnhance( int nEnhance ) const { return static_cast( nEnhance * var[7] ); }; /// 지속효과 마법 공격력 강화 int GetStateMagicPowerByEnhance( int nEnhance ) const { return static_cast( nEnhance * var[2] ); }; /// 버프/디버프 성능 int GetStatePowerByEnhance( int nEnhance ) const { return static_cast( nEnhance * var[2] ); }; /// 획복량/회복률 int GetRecoveryByEnhance( int nEnhance ) const { return static_cast( nEnhance * var[6] ); }; int GetRecoveryPerByEnhance( int nEnhance ) const { return static_cast( var[7] * 100.f ) * nEnhance; }; int GetRecoveryHPByEnhance( int nEnhance ) const { return static_cast( nEnhance * var[4] ); }; int GetRecoveryMPByEnhance( int nEnhance ) const { return static_cast( nEnhance * var[9] ); }; /// 획복량/회복률 int GetRecoveryAllPerByEnhance( int nEnhance ) const { return static_cast( var[11] * nEnhance * 100 ); }; /// 회복률 int GetAmountAbsorptionRateByEnhance( int nEnhance ) const { return static_cast( var[7] * nEnhance ); }; /// 부활시 EXP 복구률 int GetExpIncreaseByRevival( int nEnhance ) const { return static_cast( var[3] * 100.f ) * nEnhance; }; /// 지속효과 제거 레벨 int GetRemoveStateLvByEnhance( int nEnhance ) const { return static_cast( var[2]* nEnhance ); }; /// MP소모량 int GetConsumptionMPByEnhance( int nUseLevel ) const{ return static_cast( var[2]*nUseLevel ); } /// HP 흡수량 int GetAbsorptionHPPointByEnhance( int nEnhance ) const { return static_cast( nEnhance * var[4] ); }; /// MP 흡수량 int GetAbsorptionMPPointByEnhance( int nEnhance ) const { return static_cast( nEnhance * var[5] ); }; /// 테이밍 성공률 int GetTamingSuccessByEnhance( int nEnhance ) const { return static_cast( var[1] * 100.f ) * nEnhance; }; /// 초당 mp 소모 int GetCostMPPerSecondByEnhance( int nEnhance ) const { return static_cast( nEnhance * var[2] ); }; /// 헤이트 int GetAggroByEnhance( int nEnhance ) const { return static_cast( var[7] * nEnhance ); }; /// 스킬 성공률 int GetSuccessRateByEnhance( int nEnhance ) const { return static_cast( 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()