#include "SunClientPrecompiledHeader.h" #include "Player.h" #include "Hero.h" #include "Rider.h" #include "NpcInfoParser.h" #include "GameFunc.h" #include "ResourceManager.h" #include "RiderContainer.h" #include "RidingInfoParser.h" #include "ItemInfoParser.h" #include "GlobalFunc.h" #include "ObjectManager.h" #include "ObjectAniEventController.h" #include "GlobalData.h" #include "Object.h" const WzVector c_wvUp = { 0.0f, 0.0f, 1.0f }; //------------------------------------------------------------------------------ /** */ Rider::Rider( void ): m_bSetInterpolate(FALSE), m_iLinkNode(-1), body_skin_(0), effect_code_(0), is_interpoate_(false), interpolate_axis_(c_UpVector), prev_axis_(c_UpVector), current_animation_(0), prev_angle_(0.f), is_spread_(0) { MatrixIdentity(&rotate_matrix()); memset(&m_vLinkPos,0,sizeof(m_vLinkPos)); memset(&m_ppRenderPart,0,sizeof(m_ppRenderPart)); InitializeEffect(); //! ÃʱâÈ­ m_Color = 0xffffffff; } //------------------------------------------------------------------------------ /** */ Rider::~Rider( void ) { Destroy(); } //------------------------------------------------------------------------------ /** */ BOOL Rider::Create(DWORD dwRiderIndex, Player* master_ptr, BOOL summon_effect) { const sRiderInfo* rider_info = RidingInfoParser::Instance()->GetInfo(dwRiderIndex); if(rider_info == NULL) { assert(!"Á¸ÀçÇÏÁö¾Ê´Â ¶óÀÌ´õÀ妽º"); return FALSE; } BASE_NPCINFO *pInfo = NPCInfoParser::Instance()->GetNPCInfo( rider_info->monster_code_); if(pInfo == NULL) { assert(!"¶óÀÌ´õ¸ó½ºÅÍÄÚµå Á¸Àç¾ÈÇÔ"); return FALSE; } body_skin_ = ResourceManager::Instance()->GetNPCSkinResourceCode(pInfo->m_MonsterCode); m_Animaping = rider_info->anicode_[0]; m_dwRiderIndex = dwRiderIndex; if (summon_effect) { set_effect_code(rider_info->spawn_effect_code_); } //¿ÀºêÁ§Æ®°ªÀÌ Á¸ÀçÇÏ¸é ¼ÒȯÇѰÍÀÌ´Ù. RefreshApperRider(master_ptr); return TRUE; } //------------------------------------------------------------------------------ /** */ bool Rider::RefreshApperRider(Player* master_ptr) { if ( master_ptr != NULL && master_ptr->IsUseDelayLoading() ) { return false; } if (GetRenderPart()) { return false; } ResourceManager* resource_instance = ResourceManager::Instance(); m_ppRenderPart[RP_BASE] = resource_instance->AllocResourceUnitDraw(body_skin_, -1.f, false); if (m_ppRenderPart[RP_BASE] && GetRenderPart()->GetWzUnit()) { WzBoneInfo *pBaseInfo = GetRenderPart()->GetWzUnit()->GetBoneInfo(StrToWzID("LINK")); if (pBaseInfo) { m_iLinkNode = pBaseInfo->m_iNode; } //ÀÌÆåÆ® ÄÚµå Á¸Àç½Ã Ãâ·Â(Player°¡ ÀÔÀå»óÅ¿¡¼­ È£ÃâÇßÀ»°æ¿ì¿¡´Â ÀÌÆåÆ®Á¸ÀçÇϰí) //´Ù¸¥À¯Àú°¡ Å»°Í¼Òȯ»óÅ¿¡¼­ Á¤º¸¸¦ ¹ÞÀ»¶§³ª ¸¶À»¿¡ ÀÔÀå½Ã¿¡´Â ¾È¶ç¿î´Ù if (effect_code()) { GlobalFunc::CreateEffectBeUpToOption(effect_code(), master_ptr->GetVisiblePos()); } m_bSetInterpolate = TRUE; } if (master_ptr) { if (master_ptr->GetCurState() == STATE::MOVE) { // À̵¿ ÁßÀ̾ú´Ù¸é ¶óÀÌ´õ ¹«ºê ¾Ö´Ï¸ÞÀ̼ÇÀ¸·Î WzID master_anicode = GlobalFunc::GetPlayerAnimationByRiding(eANI_RUN, GetAniMapping()); master_ptr->SetPlayerAnimation(master_anicode, eANI_RUN, TRUE); } else { //¿¬Ãâ:Å»°Í ¸®¼Ò½º ¼ÒȯÈÄ¿¡ ¹Ù·Î IDLE ¾Ö´Ï¸ÞÀ̼ǽÃÄÑÁØ´Ù ePLAYER_ANI rider_anicode = ((rand() % 2) == 1) ? (eANI_IDLE):(eANI_IDLE2); WzID master_anicode = GlobalFunc::GetPlayerAnimationByRiding(rider_anicode, GetAniMapping()); master_ptr->SetPlayerAnimation(master_anicode, rider_anicode, FALSE); } } return true; } //------------------------------------------------------------------------------ /** */ void Rider::SetSubtype(int nPartIdx,int nSubType) { //0Àº º£À̽ºÆÄÃ÷ÀÓ nPartIdx += RP_BODY; if(nPartIdxGetSubTypeNum(); if(nSubType>nNum) { assert(!"¼­ºêŸÀÔÀÌ ¾øÀ½"); return; } m_ppRenderPart[nPartIdx]->SetSubType(nSubType); } } } //------------------------------------------------------------------------------ /** */ void Rider::SetScale(WzVector vScale) { for(int i=0;iSetScale(vScale.x,vScale.y,vScale.z); } } } //------------------------------------------------------------------------------ /** */ void Rider::EnableFunction(BOOL bFlag) { for(int i=0;iEnableCustomLight(bFlag); m_ppRenderPart[i]->EnableShadowCast(bFlag); m_ppRenderPart[i]->EnableShadowReceive(bFlag); } } } //------------------------------------------------------------------------------ /** ÀÎÀÚ·Î µé¾î¿À´Â ¶óÀÌ´õ °´Ã¼·ÎºÎÅÍ ¶óÀÌ´õ¸¦ º¹»çÇØ³½´Ù.(¼­ºêŸÀÔ¹×½ºÅ²) */ void Rider::CopyRider(Rider *pRider, bool is_with_parts/* = true*/) { CWzUnitDraw* pSrc = pRider->GetRenderPart(); //¿øº» CWzUnitDraw* pDest = GetRenderPart(); //º¹»çµÇ¾îÁú(this) //ÇöÀç ¹Ùµð°¡ ÇÒ´çÀ̾ȵȻóŶó¸éÇÒ´çÇÑ´Ù. if(pSrc && pSrc->GetWzUnit()) { if(!pDest) { m_ppRenderPart[RP_BASE] = ResourceManager::Instance()->AllocResourceUnitDraw(pSrc->GetWzUnit()->GetType()); } else { //µÑ´ÙÀִµ¥ ŸÀÔÀÌ ´Ù¸£´Ù¸é if((pDest->GetWzUnit() == NULL) || (pSrc->GetWzUnit()->GetType()!=pDest->GetWzUnit()->GetType())) { //ÇØÁ¦Çϰí ResourceManager::Instance()->FreeResourceUnitDraw(m_ppRenderPart[RP_BASE]); //¹Ùµð ÇÒ´çÇÑ´Ù m_ppRenderPart[RP_BASE]= ResourceManager::Instance()->AllocResourceUnitDraw(pSrc->GetWzUnit()->GetType()); m_dwRiderIndex=pRider->GetRiderIndex(); } } } if (is_with_parts) { //ÀåºñÆÄÃ÷ for(int i=RP_BODY;iGetRenderPart(i); //¿øº» pDest = GetRenderPart(i); //º¹»çµÇ¾îÁú(this) //ºñÇÒ´çÀϰæ¿ì if(!pDest) { //¿øº»Á¸ÀçÇÑ´Ù¸é ÇÒ´çÈÄ ¾Ö´ÏÂüÁ¶½ÃÄÑÁØ´Ù(ÆÄÃ÷À̱⶧¹®) if(pSrc && pSrc->GetWzUnit()) { m_ppRenderPart[i]=ResourceManager::Instance()->AllocResourceUnitDraw(pSrc->GetWzUnit()->GetType()); m_ppRenderPart[i]->SetSubType(pSrc->GetSubType()); m_ppRenderPart[i]->SetAniRefUnitDraw( GetRenderPart()); } } else { //¿øº»ÀÌ Á¸Àç && ³ªµµÁ¸Àç if(pSrc) { //µÑ´ÙÁ¸Àç½Ã ¸®¼Ò½ºÄڵ尡 ¸Â´ÂÁöüũÇÑ´Ù. if ((pDest->GetWzUnit() == NULL) || (pSrc->GetWzUnit()->GetType()!=pDest->GetWzUnit()->GetType())) { //ÇØÁ¦Çϰí ResourceManager::Instance()->FreeResourceUnitDraw(m_ppRenderPart[i]); //ÇÒ´çÇÑÈÄ m_ppRenderPart[i] = ResourceManager::Instance()->AllocResourceUnitDraw(pSrc->GetWzUnit()->GetType()); //¾Ö´Ï¹× ¼­ºêŸÀÔº¹»çÇØÁØ´Ù. m_ppRenderPart[i]->SetAniRefUnitDraw( GetRenderPart()); m_ppRenderPart[i]->SetSubType(pSrc->GetSubType()); } } else { if(pDest) { ResourceManager::Instance()->FreeResourceUnitDraw(m_ppRenderPart[i]); m_ppRenderPart[i] = NULL; } } } } } //if (is_with_parts) } //------------------------------------------------------------------------------ /** º¯È¯Á¤º¸¸¦ Player¸ÞÀÎÆÄÃ÷¿¡°Ô ¼ÂÆÃ½ÃÄÑÁØ´Ù. */ void Rider::Transform(CWzUnitDraw* pMaster) { if ((pMaster == NULL) || (GetRenderPart() == NULL)) { return; } const WzMatrix *pLinkMatrix = GetRenderPart()->GetTransformBuffer(); if (pLinkMatrix == NULL) { return; } static WzMatrix temp_matrix; memcpy(&temp_matrix, &pLinkMatrix[m_iLinkNode], sizeof(temp_matrix)); //1.Position: À§Ä¡ºÎºÐÀ» º¹»çÇÑ´Ù m_vLinkPos.x = temp_matrix._41; m_vLinkPos.y = temp_matrix._42; m_vLinkPos.z = temp_matrix._43; pMaster->SetPosition(m_vLinkPos, FALSE); //2.Rotation: ȸÀüºÎºÐÀ» º¹»çÇÑ´Ù temp_matrix._41 = 0.f; temp_matrix._42 = 0.f; temp_matrix._43 = 0.f; pMaster->SetRotationByMatrix(&temp_matrix); //3.FlagÀÖÀ»¶© º¸°£¾øÀÌ ¹Ù·Î ºÙ°Ô²ûÇÑ´Ù if(m_bSetInterpolate) { m_bSetInterpolate = FALSE; pMaster->SetInterpolationFrame(0); } } //------------------------------------------------------------------------------ /** ¶óÀÌ´õ´Â Á÷Á¢¸ÞÆ®¸¯½º¸¦ ÁöÇü¿¡ ¸Â°Ô ºÙ¿©Áà¾ßÇÑ´Ù. ij¸¯ÅͶÇÇÑ Å»°Í¿¡ ź»óÅ¿¡¼­´Â ¸¸µé¾îÁø¸ÞÆ®¸¯½º¸¦ °øÀ¯ÇÑ´Ù. */ void Rider::SetRotation(const WzVector* normal_axis, float master_angle) { if ((is_interpoate() == false) && (prev_angle() == master_angle) && (prev_axis() == *normal_axis)) { return; } WzVector axis = *normal_axis; // check degree limit float axis_angle = n_rad2deg(acosf(VectorDotProduct(normal_axis, &c_UpVector))); if ((axis_angle < 20.f) || (axis_angle > 70.f)) { axis = c_UpVector; } // Interpolation float angle_diff = n_rad2deg(acosf(VectorDotProduct(&axis, &interpolate_axis()))); if ((angle_diff != 0.f) && (angle_diff > 5.f)) { set_is_interpoate(true); InterpolateVector(&axis, &axis, &interpolate_axis(), (5.f / angle_diff)); } else { set_is_interpoate(false); } // Generate Matrix WzVector dir = {sin(master_angle), -cos(master_angle), 0.f}; WzVector right; VectorCrossProduct(&right, &axis, &dir); VectorNormalize(&right, &right); VectorCrossProduct(&dir, &axis, &right); VectorNormalize(&dir, &dir); memset(&rotate_matrix(), 0, sizeof(rotate_matrix())); rotate_matrix()._11 = right.x; rotate_matrix()._12 = right.y; rotate_matrix()._13 = right.z; //XÃà rotate_matrix()._21 = dir.x; rotate_matrix()._22 = dir.y; rotate_matrix()._23 = dir.z; //YÃà rotate_matrix()._31 = axis.x; rotate_matrix()._32 = axis.y; rotate_matrix()._33 = axis.z;; //ZÃà rotate_matrix()._44 = 1.f; // Apply Matrix if (GetRenderPart()) { GetRenderPart()->SetRotationByMatrix(&rotate_matrix()); } set_prev_axis(*normal_axis); set_prev_angle(master_angle); set_interpolate_axis(axis); } //------------------------------------------------------------------------------ /** */ void Rider::SetForceLod(int iLod) { for(int i=0;iSetForcedLOD(iLod); } } } //------------------------------------------------------------------------------ /** */ void Rider::SetAnimation(WzID wzID,BOOL bLoop, BOOL bRestart) { DestroyAllLoopEffect(); if (current_animation_ == wzID) { return; } if (bLoop == TRUE) { bRestart = FALSE; } //BOOL restart_animation = (bLoop) ? (FALSE):(TRUE); if (GetRenderPart()) { GetRenderPart()->SetCurrentAnimation(wzID, bLoop, bRestart); current_animation_ = wzID; } } //------------------------------------------------------------------------------ /** */ BOOL Rider::Process(DWORD dwTick, Player* master_ptr) { if (GetRenderPart() != NULL) { static WzEvent ani_event; ZeroMemory(&ani_event, sizeof(ani_event)); g_pSunRenderer->ProgressUnitFrame(GetRenderPart(), (float)dwTick, &ani_event, ¤t_ani_progress_rate_); if (master_ptr != NULL) { EventInfo event_info(ani_event); if ((dwTick != 0) && ((master_ptr != g_pHero) || (g_pHero->GetShow() == TRUE))) { for (size_t i = 0; i != event_info.GetSoundEventCount(); ++i) { ProcessSoundEvent(event_info.GetSoundEvent(i), GetRenderPart()->GetPosition()); } } // ÀÌÆåÆ® À̺¥Æ® for (size_t i = 0; i < event_info.GetEffectEventCount(); ++i) { ProcessEffectEvent(event_info.GetEffectEvent(i), GetRenderPart(), GetRenderPart()->GetPosition(), master_ptr->GetDirection(), master_ptr->GetObjectKey()); } // Ä¿½ºÅÒ À̺¥Æ® for (size_t i = 0; i != event_info.GetCustomEventCount(); ++i) { ProcessCustomEvent(event_info.GetCustomEvent(i), master_ptr->GetPosition()); } } } return TRUE; } //------------------------------------------------------------------------------ /** */ BOOL Rider::Render() { WzColor oldColor = g_pSunRenderer->GetDiffuseColor(); g_pSunRenderer->SetColor(m_Color); for(int i=0;iCheckUnitLoaded(m_ppRenderPart[i])) { g_pSunRenderer->RenderUnit(m_ppRenderPart[i]); } } } g_pSunRenderer->SetColor(oldColor); return TRUE; } //------------------------------------------------------------------------------ /** */ BOOL Rider::Render(St_RenderCommand *pCommand) { //±×¿ÜÆÄÃ÷ for(int i=0;iCheckUnitLoaded(m_ppRenderPart[i])) { g_pSunRenderer->RenderUnit(m_ppRenderPart[i],pCommand); } } } return TRUE; } //------------------------------------------------------------------------------ /** */ void Rider::Destroy( void ) { for(int i=0;iFreeResourceUnitDraw(m_ppRenderPart[i]); m_ppRenderPart[i] = NULL; } } m_iLinkNode = -1; DestroyAllEffect(); } //------------------------------------------------------------------------------ /** */ void Rider::AnimateUnit(Player* master_ptr) { if (GetRenderPart()) { g_pSunRenderer->AnimateUnit(GetRenderPart()); if (master_ptr != NULL) { UpdateTrail(); UpdateEffectPos(GetRenderPart(), GetRenderPart()->GetPosition(), master_ptr->GetDirection()); } } } //------------------------------------------------------------------------------ /** ¶óÀÌ´õÆÄÃ÷Á¦°Å */ void Rider::DetachRiderPart(int nIdx) { nIdx+=RP_BODY; if(nIdx>RP_BASE && nIdxFreeResourceUnitDraw(m_ppRenderPart[nIdx]); m_ppRenderPart[nIdx] = NULL; } //Á¦°ÅÈÄ ½ºÅ©¸³Æ® ÂüÁ¶ º£À̽º½ºÅ²À» ´Þ¾ÆÁØ´Ù. const sRiderInfo* pInfo = RidingInfoParser::Instance()->GetInfo(m_dwRiderIndex); if(pInfo && (nIdx-1)>=0) { RESOURCECODE SkinCode = pInfo->base_skin[nIdx-1]; //0Àϰæ¿ì¿¡´Â º£À̽º ½ºÅ²ÀÌ ¾ø´Â°æ¿ìÀÌ´Ù. if(SkinCode!=0) { m_ppRenderPart[nIdx] = ResourceManager::Instance()->AllocResourceUnitDraw(ENGINE_RESOURCE_ID_OFFSET + SkinCode); m_ppRenderPart[nIdx]->SetAniRefUnitDraw( GetRenderPart()); } } } } //------------------------------------------------------------------------------ void Rider::DetachPart(const RiderParts& rider_parts) { if (rider_parts < RP_BODY && rider_parts >= RP_COUNT) { return; } if(m_ppRenderPart[rider_parts]) { ResourceManager::Instance()->FreeResourceUnitDraw(m_ppRenderPart[rider_parts]); m_ppRenderPart[rider_parts] = NULL; } //Á¦°ÅÈÄ ½ºÅ©¸³Æ® ÂüÁ¶ º£À̽º½ºÅ²À» ´Þ¾ÆÁØ´Ù. const sRiderInfo* rider_info = RidingInfoParser::Instance()->GetInfo(m_dwRiderIndex); if (rider_info != NULL) { RESOURCECODE skin_code = rider_info->base_skin[rider_parts - 1]; //0Àϰæ¿ì¿¡´Â º£À̽º ½ºÅ²ÀÌ ¾ø´Â°æ¿ìÀÌ´Ù. if (skin_code != 0) { m_ppRenderPart[rider_parts] = ResourceManager::Instance()->AllocResourceUnitDraw(ENGINE_RESOURCE_ID_OFFSET + skin_code); m_ppRenderPart[rider_parts]->SetAniRefUnitDraw(GetRenderPart()); } } } //------------------------------------------------------------------------------ /** ¶óÀÌ´õÆÄÃ÷ÀåÂø */ void Rider::AttachRiderPart(int nIdx, DWORD dwItemCode) { nIdx+=RP_BODY; if(nIdx>RP_BASE && nIdxGetItemInfo( dwItemCode ); if(!pInfo) { assert(!"¶óÀÌ´õ Àåºñ¾ÆÅÛÀÎÆ÷¾ø³ß"); return; } RESOURCECODE SkinCode = 0; //±âÁ¸¿¡ ¹«±â°¡ ÀåÂøµÇ¾îÀÖ¾ú´Ù¸ç ÇØÁ¦ if(m_ppRenderPart[nIdx] && m_ppRenderPart[nIdx]->GetWzUnit()) { SkinCode = m_ppRenderPart[nIdx]->GetWzUnit()->GetType(); //µ¿ÀÏÇѾÆÀÌÅÛÀ̸é ÀåÂøµÇ¾îÀÖÀ¸¸é º¹»çÇÏÁö¾Ê´Â´Ù. if(SkinCode!=ENGINE_RESOURCE_ID_OFFSET + pInfo->m_wWICode) { ResourceManager::Instance()->FreeResourceUnitDraw(m_ppRenderPart[nIdx]); m_ppRenderPart[nIdx] = NULL; } else { //no operation return; } } //¸®¼Ò½ºÇÒ´ç SkinCode = ENGINE_RESOURCE_ID_OFFSET + pInfo->m_wWICode; m_ppRenderPart[nIdx] = ResourceManager::Instance()->AllocResourceUnitDraw(SkinCode); //¾Ö´ÏÂüÁ¶½ÃÄÑÁÜ if(m_ppRenderPart[nIdx]) { m_ppRenderPart[nIdx]->SetAniRefUnitDraw( GetRenderPart()); } } } //------------------------------------------------------------------------------ /** ¶óÀÌ´õÆÄÃ÷ÀåÂø */ void Rider::CopyRiderBody(DWORD dwRiderIndex, Player* master_ptr) { const sRiderInfo* pInfo = RidingInfoParser::Instance()->GetInfo(dwRiderIndex); if(pInfo) { BASE_NPCINFO *pNpcInfo=NPCInfoParser::Instance()->GetNPCInfo( pInfo->monster_code_); if(!pNpcInfo) { return; } RESOURCECODE SkinCode= ResourceManager::Instance()->GetNPCSkinResourceCode(pNpcInfo->m_MonsterCode ); //¹Ùµð°¡ÀÖ±äÇÏ´Ù if(m_ppRenderPart[RP_BASE] && m_ppRenderPart[RP_BASE]->GetWzUnit()) { //BodyÀ̹ÌÁö°¡ ´Ù¸£´Ù Á¦°ÅÇÏ°í ´Ù½Ã ÇÒ´çÇØ¾ßÇÑ´Ù. if(m_ppRenderPart[RP_BASE]->GetWzUnit()->GetType()!=SkinCode) { ResourceManager::Instance()->FreeResourceUnitDraw(m_ppRenderPart[RP_BASE]); m_ppRenderPart[RP_BASE] = ResourceManager::Instance()->AllocResourceUnitDraw(SkinCode); m_dwRiderIndex=dwRiderIndex; } } else { //¹Ùµð°¡ ¾øÀ¸¸é ¸¸µç´Ù Create(dwRiderIndex, master_ptr, FALSE); } } } //------------------------------------------------------------------------------ bool Rider::is_possible_fly() { const sRiderInfo* rider_info = RidingInfoParser::Instance()->GetInfo(m_dwRiderIndex); if (rider_info) { return rider_info->flying_; } return false; }