#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); }