Mob takip sistemi düzenlemesi

  • Konbuyu başlatan Konbuyu başlatan Admin
  • Başlangıç tarihi Başlangıç tarihi
  • Cevaplar Cevaplar 0
  • Görüntüleme Görüntüleme 33

Admin

Metin2Lobby
Yönetici
Founder
Katılım
6 Mayıs 2022
Mesajlar
52,647
Ticaret : 1 / 0 / 0
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:


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();

Metin2 Mob Takip Sistemi Düzenlemesi

Mob Takip Sistemi Nedir?
Metin2 özel sunucularında mob takip sistemi, oyuncuların belirli bir düşmanı takip ederek ona sürekli saldırmalarını sağlayan temel sistemlerden biridir. Bu sistem, PvP ve PvE mekaniklerinde kritik öneme sahiptir. Özellikle PvP odaklı sunucularda, mob takibi doğru yapılandırılmadığında game balance bozulabilir. Bu yazıda, Metin2 özel sunucu geliştirme sürecinde mob takip sistemini nasıl düzenleyeceğinizi adım adım anlatacağız.

Takip Sistemine Genel Bakış
Mob takip sistemi, genellikle C++ tabanlı game server kaynak kodunda tanımlanır. Mob nesnesi, bir target değişkeni tutar. Bu değişken, o anda hangi oyuncunun takip edildiğini belirtir. Takip mantığı, oyuncu mob'a saldırınca veya belirli bir mesafe içine girince çalışır. Bu sistem, core dosyalarında yer alan battle.cpp ve char_battle.cpp gibi dosyalarda düzenlenir.

Takip Aralığı ve Bekleme Süresi
Bazı Metin2 özel sunucularında, moblar bir oyuncuyu takip ettikten sonra kısa bir süre bekler, daha sonra başka bir oyuncuya geçebilir. Bu bekleme süresi genellikle C++ içinde sabit olarak tanımlıdır. Örneğin, MOB_TARGET_SWITCH_TIME gibi bir değişken tanımlanabilir. Bu değeri değiştirmek, mobların ne kadar süre boyunca aynı hedefi takip edeceğini belirler. Aynı zamanda, takip mesafesi de battle fonksiyonlarında kontrol edilir. Range ayarları, mobun hedefini kaybetmemesi için optimize edilmelidir.

Yanlış Takip Ayarlarının Sonuçları
Eğer takip sistemi doğru ayarlanmazsa, bazı istenmeyen durumlar ortaya çıkabilir. Örneğin, bir mob birden fazla oyuncuyu aynı anda takip edebilir ya da hedefini çok çabuk değiştirip PvE deneyimini bozabilir. Ayrıca, bazı cheat araçları ile mobları takip etmek kolaylaştırıldığında, server fairness ciddi şekilde etkilenebilir. Bu nedenle, source edit sırasında anti-cheat mekanizmaları da göz önünde bulundurulmalıdır.

Python ve GUI Kullanımıyla Ayarların Kontrolü
Bazı Metin2 geliştiricileri, mob takip ayarlarını Python arayüzleriyle yönetmeyi tercih eder. Py Root içinde tanımlanan uiscript dosyaları sayesinde, admin paneli üzerinden takip süreleri veya mesafeleri gibi ayarlar değiştirilebilir. Bu yöntem, sunucu yöneticileri için daha kullanıcı dostu bir çözüm sağlar. Ancak, bu tür GUI sistemlerinin doğrudan C++ core ile entegrasyonu dikkatle yapılmalıdır.

DB Core ve Takip Kayıtları
Mob takip sistemi, bazen database (DB) üzerinde de kayıt tutar. Özellikle party sistemleriyle entegre çalıştığında, mobun hedefini kimin belirlediği veya loot haklarının dağılımı gibi veriler db_core içinde saklanabilir. Bu verilerin doğru okunması ve yazılması, sunucu performansını doğrudan etkiler.

Sonuç
Metin2 özel sunucu geliştirme sürecinde, mob takip sisteminin doğru yapılandırılması büyük önem taşır. Bu sistem, hem PvE hem de PvP deneyimini doğrudan etkiler. Game core, auth, channel gibi diğer sistemlerle uyumlu çalışması gerekir. Geliştiriciler, source kod üzerinde değişiklik yaparken hem C++ hem de Python bilgilerini kullanarak daha esnek ve güçlü sistemler inşa edebilir.


Editing the Metin2 Mob Tracking System

What Is the Mob Tracking System?
In Metin2 private servers, the mob tracking system is one of the essential mechanisms that allows players to continuously attack a specific enemy by tracking it. This system is critical for both PvP and PvE mechanics. Especially in PvP-focused servers, incorrect configuration of mob tracking can break game balance. In this article, we will explain step by step how to configure the mob tracking system during Metin2 private server development.

Overview of the Tracking System
The mob tracking system is typically defined within C++-based game server source code. The mob object holds a target variable indicating which player is currently being tracked. The tracking logic activates when a player attacks the mob or enters its range. This system is configured in core files such as battle.cpp and char_battle.cpp.

Tracking Range and Wait Time
In some Metin2 private servers, after a mob tracks a player, it waits briefly before switching to another player. This delay is often hardcoded in C++, such as through a variable like MOB_TARGET_SWITCH_TIME. Adjusting this value determines how long the mob continues to track the same target. Additionally, the tracking range is checked within battle functions. These range settings must be optimized so the mob does not lose its target easily.

Consequences of Incorrect Tracking Settings
If the tracking system is not properly configured, unwanted behaviors may occur. For instance, a mob might track multiple players simultaneously or switch targets too quickly, thus disrupting the PvE experience. Moreover, if cheat tools make tracking mobs easier, server fairness can be seriously affected. Therefore, anti-cheat mechanisms must also be considered during source edit.

Controlling Settings with Python and GUI
Some Metin2 developers prefer to manage mob tracking settings via Python interfaces. With uiscript files defined in py root, settings such as tracking duration or range can be modified through admin panels. This method offers a more user-friendly solution for server administrators. However, integration between such GUI systems and the C++ core must be handled carefully.

DB Core and Tracking Logs
The mob tracking system sometimes stores records in the database (DB). Particularly when integrated with party systems, data such as who determined the mob's target or loot distribution rights can be stored in db_core. Proper reading and writing of these records directly impacts server performance.

Conclusion
In the process of developing Metin2 private servers, correctly configuring the mob tracking system is crucial. This system directly affects both PvE and PvP experiences and must work harmoniously with other systems such as game core, auth, and channel. Developers can build more flexible and robust systems by utilizing both C++ and Python knowledge while editing source code.
 

Şuan Bu Konuyu Görüntüleyen Kullanıcılar (Toplam : 0, Üye : 0, Misafir : 0)

Geri
Üst Alt