kralhakan2009 1
kralhakan2009
Vahsi Uzman 1
Vahsi Uzman
Best Studio 1
Best Studio
TuZaKK 1
TuZaKK
Mt2Hizmet 1
Mt2Hizmet
Agora Metin2 1
Agora Metin2
Bvural41 1
Bvural41
kaptanmikro1 1
kaptanmikro1
R 1
Roksam
[DEV]AB 1
[DEV]AB
Sevdamsın 1
Sevdamsın
farkmt2official 1
farkmt2official
Hikaye Ekle

Mob takip sistemi düzenlemesi

  • Konuyu başlatan Konuyu başlatan Koray'
  • Başlangıç tarihi Başlangıç tarihi
  • Cevaplar Cevaplar 12
  • Görüntüleme Görüntüleme 4K

Türkiye'de ilk Mobil & PC Aynı Anda Metin2 Oyna. Triarchonline kalıcı ve uzun ömürlü yapısı ile 24 Temmuz'da açılıyor. | 1-99 Mobil Metin2 Triarch HEMEN TIKLA!

Mevcut halinde mobların sizi hedef olarak belirlediği zaman karakterinizi değil yürüme yolunu yani geçtiğiniz yerleri takip ediyor, bunu sizi takip edecek şekilde düzenledim.

Öncesi:


Düzenlenmiş hali:


* char.cpp

Arat:
Kod:
        float rot = pkChr->GetRotation();
        float rot_delta = GetDegreeDelta(rot, GetDegreeFromPositionXY(GetX(), GetY(), pkChr->GetX(), pkChr->GetY()));

        float yourSpeed = pkChr->GetMoveSpeed();
        float mySpeed = GetMoveSpeed();

        float fDist = DISTANCE_SQRT(x - GetX(), y - GetY());
        float fFollowSpeed = mySpeed - yourSpeed * cos(rot_delta * M_PI / 180);

        if (fFollowSpeed >= 0.1f)
        {
            float fMeetTime = fDist / fFollowSpeed;
            float fYourMoveEstimateX, fYourMoveEstimateY;

            if( fMeetTime * yourSpeed <= 100000.0f )
            {
                GetDeltaByDegree(pkChr->GetRotation(), fMeetTime * yourSpeed, &fYourMoveEstimateX, &fYourMoveEstimateY);

                x += (long) fYourMoveEstimateX;
                y += (long) fYourMoveEstimateY;

                float fDistNew = sqrt(((double)x - GetX())*(x-GetX())+((double)y - GetY())*(y-GetY()));
                if (fDist < fDistNew)
                {
                    x = (long)(GetX() + (x - GetX()) * fDist / fDistNew);
                    y = (long)(GetY() + (y - GetY()) * fDist / fDistNew);
                }
            }
        }

Değiştir:
Kod:
        // Get the current position of the victim and the AI itself.
        float victimPosX = pkChr->GetX();
        float victimPosY = pkChr->GetY();
        float myPosX = GetX();
        float myPosY = GetY();

        // Calculate the distance to the victim for any potential use.
        float fDist = DISTANCE_SQRT(victimPosX - myPosX, victimPosY - myPosY);

        // Calculate the AI's and the victim's speeds.
        float mySpeed = GetMoveSpeed();
        float yourSpeed = pkChr->GetMoveSpeed();

        // Optionally calculate follow speed, though it's not used for direct movement.
        float fFollowSpeed = mySpeed - yourSpeed; // This is not strictly necessary for direct movement.

        // Determine if the AI should move towards the victim.
        if (mySpeed > 0.1f) // Assuming the AI should move if its speed is above a small threshold.
        {
            // Calculate the direction to the victim.
            float deltaX = victimPosX - myPosX;
            float deltaY = victimPosY - myPosY;

            // Normalize the direction.
            float length = sqrt(deltaX * deltaX + deltaY * deltaY);
            float dirX = deltaX / length;
            float dirY = deltaY / length;

            // Calculate new position based on the direction and the AI's speed.
            // Assuming a simple movement mechanism where the AI moves directly towards the victim.
            float newPositionX = myPosX + dirX * mySpeed; // Consider time delta if needed.
            float newPositionY = myPosY + dirY * mySpeed; // Consider time delta if needed.

            // Update the AI's position.
            x = (long)newPositionX;
            y = (long)newPositionY;
        }
    }

---

Arat:
Kod:
    HorseSummon(false);

Altına ekle:
Kod:
    if (IsPC())
        ClearEnemyNPCs();

---

Ekle:
Kod:
void CHARACTER::AddEnemyNPC(DWORD dwNPCVID)
{
    if (m_set_dwEnemyNPCVID.find(dwNPCVID) != m_set_dwEnemyNPCVID.end())
        return;

    if (test_server)
        sys_log(0, "AddEnemyNPC %s %u", GetName(), dwNPCVID);

    m_set_dwEnemyNPCVID.insert(dwNPCVID);
}
void CHARACTER::RemoveEnemyNPC(DWORD dwNPCVID)
{
    if (m_set_dwEnemyNPCVID.find(dwNPCVID) == m_set_dwEnemyNPCVID.end())
        return;

    if (test_server)
        sys_log(0, "RemoveEnemyNPC %s %u", GetName(), dwNPCVID);

    m_set_dwEnemyNPCVID.erase(dwNPCVID);
}
void CHARACTER::ClearEnemyNPCs()
{
    m_set_dwEnemyNPCVID.clear();
}

void CHARACTER::NotifyEnemyNPCs()
{
    if (m_set_dwEnemyNPCVID.empty())
        return;

    for (const auto& dwNPCVID : m_set_dwEnemyNPCVID)
    {
        LPCHARACTER pkNPC = CHARACTER_MANAGER::Instance().Find(dwNPCVID);
        if (pkNPC)
        {
            extern bool __CHARACTER_GotoNearTarget(LPCHARACTER self, LPCHARACTER victim);
            __CHARACTER_GotoNearTarget(pkNPC, this);
        }
        else // NPC looks like no more exists, remove it from cache list
        {
            RemoveEnemyNPC(dwNPCVID);
        }
    }
}

---

Arat:
Kod:
    SendMovePacket(FUNC_WAIT, 0, 0, 0, 0);
    return true;

Üstüne ekle:
Kod:
    if (IsNPC() && pkChr->IsPC())
        pkChr->AddEnemyNPC(GetVID());

---

* char.h

Arat:
Kod:
    VID                m_kVIDVictim;

Altına ekle:
Kod:
    void AddEnemyNPC(DWORD dwNPCVID);
    void RemoveEnemyNPC(DWORD dwNPCVID);
    void ClearEnemyNPCs();
    void NotifyEnemyNPCs();

---

Arat:
Kod:
    CTrigger        m_triggerOnClick;

Altına ekle:
Kod:
    std::set<DWORD>    m_set_dwEnemyNPCVID;

---

* char_battle.cpp

Arat:
Kod:
    ClearAffect(true);

Altına ekle:
Kod:
    if (IsPC())
        ClearEnemyNPCs();

---

Arat:
Kod:
void CHARACTER::SetVictim(LPCHARACTER pkVictim)
{

Altına ekle:
Kod:
    if (pkVictim == this)
    {
        sys_err("SetVictim: pkVictim == this");
        return;
    }

---

Arat: (CHARACTER::SetVictim)
Kod:
    if (!pkVictim)
    {

Altına ekle:
Kod:
        LPCHARACTER pkOldVictim = GetVictim();
        if (IsNPC() && pkOldVictim && pkOldVictim->IsPC())
            pkOldVictim->RemoveEnemyNPC((DWORD)GetVID());
---

Arat: (CHARACTER::SetVictim)
Kod:
    else
    {

Altına ekle:
Kod:
        if (IsNPC())
        {
            LPCHARACTER pkOldVictim = GetVictim();
            if (pkOldVictim && pkOldVictim->IsPC())
                pkOldVictim->RemoveEnemyNPC((DWORD)GetVID());
                
            if (pkVictim->IsPC())
                pkVictim->AddEnemyNPC((DWORD)GetVID());
        }
---

* input_main.cpp

Arat:
Kod:
    ch->PacketAround(&pack, sizeof(TPacketGCMove), ch);

Altına ekle:
Kod:
    if (pinfo->bFunc == FUNC_WAIT)
        ch->NotifyEnemyNPCs();
 

En Çok Reaksiyon Alan Mesajlar

Öncelikle eline sağlık güzel bir konuya değinmişsin. Karakterin yeni yazdığın şekilde yönlendirilmesi mantıklı fakat ikinci durum için o kadar şeye gerek var mı diye düşünüyorum. Tabi fonksiyonları farklı alanlarda da kullanmış olabilirsin o yüzden dolayı da senin için gerekli olabilir o konuya bir sözüm yok.

Şöyle kısa bi güncelleme ile de aynı sonuca ulaşabiliriz diye düşünüyorum.


char_state.cpp


Kod:
        if (IsMonster() && GetVictim())
        {
            LPCHARACTER victim = GetVictim();
            if (victim)
            {
                UpdateAggrPoint(victim, DAMAGE_TYPE_NORMAL, -(victim->GetLevel() / 3 + 1));
                if (dwElapsedTime > 300)
                    __CHARACTER_GotoNearTarget(this, victim);
            }
        }
Öncelikle eline sağlık güzel bir konuya değinmişsin. Karakterin yeni yazdığın şekilde yönlendirilmesi mantıklı fakat ikinci durum için o kadar şeye gerek var mı diye düşünüyorum. Tabi fonksiyonları farklı alanlarda da kullanmış olabilirsin o yüzden dolayı da senin için gerekli olabilir o konuya bir sözüm yok.

Şöyle kısa bi güncelleme ile de aynı sonuca ulaşabiliriz diye düşünüyorum.


char_state.cpp


Kod:
        if (IsMonster() && GetVictim())
        {
            LPCHARACTER victim = GetVictim();
            if (victim)
            {
                UpdateAggrPoint(victim, DAMAGE_TYPE_NORMAL, -(victim->GetLevel() / 3 + 1));
                if (dwElapsedTime > 300)
                    __CHARACTER_GotoNearTarget(this, victim);
            }
        }
 
Öncelikle eline sağlık güzel bir konuya değinmişsin. Karakterin yeni yazdığın şekilde yönlendirilmesi mantıklı fakat ikinci durum için o kadar şeye gerek var mı diye düşünüyorum. Tabi fonksiyonları farklı alanlarda da kullanmış olabilirsin o yüzden dolayı da senin için gerekli olabilir o konuya bir sözüm yok.

Şöyle kısa bi güncelleme ile de aynı sonuca ulaşabiliriz diye düşünüyorum.


char_state.cpp


Kod:
        if (IsMonster() && GetVictim())
        {
            LPCHARACTER victim = GetVictim();
            if (victim)
            {
                UpdateAggrPoint(victim, DAMAGE_TYPE_NORMAL, -(victim->GetLevel() / 3 + 1));
                if (dwElapsedTime > 300)
                    __CHARACTER_GotoNearTarget(this, victim);
            }
        }

This code is not good, because mobs can choose other targets.
 

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)

Geri
Üst