Advertisement
Guest User

PetSystem.cpp

a guest
Jan 8th, 2021
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 18.16 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include "config.h"
  3. #include "utils.h"
  4. #include "vector.h"
  5. #include "char.h"
  6. #include "sectree_manager.h"
  7. #include "char_manager.h"
  8. #include "mob_manager.h"
  9. #include "PetSystem.h"
  10. #include "../../common/VnumHelper.h"
  11. #include "packet.h"
  12. #include "item_manager.h"
  13. #include "item.h"
  14. #include "../../common/CommonDefines.h"
  15.  
  16. EVENTINFO(petsystem_event_info)
  17. {
  18.     CPetSystem* pPetSystem;
  19. };
  20.  
  21. // PetSystemŔ» update ÇŘÁÖ´Â event.
  22. // PetSystemŔş CHRACTER_MANAGERżˇĽ­ ±âÁ¸ FSMŔ¸·Î update ÇŘÁÖ´Â ±âÁ¸ chractersżÍ ´Ţ¸®,
  23. // OwnerŔÇ STATE¸¦ update ÇŇ ¶§ _UpdateFollowAI ÇÔĽö·Î update ÇŘÁŘ´Ů.
  24. // ±×·±µĄ ownerŔÇ state¸¦ update¸¦ CHRACTER_MANAGERżˇĽ­ ÇŘÁֱ⠶§ą®żˇ,
  25. // petsystemŔ» updateÇĎ´Ů°ˇ petŔ» unsummonÇĎ´Â şÎşĐżˇĽ­ ą®Á¦°ˇ »ý°ĺ´Ů.
  26. // (CHRACTER_MANAGERżˇĽ­ update Çϸé chracter destroy°ˇ pendingµÇľî, CPetSystemżˇĽ­´Â dangling Ć÷ŔÎĹ͸¦ °ˇÁö°í ŔÖ°Ô µČ´Ů.)
  27. // µű¶óĽ­ PetSystem¸¸ ľ÷µĄŔĚĆ® ÇŘÁÖ´Â event¸¦ ąß»ý˝ĂĹ´.
  28. EVENTFUNC(petsystem_update_event)
  29. {
  30.     petsystem_event_info* info = dynamic_cast<petsystem_event_info*>( event->info );
  31.     if ( info == NULL )
  32.     {
  33.         sys_err( "check_speedhack_event> <Factor> Null pointer" );
  34.         return 0;
  35.     }
  36.  
  37.     CPetSystem* pPetSystem = info->pPetSystem;
  38.  
  39.     if (NULL == pPetSystem)
  40.         return 0;
  41.  
  42.  
  43.     pPetSystem->Update(0);
  44.     // 0.25Ăʸ¶´Ů °»˝Ĺ.
  45.     return PASSES_PER_SEC(1) / 4;
  46. }
  47.  
  48. /// NOTE: 1Äł¸ŻĹÍ°ˇ ¸î°łŔÇ ĆęŔ» °ˇÁú Ľö ŔÖ´ÂÁö Á¦ÇŃ... Äł¸ŻĹ͸¶´Ů °łĽö¸¦ ´Ů¸Ł°Ô ÇҰŶó¸é şŻĽö·Î łÖµî°ˇ... Ŕ˝..
  49. /// °ˇÁú Ľö ŔÖ´Â °łĽöżÍ µż˝Ăżˇ ĽŇČŻÇŇ Ľö ŔÖ´Â °łĽö°ˇ Ʋ¸± Ľö ŔִµĄ ŔĚ·±°Ç ±âČą ľřŔ¸´Ď ŔĎ´Ü ą«˝Ă
  50. const float PET_COUNT_LIMIT = 3;
  51.  
  52. ///////////////////////////////////////////////////////////////////////////////////////
  53. //  CPetActor
  54. ///////////////////////////////////////////////////////////////////////////////////////
  55.  
  56. CPetActor::CPetActor(LPCHARACTER owner, DWORD vnum, DWORD options)
  57. {
  58.     m_dwVnum = vnum;
  59.     m_dwVID = 0;
  60.     m_dwOptions = options;
  61.     m_dwLastActionTime = 0;
  62.  
  63.     m_pkChar = 0;
  64.     m_pkOwner = owner;
  65.  
  66.     m_originalMoveSpeed = 0;
  67.  
  68.     m_dwSummonItemVID = 0;
  69.     m_dwSummonItemVnum = 0;
  70. }
  71.  
  72. CPetActor::~CPetActor()
  73. {
  74.     this->Unsummon();
  75.  
  76.     m_pkOwner = 0;
  77. }
  78.  
  79. void CPetActor::SetName(const char* name)
  80. {
  81.     std::string petName = m_pkOwner->GetName();
  82.  
  83. #ifndef ENABLE_MULTI_LANGUAGE_SYSTEM
  84.     if (0 != m_pkOwner &&
  85.         0 == name &&
  86.         0 != m_pkOwner->GetName())
  87.     {
  88.         petName += "'s Pet";
  89.     }
  90.     else
  91.         petName += name;
  92. #endif
  93.  
  94.     if (true == IsSummoned())
  95.         m_pkChar->SetName(petName);
  96.  
  97.     m_name = petName;
  98. }
  99.  
  100. bool CPetActor::Mount()
  101. {
  102.     if (0 == m_pkOwner)
  103.         return false;
  104.  
  105.     if (true == HasOption(EPetOption_Mountable))
  106.         m_pkOwner->MountVnum(m_dwVnum);
  107.  
  108.     return m_pkOwner->GetMountVnum() == m_dwVnum;;
  109. }
  110.  
  111. void CPetActor::Unmount()
  112. {
  113.     if (0 == m_pkOwner)
  114.         return;
  115.  
  116.     if (m_pkOwner->IsHorseRiding())
  117.         m_pkOwner->StopRiding();
  118. }
  119.  
  120. void CPetActor::Unsummon()
  121. {
  122.     if (true == this->IsSummoned())
  123.     {
  124.         // ąöÇÁ »čÁ¦
  125.         this->ClearBuff();
  126.         this->SetSummonItem(NULL);
  127. /*
  128.         if (NULL != m_pkOwner)
  129.             m_pkOwner->ComputePoints();*/
  130.  
  131.         if (NULL != m_pkChar)
  132.             M2_DESTROY_CHARACTER(m_pkChar);
  133.  
  134.         m_pkChar = 0;
  135.         m_dwVID = 0;
  136.     }
  137. }
  138.  
  139. DWORD CPetActor::Summon(const char* petName, LPITEM pSummonItem, bool bSpawnFar)
  140. {
  141.     long x = m_pkOwner->GetX();
  142.     long y = m_pkOwner->GetY();
  143.     long z = m_pkOwner->GetZ();
  144.  
  145.     if (true == bSpawnFar)
  146.     {
  147.         x += (number(0, 1) * 2 - 1) * number(2000, 2500);
  148.         y += (number(0, 1) * 2 - 1) * number(2000, 2500);
  149.     }
  150.     else
  151.     {
  152.         x += number(-100, 100);
  153.         y += number(-100, 100);
  154.     }
  155.  
  156.     if (0 != m_pkChar)
  157.     {
  158.         m_pkChar->Show (m_pkOwner->GetMapIndex(), x, y);
  159.         m_dwVID = m_pkChar->GetVID();
  160.  
  161.         return m_dwVID;
  162.     }
  163.  
  164.     m_pkChar = CHARACTER_MANAGER::instance().SpawnMob(
  165.                 m_dwVnum,
  166.                 m_pkOwner->GetMapIndex(),
  167.                 x, y, z,
  168.                 false, (int)(m_pkOwner->GetRotation()+180), false);
  169.  
  170.     if (0 == m_pkChar)
  171.     {
  172.         sys_err("[CPetSystem::Summon] Failed to summon the pet. (vnum: %d)", m_dwVnum);
  173.         return 0;
  174.     }
  175.  
  176.     m_pkChar->SetPet();
  177.  
  178. //  m_pkOwner->DetailLog();
  179. //  m_pkChar->DetailLog();
  180.  
  181.     //ĆęŔÇ ±ą°ˇ¸¦ ÁÖŔÎŔÇ ±ą°ˇ·Î ĽłÁ¤ÇÔ.
  182.     m_pkChar->SetEmpire(m_pkOwner->GetEmpire());
  183.  
  184.     m_dwVID = m_pkChar->GetVID();
  185.  
  186.     this->SetName(petName);
  187.  
  188.     // SetSummonItem(pSummonItem)¸¦ şÎ¸Ą ČÄżˇ ComputePoints¸¦ şÎ¸Ł¸é ąöÇÁ ŔűżëµĘ.
  189.     this->SetSummonItem(pSummonItem);
  190.     m_pkOwner->ComputePoints();
  191.     m_pkChar->Show(m_pkOwner->GetMapIndex(), x, y, z);
  192.  
  193.     return m_dwVID;
  194. }
  195.  
  196. bool CPetActor::_UpdatAloneActionAI(float fMinDist, float fMaxDist)
  197. {
  198.     float fDist = number(fMinDist, fMaxDist);
  199.     float r = (float)number (0, 359);
  200.     float dest_x = GetOwner()->GetX() + fDist * cos(r);
  201.     float dest_y = GetOwner()->GetY() + fDist * sin(r);
  202.  
  203.     //m_pkChar->SetRotation(number(0, 359));        // ąćÇâŔş ·Ł´ýŔ¸·Î ĽłÁ¤
  204.  
  205.     //GetDeltaByDegree(m_pkChar->GetRotation(), fDist, &fx, &fy);
  206.  
  207.     // ´Ŕ˝ĽÇŃ ¸ř°¨ ĽÓĽş ĂĽĹ©; ĂÖÁľ Ŕ§ÄˇżÍ Áß°Ł Ŕ§Äˇ°ˇ °ĄĽöľř´Ů¸é °ˇÁö ľĘ´Â´Ů.
  208.     //if (!(SECTREE_MANAGER::instance().IsMovablePosition(m_pkChar->GetMapIndex(), m_pkChar->GetX() + (int) fx, m_pkChar->GetY() + (int) fy)
  209.     //          && SECTREE_MANAGER::instance().IsMovablePosition(m_pkChar->GetMapIndex(), m_pkChar->GetX() + (int) fx/2, m_pkChar->GetY() + (int) fy/2)))
  210.     //  return true;
  211.  
  212.     m_pkChar->SetNowWalking(true);
  213.  
  214.     //if (m_pkChar->Goto(m_pkChar->GetX() + (int) fx, m_pkChar->GetY() + (int) fy))
  215.     //  m_pkChar->SendMovePacket(FUNC_WAIT, 0, 0, 0, 0);
  216.     if (!m_pkChar->IsStateMove() && m_pkChar->Goto(dest_x, dest_y))
  217.         m_pkChar->SendMovePacket(FUNC_WAIT, 0, 0, 0, 0);
  218.  
  219.     m_dwLastActionTime = get_dword_time();
  220.  
  221.     return true;
  222. }
  223.  
  224. // char_state.cpp StateHorseÇÔĽö ±×łÉ C&P -_-;
  225. bool CPetActor::_UpdateFollowAI()
  226. {
  227.     if (0 == m_pkChar->m_pkMobData)
  228.     {
  229.         //sys_err("[CPetActor::_UpdateFollowAI] m_pkChar->m_pkMobData is NULL");
  230.         return false;
  231.     }
  232.  
  233.     // NOTE: Äł¸ŻĹÍ(Ćę)ŔÇ żř·ˇ Ŕ̵ż ĽÓµµ¸¦ ľËľĆľß ÇϴµĄ, ÇŘ´ç °Ş(m_pkChar->m_pkMobData->m_table.sMovingSpeed)Ŕ» Á÷Á˘ŔűŔ¸·Î Á˘±ŮÇŘĽ­ ľËľĆłľ Ľöµµ ŔÖÁö¸¸
  234.     // m_pkChar->m_pkMobData °ŞŔĚ invalidÇŃ °ćżě°ˇ ŔÚÁÖ ąß»ýÇÔ. ÇöŔç ˝Ă°Ł°ü°č»ó żřŔÎŔş ´ŮŔ˝żˇ ĆÄľÇÇĎ°í ŔĎ´ÜŔş m_pkChar->m_pkMobData °ŞŔ» ľĆżą »çżëÇĎÁö ľĘµµ·Ď ÇÔ.
  235.     // ż©±âĽ­ ¸Ĺąř °Ë»çÇĎ´Â ŔĚŔŻ´Â ĂÖĂĘ ĂʱâČ­ ÇŇ ¶§ Á¤»ó °ŞŔ» Á¦´ë·Î ¸řľňľîżŔ´Â °ćżěµµ ŔÖŔ˝.. -_-;; ¤Đ¤Đ¤Đ¤Đ¤Đ¤Đ¤Đ¤Đ¤Đ
  236.     if (0 == m_originalMoveSpeed)
  237.     {
  238.         const CMob* mobData = CMobManager::Instance().Get(m_dwVnum);
  239.  
  240.         if (0 != mobData)
  241.             m_originalMoveSpeed = mobData->m_table.sMovingSpeed;
  242.     }
  243.     float   START_FOLLOW_DISTANCE = 300.0f;     // ŔĚ °Ĺ¸® ŔĚ»ó ¶łľîÁö¸é ÂѾưˇ±â ˝ĂŔŰÇÔ
  244.     float   START_RUN_DISTANCE = 900.0f;        // ŔĚ °Ĺ¸® ŔĚ»ó ¶łľîÁö¸é ¶ŮľîĽ­ ÂѾư¨.
  245.  
  246.     float   RESPAWN_DISTANCE = 4500.f;          // ŔĚ °Ĺ¸® ŔĚ»ó ¸ÖľîÁö¸é ÁÖŔÎ ż·Ŕ¸·Î ĽŇČŻÇÔ.
  247.     int     APPROACH = 200;                     // Á˘±Ů °Ĺ¸®
  248.  
  249.     //bool bDoMoveAlone = true;                 // Äł¸ŻĹÍżÍ °ˇ±îŔĚ ŔÖŔ» ¶§ ČĄŔÚ ż©±âŔú±â żňÁ÷ŔĎ°ÇÁö ż©şÎ -_-;
  250.     bool bRun = false;                          // ¶Ůľîľß ÇĎłŞ?
  251.  
  252.     DWORD currentTime = get_dword_time();
  253.  
  254.     long ownerX = m_pkOwner->GetX();        long ownerY = m_pkOwner->GetY();
  255.     long charX = m_pkChar->GetX();          long charY = m_pkChar->GetY();
  256.  
  257.     float fDist = DISTANCE_APPROX(charX - ownerX, charY - ownerY);
  258.  
  259.     if (fDist >= RESPAWN_DISTANCE)
  260.     {
  261.         float fOwnerRot = m_pkOwner->GetRotation() * 3.141592f / 180.f;
  262.         float fx = -APPROACH * cos(fOwnerRot);
  263.         float fy = -APPROACH * sin(fOwnerRot);
  264.         if (m_pkChar->Show(m_pkOwner->GetMapIndex(), ownerX + fx, ownerY + fy))
  265.         {
  266.             return true;
  267.         }
  268.     }
  269.  
  270.  
  271.     if (fDist >= START_FOLLOW_DISTANCE)
  272.     {
  273.         if( fDist >= START_RUN_DISTANCE)
  274.         {
  275.             bRun = true;
  276.         }
  277.  
  278.         m_pkChar->SetNowWalking(!bRun);     // NOTE: ÇÔĽö Ŕ̸§ş¸°í ¸ŘĂߴ°ÇÁŮ ľËľŇ´ÂµĄ SetNowWalking(false) ÇĎ¸é ¶Ů´Â°ĹŔÓ.. -_-;
  279.  
  280.         Follow(APPROACH);
  281.  
  282.         m_pkChar->SetLastAttacked(currentTime);
  283.         m_dwLastActionTime = currentTime;
  284.     }
  285.     //else
  286.     //{
  287.     //  if (fabs(m_pkChar->GetRotation() - GetDegreeFromPositionXY(charX, charY, ownerX, ownerX)) > 10.f || fabs(m_pkChar->GetRotation() - GetDegreeFromPositionXY(charX, charY, ownerX, ownerX)) < 350.f)
  288.     //  {
  289.     //      m_pkChar->Follow(m_pkOwner, APPROACH);
  290.     //      m_pkChar->SetLastAttacked(currentTime);
  291.     //      m_dwLastActionTime = currentTime;
  292.     //  }
  293.     //}
  294.     // Follow ÁßŔĚÁö¸¸ ÁÖŔΰú ŔĎÁ¤ °Ĺ¸® ŔĚł»·Î °ˇ±îżöÁł´Ů¸é ¸ŘĂă
  295.     else
  296.         m_pkChar->SendMovePacket(FUNC_WAIT, 0, 0, 0, 0);
  297.     //else if (currentTime - m_dwLastActionTime > number(5000, 12000))
  298.     //{
  299.     //  this->_UpdatAloneActionAI(START_FOLLOW_DISTANCE / 2, START_FOLLOW_DISTANCE);
  300.     //}
  301.  
  302.     return true;
  303. }
  304.  
  305. bool CPetActor::Update(DWORD deltaTime)
  306. {
  307.     bool bResult = true;
  308.  
  309.     // Ćę ÁÖŔÎŔĚ Á׾ú°ĹłŞ, ĽŇČŻµČ ĆęŔÇ »óĹ°ˇ ŔĚ»óÇϴٸé ĆęŔ» ľřľÚ. (NOTE: °ˇ˛ű°ˇ´Ů ŔĚ·± Ŕú·± ŔĚŔŻ·Î ĽŇČŻµČ ĆęŔĚ DEAD »óĹÂżˇ şüÁö´Â °ćżě°ˇ ŔÖŔ˝-_-;)
  310.     // ĆęŔ» ĽŇČŻÇŃ ľĆŔĚĹŰŔĚ ľř°ĹłŞ, ł»°ˇ °ˇÁř »óĹ°ˇ ľĆ´Ď¶ó¸é ĆęŔ» ľřľÚ.
  311.     if (m_pkOwner->IsDead() || (IsSummoned() && m_pkChar->IsDead())
  312.         || NULL == ITEM_MANAGER::instance().FindByVID(this->GetSummonItemVID())
  313.         || ITEM_MANAGER::instance().FindByVID(this->GetSummonItemVID())->GetOwner() != this->GetOwner()
  314.         )
  315.     {
  316.         this->Unsummon();
  317.         return true;
  318.     }
  319.  
  320.     if (this->IsSummoned() && HasOption(EPetOption_Followable))
  321.         bResult = bResult && this->_UpdateFollowAI();
  322.  
  323.     return bResult;
  324. }
  325.  
  326. //NOTE : ÁÖŔÇ!!! MinDistance¸¦ Ĺ©°Ô ŔâŔ¸¸é ±× şŻŔ§¸¸Ĺ­ŔÇ şŻČ­µżľČŔş followÇĎÁö ľĘ´Â´Ů,
  327. bool CPetActor::Follow(float fMinDistance)
  328. {
  329.     // °ˇ·Á´Â Ŕ§Äˇ¸¦ ąŮ¶óşÁľß ÇŃ´Ů.
  330.     if( !m_pkOwner || !m_pkChar)
  331.         return false;
  332.  
  333.     float fOwnerX = m_pkOwner->GetX();
  334.     float fOwnerY = m_pkOwner->GetY();
  335.  
  336.     float fPetX = m_pkChar->GetX();
  337.     float fPetY = m_pkChar->GetY();
  338.  
  339.     float fDist = DISTANCE_SQRT(fOwnerX - fPetX, fOwnerY - fPetY);
  340.     if (fDist <= fMinDistance)
  341.         return false;
  342.  
  343.     m_pkChar->SetRotationToXY(fOwnerX, fOwnerY);
  344.  
  345.     float fx, fy;
  346.  
  347.     float fDistToGo = fDist - fMinDistance;
  348.     GetDeltaByDegree(m_pkChar->GetRotation(), fDistToGo, &fx, &fy);
  349.  
  350.     if (!m_pkChar->Goto((int)(fPetX+fx+0.5f), (int)(fPetY+fy+0.5f)) )
  351.         return false;
  352.  
  353.     m_pkChar->SendMovePacket(FUNC_WAIT, 0, 0, 0, 0, 0);
  354.  
  355.     return true;
  356. }
  357.  
  358. void CPetActor::SetSummonItem (LPITEM pItem)
  359. {
  360.     if (NULL == pItem)
  361.     {
  362. #ifdef ENABLE_ACTIVE_PET_EFFECT
  363.         LPITEM pSummonItem = ITEM_MANAGER::instance().FindByVID(m_dwSummonItemVID);
  364.         if (NULL != pSummonItem)
  365.         {
  366.             pSummonItem->SetSocket(1, FALSE);
  367.         }
  368. #endif
  369.         m_dwSummonItemVID = 0;
  370.         m_dwSummonItemVnum = 0;
  371.         return;
  372.     }
  373.  
  374. #ifdef ENABLE_ACTIVE_PET_EFFECT
  375.     pItem->SetSocket(1, TRUE);
  376. #endif
  377.     m_dwSummonItemVID = pItem->GetVID();
  378.     m_dwSummonItemVnum = pItem->GetVnum();
  379. }
  380.  
  381. bool __PetCheckBuff(const CPetActor* pPetActor)
  382. {
  383.     bool bMustHaveBuff = true;
  384.     switch (pPetActor->GetVnum())
  385.     {
  386.         case 34004:
  387.         case 34009:
  388.             if (NULL == pPetActor->GetOwner()->GetDungeon())
  389.                 bMustHaveBuff = false;
  390.         default:
  391.             break;
  392.     }
  393.     return bMustHaveBuff;
  394. }
  395.  
  396. void CPetActor::GiveBuff()
  397. {
  398.     // ĆÄȲ Ćę ąöÇÁ´Â ´řŔüżˇĽ­¸¸ ąß»ýÇÔ.
  399.    
  400.     if (!__PetCheckBuff(this))
  401.         return;
  402.     LPITEM item = ITEM_MANAGER::instance().FindByVID(m_dwSummonItemVID);
  403.     if (NULL != item)
  404.         item->ModifyPoints(true);
  405.        
  406.     return ;
  407. }
  408.  
  409. void CPetActor::ClearBuff()
  410. {
  411.     if (NULL == m_pkOwner)
  412.         return ;
  413.     TItemTable* item_proto = ITEM_MANAGER::instance().GetTable(m_dwSummonItemVnum);
  414.     if (NULL == item_proto)
  415.         return;
  416.     if (!__PetCheckBuff(this)) // @fixme129
  417.         return;
  418.     for (int i = 0; i < ITEM_APPLY_MAX_NUM; i++)
  419.     {
  420.         if (item_proto->aApplies[i].bType == APPLY_NONE)
  421.             continue;
  422.         m_pkOwner->ApplyPoint(item_proto->aApplies[i].bType, -item_proto->aApplies[i].lValue);
  423.     }
  424.  
  425.     return ;
  426. }
  427.  
  428. ///////////////////////////////////////////////////////////////////////////////////////
  429. //  CPetSystem
  430. ///////////////////////////////////////////////////////////////////////////////////////
  431.  
  432. CPetSystem::CPetSystem(LPCHARACTER owner)
  433. {
  434. //  assert(0 != owner && "[CPetSystem::CPetSystem] Invalid owner");
  435.  
  436.     m_pkOwner = owner;
  437.     m_dwUpdatePeriod = 400;
  438.  
  439.     m_dwLastUpdateTime = 0;
  440. }
  441.  
  442. CPetSystem::~CPetSystem()
  443. {
  444.     Destroy();
  445. }
  446.  
  447. void CPetSystem::Destroy()
  448. {
  449.     for (TPetActorMap::iterator iter = m_petActorMap.begin(); iter != m_petActorMap.end(); ++iter)
  450.     {
  451.         CPetActor* petActor = iter->second;
  452.  
  453.         if (0 != petActor)
  454.         {
  455.             delete petActor;
  456.         }
  457.     }
  458.     event_cancel(&m_pkPetSystemUpdateEvent);
  459.     m_petActorMap.clear();
  460. }
  461.  
  462. /// Ćę ˝Ă˝şĹŰ ľ÷µĄŔĚĆ®. µî·ĎµČ ĆęµéŔÇ AI Ăł¸® µîŔ» ÇÔ.
  463. bool CPetSystem::Update(DWORD deltaTime)
  464. {
  465.     bool bResult = true;
  466.  
  467.     DWORD currentTime = get_dword_time();
  468.  
  469.     // CHARACTER_MANAGERżˇĽ­ Äł¸ŻĹÍ·ů UpdateÇŇ ¶§ ¸Ĺ°łşŻĽö·Î ÁÖ´Â (Pulse¶ó°í µÇľîŔÖ´Â)°ŞŔĚ ŔĚŔü ÇÁ·ąŔÓ°úŔÇ ˝Ă°ŁÂ÷ŔĚŔÎÁŮ ľËľŇ´ÂµĄ
  470.     // ŔüÇô ´Ů¸Ą °ŞŔ̶óĽ­-_-; ż©±âżˇ ŔÔ·ÂŔ¸·Î µéľîżŔ´Â deltaTimeŔş Ŕǹ̰ˇ ľřŔ˝¤Đ¤Đ
  471.  
  472.     if (m_dwUpdatePeriod > currentTime - m_dwLastUpdateTime)
  473.         return true;
  474.  
  475.     std::vector <CPetActor*> v_garbageActor;
  476.  
  477.     for (TPetActorMap::iterator iter = m_petActorMap.begin(); iter != m_petActorMap.end(); ++iter)
  478.     {
  479.         CPetActor* petActor = iter->second;
  480.  
  481.         if (0 != petActor && petActor->IsSummoned())
  482.         {
  483.             LPCHARACTER pPet = petActor->GetCharacter();
  484.  
  485.             if (NULL == CHARACTER_MANAGER::instance().Find(pPet->GetVID()))
  486.             {
  487.                 v_garbageActor.push_back(petActor);
  488.             }
  489.             else
  490.             {
  491.                 bResult = bResult && petActor->Update(deltaTime);
  492.             }
  493.         }
  494.     }
  495.     for (std::vector<CPetActor*>::iterator it = v_garbageActor.begin(); it != v_garbageActor.end(); it++)
  496.         DeletePet(*it);
  497.  
  498.     m_dwLastUpdateTime = currentTime;
  499.  
  500.     return bResult;
  501. }
  502.  
  503. /// °ü¸® ¸ń·ĎżˇĽ­ ĆęŔ» Áöżň
  504. void CPetSystem::DeletePet(DWORD mobVnum)
  505. {
  506.     TPetActorMap::iterator iter = m_petActorMap.find(mobVnum);
  507.  
  508.     if (m_petActorMap.end() == iter)
  509.     {
  510.         sys_err("[CPetSystem::DeletePet] Can't find pet on my list (VNUM: %d)", mobVnum);
  511.         return;
  512.     }
  513.  
  514.     CPetActor* petActor = iter->second;
  515.  
  516.     if (0 == petActor)
  517.         sys_err("[CPetSystem::DeletePet] Null Pointer (petActor)");
  518.     else
  519.         delete petActor;
  520.  
  521.     m_petActorMap.erase(iter);
  522. }
  523.  
  524. /// °ü¸® ¸ń·ĎżˇĽ­ ĆęŔ» Áöżň
  525. void CPetSystem::DeletePet(CPetActor* petActor)
  526. {
  527.     for (TPetActorMap::iterator iter = m_petActorMap.begin(); iter != m_petActorMap.end(); ++iter)
  528.     {
  529.         if (iter->second == petActor)
  530.         {
  531.             delete petActor;
  532.             m_petActorMap.erase(iter);
  533.  
  534.             return;
  535.         }
  536.     }
  537.  
  538.     sys_err("[CPetSystem::DeletePet] Can't find petActor(0x%x) on my list(size: %d) ", petActor, m_petActorMap.size());
  539. }
  540.  
  541. void CPetSystem::Unsummon(DWORD vnum, bool bDeleteFromList)
  542. {
  543.     CPetActor* actor = this->GetByVnum(vnum);
  544.  
  545.     if (0 == actor)
  546.     {
  547.         sys_err("[CPetSystem::GetByVnum(%d)] Null Pointer (petActor)", vnum);
  548.         return;
  549.     }
  550.     actor->Unsummon();
  551.  
  552.     if (true == bDeleteFromList)
  553.         this->DeletePet(actor);
  554.  
  555.     bool bActive = false;
  556.     for (TPetActorMap::iterator it = m_petActorMap.begin(); it != m_petActorMap.end(); it++)
  557.     {
  558.         bActive |= it->second->IsSummoned();
  559.     }
  560.     if (false == bActive)
  561.     {
  562.         event_cancel(&m_pkPetSystemUpdateEvent);
  563.         m_pkPetSystemUpdateEvent = NULL;
  564.     }
  565. }
  566.  
  567.  
  568. CPetActor* CPetSystem::Summon(DWORD mobVnum, LPITEM pSummonItem, const char* petName, bool bSpawnFar, DWORD options)
  569. {
  570.     CPetActor* petActor = this->GetByVnum(mobVnum);
  571.  
  572.     // µî·ĎµČ ĆęŔĚ ľĆ´Ď¶ó¸é »ő·Î »ýĽş ČÄ °ü¸® ¸ń·Ďżˇ µî·ĎÇÔ.
  573.     if (0 == petActor)
  574.     {
  575.         petActor = M2_NEW CPetActor(m_pkOwner, mobVnum, options);
  576.         m_petActorMap.insert(std::make_pair(mobVnum, petActor));
  577.     }
  578.  
  579. #ifdef ENABLE_NEWSTUFF
  580.     DWORD petVID = petActor->Summon(petName, pSummonItem, bSpawnFar);
  581.     if (!petVID)
  582.         sys_err("[CPetSystem::Summon(%d)] Null Pointer (petVID)", pSummonItem);
  583. #endif
  584.  
  585.     if (NULL == m_pkPetSystemUpdateEvent)
  586.     {
  587.         petsystem_event_info* info = AllocEventInfo<petsystem_event_info>();
  588.  
  589.         info->pPetSystem = this;
  590.  
  591.         m_pkPetSystemUpdateEvent = event_create(petsystem_update_event, info, PASSES_PER_SEC(1) / 4);   // 0.25ĂĘ
  592.     }
  593.  
  594.     return petActor;
  595. }
  596.  
  597.  
  598. CPetActor* CPetSystem::GetByVID(DWORD vid) const
  599. {
  600.     CPetActor* petActor = 0;
  601.  
  602.     bool bFound = false;
  603.  
  604.     for (TPetActorMap::const_iterator iter = m_petActorMap.begin(); iter != m_petActorMap.end(); ++iter)
  605.     {
  606.         petActor = iter->second;
  607.  
  608.         if (0 == petActor)
  609.         {
  610.             sys_err("[CPetSystem::GetByVID(%d)] Null Pointer (petActor)", vid);
  611.             continue;
  612.         }
  613.  
  614.         bFound = petActor->GetVID() == vid;
  615.  
  616.         if (true == bFound)
  617.             break;
  618.     }
  619.  
  620.     return bFound ? petActor : 0;
  621. }
  622.  
  623. /// µî·Ď µČ Ćę ÁßżˇĽ­ ÁÖľîÁř ¸÷ VNUMŔ» °ˇÁř ľ×Ĺ͸¦ ąÝČŻÇĎ´Â ÇÔĽö.
  624. CPetActor* CPetSystem::GetByVnum(DWORD vnum) const
  625. {
  626.     CPetActor* petActor = 0;
  627.  
  628.     TPetActorMap::const_iterator iter = m_petActorMap.find(vnum);
  629.  
  630.     if (m_petActorMap.end() != iter)
  631.         petActor = iter->second;
  632.  
  633.     return petActor;
  634. }
  635.  
  636. size_t CPetSystem::CountSummoned() const
  637. {
  638.     size_t count = 0;
  639.  
  640.     for (TPetActorMap::const_iterator iter = m_petActorMap.begin(); iter != m_petActorMap.end(); ++iter)
  641.     {
  642.         CPetActor* petActor = iter->second;
  643.  
  644.         if (0 != petActor)
  645.         {
  646.             if (petActor->IsSummoned())
  647.                 ++count;
  648.         }
  649.     }
  650.  
  651.     return count;
  652. }
  653.  
  654. void CPetSystem::RefreshBuff()
  655. {
  656.     for (TPetActorMap::const_iterator iter = m_petActorMap.begin(); iter != m_petActorMap.end(); ++iter)
  657.     {
  658.         CPetActor* petActor = iter->second;
  659.  
  660.         if (0 != petActor)
  661.         {
  662.             if (petActor->IsSummoned())
  663.             {
  664.                 petActor->GiveBuff();
  665.             }
  666.         }
  667.     }
  668. }
  669.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement