460 lines
12 KiB
C++
460 lines
12 KiB
C++
#include "stdafx.h"
|
|
#include "SPlayerInfoMgr.h"
|
|
#include "SGame.h"
|
|
#include "SGameMessage.h"
|
|
//#include "SGameMessageUI.h"
|
|
#include "SJobDB.h"
|
|
#include "SExpDB.h"
|
|
#include "SStringDB.h"
|
|
//#include "Util.h"
|
|
#include "STenacityDB.h"
|
|
#include "SSkillDB.h"
|
|
#include "SkillBaseFile.h"
|
|
#include "SUISysMsgDefine.h"
|
|
|
|
#include "SDebug_Util.h"
|
|
#include "Arena\\ArenaJoinSituationChecker.h"
|
|
#include "SGameSystem.h"
|
|
extern SGameSystem * g_pCurrentGameSystem;
|
|
|
|
namespace
|
|
{
|
|
const float c_fStateCheckTime = 1000.f;
|
|
const DWORD NO_TIME = -1;
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// SStateSlot
|
|
SStateSlot::SStateSlot()
|
|
{
|
|
m_hTarget = NULL;
|
|
|
|
state_handle = NULL;
|
|
state_code = 0;
|
|
state_level = 0;
|
|
state_value = 0;
|
|
end_time = 0;
|
|
//start_time = 0;
|
|
m_dwBeginTime = NO_TIME;
|
|
m_dwRemainTime = NO_TIME;
|
|
m_dwMaxMilliTime = NO_TIME;
|
|
|
|
m_bStateStop = false;
|
|
m_bIsToggleSkill = false;
|
|
m_bIsValidProcTime = false;
|
|
}
|
|
SStateSlot::~SStateSlot()
|
|
{
|
|
}
|
|
void SStateSlot::Process( DWORD dwTime )
|
|
{
|
|
if( m_dwBeginTime == 0 )
|
|
m_dwBeginTime = dwTime;
|
|
|
|
m_dwTime = dwTime;
|
|
CheckTime();
|
|
}
|
|
void SStateSlot::SetStateTime( DWORD StartTime, DWORD EndTime )
|
|
{
|
|
end_time = EndTime;
|
|
m_dwBeginTime = ConvertTimeToMilli(StartTime);
|
|
m_dwRemainTime = NO_TIME;
|
|
m_dwMaxMilliTime = (end_time - StartTime)*10; //클라에서의 프로세스 타임은 밀리세컨드를 사용하기 때문에 10을 곱한다.
|
|
}
|
|
void SStateSlot::CheckTime()
|
|
{
|
|
// end_time == 0 이면 삭제 안됨
|
|
// 레벨이 0이거나, 시간이 초과되었으면 삭제
|
|
if( state_level == 0 || ( end_time != 0 && GetArTime() >= end_time ) ) //여기서는 AR_TIME쓰는 것이 아마도 최대한 서버와 시간을 동기화 하기 위해서 인듯
|
|
m_dwRemainTime = m_dwMaxMilliTime;
|
|
// m_bStateStop = true; -> 자체적으로 stop하는 것은 없다. 서버에서 지속효과 종료 메세지 오기 전까지 무조건 다 까만색으로 출력
|
|
else
|
|
{
|
|
// 현재 시간 계산
|
|
if( m_dwRemainTime == NO_TIME ) m_dwRemainTime = 0;
|
|
if( m_dwRemainTime != NO_TIME && m_dwRemainTime < m_dwMaxMilliTime )
|
|
{
|
|
DWORD dwTime = m_dwTime - m_dwBeginTime;
|
|
if( dwTime > 0 && dwTime <= m_dwMaxMilliTime)
|
|
m_dwRemainTime = dwTime;
|
|
}
|
|
}
|
|
|
|
m_bIsValidProcTime = true;
|
|
}
|
|
DWORD SStateSlot::ConvertTimeToMilli( AR_TIME at_time )
|
|
{
|
|
return (at_time - GetArTimeAdjust())*10;
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// SPlayerInfo
|
|
SPlayerInfo::SPlayerInfo()
|
|
{
|
|
Clear();
|
|
}
|
|
SPlayerInfo::~SPlayerInfo()
|
|
{
|
|
}
|
|
|
|
void SPlayerInfo::Clear()
|
|
{
|
|
m_nStatus = 0;
|
|
|
|
m_nLevel = 0;
|
|
m_nExp = 0;
|
|
m_nHP = 0;
|
|
m_nMP = 0;
|
|
m_nMaxHP = 0;
|
|
m_nMaxMP = 0;
|
|
m_nJLv = 0;
|
|
m_nJp = 0;
|
|
m_nJobID = 0;
|
|
|
|
m_nCurExp = 0;
|
|
m_n64_MaxExp = 0;
|
|
m_n64_PreviosExp = 0;
|
|
|
|
m_nGold = money_t( 0 );
|
|
m_fInvenWeigth = 0.0f;
|
|
|
|
/// 2011.02.24 - prodongi
|
|
for (int i = 0; i < JOB_INDEX_MAX; ++i)
|
|
{
|
|
m_nOldJobID[i] = -1;
|
|
m_nOldJobLv[i] = -1;
|
|
}
|
|
|
|
m_strName.clear();
|
|
m_strJobName.clear();
|
|
|
|
m_nPermission = 0;
|
|
m_nPk_count = 0;
|
|
m_nDk_count = 0;
|
|
m_nRace = 0;
|
|
m_nCharisma = 0;
|
|
m_nMoral = 0;
|
|
m_nLogin_time = 0;
|
|
m_nSex = 0;
|
|
m_nX = 0;
|
|
m_nY = 0;
|
|
m_nStorage_gold= 0;
|
|
m_nStamina = 0;
|
|
m_nChaos = 0;
|
|
m_nMax_chaos = 0;
|
|
m_nMax_stamina = 0;
|
|
m_nChannel = 0;
|
|
m_nStaminaRegen= 0;
|
|
|
|
m_nEtherealStoneDurability = 0;
|
|
m_nHuntaHolicPoint = 0;
|
|
|
|
m_arContinuous_play_time = 0;
|
|
m_arPennalty_play_time = 0;
|
|
m_arMaxContinuous_play_time = 0;
|
|
|
|
m_tp = 0; /// 2011.03.28 - prodongi
|
|
m_isFirstTpSet = true;
|
|
|
|
m_bIsFirstImmoralSett = true;
|
|
|
|
ZeroMemory( &m_Stat, sizeof(m_Stat) );
|
|
ZeroMemory( &m_Attribute, sizeof(m_Attribute) );
|
|
|
|
m_ap = 0;
|
|
|
|
m_alias.clear();
|
|
}
|
|
|
|
void SPlayerInfo::SetJobName()
|
|
{
|
|
m_strJobName = GetJobDB().GetJobName(m_nJobID);
|
|
}
|
|
void SPlayerInfo::SetStat( const CreatureStat& stat, const CreatureAttribute& attribute )
|
|
{
|
|
::memcpy( &m_Stat, &stat, sizeof(m_Stat) );
|
|
::memcpy( &m_Attribute, &attribute, sizeof(m_Attribute) );
|
|
}
|
|
void SPlayerInfo::SetStatByItem( const CreatureStat& stat, const CreatureAttribute& attribute )
|
|
{
|
|
::memcpy( &m_StatByItem, &stat, sizeof(m_StatByItem) );
|
|
::memcpy( &m_AttributeByItem, &attribute, sizeof(m_AttributeByItem) );
|
|
|
|
// 빼준다
|
|
m_Stat.strength -= stat.strength ;
|
|
m_Stat.vital -= stat.vital ;
|
|
m_Stat.dexterity -= stat.dexterity ;
|
|
m_Stat.agility -= stat.agility ;
|
|
m_Stat.intelligence -= stat.intelligence;
|
|
m_Stat.mentality -= stat.mentality ;
|
|
m_Stat.luck -= stat.luck ;
|
|
|
|
m_Attribute.nCritical -= attribute.nCritical ;
|
|
m_Attribute.nCriticalPower -= attribute.nCriticalPower;
|
|
//TODO : Right/Left
|
|
m_Attribute.nAttackPointRight -= attribute.nAttackPointRight ;
|
|
m_Attribute.nAttackPointLeft -= attribute.nAttackPointLeft ;
|
|
m_Attribute.nDefence -= attribute.nDefence ;
|
|
m_Attribute.nBlockDefence -= attribute.nBlockDefence ;
|
|
m_Attribute.nMagicPoint -= attribute.nMagicPoint ;
|
|
m_Attribute.nMagicDefence -= attribute.nMagicDefence ;
|
|
//TODO : Right/Left
|
|
m_Attribute.nAccuracyRight -= attribute.nAccuracyRight;
|
|
m_Attribute.nAccuracyLeft -= attribute.nAccuracyLeft ;
|
|
m_Attribute.nMagicAccuracy -= attribute.nMagicAccuracy;
|
|
m_Attribute.nAvoid -= attribute.nAvoid ;
|
|
m_Attribute.nMagicAvoid -= attribute.nMagicAvoid ;
|
|
m_Attribute.nBlockChance -= attribute.nBlockChance ;
|
|
m_Attribute.nMoveSpeed -= attribute.nMoveSpeed ;
|
|
m_Attribute.nAttackSpeed -= attribute.nAttackSpeed ;
|
|
m_Attribute.nAttackRange -= attribute.nAttackRange ;
|
|
m_Attribute.nCastingSpeed -= attribute.nCastingSpeed ;
|
|
m_Attribute.nCoolTimeSpeed -= attribute.nCoolTimeSpeed;
|
|
m_Attribute.nItemChance -= attribute.nItemChance ;
|
|
m_Attribute.nHPRegenPercentage -= attribute.nHPRegenPercentage; // HP 리젠%
|
|
m_Attribute.nHPRegenPoint -= attribute.nHPRegenPoint ; // HP 리젠P
|
|
m_Attribute.nMPRegenPercentage -= attribute.nMPRegenPercentage; // MP 리젠%
|
|
m_Attribute.nMPRegenPoint -= attribute.nMPRegenPoint ; // MP 리젠P
|
|
/// 2011.03.30 왜 빼는 건가? - prodongi
|
|
m_Attribute.nPerfectBlock -= attribute.nPerfectBlock; // 퍼펙트블럭%
|
|
m_Attribute.nMagicalDefIgnore -= attribute.nMagicalDefIgnore; // 마법방어력무시P
|
|
m_Attribute.nMagicalDefIgnoreRatio -= attribute.nMagicalDefIgnoreRatio; // 마법방어력무시%
|
|
m_Attribute.nPhysicalDefIgnore -= attribute.nPhysicalDefIgnore; // 물리방어력무시P
|
|
m_Attribute.nPhysicalDefIgnoreRatio -= attribute.nPhysicalDefIgnoreRatio; // 물리방어력무시%
|
|
m_Attribute.nMagicalPenetration -= attribute.nMagicalPenetration; // 마법관통력P
|
|
m_Attribute.nMagicalPenetrationRatio -= attribute.nMagicalPenetrationRatio; // 마법관통력%
|
|
m_Attribute.nPhysicalPenetration -= attribute.nPhysicalPenetration; // 물리관통력P
|
|
m_Attribute.nPhysicalPenetrationRatio -= attribute.nPhysicalPenetrationRatio; // 물리관통력%
|
|
}
|
|
void SPlayerInfo::SetExp( __int64 nExp )
|
|
{
|
|
m_nExp = nExp;
|
|
RefreshExpInfo();
|
|
}
|
|
|
|
void SPlayerInfoMgr::SetGold( money_t nGold )
|
|
{
|
|
SPlayerInfo::SetGold( nGold );
|
|
ProcMsgAtStatic( &SIMSG_UI_SEND_DATA( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_TASKBAR, m_nGold, "gold" ) );
|
|
}
|
|
|
|
void SPlayerInfo::SetLevel( int nLevel )
|
|
{
|
|
m_nLevel = nLevel;
|
|
RefreshExpInfo();
|
|
}
|
|
void SPlayerInfo::RefreshExpInfo()
|
|
{
|
|
// 레벨에 따른 exp 재 계산
|
|
m_n64_PreviosExp = GetExpDB().GetNeedExp( m_nLevel - 1 );
|
|
m_n64_MaxExp = GetExpDB().GetNeedExp(m_nLevel) - m_n64_PreviosExp;
|
|
|
|
m_nCurExp = m_nExp - m_n64_PreviosExp;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// SPlayerInfoMgr
|
|
|
|
SPlayerInfoMgr::SPlayerInfoMgr()
|
|
: SGameUIMgr() // 2011.03.29 - servantes
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
SPlayerInfoMgr::~SPlayerInfoMgr()
|
|
{
|
|
}
|
|
|
|
void SPlayerInfoMgr::Clear()
|
|
{
|
|
m_nPlayerState = STATE_NONE;
|
|
|
|
m_hPlayer = 0;
|
|
m_hTarget = 0;
|
|
m_hTradeTarget = 0;
|
|
|
|
m_dwTime = 0;
|
|
|
|
m_strTargetName.clear();
|
|
m_strTradeTargetName.clear();
|
|
|
|
m_GameObjType = TS_ENTER::GAME_OBJTYPE_MAX;
|
|
}
|
|
|
|
void SPlayerInfoMgr::ResetInfo()
|
|
{
|
|
Clear();
|
|
SPlayerInfo::Clear();
|
|
}
|
|
|
|
int SPlayerInfoMgr::GetCurrentLocation()
|
|
{
|
|
if( m_pGame == NULL ) return -1;
|
|
|
|
return m_pGame->GetCurrentLocation();
|
|
}
|
|
|
|
void SPlayerInfoMgr::Process( DWORD dwTime )
|
|
{
|
|
m_dwTime = dwTime;
|
|
}
|
|
|
|
void SPlayerInfoMgr::ChangeState( int nState )
|
|
{
|
|
if( m_nPlayerState != STATE_NONE )
|
|
ProcMsgAtStatic( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_INPUTNUMBER, false) );
|
|
|
|
if( nState != m_nPlayerState )
|
|
{
|
|
if( nState == STATE_NONE )
|
|
{
|
|
switch(m_nPlayerState)
|
|
{
|
|
case STATE_TRADE:
|
|
{
|
|
//기존 트레이드 상태를 취소 하는 것인가?
|
|
_oprint( "SPlayerInfoMgr::ChangeState\n" );
|
|
|
|
SMSG_TRADE TradeMsg;
|
|
TradeMsg.mode = TS_TRADE::CANCEL_TRADE;
|
|
TradeMsg.rq_mode = true;
|
|
TradeMsg.target_player = m_hTradeTarget;
|
|
ProcMsgAtStatic( &TradeMsg );
|
|
}
|
|
break;
|
|
case STATE_STORAGE:
|
|
ProcMsgAtStatic( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_STORAGE, false) );
|
|
break;
|
|
case STATE_STALL:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
m_nPlayerState = nState;
|
|
}
|
|
|
|
void SPlayerInfoMgr::SetPlayerStat( const CreatureStat& stat, const CreatureAttribute& attribute, int nType )
|
|
{
|
|
switch(nType)
|
|
{
|
|
case TS_SC_STAT_INFO::TOTAL:
|
|
SetStat( stat, attribute );
|
|
break;
|
|
case TS_SC_STAT_INFO::BY_ITEM:
|
|
SetStatByItem( stat, attribute );
|
|
break;
|
|
}
|
|
}
|
|
|
|
//기본 공격에 시전 1, 4, 5 소스
|
|
bool SPlayerInfoMgr::IsSCastAttack( int nAttackType )
|
|
{
|
|
if( nAttackType == S_CAST_ATTACK || nAttackType == S_CAST_ATTACK_COMBAT || nAttackType == S_CAST_ATTACK_COMBAT_MAGIC )
|
|
return true;
|
|
return false;
|
|
}
|
|
//기본 공격에 피격 21, 24, 25 소스
|
|
bool SPlayerInfoMgr::IsSHitAttack( int nAttackType )
|
|
{
|
|
if( nAttackType == S_HIT_ATTACK || nAttackType == S_HIT_ATTACK_COMBAT || nAttackType == S_HIT_ATTACK_COMBAT_MAGIC )
|
|
return true;
|
|
return false;
|
|
}
|
|
//기본 공격에 히트 41, 44, 45 타겟
|
|
bool SPlayerInfoMgr::IsTHitAttack( int nAttackType )
|
|
{
|
|
if( nAttackType == T_HIT_ATTACK || nAttackType == T_HIT_ATTACK_COMBAT || nAttackType == T_HIT_ATTACK_COMBAT_MAGIC )
|
|
return true;
|
|
return false;
|
|
}
|
|
//전투 스킬에 시전 2, 4, 5 소스
|
|
bool SPlayerInfoMgr::IsSCastCombat( int nCombatType, int nFxType )
|
|
{
|
|
if( nCombatType == S_CAST_COMBAT || nCombatType == S_CAST_ATTACK_COMBAT || nCombatType == S_CAST_ATTACK_COMBAT_MAGIC )
|
|
{
|
|
//2~5까지는 근접용 스킬
|
|
//근접용 스킬인가 검사
|
|
if( nFxType == 2 || nFxType == 3 || nFxType == 4 || nFxType == 5)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
//전투 스킬에 피격 22, 24, 25 소스
|
|
bool SPlayerInfoMgr::IsSHitCombat( int nCombatType, int nFxType )
|
|
{
|
|
if( nCombatType == S_HIT_COMBAT || nCombatType == S_HIT_ATTACK_COMBAT || nCombatType == S_HIT_ATTACK_COMBAT_MAGIC )
|
|
{
|
|
//2~5까지는 근접용 스킬
|
|
if( nFxType == 2 || nFxType == 3 || nFxType == 4 || nFxType == 5)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
//전투 스킬에 피격 42, 44, 45 타겟
|
|
bool SPlayerInfoMgr::IsTHitCombat( int nCombatType, int nFxType )
|
|
{
|
|
if( nCombatType == T_HIT_COMBAT || nCombatType == T_HIT_ATTACK_COMBAT || nCombatType == T_HIT_ATTACK_COMBAT_MAGIC )
|
|
{
|
|
//2~5까지는 근접용 스킬
|
|
if( nFxType == 2 || nFxType == 3 || nFxType == 4 || nFxType == 5)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
//매직 스킬 시전 3, 5 소스
|
|
bool SPlayerInfoMgr::IsSCastMagic( int nMagicType, int nFxType )
|
|
{
|
|
if( nMagicType == S_CAST_MAGIC || nMagicType == S_CAST_ATTACK_COMBAT_MAGIC )
|
|
{
|
|
// 0, 1 마법류 스킬
|
|
if( nFxType == 0 || nFxType == 1 )
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
//매직 스킬 피격 23, 25 소스
|
|
bool SPlayerInfoMgr::IsSHitMagic( int nMagicType, int nFxType )
|
|
{
|
|
if( nMagicType == S_HIT_MAGIC || nMagicType == S_HIT_ATTACK_COMBAT_MAGIC )
|
|
{
|
|
// 0, 1 마법류 스킬
|
|
if( nFxType == 0 || nFxType == 1 )
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
//매직 스킬 히트 43, 45 타겟
|
|
bool SPlayerInfoMgr::IsTHitMagic( int nMagicType, int nFxType )
|
|
{
|
|
if( nMagicType == T_HIT_MAGIC || nMagicType == T_HIT_ATTACK_COMBAT_MAGIC )
|
|
{
|
|
// 0, 1 마법류 스킬
|
|
if( nFxType == 0 || nFxType == 1 )
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void SPlayerInfoMgr::SetTradeTarget(AR_HANDLE hTarget, const char *szName)
|
|
{
|
|
/// 2012.05.21 - prodongi
|
|
if (hTarget || m_hTradeTarget != hTarget)
|
|
checkValidArenaJoinSituationAtTrade();
|
|
|
|
m_hTradeTarget = hTarget;
|
|
m_strTradeTargetName = szName;
|
|
}
|
|
|
|
/// 2012.05.21 - prodongi
|
|
void SPlayerInfoMgr::checkValidArenaJoinSituationAtTrade()
|
|
{
|
|
sArenaJoinSituationCondition situationCondition;
|
|
/// way
|
|
situationCondition.m_notificationWays = cArenaJoinSituationChecker::WAY_NOTIFICATION_WND;
|
|
/// situation
|
|
situationCondition.add(cArenaJoinSituationChecker::SITUATION_ARENA_WAITING, S(2457));
|
|
situationCondition.add(cArenaJoinSituationChecker::SITUATION_ARENA_WAITING_COUNT, S(2457));
|
|
|
|
g_pCurrentGameSystem->isValidArenaJoinSituation(situationCondition);
|
|
}
|