1789 lines
74 KiB
C++
1789 lines
74 KiB
C++
#pragma once
|
|
|
|
|
|
#include <vector>
|
|
#include <map>
|
|
#include <set>
|
|
|
|
|
|
#include <toolkit/ILock.h>
|
|
#include <toolkit/c_fixed.h>
|
|
#include <toolkit/XFlag.h>
|
|
#include <dump/XExceptionHandler.h>
|
|
|
|
#include "Constant.h"
|
|
#include "ContentStruct.h"
|
|
#include "StructBase.h"
|
|
#include "StructMisc.h"
|
|
#include "CreatureBase.h"
|
|
#include "GameRule.h"
|
|
|
|
|
|
struct DamageMessage;
|
|
struct DamageCalculator;
|
|
struct CalculationResult;
|
|
|
|
const int CELL_SIZE = 6;
|
|
|
|
struct CreatureStatServer
|
|
{
|
|
CreatureStatServer()
|
|
: stat_id( 0 )
|
|
, strength( 0 )
|
|
, vital( 0 )
|
|
, dexterity( 0 )
|
|
, agility( 0 )
|
|
, intelligence( 0 )
|
|
, mentality( 0 )
|
|
, luck( 0 )
|
|
{}
|
|
|
|
CreatureStatServer( const CreatureStat & stat )
|
|
: stat_id( stat.stat_id )
|
|
, strength( stat.strength )
|
|
, vital( stat.vital )
|
|
, dexterity( stat.dexterity )
|
|
, agility( stat.agility )
|
|
, intelligence( stat.intelligence )
|
|
, mentality( stat.mentality )
|
|
, luck( stat.luck )
|
|
{}
|
|
|
|
const CreatureStatServer& operator+= ( const CreatureStatServer& rhs )
|
|
{
|
|
strength += rhs.strength;
|
|
vital += rhs.vital;
|
|
dexterity += rhs.dexterity;
|
|
agility += rhs.agility;
|
|
intelligence += rhs.intelligence;
|
|
mentality += rhs.mentality;
|
|
luck += rhs.luck;
|
|
|
|
return *this;
|
|
}
|
|
|
|
short stat_id;
|
|
c_fixed10 strength;
|
|
c_fixed10 vital;
|
|
c_fixed10 dexterity;
|
|
c_fixed10 agility;
|
|
c_fixed10 intelligence;
|
|
c_fixed10 mentality;
|
|
c_fixed10 luck;
|
|
};
|
|
|
|
struct CreatureAttributeServer
|
|
{
|
|
CreatureAttributeServer()
|
|
: fCritical( 0 )
|
|
, fCriticalPower( 0 )
|
|
, fAttackPointRight( 0 )
|
|
, fAttackPointLeft( 0 )
|
|
, fDefence( 0 )
|
|
, fBlockDefence( 0 )
|
|
, fMagicPoint( 0 )
|
|
, fMagicDefence( 0 )
|
|
, fAccuracyRight( 0 )
|
|
, fAccuracyLeft( 0 )
|
|
, fMagicAccuracy( 0 )
|
|
, fAvoid( 0 )
|
|
, fMagicAvoid( 0 )
|
|
, fBlockChance( 0 )
|
|
, fMoveSpeed( 0 )
|
|
, fRidingSpeed( 0 )
|
|
, fAttackSpeed( 0 )
|
|
, fAttackRange( 0 )
|
|
, fMaxWeight( 0 )
|
|
, fCastingSpeed( 0 )
|
|
, fCoolTimeSpeed( 0 )
|
|
, fItemChance( 0 )
|
|
, fHPRegenPercentage( 0 )
|
|
, fHPRegenPoint( 0 )
|
|
, fMPRegenPercentage( 0 )
|
|
, fMPRegenPoint( 0 )
|
|
|
|
, fMagicalDefIgnore( 0 )
|
|
, fMagicalDefIgnoreRatio( 0 )
|
|
, fPhysicalDefIgnore( 0 )
|
|
, fPhysicalDefIgnoreRatio( 0 )
|
|
, fMagicalPenetration( 0 )
|
|
, fMagicalPenetrationRatio( 0 )
|
|
, fPhysicalPenetration( 0 )
|
|
, fPhysicalPenetrationRatio( 0 )
|
|
|
|
, fAttackSpeedRight( 0 )
|
|
, fAttackSpeedLeft( 0 )
|
|
, fDoubleAttackRatio( 0 )
|
|
, fStunResistance( 0 )
|
|
, fMoveSpeedDecreaseResistance( 0 )
|
|
, fHPAdd( 0 )
|
|
, fMPAdd( 0 )
|
|
, fHPAddByItem( 0 )
|
|
, fMPAddByItem( 0 )
|
|
{}
|
|
|
|
CreatureAttributeServer( const CreatureAttribute & attr )
|
|
: fCritical( attr.nCritical )
|
|
, fCriticalPower( attr.nCriticalPower )
|
|
, fAttackPointRight( attr.nAttackPointRight )
|
|
, fAttackPointLeft( attr.nAttackPointLeft )
|
|
, fDefence( attr.nDefence )
|
|
, fBlockDefence( attr.nBlockDefence )
|
|
, fMagicPoint( attr.nMagicPoint )
|
|
, fMagicDefence( attr.nMagicDefence )
|
|
, fAccuracyRight( attr.nAccuracyRight )
|
|
, fAccuracyLeft( attr.nAccuracyLeft )
|
|
, fMagicAccuracy( attr.nMagicAccuracy )
|
|
, fAvoid( attr.nAvoid )
|
|
, fMagicAvoid( attr.nMagicAvoid )
|
|
, fBlockChance( attr.nBlockChance )
|
|
, fMoveSpeed( attr.nMoveSpeed )
|
|
, fAttackSpeed( attr.nAttackSpeed )
|
|
, fAttackRange( attr.nAttackRange )
|
|
, fMaxWeight( attr.nMaxWeight )
|
|
, fCastingSpeed( attr.nCastingSpeed )
|
|
, fCoolTimeSpeed( attr.nCoolTimeSpeed )
|
|
, fItemChance( attr.nItemChance )
|
|
, fHPRegenPercentage( attr.nHPRegenPercentage )
|
|
, fHPRegenPoint( attr.nHPRegenPoint )
|
|
, fMPRegenPercentage( attr.nMPRegenPercentage )
|
|
, fMPRegenPoint( attr.nMPRegenPoint )
|
|
|
|
, fPerfectBlock( attr.nPerfectBlock )
|
|
, fMagicalDefIgnore( attr.nMagicalDefIgnore )
|
|
, fMagicalDefIgnoreRatio( attr.nMagicalDefIgnoreRatio )
|
|
, fPhysicalDefIgnore( attr.nPhysicalDefIgnore )
|
|
, fPhysicalDefIgnoreRatio( attr.nPhysicalDefIgnoreRatio )
|
|
, fMagicalPenetration( attr.nMagicalPenetration )
|
|
, fMagicalPenetrationRatio( attr.nMagicalPenetrationRatio )
|
|
, fPhysicalPenetration( attr.nPhysicalPenetration )
|
|
, fPhysicalPenetrationRatio( attr.nPhysicalPenetrationRatio )
|
|
|
|
, fAttackSpeedRight( 0 )
|
|
, fAttackSpeedLeft( 0 )
|
|
, fDoubleAttackRatio( 0 )
|
|
, fStunResistance( 0 )
|
|
, fMoveSpeedDecreaseResistance( 0 )
|
|
, fHPAdd( 0 )
|
|
, fMPAdd( 0 )
|
|
, fHPAddByItem( 0 )
|
|
, fMPAddByItem( 0 )
|
|
, fRidingSpeed( 0 )
|
|
{}
|
|
|
|
const CreatureAttributeServer& operator+= ( const CreatureAttributeServer& rhs )
|
|
{
|
|
// 외부 요인에 따라 합산이 되어선 안 될 변수는 부득이하게 주석 처리
|
|
fCritical += rhs.fCritical;
|
|
fCriticalPower += rhs.fCriticalPower;
|
|
fAttackPointRight += rhs.fAttackPointRight;
|
|
//fAttackPointLeft += rhs.fAttackPointLeft;
|
|
fDefence += rhs.fDefence;
|
|
fBlockDefence += rhs.fBlockDefence;
|
|
fMagicPoint += rhs.fMagicPoint;
|
|
fMagicDefence += rhs.fMagicDefence;
|
|
fAccuracyRight += rhs.fAccuracyRight;
|
|
//fAccuracyLeft += rhs.fAccuracyLeft;
|
|
fMagicAccuracy += rhs.fMagicAccuracy;
|
|
fAvoid += rhs.fAvoid;
|
|
fMagicAvoid += rhs.fMagicAvoid;
|
|
fBlockChance += rhs.fBlockChance;
|
|
//fMoveSpeed += rhs.fMoveSpeed;
|
|
//fRidingSpeed += rhs.fRidingSpeed;
|
|
fAttackSpeed += rhs.fAttackSpeed;
|
|
//fAttackRange += rhs.fAttackRange;
|
|
fMaxWeight += rhs.fMaxWeight;
|
|
fCastingSpeed += rhs.fCastingSpeed;
|
|
fCoolTimeSpeed += rhs.fCoolTimeSpeed;
|
|
fItemChance += rhs.fItemChance;
|
|
fHPRegenPercentage += rhs.fHPRegenPercentage;
|
|
fHPRegenPoint += rhs.fHPRegenPoint;
|
|
fMPRegenPercentage += rhs.fMPRegenPercentage;
|
|
fMPRegenPoint += rhs.fMPRegenPoint;
|
|
|
|
fPerfectBlock += rhs.fPerfectBlock;
|
|
fMagicalDefIgnore += rhs.fMagicalDefIgnore;
|
|
fMagicalDefIgnoreRatio += rhs.fMagicalDefIgnoreRatio;
|
|
fPhysicalDefIgnore += rhs.fPhysicalDefIgnore;
|
|
fPhysicalDefIgnoreRatio += rhs.fPhysicalDefIgnoreRatio;
|
|
fMagicalPenetration += rhs.fMagicalPenetration;
|
|
fMagicalPenetrationRatio += rhs.fMagicalPenetrationRatio;
|
|
fPhysicalPenetration += rhs.fPhysicalPenetration;
|
|
fPhysicalPenetrationRatio += rhs.fPhysicalPenetrationRatio;
|
|
|
|
fAttackSpeedRight += rhs.fAttackSpeedRight;
|
|
//fAttackSpeedLeft += rhs.fAttackSpeedLeft;
|
|
fDoubleAttackRatio += rhs.fDoubleAttackRatio;
|
|
fStunResistance += rhs.fStunResistance;
|
|
fMoveSpeedDecreaseResistance += rhs.fMoveSpeedDecreaseResistance;
|
|
fHPAdd += rhs.fHPAdd;
|
|
fMPAdd += rhs.fMPAdd;
|
|
fHPAddByItem += rhs.fHPAddByItem;
|
|
fMPAddByItem += rhs.fMPAddByItem;
|
|
|
|
return *this;
|
|
}
|
|
|
|
c_fixed10 fCritical; // 크리티컬
|
|
c_fixed10 fCriticalPower; // 크리티컬 비율 ( % 단위 )
|
|
c_fixed10 fAttackPointRight; // 공격력(오른손. 메인)
|
|
c_fixed10 fAttackPointLeft; // 공격력(왼손. 보조)
|
|
c_fixed10 fDefence; // 방어력
|
|
c_fixed10 fBlockDefence; // 블록 방어력
|
|
c_fixed10 fMagicPoint; // 마력
|
|
c_fixed10 fMagicDefence; // 마법방어력
|
|
c_fixed10 fAccuracyRight; // 명중(오른손. 메인)
|
|
c_fixed10 fAccuracyLeft; // 명중(왼손. 보조)
|
|
c_fixed10 fMagicAccuracy; // 마명중
|
|
c_fixed10 fAvoid; // 회피
|
|
c_fixed10 fMagicAvoid; // 마법저항력
|
|
c_fixed10 fBlockChance; // 블럭율
|
|
c_fixed10 fMoveSpeed; // 이동속도
|
|
c_fixed10 fRidingSpeed; // 탈것(아이템, 크리처)으로 인한 이동속도
|
|
c_fixed10 fAttackSpeed; // 공격속도
|
|
c_fixed10 fAttackRange; // 사거리
|
|
c_fixed10 fMaxWeight; // 소지무게
|
|
c_fixed10 fCastingSpeed; // 시전속도
|
|
c_fixed10 fCoolTimeSpeed; // 재시전속도
|
|
c_fixed10 fItemChance; // 아이템 드랍율
|
|
c_fixed10 fHPRegenPercentage; // HP 리젠%
|
|
c_fixed10 fHPRegenPoint; // HP 리젠P
|
|
c_fixed10 fMPRegenPercentage; // MP 리젠%
|
|
c_fixed10 fMPRegenPoint; // MP 리젠P
|
|
|
|
c_fixed10 fPerfectBlock; // 퍼펙트 블록
|
|
c_fixed10 fPhysicalDefIgnore; // 물리 방어력 무시P
|
|
c_fixed10 fPhysicalDefIgnoreRatio; // 물리 방어력 무시%
|
|
c_fixed10 fMagicalDefIgnore; // 마법 방어력 무시P
|
|
c_fixed10 fMagicalDefIgnoreRatio; // 마법 방어력 무시%
|
|
c_fixed10 fPhysicalPenetration; // 물리 방어력 관통P
|
|
c_fixed10 fPhysicalPenetrationRatio; // 물리 방어력 관통%
|
|
c_fixed10 fMagicalPenetration; // 마법 방어력 관통P
|
|
c_fixed10 fMagicalPenetrationRatio; // 마법 방어력 관통%
|
|
|
|
c_fixed10 fAttackSpeedRight; // 공격속도(오른손, 메인)
|
|
c_fixed10 fAttackSpeedLeft; // 공격속도(왼손, 보조)
|
|
c_fixed10 fDoubleAttackRatio;
|
|
c_fixed10 fStunResistance;
|
|
c_fixed10 fMoveSpeedDecreaseResistance;
|
|
c_fixed10 fHPAdd;
|
|
c_fixed10 fMPAdd;
|
|
c_fixed10 fHPAddByItem;
|
|
c_fixed10 fMPAddByItem;
|
|
};
|
|
|
|
struct CreatureStatAmplifier
|
|
{
|
|
c_fixed10 stat_id;
|
|
c_fixed10 strength;
|
|
c_fixed10 vital;
|
|
c_fixed10 dexterity;
|
|
c_fixed10 agility;
|
|
c_fixed10 intelligence;
|
|
c_fixed10 mentality;
|
|
c_fixed10 luck;
|
|
};
|
|
|
|
struct CreatureAttributeAmplifier
|
|
{
|
|
c_fixed10 fCritical; // 크리티컬
|
|
c_fixed10 fCriticalPower; // 크리티컬 비율 ( % 단위 )
|
|
c_fixed10 fAttackPointRight; // 공격력(오른손. 메인)
|
|
c_fixed10 fAttackPointLeft; // 공격력(왼손. 보조)
|
|
c_fixed10 fDefence; // 방어력
|
|
c_fixed10 fBlockDefence; // 블록 방어력
|
|
c_fixed10 fMagicPoint; // 마력
|
|
c_fixed10 fMagicDefence; // 마법방어력
|
|
c_fixed10 fAccuracyRight; // 명중(오른손. 메인)
|
|
c_fixed10 fAccuracyLeft; // 명중(왼손. 보조)
|
|
c_fixed10 fMagicAccuracy; // 마명중
|
|
c_fixed10 fAvoid; // 회피
|
|
c_fixed10 fMagicAvoid; // 마법저항력
|
|
c_fixed10 fBlockChance; // 블럭율
|
|
c_fixed10 fMoveSpeed; // 이동속도
|
|
c_fixed10 fAttackSpeed; // 공격속도
|
|
c_fixed10 fAttackRange; // 사거리
|
|
c_fixed10 fMaxWeight; // 소지무게
|
|
c_fixed10 fCastingSpeed; // 시전속도
|
|
c_fixed10 fCoolTimeSpeed; // 재시전속도
|
|
c_fixed10 fItemChance; // 아이템 드랍율
|
|
c_fixed10 fHPRegenPercentage; // HP 리젠%
|
|
c_fixed10 fHPRegenPoint; // HP 리젠P
|
|
c_fixed10 fMPRegenPercentage; // MP 리젠%
|
|
c_fixed10 fMPRegenPoint; // MP 리젠P
|
|
|
|
c_fixed10 fPerfectBlock; // 퍼펙트 블록
|
|
c_fixed10 fPhysicalDefIgnore; // 물리 방어력 무시P
|
|
c_fixed10 fPhysicalDefIgnoreRatio; // 물리 방어력 무시%
|
|
c_fixed10 fMagicalDefIgnore; // 마법 방어력 무시P
|
|
c_fixed10 fMagicalDefIgnoreRatio; // 마법 방어력 무시%
|
|
c_fixed10 fPhysicalPenetration; // 물리 방어력 관통P
|
|
c_fixed10 fPhysicalPenetrationRatio; // 물리 방어력 관통%
|
|
c_fixed10 fMagicalPenetration; // 마법 방어력 관통P
|
|
c_fixed10 fMagicalPenetrationRatio; // 마법 방어력 관통%
|
|
|
|
c_fixed10 fAttackSpeedRight; // 공격속도(오른손, 메인)
|
|
c_fixed10 fAttackSpeedLeft; // 공격속도(왼손, 보조)
|
|
c_fixed10 fDoubleAttackRatio;
|
|
c_fixed10 fStunResistance;
|
|
c_fixed10 fMoveSpeedDecreaseResistance;
|
|
c_fixed10 fHPAdd;
|
|
c_fixed10 fMPAdd;
|
|
c_fixed10 fHPAddByItem;
|
|
c_fixed10 fMPAddByItem;
|
|
};
|
|
|
|
struct CreatureElementalResistAmplifier
|
|
{
|
|
c_fixed10 fResist[ Elemental::TYPE_COUNT ];
|
|
};
|
|
|
|
struct ParameterForSummon
|
|
{
|
|
CreatureStatServer Stat;
|
|
CreatureAttributeServer Attribute;
|
|
CreatureElementalResist Resist;
|
|
|
|
int nMaxHP;
|
|
int nMaxMP;
|
|
int nMaxSP;
|
|
short nSPRegenAdd;
|
|
|
|
c_fixed10 fAttackPointRightWithoutWeapon;
|
|
c_fixed10 fMoveSpeed;
|
|
c_fixed10 fAttackRange;
|
|
|
|
float fMaxHPAmplifier;
|
|
float fMaxMPAmplifier;
|
|
float fMaxSPAmplifier;
|
|
float fSPRegenAddAmplifier;
|
|
|
|
CreatureAttributeAmplifier AttributeAmplifier;
|
|
};
|
|
|
|
struct SkillCostModifier
|
|
{
|
|
SkillCostModifier()
|
|
{
|
|
init();
|
|
}
|
|
|
|
SkillCostModifier( const SkillCostModifier& arg )
|
|
{
|
|
MPInc = arg.MPInc;
|
|
MPAmp = arg.MPAmp;
|
|
HPInc = arg.HPInc;
|
|
HPAmp = arg.HPAmp;
|
|
}
|
|
|
|
SkillCostModifier( const float MPInc, const float MPAmp, const float HPInc, const float HPAmp )
|
|
{
|
|
init();
|
|
add( MPInc, MPAmp, HPInc, HPAmp );
|
|
}
|
|
|
|
void init()
|
|
{
|
|
MPInc = 0.0f;
|
|
MPAmp = 0.0f;
|
|
HPInc = 0.0f;
|
|
HPAmp = 0.0f;
|
|
}
|
|
|
|
void add( const SkillCostModifier& modifier )
|
|
{
|
|
add( modifier.MPInc, modifier.MPAmp, modifier.HPInc, modifier.HPAmp );
|
|
}
|
|
|
|
void add( const float MPInc, const float MPAmp, const float HPInc, const float HPAmp )
|
|
{
|
|
this->MPInc += MPInc;
|
|
this->MPAmp += MPAmp;
|
|
this->HPInc += HPInc;
|
|
this->HPAmp += HPAmp;
|
|
}
|
|
|
|
const float calculateMPCost( const float original )
|
|
{
|
|
return ( original + MPInc ) * ( 1.0f + MPAmp );
|
|
}
|
|
|
|
const float calculateHPCost( const float original )
|
|
{
|
|
return ( original + HPInc ) * ( 1.0f + HPAmp );
|
|
}
|
|
|
|
float MPInc;
|
|
float MPAmp;
|
|
float HPInc;
|
|
float HPAmp;
|
|
};
|
|
|
|
struct LearningCost
|
|
{
|
|
LearningCost() : jp( 0 ), tp( 0 ) {}
|
|
LearningCost( const __int64 jp, const int tp ) : jp( jp ), tp( tp ) {}
|
|
const LearningCost& operator +=( const LearningCost& rhs )
|
|
{
|
|
jp += rhs.jp;
|
|
tp += rhs.tp;
|
|
return *this;
|
|
}
|
|
|
|
__int64 jp;
|
|
int tp;
|
|
};
|
|
|
|
struct StructCreature : GameObject
|
|
{
|
|
ITERATOR_DEFINITION( StructCreature );
|
|
|
|
static iterator get( AR_HANDLE handle )
|
|
{
|
|
iterator It;
|
|
It.set( *GameObject::get( handle ) );
|
|
|
|
if( (*It) && !(*It)->IsCreature() )
|
|
{
|
|
It.set( NULL );
|
|
}
|
|
return It;
|
|
}
|
|
|
|
static void SetMaxSkillUID( int nUID );
|
|
static void SetMaxStateUID( int nUID );
|
|
static void SetDisabledStateList( std::vector< int > & vDisabledStateList );
|
|
static void InitCreatureSystem();
|
|
static void DeInitCreatureSystem();
|
|
|
|
struct QuadTreeItem
|
|
{
|
|
QuadTreeItem()
|
|
{
|
|
pParent = NULL;
|
|
x = 0;
|
|
y = 0;
|
|
}
|
|
|
|
inline int GetQuadX() const { return x; }
|
|
inline int GetQuadY() const { return y; }
|
|
bool operator==( const QuadTreeItem & rh ) const { return pParent == rh.pParent; }
|
|
inline void Set( StructCreature & c )
|
|
{
|
|
x = getX( c.GetPos().x );
|
|
y = getY( c.GetPos().y );
|
|
pParent = &c;
|
|
}
|
|
inline void Set( AR_UNIT x, AR_UNIT y )
|
|
{
|
|
this->x = getX( x );
|
|
this->y = getY( y );
|
|
}
|
|
|
|
static bool IsCanAdd( AR_UNIT x, AR_UNIT y );
|
|
void AddMe();
|
|
bool RemoveMe();
|
|
|
|
private:
|
|
|
|
static int getX( AR_UNIT x ) { return int(( x + CELL_SIZE/2 ) / CELL_SIZE); }
|
|
static int getY( AR_UNIT y ) { return int(( y + CELL_SIZE/2 ) / CELL_SIZE); }
|
|
|
|
StructCreature *pParent;
|
|
int x, y;
|
|
} quadTreeItem;
|
|
|
|
struct _DAMAGE
|
|
{
|
|
_DAMAGE()
|
|
{
|
|
nDamage = 0;
|
|
nResistedDamage = 0;
|
|
|
|
bCritical = false;
|
|
bMiss = false;
|
|
bBlock = false;
|
|
bPerfectBlock = false;
|
|
|
|
target_hp = 0;
|
|
}
|
|
|
|
int nDamage;
|
|
int nResistedDamage;
|
|
|
|
bool bCritical;
|
|
bool bMiss;
|
|
bool bBlock;
|
|
bool bPerfectBlock;
|
|
int target_hp;
|
|
};
|
|
|
|
struct _DAMAGE_INFO : public _DAMAGE
|
|
{
|
|
_DAMAGE_INFO()
|
|
{
|
|
memset( elemental_damage, 0, sizeof( elemental_damage ) );
|
|
}
|
|
|
|
void SetDamage( const StructCreature::_DAMAGE & damage )
|
|
{
|
|
nDamage = damage.nDamage;
|
|
|
|
bCritical = damage.bCritical;
|
|
bMiss = damage.bMiss;
|
|
bBlock = damage.bBlock;
|
|
bPerfectBlock = damage.bPerfectBlock;
|
|
|
|
target_hp = damage.target_hp;
|
|
}
|
|
|
|
int elemental_damage[ Elemental::TYPE_COUNT ];
|
|
};
|
|
|
|
struct _ATTACK_INFO : public _DAMAGE_INFO
|
|
{
|
|
_ATTACK_INFO()
|
|
{
|
|
mp_damage = 0;
|
|
attacker_damage = 0;
|
|
attacker_mp_damage = 0;
|
|
|
|
target_mp = 0;
|
|
attacker_hp = 0;
|
|
attacker_mp = 0;
|
|
}
|
|
|
|
void SetDamageInfo( const _DAMAGE_INFO & damage_info )
|
|
{
|
|
SetDamage( damage_info );
|
|
|
|
elemental_damage[0] = damage_info.elemental_damage[0];
|
|
elemental_damage[1] = damage_info.elemental_damage[1];
|
|
elemental_damage[2] = damage_info.elemental_damage[2];
|
|
elemental_damage[3] = damage_info.elemental_damage[3];
|
|
elemental_damage[4] = damage_info.elemental_damage[4];
|
|
elemental_damage[5] = damage_info.elemental_damage[5];
|
|
elemental_damage[6] = damage_info.elemental_damage[6];
|
|
}
|
|
|
|
int mp_damage;
|
|
int attacker_damage;
|
|
int attacker_mp_damage;
|
|
|
|
int target_mp;
|
|
int attacker_hp;
|
|
int attacker_mp;
|
|
};
|
|
|
|
struct StateMod
|
|
{
|
|
StateMod()
|
|
{
|
|
Init();
|
|
}
|
|
|
|
void Init()
|
|
{
|
|
fDamage = 1.0f;
|
|
nDamage = 0;
|
|
fCritical = 1.0f;
|
|
nCritical = 0;
|
|
fHate = 1.0f;
|
|
}
|
|
|
|
float fDamage;
|
|
int nDamage;
|
|
float fCritical;
|
|
int nCritical;
|
|
float fHate;
|
|
};
|
|
|
|
struct StateFlagChecker
|
|
{
|
|
StateFlagChecker( const int flag ) : flag( flag ) {}
|
|
const bool operator() ( const StructState& state ) {
|
|
return ( state.GetTimeType() & flag ) && !state.IsByEvent();
|
|
}
|
|
int flag;
|
|
};
|
|
|
|
StructCreature();
|
|
|
|
bool IsCreature() const { return true; }
|
|
|
|
virtual const char* GetName() const { return "UnknownCreature"; }
|
|
|
|
virtual int GetSID() const { return -1; }
|
|
virtual int GetStatId() const { return 200; }
|
|
virtual int GetLevel() const { return m_nLevel; }
|
|
virtual void SetLevel( int lv ) { m_nLevel = lv; }
|
|
virtual int GetMaxReachedLevel() const { return m_nMaxReachedLevel; }
|
|
virtual void SetMaxReachedLevel( int nMaxReachedLevel ) { m_nMaxReachedLevel = nMaxReachedLevel; }
|
|
virtual float GetBattleLevel() const { return m_fBattleLevel; }
|
|
virtual int GetJobId() const { return m_nJob; }
|
|
virtual int GetJobLevel() const { return m_nJobLevel; }
|
|
virtual int GetPrevJobLevel( int nDepth ) const { return ( nDepth >= 0 && nDepth < GameRule::MAX_JOB_DEPTH ) ? m_nPrevJobLevel[nDepth] : 0; }
|
|
virtual int GetPrevJobId( int nDepth ) const { return ( nDepth >= 0 && nDepth < GameRule::MAX_JOB_DEPTH ) ? m_nPrevJobId[nDepth] : 0; }
|
|
virtual int GetJobDepth() const;
|
|
virtual void SetJobLevel( int jl ) { m_nJobLevel = jl; onJobLevelUp(); }
|
|
virtual void SetPrevJobLevel( int nDepth, int jl ) { ( nDepth >= 0 && nDepth < GameRule::MAX_JOB_DEPTH - 1 ) ? m_nPrevJobLevel[nDepth] = jl : 0; }
|
|
virtual void SetPrevJobId( int nDepth, int jid ) { ( nDepth >= 0 && nDepth < GameRule::MAX_JOB_DEPTH - 1 ) ? m_nPrevJobId[nDepth] = jid : 0; }
|
|
virtual __int64 GetJobPoint() const { return m_nJobPoint; }
|
|
virtual __int64 GetTotalJobPoint() const { return m_nTotalJobPoint; }
|
|
// 특성, 플레이어 전용이지만 확장성을 위해 사용
|
|
virtual int GetTalentPoint() const { return 0; }
|
|
virtual void SetTalentPoint( int nTalentPoint ) { return; }
|
|
|
|
virtual void AddExp( __int64 exp, __int64 jp, bool bApplyStamina = true );
|
|
__int64 GetEXP() const { return m_nEXP; }
|
|
inline __int64 GetLastDecreasedEXP() { return m_nLastDecreasedEXP; }
|
|
inline void SetLastDecreasedEXP( __int64 nLastDecreasedEXP ) { m_nLastDecreasedEXP = nLastDecreasedEXP; }
|
|
void SetEXP( __int64 exp );
|
|
void SetJP( __int64 jp );
|
|
|
|
virtual unsigned long GetSkinColor() const { return 0; }
|
|
|
|
bool IsBackOf( const StructCreature & target ); // 대상의 뒤에 있는지?
|
|
bool IsSideOf( const StructCreature & target ); // 대상의 옆에 있는지?
|
|
|
|
int GetHP() const { return m_nHP; }
|
|
int GetMaxHP() const { return m_nMaxHP; }
|
|
unsigned char GetHPPercentage() const { unsigned char p = static_cast< unsigned char >( ( static_cast< float >( m_nHP ) / m_nMaxHP ) * 100 ); return ( m_nHP ? ( p ? p : 1 ) : 0 ); }
|
|
int GetMP() const { return m_nMP; }
|
|
int GetMaxMP() const { return m_nMaxMP; }
|
|
unsigned char GetMPPercentage() const { unsigned char p = static_cast< unsigned char >( ( static_cast< float >( m_nMP ) / m_nMaxMP ) * 100 ); return ( m_nMP ? ( p ? p : 1 ) : 0 ); }
|
|
int AddHP( int hp ) { return SetHP( hp + GetHP() ); }
|
|
int Heal( int hp ) { if( IsMagicalImmune() ) return 0; AddHP( hp * m_fHealRatio + m_nAdditionalHeal ); return hp * m_fHealRatio + m_nAdditionalHeal; }
|
|
int HealByItem( int hp ) { if( IsMagicalImmune() ) return 0; AddHP( hp * m_fHealRatioByItem + m_nAdditionalHealByItem ); return hp * m_fHealRatioByItem + m_nAdditionalHealByItem; }
|
|
int AddMP( int mp ) { return SetMP( mp + GetMP() ); }
|
|
int MPHeal( int mp ) { if( IsMagicalImmune() ) return 0; AddMP( mp * m_fMPHealRatio + m_nAdditionalMPHeal ); return mp * m_fMPHealRatio + m_nAdditionalMPHeal; }
|
|
int MPHealByItem( int mp ) { if( IsMagicalImmune() ) return 0; AddMP( mp * m_fMPHealRatioByItem + m_nAdditionalMPHealByItem ); return mp * m_fMPHealRatioByItem + m_nAdditionalMPHealByItem; }
|
|
|
|
// TS_SC_REGEN_HPMP 메시지 방송 있음
|
|
void RegenFullHPMP();
|
|
|
|
float GetHateRatio() { return m_fHateRatio; }
|
|
|
|
int SetHP( int hp ) { int prev_hp = m_nHP; m_nHP = hp; if( m_nHP > m_nMaxHP ) m_nHP = m_nMaxHP; if( m_nHP < 0 ) m_nHP = 0; if( prev_hp != m_nHP ) onHPChange( prev_hp ); return m_nHP; }
|
|
int SetMP( int mp ) { int prev_mp = m_nMP; m_nMP = mp; if( m_nMP > m_nMaxMP ) m_nMP = m_nMaxMP; if( m_nMP < 0 ) m_nMP = 0; if( prev_mp != m_nMP ) onMPChange( prev_mp ); return m_nMP; }
|
|
|
|
int GetEnergyCount() const { return m_nEnergy; }
|
|
int GetMaxEnergyCount() const { return m_nMaxEnergy; }
|
|
unsigned char GetEnergyUnconsumptionRate() const { return m_nEnergyUnconsumptionRate; }
|
|
void AddEnergy( int nEnergy = 1 );
|
|
void RemoveEnergy( int nEnergy );
|
|
|
|
|
|
int GetCastKeep() { return m_nCastKeep; }
|
|
|
|
virtual bool IsUsingBow() const { return false; }
|
|
virtual bool IsUsingCrossBow() const { return false; }
|
|
inline bool IsUsingDoubleWeapon() const { return m_StatusFlag.IsOn( STATUS_USING_DOUBLE_WEAPON ); } // 이도류 여부
|
|
virtual const __int64 GetBulletCount() const;
|
|
bool IsWearShield() const;
|
|
bool IsWearArmor() const { return !!GetWearedItem( ItemBase::WEAR_ARMOR ); }
|
|
virtual bool TranslateWearPosition( ItemBase::ItemWearType & pos, struct StructItem* pItem, std::vector< int > * vpOverlappItemList = NULL );
|
|
virtual ItemBase::ItemWearType GetAbsoluteWearPos( ItemBase::ItemWearType & pos ) { if( !m_anWear[pos] ) return static_cast< ItemBase::ItemWearType >( -1 ); else return pos; } // 실제 장착 위치 얻어오는 함수
|
|
bool IsWearable( ItemBase::ItemWearType pos, struct StructItem* pItem ) { return TranslateWearPosition( pos, pItem ); }
|
|
bool IsWeared( AR_HANDLE ItemHandle );
|
|
bool IsWeared( ItemBase::ItemCode code );
|
|
virtual struct StructItem* GetWearedItem( ItemBase::ItemWearType idx ) const { if( idx < ItemBase::MAX_SPARE_ITEM_WEAR && idx >= 0 ) return m_anWear[idx]; else return NULL; }
|
|
struct StructItem* GetWearedItemByAbsolutePos( ItemBase::ItemWearType idx ) const { if( idx < ItemBase::MAX_SPARE_ITEM_WEAR && idx >= 0 ) return m_anWear[idx]; else return NULL; }
|
|
unsigned short Puton( ItemBase::ItemWearType pos, struct StructItem* pItem );
|
|
unsigned short Putoff( ItemBase::ItemWearType pos );
|
|
void PutonSet( struct StructItem * pItemList[] );
|
|
|
|
// 상태 관련
|
|
bool IsDead() const { return !m_nHP; }
|
|
bool IsAlive() const { return !IsDead(); }
|
|
virtual bool IsSitDown() const { return false; }
|
|
AR_TIME GetDeadTime() const { return m_nDeadTime; }
|
|
void SetDeadTime( AR_TIME dead_time ) { m_nDeadTime = dead_time; }
|
|
|
|
bool IsFirstEnter() const { return m_StatusFlag.IsOn( STATUS_FIRST_ENTER ); }
|
|
void SetFirstEnter( bool bFirstEnter ) { m_StatusFlag.Set( STATUS_FIRST_ENTER, bFirstEnter ); }
|
|
|
|
virtual unsigned char GetRace() const { return 0; }
|
|
|
|
virtual AR_TIME GetNextAttackableTime() const { return m_nNextAttackableTime; }
|
|
virtual void SetNextAttackableTime( AR_TIME t ) { m_nNextAttackableTime = t; }
|
|
virtual AR_TIME GetNextCastableTime() const { return m_nNextCastableTime; }
|
|
virtual void SetNextCastableTime( AR_TIME t ) { m_nNextCastableTime = t; }
|
|
void SetMovableTime( AR_TIME t ) { m_nMovableTime = t; }
|
|
AR_TIME GetMovableTime() const { return m_nMovableTime; }
|
|
|
|
bool SetPendingMove( const std::vector< ArPosition > & newPos, unsigned char speed );
|
|
|
|
|
|
enum DamageType
|
|
{
|
|
DT_NORMAL_PHYSICAL_DAMAGE = 0, // 일반 공격
|
|
DT_NORMAL_MAGICAL_DAMAGE = 1, // 일반 마법
|
|
DT_NORMAL_PHYSICAL_SKILL_DAMAGE = 2, // 물리 스킬
|
|
DT_ADDITIONAL_DAMAGE = 3, // 추가 데미지
|
|
DT_NORMAL_PHYSICAL_LEFT_HAND_DAMAGE = 4, // 왼손 데미지
|
|
DT_ADDITIONAL_LEFT_HAND_DAMAGE = 5, // 왼손 추가 데미지
|
|
DT_ADDITIONAL_MAGICAL_DAMAGE = 6, // 추가 데미지
|
|
DT_STATE_MAGICAL_DAMAGE = 7, // 지속 마법 데미지
|
|
DT_STATE_PHYSICAL_DAMAGE = 8, // 지속 물리 데미지
|
|
};
|
|
|
|
enum DamageFlag
|
|
{
|
|
IGNORE_AVOID = ( 1 << 1 ), // 회피 무시
|
|
IGNORE_DEFENCE = ( 1 << 2 ), // 방어 무시
|
|
IGNORE_BLOCK = ( 1 << 3 ), // 블럭 무시
|
|
IGNORE_CRITICAL = ( 1 << 4 ), // 클티 무시(클티 안뜸)
|
|
FORCE_DOUBLE = ( 1 << 6 ),
|
|
};
|
|
|
|
void Attack( StructCreature *pTarget, AR_TIME t, AR_TIME attack_interval, struct StructCreature::_ATTACK_INFO * arDamage, bool & bIsDoubleAttack );
|
|
|
|
// 에테리얼 내구도 관련
|
|
virtual void ProcEtherealDurabilityConsumption( const bool bIsAttacker, const enum DamageType eDamageType, const int nDamage ) {}
|
|
|
|
// 데미지 인포를 리턴함.;;
|
|
|
|
StructCreature::_DAMAGE_INFO DealPhysicalNormalDamage( StructCreature *pFrom, int nDamage, Elemental::Type elemental_type = Elemental::TYPE_NONE, int accuracy_bonus = 0, int critical_bonus = 0, int nFlag = 0 );
|
|
StructCreature::_DAMAGE_INFO DealPhysicalNormalLeftHandDamage( StructCreature *pFrom, int nDamage, Elemental::Type elemental_type = Elemental::TYPE_NONE, int accuracy_bonus = 0, int critical_bonus = 0, int nFlag = 0);
|
|
|
|
StructCreature::_DAMAGE_INFO DealMagicalSkillDamage( StructCreature *pFrom, int nDamage, Elemental::Type elemental_type = Elemental::TYPE_NONE, int accuracy_bonus = 0, int critical_bonus = 0, int nFlag = 0 );
|
|
StructCreature::_DAMAGE_INFO DealPhysicalSkillDamage( StructCreature *pFrom, int nDamage, Elemental::Type elemental_type = Elemental::TYPE_NONE, int accuracy_bonus = 0, int critical_bonus = 0, int nFlag = 0 );
|
|
|
|
// 데미지를 리턴함
|
|
StructCreature::_DAMAGE DealMagicalDamage( StructCreature *pFrom, int nDamage, Elemental::Type elemental_type = Elemental::TYPE_NONE, int accuracy_bonus = 0, int critical_bonus = 0, int nFlag = 0, const StateMod * damage_penalty = NULL, const StateMod * damage_advantage = NULL );
|
|
StructCreature::_DAMAGE DealPhysicalDamage( StructCreature *pFrom, int nDamage, Elemental::Type elemental_type = Elemental::TYPE_NONE, int accuracy_bonus = 0, int critical_bonus = 0, int nFlag = 0, const StateMod * damage_penalty = NULL, const StateMod * damage_advantage = NULL );
|
|
StructCreature::_DAMAGE DealStateMagicalDamage( StructCreature *pFrom, int nDamage, Elemental::Type elemental_type = Elemental::TYPE_NONE, int accuracy_bonus = 0, int critical_bonus = 0, int nFlag = 0, const StateMod * damage_penalty = NULL, const StateMod * damage_advantage = NULL );
|
|
StructCreature::_DAMAGE DealPhysicalStateDamage( StructCreature *pFrom, int nDamage, Elemental::Type elemental_type = Elemental::TYPE_NONE, int accuracy_bonus = 0, int critical_bonus = 0, int nFlag = 0, const StateMod * damage_penalty = NULL, const StateMod * damage_advantage = NULL );
|
|
StructCreature::_DAMAGE DealPhysicalLeftHandDamage( StructCreature *pFrom, int nDamage, Elemental::Type elemental_type = Elemental::TYPE_NONE, int accuracy_bonus = 0, int critical_bonus = 0, int nFlag = 0, const StateMod * damage_penalty = NULL, const StateMod * damage_advantage = NULL );
|
|
StructCreature::_DAMAGE DealAdditionalDamage( StructCreature *pFrom, int nDamage, Elemental::Type elemental_type = Elemental::TYPE_NONE, int accuracy_bonus = 0, int critical_bonus = 0, int nFlag = 0, const StateMod * damage_penalty = NULL, const StateMod * damage_advantage = NULL );
|
|
StructCreature::_DAMAGE DealAdditionalLeftHandDamage( StructCreature *pFrom, int nDamage, Elemental::Type elemental_type = Elemental::TYPE_NONE, int accuracy_bonus = 0, int critical_bonus = 0, int nFlag = 0, const StateMod * damage_penalty = NULL, const StateMod * damage_advantage = NULL );
|
|
StructCreature::_DAMAGE DealAdditionalMagicalDamage( StructCreature *pFrom, int nDamage, Elemental::Type elemental_type = Elemental::TYPE_NONE, int accuracy_bonus = 0, int critical_bonus = 0, int nFlag = 0, const StateMod * damage_penalty = NULL, const StateMod * damage_advantage = NULL );
|
|
StructCreature::_DAMAGE DealDamage( StructCreature *pFrom, int nDamage, Elemental::Type elemental_type, DamageType damageType, int accuracy_bonus, int critical_bonus, int nFlag, const StateMod * damage_penalty, const StateMod * damage_advantage );
|
|
|
|
int GetCriticalDamage( int damage, float critical_amp, int critical_bonus ); // 크리티컬 추가 데미지
|
|
|
|
virtual bool StartAttack( AR_HANDLE target, bool bNeedFastReaction = true );
|
|
virtual void CancelAttack();
|
|
virtual void EndAttack();
|
|
bool IsAttacking() const { return !!m_hEnemy; }
|
|
AR_HANDLE GetEnemyHandle() const { return m_hEnemy; }
|
|
virtual void onAttack( StructCreature * pTarget, int nDamage ) {}
|
|
virtual int onDamage( StructCreature * pFrom, Elemental::Type elementalType, DamageType damageType, int nDamage, bool bCritical );
|
|
virtual bool IsBattleMode() const { return false; }
|
|
void AddHateToEnemyList( AR_HANDLE handle, int pt );
|
|
bool AddToEnemyList( AR_HANDLE handle );
|
|
bool RemoveFromEnemyList( AR_HANDLE handle );
|
|
size_t GetEnemyCount() { return m_vEnemyList.size(); }
|
|
void RemoveAllHate();
|
|
|
|
virtual const CreatureStat & GetBaseStat() const { static CreatureStat inst; return inst; }
|
|
|
|
inline const CreatureStatServer & GetStat() const { return m_Stat; }
|
|
inline const CreatureAttributeServer & GetAttribute() const { return m_Attribute; }
|
|
inline const CreatureStatServer & GetStatByState() const { return m_StatByState; }
|
|
inline const CreatureAttributeServer & GetAttributeByState() const { return m_AttributeByState; }
|
|
|
|
inline int GetHPRegenPercentage() { return m_Attribute.fHPRegenPercentage; }
|
|
inline int GetHPRegenPoint() { return m_Attribute.fHPRegenPoint; }
|
|
inline int GetMPRegenPercentage() { return m_Attribute.fMPRegenPercentage; }
|
|
inline int GetMPRegenPoint() { return m_Attribute.fMPRegenPoint; }
|
|
ItemBase::ItemClass GetWeaponClass();
|
|
ItemBase::ItemClass GetArmorClass();
|
|
|
|
virtual int GetCreatureGroup() const { return (m_nChangingGroup == CREATURE_NONE) ? CREATURE_ETC : m_nChangingGroup; }
|
|
|
|
inline const c_fixed10 & GetStrength() const { return m_Stat.strength; }
|
|
inline const c_fixed10 & GetVital() const { return m_Stat.vital; }
|
|
inline const c_fixed10 & GetDexterity() const { return m_Stat.dexterity; }
|
|
inline const c_fixed10 & GetAgility() const { return m_Stat.agility; }
|
|
inline const c_fixed10 & GetIntelligence() const { return m_Stat.intelligence; }
|
|
inline const c_fixed10 & GetMentality() const { return m_Stat.mentality; }
|
|
inline const c_fixed10 & GetLuck() const { return m_Stat.luck; }
|
|
|
|
virtual const c_fixed10 GetFCMRatio() const { return m_fSummonFCM; }
|
|
|
|
virtual const c_fixed10 GetRecPerMaxHP()const { return m_fRecPerMaxHP; }
|
|
virtual const c_fixed10 GetRecPerDamage()const { return m_fRecPerDamage; }
|
|
|
|
virtual const c_fixed10 GetFCM() const { return 1; }
|
|
inline float GetWeight() const { return m_fWeight; }
|
|
inline int GetCritical() const { return m_Attribute.fCritical; } // 크리티컬
|
|
inline int GetCriticalPower() const { return m_Attribute.fCriticalPower;} // 일단 100%로..
|
|
inline int GetAttackPointRight() const { return m_Attribute.fAttackPointRight; } // 오른손 공격력
|
|
int GetAttackPointRight( Elemental::Type type, bool bPhysical, bool bBad );
|
|
inline int GetAttackPointLeft() const { return m_Attribute.fAttackPointLeft; } // 왼손 공격력
|
|
inline int GetDefence() const { return m_Attribute.fDefence; } // 방어력
|
|
inline int GetMagicPoint() const { return m_Attribute.fMagicPoint; } // 마력
|
|
int GetMagicPoint( Elemental::Type type, bool bPhysical, bool bBad );
|
|
inline int GetMagicDefence() const { return m_Attribute.fMagicDefence; } // 마법방어력
|
|
inline int GetAccuracyRight() const { return m_Attribute.fAccuracyRight;} // 명중(오른손)
|
|
inline int GetAccuracyLeft() const { return m_Attribute.fAccuracyLeft; } // 명중(왼손)
|
|
inline int GetMagicAccuracy() const { return m_Attribute.fMagicAccuracy;} // 마명중
|
|
inline int GetAvoid() const { return m_Attribute.fAvoid; } // 회피
|
|
inline int GetMagicAvoid() const { return m_Attribute.fMagicAvoid; } // 마법회피
|
|
inline int GetBlockChance() const { return m_Attribute.fBlockChance; } // 블럭율
|
|
inline int GetBlockDefence() const { return m_Attribute.fBlockDefence; } // 블럭 방어력
|
|
virtual int GetMoveSpeed() const { return m_Attribute.fMoveSpeed; } // 이동속도
|
|
inline int GetRidingSpeed() const { return m_Attribute.fRidingSpeed; } // 라이딩 속도
|
|
inline int GetAttackSpeed() const { return m_Attribute.fAttackSpeed; } // 공격속도
|
|
inline int GetMaxWeight() const { return m_Attribute.fMaxWeight; } // 소지가능무게
|
|
inline int GetCastingSpeed() const { return m_Attribute.fCastingSpeed; } // 시전속도
|
|
float GetCastingMod( Elemental::Type type, bool bPhysical, bool bBad, AR_TIME nOriginalCoolTime );
|
|
float GetManaCostRatio( Elemental::Type type, bool bPhysical, bool bBad );
|
|
float GetCoolTimeMod( Elemental::Type type, bool bPhysical, bool bBad );
|
|
float GetCoolTimeSpeed() { return m_Attribute.fCoolTimeSpeed / 100.0f; }
|
|
virtual int GetItemChance() const { return m_Attribute.fItemChance; }
|
|
AR_UNIT GetDetectHideRange() const { return m_fDetectHideRange; }
|
|
float GetCreatureCardChance() const { return m_fCreatureCardChance; }
|
|
int GetElementalResist( Elemental::Type elemental_type ) const { return m_Resist.nResist[ elemental_type ]; }
|
|
float GetMagicalHateMod( Elemental::Type type, bool bPhysical, bool bBad );
|
|
std::pair< float, int> GetHateMod( int nHateModType /* 1: PhysicalSkill, 2: MagicalSkill, 3: NormalAttack */, bool bIsHarmful );
|
|
|
|
float GetStunResistance() const { return m_Attribute.fStunResistance; }
|
|
|
|
const SkillCostModifier& GetSkillCostModifier() const { return m_SkillCostModifier; }
|
|
|
|
virtual float GetScale() const { return GameRule::DEFAULT_HUMAN_SIZE; }
|
|
virtual float GetSize() const { return GameRule::DEFAULT_HUMAN_SIZE; }
|
|
inline AR_UNIT GetUnitSize() const { return GetSize() * (float) GameRule::DEFAULT_UNIT_SIZE * GetScale(); }
|
|
|
|
// (2007-03-24 리뉴얼 적용)
|
|
inline AR_TIME GetAttackInterval() const { return 100 * ( 100.0f / GetAttackSpeed() ); } // { return 115 * ( 100.0f / GetAttackSpeed() ); }
|
|
inline AR_UNIT GetRealAttackRange() const { return ( m_Attribute.fAttackRange * GameRule::DEFAULT_UNIT_SIZE ) / (float)GameRule::ATTACK_RANGE_UNIT; }
|
|
unsigned char GetRealMoveSpeed() const;
|
|
unsigned char GetRealRidingSpeed() const;
|
|
inline const c_fixed10 GetAttackPointRightWithoutWeapon() const { return m_fAttackPointRightWithoutWeapon; }
|
|
const c_fixed10 GetAttackPointRightWithoutWeapon( Elemental::Type type, bool bPhysical, bool bBad ) const;
|
|
inline const c_fixed10 GetAttackPointLeftWithoutWeapon() const { return m_fAttackPointLeftWithoutWeapon; }
|
|
|
|
inline AR_TIME GetBowAttackInterval() const { return GetAttackInterval() * ( 1.0f - m_fBowInterval ); }
|
|
inline AR_TIME GetBowInterval() const { return GetAttackInterval() * m_fBowInterval; }
|
|
|
|
// 일정 초마다 정기적으로 호출됨
|
|
virtual void OnUpdate();
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
// 상태이상
|
|
static int AllocStateUID( int & nDBEnable );
|
|
static void DeallocStateUID( const int nUID );
|
|
unsigned short AddState( StructState::StateCode code, AR_HANDLE caster, int level, AR_TIME start_time, AR_TIME end_time, bool bIsAura = false, int nStateValue = 0, const char * szStateValue = "", const bool bByEvent = false, const int nAllocatedUID = 0, int nDBEnable = StructState::NOT_IN_DB );
|
|
void PendAddState( StructState::StateCode code, AR_HANDLE caster, int level, AR_TIME start_time, AR_TIME end_time, bool bIsAura = false, int nStateValue = 0, const char * szStateValue = "", const bool bByEvent = false );
|
|
void PendAddStateByItem( StructState::StateCode code, AR_HANDLE caster, int level, AR_TIME start_time, AR_TIME end_time, bool bIsAura = false, int nStateValue = 0, const char * szStateValue = "", const bool bByEvent = false );
|
|
void AddStateByAttack( StructCreature *pTarget, const bool bIsAttacking, const DWORD nAttackType, const Elemental::Type nElementalType );
|
|
void RemoveState( StructState::StateCode code, int state_level = GameRule::MAX_STATE_LEVEL, const bool bByEvent = false ); // state_level 이하는 다 제거됨
|
|
void RemoveStatesOnDamaged();
|
|
template< typename Predicate >
|
|
void RemoveStateIf( Predicate& predicate, std::vector< StructState >* result = NULL, const bool bByDead = false );
|
|
void RemoveGoodState( int state_level ); // 이로운 state_level 이하 지속 효과는 다 제거됨
|
|
void DecreaseState( StructState::StateCode code, const unsigned char level, const bool bByEvent = false );
|
|
template< typename Predicate >
|
|
void DecreaseStateIf( Predicate& predicate, const unsigned char level, std::vector< StructState >* result = NULL );
|
|
void PendClearStateWithFlag( const StateInfo::_ATTRIBUTE_FLAG & nStateFlag ) { m_nPendedClearStateFlag |= static_cast< int >( nStateFlag ); }
|
|
const std::vector< StructState > & GetStateList() const { return m_vStateList; }
|
|
const c_fixed10 GetResistStateRate( StructState::StateCode code )
|
|
{
|
|
std::map< StructState::StateCode, c_fixed10 >::const_iterator it = m_mapResistHarmfulState.find( code );
|
|
return ( it != m_mapResistHarmfulState.end() ) ? (*it).second : 0;
|
|
}
|
|
|
|
struct StructState * GetState( const StructState::StateCode code );
|
|
const struct StructState * GetState( const StructState::StateCode code ) const;
|
|
|
|
bool ClearExpiredState( AR_TIME t = 0 );
|
|
void RestoreRemovedStateByDead();
|
|
inline void ClearRemovedStateByDead();
|
|
|
|
void RemoveAllAura();
|
|
void RemoveAllStateByDeadOrLogout();
|
|
void RemoveAllStateByQuittingHuntaholic();
|
|
void RemoveStateByEnteringDeathmatch();
|
|
void RemoveAllStateByQuittingDeathmatch();
|
|
void RemoveAllStateByQuittingBattleArena();
|
|
|
|
const bool IsFeared() const { return m_StatusFlag.IsOn( STATUS_FEARED ); }
|
|
const bool IsFormChanged() const { return m_StatusFlag.IsOn( STATUS_FORM_CHANGED ); }
|
|
|
|
bool IsPhysicalImmune() { return ( GetState( StructState::SEAL ) != NULL ); }
|
|
bool IsMagicalImmune() { return ( GetState( StructState::SEAL ) != NULL || GetState( StructState::SHINE_WALL ) != NULL ); }
|
|
|
|
bool IsNeedStateNotify() const { if( m_vStateList.size() ) return true; return false; }
|
|
|
|
virtual bool IsActable()
|
|
{
|
|
return ( !IsDead() && !IsFeared() && ( m_StatusFlag.IsOn( STATUS_MOVABLE ) || m_StatusFlag.IsOn( STATUS_ATTACKABLE ) || m_StatusFlag.IsOn( STATUS_SKILL_CASTABLE ) || m_StatusFlag.IsOn( STATUS_MAGIC_CASTABLE ) || m_StatusFlag.IsOn( STATUS_ITEM_USABLE ) ) );
|
|
}
|
|
|
|
virtual bool IsAttackable()
|
|
{
|
|
if( !IsActable() || IsSitDown() || IsUsingSkill() ) return false;
|
|
return m_StatusFlag.IsOn( STATUS_ATTACKABLE );
|
|
}
|
|
|
|
virtual bool IsMovable()
|
|
{
|
|
if( IsDead() || IsSitDown() ) return false;
|
|
if( GetMovableTime() > GetArTime() ) return false;
|
|
if( IsUsingSkill() ) return false;
|
|
|
|
return m_StatusFlag.IsOn( STATUS_MOVABLE );
|
|
}
|
|
|
|
bool IsNeedToUpdateState() const { return m_StatusFlag.IsOn( STATUS_NEED_TO_UPDATE_STATE ); }
|
|
void SetNeedToUpdateState( bool bNeedToUpdateState = true ) { m_StatusFlag.Set( STATUS_NEED_TO_UPDATE_STATE, bNeedToUpdateState ); }
|
|
|
|
virtual bool IsKnockbackable()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
virtual bool IsItemUseable()
|
|
{
|
|
if( !IsActable() || IsUsingSkill() ) return false;
|
|
|
|
return m_StatusFlag.IsOn( STATUS_ITEM_USABLE );
|
|
}
|
|
|
|
virtual bool IsItemWearable()
|
|
{
|
|
if( !IsActable() ) return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
virtual bool IsSkillCastable()
|
|
{
|
|
if( !IsActable() || GetState( StructState::MUTE ) ) return false;
|
|
if( IsSitDown() ) return false;
|
|
if( IsUsingSkill() ) return false;
|
|
if( IsAttacking() ) return false;
|
|
return m_StatusFlag.IsOn( STATUS_SKILL_CASTABLE );
|
|
}
|
|
|
|
virtual bool IsMagicCastable()
|
|
{
|
|
if( !IsActable() || GetState( StructState::MUTE ) ) return false;
|
|
if( IsSitDown() ) return false;
|
|
if( IsUsingSkill() ) return false;
|
|
if( IsAttacking() ) return false;
|
|
return m_StatusFlag.IsOn( STATUS_MAGIC_CASTABLE );
|
|
}
|
|
|
|
virtual bool IsEnemy( StructCreature* pTarget, bool bIncludeHiding = false );
|
|
virtual bool IsAlly( StructCreature* pTarget );
|
|
|
|
// 범용적인 부활 처리, 추후에 기존의 부활들도 이 함수를 통하도록 수정
|
|
bool Resurrect( const _CHARACTER_RESURRECTION_TYPE eResurrectType, const int nIncHP, const int nIncMP, const __int64 nRecoveryEXP, const bool bIsRestoreRemovedStateByDead );
|
|
bool ResurrectByState();
|
|
|
|
bool AddAimer( AR_HANDLE aimer );
|
|
bool RemoveAimer( AR_HANDLE aimer );
|
|
void ReleaseAimerList();
|
|
|
|
// 스킬 관련
|
|
struct SKILL_FUNCTOR { virtual void onSkill( int sid, int skill_id, int base_skill_level, int current_skill_level, AR_TIME total_cool_time, AR_TIME remain_cool_time ) {} };
|
|
struct ADDED_SKILL_FUNCTOR { virtual void onSkill( int skill_id, bool restricted_to_type, char added_skill_level ) {} };
|
|
struct STATE_FUNCTOR { virtual void onState( struct StructState* pState ) {} };
|
|
struct SKILL_POINTER_FUNCTOR { virtual void onSkill( struct StructSkill* pSkill ) {} };
|
|
|
|
struct StructSkill* GetCastSkill() { return m_pCastSkill; }
|
|
struct StructSkill* SetSkill( int skill_uid, int skill_id, int skill_level, AR_TIME remain_cool_time );
|
|
void RegisterSkill( int skill_id, int skill_level, AR_TIME remain_cool_time = 0, int nJobId = 0 );
|
|
size_t GetSkillCount() const { return m_vAllSkillList.size(); }
|
|
__int64 GetAllSkillJP() const;
|
|
__int64 GetAllJobLevelJP() const;
|
|
virtual int GetAllSkillTP() const { return 0; }
|
|
virtual int IsLearnableSkill( int nSkillID, int nSkillLevel, int *nSkillTreeID );
|
|
|
|
enum _SKILL_RESET_METHOD
|
|
{
|
|
SRM_ITEM = 0,
|
|
SRM_SCRIPT = 1,
|
|
SRM_SUMMON_ENHANCE = 2,
|
|
};
|
|
|
|
bool ResetSkill( const _SKILL_RESET_METHOD eMethod, const int jobDepth = 0, int doResetRandomSkill = 0 );
|
|
int GetBaseSkillLevel( int skill_id ) const;
|
|
int GetAddedSkillLevel( const StructSkill *const pSkill ) const;
|
|
int GetCurrentSkillLevel( int skill_id ) const;
|
|
|
|
int GetCurrentSkillEnchant(int skill_id) const;
|
|
|
|
int GetCurrentPassiveSkillLevel( int skill_id ) const;
|
|
struct StructSkill* GetCurrentPassiveSkill( int skill_id ) const;
|
|
struct StructSkill * GetSkill( int skill_id ) const;
|
|
const struct StructSkill * GetSkillByEffectType( const int nEffectTypeID ) const;
|
|
void AddRemainCoolTime( const int skill_id, const int nInc, const float fAmp );
|
|
AR_TIME GetRemainCoolTime( int skill_id ) const;
|
|
AR_TIME GetTotalCoolTime( int skill_id ) const;
|
|
void EnumSkill( SKILL_FUNCTOR & _fo ) const;
|
|
void EnumActiveSkill( SKILL_POINTER_FUNCTOR & _fo );
|
|
void EnumPassiveSkill( SKILL_POINTER_FUNCTOR & _fo );
|
|
void EnumAddedSkill( ADDED_SKILL_FUNCTOR & _fo ) const;
|
|
void EnumState( STATE_FUNCTOR & _fo );
|
|
bool CancelSkill();
|
|
bool OnCompleteSkill();
|
|
const unsigned short CastSkill( int nSkillId, int nSkillLevel, AR_HANDLE target_handle, const ArPosition & pos, unsigned char layer, AR_HANDLE hCastItem = 0 );
|
|
void FireSkill();
|
|
bool IsActiveAura( struct StructSkill * pSkill );
|
|
bool IsActiveLuna() { return m_nLuna; }
|
|
bool TurnOnAura( struct StructSkill * pSkill );
|
|
bool TurnOffAura( struct StructSkill * pSkill );
|
|
void ToggleAura( struct StructSkill * pSkill );
|
|
bool IsUsingSkill();
|
|
void BindSkillCard( struct StructItem *pItem, const bool bSkipDBUpdate = false );
|
|
void UnBindSkillCard( struct StructItem *pItem );
|
|
StateMod * GetMagicalSkillStatePenalty() { return &m_MagicalSkillStatePenalty; }
|
|
inline void SetTrapHandle( const AR_HANDLE handle ) { m_hTrap = handle; }
|
|
AR_HANDLE GetTrapHandle();
|
|
|
|
unsigned short onItemUseEffect( struct StructCreature *pCaster, struct StructItem* pItem, int type, c_fixed10 var1, c_fixed10 var2, const char *szParameter = NULL );
|
|
|
|
virtual void onRegionChange( unsigned prev_rx, unsigned prev_ry, unsigned rx, unsigned ry ) {}
|
|
|
|
virtual void onRemoveFromWorld() { RemoveAllHate(); ReleaseAimerList(); }
|
|
|
|
virtual void onProcess( int nThreadIdx );
|
|
virtual void onHPChange( int nPrevHP );
|
|
|
|
inline bool IsLoginComplete() { return m_StatusFlag.IsOn( STATUS_LOGIN_COMPLETE ); }
|
|
inline void SetLoginComplete() { m_StatusFlag.On( STATUS_LOGIN_COMPLETE ); }
|
|
|
|
inline bool IsReadInfoComplete() { return m_StatusFlag.IsOn( STATUS_READ_INFO_COMPLETE ); }
|
|
inline void SetReadInfoComplete() { m_StatusFlag.On( STATUS_READ_INFO_COMPLETE ); }
|
|
|
|
inline const bool IsNeedToBroadcastStatusFlag() const { return m_bNeedToBroadcastStatusFlag; }
|
|
inline void SetNeedToBroadcastStatusFlag( const bool bNeed = true ) { m_bNeedToBroadcastStatusFlag = bNeed; }
|
|
|
|
inline bool HasPendingMove() { return m_StatusFlag.IsOn( STATUS_MOVE_PENDED ); }
|
|
inline void ReleasePendingMove() { m_StatusFlag.Off( STATUS_MOVE_PENDED ); }
|
|
void ProcessAttack();
|
|
void ProcessAddHPMPOnCritical();
|
|
|
|
void SetNeedCalculateStat() { m_StatusFlag.On( STATUS_NEED_TO_CALCULATE_STAT ); }
|
|
|
|
void RemoveExhaustiveSkillStateMod( bool bPhysical, bool bHarmful, int nElementalType, AR_TIME nOriginalCastingDelay );
|
|
void PrepareRemoveExhaustiveSkillStateMod( bool bPhysical, bool bHarmful, int nElementalType, AR_TIME nOriginalCastingDelay );
|
|
|
|
void SetInvisible( bool bInvisible ) { m_StatusFlag.Set( STATUS_INVISIBLE, bInvisible ); }
|
|
bool IsInvisible() const { return m_StatusFlag.IsOn( STATUS_INVISIBLE ); }
|
|
void SetInvincible( bool bInvincible ) { m_StatusFlag.Set( STATUS_INVINCIBLE, bInvincible ); }
|
|
bool IsInvincible() const { return m_StatusFlag.IsOn( STATUS_INVINCIBLE ); }
|
|
bool IsHiding() const { return m_StatusFlag.IsOn( STATUS_HIDING ); }
|
|
virtual bool IsVisible( StructCreature *pTarget );
|
|
inline bool IsProcessingReflectDamage() const { return m_StatusFlag.IsOn( STATUS_PROCESSING_REFELCT ); }
|
|
|
|
int damage( StructCreature * pFrom, int nDamage, bool decreaseEXPOnDead = true );
|
|
|
|
// 이하 핸들러
|
|
void OnAttack( StructCreature *pTarget, const int nDamage, const DWORD nAttackType, const int nElementalType, const int nSkillId = 0 );
|
|
void OnKill( StructCreature *pTarget );
|
|
void OnCritical( StructCreature *pTarget, const int nDamage, const DWORD nAttackType, const int nElementalType );
|
|
void OnAvoid( StructCreature *pFrom, const DWORD nAttackType, const int nElementalType );
|
|
void OnBlock( StructCreature *pFrom, const int nDamage, const DWORD nAttackType, const int nElementalType );
|
|
void OnPerfectBlock( StructCreature *pFrom, const DWORD nAttackType, const int nElementalType );
|
|
void OnDoubleAttack( StructCreature *pTarget );
|
|
|
|
// 강화 관련
|
|
virtual int GetEnhance() const { return 0; }
|
|
|
|
const ParameterForSummon & GetParameterForSummon() { return m_ParameterForSummon; }
|
|
const CreatureStatServer & GetStatBeforeParamBasedCalc() { return m_StatBeforeParamBasedCalc; }
|
|
const CreatureAttributeServer & GetAttrBeforeParamBasedCalc() { return m_AttrBeforeParamBasedCalc; }
|
|
|
|
c_fixed10 CalcStatSum( const int bitset, const CreatureStatServer& statBeforeCalc );
|
|
c_fixed10 CalcStatSum( const int bitset ) { return CalcStatSum( bitset, m_Stat ); }
|
|
c_fixed10 CalcAttributeSum( const int bitset1, const int bitset2 ) { return CalcAttributeSum( bitset1, bitset2, m_Attribute); }
|
|
virtual c_fixed10 CalcAttributeSum( const int bitset1, const int bitset2, const CreatureAttributeServer& attrBeforeCalc );
|
|
|
|
protected:
|
|
|
|
virtual ~StructCreature();
|
|
|
|
friend struct DB_Login;
|
|
friend struct DB_ReadCharacter;
|
|
friend struct DB_ReadStorageList;
|
|
|
|
void CheckAndSetEnhanceSkill( StructSkill* skill );
|
|
|
|
void removeStateByDead();
|
|
void removeStateWithFlag( const int & nFlag );
|
|
|
|
void processSkill();
|
|
void processAttack();
|
|
void processPendingMove();
|
|
|
|
// 생물체 상태 플래그 관련
|
|
const bool isFirstAttack() const { return m_StatusFlag.IsOn( STATUS_FIRST_ATTACK ); }
|
|
const bool isAttackStarted() const { return m_StatusFlag.IsOn( STATUS_ATTACK_STARTED ); }
|
|
const bool isMortal() const { return m_StatusFlag.IsOn( STATUS_MORTAL ); }
|
|
const bool isMoveSpeedFixed() const { return m_StatusFlag.IsOn( STATUS_MOVE_SPEED_FIXED ); }
|
|
const bool isFearMoving() const { return m_StatusFlag.IsOn( STATUS_MOVING_BY_FEAR ); }
|
|
const bool isHPRegenStopped() const { return m_StatusFlag.IsOn( STATUS_HP_REGEN_STOPPED ); }
|
|
const bool isMPRegenStopped() const { return m_StatusFlag.IsOn( STATUS_MP_REGEN_STOPPED ); }
|
|
const bool isNeedToCalculateStat() const { return m_StatusFlag.IsOn( STATUS_NEED_TO_CALCULATE_STAT ); }
|
|
|
|
virtual void onAfterAddState( StructState & state ) { procMoveSpeedChangement(); }
|
|
virtual void onAfterRemoveState( StructState & state, const bool bByDead = false ) { procMoveSpeedChangement(); }
|
|
virtual void procMoveSpeedChangement();
|
|
|
|
virtual unsigned short putonItem( ItemBase::ItemWearType pos, struct StructItem * pItem ); // insert absolute position
|
|
virtual unsigned short putoffItem( ItemBase::ItemWearType pos ); // insert absolute position
|
|
static unsigned short putoffItem( StructCreature * pCreature, ItemBase::ItemWearType pos ); // 아악. 존나 구려!!
|
|
|
|
virtual void onUpdateState( StructState & state, bool bIsExpire = false );
|
|
bool onProcAura( struct StructSkill *pSkill, int nRequestedSkillLevel );
|
|
|
|
virtual void onCantAttack( AR_HANDLE target, AR_TIME t ) {}
|
|
virtual void onDead( StructCreature *pFrom, bool decreaseEXPOnDead = true );
|
|
virtual void onMPChange( int nPrevMP ) {}
|
|
virtual void onJobLevelUp() {}
|
|
virtual void onJPChange() {}
|
|
virtual void onExpChange() {}
|
|
virtual void onEnergyChange() {}
|
|
virtual void onRegisterSkill( int skill_uid, int skill_id, int skill_level, bool is_new_skill ) {}
|
|
virtual void onStatChange() {}
|
|
virtual void onAttributeChange() {}
|
|
|
|
// 스킬 초기화 관련
|
|
virtual __int64 getJPAfterSkillReset() { return GetJobPoint() + GetAllSkillJP(); }
|
|
virtual int getTPAfterSkillReset() { return 0; }
|
|
|
|
virtual void onResetSkill( const int jobDepth ) {}
|
|
void AdjustOverflowedSkillLevel( const int remainingMaxJobDepth );
|
|
|
|
template< typename SkillPredicate >
|
|
LearningCost RemoveSkill( const SkillPredicate& predicate );
|
|
template< typename SkillPredicate >
|
|
LearningCost removeSkillFromList( const SkillPredicate& predicate );
|
|
template< typename SkillPredicate >
|
|
void turnOffAuraOnSkillReset( const SkillPredicate& predicate );
|
|
|
|
virtual void onRemoveSkill( StructSkill* removedSkill ) {}
|
|
|
|
const bool UpdateSkillLevel( StructSkill* skill, int targetLevel );
|
|
|
|
virtual void regenHPMP( AR_TIME t );
|
|
void procStateDamage( AR_TIME t );
|
|
void procState( AR_TIME t );
|
|
|
|
int m_nLuna;
|
|
|
|
int m_nRace;
|
|
|
|
int m_nCriticalCount;
|
|
|
|
int m_nHP;
|
|
int m_nMaxHP;
|
|
int m_nMinHP;
|
|
c_fixed10 m_fMinHP;
|
|
int m_nHPDecPart;
|
|
int m_nMP;
|
|
int m_nMaxMP;
|
|
int m_nMPDecPart;
|
|
|
|
int m_nMaxEnergy;
|
|
int m_nEnergy;
|
|
int m_nEnergyStartPos;
|
|
AR_TIME m_arEnergy[GameRule::ENERGY_MAX];
|
|
AR_TIME m_nEnergyUpkeepTime;
|
|
unsigned char m_nEnergyUnconsumptionRate;
|
|
|
|
// 회복량 증폭 관련
|
|
float m_fHealRatio;
|
|
float m_fMPHealRatio;
|
|
float m_fHealRatioByItem;
|
|
float m_fMPHealRatioByItem;
|
|
float m_fHealRatioByRest;
|
|
float m_fMPHealRatioByRest;
|
|
|
|
// 회복량 증가 관련
|
|
int m_nAdditionalHeal;
|
|
int m_nAdditionalMPHeal;
|
|
int m_nAdditionalHealByItem;
|
|
int m_nAdditionalMPHealByItem;
|
|
int m_nAdditionalHealByRest;
|
|
int m_nAdditionalMPHealByRest;
|
|
|
|
SkillCostModifier m_SkillCostModifier;
|
|
|
|
// 어그로 증폭 관련
|
|
float m_fHateRatio;
|
|
|
|
float m_nCastKeep;
|
|
|
|
int m_nLevel;
|
|
int m_nMaxReachedLevel;
|
|
float m_fBattleLevel;
|
|
int m_nUnitExpertLevel;
|
|
|
|
__int64 m_nEXP;
|
|
__int64 m_nLastDecreasedEXP;
|
|
|
|
struct Experience
|
|
{
|
|
Experience() : exp( 0 ), jp( 0 ) {}
|
|
Experience( const __int64 exp, const __int64 jp) : exp( exp ), jp( jp ) {}
|
|
Experience( const Experience& arg ) : exp( arg.exp ), jp( arg.jp ) {}
|
|
|
|
const Experience operator+ ( const Experience& rhs ) const
|
|
{
|
|
return Experience( rhs.exp + exp, rhs.jp + jp );
|
|
}
|
|
|
|
const Experience& operator+= ( const Experience& rhs )
|
|
{
|
|
exp += rhs.exp;
|
|
jp += rhs.jp;
|
|
|
|
return *this;
|
|
}
|
|
|
|
__int64 exp;
|
|
__int64 jp;
|
|
};
|
|
|
|
float m_fEXPMod;
|
|
|
|
int m_nJob;
|
|
int m_nJobLevel;
|
|
int m_nPrevJobId[GameRule::MAX_JOB_DEPTH - 1];
|
|
int m_nPrevJobLevel[GameRule::MAX_JOB_DEPTH - 1];
|
|
__int64 m_nJobPoint;
|
|
__int64 m_nTotalJobPoint;
|
|
|
|
int m_nRegenHP;
|
|
int m_nRegenMP;
|
|
|
|
float m_fWeight; // 현재 소지한 아이템 무게(m_Inventory.GetWeight()를 이용해
|
|
// 필요할 때 마다 갱신시켜야 함... 왜 있을까 -_ -;?
|
|
|
|
CreatureStatServer m_Stat;
|
|
CreatureStatServer m_StatByState;
|
|
CreatureAttributeServer m_Attribute;
|
|
CreatureAttributeServer m_AttributeByState;
|
|
CreatureElementalResist m_Resist;
|
|
|
|
c_fixed10 m_fAttackPointRightWithoutWeapon;
|
|
c_fixed10 m_fAttackPointLeftWithoutWeapon;
|
|
float m_fBowInterval;
|
|
|
|
c_fixed10 m_ElementalStateDamageAdder[Elemental::TYPE_COUNT];
|
|
c_fixed10 m_ElementalStateDamageAmplifier[Elemental::TYPE_COUNT];
|
|
|
|
// 플레이어와 소환수 간의 상호 참조형 스킬을 위한 변수
|
|
ParameterForSummon m_PrevParameterForSummon;
|
|
ParameterForSummon m_ParameterForSummon;
|
|
|
|
// 생물체의 상태를 Bit flag로 사용하여 메모리 사용량 감소
|
|
enum CreatureStatus
|
|
{
|
|
// 내부 처리용
|
|
STATUS_LOGIN_COMPLETE = 0, // 로그인 처리 완료
|
|
STATUS_FIRST_ENTER = 1, // 최초 Enter 상태(Enter 메시지에 사용하여 클라에 알려줌)
|
|
STATUS_ATTACK_STARTED = 2, // 공격 처리 중(공격 상태 중에 다음 공격 대기 상태가 아닌 실제 데미지처리 중인 순간)
|
|
STATUS_FIRST_ATTACK = 3, // 첫 공격(타겟의 OnUpdate 호출 처리 여부 확인용)
|
|
STATUS_MOVE_PENDED = 4, // 대기 중인 이동이 있음(타 액션 중이어서 이동을 못하고 대기시켜둔 상태)
|
|
STATUS_NEED_TO_UPDATE_STATE = 5, // 지속효과 DB 업데이트가 필요함(소환수에만 사용되고 있음)
|
|
STATUS_MOVING_BY_FEAR = 6, // 공포에 의한 이동 처리 중
|
|
STATUS_NEED_TO_CALCULATE_STAT = 7, // 스텟 계산 처리 필요(CalculateStat 호출 필요성 체크)
|
|
STATUS_PROCESSING_REFELCT = 8, // 반사막 효과 처리 중(쌍방 반사막 사용 시 무한 반사 현상 체크)
|
|
|
|
// 게임 내 상태 관련
|
|
STATUS_INVISIBLE = 9, // 투명(GM 명령어)
|
|
STATUS_INVINCIBLE = 10, // 무적(GM 명령어)
|
|
STATUS_HIDING = 11, // 은신
|
|
//STATUS_STIGMATIZED = 12, // 죄의 낙인(여신의 축복을 받을 수 없음) - 기부 시스템 리뉴얼 이후로 사용하지 않음
|
|
STATUS_MOVABLE = 13, // 이동 가능 여부
|
|
STATUS_ATTACKABLE = 14, // 공격 가능 여부
|
|
STATUS_SKILL_CASTABLE = 15, // 스킬 사용 가능
|
|
STATUS_MAGIC_CASTABLE = 16, // 마법 사용 가능
|
|
STATUS_ITEM_USABLE = 17, // 아이템 사용 가능
|
|
STATUS_MORTAL = 18, // 피격 가능
|
|
STATUS_FEARED = 20, // 공포
|
|
STATUS_FORM_CHANGED = 21, // 변이
|
|
STATUS_MOVE_SPEED_FIXED = 22, // 이속 고정
|
|
STATUS_HP_REGEN_STOPPED = 23, // HP 리젠 중지
|
|
STATUS_MP_REGEN_STOPPED = 24, // MP 리젠 중지
|
|
STATUS_USING_DOUBLE_WEAPON = 25, // 이도류 사용 중
|
|
STATUS_COMPETE_DEAD = 26, // 대련에 의한 사망 상태
|
|
|
|
STATUS_READ_INFO_COMPLETE = 27, // 로그인 처리 뿐만 아니라 DB로부터 모든 정보를 읽어들인 상태로 호칭기록을 위해 존재한다.
|
|
STATUS_MOVE_SPEED_FIXED2 = 28,
|
|
};
|
|
|
|
XFlag< int, 1 > m_StatusFlag;
|
|
bool m_bNeedToBroadcastStatusFlag;
|
|
|
|
// 입고있는 아이템
|
|
struct StructItem* m_anWear[ ItemBase::MAX_SPARE_ITEM_WEAR ];
|
|
|
|
float m_fHPRegenMod; // HP 자연회복량 조정
|
|
float m_fMPRegenMod; // MP 자연회복량 조정
|
|
float m_fItemMod; // 아이템 효율
|
|
|
|
|
|
AR_TIME m_nMovableTime;
|
|
AR_TIME m_nLastUpdateTime;
|
|
AR_TIME m_nNextAttackableTime;
|
|
AR_TIME m_nNextCastableTime;
|
|
AR_TIME m_nLastStateProcTime;
|
|
AR_TIME m_nDeadTime; // 죽은시간
|
|
|
|
// 전투
|
|
void broadcastAttackMessage( StructCreature *pTarget, struct StructCreature::_ATTACK_INFO * arDamage, int tm, int delay, bool bIsDoubleAttack, bool bIsAiming = false, bool bEndAttack = false, bool bCancelAttack = false );
|
|
void onAttackAndSkillProcess();
|
|
AR_HANDLE m_hEnemy;
|
|
|
|
XCriticalSection m_csEnemy;
|
|
std::vector< AR_HANDLE > m_vEnemyList; // Hate 관련( 현재 내가 hate를 먹고 있는 애들)
|
|
|
|
enum { AM_ATTACK = 0, AM_AIMING, };
|
|
int m_nNextAttackMode;
|
|
|
|
std::vector< ArPosition > m_PendingMovePos;
|
|
unsigned char m_nPendingMoveSpeed;
|
|
|
|
AR_UNIT m_fDetectHideRange;
|
|
float m_fCreatureCardChance;
|
|
|
|
std::vector< AR_HANDLE > m_vAimerList; // 나를 Targeting 중인 Player들 리스트
|
|
|
|
// 상태이상
|
|
unsigned short m_nCurrentStateUID;
|
|
std::vector< StructState > m_vStateList;
|
|
std::vector< StructState > m_vPendStateList;
|
|
std::vector< std::pair< AR_TIME, StructState > > m_vPendStateListByItem;
|
|
std::vector< StructState > m_vStateListRemovedByDeath;
|
|
int m_nPendedClearStateFlag;
|
|
typedef std::vector< StructState >::iterator STATE_ITERATOR;
|
|
typedef std::vector< StructState >::const_iterator STATE_CONST_ITERATOR;
|
|
|
|
float m_fResistHarmfulState; // 해로운 지속효과 저항률(자체 저항률-마법회피-과 무관하게 따로 체크)
|
|
std::map< StructState::StateCode, c_fixed10 > m_mapResistHarmfulState; // 해로운 지속효과 저항률(자체 저항률-마법회피-과 무관하게 따로 체크)
|
|
|
|
std::vector< struct _ATTACK_TAG > m_vProcByAttack;
|
|
std::vector< struct _ATTACK_TAG > m_vProcByBeingAttacked;
|
|
std::vector< struct _KILL_TAG > m_vProcByKill;
|
|
std::vector< struct _KILL_TAG > m_vProcByDead;
|
|
std::vector< struct _ATTACK_TAG > m_vProcByCriticalAttack;
|
|
std::vector< struct _ATTACK_TAG > m_vProcByBeingCriticalAttacked;
|
|
std::vector< struct _ATTACK_TAG > m_vProcByAvoid;
|
|
std::vector< struct _ATTACK_TAG > m_vProcByBlock;
|
|
std::vector< struct _ATTACK_TAG > m_vProcByPerfectBlock;
|
|
std::map< int, std::vector< struct _PROC_TAG > > m_mapProcBySkillId;
|
|
|
|
void ProcByAttack( StructCreature *pTarget, const int nDamage, const bool bIsAttacking, const DWORD nAttackType, const int nElementalType );
|
|
void ProcBySkillId( StructCreature *pTarget, const int nDamage, const bool bIsAttacking, const int nSkillId );
|
|
void ProcByKill( StructCreature *pTarget, const bool bIsKilling );
|
|
void ProcByCritical( StructCreature *pTarget, const int nDamage, const bool bIsAttacking, const DWORD nAttackType, const int nElementalType );
|
|
void ProcByAvoid( StructCreature *pFrom, const DWORD nAttackType, const int nElementalType );
|
|
void ProcByBlock( StructCreature *pTarget, const int nDamage, const DWORD nAttackType, const int nElementalType );
|
|
void ProcByPerfectBlock( StructCreature *pTarget, const DWORD nAttackType, const int nElementalType );
|
|
|
|
int m_nDoubleWeaponMasteryLevel;
|
|
|
|
struct ExpertMod
|
|
{
|
|
float fAvoid;
|
|
float fDamage;
|
|
};
|
|
|
|
ExpertMod m_Expert[ MAX_CREATURE_TYPE_NUMBER ];
|
|
|
|
struct ElementalSkillStateMod
|
|
{
|
|
ElementalSkillStateMod()
|
|
{
|
|
Init();
|
|
}
|
|
|
|
void Init()
|
|
{
|
|
fMagicalDamage = 1.0f;
|
|
fPhysicalDamage = 1.0f;
|
|
nElementalType = 0;
|
|
fCooltime = 1.0f;
|
|
fCastingSpeed = 1.0f;
|
|
fHate = 1.0f;
|
|
nMagicalAccuracy = 0;
|
|
nPhysicalAccuracy = 0;
|
|
nCritical = 0;
|
|
fManaCostRatio = 1.0f;
|
|
vExhaustiveStateCode.clear();
|
|
nCastingSpeedApplyTime = 0;
|
|
}
|
|
|
|
void apply( float damage, float magicDamage, int critical, float hate, float coolTime, AR_TIME castingSpeedApplyTime,
|
|
int castingSpeed, bool isExhaustive, StructState::StateCode exhaustiveStateCode )
|
|
{
|
|
fPhysicalDamage += damage;
|
|
fMagicalDamage += magicDamage;
|
|
nCritical += critical;
|
|
fHate += hate;
|
|
fCooltime += coolTime;
|
|
nCastingSpeedApplyTime = std::max( nCastingSpeedApplyTime, castingSpeedApplyTime );
|
|
fCastingSpeed += castingSpeed;
|
|
|
|
if( isExhaustive )
|
|
vExhaustiveStateCode.push_back( exhaustiveStateCode );
|
|
}
|
|
|
|
float fManaCostRatio;
|
|
float fCooltime;
|
|
float fCastingSpeed;
|
|
float fHate;
|
|
int nMagicalAccuracy;
|
|
int nPhysicalAccuracy;
|
|
int nCritical;
|
|
|
|
float fMagicalDamage;
|
|
float fPhysicalDamage;
|
|
int nElementalType;
|
|
AR_TIME nCastingSpeedApplyTime;
|
|
|
|
std::vector< StructState::StateCode > vExhaustiveStateCodeForDelete;
|
|
std::vector< StructState::StateCode > vExhaustiveStateCode;
|
|
};
|
|
|
|
StateMod m_NormalStateAdvantage; // 일반 공격 보너스
|
|
StateMod m_RangeStateAdvantage; // 일반 공격 보너스
|
|
StateMod m_NormalStatePenalty; // 일반 피격 페널티
|
|
StateMod m_RangeStatePenalty; // 일반 피격 페널티
|
|
StateMod m_PhysicalSkillStatePenalty; // 물리 스킬 피격 페널티
|
|
StateMod m_MagicalSkillStatePenalty; // 마법 스킬 피격 페널티
|
|
StateMod m_StateStatePenalty; // 지속 효과 피격 페널티
|
|
|
|
ElementalSkillStateMod m_GoodPhysicalElementalSkillStateMod[Elemental::TYPE_COUNT]; // 물리 공격 보너스
|
|
ElementalSkillStateMod m_BadPhysicalElementalSkillStateMod[Elemental::TYPE_COUNT]; // 마법 공격 보너스
|
|
ElementalSkillStateMod m_GoodMagicalElementalSkillStateMod[Elemental::TYPE_COUNT]; // 마법 공격 보너스
|
|
ElementalSkillStateMod m_BadMagicalElementalSkillStateMod[Elemental::TYPE_COUNT]; // 마법 공격 보너스
|
|
|
|
void removeExhaustiveSkillStateMod( ElementalSkillStateMod *pSkillStateMod, AR_TIME nOriginalCastingDelay );
|
|
|
|
struct HateModifier
|
|
{
|
|
HateModifier( int nHateModType, int nHarmfulType, float _fAmpValue, int _nIncValue )
|
|
: fAmpValue( _fAmpValue )
|
|
, nIncValue( _nIncValue )
|
|
{
|
|
bIsApplyToPhysicalSkill = false;
|
|
bIsApplyToMagicalSkill = false;
|
|
bIsApplyToPhysicalAttack = false;
|
|
|
|
bIsApplyToHarmful = false;
|
|
bIsApplyToHelpful = false;
|
|
|
|
switch( nHateModType )
|
|
{
|
|
case 1:
|
|
bIsApplyToPhysicalSkill = true;
|
|
break;
|
|
case 2:
|
|
bIsApplyToMagicalSkill = true;
|
|
break;
|
|
case 3:
|
|
bIsApplyToPhysicalAttack = true;
|
|
break;
|
|
case 99:
|
|
bIsApplyToPhysicalSkill = true;
|
|
bIsApplyToMagicalSkill = true;
|
|
bIsApplyToPhysicalAttack = true;
|
|
break;
|
|
}
|
|
|
|
bIsApplyToHarmful = false;
|
|
bIsApplyToHelpful = false;
|
|
|
|
switch( nHarmfulType )
|
|
{
|
|
case 0:
|
|
bIsApplyToHelpful = true;
|
|
break;
|
|
case 1:
|
|
bIsApplyToHarmful = true;
|
|
break;
|
|
case 99:
|
|
bIsApplyToHelpful = true;
|
|
bIsApplyToHarmful = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool bIsApplyToPhysicalSkill;
|
|
bool bIsApplyToMagicalSkill;
|
|
bool bIsApplyToPhysicalAttack;
|
|
|
|
bool bIsApplyToHarmful;
|
|
bool bIsApplyToHelpful;
|
|
|
|
float fAmpValue;
|
|
int nIncValue;
|
|
};
|
|
|
|
std::vector< HateModifier > m_vHateMod;
|
|
|
|
struct AdditionalDamageInfo
|
|
{
|
|
AdditionalDamageInfo( unsigned char _ratio, Elemental::Type _require_type, Elemental::Type _type, unsigned short _nDamage, float _fDamage )
|
|
: ratio( _ratio ), require_type( _require_type ), type( _type ), nDamage( _nDamage ), fDamage( _fDamage ) {}
|
|
|
|
unsigned char ratio;
|
|
Elemental::Type require_type;
|
|
Elemental::Type type;
|
|
unsigned short nDamage;
|
|
float fDamage;
|
|
};
|
|
|
|
struct DamageReflectInfo
|
|
{
|
|
DamageReflectInfo( unsigned char _fire_ratio, float _range, Elemental::Type _type, unsigned short _nReflectDamage, float _fPhysicalReflectRatio, float _fPhysicalSkillReflectRatio, float _fMagicalReflectRatio, bool _bIgnoreDefence )
|
|
: fire_ratio( _fire_ratio ), range( _range ), type( _type ), nReflectDamage( _nReflectDamage ), fPhysicalReflectRatio( _fPhysicalReflectRatio )
|
|
, fPhysicalSkillReflectRatio( _fPhysicalSkillReflectRatio ), fMagicalReflectRatio( _fMagicalReflectRatio ), bIgnoreDefence( _bIgnoreDefence )
|
|
{}
|
|
|
|
unsigned char fire_ratio;
|
|
float range;
|
|
Elemental::Type type;
|
|
unsigned short nReflectDamage;
|
|
float fPhysicalReflectRatio;
|
|
float fPhysicalSkillReflectRatio;
|
|
float fMagicalReflectRatio;
|
|
bool bIgnoreDefence;
|
|
};
|
|
|
|
struct StateReflectInfo
|
|
{
|
|
StateReflectInfo( StructState::StateCode _nCode, int _nLevel, AR_TIME _nDuration )
|
|
: nCode( _nCode ), nLevel( _nLevel ), nDuration( _nDuration ) {}
|
|
|
|
StructState::StateCode nCode;
|
|
int nLevel;
|
|
AR_TIME nDuration;
|
|
};
|
|
|
|
struct AddHPMPOnCriticalInfo
|
|
{
|
|
AddHPMPOnCriticalInfo( int _nAddHP, int _nAddMP, int _nActivationRate )
|
|
: nAddHP( _nAddHP ), nAddMP( _nAddMP ), nActivationRate( _nActivationRate ) {}
|
|
|
|
int nAddHP;
|
|
int nAddMP;
|
|
int nActivationRate;
|
|
};
|
|
|
|
struct DamageReduceInfo
|
|
{
|
|
DamageReduceInfo( unsigned char _ratio, float _physical_reduce, float _physical_skill_reduce, float _magical_skill_reduce,
|
|
int _apply_creature_group_1, int _apply_creature_group_2, int _apply_creature_group_3, int _apply_creature_group_4, int _apply_creature_group_5 )
|
|
: ratio( _ratio ), physical_reduce( _physical_reduce ), physical_skill_reduce( _physical_skill_reduce ), magical_skill_reduce( _magical_skill_reduce )
|
|
{
|
|
apply_creature_group_list[0] = _apply_creature_group_1;
|
|
apply_creature_group_list[1] = _apply_creature_group_2;
|
|
apply_creature_group_list[2] = _apply_creature_group_3;
|
|
apply_creature_group_list[3] = _apply_creature_group_4;
|
|
apply_creature_group_list[4] = _apply_creature_group_5;
|
|
}
|
|
|
|
inline bool IsAppliableCreatureGroup( int creature_group ) const
|
|
{
|
|
return ( apply_creature_group_list[0] == 99 || apply_creature_group_list[0] == creature_group )
|
|
|| ( apply_creature_group_list[1] == 99 || apply_creature_group_list[1] == creature_group )
|
|
|| ( apply_creature_group_list[2] == 99 || apply_creature_group_list[2] == creature_group )
|
|
|| ( apply_creature_group_list[3] == 99 || apply_creature_group_list[3] == creature_group )
|
|
|| ( apply_creature_group_list[4] == 99 || apply_creature_group_list[4] == creature_group );
|
|
}
|
|
|
|
unsigned char ratio;
|
|
float physical_reduce;
|
|
float physical_skill_reduce;
|
|
float magical_skill_reduce;
|
|
int apply_creature_group_list[5];
|
|
};
|
|
|
|
// 추가데미지
|
|
std::vector< AdditionalDamageInfo > m_vNormalAdditionalDamage;
|
|
std::vector< AdditionalDamageInfo > m_vRangeAdditionalDamage;
|
|
std::vector< AdditionalDamageInfo > m_vPhysicalSkillAdditionalDamage;
|
|
std::vector< AdditionalDamageInfo > m_vMagicalSkillAdditionalDamage;
|
|
|
|
std::vector< DamageReflectInfo > m_vDamageReflectInfo;
|
|
std::vector< StateReflectInfo > m_vStateReflectInfo;
|
|
|
|
std::vector< DamageReduceInfo > m_vDamageReducePercentInfo;
|
|
std::vector< DamageReduceInfo > m_vDamageReduceValueInfo;
|
|
|
|
// 계열의 변경
|
|
int m_nChangingGroup;
|
|
|
|
// 크리티컬시 회복
|
|
std::vector< AddHPMPOnCriticalInfo > m_vAddHPMPOnCritical;
|
|
|
|
// 사용 금지당한 스킬
|
|
std::vector< int > m_vInterruptedSkill;
|
|
|
|
// 허용된 스킬
|
|
std::vector< std::set< int > > m_vAllowedSkill;
|
|
|
|
// 증가된 스킬
|
|
std::vector< std::pair< int, int > > m_vAddedSkillBySkillId;
|
|
std::vector< std::pair< int, int > > m_vAddedSkillBySkillType;
|
|
|
|
// 마나 실드에 의한 데미지 전이 비율
|
|
float m_fPhysicalDamageManaShieldAbsorbRatio;
|
|
float m_fMagicalDamageManaShieldAbsorbRatio;
|
|
|
|
c_fixed10 m_fRecPerMaxHP;
|
|
c_fixed10 m_fRecPerDamage;
|
|
|
|
// 스킬
|
|
struct StructSkill * m_pCastSkill;
|
|
std::vector< struct StructSkill * > m_vAllSkillList;
|
|
std::vector< struct StructSkill * > m_vPassiveSkillList;
|
|
|
|
std::vector< struct StructSkill * > m_vActiveSkillList;
|
|
struct StructSkill * getSkill( int nSkillId ) const;
|
|
AR_HANDLE m_hSkillTarget;
|
|
std::vector< std::pair<StructSkill *, int> > m_vAura;
|
|
|
|
std::vector< struct StructSkill * > m_vSkillRelatedToDamaging;
|
|
|
|
// 스킬 프랍(트랩)
|
|
AR_HANDLE m_hTrap;
|
|
|
|
float m_fSummonFCM;
|
|
float m_fPreviousSummonFCM;
|
|
|
|
private:
|
|
// 전부 static인 까닭은 공격자와 피격자의 용이한 구분과 함께 이 부분을 차후 쉽게 분리할 수 있도록 하기 위함
|
|
static const float CalculateDamageReduceSum( const DamageMessage& message, const std::vector< DamageReduceInfo >& reduceInfo );
|
|
|
|
static StructCreature::_DAMAGE DealDamage( const DamageMessage& message );
|
|
static _DAMAGE CreateDamageStruct( const CalculationResult& result );
|
|
|
|
static void ApplySkillToCalculation( const DamageMessage& message, DamageCalculator& calculator, StructSkill* skill );
|
|
|
|
static void ProcessPostDamageEffect( const DamageMessage& message, const CalculationResult& result );
|
|
static void ApplyManaShieldEffect( const DamageMessage& message, const CalculationResult& result );
|
|
static void InterruptSpellCast( const DamageMessage& message, const CalculationResult& result );
|
|
static void RemoveStateOnDamage( const DamageMessage& message, const CalculationResult& result );
|
|
static void ConsumeSoulStoneDurabilityOnDamage( const DamageMessage& message, const CalculationResult& result );
|
|
static void ConsumeEtherealDurabilityOnDamage( const DamageMessage& message, const CalculationResult& result );
|
|
static void ReflectDamage( const DamageMessage& message, const CalculationResult& result );
|
|
static void ProcessAdditionalDamage( const DamageMessage& sourceMessage, const DamageType additionalDamageType, const std::vector< AdditionalDamageInfo >& additionalDamage, _DAMAGE_INFO& damageInfo );
|
|
|
|
public:
|
|
void ProvideAttackerInfo( const DamageMessage& message, DamageCalculator& calculator );
|
|
void ProvideTargetInfo( const DamageMessage& message, DamageCalculator& calculator );
|
|
|
|
|
|
// 스탯 관련 함수 및 변수들을 아래에 정리
|
|
public:
|
|
void CalculateStat();
|
|
|
|
protected:
|
|
// --- 초기화 관련 루틴 ---
|
|
void initProc();
|
|
virtual void calcAttribute( CreatureAttributeServer* pAttribute );
|
|
|
|
// --- 스탯 및 능력치 연산에 관련된 패시브 스킬들 적용하는 루틴 ---
|
|
void applyStatByPassiveSkill();
|
|
void amplifyStatByPassiveSkill();
|
|
virtual void applyPassiveSkillEffect();
|
|
virtual void applyPassiveSkillEffect( struct StructSkill * pSkill );
|
|
virtual void applyPassiveSkillAmplifyEffect();
|
|
virtual void applyPassiveSkillAmplifyEffect( struct StructSkill * pSkill );
|
|
virtual void calcParamBasedStat();
|
|
virtual void calcParamBasedAttribute();
|
|
|
|
// --- 스탯 및 능력치 연산에 관련된 지속 효과들 적용하는 루틴 ---
|
|
void applyStateEffect();
|
|
virtual void applyState( StructState & state );
|
|
void applyStateAmplifyEffect();
|
|
virtual void applyStateAmplify( StructState & state );
|
|
virtual void applyStatByState();
|
|
virtual void amplifyStatByState();
|
|
void applyParamBasedStateEffect();
|
|
|
|
// --- 스탯 및 능력치 연산에 관련된 아이템 효과를 적용하는 루틴 ---
|
|
void applyItemEffect();
|
|
void _applyEffect( struct StructItem * pItem, const std::vector< EffectInfo * > * pvEffectList, float fRatio );
|
|
virtual void _applyEffectForState( const EffectInfo * pEffect );
|
|
void _applySkillByEffect( const std::vector< EffectInfo * > * pvEffectList, float fRatio = 1.0f );
|
|
virtual void applyStatByItem();
|
|
void _applyStatByEffect( const std::vector< EffectInfo * > * pvEffectList, float fRatio = 1.0f );
|
|
virtual void amplifyStatByItem();
|
|
void _amplifyStatByEffect( const std::vector< EffectInfo * > * pvEffectList, float fRatio = 1.0f );
|
|
void applyParamBasedItemEffect();
|
|
void _applyParamBasedEffect( const std::vector< EffectInfo * > * pvEffectList );
|
|
virtual void onItemWearEffect( struct StructItem* pItem, bool bIsBaseVar, int type, c_fixed10 var1, c_fixed10 var2, float fRatio );
|
|
|
|
// --- 스탯 및 능력치 연산에 관련된 호칭 효과를 적용하는 루틴 ---
|
|
virtual void applyStatByTitle() {}
|
|
virtual void amplifyStatByTitle() {}
|
|
virtual void applyTitleEffect() {}
|
|
|
|
// --- 기타 예외적인 처리 ---
|
|
void applyDoubleWeaponEffect();
|
|
virtual void applyJobLevelBonus();
|
|
void synchronizeParameter( const int bitset, const c_fixed10 & rate );
|
|
void addSkill( const int id, const int added_level, const int skill_type, const bool bRace );
|
|
void checkAdditionalItemEffect();
|
|
|
|
// --- 이하 핸들러들 ---
|
|
virtual void onBeforeCalculateStat();
|
|
virtual void onAfterApplyStat();
|
|
virtual void onApplyStat();
|
|
virtual void onAfterCalculateAttributeByStat();
|
|
virtual void onApplyAttributeAdjustment();
|
|
virtual void onModifyStatAndAttribute();
|
|
void onModifySkill();
|
|
void onModifyDetectRange();
|
|
virtual void onCompleteCalculateStat();
|
|
|
|
// --- 각종 스탯을 계산하는 유틸리티 함수들 ---
|
|
void accumulateStatDiffByState( const CreatureStatServer& stateStat );
|
|
void accumulateAttributeDiffByState( const CreatureAttributeServer& stateAttr );
|
|
void getAmplifiedStatByAmplifier( CreatureStatServer * pStat );
|
|
void getAmplifiedAttributeByAmplifier( CreatureAttributeServer * pAttribute );
|
|
void getAmplifiedResistByAmplifier( CreatureElementalResist * pResist );
|
|
virtual void incParameter( const int nBitset, const c_fixed10 & fValue, const bool bStat, ParameterForSummon *pParam = NULL );
|
|
virtual void ampParameter( const int nBitset, const c_fixed10 & fValue, const bool bStat );
|
|
virtual void incParameter2( const int nBitset, const c_fixed10 & fValue, ParameterForSummon *pParam = NULL );
|
|
virtual void ampParameter2( const int nBitset, const c_fixed10 & fValue );
|
|
void finalizeStat();
|
|
void onSynchronizeParameter( bool bStat );
|
|
bool isSkillModified( std::vector< std::pair< int, int > > * pvPrevAddedSkill, std::vector< std::pair< int, int > > * pvAddedSkill );
|
|
|
|
protected:
|
|
// 세트 아이템 효과 적용 판단용 맵 타입 정의
|
|
typedef std::map< int, int > SetPartFlagMap;
|
|
|
|
float m_fMaxHPAmplifier;
|
|
float m_fMaxMPAmplifier;
|
|
|
|
CreatureStatAmplifier m_StatAmplifier; // 증폭 값 계산을 한 번에 하기 위한 증폭량 누적 변수
|
|
CreatureAttributeAmplifier m_AttributeAmplifier; // 증폭 값 계산을 한 번에 하기 위한 증폭량 누적 변수
|
|
CreatureElementalResistAmplifier m_ResistAmplifier; // 증폭 값 계산을 한 번에 하기 위한 증폭량 누적 변수
|
|
CreatureStatServer m_StatBeforeParamBasedCalc;
|
|
CreatureAttributeServer m_AttrBeforeParamBasedCalc;
|
|
|
|
// 속성 이펙트 추가 성능 관련
|
|
int m_nElementalEffectAttackPointRight;
|
|
int m_nElementalEffectAttackPointLeft;
|
|
int m_nElementalEffectMagicPoint;
|
|
|
|
std::vector< struct StructSkill * > m_vAmplifyPassiveSkillList;
|
|
|
|
// 세트 아이템, 세트 소울스톤 효과 적용을 위한 임시 버퍼
|
|
std::vector< SetItemEffectInfo * > m_vSetItemEffect;
|
|
|
|
// 파라미터 동기화 ┬ 파라미터 비트셋
|
|
// │
|
|
// └┬ 적용률
|
|
// │
|
|
// └ 적용률 합산을 위한 동기화 정보의 개수
|
|
std::vector< std::pair< int, std::pair< c_fixed10, int > > > m_vSynchronizedParameter;
|
|
};
|