farkmt2official 1
farkmt2official
kralhakan2009 1
kralhakan2009
Vahsi Uzman 1
Vahsi Uzman
BlackFullMoon 1
BlackFullMoon
Hikaye Ekle

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

  • Konuyu başlatan Konuyu başlatan Silverhand
  • Başlangıç tarihi Başlangıç tarihi
  • Cevaplar Cevaplar 7
  • Görüntüleme Görüntüleme 1K
5.00 yıldız(lar) 1 Değerlendirme Değerlendirenler

Ayyıldız2 | 2008 TR Yapısı • 1-99 Orta Emek Destan • Oto Avsız • 10 Temmuz 21:00 HEMEN TIKLA!

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 : https://forum.turkmmo.com/konu/3902...by-vnum-npcnin-haritadaki-koordinatini-bulun/



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.
 

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

Geri
Üst