Files
LGram16 dd97ddec92 Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code:
- Client: Game client source (moved to Client/Client/)
- Server: Game server source
- GameTools: Development tools
- CryptoSource: Encryption utilities
- database: Database scripts
- Script: Game scripts
- rylCoder_16.02.2008_src: Legacy coder tools
- GMFont, Game: Additional resources

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 20:17:20 +09:00

683 lines
23 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#ifndef _SKILL_TABLE_H_
#define _SKILL_TABLE_H_
#pragma once
#include <Pattern/Singleton.h>
#include <Creature/AggresiveCreature.h>
#include <Utility/Math/Math.h>
#include <Utility/TypeArray.h>
#include <Skill/Spell/Spell.h>
#include <Skill/Spell/SpellUtil.h>
#include <Skill/Spell/SpellTable.h>
#include <Skill/Spell/GlobalSpellMgr.h>
#include "SkillMgr.h"
namespace Skill
{
enum PassiveType
{
ActivatePassive = 1,
DeactivatePassive = 2
};
enum MasteryType
{
NONE_MASTERY = 0,
SWORD_MASTERY = 1,
AXE_MASTERY = 2,
BLUNT_MASTERY = 3,
DAGGER_MASTERY = 4,
CRUSH_WEAPON = 5,
BLADE = 6,
CLAW_MASTERY = 7
};
typedef unsigned short (*FnProcess)(const Skill::ProtoType& ProtoType, AtType attackType,
CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, unsigned char &cOffencerJudge,
unsigned char &cDefenserJudge, unsigned short& wOffencerMPHeal, unsigned short& wDefenserMPHeal, unsigned short &wError);
class CProcessTable : public CSingleton<CProcessTable>
{
public:
struct ProcessInfo
{
unsigned short m_usSkill_ID;
Skill::FnProcess m_fnProcess;
Skill::ProtoType* m_lpProtoType;
static Skill::ProtoType m_NullProtoType;
ProcessInfo() : m_usSkill_ID(0), m_fnProcess(NULL), m_lpProtoType(&m_NullProtoType) { }
ProcessInfo(unsigned short usSkill_ID, Skill::FnProcess fnProcess, Skill::ProtoType* lpProtoType)
: m_usSkill_ID(usSkill_ID), m_fnProcess(fnProcess), m_lpProtoType(lpProtoType)
{ }
inline bool operator < (const ProcessInfo& rhs) const { return (m_usSkill_ID < rhs.m_usSkill_ID); }
};
typedef std::vector<ProcessInfo> ProcessVector;
bool Initialize();
bool InsertSkill(Skill::CProcessTable::ProcessVector& processVector, unsigned short usSkill_ID, FnProcess fnProcess);
const ProcessInfo* GetProcessInfo(unsigned short usSkill_ID);
inline unsigned short UseSkill(AtType attackType, CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim,
unsigned char &cOffencerJudge, unsigned char &cDefenserJudge, unsigned short& wOffencerMPHeal,
unsigned short& wDefenserMPHeal, unsigned short &wError)
{
const ProcessInfo* lpProcessInfo = GetProcessInfo(attackType.m_wType);
if (NULL == lpProcessInfo)
return 0;
char cLockCount = CSkillMgr::MAX_SKILL_LOCKCOUNT;
if(lpProcessInfo->m_lpProtoType->m_eSkillType == Skill::Type::ITEM)
cLockCount = 7;
if (attackType.m_cSkillLockCount >= cLockCount ||
attackType.m_cSkillLevel > CSkillMgr::MAX_SKILL_LEVEL)
{
unsigned long dwCID = (NULL != lpSkillUser) ? lpSkillUser->GetCID() : 0;
ERRLOG3(g_Log, "CID:0x%08x <20>߸<EFBFBD><DFB8><EFBFBD> <20><>ī<EFBFBD><C4AB>Ʈ/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ų<EFBFBD><C5B3> <20><><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD> <20>մϴ<D5B4>. LockCount:%d, Level:%d",
dwCID, attackType.m_cSkillLockCount, attackType.m_cSkillLevel);
}
else
{
return lpProcessInfo->m_fnProcess(lpProcessInfo->m_lpProtoType[attackType.m_cSkillLockCount], attackType,
lpSkillUser, lpVictim, cOffencerJudge, cDefenserJudge, wOffencerMPHeal, wDefenserMPHeal, wError);
}
return 0;
}
private:
CProcessTable();
~CProcessTable();
unsigned short m_usProcessInfo;
ProcessInfo* m_fnProcessTable;
static CProcessTable ms_this;
};
class CFunctions
{
public:
static short ConsumeMP(AtType attackType, CAggresiveCreature* lpSkillUser, unsigned char cOffencerJudge);
protected: // <20>Լ<EFBFBD> <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20><><EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD> ȣ<><C8A3><EFBFBD><EFBFBD> <20><> <20>ֵ<EFBFBD><D6B5><EFBFBD> <20>Ѵ<EFBFBD>.
enum Const
{
VarCastMeeleEnchantLevelMultiplier = 4
};
friend class CProcessTable;
// <20>нú<D0BD> <20><>ų : <20><><EFBFBD>ϰ<EFBFBD> - <20>ϴ<EFBFBD><CFB4><EFBFBD> 0;
// <20>ν<EFBFBD><CEBD>Ͻ<EFBFBD> <20><>ų : <20><><EFBFBD>ϰ<EFBFBD> - Victim<69><6D><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// ij<><C4B3>Ʈ <20><>ų : <20><><EFBFBD>ϰ<EFBFBD> - Victim<69><6D><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
static inline bool CheckChantOff(unsigned char cSkillLockCount, unsigned char cSkillLevel);
static inline bool SlowlySkillAttack(const Skill::ProtoType& ProtoType, AtType attackType,
CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim);
// ------------------------------------------------------------------------------------------------------------
// <20><>ȹ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Լ<EFBFBD><D4BC><EFBFBD>
// <20><>ī<EFBFBD><C4AB>Ʈ
static inline const unsigned short GetSkillLockCount(CAggresiveCreature* lpSkillUser, AtType attackType);
// <20><><EFBFBD><EFBFBD>Ʈ, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
static inline const float LevelFactor(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim);
// <20><><EFBFBD><EFBFBD> Ȯ<><C8AE>
static inline const unsigned short SuccessHitRate(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, float fFactor);
// <20><><EFBFBD><EFBFBD> Ȯ<><C8AE>
static inline const unsigned short SuccessRate(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, float fFactor);
// <20>ν<EFBFBD><CEBD>Ͻ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
static inline const unsigned short InstanceMagicDamage(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim,
AtType attackType, unsigned char cFactor);
// <20>ν<EFBFBD><CEBD>Ͻ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><>æƮ
static inline const unsigned long InstanceEnemyEnchantTick(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim,
AtType attackType, float fFactor);
// <20>ν<EFBFBD><CEBD>Ͻ<EFBFBD> <20><><EFBFBD><EFBFBD> ȸ<><C8B8>
static inline const unsigned short InstanceMagicRegen(CAggresiveCreature* lpSkillUser, AtType attackType, unsigned char cFactor);
// ij<><C4B3>Ʈ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
static inline const unsigned short CastMagicDamage(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim,
AtType attackType, unsigned char cFactor);
// <20>׸<EFBFBD><D7B8><EFBFBD> <20><>æƮ
static inline const unsigned long CastEnchantTick(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim,
AtType attackType, float fFactor);
// ij<><C4B3>Ʈ <20><>æƮ
static inline const unsigned short CastEnchantLevel(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim,
AtType attackType, float fFactor);
// <20>и<EFBFBD> <20>ɽ<EFBFBD>Ʈ <20><>æƮ
static inline const unsigned short CastMeelsEnchantLevel(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim,
AtType attackType, float fFactor);
// ij<><C4B3>Ʈ <20><><EFBFBD><EFBFBD> ȸ<><C8B8>
static inline const unsigned short CastMagicRegen(CAggresiveCreature* lpSkillUser, AtType attackType, unsigned char cFactor);
// æƮ <20><><EFBFBD><EFBFBD>
static inline const unsigned short ChantLevel(CAggresiveCreature* lpSkillUser, AtType attackType, unsigned char cFactor);
// ȸ<><C8B8><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> HP, MP <20><><EFBFBD><20><><EFBFBD><EFBFBD> <20>Լ<EFBFBD>
static inline const unsigned short PotionHPValue(unsigned char cPercent);
static inline const unsigned short PotionMPValue(unsigned char cPercent);
// ------------------------------------------------------------------------------------------------------------
// 3<><33> <20><EFBFBD><EBB7B1> <20><>ġ <20><><EFBFBD><EFBFBD> <20>Լ<EFBFBD>
// <20>ν<EFBFBD><CEBD>Ͻ<EFBFBD> <20>и<EFBFBD> ȸ<><C8B8>
static inline const unsigned short InstanceMeleeRegen(CAggresiveCreature* lpSkillUser, AtType attackType, unsigned char cFactor);
// ij<><C4B3>Ʈ <20>и<EFBFBD> ȸ<><C8B8>
static inline const unsigned short CastMeleeRegen(CAggresiveCreature* lpSkillUser, AtType attackType, unsigned char cFactor);
// <20>и<EFBFBD> æƮ <20><><EFBFBD><EFBFBD>
static inline const unsigned short MeleeChantLevel(CAggresiveCreature* lpSkillUser, AtType attackType, unsigned char cFactor);
// ij<><C4B3>Ʈ <20><>æƮ <20><>ų <20><><EFBFBD><EFBFBD>
static inline const unsigned short CastEnchantSkillLevel(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim,
AtType attackType, float fFactor1, float fFactor2 = 1.0f, float fFactor3 = 0.0f);
// ------------------------------------------------------------------------------------------------------------
#define DECLARE_SKILL(SpellName) \
static unsigned short SpellName(const Skill::ProtoType& ProtoType, AtType attackType, CAggresiveCreature* lpSkillUser, \
CAggresiveCreature* lpVictim, unsigned char &cOffencerJudge, unsigned char &cDefenserJudge, \
unsigned short& wOffencerMPHeal, unsigned short& wDefenserMPHeal, unsigned short &wError)
#define DEFINE_SKILL(SpellName) \
unsigned short Skill::CFunctions::##SpellName(const Skill::ProtoType& ProtoType, AtType attackType, \
CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, \
unsigned char &cOffencerJudge, unsigned char &cDefenserJudge, \
unsigned short& wOffencerMPHeal, unsigned short& wDefenserMPHeal, unsigned short &wError)
// <20>Ҽ<EFBFBD><D2BC><EFBFBD><EFBFBD><EFBFBD>
DECLARE_SKILL(SocialMotion);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
DECLARE_SKILL(Net);
DECLARE_SKILL(SwordMastery);
DECLARE_SKILL(AxeMastery);
DECLARE_SKILL(HardHit);
DECLARE_SKILL(BluntMastery);
DECLARE_SKILL(WillPower);
DECLARE_SKILL(Toughness);
// <20>α<EFBFBD>
DECLARE_SKILL(Detection);
DECLARE_SKILL(ImprovedCritical);
DECLARE_SKILL(Evasion);
DECLARE_SKILL(NeedleSpit);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
DECLARE_SKILL(BloodyMana);
DECLARE_SKILL(VampiricTouch);
DECLARE_SKILL(ManaShell);
DECLARE_SKILL(Grease);
DECLARE_SKILL(Serenity);
// <20><><EFBFBD>ݶ<EFBFBD><DDB6><EFBFBD>Ʈ
DECLARE_SKILL(Purification);
DECLARE_SKILL(Faith);
DECLARE_SKILL(Encourage);
DECLARE_SKILL(FirstAid);
DECLARE_SKILL(HammerOfLight);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
DECLARE_SKILL(Charging);
DECLARE_SKILL(SharedPain);
DECLARE_SKILL(FullSwing);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
DECLARE_SKILL(Blaze);
DECLARE_SKILL(BattleSong);
DECLARE_SKILL(ChainAction);
DECLARE_SKILL(DualWieldMastery);
DECLARE_SKILL(CounterAttack);
DECLARE_SKILL(CounterAttackMotion);
// <20><><EFBFBD>ؽ<EFBFBD>
DECLARE_SKILL(BackStab);
DECLARE_SKILL(Stealth);
DECLARE_SKILL(DaggerMastery);
DECLARE_SKILL(BombSet);
DECLARE_SKILL(Explosion);
DECLARE_SKILL(StealHand);
// <20><>ó
DECLARE_SKILL(AimedShot);
DECLARE_SKILL(DualShot);
DECLARE_SKILL(Camouflage);
DECLARE_SKILL(Accuracy);
// <20>Ҽ<EFBFBD><D2BC><EFBFBD>
DECLARE_SKILL(Recall);
DECLARE_SKILL(FireBolt);
DECLARE_SKILL(LightningArrow);
DECLARE_SKILL(FrostBolt);
DECLARE_SKILL(DeathRay);
DECLARE_SKILL(FreshToStone);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
DECLARE_SKILL(Disenchant);
DECLARE_SKILL(Entangle);
DECLARE_SKILL(LowerStrength);
DECLARE_SKILL(EnchantWeapon);
DECLARE_SKILL(Shatter);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ
DECLARE_SKILL(Resurrection);
DECLARE_SKILL(MaintenanceChant);
DECLARE_SKILL(AccelerationChant);
DECLARE_SKILL(BrightArmor);
DECLARE_SKILL(ManaFlow);
DECLARE_SKILL(ManaBurn);
// Ŭ<><C5AC><EFBFBD><EFBFBD>
DECLARE_SKILL(Dazzle);
DECLARE_SKILL(CureWounds);
DECLARE_SKILL(WoundsCrafting);
DECLARE_SKILL(CureLight);
DECLARE_SKILL(WoundsMake);
DECLARE_SKILL(Regeneration);
// <20>Ĺ<EFBFBD><C4B9><EFBFBD>Ʈ
DECLARE_SKILL(CrusherMastery);
DECLARE_SKILL(BladeMastery);
DECLARE_SKILL(SplitLife);
DECLARE_SKILL(ExtraLife);
// <20><><EFBFBD>Ǽ<EFBFBD><C7BC><EFBFBD><EFBFBD><EFBFBD>
DECLARE_SKILL(Dispel);
DECLARE_SKILL(MagicMissile);
DECLARE_SKILL(Flexibility);
DECLARE_SKILL(ClawMastery);
DECLARE_SKILL(LifeAura);
DECLARE_SKILL(InnerSight);
// <20><><EFBFBD>÷<EFBFBD>
DECLARE_SKILL(Guard);
DECLARE_SKILL(HardenSkin);
DECLARE_SKILL(FastHit);
DECLARE_SKILL(ManaConvert);
// <20><><EFBFBD><EFBFBD>Ŀ
DECLARE_SKILL(PowerDrain);
DECLARE_SKILL(SkillArmFight);
DECLARE_SKILL(RingGeyser);
// <20>ų<EFBFBD>
DECLARE_SKILL(FireRing);
DECLARE_SKILL(Blast);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
DECLARE_SKILL(Rot);
DECLARE_SKILL(Shock);
DECLARE_SKILL(Shackle);
DECLARE_SKILL(Crevice);
DECLARE_SKILL(SummonKindling);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
DECLARE_SKILL(Flash);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
DECLARE_SKILL(WoundsBlast);
DECLARE_SKILL(DaggerFire);
DECLARE_SKILL(Envenom);
// ȸ<><C8B8> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
DECLARE_SKILL(UseFood);
// DECLARE_SKILL(UseFoodPer);
DECLARE_SKILL(UseDrink);
// DECLARE_SKILL(UseDrinkPer);
DECLARE_SKILL(UseFusionFood);
// DECLARE_SKILL(UseFusionFoodPer);
// DECLARE_SKILL(UseHealPotion);
DECLARE_SKILL(UseHealPotionPer);
// DECLARE_SKILL(UseManaPotion);
DECLARE_SKILL(UseManaPotionPer);
// DECLARE_SKILL(UseRefreshPotion);
DECLARE_SKILL(UseRefreshPotionPer);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// DECLARE_SKILL(DemagePotion);
DECLARE_SKILL(DemagePotionPer);
// DECLARE_SKILL(ArmorPotion);
DECLARE_SKILL(ArmorPotionPer);
// DECLARE_SKILL(HitRatePotion);
DECLARE_SKILL(HitRatePotionPer);
// DECLARE_SKILL(EvadePotion);
DECLARE_SKILL(EvadePotionPer);
// DECLARE_SKILL(MaxHPPotion);
DECLARE_SKILL(MaxHPPotionPer);
// DECLARE_SKILL(MaxMPPotion);
DECLARE_SKILL(MaxMPPotionPer);
// DECLARE_SKILL(HPRegenPotion);
// DECLARE_SKILL(HPRegenPotionPer);
// DECLARE_SKILL(MPRegenPotion);
// DECLARE_SKILL(MPRegenPotionPer);
// DECLARE_SKILL(CriticalPotion);
DECLARE_SKILL(CriticalPotionPer);
// DECLARE_SKILL(BlockPotion);
DECLARE_SKILL(BlockPotionPer);
// DECLARE_SKILL(SpeedPotion);
DECLARE_SKILL(SpeedPotionPer);
// DECLARE_SKILL(DeCoolDownPotion);
DECLARE_SKILL(DeCoolDownPotionPer);
// DECLARE_SKILL(MagicPowerPotion);
DECLARE_SKILL(MagicPowerPotionPer);
// DECLARE_SKILL(MagicResistPotion);
DECLARE_SKILL(MagicResistPotionPer);
DECLARE_SKILL(ConcentrationPotionPer);
DECLARE_SKILL(FireCracker);
DECLARE_SKILL(ChinaFireCracker);
DECLARE_SKILL(Drunk);
DECLARE_SKILL(LuckyExpOrb);
DECLARE_SKILL(MichaelBless);
DECLARE_SKILL(ExpOrb);
DECLARE_SKILL(LuckyOrb);
DECLARE_SKILL(AntidotePotion);
DECLARE_SKILL(AntiFreeze);
DECLARE_SKILL(AntiFire);
DECLARE_SKILL(Gather);
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20><>ų
DECLARE_SKILL(SRSAAttack);
DECLARE_SKILL(LRSAAttack);
DECLARE_SKILL(SRCAAttack);
DECLARE_SKILL(LRCAAttack);
DECLARE_SKILL(GuardAttack);
DECLARE_SKILL(EmblemAttack);
DECLARE_SKILL(CampAttack);
DECLARE_SKILL(EmblemNewAttack);
};
// <20><><EFBFBD>ڽ<EFBFBD> <20><>ų<EFBFBD>ΰ<EFBFBD>?
static inline bool IsStealthSkill(unsigned short wSkillID);
};
inline const float Skill::CFunctions::LevelFactor(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim)
{
return lpSkillUser->CalculateLevelGapAffect(lpVictim);
}
inline const unsigned short Skill::CFunctions::SuccessHitRate(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, float fFactor)
{
return static_cast<unsigned short>((lpSkillUser->GetStatus().m_StatusInfo.m_wHitRate * fFactor /
(lpSkillUser->GetStatus().m_StatusInfo.m_wHitRate * fFactor + lpVictim->GetStatus().m_StatusInfo.m_wEvade)) * 100);
}
inline const unsigned short Skill::CFunctions::SuccessRate(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim, float fFactor)
{
return static_cast<unsigned short>((lpSkillUser->GetStatus().m_StatusInfo.m_wMagicPower * fFactor /
(lpSkillUser->GetStatus().m_StatusInfo.m_wMagicPower * fFactor + lpVictim->GetStatus().m_StatusInfo.m_fMagicResistRate)) * 100);
}
inline const unsigned short Skill::CFunctions::InstanceMagicDamage(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim,
AtType attackType, unsigned char cFactor)
{
long lDamage = static_cast<long>((attackType.m_cSkillLevel + attackType.m_cSkillLockCount * 6) * cFactor *
(75 + Math::Random::ComplexRandom(75) + lpSkillUser->GetStatus().m_StatusInfo.m_wMagicPower) / 100.0f *
(100 - lpVictim->GetStatus().m_StatusInfo.m_fMagicResistRate) / 100.0f * LevelFactor(lpSkillUser, lpVictim));
return static_cast<unsigned short>(min(lDamage, USHRT_MAX));
}
inline const unsigned long Skill::CFunctions::InstanceEnemyEnchantTick(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim,
AtType attackType, float fFactor)
{
return static_cast<unsigned long>((attackType.m_cSkillLevel + attackType.m_cSkillLockCount * 6) *
fFactor * LevelFactor(lpSkillUser, lpVictim));
}
inline const unsigned short Skill::CFunctions::InstanceMagicRegen(CAggresiveCreature* lpSkillUser, AtType attackType, unsigned char cFactor)
{
return static_cast<unsigned short>((attackType.m_cSkillLevel + attackType.m_cSkillLockCount * 6) *
cFactor * (50 + Math::Random::ComplexRandom(50) + lpSkillUser->GetStatus().m_StatusInfo.m_wMagicPower) / 100.0f);
}
inline const unsigned short Skill::CFunctions::CastMagicDamage(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim,
AtType attackType, unsigned char cFactor)
{
const unsigned short wLockCount = GetSkillLockCount(lpSkillUser, attackType);
long lDamage = static_cast<long>(((wLockCount + 1) * attackType.m_cSkillLevel + 1 + attackType.m_cSkillLockCount * wLockCount * 5) *
cFactor * (75 + Math::Random::ComplexRandom(75) + lpSkillUser->GetStatus().m_StatusInfo.m_wMagicPower) / 100.0f *
(100 - lpVictim->GetStatus().m_StatusInfo.m_fMagicResistRate) / 100.0f * LevelFactor(lpSkillUser, lpVictim));
return static_cast<unsigned short>(min(lDamage, USHRT_MAX));
}
inline const unsigned long Skill::CFunctions::CastEnchantTick(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim,
AtType attackType, float fFactor)
{
return static_cast<unsigned long>((GetSkillLockCount(lpSkillUser, attackType) + attackType.m_cSkillLevel + attackType.m_cSkillLockCount * 2) *
fFactor * LevelFactor(lpSkillUser, lpVictim));
}
inline const unsigned short Skill::CFunctions::CastEnchantLevel(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim,
AtType attackType, float fFactor)
{
unsigned short wFirstCase = static_cast<unsigned short>(((GetSkillLockCount(lpSkillUser, attackType) + 1) *
attackType.m_cSkillLevel + attackType.m_cSkillLockCount * GetSkillLockCount(lpSkillUser, attackType)) * fFactor *
(100 + lpSkillUser->GetStatus().m_StatusInfo.m_wMagicPower) / 100.0f);
unsigned short wSecondCase = static_cast<unsigned short>(lpVictim->GetStatus().m_nLevel * 3 * fFactor);
return min(wFirstCase, wSecondCase);
}
inline const unsigned short Skill::CFunctions::CastMeelsEnchantLevel(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim,
AtType attackType, float fFactor)
{
unsigned short wFirstCase = static_cast<unsigned short>(((GetSkillLockCount(lpSkillUser, attackType) + 1) *
attackType.m_cSkillLevel + attackType.m_cSkillLockCount *
GetSkillLockCount(lpSkillUser, attackType)) * fFactor *
(VarCastMeeleEnchantLevelMultiplier + GetSkillLockCount(lpSkillUser, attackType)));
unsigned short wSecondCase = static_cast<unsigned short>(lpVictim->GetStatus().m_nLevel * 3 * fFactor);
return min(wFirstCase, wSecondCase);
}
inline const unsigned short Skill::CFunctions::CastMagicRegen(CAggresiveCreature* lpSkillUser, AtType attackType, unsigned char cFactor)
{
return static_cast<unsigned short>(((GetSkillLockCount(lpSkillUser, attackType) + 1) *
attackType.m_cSkillLevel + 1 + attackType.m_cSkillLockCount * GetSkillLockCount(lpSkillUser, attackType) * 5) * cFactor *
(50 + Math::Random::ComplexRandom(50) + lpSkillUser->GetStatus().m_StatusInfo.m_wMagicPower) / 100.0f);
}
inline const unsigned short Skill::CFunctions::PotionHPValue(unsigned char cPercent)
{
switch (cPercent)
{
case 10: return 1000;
case 20: return 3000;
case 30: return 5000;
case 40: return 6000;
case 50: return 7000;
case 60: return 8000;
case 80: return 10000;
}
return 0;
}
inline const unsigned short Skill::CFunctions::PotionMPValue(unsigned char cPercent)
{
switch (cPercent)
{
case 5: return 500;
case 10: return 1000;
case 15: return 2000;
case 20: return 3000;
case 30: return 4000;
case 45: return 6000;
case 60: return 8000;
}
return 0;
}
inline const unsigned short Skill::CFunctions::ChantLevel(CAggresiveCreature* lpSkillUser, AtType attackType, unsigned char cFactor)
{
return static_cast<unsigned short>((attackType.m_cSkillLevel + attackType.m_cSkillLockCount * 6) * cFactor *
(100 + lpSkillUser->GetStatus().m_StatusInfo.m_wMagicPower) / 100.0f);
}
inline const unsigned short Skill::CFunctions::GetSkillLockCount(CAggresiveCreature* lpSkillUser, AtType attackType)
{
unsigned short wLockCount = 0;
Creature::CreatureType eCreatureType = Creature::GetCreatureType(lpSkillUser->GetCID());
if (Creature::CT_MONSTER == eCreatureType ||
Creature::CT_SUMMON == eCreatureType ||
Creature::CT_STRUCT == eCreatureType)
{
wLockCount = attackType.m_cSkillLockCount;
}
else
{
wLockCount = lpSkillUser->GetSkillLockCount(attackType.m_wType);
}
if (wLockCount < 0 || wLockCount >= CSkillMgr::MAX_SKILL_LOCKCOUNT)
{
ERRLOG3(g_Log, "CID:0x%08x <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ų<EFBFBD><C5B3> <20><>ī<EFBFBD><C4AB>Ʈ<EFBFBD><C6AE> <20>̻<EFBFBD><CCBB>մϴ<D5B4>. SkillType : 0x%04x, LockCount : %d",
lpSkillUser->GetCID(), attackType.m_wType, wLockCount);
return 0;
}
return wLockCount;
}
inline bool Skill::CFunctions::CheckChantOff(unsigned char cSkillLockCount, unsigned char cSkillLevel)
{
return (0 == cSkillLockCount && 0 == cSkillLevel) ? true : false;
}
inline bool Skill::CFunctions::SlowlySkillAttack(const Skill::ProtoType& ProtoType, AtType attackType,
CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim)
{
unsigned short wLockCount = GetSkillLockCount(lpSkillUser, attackType);
unsigned short wEnchantLevel = attackType.m_cSkillLevel + wLockCount * 6;
unsigned long dwDurationSec = static_cast<unsigned long>(
(attackType.m_cSkillLevel + wLockCount * 6) * 0.5f * LevelFactor(lpSkillUser, lpVictim));
unsigned short wResult = CAddSpell<CSlowSpell>(CSpell::Spell_Info(ProtoType, lpSkillUser,
SpellType::MAGICAL_SPELL, SpellID::Slow, wEnchantLevel, dwDurationSec))(lpVictim);
return (wResult == CSpell::ENCHANT_FAIL_BY_ENEMY_ENCHANT) ? false : true;
}
inline bool Skill::IsStealthSkill(unsigned short wSkillID)
{
switch (wSkillID)
{
case 0x8704: // <20><><EFBFBD>ڽ<EFBFBD> (<28><><EFBFBD><EFBFBD>)
case 0x9804: // <20><><EFBFBD>ڽ<EFBFBD> (<28><><EFBFBD><EFBFBD>)
case 0x8805: // ij<><C4B3><EFBFBD>ö<EFBFBD><C3B6><EFBFBD> (<28><>ó)
case 0x9504: // ij<><C4B3><EFBFBD>ö<EFBFBD><C3B6><EFBFBD> (<28>ų<EFBFBD>)
return true;
}
return false;
}
// ------------------------------------------------------------------------------------------------------------
// 3<><33> <20><EFBFBD><EBB7B1> <20><>ġ <20><><EFBFBD><EFBFBD> <20>Լ<EFBFBD>
inline const unsigned short Skill::CFunctions::InstanceMeleeRegen(CAggresiveCreature* lpSkillUser, AtType attackType, unsigned char cFactor)
{
return static_cast<unsigned short>((attackType.m_cSkillLevel + attackType.m_cSkillLockCount * 6) *
cFactor * (50 + Math::Random::ComplexRandom(50) + (attackType.m_cSkillLevel + attackType.m_cSkillLockCount * 6) * 25) / 100.0f);
}
inline const unsigned short Skill::CFunctions::CastMeleeRegen(CAggresiveCreature* lpSkillUser, AtType attackType, unsigned char cFactor)
{
return static_cast<unsigned short>(((GetSkillLockCount(lpSkillUser, attackType) + 1) *
attackType.m_cSkillLevel + 1 + attackType.m_cSkillLockCount * GetSkillLockCount(lpSkillUser, attackType) * 5) * cFactor *
(50 + Math::Random::ComplexRandom(50) + GetSkillLockCount(lpSkillUser, attackType) * 100) / 100.0f);
}
inline const unsigned short Skill::CFunctions::MeleeChantLevel(CAggresiveCreature* lpSkillUser, AtType attackType, unsigned char cFactor)
{
return static_cast<unsigned short>((attackType.m_cSkillLevel + attackType.m_cSkillLockCount * 6) * cFactor *
(100 + (attackType.m_cSkillLevel + attackType.m_cSkillLockCount * 6) * 31) / 100.0f);
}
inline const unsigned short Skill::CFunctions::CastEnchantSkillLevel(CAggresiveCreature* lpSkillUser, CAggresiveCreature* lpVictim,
AtType attackType, float fFactor1, float fFactor2, float fFactor3)
{
unsigned short wFirstCase = static_cast<unsigned short>((((GetSkillLockCount(lpSkillUser, attackType) + 1) *
attackType.m_cSkillLevel + attackType.m_cSkillLockCount * GetSkillLockCount(lpSkillUser, attackType)) * fFactor1 *
(GetSkillLockCount(lpSkillUser, attackType) + 4) * fFactor2) + fFactor3);
unsigned short wSecondCase = static_cast<unsigned short>(lpVictim->GetStatus().m_nLevel * 3 * fFactor1);
return min(wFirstCase, wSecondCase);
}
#endif