Advertisement
Guest User

PetSystem.cpp

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