#include "stdafx.h" #include ".\SGameLocalPlayer.h" #include "GameDefine.h" #include "KSeqAvatarEx.h" #include "SGameAniType.h" #include "SAvatarProperty.h" #include "SAvatarStateMachine.h" #include "SSkillDB.h" #include "SGameMessage.h" //#include "SGameMessageUI.h" #include "SSKillStageType.h" #include #include "SChatType.h" #include "SStringDB.h" #include "SMotionDB.h" #include "SGameWorld.h" #include ".\SGameLocalCreature.h" #include "SDebug_Util.h" #include "Arena\\ArenaJoinSituationChecker.h" #include "SGameSystem.h" extern SGameSystem * g_pCurrentGameSystem; #include "SUISysMsgDefine.h" AR_TIME SGameLocalPlayer::CREATURE_MOUNT_COOLTIME = 200; void SGameLocalPlayer::sKMoveTargetList::add(K3DVector const& pos) { if (m_list.size() >= sKMoveTargetList::MAX_LIST_NUM) m_list.erase(m_list.begin()); m_list.push_back(pos); } bool SGameLocalPlayer::sKMoveTargetList::is(K3DVector const& pos) const { std::vector::const_iterator it = std::find(m_list.begin(), m_list.end(), pos); if (it != m_list.end()) { return true; } return false; } bool SGameLocalPlayer::sKMoveTargetList::erase(K3DVector const& pos) { std::vector::iterator it = std::find(m_list.begin(), m_list.end(), pos); if (it != m_list.end()) { m_list.erase( it ); return true; } return false; } SGameLocalPlayer::SGameLocalPlayer() : SGamePlayer() , m_bDeadDialog( false ) , m_bDeadMsgInDeathMatch( false ) , m_bSendResurrecMsgInDeathMatch( false ) , m_bDeadMsgInDeathMatchTime( 0 ) , m_bDeadMsgInDeathMatchTime2( 0 ) , m_dwUpdateTime( 0 ) //서버 업데이트 시간 , m_dwDeadDialogTime( 0 ) , m_nPrevHP( 1 ) , m_pWayPointList( NULL ) , m_nWayPointSize( 0 ) , m_nCurrentWayPoint( -1 ) , m_nTotalLak( 0 ) , m_nTotalBonusLak( 0 ) , m_nAbsorbLak( 0 ) , m_nBonusLakType( 0 ) // sonador 3.10.2 PC 방 혜택 관련 라크 획득 시스템 메시지 변경 , m_nBonusLakPercentage( 0 ) // , m_nPKModeState( PK_MODE_OFF ) , m_instanceArenaStatus(IAS_NORMAL) , m_pPending_poslist(NULL) , m_nPending_handle( 0 ) { m_pStateVM = new SLocalPlayerStateMachine; m_pStateVM->SetReceiver( this ); m_pLocalPlayer = this; m_bFootsteps = true; m_bLocal = true; m_creatureMountedTime = 0; if (m_pPending_poslist==NULL) { m_pPending_poslist = new ArPosition[PENDINGSIZE]; } m_dwActivateSkillTime = timeGetTime(); } SGameLocalPlayer::~SGameLocalPlayer() { if( m_pStateVM ) m_pStateVM->SetReceiver( NULL ); if ( m_pPending_poslist ) delete []m_pPending_poslist; } void SGameLocalPlayer::OnInput( class SGameInput * pInput ) { if( !m_pStateVM ) return; m_pStateVM->OnInput( pInput ); } void SGameLocalPlayer::NPlayAnimation( int nType , int nAniType, float fPlayRate ) { /* if( nType == 11 ) { assert(0); } _oprint( "로컬 NPlayAnimation : %d\n", nType );*/ if ((m_nNewCurAniType==ANI_WALK || m_nNewCurAniType==ANI_RUN) && (nType>=ANI_FIRE_MAGIC01 && nType<=ANI_FIRE_MAGIC05)) return; assert( nType && "Local::NPlayAnimation Ani value is abnormal." ); SGamePlayer::NPlayAnimation( nType , nAniType, fPlayRate ); } bool SGameLocalPlayer::Render( unsigned long uRenderBitVector, KViewportObject** ppViewportList, int nViewportCount ) { return SGameAvatarEx::Render( uRenderBitVector, ppViewportList, nViewportCount ); } bool SGameLocalPlayer::Process( DWORD dwTime, unsigned long uProcessBitVector ) { if( m_bRefreshInven ) { m_bRefreshInven = false; //인벤토리에 셋팅 SIMSG_UI_MAINPLAYER_INFO msg; msg.pSeqForm = GetSeqForm(); msg.pCobName = GetCobFileName(); msg.handle = GetArID(); msg.bRefresh = true; msg.pAniName = GetMotionSetDB().GetAni( GetObjType(), ANI_DEFAULT01, GetRace(), GetSex(), m_nAniClass ); if( msg.pAniName ) { CStringUtil::GetStrKey( msg.pAniName, '_', m_strTempAniKey ); msg.pAniName = m_strTempAniKey.c_str(); } SendGameMsg( &msg ); } // { TODO : 죽었을때 다이얼로그 처리 if( /*m_nPrevHP &&*/ IsDead() ) { /*int x = GetPosition()->x; int y = GetPosition()->y; //데스매치중이다. if( ( x >= 193536 && x <= 201600 && y >= 104832 && y <= 112896) || ( x >= 201600 && x <= 209664 && y >= 104832 && y <= 112896) || ( x >= 193536 && x <= 201600 && y >= 96768 && y <= 104832) || ( x >= 201600 && x <= 209664 && y >= 96768 && y <= 104832) || ( x >= 193536 && x <= 201600 && y >= 88704 && y <= 96768) || ( x >= 201600 && x <= 209664 && y >= 88704 && y <= 96768) || ( x >= 193536 && x <= 201600 && y >= 80640 && y <= 88704) || ( x >= 201600 && x <= 209664 && y >= 80640 && y <= 88704) ) // 데스매치*/ #ifndef _EQUATION if(IsInDeathMatch()) { //10초후에 부활한다고 한다. if (!m_bDeadMsgInDeathMatch) { m_bDeadMsgInDeathMatch = true; m_bSendResurrecMsgInDeathMatch = false; m_bDeadMsgInDeathMatchTime = dwTime; m_bDeadMsgInDeathMatchTime2 = dwTime; } } else #endif { if( !m_bDeadDialog ) { m_bDeadDialog = true; // AziaMafia Temps pour Rez m_dwDeadDialogTime = GetSafeTickCount() + 100; //5000 : Une boîte de dialogue apparaît disant qu'il est mort après 5 secondes } } } else { #ifndef _EQUATION if(m_bDeadMsgInDeathMatch && !IsDead() ) { m_bDeadMsgInDeathMatch = false; m_bSendResurrecMsgInDeathMatch = false; } #endif if( m_bDeadDialog && !IsDead() ) { // 다이얼로그 닫자 m_bDeadDialog = false; m_dwDeadDialogTime = 0; SendGameMsg( &SMSG_SEND_DATA( "close_all_message_box" ) ); SendGameMsg( &SMSG_SEND_DATA( "close_rebirth_message_box" ) ); SendGameMsg( &SMSG_SEND_DATA( "close_rebirth_PVP_message_box" ) ); } } // } // m_nPrevHP = GetHP(); #ifndef _EQUATION if( m_bDeadMsgInDeathMatch ) { if( dwTime - m_bDeadMsgInDeathMatchTime > 11000 ) { if( !m_bSendResurrecMsgInDeathMatch ) { //서버에 메시지 전송 하고 이제 대기한다. m_bSendResurrecMsgInDeathMatch = true; SendGameMsg( &SMSG_RESURRECTION( 0,0,false, true) ); } } else { //부활메시지를 뿌린다. if( dwTime - m_bDeadMsgInDeathMatchTime2 > 1000) { int ttt = 10 - (DWORD)((m_bDeadMsgInDeathMatchTime2 - m_bDeadMsgInDeathMatchTime)/1000); if(ttt >= 0) { m_bDeadMsgInDeathMatchTime2 += 1000; std::string strRemain = GetStringDB().GetString( 9202 ); XStringUtil::Replace( strRemain, "#@time@#", CStringUtil::StringFormat( "%d", ttt )); SMSG_CHATTING chatmsg; chatmsg.handle = 0; chatmsg.nChatType = CHAT_NOTICE; chatmsg.szSender = "@NOTICE";//"notice"; chatmsg.strText = strRemain; chatmsg.nNoticeOnly = 0; SendGameMsg( &chatmsg ); } } } } #endif // AziaMafia Instant Rez ? //if( IsDead() && m_dwDeadDialogTime && m_dwDeadDialogTime < GetSafeTickCount() ) if (IsDead() && m_dwDeadDialogTime && m_dwDeadDialogTime < GetSafeTickCount()) { m_dwDeadDialogTime = 0; SendGameMsg( &SMSG_SEND_DATA( "close_all_message_box" ) ); int nStringID = 809; //전투 불능 상태입니다.
마을로 귀환하시려면 확인 버튼을 누르세요. int nCurrentLocation = GetCurrentLocation(); if( nCurrentLocation == PLAYER_IN_DUNGEON_SIEGE || nCurrentLocation == PLAYER_IN_DUNGEON_RAID ) nStringID = 822; //전투 불능 상태입니다.
확인 버튼을 누르면 부활지점에서 부활합니다. else if( nCurrentLocation == PLAYER_IN_MATCH ) nStringID = 963; //전투 불능 상태입니다.
확인 버튼을 누르면 경험치 소모 없이 제자리에서 부활합니다. else if (PLAYER_IN_ARENA == nCurrentLocation) nStringID = 2480; if( GetStateFlag() & FLAG_STATE::FLAG_STATE_RESURRECTION ) { StateInfoEx* pStateInfo = GetStateDBInfo( STATE_TYPE::STATE_RESURRECTION ); if( pStateInfo ) SendGameMsg( &SIMSG_REQ_OPEN_MSGBOX( SIMSG_REQ_OPEN_MSGBOX::MSGBOX_DEAD, GetArID(), false, S(nStringID), true, GetStringDB().GetString( pStateInfo->name_id ) ) ); else SendGameMsg( &SIMSG_REQ_OPEN_MSGBOX( SIMSG_REQ_OPEN_MSGBOX::MSGBOX_DEAD, GetArID(), false, S(nStringID) ) ); } else SendGameMsg( &SIMSG_REQ_OPEN_MSGBOX( SIMSG_REQ_OPEN_MSGBOX::MSGBOX_DEAD, 0, false, S(nStringID) ) ); /// 2012.05.21 - prodongi checkValidArenaJoinSituationAtDead(); } SGamePlayer::Process( dwTime, uProcessBitVector ); if( m_pStateVM ) { m_pStateVM->Process( m_dwTime ); } if( m_dwUpdateTime == 0 ) { m_dwUpdateTime = m_dwTime; } else { if( (m_dwTime - m_dwUpdateTime)>=UPDATE_TIME ) { int cur = GetArTime();; static int last = 0; if (cur>last+400 || cur 0 ) CheckWayPoint(); return true; } void SGameLocalPlayer::SetAttackMode() { if( !(GetStatus() & TS_ENTER::PlayerInfo::FLAG_BATTLE_MODE) ) { ReqBattle(); //서버에 상태 바뀜 전송 } } void SGameLocalPlayer::CheckPrevState() { if( m_pStateVM == NULL ) return; TS_ATTACK_REQUEST msg; msg.handle = GetArID(); msg.target_handle = m_pStateVM->GetAttackTarget(); SendMsg( &msg ); } void SGameLocalPlayer::ReqTakeItem( AR_HANDLE handle ) { TS_CS_TAKE_ITEM msg; msg.item_handle = handle; msg.taker_handle = GetArID(); // sonador #2.1.2.4.3 팻 조작 UI 연동 SendMsg( &msg ); } void SGameLocalPlayer::ReqMove( AR_HANDLE handle, const ArPosition & target, bool bSpeedSync, bool bChase ) { //TODO : 이 곳에서 검사를 하면, 문제가 생겨서 일단 제거. 상태 머신 안으로 들어가야 할 듯 하다. //전에 요청한 위치보다 FREQ_MOVE_LIMIT 만큼은 커야 한다. //float fLen = K3DVectorGetLength( K3DVector(m_vTargetPos.x, m_vTargetPos.y, 0.f), K3DVector(target.x, target.y, 0.f) ); //if( fLen < FREQ_MOVE_LIMIT ) //{ // return; //} //사용 중인 스킬이 있어서 이동 불가 if( !IsUseSkill_complete() ) return; if( IsUsingSkill() ) return; //뭔가를 하는중인가? if( IsIng() ) return; m_vTargetPos.x = target.x; m_vTargetPos.y = target.y; WORD wTile=0; GetHeight( m_vTargetPos.x, m_vTargetPos.y, m_vTargetPos.z,wTile ); //SetMoveTargetPos( m_vTargetPos.x, m_vTargetPos.y, m_vTargetPos.z, bChase ); int nDetourSize = GetAllDetourPointSize(); //if( nDetourSize > 1 ) //{ // SGameObject::ReqMove( handle, target, GetAllDetourPoint(), nDetourSize, bSpeedSync ); ReqGameObjectMove( handle, target, GetAllDetourPoint(), nDetourSize, bSpeedSync ); // // } //else //if ( nDetourSize == 1 ) //{ // ReqGameObjectMove( handle, target, GetAllDetourPoint(), 1, bSpeedSync ); //} //else //{ SGameObject::ReqMove( handle, target, &target, 1, bSpeedSync ); //} DeleteReqPoint(); SGameLocalCreature::SetIdleProcess( true ); stopKMove(); // _oprint( "Local ReqMove : %d %f %f %f\n", nDetourSize, target.x, target.y, target.z ); } void SGameLocalPlayer::reqKMove(AR_HANDLE handle, const K3DVector & target, bool bSpeedSync, bool bChase ) { // AziaMafia FixSkill /*if( !IsUseSkill_complete() ) return; if( IsUsingSkill() ) return; //뭔가를 하는중인가? if( IsIng() ) return; AziaMafia FixSkill end */ m_vTargetPos.x = target.x; m_vTargetPos.y = target.y; WORD wTile=0; GetHeight( m_vTargetPos.x, m_vTargetPos.y, m_vTargetPos.z,wTile ); ArPosition _target; _target.x = target.x; _target.y = target.y; _target.z = target.z; ReqGameObjectMove( handle, _target, &_target, 1, bSpeedSync ); SGameLocalCreature::SetIdleProcess( true ); } static DWORD dwLastMoveTime = timeGetTime(); void SGameLocalPlayer::ReqGameObjectMove( AR_HANDLE handle, const ArPosition & target, const ArPosition * poslist, int count, bool bSpeedSync ) { //static int pending_handle = 0; static int pending_count = 0; static ArPosition pending_target = ArPosition(0,0); //static ArPosition *pending_poslist = NULL; //static ArPosition last_req_pos = ArPosition(0,0); unsigned int cur_tick = timeGetTime(); if (cur_tick - m_dwActivateSkillTime < 1000 ) return; if (target.x == 0 && target.y==0) { if ( m_nPending_handle && cur_tick - dwLastMoveTime > 200 && ( cur_tick - m_dwActivateSkillTime > 2000 ) ) { SGameObject::ReqMove( m_nPending_handle, pending_target, m_pPending_poslist, pending_count, true ); dwLastMoveTime = cur_tick; m_nPending_handle = 0; pending_count = 0; } else { SGameWorld* pGameWorld = dynamicCast(g_pCurrentGameSystem->GetGame()); if( pGameWorld==0) return; if (pGameWorld->GetGameManager()->IsShowLoadingWnd() ) { dwLastMoveTime = cur_tick; resetPending_poslist(); pending_count = 0; return; } if (IsMoving()==0) return; if (cur_tick - dwLastMoveTime < 1000 ) return; dwLastMoveTime = cur_tick; int ts = GetAllDetourPointSize(); if (ts<=0) return; int step = GetDetourStep(); if (step==0 || step==ts) { step>0 ? step=step-1 : step=0 ; int currentX, currentY; currentX = GetPosition()->x; currentY = GetPosition()->y; int xd = currentX - m_pPending_poslist[step].x; int yd = currentY - m_pPending_poslist[step].y; int dis = (xd*xd) + (yd*yd); if ( dis >= 3000000 ) return; SGameObject::ReqMove( GetArID(), pending_target, &m_pPending_poslist[step], 1, true ); } } return; } // Timer Process End // Input Porcess Start if (count>=PENDINGSIZE) return; if( count >= 1 ) { if ( ( cur_tick - dwLastMoveTime > 200 || count>1 ) ) { dwLastMoveTime = cur_tick; SGameObject::ReqMove( handle, target, poslist, count, bSpeedSync ); m_nPending_handle = 0; pending_target.x = (int)target.x; pending_target.y = (int)target.y; pending_count = count; for (int i=0;ix; current.y = GetPosition()->y; current.z = GetPosition()->z; //pending_count = 0; dwLastMoveTime = cur_tick; resetPending_poslist(); SGameObject::ReqMove( handle, current, ¤t, 1, bSpeedSync ); //SGameObject::ReqMove( handle, target, &target, 1, bSpeedSync ); //pending_handle = 0; //pending_target = target; //pending_count = 0; } } void SGameLocalPlayer::setCameraRoll(float angle) { SGameAvatarEx::setCameraRoll(angle); SGameAvatarEx* creature = GetRiderCreatureObject(); if (creature) { creature->setCameraRoll(angle); } } void SGameLocalPlayer::addKMoveTargetList(K3DVector const& targetPos) { m_kmoveTargetList.add(targetPos); } bool SGameLocalPlayer::isKMoveTargetList(std::vector const& targetPosList) const { if (targetPosList.empty()) return false; ArPosition pos = targetPosList.back(); return m_kmoveTargetList.is(K3DVector(pos.x, pos.y, 0.0f)); } void SGameLocalPlayer::eraseKMoveTargetList(std::vector const& targetPosList) { if (targetPosList.empty()) return; ArPosition pos = targetPosList.back(); m_kmoveTargetList.erase(K3DVector(pos.x, pos.y, 0.0f)); } void SGameLocalPlayer::clearMoveTargetList() { m_kmoveTargetList.clear(); } void SGameLocalPlayer::ReqAttack( AR_HANDLE target ) // target == 0 공격 중지 요청 { assert( target && "ReqAttack : Target ID Invalid!!!" ); if( m_pArObject && !m_pArObject->FinishedReqRegionUpdate() ) return; //#ifndef NDEBUG // SGameObject * pTarget = GetGameObject( target ); // if( pTarget ) // { // float fDistance; // K3DVector tpos = *pTarget->GetPosition(); // K3DVector spos = *GetPosition(); // fDistance = K3DVectorGetLength( tpos, spos ); //전체 거리 // // _oprint( "[s크기 : %f %f], [t크기 %f %f]\n", GetSize()/2.f, GetScale(), pTarget->GetSize()/2.f, pTarget->GetScale() ); // _oprint( "[사거리 : %f], [거리 %f], , \n", GetAttackRange(), fDistance, tpos.x, tpos.y, tpos.z, spos.x, spos.y, spos.z ); // } //#endif // _oprint( "[ReqAttack : %u]\n", target ); //if( target == 0 ) //{ // int a = 2; // a = 3; //} // AziaMafia Mafia Fix Skill /* if( !IsUseSkill_complete() ) return; if( IsUsingSkill() ) return; */ //뭔가를 하는중인가? if( IsIng() ) return; // TODO : 우선 임시로 막아 두자 if( IsMount() || IsMountMode() ) return; TS_ATTACK_REQUEST msg; msg.handle = GetArID(); msg.target_handle = target; SendMsg( &msg ); } void SGameLocalPlayer::ReqCast( AR_HANDLE target, int nSkillID, int nSkillLv, K3DVector const& targetPos ) { // _oprint( "====>스킬 요청 %d %d\n", nSkillID, nSkillLv ); //TODO : 사용 중인 스킬의 모션이 있는가 판별. //_SKILL_FX* pSkillFX = GetSkillStageDB().GetSkillStageData( info.nSkillID ); //if( !pSkillFX ) //{ // return; //} //if( pSkillFX->nCasting_Type_Id != 1 ) //{ // pSkillFX->nCasting_Start_Motion_Id; //} if( !IsUseSkill_complete() ) return; if( IsUsingSkill() ) { if( IsAttackingByBow() == false ) return; } //뭔가를 하는중인가? if( IsIng() ) return; _SKILL_FX* pSkillFX = GetSkillStageDB().GetSkillStageData( nSkillID ); if( !pSkillFX ) { assert(0 && "스킬 ID 확인 : 스킬 유형이 없다!!!" ); return; } if( pSkillFX->szType == 0 || pSkillFX->szDeal_Damage == 1 ) //전투 기술이면 또는 해로운 기술 이면, 전투 모드로 전환 SetAttackMode(); SkillBaseEx* pSkill = GetSkillDB().GetSkillData(nSkillID); SGameAvatarEx* pLocal = g_pCurrentGameSystem->GetLocalPlayer(); if (pSkill && pLocal) { if (pSkill->cost_energy_per_skl == 1) { nSkillLv = pLocal->m_nEnergy;// } } TS_CS_SKILL msg; msg.caster = GetArID(); msg.skill_id = nSkillID; msg.target = target; msg.skill_level= nSkillLv; msg.x = targetPos.x; msg.y = targetPos.y; msg.z = targetPos.z; SendMsg( &msg ); //사용 여부를 인터페이스에 알리자~ } static DWORD dwCancelLastTime = GetSafeTickCount(); void SGameLocalPlayer::ReqCancelAction() { // _oprint( "SGameLocalPlayer::ReqCancelAction()\n" ); if ( GetSafeTickCount() - dwCancelLastTime > 200 ) { // _oprint( "SGameLocalPlayer::ReqCancelAction()\n" ); TS_CS_CANCEL_ACTION msg; msg.handle = GetArID(); SendMsg( &msg ); dwCancelLastTime = GetSafeTickCount(); } } void SGameLocalPlayer::ReqThrow( AR_HANDLE target, AR_HANDLE itemhandle ) { //던지는게 가능한 아이템인지 검사는 Input에서 필터링 하는 것이 맞음. //TS_CS_USE_ITEM use_msg; //use_msg.item_handle = itemhandle; //use_msg.target_handle = target; //SendMsg( &use_msg ); } void SGameLocalPlayer::ReqSit() { if( IsMount() && IsMountMode() ) return; if( IsIng() ) return; RqChatting( CHAT_NORMAL, m_pProperty->Name, "/sitdown" ); } void SGameLocalPlayer::ReqStandUp() { if( IsMount() && IsMountMode() ) return; if( IsIng() ) return; RqChatting( CHAT_NORMAL, m_pProperty->Name, "/standup" ); } void SGameLocalPlayer::ReqNormal() { if( IsMount() && IsMountMode() ) return; if( IsIng() ) return; std::string str; XStringUtil::Format(str, "%u", GetArID() ); RqChatting( CHAT_NORMAL, str.c_str(), "/normal" ); } void SGameLocalPlayer::ReqBattle() { if( IsMount() && IsMountMode() ) return; if( IsIng() ) return; std::string str; XStringUtil::Format(str, "%u", GetArID() ); RqChatting( CHAT_NORMAL, str.c_str(), "/battle" ); SGamePlayer::SetAttackMode(); } void SGameLocalPlayer::ReqMount() { if( IsIng() ) return; if (!checkCreatureMountCooltime()) return ; RqChatting( CHAT_NORMAL, m_pProperty->Name, "/mount_creature" ); } void SGameLocalPlayer::ReqUnMount() { if( IsIng() ) return; if (!checkCreatureMountCooltime()) return ; RqChatting( CHAT_NORMAL, m_pProperty->Name, "/unmount_creature" ); } void SGameLocalPlayer::ReqEmotion() { //서버로 보내기 } void SGameLocalPlayer::ReqUseItem( AR_HANDLE hTargetHandle, AR_HANDLE hItemHandle, int nSkillID, AR_HANDLE hItemUseTargetHandle, const char* lpText ) { _SKILL_FX* pSkillFX = GetSkillStageDB().GetSkillStageData( nSkillID ); if( pSkillFX ) { //전투 기술이면 또는 해로운 기술 이면, 전투 모드로 전환 if( pSkillFX->szType == 0 || pSkillFX->szDeal_Damage == 1 ) SetAttackMode(); } TS_CS_USE_ITEM msg; msg.target_handle = hTargetHandle; //로그인 되어있고, 시야에 없는 파티원등에게 사용 시 if( hItemUseTargetHandle > 0 ) msg.target_handle = hItemUseTargetHandle; msg.item_handle = hItemHandle; assert(32>::strlen(lpText)); if( 32>::strlen(lpText) ) ::memcpy( msg.szParameter, lpText, ::strlen(lpText) ); SendMsg( &msg ); } void SGameLocalPlayer::SetWayPointList( K3DVector* pWayPointList, int nWayPointSize ) { ClearWayPointList(); m_pWayPointList = pWayPointList; m_nWayPointSize = nWayPointSize; m_nCurrentWayPoint = -1; K3DVector vPos = GetCurPosWithChangeDir(); float fOldDis = 9999999.0f; for( int nCount = 0; nCount < m_nWayPointSize; nCount++ ) { float fDistance = GetDistance( vPos, m_pWayPointList[nCount] ); if( fDistance < fOldDis ) { fOldDis = fDistance; m_nCurrentWayPoint = nCount; } } //현재 웨이포인트가 마지막인가? 없는 웨이 포인트인가? 웨이 포인트와 플레이어의 거리가 5미터 이내인가? if( m_nCurrentWayPoint < m_nWayPointSize && m_nCurrentWayPoint > -1 && fOldDis < (float)GameRule::DEFAULT_UNIT_SIZE * 5 ) { //각도를 구하자 if( m_nCurrentWayPoint < m_nWayPointSize - 1 ) //다음 위치가 있어야 한다 { K3DVector vVec1 = m_pWayPointList[m_nCurrentWayPoint+1] - m_pWayPointList[m_nCurrentWayPoint]; K3DVector vVec2 = vPos - m_pWayPointList[m_nCurrentWayPoint]; vVec1.Normalize(); vVec2.Normalize(); float fAngle = K3DVectorDot( vVec1, vVec2 ); //현재 위치로 이동할지 아니면 바로 다음 위치로 이동할지 결정 if( fAngle > 0 ) m_nCurrentWayPoint++; } //길찾기 땜에 잠시 주석처리 하자 // ReqMove( GetArID(), ArPosition( m_pWayPointList[m_nCurrentWayPoint].x, m_pWayPointList[m_nCurrentWayPoint].y, 0 ), GetAllDetourPoint(), GetDetourSize(), true, true ); } else ClearWayPointList(); } void SGameLocalPlayer::CheckWayPoint() { if( m_nCurrentWayPoint < m_nWayPointSize ) { float fDistance = GetDistance( GetCurPosWithChangeDir(), m_pWayPointList[m_nCurrentWayPoint] ); if( fDistance < (float)GameRule::DEFAULT_UNIT_SIZE * 3 ) { if( ++m_nCurrentWayPoint < m_nWayPointSize ) { //길찾기 땜에 잠시 주석처리 하자 // ReqMove( GetArID(), ArPosition( m_pWayPointList[m_nCurrentWayPoint].x, m_pWayPointList[m_nCurrentWayPoint].y, 0 ), GetAllDetourPoint(), GetDetourSize(), true, true ); } else ClearWayPointList(); } } else ClearWayPointList(); } void SGameLocalPlayer::ClearWayPointList() { m_pWayPointList = NULL; m_nWayPointSize = 0; m_nCurrentWayPoint = -1; } void SGameLocalPlayer::SetStatus( unsigned status ) { if( status & TS_ENTER::PlayerInfo::FLAG_PK_ON ) { if( !(GetStatus() & TS_ENTER::PlayerInfo::FLAG_PK_ON) ) { SetPKMode( true ); SetPKModeState( PK_MODE_ON ); } } else { //현재 PKON상태 였다면 OFF로 if( GetStatus() & TS_ENTER::PlayerInfo::FLAG_PK_ON ) { SetPKMode( false ); SetPKModeState( PK_MODE_OFF ); } } SGameAvatarEx::SetStatus( status ); } void SGameLocalPlayer::stopKMove() { if (m_pMsgHandler) m_pMsgHandler->stopKMove(); } /// 2012.05.21 - prodongi void SGameLocalPlayer::checkValidArenaJoinSituationAtDead() { sArenaJoinSituationCondition situationCondition; /// way situationCondition.m_notificationWays = cArenaJoinSituationChecker::WAY_NOTIFICATION_WND; /// situation situationCondition.add(cArenaJoinSituationChecker::SITUATION_ARENA_WAITING, S(2456)); situationCondition.add(cArenaJoinSituationChecker::SITUATION_ARENA_WAITING_COUNT, S(2456)); g_pCurrentGameSystem->isValidArenaJoinSituation(situationCondition); } bool SGameLocalPlayer::checkCreatureMountCooltime() { AR_TIME curTime = GetArTime(); AR_TIME e = curTime - m_creatureMountedTime; if (e < CREATURE_MOUNT_COOLTIME) { SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_OTHER_ACTION_WAIT ) ); return false; } m_creatureMountedTime = curTime; return true; } void SGameLocalPlayer::resetPending_poslist() { m_nPending_handle = 0; if ( m_pPending_poslist ) memset ( m_pPending_poslist, 0, sizeof(m_pPending_poslist)*PENDINGSIZE ); }