Luffy Posted December 11, 2017 at 05:46 PM Share Posted December 11, 2017 at 05:46 PM (edited) Pessoal, eu gostaria de verificar se o ai_flag do pet no mob_proto o "NOMOVE" é true, se assim for eu quero que o sistema de pets não ative a animação "RUN", já que o pet em questão não tem essa animação. O que acarreta erro syserr e o pet acaba bugando. Eu quero apenas que o pet de respawn da forma que já é padrão do sistema de pets. Alguém poderia me ajudar com isso? PetSystem.cpp Spoiler #include "stdafx.h" #include "config.h" #include "utils.h" #include "vector.h" #include "char.h" #include "sectree_manager.h" #include "char_manager.h" #include "mob_manager.h" #include "PetSystem.h" #include "../../common/VnumHelper.h" #include "packet.h" #include "item_manager.h" #include "item.h" EVENTINFO (petsystem_event_info) { CPetSystem* pPetSystem; }; EVENTFUNC (petsystem_update_event) { petsystem_event_info* info = dynamic_cast<petsystem_event_info*> (event->info); if (info == NULL) { sys_err ("petsystem_update_event> <Factor> Null pointer"); return 0; } CPetSystem* pPetSystem = info->pPetSystem; if (NULL == pPetSystem) { return 0; } pPetSystem->Update (0); return PASSES_PER_SEC (1) / 4; } const float PET_COUNT_LIMIT = 3; CPetActor::CPetActor (LPCHARACTER owner, DWORD vnum, DWORD options) { m_dwVnum = vnum; m_dwVID = 0; m_dwOptions = options; m_dwLastActionTime = 0; m_pkChar = 0; m_pkOwner = owner; m_originalMoveSpeed = 0; m_dwSummonItemVID = 0; m_dwSummonItemVnum = 0; } CPetActor::~CPetActor() { this->Unsummon(); m_pkOwner = 0; } void CPetActor::SetName (const char* name) { std::string petName = m_pkOwner->GetName(); if (0 != m_pkOwner && 0 == name && 0 != m_pkOwner->GetName()) { petName += "'s Pet"; } else { petName += name; } if (true == IsSummoned()) { m_pkChar->SetName (petName); } m_name = petName; } bool CPetActor::Mount() { if (0 == m_pkOwner) { return false; } if (true == HasOption (EPetOption_Mountable)) { m_pkOwner->MountVnum (m_dwVnum); } return m_pkOwner->GetMountVnum() == m_dwVnum;; } void CPetActor::Unmount() { if (0 == m_pkOwner) { return; } if (m_pkOwner->IsHorseRiding()) { m_pkOwner->StopRiding(); } } void CPetActor::Unsummon() { if (true == this->IsSummoned()) { this->ClearBuff(); this->SetSummonItem (NULL); if (NULL != m_pkOwner) { m_pkOwner->ComputePoints(); } if (NULL != m_pkChar) { M2_DESTROY_CHARACTER (m_pkChar); } m_pkChar = 0; m_dwVID = 0; } } DWORD CPetActor::Summon (const char* petName, LPITEM pSummonItem, bool bSpawnFar) { long x = m_pkOwner->GetX(); long y = m_pkOwner->GetY(); long z = m_pkOwner->GetZ(); if (true == bSpawnFar) { x += (number (0, 1) * 2 - 1) * number (2000, 2500); y += (number (0, 1) * 2 - 1) * number (2000, 2500); } else { x += number (-100, 100); y += number (-100, 100); } if (0 != m_pkChar) { m_pkChar->Show (m_pkOwner->GetMapIndex(), x, y); m_dwVID = m_pkChar->GetVID(); return m_dwVID; } m_pkChar = CHARACTER_MANAGER::instance().SpawnMob (m_dwVnum, m_pkOwner->GetMapIndex(), x, y, z, false, (int) (m_pkOwner->GetRotation() + 180), false); if (0 == m_pkChar) { sys_err ("[CPetSystem::Summon] Failed to summon the pet. (vnum: %d)", m_dwVnum); return 0; } m_pkChar->SetPet(); m_pkChar->SetEmpire (m_pkOwner->GetEmpire()); m_dwVID = m_pkChar->GetVID(); this->SetName (petName); this->SetSummonItem (pSummonItem); m_pkOwner->ComputePoints(); m_pkChar->Show (m_pkOwner->GetMapIndex(), x, y, z); return m_dwVID; } bool CPetActor::_UpdatAloneActionAI (float fMinDist, float fMaxDist) { float fDist = number (fMinDist, fMaxDist); float r = (float) number (0, 359); float dest_x = GetOwner()->GetX() + fDist * cos (r); float dest_y = GetOwner()->GetY() + fDist * sin (r); m_pkChar->SetNowWalking (true); if (!m_pkChar->IsStateMove() && m_pkChar->Goto (dest_x, dest_y)) { m_pkChar->SendMovePacket (FUNC_WAIT, 0, 0, 0, 0); } m_dwLastActionTime = get_dword_time(); return true; } bool CPetActor::_UpdateFollowAI() { if (0 == m_pkChar->m_pkMobData) { return false; } if (0 == m_originalMoveSpeed) { const CMob* mobData = CMobManager::Instance().Get (m_dwVnum); if (0 != mobData) { m_originalMoveSpeed = mobData->m_table.sMovingSpeed; } } float START_FOLLOW_DISTANCE = 600.0f; //float START_RUN_DISTANCE = 900.0f; float RESPAWN_DISTANCE = 4500.f; int APPROACH = 200; bool bRun = false; DWORD currentTime = get_dword_time(); long ownerX = m_pkOwner->GetX(); long ownerY = m_pkOwner->GetY(); long charX = m_pkChar->GetX(); long charY = m_pkChar->GetY(); float fDist = DISTANCE_APPROX (charX - ownerX, charY - ownerY); if (fDist >= RESPAWN_DISTANCE) { float fOwnerRot = m_pkOwner->GetRotation() * 3.141592f / 180.f; float fx = -APPROACH * cos (fOwnerRot); float fy = -APPROACH * sin (fOwnerRot); if (m_pkChar->Show (m_pkOwner->GetMapIndex(), ownerX + fx, ownerY + fy)) { return true; } } if (fDist >= START_FOLLOW_DISTANCE) { //if (fDist >= START_RUN_DISTANCE) //{ bRun = true; //} m_pkChar->SetNowWalking (!bRun); Follow (APPROACH); m_pkChar->SetLastAttacked (currentTime); m_dwLastActionTime = currentTime; } else { m_pkChar->SendMovePacket (FUNC_WAIT, 0, 0, 0, 0); } return true; } bool CPetActor::Update (DWORD deltaTime) { bool bResult = true; if ((this->GetSummonItemVID() != 0 && (NULL == ITEM_MANAGER::instance().FindByVID (this->GetSummonItemVID()) || ITEM_MANAGER::instance().FindByVID (this->GetSummonItemVID())->GetOwner() != this->GetOwner()))) { this->Unsummon(); return true; } if (this->IsSummoned() && HasOption (EPetOption_Followable)) { bResult = bResult && this->_UpdateFollowAI(); } return bResult; } bool CPetActor::Follow (float fMinDistance) { if (!m_pkOwner || !m_pkChar) { return false; } float fOwnerX = m_pkOwner->GetX(); float fOwnerY = m_pkOwner->GetY(); float fPetX = m_pkChar->GetX(); float fPetY = m_pkChar->GetY(); float fDist = DISTANCE_SQRT (fOwnerX - fPetX, fOwnerY - fPetY); if (fDist <= fMinDistance) { return false; } m_pkChar->SetRotationToXY (fOwnerX, fOwnerY); float fx, fy; float fDistToGo = fDist - fMinDistance; GetDeltaByDegree (m_pkChar->GetRotation(), fDistToGo, &fx, &fy); if (!m_pkChar->Goto ((int) (fPetX + fx + 0.5f), (int) (fPetY + fy + 0.5f))) { return false; } m_pkChar->SendMovePacket (FUNC_WAIT, 0, 0, 0, 0, 0); return true; } void CPetActor::SetSummonItem (LPITEM pItem) { if (NULL == pItem) { m_dwSummonItemVID = 0; m_dwSummonItemVnum = 0; return; } m_dwSummonItemVID = pItem->GetVID(); m_dwSummonItemVnum = pItem->GetVnum(); } bool __PetCheckBuff (const CPetActor* pPetActor) { bool bMustHaveBuff = true; switch (pPetActor->GetVnum()) { case 34004: case 34009: if (NULL == pPetActor->GetOwner()->GetDungeon()) { bMustHaveBuff = false; } default: break; } return bMustHaveBuff; } void CPetActor::GiveBuff() { if (!__PetCheckBuff (this)) { return; } LPITEM item = ITEM_MANAGER::instance().FindByVID (m_dwSummonItemVID); if (NULL != item) { item->ModifyPoints (true); } return; } void CPetActor::ClearBuff() { TItemTable* item_proto = ITEM_MANAGER::instance().GetTable (m_dwSummonItemVnum); if (NULL == m_pkOwner) { return; } if (NULL == item_proto) { return; } if (!__PetCheckBuff (this)) { return; } for (int i = 0; i < ITEM_APPLY_MAX_NUM; i++) { if (item_proto->aApplies.bType == APPLY_NONE) { continue; } m_pkOwner->ApplyPoint (item_proto->aApplies.bType, -item_proto->aApplies.lValue); } return;} CPetSystem::CPetSystem (LPCHARACTER owner){ m_pkOwner = owner; m_dwUpdatePeriod = 400; m_dwLastUpdateTime = 0;} CPetSystem::~CPetSystem(){ Destroy();} void CPetSystem::Destroy(){ for (auto iter = m_petActorMap.begin(); iter != m_petActorMap.end(); ++iter) { CPetActor* petActor = iter->second; if (0 != petActor) { delete petActor; } } event_cancel (&m_pkPetSystemUpdateEvent); m_petActorMap.clear();} bool CPetSystem::Update (DWORD deltaTime){ bool bResult = true; DWORD currentTime = get_dword_time(); if (m_dwUpdatePeriod > currentTime - m_dwLastUpdateTime) { return true; } std::vector <CPetActor*> v_garbageActor; for (auto iter = m_petActorMap.begin(); iter != m_petActorMap.end(); ++iter) { CPetActor* petActor = iter->second; if (0 != petActor && petActor->IsSummoned()) { LPCHARACTER pPet = petActor->GetCharacter(); if (NULL == CHARACTER_MANAGER::instance().Find (pPet->GetVID())) { v_garbageActor.push_back (petActor); } else { bResult = bResult && petActor->Update (deltaTime); } } } for (auto it = v_garbageActor.begin(); it != v_garbageActor.end(); it++) { DeletePet (*it); } m_dwLastUpdateTime = currentTime; return bResult;} void CPetSystem::DeletePet (DWORD mobVnum){ auto iter = m_petActorMap.find (mobVnum); if (m_petActorMap.end() == iter) { sys_err ("[CPetSystem::DeletePet] Can't find pet on my list (VNUM: %d)", mobVnum); return; } CPetActor* petActor = iter->second; if (0 == petActor) { sys_err ("[CPetSystem::DeletePet] Null Pointer (petActor)"); } else { delete petActor; } m_petActorMap.erase (iter);} void CPetSystem::DeletePet (CPetActor* petActor){ for (auto iter = m_petActorMap.begin(); iter != m_petActorMap.end(); ++iter) { if (iter->second == petActor) { delete petActor; m_petActorMap.erase (iter); return; } } sys_err ("[CPetSystem::DeletePet] Can't find petActor(0x%x) on my list(size: %d) ", petActor, m_petActorMap.size());} void CPetSystem::Unsummon (DWORD vnum, bool bDeleteFromList){ CPetActor* actor = this->GetByVnum (vnum); if (0 == actor) { sys_err ("[CPetSystem::GetByVnum(%d)] Null Pointer (petActor)", vnum); return; } actor->Unsummon(); if (true == bDeleteFromList) { this->DeletePet (actor); } bool bActive = false; for (auto it = m_petActorMap.begin(); it != m_petActorMap.end(); it++) { bActive |= it->second->IsSummoned(); } if (false == bActive) { event_cancel (&m_pkPetSystemUpdateEvent); m_pkPetSystemUpdateEvent = NULL; }} CPetActor* CPetSystem::Summon (DWORD mobVnum, LPITEM pSummonItem, const char* petName, bool bSpawnFar, DWORD options){ CPetActor* petActor = this->GetByVnum (mobVnum); if (0 == petActor) { petActor = M2_NEW CPetActor (m_pkOwner, mobVnum, options); m_petActorMap.insert (std::make_pair (mobVnum, petActor)); } DWORD petVID = petActor->Summon (petName, pSummonItem, bSpawnFar); if (NULL == m_pkPetSystemUpdateEvent) { petsystem_event_info* info = AllocEventInfo<petsystem_event_info>(); info->pPetSystem = this; m_pkPetSystemUpdateEvent = event_create (petsystem_update_event, info, PASSES_PER_SEC (1) / 4); } return petActor;} CPetActor* CPetSystem::GetByVID (DWORD vid) const{ CPetActor* petActor = 0; bool bFound = false; for (auto iter = m_petActorMap.begin(); iter != m_petActorMap.end(); ++iter) { petActor = iter->second; if (0 == petActor) { sys_err ("[CPetSystem::GetByVID(%d)] Null Pointer (petActor)", vid); continue; } bFound = petActor->GetVID() == vid; if (true == bFound) { break; } } return bFound ? petActor : 0;} CPetActor* CPetSystem::GetByVnum (DWORD vnum) const{ CPetActor* petActor = 0; auto iter = m_petActorMap.find (vnum); if (m_petActorMap.end() != iter) { petActor = iter->second; } return petActor;} size_t CPetSystem::CountSummoned() const{ size_t count = 0; for (auto iter = m_petActorMap.begin(); iter != m_petActorMap.end(); ++iter) { CPetActor* petActor = iter->second; if (0 != petActor) { if (petActor->IsSummoned()) { ++count; } } } return count;} void CPetSystem::RefreshBuff(){ for (auto iter = m_petActorMap.begin(); iter != m_petActorMap.end(); ++iter) { CPetActor* petActor = iter->second; if (0 != petActor) { if (petActor->IsSummoned()) { petActor->GiveBuff(); } } }} Edited December 11, 2017 at 05:49 PM by Luffy Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now