5446 lines
150 KiB
C++
5446 lines
150 KiB
C++
#include "stdafx.h"
|
|
#include "SGameWorld.h"
|
|
#include "SCommandSystem.h"
|
|
#include "KDeviceManager.h"
|
|
#include "KRenderDeviceDX.h"
|
|
#include "SGameObject.h"
|
|
#include "SGameMessage.h"
|
|
//#include "SGameMessageUI.h"
|
|
#include "SGameWork.h"
|
|
#include "SGameViewPort.h"
|
|
|
|
#include "SGameAvatarEx.h"
|
|
#include "SGameLocalCreature.h"
|
|
#include "SGameLocalPlayer.h"
|
|
#include "SGameSkilProp.h"
|
|
|
|
#include "SGameFieldQuestProp.h"
|
|
#include "SGameOtherCreature.h"
|
|
|
|
#include "SGameOtherPlayer.h"
|
|
#include "SGameMob.h"
|
|
#include "SGameNpc.h"
|
|
#include "SGameItem.h"
|
|
#include "SGameSystem.h"
|
|
#include "SGameEffect.h"
|
|
#include "SGameLocalPet.h" // sonador 10.2.1 팻 시스템 구현
|
|
#include "SGameOtherPet.h"
|
|
|
|
#include "SUISysMsgDefine.h"
|
|
|
|
#include "K3DCamera.h"
|
|
#include "KRenderObjectBone.h"
|
|
|
|
|
|
#include "SActionMgr.h"
|
|
#include "STargetMgr.h"
|
|
|
|
#include "ErrorCode/ErrorCode.h"
|
|
|
|
#include "SGameOtherEffectMng.h"
|
|
|
|
#include "SItemDB.h"
|
|
|
|
#include "SNetMessage.h"
|
|
|
|
#include "SMonsterDB.h"
|
|
#include "SCreatureDB.h"
|
|
#include "SNpcResourceDB.h"
|
|
#include "STenacityDB.h"
|
|
#include "SPetDB.h"
|
|
#include "SFieldPropResourceDB.h"
|
|
|
|
#include "SRenderFlag.h"
|
|
|
|
#include "SGameOption.h"
|
|
#include "SUIDisplayInfo.h"
|
|
|
|
#include "SSKillStageType.h"
|
|
|
|
#include "SDebug_Util.h"
|
|
#include "SPlayerInfoMgr.h"
|
|
#include "SPetMgr.h" // sonador #2.1.2.4.3 팻 조작 UI 연동
|
|
|
|
// 2010.06.18 - prodongi
|
|
#include "SSelectedAvatarInfo.h"
|
|
/// 2010.11.10 - prodongi
|
|
#include "SGameLobbyDefine.h"
|
|
// 2011. 9. 16 - marine
|
|
#include "SGameManager.h"
|
|
#include "SGameInterface.h"
|
|
#include "TerrainMapEngine.h"
|
|
|
|
//#include "SUIUtil.h"
|
|
|
|
const float HEAD_DEF_TOP = 27.f;
|
|
const float HEAD_DEF = 20.f;
|
|
const float HEAD_DEF_HALF = 10.f; //
|
|
const float HEAD_ITEM = 5.f;
|
|
const float HEAD_PET = 5.f;
|
|
const float HEAD_GAP_MOB = 5.f;
|
|
const float HEAD_GAP_AVATAR = 2.f;
|
|
const float HEAD_GAP_PET = 2.f;
|
|
const float HEAD_GAP_ITEM = 1.f;
|
|
|
|
const float SHADOW_RENDER_MAX_LEN = 125.f; // LocalPlayer로 부터 그림자 그려지는 범위
|
|
|
|
const DWORD BOOTH_CHECK_INTERVAL = 1000; // 노점 이름 보여줄지 말지 검사하는 주기
|
|
|
|
const DWORD OBJ_LEAVE_TIME = 60000*3;
|
|
|
|
extern DWORD g_dwFPS;
|
|
|
|
//SCommandSystem::m_fAvatarVisRange = 1000.0f;
|
|
|
|
#define _WEAPON_FX_
|
|
|
|
static bool g_bRenderPlayerObj = false;
|
|
|
|
extern SGameSystem* g_pCurrentGameSystem;
|
|
|
|
|
|
SCommandSystem::SCommandSystem(K3DRenderDeviceDX *pRenderDevice, SGame* pGame)
|
|
{
|
|
m_pRenderDevice = pRenderDevice;
|
|
m_pGame = pGame;
|
|
m_dwTime = 0;
|
|
m_pPrevBoothProcTime = 0;
|
|
m_fAvatarVisRange = 5000.0f;
|
|
m_bDestroy = false;
|
|
m_hMouseOverItem = 0;
|
|
m_bCircleShadowEnable = false;
|
|
m_dwLocalCreaturePrcessTime = 0;
|
|
m_dwCheckTime = 0;
|
|
setIsTaming(false); /// 2011.01.20 - prodongi
|
|
|
|
Init();
|
|
}
|
|
|
|
SCommandSystem::~SCommandSystem()
|
|
{
|
|
Destroy();
|
|
}
|
|
|
|
void SCommandSystem::Init()
|
|
{
|
|
m_pActionMgr = new SGameActionMgr(m_pGame);
|
|
m_pOtherEffecMgr = new SGameOtherEffectMng( m_pGame );
|
|
m_nCreatureSelect = -1;
|
|
|
|
m_pTargetMgr = new STargetMgr;
|
|
}
|
|
|
|
void SCommandSystem::Destroy()
|
|
{
|
|
m_bDestroy = true;
|
|
|
|
SAFE_DELETE( m_pActionMgr );
|
|
SAFE_DELETE( m_pTargetMgr );
|
|
SAFE_DELETE( m_pOtherEffecMgr );
|
|
|
|
SGameAvatarExTag* pAvatarTag = NULL;
|
|
bool res = m_hashLeaveList.get_first_value( pAvatarTag );
|
|
while ( res )
|
|
{
|
|
if ( pAvatarTag != NULL )
|
|
{
|
|
SAFE_DELETE( pAvatarTag->ptr );
|
|
SAFE_DELETE( pAvatarTag );
|
|
}
|
|
res = m_hashLeaveList.get_next_value( pAvatarTag );
|
|
}
|
|
m_hashLeaveList.clear();
|
|
|
|
SGameAvatarEx* pGameObject = NULL;
|
|
KSortVector< class SGameAvatarEx* >::iterator it = m_svObject.begin();
|
|
while ( it != m_svObject.end() )
|
|
{
|
|
pGameObject = (*it); ++it;
|
|
if ( pGameObject != NULL )
|
|
{
|
|
delete pGameObject;
|
|
}
|
|
}
|
|
m_hashObject.clear();
|
|
m_svObject.clear();
|
|
|
|
m_svPlayerObject.clear();
|
|
m_svOtherObject.clear();
|
|
m_svRecongnizeMobObject.clear();
|
|
|
|
m_vLocalCreature.clear(); //포인터만 들어 있다.
|
|
|
|
m_svReservationObject.clear();
|
|
|
|
m_svRidingObject.clear();
|
|
|
|
KSortVector< SGameAvatarEx* >::iterator iter = m_svTransportCreatureObject.begin();
|
|
while( iter != m_svTransportCreatureObject.end() )
|
|
{
|
|
pGameObject = (*iter); ++iter;
|
|
if ( pGameObject != NULL )
|
|
{
|
|
delete pGameObject;
|
|
}
|
|
}
|
|
|
|
m_svTransportCreatureObject.clear();
|
|
m_hashTransportCreatureObject.clear();
|
|
|
|
m_hashPendingObjList.clear();
|
|
}
|
|
|
|
void SCommandSystem::PlayerEmotion( AR_HANDLE handel, int nEmotionID )
|
|
{
|
|
if( handel != 0 )
|
|
{
|
|
SGameAvatarEx * pPlayer = GetAvatar( handel );
|
|
if( pPlayer && pPlayer->GetObjType() == TS_ENTER::GAME_PLAYER )
|
|
{
|
|
if( pPlayer->IsWorkListEmpty() )
|
|
{
|
|
SWorkEmotion* pEmotion = new SWorkEmotion( pPlayer, NULL );
|
|
if( pEmotion->SetEmotion( nEmotionID ) )
|
|
{
|
|
pPlayer->AllWorkEnd();
|
|
pPlayer->AddWork( pEmotion );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int nPlayerObj = m_svPlayerObject.size();
|
|
for( int i(0); nPlayerObj>i; i++ )
|
|
{
|
|
SGameAvatarEx * pPlayer = m_svPlayerObject[i];
|
|
|
|
if( pPlayer->GetObjType() != TS_ENTER::GAME_PLAYER ) continue;
|
|
|
|
if( pPlayer->IsWorkListEmpty() )
|
|
{
|
|
SWorkEmotion* pEmotion = new SWorkEmotion( pPlayer, NULL );
|
|
if( pEmotion->SetEmotion( nEmotionID ) )
|
|
{
|
|
pPlayer->AllWorkEnd();
|
|
pPlayer->AddWork( pEmotion );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//===================================================================================================
|
|
|
|
int GetMagicType( int nMagicType )
|
|
{
|
|
switch( nMagicType )
|
|
{
|
|
case StateInfo::ET_FIRE: //화속성
|
|
return 5076;
|
|
case StateInfo::ET_WATER: //수속성
|
|
return 5077;
|
|
case StateInfo::ET_WIND: //풍속성
|
|
return 5078;
|
|
case StateInfo::ET_EARTH: //토속성
|
|
return 5079;
|
|
case StateInfo::ET_LIGHT: //명속성
|
|
return 5080;
|
|
case StateInfo::ET_DARK: //암속성
|
|
return 5081;
|
|
}
|
|
|
|
return 0; //무속성
|
|
}
|
|
|
|
void SCommandSystem::ProcMsgAtStatic( SGameMessage * pGameMsg )
|
|
{
|
|
if( pGameMsg->nType == IMSG_KEYUP ||
|
|
pGameMsg->nType == IMSG_KEYDOWN ||
|
|
pGameMsg->nType == IMSG_MOUSEMOVE ||
|
|
pGameMsg->nType == IMSG_UI_2DPOS_INFO ||
|
|
pGameMsg->nType == IMSG_UI_ETC_INFO ||
|
|
pGameMsg->nType == IMSG_UI_MY_DEGREE ||
|
|
pGameMsg->nType == IMSG_UI_MINIMAP_INFO ) return;
|
|
|
|
// _oprint( "!!!!!SCommandSystem::ProcMsgAtStatic : %d\n", pGameMsg->nType );
|
|
|
|
switch( pGameMsg->nType )
|
|
{
|
|
case MSG_RESULT :
|
|
{
|
|
OnMsgResult ( static_cast<SMSG_RESULT*>(pGameMsg) );
|
|
break;
|
|
}
|
|
case MSG_CHATTING :
|
|
{
|
|
OnMsgChatting ( static_cast<SMSG_CHATTING*>(pGameMsg) );
|
|
break;
|
|
}
|
|
|
|
case MSG_MOVE :
|
|
{
|
|
OnMsgMove ( static_cast<SMSG_MOVE*>(pGameMsg) );
|
|
break; //이동
|
|
}
|
|
case MSG_KMOVE:
|
|
{
|
|
OnMsgKMove(dynamic_cast<SMSG_KMOVE*>(pGameMsg));
|
|
break;
|
|
}
|
|
case MSG_REGION_ACK :
|
|
{
|
|
OnMsgRegionAck ( static_cast<SMSG_REGION_ACK*>(pGameMsg) );
|
|
break; //영역 요청
|
|
}
|
|
case MSG_LOGIN :
|
|
{
|
|
OnMsgLogin ( static_cast<SMSG_LOGIN*>(pGameMsg) );
|
|
break; //Login (Local Player)
|
|
}
|
|
case MSG_HAIR_INFO:
|
|
{
|
|
OnMsgHairInfo ( static_cast<SMSG_HAIR_INFO*>(pGameMsg) );
|
|
break; //Login (Local Player)
|
|
}
|
|
// 2010.05.19 - prodongi
|
|
case MSG_HIDE_EQUIP_INFO:
|
|
{
|
|
OnMsgHideEquipInfo(static_cast<SMSG_HIDE_EQUIP_INFO*>(pGameMsg));
|
|
break;
|
|
}
|
|
|
|
// 꾸미기아이템 보임숨김 개별 정보.
|
|
case MSG_HIDE_EQUIP_FLAG:
|
|
OnMsgHideEquipFlag(static_cast<SMSG_HIDE_EQUIP_INFO*>(pGameMsg));
|
|
break;
|
|
|
|
case MSG_LEAVE :
|
|
{
|
|
OnMsgLeave ( static_cast<SMSG_LEAVE*>(pGameMsg) );
|
|
break; //Leave (Other Player)
|
|
}
|
|
case MSG_ENTER :
|
|
{
|
|
OnMsgEnter ( static_cast<SMSG_ENTER*>(pGameMsg) );
|
|
break; //Enter (Other Player)
|
|
}
|
|
case MSG_ATTACK :
|
|
{
|
|
OnMsgAttack ( static_cast<SMSG_ATTACK*>(pGameMsg) );
|
|
break; //공격
|
|
}
|
|
case MSG_ATTACK_DOUBLE :
|
|
{
|
|
OnMsgAttackDouble ( static_cast<SMSG_ATTACK_DOUBLE*>(pGameMsg) );
|
|
break;
|
|
}
|
|
case MSG_CANT_ATTACK :
|
|
{
|
|
SMSG_CANT_ATTACK* pCantMsg = static_cast<SMSG_CANT_ATTACK*>(pGameMsg);
|
|
|
|
SGameAvatarEx * pAvatar = NULL;
|
|
if( (pAvatar = (SGameAvatarEx*)GetObject( pCantMsg->attacker_handle )) != NULL )
|
|
pAvatar->OnNetInput( pGameMsg );
|
|
|
|
break;
|
|
}
|
|
case MSG_UNSUMMON :
|
|
{
|
|
SMSG_UNSUMMON* pUnsummonMsg = static_cast<SMSG_UNSUMMON*>(pGameMsg);
|
|
|
|
SGameAvatarEx* pAvatar = (SGameAvatarEx*)GetObject( pUnsummonMsg->summon_handle );
|
|
if( pAvatar && pAvatar->GetObjType() == TS_ENTER::GAME_SUMMON )
|
|
{
|
|
int nMagicType = GetCreatureDB().GetMagicType( pAvatar->GetContentID() );
|
|
|
|
nMagicType = GetMagicType( nMagicType );
|
|
|
|
OnAddOtherEffect( SGameOtherEffectMng::FX_UN_SUMMONING_CREATURE, &OtherFxData( 0, pUnsummonMsg->summon_handle, 5067 ) );
|
|
pAvatar->SetReservation(true); //삭제 보류시키고
|
|
|
|
// 내가 소환한 소환수이면 소환수 삭제해준다
|
|
m_pGame->DelSummon( pUnsummonMsg->summon_handle );
|
|
}
|
|
}
|
|
break;
|
|
case MSG_UNSUMMON_PET: // sonador 10.2.1 팻 시스템 구현
|
|
{
|
|
SMSG_UNSUMMON_PET* pUnsummonPetMsg = static_cast< SMSG_UNSUMMON_PET* >( pGameMsg );
|
|
SGameAvatarEx* pAvatar = static_cast< SGameAvatarEx* >( GetObject( pUnsummonPetMsg->pet_handle ) );
|
|
if( pAvatar && pAvatar->GetObjType() == TS_ENTER::GAME_PET )
|
|
{
|
|
// 아바타 삭제 보류
|
|
OnAddOtherEffect( SGameOtherEffectMng::FX_UN_SUMMONING_CREATURE, &OtherFxData( 0, pUnsummonPetMsg->pet_handle, 5067 ) );
|
|
pAvatar->SetReservation( true );
|
|
m_pGame->RemovePet( pUnsummonPetMsg->pet_handle );
|
|
|
|
// sonador #2.3.1.45
|
|
// 팻이 가시 거리보다 멀어졌을 때(deactivated 상태)
|
|
// 서버에서 TS_LEAVE 메시지가 오지 않기 때문에
|
|
// 클라이언트에서 임의로 leave 처리를 한다.
|
|
if( !pAvatar->IsActivated() )
|
|
{
|
|
SMSG_LEAVE leaveMsg;
|
|
leaveMsg.handle = pUnsummonPetMsg->pet_handle;
|
|
ProcMsgAtStatic( &leaveMsg );
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case MSG_CHANGE_NAME :
|
|
{
|
|
SMSG_CHANGE_NAME * pChangeName = static_cast< SMSG_CHANGE_NAME* >( pGameMsg );
|
|
|
|
DATA_PET* pPetData = m_pGame->IsLocalPet( pChangeName->handle );
|
|
if( pPetData )
|
|
{
|
|
strcpy_s( pPetData->name, pChangeName->m_name.c_str() );
|
|
}
|
|
|
|
SGameAvatarEx * pAvatar = GetAvatar( pChangeName->handle );
|
|
if( pAvatar )
|
|
{
|
|
pAvatar->SetName( pChangeName->m_name.c_str() );
|
|
pChangeName->status = pAvatar->GetStatus();
|
|
}
|
|
}
|
|
break;
|
|
case MSG_SUMMON_EVOLUTION :
|
|
{
|
|
SMSG_SUMMON_EVOLUTION* pSummonEvolution = static_cast<SMSG_SUMMON_EVOLUTION*>(pGameMsg);
|
|
m_pGame->EvolutionSummon( pSummonEvolution );
|
|
|
|
SGameAvatarEx* pAvatar = (SGameAvatarEx*)GetObject( pSummonEvolution->summon_handle );
|
|
if( pAvatar && pAvatar->GetObjType() == TS_ENTER::GAME_SUMMON )
|
|
{
|
|
int nMagicType = GetCreatureDB().GetMagicType( pAvatar->GetContentID() );
|
|
|
|
nMagicType = GetMagicType( nMagicType );
|
|
|
|
OnAddOtherEffect( SGameOtherEffectMng::FX_CREATURE_EVOLUTION, &OtherFxData( 0, pSummonEvolution->summon_handle, 5067 ) );
|
|
}
|
|
|
|
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_USE_ITEM_RESULT:
|
|
{
|
|
OnMsgItemResult( static_cast<SMSG_USE_ITEM_RESULT*>(pGameMsg) );
|
|
break;
|
|
}
|
|
case MSG_SKILL_EVENT :
|
|
{
|
|
OnMsgSkillEvent ( static_cast<SMSG_SKILL_EVENT*>(pGameMsg) );
|
|
break; //Skill
|
|
}
|
|
|
|
case MSG_ADDED_SKILL_LIST:
|
|
{
|
|
break; //Skill List
|
|
}
|
|
|
|
case MSG_SKILL_LIST :
|
|
{
|
|
break; //Skill List
|
|
}
|
|
//타이밍 맞추기 곤란한다.
|
|
//case MSG_SKILL_EFFECT :
|
|
// {
|
|
// OnMsgSkillEffect( static_cast<SMSG_SKILL_EFFECT*>(pGameMsg) );
|
|
// break; //Skill Effect
|
|
// }
|
|
case MSG_TAMING_INFO:
|
|
{
|
|
OnTamingInfo( static_cast<SMSG_TAMING_INFO*>(pGameMsg) );
|
|
break;
|
|
}
|
|
case MSG_CMD_RESULT :
|
|
{
|
|
OnMsgCmd ( static_cast<SMSG_CMD_RESULT*>(pGameMsg) );
|
|
break; //Cmd
|
|
}
|
|
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_DROP_INFO :
|
|
{
|
|
OnMsgDropInfo ( static_cast<SMSG_ITEM_DROP_INFO*>(pGameMsg));
|
|
break;
|
|
}
|
|
case MSG_ITEM_WEAR :
|
|
{
|
|
OnMsgWearInfo ( static_cast<SMSG_ITEM_WEAR*>(pGameMsg) );
|
|
break; //아이템 변경
|
|
}
|
|
case MSG_ITEM_INVEN :
|
|
{
|
|
OnMsgInventory ( static_cast<SMSG_ITEM_INVEN*>(pGameMsg) );
|
|
break; //인벤 정보
|
|
}
|
|
case MSG_ITEM_DESTROY :
|
|
{
|
|
break; //Item Destroy
|
|
}
|
|
case MSG_TAKE_ITEM_RESULT :
|
|
{
|
|
OnMsgTakeItemResult( static_cast<SMSG_TAKE_ITEM_RESULT*>(pGameMsg) );
|
|
break;
|
|
}
|
|
case MSG_UPDATE_ITEM_COUNT:
|
|
{
|
|
break; //Item Count Update
|
|
}
|
|
case MSG_MIX_RESULT:
|
|
{
|
|
SMSG_MIX_RESULT* pMixResultMsg = static_cast< SMSG_MIX_RESULT* >( pGameMsg );
|
|
|
|
SGameAvatarEx* pLocalPlayer = GetLocalPlayer();
|
|
if( pLocalPlayer == NULL ) return;
|
|
|
|
FX_DATA fx_data;
|
|
fx_data.attack = pLocalPlayer->GetArID();
|
|
fx_data.owner = pLocalPlayer->GetArID();
|
|
fx_data.target = pLocalPlayer->GetArID();
|
|
fx_data.fPlayRate = 1.f;
|
|
fx_data.nEffPos = EFFECT_POS_TOP;
|
|
fx_data.nPlayID = 1;
|
|
|
|
if( pMixResultMsg->count > 0 ) //성공
|
|
{
|
|
fx_data.nFX_ID = 18016;
|
|
}
|
|
else //실패
|
|
{
|
|
fx_data.nFX_ID = 18017;
|
|
}
|
|
|
|
m_pGame->AddEffect( &fx_data );
|
|
}
|
|
break;
|
|
case MSG_BOOTH_NAME :
|
|
{
|
|
OnMsgBoothName( static_cast< SMSG_BOOTH_NAME* >( pGameMsg ) );
|
|
break;
|
|
}
|
|
case MSG_BOOTH_CLOSED :
|
|
{
|
|
OnMsgBoothClosed( static_cast< SMSG_BOOTH_CLOSED * >( pGameMsg ) );
|
|
break;
|
|
}
|
|
case MSG_TRADE :
|
|
{
|
|
SMSG_TRADE* pTradeMsg = static_cast<SMSG_TRADE*>(pGameMsg);
|
|
SGameAvatarEx * pPlayer = GetAvatar( pTradeMsg->target_player );
|
|
if( pPlayer )
|
|
pTradeMsg->target_Name = pPlayer->GetName();
|
|
break; //Trade
|
|
}
|
|
case MSG_STATE :
|
|
{
|
|
OnMsgState( static_cast<SMSG_STATE*>(pGameMsg) );
|
|
break; //상태 이상 시간
|
|
}
|
|
case MSG_PROPERTY :
|
|
{
|
|
OnMsgProperty( static_cast<SMSG_PROPERTY*>(pGameMsg) );
|
|
break; //각종 상태
|
|
}
|
|
case MSG_HPMP :
|
|
{
|
|
OnMsgHPMP( static_cast<SMSG_HPMP*>(pGameMsg) );
|
|
break; //HPMP 동시에
|
|
}
|
|
case MSG_EXP_UPDATE :
|
|
{
|
|
OnMsgExpUpdate( static_cast<SMSG_EXP_UPDATE*>(pGameMsg) );
|
|
break;
|
|
}
|
|
case MSG_MARKET :
|
|
{
|
|
break; //Market
|
|
}
|
|
case MSG_NPC_DIALOG :
|
|
{
|
|
break; //NPC Dialog
|
|
}
|
|
case MSG_LEVEL_UPDATE :
|
|
{
|
|
OnMsgLevelUpdate( static_cast<SMSG_LEVEL_UPDATE*>(pGameMsg) );
|
|
break;
|
|
}
|
|
case CMSG_WARP :
|
|
{
|
|
OnMsgWarp ( static_cast<SCMSG_WARP*>(pGameMsg) );
|
|
break; //Warp
|
|
}
|
|
case MSG_STATUS_CHANGE :
|
|
{
|
|
OnMsgStatusChange( static_cast<SMSG_STATUS_CHANGE*>(pGameMsg) );
|
|
break; //Warp
|
|
}
|
|
case MSG_REGEN_HPMP :
|
|
{
|
|
OnMsgRegenHPMP( static_cast<SMSG_REGEN_HPMP*>(pGameMsg));
|
|
break;
|
|
}
|
|
|
|
case IMSG_REQ_OPEN_MSGBOX:
|
|
{
|
|
SIMSG_REQ_OPEN_MSGBOX* pReqOpenMsg = static_cast<SIMSG_REQ_OPEN_MSGBOX*>(pGameMsg);
|
|
//Msg 박스 호출 될 경우, 로컬 플레이어의 죽는 상자를 표시 플래그를 꺼준다.
|
|
if( pReqOpenMsg->m_MsgBoxID != SIMSG_REQ_OPEN_MSGBOX::MSGBOX_DEAD )
|
|
{
|
|
if( GetLocalPlayer() && GetLocalPlayer()->IsDead() )
|
|
{
|
|
SGameLocalPlayer * pPlayer = (SGameLocalPlayer *)GetLocalPlayer();
|
|
//사라진 메세지 박스 다시 켜기 위해서
|
|
pPlayer->ResetDeadDialog();
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
case MSG_EMOTION:
|
|
{
|
|
OnMsgEmotion( static_cast<SMSG_EMOTION*>(pGameMsg) );
|
|
break;
|
|
}
|
|
//연출이 필요한 이펙트 모음
|
|
case MSG_GET_CHAOS:
|
|
{
|
|
OnMsgAddOtherEffect( pGameMsg );
|
|
break;
|
|
}
|
|
case MSG_ENERGY:
|
|
{
|
|
OnMsgAddForceSphere( static_cast<SMSG_ENERGY*>(pGameMsg) );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//===================================================================================================
|
|
//Other Object
|
|
SGameAvatarEx * SCommandSystem::GetObject( int nType, K3DVector & pos, float & fDist, int nItemType /*= -1*/, float fLimitDistance )
|
|
{
|
|
int nSelectIndex = -1;
|
|
float fFirstLen = 0.f;
|
|
|
|
switch( nType )
|
|
{
|
|
case TS_ENTER::GAME_PLAYER : break;
|
|
case TS_ENTER::GAME_NPC : break;
|
|
case TS_ENTER::GAME_ITEM :
|
|
case TS_ENTER::GAME_MOB :
|
|
{
|
|
SGameAvatarEx* pFindObject = NULL;
|
|
SGameAvatarEx* pGameObject = NULL;
|
|
KSortVector< class SGameAvatarEx* >::iterator it = m_svObject.begin();
|
|
|
|
int i=0;
|
|
while ( it != m_svObject.end() )
|
|
{
|
|
pGameObject = (*it);
|
|
if ( pGameObject != NULL && pGameObject->GetObjType() == nType && pGameObject->IsActivated() )
|
|
{
|
|
if( i == 0 )
|
|
{
|
|
fFirstLen = GetDistance( pos, *pGameObject->GetPosition() );
|
|
pFindObject = pGameObject;
|
|
i++;
|
|
}
|
|
|
|
float fLen = GetDistance( pos, *pGameObject->GetPosition() );
|
|
if( fFirstLen > fLen )
|
|
{
|
|
fFirstLen = fLen;
|
|
pFindObject = pGameObject;
|
|
}
|
|
}
|
|
++it;
|
|
}
|
|
|
|
if( pFindObject )
|
|
{
|
|
if( nType == TS_ENTER::GAME_ITEM )
|
|
{
|
|
if( fFirstLen > fLimitDistance ) return NULL; //먹는 범위 보다 크면, 안 간다.
|
|
|
|
if( nItemType != -1 )
|
|
{
|
|
if( nItemType != GetItemDB().GetUseType( pFindObject->GetContentID() ) ) return NULL;
|
|
}
|
|
}
|
|
else if( nType == TS_ENTER::GAME_MOB )
|
|
{
|
|
if( fFirstLen > 30 * GameRule::DEFAULT_UNIT_SIZE ) return NULL; //10m 보다 크면, 안 간다. // AziaMafia LoadMap 30
|
|
}
|
|
fDist = fFirstLen;
|
|
return pFindObject;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
break;
|
|
case TS_ENTER::GAME_SUMMON : break;
|
|
case TS_ENTER::GAME_SKILL_PROP : break;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
//===================================================================================================
|
|
// 펫 아이템 줍기 기능용 특수 함수 -
|
|
void SCommandSystem::GetItemObjects_For_PetAutoGather( const K3DVector& center, float fLimitRange, std::vector<SGameAvatarEx*>& vecResult, const K3DVector& dist_pos, std::vector<float>& vecDist, int nMaxCount )
|
|
{
|
|
int nSelectIndex = -1;
|
|
float fFirstLen = 0.f;
|
|
|
|
vecResult.clear();
|
|
vecDist.clear();
|
|
|
|
SGameAvatarEx* pFindObject = NULL;
|
|
SGameAvatarEx* pGameObject = NULL;
|
|
KSortVector< class SGameAvatarEx* >::iterator it = m_svObject.begin();
|
|
|
|
int i=0;
|
|
while ( it != m_svObject.end() )
|
|
{
|
|
pGameObject = (*it);
|
|
if ( pGameObject != NULL && pGameObject->GetObjType() == TS_ENTER::GAME_ITEM && pGameObject->IsActivated() )
|
|
{
|
|
float fLen = GetDistance( center, *pGameObject->GetPosition() );
|
|
SGameAvatarEx* pFindObject = pGameObject;
|
|
|
|
if( fLen < fLimitRange )
|
|
{
|
|
vecResult.push_back(pFindObject);
|
|
vecDist.push_back( GetDistance( dist_pos, *pGameObject->GetPosition() ) );
|
|
|
|
if( vecResult.size() >= nMaxCount )
|
|
break;
|
|
}
|
|
|
|
}
|
|
++it;
|
|
}
|
|
}
|
|
|
|
SGameAvatarEx* SCommandSystem::GetObjectFromLeaveList( AR_HANDLE arHandle )
|
|
{
|
|
SGameAvatarExTag* pAvatarExTag = NULL;
|
|
if( m_hashLeaveList.lookup( arHandle, pAvatarExTag ) )
|
|
{
|
|
SGameAvatarEx* pAvatar = NULL;
|
|
if( pAvatarExTag )
|
|
{
|
|
if( pAvatarExTag->bNotUse ) //사용 할수 없다면
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
pAvatar = pAvatarExTag->ptr;
|
|
|
|
if( pAvatar )
|
|
{
|
|
pAvatar->Activate();
|
|
pAvatar->ReInitialize();
|
|
|
|
_Object* arObj = &pAvatar->GetArObject();
|
|
if( arObj )
|
|
{
|
|
arObj->bIsActivate = true;
|
|
arObj->bIsLeaved = false;
|
|
arObj->leaveTime = 0;
|
|
}
|
|
}
|
|
|
|
pAvatarExTag->ptr = NULL;
|
|
SAFE_DELETE( pAvatarExTag );
|
|
}
|
|
|
|
m_hashLeaveList.erase( arHandle );
|
|
|
|
return pAvatar;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
SGameAvatarEx * SCommandSystem::GetSelectCreature()
|
|
{
|
|
if( m_vLocalCreature.empty() ) return NULL;
|
|
if( m_nCreatureSelect < 0 || m_nCreatureSelect >= (int)m_vLocalCreature.size() ) return NULL;
|
|
|
|
return m_vLocalCreature[m_nCreatureSelect];
|
|
}
|
|
|
|
void SCommandSystem::onLeave( AR_HANDLE handle, BOOL bEffect )
|
|
{
|
|
//Target 초기화~
|
|
//for( unsigned int i(0); m_vLocalList.size()>i; i++ )
|
|
//{
|
|
// m_vLocalList[i]->CheckAttackObject( pPtr->handle );
|
|
// m_vLocalList[i]->CheckTargetObject( pPtr->handle );
|
|
//}
|
|
|
|
if( m_hMouseOverItem == handle )
|
|
m_hMouseOverItem = 0;
|
|
|
|
//삭제 보류중인 Object 검사
|
|
RemoveReservationObject();
|
|
|
|
//TargetMgr Leave
|
|
m_pTargetMgr->LeaveTarget( handle );
|
|
|
|
SGameAvatarEx* pAvatar = NULL;
|
|
if( m_hashObject.lookup( handle, pAvatar ) )
|
|
{
|
|
/// 2011.01.20 - prodongi
|
|
if (pAvatar->IsLocalPlayer())
|
|
setIsTaming(false);
|
|
|
|
//마스터가 존재 한다면 Ride 정보를 초기화 시킨다
|
|
SGameAvatarEx* pMaster = GetAvatar( pAvatar->GetMaster() );
|
|
if( pMaster )
|
|
{
|
|
//같은 핸들이 Leave라면 링크 끊자
|
|
if( pMaster->GetCreatureMountHandle() == pAvatar->GetArID() )
|
|
pMaster->SetRiderCreatureInfo();
|
|
|
|
DeleteRidingObject( pAvatar->GetMaster(), pAvatar->GetArID() );
|
|
|
|
// 2010.08.12 - prodongi
|
|
if (pAvatar->GetInnObjType() == TS_ENTER::GAME_SUMMON)
|
|
pMaster->SetCreature(handle, false);
|
|
|
|
if( pMaster->IsLocalPlayer() == true )
|
|
UISendStringMessage(m_pGame->GetGameManager(), SIMSG_TOGGLE_UIWINDOW::UIWINDOW_DURABILITY, "refresh_durability");
|
|
}
|
|
|
|
LeaveTransportCreature( pAvatar->GetTransportCreatureHandle() );
|
|
|
|
pAvatar->Deactivate();
|
|
pAvatar->LeaveData();
|
|
|
|
//삭제 보류 대상인가?
|
|
|
|
//잦은 이동시 몹안나오는 문제가 있어서 임시로 삭제 2009.12.24. sfreer
|
|
/*if ((!pAvatar->IsDead()) && (pAvatar->GetInnObjType() == TS_ENTER::GAME_MOB)) // 몹이고 안 죽었는데도 Leave 메시지가 날아오면
|
|
{
|
|
pAvatar->Activate(); // 비활성화했던걸 살리고
|
|
pAvatar->SetReservation(true);
|
|
pAvatar->SetFadeOut(3000); // 3초에 걸쳐 페이드아웃하게 한다. 3초는 하드코딩
|
|
}*/
|
|
|
|
if(!pAvatar->IsReservation())
|
|
{
|
|
m_hashObject.erase( handle );
|
|
m_hashLeaveList.add( handle, new SGameAvatarExTag( pAvatar, GetSafeTickCount() ) );
|
|
m_svObject.erase( pAvatar );
|
|
|
|
if( pAvatar->GetObjType() == TS_ENTER::GAME_PLAYER )
|
|
{
|
|
m_svPlayerObject.erase( pAvatar );
|
|
}
|
|
else
|
|
{
|
|
m_svOtherObject.erase( pAvatar );
|
|
{
|
|
int idx = m_svRecongnizeMobObject.search_index( pAvatar );
|
|
if( idx >= 0)
|
|
m_svRecongnizeMobObject.erase( pAvatar );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
m_svReservationObject.push_back(handle);
|
|
|
|
m_pGame->DelOwnerEffect( handle );
|
|
}
|
|
else
|
|
{
|
|
LeaveTransportCreature( handle );
|
|
}
|
|
|
|
pAvatar = NULL;
|
|
if( m_hashPendingObjList.lookup( handle, pAvatar ) )
|
|
{
|
|
m_hashPendingObjList.erase( handle );
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::LeaveTransportCreature( AR_HANDLE hCreature, bool bWithArObj )
|
|
{
|
|
SGameAvatarEx* pCreature = NULL;
|
|
if( m_hashTransportCreatureObject.lookup( hCreature, pCreature ) )
|
|
{
|
|
pCreature->Deactivate();
|
|
pCreature->LeaveData();
|
|
|
|
m_hashTransportCreatureObject.erase( hCreature );
|
|
m_hashLeaveList.add( hCreature, new SGameAvatarExTag( pCreature, GetSafeTickCount() ) );
|
|
m_svTransportCreatureObject.erase( pCreature );
|
|
|
|
if( bWithArObj ) m_pArObject->onLeave( hCreature );
|
|
}
|
|
|
|
pCreature = NULL;
|
|
if( m_hashPendingObjList.lookup( hCreature, pCreature ) )
|
|
{
|
|
m_hashPendingObjList.erase( hCreature );
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::ActivateStateEffect()
|
|
{
|
|
int nObjSize( m_svObject.size() );
|
|
for( int i(0); i<nObjSize; ++i )
|
|
{
|
|
RefreshStateEffect( m_svObject[i] );
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::RefreshStateEffect( SGameAvatarEx* pAvatar )
|
|
{
|
|
if( pAvatar == NULL ) return;
|
|
|
|
pAvatar->RefreshAllStateEffect();
|
|
|
|
SGameOption& gameoption = GetGameOption();
|
|
|
|
std::vector<SStateSlot*> vecStateList;
|
|
SStateSlot* pStateSlot(NULL);
|
|
|
|
pAvatar->GetAllStateList( vecStateList, false );
|
|
|
|
SMSG_STATE state;
|
|
std::vector<SStateSlot*>::iterator iter = vecStateList.begin();
|
|
for( ; iter != vecStateList.end(); ++iter )
|
|
{
|
|
pStateSlot = (*iter);
|
|
if( pStateSlot == NULL ) continue;
|
|
|
|
state.handle = pStateSlot->GetTargetHandle();
|
|
state.state_handle = pStateSlot->GetStateHandle();
|
|
state.state_code = pStateSlot->GetStateCode();
|
|
state.state_level = pStateSlot->GetStateLevel();
|
|
state.end_time = pStateSlot->GetEndTime();
|
|
|
|
StateInfoEx* pStateInfo = GetTenacityDB().GetTenacityData( state.state_code );
|
|
if( pStateInfo )
|
|
{
|
|
switch( pStateInfo->effect_type )
|
|
{
|
|
case STATE_TYPE::STATE_RIDING:
|
|
{
|
|
if( pAvatar->GetObjType() == TS_ENTER::GAME_PLAYER )
|
|
{
|
|
if( state.state_level > 0 )
|
|
{
|
|
OnUnMount( pStateInfo, pAvatar, true );
|
|
OnMount( pStateInfo, pAvatar, false );
|
|
}
|
|
else if( state.state_level == 0 )
|
|
{
|
|
OnUnMount( pStateInfo, pAvatar );
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
vecStateList.clear();
|
|
}
|
|
|
|
void SCommandSystem::RemoveAllReservationObject()
|
|
{
|
|
std::vector< AR_HANDLE >::iterator iter = m_svReservationObject.begin();
|
|
for( ; iter != m_svReservationObject.end(); )
|
|
{
|
|
SGameAvatarEx* pAvatar = NULL;
|
|
if( m_hashObject.lookup( (*iter), pAvatar ) )
|
|
{
|
|
m_hashObject.erase( (*iter) );
|
|
m_hashLeaveList.add( (*iter), new SGameAvatarExTag( pAvatar, GetSafeTickCount() ) );
|
|
m_svObject.erase( pAvatar );
|
|
|
|
if( pAvatar->GetObjType() == TS_ENTER::GAME_PLAYER )
|
|
{
|
|
m_svPlayerObject.erase( pAvatar );
|
|
}
|
|
else
|
|
{
|
|
m_svOtherObject.erase( pAvatar );
|
|
|
|
{
|
|
int idx = m_svRecongnizeMobObject.search_index( pAvatar );
|
|
if( idx >= 0)
|
|
m_svRecongnizeMobObject.erase( pAvatar );
|
|
}
|
|
|
|
}
|
|
|
|
iter = m_svReservationObject.erase(iter);
|
|
}
|
|
else
|
|
{
|
|
assert( false && "SCommandSystem::RemoveReservationObject ( 들어오면 안되는데... )");
|
|
iter = m_svReservationObject.erase(iter);
|
|
}
|
|
}
|
|
}
|
|
|
|
//삭제 시기 이펙트 종료 되거나 SkillCancel
|
|
void SCommandSystem::RemoveReservationObject( bool bCastingCancel )
|
|
{
|
|
std::vector< AR_HANDLE >::iterator iter = m_svReservationObject.begin();
|
|
for( ; iter != m_svReservationObject.end(); )
|
|
{
|
|
SGameAvatarEx* pAvatar = NULL;
|
|
if( m_hashObject.lookup( (*iter), pAvatar ) )
|
|
{
|
|
//캐스팅 캔슬이 거나 삭제 보류가 해제됐다면 삭제
|
|
if( bCastingCancel || !pAvatar->IsReservation() )
|
|
{
|
|
m_hashObject.erase( (*iter) );
|
|
m_hashLeaveList.add( (*iter), new SGameAvatarExTag( pAvatar, GetSafeTickCount() ) );
|
|
m_svObject.erase( pAvatar );
|
|
|
|
if( pAvatar->GetObjType() == TS_ENTER::GAME_PLAYER )
|
|
{
|
|
m_svPlayerObject.erase( pAvatar );
|
|
}
|
|
else
|
|
{
|
|
m_svOtherObject.erase( pAvatar );
|
|
{
|
|
int idx = m_svRecongnizeMobObject.search_index( pAvatar );
|
|
if( idx >= 0)
|
|
m_svRecongnizeMobObject.erase( pAvatar );
|
|
}
|
|
|
|
}
|
|
|
|
iter = m_svReservationObject.erase(iter);
|
|
}
|
|
else
|
|
iter++;
|
|
}
|
|
else
|
|
{
|
|
assert( false && "SCommandSystem::RemoveReservationObject ( 들어오면 안되는데... )");
|
|
iter = m_svReservationObject.erase(iter);
|
|
}
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::OnWarp()
|
|
{
|
|
RemoveAllReservationObject();
|
|
|
|
SGameAvatarExTag* pAvatarTag = NULL;
|
|
|
|
bool res = m_hashLeaveList.get_first_value( pAvatarTag );
|
|
while ( res )
|
|
{
|
|
if( pAvatarTag != NULL )
|
|
{
|
|
pAvatarTag->bNotUse = true;
|
|
pAvatarTag->dwTime -= OBJ_LEAVE_TIME;
|
|
}
|
|
res = m_hashLeaveList.get_next_value( pAvatarTag );
|
|
}
|
|
|
|
m_hashPendingObjList.clear();
|
|
|
|
//미리 삭제 할수 있으면 삭제 하자
|
|
SetArrangeObject();
|
|
}
|
|
|
|
void SCommandSystem::AddRidingObject( AR_HANDLE hMaster, AR_HANDLE hCreature, bool bMount )
|
|
{
|
|
std::vector< RIDING_INFO >::iterator iter = m_svRidingObject.begin();
|
|
for( ; iter != m_svRidingObject.end(); ++iter )
|
|
{
|
|
if( (*iter).player_handle == hMaster && (*iter).creature_handle == hCreature )
|
|
{
|
|
//같은게 있다면 리턴
|
|
return;
|
|
}
|
|
}
|
|
|
|
RIDING_INFO info;
|
|
info.player_handle = hMaster;
|
|
info.creature_handle = hCreature;
|
|
info.dwLeftTime = m_dwTime;
|
|
|
|
if( bMount )
|
|
info.mount_type = RIDING_INFO::MOUNT_TYPE::MOUNT_CREATURE_TYPE;
|
|
else
|
|
info.mount_type = RIDING_INFO::MOUNT_TYPE::UNMOUNT_CREATURE_TYPE;
|
|
|
|
m_svRidingObject.push_back( info );
|
|
}
|
|
void SCommandSystem::DeleteRidingObject( AR_HANDLE hMaster, AR_HANDLE hCreature )
|
|
{
|
|
std::vector< RIDING_INFO >::iterator iter = m_svRidingObject.begin();
|
|
for( ; iter != m_svRidingObject.end(); )
|
|
{
|
|
if( (*iter).player_handle == hMaster && (*iter).creature_handle == hCreature )
|
|
{
|
|
iter = m_svRidingObject.erase(iter);
|
|
}
|
|
else
|
|
++iter;
|
|
}
|
|
}
|
|
void SCommandSystem::FindRidingObject()
|
|
{
|
|
if( m_svRidingObject.empty() ) return;
|
|
std::vector< RIDING_INFO >::iterator iter = m_svRidingObject.begin();
|
|
for( ; iter != m_svRidingObject.end(); )
|
|
{
|
|
SGameAvatarEx* pPlayer = GetAvatar( (*iter).player_handle );
|
|
SGameAvatarEx* pCreature = GetAvatar( (*iter).creature_handle );
|
|
|
|
//플레이어 및 크리처 둘다 찾을수 없다면 삭제
|
|
/* if( pPlayer == NULL && pCreature == NULL )
|
|
{
|
|
assert( false && "FindRidingObject() pPlayer == NULL && pCreature == NULL" );
|
|
iter = m_svRidingObject.erase(iter);
|
|
}*/
|
|
bool bCheck = false;
|
|
if( pPlayer == NULL || pCreature == NULL )
|
|
bCheck = true;
|
|
else
|
|
{
|
|
if( (*iter).mount_type == RIDING_INFO::MOUNT_TYPE::MOUNT_CREATURE_TYPE )
|
|
{
|
|
KEventPointSeq* pEventPoint = pCreature->GetSaddleEffectPos();
|
|
if( pEventPoint == NULL )
|
|
bCheck = true;
|
|
else
|
|
{
|
|
pPlayer->SetMountMode();
|
|
pCreature->SetMountMode();
|
|
|
|
pPlayer->SetAniLock( false );
|
|
|
|
int nAniType = 0;
|
|
// #2.1.6 sonador
|
|
if( pPlayer->IsMoving() )
|
|
nAniType = pPlayer->GetPlayerMRunAniID();
|
|
else
|
|
nAniType = pPlayer->GetPlayerMDefAniID();
|
|
|
|
pPlayer->NPlayAnimation( nAniType, SEQTYPE_LOOP );
|
|
|
|
pPlayer->SetRiderCreatureInfo( &SGameAvatarEx::RiderCreatureInfo( (*iter).creature_handle, EFFECT_POS_SADDLE, pCreature->GetCreatureMountType() ) );
|
|
|
|
pCreature->SetAniLock( false );
|
|
|
|
if( pCreature->IsMoving()) pCreature->NPlayAnimation( ANI_RUN, SEQTYPE_LOOP );
|
|
else pCreature->NPlayAnimation( ANI_DEFAULT01, SEQTYPE_LOOP );
|
|
|
|
iter = m_svRidingObject.erase(iter);
|
|
}
|
|
}
|
|
else if( (*iter).mount_type == RIDING_INFO::MOUNT_TYPE::UNMOUNT_CREATURE_TYPE )
|
|
{
|
|
pPlayer->SetNormalMode();
|
|
pCreature->SetNormalMode();
|
|
|
|
pPlayer->SetRiderCreatureInfo();
|
|
pPlayer->SetAniLock( false );
|
|
pPlayer->Default();
|
|
|
|
pCreature->SetBestPosition();
|
|
pCreature->SetAniLock( false );
|
|
pCreature->Default();
|
|
|
|
iter = m_svRidingObject.erase(iter);
|
|
}
|
|
else
|
|
bCheck = true;
|
|
}
|
|
|
|
if( bCheck )
|
|
{
|
|
//3분이 지났다면 그냥 삭제
|
|
if( (*iter).dwLeftTime != 0 )
|
|
{
|
|
if( (m_dwTime - (*iter).dwLeftTime) > 180000 )
|
|
{
|
|
//임시로 지움
|
|
//assert( false && "FindRidingObject() 타임 오빠~" );
|
|
iter = m_svRidingObject.erase(iter);
|
|
}
|
|
else
|
|
++iter;
|
|
}
|
|
else
|
|
{
|
|
(*iter).dwLeftTime = m_dwTime;
|
|
++iter;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::ResetFailAddCreature()
|
|
{
|
|
SGameAvatarEx* pMaster(NULL);
|
|
|
|
ENTER_CREATURE_FAIL* FailInfo;
|
|
std::vector< ENTER_CREATURE_FAIL >::iterator it = m_FailAddCreatureList.begin();
|
|
while( it != m_FailAddCreatureList.end() )
|
|
{
|
|
FailInfo = &(*it);
|
|
pMaster = GetAvatar( FailInfo->hMaster );
|
|
if( pMaster )
|
|
{
|
|
if( pMaster->IsMount() || pMaster->IsMountMode() )
|
|
AddRidingObject( FailInfo->hMaster, FailInfo->hCreature, true );
|
|
// 2010.08.12 - prodongi
|
|
pMaster->SetCreature( FailInfo->hCreature, true );
|
|
|
|
it = m_FailAddCreatureList.erase( it );
|
|
}
|
|
else ++it;
|
|
}
|
|
}
|
|
|
|
SGameAvatarEx * SCommandSystem::GetAvatar( AR_HANDLE target )
|
|
{
|
|
if( m_bDestroy ) return NULL;
|
|
|
|
if( target <= 0 ) return NULL;
|
|
|
|
SGameAvatarEx * pDamager = NULL;
|
|
m_hashObject.lookup( target, pDamager );
|
|
|
|
return pDamager;
|
|
}
|
|
|
|
SGameObject * SCommandSystem::GetObject( AR_HANDLE objHandle )
|
|
{
|
|
if( m_bDestroy ) return NULL;
|
|
|
|
if( objHandle <= 0 ) return NULL;
|
|
|
|
SGameAvatarEx * pDamager = NULL;
|
|
m_hashObject.lookup( objHandle, pDamager );
|
|
return pDamager;
|
|
}
|
|
|
|
SGameAvatarEx * SCommandSystem::GetPickObject( K3DVector &vNear, K3DVector &vFar, BOOL bLocal )
|
|
{
|
|
SGameAvatarEx* pGameObject = NULL;
|
|
KSortVector< class SGameAvatarEx* >::iterator it;
|
|
|
|
// First, try it with the checkbox
|
|
float fDist = 9999999.0f;
|
|
float fTempDist = 0.0f;
|
|
SGameAvatarEx* pTempPickObj = NULL;
|
|
K3DVector vCameraPos = m_pGame->GetCamera()->GetCamPos();
|
|
|
|
for ( it = m_svObject.begin(); it != m_svObject.end(); ++it )
|
|
{
|
|
pGameObject = (*it);
|
|
if ( pGameObject != NULL )
|
|
{
|
|
SGameAvatarEx* pPickObj = NULL;
|
|
if( bLocal )
|
|
{ // Click on my character or the dead ones
|
|
if( pGameObject->GetArID() == m_LocalHandle && pGameObject->CheckCollision( vNear, vFar ) )
|
|
pPickObj = pGameObject;
|
|
|
|
if( !pGameObject->IsLive() && pGameObject->CheckCollision( vNear, vFar ) )
|
|
pPickObj = pGameObject;
|
|
}
|
|
else
|
|
{
|
|
if( pGameObject->GetObjType() == TS_ENTER::GAME_ITEM || pGameObject->GetObjType() == TS_ENTER::GAME_FIELD_PROP )
|
|
{ // Item
|
|
if( pGameObject->GetArID() != m_LocalHandle && pGameObject->CheckCollision( vNear, vFar ) )
|
|
pPickObj = pGameObject;
|
|
}
|
|
else
|
|
{
|
|
//살은 넘들 클릭
|
|
if( pGameObject->GetArID() != m_LocalHandle && pGameObject->IsLive() && pGameObject->CheckCollision( vNear, vFar ) )
|
|
pPickObj = pGameObject;
|
|
}
|
|
}
|
|
|
|
if( pPickObj )
|
|
{
|
|
fTempDist = K3DVectorLength( (*pPickObj->GetPosition() - vCameraPos) );
|
|
if( fDist > fTempDist )
|
|
{
|
|
fDist = fTempDist;
|
|
pTempPickObj = pPickObj;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( pTempPickObj )
|
|
{
|
|
if(pTempPickObj->GetStatus() & TS_ENTER::CreatureInfo::FLAG_INVISIBLE)
|
|
pTempPickObj = NULL;
|
|
else
|
|
{
|
|
if( !pTempPickObj->IsRender() )
|
|
pTempPickObj = NULL;
|
|
}
|
|
|
|
return pTempPickObj;
|
|
}
|
|
|
|
// If there are no objects detected, expand each checkbox and check again, then select an appropriate object from the detected ones
|
|
SGameAvatarEx *pSelf = NULL, *pCorpse = NULL, *pItem = NULL, *pAliveObj = NULL;
|
|
for ( it = m_svObject.begin(); it != m_svObject.end(); ++it )
|
|
{
|
|
pGameObject = (*it);
|
|
if ( pGameObject != NULL )
|
|
{
|
|
K3DVALUE r = GetDistance( *pGameObject->GetPosition(), vNear ) * 0.005f; // A suitable value
|
|
|
|
if( bLocal )
|
|
{
|
|
if( pGameObject->GetArID() == m_LocalHandle && pGameObject->RelaxedCheckCollision( vNear, vFar, r ) ) {
|
|
pSelf = pGameObject;
|
|
continue;
|
|
}
|
|
|
|
if( !pGameObject->IsLive() && pGameObject->RelaxedCheckCollision( vNear, vFar, r ) ) {
|
|
pCorpse = pGameObject;
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( pGameObject->GetObjType() == TS_ENTER::GAME_ITEM )
|
|
{
|
|
if( pGameObject->GetArID() != m_LocalHandle && pGameObject->RelaxedCheckCollision( vNear, vFar, r ) ) {
|
|
pItem = pGameObject;
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( pGameObject->GetArID() != m_LocalHandle && pGameObject->IsLive() && pGameObject->RelaxedCheckCollision( vNear, vFar, r ) ) {
|
|
pAliveObj = pGameObject;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Select in order of priority: living creatures, items, corpses, then own character
|
|
SGameAvatarEx* pPickObj = pAliveObj ? pAliveObj : pItem ? pItem : pCorpse ? pCorpse : pSelf;
|
|
if(pPickObj)
|
|
{
|
|
if(pPickObj->GetStatus() & TS_ENTER::CreatureInfo::FLAG_INVISIBLE)
|
|
pPickObj = NULL;
|
|
else
|
|
{
|
|
if( !pPickObj->IsRender() )
|
|
pPickObj = NULL;
|
|
}
|
|
}
|
|
|
|
return pPickObj;
|
|
}
|
|
|
|
SGameAvatarEx * SCommandSystem::GetTransportCreatureObject( AR_HANDLE objHandle )
|
|
{
|
|
if( m_bDestroy ) return NULL;
|
|
|
|
if( objHandle <= 0 ) return NULL;
|
|
|
|
SGameAvatarEx * pCreature = NULL;
|
|
m_hashTransportCreatureObject.lookup( objHandle, pCreature );
|
|
return pCreature;
|
|
}
|
|
|
|
void SCommandSystem::Render( unsigned long uRenderBitVector, KViewportObject** ppViewportList, int nViewportCount )
|
|
{
|
|
if( uRenderBitVector & Game_RenderAvatar )
|
|
{ //랜더링 순서 있음, 플레이어가 나중에 랜더링
|
|
SGameAvatarEx* pGameObject = NULL;
|
|
KSortVector< class SGameAvatarEx* >::iterator it = m_svOtherObject.begin();
|
|
while ( it != m_svOtherObject.end() )
|
|
{
|
|
pGameObject = (*it);
|
|
if ( pGameObject != NULL /*&& pGameObject->IsLocalPlayer()*/ )
|
|
{
|
|
if( pGameObject->GetObjType() != TS_ENTER::GAME_ITEM || GetKeyState(VK_MENU) < 0 )
|
|
{
|
|
DisplayNamePanel( pGameObject );
|
|
}
|
|
pGameObject->Render( uRenderBitVector, ppViewportList, nViewportCount );
|
|
}
|
|
++it;
|
|
}
|
|
|
|
//운송 전용 크리처
|
|
it = m_svTransportCreatureObject.begin();
|
|
for( ; it != m_svTransportCreatureObject.end(); ++it )
|
|
{
|
|
(*it)->Render( uRenderBitVector, ppViewportList, nViewportCount );
|
|
}
|
|
|
|
unsigned int nStateFlag = SGameAvatarEx::FLAG_STATE_NONE;
|
|
SGameAvatarEx* pLocalPlayer = GetLocalPlayer();
|
|
if( pLocalPlayer ) nStateFlag = pLocalPlayer->GetStateFlag();
|
|
|
|
SGamePlayer* pPlayer = (SGamePlayer*)pLocalPlayer;
|
|
AR_HANDLE hCreatureHandle = pPlayer->GetCreature();
|
|
SGameAvatarEx* _pCreature = NULL;
|
|
unsigned int nCreatureStateFlag = SGameAvatarEx::FLAG_STATE_NONE;
|
|
if (hCreatureHandle != 0)
|
|
{
|
|
_pCreature = (SGameAvatarEx*)GetObjectA(hCreatureHandle);
|
|
if (_pCreature != NULL)
|
|
nCreatureStateFlag = _pCreature->GetStateFlag();
|
|
}
|
|
|
|
it = m_svPlayerObject.begin();
|
|
if(( nStateFlag & SGameAvatarEx::FLAG_STATE_DETECT_HIDING) || (nCreatureStateFlag & SGameAvatarEx::FLAG_STATE_DETECT_HIDING))
|
|
{
|
|
float fDetectRange = pLocalPlayer->GetHidingDetectRange();
|
|
K3DVector vPos = *pLocalPlayer->GetPosition();
|
|
|
|
float fCreatureDetectRange = 0;
|
|
K3DVector vCreaturePos(0, 0, 0);
|
|
|
|
if (_pCreature != NULL)
|
|
{
|
|
if(_pCreature->GetInnObjType() == TS_ENTER::GAME_SUMMON)
|
|
{
|
|
fCreatureDetectRange = _pCreature->GetHidingDetectRange();
|
|
vCreaturePos = *_pCreature->GetPosition();
|
|
}
|
|
}
|
|
|
|
while ( it != m_svPlayerObject.end() )
|
|
{
|
|
pGameObject = (*it);
|
|
if( (pGameObject->GetStatus() & TS_ENTER::CreatureInfo::FLAG_INVISIBLE) )
|
|
{
|
|
if( pGameObject->IsLocalPlayer() )
|
|
DisplayNamePanel( pGameObject );
|
|
}
|
|
else
|
|
{
|
|
if( !pGameObject->IsLocalPlayer() )
|
|
{
|
|
if( pGameObject->GetStateFlag() & SGameAvatarEx::FLAG_STATE_HIDING )
|
|
{
|
|
if( m_pGame->IsPartyRaidMemeber( pGameObject->GetArID() ) )
|
|
{
|
|
pGameObject->SetHidingVisiblity( HIDING_VISIBILITY_RATE_PARTY_RAID ); //파티원이나 레이드원이면
|
|
}
|
|
else
|
|
{
|
|
K3DVector vTargetPos = *pGameObject->GetPosition();
|
|
float fLength = K3DVectorLength( vTargetPos - vPos );
|
|
float fCreatureLength = K3DVectorLength( vTargetPos - vCreaturePos );
|
|
if( fLength < fDetectRange || fCreatureLength < fCreatureDetectRange ) //Detect 사거리가 더 크다면
|
|
pGameObject->SetHidingVisiblity( HIDING_VISIBILITY_RATE ); //Detect 시야 안에 있다
|
|
else
|
|
{
|
|
pGameObject->SetHidingVisiblity( 0.0f ); //Detect 시야 밖에 있다
|
|
DisplayNamePanel( pGameObject );
|
|
m_pTargetMgr->LeaveTarget(pGameObject->GetArID());
|
|
|
|
// 은신 감지 거리를 벗어 날 경우, 현재 타겟 비교 후 타겟 해제. kappamind, 2010.01.28
|
|
if( g_pCurrentGameSystem->IsTarget( pGameObject->GetArID() ) )
|
|
{
|
|
g_pCurrentGameSystem->SetTarget(NULL);
|
|
pGameObject = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( pGameObject )
|
|
{
|
|
DisplayNamePanel( pGameObject );
|
|
pGameObject->Render( uRenderBitVector, ppViewportList, nViewportCount );
|
|
}
|
|
}
|
|
++it;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while ( it != m_svPlayerObject.end() )
|
|
{
|
|
pGameObject = (*it);
|
|
if( (pGameObject->GetStatus() & TS_ENTER::CreatureInfo::FLAG_INVISIBLE) )
|
|
{
|
|
if( pGameObject->IsLocalPlayer() )
|
|
DisplayNamePanel( pGameObject );
|
|
}
|
|
else
|
|
{
|
|
if( !pGameObject->IsLocalPlayer() )
|
|
{
|
|
if( pGameObject->GetStateFlag() & SGameAvatarEx::FLAG_STATE_HIDING )
|
|
{
|
|
if( m_pGame->IsPartyRaidMemeber( pGameObject->GetArID() ) )
|
|
pGameObject->SetHidingVisiblity( HIDING_VISIBILITY_RATE_PARTY_RAID ); //파티원이나 레이드원이면
|
|
else
|
|
{
|
|
pGameObject->SetHidingVisiblity( 0.0f );
|
|
DisplayNamePanel( pGameObject );
|
|
pGameObject = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( pGameObject )
|
|
{
|
|
DisplayNamePanel( pGameObject );
|
|
pGameObject->Render( uRenderBitVector, ppViewportList, nViewportCount );
|
|
}
|
|
}
|
|
++it;
|
|
}
|
|
}
|
|
|
|
if( m_hMouseOverItem )
|
|
{
|
|
pGameObject = GetAvatar( m_hMouseOverItem );
|
|
if( pGameObject ) DisplayNamePanel( pGameObject );
|
|
}
|
|
}
|
|
|
|
if( uRenderBitVector & Game_RenderAction )
|
|
{
|
|
if (m_pActionMgr) m_pActionMgr->Render( uRenderBitVector, ppViewportList, nViewportCount );
|
|
}
|
|
|
|
if( uRenderBitVector & Game_RenderEffect )
|
|
{
|
|
m_pOtherEffecMgr->Render( uRenderBitVector, ppViewportList, nViewportCount );
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::DisplayNamePanel( SGameAvatarEx* pAvatar )
|
|
{
|
|
/// 2011.08.17 필드 프랍 체크 제거 - prodongi
|
|
if( pAvatar->GetObjType() == TS_ENTER::GAME_SKILL_PROP )
|
|
return;
|
|
|
|
if( !pAvatar->IsLoadComplete() )
|
|
return;
|
|
|
|
//내 플레이어 예외 처리
|
|
SIMSG_UI_2DPOS_INFO msg;
|
|
static K3DVector mypos, mypos_ori, mypos_middle, _2Dpos, _2Dpos_ori, _2Dpos_middle;
|
|
|
|
mypos = *pAvatar->GetPosition();
|
|
mypos_ori = *pAvatar->GetPosition();
|
|
mypos_middle = *pAvatar->GetPosition();
|
|
msg.bVisible = true;
|
|
msg.bNotClip = true;
|
|
msg.bUse = false;
|
|
msg.nObjType = pAvatar->GetObjType();
|
|
|
|
//플레이어가 마운트 모드일경우
|
|
if( pAvatar->IsMountMode() )
|
|
{
|
|
SGameAvatarEx* pCreature = (SGameAvatarEx*)GetObject( pAvatar->GetCreatureMountHandle() );
|
|
if( pCreature == NULL ) pCreature = GetTransportCreatureObject( pAvatar->GetCreatureMountHandle() );
|
|
|
|
if( pCreature )
|
|
{
|
|
mypos = *pCreature->GetPosition();
|
|
mypos_ori = *pCreature->GetPosition();
|
|
mypos_middle = *pCreature->GetPosition();
|
|
}
|
|
|
|
mypos.z += HEAD_DEF_TOP;
|
|
mypos_middle.z += HEAD_DEF_TOP/2.f;
|
|
}
|
|
else if( pAvatar->GetStatus() & TS_ENTER::PlayerInfo::FLAG_SITDOWN && pAvatar->GetCurrAnimationID() == ANI_SIT )
|
|
{
|
|
mypos.z += HEAD_DEF_HALF;
|
|
mypos_middle.z += HEAD_DEF_HALF/2.f;
|
|
}
|
|
else
|
|
{
|
|
const float* selectCube = pAvatar->GetSelectCube();
|
|
float zHeight;
|
|
|
|
if( pAvatar->GetObjType() == TS_ENTER::GAME_MOB )
|
|
{
|
|
zHeight = selectCube[ 5 ] * pAvatar->GetScale() + HEAD_GAP_MOB;
|
|
}
|
|
else if( pAvatar->GetObjType() == TS_ENTER::GAME_PET )
|
|
{
|
|
zHeight = selectCube[ 5 ] * pAvatar->GetScale() + HEAD_GAP_PET;
|
|
}
|
|
else if( pAvatar->GetObjType() == TS_ENTER::GAME_ITEM )
|
|
{
|
|
zHeight = selectCube[ 5 ] * pAvatar->GetScale() + HEAD_GAP_ITEM;
|
|
}
|
|
else
|
|
{
|
|
zHeight = selectCube[ 5 ] * pAvatar->GetScale() + HEAD_GAP_AVATAR;
|
|
}
|
|
mypos.z += zHeight;
|
|
mypos_middle.z += zHeight / 2.f;
|
|
}
|
|
|
|
msg.fCamDistance = GetDistance( m_pGame->GetCamera()->GetCamPos(), mypos );
|
|
|
|
m_pGame->Get2DPos( mypos_ori , _2Dpos_ori );
|
|
m_pGame->Get2DPos( mypos , _2Dpos );
|
|
m_pGame->Get2DPos( mypos_middle, _2Dpos_middle );
|
|
msg.handle = pAvatar->GetArID();
|
|
msg.bVisible = pAvatar->IsRender();
|
|
msg.bNotClip = pAvatar->IsRender();
|
|
msg.nX = _2Dpos.x;
|
|
msg.nY = _2Dpos.y;
|
|
msg.nX_middle = _2Dpos_middle.x;
|
|
msg.nY_middle = _2Dpos_middle.y;
|
|
msg.nX_bottom = _2Dpos_ori.x;
|
|
msg.nY_bottom = _2Dpos_ori.y;
|
|
msg.nReal_X = mypos.x;
|
|
msg.nReal_Y = mypos.y;
|
|
msg.fAlpha = 1.f;
|
|
msg.fCamDistance = GetDistance( m_pGame->GetCamera()->GetCamPos(), mypos );
|
|
|
|
if( pAvatar->GetObjType() != TS_ENTER::GAME_ITEM )
|
|
{
|
|
if( !pAvatar->IsLocalPlayer() )
|
|
{
|
|
float fLen = GetDistance( m_pGame->GetCamera()->GetTargetPos(), mypos );
|
|
//이름 판넬 컬링
|
|
if( fLen < VIEW_NAME_PLATE_CULL_SIZE )
|
|
msg.fAlpha = GetNameAlpha( fLen );
|
|
else
|
|
msg.bVisible = false;
|
|
}
|
|
}
|
|
|
|
if( pAvatar->GetObjType() == TS_ENTER::GAME_PLAYER )
|
|
{
|
|
if( pAvatar->IsLocalPlayer() )
|
|
{
|
|
SGameAvatarEx* pCreature = (SGameAvatarEx*)GetObject( pAvatar->GetCreatureMountHandle() );
|
|
if( pCreature == NULL ) pCreature = GetTransportCreatureObject( pAvatar->GetCreatureMountHandle() );
|
|
if( pCreature )
|
|
{
|
|
msg.fRadian = GetViewRadian( pCreature->GetNextPos(), mypos );
|
|
}
|
|
else
|
|
msg.fRadian = GetViewRadian( pAvatar->GetNextPos(), mypos );
|
|
|
|
msg.nObjType = SIMSG_UI_2DPOS_INFO::TY_MY;
|
|
}
|
|
else
|
|
msg.nObjType = SIMSG_UI_2DPOS_INFO::TY_PLAYER;
|
|
}
|
|
else if( pAvatar->GetObjType() == TS_ENTER::GAME_NPC )
|
|
msg.nObjType = SIMSG_UI_2DPOS_INFO::TY_NPC;
|
|
else if( pAvatar->GetObjType() == TS_ENTER::GAME_MOB )
|
|
msg.nObjType = SIMSG_UI_2DPOS_INFO::TY_MOB;
|
|
else if( pAvatar->GetObjType() == TS_ENTER::GAME_SUMMON )
|
|
{
|
|
//크리처가 마운트 모드일경우 이름 숨기자
|
|
if( pAvatar->IsMountMode() )
|
|
{
|
|
msg.bVisible = false;
|
|
msg.bNotClip = false;
|
|
}
|
|
msg.nObjType = SIMSG_UI_2DPOS_INFO::TY_CREATURE;
|
|
}
|
|
else if( pAvatar->GetObjType() == TS_ENTER::GAME_PET )
|
|
msg.nObjType = SIMSG_UI_2DPOS_INFO::TY_PET;
|
|
else if( pAvatar->GetObjType() == TS_ENTER::GAME_ITEM )
|
|
msg.nObjType = SIMSG_UI_2DPOS_INFO::TY_ITEM;
|
|
|
|
m_pGame->ProcMsgAtStatic( &msg );
|
|
}
|
|
|
|
void SCommandSystem::SetPlayerAndCreaturePosition( SMSG_UNMOUNT_SUMMON* pMsg )
|
|
{
|
|
SGameAvatarEx* pLocalPlayer = GetLocalPlayer();
|
|
|
|
ArPosition arPlayerPos;
|
|
arPlayerPos.x = pLocalPlayer->GetPosition()->x;
|
|
arPlayerPos.y = pLocalPlayer->GetPosition()->y;
|
|
m_pGame->ReqMove( pLocalPlayer->GetArID(), arPlayerPos, &arPlayerPos, 1, false );
|
|
|
|
SGameAvatarEx* pLocalCreature = GetLocalCreature( pMsg->summon_handle );
|
|
|
|
ArPosition arCreturePos;
|
|
arCreturePos.x = pLocalCreature->GetPosition()->x;
|
|
arCreturePos.y = pLocalCreature->GetPosition()->y;
|
|
m_pGame->ReqMove( pLocalCreature->GetArID(), arCreturePos, &arCreturePos, 1, false );
|
|
}
|
|
|
|
bool SCommandSystem::IsActivated()
|
|
{
|
|
SGameAvatarEx* pGameObject = NULL;
|
|
KSortVector< class SGameAvatarEx* >::iterator it = m_svObject.begin();
|
|
while ( it != m_svObject.end() )
|
|
{
|
|
pGameObject = (*it);
|
|
if ( pGameObject != NULL && pGameObject->IsActivated() == false )
|
|
{
|
|
if( pGameObject->IsPendLoading() == false ) //true면 옵션에서 타인 렌더가 꺼진 상태
|
|
return false;
|
|
}
|
|
|
|
++it;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//Leave List 삭제
|
|
void SCommandSystem::SetArrangeObject()
|
|
{
|
|
DWORD dwTime = GetSafeTickCount();
|
|
|
|
SGameAvatarExTag* pAvatarTag = NULL;
|
|
SGameAvatarEx* pObject = NULL;
|
|
|
|
std::vector< AR_HANDLE > vDeleteList;
|
|
|
|
bool res = m_hashLeaveList.get_first_value( pAvatarTag );
|
|
while ( res )
|
|
{
|
|
pObject = NULL;
|
|
|
|
if( pAvatarTag != NULL )
|
|
{
|
|
pObject = pAvatarTag->ptr;
|
|
|
|
// 일단 30초 이상 지난 애들만 지우도록 땜방.... by Testors
|
|
// NPC만 3분으로 늘리고 그외 것들은 바로 삭제 by metarrgear
|
|
//GAME_PLAYER = 0, GAME_NPC = 1, GAME_ITEM = 2, GAME_MOB = 3, GAME_SUMMON = 4, GAME_SKILL_PROP = 5, GAME_FIELD_PROP = 6,
|
|
bool bLeave = true;
|
|
if( pObject->GetObjType() == TS_ENTER::GAME_NPC )
|
|
{
|
|
bLeave = false;
|
|
}
|
|
|
|
if( pObject->IsLoadComplete() && ( bLeave || pAvatarTag->bNotUse ||
|
|
pAvatarTag->dwTime + OBJ_LEAVE_TIME < dwTime ) )
|
|
{
|
|
//성공
|
|
}
|
|
else if( pObject->IsPendLoading() )
|
|
{
|
|
//PendLoading() 중이면 바로 삭제
|
|
}
|
|
else
|
|
{
|
|
pObject = NULL;
|
|
}
|
|
}
|
|
|
|
if( pObject != NULL )
|
|
{
|
|
vDeleteList.push_back( pObject->GetArID() );
|
|
}
|
|
|
|
res = m_hashLeaveList.get_next_value( pAvatarTag );
|
|
}
|
|
|
|
pAvatarTag = NULL;
|
|
|
|
std::vector< AR_HANDLE >::iterator iter = vDeleteList.begin();
|
|
for( ; iter != vDeleteList.end(); ++iter )
|
|
{
|
|
if( m_hashLeaveList.lookup( *iter, pAvatarTag ) )
|
|
{
|
|
SAFE_DELETE( pAvatarTag->ptr );
|
|
SAFE_DELETE( pAvatarTag );
|
|
}
|
|
|
|
m_hashLeaveList.erase( *iter );
|
|
}
|
|
|
|
vDeleteList.clear();
|
|
}
|
|
|
|
void SCommandSystem::SetHeight()
|
|
{
|
|
SGameAvatarEx* pGameObject = NULL;
|
|
KSortVector< class SGameAvatarEx* >::iterator it = m_svObject.begin();
|
|
while ( it != m_svObject.end() )
|
|
{
|
|
pGameObject = (*it);
|
|
if ( pGameObject != NULL )
|
|
{
|
|
K3DVector mypos = *pGameObject->GetPosition();
|
|
WORD wTile=0;
|
|
m_pGame->GetHeight(mypos.x, mypos.y, mypos.z,wTile);
|
|
pGameObject->SetPosition( mypos );
|
|
}
|
|
it++;
|
|
}
|
|
}
|
|
|
|
float SCommandSystem::GetNameAlpha( float fLen )
|
|
{
|
|
if( fLen > (20*12) ) //20m 이상일 경우
|
|
{
|
|
float fAlpha = (1.5f-(fLen/(40*12)));
|
|
return fAlpha;
|
|
}
|
|
|
|
//20m 이하 인 경우
|
|
|
|
//// 20% 범위에 걸치면 알파 먹임
|
|
//if( fLen > ( VIEW_NAME_PLATE_CULL_SIZE * 0.9f ) )
|
|
//{
|
|
// float fAlpha = ( VIEW_NAME_PLATE_CULL_SIZE - fLen ) / ( VIEW_NAME_PLATE_CULL_SIZE * 0.1f );
|
|
// return fAlpha;
|
|
//}
|
|
return 1.f;
|
|
}
|
|
|
|
void SCommandSystem::Process( DWORD dwTime )
|
|
{
|
|
if( m_dwTime == dwTime ) return;
|
|
|
|
/// 2010.11.10 - prodongi
|
|
//#ifdef _DEV
|
|
// extern bool g_bDebugMode;
|
|
//#endif
|
|
|
|
m_dwTime = dwTime;
|
|
|
|
// 이전 프레임의 LeaveList를 정리
|
|
if( m_dwTime - m_dwCheckTime > 41 )
|
|
{
|
|
m_dwCheckTime = m_dwTime;
|
|
SetArrangeObject();
|
|
|
|
// 라이딩 안된것들 찾자
|
|
FindRidingObject();
|
|
}
|
|
|
|
// if( m_dwTime == 0 ) m_dwTime = dwTime;
|
|
if( m_dwLocalCreaturePrcessTime == 0 ) m_dwLocalCreaturePrcessTime = dwTime;
|
|
// if( m_dwCheckTime == 0 ) m_dwCheckTime = m_dwTime;
|
|
|
|
K3DVector mypos, _2Dpos;
|
|
K3DMatrix mat;
|
|
K3DMatrixIdentity(mat);
|
|
KMsgGET_BONEMATRIX2 bonemsg;
|
|
bonemsg.nDetailIndex = DETAIL_HEAD;
|
|
|
|
K3DCamera* pCamera = m_pGame->GetCamera();
|
|
SGameViewPort* pViewport = m_pGame->GetViewPort();
|
|
|
|
//Position 및 view Frustum cull
|
|
K3DVertex vtCameraTarget;
|
|
pCamera->GetTargetPos( vtCameraTarget.x, vtCameraTarget.y, vtCameraTarget.z );
|
|
K3DVector * pFrustum = pViewport->GetFrustum();
|
|
|
|
K3DVector cullPosition;
|
|
float fLen = 0.f;
|
|
|
|
//Local 은 먼저 처리
|
|
SGameAvatarEx* pGameObject = NULL;
|
|
SGameAvatarEx* pLocalObject = NULL;
|
|
|
|
if( m_hashObject.lookup( m_LocalHandle, pGameObject ) )
|
|
{
|
|
pLocalObject = pGameObject;
|
|
|
|
pGameObject->Process( dwTime );
|
|
|
|
pGameObject->SetShadowRenderFlag( true ); //우선 내것을 그림자 그림
|
|
|
|
mypos = *pGameObject->GetPosition();
|
|
|
|
cullPosition = mypos;
|
|
|
|
if( m_LocalHandle == pGameObject->GetArID() )
|
|
{
|
|
/// 2010.11.10 - prodongi
|
|
//#ifdef _DEV
|
|
if (g_UserInfo.isMonkeyTail())
|
|
{
|
|
extern bool g_bDebugMode;
|
|
if( g_bDebugMode && ( GetKeyState( VK_SCROLL ) & 0x01 ) )
|
|
{
|
|
K3DVector myLocal;
|
|
K3DVector myCreature;
|
|
K3DVector newpos;
|
|
|
|
myLocal = mypos;
|
|
if( m_vLocalCreature.empty() )
|
|
{
|
|
if( (dwTime - m_dwLocalCreaturePrcessTime) >= 100 )
|
|
{
|
|
SIMSG_UI_ETC_INFO etcmsg;
|
|
etcmsg.fps = g_dwFPS;
|
|
KDeviceManager::GetDeviceManager()->GetRenderDevice()->GetVGAMem( etcmsg.dwFree, etcmsg.dwTotal );
|
|
|
|
m_pGame->CorrectivePosition( myLocal, newpos );
|
|
etcmsg.x = newpos.x;
|
|
etcmsg.y = newpos.y;
|
|
etcmsg.z = newpos.z;
|
|
etcmsg.cx = 0;
|
|
etcmsg.cy = 0;
|
|
etcmsg.cz = 0;
|
|
|
|
m_pGame->SendGameInterfaceMsg( &etcmsg );
|
|
m_dwLocalCreaturePrcessTime = dwTime;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//#endif
|
|
}
|
|
}
|
|
|
|
pGameObject = NULL;
|
|
|
|
// { 노점 처리용
|
|
std::vector< AR_HANDLE > vBoothNameRequestList;
|
|
bool bNeedBoothProc = false;
|
|
if( m_pPrevBoothProcTime + BOOTH_CHECK_INTERVAL < dwTime )
|
|
{
|
|
bNeedBoothProc = true;
|
|
m_pPrevBoothProcTime = dwTime;
|
|
}
|
|
// }
|
|
|
|
bool bEvScene = ( m_pGame->GetGameRef() == SGame::STAGE_EVENT_SCENE ) ? true : false;
|
|
|
|
KSortVector< class SGameAvatarEx* >::iterator it = m_svObject.begin();
|
|
while ( it != m_svObject.end() )
|
|
{
|
|
pGameObject = (*it); ++it;
|
|
|
|
if( pGameObject == NULL || m_LocalHandle == pGameObject->GetArID() ) continue;
|
|
|
|
pGameObject->Process( dwTime );
|
|
pGameObject->SetShadowRenderFlag( true ); //우선 내것을 그림자 그림
|
|
|
|
if( bEvScene )
|
|
{
|
|
pGameObject->SetVisible(true);
|
|
pGameObject->ClipTest( pFrustum );
|
|
pGameObject->SetShadowRenderFlag( true );
|
|
}
|
|
else
|
|
{
|
|
mypos = *pGameObject->GetPosition();
|
|
|
|
float fCamTargetDist = GetDistance( pCamera->GetTargetPos(), mypos );
|
|
|
|
if(fCamTargetDist < m_fAvatarVisRange)
|
|
{
|
|
pGameObject->SetVisible(true);
|
|
|
|
//Vérifiez uniquement ce qui est visible
|
|
pGameObject->ClipTest( pFrustum );
|
|
}
|
|
else
|
|
{
|
|
pGameObject->SetVisible(false);
|
|
}
|
|
|
|
//시야에 안보이는것들은 프러스텀 검사를 안해도 될듯
|
|
// pGameObject->ClipTest( pFrustum );
|
|
|
|
fLen = GetDistance( cullPosition, mypos );
|
|
//그림자 컬링
|
|
if( fLen < SHADOW_RENDER_MAX_LEN )
|
|
{
|
|
pGameObject->SetShadowRenderFlag( true );
|
|
}
|
|
else
|
|
{
|
|
pGameObject->SetShadowRenderFlag( false );
|
|
}
|
|
}
|
|
|
|
// 노점 이름 요청 리스트 수집
|
|
if( bNeedBoothProc && pGameObject->GetObjType() == TS_ENTER::GAME_PLAYER )
|
|
{
|
|
if( static_cast< SGameOtherPlayer* >( pGameObject )->IsNeedBoothName( dwTime ) ) vBoothNameRequestList.push_back( pGameObject->GetArID() );
|
|
}
|
|
}
|
|
|
|
it = m_svTransportCreatureObject.begin();
|
|
while( it != m_svTransportCreatureObject.end() )
|
|
{
|
|
pGameObject = (*it);
|
|
|
|
pGameObject->Process( dwTime );
|
|
pGameObject->SetShadowRenderFlag( true ); //우선 내것을 그림자 그림
|
|
|
|
if( bEvScene )
|
|
{
|
|
pGameObject->SetVisible(true);
|
|
pGameObject->ClipTest( pFrustum ); //시야에 보이는것들만 체크
|
|
pGameObject->SetShadowRenderFlag( true );
|
|
}
|
|
else
|
|
{
|
|
mypos = *pGameObject->GetPosition();
|
|
|
|
float fCamTargetDist = GetDistance( pCamera->GetTargetPos(), mypos );
|
|
|
|
if(fCamTargetDist < m_fAvatarVisRange)
|
|
{
|
|
pGameObject->SetVisible(true);
|
|
pGameObject->ClipTest( pFrustum ); //시야에 보이는것들만 체크
|
|
}
|
|
else
|
|
pGameObject->SetVisible(false);
|
|
|
|
fLen = GetDistance( cullPosition, mypos );
|
|
if( fLen < SHADOW_RENDER_MAX_LEN ) //그림자 컬링
|
|
pGameObject->SetShadowRenderFlag( true );
|
|
else
|
|
pGameObject->SetShadowRenderFlag( false );
|
|
}
|
|
|
|
++it;
|
|
}
|
|
|
|
// { 노점 이름 요청
|
|
if( !vBoothNameRequestList.empty() )
|
|
{
|
|
SMSG_REQUEST_BOOTH_NAME msg;
|
|
msg.pvBoothList = &vBoothNameRequestList;
|
|
m_pGame->ProcMsgAtStatic( &msg );
|
|
}
|
|
vBoothNameRequestList.clear();
|
|
// }
|
|
|
|
if (m_pActionMgr) m_pActionMgr->Process( dwTime );
|
|
|
|
m_pOtherEffecMgr->Process( dwTime );
|
|
|
|
|
|
//선공몬스터 인식속도 관련. 0.3초마다 한번씩 체크해서 서버로 보낼 것... 2010.01.06 sfreer
|
|
static AR_TIME nLastGameGradeText = 0;
|
|
AR_TIME nCurArTime = GetArTime();
|
|
|
|
if(pLocalObject && (nLastGameGradeText == 0 || 30<= (nCurArTime - nLastGameGradeText) ) )
|
|
//if(false)
|
|
{
|
|
nLastGameGradeText = nCurArTime;
|
|
SGameAvatarEx* pGameObject = NULL;
|
|
KSortVector< class SGameAvatarEx* >::iterator it = m_svOtherObject.begin();
|
|
while ( it != m_svOtherObject.end() )
|
|
{
|
|
pGameObject = (*it);
|
|
if ( pGameObject != NULL /*&& pGameObject->IsLocalPlayer()*/ )
|
|
{
|
|
if(pGameObject->GetObjType() == TS_ENTER::GAME_MOB )
|
|
{
|
|
_MONSTER_INFO_FILE* pMob = GetMonsterDB().GetMonsterData( pGameObject->GetContentID() );
|
|
|
|
if(pMob)
|
|
{
|
|
bool bInsertData = true;
|
|
|
|
for( KSortVector< class SGameAvatarEx* >::iterator it2= m_svRecongnizeMobObject.begin() ; it2 != m_svRecongnizeMobObject.end() ; it2++)
|
|
{
|
|
if( (*it2) == pGameObject )
|
|
{
|
|
bInsertData = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
bool bInArea = false;
|
|
AR_HANDLE checkhandle = NULL;
|
|
|
|
float dx = pLocalObject->GetPosition()->x - pGameObject->GetPosition()->x;
|
|
float dy = pLocalObject->GetPosition()->y - pGameObject->GetPosition()->y;
|
|
int dis = sqrt( (float) dx*dx + dy*dy );
|
|
|
|
if( pMob->visible_range*GameRule::DEFAULT_UNIT_SIZE >= dis && !(pLocalObject->GetStateFlag() & SGameAvatarEx::FLAG_STATE_HIDING) )
|
|
{
|
|
bInArea = true;
|
|
checkhandle = m_LocalHandle;
|
|
}
|
|
|
|
if(!bInArea)
|
|
{
|
|
KHash< SGameAvatarEx *, hashPr_mod_basic<AR_HANDLE> >::node* _node = NULL;
|
|
bool bResult = m_hashObject.get_first_node( _node );
|
|
while ( bResult )
|
|
{
|
|
if(_node->value->IsLocalCreature())
|
|
{
|
|
float dx = _node->value->GetPosition()->x - pGameObject->GetPosition()->x;
|
|
float dy = _node->value->GetPosition()->y - pGameObject->GetPosition()->y;
|
|
int dis = sqrt( (float) dx*dx + dy*dy );
|
|
|
|
if( pMob->visible_range*GameRule::DEFAULT_UNIT_SIZE/2 >= dis )
|
|
{
|
|
bInArea = true;
|
|
checkhandle = _node->key;
|
|
break;
|
|
}
|
|
}
|
|
bResult = m_hashObject.get_next_node( _node );
|
|
}
|
|
}
|
|
|
|
|
|
if( bInArea ) //pMob->visible_range*GameRule::DEFAULT_UNIT_SIZE >= dis )
|
|
{
|
|
if(bInsertData)
|
|
{
|
|
AR_HANDLE handle = 0;
|
|
KHash< SGameAvatarEx *, hashPr_mod_basic<AR_HANDLE> >::node* _node = NULL;
|
|
bool bResult = m_hashObject.get_first_node( _node );
|
|
while ( bResult )
|
|
{
|
|
if(_node->value == pGameObject)
|
|
{
|
|
handle = _node->key;
|
|
break;
|
|
}
|
|
bResult = m_hashObject.get_next_node( _node );
|
|
}
|
|
//메시지를 보내라.
|
|
|
|
_oprint("몬스터인지패킷 %d, %s\n",handle, GetStringDB().GetString(pMob->name_id));
|
|
if(handle>0)
|
|
{
|
|
TS_CS_MONSTER_RECOGNIZE _msg;
|
|
_msg.handle = handle;
|
|
_msg.recognizer_handle = checkhandle;
|
|
m_pGame->SendMsg( &_msg );
|
|
|
|
m_svRecongnizeMobObject.insert( pGameObject );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(!bInsertData)
|
|
{
|
|
m_svRecongnizeMobObject.erase( pGameObject );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
++it;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
SGameAvatarEx * SCommandSystem::GetLocalPlayer()
|
|
{
|
|
SGameAvatarEx * pLocal = NULL;
|
|
if( m_hashObject.lookup( m_LocalHandle, pLocal ) )
|
|
{
|
|
return pLocal;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
SGameAvatarEx * SCommandSystem::GetLocalCreature( AR_HANDLE objHandle )
|
|
{
|
|
//내 소환수 리스트
|
|
SGameAvatarEx * pLocalCreature = NULL;
|
|
if( m_hashObject.lookup( objHandle, pLocalCreature ) )
|
|
{
|
|
return pLocalCreature;
|
|
}
|
|
|
|
return NULL;
|
|
};
|
|
|
|
//===================================================================================================
|
|
//Enter Object
|
|
void SCommandSystem::InsertAvatarEX(AR_HANDLE handle, class SGameAvatarEx* pAvatar, bool bIsTransportCreature )
|
|
{
|
|
if( bIsTransportCreature )
|
|
{
|
|
m_hashTransportCreatureObject.add( handle, pAvatar );
|
|
m_svTransportCreatureObject.insert( pAvatar );
|
|
}
|
|
else
|
|
{
|
|
m_hashObject.add(handle, pAvatar);
|
|
m_svObject.insert( pAvatar );
|
|
}
|
|
|
|
if(m_bCircleShadowEnable)
|
|
pAvatar->ActivateCircleShadow();
|
|
}
|
|
|
|
void SCommandSystem::DeleteAvatar(AR_HANDLE handle) // 2011.03.10 - servantes
|
|
{
|
|
SGameAvatarEx* pAvatar = NULL;
|
|
if( m_hashObject.lookup( handle, pAvatar ) )
|
|
{
|
|
m_hashObject.erase(handle);
|
|
m_svObject.erase( pAvatar );
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::InsertPendLoading( SGameAvatarEx* pAvatar )
|
|
{
|
|
if( pAvatar == NULL ) return;
|
|
|
|
bool bLoadingNow = true;
|
|
if( g_bRenderPlayerObj )
|
|
{
|
|
//마을 안 다른 플레이어 표시 OFF
|
|
if( GetGameOption().GetRenderOtherPlayerType() == 0 )
|
|
{
|
|
//마을안에 있다
|
|
if( m_pGame->PlayerInTown( pAvatar ) )
|
|
{
|
|
bLoadingNow = false;
|
|
}
|
|
}
|
|
|
|
if( bLoadingNow )
|
|
{
|
|
pAvatar->PendLoading();
|
|
return;
|
|
}
|
|
}
|
|
|
|
SGameAvatarEx* pFindAvatar = NULL;
|
|
if( m_hashPendingObjList.lookup( pAvatar->GetArID(), pFindAvatar ) )
|
|
{
|
|
assert( false && "웨 여기 들어오냐" );
|
|
}
|
|
else
|
|
{
|
|
m_hashPendingObjList.add( pAvatar->GetArID(), pAvatar );
|
|
pAvatar->SetPendLoading( true );
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::ActivatePendLoadingListByMove( SGameAvatarEx* pAvatar )
|
|
{
|
|
if( pAvatar == NULL || g_bRenderPlayerObj == false ) return;
|
|
|
|
if( pAvatar->IsPendLoading() )
|
|
{
|
|
pAvatar->SetPendLoading( false );
|
|
}
|
|
|
|
SGameAvatarEx* pPendAvatar = NULL;
|
|
if( m_hashPendingObjList.lookup( pAvatar->GetArID(), pPendAvatar ) )
|
|
{
|
|
pAvatar->PendLoading();
|
|
RefreshStateEffect( pAvatar );
|
|
|
|
m_hashPendingObjList.erase( pAvatar->GetArID() );
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::ActivatePendLoadingList( int nRender, bool bGetOutTown )
|
|
{
|
|
if( nRender )
|
|
{
|
|
g_bRenderPlayerObj = true;
|
|
}
|
|
else
|
|
{
|
|
g_bRenderPlayerObj = false;
|
|
}
|
|
|
|
if( g_bRenderPlayerObj )
|
|
{
|
|
std::vector< AR_HANDLE > vDeleteList;
|
|
|
|
SMSG_STATE state;
|
|
|
|
SGameAvatarEx* pAvatar = NULL;
|
|
bool res = m_hashPendingObjList.get_first_value( pAvatar );
|
|
while ( res )
|
|
{
|
|
if ( pAvatar != NULL )
|
|
{
|
|
if( bGetOutTown && m_pGame->PlayerInTown( pAvatar ) )
|
|
{
|
|
//마을 안에 있다
|
|
}
|
|
else
|
|
{
|
|
pAvatar->SetPendLoading( false );
|
|
pAvatar->PendLoading();
|
|
|
|
vDeleteList.push_back( pAvatar->GetArID() );
|
|
}
|
|
}
|
|
res = m_hashPendingObjList.get_next_value( pAvatar );
|
|
}
|
|
|
|
pAvatar = NULL;
|
|
std::vector< AR_HANDLE >::iterator iter = vDeleteList.begin();
|
|
for( ; iter != vDeleteList.end(); ++iter )
|
|
{
|
|
if( m_hashPendingObjList.lookup( (*iter), pAvatar ) )
|
|
{
|
|
m_hashPendingObjList.erase( (*iter) );
|
|
}
|
|
}
|
|
|
|
vDeleteList.clear();
|
|
|
|
KSortVector< class SGameAvatarEx* >::iterator itObj = m_svObject.begin();
|
|
while( itObj != m_svObject.end() )
|
|
{
|
|
pAvatar = (*itObj);
|
|
++itObj;
|
|
|
|
if( pAvatar->IsLocalPlayer() || pAvatar->IsLocalCreature() )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
unsigned char nObjType = pAvatar->GetObjType();
|
|
if( nObjType == TS_ENTER::GAME_PLAYER ||
|
|
nObjType == TS_ENTER::GAME_SUMMON ||
|
|
nObjType == TS_ENTER::GAME_PET )
|
|
{
|
|
if( bGetOutTown && m_pGame->PlayerInTown( pAvatar ) )
|
|
{
|
|
//마을 안에 있다
|
|
}
|
|
else
|
|
{
|
|
pAvatar->SetPendLoading( false );
|
|
RefreshStateEffect( pAvatar );
|
|
}
|
|
}
|
|
}
|
|
|
|
itObj = m_svTransportCreatureObject.begin();
|
|
while( itObj != m_svTransportCreatureObject.end() )
|
|
{
|
|
pAvatar = (*itObj);
|
|
++itObj;
|
|
|
|
if( pAvatar->IsLocalCreature() == false )
|
|
{
|
|
if( bGetOutTown && m_pGame->PlayerInTown( pAvatar ))
|
|
{
|
|
}
|
|
else
|
|
{
|
|
pAvatar->SetPendLoading( false );
|
|
RefreshStateEffect( pAvatar );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SGameAvatarEx* pAvatar = NULL;
|
|
|
|
KSortVector< class SGameAvatarEx* >::iterator itObj = m_svObject.begin();
|
|
while( itObj != m_svObject.end() )
|
|
{
|
|
pAvatar = (*itObj);
|
|
++itObj;
|
|
|
|
if( pAvatar->IsLocalPlayer() || pAvatar->IsLocalCreature() || pAvatar->IsLocalPet() ) // sonador #2.3.1.13
|
|
{
|
|
continue;
|
|
}
|
|
|
|
unsigned char nObjType = pAvatar->GetObjType();
|
|
if( nObjType == TS_ENTER::GAME_PLAYER ||
|
|
nObjType == TS_ENTER::GAME_SUMMON ||
|
|
nObjType == TS_ENTER::GAME_PET )
|
|
{
|
|
pAvatar->SetPendLoading( true );
|
|
pAvatar->RemoveAllStateEffect();
|
|
}
|
|
}
|
|
|
|
itObj = m_svTransportCreatureObject.begin();
|
|
while( itObj != m_svTransportCreatureObject.end() )
|
|
{
|
|
if( (*itObj)->IsLocalCreature() == false )
|
|
{
|
|
(*itObj)->SetPendLoading( true );
|
|
}
|
|
++itObj;
|
|
}
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::AddPlayer( SMSG_ENTER* pMsg )
|
|
{
|
|
SMSG_ENTER::PlayerInfo * pPlayerInfo = (SMSG_ENTER::PlayerInfo *)(pMsg+1);
|
|
|
|
SGameOtherPlayer* pAvatar = new SGameOtherPlayer;
|
|
|
|
SMSG_STATUS_CHANGE status_change;
|
|
status_change.handle = pMsg->handle;
|
|
status_change.status = pPlayerInfo->status;
|
|
|
|
pAvatar->OnNetInput( &status_change );
|
|
|
|
pAvatar->ProcMsgAtStatic( pMsg );
|
|
|
|
pAvatar->Initialize( m_pRenderDevice );
|
|
|
|
pAvatar->SetMessageHandler( m_pGame );
|
|
pAvatar->SetArID( pMsg->handle );
|
|
|
|
pAvatar->GetArObject().type = pMsg->type;
|
|
pAvatar->GetArObject().mv.face = pPlayerInfo->face_direction;
|
|
|
|
float fHeight = 0.f;
|
|
WORD wTile=0;
|
|
m_pGame->GetHeight( pMsg->x, pMsg->y, fHeight,wTile );
|
|
K3DVector pos( pMsg->x, pMsg->y, fHeight );
|
|
pAvatar->SetArObjectPos( pos.x, pos.y, pos.z, pMsg->layer );
|
|
|
|
pAvatar->SetPosition( pos );
|
|
// pAvatar->Activate(); 플레이어들은 아이템이 오면 업데이트 시킨다.
|
|
pAvatar->SetHP( pPlayerInfo->hp, true );
|
|
|
|
pAvatar->SetVisibility( 1.0f );
|
|
|
|
// 2010.05.20 - prodongi
|
|
pAvatar->setHideEquipInfo(pPlayerInfo->hideEquipFlag);
|
|
// 2010.06.18 - prodongi
|
|
pAvatar->setDecoIndex(pPlayerInfo->faceTextureId);
|
|
|
|
#ifdef _WEAPON_FX_
|
|
pAvatar->ActivateFxSwordSlash();
|
|
#endif
|
|
|
|
pAvatar->ActivateForceSphere();
|
|
|
|
if( pPlayerInfo->energy > 0 )
|
|
pAvatar->OnMsgForceSphere( pPlayerInfo->energy );
|
|
|
|
InsertAvatarEX(pMsg->handle,pAvatar);
|
|
|
|
m_svPlayerObject.insert( pAvatar );
|
|
|
|
m_pArObject->onEnter( &pAvatar->GetArObject() );
|
|
|
|
if( pPlayerInfo->ride_handle )
|
|
AddRidingObject( pMsg->handle, pPlayerInfo->ride_handle, true );
|
|
|
|
_oprint("About to set hair color rgb! Color is: %d; index is: %d\n", pPlayerInfo->hairColorRGB, pPlayerInfo->hairColorIndex);
|
|
//pAvatar->SetHairColorIndex(pPlayerInfo->hairColorIndex);
|
|
if (pPlayerInfo->hairColorRGB > 0)
|
|
{
|
|
pAvatar->SetHairColorRGB(pPlayerInfo->hairColorRGB);
|
|
pAvatar->SetHairColorIndex(0);
|
|
}
|
|
else
|
|
{
|
|
pAvatar->SetHairColorRGB(-16777216);
|
|
pAvatar->SetHairColorIndex(pPlayerInfo->hairColorIndex);
|
|
}
|
|
|
|
if( pPlayerInfo->skin_color != 0 )
|
|
{
|
|
// 2010.04.22 - prodongi
|
|
// pAvatar->SetSkinColorized( pPlayerInfo->skin_color, K3DTexture::COLORIZED_DEF, 0 );
|
|
pAvatar->SetSkinColorized( pPlayerInfo->skin_color, K3DTexture::COLORIZED_DEF, pPlayerInfo->hairColorRGB );
|
|
}
|
|
else
|
|
{
|
|
unsigned long color_value = GetSkinColorTable().GetColorValue( pPlayerInfo->race-GCLAN_GAIA, 0 );
|
|
pAvatar->SetSkinColorized( color_value, K3DTexture::COLORIZED_DEF, pPlayerInfo->hairColorRGB );
|
|
}
|
|
|
|
InsertPendLoading( pAvatar );
|
|
|
|
if( !m_FailAddCreatureList.empty() )
|
|
ResetFailAddCreature();
|
|
}
|
|
|
|
void SCommandSystem::AddNPC ( SMSG_ENTER* pMsg )
|
|
{
|
|
SMSG_ENTER::NPCInfo * pNpcInfo = (SMSG_ENTER::NPCInfo *)(pMsg+1);
|
|
|
|
bool bIsRecycle = true;
|
|
|
|
SGameNpc * pNpc = static_cast<SGameNpc*>( GetObjectFromLeaveList( pMsg->handle ) );
|
|
if( pNpc == NULL )
|
|
{
|
|
pNpc = new SGameNpc(pNpcInfo->npc_id);
|
|
bIsRecycle = false;
|
|
}
|
|
else
|
|
{
|
|
if( pNpc->GetInnContentID() != pNpcInfo->npc_id )
|
|
{
|
|
SAFE_DELETE( pNpc );
|
|
pNpc = new SGameNpc(pNpcInfo->npc_id);
|
|
bIsRecycle = false;
|
|
}
|
|
}
|
|
|
|
pNpc->SetObjType( pMsg->ObjType );
|
|
|
|
pNpc->Initialize( m_pRenderDevice );
|
|
|
|
pNpc->ProcMsgAtStatic( pMsg );
|
|
|
|
pNpc->SetMessageHandler( m_pGame );
|
|
pNpc->SetArID( pMsg->handle );
|
|
|
|
pNpc->GetArObject().type = pMsg->type;
|
|
pNpc->GetArObject().mv.face = pNpcInfo->face_direction;
|
|
|
|
float fHeight = 0.f;
|
|
WORD wTile=0;
|
|
m_pGame->GetHeight( pMsg->x, pMsg->y, fHeight,wTile );
|
|
K3DVector pos( pMsg->x, pMsg->y, fHeight );
|
|
pNpc->SetArObjectPos( pos.x, pos.y, pos.z, pMsg->layer );
|
|
|
|
pNpc->SetPosition( pos );
|
|
pNpc->Activate();
|
|
pNpc->SetHP( 10/*pNpcInfo->hp*/ );//, true );
|
|
|
|
pNpc->SetVisibility( 1.0f );
|
|
|
|
pNpc->SetViewVectorAngle( GetNpcResourceDB().GetDirection( pNpcInfo->npc_id ) );
|
|
|
|
pNpc->OnNetInput( pMsg ); //퀘스트 상태 처리
|
|
|
|
InsertAvatarEX(pMsg->handle,pNpc);
|
|
|
|
m_svOtherObject.insert( pNpc );
|
|
|
|
m_pArObject->onEnter( &pNpc->GetArObject() );
|
|
|
|
//
|
|
int nHairColorIndex = 0;
|
|
|
|
NpcResourceBase * pNpcResourceInfo = GetNpcResourceDB().GetNpcInfo(pNpcInfo->npc_id);
|
|
if (pNpcResourceInfo)
|
|
{
|
|
switch (pNpcResourceInfo->hair_id)
|
|
{
|
|
case 101:
|
|
case 103:
|
|
case 105:
|
|
nHairColorIndex = 1;
|
|
break;
|
|
case 102:
|
|
case 104:
|
|
case 106:
|
|
nHairColorIndex = 2;
|
|
break;
|
|
}
|
|
}
|
|
pNpc->SetHairColorIndex(nHairColorIndex);
|
|
|
|
//기본 값
|
|
unsigned long color_value = GetSkinColorTable().GetColorValue( 0, 0 );
|
|
pNpc->SetSkinColorized( color_value, K3DTexture::COLORIZED_DEF, 0 );
|
|
|
|
int nRace = pNpc->GetRace();
|
|
int nSex = pNpc->GetSex();
|
|
|
|
if( bIsRecycle == false )
|
|
{
|
|
NpcResourceBase* pNpcInfoDB = GetNpcResourceDB().GetNpcInfo( pNpcInfo->npc_id );
|
|
if( pNpcInfoDB && pNpcInfoDB->sexsual_id > 0 )
|
|
{
|
|
for( int j(0); ItemBase::MAX_ITEM_WEAR>j; ++j )
|
|
{
|
|
int nItemCode = GetNpcResourceDB().GetNpcItemCode( j, pNpcInfoDB );
|
|
pNpc->SetItemCodeLevel( j, nItemCode, 0 );
|
|
|
|
SGameAvatarEx::WEAR_DATA weardata;
|
|
|
|
if( nItemCode < 10000 ) //기본 Mesh
|
|
{
|
|
weardata.strFileName = GetDefaultItemDB().GetFileName( nRace, nSex, nItemCode );
|
|
weardata.nItemClass = 0;
|
|
weardata.nWearType = j;
|
|
weardata.nItemCode = 0;
|
|
weardata.nItemLevel = 0;
|
|
weardata.nItemEnhanceLevel = 0;
|
|
}
|
|
else
|
|
{
|
|
// NPC 투구 왜 안보이게 한걸까여?
|
|
// 일단 풀어 놓음
|
|
// 2009-07-23 : hunee
|
|
//if( j == ItemBase::WEAR_HELM )
|
|
// continue;
|
|
|
|
weardata.strFileName = GetItemDB().GetFileName( nRace, nSex, nItemCode, 0 );
|
|
weardata.strFileName += ".nx3";
|
|
weardata.nItemClass = GetItemDB().GetClassID( nItemCode );
|
|
weardata.nWearType = j;
|
|
weardata.nItemCode = nItemCode;
|
|
weardata.nItemLevel = 0;
|
|
weardata.nItemEnhanceLevel = 0;
|
|
}
|
|
|
|
if( weardata.strFileName.empty() == false )
|
|
{
|
|
if( strstr( weardata.strFileName.c_str(), "NotFoundFile" ) == NULL )
|
|
pNpc->AddThreadItemWear( weardata );
|
|
}
|
|
}
|
|
}
|
|
|
|
pNpc->PendLoading();
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::AddCreature ( SMSG_ENTER* pMsg )
|
|
{
|
|
//이미 소환된 크리처인가?
|
|
SMSG_ENTER::SummonInfo * pCreInfo = (SMSG_ENTER::SummonInfo *)(pMsg+1);
|
|
|
|
SGameAvatarEx * pAvatar = NULL;
|
|
|
|
struct DATA_CREATURE * pCreatureData = m_pGame->IsLocalCreature( pMsg->handle );
|
|
if( pCreatureData )
|
|
{
|
|
pAvatar = new SGameLocalCreature( pCreInfo->summon_code, pCreInfo->enhance );
|
|
pAvatar->SetLevel( pCreatureData->level );
|
|
|
|
UISendStringMessage(m_pGame->GetGameManager(), SIMSG_TOGGLE_UIWINDOW::UIWINDOW_DURABILITY, "refresh_durability");
|
|
}
|
|
else
|
|
{
|
|
pAvatar = new SGameOtherCreature( pCreInfo->summon_code, pCreInfo->enhance );
|
|
pAvatar->SetMaster( pCreInfo->master_handle, NULL );
|
|
}
|
|
|
|
pAvatar->SetName(pCreInfo->szName);
|
|
pAvatar->SetObjType( pMsg->ObjType );
|
|
|
|
pAvatar->ProcMsgAtStatic( pMsg );
|
|
|
|
pAvatar->Initialize( m_pRenderDevice );
|
|
|
|
pAvatar->SetMessageHandler( m_pGame );
|
|
pAvatar->SetArID( pMsg->handle );
|
|
|
|
pAvatar->GetArObject().type = pMsg->type;
|
|
pAvatar->GetArObject().mv.face = pCreInfo->face_direction;
|
|
|
|
float fHeight = 0.f;
|
|
WORD wTile=0;
|
|
m_pGame->GetHeight( pMsg->x, pMsg->y, fHeight,wTile);
|
|
K3DVector pos( pMsg->x, pMsg->y, fHeight );
|
|
pAvatar->SetArObjectPos( pos.x, pos.y, pos.z, pMsg->layer );
|
|
|
|
pAvatar->SetPosition( pos );
|
|
pAvatar->Activate();
|
|
pAvatar->SetHP( pCreInfo->hp, true );
|
|
|
|
pAvatar->SetCreatureMountType( GetCreatureDB().GetRidingMotionType( pCreInfo->summon_code ) );
|
|
|
|
pAvatar->ActivateForceSphere();
|
|
if( pCreInfo->energy > 0 )
|
|
pAvatar->OnMsgForceSphere( pCreInfo->energy );
|
|
|
|
if( GetCreatureDB().GetSlantType( pCreInfo->summon_code ) == 1 )
|
|
pAvatar->ActivateTerrainDegree();
|
|
|
|
InsertAvatarEX(pMsg->handle,pAvatar);
|
|
|
|
m_svOtherObject.insert( pAvatar );
|
|
|
|
/* SGameAvatarEx* pLocal = GetLocalPlayer();
|
|
|
|
//소환 이펙트 관련 처리 따로 따로 해줘야 한다.
|
|
if( pLocal && pCreInfo->is_first_enter )
|
|
{
|
|
int nMagicType = GetCreatureDB().GetMagicType( pCreInfo->summon_code );
|
|
std::string strEffect;
|
|
switch( nMagicType )
|
|
{
|
|
case StateInfo::ET_FIRE: //화속성
|
|
strEffect = "rcfx_summon_fire_call01_lv01.nx3";
|
|
break;
|
|
case StateInfo::ET_WATER: //수속성
|
|
strEffect = "rcfx_summon_water_call01_lv01.nx3";
|
|
break;
|
|
case StateInfo::ET_WIND: //풍속성
|
|
strEffect = "rcfx_summon_wind_call01_lv01.nx3";
|
|
break;
|
|
case StateInfo::ET_EARTH: //토속성
|
|
strEffect = "rcfx_summon_earth_call01_lv01.nx3";
|
|
break;
|
|
case StateInfo::ET_LIGHT: //명속성
|
|
strEffect = "rcfx_summon_light_call01_lv01.nx3";
|
|
break;
|
|
case StateInfo::ET_DARK: //암속성
|
|
strEffect = "rcfx_summon_dark_call01_lv01.nx3";
|
|
break;
|
|
}
|
|
|
|
if( strEffect.length() )
|
|
m_pGame->AddEffect( &FX_DATA_EX( strEffect.c_str(), 1, pAvatar->GetArID(), pAvatar->GetArID(), pAvatar->GetArID(), EFFECT_POS_BOTTOM ) );
|
|
}*/
|
|
|
|
OnAddOtherEffect( SGameOtherEffectMng::FX_SUMMONING_CREATURE, &OtherFxData( 0, pMsg->handle, 0 ) );
|
|
|
|
pAvatar->SetVisibility( 0.f );
|
|
|
|
//내것의 소환수면 검사 해서 넣는다.
|
|
m_pGame->AddSummon( pAvatar, pMsg );
|
|
|
|
// floyd 2008. 6. 13
|
|
// sonador #2.3.1.14
|
|
// 크리쳐 소환시 메시지 부분을 SGameSystem::AddSummon함수에서 SCommandSystem::AddCreature함수로 이동
|
|
// 크리쳐 소환때만이 아니라 시야 밖으로 벗어났던 크리쳐가 시야 안으로 다시 들어오면 메시지가 출력 되는 문제 수정
|
|
// http://bug.nflavor.com/view.php?id=3388
|
|
|
|
// 소환 메시지
|
|
if ( m_pGame->IsLocalCreature( pAvatar->GetArID() ))
|
|
m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_CREATURE_CALL, pAvatar->GetContentID() ) );
|
|
|
|
m_pArObject->onEnter( &pAvatar->GetArObject() );
|
|
|
|
SGameAvatarEx* pMaster = GetAvatar( pCreInfo->master_handle );
|
|
if( pMaster )
|
|
{
|
|
if( pMaster->IsMount() || pMaster->IsMountMode() )
|
|
{
|
|
//탑승가능 크리쳐 관련 버그 수정
|
|
//탑승 가능 크리쳐 와 기린처럼 타는 크리쳐가 동시 등장시
|
|
//탑승 크리쳐에 플레이어가 타는 문제 수정
|
|
//2009-03-16: hunee
|
|
//AddRidingObject( pCreInfo->master_handle, pMsg->handle, true );
|
|
AR_HANDLE rideHandle = pMaster->GetTransportCreatureHandle();//pMaster->GetCreatureMountHandle();
|
|
AddRidingObject( pCreInfo->master_handle, rideHandle, true );
|
|
}
|
|
|
|
// 2010.08.12 - prodongi
|
|
pMaster->SetCreature( pMsg->handle, true );
|
|
}
|
|
else
|
|
{
|
|
m_FailAddCreatureList.push_back( ENTER_CREATURE_FAIL(pMsg->handle, pCreInfo->master_handle) );
|
|
}
|
|
|
|
if( pAvatar->IsLocalCreature() == false )
|
|
InsertPendLoading( pAvatar );
|
|
else
|
|
pAvatar->PendLoading();
|
|
}
|
|
|
|
// sonador 10.2.1 팻 시스템 구현
|
|
void SCommandSystem::AddPet( SMSG_ENTER* pMsg )
|
|
{
|
|
SMSG_ENTER::PetInfo* PetInfo = (SMSG_ENTER::PetInfo*)( pMsg + 1 );
|
|
SGameAvatarEx* Avatar = 0;
|
|
|
|
struct DATA_PET* PetData = m_pGame->IsLocalPet( pMsg->handle );
|
|
if( PetData )
|
|
{
|
|
Avatar = new SGameLocalPet( PetInfo->pet_code );
|
|
}
|
|
else
|
|
{
|
|
Avatar = new SGameOtherPet( PetInfo->pet_code );
|
|
}
|
|
|
|
float height = 0.f;
|
|
WORD tile = 0;
|
|
m_pGame->GetHeight( pMsg->x, pMsg->y, height, tile );
|
|
K3DVector pos( pMsg->x, pMsg->y, height );
|
|
|
|
Avatar->SetName( PetInfo->szName );
|
|
Avatar->SetObjType( pMsg->ObjType );
|
|
Avatar->SetMaster( PetInfo->master_handle, 0 );
|
|
Avatar->ProcMsgAtStatic( pMsg );
|
|
Avatar->Initialize( m_pRenderDevice );
|
|
Avatar->SetMessageHandler( m_pGame );
|
|
Avatar->SetArID( pMsg->handle );
|
|
Avatar->GetArObject().type = pMsg->type;
|
|
Avatar->GetArObject().mv.face = PetInfo->face_direction;
|
|
Avatar->SetArObjectPos( pos.x, pos.y, pos.z, pMsg->layer );
|
|
Avatar->SetPosition( pos );
|
|
Avatar->SetVisibility( 0.f );
|
|
Avatar->Activate();
|
|
Avatar->ActivateForceSphere();
|
|
if( PetInfo->energy > 0 )
|
|
Avatar->OnMsgForceSphere( PetInfo->energy );
|
|
if( GetPetDB().Find( PetInfo->pet_code ).getSlantType() == 1 )
|
|
Avatar->ActivateTerrainDegree();
|
|
|
|
InsertAvatarEX( pMsg->handle, Avatar );
|
|
m_svOtherObject.insert( Avatar );
|
|
OnAddOtherEffect( SGameOtherEffectMng::FX_SUMMONING_CREATURE, &OtherFxData( 0, pMsg->handle, 0 ) );
|
|
Avatar->SetVisibility( 0.f );
|
|
m_pGame->AddPet( Avatar, pMsg );
|
|
m_pArObject->onEnter( &Avatar->GetArObject() );
|
|
/// 2011.10.24 자동 줍기 활성화 - prodongi
|
|
if (Avatar->IsLocalPet())
|
|
{
|
|
m_pGame->SendGameInterfaceMsg(&SIMSG_UI_SEND_DATA(SIMSG_TOGGLE_UIWINDOW::UIWINDOW_PET_COMMAND, "useAutoPickSkill"));
|
|
}
|
|
|
|
if( Avatar->IsLocalPet() == false ) // sonador #2.3.1.13
|
|
InsertPendLoading( Avatar );
|
|
else
|
|
Avatar->PendLoading();
|
|
}
|
|
|
|
void SCommandSystem::AddMob ( SMSG_ENTER* pMsg )
|
|
{
|
|
SMSG_ENTER::MonsterInfo * pMobInfo = (SMSG_ENTER::MonsterInfo *)(pMsg+1);
|
|
|
|
SGameMob* pMob = new SGameMob(pMobInfo->monster_id);
|
|
|
|
pMob->SetObjType( pMsg->ObjType );
|
|
pMob->Initialize( m_pRenderDevice );
|
|
pMob->ProcMsgAtStatic( pMsg );
|
|
|
|
//몬스터 스캐일
|
|
//float fScale = GetMonsterDB().GetScale( pMobInfo->monster_id );
|
|
// _oprint( "몬스터 스케일 : %f\n", fScale );
|
|
|
|
// pMob->SetScale( fScale );
|
|
|
|
pMob->SetMessageHandler( m_pGame );
|
|
pMob->SetArID( pMsg->handle );
|
|
|
|
pMob->GetArObject().type = pMsg->type;
|
|
pMob->GetArObject().mv.face = pMobInfo->face_direction;
|
|
|
|
//pMob->SetMobType( GetMonsterDB().GetFightType( pMobInfo->monster_id ) );
|
|
|
|
if( pMob->GetMobType() == SGameMob::CORE_MOB )
|
|
pMob->SetViewVectorAngle( pMobInfo->face_direction );
|
|
|
|
float fHeight = 0.f;
|
|
WORD wTile=0;
|
|
m_pGame->GetHeight( pMsg->x, pMsg->y, fHeight, wTile );
|
|
K3DVector pos( pMsg->x, pMsg->y, fHeight );
|
|
|
|
pMob->SetArObjectPos( pos.x, pos.y, pos.z, pMsg->layer );
|
|
|
|
pMob->SetPosition( pos );
|
|
pMob->Activate();
|
|
pMob->SetHP( pMobInfo->hp, true );
|
|
|
|
if( pMob->GetSlantType() == 1 )
|
|
pMob->ActivateTerrainDegree();
|
|
|
|
InsertAvatarEX(pMsg->handle,pMob);
|
|
|
|
m_svOtherObject.insert( pMob );
|
|
|
|
m_pArObject->onEnter( &pMob->GetArObject() );
|
|
|
|
pMob->PendLoading();
|
|
|
|
m_pGame->SendGameInterfaceMsg( &SIMSG_UI_ADD_MONSTER( pMob->GetArID(), pMob->GetContentID(), pMob->GetObjType(), pMob->GetNameID(), pMob->GetHP(), pMob->GetMaxHP() ) );
|
|
}
|
|
|
|
//Skill Prop
|
|
void SCommandSystem::AddSkillProp ( struct SMSG_ENTER* pMsg )
|
|
{
|
|
SMSG_ENTER::SkillInfo * pSkillInfo = (SMSG_ENTER::SkillInfo *)(pMsg+1);
|
|
pSkillInfo->start_time; //이것도 설정 해야 된다.
|
|
//
|
|
SGameSkilProp * pSkillProp = new SGameSkilProp( pSkillInfo->skill_num ) ;
|
|
|
|
pSkillProp->SetMessageHandler( m_pGame );
|
|
pSkillProp->SetArID( pMsg->handle );
|
|
|
|
pSkillProp->ProcMsgAtStatic( pMsg );
|
|
|
|
pSkillProp->Initialize( m_pRenderDevice );
|
|
|
|
pSkillProp->SetCasterHandle( pSkillInfo->caster );
|
|
|
|
pSkillProp->SetObjType( pMsg->ObjType );
|
|
pSkillProp->GetArObject().type = pMsg->type;
|
|
|
|
float fHeight = 0.f;
|
|
WORD wTile=0;
|
|
m_pGame->GetHeight( pMsg->x, pMsg->y, fHeight,wTile );
|
|
pSkillProp->SetArObjectPos( pMsg->x, pMsg->y, fHeight, pMsg->layer );
|
|
|
|
pSkillProp->Activate();
|
|
|
|
InsertAvatarEX(pMsg->handle,pSkillProp);
|
|
|
|
m_svOtherObject.insert( pSkillProp );
|
|
|
|
m_pArObject->onEnter( &pSkillProp->GetArObject() );
|
|
|
|
m_pGame->AddSkillProp( pSkillProp );
|
|
}
|
|
|
|
void SCommandSystem::AddFieldQuestProp( struct SMSG_ENTER* pMsg )
|
|
{
|
|
SMSG_ENTER::FieldPropInfo* pFieldPropInfo = (SMSG_ENTER::FieldPropInfo *)(pMsg+1);
|
|
|
|
SGameFieldQuestProp* pFieldQuestProp = new SGameFieldQuestProp(pFieldPropInfo->prop_id);
|
|
|
|
pFieldQuestProp->SetObjType( TS_ENTER::GAME_FIELD_PROP );
|
|
pFieldQuestProp->SetMessageHandler( m_pGame );
|
|
pFieldQuestProp->SetArID( pMsg->handle );
|
|
|
|
pFieldQuestProp->ProcMsgAtStatic( pMsg );
|
|
|
|
/*float fHeight = 0.f;
|
|
if( !m_pGame->GetOnlyTerrainHeight( pMsg->x, pMsg->y, fHeight ) )
|
|
pFieldQuestProp->SetTryHeightValue();*/
|
|
|
|
WORD wTile;
|
|
float fHeight = 0.f;
|
|
|
|
// 터레인 위에만 나오는 프랍이냐? 오브젝트 위에 나오는 프랍이냐? 체크 하는 부분
|
|
// 2010-3-25 : hunee
|
|
int nTerrainCheck = GetFieldPropResourceDB().GetTerrainCheck( pFieldQuestProp->GetQuestPropDBID() );
|
|
if( nTerrainCheck == 1)
|
|
{
|
|
// 2010.09.02 실패 했을 경우 처리 추가 - prodongi
|
|
//m_pGame->GetHeight( pMsg->x, pMsg->y, fHeight, wTile );
|
|
if (!m_pGame->GetHeight( pMsg->x, pMsg->y, fHeight, wTile ))
|
|
pFieldQuestProp->SetTryHeightValue();
|
|
}
|
|
else if( !m_pGame->GetOnlyTerrainHeight( pMsg->x, pMsg->y, fHeight ) )
|
|
{
|
|
pFieldQuestProp->SetTryHeightValue();
|
|
}
|
|
|
|
pFieldQuestProp->SetArObjectPos( pMsg->x, pMsg->y, fHeight, pMsg->layer );
|
|
pFieldQuestProp->SetPosition( K3DVector( pMsg->x, pMsg->y, fHeight ) );
|
|
|
|
pFieldQuestProp->SetZOffSet( pFieldPropInfo->fZOffset );
|
|
/// 2011.01.21 - prodongi
|
|
if (pFieldQuestProp->GetQuestPropDBID() == 130091)
|
|
pFieldQuestProp->SetRatation( K3DVector( 0.0f, 0.0f, 1.5f ));
|
|
else
|
|
pFieldQuestProp->SetRatation( K3DVector( pFieldPropInfo->fRotateX, pFieldPropInfo->fRotateY, pFieldPropInfo->fRotateZ ) );
|
|
pFieldQuestProp->SetPropScale( K3DVector( pFieldPropInfo->fScaleX, pFieldPropInfo->fScaleY, pFieldPropInfo->fScaleZ ) );
|
|
|
|
pFieldQuestProp->SetLockHeight( pFieldPropInfo->bLockHeight );
|
|
pFieldQuestProp->SetLockHeight( pFieldPropInfo->fLockHeight );
|
|
|
|
pFieldQuestProp->Initialize(NULL);
|
|
pFieldQuestProp->Activate();
|
|
|
|
InsertAvatarEX(pMsg->handle, pFieldQuestProp);
|
|
|
|
m_svOtherObject.insert( pFieldQuestProp );
|
|
|
|
m_pArObject->onEnter( &pFieldQuestProp->GetArObject() );
|
|
|
|
}
|
|
|
|
//TransportCreature ( 서버와 관계없음 )
|
|
void SCommandSystem::AddTransportCreature( SMSG_ENTER* pMsg, SGameAvatarEx* pPlayer )
|
|
{
|
|
_oprint( "소환수 핸들 %u\n", pMsg->handle );
|
|
|
|
//이미 소환된 크리처인가?
|
|
SMSG_ENTER::SummonInfo * pCretureInfo = (SMSG_ENTER::SummonInfo *)(pMsg+1);
|
|
|
|
SGameCreatureForTransport* pAvatar = new SGameCreatureForTransport( pCretureInfo->summon_code, pCretureInfo->enhance );
|
|
|
|
pAvatar->SetMaster( pCretureInfo->master_handle, pPlayer );
|
|
|
|
pAvatar->SetName(pCretureInfo->szName);
|
|
pAvatar->SetObjType( pMsg->ObjType );
|
|
|
|
pAvatar->ProcMsgAtStatic( pMsg );
|
|
|
|
pAvatar->Initialize( m_pRenderDevice );
|
|
|
|
pAvatar->SetMessageHandler( m_pGame );
|
|
pAvatar->SetArID( pMsg->handle );
|
|
|
|
pAvatar->GetArObject().type = pMsg->type;
|
|
pAvatar->GetArObject().mv.face = pCretureInfo->face_direction;
|
|
pAvatar->SetArObjectPos( pMsg->x, pMsg->y, pMsg->z , pMsg->layer );
|
|
|
|
pAvatar->SetPosition( K3DVector( pMsg->x, pMsg->y, pMsg->z ) );
|
|
pAvatar->Activate();
|
|
pAvatar->SetHP( pCretureInfo->hp, true );
|
|
|
|
pAvatar->SetCreatureMountType( GetCreatureDB().GetRidingMotionType( pCretureInfo->summon_code ) );
|
|
|
|
if( GetCreatureDB().GetSlantType( pCretureInfo->summon_code ) == 1 )
|
|
pAvatar->ActivateTerrainDegree();
|
|
|
|
InsertAvatarEX( pMsg->handle, pAvatar, true);
|
|
|
|
pAvatar->SetVisibility( 0.f );
|
|
|
|
if( pAvatar->IsLocalCreature() == false )
|
|
InsertPendLoading( pAvatar );
|
|
else
|
|
pAvatar->PendLoading();
|
|
|
|
pPlayer->SetTransportCreatureHandle( pMsg->handle );
|
|
|
|
m_pArObject->onEnter( &pAvatar->GetArObject() );
|
|
}
|
|
|
|
//==== 테스트용 더미 크리처
|
|
//테스트용 크리처 ( 서버와 관계없음 치트로 생성되는 크리처 )
|
|
void SCommandSystem::AddDummyNpc( int nContentID )
|
|
{
|
|
AddDummy( nContentID, TS_ENTER::GAME_NPC );
|
|
}
|
|
|
|
void SCommandSystem::AddDummySummon( int nContentID )
|
|
{
|
|
AddDummy( nContentID, TS_ENTER::GAME_SUMMON );
|
|
}
|
|
|
|
void SCommandSystem::AddDummyMob( int nContentID )
|
|
{
|
|
AddDummy( nContentID, TS_ENTER::GAME_MOB );
|
|
}
|
|
|
|
void SCommandSystem::AddDummyMobCirclePos( int nContentID, int nPosCnt, float fLength )
|
|
{
|
|
for( int i = 0; i < nPosCnt; ++i )
|
|
{
|
|
SGameAvatarEx* pDummy = AddDummy( nContentID, TS_ENTER::GAME_MOB );
|
|
if( pDummy )
|
|
{
|
|
K3DVector vTrans( fLength, fLength, 0.0f );
|
|
|
|
K3DMatrix matRot, matTrans;
|
|
K3DMatrixRotationZ( matRot, (float)i * ( ( K3D_PI*2.0f ) / nPosCnt ) );
|
|
K3DMatrixTranslation( matTrans, vTrans.x, vTrans.y, vTrans.z );
|
|
K3DMatrixMultiply( matTrans, matTrans, matRot );
|
|
|
|
K3DVector vPos = *pDummy->GetPosition();
|
|
|
|
vPos.x += matTrans._41;
|
|
vPos.y += matTrans._42;
|
|
|
|
WORD wTile=0;
|
|
m_pGame->GetHeight( vPos.x, vPos.y, vPos.z,wTile );
|
|
pDummy->SetArObjectPos( vPos.x, vPos.y, vPos.z, 0 );
|
|
pDummy->SetPosition( vPos );
|
|
}
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::AddDummyMobRandomPos( int nContentID, int nPosCnt, float fLength )
|
|
{
|
|
for( int i = 0; i < nPosCnt; ++i )
|
|
{
|
|
SGameAvatarEx* pDummy = AddDummy( nContentID, TS_ENTER::GAME_MOB );
|
|
if( pDummy )
|
|
{
|
|
float fRandomX = (float)rand() / (float)RAND_MAX;
|
|
fRandomX = ((fRandomX * (float)fabs( fLength - (-fLength) ) ) + (-fLength) );
|
|
|
|
float fRandomY = (float)rand() / (float)RAND_MAX;
|
|
fRandomY = ((fRandomY * (float)fabs( fLength - (-fLength) ) ) + (-fLength) );
|
|
|
|
K3DVector vPos = *pDummy->GetPosition();
|
|
|
|
vPos.x += fRandomX;
|
|
vPos.y += fRandomY;
|
|
|
|
WORD wTile=0;
|
|
m_pGame->GetHeight( vPos.x, vPos.y, vPos.z,wTile );
|
|
pDummy->SetArObjectPos( vPos.x, vPos.y, vPos.z, 0 );
|
|
pDummy->SetPosition( vPos );
|
|
}
|
|
}
|
|
}
|
|
|
|
SGameAvatarEx* SCommandSystem::AddDummy( int nContentID, int nObjType )
|
|
{
|
|
SGameAvatarEx* pLocal = GetLocalPlayer();
|
|
if( pLocal == NULL ) return NULL;
|
|
|
|
static int nDummyHandle = 9090900;
|
|
|
|
SGameAvatarEx* pDummyCreature = NULL;
|
|
pDummyCreature = new SGameDummyCreature( nContentID, 0 );
|
|
|
|
pDummyCreature->SetObjType( nObjType );
|
|
|
|
pDummyCreature->SetHP( 9999 );
|
|
pDummyCreature->SetMaxHP( 9999 );
|
|
pDummyCreature->SetMP( 9999 );
|
|
pDummyCreature->SetMaxMP( 9999 );
|
|
pDummyCreature->SetLevel( 300 );
|
|
|
|
pDummyCreature->Initialize( m_pRenderDevice );
|
|
|
|
((SGameDummyCreature*)pDummyCreature)->SetDBData();
|
|
|
|
pDummyCreature->SetMessageHandler( m_pGame );
|
|
pDummyCreature->SetArID( nDummyHandle);
|
|
|
|
pDummyCreature->GetArObject().type = 3;
|
|
pDummyCreature->GetArObject().mv.face = 1.0f;
|
|
|
|
float fHeight = 0.f;
|
|
WORD wTile=0;
|
|
m_pGame->GetHeight( pLocal->GetPosition()->x, pLocal->GetPosition()->y, fHeight,wTile );
|
|
K3DVector pos( pLocal->GetPosition()->x, pLocal->GetPosition()->y, fHeight );
|
|
|
|
pDummyCreature->SetArObjectPos( pos.x, pos.y, pos.z, 0 );
|
|
pDummyCreature->SetPosition( pos );
|
|
|
|
pDummyCreature->SetVisibility( 1.0f );
|
|
pDummyCreature->Activate();
|
|
|
|
InsertAvatarEX( nDummyHandle, pDummyCreature );
|
|
|
|
m_svOtherObject.insert( pDummyCreature );
|
|
|
|
m_pArObject->onEnter( &pDummyCreature->GetArObject() );
|
|
|
|
pDummyCreature->PendLoading();
|
|
|
|
++nDummyHandle;
|
|
|
|
return pDummyCreature;
|
|
}
|
|
|
|
//그냥 바로 처리
|
|
void SCommandSystem::LeaveDummyCreature( SGameAvatarEx* pDummyCreature )
|
|
{
|
|
SMSG_LEAVE msg;
|
|
msg.handle = pDummyCreature->GetArID();
|
|
OnMsgLeave( &msg );
|
|
}
|
|
|
|
void SCommandSystem::SetDummyCreatureSpeed( SGameAvatarEx* pDummyCreature, float fSpeed )
|
|
{
|
|
((SGameDummyCreature*)pDummyCreature)->SetDummyCreatureSpeed( fSpeed );
|
|
}
|
|
|
|
void SCommandSystem::SetDummyCreatureSpeedWithPlayRate( SGameAvatarEx* pDummyCreature, float fSpeed )
|
|
{
|
|
((SGameDummyCreature*)pDummyCreature)->SetDummyCreatureSpeedWithPlayRate( fSpeed );
|
|
}
|
|
|
|
void SCommandSystem::SetDummyCreatureMode( SGameAvatarEx* pDummyCreature, int nMode )
|
|
{
|
|
((SGameDummyCreature*)pDummyCreature)->SetDummyCreatureMode( nMode );
|
|
}
|
|
|
|
void SCommandSystem::SetDummyCreaturePlayRate( SGameAvatarEx* pDummyCreature, float fPlayRate )
|
|
{
|
|
((SGameDummyCreature*)pDummyCreature)->SetDummyCreaturePlayRate( fPlayRate );
|
|
}
|
|
|
|
void SCommandSystem::MoveDummyCreature( SGameAvatarEx* pDummyCreature, K3DVector & res )
|
|
{
|
|
SMSG_MOVE msg;
|
|
msg.handle = pDummyCreature->GetArID();
|
|
msg.start_time = 0;
|
|
msg.pos_target = res;
|
|
msg.speed = ((SGameDummyCreature*)pDummyCreature)->GetDummyCreatureSpeed();
|
|
msg.m_vecMoveInfo.push_back( ArPosition( res.x, res.y, res.z ) );
|
|
|
|
m_pArObject->onMultiMove( msg.handle, ArPosition( res.x, res.y, res.z ), msg.m_vecMoveInfo, msg.speed, 0 );
|
|
pDummyCreature->OnNetInput( &msg );
|
|
|
|
msg.m_vecMoveInfo.clear();
|
|
}
|
|
|
|
//치트키
|
|
void SCommandSystem::CheatWhirlWindSkill()
|
|
{
|
|
SGameAvatarEx* pLocal = GetLocalPlayer();
|
|
if( pLocal == NULL ) return;
|
|
|
|
std::vector< AR_HANDLE > vHandle;
|
|
KSortVector< class SGameAvatarEx* >::iterator it = m_svObject.begin();
|
|
for( ; it != m_svObject.end(); ++it )
|
|
{
|
|
if( (*it)->GetObjType() == TS_ENTER::GAME_MOB && (*it)->GetArID() >= 9090900 )
|
|
vHandle.push_back( (*it)->GetArID() );
|
|
}
|
|
|
|
((SGamePlayer*)pLocal)->CheatWhirlWindSkill( vHandle );
|
|
|
|
vHandle.clear();
|
|
}
|
|
|
|
void SCommandSystem::CheatLightningSkill()
|
|
{
|
|
SGameAvatarEx* pLocal = GetLocalPlayer();
|
|
if( pLocal == NULL ) return;
|
|
|
|
struct SMSG_SKILL_EVENT msg;
|
|
|
|
msg.caster = pLocal->GetArID();
|
|
msg.target = 0;
|
|
msg.nType = SGameActionMgr::SKILL_LIGHTNING;
|
|
msg.skill_id = 3202;
|
|
msg.fire.count = 1;
|
|
|
|
KSortVector< class SGameAvatarEx* >::iterator it = m_svObject.begin();
|
|
for( ; it != m_svObject.end(); ++it )
|
|
{
|
|
if( (*it)->GetObjType() == TS_ENTER::GAME_MOB )
|
|
{
|
|
SkillResult damage;
|
|
damage.damage.hTarget = (*it)->GetArID();
|
|
msg.vSkillResult.push_back( damage );
|
|
|
|
msg.target = (*it)->GetArID();
|
|
}
|
|
}
|
|
|
|
if (m_pActionMgr) m_pActionMgr->AddTestAction( &msg );
|
|
}
|
|
|
|
void SCommandSystem::CheatHealingWaveSkill()
|
|
{
|
|
SGameAvatarEx* pLocal = GetLocalPlayer();
|
|
if( pLocal == NULL ) return;
|
|
|
|
struct SMSG_SKILL_EVENT msg;
|
|
|
|
msg.caster = pLocal->GetArID();
|
|
msg.target = 0;
|
|
msg.nType = SGameActionMgr::SKILL_HEALINGWAVE;
|
|
msg.skill_id = 3202;
|
|
msg.fire.count = 1;
|
|
|
|
KSortVector< class SGameAvatarEx* >::iterator it = m_svObject.begin();
|
|
for( ; it != m_svObject.end(); ++it )
|
|
{
|
|
if( (*it)->GetObjType() == TS_ENTER::GAME_MOB )
|
|
{
|
|
SkillResult damage;
|
|
damage.damage.hTarget = (*it)->GetArID();
|
|
msg.vSkillResult.push_back( damage );
|
|
|
|
msg.target = (*it)->GetArID();
|
|
}
|
|
}
|
|
|
|
if (m_pActionMgr) m_pActionMgr->AddTestAction( &msg );
|
|
}
|
|
|
|
void SCommandSystem::CheatBlessingHammerSkill()
|
|
{
|
|
SGameAvatarEx* pLocal = GetLocalPlayer();
|
|
if( pLocal == NULL ) return;
|
|
|
|
struct SMSG_SKILL_EVENT msg;
|
|
|
|
msg.caster = pLocal->GetArID();
|
|
msg.target = 0;
|
|
msg.nType = SGameActionMgr::SKILL_BLESSINGHAMMER;
|
|
msg.skill_id = 3202;
|
|
msg.fire.count = 1;
|
|
|
|
KSortVector< class SGameAvatarEx* >::iterator it = m_svObject.begin();
|
|
for( ; it != m_svObject.end(); ++it )
|
|
{
|
|
if( (*it)->GetObjType() == TS_ENTER::GAME_MOB && (*it)->GetArID() >= 9090900 )
|
|
{
|
|
SkillResult damage;
|
|
damage.damage.hTarget = (*it)->GetArID();
|
|
msg.vSkillResult.push_back( damage );
|
|
|
|
msg.target = (*it)->GetArID();
|
|
}
|
|
}
|
|
|
|
if (m_pActionMgr) m_pActionMgr->AddTestAction( &msg );
|
|
}
|
|
|
|
//테스트용 더미 크리처 ====//
|
|
|
|
void SCommandSystem::DropItem( AR_HANDLE item_handle )
|
|
{
|
|
//아이템을 보여주게 한다.
|
|
SGameAvatarEx* pItem = NULL;
|
|
if( m_hashObject.lookup( item_handle, pItem ) )
|
|
{
|
|
pItem->Activate();
|
|
pItem->DropSound();
|
|
}
|
|
|
|
//Drop Item 삭제
|
|
unsigned int nDropItemSize = m_vMobDropItemList.size();
|
|
for( unsigned int i(0); nDropItemSize>i; i++ )
|
|
{
|
|
if( m_vMobDropItemList[i].item_handle == item_handle )
|
|
{
|
|
m_vMobDropItemList.erase( m_vMobDropItemList.begin()+i );
|
|
return;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void SCommandSystem::AddItem ( SMSG_ENTER* pMsg )
|
|
{
|
|
SMSG_ENTER::ItemInfo * pItemInfo = (SMSG_ENTER::ItemInfo*)(pMsg+1);
|
|
|
|
#ifdef _TEST_ONLY_TAKE_CARD_ITEM_ /// 2011.01.25 - prodongi
|
|
if (GetItemDB().GetUseType(pItemInfo->code) != ItemBase::TYPE_CARD)
|
|
return ;
|
|
#endif
|
|
|
|
SGameItem * pItem = NULL;
|
|
|
|
pItem = new SGameItem( pItemInfo->code );
|
|
pItem->Initialize( m_pRenderDevice );
|
|
pItem->SetMessageHandler( m_pGame );
|
|
pItem->SetObjType( pMsg->ObjType );
|
|
pItem->SetArID( pMsg->handle );
|
|
|
|
pItem->ProcMsgAtStatic( pMsg );
|
|
|
|
//먹자 방지 설정
|
|
pItem->SetPickUpOrder( pMsg );
|
|
|
|
pItem->GetArObject().type = pMsg->type;
|
|
|
|
float fHeight = 0.f;
|
|
WORD wTile=0;
|
|
if( !m_pGame->GetHeight( pMsg->x, pMsg->y, fHeight,wTile ) )
|
|
pItem->SetTryHeightValue();
|
|
|
|
K3DVector pos( pMsg->x, pMsg->y, fHeight );
|
|
pItem->SetArObjectPos( pos.x, pos.y, pos.z, pMsg->layer );
|
|
pItem->SetPosition( pos );
|
|
|
|
pItem->PlayAnimation( 0, SEQTYPE_LOOP ); //고치자
|
|
|
|
InsertAvatarEX(pMsg->handle,pItem);
|
|
|
|
m_svOtherObject.insert( pItem );
|
|
|
|
m_pArObject->onEnter( &pItem->GetArObject() );
|
|
|
|
/// 2010.11.23 몹 아이템을 바로 드랍하도록 설정 - prodongi
|
|
/*
|
|
//몹이 떨군 아이템은 안 보여 준다.
|
|
unsigned int nDropItemSize = m_vMobDropItemList.size();
|
|
for( unsigned int i(0); nDropItemSize>i; i++ )
|
|
{
|
|
if( m_vMobDropItemList[i].item_handle == pItem->GetArID() )
|
|
return;
|
|
}
|
|
*/
|
|
|
|
//없으면, 그냥 떨굴 아이템이므로 보여 준다.
|
|
pItem->Activate();
|
|
}
|
|
|
|
//===================================================================================================
|
|
//Msg Event Process
|
|
|
|
void SCommandSystem::OnMsgChatting ( SMSG_CHATTING* pMsg )
|
|
{
|
|
//Local 채팅 Name 설정
|
|
SGameAvatarEx * pPlayer = GetAvatar( pMsg->handle );
|
|
if( pPlayer ) //지역 메세지 임..
|
|
pMsg->szSender = pPlayer->GetName();
|
|
}
|
|
|
|
//특정 Object의 모션 연출은 SGameSystem으로 옮기지 않는다.
|
|
void SCommandSystem::OnMsgStatusChange( SMSG_STATUS_CHANGE* pMsg )
|
|
{
|
|
SGameAvatarEx * pPlayer = GetAvatar( pMsg->handle );
|
|
if( pPlayer )
|
|
{
|
|
//로컬 플레이어는 StateMachine에서 모드를 바꿔준다
|
|
if( !pPlayer->IsLocalPlayer() )
|
|
{
|
|
if( !pPlayer->IsMount() && !pPlayer->IsMountMode() )
|
|
{
|
|
if( !(pMsg->status & TS_ENTER::PlayerInfo::FLAG_BATTLE_MODE) )
|
|
pPlayer->SetNormalMode();
|
|
}
|
|
}
|
|
|
|
pPlayer->OnNetInput( pMsg );
|
|
pPlayer->SetStatus( pMsg->status );
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::OnMsgRegenHPMP( SMSG_REGEN_HPMP* pMsg )
|
|
{
|
|
/* SGameAvatarEx * pObject = (SGameAvatarEx*)GetObject( pMsg->handle );
|
|
if( pObject )
|
|
{
|
|
pObject->ProcMsgAtStatic( pMsg );
|
|
}*/
|
|
}
|
|
|
|
//추가, 삭제 관련===========================================================
|
|
void SCommandSystem::OnMsgLeave ( SMSG_LEAVE* pMsg )
|
|
{
|
|
// _oprint( "Leave \n" );
|
|
//사라지면, 삭제하자..
|
|
unsigned int nDropItemSize = m_vMobDropItemList.size();
|
|
for( unsigned int i(0); nDropItemSize>i; i++ )
|
|
{
|
|
if( m_vMobDropItemList[i].item_handle == pMsg->handle )
|
|
{
|
|
m_vMobDropItemList.erase( m_vMobDropItemList.begin()+i );
|
|
break;
|
|
}
|
|
}
|
|
|
|
delCustomBlock(pMsg->handle);
|
|
|
|
|
|
_Object *pObj = m_pArObject->onLeave( pMsg->handle );
|
|
|
|
onLeave( pMsg->handle, TRUE );
|
|
}
|
|
|
|
void SCommandSystem::OnMsgEnter ( SMSG_ENTER* pMsg )
|
|
{
|
|
// _oprint( "Enter : %d\n", pMsg->ObjType );
|
|
//삭제 보류중인 Object 검사
|
|
RemoveReservationObject();
|
|
|
|
SGameAvatarEx * pGameObject = NULL;
|
|
if( m_hashObject.lookup( pMsg->handle, pGameObject ) )
|
|
{
|
|
//이미 있는 게임 오브젝트
|
|
if( pMsg->ObjType == TS_ENTER::GAME_SUMMON )
|
|
{
|
|
SGameAvatarEx* pLocalSummonCreature = m_pGame->IsSummonCreature( pMsg->handle );
|
|
if( pLocalSummonCreature )
|
|
{
|
|
pLocalSummonCreature->ProcMsgAtStatic( pMsg );
|
|
|
|
pLocalSummonCreature->Activate();
|
|
pLocalSummonCreature->SetArObjectPos( pMsg->x, pMsg->y, pMsg->z, pMsg->layer );
|
|
m_pArObject->SetActivate( pMsg->handle );
|
|
|
|
OnAddOtherEffect( SGameOtherEffectMng::FX_SUMMONING_CREATURE, &OtherFxData( 0, pMsg->handle, 0 ) );
|
|
|
|
m_pGame->AddSummon( pLocalSummonCreature, pMsg );
|
|
}
|
|
return;
|
|
}
|
|
else if( pMsg->ObjType == TS_ENTER::GAME_PET ) // sonador 10.2.1 팻 시스템 구현
|
|
{
|
|
SGameAvatarEx* pLocalSummonPet = m_pGame->IsSummonPet( pMsg->handle );
|
|
if( pLocalSummonPet )
|
|
{
|
|
pLocalSummonPet->ProcMsgAtStatic( pMsg );
|
|
pLocalSummonPet->Activate();
|
|
pLocalSummonPet->SetArObjectPos( pMsg->x, pMsg->y, pMsg->z, pMsg->layer );
|
|
pLocalSummonPet->SetReservation( false );
|
|
m_pArObject->SetActivate( pMsg->handle );
|
|
|
|
m_pGame->AddPet( pLocalSummonPet, pMsg );
|
|
}
|
|
else if( pGameObject->IsReservation() )
|
|
{
|
|
m_pOtherEffecMgr->DelOtherEffect( pMsg->handle, SGameOtherEffectMng::FX_UN_SUMMONING_CREATURE, true );
|
|
pGameObject->SetReservation( false );
|
|
RemoveReservationObject();
|
|
}
|
|
return; // sonador #2.3.1.45
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
if( pMsg->type == TS_ENTER::NPC )
|
|
{
|
|
if( pMsg->ObjType == TS_ENTER::GAME_MOB ) //NPC와 MOB으로 분리 하는게 좋지 않을까?
|
|
{
|
|
AddMob(pMsg);
|
|
}
|
|
else if( pMsg->ObjType == TS_ENTER::GAME_SUMMON ) //Summon
|
|
{
|
|
AddCreature(pMsg);
|
|
}
|
|
else if( pMsg->ObjType == TS_ENTER::GAME_NPC ) //NPC
|
|
{
|
|
AddNPC(pMsg);
|
|
}
|
|
else if( pMsg->ObjType == TS_ENTER::GAME_PET ) // PET // sonador 10.2.1 팻 시스템 구현
|
|
{
|
|
AddPet( pMsg );
|
|
}
|
|
}
|
|
else if( pMsg->type == TS_ENTER::PLAYER )
|
|
{
|
|
AddPlayer(pMsg);
|
|
}
|
|
else if( pMsg->type == TS_ENTER::STATIC_OBJECT ) //Item
|
|
{
|
|
if( pMsg->ObjType == TS_ENTER::GAME_ITEM )
|
|
{
|
|
AddItem(pMsg);
|
|
}
|
|
else if( pMsg->ObjType == TS_ENTER::GAME_SKILL_PROP )
|
|
{
|
|
AddSkillProp(pMsg);
|
|
}
|
|
else if( pMsg->ObjType == TS_ENTER::GAME_FIELD_PROP )
|
|
{
|
|
AddFieldQuestProp( pMsg );
|
|
}
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::OnMsgHairInfo( SMSG_HAIR_INFO* pMsg )
|
|
{
|
|
assert( pMsg->hPlayer != 0 && "Handle이 0이다!!!" );
|
|
if( pMsg->hPlayer == 0 ) return;
|
|
|
|
SGameAvatarEx * pFind = NULL;
|
|
if( m_hashObject.lookup( pMsg->hPlayer, pFind ) == true )
|
|
{
|
|
// 2010.04.22 - prodongi
|
|
pFind->setHairThreadData(pMsg);
|
|
}
|
|
}
|
|
|
|
// 2010.05.19 - prodongi
|
|
void SCommandSystem::OnMsgHideEquipInfo(SMSG_HIDE_EQUIP_INFO* pMsg)
|
|
{
|
|
assert(pMsg->hPlayer && "HideEquipInfo player handle is NULL");
|
|
if( pMsg->hPlayer == 0 ) return;
|
|
SGameAvatarEx * pFind = NULL;
|
|
if( m_hashObject.lookup( pMsg->hPlayer, pFind ) == true )
|
|
{
|
|
pFind->setHideEquipInfo(pMsg->nHideEquipFlag);
|
|
pFind->RefreshItemWear();
|
|
|
|
/// 2011.05.16 ProcMsgAtStatic는 정적 입력 변수이다 - prodongi
|
|
// 꾸미기아이템 보임,숨김 처리 전달.
|
|
//m_pGame->ProcMsgAtStatic( new SIMSG_DECO_VISIBILITY_CHANGE( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_EQUIPMENT ) );
|
|
m_pGame->ProcMsgAtStatic( &SIMSG_DECO_VISIBILITY_CHANGE( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_EQUIPMENT ) );
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void SCommandSystem::OnMsgHideEquipFlag(struct SMSG_HIDE_EQUIP_INFO * pMsg)
|
|
{
|
|
assert(pMsg->hPlayer && "HideEquipInfo player handle is NULL");
|
|
if( pMsg->hPlayer == 0 )
|
|
return;
|
|
|
|
SGameAvatarEx * pFind = NULL;
|
|
if( m_hashObject.lookup( pMsg->hPlayer, pFind ) == true )
|
|
{
|
|
unsigned int equipSet = pFind->getHideEquipInfo();
|
|
equipSet ^= ( 1 << pMsg->nHideEquipFlag ); // 토글시킴.
|
|
|
|
TS_CS_HIDE_EQUIP_INFO info;
|
|
info.nHideEquipFlag = equipSet;
|
|
this->m_pGame->PendMessage( &info );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SCommandSystem::OnMsgLogin ( SMSG_LOGIN* pMsg )
|
|
{
|
|
assert( pMsg->handle != 0 && "Handle이 0이다!!!" );
|
|
if( pMsg->handle == 0 ) return;
|
|
|
|
SGameAvatarEx * pFind = NULL;
|
|
if( m_hashObject.lookup( pMsg->handle, pFind ) == true )
|
|
{ //이미 로그인 되었음.
|
|
return;
|
|
}
|
|
|
|
m_pArObject->onLogin( ArPosition( pMsg->x, pMsg->y, pMsg->z ), pMsg->handle );
|
|
m_pArObject->SetLayer( pMsg->layer );
|
|
m_pArObject->GetMyPos().face = pMsg->face_direction;
|
|
g_nRegionSize = pMsg->region_size;
|
|
|
|
SGameAvatarEx * pAvatar = NULL;
|
|
pAvatar = new SGameLocalPlayer;
|
|
pAvatar->ProcMsgAtStatic( pMsg );
|
|
|
|
//pAvatar->SetHairColorIndex(pMsg->hairColorIndex);
|
|
if (pMsg->hairColorRGB > 0)
|
|
{
|
|
pAvatar->SetHairColorRGB(pMsg->hairColorRGB);
|
|
pAvatar->SetHairColorIndex(0);
|
|
}
|
|
else
|
|
{
|
|
pAvatar->SetHairColorRGB(-16777216);
|
|
pAvatar->SetHairColorIndex(pMsg->hairColorIndex);
|
|
}
|
|
|
|
_oprint("[debug] pMsg->hairColorRGB: %d\n", pMsg->hairColorRGB);
|
|
|
|
if( pMsg->skin_color != 0 )
|
|
{
|
|
// 2010.04.22 - prodongi
|
|
// pAvatar->SetSkinColorized( pMsg->skin_color, K3DTexture::COLORIZED_DEF, 0 );
|
|
pAvatar->SetSkinColorized( pMsg->skin_color, K3DTexture::COLORIZED_DEF, pMsg->hairColorRGB );
|
|
}
|
|
else
|
|
{
|
|
unsigned long color_value = GetSkinColorTable().GetColorValue( pMsg->race-GCLAN_GAIA, 0 );
|
|
pAvatar->SetSkinColorized( color_value, K3DTexture::COLORIZED_DEF, pMsg->hairColorRGB );
|
|
}
|
|
|
|
pAvatar->SetArID( pMsg->handle );
|
|
pAvatar->SetArcadiaClient( m_pArObject );
|
|
pAvatar->SetArObjectPos( pMsg->x, pMsg->y, pMsg->z, pMsg->layer );
|
|
float fHeight = 0.f;
|
|
WORD wTile=0;
|
|
m_pGame->GetHeight(pMsg->x,pMsg->y,fHeight,wTile);
|
|
K3DVector mypos( pMsg->x,pMsg->y, fHeight );
|
|
pAvatar->SetPosition( mypos );
|
|
|
|
pAvatar->Initialize( m_pRenderDevice );
|
|
pAvatar->SetHP( pMsg->hp, true );
|
|
pAvatar->SetRenderFlag( AV_BASIC );
|
|
pAvatar->ActivateForceSphere();
|
|
pAvatar->SetMessageHandler( m_pGame );
|
|
// 2010.05.20 - prodongi
|
|
pAvatar->setHideEquipInfo(pMsg->hideEquipInfo);
|
|
m_pGame->SendGameInterfaceMsg(&SIMSG_HIDE_EQUIP_INFO(pMsg->hideEquipInfo));
|
|
// 2010.06.18 - prodongi
|
|
pAvatar->setDecoIndex(GetSelectedAvatarInfo().getDecoIndex());
|
|
|
|
// pAvatar->ActivateTerrainDegree();
|
|
|
|
#ifdef _WEAPON_FX_
|
|
pAvatar->ActivateFxSwordSlash();
|
|
#endif
|
|
|
|
//아이템 정보가 오면, Activate 시킨다.
|
|
|
|
m_LocalHandle = pMsg->handle;
|
|
|
|
SIMSG_UI_2DPOS_INFO msg;
|
|
|
|
K3DVector _2Dpos;
|
|
m_pGame->Get2DPos( mypos, _2Dpos );
|
|
|
|
msg.handle = pAvatar->GetArID();
|
|
msg.nX = _2Dpos.x;
|
|
msg.nY = _2Dpos.y;
|
|
|
|
m_pGame->ProcMsgAtStatic( &msg );
|
|
|
|
InsertAvatarEX(pMsg->handle,pAvatar);
|
|
|
|
m_svPlayerObject.insert( pAvatar );
|
|
|
|
pAvatar->PendLoading();
|
|
}
|
|
|
|
void SCommandSystem::OnMsgResult ( SMSG_RESULT* pMsg )
|
|
{
|
|
SGameAvatarEx* pLocalPlayer = GetLocalPlayer();
|
|
if( pLocalPlayer ) pLocalPlayer->OnNetInput( pMsg );
|
|
|
|
switch( pMsg->request_msg_id )
|
|
{
|
|
// 대련 신청시 오류 메세지 출력, kappamind.
|
|
case TM_CS_COMPETE_REQUEST:
|
|
{
|
|
if( pMsg->result == RESULT_TARGET_ALREADY_IN_COMPETE )
|
|
{
|
|
m_pGame->AddChatMessage( S( 1636 ) );
|
|
}
|
|
|
|
else if( pMsg->result == RESULT_TOO_FAR ||
|
|
pMsg->result == RESULT_ALREADY_IN_COMPETE ||
|
|
pMsg->result == RESULT_LIMIT_TARGET ||
|
|
pMsg->result == RESULT_NOT_IN_COMPETIBLE_PLACE ||
|
|
pMsg->result == RESULT_TARGET_NOT_IN_COMPETIBLE_PLACE ||
|
|
pMsg->result == RESULT_NOT_EXIST ||
|
|
pMsg->result == RESULT_WAITING_COMPETE_REQUEST_ANSWER ||
|
|
pMsg->result == RESULT_TARGET_WAITING_COMPETE_REQUEST_ANSWER )
|
|
{
|
|
m_pGame->AddChatMessage( S( 1633 ) );
|
|
g_pCurrentGameSystem->SetPVPAcceptCheck( false );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case TM_CS_COMPETE_ANSWER:
|
|
{
|
|
if( pMsg->result == RESULT_ALREADY_IN_COMPETE ||
|
|
pMsg->result == RESULT_TARGET_ALREADY_IN_COMPETE )
|
|
{
|
|
m_pGame->AddChatMessage( S( 1636 ) );
|
|
}
|
|
|
|
else if( pMsg->result == RESULT_TARGET_NOT_IN_COMPETIBLE_PLACE ||
|
|
pMsg->result == RESULT_NOT_IN_COMPETIBLE_PLACE ||
|
|
pMsg->result == RESULT_NOT_IN_COMPETE ||
|
|
pMsg->result == RESULT_NOT_EXIST )
|
|
{
|
|
m_pGame->AddChatMessage( S( 1633 ) );
|
|
g_pCurrentGameSystem->SetPVPAcceptCheck( false );
|
|
}
|
|
}
|
|
break;
|
|
//
|
|
case TM_CS_DONATE_REWARD:
|
|
{
|
|
if( pMsg->result == RESULT_NOT_OWN )
|
|
m_pGame->AddChatMessage( S( 6746 ) ); // 모럴 포인트 부족 채팅 메세지
|
|
}
|
|
case TM_CS_USE_ITEM:
|
|
{
|
|
if( pMsg->result == RESULT_NOT_ACTABLE_IN_DEATHMATCH ) m_pGame->AddChatMessage( S( 9201 ) ); //데스매치에서는 아이템 사용이 불가능하다.
|
|
else if (pMsg->result == RESULT_TARGET_IN_DEATHMATCH) m_pGame->AddChatMessage(S(9252)); // 2011.07.27 - prodongi
|
|
else if (pMsg->result == RESULT_NO_SKILL) m_pGame->AddChatMessage(S(740)); /// 해당 아이템을 사용하기 위한 스킬을 습득하지 못하였습니다.
|
|
else if (pMsg->result == RESULT_ALREADY_TAMING) m_pGame->AddChatMessage(S(741)); /// 다른 몬스터를 테이밍 중입니다.
|
|
else if (pMsg->result == RESULT_NOT_TAMABLE) m_pGame->AddChatMessage(S(742)); /// 테이밍이 불가능한 몬스터 입니다.
|
|
else if (pMsg->result == RESULT_TARGET_ALREADY_BEING_TAMED) m_pGame->AddChatMessage(S(743)); /// 이미 테이밍이 진행되고 있는 몬스터 입니다.
|
|
else if (pMsg->result == RESULT_NOT_ENOUGH_TARGET_HP) m_pGame->AddChatMessage(S(325)); /// 대상의 HP가 100 %일때만 테이밍을 시도할 수 있습니다.
|
|
else if (pMsg->result == RESULT_NOT_ENOUGH_SUMMON_CARD) m_pGame->AddChatMessage(S(324)); /// 빈 크리처 카드를 보유해야만 테이밍을 시도할 수 있습니다.
|
|
else if (pMsg->result == RESULT_NOT_ENOUGH_SOUL_TAMING_CARD) m_pGame->AddChatMessage(S(324)); /// 빈 크리처 카드를 보유해야만 테이밍을 시도할 수 있습니다.
|
|
else if (pMsg->result == RESULT_NOT_ACTABLE_ON_STAND_UP) m_pGame->AddChatMessage(S(895)); /// 앉은 상태에서만 사용 가능합니다.
|
|
else if (pMsg->result == RESULT_NOT_ACTABLE_IN_BATTLE_ARENA) m_pGame->AddChatMessage(S(9243)); /// 아레나에서의 아이템 사용 불가
|
|
else if (pMsg->result == RESULT_TARGET_IN_BATTLE_ARENA) m_pGame->AddChatMessage(S(396)); /// 아레나에서의 아이템 사용 불가
|
|
else if (pMsg->result == RESULT_NOT_IN_COMPETE ) m_pGame->AddChatMessage(S(1009)); /// 대련 중에 사용 불가
|
|
else if (pMsg->result == RESULT_ALREADY_EXIST ) m_pGame->AddChatMessage(S(1008)); /// 같은 부류의 지속효과가 이미 걸려있어 사용 불가
|
|
else if (pMsg->result == RESULT_NOT_EXIST_PARTY ) m_pGame->AddChatMessage(S(434)); /// 파티 아이템 사용 불가
|
|
else if (pMsg->result == RESULT_NOT_EXIST_GUILD ) m_pGame->AddChatMessage(S(629)); /// 길드 아이템 사용 불가
|
|
}
|
|
break;
|
|
case TM_CS_TAKE_ITEM :
|
|
{
|
|
//TODO 크리처가 아이템을 습득할 경우에는 별도 처리 해줘야함
|
|
if( pMsg->result == RESULT_TOO_FAR )
|
|
{
|
|
_oprint( "아템이 너무 멀어~.\n" );
|
|
}
|
|
}
|
|
break;
|
|
case TM_CS_SKILL :
|
|
{
|
|
//현재 사용 시전 중인 Skill 을 멈춘다.
|
|
//_oprint( "공용 메세지 - 스킬 취소 : %d\n", pMsg->result );
|
|
if (pMsg->result == RESULT_NO_SKILL) m_pGame->AddChatMessage(S(740)); /// 해당 아이템을 사용하기 위한 스킬을 습득하지 못하였습니다.
|
|
else if (pMsg->result == RESULT_ALREADY_TAMING) m_pGame->AddChatMessage(S(741)); /// 다른 몬스터를 테이밍 중입니다.
|
|
else if (pMsg->result == RESULT_NOT_TAMABLE) m_pGame->AddChatMessage(S(742)); /// 테이밍이 불가능한 몬스터 입니다.
|
|
else if (pMsg->result == RESULT_TARGET_ALREADY_BEING_TAMED) m_pGame->AddChatMessage(S(743)); /// 이미 테이밍이 진행되고 있는 몬스터 입니다.
|
|
else if (pMsg->result == RESULT_NOT_ENOUGH_TARGET_HP) m_pGame->AddChatMessage(S(325)); /// 대상의 HP가 100 %일때만 테이밍을 시도할 수 있습니다.
|
|
else if (pMsg->result == RESULT_NOT_ENOUGH_SUMMON_CARD) m_pGame->AddChatMessage(S(324)); /// 빈 크리처 카드를 보유해야만 테이밍을 시도할 수 있습니다.
|
|
else if (pMsg->result == RESULT_NOT_ENOUGH_SOUL_TAMING_CARD) m_pGame->AddChatMessage(S(324)); /// 빈 크리처 카드를 보유해야만 테이밍을 시도할 수 있습니다.
|
|
}
|
|
break;
|
|
case TM_CS_MOVE_REQUEST:
|
|
{
|
|
if (pMsg->result == RESULT_ALREADY_EXIST)
|
|
_oprint("Move request results in move to current location.\n");
|
|
else
|
|
{
|
|
_oprint("It's an area I can't go to. - %d \n", pMsg->result);
|
|
}
|
|
}
|
|
break;
|
|
// PK On 모드에서 대련신청시 거부 메세지
|
|
case TM_TRADE :
|
|
{
|
|
if( pMsg->result == RESULT_PK_LIMIT )
|
|
{
|
|
m_pGame->AddChatMessage( S(1652) );
|
|
}
|
|
else if( pMsg->result == RESULT_TARGET_IS_USING_STORAGE) // 2011. 9 .16 - marine 거래 신청 대상이 창고 이용
|
|
{
|
|
m_pGame->GetGameManager()->GetGameInterface()->OpenMessageBox(SIMSG_REQ_OPEN_MSGBOX::MSGBOX_OK, SIMSG_REQ_OPEN_MSGBOX::MSGBOX_GENERAL, 0, -1, S(9824));
|
|
m_pGame->AddChatMessage( S(9824) );
|
|
}
|
|
}
|
|
break;
|
|
case TM_CS_START_BOOTH:
|
|
{
|
|
if( pMsg->result == RESULT_NOT_ACTABLE )
|
|
{
|
|
m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_BOOTH_NOTICE_TRANSACTION ) );
|
|
}
|
|
/*else if ( pMsg->result == RESULT_NOT_ACTABLE_HERE )
|
|
{
|
|
m_pGame->AddChatMessage( S(727) );
|
|
}*/
|
|
}
|
|
break;
|
|
case TM_CS_JOB_LEVEL_UP:
|
|
{
|
|
if( pMsg->result == RESULT_SUCCESS )
|
|
{
|
|
SGameAvatarEx* pTarget = (SGameAvatarEx *)GetObject( (unsigned int)pMsg->value );
|
|
if( pLocalPlayer && pTarget )
|
|
{
|
|
if( pLocalPlayer->GetArID() == pTarget->GetArID() )
|
|
m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_JLV_UP ) );
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case TM_CS_LEARN_SKILL:
|
|
{
|
|
if( pMsg->result == RESULT_SUCCESS )
|
|
m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_LEARN_SKILL, pMsg->value ) );
|
|
}
|
|
break;
|
|
case TM_CS_SOULSTONE_CRAFT:
|
|
{
|
|
if( pMsg->result == RESULT_ACCESS_DENIED )
|
|
m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_ERR_ITEM, pMsg->value ) );
|
|
else if( pMsg->result == RESULT_NOT_ACTABLE )
|
|
m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_CANT_EQUIP_JEWEL, pMsg->value ) );
|
|
else if( pMsg->result == RESULT_ALREADY_EXIST )
|
|
m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_EQUIP_JEWEL_OVER, pMsg->value ) );
|
|
else if( pMsg->result == RESULT_NOT_ENOUGH_MONEY )
|
|
m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_BUY_ITEM_FAIL002, pMsg->value ) );
|
|
else if( pMsg->result == RESULT_SUCCESS )
|
|
m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_SUCCESS_EQUIP_JEWEL, pMsg->value ) );
|
|
}
|
|
break;
|
|
case TM_CS_INSTANCE_GAME_ENTER:
|
|
{
|
|
//RESULT_NOT_ACTABLE_IN_DEATHMATCH
|
|
if( pMsg->result == RESULT_NOT_ENOUGH_MONEY )
|
|
m_pGame->AddChatMessage( S( 9234 ) ); //돈이 부족해서 베어로드에 들어갈 수 없다.
|
|
else if( pMsg->result == RESULT_NOT_ACTABLE_IN_HUNTAHOLIC || pMsg->result == RESULT_NOT_ACTABLE_IN_DEATHMATCH )
|
|
m_pGame->AddChatMessage( S( 9239 ) ); //다른 채널로 가기 위해서는 먼저 필드로 귀환 해야 합니다.
|
|
// 2010.06.09 - prodongi
|
|
else if (pMsg->result == RESULT_NOT_ACTABLE_IN_SECRET_DUNGEON)
|
|
m_pGame->AddChatMessage( S( 9245 ) ); // 숨겨진 던전 안에서는 할 수 없는 동작입니다
|
|
}
|
|
break;
|
|
case TM_CS_HUNTAHOLIC_CREATE_INSTANCE:
|
|
{
|
|
if( pMsg->result == RESULT_NOT_ENOUGH_BULLET )
|
|
m_pGame->AddChatMessage( S( 9237 ) ); //베어로드 플레이 횟수 부족으로 방 만들기 실패
|
|
else if (pMsg->result == RESULT_INVALID_TEXT)
|
|
m_pGame->AddChatMessage( S( 128 ) ); // 2012.02.08 유효하지 않은 방제를 사용 했을 때 - prodongi
|
|
}
|
|
break;
|
|
case TM_CS_HUNTAHOLIC_JOIN_INSTANCE:
|
|
{
|
|
if( pMsg->result == RESULT_NOT_ENOUGH_BULLET )
|
|
m_pGame->AddChatMessage( S( 9237 ) ); //베어로드 플레이 횟수 부족으로 입장 실패
|
|
}
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
//특정 Object의 모션 연출은 SGameSystem으로 옮기지 않는다.
|
|
//이동, 영역 관련===========================================================
|
|
void SCommandSystem::OnMsgMove ( SMSG_MOVE* pMsg )
|
|
{
|
|
SGameAvatarEx* localPlayer = GetLocalPlayer();
|
|
if (pMsg->handle == localPlayer->GetArID())
|
|
{
|
|
#ifdef KMOVE_DEBUG
|
|
m_pArObject->addKMovePrimitive(pMsg->m_vecMoveInfo, m_pArObject->GetMyPos().GetPos(), 1);
|
|
#endif
|
|
m_pArObject->setSpeed(pMsg->handle, pMsg->speed);
|
|
|
|
/// 키보드 이동으로 보낸 좌표일 경우에는 클라이언트 자체에서 이동을 시켜 주기 때문에 그냥 리턴한다.
|
|
if (localPlayer->isKMoveTargetList(pMsg->m_vecMoveInfo))
|
|
{
|
|
return ;
|
|
}
|
|
|
|
if (localPlayer->isKMoving())
|
|
{
|
|
SGameWorld* pGameWorld = dynamicCast<SGameWorld*>(g_pCurrentGameSystem->GetGame());
|
|
if( pGameWorld != NULL )
|
|
{
|
|
pGameWorld->stopKMove();
|
|
}
|
|
}
|
|
}
|
|
|
|
//K3DVector targetpos;
|
|
{
|
|
m_pArObject->onMultiMove( pMsg->handle, ArPosition(pMsg->pos_target.x,pMsg->pos_target.y, pMsg->pos_target.z), pMsg->m_vecMoveInfo, pMsg->speed, pMsg->start_time );
|
|
|
|
//targetpos = K3DVector(pMsg->pos_target.x,pMsg->pos_target.y, pMsg->pos_target.z);
|
|
}
|
|
|
|
SGameAvatarEx * pAvatar = NULL;
|
|
if( m_hashObject.lookup( pMsg->handle, pAvatar ) )
|
|
{
|
|
if( pAvatar->IsPendLoading() )
|
|
ActivatePendLoadingListByMove( pAvatar );
|
|
|
|
pAvatar->OnNetInput( pMsg );
|
|
|
|
//플레이어냐?
|
|
if( pAvatar->GetObjType() == TS_ENTER::GAME_PLAYER )
|
|
{
|
|
//로컬 플레이어 이동 시 타겟 리스트 삭제 한다.
|
|
if( pAvatar->IsLocalPlayer() )
|
|
m_pTargetMgr->ClearTargetList();
|
|
|
|
// if( pAvatar->IsMountMode() )
|
|
{
|
|
if( pAvatar->GetCreatureMountHandle() )
|
|
{
|
|
m_pArObject->onMultiMove( pAvatar->GetCreatureMountHandle(), ArPosition(pMsg->pos_target.x,pMsg->pos_target.y, pMsg->pos_target.z), pMsg->m_vecMoveInfo, pMsg->speed, pMsg->start_time );
|
|
|
|
SGameAvatarEx* pCreature = pAvatar->GetRiderCreatureObject();
|
|
if( pCreature )
|
|
{
|
|
pCreature->OnNetInput( pMsg );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
{
|
|
//#ifndef NDEBUG
|
|
// K3DVector pos = K3DVector( m_pArObject->GetMyPos().x, m_pArObject->GetMyPos().y, 0 );
|
|
// targetpos.z = 0.f;
|
|
|
|
// float fLen = K3DVectorGetLength( pos, targetpos );
|
|
|
|
// _oprint( "!!! - 움직일 놈을 못 찾았다. 나와의 거리 : %f \n", fLen );
|
|
|
|
//#endif
|
|
|
|
//Enter 를 강제로 해달라~
|
|
TS_CS_QUERY query_msg;
|
|
query_msg.handle = pMsg->handle;
|
|
m_pGame->SendMsg( &query_msg );
|
|
}
|
|
}
|
|
|
|
|
|
void SCommandSystem::OnMsgRegionAck( SMSG_REGION_ACK* pMsg )
|
|
{
|
|
m_pArObject->onRegionAck( pMsg->rx, pMsg->ry );
|
|
}
|
|
|
|
void SCommandSystem::OnAttack( SGameAvatarEx * pAttack, SGameAvatarEx * pTarget, AR_HANDLE hAttack , AR_HANDLE hTarget, SGameMessage * pMsg )
|
|
{
|
|
if( pAttack && pTarget )
|
|
{
|
|
// TODO: 마운트 모드 이거나 마운트 상태일때는 무시한다
|
|
if( !pAttack->IsMountMode() && !pAttack->IsMount() )
|
|
{
|
|
pAttack->OnNetInput( pMsg );
|
|
pAttack->SetAttackMode();
|
|
}
|
|
|
|
//pAttacker 와 pTarget 이 Player 계열 이면, 전투 대기 중으로 변경 해달라고 한다.
|
|
//이미 전투 대기 중이거나, 공격 중이면, 무시 된다.
|
|
|
|
if(pTarget->GetObjType() == TS_ENTER::GAME_NPC )
|
|
{
|
|
pTarget->SetAttackMode();
|
|
pTarget->Default3(); //맞는 놈한테 알려 준다.
|
|
}
|
|
else
|
|
{
|
|
if( !pTarget->IsMountMode() && !pTarget->IsMount() )
|
|
{
|
|
pTarget->SetAttackMode();
|
|
pTarget->Default3(); //맞는 놈한테 알려 준다.
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//Enter 를 강제로 해달라~
|
|
TS_CS_QUERY query_msg;
|
|
if( pAttack == NULL )
|
|
{
|
|
query_msg.handle = hAttack;
|
|
m_pGame->SendMsg( &query_msg );
|
|
|
|
#ifndef NDEBUG
|
|
_oprint( "공격 메세지 : Attacker 찾을 수 없다.\n" );
|
|
#endif
|
|
}
|
|
|
|
if( pTarget == NULL )
|
|
{
|
|
query_msg.handle = hTarget;
|
|
m_pGame->SendMsg( &query_msg );
|
|
|
|
#ifndef NDEBUG
|
|
_oprint( "공격 메세지 : Target 찾을 수 없다.\n" );
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::OnMsgAttackDouble( struct SMSG_ATTACK_DOUBLE* pMsg )
|
|
{
|
|
// _oprint( "OnMsgAttackDouble\n" );
|
|
SGameAvatarEx * pAttacker = NULL;
|
|
SGameAvatarEx * pTarget = NULL;
|
|
|
|
pAttacker = (SGameAvatarEx *)GetObject( pMsg->attacker_handle );
|
|
pTarget = (SGameAvatarEx *)GetObject( pMsg->target_handle );
|
|
|
|
if( pTarget )
|
|
{
|
|
pMsg->pos_target = pTarget->GetCurPosWithChangeDir();
|
|
}
|
|
|
|
OnAttack( pAttacker, pTarget, pMsg->attacker_handle, pMsg->target_handle, pMsg );
|
|
|
|
|
|
}
|
|
|
|
//공격, 스킬, 명령 관련=====================================================
|
|
void SCommandSystem::OnMsgAttack ( SMSG_ATTACK* pMsg )
|
|
{
|
|
SGameAvatarEx * pAttacker = NULL;
|
|
SGameAvatarEx * pTarget = NULL;
|
|
|
|
pAttacker = (SGameAvatarEx *)GetObject( pMsg->attacker_handle );
|
|
pTarget = (SGameAvatarEx *)GetObject( pMsg->target_handle );
|
|
|
|
if( pTarget )
|
|
{
|
|
pMsg->pos_target = pTarget->GetCurPosWithChangeDir();
|
|
}
|
|
|
|
OnAttack( pAttacker, pTarget, pMsg->attacker_handle, pMsg->target_handle, pMsg );
|
|
}
|
|
|
|
void SCommandSystem::AddAction( struct SGameMessage* pMsg )
|
|
{
|
|
if (m_pActionMgr) m_pActionMgr->AddAction( pMsg );
|
|
}
|
|
|
|
//스킬
|
|
void SCommandSystem::OnMsgSkillEvent( struct SMSG_SKILL_EVENT* pMsg )
|
|
{
|
|
if( pMsg->status_type == TS_SC_SKILL::FIRE ) //뭔가 발사 되거나, 행동을 취한다.
|
|
{
|
|
std::vector<SkillResult>::iterator it;
|
|
|
|
for( it = pMsg->vSkillResult.begin(); it != pMsg->vSkillResult.end(); ++it )
|
|
{
|
|
if( (*it).GetType() == SkillResult::RUSH ) {
|
|
if( (*it).rush.bResult ) {
|
|
K3DVector vPos = K3DVector( (*it).rush.x, (*it).rush.y, 0.0f );
|
|
WORD wTile=0;
|
|
m_pGame->GetHeight( vPos.x, vPos.y, vPos.z,wTile );
|
|
m_pArObject->onMove( pMsg->caster,
|
|
ArPosition( vPos.x, vPos.y, vPos.z ),
|
|
(*it).rush.speed );
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
SGameAvatarEx * pAvatar = (SGameAvatarEx *)GetObject( pMsg->caster );
|
|
if( !pAvatar ) return;
|
|
|
|
//WORK에서 호출 하도록 변경됨 ( 몬스터만 )
|
|
if( pAvatar->GetObjType() != TS_ENTER::GAME_MOB )
|
|
{
|
|
if (m_pActionMgr) m_pActionMgr->AddAction( pMsg );
|
|
}
|
|
|
|
pAvatar->OnNetInput( pMsg );
|
|
}
|
|
else if( pMsg->status_type == TS_SC_SKILL::CASTING ) //캐스팅이다~
|
|
{
|
|
SGameAvatarEx * pAvatar = (SGameAvatarEx *)GetObject( pMsg->caster );
|
|
if( pAvatar )
|
|
{
|
|
pAvatar->OnNetInput( pMsg );
|
|
|
|
|
|
K3DVector tpos; tpos.x = pMsg->x; tpos.y = pMsg->y; tpos.z = pMsg->z;
|
|
pAvatar->SetViewVector( tpos ); //몸통 방향 바꾸기
|
|
|
|
//if( vTargetPos.y == GetPosition()->y && vTargetPos.x == GetPosition()->x )
|
|
//m_fTargetRoll = atan2( vTargetPos.y-GetPosition()->y, vTargetPos.x-GetPosition()->x );
|
|
//m_dwPrevTime = m_dwTime;
|
|
//m_bUseRot = true;
|
|
|
|
/* if( pMsg->cast.nErrorCode == RESULT_NOT_ENOUGH_HP ||
|
|
pMsg->cast.nErrorCode == RESULT_NOT_ENOUGH_MP ||
|
|
pMsg->cast.nErrorCode == RESULT_COOL_TIME )
|
|
{
|
|
// pAvatar->CheckPrevState();
|
|
}*/
|
|
|
|
/// 2011.01.20 - prodongi
|
|
if (4003 == pMsg->skill_id && pAvatar->IsLocalPlayer())
|
|
{
|
|
setIsTaming(true);
|
|
}
|
|
}
|
|
}
|
|
else if( pMsg->status_type == TS_SC_SKILL::CASTING_UPDATE )
|
|
{
|
|
SGameAvatarEx * pAvatar = (SGameAvatarEx *)GetObject( pMsg->caster );
|
|
if( pAvatar )
|
|
pAvatar->OnNetInput( pMsg );
|
|
}
|
|
else if( pMsg->status_type == TS_SC_SKILL::CANCEL )
|
|
{
|
|
SGameAvatarEx * pAvatar = (SGameAvatarEx *)GetObject( pMsg->caster );
|
|
if( pAvatar )
|
|
pAvatar->OnNetInput( pMsg );
|
|
|
|
RemoveReservationObject(true);
|
|
|
|
/// 2011.01.20 - prodongi
|
|
if (4003 == pMsg->skill_id && pAvatar->IsLocalPlayer())
|
|
{
|
|
setIsTaming(false);
|
|
}
|
|
}
|
|
else if( pMsg->status_type == TS_SC_SKILL::REGION_FIRE )
|
|
{
|
|
if (m_pActionMgr) m_pActionMgr->AddAction( pMsg );
|
|
|
|
SGameAvatarEx * pAvatar = (SGameAvatarEx *)GetObject( pMsg->caster );
|
|
if( pAvatar )
|
|
pAvatar->OnNetInput( pMsg );
|
|
}
|
|
else if( pMsg->status_type == TS_SC_SKILL::COMPLETE )
|
|
{
|
|
SGameAvatarEx * pAvatar = (SGameAvatarEx *)GetObject( pMsg->caster );
|
|
if( pAvatar )
|
|
pAvatar->OnNetInput( pMsg );
|
|
}
|
|
}
|
|
|
|
////스킬 범위 데미지
|
|
//void SCommandSystem::OnMsgSkillEffect( SMSG_SKILL_EFFECT* pMsg )
|
|
//{
|
|
// _oprint( "스킬 범위 데미지\n" );
|
|
//
|
|
// m_pActionMgr->AddAction( pMsg );
|
|
//}
|
|
|
|
//명령
|
|
void SCommandSystem::OnMsgCmd ( SMSG_CMD_RESULT* pMsg )
|
|
{
|
|
//Object 찾아서 하라고 시킴.
|
|
}
|
|
|
|
//타기
|
|
void SCommandSystem::OnMsgMount( SMSG_MOUNT_SUMMON* pMsg )
|
|
{
|
|
SGameAvatarEx* pAvatar = (SGameAvatarEx *)GetObject( pMsg->handle );
|
|
SGameAvatarEx* pCreature = (SGameAvatarEx *)GetObject( pMsg->summon_handle );
|
|
|
|
if( pAvatar && pCreature )
|
|
{
|
|
DeleteRidingObject( pMsg->handle, pMsg->summon_handle );
|
|
|
|
if( !pMsg->success )
|
|
{
|
|
//타기 실패
|
|
// pAvatar->SetNormalMode();
|
|
return;
|
|
}
|
|
|
|
//살짝쿵 위치 보정
|
|
K3DVector vPos = K3DVector( pMsg->x, pMsg->y, 0.0f );
|
|
WORD wTile=0;
|
|
m_pGame->GetHeight( vPos.x, vPos.y, vPos.z,wTile );
|
|
m_pArObject->onMove( pMsg->handle,
|
|
ArPosition( vPos.x, vPos.y, vPos.z ),
|
|
(unsigned char)140 );
|
|
|
|
m_pArObject->onMove( pMsg->summon_handle,
|
|
ArPosition( vPos.x, vPos.y, vPos.z ),
|
|
(unsigned char)140 );
|
|
|
|
pAvatar->SetMountMode();
|
|
pCreature->SetMountMode();
|
|
|
|
pAvatar->OnNetInput( pMsg );
|
|
pCreature->OnNetInput( pMsg );
|
|
}
|
|
else if( pAvatar == NULL || pCreature == NULL)
|
|
{
|
|
//플레이어 및 크리처를 찾을수 없다면
|
|
AddRidingObject( pMsg->handle, pMsg->summon_handle, true );
|
|
}
|
|
}
|
|
//내리기
|
|
void SCommandSystem::OnMsgUnMount( SMSG_UNMOUNT_SUMMON* pMsg )
|
|
{
|
|
SGameAvatarEx* pAvatar = (SGameAvatarEx *)GetObject( pMsg->handle );
|
|
SGameAvatarEx* pCreature = (SGameAvatarEx *)GetObject( pMsg->summon_handle );
|
|
if(pAvatar && pCreature )
|
|
{
|
|
// 2009.02.03 kappamind. 크리처 탑승 후, 이동중 내리기를 하면 나타나던 오류를
|
|
// 내리기를 선택 시 그자리에 멈추게 한 후 동작되게 변경.
|
|
|
|
/// 2012.08.08 로컬 플레이어 일 때만 적용해 준다 - prodongi
|
|
if( pAvatar->IsLocalPlayer() )
|
|
{
|
|
SetPlayerAndCreaturePosition( pMsg );
|
|
}
|
|
|
|
DeleteRidingObject( pMsg->handle, pMsg->summon_handle );
|
|
|
|
//로컬 플레이어가 아닐경우 바로 노멀 모드로
|
|
if( !pAvatar->IsLocalPlayer() )
|
|
{
|
|
pAvatar->SetNormalMode();
|
|
pCreature->SetNormalMode();
|
|
}
|
|
|
|
pAvatar->OnNetInput( pMsg );
|
|
pCreature->OnNetInput( pMsg );
|
|
}
|
|
else if( pAvatar == NULL || pCreature == NULL )
|
|
{
|
|
//플레이어 및 크리처를 찾을수 없다면
|
|
AddRidingObject( pMsg->handle, pMsg->summon_handle, false );
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::OnMount( const StateInfoEx* pStateInfoEx, SGameAvatarEx* pPlayer, bool bWithEffect )
|
|
{
|
|
if( pPlayer == NULL || pStateInfoEx == NULL ) return;
|
|
|
|
AR_HANDLE hCreature = pPlayer->GetArID() + 1000000000;
|
|
|
|
SMSG_ENTER entermsg;// = (SMSG_ENTER*)pEnterMsg;
|
|
|
|
entermsg.handle = hCreature;
|
|
entermsg.x = pPlayer->GetPosition()->x;
|
|
entermsg.y = pPlayer->GetPosition()->y;
|
|
entermsg.z = pPlayer->GetPosition()->z;
|
|
entermsg.layer = 0;
|
|
entermsg.nType = MSG_ENTER;
|
|
entermsg.type = TS_ENTER::NPC;
|
|
entermsg.ObjType = TS_ENTER::GAME_SUMMON;
|
|
|
|
char* pEnterMsg = new char[sizeof(SMSG_ENTER)+sizeof(SMSG_ENTER::SummonInfo)];
|
|
memcpy( pEnterMsg, &entermsg, sizeof(SMSG_ENTER) );
|
|
|
|
SMSG_ENTER* pEnterSummon = (SMSG_ENTER*)pEnterMsg;
|
|
SMSG_ENTER::SummonInfo * pCretureInfo = (SMSG_ENTER::SummonInfo *)(pEnterSummon+1);
|
|
pCretureInfo->hp = 1;
|
|
pCretureInfo->mp = 1;
|
|
pCretureInfo->max_hp = 1;
|
|
pCretureInfo->max_mp = 1;
|
|
pCretureInfo->level = 1;
|
|
pCretureInfo->master_handle = pPlayer->GetArID();
|
|
pCretureInfo->summon_code = pStateInfoEx->fValue[1];
|
|
pCretureInfo->energy = 0;
|
|
pCretureInfo->face_direction = 0;
|
|
// 2011.3.4 marine - enhance 초기화
|
|
pCretureInfo->enhance = 0;
|
|
|
|
strcpy( pCretureInfo->szName, "summon" );
|
|
|
|
AddTransportCreature( pEnterSummon, pPlayer );
|
|
|
|
SAFE_DELETE_ARRAY( pEnterMsg );
|
|
|
|
SWorkMountWithOutAnimation* pMount = NULL;
|
|
if( bWithEffect )
|
|
pMount = new SWorkMountWithOutAnimation( pPlayer, hCreature, pStateInfoEx->fValue[2], pStateInfoEx->fValue[3] );
|
|
else
|
|
pMount = new SWorkMountWithOutAnimation( pPlayer, hCreature, 0, 0 );
|
|
|
|
pPlayer->AllWorkEnd();
|
|
pPlayer->AddWork( pMount );
|
|
}
|
|
|
|
void SCommandSystem::OnUnMount( const struct StateInfoEx* pStateInfoEx, SGameAvatarEx* pPlayer, bool bForceUnMount )
|
|
{
|
|
if( pPlayer == NULL ) return;
|
|
|
|
AR_HANDLE hCreature = pPlayer->GetTransportCreatureHandle();
|
|
|
|
if( hCreature == 0 ) return;
|
|
|
|
SMSG_LEAVE msgleave;
|
|
msgleave.handle = hCreature;
|
|
|
|
OnMsgLeave( &msgleave );
|
|
|
|
if( bForceUnMount )
|
|
{
|
|
pPlayer->SetMotionBlend( true );
|
|
|
|
pPlayer->SetNormalMode();
|
|
pPlayer->SetRiderCreatureInfo();
|
|
pPlayer->SetDefaultView();
|
|
|
|
if( pPlayer->IsMoving() ) pPlayer->Run();
|
|
else pPlayer->Default();
|
|
|
|
return;
|
|
}
|
|
|
|
SWorkUnMountWithOutAnimation* pUnMount = NULL;
|
|
|
|
if( pStateInfoEx == NULL )
|
|
pUnMount = new SWorkUnMountWithOutAnimation( pPlayer, hCreature, 0, 0 );
|
|
else
|
|
pUnMount = new SWorkUnMountWithOutAnimation( pPlayer, hCreature, pStateInfoEx->fValue[4], pStateInfoEx->fValue[5] );
|
|
|
|
pPlayer->AllWorkEnd();
|
|
pPlayer->AddWork( pUnMount );
|
|
}
|
|
|
|
//Item 관련=================================================================
|
|
void SCommandSystem::OnMsgTakeResult( SMSG_ITEM_TAKE* pMsg )
|
|
{
|
|
int x = 0;
|
|
// _oprint( "SCommandSystem::아이템 먹었다\n" );
|
|
}
|
|
|
|
void SCommandSystem::OnMsgDropResult( SMSG_ITEM_DROP* pMsg )
|
|
{
|
|
//몬스터가 가진 아이템은 보여 주지 않는다.
|
|
unsigned int nDropItemSize = m_vMobDropItemList.size();
|
|
for( unsigned int i(0); nDropItemSize>i; i++ )
|
|
{
|
|
if( m_vMobDropItemList[i].item_handle == pMsg->item_handle )
|
|
return;
|
|
}
|
|
|
|
SGameAvatarEx * pItem = NULL;
|
|
if( m_hashObject.lookup( pMsg->item_handle, pItem ) )
|
|
{
|
|
pItem->Activate();
|
|
}
|
|
|
|
// assert( 0 && "아이템 에러 : 보여줄 아이템을 찾을 수 없다!!!" );
|
|
}
|
|
|
|
void SCommandSystem::OnMsgDropInfo ( SMSG_ITEM_DROP_INFO* pMsg )
|
|
{
|
|
/// 2010.11.23 - prodongi
|
|
/*
|
|
//몹이 떨어 트리는, 아이템
|
|
DROP_INFO drop_info;
|
|
drop_info.item_handle = pMsg->item_handle;
|
|
drop_info.mob_handle = pMsg->monster_handle;
|
|
m_vMobDropItemList.push_back( drop_info );
|
|
|
|
SGameAvatarEx* pMob = (SGameAvatarEx*)GetObject( pMsg->monster_handle );
|
|
if( pMob )
|
|
{
|
|
//내가 떨굴 아이템
|
|
pMob->SetDropItemInfo( pMsg->item_handle );
|
|
}
|
|
else
|
|
{
|
|
_oprint( "아이템을 보여 줄 수 없다.\n" );
|
|
}
|
|
*/
|
|
}
|
|
|
|
void SCommandSystem::OnMsgWearInfo ( SMSG_ITEM_WEAR* pMsg )
|
|
{
|
|
//Local Player
|
|
SGameAvatarEx* pPlayer = GetAvatar( pMsg->handle );
|
|
if( !pPlayer ) return;
|
|
|
|
//쌓여 있는 것을 지운다.
|
|
pPlayer->ClearThreadLoadWear();
|
|
|
|
int nRace = 0, nSex = 0;
|
|
for( int j(0); ItemBase::WEAR_FACE >= j; j++ ) //WEAR_FACE까지가 기본 장비
|
|
{
|
|
nRace = pPlayer->GetRace();
|
|
nSex = pPlayer->GetSex();
|
|
|
|
pPlayer->SetItemCodeLevel( j, pMsg->nItemCode[j], pMsg->nItemLevel[j] );
|
|
|
|
SGameAvatarEx::WEAR_DATA weardata;
|
|
if( pMsg->nItemCode[j] < 10000 ) //기본 Mesh
|
|
{
|
|
if( pMsg->nItemCode[j] != 0 ) weardata.strFileName = GetDefaultItemDB().GetFileName( nRace, nSex, pMsg->nItemCode[j] );
|
|
else weardata.strFileName = "_NoItem_";
|
|
|
|
weardata.nItemCode = pMsg->nItemCode[j];
|
|
|
|
weardata.nItemClass = 0;
|
|
weardata.nItemLevel = 0;
|
|
weardata.nItemEnhanceLevel = 0;
|
|
}
|
|
else //Item
|
|
{
|
|
// 2012. 7. 24 - marine 아이템 형상변환.. 형상변환 아이템 코드가 있으면 모델과 텍스쳐를 바꿔준다.
|
|
if( pMsg->nAppearanceItemCode[j] )
|
|
{
|
|
weardata.strFileName = GetItemDB().GetFileName( nRace, nSex, pMsg->nAppearanceItemCode[j], pMsg->nItemLevel[j] );
|
|
weardata.strTextureName = GetItemDB().GetAdditionalTexture(pMsg->nAppearanceItemCode[j]);
|
|
weardata.nItemClass = GetItemDB().GetClassID( pMsg->nAppearanceItemCode[j] );
|
|
}
|
|
else
|
|
{
|
|
weardata.strFileName = GetItemDB().GetFileName( nRace, nSex, pMsg->nItemCode[j], pMsg->nItemLevel[j] );
|
|
weardata.strTextureName = GetItemDB().GetAdditionalTexture(pMsg->nItemCode[j]);
|
|
weardata.nItemClass = GetItemDB().GetClassID( pMsg->nItemCode[j] );
|
|
}
|
|
|
|
weardata.strFileName += ".nx3";
|
|
weardata.nItemCode = pMsg->nItemCode[j];
|
|
weardata.nItemLevel = pMsg->nItemLevel[j];
|
|
weardata.nItemEnhanceLevel = pMsg->nItemEnhance[j];
|
|
weardata.cElementalEffect = pMsg->elemental_effect_type[j];
|
|
weardata.nAppearanceItemCode = pMsg->nAppearanceItemCode[j];
|
|
}
|
|
|
|
|
|
|
|
ItemBase::ItemWearType nDecoWearType = ItemBase::WEAR_NONE;
|
|
switch( j )
|
|
{
|
|
case ItemBase::WEAR_WEAPON: nDecoWearType = ItemBase::WEAR_DECO_WEAPON; break;
|
|
case ItemBase::WEAR_SHIELD: nDecoWearType = ItemBase::WEAR_DECO_SHIELD; break;
|
|
case ItemBase::WEAR_ARMOR: nDecoWearType = ItemBase::WEAR_DECO_ARMOR; break;
|
|
case ItemBase::WEAR_HELM: nDecoWearType = ItemBase::WEAR_DECO_HELM; break;
|
|
case ItemBase::WEAR_GLOVE: nDecoWearType = ItemBase::WEAR_DECO_GLOVE; break;
|
|
case ItemBase::WEAR_BOOTS: nDecoWearType = ItemBase::WEAR_DECO_BOOTS; break;
|
|
case ItemBase::WEAR_MANTLE: nDecoWearType = ItemBase::WEAR_DECO_MANTLE; break;
|
|
|
|
|
|
}
|
|
|
|
if( nDecoWearType != ItemBase::WEAR_NONE )
|
|
{
|
|
if( pMsg->nItemCode[nDecoWearType] != 0 )
|
|
{
|
|
if( pMsg->nAppearanceItemCode[nDecoWearType] != 0 )
|
|
{
|
|
weardata.strDecoFileName = GetItemDB().GetFileName( nRace, nSex, pMsg->nAppearanceItemCode[nDecoWearType], pMsg->nAppearanceItemCode[nDecoWearType] );
|
|
weardata.strDecoTextureName = GetItemDB().GetAdditionalTexture( pMsg->nAppearanceItemCode[nDecoWearType] );
|
|
weardata.nDecoItemClass = GetItemDB().GetClassID( pMsg->nAppearanceItemCode[nDecoWearType] );
|
|
}
|
|
else
|
|
{
|
|
weardata.strDecoFileName = GetItemDB().GetFileName( nRace, nSex, pMsg->nItemCode[nDecoWearType], pMsg->nItemLevel[nDecoWearType] );
|
|
weardata.strDecoTextureName = GetItemDB().GetAdditionalTexture( pMsg->nItemCode[nDecoWearType] );
|
|
weardata.nDecoItemClass = GetItemDB().GetClassID( pMsg->nItemCode[nDecoWearType] );
|
|
}
|
|
|
|
weardata.strDecoFileName += ".nx3";
|
|
weardata.nDecoItemCode = pMsg->nItemCode[nDecoWearType];
|
|
weardata.bAttachDecoItem = GetItemDB().GetDecoModelChange( pMsg->nItemCode[nDecoWearType] );
|
|
|
|
weardata.bWithDecoItem = true;
|
|
weardata.nAppearanceItemCode = pMsg->nAppearanceItemCode[nDecoWearType];
|
|
|
|
pPlayer->SetItemCodeLevel( nDecoWearType, pMsg->nItemCode[nDecoWearType], pMsg->nItemLevel[nDecoWearType] );
|
|
}
|
|
}
|
|
|
|
weardata.nWearType = j;
|
|
pPlayer->AddThreadItemWear( weardata );
|
|
}
|
|
|
|
|
|
ItemBase::ItemWearType itemwear = ItemBase::WEAR_BACKPACK;
|
|
if( pMsg->nItemCode[itemwear] != 0 )
|
|
{
|
|
SGameAvatarEx::WEAR_DATA weardata;
|
|
|
|
if( pMsg->nAppearanceItemCode[itemwear] != 0 )
|
|
{
|
|
weardata.strDecoFileName = GetItemDB().GetFileName( nRace, nSex, pMsg->nAppearanceItemCode[itemwear], pMsg->nAppearanceItemCode[itemwear] );
|
|
weardata.strDecoTextureName = GetItemDB().GetAdditionalTexture( pMsg->nAppearanceItemCode[itemwear] );
|
|
weardata.nDecoItemClass = GetItemDB().GetClassID( pMsg->nAppearanceItemCode[itemwear] );
|
|
}
|
|
else
|
|
{
|
|
weardata.strDecoFileName = GetItemDB().GetFileName( nRace, nSex, pMsg->nItemCode[itemwear], pMsg->nItemLevel[itemwear] );
|
|
weardata.strDecoTextureName = GetItemDB().GetAdditionalTexture( pMsg->nItemCode[itemwear] );
|
|
weardata.nDecoItemClass = GetItemDB().GetClassID( pMsg->nItemCode[itemwear] );
|
|
}
|
|
|
|
weardata.strDecoFileName += ".nx3";
|
|
weardata.nItemCode = pMsg->nItemCode[itemwear];
|
|
weardata.nItemLevel = pMsg->nItemLevel[itemwear];
|
|
weardata.nItemEnhanceLevel = pMsg->nItemEnhance[itemwear];
|
|
weardata.cElementalEffect = pMsg->elemental_effect_type[itemwear];
|
|
weardata.nWearType = itemwear;
|
|
|
|
|
|
//어깨 장식이 출력되지 않아 수정함 2009.04.13 sfreer
|
|
weardata.nDecoItemCode = pMsg->nItemCode[itemwear];
|
|
weardata.bAttachDecoItem = GetItemDB().GetDecoModelChange( pMsg->nItemCode[itemwear] );
|
|
weardata.bWithDecoItem = true;
|
|
weardata.nAppearanceItemCode = pMsg->nAppearanceItemCode[itemwear];
|
|
|
|
|
|
|
|
pPlayer->SetItemCodeLevel( itemwear, pMsg->nItemCode[itemwear], pMsg->nItemLevel[itemwear] );
|
|
pPlayer->AddThreadItemWear( weardata );
|
|
}
|
|
|
|
itemwear = ItemBase::WEAR_DECO_SHOULDER;
|
|
if (pMsg->nItemCode[itemwear] != 0)
|
|
{
|
|
SGameAvatarEx::WEAR_DATA weardata;
|
|
|
|
if (pMsg->nAppearanceItemCode[itemwear] != 0)
|
|
{
|
|
weardata.strDecoFileName = GetItemDB().GetFileName(nRace, nSex, pMsg->nAppearanceItemCode[itemwear], pMsg->nAppearanceItemCode[itemwear]);
|
|
weardata.strDecoTextureName = GetItemDB().GetAdditionalTexture(pMsg->nAppearanceItemCode[itemwear]);
|
|
weardata.nDecoItemClass = GetItemDB().GetClassID(pMsg->nAppearanceItemCode[itemwear]);
|
|
}
|
|
else
|
|
{
|
|
weardata.strDecoFileName = GetItemDB().GetFileName(nRace, nSex, pMsg->nItemCode[itemwear], pMsg->nItemLevel[itemwear]);
|
|
weardata.strDecoTextureName = GetItemDB().GetAdditionalTexture(pMsg->nItemCode[itemwear]);
|
|
weardata.nDecoItemClass = GetItemDB().GetClassID(pMsg->nItemCode[itemwear]);
|
|
}
|
|
|
|
weardata.strDecoFileName += ".nx3";
|
|
weardata.nItemCode = pMsg->nItemCode[itemwear];
|
|
weardata.nItemLevel = pMsg->nItemLevel[itemwear];
|
|
weardata.nItemEnhanceLevel = pMsg->nItemEnhance[itemwear];
|
|
weardata.cElementalEffect = pMsg->elemental_effect_type[itemwear];
|
|
weardata.nWearType = itemwear;
|
|
|
|
//어깨 장식이 출력되지 않아 수정함 2009.04.13 sfreer
|
|
weardata.nDecoItemCode = pMsg->nItemCode[itemwear];
|
|
weardata.bAttachDecoItem = GetItemDB().GetDecoModelChange(pMsg->nItemCode[itemwear]);
|
|
weardata.bWithDecoItem = true;
|
|
weardata.nAppearanceItemCode = pMsg->nAppearanceItemCode[itemwear];
|
|
|
|
pPlayer->SetItemCodeLevel(itemwear, pMsg->nItemCode[itemwear], pMsg->nItemLevel[itemwear]);
|
|
pPlayer->AddThreadItemWear(weardata);
|
|
}
|
|
|
|
|
|
//itemwear = ItemBase::WEAR_DECO_HAIR;
|
|
//if( pMsg->nItemCode[itemwear] != 0 )
|
|
//{
|
|
// SGameAvatarEx::WEAR_DATA weardata;
|
|
// weardata.strDecoFileName = GetItemDB().GetFileName( nRace, nSex, pMsg->nItemCode[itemwear], pMsg->nItemLevel[itemwear] );
|
|
// weardata.strDecoFileName += ".nx3";
|
|
//
|
|
// weardata.nItemClass = GetItemDB().GetClassID( pMsg->nItemCode[itemwear] );
|
|
// weardata.nItemCode = pMsg->nItemCode[itemwear];
|
|
// weardata.nItemLevel = pMsg->nItemLevel[itemwear];
|
|
// weardata.nItemEnhanceLevel = pMsg->nItemEnhance[itemwear];
|
|
// weardata.cElementalEffect = pMsg->elemental_effect_type[itemwear];
|
|
// weardata.nWearType = itemwear;
|
|
//
|
|
// weardata.nDecoItemCode = pMsg->nItemCode[itemwear];
|
|
// weardata.bAttachDecoItem = GetItemDB().GetDecoModelChange( pMsg->nItemCode[itemwear] );
|
|
// weardata.bWithDecoItem = true;
|
|
//
|
|
// pPlayer->SetItemCodeLevel( itemwear, pMsg->nItemCode[itemwear], pMsg->nItemLevel[itemwear] );
|
|
// pPlayer->AddThreadItemWear( weardata );
|
|
//}
|
|
}
|
|
|
|
|
|
void SCommandSystem::OnMsgBoothClosed( struct SMSG_BOOTH_CLOSED * pMsg )
|
|
{
|
|
SGameAvatarEx * pAvatar = static_cast< SGameAvatarEx * >( GetObject( pMsg->hTarget ) );
|
|
if( !pAvatar ) return;
|
|
|
|
static_cast< SGameOtherPlayer* >( pAvatar )->SetBoothName( "" );
|
|
}
|
|
|
|
void SCommandSystem::OnMsgBoothName ( struct SMSG_BOOTH_NAME* pMsg )
|
|
{
|
|
for( size_t idx = 0; idx < pMsg->vBoothName.size(); ++idx )
|
|
{
|
|
SGameAvatarEx * pAvatar = static_cast< SGameAvatarEx * >( GetObject( pMsg->vBoothName[idx].handle ) );
|
|
if( !pAvatar ) continue;
|
|
static_cast< SGameOtherPlayer* >( pAvatar )->SetBoothName( pMsg->vBoothName[idx].name );
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::OnMsgProperty ( SMSG_PROPERTY* pGameMsg )
|
|
{
|
|
SGameAvatarEx * pAvatar = (SGameAvatarEx *)GetObject(pGameMsg->handle);
|
|
if( !pAvatar ) return;
|
|
|
|
if( pGameMsg->nPropertyType == SMSG_PROPERTY::PROPERTY_JOB_LEVEL )
|
|
{
|
|
if( pAvatar->SetJobLevel( atoi(pGameMsg->strValue.c_str()) ) )
|
|
{
|
|
AR_HANDLE handle = pAvatar->GetArID();
|
|
FX_DATA fx_data;
|
|
fx_data.attack = handle;
|
|
fx_data.owner = handle;
|
|
fx_data.target = handle;
|
|
fx_data.fPlayRate = 1.f;
|
|
fx_data.nEffPos = EFFECT_POS_BOTTOM;
|
|
fx_data.nPlayID = 1;
|
|
fx_data.nFX_ID = 8002;
|
|
|
|
m_pGame->AddEffect( &fx_data );
|
|
}
|
|
}
|
|
else if( pGameMsg->nPropertyType == SMSG_PROPERTY::PROPERTY_LEVEL )
|
|
{
|
|
if( pAvatar->SetLevel( atoi(pGameMsg->strValue.c_str()) ) )
|
|
{
|
|
AR_HANDLE handle = pAvatar->GetArID();
|
|
FX_DATA fx_data;
|
|
fx_data.attack = handle;
|
|
fx_data.owner = handle;
|
|
fx_data.target = handle;
|
|
fx_data.fPlayRate = 1.f;
|
|
fx_data.nEffPos = EFFECT_POS_BOTTOM;
|
|
fx_data.nPlayID = 1;
|
|
fx_data.nFX_ID = 8001;
|
|
|
|
m_pGame->AddEffect( &fx_data );
|
|
}
|
|
}
|
|
else if( pGameMsg->nPropertyType == SMSG_PROPERTY::PROPERTY_SEX )
|
|
{
|
|
pAvatar->SetSex( _ttoi( pGameMsg->strValue.c_str() ) );
|
|
pAvatar->SetReloadWearListFileName( true );
|
|
pAvatar->PendLoading();
|
|
}
|
|
else if( pGameMsg->nPropertyType == SMSG_PROPERTY::PROPERTY_HP )
|
|
{
|
|
pAvatar->ProcMsgAtStatic( pGameMsg );
|
|
}
|
|
/// 2011.07.11 - prodongi
|
|
else if (pGameMsg->nPropertyType == SMSG_PROPERTY::PROPERTY_JOB)
|
|
{
|
|
int oldJobId = pAvatar->GetJobID();
|
|
int newJobId = atoi(pGameMsg->strValue.c_str());
|
|
if (oldJobId != newJobId)
|
|
{
|
|
pAvatar->SetJobID(newJobId);
|
|
// 2011. 7. 12 - marine
|
|
if((pAvatar->IsMasterClass(newJobId)) && (oldJobId != 0))
|
|
{
|
|
AR_HANDLE handle = pAvatar->GetArID();
|
|
FX_DATA fx_data;
|
|
fx_data.attack = handle;
|
|
fx_data.owner = handle;
|
|
fx_data.target = handle;
|
|
fx_data.fPlayRate = 1.f;
|
|
fx_data.nEffPos = EFFECT_POS_BOTTOM;
|
|
fx_data.nPlayID = 1;
|
|
fx_data.nFX_ID = 8005;
|
|
|
|
m_pGame->AddEffect( &fx_data );
|
|
}
|
|
}
|
|
}
|
|
else if(pGameMsg->nPropertyType == SMSG_PROPERTY::PROPERTY_RACE)
|
|
{
|
|
int type = atoi(pGameMsg->strValue.c_str());
|
|
|
|
if( pAvatar->GetRace() == 0 )
|
|
return;
|
|
|
|
if( pAvatar->GetRace() != type)
|
|
{
|
|
pAvatar->SetRace(type);
|
|
pAvatar->SetReloadWearListFileName( true );
|
|
pAvatar->PendLoading();
|
|
}
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::OnMsgHPMP( SMSG_HPMP* pGameMsg )
|
|
{
|
|
/* SGameAvatarEx * pObject = (SGameAvatarEx*)GetObject( pGameMsg->handle );
|
|
if( pObject )
|
|
{
|
|
pObject->ProcMsgAtStatic( pGameMsg );
|
|
}*/
|
|
}
|
|
|
|
const int PRELOAD_LEVEL_VALUE = 95;
|
|
|
|
void SCommandSystem::OnMsgExpUpdate ( SMSG_EXP_UPDATE* pMsg )
|
|
{
|
|
SGameAvatarEx * pObject = (SGameAvatarEx*)GetObject( pMsg->handle );
|
|
if( pObject )
|
|
{
|
|
pObject->ProcMsgAtStatic( pMsg );
|
|
|
|
if( pObject->GetPercentEXP() > PRELOAD_LEVEL_VALUE )
|
|
{
|
|
SGamePreLoad preload;
|
|
preload.RequestThreadLoading( 8001 );
|
|
}
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::OnMsgState ( SMSG_STATE* pGameMsg )
|
|
{
|
|
// if( pGameMsg->state_code == 9004 )
|
|
// { //시크루드 패스는 처리 안함.
|
|
// return;
|
|
// }
|
|
|
|
SGameOption& gameoption = GetGameOption();
|
|
|
|
bool bNewStateEffect = true;
|
|
SGameAvatarEx * pObject = (SGameAvatarEx*)GetObject( pGameMsg->handle );
|
|
if( pObject )
|
|
{
|
|
// _oprint( "상태 이상 걸렸구나~\n" );
|
|
//상태 이상 추가
|
|
if( pGameMsg->state_level )
|
|
{
|
|
int nPos = 0;
|
|
SStateSlot* pOldState = pObject->GetOldStateInfo(pGameMsg, nPos);
|
|
SStateSlot* pOldCashState = pObject->GetOldCashStateInfo(pGameMsg, nPos);
|
|
|
|
if( pOldState )
|
|
{
|
|
if( pOldState->GetStateLevel() == pGameMsg->state_level ) bNewStateEffect = false;
|
|
}
|
|
|
|
if( pOldCashState )
|
|
{
|
|
if( pOldCashState->GetStateLevel() == pGameMsg->state_level ) bNewStateEffect = false;
|
|
}
|
|
|
|
pGameMsg->isNewState = bNewStateEffect; /// 2012.02.01 - prodongi
|
|
|
|
if( bNewStateEffect )
|
|
{
|
|
//기존 상태이상 이펙트는 삭제
|
|
m_pGame->DelStateEffect( pGameMsg );
|
|
|
|
//상태 이상은 따라다님.
|
|
bool bAdd = false;
|
|
unsigned char Type;
|
|
int handleType = m_pGame->IsFriend(pGameMsg->handle, Type);
|
|
if( (handleType==SUIDisplayInfo::LocalPlayer || handleType==SUIDisplayInfo::Creature) && gameoption.IsStatePlayerEftRend() )
|
|
bAdd = true;
|
|
else if( (handleType==SUIDisplayInfo::Party || handleType==SUIDisplayInfo::PartyCreature) && gameoption.IsStatePartyEftRend() )
|
|
bAdd = true;
|
|
else
|
|
{
|
|
if( gameoption.IsStateEnemyEftRend() )
|
|
bAdd = true;
|
|
}
|
|
|
|
if( pObject->GetStatus() & TS_ENTER::CreatureInfo::FLAG_INVISIBLE ||
|
|
pObject->GetStateFlag() & SGameAvatarEx::FLAG_STATE_HIDING )
|
|
{
|
|
bAdd = false; //Invisible모드이거나 은신모드일경우 이펙트를 보여주지 않는다
|
|
}
|
|
|
|
if( bAdd ) m_pGame->AddStateEffect( pGameMsg );
|
|
}
|
|
else
|
|
{
|
|
m_pGame->UpdateStateEffect( pGameMsg );
|
|
}
|
|
|
|
}
|
|
//상태 이상 삭제 한다.
|
|
else if( pGameMsg->state_level == 0 )
|
|
{
|
|
m_pGame->DelStateEffect( pGameMsg );
|
|
}
|
|
|
|
pObject->ProcMsgAtStatic( pGameMsg );
|
|
}
|
|
|
|
if( pObject == NULL ) return;
|
|
|
|
StateInfoEx* pStateInfo = GetTenacityDB().GetTenacityData( pGameMsg->state_code );
|
|
if( pStateInfo )
|
|
{
|
|
switch( pStateInfo->effect_type )
|
|
{
|
|
case STATE_TYPE::STATE_RIDING:
|
|
{
|
|
if( pObject->GetObjType() == TS_ENTER::GAME_PLAYER )
|
|
{
|
|
if( pGameMsg->state_level > 0 && bNewStateEffect )
|
|
{
|
|
OnUnMount( pStateInfo, pObject, true );
|
|
OnMount( pStateInfo, pObject );
|
|
}
|
|
else if( pGameMsg->state_level == 0 )
|
|
{
|
|
OnUnMount( pStateInfo, pObject );
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case STATE_TYPE::STATE_MUTATION_B:
|
|
{
|
|
if( pGameMsg->state_level > 0 )
|
|
{
|
|
SIMSG_UI_CHANGE_DISPLAY_NAME disname( pObject->GetArID(), pGameMsg->state_string_value.c_str(), false );
|
|
m_pGame->SendGameInterfaceMsg( &disname );
|
|
}
|
|
else if( pGameMsg->state_level == 0 )
|
|
{
|
|
SIMSG_UI_CHANGE_DISPLAY_NAME disname( pObject->GetArID(), NULL, true );
|
|
m_pGame->SendGameInterfaceMsg( &disname );
|
|
}
|
|
}
|
|
break;
|
|
case STATE_TYPE::STATE_DETECT_HIDING:
|
|
{
|
|
if( pGameMsg->state_level == 0 ) //상태이상 종료
|
|
{
|
|
SGameAvatarEx* pGameObject = NULL;
|
|
KSortVector< class SGameAvatarEx* >::iterator it = m_svPlayerObject.begin();
|
|
while ( it != m_svPlayerObject.end() )
|
|
{
|
|
pGameObject = (*it);
|
|
if( !pGameObject->IsLocalPlayer() && pGameObject->GetObjType() == TS_ENTER::GAME_PLAYER )
|
|
{
|
|
if( pGameObject->GetStateFlag() & SGameAvatarEx::FLAG_STATE_HIDING )
|
|
pGameObject->SetHidingVisiblity( 0.0f );
|
|
}
|
|
++it;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::OnMsgInventory ( SMSG_ITEM_INVEN* pMsg )
|
|
{
|
|
//SGameAvatarEx* pPlayer = GetLocalPlayer(); //플레이어 핸들이 안넘어 온다 임시로 로컬 플에이어만 적용
|
|
//if( pPlayer == NULL ) return;
|
|
|
|
//bool bUpdate = false;
|
|
//SGameAvatarEx::WEAR_DATA weardata;
|
|
//weardata.strFileName = GetItemDB().GetFileName( pPlayer->GetRace(), pPlayer->GetSex(), pMsg->pItemInfo->Code, pMsg->pItemInfo->level );
|
|
//weardata.strFileName += ".nx3";
|
|
//std::string strWeaponName = weardata.strFileName;
|
|
//if( pMsg->pItemInfo->wear_position == ItemBase::WEAR_LEFTHAND )
|
|
//{
|
|
// strWeaponName.replace( strWeaponName.size() - 4, 1, "_L." );
|
|
// bUpdate = true;
|
|
//}
|
|
//else if( pMsg->pItemInfo->wear_position == ItemBase::WEAR_RIGHTHAND )
|
|
//{
|
|
// bUpdate = true;
|
|
//}
|
|
|
|
//if( bUpdate )
|
|
//{
|
|
// weardata.nItemClass = GetItemDB().GetClassID( pMsg->pItemInfo->Code );
|
|
// weardata.nWearType = pMsg->pItemInfo->wear_position;
|
|
// weardata.nItemCode = pMsg->pItemInfo->Code;
|
|
// weardata.nItemLevel = pMsg->pItemInfo->level;
|
|
// weardata.nItemEnhanceLevel = pMsg->pItemInfo->enhance;
|
|
|
|
// std::string strEffectPosName = "wfx_" + strWeaponName;
|
|
// pPlayer->SetWeaponInfo( pPlayer->GetSeqForm() , weardata, strEffectPosName.c_str() );
|
|
// pPlayer->RefreshEffectPos();
|
|
//}
|
|
}
|
|
|
|
void SCommandSystem::OnMsgItemUse()
|
|
{
|
|
|
|
}
|
|
|
|
void SCommandSystem::OnMsgItemDrop()
|
|
{
|
|
|
|
}
|
|
|
|
void SCommandSystem::OnMsgTakeItemResult( struct SMSG_TAKE_ITEM_RESULT* pMsg )
|
|
{
|
|
SGameAvatarEx* pItem = (SGameAvatarEx *)GetObject( pMsg->item_handle );
|
|
if( pItem && pItem->GetObjType() == TS_ENTER::GAME_ITEM )
|
|
{
|
|
SGameAvatarEx * pPlayer = (SGameAvatarEx *)GetObject( pMsg->item_taker );
|
|
if( pPlayer )
|
|
{
|
|
if( !pPlayer->IsMountMode() ) //탑승된 상태면 줍기 모션은 생략
|
|
{
|
|
SWorkPickUp* pPickUpWork = new SWorkPickUp( pPlayer, pItem );
|
|
pPlayer->AllWorkEnd();
|
|
pPlayer->AddWork( pPickUpWork );
|
|
}
|
|
}
|
|
|
|
SPetMgr* petMgr = static_cast< SPetMgr* >( GameUIMgrInstance.GetUIMgr( SGameUIInstance::PET_MGR ) );
|
|
SGameLocalPet* petAvatar = static_cast< SGameLocalPet* >( petMgr->GetSummonPetData().pet_avatar );
|
|
if (petAvatar != NULL)
|
|
{
|
|
petAvatar->DeleteItemFromIgnoreQueue(pMsg->item_handle);
|
|
} // 펫 자동줍기가 설정되어있을때 한번 줍기를 시도한 아이템은 10분간 다시 안 줍는데, 만일 줍는데 성공(인벤으로 들어옴)하면 안 주울 아이템 리스트에서 지워버려도 된다.
|
|
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::OnMsgLevelUpdate ( SMSG_LEVEL_UPDATE* pMsg )
|
|
{
|
|
//Level Update
|
|
SGameAvatarEx * pAvatar = (SGameAvatarEx *)GetObject(pMsg->handle);
|
|
if( pAvatar )
|
|
{
|
|
if( pAvatar->GetLevel() < pMsg->level && pAvatar->GetLevel() != 0 )
|
|
{
|
|
AR_HANDLE handle = pAvatar->GetArID();
|
|
FX_DATA fx_data;
|
|
fx_data.attack = handle;
|
|
fx_data.owner = handle;
|
|
fx_data.target = handle;
|
|
fx_data.fPlayRate = 1.f;
|
|
fx_data.nEffPos = EFFECT_POS_BOTTOM;
|
|
fx_data.nPlayID = 1;
|
|
fx_data.nFX_ID = 8001;
|
|
|
|
m_pGame->AddEffect( &fx_data );
|
|
|
|
SGameAvatarEx* pLocalPlayer = GetLocalPlayer();
|
|
if( pLocalPlayer )
|
|
{
|
|
if( pAvatar->GetArID() == pLocalPlayer->GetArID() )
|
|
m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_LV_UP ) );
|
|
}
|
|
}
|
|
|
|
pAvatar->SetLevel( pMsg->level );
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::OnMsgEmotion( SMSG_EMOTION* pMsg )
|
|
{
|
|
PlayerEmotion( pMsg->handle, pMsg->emotion );
|
|
}
|
|
|
|
void SCommandSystem::OnMsgAddOtherEffect( SGameMessage* pGameMsg )
|
|
{
|
|
if( m_pOtherEffecMgr == NULL ) return;
|
|
|
|
switch( pGameMsg->nType )
|
|
{
|
|
case MSG_GET_CHAOS:
|
|
{
|
|
SMSG_GET_CHAOS* pChaos = static_cast<SMSG_GET_CHAOS*>(pGameMsg);
|
|
SGameAvatarEx* pPlayer = GetLocalPlayer();
|
|
if( pPlayer )
|
|
{
|
|
if( pPlayer->GetArID() == pChaos->hPlayer )
|
|
{
|
|
// sonador 3.10.2 PC 방 혜택 관련 라크 획득 시스템 메시지 변경
|
|
if( pChaos->nBonusType == SMSG_GET_CHAOS::CHAOS_BONUS_PCBANG ||
|
|
pChaos->nBonusType == SMSG_GET_CHAOS::CHAOS_BONUS_PREMIUM_PCBANG )
|
|
((SGameLocalPlayer*)pPlayer)->SetLakSize( pChaos->nChaos, pChaos->nBonus, pChaos->nBonusPercent, pChaos->nBonusType );
|
|
else
|
|
((SGameLocalPlayer*)pPlayer)->SetLakSize( pChaos->nChaos, -1, 0, SMSG_GET_CHAOS::CHAOS_BONUS_NONE );
|
|
}
|
|
}
|
|
m_pOtherEffecMgr->AddChaosEffect( pChaos );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
int SCommandSystem::OnAddOtherEffect( int nFxID, struct OtherFxData* fxdata )
|
|
{
|
|
if( m_pOtherEffecMgr == NULL ) return 0;
|
|
|
|
switch( nFxID )
|
|
{
|
|
case SGameOtherEffectMng::FX_CREATURE_EVOLUTION:
|
|
{
|
|
return m_pOtherEffecMgr->AddCreatureEvolutionEffect( nFxID, fxdata );
|
|
}
|
|
case SGameOtherEffectMng::FX_CAST_SUMMONING_CREATURE:
|
|
{
|
|
return m_pOtherEffecMgr->AddCastSummoningCreatureEffect( nFxID, fxdata );
|
|
}
|
|
case SGameOtherEffectMng::FX_SUMMONING_CREATURE:
|
|
{
|
|
return m_pOtherEffecMgr->AddSummoningCreatureEffect( nFxID, fxdata );
|
|
}
|
|
case SGameOtherEffectMng::FX_UN_SUMMONING_CREATURE:
|
|
{
|
|
return m_pOtherEffecMgr->AddUnSummoningCreatureEffect( nFxID, fxdata );
|
|
}
|
|
case SGameOtherEffectMng::FX_MONSTER_TAMING:
|
|
{
|
|
return m_pOtherEffecMgr->AddMonsterTamingEffect( nFxID, fxdata );
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void SCommandSystem::SetNextStepOtherEffect( int nFxID )
|
|
{
|
|
if( m_pOtherEffecMgr )
|
|
m_pOtherEffecMgr->SetNextStepOtherEffect( nFxID );
|
|
}
|
|
|
|
void SCommandSystem::SetNextStepOtherEffect( AR_HANDLE hHandle, int nFxType, bool bCheckTargetHandle )
|
|
{
|
|
if( m_pOtherEffecMgr )
|
|
m_pOtherEffecMgr->SetNextStepOtherEffect( hHandle, nFxType, bCheckTargetHandle );
|
|
}
|
|
|
|
void SCommandSystem::EndOtherEffect( int nFxID )
|
|
{
|
|
if( m_pOtherEffecMgr ) m_pOtherEffecMgr->EndOtherEffect( nFxID );
|
|
}
|
|
|
|
void SCommandSystem::EndOtherEffect( AR_HANDLE hHandle, int nFxType, bool bCheckTargetHandle )
|
|
{
|
|
if( m_pOtherEffecMgr ) m_pOtherEffecMgr->EndOtherEffect( hHandle, nFxType, bCheckTargetHandle );
|
|
}
|
|
|
|
void SCommandSystem::SetCircleShadowEnable(bool bEnable)
|
|
{
|
|
m_bCircleShadowEnable = bEnable;
|
|
if(m_bCircleShadowEnable)
|
|
{
|
|
for_each(m_svObject.begin(), m_svObject.end(), std::mem_fun<void>(&SGameAvatarEx::ActivateCircleShadow) );
|
|
}
|
|
else
|
|
{
|
|
for_each(m_svObject.begin(), m_svObject.end(), std::mem_fun<void>(&SGameAvatarEx::DeActivateCircleShadow) );
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::SetEffectSpeed( float fSpeed )
|
|
{
|
|
if( m_pActionMgr ) m_pActionMgr->SetSpeed( fSpeed );
|
|
}
|
|
|
|
void SCommandSystem::OnMsgAddForceSphere( SMSG_ENERGY* pMsg )
|
|
{
|
|
SGameAvatarEx* pPlayer = (SGameAvatarEx*)GetObject( pMsg->handle );
|
|
if( pPlayer )
|
|
{
|
|
pPlayer->OnMsgForceSphere( pMsg->energy );
|
|
pPlayer->m_nEnergy = pMsg->energy;
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::OnTamingInfo( SMSG_TAMING_INFO* pMsg )
|
|
{
|
|
if( pMsg->mode == 0 ) //테이밍 걸었다면 이펙트 생김
|
|
OnAddOtherEffect( SGameOtherEffectMng::FX_MONSTER_TAMING, &OtherFxData( 0, pMsg->target_handle, 0 ) );
|
|
else if( pMsg->mode == 1 ) //테이밍 초기화 됐다면 이펙트 삭제
|
|
EndOtherEffect( pMsg->target_handle, SGameOtherEffectMng::FX_MONSTER_TAMING, true );
|
|
else if( pMsg->mode == 2 || pMsg->mode == 3 ) //테이밍 성공 됐다면 마지막 이펙트 플레이
|
|
{
|
|
FX_DATA fx_data;
|
|
fx_data.attack = pMsg->target_handle;
|
|
fx_data.owner = pMsg->target_handle;
|
|
fx_data.target = pMsg->target_handle;
|
|
fx_data.fPlayRate = 1.f;
|
|
fx_data.nEffPos = EFFECT_POS_TOP;
|
|
fx_data.nPlayID = 1;
|
|
|
|
if( pMsg->mode == 2 ) //테이밍 성공
|
|
{
|
|
fx_data.nFX_ID = 18018;
|
|
}
|
|
else //테이밍 실패
|
|
{
|
|
fx_data.nFX_ID = 18019;
|
|
}
|
|
|
|
m_pGame->AddEffect( &fx_data );
|
|
EndOtherEffect( pMsg->target_handle, SGameOtherEffectMng::FX_MONSTER_TAMING, true );
|
|
|
|
// SetNextStepOtherEffect( pMsg->target_handle, SGameOtherEffectMng::FX_MONSTER_TAMING, true );
|
|
}
|
|
/* else if( pMsg->mode == 3 ) //테이밍 실패 했다면 마지막 이펙트 플레이
|
|
{
|
|
SetNextStepOtherEffect( pMsg->target_handle, SGameOtherEffectMng::FX_MONSTER_TAMING, true );
|
|
}*/
|
|
|
|
/*
|
|
SGameAvatarEx* pPlayer = GetLocalPlayer();
|
|
if( !pPlayer ) return;
|
|
if( pMsg->tamer_handle == pPlayer->GetArID() )
|
|
{
|
|
|
|
if( pMsg->mode == 0 ) //테이밍 걸었음
|
|
{
|
|
int nCode = GetMonsterNameID( pMsg->target_handle );
|
|
if( nCode != -1 )
|
|
m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_CREATURE_TAME_SUCCESS, nCode ) );
|
|
}
|
|
else if( pMsg->mode == 1 )
|
|
m_pGame->AddChatMessage( "테이밍 초기화 됨" );
|
|
테이밍 성공 실패 메세지를 파티원들에게 뿌려주기로 설정이 바뀌어서 서버에서 파티쳇으로 방송하기로 결정
|
|
else if( pMsg->mode == 2 ) //테이밍 성공
|
|
{
|
|
int nCode = GetMonsterNameID( pMsg->target_handle );
|
|
if( nCode != -1 )
|
|
m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_CREATURE_TAME_SUCCESS_BONUS, nCode ) );
|
|
}
|
|
else if( pMsg->mode == 3 ) //테이밍 실패
|
|
{
|
|
int nCode = GetMonsterNameID( pMsg->target_handle );
|
|
if( nCode != -1 )
|
|
m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_CREATURE_TAME_DISAPPEAR, nCode ) );
|
|
}
|
|
}
|
|
*/
|
|
/// 2011.01.20 - prodongi
|
|
if (SMSG_TAMING_INFO::START == pMsg->mode)
|
|
{
|
|
setIsTaming(true);
|
|
}
|
|
else
|
|
{
|
|
setIsTaming(false);
|
|
}
|
|
}
|
|
|
|
int SCommandSystem::GetCretureNameID( AR_HANDLE handle )
|
|
{
|
|
SGameAvatarEx* pMonster = (SGameAvatarEx*)GetObject( handle );
|
|
if( pMonster )
|
|
return pMonster->GetContentID();
|
|
return -1;
|
|
}
|
|
|
|
int SCommandSystem::GetMonsterNameID( AR_HANDLE handle )
|
|
{
|
|
SGameAvatarEx* pMonster = (SGameAvatarEx*)GetObject( handle );
|
|
if( pMonster )
|
|
return pMonster->GetContentID();
|
|
return -1;
|
|
}
|
|
|
|
void SCommandSystem::SetSkyType( DWORD dwSkyType )
|
|
{
|
|
BOOL bShadowRender = FALSE;
|
|
if( dwSkyType == 0 || dwSkyType == 2 ) //1은 하늘 도시임
|
|
bShadowRender = TRUE;
|
|
|
|
SGameAvatarEx* pGameObject = NULL;
|
|
KSortVector< class SGameAvatarEx* >::iterator it = m_svObject.begin();
|
|
while ( it != m_svObject.end() )
|
|
{
|
|
pGameObject = (*it); ++it;
|
|
if ( pGameObject != NULL )
|
|
{
|
|
pGameObject->SetShadowRenderFlag( bShadowRender );
|
|
}
|
|
}
|
|
}
|
|
|
|
//===================================================================================================
|
|
//Cheating 관련
|
|
//Warp
|
|
//다른 방법을 연구 해 보자...
|
|
void SCommandSystem::OnMsgWarp( SCMSG_WARP* pMsg )
|
|
{
|
|
//이동할 넘을 찾은 다음에~
|
|
//이동 시키자~
|
|
//맵 로딩과, Leave, Enter 는 어떻게 처리 하나?
|
|
|
|
SGameAvatarEx* pAvatar = GetLocalPlayer();
|
|
if( pAvatar )
|
|
{
|
|
SWorkWarp * pWarpWork = new SWorkWarp( pAvatar, pMsg );
|
|
pAvatar->AllWorkEnd();
|
|
pAvatar->AddWork( pWarpWork );
|
|
|
|
pAvatar->ClearPendingNextState();
|
|
|
|
pAvatar->InputFreezing(); //워프가 완료 되기 전까지 입력 안 되도록 설정
|
|
|
|
pAvatar->SetIng( false );
|
|
|
|
//마운트 모드이면 크리처도 같은 위치로 워프 시킨다
|
|
if( pAvatar->IsMountMode() )
|
|
{
|
|
SGameAvatarEx* pCreature = (SGameAvatarEx*)GetObject( pAvatar->GetCreatureMountHandle() );
|
|
if( pCreature == NULL ) pCreature = GetTransportCreatureObject( pAvatar->GetCreatureMountHandle() );
|
|
|
|
if( pCreature )
|
|
{
|
|
pCreature->SetArObjectPos( pMsg->x, pMsg->y, pMsg->z, pMsg->layer );
|
|
float fHeight = 0.f;
|
|
WORD wTile=0;
|
|
pAvatar->GetHeight(pMsg->x,pMsg->y,fHeight,wTile);
|
|
pCreature->SetPosition( K3DVector( pMsg->x, pMsg->y, fHeight ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//===================================================================================================
|
|
//Target 관련
|
|
SGameAvatarEx * SCommandSystem::GetNextTarget( float fMaxLen, bool bIsResetTargetList )
|
|
{
|
|
if( bIsResetTargetList ) //타겟 리스트를 새로 작성해야 한다면
|
|
m_pTargetMgr->ClearTargetList();
|
|
|
|
K3DVector cullPosition;
|
|
if( GetLocalPlayer() )
|
|
{
|
|
cullPosition = *GetLocalPlayer()->GetPosition();
|
|
}
|
|
|
|
if( !m_pTargetMgr->IsTarget() )
|
|
{
|
|
K3DVector mypos;
|
|
float fLen = 0.f;
|
|
|
|
SGameAvatarEx* pGameObject = NULL;
|
|
KSortVector< class SGameAvatarEx* >::iterator it = m_svObject.begin();
|
|
while ( it != m_svObject.end() )
|
|
{
|
|
pGameObject = (*it); ++it;
|
|
|
|
if( pGameObject == NULL ) continue;
|
|
|
|
if( pGameObject->IsLocalPlayer() || pGameObject->IsLocalCreature() ) continue;
|
|
|
|
if( pGameObject->GetObjType() == TS_ENTER::GAME_MOB ||
|
|
pGameObject->GetObjType() == TS_ENTER::GAME_PLAYER ||
|
|
pGameObject->GetObjType() == TS_ENTER::GAME_SUMMON )
|
|
{
|
|
if( pGameObject->IsActivated() && pGameObject->GetHP() != 0 && pGameObject->IsRender() )
|
|
{
|
|
//탈것 이용시 z축 값에 문제가 있어서 일단 임시 수정 2009.08.24 sfreer
|
|
K3DVector local = cullPosition;
|
|
K3DVector object = *pGameObject->GetPosition();
|
|
local.z = 0;
|
|
object.z = 0;
|
|
|
|
float fLen = GetDistance( local, object);
|
|
if( fLen < fMaxLen )
|
|
{
|
|
//자동 타겟에 넣는다. 거리는 임의이기 때문에 자동타겟 거리는 별도로 나중에 수정 하자.
|
|
if( pGameObject->GetObjType() != TS_ENTER::GAME_MOB )
|
|
{
|
|
if( m_pGame->IsAttack( pGameObject ) == false )
|
|
pGameObject = NULL;
|
|
}
|
|
|
|
if( pGameObject )
|
|
m_pTargetMgr->AddTarget( pGameObject );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( m_pTargetMgr->IsTarget() )
|
|
{
|
|
//LocalPlayer 중심으로 소팅
|
|
m_pTargetMgr->SortTarget( &cullPosition );
|
|
}
|
|
|
|
return m_pTargetMgr->GetNextTarget();
|
|
};
|
|
|
|
void SCommandSystem::OnMsgItemResult( SMSG_USE_ITEM_RESULT* pMsg )
|
|
{
|
|
SGameAvatarEx * pAvatar = NULL;
|
|
if( pMsg->target_handle == 0 )
|
|
{
|
|
pAvatar = GetLocalPlayer();
|
|
if( pAvatar )
|
|
{
|
|
pAvatar->OnNetInput( pMsg );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pAvatar = (SGameAvatarEx *)GetObject( pMsg->target_handle );
|
|
if( pAvatar )
|
|
{
|
|
pAvatar->OnNetInput( pMsg );
|
|
}
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::MoveImpossibleMsg()
|
|
{
|
|
m_pGame->SendGameInterfaceMsg( &SIMSG_UI_DISPLAY_SYS_MSG( SYS_MSG_MOVE_IMPOSSIBLE ) );
|
|
}
|
|
|
|
void SCommandSystem::DeleteRenderBooth()
|
|
{
|
|
SGameAvatarEx* pGameObject = NULL;
|
|
KSortVector< class SGameAvatarEx* >::iterator it = m_svPlayerObject.begin();
|
|
while ( it != m_svPlayerObject.end() )
|
|
{
|
|
pGameObject = (*it);
|
|
if( !pGameObject->IsLocalPlayer() && pGameObject->GetObjType() == TS_ENTER::GAME_PLAYER )
|
|
{
|
|
((SGameOtherPlayer*)pGameObject)->DeleteRenderBooth();
|
|
}
|
|
++it;
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::refreshWinkAllPlayerObj()
|
|
{
|
|
KSortVector< class SGameAvatarEx* >::iterator it = m_svPlayerObject.begin();
|
|
while ( it != m_svPlayerObject.end() )
|
|
{
|
|
(*it)->refreshWinkByOption();
|
|
++it;
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::getOtherObjectList(std::vector<SGameAvatarEx*>& objList)
|
|
{
|
|
objList.clear();
|
|
objList.assign(m_svOtherObject.begin(), m_svOtherObject.end());
|
|
}
|
|
|
|
void SCommandSystem::addCustomBlock(SGameFieldQuestProp* prop)
|
|
{
|
|
/// 2012.06.26 이동 불가 프랍일 경우에 블럭 정보 추가 - prodongi
|
|
FieldPropResource* res = GetFieldPropResourceDB().GetFieldPropResource(prop->GetQuestPropDBID());
|
|
/// 이동 제한, 타입을 따로 정의해 놓은게 없다.. 정의가 필요할 것 같긴 한데,,우선 이렇게 함
|
|
if (res && 50 == res->type)
|
|
{
|
|
CTerrainMapEngine* mapEngine = m_pGame->getTerrainMapEngine();
|
|
if (mapEngine)
|
|
{
|
|
int blockLine[4];
|
|
prop->getBlockLine(blockLine);
|
|
mapEngine->addCustomBlock(prop->GetArID(), blockLine);
|
|
}
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::delCustomBlock(AR_HANDLE handle)
|
|
{
|
|
SGameAvatarEx* avatar = (SGameAvatarEx*)m_pGame->GetGameObject(handle);
|
|
if (!avatar)
|
|
return ;
|
|
/// 이동 블럭 프랍일 경우에는 지형 엔진에서 해당 내용을 삭제해 줘야 한다
|
|
if (TS_ENTER::GAME_FIELD_PROP == avatar->GetObjType())
|
|
{
|
|
SGameFieldQuestProp* prop = dynamicCast<SGameFieldQuestProp*>(avatar);
|
|
if (prop)
|
|
{
|
|
FieldPropResource* res = GetFieldPropResourceDB().GetFieldPropResource(prop->GetQuestPropDBID());
|
|
if (res && 50 == res->type)
|
|
{
|
|
CTerrainMapEngine* mapEngine = m_pGame->getTerrainMapEngine();
|
|
if (mapEngine)
|
|
{
|
|
mapEngine->delCustomBlock(prop->GetArID());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void SCommandSystem::OnMsgKMove(SMSG_KMOVE* pMsg)
|
|
{
|
|
{
|
|
m_pArObject->onMultiMove( pMsg->handle, ArPosition(pMsg->pos_target.x,pMsg->pos_target.y, pMsg->pos_target.z), pMsg->m_vecMoveInfo, pMsg->speed, pMsg->start_time );
|
|
}
|
|
|
|
SGameAvatarEx * pAvatar = NULL;
|
|
if( m_hashObject.lookup( pMsg->handle, pAvatar ) )
|
|
{
|
|
if( pAvatar->IsPendLoading() )
|
|
ActivatePendLoadingListByMove( pAvatar );
|
|
|
|
pAvatar->OnNetInput( pMsg );
|
|
|
|
//플레이어냐?
|
|
if( pAvatar->GetObjType() == TS_ENTER::GAME_PLAYER )
|
|
{
|
|
//로컬 플레이어 이동 시 타겟 리스트 삭제 한다.
|
|
if( pAvatar->IsLocalPlayer() )
|
|
m_pTargetMgr->ClearTargetList();
|
|
|
|
// if( pAvatar->IsMountMode() )
|
|
{
|
|
if( pAvatar->GetCreatureMountHandle() )
|
|
{
|
|
m_pArObject->onMultiMove( pAvatar->GetCreatureMountHandle(), ArPosition(pMsg->pos_target.x,pMsg->pos_target.y, pMsg->pos_target.z), pMsg->m_vecMoveInfo, pMsg->speed, pMsg->start_time );
|
|
|
|
SGameAvatarEx* pCreature = pAvatar->GetRiderCreatureObject();
|
|
if( pCreature )
|
|
{
|
|
pCreature->OnNetInput( pMsg );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
{
|
|
//Enter 를 강제로 해달라~
|
|
TS_CS_QUERY query_msg;
|
|
query_msg.handle = pMsg->handle;
|
|
m_pGame->SendMsg( &query_msg );
|
|
}
|
|
}
|
|
|
|
bool SCommandSystem::IsTarget()
|
|
{
|
|
return m_pTargetMgr->IsTarget();
|
|
} |