Files
Leviathan/Client/Game/game/GameSystem/SGameSystem.cpp
T
2026-06-01 12:46:52 +02:00

8579 lines
271 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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 <toolkit/XStringUtil.h>
#include "ErrorCode/ErrorCode.h"
#include "SUISysMsgDefine.h"
#include "SGameUISyncMng.h"
#include "SChatType.h"
#include "SSkillStageType.h"
#include "SGameOption.h"
#include <toolkit/XEnv.h>
#include "SDebug_Util.h"
#include "tchar.h"
#include "CInput.h"
#include <toolkit/nsl.h>
#include <toolkit/nsluni.h>
#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<std::string>& 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<SRaidMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::RAID_MGR ) ) )
, m_PartyMgr ( *static_cast<CPartyListMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::PARTY_MGR )) )
, m_GuildMgr ( *static_cast<SGuildMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::GUILD_MGR )) )
, m_FriendMgr ( *static_cast<SFriendMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::FRIEND_MGR )) )
, m_CutMgr ( *static_cast<SCutMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::CUT_MGR )) )
, m_TradeMgr ( *static_cast<STradeMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::TRADE_MGR )) )
, m_StorageMgr ( *static_cast<SStorageMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::STORAGE_MGR )) )
, m_MotionMgr ( *static_cast<SMotionMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::MOTION_MGR )) )
, m_PlayerInfoMgr ( *static_cast<SPlayerInfoMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::PLAYERINFO_MGR )) )
, m_InventoryMgr ( *static_cast<SInventoryMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::INVENTORY_MGR )) )
, m_CreatureSlotMgr ( *static_cast<SCreatureSlotMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::CREATURESLOT_MGR )) )
, m_SkillSlotMgr ( *static_cast<SSkillSlotMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::SKILLSLOT_MGR )) )
, m_CreatureSkillSlotMgr( *static_cast<SCreatureSkillSlotMgr*>(GameUIMgrInstance.GetUIMgr( SGameUIInstance::CREATURESKILLSLOT_MGR )) )
, m_GuildDataMgr ( *static_cast<SGuildDataMgr*>(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<SMSG_CHATTING_REQUEST*>(pGameMsg) ); pGameMsg->bUse = true; break;
case MSG_ENTER_EVENTAREA : OnMsgEnterEventArea( static_cast<SMSG_ENTER_EVENTAREA*>(pGameMsg) ); pGameMsg->bUse = true; break;
case MSG_LEAVE_EVENTAREA : OnMsgLeaveEventArea( static_cast<SMSG_LEAVE_EVENTAREA*>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_REQ_UIDISPLAY_INFO : OnMsgReqUIDisplayInfo( static_cast<SIMSG_REQ_UIDISPLAY_INFO*>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_UI_ACT_INVENTORY : OnMsgActInventory( static_cast<SIMSG_UI_ACT_INVENTORY*>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_UI_ACT_CREATURE : OnMsgActCreature ( static_cast<SIMSG_UI_ACT_CREATURE *>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_UI_ACT_TARGET : OnMsgActTarget( static_cast<SIMSG_UI_ACT_TARGET *>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_UI_ACT_NPCDIALOG : OnMsgActNPCDialog( static_cast<SIMSG_UI_ACT_NPCDIALOG*>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_UI_ACT_LEARN_SKILL : OnMsgActLearnSkill( static_cast<SIMSG_UI_ACT_LEARN_SKILL*>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_UI_ACT_JOB_LEVELUP : OnMsgActJopLevelUp( static_cast<SIMSG_UI_ACT_JOB_LEVELUP*>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_UI_ACT_FULLEQUIP : OnMsgActFullEquip( static_cast<SIMSG_UI_ACT_FULLEQUIP *>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_UI_ACT_USESKILL : OnMsgUseSkill( static_cast<SIMSG_UI_ACT_USESKILL *>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_UI_ACT_USEITEM : OnMsgUseItem( static_cast<SIMSG_UI_ACT_USEITEM*>(pGameMsg)); pGameMsg->bUse = true; break;
case IMSG_UI_BOOTH : OnMsgBooth( static_cast<SMSG_UI_BOOTH *>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_UI_ACT_USECOMMAND : OnMsgUseCommand( static_cast<SIMSG_UI_ACT_USECOMMAND *>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_UI_ACT_ITEMCOMBINE : OnMsgActItemCombine( static_cast<SIMSG_UI_ACT_ITEMCOMBINE*>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_UI_ACT_ITEMCONTRIBUTION : OnMsgActItemContribution( static_cast<SIMSG_UI_ACT_ITEMCONTRIBUTION*>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_UI_ACT_REQUEST_REWARD : OnMsgActRequestRewardItem( static_cast<SIMSG_UI_ACT_REQUESTREWARDITEM*>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_UI_ACT_BUYITEMS_FROM_STORE : OnMsgActBuyItemsFromStore( static_cast<SIMSG_UI_ACT_BUYITEMS_FROM_STORE*>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_UI_ACT_SELLITEMS_TO_STORE : OnMsgActSellItemsToStore( static_cast<SIMSG_UI_ACT_SELLITEMS_TO_STORE*>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_UI_ACT_BUYITEMS : OnMsgActBuyItems( static_cast<SIMSG_UI_ACT_BUYITEMS*>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_UI_ACT_SELLITEMS : OnMsgActSellItems( static_cast<SIMSG_UI_ACT_SELLITEMS*>(pGameMsg) ); pGameMsg->bUse = true; break;
case TMSG_CHANGEAVATAR : OnMsgChangeAvatar( static_cast<STMSG_CHANGEAVATAR*>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_UI_ACT_EQUIP_SUMMON: OnMsgActEquipSummon( static_cast<SIMSG_UI_ACT_EQUIP_SUMMON*>(pGameMsg) ); break;//pGameMsg->bUse = true; break;
case IMSG_UI_ACT_SELECT_SUMMON: OnMsgActSelectSummon( static_cast<SIMSG_UI_ACT_SELECT_SUMMON*>(pGameMsg) ); break;
case IMSG_UI_SAVE_CLIENT_INFO: OnMsgSaveClientInfo( static_cast<SIMSG_UI_SAVE_CLIENT_INFO*>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_UI_SAVE_QUICK_SLOT: OnMsgSaveQuickSlot( static_cast<SIMSG_UI_SAVE_QUICK_SLOT*>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_UI_SAVE_CURRENT_KEY: OnMsgSaveCurrentKey( static_cast<SIMSG_UI_SAVE_CURRENT_KEY*>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_UI_SAVE_SAVED_KEY : OnMsgSaveSavedKey( static_cast<SIMSG_UI_SAVE_SAVED_KEY*>(pGameMsg) ); pGameMsg->bUse = true; break; //added by gmpbigsun(20130419)
case MSG_RQ_SUMMON : OnMsgRqSummon( static_cast<SMSG_RQ_SUMMON*>(pGameMsg) ); pGameMsg->bUse = true; break;
case MSG_WATCH_BOOTH : OnMsgWatchBooth( static_cast<SMSG_WATCH_BOOTH*>(pGameMsg) ); pGameMsg->bUse = true; break;
case MSG_REQUEST_BOOTH_NAME : OnMsgRqBoothName( static_cast<SMSG_REQUEST_BOOTH_NAME*>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_UI_SOULSTONE_CRAFT : OnMsgSoulstoneCraft( static_cast<SIMSG_UI_SOULSTONE_CRAFT*>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_UI_REPAIR_SOULSTONE: OnMsgRepairSoulstone( static_cast<SIMSG_UI_REPAIR_SOULSTONE*>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_REQUEST_REMOVE_STATE: OnMsgRequestRemoveState( static_cast<SIMSG_REQUEST_REMOVE_STATE*>(pGameMsg) ); pGameMsg->bUse = true; break;
case IMSG_REQ_CHANGE_ITEM_POSITION: OnMsgMsgReqChangeItemPosition( static_cast<SIMSG_REQ_CHANGE_ITEM_POSITION*>(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<SMSG_ENTER*>(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<SMSG_RESURRECTION*>(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<SMSG_CS_COMPETE_REQUEST*>(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<SMSG_CS_COMPETE_ANSWER*>(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<SMSG_INSTANCE_GAME_ENTER*>(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<SIMSG_QUEST_INFO_REQUEST*>( 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<SIMSG_UI_MINIMAP_ROTATE*>( 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<SIMSG_UI_2DPOS_INFO*>(pGameMsg);
if( pMsg->handle == GetTarget()->GetArID() && pMsg->bNotClip == true )
{ //시야에 보이는 경우만, 강제로 켠다.
pMsg->bVisible = true;
pMsg->fAlpha = 1.0f;
}
}
}
break;
case TMSG_REQ_CLOSE : OnMsgReqClose( static_cast<STMSG_REQ_CLOSE*>(pGameMsg) ); break; // buse 안킨다.
//이건 거의 응답~
case MSG_NPC_DIALOG : OnMsgNPCDialog ( static_cast<SMSG_NPC_DIALOG*>(pGameMsg) ); break;
case MSG_MARKET : OnMsgMarket ( static_cast<SMSG_MARKET*>(pGameMsg) ); break;
case MSG_RESULT : OnMsgResult ( static_cast<SMSG_RESULT*>(pGameMsg) ); break;
case MSG_LOGIN : OnMsgLogin ( static_cast<SMSG_LOGIN*>(pGameMsg) ); break;
case MSG_LEAVE : OnMsgLeave ( static_cast<SMSG_LEAVE*>(pGameMsg) ); break;
case MSG_ATTACK : OnMsgAttack ( static_cast<SMSG_ATTACK*>(pGameMsg) ); break;
case MSG_ATTACK_DOUBLE : OnMsgAttackDouble ( static_cast<SMSG_ATTACK_DOUBLE*>(pGameMsg) ); break;
case MSG_SKILL_EVENT : OnMsgSkillEvent( static_cast<SMSG_SKILL_EVENT*>(pGameMsg) ); break; //Skill
// case MSG_SKILL_CASTING_TIME : OnMsgSkillCastingTime( static_cast<SMSG_SKILL_CASTING_TIME*>(pGameMsg) ); break; //Skill Casting Time
case MSG_SKILL_LIST : OnSkillList ( static_cast<SMSG_SKILL_LIST*>(pGameMsg) ); break;
case MSG_ADDED_SKILL_LIST : OnAddedSkillList ( static_cast<SMSG_ADDED_SKILL_LIST*>(pGameMsg) ); break;
case MSG_SKILLCARD_INFO : OnSkillCardInfo( static_cast<SMSG_SKILLCARD_INFO*>(pGameMsg) ); break;
case MSG_MOUNT_SUMMON : OnMsgMount ( static_cast<SMSG_MOUNT_SUMMON*>(pGameMsg) ); break;
case MSG_UNMOUNT_SUMMON : OnMsgUnMount ( static_cast<SMSG_UNMOUNT_SUMMON*>(pGameMsg) ); break;
case MSG_STAT_INFO : OnStatInfo ( static_cast<SMSG_STAT_INFO*>(pGameMsg) ); break;
case MSG_GOLD_UPDATE : OnGoldUpdate ( static_cast<SMSG_GOLD_UPDATE*>(pGameMsg) ); break;
case MSG_ADD_SUMMON_INFO : OnMsgAddSummonInfo ( static_cast<SMSG_ADD_SUMMON_INFO *>(pGameMsg) ); break;
case MSG_REMOVE_SUMMON_INFO : OnMsgRemoveSummonInfo ( static_cast<SMSG_REMOVE_SUMMON_INFO*>(pGameMsg) ); break;
case MSG_EQUIP_SUMMON : OnMsgEquipSummon ( static_cast<SMSG_EQUIP_SUMMON *>(pGameMsg) ); break;
case IMSG_UI_CHANGE_SUMMON_NAME : OnMsgSummonNameChange ( static_cast<SIMSG_UI_CHANGE_SUMMON_NAME *>(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<SMSG_ITEM_TAKE*>(pGameMsg) ); break; //인벤에 넣기
case MSG_ITEM_DROP_RESULT : OnMsgDropResult( static_cast<SMSG_ITEM_DROP*>(pGameMsg) ); break; //인벤에서 삭제
case MSG_ITEM_DESTROY : OnMsgItemDestroy ( static_cast<SMSG_ITEM_DESTROY*>(pGameMsg) ); break; //Item Destroy //아이템 삭제
case MSG_ITEM_ERASE :
//pGameMsg->bUse = true;
OnMsgItemErase( static_cast<SMSG_ERASE_ITEM*>(pGameMsg) ); break; // 아이템파괴.
case MSG_UPDATE_ITEM_COUNT : OnMsgUpdateItemCount( static_cast<SMSG_UPDATE_ITEM_COUNT*>(pGameMsg) ); break; //Item Count Update //아이템정보 변경
case MSG_MIX_RESULT : break; //Mix Result
case MSG_ITEM_WEAR : OnMsgItemWear ( static_cast<SMSG_ITEM_WEAR*>(pGameMsg) ); break; //아이템 변경
case MSG_ITEM_WEAR_INFO : OnMsgItemWearInfo( static_cast<SMSG_ITEM_WEAR_INFO*>(pGameMsg) ); break; //아이템 장착 위치 변경
case MSG_ITEM_INVEN : OnMsgInventory ( static_cast<SMSG_ITEM_INVEN*>(pGameMsg) ); break; //인벤 정보
case MSG_ITEM_COOL_TIME : OnMsgItemcooltime( static_cast<SMSG_ITEM_COOL_TIME*>(pGameMsg) ); break; //아이템 그룹 쿨 타임정보
case MSG_CHATTING : OnMsgChatting ( static_cast<SMSG_CHATTING*>(pGameMsg) ); break; //채팅
case MSG_TRADE : OnMsgTrade ( static_cast<SMSG_TRADE*>(pGameMsg) ); break; //Trade
case MSG_BELT_SLOT_INFO : OnMsgBeltSlotInfo( static_cast<SMSG_BELT_SLOT_INFO*>(pGameMsg) ); break; //BeltSlotInfo
case MSG_QUEST_UPDATA : OnMsgQuestUpdata( static_cast<SMSG_QUEST_UPDATA*>(pGameMsg) ); break;
case MSG_END_QUEST : OnMsgEndQuest( static_cast<SMSG_END_QUEST*>(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<SMSG_OPEN_STORAGE*>(pGameMsg) ); break;
case MSG_CHANGE_STORAGE : OnMsgChangeStorage( static_cast<SMSG_CHANGE_STORAGE*>(pGameMsg) ); break;
case MSG_REGEN_HPMP : OnMsgRegenHPMP( static_cast<SMSG_REGEN_HPMP*>(pGameMsg) ); break;
case MSG_TARGET : OnMsgTarget( static_cast<SMSG_TARGET*>(pGameMsg) ); break;
case MSG_PROPERTY: OnMsgProperty( static_cast<SMSG_PROPERTY*>(pGameMsg) ); break;
case MSG_LEVEL_UPDATE: OnMsgLevelUpdate( static_cast<SMSG_LEVEL_UPDATE*>(pGameMsg) ); break;
case IMSG_UI_TARGET_STAT: OnMsgTargetStat( static_cast<SIMSG_UI_TARGET_STAT*>(pGameMsg) ); break;
case MSG_HPMP: OnMsgHPMP( static_cast<SMSG_HPMP*>(pGameMsg) ); break;
case MSG_SP: OnMsgSP( static_cast<SMSG_SP*>(pGameMsg) ); break;
case MSG_EXP_UPDATE: OnMsgExpUpdate( static_cast<SMSG_EXP_UPDATE*>(pGameMsg) ); break;
case IMSG_UI_TARGET_INFO: OnMsgTargetInfo( static_cast<SIMSG_UI_TARGET_INFO*>(pGameMsg) ); break;
case MSG_STATE: OnMsgState( static_cast<SMSG_STATE*>(pGameMsg) ); break;
case MSG_STATUS_CHANGE: OnMsgStatusChange( static_cast<SMSG_STATUS_CHANGE*>(pGameMsg) ); break;
case MSG_STATE_RESULT: OnMsgStateResult( static_cast<SMSG_STATE_RESULT*>(pGameMsg) ); break;
case IMSG_UI_NPC_SEQFORM_INFO:
{
SIMSG_UI_NPC_SEQFORM_INFO* pMsg = static_cast<SIMSG_UI_NPC_SEQFORM_INFO*>(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<SIMSG_UI_CREATURE_SEQFORM_INFO*>(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<SIMSG_SHOW_UIWINDOW*>(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<SMSG_AURA*>(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<SMSG_CHAT_COMMAND*>(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<SMSG_PARTY_COMMAND*>(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<SMSG_FRIEND_COMMAND*>(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<SMSG_FRIEND_COMMAND*>(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<SMSG_TAKEOUT_COMMERCIAL_ITEM*>(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<SMSG_COMMERCIAL_STORAGE_LIST*>(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<SMSG_COMMERCIAL_STORAGE_INFO*>(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<SIMSG_UI_ACT_USESKILL_BY_TOGGLE*>(pGameMsg);
if( OnMsgUseSkill_by_toggle( pUseSkill ) )
pUseSkill->bSucceed = true;
pGameMsg->bUse = true;
}
break;
case MSG_SECURITY_NO:
{
SMSG_SECURITY_NO* pSecurityMsg = static_cast<SMSG_SECURITY_NO*>(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<SMSG_WHISPER_ADDONWND*>(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<SMSG_COMMAND_BY_ADDONWND*>(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<SMSG_GAME_OUT*>(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<SMSG_GUILD_COMMAND*>(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<SIMSG_UI_SUMMON_CARD_SKILL_LIST*>(pGameMsg)); break;
case IMSG_DECOMPOSE_DO:
OnMsgDoDecompose( static_cast<SMSG_DECOMPOSE_DO*>(pGameMsg) );
break;
case MSG_CHANGE_SKIN_COLOR:
OnMsgChangeSkinColor( static_cast<SMSG_CHANGE_SKIN_COLOR*>(pGameMsg) );
break;
case TMSG_REQ_CLOSE_EX:
{
SendLogOutMessage();
pGameMsg->bUse = false;
}
break;
case MSG_PARTYMATCH_ACTION:
{
OnMsgPartyMatchingAction(static_cast<SMSG_PARTYMATCH_ACTION*>(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<TS_CS_SET_PROPERTY*>(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<TS_CS_SET_PROPERTY*>(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<TS_CS_SET_PROPERTY*>(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<TS_CS_SET_PROPERTY*>(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<std::string> NewQuestText;
_SplitText( strQuest.c_str(), "<br>", NewQuestText, "<BR>" );
std::vector<std::string> OldQuestText;
_SplitText( pGameMsg->strOldQuest.c_str(), "<br>", OldQuestText, "<BR>" );
if( NewQuestText.size() != OldQuestText.size() )
{
NewQuestText.clear();
OldQuestText.clear();
assert( true && "퀘스트 정보가 이상하다." );
return;
}
std::vector<std::string> UpdateQuestText;
for( size_t i(0); i<NewQuestText.size(); ++i )
{
if( NewQuestText[i] != OldQuestText[i] )
UpdateQuestText.push_back( NewQuestText[i] );
}
if( UpdateQuestText.size() == 0 )
{
NewQuestText.clear();
OldQuestText.clear();
return;
}
std::string OutQuestText = "<#00FFFC>";
for( size_t i(0); i<UpdateQuestText.size(); ++i )
OutQuestText += UpdateQuestText[i];
if( m_pGame )
{
m_pGame->ProcMsgAtStatic( &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<std::string>& 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<SGameWorld*>(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<SGameWorld*>(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<SGameWorld*>(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); i<TS_CS_SOULSTONE_CRAFT::MAX_SOULSTONE_NUM; ++i )
{
msg.soulstone_handle[i] = pMsg->soulstone_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); i<TS_CS_REPAIR_SOULSTONE::MAX_REPAIR_COUNT; ++i )
{
msg.item_handle[i] = pMsg->item_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); i<MsgCount; ++i )
{
char *pBuf = new char[ sizeof(TS_CS_SELL_TO_BOOTH) ];
TS_CS_SELL_TO_BOOTH msg;
msg.target = pMsg->vList[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<SIMSG_UI_ACT_BUYITEMS::BuyItemInfo>::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<SIMSG_UI_ACT_SELLITEMS::SellItemInfo>::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<int> 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); i<nSkillSize; ++i )
{ //쿨링 리스트에 쿨타임 그룹 모두 추가
/// 2012.02.28 isFire == true일 때만 쿨타임 리스트에 추가 - prodongi
if (m_SkillSlotMgr.SetFireSkill( vecSkillList[i], true, pMsg->caster ))
{
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); i<nSkillSize; ++i )
{ //cancle에서도 쿨타임 그룹의 모든 스킬 쎄팅
m_SkillSlotMgr.AddCooling( vecSkillList[i] );
m_SkillSlotMgr.SetCastingCancelSkill( vecSkillList[i], pMsg->caster );
}
}
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; i<pMsg->item_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<SMSG_ATTACK *>(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<SMSG_SKILL_EVENT *>(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<SMSG_STATE_RESULT *>(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<SMSG_PROPERTY *>(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<SMSG_HPMP *>(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<SMSG_REGEN_HPMP *>(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<SMSG_SP *>(pMsg);
handle = pGameMsg->handle;
}*/
case MSG_EXP_UPDATE :
{
UI_SYNC_INFO uisyncinfo;
SMSG_EXP_UPDATE * pGameMsg = static_cast<SMSG_EXP_UPDATE *>(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<SMSG_BONUS_EXP_JP *>(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<int> 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<std::string> 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<SPlayerSlot*> MemberList = m_PartyMgr.GetMemberList(&strPartyName);
int size( MemberList.size() );
for( int i(0); i<size; ++i )
{
AR_HANDLE handle(NULL);
handle = MemberList[i]->GetHandle();
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<SPlayerSlot*> MemberList = m_PartyMgr.GetMemberList();
int size( MemberList.size() );
for( int i(0); i<size; ++i )
{
handle = MemberList[i]->GetHandle();
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<SPlayerSlot*> MemberList = m_PartyMgr.GetMemberList();
int size( MemberList.size() );
for( int i(0); i<size; ++i )
{
AR_HANDLE handle(NULL);
handle = MemberList[i]->GetHandle();
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); i<vecText.size(); i+=9 ) // 2011.10.20 - servantes : 추가된 파라미터 때문에 인덱스 증가
{
char* strstoper;
AR_HANDLE handle = ::strtoul( vecText[i].c_str(), &strstoper, 10 );
// if( handle && !m_PartyMgr.IsLocalPlayer(handle) ) //LocalPlayer는 이미 생성되어 있다
if( handle && !m_PartyMgr.IsLocalPlayer(handle, &strPartyName) ) //LocalPlayer는 이미 생성되어 있다
CreateGuage(handle, true);
}
}
}
//===============================================================================================================================================
vecText.clear();
}
//채팅
void SGameSystem::OnMsgChatting ( struct SMSG_CHATTING* pMsg )
{
if( pMsg->nChatType == 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<delimiter.size(); ++i )
{
if ( delimiter[i] == _c ) return true;
}
return false;
}
void SGameSystem::Split( const wchar_t* szMsg, std::wstring& delimiter, std::vector< std::wstring >& 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<TS_CS_CHAT_REQUEST*>(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); i<size; i++ )
{
// 아이템 리스트에서 제거.
//DestroyItem( arrItems[ i ].item_handle );
// 파괴 패킷.
memcpy( pDes, &arrItems[ i ], sizeof(TS_CS_ERASE_ITEM::EraseItemInfo) );
pDes += sizeof(TS_CS_ERASE_ITEM::EraseItemInfo);
}
if( m_pGame ) m_pGame->SendMsg( (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<SStateSlot*> vecStateList;
pAvatar->GetAllStateList(vecStateList, false);
std::vector<SStateSlot*>::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<SStateSlot*> vecStateList;
pAvatar->GetAllStateList(vecStateList, false);
std::vector<SStateSlot*>::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<SMSG_DAMAGE*>(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<SStateSlot*> vecStateList;
pAvatar->GetAllStateList(vecStateList, false);
std::vector<SStateSlot*>::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<SGameWorld*>(GetGame());
int playerLocation = gameWorld->GetPlayerCurrentLocation();
return PLAYER_IN_ARENA == playerLocation;
}
bool SGameSystem::isInArcade() const
{
SGameWorld* gameWorld = dynamicCast<SGameWorld*>(GetGame());
int playerLocation = gameWorld->GetWorldID();
return 10300 == playerLocation;
}
bool SGameSystem::isHorizon() const
{
SGameWorld* gameWorld = dynamicCast<SGameWorld*>(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<SGameAvatarEx*>( 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() );
}