Jump to content

[AJUDA]Verificar ai_flag do mob_proto através da PetSystem.cpp


Recommended Posts

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 by Luffy
Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...