#include "stdafx.h" #include "SGame.h" #include "SGameEffect.h" #include "K3DTypes.h" #include "SGameAvatarEx.h" #include "SGameLocalPlayer.h" #include "SGameOtherPlayer.h" #include "SGameskilprop.h" #include "SGameSystem.h" #include "STargetMgr.h" //#include "SUIWnd.h" #include "SInventoryMgr.h" #include "SSKillSlot.h" #include "SSummonSlotMgr.h" #include "SMessengerMgr.h" #include "STradeMgr.h" #include "SStorageMgr.h" #include "SMotionMgr.h" #include "STargetMgr.h" #include "SPlayerInfoMgr.h" #include "SStoreMgr.h" #include "SGameMessage.h" //#include "SGameMessageUI.h" #include "SGameUIMgr.h" #include "SPetMgr.h" #include "SPetSkillMgr.h" #include "STitleMgr.h" #include "SGameInput.h" #include "SGameFieldQuestProp.h" #include "SBasicStat.h" #include "SCreatureDB.h" #include "SItemDB.h" #include "SMonsterDB.h" #include "SSkillDB.h" #include "SMotionDB.h" #include "STenacityDB.h" #include "SNpcDB.h" #include "SNpcResourceDB.h" #include "SStringDB.h" #include "SQuestDB.h" #include "SFieldPropResourceDB.h" #include "SPetDB.h" #include #include "ErrorCode/ErrorCode.h" #include "SUISysMsgDefine.h" #include "SGameUISyncMng.h" #include "SChatType.h" #include "SSkillStageType.h" #include "SGameOption.h" #include #include "SDebug_Util.h" #include "tchar.h" #include "CInput.h" #include #include #include "SQuestMgr.h" #include "SLocalCommandDB.h" #include "SContentsManager.h" #include "SHuntaHolicSystem.h" #include "SGameLocalPet.h" #include "SLog.h" #include "SGameManager.h" //#include "SUIWnd.h" //#include "SUIUtil.h" #include "Arena\\ArenaJoinSituationChecker.h" #include "Arena\\ArenaSystem.h" #include "SCommandSystem.h" #include "SUIPartyTypes.h" #include "SGameWorld.h" #include "CommonUtil.h" #define SKILL_DISABLE 0 #define SKILL_USEABLE 1 #define SKILL_UNKNOWN 2 #define BATTLE_COUNT_DOWN 1000 //서버와 카운트 다운 시간이 맞아야 함 extern void CurOtherURLRefresh( int nWinID ); extern string ParseQuestText( const char *szQuestString, int nQuestCode ); extern void MsgSplit( const char* szMsg, std::vector& vecText, const wchar_t* lpDelimiter, bool bProcSpecialCharacter=false ); SGameSystem* g_pCurrentGameSystem=NULL; int g_nMoveSpeed = 119; bool SGameSystem::sActivatePropUpdate::enable(int skillId) const { if (skillId != SKILL_ID) return true; return m_update.m_active ? false : true; } void SGameSystem::sActivatePropUpdate::update(float elapsedtime) { m_update.update(elapsedtime); } void SGameSystem::sActivatePropUpdate::checkBegin(int skillId) { if (SKILL_ID == skillId) m_update.begin(2.0f, false); } SGameSystem::SGameSystem( SGame * pGame ) : m_pQuestProp(NULL) , m_pBattle_Info ( NULL ) , m_pBattle_End_Info ( NULL ) , m_RaidMgr ( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::RAID_MGR ) ) ) , m_PartyMgr ( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::PARTY_MGR )) ) , m_GuildMgr ( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::GUILD_MGR )) ) , m_FriendMgr ( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::FRIEND_MGR )) ) , m_CutMgr ( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::CUT_MGR )) ) , m_TradeMgr ( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::TRADE_MGR )) ) , m_StorageMgr ( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::STORAGE_MGR )) ) , m_MotionMgr ( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::MOTION_MGR )) ) , m_PlayerInfoMgr ( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::PLAYERINFO_MGR )) ) , m_InventoryMgr ( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::INVENTORY_MGR )) ) , m_CreatureSlotMgr ( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::CREATURESLOT_MGR )) ) , m_SkillSlotMgr ( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::SKILLSLOT_MGR )) ) , m_CreatureSkillSlotMgr( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::CREATURESKILLSLOT_MGR )) ) , m_GuildDataMgr ( *static_cast(GameUIMgrInstance.GetUIMgr( SGameUIInstance::GUILDDATA_MGR )) ) , m_PetMgr ( *static_cast< SPetMgr* >( GameUIMgrInstance.GetUIMgr( SGameUIInstance::PET_MGR ) ) ) , m_PetSkillMgr ( *static_cast< SPetSkillMgr* >( GameUIMgrInstance.GetUIMgr( SGameUIInstance::PETSKILL_MGR ) ) ) , m_TitleMgr ( *static_cast< STitleMgr* >( GameUIMgrInstance.GetUIMgr( SGameUIInstance::TITLE_MGR ) ) ) , m_pContentsMgr ( 0 ) // #2.1.2.11.1 , m_bDeathPVP ( false ) , m_bPVPStart ( false ) , m_bShowPVPIcon ( false ) , m_bIsShowBattleAccept ( false ) , m_bCheckPVP ( false ) { m_pGame = pGame; m_pFRecord = NULL; Init(); //!!TEST if (g_pCurrentGameSystem==NULL) g_pCurrentGameSystem=this; } SGameSystem::~SGameSystem() { if( m_pFRecord ) { fclose( m_pFRecord ); m_pFRecord = NULL; } Destory(); //!!TEST if (g_pCurrentGameSystem==this) g_pCurrentGameSystem=NULL; } void SGameSystem::Init() { GameUIMgrInstance.SetGame( m_pGame ); m_pTargetMgr = new SGameTargetMgr ( m_pGame ); m_pUISyncMng = new SGameUISyncMng( m_pGame ); SQuestMgr::GetInstance().SetGame(m_pGame); m_nContentState = CS_NONE; m_bIsShowTarget = false; m_dwTime = 0; int nBoothType = GetGameOption().GetBoothType(); if( nBoothType == BOOTH_TYPE::RENDER_NONE_BOOTH ) SGameOtherPlayer::SetRenderNoneBooth(); else if( nBoothType == BOOTH_TYPE::RENDER_SIMPLE_BOOTH ) SGameOtherPlayer::SetRenderSimpleBooth(); else if( nBoothType == BOOTH_TYPE::RENDER_DETAIL_BOOTH ) SGameOtherPlayer::SetRenderDetailBooth(); else if( nBoothType == BOOTH_TYPE::RENDER_AVATAR_BOOTH ) SGameOtherPlayer::SetRenderAvatarBooth(); else { GetGameOption().SetBoothRendType(BOOTH_TYPE::RENDER_NONE_BOOTH); SGameOtherPlayer::SetRenderNoneBooth(); } SetLocalPlayer( NULL ); m_pContentsMgr = new SContentsManager( m_pGame ); // #2.1.2.11.1 m_pContentsMgr->acquire< SHuntaHolicSystem >( "huntaholic" ); // 헌터홀릭 시스템 준비 m_arenaJoinSituationChecker = new cArenaJoinSituationChecker; m_arenaSystem = new sArenaSystem; } void SGameSystem::Destory() { SAFE_DELETE( m_pTargetMgr ); SAFE_DELETE( m_pUISyncMng ); SAFE_DELETE( m_pBattle_End_Info ); SAFE_DELETE( m_pBattle_Info ); // m_vCreatureDataList.clear(); m_vSkillPropList.clear(); GameUIMgrInstance.SetGame( NULL ); GameUIMgrInstance.ResetInfoMgr(); SAFE_DELETE( m_pContentsMgr ); // #2.1.2.11.1 SAFE_DELETE(m_arenaJoinSituationChecker); SAFE_DELETE(m_arenaSystem); } void SGameSystem::LeaveSummon( AR_HANDLE hLeaveHandle ) { SGameAvatarEx* pTarget = m_pTargetMgr->GetTarget(); if( pTarget ) { if( pTarget->GetArID() == hLeaveHandle ) m_pTargetMgr->SetTarget( NULL ); } for( unsigned int i(0); m_vSummonList.size()>i; i++ ) { if( m_vSummonList[i]->GetArID() == hLeaveHandle ) { //역소환 메시지 m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_CREATURE_AUTO_RECALL, m_vSummonList[i]->GetContentID() ) ); m_vSummonList.erase( m_vSummonList.begin()+i ); //소환된 크리처가 다수였고 현재는 1마리 밖에 존재 하지 않는다면 남아 있는 크리처를 좌측으로 위치시킨다 if( m_vSummonList.size() == 1 ) { m_vSummonList[0]->SetMoveLeft(); m_vSummonList[0]->AddNLeaveSummon(); //메인 크리처가 됐다는 메시지 m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_CREATURE_SECOND_SUMMON, m_vSummonList[0]->GetContentID() ) ); } return; } } } void SGameSystem::DelSummoon( AR_HANDLE hCreature ) { // 내 소환수면 저장 if( m_CreatureSlotMgr.IsEquipedCreature(hCreature) ) m_CreatureSlotMgr.DelSummonCreature(hCreature); // 2010.07.07 스킬 초기화 됬을때- prodongi else if (m_CreatureSlotMgr.IsEquipedCreatureCheckZeroCount(hCreature)) m_CreatureSlotMgr.DelSummonCreature(hCreature); } void SGameSystem::AddSummon( class SGameAvatarEx * pSummon, SMSG_ENTER* pEnterMsg ) { if( !pSummon ) return; if( !GetLocalPlayer() ) return; //뜯어 고쳐야 하는 코드들이군 // 내 소환수면 저장 if( m_CreatureSlotMgr.IsEquipedCreature(pSummon->GetArID()) ) { m_CreatureSlotMgr.AddSummonCreature(pSummon->GetArID()); const SCreatureInfo* pCreature = m_CreatureSlotMgr.GetCreatureInfo(pSummon->GetArID()); if( pCreature ) { _SUMMON_INFO_FILE* pSummonData = GetCreatureDB().GetCreatureData( pCreature->GetID() ); if( pSummonData ) { std::string strCreatureClass = GetStringDB().GetString( pSummonData->name_id ); std::string strText = SR(6434, "#@creature_class@#", strCreatureClass.c_str(), "#@creature_name@#", pSummon->GetName() ); m_pGame->SendGameInterfaceMsg( &SIMSG_UI_INPUTTEXT_UPDATE( SIMSG_UI_REQ_INPUTTEXT::USAGE_CREATURE_NAMEPLATE, strText.c_str(), 6784 ) ); // [sonador][7.0.6] Mantis 0002624 } //힘들게 설정한다 ㅡ.,ㅡ SMSG_ENTER::SummonInfo * pCreInfo = (SMSG_ENTER::SummonInfo *)(pEnterMsg+1); m_CreatureSlotMgr.SetCreatureHP( pSummon->GetArID(), pCreInfo->hp ); m_CreatureSlotMgr.SetCreatureMP( pSummon->GetArID(), pCreInfo->mp ); m_CreatureSlotMgr.SetCreatureMaxHP( pSummon->GetArID(), pCreInfo->max_hp ); m_CreatureSlotMgr.SetCreatureMaxMP( pSummon->GetArID(), pCreInfo->max_mp ); m_CreatureSlotMgr.SetCreatureLevel( pSummon->GetArID(), pCreInfo->level ); } } for( unsigned int i(0); m_vCreatureDataList.size()>i; i++ ) { if( m_vCreatureDataList[i].summon_handle == pSummon->GetArID() ) { //Stat 설정 for( unsigned int n(0); m_vStatList.size()>n; n++ ) { if( m_vStatList[n].handle == pSummon->GetArID() ) { pSummon->SetStat( &m_vStatList[n] ); break; } } pSummon->SetName( m_vCreatureDataList[i].name ); //소환 메시지 // // floyd 2008. 6. 13 // 크리쳐 소환시 메시지 부분을 SGameSystem::AddSummon함수에서 SCommandSystem::AddCreature함수로 이동 // 크리쳐 소환때만이 아니라 시야 밖으로 벗어났던 크리쳐가 시야 안으로 다시 들어오면 메시지가 출력 되는 문제 수정 // http://bug.nflavor.com/view.php?id=3388 // sonador #2.3.1.14 SCommandSystem::AddCreature 로 옮김 // // m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_CREATURE_CALL, pSummon->GetContentID() ) ); //주인님 설정 pSummon->SetMaster( GetLocalPlayer()->GetArID(), GetLocalPlayer() ); size_t summon_size = m_vSummonList.size(); for( size_t summon = 0; summon < summon_size; ++summon ) { if( m_vSummonList[summon]->GetArID() == pSummon->GetArID() ) return; } if( summon_size == 1 ) //먼저 소환된 넘이 있다면 현재 소환된넘을 우측으로 위치하게 한다 { //소환 연출땜에 주석처리 // pSummon->AddNLeaveSummon( CREATURE_MOVE_RIGHT ); pSummon->SetMoveRight(); //현재 소환된넘 m_vSummonList[0]->SetMoveLeft(); m_vSummonList[0]->AddNLeaveSummon(); //기존 존재했던넘 } //소환 연출땜에 주석처리 // else // pSummon->SetBestPosition(); //기존 존재했던 소환수가 없을경우 적절한 포지션으로 이동시킨다 m_vSummonList.push_back( pSummon ); } } } void SGameSystem::EvolutionSummon( SMSG_SUMMON_EVOLUTION* pMsg ) { for( unsigned int i(0); m_vSummonList.size()>i; i++ ) { SGameAvatarEx * pCreature = m_vSummonList[i]; if( pCreature->GetArID() == pMsg->summon_handle ) { //소유하고 있는 이펙트 삭제 한다. //TODO : 기존에 보이던 이펙트를 다시 생성해야 하는 문제가 발생. m_pGame->DelOwnerEffect( pMsg->summon_handle ); pCreature->EvolutionSummon( pMsg ); m_CreatureSlotMgr.SetUpdateInfo( pMsg ); m_PlayerInfoMgr.SetTarget( pMsg->summon_handle, pMsg->name, TS_ENTER::GAME_SUMMON ); m_pTargetMgr->SetTarget( NULL ); //타겟창 비활성화 SIMSG_UI_TARGET_INFO msg; m_pGame->ProcMsgAtStatic( &msg ); } } for( unsigned int i(0); m_vCreatureDataList.size()>i; i++ ) { if( m_vCreatureDataList[i].summon_handle == pMsg->summon_handle ) { strcpy( m_vCreatureDataList[i].name, pMsg->name ); m_CreatureSlotMgr.SetUpdateInfo( pMsg ); m_PlayerInfoMgr.SetTarget( pMsg->summon_handle, pMsg->name, TS_ENTER::GAME_SUMMON ); m_pTargetMgr->SetTarget( NULL ); break; } } } // { sonador 10.2.1 팻 시스템 구현 DATA_PET* SGameSystem::IsLocalPet( AR_HANDLE hPetHandle ) { return m_PetMgr.IsLocalPet( hPetHandle ); } SGameAvatarEx* SGameSystem::IsSummonPet( AR_HANDLE hPetHandle ) { return m_PetMgr.IsSummonPet( hPetHandle ); } DATA_PET* SGameSystem::IsLocalPetCage( AR_HANDLE hPetCageHandle ) { return m_PetMgr.IsLocalPetCage( hPetCageHandle ); } void SGameSystem::AddPet( class SGameAvatarEx* pet, struct SMSG_ENTER* enterMsg ) { m_PetMgr.AddPet( pet, enterMsg ); // sonador #2.1.2.4.3 팻 조작 UI 연동 // 서버를 통해 SMSG_SKILL_LIST 메시지를 받는 것과 동일한 처리를 하기 위함 // 추후, 팻 스킬 처리를 서버에서 담당하게 될 경우를 대비함 m_PetSkillMgr.UpdateSkillList( enterMsg->handle ); } void SGameSystem::RemovePet( AR_HANDLE hPetHandle ) { m_PetMgr.RemovePet( hPetHandle ); } // } void SGameSystem::AddSkillProp( SGameAvatarEx* pSkillProp ) { if( !pSkillProp ) return; m_vSkillPropList.push_back( pSkillProp ); ((SGameSkilProp*)pSkillProp)->SetHideProp(); } void SGameSystem::LeaveSkillProp( AR_HANDLE hLeave ) { std::vector< class SGameAvatarEx * >::iterator iter = m_vSkillPropList.begin(); for( ; iter != m_vSkillPropList.end() ; ) { SGameAvatarEx* pSkillProp = (*iter); if( hLeave == pSkillProp->GetArID() ) iter = m_vSkillPropList.erase( iter ); else ++iter; } } void SGameSystem::SetHideSkillProp() { std::vector< class SGameAvatarEx * >::iterator iter = m_vSkillPropList.begin(); for( ; iter != m_vSkillPropList.end() ; ++iter ) { SGameSkilProp* pSkillProp = (SGameSkilProp*)(*iter); pSkillProp->SetHideProp(); } } struct DATA_CREATURE * SGameSystem::IsLocalCreature( AR_HANDLE handle ) { for( unsigned int i(0); m_vCreatureDataList.size()>i; i++ ) { if( m_vCreatureDataList[i].summon_handle == handle ) { return &m_vCreatureDataList[i]; } } return NULL; } //현재 소환된 크리처인가? SGameAvatarEx* SGameSystem::IsSummonCreature( AR_HANDLE handle ) { if( !m_vSummonList.empty() ) { std::vector< class SGameAvatarEx* >::iterator iter = m_vSummonList.begin(); for(; iter != m_vSummonList.end(); iter++ ) { if( (*iter)->GetArID() == handle ) return (*iter); } } return NULL; } //퇴각 void SGameSystem::SetCreatureBackDown( AR_HANDLE handle ) //nIndex == 0, All { // K3DVector cpos = GetLocalPlayer()->GetCurPos(); // K3DVector tpos = K3DVector( cpos.x+18.f, cpos.y+18.f, cpos.z ); //소환된 크리처만 적용 for( unsigned int i(0); m_vSummonList.size()>i; i++ ) { SGameAvatarEx * pObject = m_vSummonList[i]; if( i == 0 ) pObject->SetMoveLeft(); else if( i == 1 ) pObject->SetMoveRight(); SInputCastCancel inputCastCancel; pObject->OnInput( &inputCastCancel ); pObject->CreatureBackDownSpeedOfCreature(); pObject->SetUnHold(); } /* if( handle ) { //일부 for( unsigned int i(0); m_vCreatureDataList.size()>i; i++ ) { if( m_vCreatureDataList[i].summon_handle == handle ) { SGameAvatarEx * pObject = (SGameAvatarEx*)m_pGame->GetGameObject( m_vCreatureDataList[i].summon_handle ); if( !pObject ) return; pObject->SetUnHold(); // SInputMove inputMove( tpos ); // pObject->OnInput( &inputMove ); return; } } } else { //전체 for( unsigned int i(0); m_vCreatureDataList.size()>i; i++ ) { SGameAvatarEx * pObject = (SGameAvatarEx*)m_pGame->GetGameObject( m_vCreatureDataList[i].summon_handle ); if( !pObject ) continue; pObject->SetUnHold(); // if( i == 1 ) // tpos = K3DVector( cpos.x+18.f, cpos.y+18.f, cpos.z ); // else if( i == 2 ) // tpos = K3DVector( cpos.x+18.f, cpos.y-18.f, cpos.z ); // SInputMove inputMove( tpos ); // pObject->OnInput( &inputMove ); } }*/ } void SGameSystem::SetCreatureAttack( class SGameAvatarEx * pTarget, AR_HANDLE handle ) { unsigned int nCreateSize = m_vCreatureDataList.size(); if( nCreateSize == 0 ) return; if( handle ) { //일부 for( unsigned int i(0); nCreateSize>i; i++ ) { SGameAvatarEx * pObject = (SGameAvatarEx*)m_pGame->GetGameObject( m_vCreatureDataList[i].summon_handle ); if( !pObject ) continue; if( m_vCreatureDataList[i].summon_handle == handle ) { pObject->SetUnHold(); SInputAttack inputAttack( pTarget->GetArID() ); pObject->SetTargetMonster( pTarget->GetArID() ); pObject->OnInput( &inputAttack ); break; } } } else { //전체 for( unsigned int i(0); nCreateSize>i; i++ ) { SGameAvatarEx * pObject = (SGameAvatarEx*)m_pGame->GetGameObject( m_vCreatureDataList[i].summon_handle ); if( !pObject ) continue; pObject->SetUnHold(); SInputAttack inputAttack( pTarget->GetArID() ); pObject->SetTargetMonster( pTarget->GetArID() ); pObject->OnInput( &inputAttack ); } } } void SGameSystem::SetCreatureCastCancel( AR_HANDLE handle ) { unsigned int nCreateSize = m_vCreatureDataList.size(); if( nCreateSize == 0 ) return; if( handle ) { //일부 for( unsigned int i(0); nCreateSize>i; i++ ) { SGameAvatarEx * pObject = (SGameAvatarEx*)m_pGame->GetGameObject( m_vCreatureDataList[i].summon_handle ); if( !pObject ) continue; if( m_vCreatureDataList[i].summon_handle == handle ) { SInputCastCancel inputCastCancel; pObject->OnInput( &inputCastCancel ); //캐스팅 캔슬 명령이 내려졌다면 이전 상태를 IDLE로 바꿔준다 if( pObject->IsCasting() || pObject->IsAttack() ) pObject->SetDefaultPrevState(); break; } } } else { //전체 for( unsigned int i(0); nCreateSize>i; i++ ) { SGameAvatarEx * pObject = (SGameAvatarEx*)m_pGame->GetGameObject( m_vCreatureDataList[i].summon_handle ); if( !pObject ) continue; SInputCastCancel inputCastCancel; pObject->OnInput( &inputCastCancel ); //캐스팅 캔슬 명령이 내려졌다면 이전 상태를 IDLE로 바꿔준다 if( pObject->IsCasting() || pObject->IsAttack() ) pObject->SetDefaultPrevState(); } } } void SGameSystem::UseEscCommand() { SGameAvatarEx * pPlayer = GetLocalPlayer(); if( pPlayer ) { //플레이어가 현재 스킬 및 활 조준 중이면 캐스팅 캔슬이 적용 if( pPlayer->IsCasting() || pPlayer->IsAttack() ) return; } //소환된 크리처가 있나? if( !m_vSummonList.empty() ) { for( unsigned int i = 0; i < m_vSummonList.size(); i++ ) { //소환된 크리처 중에 현재 스킬을 사용중인 넘이 있나? if( m_vSummonList[i]->IsCasting() || m_vSummonList[i]->IsAttack() ) return; } } //플레이어 및 크리처가 스킬을 사용중이지 않다면 SetTarget( NULL )설정 SetTarget(NULL); // esc키를 누르면 파티 타겟 삭제. m_PartyMgr.SetSelectMemberHandle( NULL ); m_PartyMgr.SetSelectMember( "none" ); } //----------------------------------------------------------------------------------------------------------------- // 타겟 정보 설정 (플레이어) //----------------------------------------------------------------------------------------------------------------- void SGameSystem::SetTargetInfo_Player( SGameAvatarEx* const pTarget ) { SIMSG_UI_TARGET_INFO_PLAYER msg; if( pTarget ) { if (pTarget->IsLocalPlayer()) { sArenaSystem* arenaSystem( g_pCurrentGameSystem->getArenaSystem() ); if( arenaSystem ) msg.strName = arenaSystem->getPlayerName( &m_PlayerInfoMgr ); msg.nLevel = pTarget->GetLevel(); } else { msg.strName = pTarget->GetName(); // 한국이고 운영자이면 if( GameRule::GetCurrentLocalBitSet() == GameRule::LOCAL_BITSET::KR && g_pCurrentGameSystem->GetLocalPlayerPermission() > 0 ) { msg.nLevel = pTarget->GetLevel(); } else { msg.nLevel = 0; } //#ifdef _DEV ///toggle off/on player level ingame msg.nLevel = pTarget->GetLevel(); //#endif } msg.handle = pTarget->GetArID(); msg.pSeqForm = pTarget->GetSeqForm(); msg.nHP = pTarget->GetHP(); msg.nMP = pTarget->GetMP(); msg.nMaxHP = pTarget->GetMaxHP(); msg.nMaxMP = pTarget->GetMaxMP(); msg.nObjType = pTarget->GetObjType(); msg.nJobID = pTarget->GetJobID(); msg.nMobID = pTarget->GetContentID(); msg.strCobName = pTarget->GetCobFileName(); msg.eClan = (GAME_DEFINE::CLAN)pTarget->GetRace(); if( m_pFRecord ) { fprintf( m_pFRecord, "%s\n", pTarget->GetName() ); fflush( m_pFRecord ); } } if( m_pGame ) m_pGame->ProcMsgAtStatic( &msg ); } //----------------------------------------------------------------------------------------------------------------- // 타겟 정보 설정 (NPC) //----------------------------------------------------------------------------------------------------------------- void SGameSystem::SetTargetInfo_Npc( SGameAvatarEx* const pTarget ) { SIMSG_UI_TARGET_INFO_NPC msg; if( pTarget ) { msg.strName = GetNpcResourceDB().GetNpcName( pTarget->GetContentID() ); msg.handle = pTarget->GetArID(); msg.pSeqForm = pTarget->GetSeqForm(); msg.nHP = pTarget->GetHP(); msg.nMP = pTarget->GetMP(); msg.nMaxHP = pTarget->GetMaxHP(); msg.nMaxMP = pTarget->GetMaxMP(); msg.nObjType = pTarget->GetObjType(); msg.nJobID = pTarget->GetJobID(); msg.nMobID = pTarget->GetContentID(); msg.strCobName = pTarget->GetCobFileName(); msg.strJobName = GetNpcResourceDB().GetNpcJobName( pTarget->GetContentID() ); } if( m_pGame ) m_pGame->ProcMsgAtStatic( &msg ); } //----------------------------------------------------------------------------------------------------------------- // 타겟 정보 설정 (몬스터) //----------------------------------------------------------------------------------------------------------------- void SGameSystem::SetTargetInfo_Mob( SGameAvatarEx* const pTarget ) { SIMSG_UI_TARGET_INFO msg; if( pTarget ) { msg.strName = GetStringDB().GetString( GetMonsterDB().GetTextID( pTarget->GetContentID() ) ); msg.handle = pTarget->GetArID(); msg.pSeqForm = pTarget->GetSeqForm(); msg.nHP = pTarget->GetHP(); msg.nMP = pTarget->GetMP(); msg.nMaxHP = pTarget->GetMaxHP(); msg.nMaxMP = pTarget->GetMaxMP(); msg.nObjType = pTarget->GetObjType(); msg.nJobID = pTarget->GetJobID(); msg.nMobID = pTarget->GetContentID(); msg.strCobName = pTarget->GetCobFileName(); msg.nLevel = GetMonsterDB().GetMobLevel( pTarget->GetContentID() ); if( !GetGameOption().IsMobFace() ) msg.pSeqForm = NULL; } if( m_pGame ) m_pGame->ProcMsgAtStatic( &msg ); } //----------------------------------------------------------------------------------------------------------------- // 타겟 정보 설정 (크리쳐) //----------------------------------------------------------------------------------------------------------------- void SGameSystem::SetTargetInfo_Summon( SGameAvatarEx* const pTarget ) { SIMSG_UI_TARGET_INFO msg; if( pTarget ) { msg.strName = pTarget->GetName(); msg.strEvolutionName = GetStringDB().GetString( GetCreatureDB().GetTextID( pTarget->GetContentID() ) ); msg.handle = pTarget->GetArID(); msg.pSeqForm = pTarget->GetSeqForm(); msg.nHP = pTarget->GetHP(); msg.nMP = pTarget->GetMP(); msg.nMaxHP = pTarget->GetMaxHP(); msg.nMaxMP = pTarget->GetMaxMP(); msg.nObjType = pTarget->GetObjType(); msg.nJobID = pTarget->GetJobID(); msg.nMobID = pTarget->GetContentID(); msg.strCobName = pTarget->GetCobFileName(); msg.nLevel = pTarget->GetLevel(); } if( m_pGame ) m_pGame->ProcMsgAtStatic( &msg ); } //----------------------------------------------------------------------------------------------------------------- // 타겟 정보 설정 (펫) //----------------------------------------------------------------------------------------------------------------- void SGameSystem::SetTargetInfo_Pet( SGameAvatarEx* const pTarget ) { SIMSG_UI_TARGET_INFO msg; if( pTarget ) { msg.strName = pTarget->GetName(); msg.strEvolutionName = GetStringDB().GetString( GetPetDB().Find( pTarget->GetInnContentID() ).getNameID() ); msg.handle = pTarget->GetArID(); msg.pSeqForm = pTarget->GetSeqForm(); msg.nHP = pTarget->GetHP(); msg.nMP = pTarget->GetMP(); msg.nMaxHP = pTarget->GetMaxHP(); msg.nMaxMP = pTarget->GetMaxMP(); msg.nObjType = pTarget->GetObjType(); msg.nJobID = pTarget->GetJobID(); msg.nMobID = pTarget->GetContentID(); msg.strCobName = pTarget->GetCobFileName(); msg.nLevel = pTarget->GetLevel(); } if( m_pGame ) m_pGame->ProcMsgAtStatic( &msg ); } //----------------------------------------------------------------------------------------------------------------- // 타겟 정보 설정 (필드 프랍) //----------------------------------------------------------------------------------------------------------------- void SGameSystem::SetTargetInfo_Field_Prop( SGameAvatarEx* const pTarget ) { SIMSG_UI_TARGET_INFO_PROP msg; if( pTarget ) { msg.strName = GetStringDB().GetString( ((SGameFieldQuestProp*)pTarget)->GetQuestPropTextID() ); msg.handle = pTarget->GetArID(); msg.pSeqForm = pTarget->GetSeqForm(); msg.nHP = pTarget->GetHP(); msg.nMP = pTarget->GetMP(); msg.nMaxHP = pTarget->GetMaxHP(); msg.nMaxMP = pTarget->GetMaxMP(); msg.nObjType = pTarget->GetObjType(); msg.nJobID = pTarget->GetJobID(); msg.nMobID = pTarget->GetContentID(); msg.strCobName = pTarget->GetCobFileName(); FieldPropResource* pFieldPropResource( GetFieldPropResourceDB().GetFieldPropResource( ((SGameFieldQuestProp*)pTarget)->GetQuestPropDBID() ) ); if( pFieldPropResource ) msg.nType = pFieldPropResource->type; } if( m_pGame ) m_pGame->ProcMsgAtStatic( &msg ); } //----------------------------------------------------------------------------------------------------------------- // 타겟 정보 설정 (스킬 프랍) //----------------------------------------------------------------------------------------------------------------- void SGameSystem::SetTargetInfo_Skill_Prop( SGameAvatarEx* const pTarget ) { SIMSG_UI_TARGET_INFO msg; if( pTarget ) { msg.handle = pTarget->GetArID(); msg.pSeqForm = pTarget->GetSeqForm(); msg.nHP = pTarget->GetHP(); msg.nMP = pTarget->GetMP(); msg.nMaxHP = pTarget->GetMaxHP(); msg.nMaxMP = pTarget->GetMaxMP(); msg.nObjType = pTarget->GetObjType(); msg.nJobID = pTarget->GetJobID(); msg.nMobID = pTarget->GetContentID(); msg.strCobName = pTarget->GetCobFileName(); } if( m_pGame ) m_pGame->ProcMsgAtStatic( &msg ); } //----------------------------------------------------------------------------------------------------------------- // 타겟 정보 설정 (아이템) //----------------------------------------------------------------------------------------------------------------- void SGameSystem::SetTargetInfo_Item( SGameAvatarEx* const pTarget ) { SIMSG_UI_TARGET_INFO msg; if( pTarget ) { msg.handle = pTarget->GetArID(); msg.pSeqForm = pTarget->GetSeqForm(); msg.nHP = pTarget->GetHP(); msg.nMP = pTarget->GetMP(); msg.nMaxHP = pTarget->GetMaxHP(); msg.nMaxMP = pTarget->GetMaxMP(); msg.nObjType = pTarget->GetObjType(); msg.nJobID = pTarget->GetJobID(); msg.nMobID = pTarget->GetContentID(); msg.strCobName = pTarget->GetCobFileName(); } if( m_pGame ) m_pGame->ProcMsgAtStatic( &msg ); } //----------------------------------------------------------------------------------------------------------------- // 타겟 설정 // 추가 설명 : 서버가 강제로 타겟 변경 지시할경우 클라이언트에서 변경만 해주면 된다 //----------------------------------------------------------------------------------------------------------------- static DWORD dwTargetLastTime = GetSafeTickCount(); void SGameSystem::SetTarget( SGameAvatarEx* pTarget, bool bChangeTargetFromSvr ) { if( NULL == m_pGame ) { SDEBUGLOG( "[GameSystem] Game Pointer is Invalid" ); assert( NULL ); return; } SIMSG_SELECT_TARGET stTargetMsg; if ( pTarget && m_pTargetMgr ) { stTargetMsg.handle = pTarget->GetArID(); m_pTargetMgr->SetTarget( pTarget ); } m_pGame->SendGameInterfaceMsg( &stTargetMsg ); if( pTarget ) { switch( pTarget->GetObjType() ) { case TS_ENTER::GAME_PLAYER: SetTargetInfo_Player( pTarget ); break; case TS_ENTER::GAME_NPC : SetTargetInfo_Npc( pTarget ); break; case TS_ENTER::GAME_MOB: SetTargetInfo_Mob( pTarget ); break; case TS_ENTER::GAME_SUMMON: SetTargetInfo_Summon( pTarget ); break; case TS_ENTER::GAME_PET: SetTargetInfo_Pet( pTarget ); break; case TS_ENTER::GAME_FIELD_PROP: SetTargetInfo_Field_Prop( pTarget ); break; case TS_ENTER::GAME_SKILL_PROP: SetTargetInfo_Skill_Prop( pTarget ); break; case TS_ENTER::GAME_ITEM: SetTargetInfo_Item( pTarget ); break; } } else { m_pGame->ProcMsgAtStatic( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_TARGET_PLAYER, false ) ); m_pGame->ProcMsgAtStatic( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_TARGET_CREATURE, false ) ); m_pGame->ProcMsgAtStatic( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_TARGET_NPC, false ) ); m_pGame->ProcMsgAtStatic( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_TARGET_PROP, false ) ); m_pGame->ProcMsgAtStatic( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_TARGET_STATE, false ) ); SIMSG_UI_TARGET_INFO msg; if( m_pGame ) m_pGame->ProcMsgAtStatic( &msg ); //gmpbigsun( 20131105 ) : 타겟제거 m_pTargetMgr->SetTarget( NULL ); } //서버에 상태 이상 리스트 요청한다. // 서버가 강제 타겟 변경 지시할 경우는 서버에서 상태이상 리스트 요청할 필요 없다 if( !bChangeTargetFromSvr ) { if( pTarget ) { if( pTarget && (pTarget->GetObjType() == TS_ENTER::GAME_PLAYER || pTarget->GetObjType() == TS_ENTER::GAME_MOB || pTarget->GetObjType() == TS_ENTER::GAME_SUMMON || pTarget->GetObjType() == TS_ENTER::GAME_PET ) ) // sonador 10.2.1 팻 시스템 구현 { if ( GetSafeTickCount() - dwTargetLastTime > 200 ) { //상태 이상 정보 요청 추가 TS_CS_TARGETING msg; msg.target = pTarget->GetArID(); m_pGame->SendMsg( &msg ); dwTargetLastTime = GetSafeTickCount(); } } } else { if ( GetSafeTickCount() - dwTargetLastTime > 200 ) { //상태 이상 정보 요청 추가 TS_CS_TARGETING msg; msg.target = NULL; m_pGame->SendMsg( &msg ); dwTargetLastTime = GetSafeTickCount(); } } } } // 2010.05.11 - prodongi /// 2012.01.05 크래쉬 의심나는 부분 수정, 타겟창의 모델만 업데이트 해준다- prodongi void SGameSystem::updateCurTarget(AR_HANDLE handle) { SGameAvatarEx* avatar = m_pTargetMgr->GetTarget(); if (avatar && avatar->GetArID() == handle) { SIMSG_UI_TARGET_PORTRAIT_REFRESH* msg = new SIMSG_UI_TARGET_PORTRAIT_REFRESH; msg->handle = avatar->GetArID(); msg->pSeqForm = avatar->GetSeqForm(); msg->nHP = avatar->GetHP(); msg->nMP = avatar->GetMP(); msg->nMaxHP = avatar->GetMaxHP(); msg->nMaxMP = avatar->GetMaxMP(); msg->nObjType = avatar->GetObjType(); msg->nJobID = avatar->GetJobID(); msg->nMobID = avatar->GetContentID(); msg->pCobName = avatar->GetCobFileName(); m_pGame->GetGameManager()->PostMsgAtDynamic(msg); } } void SGameSystem::CheckTarget( AR_HANDLE leaveID ) { if( m_pTargetMgr->CheckTarget( leaveID ) ) { SetTarget(NULL); } } SGameAvatarEx* SGameSystem::GetTarget() { return m_pTargetMgr->GetTarget(); } bool SGameSystem::IsTarget( AR_HANDLE handle ) { if( m_pTargetMgr ) return m_pTargetMgr->IsTarget( handle ); return false; } /// 2011.01.17 - prodongi bool SGameSystem::IsLocalPlayer(AR_HANDLE handle) const { if (!m_pPlayer) return false; return m_pPlayer->GetArID() == handle; } /// 2011.02.11 - prodongi bool SGameSystem::isMyGuild(int id) const { return m_GuildMgr.GetGuildID() == id; } BOOL SGameSystem::IsLocal( AR_HANDLE handle ) { if( m_vLocalHandleList.empty() ) return FALSE; for( unsigned int i(0); m_vLocalHandleList.size()>i; i++ ) { if( m_vLocalHandleList[i] == handle ) return TRUE; } return FALSE; } void SGameSystem::Process( DWORD dwTime ) { DWORD elapsedtime = dwTime - m_dwTime; m_dwTime = dwTime; GameUIMgrInstance.Process( dwTime ); m_pContentsMgr->process( dwTime ); // #2.1.2.11.1 m_activatePropUpdate.update((float)elapsedtime/1000.0f); m_arenaSystem->process((float)elapsedtime/1000.0f); //머리 이름 표시 삭제 if( GetTarget() ) { if( m_bIsShowTarget != GetTarget()->IsRender() ) { m_bIsShowTarget = GetTarget()->IsRender(); if( !m_bIsShowTarget ) m_pGame->SetUI_TargetActiveInfo( GetTarget()->GetArID(), SIMSG_UI_TARGET_ACTIVE_INFO::TARGET_HIDEWINDOW ); else m_pGame->SetUI_TargetActiveInfo( GetTarget()->GetArID(), SIMSG_UI_TARGET_ACTIVE_INFO::TARGET_SHOWWINDOW ); } } //NPC 창 닫기 처리 SGameObject * pLocal = GetLocalPlayer(); if( !m_ClickNpcList.empty() && pLocal ) { SGameAvatarEx* pNPC = (SGameAvatarEx*)m_pGame->GetGameObject( m_ClickNpcList[0] ); if( pNPC ) { //탈것 이용시 z축 값에 문제가 있어서 일단 임시 수정 2009.08.06 sfreer K3DVector local = *pLocal->GetPosition(); K3DVector npc = *pNPC->GetPosition(); local.z = 0; npc.z = 0; float len = GetDistance( local, npc ); if( len > 100.f ) { //Npc Dialog, 상점 닫아라~ m_pGame->ProcMsgAtStatic( &SMSG_TOOFAR_AS_CONTACTEDNPC() ); m_pGame->ProcMsgAtStatic( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_QUEST_REWARD, false) ); pNPC->SetNpcTargetHandle(0); m_ClickNpcList.clear(); } } else { //Npc Dialog, 상점 닫아라~ m_pGame->ProcMsgAtStatic( &SMSG_TOOFAR_AS_CONTACTEDNPC() ); m_pGame->ProcMsgAtStatic( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_QUEST_REWARD, false) ); m_ClickNpcList.clear(); } } if( !m_ClickStoreList.empty() && pLocal ) { SGameAvatarEx* pStore = (SGameAvatarEx*)m_pGame->GetGameObject( m_ClickStoreList[0] ); if( pStore ) { float len = GetDistance( *pLocal->GetPosition(), *pStore->GetPosition() ); if( len > 100.f ) { //Store Dialog, 노점 닫아라~ m_pGame->ProcMsgAtStatic( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_STORE_CLIENT, false) ); m_pGame->ProcMsgAtStatic( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_INPUTNUMBER, false ) ); m_ClickStoreList.clear(); } } else { //Store Dialog, 노점 닫아라~ m_pGame->ProcMsgAtStatic( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_STORE_CLIENT, false) ); m_pGame->ProcMsgAtStatic( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_INPUTNUMBER, false ) ); m_ClickStoreList.clear(); } } if( m_pUISyncMng ) m_pUISyncMng->ProcessUIMsg( dwTime ); //퀘스트 실시간 감시 /// 2011.09.28 dwTime 추가 - prodongi SQuestMgr::GetInstance().Process(dwTime); // if( m_pBattle_Info ) { if( m_pBattle_Info->bStartBattle == false ) { AR_TIME arCurtime = GetArTime(); if( m_pBattle_Info->arOldTime == 0 ) m_pBattle_Info->arOldTime = arCurtime; DWORD dwCountDown = ( m_pBattle_Info->arTime - BATTLE_COUNT_DOWN ) + (arCurtime - m_pBattle_Info->arOldTime); int nCount = (int)(m_pBattle_Info->arTime - dwCountDown) / 100; if( nCount > 0 ) { if( m_pBattle_Info->nOldCount != nCount ) { //962 대련시작 #@time@#초 전입니다. std::string strSysMsg = SR(1640, "#@time@#", nCount ); m_pGame->AddNoticeMessageOnly( strSysMsg.c_str() ); m_pBattle_Info->nOldCount = nCount; } } else { // 2009.02.24 1:1 대련 수정 //{ //SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pGame->GetGameObject( m_pBattle_Info->hTarget ); //if( pTarget ) // pTarget->SetActivateBattleInArena( true ); //std::string strSysMsg = S(957); //m_pGame->AddChatMessage( strSysMsg.c_str() ); //} m_pBattle_Info->bStartBattle = true; } } else { SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pGame->GetGameObject( m_pBattle_Info->hTarget ); if( pTarget ) { if( pTarget->IsActivateBattleInArena() == false ) pTarget->SetActivateBattleInArena( true ); } } } } void SGameSystem::SendLogOutMessage() { TS_CS_LOGOUT msg; m_pGame->SendMsg( &msg ); } void SGameSystem::ReturnToLobby() { TS_CS_RETURN_LOBBY msg; m_pGame->PendMessage( &msg ); m_pGame->StopProcess(); } // bool SGameSystem::ProcMsgAtStatic( struct SGameMessage * pGameMsg ) { //m_pGame->AddChatMessage("bool SGameSystem::ProcMsgAtStatic( struct SGameMessage * pGameMsg )"); //UI Sync ProcMsgAtStatic UISyncData( pGameMsg ); if( m_pContentsMgr ) m_pContentsMgr->ProcMsgAtStatic( pGameMsg ); // #2.1.2.11.1 switch( pGameMsg->nType ) { //여긴 거의 요청~ case MSG_CHATTING_REQUEST : OnMsgChattingRequest( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case MSG_ENTER_EVENTAREA : OnMsgEnterEventArea( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case MSG_LEAVE_EVENTAREA : OnMsgLeaveEventArea( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_REQ_UIDISPLAY_INFO : OnMsgReqUIDisplayInfo( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_UI_ACT_INVENTORY : OnMsgActInventory( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_UI_ACT_CREATURE : OnMsgActCreature ( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_UI_ACT_TARGET : OnMsgActTarget( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_UI_ACT_NPCDIALOG : OnMsgActNPCDialog( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_UI_ACT_LEARN_SKILL : OnMsgActLearnSkill( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_UI_ACT_JOB_LEVELUP : OnMsgActJopLevelUp( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_UI_ACT_FULLEQUIP : OnMsgActFullEquip( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_UI_ACT_USESKILL : OnMsgUseSkill( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_UI_ACT_USEITEM : OnMsgUseItem( static_cast(pGameMsg)); pGameMsg->bUse = true; break; case IMSG_UI_BOOTH : OnMsgBooth( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_UI_ACT_USECOMMAND : OnMsgUseCommand( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_UI_ACT_ITEMCOMBINE : OnMsgActItemCombine( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_UI_ACT_ITEMCONTRIBUTION : OnMsgActItemContribution( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_UI_ACT_REQUEST_REWARD : OnMsgActRequestRewardItem( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_UI_ACT_BUYITEMS_FROM_STORE : OnMsgActBuyItemsFromStore( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_UI_ACT_SELLITEMS_TO_STORE : OnMsgActSellItemsToStore( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_UI_ACT_BUYITEMS : OnMsgActBuyItems( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_UI_ACT_SELLITEMS : OnMsgActSellItems( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case TMSG_CHANGEAVATAR : OnMsgChangeAvatar( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_UI_ACT_EQUIP_SUMMON: OnMsgActEquipSummon( static_cast(pGameMsg) ); break;//pGameMsg->bUse = true; break; case IMSG_UI_ACT_SELECT_SUMMON: OnMsgActSelectSummon( static_cast(pGameMsg) ); break; case IMSG_UI_SAVE_CLIENT_INFO: OnMsgSaveClientInfo( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_UI_SAVE_QUICK_SLOT: OnMsgSaveQuickSlot( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_UI_SAVE_CURRENT_KEY: OnMsgSaveCurrentKey( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_UI_SAVE_SAVED_KEY : OnMsgSaveSavedKey( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; //added by gmpbigsun(20130419) case MSG_RQ_SUMMON : OnMsgRqSummon( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case MSG_WATCH_BOOTH : OnMsgWatchBooth( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case MSG_REQUEST_BOOTH_NAME : OnMsgRqBoothName( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_UI_SOULSTONE_CRAFT : OnMsgSoulstoneCraft( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_UI_REPAIR_SOULSTONE: OnMsgRepairSoulstone( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_REQUEST_REMOVE_STATE: OnMsgRequestRemoveState( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; case IMSG_REQ_CHANGE_ITEM_POSITION: OnMsgMsgReqChangeItemPosition( static_cast(pGameMsg) ); pGameMsg->bUse = true; break; // { [sonador][3.1.2]경매장 구현 case IMSG_REQ_AUCTION_SEARCH : OnMsgReqAuctionSearch( static_cast< SIMSG_REQ_AUCTION_SEARCH* >( pGameMsg ) ); pGameMsg->bUse = true; break; case IMSG_REQ_AUCTION_SELLING_LIST : OnMsgReqAuctionSellingList( static_cast< SIMSG_REQ_AUCTION_SELLING_LIST* >( pGameMsg ) ); pGameMsg->bUse = true; break; case IMSG_REQ_AUCTION_BIDDED_LIST : OnMsgReqAuctionBiddedList( static_cast< SIMSG_REQ_AUCTION_BIDDED_LIST* >( pGameMsg ) ); pGameMsg->bUse = true; break; case IMSG_REQ_AUCTION_BID : OnMsgReqAuctionBid( static_cast< SIMSG_REQ_AUCTION_BID* >( pGameMsg ) ); pGameMsg->bUse = true; break; case IMSG_REQ_AUCTION_INSTANT_PURCHASE : OnMsgReqAuctionInstantPurchase( static_cast< SIMSG_REQ_AUCTION_INSTANT_PURCHASE* >( pGameMsg ) ); pGameMsg->bUse = true; break; case IMSG_REQ_AUCTION_REGISTER : OnMsgReqAuctionRegister( static_cast< SIMSG_REQ_AUCTION_REGISTER* >( pGameMsg ) ); pGameMsg->bUse = true; break; case IMSG_REQ_AUCTION_CANCEL : OnMsgReqAuctionCancel( static_cast< SIMSG_REQ_AUCTION_CANCEL* >( pGameMsg ) ); pGameMsg->bUse = true; break; case IMSG_REQ_AUCTION_ITEM_KEEPING_LIST : OnMsgReqAuctionItemKeepingList( static_cast< SIMSG_REQ_AUCTION_ITEM_KEEPING_LIST* >( pGameMsg ) ); pGameMsg->bUse = true; break; case IMSG_REQ_AUCTION_ITEM_KEEPING_TAKE : OnMsgReqAuctionItemKeepingTake( static_cast< SIMSG_REQ_AUCTION_ITEM_KEEPING_TAKE* >( pGameMsg ) ); pGameMsg->bUse = true; break; //1:1 대련구현 //2009-02-05: hunee case MSG_SC_COMPETE_REQUEST : OnMsgCompeteRequest( static_cast< SMSG_SC_COMPETE_REQUEST* >( pGameMsg ) ); pGameMsg->bUse = true; break; case MSG_SC_COMPETE_ANSWER : OnMsgCompeteAnswer( static_cast< SMSG_SC_COMPETE_ANSWER* >( pGameMsg ) ); pGameMsg->bUse = true; break; case MSG_SC_COMPETE_COUNTDOWN : OnMsgCompeteCountdown( static_cast< SMSG_SC_COMPETE_COUNTDOWN* >( pGameMsg ) ); pGameMsg->bUse = true; break; case MSG_SC_COMPETE_START : OnMsgCompeteStart( static_cast< SMSG_SC_COMPETE_START* >( pGameMsg ) ); pGameMsg->bUse = true; break; case MSG_SC_COMPETE_END : { // 대련 상태가 아닐 때, 멀어져서 대련신청이 최소 할 때를 위해서, kappamind. if( !GetPVPStart() ) { SMSG_SC_COMPETE_COUNTDOWN* pMsg = static_cast< SMSG_SC_COMPETE_COUNTDOWN* >( pGameMsg ); m_pBattle_End_Info = new SGameSystem::Battle_Info; m_pBattle_End_Info->hTarget = pMsg->handle_competitor; } OnMsgCompeteEnd( static_cast< SMSG_SC_COMPETE_END* >( pGameMsg ) ); pGameMsg->bUse = true; break; } // } case IMSG_REQ_ARRANGE_ITEM: OnMsgReqArrangeItem( static_cast< SIMSG_REQ_ARRANGE_ITEM* >( pGameMsg ) ); pGameMsg->bUse = true; break; // sonador 1.9.1 인벤토리 및 창고 정렬 기능 구현 case MSG_CHANGE_NAME : { SMSG_CHANGE_NAME * pChangeName = static_cast< SMSG_CHANGE_NAME* >( pGameMsg ); //자신것 변경 if( GetLocalPlayer() && GetLocalPlayer()->GetArID() == pChangeName->handle ) { pChangeName->IsLocal = true; m_PlayerInfoMgr.SetName( pChangeName->m_name.c_str() ); } //타겟창 if( m_PlayerInfoMgr.GetTarget() == pChangeName->handle ) { SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pGame->GetGameObject( pChangeName->handle ); if( pTarget ) m_PlayerInfoMgr.SetTarget( pChangeName->handle, pChangeName->m_name.c_str(), pTarget->GetObjType() ); else m_PlayerInfoMgr.SetTarget( pChangeName->handle, pChangeName->m_name.c_str(), TS_ENTER::GAME_OBJTYPE_MAX ); } { //파티 SPlayerSlot * pPlayer = m_PartyMgr.FindMember( pChangeName->handle ); if( pPlayer ) { pPlayer->SetName( pChangeName->m_name.c_str() ); //리더 이름 변경 if( pPlayer->IsLeader() ) m_PartyMgr.ChangeLeader( pChangeName->m_name.c_str() ); } } { //길드 SPlayerSlot * pPlayer = m_GuildMgr.FindMember( pChangeName->handle ); if( pPlayer ) { pPlayer->SetName( pChangeName->m_name.c_str() ); //리더 이름 변경 if( pPlayer->IsLeader() ) m_GuildMgr.ChangeLeader( pChangeName->m_name.c_str() ); } } { if( m_CreatureSlotMgr.IsEquipedCreature(pChangeName->handle) ) m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_CREATURE_NAME_CHANGE, 0, 0, pChangeName->m_name.c_str() ) ); } } break; case MSG_BOOTH_INFO : { //노점 클릭 AR_HANDLE hTarget = static_cast< SMSG_BOOTH_INFO* >( pGameMsg )->hTarget; if( GetLocalPlayer() && hTarget != GetLocalPlayer()->GetArID() ) { AddClickStore( hTarget ); } } break; case MSG_ENTER : { SMSG_ENTER* pEnterMsg = static_cast(pGameMsg); //플레이어일 경우 길드 정보 요청 if( pEnterMsg->type == TS_ENTER::PLAYER ) { SMSG_ENTER::PlayerInfo * pPlayerInfo = (SMSG_ENTER::PlayerInfo *)(pEnterMsg+1); if( pPlayerInfo->guild_id != 0 && IsExistGuildInfo( pPlayerInfo->guild_id ) == false ) Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/gicon %d", pPlayerInfo->guild_id ).c_str() ); } } break; //Enter (Other Player) case MSG_REQ_GUILD_ICON : { SMSG_REQ_GUILD_ICON* pReqGuildData = static_cast< SMSG_REQ_GUILD_ICON* >( pGameMsg ); if( IsExistGuildInfo( pReqGuildData->nGuild_id ) ) { //기존것 갱신 하라함 SendGuildData( pReqGuildData->nGuild_id ); } pGameMsg->bUse = true; } break; case MSG_SEND_DATA : { SMSG_SEND_DATA *pMsg = static_cast< SMSG_SEND_DATA * >( pGameMsg ); if( pMsg->strMessage == "drop_quest" ) { TS_CS_DROP_QUEST msg; msg.code = pMsg->nNumber; if( m_pGame ) m_pGame->SendMsg( &msg ); break; } else if( pMsg->strMessage == "req_summon_formation" ) { TS_CS_GET_SUMMON_SETUP_INFO msg; msg.show_dialog = !m_pGame->IsUIWindowOpened( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_CREATUREFORM ); if( m_pGame ) m_pGame->SendMsg( &msg ); break; } else if( pMsg->strMessage == "close_item_shop" || pMsg->strMessage == "close_guild_web" || pMsg->strMessage == "close_help_web" || pMsg->strMessage == "close_popurl_web" || pMsg->strMessage == "web_close" ) { if( GetLocalPlayer() && GetLocalPlayer()->IsDead() ) { //여기서 왜 죽는 처리를 또 하는지 모르겠지만, 일단 기존에 있떤 코드니 데스매치 존 예외처리만 함. //sfreer 2009.12.18 /*int x = GetLocalPlayer()->GetPosition()->x; int y = GetLocalPlayer()->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) ) // 데스매치 { } else*/ if(!GetLocalPlayer()->IsInDeathMatch()) { //Local Player Dead 처리 m_pGame->SendGameMsg( &SMSG_SEND_DATA( "close_all_message_box" ) ); int stringid = 809; if( m_pGame->GetCurrentLocation() == 2/*PLAYER_INSIDE_DUNGEON_SIEGE*/ || m_pGame->GetCurrentLocation() == 3/*PLAYER_INSIDE_DUNGEON_RAID*/ ) { stringid = 822; } SIMSG_REQ_OPEN_MSGBOX msg( SIMSG_REQ_OPEN_MSGBOX::MSGBOX_DEAD, S(stringid), false ); msg.m_bIsPlayer = true; m_pGame->SendGameMsg( &msg ); } } break; } else if( pMsg->strMessage == "contribution_update" ) { UpdateContributionPropData(); } else if( pMsg->strMessage == "contribution_prop_clear" ) { m_pQuestProp = NULL; } else if( pMsg->strMessage == "battle_start" ) { //std::string strTex = "/battle_accept "; //strTex += pMsg->strData; //Rq_Chatting( CHAT_NORMAL, NULL, strTex.c_str() ); SetPVPAcceptCheck( true ); TS_CS_COMPETE_ANSWER msg; msg.compete_type = COMPETE_TYPE_VS_PLAYER; msg.answer_type = COMPETE_ANSWER_TYPE_ACCEPT; if( m_pGame ) m_pGame->SendMsg( &msg ); } else if( pMsg->strMessage == "battle_reject" ) // sonador 1.10.1 모럴 포인트 증/감 메시지 및 대련장 관련 메시지 추가 { //std::string strTex = "/battle_reject "; //strTex += pMsg->strData; //Rq_Chatting( CHAT_NORMAL, NULL, strTex.c_str() ); m_bIsShowBattleAccept = false; SetPVPAcceptCheck( false ); TS_CS_COMPETE_ANSWER msg; msg.compete_type = COMPETE_TYPE_VS_PLAYER; msg.answer_type = COMPETE_ANSWER_TYPE_REJECT_BY_USER; m_pGame->AddChatMessage( S(1651) ); if( m_pGame ) m_pGame->SendMsg( &msg ); } else if( pMsg->strMessage == "Alliance_Accept" ) { std::string strTex = "/gajoin "; strTex += m_strAllianceId; strTex += " "; strTex += m_strPassword; Rq_Chatting( CHAT_NORMAL, NULL, strTex.c_str() ); } else if( pMsg->strMessage == "Ranking_Top_Record") { TS_CS_RANKING_TOP_RECORD msg; msg.ranking_type = RANKING_TYPE_DONATION; if( m_pGame ) m_pGame->SendMsg( &msg ); } } break; case IMSG_RESURRECTION: { SMSG_RESURRECTION* pResurrection = static_cast(pGameMsg); TS_CS_RESURRECTION msg; msg.handle = 0; /** 1:1 대련 추가 * 2009-01-29 : hunee */ //msg.use_potion = false; //msg.use_state = false; if( pResurrection->bDeathmatch ) { msg.type = TS_CS_RESURRECTION::RESURRECT_TYPE_BY_DEATHMATCH; } else if( pResurrection->hOwner ) //버퍼로 부활 { msg.handle = pResurrection->hOwner; //msg.use_state = true; msg.type = TS_CS_RESURRECTION::RESURRECT_TYPE_BY_STATE; } else if( pResurrection->nUseItem > 0 ) //아이템으로 부활 { //msg.use_potion = true; msg.type = TS_CS_RESURRECTION::RESURRECT_TYPE_BY_POTION; } else if (pResurrection->bCompete) //대련 부활 { msg.type = TS_CS_RESURRECTION::RESURRECT_TYPE_BY_COMPETE; } else //마을에서 부활 { msg.type = TS_CS_RESURRECTION::RESURRECT_TYPE_NORMAL; } if( m_pGame ) m_pGame->SendMsg( &msg ); SetDeathPVP( false ); /* else if( pMsg->strMessage == "resurrection" ) { TS_CS_RESURRECTION msg; if( pMsg->nNumber <= 0 ) //기본 부활 msg.use_potion = false; else if( pMsg->nNumber > 0 ) //아이템 사용으로 부활 msg.use_potion = true; if( m_pGame ) m_pGame->SendMsg( &msg ); break; } else if( pMsg->strMessage == "resurrection_by_state" ) { TS_CS_RESURRECTION msg; msg.use_potion = false; msg.use_state = false; if( pMsg->nNumber > 0 ) //지속 효과로 부활 { msg.handle = pMsg->nNumber; msg.use_state = true; } if( m_pGame ) m_pGame->SendMsg( &msg ); break; }*/ } break; case MSG_CS_COMPETE_REQUEST: { SMSG_CS_COMPETE_REQUEST* pCompete = static_cast(pGameMsg); TS_CS_COMPETE_REQUEST msg; msg.compete_type = pCompete->compete_type; strcpy(msg.requestee, pCompete->requestee); if( m_pGame ) m_pGame->SendMsg( &msg ); } break; /*case MSG_CS_COMPETE_ANSWER: { SMSG_CS_COMPETE_ANSWER* pCompete = static_cast(pGameMsg); TS_CS_COMPETE_ANSWER msg; msg.compete_type = pCompete->compete_type; msg.answer_type = pCompete->answer_type; if( m_pGame ) m_pGame->SendMsg( &msg ); } break;*/ case IMSG_UI_REQ_RETURN_LOBBY: { //캐릭터 선택 로비로 돌아가기 ReturnToLobby(); pGameMsg->bUse = true; } break; case IMSG_INSTANCE_GAME_ENTER : { SMSG_INSTANCE_GAME_ENTER* pEntermsg = static_cast(pGameMsg); TS_CS_INSTANCE_GAME_ENTER msg; msg.instance_game_type = pEntermsg->instance_game_type; if( m_pGame ) m_pGame->SendMsg( &msg ); } break; case IMSG_INSTANCE_GAME_EXIT : { TS_CS_INSTANCE_GAME_EXIT msg; if( m_pGame ) m_pGame->SendMsg( &msg ); } break; case MSG_INSTANCE_GAME_SCORE_REQUEST : { TS_CS_INSTANCE_GAME_SCORE_REQUEST msg; if( m_pGame ) m_pGame->SendMsg( &msg ); } break; case MSG_QUEST_INFO_REQUEST: { TS_CS_QUEST_INFO msg; SIMSG_QUEST_INFO_REQUEST* pMsg = static_cast( pGameMsg ); msg.code = pMsg->nQuestCode; if( m_pGame ) m_pGame->SendMsg( &msg ); } break; case IMSG_UI_MINIMAP_ROTATE: { SIMSG_UI_MINIMAP_ROTATE* pMsg = static_cast( pGameMsg ); SGameAvatarEx * pObject = (SGameAvatarEx*)m_pGame->GetGameObject( pMsg->m_hPlayer ); if( pObject ) { K3DVector viewVec = ( pMsg->m_vecPlayerPos - pObject->GetViewVector() ); viewVec.z = 0.f; float fLen = viewVec.Magnitude(); float fDX = fabsf(viewVec.x); float fDY = fabsf(viewVec.y); pMsg->m_fRadian = ( fDX > fDY ) ? acosf( fDX / fLen ) : asinf( fDY / fLen ); if( fLen == 0.f ) return 0.f; if( viewVec.x >= 0.f ) pMsg->m_fRadian = (viewVec.y >= 0.f) ? pMsg->m_fRadian : ((2.f * K3D_PI) - pMsg->m_fRadian); else pMsg->m_fRadian = (viewVec.y >= 0.f) ? (K3D_PI - pMsg->m_fRadian) : (K3D_PI + pMsg->m_fRadian); } } break; case IMSG_UI_2DPOS_INFO : { if( GetTarget() ) { SIMSG_UI_2DPOS_INFO* pMsg = static_cast(pGameMsg); if( pMsg->handle == GetTarget()->GetArID() && pMsg->bNotClip == true ) { //시야에 보이는 경우만, 강제로 켠다. pMsg->bVisible = true; pMsg->fAlpha = 1.0f; } } } break; case TMSG_REQ_CLOSE : OnMsgReqClose( static_cast(pGameMsg) ); break; // buse 안킨다. //이건 거의 응답~ case MSG_NPC_DIALOG : OnMsgNPCDialog ( static_cast(pGameMsg) ); break; case MSG_MARKET : OnMsgMarket ( static_cast(pGameMsg) ); break; case MSG_RESULT : OnMsgResult ( static_cast(pGameMsg) ); break; case MSG_LOGIN : OnMsgLogin ( static_cast(pGameMsg) ); break; case MSG_LEAVE : OnMsgLeave ( static_cast(pGameMsg) ); break; case MSG_ATTACK : OnMsgAttack ( static_cast(pGameMsg) ); break; case MSG_ATTACK_DOUBLE : OnMsgAttackDouble ( static_cast(pGameMsg) ); break; case MSG_SKILL_EVENT : OnMsgSkillEvent( static_cast(pGameMsg) ); break; //Skill // case MSG_SKILL_CASTING_TIME : OnMsgSkillCastingTime( static_cast(pGameMsg) ); break; //Skill Casting Time case MSG_SKILL_LIST : OnSkillList ( static_cast(pGameMsg) ); break; case MSG_ADDED_SKILL_LIST : OnAddedSkillList ( static_cast(pGameMsg) ); break; case MSG_SKILLCARD_INFO : OnSkillCardInfo( static_cast(pGameMsg) ); break; case MSG_MOUNT_SUMMON : OnMsgMount ( static_cast(pGameMsg) ); break; case MSG_UNMOUNT_SUMMON : OnMsgUnMount ( static_cast(pGameMsg) ); break; case MSG_STAT_INFO : OnStatInfo ( static_cast(pGameMsg) ); break; case MSG_GOLD_UPDATE : OnGoldUpdate ( static_cast(pGameMsg) ); break; case MSG_ADD_SUMMON_INFO : OnMsgAddSummonInfo ( static_cast(pGameMsg) ); break; case MSG_REMOVE_SUMMON_INFO : OnMsgRemoveSummonInfo ( static_cast(pGameMsg) ); break; case MSG_EQUIP_SUMMON : OnMsgEquipSummon ( static_cast(pGameMsg) ); break; case IMSG_UI_CHANGE_SUMMON_NAME : OnMsgSummonNameChange ( static_cast(pGameMsg) ); break; // sonador 10.2.1 팻 시스템 구현 case MSG_ADD_PET_INFO : OnMsgAddPetInfo ( static_cast< SMSG_ADD_PET_INFO* >( pGameMsg ) ); break; case MSG_REMOVE_PET_INFO : OnMsgRemovePetInfo( static_cast< SMSG_REMOVE_PET_INFO* >( pGameMsg ) ); break; case IMSG_REQ_SET_PET_NAME : OnMsgReqSetPetName( static_cast< SIMSG_REQ_SET_PET_NAME* >( pGameMsg ) ); pGameMsg->bUse = true; break; case MSG_ITEM_TAKE_RESULT : OnMsgTakeResult( static_cast(pGameMsg) ); break; //인벤에 넣기 case MSG_ITEM_DROP_RESULT : OnMsgDropResult( static_cast(pGameMsg) ); break; //인벤에서 삭제 case MSG_ITEM_DESTROY : OnMsgItemDestroy ( static_cast(pGameMsg) ); break; //Item Destroy //아이템 삭제 case MSG_ITEM_ERASE : //pGameMsg->bUse = true; OnMsgItemErase( static_cast(pGameMsg) ); break; // 아이템파괴. case MSG_UPDATE_ITEM_COUNT : OnMsgUpdateItemCount( static_cast(pGameMsg) ); break; //Item Count Update //아이템정보 변경 case MSG_MIX_RESULT : break; //Mix Result case MSG_ITEM_WEAR : OnMsgItemWear ( static_cast(pGameMsg) ); break; //아이템 변경 case MSG_ITEM_WEAR_INFO : OnMsgItemWearInfo( static_cast(pGameMsg) ); break; //아이템 장착 위치 변경 case MSG_ITEM_INVEN : OnMsgInventory ( static_cast(pGameMsg) ); break; //인벤 정보 case MSG_ITEM_COOL_TIME : OnMsgItemcooltime( static_cast(pGameMsg) ); break; //아이템 그룹 쿨 타임정보 case MSG_CHATTING : OnMsgChatting ( static_cast(pGameMsg) ); break; //채팅 case MSG_TRADE : OnMsgTrade ( static_cast(pGameMsg) ); break; //Trade case MSG_BELT_SLOT_INFO : OnMsgBeltSlotInfo( static_cast(pGameMsg) ); break; //BeltSlotInfo case MSG_QUEST_UPDATA : OnMsgQuestUpdata( static_cast(pGameMsg) ); break; case MSG_END_QUEST : OnMsgEndQuest( static_cast(pGameMsg) ); break; // 2011.07.12 - servantes case MSG_TITLE_LIST: case MSG_TITLE_CONDITION_LIST: case MSG_TITLE_REAMIN_TIME: case MSG_TITLE_SET_MAIN_TITLE: case MSG_TITLE_SET_SUB_TITLE: case MSG_TITLE_BOOKMARK: case MSG_TITLE_ACHIEVE: case MSG_TITILE_OPEN: case MSG_TITLE_CHANGE_CONDITION: OnMsgTitle( pGameMsg ); break; // 2012. 4. 20 - marine // storage case MSG_OPEN_STORAGE : OnMsgOpenStorage ( static_cast(pGameMsg) ); break; case MSG_CHANGE_STORAGE : OnMsgChangeStorage( static_cast(pGameMsg) ); break; case MSG_REGEN_HPMP : OnMsgRegenHPMP( static_cast(pGameMsg) ); break; case MSG_TARGET : OnMsgTarget( static_cast(pGameMsg) ); break; case MSG_PROPERTY: OnMsgProperty( static_cast(pGameMsg) ); break; case MSG_LEVEL_UPDATE: OnMsgLevelUpdate( static_cast(pGameMsg) ); break; case IMSG_UI_TARGET_STAT: OnMsgTargetStat( static_cast(pGameMsg) ); break; case MSG_HPMP: OnMsgHPMP( static_cast(pGameMsg) ); break; case MSG_SP: OnMsgSP( static_cast(pGameMsg) ); break; case MSG_EXP_UPDATE: OnMsgExpUpdate( static_cast(pGameMsg) ); break; case IMSG_UI_TARGET_INFO: OnMsgTargetInfo( static_cast(pGameMsg) ); break; case MSG_STATE: OnMsgState( static_cast(pGameMsg) ); break; case MSG_STATUS_CHANGE: OnMsgStatusChange( static_cast(pGameMsg) ); break; case MSG_STATE_RESULT: OnMsgStateResult( static_cast(pGameMsg) ); break; case IMSG_UI_NPC_SEQFORM_INFO: { SIMSG_UI_NPC_SEQFORM_INFO* pMsg = static_cast(pGameMsg); if( pMsg->hTarget != NULL ) { SGameAvatarEx * pTarget = (SGameAvatarEx *)m_pGame->GetGameObject(pMsg->hTarget); if( pTarget != NULL ) { pMsg->pCobName = pTarget->GetCobFileName(); pMsg->pSeqForm = pTarget->GetSeqForm(); pMsg->nObjectType = pTarget->GetObjType(); pMsg->nContentID = pTarget->GetContentID(); } } } break; case IMSG_UI_CREATURE_SEQFORM_INFO: //servantes 2011.01.24 { SIMSG_UI_CREATURE_SEQFORM_INFO* pMsg = static_cast(pGameMsg); if( pMsg->hTarget != NULL ) { SGameAvatarEx * pTarget = (SGameAvatarEx *)m_pGame->GetGameObject(pMsg->hTarget); if( pTarget != NULL ) { pMsg->pCobName = pTarget->GetCobFileName(); pMsg->pSeqForm = pTarget->GetSeqForm(); pMsg->nObjectType = pTarget->GetObjType(); pMsg->nContentID = pTarget->GetContentID(); } } } break; //case IMSG_SHOW_UIWINDOW: // { // SIMSG_SHOW_UIWINDOW* pUiMsg = static_cast(pGameMsg); // if( /*pUiMsg->m_Type == SIMSG_TOGGLE_UIWINDOW::UIWINDOW_NPCDIALOG ||*/ // pUiMsg->m_Type == SIMSG_TOGGLE_UIWINDOW::UIWINDOW_QUEST_REWARD ) // { // if( pUiMsg->m_bShow == false ) // { // SetTarget( NULL ); // } // } // } // break; //case IMSG_TOGGLE_UIWINDOW: // { // int x = 0; // x = 1; // } // break; case MSG_AURA: { SMSG_AURA* pAuraMsg = static_cast(pGameMsg); if( IsLocal( pAuraMsg->caster ) ) { pAuraMsg->data_owner = SMSG_AURA::OWNER_LOCAL_PLAYER; } else if( IsLocalCreature( pAuraMsg->caster ) ) { pAuraMsg->data_owner = SMSG_AURA::OWNER_LOCAL_CREATURE; } } break; case MSG_CHAT_COMMAND: { SMSG_CHAT_COMMAND* pUiMsg = static_cast(pGameMsg); if( pUiMsg->nMode == SMSG_CHAT_COMMAND::CHAT_CASHSTORAGE_OPEN ) { Rq_Chatting( CHAT_NORMAL, NULL, "/cstorage" ); } else if( pUiMsg->nMode == SMSG_CHAT_COMMAND::CHAT_CASHSHOP_OPEN ) { Rq_Chatting( CHAT_NORMAL, NULL, "/cshop" ); } } break; case MSG_PARTY_COMMAND: { SMSG_PARTY_COMMAND* pUiMsg = static_cast(pGameMsg); pGameMsg->bUse = true; if( pUiMsg->mode == SMSG_PARTY_COMMAND::PARTY_INVITE || pUiMsg->mode == SMSG_PARTY_COMMAND::PARTY_KICK || pUiMsg->mode == SMSG_PARTY_COMMAND::PARTY_DESTROY || pUiMsg->mode == SMSG_PARTY_COMMAND::PARTY_TRANSFER || pUiMsg->mode == SMSG_PARTY_COMMAND::PARTY_OPTION ) { if( !m_PartyMgr.IsLeader() ) { m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_DONUSE_PARTY_COMMAND ) ); break; } } SGameAvatarEx * pAvatar = GetTarget(); if( pUiMsg->mode == SMSG_PARTY_COMMAND::PARTY_CREATE ) { Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/pcreate %s", pUiMsg->strName.c_str() ).c_str() ); } else if( pUiMsg->mode == SMSG_PARTY_COMMAND::PARTY_INVITE ) { char const* token; if (g_pCurrentGameSystem->isArenaExercise()) token = "/bp_minvite"; else token = "/pinvite"; char const* targetName; if( pAvatar && pAvatar->GetObjType() == TS_ENTER::GAME_PLAYER ) targetName = pAvatar->GetName(); else targetName = pUiMsg->strName.c_str(); Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "%s %s", token, targetName).c_str()); } else if(pUiMsg->mode == SMSG_PARTY_COMMAND::PARTY_KICK ) { char const* token; if (g_pCurrentGameSystem->isArenaExercise()) token = "/bp_mkick"; else token = "/pkick"; char const* targetName; if( pAvatar && pAvatar->GetObjType() == TS_ENTER::GAME_PLAYER ) targetName = pAvatar->GetName(); else targetName = pUiMsg->strName.c_str(); Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "%s %s", token, targetName).c_str()); } else if(pUiMsg->mode == SMSG_PARTY_COMMAND::PARTY_DESTROY ) { Rq_Chatting( CHAT_NORMAL, NULL, "/pdestroy" ); } else if(pUiMsg->mode == SMSG_PARTY_COMMAND::PARTY_TRANSFER ) // 권한 인계 : 파티장 : 2011.11.01 - servantes 주석추가 { if( pAvatar && pAvatar->GetObjType() == TS_ENTER::GAME_PLAYER ) Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/ppromote %s", pAvatar->GetName() ).c_str() ); else Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/ppromote %s", pUiMsg->strName.c_str() ).c_str() ); } else if(pUiMsg->mode == SMSG_PARTY_COMMAND::PARTY_OPTION ) { Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/pshare %s", pUiMsg->strName.c_str() ).c_str() ); } else if(pUiMsg->mode == SMSG_PARTY_COMMAND::PARTY_LEAVE ) { Rq_Chatting( CHAT_NORMAL, NULL, "/pleave" ); } } break; case MSG_FRIEND_COMMAND: { SMSG_FRIEND_COMMAND* pUiMsg = static_cast(pGameMsg); if( pUiMsg->strName.empty() ) { SGameAvatarEx* pPlayer = (SGameAvatarEx *)m_pGame->GetGameObject(pUiMsg->target); if( pPlayer ) { pUiMsg->strName = pPlayer->GetName(); } } if( pUiMsg->mode == SMSG_FRIEND_COMMAND::FRIEND_ADD ) { Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/add_friend %s", pUiMsg->strName.c_str() ).c_str() ); } else if( pUiMsg->mode == SMSG_FRIEND_COMMAND::FRIEND_DELETE ) { Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/del_friend %s", pUiMsg->strName.c_str() ).c_str() ); /*if( pAvatar && pAvatar->GetObjType() == TS_ENTER::GAME_PLAYER ) Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/친구삭제 %s", pAvatar->GetName() ).c_str() ); else Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/파티초대 %s", pUiMsg->strName.c_str() ).c_str() );*/ } else if( pUiMsg->mode == SMSG_FRIEND_COMMAND::CUT_ADD ) { Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/add_denial %s", pUiMsg->strName.c_str() ).c_str() ); } else if( pUiMsg->mode == SMSG_FRIEND_COMMAND::CUT_DELETE ) { Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/del_denial %s", pUiMsg->strName.c_str() ).c_str() ); } } break; case MSG_ALLIANCE_COMMAND: { SMSG_FRIEND_COMMAND* pUiMsg = static_cast(pGameMsg); if( pUiMsg->mode == SMSG_ALLIANCE_COMMAND::ALLIANCE_ADD ) { // Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/친구추가 %s", pUiMsg->strName.c_str() ).c_str() ); } } break; case MSG_TAKEOUT_COMMERCIAL_ITEM: { SMSG_TAKEOUT_COMMERCIAL_ITEM* pTakeOutItemInfo = static_cast(pGameMsg); TS_CS_TAKEOUT_COMMERCIAL_ITEM msg; msg.commercial_item_uid = pTakeOutItemInfo->commercial_item_uid; msg.count = pTakeOutItemInfo->count; //캐쉬 아이템 꺼내기 요청 m_pGame->SendMsg( &msg ); pGameMsg->bUse = true; } break; case MSG_COMMERCIAL_STORAGE_LIST: { //캐쉬템 저장 OnCommercialStorage( static_cast(pGameMsg) ); //창고 열자 m_pGame->SendGameInterfaceMsg( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_CASH_STORAGE, true) ); //인벤토리에 캐쉬템 저장을 알림. //m_pGame->SendGameInterfaceMsg( MSG_COMMERCIAL_STORAGE_LIST ); // 인벤토리에 캐쉬템 업데이트를 알림. m_pGame->SendGameInterfaceMsg( &SIMSG_UPDATE_CASHITEM( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_INVENTORY ) ); } break; case MSG_COMMERCIAL_STORAGE_INFO: { SMSG_COMMERCIAL_STORAGE_INFO* pStorageInfo = static_cast(pGameMsg); if( pStorageInfo->new_item_count > 0 ) { m_pGame->AddChatMessage( SR(6396, "#@item_count@#", pStorageInfo->new_item_count ).c_str() ); } //if( pStorageInfo->total_item_count > 0 ) //{ 제거 요청 들어와서 삭제됨. // m_pGame->AddChatMessage( SR(6397, "#@item_count@#", pStorageInfo->total_item_count ).c_str() ); //} if( m_pGame->IsUIWindowOpened( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_CASH_STORAGE ) ) { //캐쉬 창고 열려 있으면, 갱신 요청 //캐쉬 창고 갱신 요청 Rq_Chatting( CHAT_NORMAL, NULL, "/cstorage" ); } // 인벤토리에 캐쉬템 업데이트를 알림. if( pStorageInfo->total_item_count > 0 || pStorageInfo->new_item_count ) m_pGame->SendGameInterfaceMsg( &SIMSG_UPDATE_CASHITEM( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_INVENTORY ) ); } break; case IMSG_UI_ACT_USESKILL_BY_TOGGLE: { SIMSG_UI_ACT_USESKILL_BY_TOGGLE* pUseSkill = static_cast(pGameMsg); if( OnMsgUseSkill_by_toggle( pUseSkill ) ) pUseSkill->bSucceed = true; pGameMsg->bUse = true; } break; case MSG_SECURITY_NO: { SMSG_SECURITY_NO* pSecurityMsg = static_cast(pGameMsg); TS_CS_SECURITY_NO msg; msg.mode = pSecurityMsg->mode; ::strncpy( msg.security_no, pSecurityMsg->security_no, 18 ); if( m_pGame ) m_pGame->SendMsg( &msg ); pGameMsg->bUse = true; } break; // 2009.02.24 대련 수정 // case MSG_WHISPER_ADDONWND: // { // SMSG_WHISPER_ADDONWND* pUiMsg = static_cast(pGameMsg); // // SGameAvatarEx* pPlayer = (SGameAvatarEx *)m_pGame->GetGameObject(pUiMsg->target); // if( pPlayer ) // { // //Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/battle_invite %s", pPlayer->GetName() ).c_str() ); // m_pGame->SendGameInterfaceMsg( &SIMSG_UI_WHISPER( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_CHATTING, pPlayer->GetName() ) ); // } // // pGameMsg->bUse = true; // } // break; case MSG_COMMAND_BY_ADDONWND: { SMSG_COMMAND_BY_ADDONWND* pUiMsg = static_cast(pGameMsg); SGameAvatarEx* pPlayer = (SGameAvatarEx *)m_pGame->GetGameObject(pUiMsg->target); if( pPlayer ) { switch( pUiMsg->command_type ) { case SMSG_COMMAND_BY_ADDONWND::COMMAND_CHALLENGE: { Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/battle_invite %s", pPlayer->GetName() ).c_str() ); } break; case SMSG_COMMAND_BY_ADDONWND::COMMAND_WHISPER: { m_pGame->SendGameInterfaceMsg( &SIMSG_UI_WHISPER( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_CHATTING, pPlayer->GetName() ) ); } } } pGameMsg->bUse = true; } break; case MSG_GAME_OUT: { SMSG_GAME_OUT* pGameOut = static_cast(pGameMsg); pGameMsg->bUse = true; SGameAvatarEx* pLocalPlayer = GetLocalPlayer(); if( pLocalPlayer ) { // sonador 1.8.2 접속종료시 아바타 이동 정지 if( m_pGame ) { ArPosition arPos; arPos.x = pLocalPlayer->GetPosition()->x; arPos.y = pLocalPlayer->GetPosition()->y; m_pGame->ReqMove( pLocalPlayer->GetArID(), arPos, &arPos, 1, false ); } //웹페이지 창이 떠 있을시 "게임종료" 창이 나타나는 문제 수정 //2009-03-17: hunee // 2010.08.23 웹페이지가 떠 있을 경우에는 메세지 박스 출력 안되도록 수정 - prodongi if (!m_pGame->IsWebPageWndOpened()) { if (pGameOut->character_select) { TS_CS_REQUEST_RETURN_LOBBY msg; if( m_pGame ) m_pGame->SendMsg( &msg ); } else { TS_CS_REQUEST_LOGOUT msg; if( m_pGame ) m_pGame->SendMsg( &msg ); } } /*if( m_pGame->IsWebPageWndOpened() == false && pGameOut->character_select ) { TS_CS_REQUEST_RETURN_LOBBY msg; if( m_pGame ) m_pGame->SendMsg( &msg ); } else { TS_CS_REQUEST_LOGOUT msg; if( m_pGame ) m_pGame->SendMsg( &msg ); }*/ } } break; //------------------------------------------ // 2010.04.21 bintitle. // 길드 guild case MSG_GUILD_COMMAND: { SMSG_GUILD_COMMAND* pUiMsg = static_cast(pGameMsg); pGameMsg->bUse = true; switch( pUiMsg->nMode ) { // 공격대정보 요청. case SMSG_GUILD_COMMAND::GUILD_RAID : Rq_Chatting( CHAT_NORMAL, NULL, "/graidsiegetip" ); break; // 길드 해산. case SMSG_GUILD_COMMAND::GUILD_DESTROY : Rq_Chatting( CHAT_NORMAL, NULL, "/gdestroy" ); break; // 길드장 인계. case SMSG_GUILD_COMMAND::GUILD_PROMOTE : Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/gpromote %s", pUiMsg->strMemo.c_str() ).c_str() ); // GLEADER_CHANGE 회신 받는다 //2011.06.29 - servantes break; // 길드 초대. case SMSG_GUILD_COMMAND::GUILD_INVITATION : Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/ginvite %s", pUiMsg->strMemo.c_str() ).c_str() ); break; // 길드 공지 변경. case SMSG_GUILD_COMMAND::GUILD_NOTICE : Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/gnotice %s", pUiMsg->strMemo.c_str() ).c_str() ); // 공지. Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/gurl %s", pUiMsg->strName.c_str() ).c_str() ); // URL. break; // 길드원 메모변경. case SMSG_GUILD_COMMAND::GUILD_MEMBER_MEMO : Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/gmemo %s %s", pUiMsg->strName.c_str(), pUiMsg->strMemo.c_str() ).c_str() ); break; // 길드원 권한변경. case SMSG_GUILD_COMMAND::GUILD_AUTHORITY : Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/gpermission %s %d", pUiMsg->strName.c_str(), pUiMsg->nClass ).c_str() ); break; // 길드 등급명. case SMSG_GUILD_COMMAND::GUILD_AUTHORITY_CLASS_NAME : Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/gpermissionname %d %s", pUiMsg->nClass, pUiMsg->strName.c_str() ).c_str() ); break; // 길드권한등급 비트플래그(권한세트). case SMSG_GUILD_COMMAND::GUILD_AUTHORITY_SET : Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/gpermissionset %d %d", pUiMsg->nClass, pUiMsg->nClassBitSet ).c_str() ); break; case SMSG_GUILD_COMMAND::GUILD_BUFF : Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/gbuff %s", pUiMsg->strMemo.c_str() ).c_str() ); break; case SMSG_GUILD_COMMAND::GUILD_DONATE : Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/gdonate %s", pUiMsg->strMemo.c_str() ).c_str() ); break; case SMSG_GUILD_COMMAND::GUILD_UPGRADE : Rq_Chatting( CHAT_NORMAL, NULL, "/gupgrade" ); break; } } break; /// 2011.05.12 - prodongi case IMSG_UI_SUMMON_CARD_SKILL_LIST: OnMsgSummonCardSkillList(static_cast(pGameMsg)); break; case IMSG_DECOMPOSE_DO: OnMsgDoDecompose( static_cast(pGameMsg) ); break; case MSG_CHANGE_SKIN_COLOR: OnMsgChangeSkinColor( static_cast(pGameMsg) ); break; case TMSG_REQ_CLOSE_EX: { SendLogOutMessage(); pGameMsg->bUse = false; } break; case MSG_PARTYMATCH_ACTION: { OnMsgPartyMatchingAction(static_cast(pGameMsg)); pGameMsg->bUse = false; } break;// 파티 매칭 } return pGameMsg->bUse; } void SGameSystem::OnMsgState( struct SMSG_STATE* pMsg ) { if( GetLocalPlayer() ) { if( pMsg->handle == GetLocalPlayer()->GetArID() ) pMsg->data_owner = SMSG_STATE::OWNER_LOCAL_PLAYER; else if( m_CreatureSlotMgr.IsExistCreature( pMsg->handle ) ) pMsg->data_owner = SMSG_STATE::OWNER_LOCAL_CREATURE; else if( m_PartyMgr.IsExistMember( pMsg->handle ) ) pMsg->data_owner = SMSG_STATE::OWNER_LOCAL_PARTY; else if( m_GuildMgr.IsExistMember( pMsg->handle ) ) pMsg->data_owner = SMSG_STATE::OWNER_LOCAL_GUILD; } switch( pMsg->state_code ) { case STATE_CODE::HIDING: case STATE_CODE::TRACE_OF_FUGITIVE: { if( pMsg->state_level ) { SGameAvatarEx* pTarget = m_pTargetMgr->GetTarget(); if( pTarget ) { //타겟과 Hiding핸들이 같다면 타겟 NULL if( pMsg->handle == pTarget->GetArID() ) SetTarget( NULL, true ); } } } break; } StateInfoEx* pStateInfo = GetTenacityDB().GetTenacityData( pMsg->state_code ); if (pStateInfo) { switch (pStateInfo->effect_type) { case STATE_TYPE::STATE_DETECT_HIDING: { if( pMsg->state_level == 0 ) { SGameAvatarEx* pTarget = m_pTargetMgr->GetTarget(); if( pTarget ) { if( pTarget->GetStateFlag() & SGameAvatarEx::FLAG_STATE_HIDING ) { //파티원이나 레이드원이 아니라면 타겟 NULL if( !m_pGame->IsPartyRaidMemeber( pTarget->GetArID() ) ) SetTarget( NULL, true ); } } } } break; } } } void SGameSystem::OnMsgStatusChange( struct SMSG_STATUS_CHANGE* pMsg ) { if( m_PlayerInfoMgr.IsLocalPlayer(pMsg->handle) ) m_PlayerInfoMgr.SetStatus(pMsg->status); SGameAvatarEx * pPlayer = (SGameAvatarEx *)m_pGame->GetGameObject(pMsg->handle); if( pPlayer ) { if( pMsg->status & TS_ENTER::CreatureInfo::FLAG_INVISIBLE ) { SGameAvatarEx* pTarget = m_pTargetMgr->GetTarget(); if( pTarget ) { if( pTarget->GetArID() == pMsg->handle ) SetTarget( NULL, true ); } } } } void SGameSystem::OnMsgTargetInfo( struct SIMSG_UI_TARGET_INFO* pMsg ) { if( pMsg->handle == NULL ) m_PlayerInfoMgr.SetTarget( NULL, "", TS_ENTER::GAME_OBJTYPE_MAX ); else m_PlayerInfoMgr.SetTarget( pMsg->handle, pMsg->strName.c_str(), pMsg->nObjType ); //여기서 타겟의 스테이트를 삭제하면 타겟에 대한 지속효과 정보가 모두 날라간다. //이로 인해서 서버에서 타겟을 잡을때마다 지속효과의 정보를 보내줬는데 필요없는 메세지와 메모리 낭비로 인해 주석처리한다. // m_PlayerInfoMgr.DeleteTargetStateList(); } void SGameSystem::OnMsgExpUpdate( struct SMSG_EXP_UPDATE* pMsg ) { // 크리처일 경우 if( m_CreatureSlotMgr.IsExistCreature( pMsg->handle ) ) { m_CreatureSlotMgr.SetCreatureExp( pMsg->handle, pMsg->exp ); m_CreatureSlotMgr.SetCreatureJP( pMsg->handle, pMsg->jp ); } else if( m_PlayerInfoMgr.IsLocalPlayer(pMsg->handle) ) { m_PlayerInfoMgr.SetExp(pMsg->exp); m_PlayerInfoMgr.SetJP(pMsg->jp); } } void SGameSystem::OnMsgHPMP( struct SMSG_HPMP* pMsg ) { // 크리처일 경우 if( m_CreatureSlotMgr.IsExistCreature( pMsg->handle ) ) { m_CreatureSlotMgr.SetCreatureHP( pMsg->handle, pMsg->hp ); m_CreatureSlotMgr.SetCreatureMP( pMsg->handle, pMsg->mp ); m_CreatureSlotMgr.SetCreatureMaxHP( pMsg->handle, pMsg->max_hp ); m_CreatureSlotMgr.SetCreatureMaxMP( pMsg->handle, pMsg->max_mp ); } else if( m_PlayerInfoMgr.IsLocalPlayer(pMsg->handle) ) { m_PlayerInfoMgr.SetHP(pMsg->hp); m_PlayerInfoMgr.SetMP(pMsg->mp); m_PlayerInfoMgr.SetMaxHP(pMsg->max_hp); m_PlayerInfoMgr.SetMaxMP(pMsg->max_mp); } } void SGameSystem::OnMsgSP( struct SMSG_SP* pMsg ) { if( m_CreatureSlotMgr.IsExistCreature( pMsg->handle ) ) { m_CreatureSlotMgr.SetCreatureSP( pMsg->handle, pMsg->sp ); } } void SGameSystem::OnMsgTargetStat( struct SIMSG_UI_TARGET_STAT* pMsg ) { if( pMsg->m_nMode == SIMSG_UI_TARGET_STAT::USE_DEF || pMsg->m_nMode == SIMSG_UI_TARGET_STAT::USE_HPMP ) // hp, mp { if( m_CreatureSlotMgr.IsExistCreature(pMsg->handle) ) { m_CreatureSlotMgr.SetCreatureHP( pMsg->handle, pMsg->m_nVar1 ); m_CreatureSlotMgr.SetCreatureMP( pMsg->handle, pMsg->m_nVar2 ); m_CreatureSlotMgr.SetCreatureMaxHP( pMsg->handle, pMsg->m_nVar3 ); m_CreatureSlotMgr.SetCreatureMaxMP( pMsg->handle, pMsg->m_nVar4 ); } else if( m_PlayerInfoMgr.IsLocalPlayer(pMsg->handle) ) { m_PlayerInfoMgr.SetHP(pMsg->m_nVar1); m_PlayerInfoMgr.SetMP(pMsg->m_nVar2); m_PlayerInfoMgr.SetMaxHP(pMsg->m_nVar3); m_PlayerInfoMgr.SetMaxMP(pMsg->m_nVar4); } } } void SGameSystem::OnMsgLevelUpdate( struct SMSG_LEVEL_UPDATE* pMsg ) { // 크리처일 경우 if( m_CreatureSlotMgr.IsExistCreature( pMsg->handle ) ) m_CreatureSlotMgr.SetCreatureLevel( pMsg->handle, pMsg->level ); else if( m_PlayerInfoMgr.IsLocalPlayer(pMsg->handle) ) { m_PlayerInfoMgr.SetLevel(pMsg->level); m_PlayerInfoMgr.SetJLv(pMsg->job_level); } } #include "SLog.h" void SGameSystem::OnMsgProperty( struct SMSG_PROPERTY* pMsg ) { // 크리처 if( m_CreatureSlotMgr.IsExistCreature( pMsg->handle ) ) { switch(pMsg->nPropertyType) { case SMSG_PROPERTY::PROPERTY_HP : m_CreatureSlotMgr.SetCreatureHP( pMsg->handle, atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_MP : m_CreatureSlotMgr.SetCreatureMP( pMsg->handle, atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_MAX_HP : m_CreatureSlotMgr.SetCreatureMaxHP( pMsg->handle, atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_MAX_MP : m_CreatureSlotMgr.SetCreatureMaxHP( pMsg->handle, atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_NAME : m_CreatureSlotMgr.SetCreatureName( pMsg->handle, pMsg->strValue.c_str() ); break; case SMSG_PROPERTY::PROPERTY_EXP : m_CreatureSlotMgr.SetCreatureExp( pMsg->handle, atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_JP : m_CreatureSlotMgr.SetCreatureJP( pMsg->handle, _atoi64(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_LEVEL : m_CreatureSlotMgr.SetCreatureLevel( pMsg->handle, atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_SP : m_CreatureSlotMgr.SetCreatureSP( pMsg->handle, atoi(pMsg->strValue.c_str()) ); break; } } else if( m_PlayerInfoMgr.IsLocalPlayer(pMsg->handle) ) { switch(pMsg->nPropertyType) { case SMSG_PROPERTY::PROPERTY_MAX_HP : m_PlayerInfoMgr.SetMaxHP( ::atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_MAX_MP : m_PlayerInfoMgr.SetMaxMP( ::atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_NAME : m_PlayerInfoMgr.SetName( pMsg->strValue.c_str() ); break; case SMSG_PROPERTY::PROPERTY_EXP : m_PlayerInfoMgr.SetExp( ::_atoi64(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_JP : m_PlayerInfoMgr.SetJP( ::_atoi64(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_JOB_LEVEL : m_PlayerInfoMgr.SetJLv( ::atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_JOB : m_PlayerInfoMgr.SetJobID( ::atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_LEVEL : m_PlayerInfoMgr.SetLevel( ::atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_WEIGHT : m_PlayerInfoMgr.SetWeight( short(::atoi(pMsg->strValue.c_str())) ); break; case SMSG_PROPERTY::PROPERTY_STR : m_PlayerInfoMgr.SetStrength( short(::atoi(pMsg->strValue.c_str())) ); break; case SMSG_PROPERTY::PROPERTY_AGI : m_PlayerInfoMgr.SetAgility( short(::atoi(pMsg->strValue.c_str())) ); break; case SMSG_PROPERTY::PROPERTY_DEX : m_PlayerInfoMgr.SetDex( short(::atoi(pMsg->strValue.c_str())) ); break; case SMSG_PROPERTY::PROPERTY_INT : m_PlayerInfoMgr.SetIntelligence( short(::atoi(pMsg->strValue.c_str())) ); break; case SMSG_PROPERTY::PROPERTY_LUCK : m_PlayerInfoMgr.SetLuck( short(::atoi(pMsg->strValue.c_str())) ); break; case SMSG_PROPERTY::PROPERTY_VITAL : m_PlayerInfoMgr.SetVital( short(::atoi(pMsg->strValue.c_str())) ); break; case SMSG_PROPERTY::PROPERTY_MENTAL : m_PlayerInfoMgr.SetMental( short(::atoi(pMsg->strValue.c_str())) ); break; case SMSG_PROPERTY::PROPERTY_SPEED : m_PlayerInfoMgr.SetSpeed( short(::atoi(pMsg->strValue.c_str())) ); break; case SMSG_PROPERTY::PROPERTY_JOB_0 : m_PlayerInfoMgr.SetOldJobID( ::atoi(pMsg->strValue.c_str()), 0 ); break; case SMSG_PROPERTY::PROPERTY_JOB_1 : m_PlayerInfoMgr.SetOldJobID( ::atoi(pMsg->strValue.c_str()), 1 ); break; case SMSG_PROPERTY::PROPERTY_JOB_2 : m_PlayerInfoMgr.SetOldJobID( ::atoi(pMsg->strValue.c_str()), 2 ); break; case SMSG_PROPERTY::PROPERTY_JLV_0 : m_PlayerInfoMgr.SetOldJobLv( ::atoi(pMsg->strValue.c_str()), 0 ); break; case SMSG_PROPERTY::PROPERTY_JLV_1 : m_PlayerInfoMgr.SetOldJobLv( ::atoi(pMsg->strValue.c_str()), 1 ); break; case SMSG_PROPERTY::PROPERTY_JLV_2 : m_PlayerInfoMgr.SetOldJobLv( ::atoi(pMsg->strValue.c_str()), 2 ); break; /// 2011.03.28 특성 포인트 - prodongi case SMSG_PROPERTY::PROPERTY_TP : { int getTp = ::atoi(pMsg->strValue.c_str()); /// tp가 바꼈을 때 if (!m_PlayerInfoMgr.IsFirstTpSet()) { int diffTp = getTp - m_PlayerInfoMgr.GetTP(); if (0 != diffTp) m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG(SYS_MSG_MODIFY_TP, diffTp)); } else { m_PlayerInfoMgr.setFalseFirstTpSet(); } m_PlayerInfoMgr.SetTP(getTp); } break; case SMSG_PROPERTY::PROPERTY_AP: m_PlayerInfoMgr.SetAP(::atoi(pMsg->strValue.c_str())); break; /// 2012.08.06 - prodongi case SMSG_PROPERTY::PROPERTY_ALIAS: m_PlayerInfoMgr.SetAlias(pMsg->strValue.c_str()); break; case SMSG_PROPERTY::PROPERTY_GOLD : m_PlayerInfoMgr.SetGold( money_t( ::_atoi64(pMsg->strValue.c_str()) ) ); break; case SMSG_PROPERTY::PROPERTY_PERMISSION : m_PlayerInfoMgr.SetPermission ( ::atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_PK_COUNT : m_PlayerInfoMgr.SetPk_count ( ::atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_DK_COUNT : m_PlayerInfoMgr.SetDk_count ( ::atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_RACE : m_PlayerInfoMgr.SetRace ( ::atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_CHARISMA : m_PlayerInfoMgr.SetCharisma ( ::atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_MORAL : { // int nMoralPoint = ( ::atoi(pMsg->strValue.c_str() ) ) / 10000; // 소수점 넷째자리 까지 손실 없이 하기 위해 10000을 곱해줬음. // bintitle. 2011.11.07. int => __int64. __int64 nMoralPoint = ( ::_atoi64(pMsg->strValue.c_str() ) ); // 소수점 처리를 위해 10000곱한 값으로 유지. __int64 nOldMoralPoint = ( m_PlayerInfoMgr.GetMoral() ); if( !m_PlayerInfoMgr.IsFirstImmoralSetting() && nMoralPoint != nOldMoralPoint ) { if( nMoralPoint>0 ) { if( nMoralPoint > nOldMoralPoint ) m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_IMMORAL_POINT_INCREASE ) ); else m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_IMMORAL_POINT_DECREASE ) ); } else if( nMoralPoint<0 ) { if( nMoralPoint < nOldMoralPoint ) m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_MORAL_POINT_INCREASE ) ); else m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_MORAL_POINT_DECREASE ) ); } else { if( nOldMoralPoint>0 ) m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_IMMORAL_POINT_DECREASE ) ); else m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_MORAL_POINT_DECREASE ) ); } } else m_PlayerInfoMgr.SetFirstImmoralSetting(); m_PlayerInfoMgr.SetMoral( nMoralPoint ); break; } case SMSG_PROPERTY::PROPERTY_LOGIN_TIME: m_PlayerInfoMgr.SetLogin_time ( ::atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_SEX: m_PlayerInfoMgr.SetSex ( ::atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_X: m_PlayerInfoMgr.SetX ( ::atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_Y: m_PlayerInfoMgr.SetY ( ::atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_STORAGE_GOLD: m_PlayerInfoMgr.SetStorage_gold( ::atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_STAMINA: m_PlayerInfoMgr.SetStamina ( ::atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_CHAOS: m_PlayerInfoMgr.SetChaos ( ::atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_MAX_CHAOS: m_PlayerInfoMgr.SetMax_chaos ( ::atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_MAX_STAMINA: m_PlayerInfoMgr.SetMax_stamina ( ::atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_CHANNEL: m_PlayerInfoMgr.SetChannel ( ::atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_STAMINA_REGEN_RATE: m_PlayerInfoMgr.SetStaminaRegen( ::atoi(pMsg->strValue.c_str()) ); break; case SMSG_PROPERTY::PROPERTY_PLAYTIME: m_PlayerInfoMgr.SetContinuousPlayTime( (AR_TIME)::atoi(pMsg->strValue.c_str()) ); break; // 1/100초 단위 case SMSG_PROPERTY::PROPERTY_PLAYTIME_LIMIT1: m_PlayerInfoMgr.SetPennaltyPlayTime( (AR_TIME)::atoi(pMsg->strValue.c_str()) ); break; //1초 * 60초 * 60분 * 3시간 == 3시간 case SMSG_PROPERTY::PROPERTY_PLAYTIME_LIMIT2: m_PlayerInfoMgr.SetMaxContinuousPlayTime( (AR_TIME)::atoi(pMsg->strValue.c_str()) ); break; //1초 * 60초 60분 * 5시간 == 5시간 case SMSG_PROPERTY::PROPERTY_ETHEREAL_STONE_DURABILITY : // 에테리얼스톤. bintitle. 2010.08.25. { int ethereal = ::atoi(pMsg->strValue.c_str()); if( ethereal > 0 ) ethereal /= 10000; m_PlayerInfoMgr.SetEtherealStoneDurability( ethereal ); } break; case SMSG_PROPERTY::PROPERTY_HUNTAHOLICPOINT : // 헌터홀릭포인트. bintitle. 2010.09.03. m_PlayerInfoMgr.SetHuntaHolicPoint( ::atoi(pMsg->strValue.c_str()) ); break; } } } // MJ 2005/03/04 // 서버에서 타겟 변경 메시지 보내면 타겟 변경해준다 void SGameSystem::OnMsgTarget( struct SMSG_TARGET* pMsg ) { if( pMsg->target ) { //타겟 설정 SGameAvatarEx * pTarget = (SGameAvatarEx *)m_pGame->GetGameObject(pMsg->target); SetTarget(pTarget, true); } else { //타겟 해제 SetTarget(NULL, true); } } void SGameSystem::OnMsgNPCDialog ( struct SMSG_NPC_DIALOG* pMsg ) { if( pMsg->npc_handle ) { AddClickNpc( pMsg->npc_handle ); } } void SGameSystem::OnMsgMarket ( struct SMSG_MARKET* pMsg ) { if( pMsg->npc_handle ) AddClickNpc( pMsg->npc_handle ); else m_ClickNpcList.clear(); m_InventoryMgr.AddShopItem(pMsg); } void SGameSystem::OnMsgLogin ( struct SMSG_LOGIN* pMsg ) { if( pMsg->handle ) m_vLocalHandleList.push_back( pMsg->handle ); m_PartyMgr.SetPlayerInfo( pMsg->handle, pMsg->szName ); m_GuildMgr.SetPlayerInfo( pMsg->handle, pMsg->szName ); m_PlayerInfoMgr.SetPlayerHandle( pMsg->handle ); m_PlayerInfoMgr.SetName( pMsg->szName ); m_PlayerInfoMgr.SetHP(pMsg->hp); m_PlayerInfoMgr.SetMaxHP( pMsg->max_hp ); m_PlayerInfoMgr.SetMP(pMsg->mp); m_PlayerInfoMgr.SetMaxMP( pMsg->max_mp ); //로그인 됐다면 서버에 월드 시간 요청 TS_CS_GAME_TIME time_msg; if( m_pGame ) m_pGame->SendMsg( &time_msg ); //if( pMsg->guild_id >= 0 ) //{ // //길드 정보 요청 // if( IsExistGuildInfo( pMsg->guild_id ) == false ) // Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/gicon %d", pMsg->guild_id ).c_str() ); //} /* SMSG_HP msg; msg.hp = pMsg->hp; msg.handle = pMsg->handle; msg.hp_percentage = m_PlayerInfoMgr.GetPercentHP(); m_pGame->ProcMsgAtStatic( &msg );*/ } //GameOver 관련-----------------------------------------------------------// MJ 2004/10/13 void SGameSystem::OnMsgChangeAvatar( struct STMSG_CHANGEAVATAR* pMsg ) { // 아바타 바꾸자~ _oprint( "아바타 변경 처리 해줘요 ~\n" ); } void SGameSystem::OnMsgReqClose( struct STMSG_REQ_CLOSE* pMsg ) { // 게임종료 여부를 묻는 메시지박스를 띄우도록 한다. 퀵슬롯 작동(alt+F4)때문에 윈도우메시지로부터 온것은 무시. if( !pMsg->m_bByWndMsg ) m_pGame->ProcMsgAtStatic( &SIMSG_REQ_OPEN_MSGBOX( SIMSG_REQ_OPEN_MSGBOX::MSGBOX_EXITGAME, SYS_MSG_SERVER_EXITGAME ) ); } void SGameSystem::OnMsgActEquipSummon( struct SIMSG_UI_ACT_EQUIP_SUMMON* pMsg ) { TS_EQUIP_SUMMON msg; for( int i(0); 6>i; i++ ) msg.card_handle[i] = pMsg->card_handle[i]; if( m_pGame ) m_pGame->SendMsg( &msg ); } // 소환할 얘 // MJ 2004/10/17 void SGameSystem::OnMsgActSelectSummon( struct SIMSG_UI_ACT_SELECT_SUMMON* pMsg ) { m_CreatureSlotMgr.SetSelectCreatureCard( pMsg->card_handle ); } void SGameSystem::OnMsgSaveClientInfo( struct SIMSG_UI_SAVE_CLIENT_INFO* pMsg ) { TS_CS_SET_PROPERTY msg; memset( msg.name, 0, sizeof(msg.name) ); strcpy( msg.name, "client_info" ); int nSize = int(pMsg->m_strInfo.size() + 1); // NULL문자 포함 //chatting 크기만큼 사이즈 늘림. msg.size += static_cast< unsigned int >( sizeof(char) * nSize ); // 체크섬 추가해야함. msg.set_check_sum(); // 메모리 할당 char * pBuffer = new char[ msg.size ]; memset( pBuffer, 0, sizeof(char)*msg.size ); // 버퍼에 헤더 복사 memcpy( pBuffer, &msg, sizeof(TS_CS_SET_PROPERTY) ); // 문자열 복사 memcpy( pBuffer + sizeof(TS_CS_SET_PROPERTY), pMsg->m_strInfo.c_str(), sizeof(char)*nSize ); if( m_pGame ) m_pGame->SendMsg( reinterpret_cast(pBuffer) ); delete [] pBuffer; } void SGameSystem::OnMsgSaveQuickSlot( struct SIMSG_UI_SAVE_QUICK_SLOT* pMsg ) { TS_CS_SET_PROPERTY msg; memset( msg.name, 0, sizeof(msg.name) ); strcpy( msg.name, "quick_slot" ); int nSize = int(pMsg->m_strInfo.size() + 1); // NULL문자 포함 //chatting 크기만큼 사이즈 늘림. msg.size += static_cast< unsigned int >( sizeof(char) * nSize ); // 체크섬 추가해야함. msg.set_check_sum(); // 메모리 할당 char * pBuffer = new char[ msg.size ]; memset( pBuffer, 0, sizeof(char)*msg.size ); // 버퍼에 헤더 복사 memcpy( pBuffer, &msg, sizeof(TS_CS_SET_PROPERTY) ); // 문자열 복사 memcpy( pBuffer + sizeof(TS_CS_SET_PROPERTY), pMsg->m_strInfo.c_str(), sizeof(char)*nSize ); if( m_pGame ) m_pGame->SendMsg( reinterpret_cast(pBuffer) ); delete [] pBuffer; } void SGameSystem::OnMsgSaveCurrentKey( struct SIMSG_UI_SAVE_CURRENT_KEY* pMsg ) { TS_CS_SET_PROPERTY msg; memset( msg.name, 0, sizeof(msg.name) ); strcpy( msg.name, "current_key" ); int nSize = int(pMsg->m_strInfo.size() + 1); // NULL문자 포함 //chatting 크기만큼 사이즈 늘림. msg.size += static_cast< unsigned int >( sizeof(char) * nSize ); // 체크섬 추가해야함. msg.set_check_sum(); // 메모리 할당 char * pBuffer = new char[ msg.size ]; memset( pBuffer, 0, sizeof(char)*msg.size ); // 버퍼에 헤더 복사 memcpy( pBuffer, &msg, sizeof(TS_CS_SET_PROPERTY) ); // 문자열 복사 memcpy( pBuffer + sizeof(TS_CS_SET_PROPERTY), pMsg->m_strInfo.c_str(), sizeof(char)*nSize ); if( m_pGame ) m_pGame->SendMsg( reinterpret_cast(pBuffer) ); delete [] pBuffer; } void SGameSystem::OnMsgSaveSavedKey( struct SIMSG_UI_SAVE_SAVED_KEY* pMsg ) { TS_CS_SET_PROPERTY msg; memset( msg.name, 0, sizeof(msg.name) ); strcpy( msg.name, "saved_key" ); int nSize = int(pMsg->m_strInfo.size() + 1); // NULL문자 포함 //chatting 크기만큼 사이즈 늘림. msg.size += static_cast< unsigned int >( sizeof(char) * nSize ); // 체크섬 추가해야함. msg.set_check_sum(); // 메모리 할당 char * pBuffer = new char[ msg.size ]; memset( pBuffer, 0, sizeof(char)*msg.size ); // 버퍼에 헤더 복사 memcpy( pBuffer, &msg, sizeof(TS_CS_SET_PROPERTY) ); // 문자열 복사 memcpy( pBuffer + sizeof(TS_CS_SET_PROPERTY), pMsg->m_strInfo.c_str(), sizeof(char)*nSize ); if( m_pGame ) m_pGame->SendMsg( reinterpret_cast(pBuffer) ); delete [] pBuffer; } void SGameSystem::OnMsgRqSummon( struct SMSG_RQ_SUMMON* pMsg ) { //TS_CS_SUMMON msg; //msg.card_handle = pMsg->card_handle; //msg.is_summon = pMsg->is_summon; //if( m_pGame ) m_pGame->SendMsg( &msg ); } void SGameSystem::OnMsgAddSummonInfo ( struct SMSG_ADD_SUMMON_INFO * pMsg ) { DATA_CREATURE creature; creature.card_handle = pMsg->card_handle; creature.summon_handle = pMsg->summon_handle; strcpy( creature.name ,pMsg->name ) ; creature.code = pMsg->code ; creature.level = pMsg->level; creature.sp = pMsg->sp ; m_vCreatureDataList.push_back( creature ); m_CreatureSlotMgr.AddCreature( pMsg ); } void SGameSystem::OnMsgSummonNameChange ( struct SIMSG_UI_CHANGE_SUMMON_NAME* pMsg ) { TS_CS_CHANGE_SUMMON_NAME msg; memset( msg.szName, 0, sizeof(msg.szName) ); strcpy( msg.szName, pMsg->m_strName.c_str() ); msg.szName[_countof(msg.szName)-1] = 0; if( m_pGame ) m_pGame->SendMsg( &msg ); } void SGameSystem::OnMsgRemoveSummonInfo ( struct SMSG_REMOVE_SUMMON_INFO* pMsg ) { // 2010.08.17 기존 스킬 삭제, 크리쳐가 생성 안된 카드를 강화 했을 경우에는 SKILL_LIST가 안날라와서 // 기존 크리처의 스킬이 삭제가 안되기 때문에 여기서 삭제를 해줘야 된다. - prodongi std::vector< DATA_CREATURE >::iterator it = m_vCreatureDataList.begin(); for (; it != m_vCreatureDataList.end(); ++it) { if (it->card_handle == pMsg->card_handle) { m_CreatureSkillSlotMgr.ResetCreatureSkill(it->summon_handle); break; } } // sonador 10.2.1 팻 시스템 구현 struct CreatureDataRemover { CreatureDataRemover( AR_HANDLE cardHandle ) : mCardHandle( cardHandle ) {} AR_HANDLE mCardHandle; bool operator()( const DATA_CREATURE& creatureData ) { return mCardHandle == creatureData.card_handle; } }; m_vCreatureDataList.erase( std::remove_if( m_vCreatureDataList.begin(), m_vCreatureDataList.end(), CreatureDataRemover( pMsg->card_handle ) ), m_vCreatureDataList.end() ); m_CreatureSlotMgr.DelCreature( pMsg->card_handle ); } void SGameSystem::OnMsgEquipSummon ( struct SMSG_EQUIP_SUMMON * pMsg ) { //편성 정보 m_CreatureSlotMgr.SetEquipCreature( pMsg ); } // { sonador 10.2.1 팻 시스템 구현 void SGameSystem::OnMsgAddPetInfo( struct SMSG_ADD_PET_INFO* msg ) { m_PetMgr.OnMsgAddPetInfo( msg ); } void SGameSystem::OnMsgRemovePetInfo( struct SMSG_REMOVE_PET_INFO* msg ) { m_PetMgr.OnMsgRemovePetInfo( msg ); } // } void SGameSystem::OnMsgChattingRequest( SMSG_CHATTING_REQUEST* pMsg ) { Rq_Chatting( pMsg->type, pMsg->szTarget, pMsg->strText.c_str() ); } void SGameSystem::OnMsgWatchBooth( SMSG_WATCH_BOOTH* pMsg ) { if( pMsg->bIsStartWatch ) { SGameAvatarEx* pPlayer = GetLocalPlayer(); SGameAvatarEx* pStore = (SGameAvatarEx*)m_pGame->GetGameObject( pMsg->hTarget ); if( pPlayer && pStore ) { float len = GetDistance( *pPlayer->GetPosition(), *pStore->GetPosition() ); if( len < 100.f ) { TS_CS_WATCH_BOOTH msg; msg.target = pMsg->hTarget; msg.set_check_sum(); if( m_pGame ) m_pGame->PendMessage( &msg ); return; } } //TODO : 메시지 박스 띄우자 if( m_pGame ) m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_BOOTH_DISTANCE ) ); } else { TS_CS_STOP_WATCH_BOOTH msg; msg.target = pMsg->hTarget; msg.set_check_sum(); if( m_pGame ) m_pGame->PendMessage( &msg ); } } void SGameSystem::OnMsgRqBoothName( SMSG_REQUEST_BOOTH_NAME* pMsg ) { TS_CS_GET_BOOTHS_NAME msg; msg.cnt = pMsg->pvBoothList->size(); msg.size += (sizeof(AR_HANDLE) * msg.cnt); TS_CS_GET_BOOTHS_NAME *pRequest; char *pBuf = new char[ msg.size ]; pRequest = reinterpret_cast< TS_CS_GET_BOOTHS_NAME * >( pBuf ); memcpy( pBuf, &msg, sizeof( TS_CS_GET_BOOTHS_NAME ) ); memcpy( pBuf + sizeof( TS_CS_GET_BOOTHS_NAME ), &(*pMsg->pvBoothList->begin()), sizeof(AR_HANDLE)*msg.cnt ); pRequest->set_check_sum(); if( m_pGame ) m_pGame->SendMsg( pRequest ); delete [] pBuf; } void SGameSystem::OnMsgBooth( SMSG_UI_BOOTH *pMsg ) { switch( pMsg->nBoothType ) { case SMSG_UI_BOOTH::END_BOOTH: { TS_CS_STOP_BOOTH msg; msg.set_check_sum(); if( m_pGame ) m_pGame->SendMsg( &msg ); } break; case SMSG_UI_BOOTH::START_BOOTH: { TS_CS_START_BOOTH msg; msg.cnt = (unsigned short)pMsg->vItemList.size(); strncpy( msg.name, pMsg->strBoothName.c_str(), _countof(msg.name) - 1 ); // msg.type = !pMsg->nBoothType; msg.type = pMsg->nMode ? 2 : 1; //SMSG_UI_BOOTH에서는 0 판매/1 구매 -> SMSG_UI_BOOTH에서는 1판매 / 2구매 msg.size += msg.cnt * sizeof( TS_CS_START_BOOTH::TS_BOOTH_OPEN_ITEM_INFO ); char *pBooth = new char[ msg.size ]; memcpy( pBooth, &msg, sizeof( TS_CS_START_BOOTH ) ); TS_CS_START_BOOTH::TS_BOOTH_OPEN_ITEM_INFO *pInfo = reinterpret_cast< TS_CS_START_BOOTH::TS_BOOTH_OPEN_ITEM_INFO * >( pBooth + sizeof( TS_CS_START_BOOTH ) ); for( size_t idx = 0; idx < pMsg->vItemList.size(); ++idx ) { pInfo->item_handle = pMsg->vItemList[idx]; pInfo->cnt = pMsg->vCountList[idx].getAmount(); pInfo->gold = pMsg->vPriceList[idx].getAmount(); ++pInfo; } reinterpret_cast< TS_MESSAGE* >( pBooth )->set_check_sum(); if( m_pGame ) m_pGame->SendMsg( reinterpret_cast< TS_MESSAGE* >( pBooth ) ); delete [] pBooth; } break; } } //2011.07.12 - servantes void SGameSystem::OnMsgEndQuest( struct SMSG_END_QUEST* pGameMsg ) { TS_CS_END_QUEST msg; msg.code = pGameMsg->quest_code; msg.nOptionalReward = pGameMsg->nOptionalReward; m_pGame->SendMsg( &msg ); } void SGameSystem::OnMsgTitle( struct SGameMessage * pMsg ) { m_TitleMgr.SetMsgTitleData( pMsg ); } void SGameSystem::OnMsgQuestUpdata( SMSG_QUEST_UPDATA* pGameMsg ) { QuestBase *pBase = GetQuestDB().GetQuestData( pGameMsg->nQuestID ); if( !pBase ) return; std::string strQuest = ParseQuestText( GetStringDB().GetQuestString( pBase->nStatusTextId ), pGameMsg->nQuestID ); std::vector NewQuestText; _SplitText( strQuest.c_str(), "
", NewQuestText, "
" ); std::vector OldQuestText; _SplitText( pGameMsg->strOldQuest.c_str(), "
", OldQuestText, "
" ); if( NewQuestText.size() != OldQuestText.size() ) { NewQuestText.clear(); OldQuestText.clear(); assert( true && "퀘스트 정보가 이상하다." ); return; } std::vector UpdateQuestText; for( size_t i(0); iProcMsgAtStatic( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_NOTICE, true ) ); m_pGame->ProcMsgAtStatic( &SIMSG_UI_SEND_DATA( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_NOTICE, "questupdate", OutQuestText.c_str() ) ); } NewQuestText.clear(); OldQuestText.clear(); UpdateQuestText.clear(); } void SGameSystem::_SplitText( const char* lpText, const char* lpTag, std::vector& rVecText, const char* lpTag2 ) { std::string strScString = lpText; int nPos(0); int nEraseSize(0); while( nPos!=-1 ) { nPos = strScString.find( lpTag ); nEraseSize = ::strlen(lpTag); if( nPos == -1 ) { nPos = strScString.find( lpTag2 ); nEraseSize = ::strlen(lpTag2); } if( nPos != -1 ) { rVecText.push_back( strScString.substr(0, nPos) ); strScString.erase(0, nPos+nEraseSize); } else { rVecText.push_back( strScString ); } } } void SGameSystem::OnMsgBeltSlotInfo ( struct SMSG_BELT_SLOT_INFO* pMsg ) { m_InventoryMgr.SetBeltSlotCard( pMsg ); } void SGameSystem::OnMsgTrade ( struct SMSG_TRADE* pMsg ) { switch(pMsg->mode) { case TS_TRADE::BEGIN_TRADE : m_nContentState = CS_TRADE; break; case TS_TRADE::CANCEL_TRADE : m_nContentState = CS_NONE; break; case TS_TRADE::PROCESS_TRADE: { if( pMsg->rq_mode == false ) { //서버에서 온 메세지 일 경우만 메세지 출력 m_nContentState = CS_NONE; //거래가 정상 적으로 이루워 졌음 m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_TRANSACTION_COMPLETE ) ); } } break; case TS_TRADE::ACCEPT_TRADE: break; case TS_TRADE::REJECT_TRADE: { if( pMsg->bLocalPlyaer ) //내가 거절 했을경우 true m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_TRADE_REJECTION ) ); else //거래 신청에 상대방이 거절함 m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_TRADE_REJECT ) ); } break; case TS_TRADE::CONFIRM_TRADE: break; case TS_TRADE::REQUEST_TRADE: { SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pGame->GetGameObject(pMsg->target_player); if( pTarget && pTarget->GetObjType() == TS_ENTER::GAME_PLAYER ) { //거래 신청 if (!pMsg->bIncoming) m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_TRADE_REQUEST ) ); } else { //올바른 대상 선택 m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_TRADE_NOT_TRADETARGET ) ); return; } } break; } if( pMsg->rq_mode ) m_TradeMgr.ProcTradeMsg( pMsg ); } void SGameSystem::OnMsgReqUIDisplayInfo( struct SIMSG_REQ_UIDISPLAY_INFO* pMsg ) { //// 요청하는 정보의 종류 //if( pMsg->m_Type == SIMSG_REQ_UIDISPLAY_INFO::UIREQ_CHARSTATUS ) //{ // for( unsigned int i=0; m_vStatList.size()>i; i++ ) // { // SIMSG_UI_CHARSTATUS_INFO msg; // msg.pStatus = &m_vStatList[i]; // m_pGame->ProcMsgAtStatic( &msg ); // } //} //else if( pMsg->m_Type == SIMSG_REQ_UIDISPLAY_INFO::UIREQ_QUICKSLOT ) //{ // //PD 에선 없다. //} //else if( pMsg->m_Type == SIMSG_REQ_UIDISPLAY_INFO::UIREQ_INVENTORY ) //{ // //인벤토리???? //} } void SGameSystem::OnMsgActInventory( SIMSG_UI_ACT_INVENTORY* pMsg ) { SGameAvatarEx* pPlayer = GetLocalPlayer(); if( pPlayer ) { if( pPlayer->IsIng() ) { if( pMsg->m_nActType == SIMSG_UI_ACT_INVENTORY::ACT_USE ) { Rq_UseItem( pMsg->m_nHandle, pMsg->m_TargetHandle, pMsg->m_ItemUseTargetHandle ); } return; } } //상태 if( m_nContentState != CS_NONE && m_nContentState != CS_STORAGE ) return; if( pMsg->m_nActType == SIMSG_UI_ACT_INVENTORY::ACT_USE ) { Rq_UseItem( pMsg->m_nHandle, pMsg->m_TargetHandle, pMsg->m_ItemUseTargetHandle, pMsg->m_strParameter.c_str() ); } else if( pMsg->m_nActType == SIMSG_UI_ACT_INVENTORY::ACT_DISCARD ) { Rq_DropItem( pMsg->m_nHandle, pMsg->m_nCnt ); } else if( pMsg->m_nActType == SIMSG_UI_ACT_INVENTORY::ACT_SKILLCARD_BIND ) { TS_CS_BIND_SKILLCARD msg; msg.item_handle = pMsg->m_nHandle; msg.target_handle = pMsg->m_TargetHandle; if( m_pGame ) m_pGame->SendMsg( &msg ); } else if( pMsg->m_nActType == SIMSG_UI_ACT_INVENTORY::ACT_SKILLCARD_UNBIND ) { TS_CS_UNBIND_SKILLCARD msg; msg.item_handle = pMsg->m_nHandle; msg.target_handle = pMsg->m_TargetHandle; if( m_pGame ) m_pGame->SendMsg( &msg ); } else if( pMsg->m_nActType == SIMSG_UI_ACT_INVENTORY::ACT_CREATURE_USE ) { m_InventoryMgr.Rq_CreatureUseItem( pMsg->m_nHandle, pMsg->m_TargetHandle ); } else if( pMsg->m_nActType == SIMSG_UI_ACT_INVENTORY::ACT_BELT_PUTON ) { // 2010.08.17 - prodongi //m_InventoryMgr.Rq_BeltCardPut( true, pMsg->m_nHandle ); m_InventoryMgr.Rq_BeltCardPut( true, pMsg->m_nHandle, pMsg->m_putBeltSlot ); } else if( pMsg->m_nActType == SIMSG_UI_ACT_INVENTORY::ACT_BELT_PUTOFF ) { m_InventoryMgr.Rq_BeltCardPut( false, pMsg->m_nHandle ); } } void SGameSystem::OnMsgActCreature ( SIMSG_UI_ACT_CREATURE * pMsg ) { //소환, 역소환을 할 것인가? pMsg->m_nHandle; } void SGameSystem::OnMsgActTarget ( struct SIMSG_UI_ACT_TARGET * pMsg ) { if( pMsg->m_nTargetHandle ) { //타겟 설정 SGameAvatarEx * pTarget = (SGameAvatarEx *)m_pGame->GetGameObject(pMsg->m_nTargetHandle); SetTarget(pTarget); } else { //타겟 해제 SetTarget(NULL); //if( GetLocalPlayer() ) // GetLocalPlayer()->SetTargetObject(NULL); } } void SGameSystem::OnMsgActNPCDialog ( struct SIMSG_UI_ACT_NPCDIALOG* pMsg ) { if( pMsg->m_strTrigger.size() <= 1 ) return; TS_CS_DIALOG msg; msg.trigger_length = unsigned short(pMsg->m_strTrigger.size()); msg.size = sizeof(TS_CS_DIALOG) + msg.trigger_length; msg.set_check_sum(); char* pMsgBuffer = new char[ msg.size ]; ::memcpy( pMsgBuffer, &msg, sizeof(TS_CS_DIALOG) ); ::memcpy( pMsgBuffer + sizeof(TS_CS_DIALOG), pMsg->m_strTrigger.c_str(), msg.trigger_length ); _performance_print( "ActNPCDialog - %s\n", pMsg->m_strTrigger.c_str() ); if( m_pGame ) m_pGame->SendMsg( (TS_CS_DIALOG*)pMsgBuffer ); delete [] pMsgBuffer; } //스킬 배우기 요청 void SGameSystem::OnMsgActLearnSkill( struct SIMSG_UI_ACT_LEARN_SKILL* pMsg ) { Rq_Skill_Learn( pMsg->handle, pMsg->nSkillID, pMsg->nOriginSkillID, pMsg->nSkillLv ); } //잡 레벨 업 (1씩) void SGameSystem::OnMsgActJopLevelUp( struct SIMSG_UI_ACT_JOB_LEVELUP* pMsg ) { Rq_JopLevelUp( pMsg->handle ); } //셋트 장착 void SGameSystem::OnMsgActFullEquip( struct SIMSG_UI_ACT_FULLEQUIP* pMsg ) { TS_CS_PUTON_ITEM_SET msg; for( int i(0); ItemBase::MAX_ITEM_WEAR>i; i++ ) { msg.handle[i] = pMsg->itemHandle[i]; } if( m_pGame ) m_pGame->SendMsg( &msg ); } bool SGameSystem::IsSummon( AR_HANDLE handle ) { if( m_vCreatureDataList.empty() ) return false; for( unsigned int i(0); m_vCreatureDataList.size()>i; i++ ) { if( m_vCreatureDataList[i].summon_handle == handle ) return true; } return false; } void SGameSystem::SetSkillInputData( SGameAvatarEx * pCaster, SGameAvatarEx * pTarget, SkillBaseEx * pSkill, struct SIMSG_UI_ACT_USESKILL * pMsg ) { //소환수 스킬 처리 //m로 전환 한다. AR_UNIT nCastRange = pSkill->GetCastRange() * GameRule::DEFAULT_UNIT_SIZE; //실제 게임 단위로 변환 AR_UNIT nValidRange = pSkill->GetValidRange()* GameRule::DEFAULT_UNIT_SIZE; //실제 게임 단위로 변환 if( pSkill->GetCastRange() == -1 ) { //이미 m로 계산되어 진것이다. nCastRange = pCaster->GetAttackRange(); //아이템 사거리를 가져 온다. if( nCastRange == 0 ) { assert( nCastRange && "스킬 사용 - 사거리 이상함" ); _oprint( "!!!Data 이상 : 스킬 사용 - 사거리 이상함\n" ); } } SInputSkill inputSkill(0,0,0,0,0); if( pMsg->nSkillID==4001 || pMsg->nSkillID==4002 ) { //소환수, 역소환은 보내준 Card 로 한다. inputSkill = SInputSkill( pMsg->nSkillID, pMsg->nLevel, pMsg->summon_card_handle, nCastRange, nValidRange ); } else { //스킬 사용 /// 2010.10.14 타겟이 있으면 targetPos를 targetAr로 세팅해버리기 때문에 지면 타겟은 0으로 해준다, 서버에서도 지면타겟 스킬은 타겟을 0으로 체크한다 - prodongi AR_HANDLE targetAr = (pMsg->m_isRegionTarget) ? 0 : pTarget->GetArID(); inputSkill = SInputSkill( pMsg->nSkillID, pMsg->nLevel, targetAr, nCastRange, nValidRange, pMsg->m_targetPos, pMsg->m_isRegionTarget ); } // 2010.05.24 - prodongi inputSkill.setIsValidToCorpse(pSkill->IsValidToCorpse()); _SKILL_FX* pSkillFX = GetSkillStageDB().GetSkillStageData( pSkill->GetID() ); if( pSkillFX ) { //미리 쓰레드 로딩 걸어 놓는다. SGamePreLoad gamepreload; gamepreload.RequestThreadLoading( pSkillFX ); } pCaster->OnInput( &inputSkill ); } // 2008. 6. 18 floyd #2.3.1.23 // http://bug.nflavor.com/view.php?id=2868 // 아바타가 대상을 타겟하지 않으면, 크리쳐는 스킬 자동공격을 하지 않는 문제 관련 수정 // 기본적으로 SGameSystem::GetTarget()을 대상으로 인식하던 것을 타겟핸들을 받도록 수정 SGameAvatarEx * SGameSystem::CheckSkillTarget( SkillBaseEx * pSkill, SGameAvatarEx * pCaster, bool bEnableSysMsg, AR_HANDLE target_handle ) { if( pSkill->IsNeedTarget() ) // 타겟이 꼭 필요한 스킬 { SGameAvatarEx* pTarget; if ( target_handle == NULL ) pTarget = GetTarget(); else pTarget = (SGameAvatarEx*)m_pGame->GetGameObject( target_handle ); // SGameAvatarEx* pTarget = GetTarget(); if( pTarget ) { //// MJ 2004/11/10 //// CA : 강제 공격/PK 지원하지 않음 if( pSkill->IsHarmful() )//대상에 해로운 스킬 { //시체 대상인가? if( pSkill->IsValidToCorpse() ) { //대상이 안죽었다면 if( !pTarget->IsDead() ) { if( bEnableSysMsg ) m_pGame->AddChatMessage( GetStringDB().GetString( SYS_MSG_POINT_TARGET ) );// 타겟 잘못 지정 307 return NULL; } } else { //시체 대상이 아닌데 대상이 죽었다면 if( pTarget->IsDead() ) { if( bEnableSysMsg && GetGameOption().IsAutoTarget() ) { SGameWorld* gameWorld = dynamicCast(GetGame()); SGameAvatarEx * pTarget = gameWorld->GetCommandSystem()->GetNextTarget( 360, true ); // 360은 c_nTARGET_MAX_LEN 대신 넣었습니다. if( pTarget ) SetTarget( pTarget ); return pTarget; } } } //공격 할 수 없는 타겟 if( !m_pGame->IsAttack( pTarget ) ) { //if( bEnableSysMsg ) m_pGame->AddChatMessage( GetStringDB().GetString( SYS_MSG_POINT_TARGET ) );// 타겟 잘못 지정 307 //return NULL; if( bEnableSysMsg && GetGameOption().IsAutoTarget()) { SGameWorld* gameWorld = dynamicCast(GetGame()); SGameAvatarEx * pTarget = gameWorld->GetCommandSystem()->GetNextTarget( 360, true ); // 360은 c_nTARGET_MAX_LEN 대신 넣었습니다. if( pTarget ) SetTarget( pTarget ); return pTarget; } } if( !pSkill->IsUseableOnMonster() && !(pSkill->GetUseAble( SkillBase::USE_ENEMY ) == SKILL_USEABLE) ) { if( bEnableSysMsg ) m_pGame->AddChatMessage( GetStringDB().GetString( SYS_MSG_POINT_TARGET ) );// 타겟 잘못 지정 307 return NULL; } return pTarget; } else //대상에 이로운 스킬 { //시체 대상인가? if( pSkill->IsValidToCorpse() ) { //대상이 안죽었다면 if( !pTarget->IsDead() ) { if( bEnableSysMsg ) m_pGame->AddChatMessage( GetStringDB().GetString( SYS_MSG_POINT_TARGET ) );// 타겟 잘못 지정 307 return NULL; } } if( m_pGame->IsAttack( pTarget ) ) { //같은 파티원 및 길드원인가 if( m_PartyMgr.FindMember( pTarget->GetArID() ) || m_GuildMgr.FindMember( pTarget->GetArID() ) ) { //PK 룰 int nRule = 0; nRule += ( pCaster->GetStatus() & TS_ENTER::PlayerInfo::FLAG_PK_ON ) ? 1 : 0; nRule += ( pTarget->GetStatus() & TS_ENTER::PlayerInfo::FLAG_PK_ON ) ? 1 : 0; //둘다 PK OFF 이거나 PK ON 일때 우호~ if( nRule == 0 || nRule == 2 ) { //시체 대상이 아닌데 대상이 죽었다면 if( pSkill->IsValidToCorpse() == false && pTarget->IsDead() ) { if( bEnableSysMsg ) m_pGame->AddChatMessage( GetStringDB().GetString( SYS_MSG_POINT_TARGET ) );// 타겟 잘못 지정 307 return NULL; } return pTarget; } // 타겟에게는 사용하지 못하고 아바타에게 사용 가능하면 if( pSkill->IsUseableOnAvatar() ) { // 크리처라면 주인에게 시전 SGameAvatarEx* pMaster = (SGameAvatarEx *)m_pGame->GetGameObject( pCaster->GetMaster() ); if( pMaster != NULL ) { return pMaster; } // 크리처가 아니라면 자신에게 시전 return pCaster; } // 타겟에게는 사용하지 못하고 크리처에게 사용 가능하면 else if( pSkill->IsUseableOnSummon() ) { // 자신이 크리처라면 자신에게 시전 if( pCaster->GetObjType() == TS_ENTER::GAME_SUMMON ) { return pCaster; } } if( bEnableSysMsg ) m_pGame->AddChatMessage( GetStringDB().GetString( SYS_MSG_POINT_TARGET ) );// 타겟 잘못 지정 307 return NULL; } else { // 타겟에게는 사용하지 못하고 아바타에게 사용 가능하면 if( pSkill->IsUseableOnAvatar() ) { // 크리처라면 주인에게 시전 SGameAvatarEx* pMaster = (SGameAvatarEx *)m_pGame->GetGameObject( pCaster->GetMaster() ); if( pMaster != NULL ) { return pMaster; } // 크리처가 아니라면 자신에게 시전 return pCaster; } // 타겟에게는 사용하지 못하고 크리처에게 사용 가능하면 else if( pSkill->IsUseableOnSummon() ) { // 자신이 크리처라면 자신에게 시전 if( pCaster->GetObjType() == TS_ENTER::GAME_SUMMON ) { return pCaster; } } if( bEnableSysMsg ) m_pGame->AddChatMessage( GetStringDB().GetString( SYS_MSG_POINT_TARGET ) );// 타겟 잘못 지정 307 return NULL; } } //시체 대상이 아닌데 대상이 죽었다면 if( pSkill->IsValidToCorpse() == false && pTarget->IsDead() ) { if( bEnableSysMsg ) m_pGame->AddChatMessage( GetStringDB().GetString( SYS_MSG_POINT_TARGET ) );// 타겟 잘못 지정 307 return NULL; } if( pTarget->GetObjType() == TS_ENTER::GAME_SUMMON || pTarget->GetObjType() == TS_ENTER::GAME_PLAYER && (pSkill->IsUseableOnAvatar() || pSkill->IsUseableOnSummon()) ) { return pTarget; } else if( pTarget->GetObjType() == TS_ENTER::GAME_MOB ) { if( pSkill->IsUseableOnMonster() ) //이로운 스킬을 몬스터에게 사용 가능 하면 사용하자 { return pTarget; } else { if( bEnableSysMsg ) m_pGame->AddChatMessage( GetStringDB().GetString( SYS_MSG_POINT_TARGET ) );// 타겟 잘못 지정 307 return NULL; } } else { if( bEnableSysMsg ) m_pGame->AddChatMessage( GetStringDB().GetString( SYS_MSG_POINT_TARGET ) );// 타겟 잘못 지정 307 return NULL; } } } } else { return pCaster; } //스킬이 토글형이면 타겟은 나다~ if( pSkill->IsToggle() ) return pCaster; //타겟이 없고 아바타및 소환수에게 사용 가능 하며 이로운 스킬이면 자신에게 시전 if( pSkill->IsUseableOnAvatar() || pSkill->IsUseableOnSummon() ) { if( pSkill->IsHarmful() == false ) return pCaster; } // if( bEnableSysMsg ) m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_USE_SKILL_NEED_TARGET ) ); // 타겟을 먼저 지정해 주십시오. if( bEnableSysMsg && GetGameOption().IsAutoTarget() ) { SGameWorld* gameWorld = dynamicCast(GetGame()); SGameAvatarEx * pTarget = gameWorld->GetCommandSystem()->GetNextTarget( 360, false ); // 360은 c_nTARGET_MAX_LEN 대신 넣었습니다. gameWorld->SetResetTargetList(false); if( pTarget ) SetTarget( pTarget ); return pTarget; } return NULL; } //스킬 사용 void SGameSystem::OnMsgUseSkill( struct SIMSG_UI_ACT_USESKILL * pMsg ) { SkillBaseEx * pSkill = GetSkillDB().GetSkillData( pMsg->nSkillID ); if( !pSkill ) return; if( !pSkill->IsValid() ) { m_pGame->AddChatMessage( S(388) ); return; } if( IsSummon( pMsg->caster_handle ) ) { if( m_CreatureSkillSlotMgr.CheckCoolTime( pMsg->nSkillID, pMsg->caster_handle ) ) { m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_SKILL_DELAYTIME ) ); return; } } else { //스킬 쿨타임 체크 if( m_SkillSlotMgr.CheckCoolTime( pMsg->nSkillID ) ) { m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_SKILL_DELAYTIME ) ); return; } } //Use 소환수 if( IsSummon( pMsg->caster_handle ) && m_pGame ) { SGameAvatarEx * pCreature = (SGameAvatarEx *)m_pGame->GetGameObject( pMsg->caster_handle ); if( !pCreature ) return; if( pCreature->IsMount() || pCreature->IsMountMode() ) { m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_RIDING_IMPASSABLE ) ); return; } SGameAvatarEx * pTarget = CheckSkillTarget( pSkill, pCreature, true ); // 타겟이 필요한데 타겟이 없는 경우만 체크.. if( !pTarget ) { pTarget = (SGameAvatarEx*)m_pGame->GetGameObject( pMsg->target_handle ); if( !pTarget ) { m_pGame->AddChatMessage( GetStringDB().GetString( 318 ) ); // 타겟을 먼저 지정해 주십시오. return; } } SetSkillInputData( pCreature, pTarget, pSkill, pMsg ); return; } //로컬 플레이어 if( !GetLocalPlayer() || GetLocalPlayer()->GetArID() != pMsg->caster_handle ) return; //로컬 캐릭터가 없거나, 로컬 캐릭터 ID 아니면... if( pMsg->nSkillID==4001 || pMsg->nSkillID==4002 ) { int nSlot = m_CreatureSlotMgr.GetEquipedCardIndex( pMsg->summon_card_handle ) + 1; int nMaxSlot = m_SkillSlotMgr.GetCurrentSkillLevel( 1801 ); if (nSlot > nMaxSlot) { m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_POINT_TARGET ) ); return; } if( pMsg->summon_card_handle == NULL ) { m_pGame->AddChatMessage( S( 378 ) ); return; } } //이건 테스트 스킬 아이디 인데 나중에 DB 바뀌면 바꿔야할듯 //새크리 파이스 크리처 스킬 if(pMsg->nSkillID == 9503) { //소환된 크리처가 없으면 안된다 if(m_vSummonList.empty()) { m_pGame->AddChatMessage( S(390) ); return; } } if( !pSkill ) { m_pGame->AddChatMessage( S(388) ); return; } SGameAvatarEx * pLocal = GetLocalPlayer(); if( !pLocal ) return; if( pSkill->IsPassive() ) { m_pGame->AddChatMessage( S(391) ); return; } if( pSkill->IsHarmful() ) { //1:대상에게 해로운 스킬 } else { //0:대상에게 이로운 스킬 } SGameAvatarEx * pTarget = CheckSkillTarget( pSkill, pLocal, true ); // 타겟이 필요한데 타겟이 없는 경우만 체크.. if( !pTarget ) { // MJ 2004/11/08 타겟이 필요한 스킬의 경우, 타겟이 없을 경우 경고해준다 // _oprint( "Error Content : 타겟이 없다...\n" ); // m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_USE_SKILL_NEED_TARGET ) ); // 타겟을 먼저 지정해 주십시오. return; } //시체대상 if( pSkill->IsValidToCorpse() ) { if( pTarget->IsLive() ) { m_pGame->AddChatMessage( S(392) ); return; } } /// 2011.09.27 대련, 데스매치 중에 사용 가능 체크 if (GetPVPStart() || pLocal->IsInDeathMatch()) { if (!enableUseSkillAtPVP(pSkill)) { m_pGame->AddChatMessage( S(290) ); return ; } } //장착 무기 제한 0:사용불가 // 1:사용가능 //방패 전용 ? //사용가능/불가/강제공격 처리 : 자신 파티원 길드원 중립 PK시 중립 적 //대상종류 제한 : 아바타 크리처 몬스터 //현재 스킬에 맞는 무기를 갖고 있는가?? ItemBase::ItemCode itemcode = pLocal->GetItemCode( ItemBase::WEAR_WEAPON ); //장착 한 무기 아이템 코드 얻기 ItemBase::ItemCode itemcode2 = pLocal->GetItemCode( ItemBase::WEAR_SHIELD ); //방패를 끼고 있는가?, 장착 한 방패 아이템 코드 얻기 ItemBase::ItemClass nItemClass = GetItemDB().GetClassID( itemcode ); //장착한 무기의 클래스 얻기 ItemBase::ItemClass nItemClass2 = GetItemDB().GetClassID( itemcode2 ); //장착한 무기의 클래스 얻기 ItemBase::ItemClass nDoubleWeapon = ItemBase::CLASS_ETC; <<<<<<< HEAD if( nItemClass == ItemBase::CLASS_DAGGER && nItemClass2 == ItemBase::CLASS_DAGGER ) nDoubleWeapon = ItemBase::CLASS_DOUBLE_DAGGER; //단검 이도 else if( nItemClass == ItemBase::CLASS_ONEHAND_SWORD && nItemClass2 == ItemBase::CLASS_ONEHAND_SWORD ) nDoubleWeapon = ItemBase::CLASS_DOUBLE_SWORD; //검 이도류 else if( nItemClass == ItemBase::CLASS_ONEHAND_AXE && nItemClass2 == ItemBase::CLASS_ONEHAND_AXE ) nDoubleWeapon = ItemBase::CLASS_DOUBLE_AXE; //도끼 이도류 if (nItemClass == ItemBase::CLASS_CROSSBOW && nItemClass2 == ItemBase::CLASS_CROSSBOW) // Double Crossbow ======= if (nItemClass == ItemBase::CLASS_DAGGER && nItemClass2 == ItemBase::CLASS_DAGGER) nDoubleWeapon = ItemBase::CLASS_DOUBLE_DAGGER; //단검 이도류 else if (nItemClass == ItemBase::CLASS_ONEHAND_SWORD && nItemClass2 == ItemBase::CLASS_ONEHAND_SWORD) nDoubleWeapon = ItemBase::CLASS_DOUBLE_SWORD; //검 이도류 else if (nItemClass == ItemBase::CLASS_ONEHAND_AXE && nItemClass2 == ItemBase::CLASS_ONEHAND_AXE) nDoubleWeapon = ItemBase::CLASS_DOUBLE_AXE; //도끼 이도류 else if (nItemClass == ItemBase::CLASS_CROSSBOW && nItemClass2 == ItemBase::CLASS_CROSSBOW) // From ZONE source; dual crossbows >>>>>>> a34328224e914a577b99c79ec6e8ffbcea554a05 nDoubleWeapon = ItemBase::CLASS_DOUBLE_CROSSBOW; if( pSkill->IsNeedWeapon() ) { //방패 전용 스킬임. if( pSkill->IsNeedShield() ) { if( nItemClass2 != ItemBase::CLASS_SHIELD ) { m_pGame->AddChatMessage( GetStringDB().GetString( 317 ) );//현재 장착중인 무기로는 해당 스킬을 사용할 수 없습니다. return; } itemcode = itemcode2; } else { // Cannot use bare hands // Exception handling for dual short swords // Exception handling for dual wield // Can it be used with the current weapon? if( nItemClass < 0 || !pSkill->IsUseableWeapon( nItemClass ) ) { if( nDoubleWeapon == ItemBase::CLASS_ETC || !pSkill->IsUseableWeapon( nDoubleWeapon ) ) { _oprint("[if( nDoubleWeapon == ItemBase::CLASS_ETC || !pSkill->IsUseableWeapon( nDoubleWeapon ) )]\n"); //m_pGame->AddChatMessage("if( nDoubleWeapon == ItemBase::CLASS_ETC || !pSkill->IsUseableWeapon( nDoubleWeapon ) )"); m_pGame->AddChatMessage( GetStringDB().GetString( 317 ) );//현재 장착중인 무기로는 해당 스킬을 사용할 수 없습니다. return; } } } } //리저렉션 일경우 파티원 및 자신의 크리처에게만 사용가능 if( pMsg->nSkillID == 3205 ) { //내 크리처 인지 검사 if( !IsLocalCreature( pTarget->GetArID() ) ) { //파티원 인지 검사 if( !m_PartyMgr.FindMember( pTarget->GetArID() ) ) { //파티원의 크리처 인지 검사 if( pTarget->GetObjType() == TS_ENTER::GAME_SUMMON ) { if( !m_PartyMgr.FindMember( pTarget->GetMaster() ) ) { m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_POINT_TARGET ) ); return; } } else { m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_POINT_TARGET ) ); return; } } } } SetSkillInputData( pLocal, pTarget, pSkill, pMsg ); } bool SGameSystem::OnMsgUseSkill_by_toggle( struct SIMSG_UI_ACT_USESKILL_BY_TOGGLE* pMsg ) { //크리처만 적용시키자 ( 나중에 필요하면 플레이어도 ) SkillBaseEx * pSkill = GetSkillDB().GetSkillData( pMsg->nSkillID ); if( !pSkill ) return false; if( !pSkill->IsValid() ) { return false; } if( IsSummon( pMsg->caster_handle ) ) { if( m_CreatureSkillSlotMgr.CheckCoolTime( pMsg->nSkillID, pMsg->caster_handle ) ) return false; } else { //스킬 쿨타임 체크 if( m_SkillSlotMgr.CheckCoolTime( pMsg->nSkillID ) ) return false; } //Use 소환수 if( IsSummon( pMsg->caster_handle ) && m_pGame ) { SGameAvatarEx * pCreature = (SGameAvatarEx *)m_pGame->GetGameObject( pMsg->caster_handle ); if( !pCreature ) return false; // 2008. 6. 18 floyd #2.3.1.23 // http://bug.nflavor.com/view.php?id=2868 // 아바타가 대상을 타겟하지 않으면, 크리쳐는 스킬 자동공격을 하지 않는 문제 관련 수정 // 기본적으로 SGameSystem::GetTarget()을 대상으로 인식하던 것을 타겟핸들을 받도록 수정 SGameAvatarEx * pTarget = CheckSkillTarget( pSkill, pCreature, false, pCreature->GetCurrTarget() ); // 타겟이 필요한데 타겟이 없는 경우만 체크.. if( !pTarget ) { pTarget = (SGameAvatarEx*)m_pGame->GetGameObject( pMsg->target_handle ); if( !pTarget ) return false; } SetSkillInputData( pCreature, pTarget, pSkill, pMsg ); return true; } return false; } void SGameSystem::OnMsgUseItem( struct SIMSG_UI_ACT_USEITEM* pMsg ) { SGameAvatarEx * pLocal = GetLocalPlayer(); if( !pLocal ) return; SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo(pMsg->m_hItemHandle); if( pSlot ) { const ItemBaseEx_info * pItemInfo = GetItemDB().GetItemData( pSlot->GetItemCode() ); if( pItemInfo ) { if( pItemInfo->nOptType[0] == 5 ) //스킬 호출형이면 { if( pLocal->IsStateRide() || pLocal->CurrentlyAnimationIsMount() ) { if( m_pGame ) m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_RIDING_IMPASSABLE ) ); return; } } // 캐릭터가 앉은 상태고, 앉아 있는 상태에서 사용 불가능한 아이템일 경우 if ( (pLocal->GetStatus() & TS_ENTER::PlayerInfo::FLAG_SITDOWN ) && pItemInfo->CheckFlag( ItemBase::FLAG_SIT ) ) { if( m_pGame ) m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_CHA_SITWARNIG ) ); return; } } else // 아이템이 아닌가봐 { if( m_pGame ) m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_USE_ITEM_FAIL ) ); return; } } //타겟 필요 없다 자신한테 사용 if( !pMsg->m_bNeedTarget ) { if( pMsg->m_bIsPosition ) { TS_CS_USE_ITEM msg; msg.target_handle = pMsg->m_hTargetHandle; msg.item_handle = pMsg->m_hItemHandle; m_pGame->SendMsg( &msg ); } else { SInputUseItem inupt( 0, pMsg->m_hItemHandle, 0, 0, 0, pMsg->m_strParameter.c_str() ); AddGameInput( &inupt ); } return; } SkillBaseEx * pSkill = GetSkillDB().GetSkillData( pMsg->m_nSkillID ); if( pSkill == NULL ) { //그냥 서버에 요청 SInputUseItem inupt( pMsg->m_hTargetHandle, pMsg->m_hItemHandle, pMsg->m_fUseRange, pMsg->m_nSkillID, pMsg->m_hItemUseTargetHandle, pMsg->m_strParameter.c_str() ); AddGameInput( &inupt ); return; } //타겟이 0이라면 해당 아이템이 타겟을 필요로 하는지 검사한다 if( pMsg->m_hTargetHandle == 0 ) { //타겟이 필요한 아이템이라면 if( pSkill->IsNeedTarget() ) { SGameAvatarEx * pTarget = CheckSkillTarget( pSkill, pLocal, false ); if( pTarget == NULL ) { //타겟을 지정해주셔요~~~ m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_USE_SKILL_NEED_TARGET ) ); return; } pMsg->m_hTargetHandle = pTarget->GetArID(); } else//자신한테 사용하자 { SInputUseItem inupt( 0, pMsg->m_hItemHandle, 0, 0, 0, pMsg->m_strParameter.c_str() ); AddGameInput( &inupt ); return; } } if( pSkill->IsNeedTarget() ) { SGameAvatarEx * pTarget = CheckSkillTarget( pSkill, pLocal, true, pMsg->m_hTargetHandle ); if( !pTarget ) { //타겟을 지정해주셔요~~~ m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_USE_SKILL_NEED_TARGET ) ); return; } pMsg->m_hTargetHandle = pTarget->GetArID(); } //부활 주문서 일경우 파티원 및 자신의 크리처에게만 사용가능 if( pMsg->m_nSkillID == 6001 ) { //내 크리처 인지 검사 if( !IsLocalCreature( pMsg->m_hTargetHandle ) ) { //파티원 인지 검사 if( !m_PartyMgr.FindMember( pMsg->m_hTargetHandle ) ) { //파티원의 크리처 인지 검사 SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pGame->GetGameObject( pMsg->m_hTargetHandle ); if( pTarget && pTarget->GetObjType() == TS_ENTER::GAME_SUMMON ) { if( !m_PartyMgr.FindMember( pTarget->GetMaster() ) ) { m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_POINT_TARGET_ITEM ) ); return; } } else { m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_POINT_TARGET_ITEM ) ); return; } } } } SInputUseItem input( pMsg->m_hTargetHandle, pMsg->m_hItemHandle, pMsg->m_fUseRange, pMsg->m_nSkillID, pMsg->m_hItemUseTargetHandle, pMsg->m_strParameter.c_str() ); AddGameInput( &input ); } void SGameSystem::OnMsgSoulstoneCraft( struct SIMSG_UI_SOULSTONE_CRAFT* pMsg) { TS_CS_SOULSTONE_CRAFT msg; msg.craft_item_handle = pMsg->craft_item_handle; for( int i(0); isoulstone_handle[i]; } msg.size = sizeof(msg); msg.set_check_sum(); if( m_pGame ) m_pGame->SendMsg( &msg ); } void SGameSystem::OnMsgRepairSoulstone( struct SIMSG_UI_REPAIR_SOULSTONE* pMsg ) { TS_CS_REPAIR_SOULSTONE msg; for( int i(0); iitem_handle[i]; } msg.size = sizeof(msg); msg.set_check_sum(); if( m_pGame ) m_pGame->SendMsg( &msg ); } void SGameSystem::OnMsgRequestRemoveState( struct SIMSG_REQUEST_REMOVE_STATE* pMsg ) { TS_CS_REQUEST_REMOVE_STATE msg; msg.target = pMsg->target; msg.state_code = pMsg->m_nState; msg.size = sizeof(msg); msg.set_check_sum(); if( m_pGame ) m_pGame->SendMsg( &msg ); } void SGameSystem::OnMsgMsgReqChangeItemPosition( struct SIMSG_REQ_CHANGE_ITEM_POSITION* pMsg ) { TS_CS_CHANGE_ITEM_POSITION msg; msg.is_storage = pMsg->is_storage; msg.item_handle_1 = pMsg->item_handle_1; msg.item_handle_2 = pMsg->item_handle_2; msg.size = sizeof(msg); msg.set_check_sum(); if( m_pGame ) m_pGame->SendMsg( &msg ); } // { [sonador][3.1.2] 경매장 구현 void SGameSystem::OnMsgReqAuctionSearch( struct SIMSG_REQ_AUCTION_SEARCH* pMsg ) { TS_CS_AUCTION_SEARCH msg; msg.category_id = pMsg->category_id; // 3.1.5 검색 카테고리 수정.sonador msg.sub_category_id = pMsg->sub_category_id; // 3.1.5 검색 카테고리 수정.sonador msg.page_num = pMsg->page_num; ::strncpy( msg.keyword, pMsg->keyword.c_str( ), 31 ); msg.size = sizeof( msg ); msg.is_equipable = pMsg->is_equipable; // 2010.08.27 - prodongi msg.set_check_sum( ); if( m_pGame ) m_pGame->SendMsg( &msg ); } void SGameSystem::OnMsgReqAuctionSellingList( struct SIMSG_REQ_AUCTION_SELLING_LIST* pMsg ) { TS_CS_AUCTION_SELLING_LIST msg; msg.page_num = pMsg->page_num; msg.size = sizeof( msg ); msg.set_check_sum( ); if( m_pGame ) m_pGame->SendMsg( &msg ); } void SGameSystem::OnMsgReqAuctionBiddedList( struct SIMSG_REQ_AUCTION_BIDDED_LIST* pMsg ) { TS_CS_AUCTION_BIDDED_LIST msg; msg.page_num = pMsg->page_num; msg.size = sizeof( msg ); msg.set_check_sum( ); if( m_pGame ) m_pGame->SendMsg( &msg ); } void SGameSystem::OnMsgReqAuctionBid( struct SIMSG_REQ_AUCTION_BID* pMsg ) { TS_CS_AUCTION_BID msg; msg.auction_uid = pMsg->auction_uid; msg.bidding_price = pMsg->bidding_price.getAmount(); msg.size = sizeof( msg ); msg.set_check_sum( ); if( m_pGame ) m_pGame->SendMsg( &msg ); } void SGameSystem::OnMsgReqAuctionInstantPurchase( struct SIMSG_REQ_AUCTION_INSTANT_PURCHASE* pMsg ) { TS_CS_AUCTION_INSTANT_PURCHASE msg; msg.auction_uid = pMsg->auction_uid; msg.size = sizeof( msg ); msg.set_check_sum( ); if( m_pGame ) m_pGame->SendMsg( &msg ); } void SGameSystem::OnMsgReqAuctionRegister( struct SIMSG_REQ_AUCTION_REGISTER* pMsg ) { TS_CS_AUCTION_REGISTER msg; msg.item_handle = pMsg->item_handle; msg.item_count = pMsg->item_count.getAmount(); msg.start_price = pMsg->start_price.getAmount(); msg.instant_purchase_price = pMsg->instant_purchase_price.getAmount(); msg.duration_type = pMsg->duration_type; msg.size = sizeof( msg ); msg.set_check_sum( ); if( m_pGame ) m_pGame->SendMsg( &msg ); } void SGameSystem::OnMsgReqAuctionCancel( struct SIMSG_REQ_AUCTION_CANCEL* pMsg ) { TS_CS_AUCTION_CANCEL msg; msg.auction_uid = pMsg->auction_uid; msg.size = sizeof( msg ); msg.set_check_sum( ); if( m_pGame ) m_pGame->SendMsg( &msg ); } void SGameSystem::OnMsgReqAuctionItemKeepingList( struct SIMSG_REQ_AUCTION_ITEM_KEEPING_LIST* pMsg ) { TS_CS_ITEM_KEEPING_LIST msg; msg.page_num = pMsg->page_num; msg.size = sizeof( msg ); msg.set_check_sum( ); if( m_pGame ) m_pGame->SendMsg( &msg ); } void SGameSystem::OnMsgReqAuctionItemKeepingTake( struct SIMSG_REQ_AUCTION_ITEM_KEEPING_TAKE* pMsg ) { TS_CS_ITEM_KEEPING_TAKE msg; msg.keeping_uid = pMsg->keeping_uid; msg.size = sizeof( msg ); msg.set_check_sum( ); if( m_pGame ) m_pGame->SendMsg( &msg ); } // } [sonador][3.1.2] 경매장 구현 // sonador 10.2.1 팻 시스템 구현 void SGameSystem::OnMsgReqSetPetName( struct SIMSG_REQ_SET_PET_NAME* pMsg ) { TS_CS_SET_PET_NAME msg; msg.handle = pMsg->handle; ::strcpy_s( msg.name, pMsg->name.c_str() ); msg.set_check_sum(); if( m_pGame ) m_pGame->SendMsg( &msg ); } // sonador 1.9.1 인벤토리 및 창고 정렬 기능 구현 void SGameSystem::OnMsgReqArrangeItem( struct SIMSG_REQ_ARRANGE_ITEM* pMsg ) { TS_CS_ARRANGE_ITEM msg; msg.bIsStorage = pMsg->bIsStorage; msg.size = sizeof( msg ); msg.set_check_sum(); if( m_pGame ) m_pGame->SendMsg( &msg ); } void SGameSystem::SetCurSkill( int nSkillID ) { m_SkillSlotMgr.SetCurSkill( nSkillID ); //현재 스킬 초기화 } //Local 명령어 //명령 사용, 앉기, 서기, 등등 void SGameSystem::OnMsgUseCommand ( struct SIMSG_UI_ACT_USECOMMAND* pMsg ) { SGameAvatarEx * pPlayer = GetLocalPlayer(); if( !pPlayer ) return; if( !pPlayer->IsLive() ) return; switch(pMsg->nCmdID) { case MOTION_ATTACK: // 공격 { SGameAvatarEx * pTarget = GetTarget(); if( pTarget && m_pGame->IsAttack(pTarget) ) { // if( !WeightConfirmationTheBeforeAttacking() ) return; SInputAttack inputAttack( pTarget->GetArID() ); AddGameInput( &inputAttack ); //pPlayer->SetAttackObject( pTarget ); m_pGame->SetPlayerAttack( pTarget ); } } break; case MOTION_STANDUP: // 앉기, 서기 { if( pPlayer->IsMountMode() ) { // TODO : 메시지 추가해야함 임시로 추가 m_pGame->AddChatMessage( S(367) ); return; } if( pPlayer->GetStatus() & TS_ENTER::PlayerInfo::FLAG_SITDOWN ) { m_pGame->ProcMsgAtStatic( &SIMSG_UI_SEND_DATA( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_STORE_HOST, "stand_up" ) ); SInputSitUp inputSitUp; pPlayer->OnInput( &inputSitUp ); } else if( pPlayer->GetCurrAnimationID() != ANI_SITUP ) { SInputSit inputSit; pPlayer->OnInput( &inputSit ); } } break; case MOTION_COMBINE: // 조합 앉아라 명령 { if( pPlayer->IsMountMode() ) { // TODO : 메시지 추가해야함 임시로 추가 m_pGame->AddChatMessage( S(367) ); return; } // 조합은 앉지 않는것으로 수정. kappamind, 2010.01.08 //SInputSit inputSit; //pPlayer->OnInput( &inputSit ); } break; case MOTION_BOOTH: // 노점 앉아라 명령 { //노점 가능한지 서버에 요청 if( m_pGame ) { TS_CS_CHECK_BOOTH_STARTABLE msg; m_pGame->SendMsg( &msg ); } } break; case MOTION_PICKUP: // 줍기 { float fDist = 0.f; SGameObject * pItem = m_pGame->GetItemObject( *pPlayer->GetPosition(), fDist, -1, ITEM_TAKE_RANGE ); // sonador #2.1.2.4.3 팻 조작 UI 연동 if( pItem ) { // if( pPlayer->GetCurrAnimationID() != ANI_PICKUP01 ) { SInputTakeItem inputTakeItem( pItem->GetArID(), fDist ); pPlayer->OnInput( &inputTakeItem ); } //m_pGame->StartSound( "item_pickup_etc.wav" ); } } break; case MOTION_PKMODE: { if (pPlayer->GetStatus() & TS_ENTER::PlayerInfo::FLAG_PK_ON) { TS_CS_TURN_OFF_PK_MODE msg; m_pGame->SendMsg(&msg); } else { TS_CS_TURN_ON_PK_MODE msg; m_pGame->SendMsg(&msg); } /* if( pPlayer->GetStatus() & TS_ENTER::PlayerInfo::FLAG_PK_ON ) { m_pGame->Rq_ChagePKMode(false); } else { if( !m_pGame->Rq_ChagePKMode(true) ) m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_PKMODE_IMPOSSIBLE ) ); } */ } break; case MOTION_RUN:// 걷기, 뛰기 { if( pPlayer->GetStatus() & TS_ENTER::PlayerInfo::FLAG_WALKING ) Rq_Chatting( CHAT_NORMAL, NULL, "/run" ); else Rq_Chatting( CHAT_NORMAL, NULL, "/walk on" ); } break; case MOTION_MOUNT: //타기 내리기 { CheckPossibilityCreatureMount( pPlayer ); } break; case MOTION_CAST_CANCEL: { SInputCastCancel inputCastCancel; pPlayer->OnInput( &inputCastCancel ); //캐스팅 캔슬 명령이 내려졌다면 이전 상태를 IDLE로 바꿔준다 if( pPlayer->IsCasting() || pPlayer->IsAttack() ) pPlayer->SetDefaultPrevState(); SetCreatureCastCancel( m_CreatureSlotMgr.GetSelectSummonCreature() ); } break; case MOTION_ASSIST: { Rq_Chatting( CHAT_NORMAL, NULL, "/어시스트" ); } break; case MOTION_PICKUP_CARD: // 카드 줍기 { float fDist = 0.f; SGameObject * pItem = m_pGame->GetItemObject( *pPlayer->GetPosition(), fDist, ItemBase::TYPE_CARD, ITEM_TAKE_RANGE ); // sonador #2.1.2.4.3 팻 조작 UI 연동 if( pItem ) { // if( pPlayer->GetCurrAnimationID() != ANI_PICKUP01 ) { SInputTakeItem inputTakeItem( pItem->GetArID(), fDist ); pPlayer->OnInput( &inputTakeItem ); } //m_pGame->StartSound( "item_pickup_etc.wav" ); } } break; case CREATURE_ATTACK: { //크리쳐 공격 SGameAvatarEx * pTarget = GetTarget(); if( pTarget && m_pGame->IsAttack(pTarget) ) { // 2010.08.03 소환된 크리처는 모두 공격하도록 - prodongi //SetCreatureAttack( pTarget, m_CreatureSlotMgr.GetSelectSummonCreature() ); int count = m_CreatureSlotMgr.GetSummonedCreatureCount(); for (int i = 0; i < count; ++i) SetCreatureAttack(pTarget, m_CreatureSlotMgr.GetSummonedCreature(i)); } } break; case CREATURE_BACKDOWN: { //크리쳐 퇴각 // 2010.08.03 입력 변수는 쓰이지 않는다- prodongi //SetCreatureBackDown( m_CreatureSlotMgr.GetSelectSummonCreature() ); SetCreatureBackDown( ); } break; case CREATURE_ALLATTACK: { //합동 공격 SGameAvatarEx * pTarget = GetTarget(); if( pTarget && m_pGame->IsAttack(pTarget) ) { // if( !WeightConfirmationTheBeforeAttacking() ) return; SInputAttack inputAttack( pTarget->GetArID() ); AddGameInput( &inputAttack ); m_pGame->SetPlayerAttack( pTarget ); SetCreatureAttack( pTarget ); //크리처 전체 } } break; } } void SGameSystem::CheckPossibilityCreatureMount( SGameAvatarEx* pPlayer ) { // 올라타거나 내려오는 중이면 return if( pPlayer->IsMount() ) return; //크리처 탑승 불 가능한 지역 if( !m_pGame->CheckPlayerMountLocation() ) { m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_CREATURE_MOUNT_DUNGEON ) ); return; } // 완전 올라탄 상태 이거나 완전 내려온 상태 if( pPlayer->IsMountMode() ) { SGameAvatarEx* pCreature = (SGameAvatarEx*)m_pGame->GetGameObject( pPlayer->GetCreatureMountHandle() ); if( pCreature ) { if( pPlayer->IsMoving() || pCreature->IsMoving() ) { //이동 중 불가능 m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_CHA_MOVING ) ); return; } } if( pPlayer->IsMoving() ) { //이동 중 불가능 m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_CHA_MOVING ) ); return; } if( !pPlayer->CurrentlyAnimationIsMount() ) { SInputUnMount InputUnMount; pPlayer->OnInput( &InputUnMount ); } } else { if( !pPlayer->CurrentlyAnimationIsUnMount() ) { if( m_vSummonList.empty() ) { //탑승하려면 먼저 크리처를 소환하시오 m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_CREATURE_NEEDS_SUMMON ) ); return; } SGameAvatarEx* pCreature = NULL; int nCreatureCnt = (int)m_vSummonList.size(); if( nCreatureCnt == 1 ) { //소환된넘이 1마리면 타겟이 누가 됐든 자동으로 메인 크리처에 올라타게 된다 pCreature = m_vSummonList[0]; } else if( nCreatureCnt > 1 ) { //소환된넘이 2마리이고 타겟이 존재 하고 타겟이 소환된 2마리중 한넘이라면 //소환된넘이 2마리이고 타겟은 존재 하지만 소환된 크리처 2마리중 일치하는 넘이 없다면 자동으로 메인 크리처에 올라타게 된다 SGameAvatarEx* pTarget = GetTarget(); if( pTarget && pTarget->GetObjType() == TS_ENTER::GAME_SUMMON ) { if( pTarget->GetArID() == m_vSummonList[0]->GetArID() ) pCreature = m_vSummonList[0]; else if( pTarget->GetArID() == m_vSummonList[1]->GetArID() ) pCreature = m_vSummonList[1]; else pCreature = m_vSummonList[0]; } //소환된넘이 2마리이고 타겟이 존재 하지 않는다면 자동으로 메인 크리처에 올라타게 된다 else { pCreature = m_vSummonList[0]; } } if( pCreature ) { if( GetCreatureDB().IsPossibilityCreatureMount( pCreature->GetContentID() ) == false ) { //탑승 가능한 소환수가 존재 하지 않는다 m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_CREATURE_MOUNT_IMPOSSIBLE ) ); return; } if( pCreature->IsMoving() || pPlayer->IsMoving() ) { //이동 중 불가능 m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_CHA_MOVING ) ); return; } if( pCreature->IsDead() ) { //탑승 가능한 소환수가 존재 하지 않는다 m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_CREATURE_MOUNT_IMPOSSIBLE ) ); return; } float fDistance = GetDistance( pPlayer->GetCurPosWithChangeDir(), pCreature->GetCurPosWithChangeDir() ); if( fDistance <= (float)GameRule::DEFAULT_UNIT_SIZE * 3 ) //3미터 { SInputMount InputMount; pPlayer->OnInput( &InputMount ); } else { //소환수와 멀리 떨어져 있다 m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_CREATURE_MOUNT_IMPOSSIBLE_NEAR ) ); } } else { //탑승하려면 먼저 크리처를 소환하시오 m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_CREATURE_NEEDS_SUMMON ) ); return; } } } } void SGameSystem::OnMsgAttack( struct SMSG_ATTACK* pMsg ) { if( pMsg->attack_flag & TS_ATTACK_EVENT::ATTACK_FLAG_BOW || pMsg->attack_flag & TS_ATTACK_EVENT::ATTACK_FLAG_CROSS_BOW ) { if( pMsg->attack_action == TS_ATTACK_EVENT::ATTACK_AIMING ) { if( pMsg->attacker_handle == GetLocalPlayer()->GetArID() ) { m_MotionMgr.SetCastingMotion( MOTION_ATTACK, true ); } } else if ( pMsg->attack_action == TS_ATTACK_EVENT::ATTACK_ATTACK ) { if( pMsg->attacker_handle == GetLocalPlayer()->GetArID() ) { m_MotionMgr.AddCooling( MOTION_ATTACK ); m_MotionMgr.SetShootingMotion( MOTION_ATTACK, true, pMsg->attack_speed ); AddStatusAction( pMsg->attacker_handle, pMsg->target_handle ); } } else if ( pMsg->attack_action == TS_ATTACK_EVENT::ATTACK_END || pMsg->attack_action == TS_ATTACK_EVENT::ATTACK_CANCEL ) { if( pMsg->attacker_handle == GetLocalPlayer()->GetArID() ) { m_MotionMgr.AddCooling( MOTION_ATTACK ); m_MotionMgr.SetCastingMotion( MOTION_ATTACK, false ); } } } else { //기냥 어택 AddStatusAction( pMsg->attacker_handle, pMsg->target_handle ); } } void SGameSystem::OnMsgAttackDouble( struct SMSG_ATTACK_DOUBLE* pMsg ) { AddStatusAction( pMsg->attacker_handle, pMsg->target_handle ); } void SGameSystem::OnMsgActItemCombine( struct SIMSG_UI_ACT_ITEMCOMBINE* pMsg) { if( pMsg->vtItems.empty() ) return; TS_CS_MIX msg; //Main Item msg.main_item.count = pMsg->main_Items.uiCount; msg.main_item.handle = pMsg->main_Items.hItem; msg.count = (int)pMsg->vtItems.size(); msg.size += (sizeof(TS_CS_MIX::MIX_INFO)*msg.count); msg.set_check_sum(); char * pMix = new char[ sizeof(TS_CS_MIX) + (msg.count * sizeof(TS_CS_MIX::MIX_INFO)) ]; memcpy( pMix, &msg, sizeof(TS_CS_MIX) ); char* pDes = pMix + sizeof(TS_CS_MIX); for( int i(0); msg.count>i; i++ ) { memcpy( pDes, &pMsg->vtItems[i], sizeof(TS_CS_MIX::MIX_INFO) ); pDes += sizeof(TS_CS_MIX::MIX_INFO); } if( m_pGame ) m_pGame->SendMsg( (TS_CS_MIX*)pMix ); delete [] pMix; } // 기부 아이템 보내기 void SGameSystem::OnMsgActItemContribution( struct SIMSG_UI_ACT_ITEMCONTRIBUTION* pMsg) { if( pMsg->vtItems.empty() && pMsg->n64_Gold == 0 && pMsg->jp == 0) return; TS_CS_DONATE_ITEM msg; msg.item_count = (int)pMsg->vtItems.size(); msg.gold = pMsg->n64_Gold; msg.jp = pMsg->jp; msg.size += ( sizeof(TS_CS_DONATE_ITEM::DonateItemInfo)*msg.item_count ); msg.set_check_sum(); char * pDonate = new char[ sizeof(TS_CS_DONATE_ITEM) + (msg.item_count * sizeof(TS_CS_DONATE_ITEM::DonateItemInfo)) ]; memcpy( pDonate, &msg, sizeof(TS_CS_DONATE_ITEM) ); char* pDes = pDonate + sizeof(TS_CS_DONATE_ITEM); for( int i(0); msg.item_count>i; i++ ) { memcpy( pDes, &pMsg->vtItems[i], sizeof(TS_CS_DONATE_ITEM::DonateItemInfo) ); pDes += sizeof(TS_CS_DONATE_ITEM::DonateItemInfo); } if( m_pGame ) m_pGame->SendMsg( (TS_CS_DONATE_ITEM*)pDonate ); delete [] pDonate; } // 보상 아이템 받기 void SGameSystem::OnMsgActRequestRewardItem( struct SIMSG_UI_ACT_REQUESTREWARDITEM* pMsg) { TS_CS_DONATE_REWARD msg; msg .reward_count = 0; for( int i=0; i<4; ++i ) { if( pMsg->nRewardCount[i] > 0 ) msg.reward_count++; } msg.size += ( sizeof(TS_CS_DONATE_REWARD::RewardInfo)*msg.reward_count ); msg.set_check_sum(); char * pRequest = new char[ sizeof(TS_CS_DONATE_REWARD) + (msg.reward_count * sizeof(TS_CS_DONATE_REWARD::RewardInfo)) ]; memcpy( pRequest, &msg, sizeof(TS_CS_DONATE_REWARD) ); char* pDes = pRequest + sizeof(TS_CS_DONATE_REWARD); for( int i = 0; i < 4; i++ ) { if( pMsg->nRewardCount[i] > 0 ) { TS_CS_DONATE_REWARD::RewardInfo rewardInfo; rewardInfo.reward_type = i; rewardInfo.count = pMsg->nRewardCount[i]; memcpy( pDes, &rewardInfo, sizeof(TS_CS_DONATE_REWARD::RewardInfo) ); pDes += sizeof(TS_CS_DONATE_REWARD::RewardInfo); } } if( m_pGame ) m_pGame->SendMsg( (TS_CS_DONATE_REWARD*)pRequest ); delete [] pRequest; } void SGameSystem::OnMsgActBuyItemsFromStore( struct SIMSG_UI_ACT_BUYITEMS_FROM_STORE* pMsg ) { char *pBuf = new char[ sizeof(TS_CS_BUY_FROM_BOOTH) + sizeof(TS_ITEM_BASE_INFO)*pMsg->vList.size() ]; TS_CS_BUY_FROM_BOOTH msg; msg.target = pMsg->hTarget; msg.cnt = pMsg->vList.size(); msg.size += sizeof(TS_ITEM_BASE_INFO)*pMsg->vList.size(); memcpy( pBuf, &msg, sizeof(TS_CS_BUY_FROM_BOOTH) ); TS_CS_BUY_FROM_BOOTH *pSendMsg = reinterpret_cast< TS_CS_BUY_FROM_BOOTH * >( pBuf ); TS_ITEM_BASE_INFO *pInfo = reinterpret_cast< TS_ITEM_BASE_INFO * >( pSendMsg+1 ); for( size_t idx = 0; idx < pMsg->vList.size(); ++idx ) { *pInfo = pMsg->vList[idx]; pInfo++; } pSendMsg->set_check_sum(); if( m_pGame ) m_pGame->SendMsg( pSendMsg ); delete [] pBuf; } void SGameSystem::OnMsgActSellItemsToStore( struct SIMSG_UI_ACT_SELLITEMS_TO_STORE* pMsg ) { int MsgCount = pMsg->vList.size(); for( int i(0); ivList[i].target; msg.item_handle = pMsg->vList[i].item_handle; msg.cnt = pMsg->vList[i].cnt.getAmount(); memcpy( pBuf, &msg, sizeof(TS_CS_SELL_TO_BOOTH) ); TS_CS_SELL_TO_BOOTH *pSendMsg = reinterpret_cast< TS_CS_SELL_TO_BOOTH * >( pBuf ); pSendMsg->set_check_sum(); if( m_pGame ) m_pGame->SendMsg( pSendMsg ); delete [] pBuf; } } void SGameSystem::OnMsgActBuyItems( struct SIMSG_UI_ACT_BUYITEMS* pMsg ) { for( std::vector::const_iterator itItem = pMsg->vtBuyItems.begin(); itItem != pMsg->vtBuyItems.end(); itItem++ ) { TS_CS_BUY_ITEM msgBuy; msgBuy.item_code = (*itItem).item_code; msgBuy.buy_count = (*itItem).buy_count.getAmount(); if( m_pGame ) m_pGame->SendMsg( &msgBuy ); } } void SGameSystem::OnMsgActSellItems( struct SIMSG_UI_ACT_SELLITEMS* pMsg ) { for( std::vector::const_iterator itItem = pMsg->vtSellItems.begin(); itItem != pMsg->vtSellItems.end(); itItem++ ) { TS_CS_SELL_ITEM msgSell; msgSell.handle = (*itItem).handle; msgSell.sell_count = (*itItem).sell_count.getAmount(); if( m_pGame ) m_pGame->SendMsg( &msgSell ); } } void SGameSystem::OnMsgResult ( SMSG_RESULT* pMsg ) { //채팅 창에 뿌릴 수 있는 데이타 만들자~ switch( pMsg->request_msg_id ) { case TM_CS_TAKE_ITEM : { if( pMsg->result == RESULT_SUCCESS ) { if( GetLocalPlayer() ) m_pGame->StartSound( "effect_item_pickup.wav", *GetLocalPlayer()->GetPosition() ); _oprint( "Item consumed: %d\n", pMsg->value ); SGameLocalPet* petAvatar = static_cast< SGameLocalPet* >( m_PetMgr.GetSummonPetData().pet_avatar ); if (petAvatar != NULL) { petAvatar->DeleteItemFromIgnoreQueue(pMsg->value); } // 펫 자동줍기가 설정되어있을때 한번 줍기를 시도한 아이템은 10분간 다시 안 줍는데, 만일 줍는데 성공(인벤으로 들어옴)하면 안 주울 아이템 리스트에서 지워버려도 된다. } else if( pMsg->result == RESULT_ACCESS_DENIED ) { if( GetLocalPlayer() ) m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_ITEM_NOT_PICKUP ) ); _oprint( "아이템에 대한 획득 권한이 없음.\n" ); } else if( pMsg->result == RESULT_TOO_HEAVY ) { if( GetLocalPlayer() ) m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_WEIGHT_TOO_HEAVY ) ); _oprint( "아이템의 소지 무게량(WT)을 초과하여 더 이상 습득할 수 없습니다.\n" ); } else _oprint( "아이템 못 먹었습니다.\n" ); } break; case TM_CS_SKILL : { _oprint( "Skill failed: %d\n", pMsg->result ); //서버에세 취소 되었기 때문에, //여기서 처리 해야 하는데... m_SkillSlotMgr.SetCurSkill(); } break; case TM_CS_MOVE_REQUEST : { //갈 수 없는 지역 입니다. // _oprint( "갈 수 없는 지역 입니다.\n" ); } break; case TM_CS_TURN_ON_PK_MODE: { SGameLocalPlayer* pLocalPlayer = (SGameLocalPlayer*)GetLocalPlayer(); if( pLocalPlayer ) { if( pMsg->result == RESULT_SUCCESS ) { pLocalPlayer->SetPKModeState( SGameLocalPlayer::PK_MODE_ON_COUNT_DOWN ); } else if( pMsg->result == RESULT_NOT_ACTABLE ) { pLocalPlayer->SetPKModeState( SGameLocalPlayer::PK_MODE_OFF ); } } } break; case TM_CS_TURN_OFF_PK_MODE: { SGameLocalPlayer* pLocalPlayer = (SGameLocalPlayer*)GetLocalPlayer(); if( pLocalPlayer ) { if( pMsg->result == RESULT_SUCCESS ) { pLocalPlayer->SetPKModeState( SGameLocalPlayer::PK_MODE_OFF_COUNT_DOWN ); } } } break; case TM_CS_TAKEOUT_COMMERCIAL_ITEM: { if( pMsg->result == RESULT_SUCCESS ) { //캐쉬 창고 갱신 요청 Rq_Chatting( CHAT_NORMAL, NULL, "/cstorage" ); // m_pGame->AddChatMessage( S(6398) ); //처리 안 되도록 요청 들어옮 } } break; case TM_CS_USE_ITEM: { /// 2011.07.20 - prodongi if (RESULT_NOT_ACTABLE_IN_INSTANCE_DUNGEON == pMsg->result) m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_INVALID_ACT_IN_DUN ) ); } break; case TM_CS_DONATE_ITEM: { if( pMsg->result == RESULT_SUCCESS ) UpdateContributionPropData(); } break; case TM_CS_INSTANCE_GAME_ENTER: /// 2011.07.20 - prodongi { if (RESULT_NOT_ACTABLE_IN_INSTANCE_DUNGEON == pMsg->result) m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_INVALID_ACT_IN_DUN ) ); } break; } } void SGameSystem::onLeave( struct SMSG_LEAVE* pMsg ) { OnMsgLeave( pMsg ); } void SGameSystem::OnMsgLeave ( struct SMSG_LEAVE* pMsg ) { CheckTarget( pMsg->handle ); //타겟 재설정~ LeaveSummon( pMsg->handle ); //핸들이 같으면 소환수 제거 LeaveSkillProp( pMsg->handle ); //UI 동기화 객체 삭제 m_pUISyncMng->LeaveHandle( pMsg->handle ); SGameAvatarEx* pAvatar = (SGameAvatarEx*)m_pGame->GetGameObject( pMsg->handle ); if( pAvatar ) m_pUISyncMng->LeaveUISyncMsg( pAvatar ); } //Skill Casting Time //void SGameSystem::OnMsgSkillCastingTime( struct SMSG_SKILL_CASTING_TIME* pMsg ) //{ // //캐스팅 표시바를 늘려줘야 한다. //} /// 2011.07.04 - prodongi void SGameSystem::OnSkillList ( struct SMSG_SKILL_LIST* pMsg ) { //Skill List 처리~.. if( IsLocal( pMsg->target ) ) { if( pMsg->isRefresh() ) { m_SkillSlotMgr.ResetSkill(); for( int i(0); pMsg->count>i; i++ ) { m_SkillSlotMgr.AddSkill( pMsg->dwTime, pMsg->pSkillInfo[i], pMsg->target, pMsg->modification_type ); } /// 2012.01.26 - prodongi m_pGame->SendGameInterfaceMsg( &SIMSG_UI_SEND_DATA(SIMSG_TOGGLE_UIWINDOW::UIWINDOW_SKILLFUND, "refresh")); } else if (pMsg->isUpdate()) { for( int i(0); pMsg->count>i; i++ ) { m_SkillSlotMgr.AddSkill( pMsg->dwTime, pMsg->pSkillInfo[i], pMsg->target, pMsg->modification_type ); } } } else if( m_CreatureSlotMgr.IsExistCreature( pMsg->target ) ) // sonador #2.1.2.4.3 팻 조작 UI 연동 { if( pMsg->isRefresh() ) { m_CreatureSkillSlotMgr.ResetCreatureSkill( pMsg->target ); for( int i = 0; i < pMsg->count; i++ ) m_CreatureSkillSlotMgr.AddSkill( pMsg->dwTime, pMsg->pSkillInfo[i], pMsg->target ); /// 2012.01.26 - prodongi m_pGame->SendGameInterfaceMsg( &SIMSG_UI_SEND_DATA(SIMSG_TOGGLE_UIWINDOW::UIWINDOW_CREATURE_SKILLFUND, "refresh")); } else if (pMsg->isUpdate()) { for( int i = 0; i < pMsg->count; i++ ) m_CreatureSkillSlotMgr.AddSkill( pMsg->dwTime, pMsg->pSkillInfo[i], pMsg->target ); } } else if( m_PetMgr.IsLocalPet( pMsg->target ) ) // sonador #2.1.2.4.3 팻 조작 UI 연동 { if( pMsg->isRefresh() ) { m_PetSkillMgr.ResetSkill(); for( int i = 0; i < pMsg->count; i++ ) m_PetSkillMgr.AddSkill( pMsg->dwTime, pMsg->pSkillInfo[i], pMsg->target ); } else if (pMsg->isUpdate()) { m_PetSkillMgr.ResetSkill(); for( int i = 0; i < pMsg->count; i++ ) m_PetSkillMgr.AddSkill( pMsg->dwTime, pMsg->pSkillInfo[i], pMsg->target ); } } } void SGameSystem::OnAddedSkillList ( struct SMSG_ADDED_SKILL_LIST* pMsg ) { //Added Skill List 처리~.. if( IsLocal( pMsg->target ) ) { m_SkillSlotMgr.ResetAddedSkill(); for( int i(0); pMsg->count>i; i++ ) m_SkillSlotMgr.AddAddedSkill( pMsg->pAddedSkillInfo[i], pMsg->target ); } else if( m_CreatureSlotMgr.IsExistCreature( pMsg->target ) ) // sonador #2.1.2.4.3 팻 조작 UI 연동 { m_CreatureSkillSlotMgr.ResetAddedSkill(); for( int i(0); pMsg->count>i; i++ ) m_CreatureSkillSlotMgr.AddAddedSkill( pMsg->pAddedSkillInfo[i], pMsg->target ); } else if( m_PetMgr.IsLocalPet( pMsg->target ) ) // sonador #2.1.2.4.3 팻 조작 UI 연동 { m_PetSkillMgr.ResetAddedSkill(); for( int i(0); pMsg->count>i; i++ ) m_PetSkillMgr.AddAddedSkill( pMsg->pAddedSkillInfo[i], pMsg->target ); } } void SGameSystem::OnSkillCardInfo( struct SMSG_SKILLCARD_INFO* pMsg ) { // 인벤에서 디져서 해당 스킬아이디를 가져와서 세팅해준다 SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo(pMsg->item_handle); if( pSlot ) { int nSkillID = GetItemDB().GetSkillID( pSlot->GetItemCode() ); // 장착해제 : 리스트 모두 디져라 if( pMsg->target_handle == NULL ) { m_SkillSlotMgr.SetSkillCard( nSkillID, 0 ); m_InventoryMgr.DelEquipCard( pMsg->target_handle, pMsg->item_handle ); } // 플레이어 else if( IsLocal( pMsg->target_handle ) ) { m_SkillSlotMgr.SetSkillCard( nSkillID, pMsg->item_handle ); m_InventoryMgr.AddEquipCard( pMsg->target_handle, pMsg->item_handle ); } } } void SGameSystem::OnMsgSkillEvent( struct SMSG_SKILL_EVENT* pMsg ) { std::vector vecSkillList; //취소 되거나, 발사 되면, 쿨타임 적용. if( (pMsg->status_type == TS_SC_SKILL::FIRE || pMsg->status_type == TS_SC_SKILL::CANCEL ) ) { //쿨타임 그룹 얻어오기 if( IsLocal( pMsg->caster ) ) //크리처 스킬도 현재 캐릭터의 스킬리스트에서 검색하게 되있어서 추가..... -N4- m_SkillSlotMgr.GetIdenticalCoolTimeGroup( pMsg->skill_id, vecSkillList ); } // 인터페이스에서 필요한 정보 세팅해줄까? // TODO 사용 되지 않는 것 같다. 정리 요망 switch( pMsg->status_type ) { case TS_SC_SKILL::FIRE: case TS_SC_SKILL::REGION_FIRE: { if( IsLocal( pMsg->caster ) && !vecSkillList.empty() ) { pMsg->data_owner = SMSG_SKILL_EVENT::OWNER_LOCAL_PLAYER; unsigned int nSkillSize = vecSkillList.size(); for( unsigned int i(0); icaster )) { if (m_SkillSlotMgr.IsFireSkill(vecSkillList[i], pMsg->caster)) { m_SkillSlotMgr.AddCooling( vecSkillList[i] ); } } } } else { /// 2012.02.28 isFire == true일 때만 쿨타임 리스트에 추가 - prodongi if( m_CreatureSkillSlotMgr.SetFireSkill( pMsg->skill_id, true, pMsg->caster ) ) { pMsg->data_owner = SMSG_SKILL_EVENT::OWNER_LOCAL_CREATURE; if (m_CreatureSkillSlotMgr.IsFireSkill(pMsg->skill_id, pMsg->caster)) { m_CreatureSkillSlotMgr.AddCooling( pMsg->skill_id, pMsg->caster ); } } } } break; case TS_SC_SKILL::CASTING: { if( pMsg->cast.nErrorCode != 0 ) { if( IsLocal( pMsg->caster ) ) pMsg->data_owner = SMSG_SKILL_EVENT::OWNER_LOCAL_PLAYER; else pMsg->data_owner = SMSG_SKILL_EVENT::OWNER_LOCAL_CREATURE; break; } if( IsLocal( pMsg->caster ) ) // 캐스팅 성공 { m_SkillSlotMgr.SetCastingSkill( pMsg->skill_id, true, pMsg->caster ); pMsg->data_owner = SMSG_SKILL_EVENT::OWNER_LOCAL_PLAYER; } else { if( m_CreatureSkillSlotMgr.SetCastingSkill( pMsg->skill_id, true, pMsg->caster ) ) pMsg->data_owner = SMSG_SKILL_EVENT::OWNER_LOCAL_CREATURE; } //버프가 있다면 이펙트 출력 AddStatusCastingAction( pMsg ); } break; case TS_SC_SKILL::CASTING_UPDATE : { if( IsLocal( pMsg->caster ) ) { pMsg->data_owner = SMSG_SKILL_EVENT::OWNER_LOCAL_PLAYER; } else if( IsLocalCreature( pMsg->caster ) ) { pMsg->data_owner = SMSG_SKILL_EVENT::OWNER_LOCAL_CREATURE; } } break; case TS_SC_SKILL::CANCEL: { if( IsLocal( pMsg->caster ) && !vecSkillList.empty() ) { pMsg->data_owner = SMSG_SKILL_EVENT::OWNER_LOCAL_PLAYER; unsigned int nSkillSize = vecSkillList.size(); for( unsigned int i(0); icaster ); } } else { m_CreatureSkillSlotMgr.AddCooling( pMsg->skill_id, pMsg->caster ); if( m_CreatureSkillSlotMgr.SetCastingCancelSkill( pMsg->skill_id, pMsg->caster ) ) pMsg->data_owner = SMSG_SKILL_EVENT::OWNER_LOCAL_CREATURE; } } break; case TS_SC_SKILL::COMPLETE: { if( IsLocal( pMsg->caster ) && !vecSkillList.empty() ) pMsg->data_owner = SMSG_SKILL_EVENT::OWNER_LOCAL_PLAYER; else pMsg->data_owner = SMSG_SKILL_EVENT::OWNER_LOCAL_CREATURE; } break; } vecSkillList.clear(); } void SGameSystem::OnStatInfo ( struct SMSG_STAT_INFO* pMsg ) { //우선 통째로 갖고 있자~ //로컬 플레이어와, 로컬 크리쳐는 내가 관리 해야 겠지? // MJ 2005/04/06, 크리처 스탯 관리 if( m_CreatureSlotMgr.IsExistCreature( pMsg->handle ) ) m_CreatureSlotMgr.SetCreatureStat( pMsg->handle, pMsg->stat, pMsg->attribute, pMsg->type ); else if( m_PlayerInfoMgr.IsLocalPlayer(pMsg->handle) ) m_PlayerInfoMgr.SetPlayerStat( pMsg->stat, pMsg->attribute, pMsg->type ); if( pMsg->type != TS_SC_STAT_INFO::TOTAL ) return; unsigned int nSize = m_vStatList.size(); for( unsigned int i(0); nSize>i; i++ ) { if( m_vStatList[i].handle == pMsg->handle ) { //이미 있는 것은 삭제한 후 추가 한다. m_vStatList.erase( m_vStatList.begin()+i ); break; } } SMSG_STAT_INFO stat; memcpy( &stat, pMsg, sizeof(SMSG_STAT_INFO) ); m_vStatList.push_back( stat ); if( !GetLocalPlayer() ) return; //캐릭터 스탯 갱신 nSize = m_vStatList.size(); for( unsigned int i(0); nSize>i; i++ ) { if( GetLocalPlayer()->GetArID() == pMsg->handle ) { GetLocalPlayer()->SetStat( pMsg ); g_nMoveSpeed = stat.attribute.nMoveSpeed; return; } } //소환수 스탯 갱신 nSize = m_vSummonList.size(); for( unsigned int i(0); nSize>i; i++ ) { if( m_vSummonList[i]->GetArID() == pMsg->handle ) { m_vSummonList[i]->SetStat( pMsg ); return; } } } //타기 void SGameSystem::OnMsgMount( struct SMSG_MOUNT_SUMMON* pMsg ) { if( pMsg->success ) { if( pMsg->handle == GetLocalPlayer()->GetArID() ) { SGameAvatarEx* pSummon = (SGameAvatarEx*)m_pGame->GetGameObject( pMsg->summon_handle ); if( pSummon) m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_CREATURE_MOUNT, pSummon->GetContentID() ) ); } } } //내리기 void SGameSystem::OnMsgUnMount( struct SMSG_UNMOUNT_SUMMON* pMsg ) { if( pMsg->handle == GetLocalPlayer()->GetArID() ) { SGameAvatarEx* pSummon = (SGameAvatarEx*)m_pGame->GetGameObject( pMsg->summon_handle ); if( pSummon) m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_CREATURE_DISMOUNT, pSummon->GetContentID() ) ); } } void SGameSystem::OnGoldUpdate( struct SMSG_GOLD_UPDATE* pMsg ) { // int nGold = m_PlayerInfoMgr.GetGold(); m_PlayerInfoMgr.SetGold( pMsg->gold ); /* int nChaos = m_PlayerInfoMgr.GetChaos(); m_PlayerInfoMgr.SetChaos( pMsg->chaos ); if( pMsg->gold != nGold ) { nGold = pMsg->gold - nGold; } nChaos = pMsg->chaos - nChaos;*/ } void SGameSystem::OnMsgTakeResult( struct SMSG_ITEM_TAKE* pMsg ) { } void SGameSystem::OnMsgDropResult( struct SMSG_ITEM_DROP* pMsg ) { // _oprint( "SGameSystem::아이템 Drop\n" ); // _oprint( "아이템 Drop\n" ); if( !pMsg->isAccepted ) { SYS_RESULT_MSG sysmsg = SYS_MSG_BOOTH_NOTICE_TRANSACTION; SInventorySlot* pInvenSlot = m_InventoryMgr.GetItemInfo( pMsg->item_handle ); if( pInvenSlot ) { const ItemBaseEx_info* pItemInfo = GetItemDB().GetItemData( pInvenSlot->GetItemCode() ); if( pItemInfo ) { if( pItemInfo->CheckFlag( ItemBase::FLAG_CASHITEM ) ) { sysmsg = SYS_MSG_DUMP_FAIL; } else if( pItemInfo->nGroup == ItemBase::GROUP_SUMMONCARD ) { sysmsg = SYS_MSG_DUMP_ITEM_FAIL; } } } m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( sysmsg ) ); } } void SGameSystem::OnMsgItemDestroy ( struct SMSG_ITEM_DESTROY* pMsg ) { _oprint( "SGameSystem::아이템 삭제\n" ); //홀릭 포인터 사용 //2009-02-25: hunee /*SInventorySlot* pItem = m_InventoryMgr.GetItemInfo( pMsg->item_handle ); if( pItem ) { TS_ITEM_INFO * pItemInfo = pItem->GetItem(); if (pItemInfo->Code == 806808) m_pGame->AddChatMessage( SR(SYS_MSG_USE_HOLICPOINT, "#@p@#", (int) pItemInfo->endurance ).c_str() ); }*/ DestroyItem( pMsg->item_handle ); } void SGameSystem::OnMsgItemErase( struct SMSG_ERASE_ITEM * pMsg ) { _oprint( "SGameSystem::아이템 파괴\n" ); for( int i=0; iitem_count; ++i ) { if( (pMsg->pItemInfo + i)->handle ) m_InventoryMgr.EraseItem( (pMsg->pItemInfo + i)->handle, (pMsg->pItemInfo + i)->count ); } } void SGameSystem::OnMsgUpdateItemCount( struct SMSG_UPDATE_ITEM_COUNT* pMsg ) { // _oprint( "SGameSystem::아이템 UpdateItemCount\n" ); UpdateItemCount( pMsg->item_handle, pMsg->count ); } //아이템 장착 정보 갱신 void SGameSystem::OnMsgItemWear( struct SMSG_ITEM_WEAR* pMsg ) { // _oprint( "SGameSystem::WearInfo\n" ); m_InventoryMgr.UpdateWear( pMsg ); } void SGameSystem::OnMsgItemWearInfo( struct SMSG_ITEM_WEAR_INFO* pMsg ) { // 플레이어가 아닐때 bool bCreature = false; if( !IsLocal( pMsg->target_handle ) ) { m_CreatureSlotMgr.SetCreatureItem( pMsg->target_handle, pMsg->item_handle, pMsg->wear_position ); bCreature = true; } m_InventoryMgr.UpdateWearInfo( pMsg, bCreature ); if( bCreature ) UISendStringMessage(m_pGame->GetGameManager(), SIMSG_TOGGLE_UIWINDOW::UIWINDOW_CREATURE_PAGE, "refresh_durability"); } // storage void SGameSystem::OnMsgOpenStorage( struct SMSG_OPEN_STORAGE* pMsg ) { m_nContentState = CS_STORAGE; m_StorageMgr.SetStorageOpen(true); m_StorageMgr.SetMaxSlotNum(pMsg->maxStorageItemCount); // 2011. 9 .15 - marine m_PlayerInfoMgr.ChangeState(SPlayerInfoMgr::STATE_STORAGE); } void SGameSystem::OnMsgChangeStorage( struct SMSG_CHANGE_STORAGE* pMsg ) { TS_CS_STORAGE msg; msg.item_handle = pMsg->hItem; msg.count = pMsg->nCount.getAmount(); msg.mode = pMsg->nMode; if( pMsg->nMode == TS_CS_STORAGE::CLOSE_STORAGE ) { m_nContentState = CS_NONE; m_StorageMgr.SetStorageOpen(false); m_PlayerInfoMgr.ChangeState(-1); } m_pGame->SendMsg( &msg ); } void SGameSystem::UISyncData( SGameMessage * pMsg ) { switch( pMsg->nType ) { case MSG_ATTACK : { SMSG_ATTACK * pGameMsg = static_cast(pMsg); if( pGameMsg->attack_action == TS_ATTACK_EVENT::ATTACK_END || pGameMsg->attack_action == TS_ATTACK_EVENT::ATTACK_CANCEL || pGameMsg->attack_action == TS_ATTACK_EVENT::ATTACK_AIMING ) { return; } SGameAvatarEx* pAttacker = (SGameAvatarEx*)m_pGame->GetGameObject( pGameMsg->attacker_handle ); SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pGame->GetGameObject( pGameMsg->target_handle ); if( !pAttacker ) return; for( int i = 0; i < pGameMsg->count; i++ ) { // if( pGameMsg->m_vAttackInfoList[i].damage > 0 ) UI_SYNC_INFO uisyncinfo; { if( pAttacker ) { uisyncinfo.dwTime = m_dwTime; uisyncinfo.CasterInfo.hTarget = pGameMsg->attacker_handle; uisyncinfo.CasterInfo.nTarget_hp = pGameMsg->m_vAttackInfoList[i].attacker_hp; uisyncinfo.CasterInfo.nTarget_mp = pGameMsg->m_vAttackInfoList[i].attacker_mp; uisyncinfo.CasterInfo.nDamage = pGameMsg->m_vAttackInfoList[i].attacker_damage; uisyncinfo.CasterInfo.nMPDamage = pGameMsg->m_vAttackInfoList[i].attacker_mp_damage; } else { assert( 0 && "SGameSystem::UISyncData case MSG_ATTACK : 캐스터가 존재 하지 않음" ); } if( pTarget ) { UI_SYNC_INFO::TARGET_INFO targetinfo; targetinfo.hTarget = pGameMsg->target_handle; targetinfo.nTarget_hp = pGameMsg->m_vAttackInfoList[i].target_hp; targetinfo.nTarget_mp = pGameMsg->m_vAttackInfoList[i].target_mp; targetinfo.nDamage = pGameMsg->m_vAttackInfoList[i].damage; targetinfo.nMPDamage = pGameMsg->m_vAttackInfoList[i].mp_damage; uisyncinfo.vTargetInfo.push_back( targetinfo ); } else { assert( 0 && "SGameSystem::UISyncData case MSG_ATTACK : 타겟이 존재 하지 않음" ); } pAttacker->AddUISyncData( uisyncinfo ); } } } break; case MSG_SKILL_EVENT : { UI_SYNC_INFO uisyncinfo; //발사체는 언제 터지는지 알 수 없는 타이밍이 있다. SMSG_SKILL_EVENT * pGameMsg = static_cast(pMsg); SGameAvatarEx* pCaster = (SGameAvatarEx*)m_pGame->GetGameObject( pGameMsg->caster ); if( !pCaster ) { assert( 0 && "SGameSystem::UISyncData case MSG_ATTACK: Caster does not exist!" ); return; } if( pGameMsg->status_type == TS_SC_SKILL::CASTING ) { if( pGameMsg->cast.nErrorCode != 0 ) return; uisyncinfo.dwTime = m_dwTime; uisyncinfo.nMode = SIMSG_UI_TARGET_STAT::USE_HPMP; uisyncinfo.CasterInfo.hTarget = pGameMsg->caster; uisyncinfo.CasterInfo.nDamage = 0; uisyncinfo.CasterInfo.nMPDamage = 0; uisyncinfo.CasterInfo.nTarget_hp = pGameMsg->caster_hp; uisyncinfo.CasterInfo.nTarget_mp = pGameMsg->caster_mp; pCaster->AddUISyncData( uisyncinfo ); m_pUISyncMng->AddHandle( pGameMsg->caster ); return; } if( pGameMsg->status_type != TS_SC_SKILL::FIRE && pGameMsg->status_type != TS_SC_SKILL::REGION_FIRE ) return; if( pGameMsg->status_type == TS_SC_SKILL::FIRE ) { _SKILL_FX* pSkillFx = GetSkillStageDB().GetSkillStageData( pGameMsg->skill_id ); //스킬 데이터 if( pSkillFx && pSkillFx->nStage_Type_Id == SS_TYPE_604 ) //지면 지속이면 Fire는 쌩까자 return; } uisyncinfo.dwTime = m_dwTime; uisyncinfo.CasterInfo.hTarget = pGameMsg->caster; uisyncinfo.CasterInfo.nDamage = pGameMsg->hp_cost; uisyncinfo.CasterInfo.nMPDamage = pGameMsg->mp_cost; uisyncinfo.CasterInfo.nTarget_hp = pGameMsg->caster_hp; uisyncinfo.CasterInfo.nTarget_mp = pGameMsg->caster_mp; unsigned int nSkillSize = pGameMsg->vSkillResult.size(); if( nSkillSize == 0 ) { uisyncinfo.nMode = SIMSG_UI_TARGET_STAT::USE_HPMP; pCaster->AddUISyncData( uisyncinfo ); m_pUISyncMng->AddHandle( pGameMsg->caster ); return; } bool bIsMissNPblock = false; bool bSkillResult = false; unsigned int nSkillResultSize = pGameMsg->vSkillResult.size(); for( unsigned int i(0); nSkillResultSize>i; i++ ) { UI_SYNC_INFO::TARGET_INFO targetinfo; /// 2011.03.25 - prodongi if( pGameMsg->vSkillResult[i].GetType() == SkillResult::DAMAGE || pGameMsg->vSkillResult[i].GetType() == SkillResult::MAGIC_DAMAGE || pGameMsg->vSkillResult[i].GetType() == SkillResult::CHAIN_DAMAGE || pGameMsg->vSkillResult[i].GetType() == SkillResult::CHAIN_MAGIC_DAMAGE ) { /* if( pGameMsg->vSkillResult[i].damage.flag & SkillResult::MISS || pGameMsg->vSkillResult[i].damage.flag & SkillResult::PERFECT_BLOCK ) { bIsMissNPblock = true; break; }*/ targetinfo.hTarget = pGameMsg->vSkillResult[i].damage.hTarget; targetinfo.nDamage = pGameMsg->vSkillResult[i].damage.damage; targetinfo.nMPDamage = 0; targetinfo.nTarget_hp = pGameMsg->vSkillResult[i].damage.target_hp; targetinfo.nTarget_mp = -1; uisyncinfo.vTargetInfo.push_back( targetinfo ); } else if( pGameMsg->vSkillResult[i].GetType() == SkillResult::DAMAGE_WITH_KNOCK_BACK ) { /* if( pGameMsg->vSkillResult[i].damage_kb.flag & SkillResult::MISS || pGameMsg->vSkillResult[i].damage_kb.flag & SkillResult::PERFECT_BLOCK ) { bIsMissNPblock = true; break; }*/ targetinfo.hTarget = pGameMsg->vSkillResult[i].damage_kb.hTarget; targetinfo.nDamage = pGameMsg->vSkillResult[i].damage_kb.damage; targetinfo.nMPDamage = 0; targetinfo.nTarget_hp = pGameMsg->vSkillResult[i].damage_kb.target_hp; targetinfo.nTarget_mp = -1; uisyncinfo.vTargetInfo.push_back( targetinfo ); } /// 2011.03.25 - prodongi else if( pGameMsg->vSkillResult[i].GetType() == SkillResult::ADD_HP || pGameMsg->vSkillResult[i].GetType() == SkillResult::CHAIN_HEAL ) { targetinfo.hTarget = pGameMsg->vSkillResult[i].add_hp.hTarget; targetinfo.nDamage = -pGameMsg->vSkillResult[i].add_hp.nIncHP; targetinfo.nMPDamage = 0; targetinfo.nTarget_hp = pGameMsg->vSkillResult[i].add_hp.target_hp; targetinfo.nTarget_mp = -1; uisyncinfo.vTargetInfo.push_back( targetinfo ); } else if( pGameMsg->vSkillResult[i].GetType() == SkillResult::ADD_MP ) { targetinfo.hTarget = pGameMsg->vSkillResult[i].add_hp.hTarget; targetinfo.nDamage = 0; targetinfo.nMPDamage = -pGameMsg->vSkillResult[i].add_hp.nIncHP; targetinfo.nTarget_hp = -1; targetinfo.nTarget_mp = pGameMsg->vSkillResult[i].add_hp.target_hp; uisyncinfo.vTargetInfo.push_back( targetinfo ); } else if( pGameMsg->vSkillResult[i].GetType() == SkillResult::ADD_HP_MP_SP ) { //SP는 잠시 보류 targetinfo.hTarget = pGameMsg->vSkillResult[i].add_hp_mp_sp.hTarget; targetinfo.nDamage = -pGameMsg->vSkillResult[i].add_hp_mp_sp.nIncHP; targetinfo.nMPDamage = -pGameMsg->vSkillResult[i].add_hp_mp_sp.nIncMP; targetinfo.nTarget_hp = pGameMsg->vSkillResult[i].add_hp_mp_sp.target_hp; targetinfo.nTarget_mp = pGameMsg->vSkillResult[i].add_hp_mp_sp.target_mp; uisyncinfo.vTargetInfo.push_back( targetinfo ); } else if( pGameMsg->vSkillResult[i].GetType() == SkillResult::REBIRTH ) { targetinfo.hTarget = pGameMsg->vSkillResult[i].rebirth.hTarget; targetinfo.nDamage = -pGameMsg->vSkillResult[i].rebirth.nIncHP; targetinfo.nMPDamage = -pGameMsg->vSkillResult[i].rebirth.nIncMP; targetinfo.nTarget_hp = pGameMsg->vSkillResult[i].rebirth.target_hp; targetinfo.nTarget_mp = pGameMsg->vSkillResult[i].rebirth.target_mp; uisyncinfo.vTargetInfo.push_back( targetinfo ); } else if( pGameMsg->vSkillResult[i].GetType() == SkillResult::RESULT ) { targetinfo.hTarget = pGameMsg->vSkillResult[i].result.hTarget; targetinfo.nDamage = 0; targetinfo.nMPDamage = 0; targetinfo.nTarget_hp = -1; targetinfo.nTarget_mp = -1; } else if( pGameMsg->vSkillResult[i].GetType() == SkillResult::RUSH ) { bSkillResult = true; continue; } /* else if( pGameMsg->vSkillResult[i].GetType() != SkillResult::NOT_USE ) { bSkillResult = true; continue; }*/ } if( /*!pGameMsg->vSkillResult.empty() &&*/ !bIsMissNPblock && !bSkillResult ) { // uisyncinfo.nMode = SIMSG_UI_TARGET_STAT::USE_HPMP; pCaster->AddUISyncData( uisyncinfo ); } /* else { assert( 0 && "pCaster->AddUISyncData( uisyncinfo ) 안됨" ); }*/ } break; case MSG_STATE_RESULT : { UI_SYNC_INFO uisyncinfo; SMSG_STATE_RESULT* pGameMsg = static_cast(pMsg); SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pGame->GetGameObject( pGameMsg->target_handle ); if( pTarget == NULL ) return; uisyncinfo.dwTime = m_dwTime; uisyncinfo.CasterInfo.hTarget = pGameMsg->target_handle; switch( pGameMsg->result_type ) { case TS_SC_STATE_RESULT::STATE_DAMAGE_HP: { uisyncinfo.nMode = SIMSG_UI_TARGET_STAT::USE_STATE_DMG; uisyncinfo.CasterInfo.nDamage = pGameMsg->value; uisyncinfo.CasterInfo.nMPDamage = 0; uisyncinfo.CasterInfo.nTarget_hp = pGameMsg->target_value; uisyncinfo.CasterInfo.nTarget_mp = -1; } break; case TS_SC_STATE_RESULT::STATE_DAMAGE_MP: { uisyncinfo.nMode = SIMSG_UI_TARGET_STAT::USE_STATE_DMG; uisyncinfo.CasterInfo.nDamage = 0; uisyncinfo.CasterInfo.nMPDamage = pGameMsg->value; uisyncinfo.CasterInfo.nTarget_hp = -1; uisyncinfo.CasterInfo.nTarget_mp = pGameMsg->target_value; } break; case TS_SC_STATE_RESULT::STATE_DAMAGE_SP: //SP는 패스 break; case TS_SC_STATE_RESULT::STATE_HEAL_HP: { uisyncinfo.nMode = SIMSG_UI_TARGET_STAT::USE_DEF; uisyncinfo.CasterInfo.nDamage = -pGameMsg->value; uisyncinfo.CasterInfo.nMPDamage = 0; uisyncinfo.CasterInfo.nTarget_hp = pGameMsg->target_value; uisyncinfo.CasterInfo.nTarget_mp = -1; } break; case TS_SC_STATE_RESULT::STATE_HEAL_MP: { uisyncinfo.nMode = SIMSG_UI_TARGET_STAT::USE_DEF; uisyncinfo.CasterInfo.nDamage = 0; uisyncinfo.CasterInfo.nMPDamage = -pGameMsg->value; uisyncinfo.CasterInfo.nTarget_hp = -1; uisyncinfo.CasterInfo.nTarget_mp = pGameMsg->target_value; } break; case TS_SC_STATE_RESULT::STATE_HEAL_SP: //SP는 패스 break; } pTarget->AddUISyncData( uisyncinfo ); m_pUISyncMng->AddHandle( pGameMsg->target_handle ); } break; case MSG_PROPERTY : { UI_SYNC_INFO uisyncinfo; SMSG_PROPERTY * pGameMsg = static_cast(pMsg); SGameAvatarEx* pCaster = (SGameAvatarEx*)m_pGame->GetGameObject( pGameMsg->handle ); if( pCaster == NULL ) return; uisyncinfo.dwTime = m_dwTime; uisyncinfo.nMode = SIMSG_UI_TARGET_STAT::USE_HPMP; uisyncinfo.CasterInfo.hTarget = pGameMsg->handle; uisyncinfo.CasterInfo.nDamage = 0; uisyncinfo.CasterInfo.nMPDamage = 0; switch( pGameMsg->nPropertyType ) { case SMSG_PROPERTY::PROPERTY_HP: { uisyncinfo.CasterInfo.nTarget_hp = atoi( pGameMsg->strValue.c_str() ); uisyncinfo.CasterInfo.nTarget_mp = -1; } break; case SMSG_PROPERTY::PROPERTY_MP: { uisyncinfo.CasterInfo.nTarget_hp = -1; uisyncinfo.CasterInfo.nTarget_mp = atoi( pGameMsg->strValue.c_str() ); } break; case SMSG_PROPERTY::PROPERTY_STAMINA: case SMSG_PROPERTY::PROPERTY_STAMINA_REGEN_RATE: { // sync_info.stamina = atoi( pGameMsg->strValue.c_str() ); return; //UI 구현되면 처리 } break; case SMSG_PROPERTY::PROPERTY_MAX_HP: { uisyncinfo.CasterInfo.nTarget_maxHp = atoi( pGameMsg->strValue.c_str() ); } break; case SMSG_PROPERTY::PROPERTY_MAX_MP: { uisyncinfo.CasterInfo.nTarget_maxMp = atoi( pGameMsg->strValue.c_str() ); } break; default: //HP MP STAMINA 이외 리턴 return; } pCaster->AddUISyncData( uisyncinfo ); m_pUISyncMng->AddHandle( pGameMsg->handle ); } break; case MSG_HPMP : { UI_SYNC_INFO uisyncinfo; // TODO : UI 수정 작업 SMSG_HPMP * pGameMsg = static_cast(pMsg); SGameAvatarEx* pCaster = (SGameAvatarEx*)m_pGame->GetGameObject( pGameMsg->handle ); if( pCaster == NULL ) { //소환되지 않은 크리처 일때 if( m_CreatureSlotMgr.IsEquipedCreature( pGameMsg->handle ) ) { SIMSG_UI_TARGET_STAT ui_sync; ui_sync.handle = pGameMsg->handle; ui_sync.m_nMode = SIMSG_UI_TARGET_STAT::USE_HPMP; ui_sync.m_nVar1 = pGameMsg->hp; ui_sync.m_nVar2 = pGameMsg->mp; ui_sync.m_nVar3 = pGameMsg->max_hp; ui_sync.m_nVar4 = pGameMsg->max_mp; m_pGame->ProcMsgAtStatic( &ui_sync ); } return; } uisyncinfo.dwTime = m_dwTime; uisyncinfo.nMode = SIMSG_UI_TARGET_STAT::USE_HPMP; uisyncinfo.CasterInfo.hTarget = pGameMsg->handle; uisyncinfo.CasterInfo.nDamage = 0; uisyncinfo.CasterInfo.nMPDamage = 0; uisyncinfo.CasterInfo.nTarget_hp = pGameMsg->hp; uisyncinfo.CasterInfo.nTarget_mp = pGameMsg->mp; uisyncinfo.CasterInfo.nTarget_maxHp = pGameMsg->max_hp; uisyncinfo.CasterInfo.nTarget_maxMp = pGameMsg->max_mp; pCaster->AddUISyncData( uisyncinfo ); m_pUISyncMng->AddHandle( pGameMsg->handle ); SGameAvatarEx* pLocalPlayer = GetLocalPlayer(); if( pGameMsg->need_to_display && pLocalPlayer ) { SMSG_DAMAGE damage; damage.attacker_handle = pLocalPlayer->GetArID(); damage.target_handle = pGameMsg->handle; damage.flag = 0; damage.strTargetName = pCaster->GetName(); damage.skillresult.damage.hTarget = pGameMsg->handle; damage.skillresult.damage.type = SkillResult::MAGIC_DAMAGE; damage.skillresult.damage.flag = 0; if( pGameMsg->add_hp != 0 ) { if( pGameMsg->add_hp < 0 ) { damage.nDamage = -pGameMsg->add_hp; damage.skillresult.damage.damage = -pGameMsg->add_hp; damage.skillresult.damage.target_hp = pGameMsg->max_hp; } m_pGame->OnDisplayDamage( &damage ); } if( pGameMsg->add_mp != 0 ) { if( pGameMsg->add_mp < 0 ) { damage.nDamage = -pGameMsg->add_mp; damage.skillresult.damage.damage = -pGameMsg->add_mp; damage.skillresult.damage.target_hp = pGameMsg->max_mp; } m_pGame->OnDisplayDamage( &damage ); } } } break; case MSG_REGEN_HPMP: { UI_SYNC_INFO uisyncinfo; SMSG_REGEN_HPMP* pGameMsg = static_cast(pMsg); SGameAvatarEx* pCaster = (SGameAvatarEx*)m_pGame->GetGameObject( pGameMsg->handle ); if( pCaster == NULL ) { //소환되지 않은 크리처 일때 const SCreatureInfo* pCreatureInfo = m_CreatureSlotMgr.GetCreatureInfo( pGameMsg->handle ); if( pCreatureInfo ) { SIMSG_UI_TARGET_STAT ui_sync; ui_sync.handle = pGameMsg->handle; ui_sync.m_nMode = SIMSG_UI_TARGET_STAT::USE_HPMP; ui_sync.m_nVar1 = pGameMsg->hp; ui_sync.m_nVar2 = pGameMsg->mp; ui_sync.m_nVar3 = pCreatureInfo->GetMaxHP(); ui_sync.m_nVar4 = pCreatureInfo->GetMaxMP(); m_pGame->ProcMsgAtStatic( &ui_sync ); } return; } uisyncinfo.dwTime = m_dwTime; uisyncinfo.nMode = SIMSG_UI_TARGET_STAT::USE_HPMP; uisyncinfo.CasterInfo.hTarget = pGameMsg->handle; uisyncinfo.CasterInfo.nDamage = 0; uisyncinfo.CasterInfo.nMPDamage = 0; uisyncinfo.CasterInfo.nTarget_hp = pGameMsg->hp; uisyncinfo.CasterInfo.nTarget_mp = pGameMsg->mp; pCaster->AddUISyncData( uisyncinfo ); m_pUISyncMng->AddHandle( pGameMsg->handle ); } break; /* case MSG_SP : { SMSG_SP* pGameMsg = static_cast(pMsg); handle = pGameMsg->handle; }*/ case MSG_EXP_UPDATE : { UI_SYNC_INFO uisyncinfo; SMSG_EXP_UPDATE * pGameMsg = static_cast(pMsg); SGameAvatarEx * pObject = (SGameAvatarEx*)m_pGame->GetGameObject( pGameMsg->handle ); if( !pObject ) return; if( pObject->GetEXP() || pObject->GetJP() ) { uisyncinfo.dwTime = m_dwTime; uisyncinfo.nMode = SIMSG_UI_TARGET_STAT::USE_EXP; uisyncinfo.CasterInfo.hTarget = pGameMsg->handle; uisyncinfo.CasterInfo.nDamage = 0; uisyncinfo.CasterInfo.nMPDamage = 0; uisyncinfo.CasterInfo.nTarget_hp = pGameMsg->exp - pObject->GetEXP(); uisyncinfo.CasterInfo.nTarget_mp = pGameMsg->jp - pObject->GetJP(); //계산이 완료 되었으므로, 바로 갱신 pObject->AddExp( uisyncinfo.CasterInfo.nTarget_hp ); pObject->AddJP( uisyncinfo.CasterInfo.nTarget_mp ); pObject->AddUISyncData( uisyncinfo ); m_pUISyncMng->AddHandle( pGameMsg->handle ); } else { //처음엔 AvatarProperty 에서 설정 return; } } break; case MSG_BONUS_EXP_JP: { UI_SYNC_INFO uisyncinfo; SMSG_BONUS_EXP_JP* pGameMsg = static_cast(pMsg); SGameAvatarEx* pLocalPlayer = GetLocalPlayer(); if( !pLocalPlayer ) return; if( pGameMsg->m_vBonusInfo.empty() ) return; std::vector< TS_SC_BONUS_EXP_JP::BONUS_INFO >::iterator iter = pGameMsg->m_vBonusInfo.begin(); for( ; iter != pGameMsg->m_vBonusInfo.end(); ++iter ) { bool bSuc = true; switch( (*iter).type ) { case TS_SC_BONUS_EXP_JP::BONUS_PCBANG: { uisyncinfo.nMode = SIMSG_UI_TARGET_STAT::USE_EXP_JP_BONUS_PCBANG; uisyncinfo.CasterInfo.nDamage = (*iter).rate; // sonador 3.10.1 PC 방 혜택 관련 시스템 메시지 변경 } break; case TS_SC_BONUS_EXP_JP::BONUS_STAMINA: { uisyncinfo.nMode = SIMSG_UI_TARGET_STAT::USE_EXP_JP_BONUS_STAMINA; uisyncinfo.CasterInfo.nDamage = (*iter).rate; // sonador 3.10.1 PC 방 혜택 관련 시스템 메시지 변경 } break; case TS_SC_BONUS_EXP_JP::BONUS_PREMIUM_PCBANG: { uisyncinfo.nMode = SIMSG_UI_TARGET_STAT::USE_EXP_JP_BONUS_PREMIUM_PCBANG; uisyncinfo.CasterInfo.nDamage = (*iter).rate; // sonador 3.10.1 PC 방 혜택 관련 시스템 메시지 변경 } break; case TS_SC_BONUS_EXP_JP::BONUS_SUMMON_STAMINA:// 오곡크래커 관련 2009.04.14 sfreer { uisyncinfo.nMode = SIMSG_UI_TARGET_STAT::USE_EXP_JP_BONUS_OGOK; uisyncinfo.CasterInfo.nDamage = (*iter).rate; } break; // 2010.10.01 성장의 물약(구슈퍼세이버)- prodongi case TS_SC_BONUS_EXP_JP::BOUNUS_SUPER_SAVE: { uisyncinfo.nMode = SIMSG_UI_TARGET_STAT::USE_EXP_JP_BONUS_SUPER_SAVE; uisyncinfo.CasterInfo.nDamage = (*iter).rate; } break; default: { bSuc = false; } break; } if( bSuc ) { uisyncinfo.dwTime = m_dwTime; uisyncinfo.CasterInfo.hTarget = pLocalPlayer->GetArID(); uisyncinfo.CasterInfo.nMPDamage = 0; uisyncinfo.CasterInfo.nTarget_hp = (*iter).exp; uisyncinfo.CasterInfo.nTarget_mp = (*iter).jp; pLocalPlayer->AddUISyncData( uisyncinfo ); m_pUISyncMng->AddHandle( pLocalPlayer->GetArID() ); } } } break; } } void SGameSystem::OnUISync( AR_HANDLE caster, AR_HANDLE target, int nUseType ) { SGameAvatarEx* pAvatar = (SGameAvatarEx*)m_pGame->GetGameObject( caster ); if( pAvatar ) m_pUISyncMng->ProcUiSyncMsg( pAvatar, target, nUseType ); } void SGameSystem::OnMsgRegenHPMP( struct SMSG_REGEN_HPMP* pMsg ) { //내가 죽으면, 타겟 창을 강제로 닫는다. if( GetLocalPlayer() && GetLocalPlayer()->GetArID() == pMsg->handle && pMsg->hp <= 0 ) SetTarget( NULL ); //살아 난 것임. if( GetLocalPlayer() && GetLocalPlayer()->GetArID() == pMsg->handle && GetLocalPlayer()->GetHP() <= 0 && pMsg->hp > 0 ) { //NPC 창, 마을 귀환 윈도우 Off 메세지 날린다. m_pGame->ProcMsgAtStatic( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_NPCDIALOG, false ) ); } } void SGameSystem::OnMsgStateResult( SMSG_STATE_RESULT* pMsg ) { SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pGame->GetGameObject( pMsg->target_handle ); if( !pTarget ) { assert( pTarget && "OnMsgStateDamage pTarget == NULL" ); return; } AR_HANDLE hPlayer = pMsg->target_handle; SGameAvatarEx* pPlayer = GetLocalPlayer(); if( pPlayer ) { //pPlayer가 존재 하지 않으면 데미지 표시가 안됨 ( 존재 하지 않은 일은 없겠지 ㅡ,.ㅡ ) hPlayer = pPlayer->GetArID(); } SMSG_DAMAGE damage; damage.attacker_handle = hPlayer; damage.target_handle = pMsg->target_handle; // damage.nDamage = pMsg->total_damage; //합산된 데미지 damage.nDamage = pMsg->value; //틱당 데미지 damage.flag = 0; damage.strTargetName = pTarget->GetName(); switch( pMsg->result_type ) { //HP MP 데미지는 동일하게 처리 case TS_SC_STATE_RESULT::STATE_DAMAGE_HP: case TS_SC_STATE_RESULT::STATE_DAMAGE_MP: { pTarget->Damage(); pTarget->SetAttackMode(); m_pUISyncMng->ProcUiSyncMsg( pTarget, pMsg->target_handle, SIMSG_UI_TARGET_STAT::USE_STATE_DMG ); damage.skillresult.damage.hTarget = pMsg->target_handle; damage.skillresult.damage.damage = pMsg->value; damage.skillresult.damage.target_hp = pMsg->target_value; damage.skillresult.damage.type = SkillResult::MAGIC_DAMAGE; damage.skillresult.damage.flag = 0; } break; case TS_SC_STATE_RESULT::STATE_DAMAGE_SP: //패스 assert( false ); return; case TS_SC_STATE_RESULT::STATE_HEAL_HP: { m_pUISyncMng->ProcUiSyncMsg( pTarget, pMsg->target_handle, SIMSG_UI_TARGET_STAT::USE_DEF ); damage.skillresult.add_hp.hTarget = pMsg->target_handle; damage.skillresult.add_hp.nIncHP = pMsg->value; damage.skillresult.add_hp.target_hp = pMsg->target_value; damage.skillresult.add_hp.type = SkillResult::ADD_HP; } break; case TS_SC_STATE_RESULT::STATE_HEAL_MP: { m_pUISyncMng->ProcUiSyncMsg( pTarget, pMsg->target_handle, SIMSG_UI_TARGET_STAT::USE_DEF ); damage.skillresult.add_hp.hTarget = pMsg->target_handle; damage.skillresult.add_hp.nIncHP = pMsg->value; damage.skillresult.add_hp.target_hp = pMsg->target_value; damage.skillresult.add_hp.type = SkillResult::ADD_MP; } break; case TS_SC_STATE_RESULT::STATE_HEAL_SP: //패스 assert( false ); return; } m_pGame->OnDotDamage( &damage, true ); SGameAvatarEx* pLocalPlayer = GetLocalPlayer(); if( pLocalPlayer->GetArID() != pMsg->caster_handle && pLocalPlayer->GetArID() != pMsg->target_handle ) return; if( pMsg->final && pMsg->total_amount > 0 ) { StateInfoEx* pStateInfo = GetTenacityDB().GetTenacityData( pMsg->code ); if( pStateInfo ) { SIMSG_UI_DISPLAY_STATE_DMG_SYS_MSG statedmg; switch( pMsg->result_type ) { case TS_SC_STATE_RESULT::STATE_DAMAGE_HP: { if( pTarget->IsLocalPlayer() ) statedmg.nSystemMsg = SYS_MSG_BATTLE_BEATTACK_DOT; else if( pTarget->IsLocalCreature() ) statedmg.nSystemMsg = SYS_MSG_CREATURE_BATTLE_BEATTACK_DOT; else statedmg.nSystemMsg = SYS_MSG_SKILL_DAMAGE_DOT; } break; case TS_SC_STATE_RESULT::STATE_DAMAGE_MP: { if( pTarget->IsLocalPlayer() ) statedmg.nSystemMsg = SYS_MSG_TOTAL_DAMAGE_MP; else if( pTarget->IsLocalCreature() ) statedmg.nSystemMsg = SYS_MSG_CREATURE_TOTAL_DAMAGEL_MP; else statedmg.nSystemMsg = SYS_MSG_BATTLE_TOTAL_DAMAGE_MP; } break; case TS_SC_STATE_RESULT::STATE_DAMAGE_SP: assert( false ); return; case TS_SC_STATE_RESULT::STATE_HEAL_HP: { if( pTarget->IsLocalPlayer() ) statedmg.nSystemMsg = SYS_MSG_TOTAL_RECOVERY_HP; else if( pTarget->IsLocalCreature() ) statedmg.nSystemMsg = SYS_MSG_CREATURE_TOTAL_RECOVERY_HP; else statedmg.nSystemMsg = SYS_MSG_TARGET_TOTAL_RECOVERY_HP; } break; case TS_SC_STATE_RESULT::STATE_HEAL_MP: { if( pTarget->IsLocalPlayer() ) statedmg.nSystemMsg = SYS_MSG_TOTAL_RECOVERY_MP; else if( pTarget->IsLocalCreature() ) statedmg.nSystemMsg = SYS_MSG_CREATURE_TOTAL_RECOVERY_MP; else statedmg.nSystemMsg = SYS_MSG_TARGET_TOTAL_RECOVERY_MP; } break; case TS_SC_STATE_RESULT::STATE_HEAL_SP: assert( false ); return; } if( pTarget ) { if( pTarget->GetObjType() == TS_ENTER::GAME_PLAYER ) statedmg.strTargetNamme = pTarget->GetName(); else if( pTarget->GetObjType() == TS_ENTER::GAME_MOB ) statedmg.strTargetNamme = GetStringDB().GetString( GetMonsterDB().GetTextID( pTarget->GetContentID() ) ); else if( pTarget->GetObjType() == TS_ENTER::GAME_SUMMON ) statedmg.strTargetNamme = GetStringDB().GetString( GetCreatureDB().GetTextID( pTarget->GetContentID() ) ) ; else if( pTarget->GetObjType() == TS_ENTER::GAME_NPC ) statedmg.strTargetNamme = GetStringDB().GetString( GetNpcDB().GetTextID( pTarget->GetContentID() ) ); } statedmg.strStateName = S( pStateInfo->name_id ); statedmg.nValue = pMsg->total_amount; statedmg.nLevel = pMsg->level; m_pGame->SendGameInterfaceMsg( &statedmg ); } else _oprint( "SGameSystem::OnMsgStateDamage 상태 정보 없음 %d\n", pMsg->code ); } } void SGameSystem::OnMsgInventory ( struct SMSG_ITEM_INVEN* pMsg ) { char * pItemInven = NULL; //인터페이스 알림 if( pMsg->nItemCnt > 0 ) { TS_ITEM_INFO* pItemInfo( &pMsg->pItemInfo[0] ); bool bInven( pItemInfo && pItemInfo->wear_position != ItemBase::WEAR_STORAGE ); // 창고인지 아닌지 for( int i(0); pMsg->nItemCnt>i; i++ ) { pItemInfo = &pMsg->pItemInfo[i]; if( NULL == pItemInfo ) continue; // 크리처 아이템 정의0 if( pItemInfo->own_summon_handle != NULL ) m_CreatureSlotMgr.SetCreatureItem( pItemInfo->own_summon_handle, pItemInfo->handle, pItemInfo->wear_position ); m_CreatureSlotMgr.SetCreatureEvolutionLevel( pItemInfo->handle, pItemInfo->socket ); AddItem( pItemInfo ); ItemBase::ItemClass classID = GetItemDB().GetClassID(pItemInfo->Code); int nLevel = (classID >= ItemBase::CLASS_ETCWEAPON && classID < ItemBase::CLASS_ETC_ACCESSORY) ? pItemInfo->level : 0; int nIconID = GetItemDB().GetIconID( pItemInfo->Code ); //아이템 코드로 바꿔야 한다. XFlag xFlag; xFlag.CopyFrom( &pItemInfo->Flag ); SInventorySlot* pSlot = NULL; if( pItemInfo->wear_position == ItemBase::WEAR_STORAGE ) // 창고 pSlot = m_StorageMgr.GetItemInfo(pItemInfo->handle); else pSlot = m_InventoryMgr.GetItemInfo(pItemInfo->handle); if( pSlot ) { pSlot->SetIconID( nIconID ); pSlot->SetXFlag( xFlag ); SInventorySlot* pUpdateSlot = NULL; if( pItemInfo->wear_position == ItemBase::WEAR_STORAGE ) // 창고 pUpdateSlot = pSlot; else pUpdateSlot = m_InventoryMgr.GetUpdateItemInfo(pItemInfo->handle); if( pUpdateSlot ) { pUpdateSlot->SetIconID( nIconID ); pUpdateSlot->SetXFlag( xFlag ); } } } if( bInven ) m_InventoryMgr.SortItemList(); else m_StorageMgr.SortItemList(); } } void SGameSystem::OnMsgItemcooltime( struct SMSG_ITEM_COOL_TIME* pMsg ) { for( int i(0); TS_SC_ITEM_COOL_TIME::MAX_ITEM_COOLTIME_GROUP>i; i++ ) { //msec 로 변환 m_InventoryMgr.SetItemCoolTime( i, pMsg->cool_time[i]*10 ); } } static const char *getQuestName( int nCode ) { QuestBase *pBase = GetQuestDB().GetQuestData( nCode ); if( !pBase ) return "???"; return GetStringDB().GetQuestString( pBase->nQuestTextId ); } void SGameSystem::RefreshTargetGuage( AR_HANDLE handle, bool bFriend ) { if( m_pTargetMgr->IsTarget( handle ) ) { SGameAvatarEx* pAvatar(NULL); pAvatar = m_pTargetMgr->GetTarget(); if( pAvatar ) { SIMSG_UI_TARGET_STAT msg; msg.handle = handle; msg.m_nVar3 = pAvatar->GetMaxHP(); msg.m_nVar4 = pAvatar->GetMaxMP(); if( bFriend ) msg.m_nVar1 = pAvatar->GetHP(); if( bFriend ) msg.m_nVar2 = pAvatar->GetMP(); m_pGame->ProcMsgAtStatic( &msg ); } } } AR_HANDLE SGameSystem::GetSummonCreature(AR_HANDLE handle) { SGameAvatarEx* pAvatar(NULL); pAvatar = (SGameAvatarEx*)( m_pGame->GetGameObject(handle) ); if( pAvatar ) return pAvatar->GetCreature(); else return NULL; } void SGameSystem::CreateGuage(AR_HANDLE handle, bool bCreate) { AR_HANDLE hCreature(NULL); hCreature = GetSummonCreature(handle); if( hCreature ) { m_pGame->ProcMsgAtStatic( &SIMSG_SHOW_GUAGE(hCreature, bCreate) ); RefreshTargetGuage( hCreature, bCreate ); } else { m_pGame->ProcMsgAtStatic( &SIMSG_SHOW_GUAGE( handle, bCreate ) ); RefreshTargetGuage( handle, bCreate ); } } void SGameSystem::InitRaidInfo() { m_RaidMgr.Clear(); m_pGame->SendGameInterfaceMsg( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_DUNGEON_UNIT, false ) ); m_pGame->SendGameInterfaceMsg( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_DUNGEON_UNIT_MINI, false ) ); // 2011. 11. 9 - marine 미니창, 공대 초대창, 공대 리스트 창 닫기 m_pGame->SendGameInterfaceMsg( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_DUNGEON_UNIT_INVITATION, false ) ); m_pGame->SendGameInterfaceMsg( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_GUILD_MEMBER_LIST, false ) ); } void SGameSystem::OnMsgChatPartySystem ( struct SMSG_CHATTING* pMsg ) { std::vector vecText; MsgSplit( pMsg->strText.c_str(), vecText, L"|" ); // 2011.11.11 - servantes : 파티이름 std::string strPartyName = ""; bool bIsRaidMsg(false); if( !vecText.empty() ) { //파티원을 강퇴하거나 파티를 파괴하면 기존의 동료였던 플레이어의 게이지를 출력하지 않는다. -N4- if( ::_stricmp( vecText[0].c_str(), "KICK" ) == 0 ) { if( vecText.size() > 2 ) { // 2011.11.11 - servantes : 해당 파티에서 핸들 찾도록 수정 strPartyName = vecText[1]; // 메세지 받은 파티 이름 AR_HANDLE handle = m_PartyMgr.GetMemberHandle( vecText[2].c_str(), &strPartyName ); if( handle && m_PartyMgr.IsLocalPlayer(handle) ) //LocalPlayer가 강퇴 되면 DESTROY와 마찬가지 상황이다. { std::vector MemberList = m_PartyMgr.GetMemberList(&strPartyName); int size( MemberList.size() ); for( int i(0); iGetHandle(); if( handle && !m_PartyMgr.IsLocalPlayer(handle, &strPartyName) ) //LocalPlayer를 지우면 안된다. { CreateGuage(handle, false); //레이드파티 해산일때에도 KICK메세지가 오기 때문에 그냥 일괄처리 InitRaidInfo(); } } } else CreateGuage(handle, false); } } else if( ::_stricmp( vecText[0].c_str(), "LEAVE" ) == 0 ) { if( vecText.size() > 1 ) { // 2011.11.11 - servantes : 해당 파티에서 핸들 찾도록 수정 AR_HANDLE handle = m_PartyMgr.GetMemberHandleSearchAllParty( vecText[1].c_str() ); if( m_PartyMgr.IsLocalPlayer(handle) ) { std::vector MemberList = m_PartyMgr.GetMemberList(); int size( MemberList.size() ); for( int i(0); iGetHandle(); if( handle && !m_PartyMgr.IsLocalPlayer(handle) ) //LocalPlayer를 지우면 안된다. CreateGuage(handle, false); } InitRaidInfo(); } else { CreateGuage(handle, false); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////// //레이드파티 해산일때에도 LEAVE메세지가 오기 때문에 그냥 일괄처리 //InitRaidInfo(); //////////////////////////////////////////////////////////////////////////////////////////////////////////////// } } else if( ::_stricmp( vecText[0].c_str(), "DESTROY" ) == 0 ) { if( vecText.size() > 1 ) { // 2011.11.11 - servantes strPartyName = vecText[1]; // 메세지 받은 파티 이름 if( vecText[1].compare( m_PartyMgr.GetPartyName() ) == 0 ) { std::vector MemberList = m_PartyMgr.GetMemberList(); int size( MemberList.size() ); for( int i(0); iGetHandle(); if( handle && !m_PartyMgr.IsLocalPlayer(handle) ) //LocalPlayer를 지우면 안된다. CreateGuage(handle, false); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////// //레이드파티 해산일때에도 DESTROY메세지가 오기 때문에 그냥 일괄처리 InitRaidInfo(); //////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// 2011.12.22 자기 자신 일 경우에는 hide 시켜준다 m_pGame->SendGameInterfaceMsg( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_PARTY, false ) ); m_pGame->SendGameInterfaceMsg( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_PARTYMATCHING, false )); m_pGame->SendGameInterfaceMsg( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_PARTYMATCHING_REGISTER, false )); // 파티매칭 // 파티매칭 } else { /// 2011.12.22 해당 파티 정보들 삭제 - prodongi SPartyMgr *pParty = m_PartyMgr.GetParty(&strPartyName); if(pParty != NULL) m_PartyMgr.AddMessage( pMsg->strText.c_str(), pParty->m_bSelf ); m_PartyMgr.Delete(&strPartyName); m_RaidMgr.DeleteParty(strPartyName.c_str()); bIsRaidMsg = true; m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DUNGEONUNIT_UPDATE() ); } } } } if( !bIsRaidMsg ) //DESTROY가 RAID일때도 들어오기 때문에 레이드이면서 자신의 파티해산이 아니라면 여길 들어오면 안된다. { // 2011.10.18 : servantes : 파티리스트 매니저 SPartyMgr *pParty = NULL; if(strPartyName.size() <= 0) pParty = m_PartyMgr.GetParty(); else pParty = m_PartyMgr.GetParty(&strPartyName); if(pParty != NULL) m_PartyMgr.AddMessage( pMsg->strText.c_str(), pParty->m_bSelf ); // 미니맵과 파티창에 이벤트 전파 m_pGame->ProcMsgAtStatic( &SIMSG_UI_SEND_DATA( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_MINIMAP, "party_update" ) ); // 2011.11.09 : servantes : 메세지 처리한 파티 이름 추가 m_pGame->ProcMsgAtStatic( &SIMSG_UI_SEND_DATA( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_PARTY, "party_update", strPartyName.c_str() ) ); m_pGame->ProcMsgAtStatic( &SIMSG_UI_SEND_DATA( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_PARTY_STATE, "party_update", strPartyName.c_str() ) ); // m_pGame->ProcMsgAtStatic( &SIMSG_UI_SEND_DATA( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_PARTY_CREATURE1, "party_update" ) ); // m_pGame->ProcMsgAtStatic( &SIMSG_UI_SEND_DATA( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_PARTY_CREATURE2, "party_update" ) ); if( !vecText.empty() ) { if( ::_stricmp( vecText[0].c_str(), "PINFO" ) == 0 || ::_stricmp( vecText[0].c_str(), "LEAVE" ) == 0 || ::_stricmp( vecText[0].c_str(), "KICK" ) == 0 || ::_stricmp( vecText[0].c_str(), "DESTROY" ) == 0 || ::_stricmp( vecText[0].c_str(), "LOGOUT" ) == 0 || ::_stricmp( vecText[0].c_str(), "JOIN" ) == 0 || ::_stricmp( vecText[0].c_str(), "LOGIN" ) == 0 || ::_stricmp( vecText[0].c_str(), "NEW" ) == 0 ) SetHideSkillProp(); } } //=============================================================================================================================================== //파티원이 바로 근처에서 ENTER와 동시에 로그인했을때 처리하는 부분 //파티원 게이지윈도우 생성을 위해서 추가되는 부분 -N4- //파티원이 ENTER가 발생하지 않는 곳에서 로그인후 근처로 와서 ENTER가 발생하면 이미 PartyMgr이 세팅된 후이기에 문제없이 생성되지만 //바로 옆에서 ENTER가 발생하면서 로그인하게 되면 PartyMgr이 세팅되기 전에 ENTER가 발생하기 때문에 게이지가 생성 안된다. //따라서 PartyMgr에 쎄팅된 후에 이곳으로 오기 때문에 여기서 게이지관련된 코딩을 한다. //중요한 요점은 ENTER발생시 모든 아바타는 게이지가 생성된다. 다만 게이지가 안나오는것은 리소스를 쎄팅하지 않기 때문이다. //따라서 여기서는 새로 추가된 파티원이 게이지가 있는지 체크하고 그 게이지가 보이도록 리소스를 쎄팅해주는 것이다. if( !vecText.empty() ) { if( ::_stricmp( vecText[0].c_str(), "MINFO" ) == 0 ) { if( vecText.size() > 1 ) { char * strstoper; AR_HANDLE handle = ::strtoul( vecText[1].c_str(), &strstoper, 10 ); CreateGuage(handle, true); } } else if( ::_stricmp( vecText[0].c_str(), "PINFO" ) == 0 ) { // 2011.09.20 - servantes : 7번째 인자에 파티 타입 추가 strPartyName = vecText[2]; // 파티 이름 for( size_t i(8); inChatType == CHAT_PARTY_SYSTEM ) { OnMsgChatPartySystem( pMsg ); } else if( pMsg->nChatType == CHAT_RAID_SYSTEM ) { if( m_RaidMgr.AddMessage( pMsg->strText.c_str() ) ) //레이드 정보 추가 성공 { /// 2012.06.22 아레나 체크 코드 추가 - prodongi if (PARTY_ARENA != m_PartyMgr.GetPartyType()) { bool b_IsNomalOpen = m_pGame->GetGameManager()->GetSUI(SIMSG_TOGGLE_UIWINDOW::UIWINDOW_DUNGEON_UNIT)->IsShow(); bool b_IsMiniOpen = m_pGame->GetGameManager()->GetSUI(SIMSG_TOGGLE_UIWINDOW::UIWINDOW_DUNGEON_UNIT_MINI)->IsShow(); if(b_IsMiniOpen == false && b_IsNomalOpen == false) // 노멀창과 미니창이 모두 안열려 있을 때만 호출 //m_pGame->SendGameInterfaceMsg( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_DUNGEON_UNIT, true ) ); m_pGame->SendGameInterfaceMsg( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_DUNGEON_UNIT_MINI, true ) ); m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DUNGEONUNIT_UPDATE(true) ); } } } else if( pMsg->nChatType == CHAT_GUILD_SYSTEM ) { //// _oprint( "GUILD : %s\n", pMsg->strText.c_str() ); // // int nNewGuildID = 0; // if( m_GuildMgr.AddMessage( pMsg->strText.c_str(), nNewGuildID ) == false ) // { // int nValue = 0; // int nReqValue = m_GuildDataMgr.AddMessage( pMsg->strText.c_str(), nValue ); // // // 제거. bintitle. 2010.06.18. // //if( m_pGame->IsUIWindowOpened( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_GUILD_TITLE ) ) // //{ //웹 페이지 갱신 // // CurOtherURLRefresh( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_GUILD_TITLE ); // //} // // if( nReqValue == SGuildDataMgr::REQ_GUILD_ICON ) // { //갱신됨. 다시 요청 한다. // Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/gicon %d", nValue ).c_str() ); // } // } // else // { // if( nNewGuildID != 0 ) // { // if( IsExistGuildInfo( nNewGuildID ) == false ) // { //아이콘 정보 요청 // Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/gicon %d", nNewGuildID ).c_str() ); // // // ////주변 길드 셋팅 // // //SIMSG_UI_GUILDICON_REFRESH msg; // // //msg.nGuild_id = nNewGuildID; // // //msg.strGuildName = m_GuildMgr.GetGuildName(); // // //m_GuildMgr.GetMemberHandle( msg.vHandleList ); // // // //m_pGame->SendGameInterfaceMsg( &msg ); // } // // //else // // //{ //내 길드만 처리됨 // // // const GUILD_ICON* pGuildIcon = m_GuildDataMgr.GetGuildData( nNewGuildID ); // // // if( pGuildIcon ) // // // { // // // SIMSG_UI_GUILDICON_REFRESH msg; // // // msg.nGuild_id = pGuildIcon->nGuildID; // // // msg.strGuildName = pGuildIcon->strGuildName; // // // msg.strIconAniName = pGuildIcon->strIconAniName; // // // m_GuildMgr.GetMemberHandle( msg.vHandleList ); // // // // m_pGame->SendGameInterfaceMsg( &msg ); // // // } // // //} // } // } // // //길드 윈도우 업데이트 // m_pGame->ProcMsgAtStatic( &SIMSG_UI_SEND_DATA( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_CHARINFO, "guild_update" ) ); // m_pGame->ProcMsgAtStatic( &SIMSG_UI_SEND_DATA( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_COMMUNITY, "guild_update" ) ); // // // bintitle // m_pGame->ProcMsgAtStatic( &SIMSG_UI_SEND_DATA( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_GUILD_MAINWND, "guild_update" ) ); // _oprint( "GUILD : %s\n", pMsg->strText.c_str() ); // 위의 코드를 수정. bintitle. 2010.06.18. bool bSelf = false; // 해당 메세지가 자신에게만 해당되는지 여부. bintitle. 2010.11.29. int nNewGuildID = 0; unsigned int nRes = m_GuildMgr.AddMessage( pMsg->strText.c_str(), nNewGuildID, bSelf ); if( nRes & GUILD_UPDATE::GUILD_UPDATE_NONE ) { int nValue = 0; int nReqValue = m_GuildDataMgr.AddMessage( pMsg->strText.c_str(), nValue ); if( nReqValue == SGuildDataMgr::REQ_GUILD_ICON ) { //갱신됨. 다시 요청 한다. Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/gicon %d", nValue ).c_str() ); } } else { if( nNewGuildID != 0 ) { if( IsExistGuildInfo( nNewGuildID ) == false ) { //아이콘 정보 요청 Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "/gicon %d", nNewGuildID ).c_str() ); } } } //길드 윈도우 업데이트 m_pGame->ProcMsgAtStatic( &SIMSG_UI_SEND_DATA( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_CHARINFO, "guild_update" ) ); //m_pGame->ProcMsgAtStatic( &SIMSG_UI_SEND_DATA( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_COMMUNITY, "guild_update" ) ); // bintitle. //if( nRes != GUILD_UPDATE::GUILD_UPDATE_NONE ) m_pGame->ProcMsgAtStatic( &SIMSG_UI_SEND_DATA( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_GUILD_MAINWND, "guild_update", nRes, bSelf ? "Self" : "" ) ); // 해당 메세지가 자신에게만 해당되는지 여부. bintitle. 2010.11.29. m_pGame->ProcMsgAtStatic( &SIMSG_UI_SEND_DATA(SIMSG_TOGGLE_UIWINDOW::UIWINDOW_GUILD_MEMBER_LIST, "guild_update" ) ); } else if( pMsg->nChatType == CHAT_COMMAND ) { Rq_Chatting( CHAT_NORMAL, pMsg->szSender.c_str(), pMsg->strText.c_str() ); } else if( pMsg->nChatType == CHAT_FRIEND_SYSTEM ) { std::vector< std::string > vToken; MsgSplit( pMsg->strText.c_str(), vToken, L"|" ); if( vToken.size() > 0 ) { if( vToken[0] == "FLIST" ) { /// 2011.01.19 bool형을 int로 바꿈 - prodongi if( m_FriendMgr.AddMessage( pMsg->strText.c_str(), m_FriendMgr.m_bSelf ) != 0/*== true*/ ) m_pGame->ProcMsgAtStatic( &SIMSG_UI_SEND_DATA( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_COMMUNITY, "friend_update" ) ); } else if( vToken[0] == "FSTATUS" ) { m_FriendMgr.AddMessage( pMsg->strText.c_str(), m_FriendMgr.m_bSelf ); } else if( vToken[0] == "DLIST" ) { /// 2011.01.19 bool형을 int로 바꿈 - prodongi if( m_CutMgr.AddMessage( pMsg->strText.c_str(), m_CutMgr.m_bSelf ) != 0/*== true*/ ) m_pGame->ProcMsgAtStatic( &SIMSG_UI_SEND_DATA( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_COMMUNITY, "cut_update" ) ); } } vToken.clear(); } else if( pMsg->nChatType == CHAT_ALLIANCE_SYSTEM ) { if( ::strcmp( pMsg->szSender.c_str(), "@ALLIANCE" ) == 0 ) { // 연합에 속한 길드의 정보변경여부. bool bChangeAlliance = false; std::vector< std::string > vToken; MsgSplit( pMsg->strText.c_str(), vToken, L"|" ); if( vToken.size() >= 5 && vToken[0] == "INVITE" ) // INVITE|leader_name|alliance_name|alliance_id|password { m_strAllianceId = vToken[3]; m_strPassword = vToken[4]; //"""#@alliance_name@#""의 마스터""#@user_name@#""으로부터 연합길드 제의를 받았습니다.", std::string strAllianceInvite = SR( 852, "#@alliance_name@#", vToken[2].c_str(), "#@user_name@#", vToken[1].c_str() ); m_pGame->SendGameMsg( &SIMSG_REQ_OPEN_MSGBOX( SIMSG_REQ_OPEN_MSGBOX::MSGBOX_ALLIANCE_ACCEPT, strAllianceInvite.c_str(), false ) ); } else if( vToken.size() >= 3 && vToken[0] == "KICK" ) // KICK|alliance_name|guild_name { //“#@guild_name@#”을 “#@alliance_name@#”에서 추방하였습니다. std::string strAllianceKick = SR( 866, "#@guild_name@#", vToken[2].c_str(), "#@alliance_name@#", vToken[1].c_str() ); m_pGame->AddChatMessage( strAllianceKick.c_str() ); // 연합에서 탈퇴한 길드가 자신의 길드와 같다. if( vToken[2] == this->m_GuildMgr.GetGuildName() ) { // 연합길드정보 제거. this->m_GuildMgr.ClearAlliance(); bChangeAlliance = true; } } else if( vToken.size() >= 3 && vToken[0] == "LEAVE" ) // LEAVE|alliance_name|guild_name { //“#@guild_name@#”길드가 “#@alliance_name@#”연합에서 탈퇴했습니다. std::string strAllianceLeave = SR( 857, "#@guild_name@#", vToken[2].c_str(), "#@alliance_name@#", vToken[1].c_str() ); m_pGame->AddChatMessage( strAllianceLeave.c_str() ); // 연합에서 탈퇴한 길드가 자신의 길드와 같다. if( vToken[2] == this->m_GuildMgr.GetGuildName() ) { // 연합길드정보 제거. this->m_GuildMgr.ClearAlliance(); bChangeAlliance = true; } } else if( vToken.size() >= 3 && vToken[0] == "JOIN" ) // JOIN|alliance_name|guild_name { //“#@guild_name@#”길드가 “#@alliance_name@#”연합에 참여했습니다. std::string strAllianceLeave = SR( 856, "#@guild_name@#", vToken[2].c_str(), "#@alliance_name@#", vToken[1].c_str() ); m_pGame->AddChatMessage( strAllianceLeave.c_str() ); } else if( vToken.size() >= 2 && vToken[0] == "DESTROY" ) // DESTROY|alliance_name { //“#@alliance_name@#”연합이 해체됐습니다. std::string strAllianceLeave = SR( 858, "#@alliance_name@#", vToken[1].c_str() ); m_pGame->AddChatMessage( strAllianceLeave.c_str() ); // 연합길드정보 제거. this->m_GuildMgr.ClearAlliance(); bChangeAlliance = true; } //------------------------------------------------------ // 추가. bintitle. 2010.05.14. 연합길드정보 변경. // 연합 소속 길드에서 길드원 가입/탈퇴/추방이 발생하여 길드원 수가 변경되었을 경우. else if( vToken.size() > 2 && vToken[0] == "GMEMBER_CHANGE" ) { bChangeAlliance = true; this->m_GuildMgr.ChangeAllianceMemberCount( ::atoi( vToken[ 1 ].c_str() ), ::atoi( vToken[ 2 ].c_str() ) ); } // 연합 소속 길드에서 길드장 인계가 발생하여 길드장이 변경되었을 경우. else if( vToken.size() > 2 && vToken[0] == "GLEADER_CHANGE" ) { bChangeAlliance = true; this->m_GuildMgr.ChangeAllianceMaster( ::atoi( vToken[ 1 ].c_str() ), vToken[ 2 ] ); } // 연합길드정보가 변경되었다. 길드UI에 메세지 전송. if( bChangeAlliance ) { m_pGame->ProcMsgAtStatic( &SIMSG_UI_SEND_DATA( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_GUILD_SUB_INFO, "allianceGuild_update" ) ); } //------------------------------------------------------ vToken.clear(); } } else if( pMsg->nChatType == CHAT_NORMAL ) { if( ::strcmp( pMsg->szSender.c_str(), "@BATTLE" ) == 0 ) { std::vector< std::string > vToken; MsgSplit( pMsg->strText.c_str(), vToken, L"|" ); if( vToken[0] == "NOT_IN_BATTLE" ) // 대련장 밖에서는 대련 신청이 불가능 합니다. // sonador 1.10.1 모럴 포인트 증/감 메시지 및 대련장 관련 메시지 추가 { m_pGame->AddChatMessage( S( 531 ) ); } else if( vToken.size() == 2 ) { if( vToken[0] == "BATTLE_INVITE" ) //BATTLE_INVITE|inviter_name { std::string strMsgBoxText = SR(956, "#@player_name@#", vToken[1].c_str() ); m_pGame->SendGameMsg( &SIMSG_REQ_OPEN_MSGBOX( SIMSG_REQ_OPEN_MSGBOX::MSGBOX_BATTLE_ACCEPT, strMsgBoxText.c_str(), vToken[1].c_str(), false ) ); } else if( vToken[0] == "BATTLE_END" ) //BATTLE_END|handle { m_pGame->AddChatMessage( S(1635) ); //대련이 종료되었습니다 SAFE_DELETE( m_pBattle_Info ); SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pGame->GetGameObject( atoi( vToken[1].c_str() ) ); if( pTarget ) pTarget->SetActivateBattleInArena( false ); } else if( vToken[0] == "ALREADY_IN_BATTLE" ) //ALREADY_IN_BATTLE|target_name { m_pGame->AddChatMessage( S(1636) ); //이미 대련중인 상대입니다. } else if( vToken[0] == "BATTLE_REJECT" ) // \"#@player_name@#\"님이 대련을 거부했습니다. { m_pGame->AddChatMessage( SR(1632, "#@player_name@#", vToken[1].c_str() ).c_str() ); } } else if( vToken.size() == 3 ) { if( vToken[0] == "BATTLE_START" ) //BATTLE_START|target_handle|battle_start_time { /* std::string strMsgBoxText = SR(1634, "#@player_name@#", strBattleName.c_str()); m_pGame->AddChatMessage( strMsgBoxText.c_str() ); pTarget->SetActivateBattleInArena( true );*/ SAFE_DELETE( m_pBattle_Info ); m_pBattle_Info = new SGameSystem::Battle_Info; m_pBattle_Info->hTarget = (AR_HANDLE)atoi( vToken[1].c_str() ); m_pBattle_Info->arTime = (AR_TIME)atoi( vToken[2].c_str() ); } else if( vToken[0] == "RESULT_RETREAT" ) //RESULT_RETREAT|winner|loser { //964 "#@loser_name@#"님이 "#@winner_name@#"님과의 대련을 포기했습니다. //Loser가 Winner와의 대련에서 도망갔습니다. std::string strSysMsg = SR(1641, "#@loser_name@#", vToken[2].c_str(), "#@winner_name@#", vToken[1].c_str() ); m_pGame->AddChatMessage( strSysMsg.c_str() ); } else if( vToken[0] == "RESULT_WIN" ) //RESULT_WIN|winner|loser { //960 "#@winner_name@#"님이 "#@loser_name@#"님과의 대련에서 승리했습니다. //Winner가 Loser와의 대련에서 승리했습니다. std::string strSysMsg = SR(1637, "#@winner_name@#", vToken[1].c_str(), "#@loser_name@#", vToken[2].c_str() ); m_pGame->AddChatMessage( strSysMsg.c_str() ); } // { [sonador][3.3.1] Mantis 0001610 else if( vToken[ 0 ] == "PK_KILLED_ITEM_DROP" ) // PK_KILLED_ITEM_DROP|character_name|dropped_itme_code { std::string strItemName; int nItemCode = ::atoi( vToken[ 2 ].c_str( ) ); const ItemBaseEx_info* pItemData = GetItemDB( ).GetItemData( nItemCode ); if( pItemData ) strItemName = GetStringDB( ).GetString( pItemData->nNameId ); else strItemName = S( 88 ); std::string strSysMsg = SR( 487, "#@someone@#", vToken[ 1 ].c_str( ), "#@item_name@#", strItemName.c_str( ) ); // 487 #@someone@#(와/과)의 전투에서 패배하여 #@item_name@#(을/를) 떨어뜨렸습니다. m_pGame->AddChatMessage( strSysMsg.c_str( ) ); } // } } vToken.clear(); } } if( pMsg->nChatType == CHAT_QUEST_SYSTEM ) { std::vector< std::string > vToken; MsgSplit( pMsg->strText.c_str(), vToken, L"|" ); if( vToken.size() > 2 && vToken[0] == "START" ) { std::string strMessage; // 2011.07.06 - servantes if( vToken[1] == "SUCCESS" ) // 퀘스트 받는 곳 : 시작 { int nQuestID = atoi( vToken[2].c_str() ); if(nQuestID <= 0) { vToken.clear(); return ; } QuestBase* pQB = GetQuestDB().GetQuestData(nQuestID); if(pQB == NULL) { vToken.clear(); return ; } strMessage = SStringDB::ParseString( 504, "#@quest_name@#", getQuestName( atoi( vToken[2].c_str() ) ) ); } else if( vToken[1] == "WARNING" ) { if( vToken.size() > 3 ) { if( vToken[2] == "GAME_TIME_LIMIT" ) { strMessage = SStringDB::ParseString( GetStringDB().GetString( SYS_MSG_CHINA_FATIGUE_TIME_QUEST ) ); } } } else if( vToken[1] == "FAIL" ) { if( vToken.size() > 3 ) { if( vToken[2] == "GAME_TIME_LIMIT" ) { strMessage = SStringDB::ParseString( GetStringDB().GetString( SYS_MSG_CHINA_BAD_TIME_QUEST ) ); } else if( vToken[2] == "QUEST_NUMBER_EXCEED" ) { //getQuestName( atoi( vToken[3].c_str() ) ) } else if( vToken[2] == "NOT_STARTABLE" ) { //getQuestName( atoi( vToken[3].c_str() ) ) } } } m_pGame->AddChatMessage( strMessage.c_str() ); vToken.clear(); return; } if( vToken.size() > 2 && vToken[0] == "END" ) { std::vector< std::string > vToken; MsgSplit( pMsg->strText.c_str(), vToken, L"|" ); if( vToken[1] == "FAIL" || vToken[1] == "FAILED" || vToken[1] == "TIMEOUT") { std::string strMessage = SStringDB::ParseString( 508, "#@quest_name@#", getQuestName( atoi( vToken[2].c_str() ) ) ); m_pGame->AddChatMessage( strMessage.c_str() ); } else if( vToken[1] == "EXP" ) { // 2011.07.19 - servantes int nQuestID = atoi( vToken[2].c_str() ); if(nQuestID <= 0) { vToken.clear(); return ; } QuestBase* pQB = GetQuestDB().GetQuestData(nQuestID); if(pQB == NULL) { vToken.clear(); return ; } std::string strMessage = SStringDB::ParseString( 506, "#@quest_name@#", getQuestName( atoi( vToken[2].c_str() ) ) ); m_pGame->AddChatMessage( strMessage.c_str() ); } else if( vToken[1] == "REWARD" || vToken[1] == "GAMETIME_HALF_REWARD" || vToken[1] == "GAMETIME_NO_REWARD" ) { if( vToken[1] == "GAMETIME_HALF_REWARD" ) { m_pGame->AddChatMessage( SStringDB::ParseString( GetStringDB().GetString( SYS_MSG_CHINA_FATIGUE_TIME_QUEST ) ).c_str() ); vToken.clear(); return; } else if( vToken[1] == "GAMETIME_NO_REWARD" ) { m_pGame->AddChatMessage( SStringDB::ParseString( GetStringDB().GetString( SYS_MSG_CHINA_BAD_TIME_QUEST ) ).c_str() ); vToken.clear(); return; } const ItemBaseEx_info * pItemBase = GetItemDB().GetItemData( atoi( vToken[2].c_str() ) ); std::string strItemName( GetStringDB().GetString( pItemBase->nNameId ) ); std::string strMessage = SStringDB::ParseString( 509, "#@item_name@#", strItemName.c_str() ); m_pGame->AddChatMessage( strMessage.c_str() ); } else if( vToken[ 1 ] == "TOO_MUCH_MONEY" ) // sonador 3.4.3 소지금 최대 한도 오류 시스템 메시지 추가 { m_pGame->AddChatMessage( S( 574 ) ); } vToken.clear(); } } if( pMsg->nChatType == CHAT_NOTICE ) { std::vector< std::string > vToken; MsgSplit( pMsg->strText.c_str(), vToken, L"|" ); if( vToken.size() >= 2 ) { if( vToken[0] == "ITEM_EXPIRE" ) m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SMSG_ITEM_TIME_DISAPPEAR, atoi( vToken[1].c_str() ) ) ); else if( vToken[0] == "ITEM_EXPIRE_STORAGE" ) m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SMSG_STORAGE_ITEM_TIME_DISAPPEAR, atoi( vToken[1].c_str() ) ) ); } vToken.clear(); } } // 실패 메세지 출력, kappamind. void SGameSystem::OnChatRequestFailed() { m_pGame->AddChatMessage( S(1633) ); } //1:1 대련 //2009-02-05: hunee void SGameSystem::OnMsgCompeteRequest( struct SMSG_SC_COMPETE_REQUEST* pMsg ) { const _OPT_DATA& opt_data = GetGameOption().GetOptData(); //std::string strMsgBoxText = SR(956, "#@player_name@#", vToken[1].c_str() ); if( opt_data.nPVP == 0 && !( GetLocalPlayer()->IsDead() ) ) // #kappamind. 상대가 거부옵션 체크와 죽음상태가 아니라면 신청 가능. { SetPVPAcceptCheck( true ); std::string strMsgBoxText = SR(956, "#@player_name@#", (const char *) pMsg->requester ); m_pGame->SendGameMsg( &SIMSG_REQ_OPEN_MSGBOX( SIMSG_REQ_OPEN_MSGBOX::MSGBOX_BATTLE_ACCEPT, strMsgBoxText.c_str(), pMsg->requester ) ); } else { //std::string strTex = "/battle_reject "; //strTex += pMsg->strData; //Rq_Chatting( CHAT_NORMAL, NULL, strTex.c_str() ); TS_CS_COMPETE_ANSWER msg; msg.compete_type = COMPETE_TYPE_VS_PLAYER; msg.answer_type = COMPETE_ANSWER_TYPE_REJECT_BY_OPTION; if( m_pGame ) m_pGame->SendMsg( &msg ); } } void SGameSystem::OnMsgCompeteAnswer( struct SMSG_SC_COMPETE_ANSWER* pMsg ) { char * __answer[] = { "COMPETE_ANSWER_TYPE_ACCEPT", "COMPETE_ANSWER_TYPE_REJECT_BY_USER", "COMPETE_ANSWER_TYPE_REJECT_BY_OPTION", "COMPETE_ANSWER_TYPE_REJECT_BY_TIMEOUT", }; SetPVPAcceptCheck( false ); switch (pMsg->answer_type) { case COMPETE_ANSWER_TYPE_ACCEPT: break; case COMPETE_ANSWER_TYPE_REJECT_BY_USER: if( !m_bIsShowBattleAccept ) m_pGame->AddChatMessage( SR(1632, "#@player_name@#", (const char *) pMsg->requestee ).c_str() ); break; case COMPETE_ANSWER_TYPE_REJECT_BY_OPTION: m_pGame->AddChatMessage( S(1633) ); break; case COMPETE_ANSWER_TYPE_REJECT_BY_TIMEOUT: if( 0 == ::stricmp( pMsg->requestee, "" ) ) m_pGame->AddChatMessage( S(1651) ); else m_pGame->AddChatMessage( SR(1632, "#@player_name@#", (const char *) pMsg->requestee ).c_str() ); m_pGame->SendGameMsg( &SIMSG_REQ_OPEN_MSGBOX( SIMSG_REQ_OPEN_MSGBOX::MSGBOX_BATTLE_ACCEPT, "", "", true ) ); break; } } void SGameSystem::OnMsgCompeteCountdown( struct SMSG_SC_COMPETE_COUNTDOWN* pMsg ) { m_pBattle_Info = new SGameSystem::Battle_Info; m_pBattle_Info->hTarget = pMsg->handle_competitor; m_pBattle_Info->arTime = GetArTime(); //m_pBattle_Info->bStartBattle = false; } void SGameSystem::OnMsgCompeteStart( struct SMSG_SC_COMPETE_START* pMsg ) { SetDeathPVP( false ); SetPVPStart( true ); // SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pGame->GetGameObject( m_pBattle_Info->hTarget ); if( pTarget ) pTarget->SetActivateBattleInArena( true ); //m_pBattle_Info->bStartBattle = true; //1:1 대련 시작 std::string strSysMsg = S(1634); m_pGame->AddNoticeMessageOnly( strSysMsg.c_str() ); m_pGame->AddChatMessage( S(1634) ); } void SGameSystem::OnMsgCompeteEnd( struct SMSG_SC_COMPETE_END* pMsg ) { SGameAvatarEx* pTarget; if( GetPVPStart() ) { pTarget = (SGameAvatarEx*)m_pGame->GetGameObject( m_pBattle_Info->hTarget ); } else { /// 2010.12.13 일감 #668과 관련된 내용, m_pBattle_End_Info->hTarget 값이 이상하게 들어오는데, 서버팀에서 확인 해줘야 될 것 같음 - prodongi pTarget = (SGameAvatarEx*)m_pGame->GetGameObject( m_pBattle_End_Info->hTarget ); } // if( pTarget ) pTarget->SetActivateBattleInArena( false ); m_pGame->AddNoticeMessageOnly( " " ); SAFE_DELETE( m_pBattle_Info ); SAFE_DELETE( m_pBattle_End_Info ); if( GetPVPStart() ) { std::string strSysMsg = S(958); m_pGame->AddNoticeMessageOnly( strSysMsg.c_str() ); m_pGame->AddChatMessage( S(958) ); //대련이 종료되었습니다.. } char * __endby[] = { "COMPETE_END_BY_DEATH", "COMPETE_END_BY_LOGOUT", "COMPETE_END_BY_RINGOUT", "COMPETE_END_BY_TIMEOUT", "COMPETE_END_BY_INTERRUPT", "COMPETE_END_BY_ENTERING_SAFETY_ZONE", }; // switch (pMsg->end_type) { case COMPETE_END_BY_RINGOUT: { if( GetPVPStart() ) { std::string strSysMsg = SR(1641, "#@loser_name@#", (const char *) pMsg->loser, "#@winner_name@#", (const char *) pMsg->winner ); m_pGame->AddChatMessage( strSysMsg.c_str() ); } else { m_pGame->SendGameMsg( &SIMSG_REQ_OPEN_MSGBOX( SIMSG_REQ_OPEN_MSGBOX::MSGBOX_BATTLE_ACCEPT, "", "", true ) ); m_pGame->AddChatMessage( SR(1632, "#@player_name@#", (const char *) pMsg->loser ).c_str() ); } } break; case COMPETE_END_BY_DEATH: { if( 0 == ::stricmp( GetLocalPlayer()->GetName(), pMsg->winner ) ) { SetDeathPVP( false ); } else { SetDeathPVP( true ); } std::string strSysMsg = SR(1637, "#@winner_name@#", (const char *) pMsg->winner, "#@loser_name@#", (const char *) pMsg->loser ); m_pGame->AddChatMessage( strSysMsg.c_str() ); /// 2011.01.20 - prodongi if (pTarget) { if( 0 == ::_stricmp( pTarget->GetName(), pMsg->winner ) ) { std::string strSysMsg = SR(1639, "#@winner_name@#", (const char *) pMsg->winner ); m_pGame->AddNoticeMessageOnly( strSysMsg.c_str() ); } else { std::string strSysMsg = SR(1638, "#@loser_name@#", (const char *) pMsg->loser ); m_pGame->AddNoticeMessageOnly( strSysMsg.c_str() ); } } } break; case COMPETE_END_BY_LOGOUT: { std::string strSysMsg = SR(1641, "#@loser_name@#", (const char *) pMsg->loser, "#@winner_name@#", (const char *) pMsg->winner ); m_pGame->AddChatMessage( strSysMsg.c_str() ); } break; case COMPETE_END_BY_INTERRUPT: { std::string strSysMsg = S(1642); m_pGame->AddNoticeMessageOnly( strSysMsg.c_str() ); m_pGame->AddChatMessage( S(1642) ); } break; case COMPETE_END_BY_TIMEOUT: { std::string strSysMsg = S(1643); m_pGame->AddNoticeMessageOnly( strSysMsg.c_str() ); m_pGame->AddChatMessage( S(1643) ); } break; case COMPETE_END_BY_ENTERING_SAFETY_ZONE: { if( GetPVPStart() ) { std::string strSysMsg = SR(1641, "#@loser_name@#", (const char *) pMsg->loser, "#@winner_name@#", (const char *) pMsg->winner ); m_pGame->AddChatMessage( strSysMsg.c_str() ); } else { m_pGame->SendGameMsg( &SIMSG_REQ_OPEN_MSGBOX( SIMSG_REQ_OPEN_MSGBOX::MSGBOX_BATTLE_ACCEPT, "", "", true ) ); m_pGame->AddChatMessage( SR(1632, "#@player_name@#", (const char *) pMsg->loser ).c_str() ); } } break; default: break; } SetPVPStart( false ); SetShowPVPIcon( false ); SetPVPAcceptCheck( false ); } struct SGameCommand { typedef std::string ( SGameSystem::*CMD_FUNCTION )( const char* ); typedef std::string ( SGameSystem::*CMD_FUNCTION_TOKEN )( const char*, std::vector< std::string > & ); typedef std::string ( SGameSystem::*CMD_FUNCTION_EMOTION )( int ); char* szCommand; CMD_FUNCTION _run; int nType; int nAdditionalParam; char* szReplace; std::string Run( const char* pCommand, SGameSystem* pGS, const char* pszAdditional = NULL ) const { switch ( nType ) { case 0 : return (pGS->*_run)( pCommand ); case 1 : { std::vector< std::string > vString; MsgSplit( pCommand, vString, L"\t " ); //Tab or Space std::string ret = (pGS->*((CMD_FUNCTION_TOKEN)_run))( pCommand, vString ); vString.clear(); return ret; } case 2 : pGS->OnMsgEmotion( nAdditionalParam ); return ""; case 3 : return szReplace; case 4 : { std::vector< std::string > vString; MsgSplit( pCommand, vString, L"\t " ); //Tab or Space std::string ret = Composite( szReplace, vString ); vString.clear(); return ret; } case 5 : { std::vector< std::string > vString; MsgSplit( pCommand, vString, L"\t " ); //Tab or Space std::string strCheat = "/"; strCheat += szCommand; strCheat += " "; pGS->CompleteRqChat( strCheat, vString, true ); vString.clear(); return strCheat; } case 6 : return (pGS->*_run)( pszAdditional ); default : assert( false ); return pCommand; } } std::string Composite( const char* szComposite, std::vector< std::string > & vToken ) const { std::string strCheat = szComposite; std::string strParam; int nPos; for ( size_t i = 1; i < vToken.size(); ++i ) { XStringUtil::Format( strParam, "__@%d", i ); nPos = strCheat.find( strParam ); while ( nPos != std::string::npos ) { strCheat.replace( nPos, strParam.size(), vToken[i] ); nPos = strCheat.find( strParam ); } } if ( strCheat.find( "__@" ) != std::string::npos ) // 변환 안된 파라메터가 있으면 사용자가 파라메터 갯수를 잘못 준거다 return ""; else return strCheat; } }; #define BEGIN_GM_COMMAND \ static SGameCommand __s_GMCommand[] = \ { #define BEGIN_COMMAND \ static SGameCommand __s_Command[] = \ { #define END_COMMAND \ { NULL, NULL, 0, 0, NULL } \ }; #define CMD( cmd, function ) \ { cmd, (SGameCommand::CMD_FUNCTION)(function), 0, 0, NULL }, #define CMDT( cmd, function ) \ { cmd, (SGameCommand::CMD_FUNCTION)(function), 1, 0, NULL }, #define EMOTION( cmd, param ) \ { cmd, NULL, 2, param, NULL }, #define REPLACE( cmd, string ) \ { cmd, NULL, 3, 0, string }, #define COMPOSITE( cmd, string ) \ { cmd, NULL, 4, 0, string }, #define COMPLETE( cmd ) \ { cmd, NULL, 5, 0, NULL }, #define CMDA( cmd, function ) \ { cmd, (SGameCommand::CMD_FUNCTION)(function), 6, 0, NULL }, BEGIN_GM_COMMAND CMDT( "set_r", &SGameSystem::OnGMCMDSysCommand ) CMDT( "set_w", &SGameSystem::OnGMCMDSysCommand ) CMDT( "set_g", &SGameSystem::OnGMCMDSysCommand ) CMDT( "web_url", &SGameSystem::OnGMCMDSysCommand ) CMDT( "web_open", &SGameSystem::OnGMCMDSysCommand ) CMDT( "web_toggle", &SGameSystem::OnGMCMDSysCommand ) CMDT( "web_close", &SGameSystem::OnGMCMDSysCommand ) CMDT( "sendtown", &SGameSystem::OnGMCMDSendTown ) REPLACE( "회복", "/heal" ) CMD( "타겟기록", &SGameSystem::OnGMCMDTargetRecord ) CMD( "target_record", &SGameSystem::OnGMCMDTargetRecord ) CMDT( "상태부과", &SGameSystem::OnGMCMDAddStatus ) REPLACE( "rebirth", "/rebirth" ) REPLACE( "부활", "/rebirth" ) CMDT( "levelup", &SGameSystem::OnGMCMDLevelUp ) CMDT( "leveldown", &SGameSystem::OnGMCMDLevelDown ) REPLACE( "고속이동", "/speed 150" ) REPLACE( "speedup", "/speed 1000" ) REPLACE( "이속증가", "/speed 1000" ) REPLACE( "이속표준", "/speed 100" ) CMD( "크리쳐진화", &SGameSystem::OnGMCMDEvolution ) CMDT( "크에피", &SGameSystem::OnGMCMDCreatureSP ) CMDT( "크리쳐피", &SGameSystem::OnGMCMDCreatureHP ) CMDT( "크리쳐엠피", &SGameSystem::OnGMCMDCreatureMP ) CMDT( "크리쳐경험치", &SGameSystem::OnGMCMDCreatureEXP ) CMDT( "크리쳐기본경험치", &SGameSystem::OnGMCMDCreatureBasicEXP ) CMDT( "크리쳐성장경험치", &SGameSystem::OnGMCMDCreatureGrowthEXP ) CMDT( "확인", &SGameSystem::OnGMCMDEvaluate ) CMDT( "조정", &SGameSystem::OnGMCMDAdjust ) CMDT( "오토설정", &SGameSystem::OnGMCMDSetAutoUser ) CMDT( "오토해제", &SGameSystem::OnGMCMDUnsetAutoUser ) CMDT( "오토확인", &SGameSystem::OnGMCMDCheckAutoUser ) CMDT( "set_auto_user", &SGameSystem::OnGMCMDSetAutoUser ) CMDT( "unset_auto_user", &SGameSystem::OnGMCMDUnsetAutoUser ) CMDT( "check_auto_user", &SGameSystem::OnGMCMDCheckAutoUser ) CMDT( "warp", &SGameSystem::OnGMCMDWarp ) CMDT( "공지", &SGameSystem::OnGMCMDNotice) CMDT( "notice", &SGameSystem::OnGMCMDNotice ) /// 2011.07.19 CMDT( "알림", &SGameSystem::OnGMCMDAnnounce) CMDT( "announce", &SGameSystem::OnGMCMDAnnounce) CMDT( "투명", &SGameSystem::OnGMCMDInvisible ) CMDT( "clarify", &SGameSystem::OnGMCMDInvisible ) CMDT( "show_player", &SGameSystem::OnGMCMDShowPlayer ) CMDT( "나홀로", &SGameSystem::OnGMCMDShowPlayer ) CMDT( "rupi", &SGameSystem::OnGMCMDRupi ) CMDT( "루피", &SGameSystem::OnGMCMDRupi ) CMD( "debug", &SGameSystem::OnGMCMDDebug ) CMD( "camera", &SGameSystem::OnGMCMDCamera ) CMDT( "level", &SGameSystem::OnGMCMDLevel ) CMDT( "레벨", &SGameSystem::OnGMCMDLevel ) CMDT( "exp", &SGameSystem::OnGMCMDExp ) CMDT( "경험치", &SGameSystem::OnGMCMDExp ) CMDT( "jp", &SGameSystem::OnGMCMDJobPoint ) CMDT( "잡포", &SGameSystem::OnGMCMDJobPoint ) CMDT( "jlv", &SGameSystem::OnGMCMDJobLevel ) CMDT( "잡레벨", &SGameSystem::OnGMCMDJobLevel ) CMDT( "protect_chat", &SGameSystem::OnGMCMDProhibitChat ) CMDT( "채금", &SGameSystem::OnGMCMDProhibitChat ) CMDT( "regenerate", &SGameSystem::OnGMCMDRegenerate ) CMDT( "리젠", &SGameSystem::OnGMCMDRegenerate ) COMPOSITE( "rate_rupi", "/run set_env( 'game.gold_drop_rate', __@1 )" ) COMPOSITE( "루피드랍율", "/run set_env( 'game.gold_drop_rate', __@1 )" ) COMPOSITE( "rate_item", "/run set_env( 'game.item_drop_rate', __@1 )" ) COMPOSITE( "아이템드랍율", "/run set_env( 'game.item_drop_rate', __@1 )" ) COMPOSITE( "item", "/run insert_item( __@1, __@2 )" ) COMPOSITE( "아생", "/run insert_item( __@1, __@2 )" ) COMPOSITE( "rate_exp", "/run set_env( 'game.exp_rate', __@1 )" ) COMPOSITE( "경험치비율", "/run set_env( 'game.exp_rate', __@1 )" ) COMPOSITE( "party_exp", "/run set_env( 'game.party_exp_rate', __@1 )" ) COMPOSITE( "파티경험치비율", "/run set_env( 'game.party_exp_rate', __@1 )" ) COMPOSITE( "warf", "/warp __@1 __@2" ) COMPOSITE( "워프", "/warp __@1 __@2" ) COMPOSITE( "force_warp", "/force_warp __@1 __@2" ) COMPOSITE( "강제워프", "/force_warp __@1 __@2" ) COMPOSITE( "move", "/warp __@1" ) COMPOSITE( "이동", "/warp __@1" ) COMPOSITE( "force_move", "/force_warp __@1" ) COMPOSITE( "강제이동", "/force_warp __@1" ) COMPOSITE( "send", "/warp __@1 __@2 __@3" ) COMPOSITE( "대상이동", "/warp __@1 __@2 __@3" ) COMPOSITE( "force_send", "/force_warp __@1 __@2 __@3" ) COMPOSITE( "강제대상이동", "/force_warp __@1 __@2 __@3" ) REPLACE( "user_count", "/run cprint( get_env( 'game.user_count' ) )" ) REPLACE( "접속자수", "/run cprint( get_env( 'game.user_count' ) )" ) COMPOSITE( "player_out", "/kick __@1" ) COMPOSITE( "퇴출", "/kick __@1" ) COMPOSITE( "where", "/run cprint( gv( 'x', '__@1' ) .. ' ' .. gv( 'y', '__@1' ) )" ) COMPOSITE( "어디", "/run cprint( gv( 'x', '__@1' ) .. ' ' .. gv( 'y', '__@1' ) )" ) /// 2010.11.15 안쓰여서 주석처리 함- prodongi /* REPLACE( "kick_out", "/run notice( '~~kick' )" ) REPLACE( "전체퇴출", "/run notice( '~~kick' )" ) */ REPLACE( "all화남", "/run notice( '~~ANI_ANGRY' )" ) //[이모션]- 화남 REPLACE( "all사죄", "/run notice( '~~ANI_APOLOGIZE' )" ) //[이모션]- 사죄 REPLACE( "all지겨움", "/run notice( '~~ANI_BORING' )" ) //[이모션]- 지겨움 REPLACE( "all절하기", "/run notice( '~~ANI_BOW' )" )//[이모션]- 절하기 REPLACE( "all환호", "/run notice( '~~ANI_CHEER' )" ) //[이모션]- 환호 REPLACE( "all박수", "/run notice( '~~ANI_CLAP' )" ) //[이모션]- 박수 REPLACE( "all춤", "/run notice( '~~ANI_DANCE' )" ) //[이모션]- 춤 REPLACE( "all행복", "/run notice( '~~ANI_HAPPY' )" ) //[이모션]- 행복 REPLACE( "all인사", "/run notice( '~~ANI_HI' )" ) //[이모션]- 인사 REPLACE( "all부정", "/run notice( '~~ANI_NO' )" ) //[이모션]- 부정 REPLACE( "all뿌루퉁", "/run notice( '~~ANI_POUT' )" ) //[이모션]- 뿌루퉁 REPLACE( "all약올리기", "/run notice( '~~ANI_PROVOKE' )" ) //[이모션]- 약올리기 REPLACE( "all슬픔", "/run notice( '~~ANI_SORROW' )" ) //[이모션]- 슬픔 REPLACE( "all긍정", "/run notice( '~~ANI_YES' )" ) //[이모션]- 긍정 REPLACE( "all기도", "/run notice( '~~ANI_PRAY' )" ) //[이모션]- 기도 CMDT( "npcrot", &SGameSystem::OnGMCMDNPCRotation ) CMDT( "npcrotoff", &SGameSystem::OnGMCMDNPCRotationOff ) CMDT( "자동이동", &SGameSystem::OnGMCMDAutoMove ) CMDT( "UI", &SGameSystem::OnGMCMDUI ) CMDT( "QUEST", &SGameSystem::OnGMCMDQuest ) CMDT( "QUESTADD", &SGameSystem::OnGMCMDQuestAdd ) CMDT( "autotooltip", &SGameSystem::OnGMCMDAutoToolTip) END_COMMAND SGameCommand& FindCommand( const char* szMsg, SGameCommand* vCmds ) { std::string strToken; const char* p = szMsg; while ( *p != NULL && *p == '/' ) ++p; while ( *p != NULL && *p != ' ' && *p != '\t' ) strToken += *p++; int i; for ( i = 0; vCmds[i].szCommand != NULL; ++i ) { if ( strToken == vCmds[i].szCommand ) break; } return vCmds[i]; } std::string SGameSystem::procGMCommand( const char *pChat ) { SGameCommand gc = FindCommand( pChat, __s_GMCommand ); if ( gc.szCommand != NULL ) { return gc.Run( pChat, this ); } else if (pChat[2]=='/') { std::string str = "/run cprint("; str += pChat+3; str += ")"; return str; } else { std::string str = "/run "; str += pChat+2; return str; } return pChat; /* 아이템생성 아이템을 생성한다. /아생 아이템명 수량 수량 디폴트는 1 1 : ADD 2: SET 몬스터생성 몬스터를 소환한다. /리젠 몬스터명 수량 스킬초기 캐릭터의 스킬을 초기화 한다 /스킬초기 직업초기 해당 종족의 기본직업으로 돌아간다. 스킬도 함께 초기화 된다. /직업초기 소환 캐릭터를 자신에게 소환함. /소환 캐릭터명 어디 대상의 위치 및 접속 상태 확인 /어디 캐릭터명 제재 대상의 캐릭터를 접속하지 못하게 한다 /제재 캐릭터명 전체퇴출 서버 내에 모든 사용자를 강제접속 해제 시킨다. /전체퇴출 투명 자신의 캐릭터를 다른 캐릭터가 보지 못하도록 한다. /투명 투명해제 투명상태를 해제한다. /투명해제 몬스터삭제 유령 몬스터 삭제 시 /몬스터삭제 좌표 */ } ////////////////////////////////////////////////////////////////////////// //요청~ //Chatting void SGameSystem::GetTargetName( std::string& strName ) { // 뒤에 캐릭터 이름이 붙어있지 않다면 타겟의 이름을 붙여준다. SGameAvatarEx* pTarget = GetTarget(); if( NULL != pTarget ) { if( TS_ENTER::GAME_PLAYER == pTarget->GetObjType() ) // 플레이어인 경우만 strName = pTarget->GetName(); } } bool SGameSystem::IsDelimiter( const wchar_t _c, std::wstring& delimiter ) { for( size_t i(0); i& vToken ) { if ( !szMsg ) return; std::wstring strTmp; unsigned len = (unsigned)::wcslen(szMsg)+1; for ( unsigned i = 0 ; i < len ; i++ ) { if ( IsDelimiter(szMsg[i], delimiter) ) { if ( !strTmp.empty() ) vToken.push_back( strTmp ); strTmp.erase( strTmp.begin(), strTmp.end() ); continue; } strTmp += szMsg[i]; } if( !strTmp.empty() ) vToken.push_back( strTmp ); } BEGIN_COMMAND CMD( "help", &SGameSystem::OnCMDHelp ) CMD( "returnlobby", &SGameSystem::OnCMDReturnLobby ) CMDT( "rpcreate", &SGameSystem::OnCMDCreateSiegeRaidParty ) CMDT( "gappoint_battle_commander", &SGameSystem::OnCMDAppointBattleCommander ) // sonador 3.5.1 던전 시즈 레벨 제한 CMDT( "gdelegate_battle_commander", &SGameSystem::OnCMDDelegateBattleCommander ) // COMPLETE( "rp_ginvite" ) COMPLETE( "rp_minvite" ) COMPLETE( "pcreate" ) COMPLETE( "pinvite" ) /// 2012.06.11 - prodongi COMPLETE("bp_oinvite") COMPLETE("bp_minvite") CMD( "assist", &SGameSystem::OnCMDAssist ) COMPLETE( "pkick" ) COMPLETE( "ppromote" ) CMDT( "change_guild_name", &SGameSystem::OnCMDChangeGuildName ) CMDT( "change_name", &SGameSystem::OnCMDChangeName ) COMPLETE( "ginvite" ) COMPLETE( "gkick" ) COMPLETE( "gpromote" ) COMPLETE( "add_friend" ) COMPLETE( "del_friend" ) COMPLETE( "add_denial" ) COMPLETE( "del_denial" ) CMDT( "gacreate", &SGameSystem::OnCMDCreateGuildAlliance ) CMDT( "gainvite", &SGameSystem::OnCMDInviteGuildAlliance ) CMDT( "gakick", &SGameSystem::OnCMDKickGuildAlliance ) CMDT( "gajoin", &SGameSystem::OnCMDJoinGuildAlliance ) CMDT( "change_alliance_name", &SGameSystem::OnCMDChangeGuildAllianceName ) COMPLETE( "battle_invite" ) CMDT( "battle_accept", &SGameSystem::OnCMDAcceptBattle ) CMD( "sit", &SGameSystem::OnCMDSit ) CMD( "stand", &SGameSystem::OnCMDStandUp ) CMDT( "townproplimit", &SGameSystem::OnCMDTownPropLimit ) CMD( "shopmode", &SGameSystem::OnCMDShopMode ) CMD( "ride", &SGameSystem::OnCMDRide ) CMD( "leave", &SGameSystem::OnCMDRide ) CMD( "mount_creature", &SGameSystem::OnCMDMountCreature ) CMDA( "normal", &SGameSystem::OnCMDNormal ) CMDA( "battle", &SGameSystem::OnCMDBattle ) CMD( "shop", &SGameSystem::OnCMDShop ) CMD( "union", &SGameSystem::OnCMDUnion ) CMD( "파티창추가", &SGameSystem::OnCMDAddPartyWindow ) CMD( "파티창삭제", &SGameSystem::OnCMDDelPartyWindow ) CMD( "trade", &SGameSystem::OnCMDTrade ) CMD( "movesoundon", &SGameSystem::OnCMDMoveSoundOn ) CMD( "movesoundoff", &SGameSystem::OnCMDMoveSoundOff ) CMD( "pkon", &SGameSystem::OnCMDPkOn ) CMD( "pkoff", &SGameSystem::OnCMDPkOff ) CMDT( "set_vol", &SGameSystem::OnCMDSetVolume ) CMD( "music_off", &SGameSystem::OnCMDMusicOff ) EMOTION( "rage", ANI_ANGRY ) EMOTION( "apology", ANI_APOLOGIZE ) EMOTION( "boring", ANI_BORING ) EMOTION( "greeting", ANI_BOW ) EMOTION( "cheers", ANI_CHEER ) EMOTION( "clap", ANI_CLAP ) #ifdef _COUNTRY_ME_ EMOTION( "dance", ANI_HAPPY ) #else EMOTION( "dance", ANI_DANCE ) #endif EMOTION( "laugh", ANI_HAPPY ) EMOTION( "hi", ANI_HI ) EMOTION( "no", ANI_NO ) EMOTION( "pish", ANI_POUT ) EMOTION( "makeangry", ANI_PROVOKE ) EMOTION( "sadness", ANI_SORROW ) EMOTION( "yes", ANI_YES ) EMOTION( "pray", ANI_PRAY ) #ifndef NDEBUG CMD( "guildicon", &SGameSystem::OnCMDGuildIcon ) #endif CMDT( "pshare", &SGameSystem::OnCMDPartyShare ) CMDT( "run", &SGameSystem::OnCMDRun ) CMD( "cashitem", &SGameSystem::OnCMDCashItem ) CMD( "urltest", &SGameSystem::OnCMDURLTest ) #ifdef _COUNTRY_ME_ CMD( "pango_test", &SGameSystem::OnCMDPangoTest ) #endif END_COMMAND void SGameSystem::Rq_Chatting( int nChatType, const char * pTargetName, const char * pChat ) { if( !pChat ) return; if( !ENV().IsExist( "cash" ) ) { if( CStringUtil::isCommand( pChat, "/cstorage" ) || CStringUtil::isCommand( pChat, "/cshop" ) ) return; } std::string strCommand = pChat; if (strCommand.length() >1 && strCommand[0] == '/' && strCommand[1] == '/' ) strCommand = procGMCommand( pChat ); if (strCommand.length() >1 && strCommand[0] == '/' && ( nChatType != CHAT_TYPE::CHAT_GM_WHISPER && nChatType != CHAT_TYPE::CHAT_HELPER_WHISPER && nChatType != CHAT_TYPE::CHAT_WHISPER && nChatType != CHAT_TYPE::CHAT_WHISPER ) ) { strCommand = GetLocalCommandDB().Convert( strCommand.c_str() ); SGameCommand gc = FindCommand( strCommand.c_str(), __s_Command ); if ( gc.szCommand != NULL ) strCommand = gc.Run( strCommand.c_str(), this, pTargetName ); } if ( strCommand.length() ) { // 메세지 헤더 TS_CS_CHAT_REQUEST msg; if( pTargetName == NULL ) strcpy( msg.szTarget, "Nothing" ); else strcpy( msg.szTarget, pTargetName ); msg.type = nChatType; msg.len = static_cast< unsigned >( strCommand.length() ); const int BUFFER_MAX = 170; char szText[BUFFER_MAX] = {0,}; //#define _EUROPE_TEST_ #ifdef _EUROPE_TEST_ //ANSI -> UNICODE 변환 //UNICODE -> UTF8 변환 wchar_t wszBuffer[BUFFER_MAX]; MultiByteToWideChar( CP_ACP, 0, szTmp, -1, wszBuffer, BUFFER_MAX ); msg.len = WideCharToMultiByte( CP_UTF8, 0, wszBuffer, -1, szText, BUFFER_MAX, NULL, NULL ); #else /// 2011.07.13 복사 길이 체크 - prodongi //strcpy( szText, strCommand.c_str() ); strncpy(szText, strCommand.c_str(), BUFFER_MAX); #endif if( msg.len > BUFFER_MAX ) msg.len = BUFFER_MAX; //chatting 크기만큼 사이즈 늘림. msg.size += static_cast< unsigned >( sizeof(char) * msg.len ); // 체크섬 추가해야함. msg.set_check_sum(); // 메모리 할당 char * pBuffer = new char[ msg.size ]; memset( pBuffer, 0, sizeof(char)*msg.size ); // 버퍼에 헤더 복사 memcpy( pBuffer, &msg, sizeof(TS_CS_CHAT_REQUEST) ); char * pChatting = (char *)( pBuffer + sizeof(TS_CS_CHAT_REQUEST) ); memcpy( pChatting, szText, sizeof(char)*msg.len ); if( m_pGame ) m_pGame->SendMsg( reinterpret_cast(pBuffer) ); delete [] pBuffer; } } void SGameSystem::CompleteRqChat( std::string& rq_chat, std::vector< std::string >& vString, bool bTarget ) { std::string strName; if( vString.size() < 2 ) { if( bTarget ) GetTargetName( strName ); } else strName = vString[1].c_str(); if( !strName.empty() ) rq_chat += strName; } void SGameSystem::SetLocalPlayer( SGameAvatarEx* pPlayer ) { m_pPlayer = pPlayer; #ifndef NDEBUG if( m_pPlayer ) m_GuildDataMgr.SetLocalPlayer( m_pPlayer->GetArID() ); #endif if( pPlayer ) { //인벤토리에 셋팅 SIMSG_UI_MAINPLAYER_INFO msg; msg.pSeqForm = pPlayer->GetSeqForm(); m_pGame->SendGameInterfaceMsg( &msg ); } } void SGameSystem::SetLocalInven() { if( m_pPlayer ) { //인벤토리에 셋팅 SIMSG_UI_MAINPLAYER_INFO msg; msg.pSeqForm = m_pPlayer->GetSeqForm(); msg.pCobName = m_pPlayer->GetCobFileName(); msg.handle = m_pPlayer->GetArID(); msg.bRefresh = true; m_pGame->SendGameInterfaceMsg( &msg ); } } SGameAvatarEx* SGameSystem::GetLocalPlayer() { return m_pPlayer; } char const* SGameSystem::getLocalPlayerName() { if (PARTY_ARENA == m_PartyMgr.GetPartyType() || m_PartyMgr.isArenaParty()) { if (m_PlayerInfoMgr.IsAlias()) return m_PlayerInfoMgr.GetAlias(); } return m_PlayerInfoMgr.GetName(); } bool SGameSystem::isLocalPlayerName(char const* name) { if (strcmp(m_PlayerInfoMgr.GetName(), name) == 0) return true; if (m_PlayerInfoMgr.IsAlias()) { if (strcmp(m_PlayerInfoMgr.GetAlias(), name) == 0) return true; } return false; } int SGameSystem::GetLocalPlayerPermission() { return m_PlayerInfoMgr.GetPermission(); } void SGameSystem::OnMsgEmotion( int nEmotionID ) { SGameAvatarEx* pPlayer = GetLocalPlayer(); if( pPlayer ) { if( pPlayer->CheckAllState() == false || pPlayer->IsWorkListEmpty() == false ) { // TODO : 메시지 추가해야함 임시로 추가 m_pGame->AddChatMessage( S(228) ); return; } TS_CS_EMOTION emotion_msg; emotion_msg.emotion = nEmotionID; if( m_pGame ) m_pGame->SendMsg( &emotion_msg ); } } //Inventory 관련-------------------------------------------------------- //요청 //Item 추가 void SGameSystem::Rq_TakeItem( AR_HANDLE item_handle ) { //서버에 Item 먹고 싶다고 요청. SGameAvatarEx* pPlayer = GetLocalPlayer(); SGameAvatarEx* pItem = (SGameAvatarEx*)m_pGame->GetGameObject( item_handle ); if( pPlayer && pItem ) { if( pPlayer->GetCurrAnimationID() != ANI_PICKUP01 ) { float fDist = GetDistance( *pPlayer->GetPosition(), *pItem->GetPosition() ); SInputTakeItem inputTakeItem( item_handle, fDist ); pPlayer->OnInput( &inputTakeItem ); } //m_pGame->StartSound( "item_pickup_etc.wav" ); } /* TS_CS_TAKE_ITEM msg; msg.item_handle = item_handle; if( m_pGame ) m_pGame->SendMsg( &msg );*/ } void SGameSystem::Rq_PutOnOffItem( AR_HANDLE hTarget, AR_HANDLE hItem, int nPosition ) { SGameAvatarEx* pPlayer = GetLocalPlayer(); if( pPlayer ) { if( pPlayer->IsCasting() || pPlayer->IsAttack() || pPlayer->IsUsingSkill() || pPlayer->IsAttacking() || pPlayer->IsIng() ) { m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_OTHER_ACTION_WAIT ) ); return; } if( hItem ) { TS_CS_PUTON_ITEM msg; msg.target_handle = hTarget; msg.item_handle = hItem; msg.position = nPosition; m_pGame->SendMsg( &msg ); } else { TS_CS_PUTOFF_ITEM msg; msg.target_handle = hTarget; msg.position = nPosition; m_pGame->SendMsg( &msg ); } } } //Item 떨굼 void SGameSystem::Rq_DropItem( AR_HANDLE item_handle, count_t nDropCnt ) { SInventorySlot* pSlot = m_InventoryMgr.GetItemInfo(item_handle); assert( pSlot != NULL && "Data Error: Interface data and GameSystem do not match." ); if( pSlot ) { TS_CS_DROP_ITEM msg; msg.item_handle = pSlot->GetHandle(); msg.count = nDropCnt.getAmount(); if( msg.item_handle > 0 ) { if( m_pGame ) m_pGame->SendMsg( &msg ); } } } //Item 파괴 void SGameSystem::Rq_DestroyItem( void * pVItems, int size ) { TS_CS_ERASE_ITEM::EraseItemInfo * arrItems = (TS_CS_ERASE_ITEM::EraseItemInfo * )pVItems; // 파괴 패킷 생성. TS_CS_ERASE_ITEM msg; msg.item_count = size; msg.size += ( sizeof(TS_CS_ERASE_ITEM::EraseItemInfo) * size ); msg.set_check_sum(); char * pBuffer = new char[ sizeof(TS_CS_ERASE_ITEM) + ( sizeof(TS_CS_ERASE_ITEM::EraseItemInfo) * size ) ]; memcpy( pBuffer, &msg, sizeof(TS_CS_ERASE_ITEM) ); char* pDes = pBuffer + sizeof(TS_CS_ERASE_ITEM); for( int i(0); iSendMsg( (TS_CS_ERASE_ITEM * )pBuffer ); delete [] pBuffer; delete [] arrItems; // 패킷전송. // 같은 패킷을 왜 두번 보내나.... /*if( m_pGame ) m_pGame->SendMsg( &msg );*/ } // void SGameSystem::Rq_ItemSet( int nItemSetIndex ) { return; //서버에 Item Set 변경 요청. TS_MESSAGE msg; //아이템 ID //Set Index if( m_pGame ) m_pGame->SendMsg( &msg ); } void SGameSystem:: Rq_NPC_Contact( AR_HANDLE nNpcHandle ) { TS_CS_CONTACT msg; msg.handle = nNpcHandle; if( m_pGame ) m_pGame->SendMsg( &msg ); } void SGameSystem::OnCommercialStorage( struct SMSG_COMMERCIAL_STORAGE_LIST* pCashItem ) { assert( pCashItem->vItemList.size() == pCashItem->count ); //기존 것 모두 삭제 m_InventoryMgr.ClearCashItem(); //전체 다 갱신함. unsigned int nItemSize = pCashItem->vItemList.size(); for( unsigned int i(0); nItemSize>i; i++ ) { TS_SC_COMMERCIAL_STORAGE_LIST::CommercialItemInfo * pItemInfo = &pCashItem->vItemList[i]; m_InventoryMgr.UpdateCashItem( pItemInfo ); } } //응답 //Item 추가 int SGameSystem::AddItem( TS_ITEM_INFO * pItemInfo ) { if( pItemInfo->wear_position == ItemBase::WEAR_STORAGE ) // 창고 m_StorageMgr.AddItem( pItemInfo ); else m_InventoryMgr.AddItem( pItemInfo ); return 1; } int SGameSystem::Rq_UseItem( AR_HANDLE item_handle, AR_HANDLE target_handle, AR_HANDLE item_use_target_handle, const char* lpText/*=NULL*/ ) { m_InventoryMgr.Rq_UseItem( m_pPlayer->GetRace(), item_handle, target_handle, item_use_target_handle, lpText ); return 1; } //Item 떨굼 int SGameSystem::DropItem( AR_HANDLE item_handle ) { m_InventoryMgr.DropItem( item_handle ); return 1; } //Item 파괴 int SGameSystem::DestroyItem( AR_HANDLE item_handle ) { // redmine_23159 아이템 파괴 요청 상태일 때는 모든 수량이 파괴되는 아이템도 카운트를 업데이트 해준다.. if(m_InventoryMgr.GetIsRquestDestroyState()) m_InventoryMgr.UpdateItemCount( item_handle, count_t(0), true ); m_StorageMgr.DeleteItem( item_handle ); m_InventoryMgr.DestroyItem( item_handle ); return 1; } //Item 수량 변경 int SGameSystem::UpdateItemCount( AR_HANDLE item_handle, count_t nItemCount ) { m_StorageMgr.UpdateItemCount( item_handle, nItemCount ); m_InventoryMgr.UpdateItemCount( item_handle, nItemCount ); return 1; } //Item Set void SGameSystem::ItemSet( int nItemSetIndex ) { m_InventoryMgr.ItemSet( nItemSetIndex ); } //구매 노점 개설 void SGameSystem::Rq_MarketStall_Buy( const char * pName ) { } //판매 노점 개설 void SGameSystem::Rq_MarketStall_Sale( const char * pName ) { } //Skill 관련-------------------------------------------------------- void SGameSystem::Rq_Skill_Learn( AR_HANDLE handle, int nSkillID, int nOriginSkillID, short nSkillLv ) //스킬 레벨 올림 또는 스킬 배우다. { TS_CS_LEARN_SKILL msg; msg.target = handle; msg.skill_id = nSkillID; msg.origin_skill_id = nOriginSkillID; msg.skill_level = nSkillLv; if( m_pGame ) m_pGame->SendMsg( &msg ); } //Job 관련 void SGameSystem::Rq_JopLevelUp( AR_HANDLE handle ) //잡 레벨을 올린다(1씩) { TS_CS_JOB_LEVEL_UP msg; msg.target = handle; if( m_pGame ) m_pGame->SendMsg( &msg ); } void SGameSystem::Rq_ChangeLocation() { SGameAvatarEx* pPlayer = GetLocalPlayer(); if( pPlayer ) { TS_CS_CHANGE_LOCATION changelc_msg; changelc_msg.x = pPlayer->GetPosition()->x; changelc_msg.y = pPlayer->GetPosition()->y; if( m_pGame ) m_pGame->SendMsg( &changelc_msg ); } } void SGameSystem::AddGameCreatureInput( SGameInput * pInput ) { for( unsigned int i(0); m_vCreatureDataList.size()>i; i++ ) { SGameAvatarEx * pCreature = (SGameAvatarEx*)m_pGame->GetGameObject( m_vCreatureDataList[i].summon_handle ); if( !pCreature ) continue; //마운트 상태이거나 마운트 모드가 아니여야한다 if( !pCreature->IsMount() && !pCreature->IsMountMode() ) { //Shift키로 이동했다고 알린다 pCreature->SetHold(); pCreature->OnInput( pInput ); } } } void SGameSystem::AddGameInput( SGameInput * pInput ) { if( GetLocalPlayer() ) GetLocalPlayer()->OnInput( pInput ); } void SGameSystem::AddNetInputNet( struct SGameMessage* pGameMsg ) { if( GetLocalPlayer() ) GetLocalPlayer()->OnNetInput( pGameMsg ); } void SGameSystem::InitInterfaceData() { // 각 매니저의 초기화를 시킨다 } void SGameSystem::CmdUseSkil( STRUCT_CREATURE_CMD_SCRIPT &sCCmdScr ) { //m_pGame->AddChatMessage("void SGameSystem::CmdUseSkil( STRUCT_CREATURE_CMD_SCRIPT &sCCmdScr )"); QUICK_SKILL* pSlot = m_CreatureSkillSlotMgr.FindQuickSlot( sCCmdScr.cHandle, sCCmdScr.nSlotNum ); if( pSlot ) { //현재 사용중이거나 쿨 타임중인지 체크 if( m_CreatureSkillSlotMgr.IsUseSkill( sCCmdScr.cHandle, pSlot->m_nSkillID ) ) return; if( sCCmdScr.mHandle ) { if( m_CreatureSkillSlotMgr.IsExistSkill( pSlot->m_nSkillID, sCCmdScr.cHandle ) ) { SIMSG_UI_ACT_USESKILL msg; msg.nSkillID = pSlot->m_nSkillID; msg.nLevel = pSlot->m_nUseLevel; msg.caster_handle = sCCmdScr.cHandle; msg.target_handle = sCCmdScr.mHandle; OnMsgUseSkill( &msg ); } } } } //기본 공격 시작시 상태이상 이펙트 void SGameSystem::AddStatusAction( AR_HANDLE hAttackter, AR_HANDLE hTarget ) { SGameAvatarEx* pAvatar = (SGameAvatarEx*)m_pGame->GetGameObject( hAttackter ); SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pGame->GetGameObject( hTarget ); if( pAvatar == NULL || pTarget == NULL ) return; if( pAvatar->GetObjType() != TS_ENTER::GAME_PLAYER ) return; //상태이상 정보를 가져온다 std::vector vecStateList; pAvatar->GetAllStateList(vecStateList, false); std::vector::iterator iter = vecStateList.begin(); for(; iter != vecStateList.end(); iter++ ) { SStateSlot* pStateSlot = (*iter); StateInfoEx* pStateInfo = GetTenacityDB().GetTenacityData( pStateSlot->GetStateCode() ); if( pStateInfo ) { //내가 공격을 시작하면 발동되는 이펙트 if( m_PlayerInfoMgr.IsSCastAttack( pStateInfo->special_output_timing_id ) ) { pAvatar->AddEffect( hAttackter, hAttackter, hAttackter, pStateInfo->special_output_fx_id, pStateInfo->special_output_fx_pos_id); } } else _oprint( "SGameSystem::AddStatusAction 상태 정보 없음 %d\n", pStateSlot->GetStateCode() ); } vecStateList.clear(); } //시전시 발생하는 상태이상 이펙트 void SGameSystem::AddStatusCastingAction( struct SMSG_SKILL_EVENT* pMsg ) { SGameAvatarEx* pAvatar = (SGameAvatarEx*)m_pGame->GetGameObject( pMsg->caster ); if( pAvatar == NULL ) return; //상태이상 정보를 가져온다 std::vector vecStateList; pAvatar->GetAllStateList(vecStateList, false); std::vector::iterator iter = vecStateList.begin(); for(; iter != vecStateList.end(); iter++ ) { SStateSlot* pStateSlot = (*iter); StateInfoEx* pStateInfo = GetTenacityDB().GetTenacityData( pStateSlot->GetStateCode() ); if( pStateInfo ) { //지금 시전된 스킬과 같은 상태이상 스킬 아이디가 있을경우 출력 if( pStateInfo->cast_fx_id == pMsg->skill_id ) { pAvatar->AddEffect( pMsg->caster, pMsg->caster, pMsg->caster, pStateInfo->cast_fx_pos_id, pStateInfo->hit_fx_id ); } _MOTION_FX_SET* pMotionFxSet = GetMotionFxSetDB().GetFXSet( pMsg->skill_id ); if( pMotionFxSet ) { if( m_PlayerInfoMgr.IsSCastCombat( pStateInfo->special_output_timing_id, pMotionFxSet->nFx_Type ) || m_PlayerInfoMgr.IsSCastMagic( pStateInfo->special_output_fx_id, pMotionFxSet->nFx_Type ) ) { pAvatar->AddEffect( pMsg->caster, pMsg->caster, pMsg->caster, pStateInfo->special_output_fx_id, pStateInfo->special_output_fx_pos_id ); } } else _oprint( "SGameSystem::AddStatusCastingAction FxSet 정보 없음 %d\n", pMsg->skill_id ); } else _oprint( "SGameSystem::AddStatusCastingAction 상태 정보 없음 %d\n", pStateSlot->GetStateCode() ); } vecStateList.clear(); } //히트시 발생하는 상태이상 이펙트 void SGameSystem::AddStatusFireAction( SGameMessage* msg ) { SMSG_DAMAGE* pDmgMsg = static_cast(msg); SGameAvatarEx* pAvatar = (SGameAvatarEx*)m_pGame->GetGameObject(pDmgMsg->attacker_handle); SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pGame->GetGameObject(pDmgMsg->target_handle ); //완료되면 몹에게도 적용 if( pAvatar == NULL || pTarget == NULL || pAvatar->GetObjType() != TS_ENTER::PLAYER ) return; bool bAddDamage = false; for( int i(0); CreatureElemental::ElementalType::COUNT>i; i++ ) { //데미지 타입이 스킬일 경우 100% 발동 //물리 공격일경우 추가 뎀쥐가 존재한다면 발동 if( pDmgMsg->elemental_damage[i] != 0 ) { bAddDamage = true; break; } } std::vector vecStateList; pAvatar->GetAllStateList(vecStateList, false); std::vector::iterator iter = vecStateList.begin(); for(; iter != vecStateList.end(); iter++ ) { SStateSlot* pStateSlot = (*iter); StateInfoEx* pStateInfo = GetTenacityDB().GetTenacityData( pStateSlot->GetStateCode() ); if( pStateInfo == NULL ) { _oprint( "SGameSystem::AddStatusFireAction 상태 정보 없음 %d\n", pStateSlot->GetStateCode() ); continue; } if( bAddDamage && pDmgMsg->nSkillID == 0) //기본 공격 { //내 공격이 타겟에 적중했을경우 상대방에 발동되는 이펙트 if( !(pDmgMsg->flag & TS_ATTACK_EVENT::FLAG_MISS ) && m_PlayerInfoMgr.IsTHitAttack( pStateInfo->special_output_timing_id ) ) { pAvatar->AddEffect( pDmgMsg->target_handle, pDmgMsg->target_handle, pDmgMsg->target_handle, pStateInfo->special_output_fx_id, pStateInfo->special_output_fx_pos_id ); } } else if( bAddDamage == false && pDmgMsg->nSkillID != 0 && !(pDmgMsg->skillresult.damage.flag & SkillResult::MISS) ) //마법 공격 및 전투스킬 공격 { _SKILL_FX* pSkillFX = GetSkillStageDB().GetSkillStageData( pDmgMsg->nSkillID ); if( pSkillFX ) { //내 스킬이 타겟에 적중했을 경우 상대방에 발동되는 이펙트 if( m_PlayerInfoMgr.IsTHitMagic( pStateInfo->special_output_timing_id , pSkillFX->nCasting_Type_Id ) || m_PlayerInfoMgr.IsSHitMagic( pStateInfo->special_output_fx_id , pSkillFX->nCasting_Type_Id ) ) { pAvatar->AddEffect( pDmgMsg->target_handle, pDmgMsg->target_handle, pDmgMsg->target_handle, pStateInfo->special_output_fx_id, pStateInfo->special_output_fx_pos_id ); } //내 전투 스킬이 타겟에 적중했을 경우 상대방에 발동되는 이펙트 else if( m_PlayerInfoMgr.IsTHitCombat( pStateInfo->special_output_timing_id , pSkillFX->nCasting_Type_Id ) || m_PlayerInfoMgr.IsTHitMagic( pStateInfo->special_output_fx_id , pSkillFX->nCasting_Type_Id ) ) { pAvatar->AddEffect( pDmgMsg->target_handle, pDmgMsg->target_handle, pDmgMsg->target_handle, pStateInfo->special_output_fx_id, pStateInfo->special_output_fx_pos_id ); } } else _oprint( "SGameSystem::AddStatusFireAction FxSet 정보 없음 %d\n", pDmgMsg->nSkillID ); } } pTarget->GetAllStateList(vecStateList, false); iter = vecStateList.begin(); for(; iter != vecStateList.end(); iter++ ) { SStateSlot* pStateSlot = (*iter); StateInfoEx* pStateInfo = GetTenacityDB().GetTenacityData( pStateSlot->GetStateCode() ); if( pStateInfo == NULL ) { _oprint( "SGameSystem::AddStatusFireAction 상태 정보 없음 %d\n", pStateSlot->GetStateCode() ); continue; } if( pDmgMsg->nSkillID != 0 && !(pDmgMsg->skillresult.damage.flag & SkillResult::MISS) ) //마법 공격 및 전투스킬 공격 { _SKILL_FX* pSkillFX = GetSkillStageDB().GetSkillStageData( pDmgMsg->nSkillID ); if( pSkillFX ) { //상대방이 내 전투 스킬및 스킬에 적중했을 경우 상대방 상태를 검사하여 이펙트를 발동시킨다 if( m_PlayerInfoMgr.IsSHitMagic( pStateInfo->special_output_timing_id , pSkillFX->nCasting_Type_Id ) || m_PlayerInfoMgr.IsSHitMagic( pStateInfo->special_output_fx_id , pSkillFX->nCasting_Type_Id ) ) { pAvatar->AddEffect( pDmgMsg->target_handle, pDmgMsg->target_handle, pDmgMsg->target_handle, pStateInfo->special_output_fx_id, pStateInfo->special_output_fx_pos_id ); } else if( m_PlayerInfoMgr.IsSHitCombat( pStateInfo->special_output_timing_id , pSkillFX->nCasting_Type_Id ) || m_PlayerInfoMgr.IsSHitMagic( pStateInfo->special_output_fx_id , pSkillFX->nCasting_Type_Id ) ) { pAvatar->AddEffect( pDmgMsg->target_handle, pDmgMsg->target_handle, pDmgMsg->target_handle, pStateInfo->special_output_fx_id, pStateInfo->special_output_fx_pos_id ); } } else _oprint( "SGameSystem::AddStatusFireAction FxSet 정보 없음 %d\n", pDmgMsg->nSkillID ); } else { if( !(pDmgMsg->flag & TS_ATTACK_EVENT::FLAG_MISS ) && m_PlayerInfoMgr.IsSHitAttack( pStateInfo->special_output_timing_id ) ) { pAvatar->AddEffect( pDmgMsg->target_handle, pDmgMsg->target_handle, pDmgMsg->target_handle, pStateInfo->special_output_fx_id, pStateInfo->special_output_fx_pos_id); } } } vecStateList.clear(); } //공격 전 무게 확인 bool SGameSystem::WeightConfirmationTheBeforeAttacking() { float fInvenWeight = m_PlayerInfoMgr.GetInvenWeigth(); int nMaxWeight = m_PlayerInfoMgr.GetWeight(); int nWeightRatio = ( fInvenWeight / (float)nMaxWeight) * 100.f; if( nWeightRatio >= 90 ) { m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_WEIGHT_EXCESS_NOT_ATTACK ) ); return false; } return true; } void SGameSystem::SendGuildData( int nGuild_id ) { return m_GuildDataMgr.SendGuildData( nGuild_id ); } bool SGameSystem::IsExistGuildInfo( int nGuild_id ) { return m_GuildDataMgr.IsExistGuild( nGuild_id ); } void SGameSystem::ActivateQuestProp( SGameAvatarEx* pCaster, SGameAvatarEx* pQuestProp ) { if( pCaster->IsStateRide() || pCaster->CurrentlyAnimationIsMount() ) { if( m_pGame ) m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_RIDING_IMPASSABLE ) ); return; } AR_UNIT nCastRange = ((SGameFieldQuestProp*)pQuestProp)->GetCastingRange(); AR_UNIT nValidRange = 0.0f; if( nCastRange == 0 ) { assert( nCastRange && "Skill use – range is abnormal" ); _oprint( "Data error! Skill use – range is abnormal\n" ); } SGameFieldQuestProp* pFiledQuestProp = static_cast< SGameFieldQuestProp* >(pQuestProp); switch( pFiledQuestProp->GetActivationtype() ) { case SGameFieldQuestProp::CHECK_ITEM: { bool bCheck = false; count_t nItemCount = m_InventoryMgr.GetItemCount( pFiledQuestProp->GetActivationValue1() ); if( nItemCount <= 0 ) bCheck = true; else { if( nItemCount < pFiledQuestProp->GetActivationValue2() ) bCheck = true; } if( bCheck ) { //TODO : 임시 시스템 메시지 if( m_pGame ) m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_USE_ITEM_FAIL ) ); return; } } break; case SGameFieldQuestProp::CHECK_QUEST: break; case SGameFieldQuestProp::CHECK_SKILL: break; case SGameFieldQuestProp::CHECK_WEAPON: { //착용 유무 체크 if( pFiledQuestProp->GetActivationValue2() ) { //착용 유 ItemBase::ItemCode nRItemCode = pCaster->GetItemCode(ItemBase::WEAR_WEAPON); ItemBase::ItemCode nLItemCode = pCaster->GetItemCode(ItemBase::WEAR_SHIELD); int nNeedItem = pFiledQuestProp->GetActivationValue1(); if( nNeedItem != nRItemCode && nNeedItem != nLItemCode ) { //TODO : 임시 시스템 메시지 if( m_pGame ) m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_USE_ITEM_FAIL ) ); return; } } else { //착용 무 count_t nItemCount = m_InventoryMgr.GetItemCount( pFiledQuestProp->GetActivationValue1() ); if( nItemCount <= 0 ) { //TODO : 임시 시스템 메시지 if( m_pGame ) m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_USE_ITEM_FAIL ) ); return; } } } break; case SGameFieldQuestProp::CHECK_CREATURE: break; case SGameFieldQuestProp::CHECK_PROP: break; case SGameFieldQuestProp::CHECK_PERSONS: break; } int nSkillID = GetFieldPropResourceDB().GetSkillID( pFiledQuestProp->GetQuestPropDBID() ); // 2011.12.07 Activation prop delay check - prodongi if (m_activatePropUpdate.enable(nSkillID)) { SInputSkill inputSkill( nSkillID, 1, pQuestProp->GetArID(), nCastRange, nValidRange ); pCaster->OnInput( &inputSkill ); m_activatePropUpdate.checkBegin(nSkillID); } if( pFiledQuestProp->GetQuestPropDBID() == 9000 ) m_pQuestProp = pQuestProp; } void SGameSystem::UpdateContributionPropData() { if( m_pQuestProp == NULL ) return; SGameAvatarEx* pLocalPlayer = GetLocalPlayer(); if( pLocalPlayer == NULL ) return; SGameFieldQuestProp* pFiledQuestProp = static_cast< SGameFieldQuestProp* >(m_pQuestProp); int nSkillID = GetFieldPropResourceDB().GetSkillID( pFiledQuestProp->GetQuestPropDBID() ); SInputSkill inputSkill( nSkillID, 1, m_pQuestProp->GetArID(), 0.0f, 0.0f ); pLocalPlayer->OnInput( &inputSkill ); } bool SGameSystem::IsPartyMember( AR_HANDLE hTarget ) { SGameAvatarEx* pLocalPlayer = GetLocalPlayer(); if( pLocalPlayer ) { if( pLocalPlayer->GetArID() == hTarget ) return true; } return m_PartyMgr.FindMember( hTarget ) != NULL ? true : false; } bool SGameSystem::IsGuildMember( AR_HANDLE hTarget ) { SGameAvatarEx* pLocalPlayer = GetLocalPlayer(); if( pLocalPlayer ) { if( pLocalPlayer->GetArID() == hTarget ) return true; } return m_GuildMgr.FindMember( hTarget ) != NULL ? true : false; } bool SGameSystem::IsRaidMember( AR_HANDLE hTarget ) { SGameAvatarEx* pLocalPlayer = GetLocalPlayer(); if( pLocalPlayer ) { if( pLocalPlayer->GetArID() == hTarget ) return true; } return true; // return m_RaidMgr.FindMember( hTarget ) != NULL ? true : false; } void SGameSystem::OnMsgEnterEventArea(struct SMSG_ENTER_EVENTAREA *pMsg) { TS_CS_ENTER_EVENT_AREA msg; msg.event_area_id = pMsg->nID; msg.area_index = pMsg->nPolyNum; m_pGame->SendMsg( &msg ); _oprint("Enter Event Area! : ID = %d\n", pMsg->nID); } void SGameSystem::OnMsgLeaveEventArea(struct SMSG_LEAVE_EVENTAREA *pMsg) { // 2011.07.06 - servantes / 패킷 보내는 코드 추가 TS_CS_LEAVE_EVENT_AREA msg; msg.event_area_id = pMsg->nID; msg.area_index = pMsg->nPolyNum; m_pGame->SendMsg( &msg ); _oprint("Leave Event Area! : ID = %d\n", pMsg->nID); } /// 2011.05.12 우클릭 유동 - prodongi void SGameSystem::OnMsgSummonCardSkillList(SIMSG_UI_SUMMON_CARD_SKILL_LIST *pMsg) { TS_CS_SUMMON_CARD_SKILL_LIST msg; msg.item_handle = pMsg->handle; m_pGame->SendMsg(&msg); } /// 2011.09.27 대련중 사용 가능 체크 - prodongi bool SGameSystem::enableUseSkillAtPVP(SkillBaseEx* skill) { if (!skill) return true; if (0 == skill->state_id) return true; StateInfoEx* state = GetTenacityDB().GetTenacityData(skill->state_id); if (!state) return true; if (state->state_time_type & (1<<13)) return false; return true; } /// 2012.05.17 - prodongi bool SGameSystem::isTrading() const { if (m_PlayerInfoMgr.GetTradeTarget()) return true; return false; } bool SGameSystem::isParting() const { if (m_PartyMgr.IsExist()) return true; return false; } bool SGameSystem::isNormalParting() const { if (m_PartyMgr.IsExist()) { if (PARTY_NORMAL == m_PartyMgr.GetPartyType()) return true; return false; } return false; } bool SGameSystem::isInArena() const { SGameWorld* gameWorld = dynamicCast(GetGame()); int playerLocation = gameWorld->GetPlayerCurrentLocation(); return PLAYER_IN_ARENA == playerLocation; } bool SGameSystem::isInArcade() const { SGameWorld* gameWorld = dynamicCast(GetGame()); int playerLocation = gameWorld->GetWorldID(); return 10300 == playerLocation; } bool SGameSystem::isHorizon() const { SGameWorld* gameWorld = dynamicCast(GetGame()); int playerLocation = gameWorld->GetWorldID(); return 90400 == playerLocation; } bool SGameSystem::isArenaExercise() const { if (PARTY_ARENA != m_PartyMgr.GetPartyType()) return false; return m_arenaSystem->isExercise(); } bool SGameSystem::isValidArenaJoinSituation(sArenaJoinSituationCondition const& situationCondition) { assert(!m_arenaJoinSituationChecker); return m_arenaJoinSituationChecker->isValidSituation(situationCondition); } int SGameSystem::getArenaId() const { return m_arenaSystem->getArenaId(); } sArenaSystem* SGameSystem::getArenaSystem() const { return m_arenaSystem; } void SGameSystem::OnMsgDoDecompose( struct SMSG_DECOMPOSE_DO* pMsg ) { if( NULL == pMsg ) { SDEBUGLOG( "[GameSystem] Decompose Message is NULL" ); assert( pMsg ); return; } TS_CS_DECOMPOSE stMsg; UINT nItemCount( pMsg->m_vecItemData.size() ); stMsg.count = nItemCount; stMsg.size += ( sizeof( TS_CS_DECOMPOSE::DECOMPOSE_INFO ) * nItemCount ); stMsg.set_check_sum(); int nDataSize( sizeof( TS_CS_DECOMPOSE::DECOMPOSE_INFO ) ); int nPacketSize( sizeof( TS_CS_DECOMPOSE ) ); int nPacketTotalSize( nPacketSize + ( nDataSize * nItemCount ) ); BYTE* pbyPacketSection( new BYTE[nPacketTotalSize] ); ::memcpy( pbyPacketSection, &stMsg, nPacketSize ); BYTE* pbyPacketDataSection( pbyPacketSection + nPacketSize ); for( UINT nCount = 0; nCount < pMsg->m_vecItemData.size(); nCount++ ) { ::memcpy( pbyPacketDataSection, &pMsg->m_vecItemData[nCount], nDataSize ); pbyPacketDataSection += nDataSize; } if( m_pGame ) m_pGame->SendMsg( (TS_CS_DECOMPOSE*)pbyPacketSection ); else { SDEBUGLOG( "[GameSystem] Critical Error Need Check" ); assert( m_pGame ); } SAFE_DELETE_ARRAY( pbyPacketSection ); } void SGameSystem::OnMsgChangeSkinColor( struct SMSG_CHANGE_SKIN_COLOR* pMsg ) { if( NULL == pMsg ) { SDEBUGLOG( "[GameSystem] Change SKin Color Message is NULL" ); assert( pMsg ); return; } SGameAvatarEx* pObject( static_cast( m_pGame->GetGameObject( pMsg->hPlayer ) ) ); if( NULL == pObject ) { SDEBUGLOG( "[GameSystem] Cannot find the target to change the skin color.." ); assert( pMsg ); return; } pObject->SetSkinColor( pMsg->dwSkinColor ); pObject->RefreshSkinColorized(); } void SGameSystem::OnMsgPartyMatchingAction( struct SMSG_PARTYMATCH_ACTION* pMsg ) { TS_CS_PARTYMATCH_ACTION msg; msg.nAction = pMsg->nAction; msg.nPage = pMsg->nPage; msg.nMaster = pMsg->nMaster; memcpy ( &msg.stRoom, &pMsg->stRoom, sizeof (STRUCT_PARTYMATCH_ROOM ) ); m_pGame->SendMsg(&msg); } void SGameSystem::OnMsgMoveMap ( int worldPosX, int worldPosY ) { Rq_Chatting( CHAT_NORMAL, NULL, CStringUtil::StringFormat( "//warp %d %d", worldPosX, worldPosY ).c_str() ); }