[C++] Oto Pot Doldurma Sistemi [Auto Potion Refill]

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

Admin

Metin2Lobby
Yönetici
Founder
Katılım
6 Mayıs 2022
Mesajlar
52,647
Ticaret : 1 / 0 / 0
Merhaba,

Sistem aslında doğru kullanılırsa mükemmel bir fikir içeriyor.
Mantık çok basit, eğer belirlediğiniz NPC'ye doğru yaklaşırsanız, oto potlarınız otomatik olarak dolmaya başlıyor.
Aşağıdaki videodaki gibi. Silah satıcısına karakter yaklaştığında oto potun doluşuna bakın. Bunu wslik olur, arena alanlarında olur benzinlik NPC si gibi bir NPC ile potları otomatik doldurma imkanı sağlayarak oyuncularınıza çok güzel pazarlayabilirsiniz.



DİKKATLE OKU!
Eğer GET NPC LOCATION BY VNUM sistemi sizde ekli değilse, önce onu eklemeniz gerek!!!!
Burada paylaştım :



Service.h / CommonDefines.h
Kod:
//ekle: #define ENABLE_POTION_REFILL

game/sectree_manager.h
Kod:
//Bul:         bool        SaveAttributeToImage(int lMapIndex, const char * c_pszFileName, LPSECTREE_MAP pMapSrc = NULL); //Ekle: #ifdef ENABLE_POTION_REFILL         bool        GetNpcLocationByVnum(long lMapIndex, DWORD npcVnum, std::vector<std::pair<long, long>>& positions); #endif


game/sectree_manager.cpp
Kod:
//Fonkisyonu bul: bool SECTREE_MANAGER::SaveAttributeToImage(int lMapIndex, const char * c_pszFileName, LPSECTREE_MAP pMapSrc) //Fonkisyonun bitişini takip et ve ekle: #ifdef ENABLE_POTION_REFILL bool SECTREE_MANAGER::GetNpcLocationByVnum(long lMapIndex, DWORD npcVnum, std::vector<std::pair<long, long>>& positions) {     LPSECTREE_MAP sectree = SECTREE_MANAGER::instance().GetMap(lMapIndex);     if (sectree != nullptr)     {         struct FFindNPCByVnum         {             DWORD specifiedVnum;             std::vector<std::pair<long, long>>& npcPositions;             FFindNPCByVnum(DWORD vnum, std::vector<std::pair<long, long>>& positions)                 : specifiedVnum(vnum), npcPositions(positions) {}             void operator()(LPENTITY ent)             {                 if (ent->IsType(ENTITY_CHARACTER))                 {                     LPCHARACTER pChar = static_cast<LPCHARACTER>(ent);                     if (pChar->IsNPC() && pChar->GetMobTable().dwVnum == specifiedVnum)                     {                         npcPositions.emplace_back(pChar->GetX(), pChar->GetY());                     }                 }             }         };         std::vector<std::pair<long, long>> npcPositions;         FFindNPCByVnum finder(npcVnum, npcPositions);         sectree->for_each(finder);         positions.insert(positions.end(), npcPositions.begin(), npcPositions.end());         return !positions.empty();     }     return false; } #endif

game/unique_item.h
Kod:
/!!!ÖNEMLİ!!! //Enum'u ihtiyaçlarınıza göre ayarlayın, ör. Farklı otomatik iksir vnum'ları kullanıyorsanız. //AUTO_POTION_MAX_NUM, kullandığınız otomatik iksirlerin sayısına eşit olmalıdır. //!!!ÖNEMLİ!!! //Dosyanın sonuna ekle: #ifdef ENABLE_POTION_REFILL enum EAutoPotion {     ITEM_AUTO_HP_POTION_1 = ITEM_AUTO_HP_RECOVERY_S,     ITEM_AUTO_HP_POTION_2 = ITEM_AUTO_HP_RECOVERY_M,     ITEM_AUTO_HP_POTION_3 = ITEM_AUTO_HP_RECOVERY_L,     ITEM_AUTO_HP_POTION_4 = ITEM_AUTO_HP_RECOVERY_X,     ITEM_AUTO_SP_POTION_1 = ITEM_AUTO_SP_RECOVERY_S,     ITEM_AUTO_SP_POTION_2 = ITEM_AUTO_SP_RECOVERY_M,     ITEM_AUTO_SP_POTION_3 = ITEM_AUTO_SP_RECOVERY_L,     ITEM_AUTO_SP_POTION_4 = ITEM_AUTO_SP_RECOVERY_X,     AUTO_POTION_MAX_NUM = 8, }; #endif

game/char.h
Kod:
//bul:         BYTE            m_bChatCounter; //ekle: #ifdef ENABLE_POTION_REFILL         bool            m_bIsNearRefillNPC;         LPEVENT            m_refillPotionEvent;         void            PotionRefillMgt(); #endif //bul:         DWORD            GetLastAttackTime() const    { return m_dwLastAttackTime; } //ekle: #ifdef ENABLE_POTION_REFILL         void            PotionRefillMgt();         void            SetNearRefillNPC(bool bIsNear);         bool            GetNearRefillNPC() const        { return m_bIsNearRefillNPC; } #endif

game/char.cpp
Kod:
//bool CHARACTER::Move(long x, long y): fonksiyonu içinde bul     OnMove();     return Sync(x, y);      //bulduğun fonksiyonun üstüne ekle: #ifdef ENABLE_POTION_REFILL     PotionRefillMgt(); #endif //fonksiyonun içinde void CHARACTER::Disconnect(const char * c_pszReason): aşağıdaki kodu bul marriage::CManager::instance().Logout(this); //üstüne ekle #ifdef ENABLE_POTION_REFILL     if (GetNearRefillNPC())     {         SetNearRefillNPC(false);     } #endif //fonksiyonu bul: void CHARACTER::SendMovePacket(BYTE bFunc, BYTE bArg, DWORD x, DWORD y, DWORD dwDuration, DWORD dwTime, int iRot) //fonksiyon bittikten sonra altına yeni fonksiyon olarak ekleyin: #ifdef ENABLE_POTION_REFILL void CHARACTER::PotionRefillMgt() {     if (IsPC())     {         DWORD dwVnum = 9001; //Change NPC vnum here         float fArea = 1500.0f; //Change area around NPC here         std::vector<std::pair<long, long>> positions;         if (SECTREE_MANAGER::Instance().GetNpcLocationByVnum(GetMapIndex(), dwVnum, positions))         {             if (!positions.empty())             {                 if (!GetNearRefillNPC())                 {                     for (const auto& position : positions)                     {                         if (DISTANCE_APPROX(position.first - GetX(), position.second - GetY()) <= fArea)                         {                             ChatPacket(CHAT_TYPE_INFO, "Potions are refilling...");                             SetNearRefillNPC(true);                             break;                         }                     }                 }                 else                 {                     for (const auto& position : positions)                     {                         if (DISTANCE_APPROX(position.first - GetX(), position.second - GetY()) > fArea)                         {                             ChatPacket(CHAT_TYPE_INFO, "Refilling of potions stopped");                             SetNearRefillNPC(false);                             break;                         }                     }                 }             }         }     } } void CHARACTER::PotionRefillMgt() {     if (IsPC())     {         DWORD dwVnum = 9001; //Change NPC vnum here         float fArea = 1500.0f; //Change area around NPC here         std::vector<std::pair<long, long>> positions;         if (SECTREE_MANAGER::Instance().GetNpcLocationByVnum(GetMapIndex(), dwVnum, positions))         {             if (!positions.empty())             {                 if (!GetNearRefillNPC())                 {                     for (const auto& position : positions)                     {                         if (DISTANCE_APPROX(position.first - GetX(), position.second - GetY()) <= fArea)                         {                             ChatPacket(CHAT_TYPE_INFO, "Potions are refilling...");                             SetNearRefillNPC(true);                             break;                         }                     }                 }                 else                 {                     for (const auto& position : positions)                     {                         if (DISTANCE_APPROX(position.first - GetX(), position.second - GetY()) > fArea)                         {                             ChatPacket(CHAT_TYPE_INFO, "Refilling of potions stopped");                             SetNearRefillNPC(false);                             break;                         }                     }                 }             }         }     } } void CHARACTER::SetNearRefillNPC(bool bIsNear) {     m_bIsNearRefillNPC = bIsNear;     std::vector<LPITEM> ownedPotions;     LPITEM item = nullptr;     for (int i = 0; i < AUTO_POTION_MAX_NUM; i++)     {         switch (i)         {             case 0:                 item = FindSpecifyItem(ITEM_AUTO_HP_POTION_1);                 break;             case 1:                 item = FindSpecifyItem(ITEM_AUTO_HP_POTION_2);                 break;             case 2:                 item = FindSpecifyItem(ITEM_AUTO_HP_POTION_3);                 break;             case 3:                 item = FindSpecifyItem(ITEM_AUTO_HP_POTION_4);                 break;             case 4:                 item = FindSpecifyItem(ITEM_AUTO_SP_POTION_1);                 break;             case 5:                 item = FindSpecifyItem(ITEM_AUTO_SP_POTION_2);                 break;             case 6:                 item = FindSpecifyItem(ITEM_AUTO_SP_POTION_3);                 break;             case 7:                 item = FindSpecifyItem(ITEM_AUTO_SP_POTION_4);                 break;             default:                 break;         }         if (item)             ownedPotions.push_back(item);     }     for (auto &potion : ownedPotions)     {         if (bIsNear)             potion->StartPotionRecoveryEvent();         else             potion->StopPotionRecoveryEvent();     } } #endif // void CHARACTER::Disconnect(const char * c_pszReason): fonksiyonu içinde bul     marriage::CManager::instance().Logout(this);      //Add üstüne ekle: #ifdef ENABLE_POTION_REFILL     if (GetNearRefillNPC())     {         SetNearRefillNPC(false);     } #endif

game/item.h
Kod:
//bul:         void        StartDestroyEvent(int iSec=300); //ekle: #ifdef ENABLE_POTION_REFILL         void        SetPotionRecoveryEvent(LPEVENT pkEvent);         void        StartPotionRecoveryEvent();         void        StopPotionRecoveryEvent(); #endif //bul:         LPEVENT        m_pkOwnershipEvent; //ekle: #ifdef ENABLE_POTION_REFILL         LPEVENT        m_pkPotionRecoveryEvent; #endif

game/item.cpp
Kod:
//bul:     m_pkRealTimeExpireEvent = NULL; //ekle: #ifdef ENABLE_POTION_REFILL     m_pkPotionRecoveryEvent = NULL; #endif // void CItem::Destroy()): fonksiyonu içinde bul CEntity::Destroy(); //altına ekle: #ifdef ENABLE_POTION_REFILL     event_cancel(&m_pkPotionRecoveryEvent); #endif //şu fonksiyonu bul: void CItem::StartDestroyEvent(int iSec) //fonksiyon bitince altına ekle #ifdef ENABLE_POTION_REFILL EVENTFUNC(potion_recovery_event) {     item_event_info* info = dynamic_cast<item_event_info*>(event->info);     if (info == NULL)     {         sys_err("potion_recovery_event> <Factor> Null pointer");         return 0;     }     LPITEM pkItem = info->item;     //Check if potion is fully restored     //return and cancel event if so     const TItemTable* itemTable = pkItem->GetProto();     if (pkItem->GetSocket(1) == 0)     {         pkItem->SetPotionRecoveryEvent(NULL);         return 0;     }     else     {         int potionValueToRestore = itemTable->alValues[0] / 100 * 10;         int missingPotionValue = pkItem->GetSocket(1);         int newPotionValue = 0;         if (missingPotionValue < potionValueToRestore)         {             pkItem->SetSocket(1, 0, false);             pkItem->SetPotionRecoveryEvent(NULL);             return 0;         }         else         {             newPotionValue = pkItem->GetSocket(1) - potionValueToRestore;             pkItem->SetSocket(1, newPotionValue, false);             return PASSES_PER_SEC(3);         }     } } void CItem::SetPotionRecoveryEvent(LPEVENT pkEvent) {     m_pkPotionRecoveryEvent = pkEvent; } void CItem::StartPotionRecoveryEvent() {     if (m_pkPotionRecoveryEvent)         return;     item_event_info* info = AllocEventInfo<item_event_info>();     info->item = this;     SetPotionRecoveryEvent(event_create(potion_recovery_event, info, PASSES_PER_SEC(3))); } void CItem::StopPotionRecoveryEvent() {     if (m_pkPotionRecoveryEvent)     {         event_cancel(&m_pkPotionRecoveryEvent);     } } #endif

game/input_login.cpp
Kod:
//Fonksiyonu bul: void CInputLogin::Entergame(LPDESC d, const char * data) //Altına ekle #ifdef ENABLE_POTION_REFILL     ch->PotionRefillMgt(); #endif //void CInputLogin::Entergame(LPDESC d, const char * data) fonksiyonunun altına ekleyin: #ifdef ENABLE_POTION_REFILL     ch->PotionRefillMgt(); #endif

İşlem bu kadar.
Metin2 Lobby'da C++ ile Oto Pot Doldurma Sistemi (Auto Potion Refill)

Giriş
Metin2 özel sunucularında oyun deneyimini artırmak amacıyla birçok geliştirici, oyuncuların daha rahat oynamasını sağlayacak sistemler geliştirmektedir. Bu sistemlerden biri olan Oto Pot Doldurma Sistemi (Auto Potion Refill), oyuncuların savaş sırasında veya dikkatini başka şeylere vermesi gerektiğinde potasyumların otomatik olarak yeniden doldurulmasını sağlar. Bu sayede oyuncular, potasyon eksikliği nedeniyle can kaybı yaşamaz ve daha verimli bir şekilde savaşabilirler. Bu makalede, C++ programlama dili kullanılarak Metin2 özel sunucularına nasıl oto pot doldurma sistemi entegre edileceği detaylı olarak ele alınacaktır.

Sistem Hakkında Genel Bilgi
Oto pot sistemi, oyuncunun belirli potasyonları envanterde belirli bir adetin altına düştüğünde, sistem tarafından otomatik olarak marketten satın alınması veya depodan aktarılması prensibiyle çalışır. Bu işlem, genellikle bir komut veya buton yardımıyla başlatılır ve arka planda C++ tabanlı sunucu kodları tarafından yönetilir. Bu sistem, Metin2 özel sunucu geliştiricileri arasında oldukça popülerdir çünkü hem oyun deneyimini artırır hem de oyuncuların potasyon takibini yapmalarını kolaylaştırır.

Sistemin C++ Kodlama Adımları
1. Envanter Kontrolü: İlk adım olarak, oyuncunun envanterindeki belirli potasyonların miktarı kontrol edilmelidir. Bu işlem genellikle game core içinde yer alır ve C++ ile yazılmış fonksiyonlar tarafından gerçekleştirilir.
2. Potasyon Eksikliği Tespiti: Eğer belirtilen potasyonlardan biri minimum seviyenin altına düşerse, sistem bu durumu fark eder ve gerekli aksiyonu başlatır.
3. Marketten Satın Alma veya Depodan Aktarma: Sistem, potasyonu doğrudan market üzerinden satın alabilir veya depoda varsa oradan aktarabilir. Bu işlem, auth ve db core ile entegre çalışan mekanizmalarla sağlanır.
4. Otomatik Tetikleme: Oyuncu savaş halindeyken veya belirli bir süre boyunca potasyon eksikliği yaşarsa sistem, otomatik olarak tetiklenebilir.

Python GUI Entegrasyonu
Sistemin kullanıcı dostu bir arayüzü olması için, Python tabanlı GUI (grafiksel kullanıcı arayüzü) ile birleştirilmesi önerilir. Bu sayede sunucu yöneticisi, sistem ayarlarını daha kolay şekilde düzenleyebilir. Örneğin, hangi potasyonların otomatik olarak doldurulacağını, minimum seviye değerlerini ve tetikleme yöntemlerini ayarlamak mümkün olur. Py Root ve UIScript gibi yapılar, bu entegrasyonu kolaylaştırır.

Avantajlar ve Uygulamalar
- Zaman Tasarrufu: Oyuncular potasyon takibiyle uğraşmaz.
- Daha Verimli PvP: Can potasyonu eksikliği nedeniyle ölümler azalır.
- Kolay Yönetim: Sunucu sahipleri, sistem ayarlarını kolayca değiştirebilir.
- Otomatikleştirme: Sistem tamamen otomatiktir ve kullanıcı müdahalesi gerekmez.

Sonuç
Metin2 özel sunucularında oto pot doldurma sistemi, oyuncu memnuniyetini artıran ve oyun akışını destekleyen önemli bir özelliktir. C++ tabanlı kodlama ile geliştirilen bu sistem, aynı zamanda Python GUI entegrasyonu sayesinde yönetim kolaylığı sunar. Bu makale, Metin2 geliştiricileri için faydalı bir kaynak niteliğindedir ve sistemlerine bu tür gelişmiş özellikler eklemelerine yardımcı olabilir.


Auto Potion Refill System in C++ on Metin2 Lobby

Introduction
To enhance the gaming experience in Metin2 private servers, many developers implement systems that allow players to play more comfortably. One such system is the Auto Potion Refill, which automatically refills potions for players during combat or when they need to focus on other tasks. This prevents players from losing health due to lack of potions and allows them to fight more efficiently. In this article, we will detail how to integrate an auto potion refill system into Metin2 private servers using the C++ programming language.

General Information About The System
The auto-potion system works by automatically purchasing potions from the market or transferring them from storage when the player's inventory falls below a certain amount of specific potions. This process is usually triggered by a command or button and managed in the background by C++ based server codes. This system is very popular among Metin2 private server developers because it enhances the gaming experience and simplifies potion tracking for players.

Steps for Coding The System in C++
1. Inventory Check: First, check the quantity of specific potions in the player’s inventory. This is typically handled within the game core and executed by functions written in C++.
2. Detecting Low Potion Levels: If any of the specified potions fall below the minimum level, the system detects this and initiates the necessary action.
3. Purchase From Market or Transfer From Storage: The system can either purchase the potion directly from the market or transfer it from storage if available. This process is supported by mechanisms integrated with auth and db core.
4. Automatic Triggering: When the player is in combat or experiences low potion levels for a certain duration, the system can trigger automatically.

Python GUI Integration
For a user-friendly interface, integrating the system with a Python based GUI is recommended. This allows server administrators to easily adjust system settings. For instance, they can configure which potions are refilled automatically, set minimum levels, and define triggering methods. Structures like Py Root and UIScript facilitate this integration.

Benefits and Applications
- Time Saving: Players no longer need to track potions manually.
- More Efficient PvP: Deaths caused by lack of health potions are reduced.
- Easy Management: Server owners can easily change system settings.
- Automation: The system operates entirely automatically without user intervention.

Conclusion
The auto potion refill system in Metin2 private servers is a key feature that increases player satisfaction and supports game flow. Developed using C++ based coding, this system also provides ease of management thanks to its Python GUI integration. This article serves as a useful resource for Metin2 developers and helps them add advanced features like this to their systems.
 

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

Benzer konular

Geri
Üst Alt