[C++] Renewal For GM's /full_set Commands

MT2Dev

Cplusplus
Premium Üye
MT Üye
Mesaj
213
Çözümler
11
Beğeni
326
Puan
824
Ticaret Puanı
0
GÜNCELLEME - 25/04/2024

Metin2.dev'den bir kullanıcının isteği üzerine GM karakterin, kuşanılacak itemlerin seviyesinden düşük olmaması için kontrol eklendi, eğer karakter 90 Lvl'den düşükse, fonksiyon hata verip devam etmeyecektir. Bunun dışında item_attr bölümünde her item için ayrı bilgilendirme mesajı eklendi.

ÖNEMLİ BİLGİ

Bu düzenlemeyi sadece C++11 standartlarında bir derleyici kullananlar uygulayabilir !
(C++11 Destekleyen Derleyiciler; GCC 4.8 ve üstü, Clang 3.3 ve üstü, VS 12 ve üstü)

GİRİŞ & PROBLEM

Merhaba, bugün GM komutlarından /full_set komutunu ve ona bağlı olan diğer komutları (do_all_skill_master, do_item_full_set, do_attr_full_set) komple yenileyeceğiz. Kullanışsız itemleri ve efsunlarını değiştirip, fonksiyon içeriğini daha modern hale getirip, (C++11 ve üstü) bilgilendirme mesajları ekleyeceğiz. Taş ve cevher eklemeye gerek duymadım, zaten itemler ve efsunları yeterince op oldu. :LOL:

NEDEN ?

Test aşamasında veya live sunucuda GM karakter ile deneme yapmak isteyen veya sadece karakterin, güçlendirmek isteyen herkes DB üzerinden kendine özel item üretmekle uğraşmıştır (veya çeşitli yardımcı scriptler ile), oyunun orijinalinde var olan bu kod ile ekstra bir zahmetten kurtulmayı hedefliyoruz.

ÖNERİ !

Buradan edinilecek eşyalar çok yüksek oranlı olacağı için, bu kodları sadece GM_IMPLEMENTOR yetkisine sahip kişilerin kullanımına açmanızı tavsiye ederim.

ÇÖZÜM

Öncelikle "cmd_gm.cpp" dosyası açılır.

MT2Dev Renewal:
// FIND THIS FUNCS;

ACMD (do_full_set)
{
    extern void do_all_skill_master (LPCHARACTER ch, const char* argument, int cmd, int subcmd);
    do_all_skill_master (ch, NULL, 0, 0);
// etc.

}

ACMD (do_all_skill_master)
{
    ch->SetHorseLevel (SKILL_MAX_LEVEL);
// etc.
}

ACMD (do_item_full_set)
{
    BYTE job = ch->GetJob();
    LPITEM item;
// etc.
}

ACMD (do_attr_full_set)
{
    BYTE job = ch->GetJob();
    LPITEM item;
    // etc.
}



// CHANGE ALL;

// FULL_SET_COMMAND_RENEWAL
ACMD (do_all_skill_master)   // DevFix 54 (Thanks to MartySaMa for do_all_skill_master renewal)
{
    ch->SetHorseLevel (HORSE_MAX_LEVEL);
    for (int i = 0; i < SKILL_MAX_NUM; i++)
    {
        if (ch->CanUseSkill (i))
        {
            switch (i)
            {
                case SKILL_COMBO:
                    ch->SetSkillLevel (i, 2);
                    break;

                case SKILL_LANGUAGE1:
                case SKILL_LANGUAGE2:
                case SKILL_LANGUAGE3:
                    ch->SetSkillLevel (i, 20);
                    break;

                case SKILL_HORSE_SUMMON:
                    ch->SetSkillLevel (i, 10);
                    break;

                case SKILL_HORSE:
                    ch->SetSkillLevel (i, 21);
                    break;

                case SKILL_HORSE_WILDATTACK:
                case SKILL_HORSE_CHARGE:
                case SKILL_HORSE_ESCAPE:
                case SKILL_HORSE_WILDATTACK_RANGE:
                    ch->SetSkillLevel (i, 20);
                    break;

                default:
                    ch->SetSkillLevel (i, SKILL_MAX_LEVEL);
                    break;
            }
            ch->ChatPacket (CHAT_TYPE_INFO, "<GM> All of your skills are being upgraded to master...");
        }
        else
        {
            switch (i)
            {
                case SKILL_HORSE_WILDATTACK:
                case SKILL_HORSE_CHARGE:
                case SKILL_HORSE_ESCAPE:
                case SKILL_HORSE_WILDATTACK_RANGE:
                    ch->SetSkillLevel (i, 20);
                    break;
            }
            ch->ChatPacket (CHAT_TYPE_INFO, "<GM> Your horse skills are being upgraded to master...");
        }
    }

    ch->SetHorseLevel (21); // Soldier Horse
    ch->ComputePoints();
    ch->SkillLevelPacket();
    ch->ChatPacket (CHAT_TYPE_INFO, "<GM> Upgrade is done successfully!");
}

ACMD (do_item_full_set)   // DevFix 54
{
    if (ch->GetLevel() < 90) // 90 Lvl is enough for items that i use in this function, if you change vnums in the future, make sure change this level limit! - [MT2Dev Note] - 25/04/2024
    {
        ch->ChatPacket (CHAT_TYPE_INFO, "<GM Control> You need to at least 90 Level for use this command!");
        return;
    }

    struct GMItemInfo // General structure for all job types. - [MT2Dev Note] - 23/04/2024
    {
        DWORD vnum;
        BYTE count;
    };

    LPITEM pItem; // We need to look all equipments and unequip all of them (Thanks to Ken for the idea). - [MT2Dev Note] - 23/04/2024
    for (BYTE i = 0; i < WEAR_MAX_NUM; i++) // Using WEAR_MAX_NUM instead of hard-coded value. - [MT2Dev Note] - 23/04/2024
    {
        if (! (pItem = ch->GetWear (i)))
        {
            continue;
        }
        ch->UnequipItem (pItem);
    }

    BYTE job = ch->GetJob();
    switch (job)   // Ps; Item & Bonus names were written with reference to the Turkish locale.. - [MT2Dev Note] - 23/05/2023
    {
        case JOB_SURA:
        {
            const std::vector<GMItemInfo> Suraitems =
            {
                {11973, 1}, // Sura Kraliyet Zirhi      (WEAR_BODY)
                {13149, 1}, // Titan Kalkan +9          (WEAR_SHIELD)
                {15419, 1}, // Kirin Ayakkabi +9        (WEAR_FOOTS)
                {239,   1}, // Ilahi Kilic +9           (WEAR_WEAPON)
                {12539, 1}, // Boynuzlu Kask +9         (WEAR_HEAD)
                {14209, 1}, // Cennetin Gozu Bilezik +9 (WEAR_WRIST)
                {17209, 1}, // Cennetin Gozu Kupe +9    (WEAR_EAR)
                {16209, 1}, // Cennetin Gozu Kolye +9   (WEAR_NECK)
                {71143, 1}, // Mutluluk Yuzugu          (WEAR_UNIQUE1)
                {72702, 1}, // Ruzgarin Ayakkabilari    (WEAR_UNIQUE2)
            };

            for (const auto& GMItemInfo: Suraitems)
            {
                auto item = ITEM_MANAGER::instance().CreateItem (GMItemInfo.vnum);
                if (!item || !item->EquipTo (ch, item->FindEquipCell (ch)))
                {
                    M2_DESTROY_ITEM (item);
                }
            }
        }
        break;

        case JOB_WARRIOR:
        {
            const std::vector<GMItemInfo> Warrioritems =
            {
                {11971, 1}, // Savasci Kraliyet Zirhi   (WEAR_BODY)
                {13149, 1}, // Titan Kalkan +9          (WEAR_SHIELD)
                {15419, 1}, // Kirin Ayakkabi +9        (WEAR_FOOTS)
                {229,   1}, // Ay Kilici +9             (WEAR_WEAPON)
                {12269, 1}, // Korku Maskesi +9         (WEAR_HEAD)
                {14209, 1}, // Cennetin Gozu Bilezik +9 (WEAR_WRIST)
                {17109, 1}, // Abanoz Kupe +9           (WEAR_EAR)
                {16209, 1}, // Cennetin Gozu Kolye +9   (WEAR_NECK)
                {71143, 1}, // Mutluluk Yuzugu          (WEAR_UNIQUE1)
                {72702, 1}, // Ruzgarin Ayakkabilari    (WEAR_UNIQUE2)
            };

            for (const auto& GMItemInfo: Warrioritems)
            {
                auto item = ITEM_MANAGER::instance().CreateItem (GMItemInfo.vnum);
                if (!item || !item->EquipTo (ch, item->FindEquipCell (ch)))
                {
                    M2_DESTROY_ITEM (item);
                }
            }
        }
        break;

        case JOB_SHAMAN:
        {
            const std::vector<GMItemInfo> Shamanitems =
            {
                {11974, 1}, // Saman Kraliyet Zirhi     (WEAR_BODY)
                {13149, 1}, // Titan Kalkan +9          (WEAR_SHIELD)
                {15419, 1}, // Kirin Ayakkabi +9        (WEAR_FOOTS)
                {7159,  1}, // Mutluluk Yelpazesi +9    (WEAR_WEAPON)
                {12679, 1}, // Kardinal Sapka +9        (WEAR_HEAD)
                {14209, 1}, // Cennetin Gozu Bilezik +9 (WEAR_WRIST)
                {17209, 1}, // Cennetin Gozu Kupe +9    (WEAR_EAR)
                {16209, 1}, // Cennetin Gozu Kolye +9   (WEAR_NECK)
                {71143, 1}, // Mutluluk Yuzugu          (WEAR_UNIQUE1)
                {72702, 1}, // Ruzgarin Ayakkabilari    (WEAR_UNIQUE2)
            };

            for (const auto& GMItemInfo: Shamanitems)
            {
                auto item = ITEM_MANAGER::instance().CreateItem (GMItemInfo.vnum);
                if (!item || !item->EquipTo (ch, item->FindEquipCell (ch)))
                {
                    M2_DESTROY_ITEM (item);
                }
            }
        }
        break;

        case JOB_ASSASSIN:
        {
            const std::vector<GMItemInfo> Assassinitems =
            {
                {11972, 1}, // Ninja Kraliyet Zirhi     (WEAR_BODY)
                {13149, 1}, // Titan Kalkan +9          (WEAR_SHIELD)
                {15419, 1}, // Kirin Ayakkabi +9        (WEAR_FOOTS)
                {4019,  1}, // Dokuz Pala +9            (WEAR_WEAPON)
                {12399, 1}, // Ork Kapsonu +9           (WEAR_HEAD)
                {14209, 1}, // Cennetin Gozu Bilezik +9 (WEAR_WRIST)
                {17169, 1}, // Kristal Kupe +9          (WEAR_EAR)
                {16209, 1}, // Cennetin Gozu Kolye +9   (WEAR_NECK)
                {71143, 1}, // Mutluluk Yuzugu          (WEAR_UNIQUE1)
                {72702, 1}, // Ruzgarin Ayakkabilari    (WEAR_UNIQUE2)
            };

            for (const auto& GMItemInfo: Assassinitems)
            {
                auto item = ITEM_MANAGER::instance().CreateItem (GMItemInfo.vnum);
                if (!item || !item->EquipTo (ch, item->FindEquipCell (ch)))
                {
                    M2_DESTROY_ITEM (item);
                }
            }
        }
        break;
    }

    ch->ChatPacket (CHAT_TYPE_INFO, "<GM> New items created and equipped successfully!");
    ch->ComputePoints();
}

ACMD (do_attr_full_set)   // DevFix 54
{
    BYTE job = ch->GetJob();
    switch (job) // I know SetForceAttribute use UpdatePacket for each time but this command only useable by few GM's so that's not a big deal.. - [MT2Dev Note] - 23/04/2024
    {
        case JOB_WARRIOR:
        case JOB_ASSASSIN:
        case JOB_SURA:
        case JOB_SHAMAN:
        {
            LPITEM item;
            item = ch->GetWear (WEAR_HEAD);
            if (item)
            {
                item->ClearAttribute();
                item->SetForceAttribute (0, APPLY_MAX_HP, 32000); // Maks. HP
                item->SetForceAttribute (1, APPLY_CON,      100); // Canlilik
                item->SetForceAttribute (2, APPLY_INT,      100); // Zeka
                item->SetForceAttribute (3, APPLY_STR,      100); // Guc
                item->SetForceAttribute (4, APPLY_DEX,      100); // Ceviklik
                ch->ChatPacket (CHAT_TYPE_INFO, "<GM> Helmet attr is changed successfully..");
            }
            else
            {
                ch->ChatPacket (CHAT_TYPE_INFO, "<GM Control> You're not wear any helmet!");
            }

            item = ch->GetWear (WEAR_WEAPON);
            if (item)
            {
                item->ClearAttribute();
                item->SetForceAttribute (0, APPLY_ATT_SPEED,                100); // Saldiri Hizi
                item->SetForceAttribute (1, APPLY_MOV_SPEED,                100); // Hareket Hizi
                item->SetForceAttribute (2, APPLY_CAST_SPEED,              1000); // Buyu Hizi
                item->SetForceAttribute (3, APPLY_SKILL_DAMAGE_BONUS,      1000); // Beceri Hasari
                item->SetForceAttribute (4, APPLY_NORMAL_HIT_DAMAGE_BONUS, 1000); // Ortalama Zarar
                ch->ChatPacket (CHAT_TYPE_INFO, "<GM> Weapon attr is changed successfully..");
            }
            else
            {
                ch->ChatPacket (CHAT_TYPE_INFO, "<GM Control> You're not wear any weapon!");
            }

            item = ch->GetWear (WEAR_SHIELD);
            if (item)
            {
                item->ClearAttribute();
                item->SetForceAttribute (0, APPLY_CRITICAL_PCT,    100); // Kritik Vurus Sansi
                item->SetForceAttribute (1, APPLY_PENETRATE_PCT,   100); // Delici Vurus Sansi
                item->SetForceAttribute (2, APPLY_IMMUNE_STUN,       1); // Sersemlik Bagisikliligi
                item->SetForceAttribute (3, APPLY_IMMUNE_SLOW,       1); // Yavaslama Bagisikliligi
                item->SetForceAttribute (4, APPLY_IMMUNE_FALL,       1); // Dusmeye Karsi Bagisiklilik
                ch->ChatPacket (CHAT_TYPE_INFO, "<GM> Shield attr is changed successfully..");
            }
            else
            {
                ch->ChatPacket (CHAT_TYPE_INFO, "<GM Control> You're not wear any shield!");
            }

            item = ch->GetWear (WEAR_BODY);
            if (item)
            {
                item->ClearAttribute();
                item->SetForceAttribute (0, APPLY_MAX_HP,       32000); // Maks HP
                item->SetForceAttribute (1, APPLY_BLOCK,          100); // Bloklama
                item->SetForceAttribute (2, APPLY_RESIST_SWORD,   100); // Kilic Sav.
                item->SetForceAttribute (3, APPLY_RESIST_TWOHAND, 100); // Cift-el Sav.
                item->SetForceAttribute (4, APPLY_RESIST_DAGGER,  100); // Bicak Sav.
                ch->ChatPacket (CHAT_TYPE_INFO, "<GM> Armor attr is changed successfully..");
            }
            else
            {
                ch->ChatPacket (CHAT_TYPE_INFO, "<GM Control> You're not wear any armor!");
            }

            item = ch->GetWear (WEAR_FOOTS);
            if (item)
            {
                item->ClearAttribute();
                item->SetForceAttribute (0, APPLY_MAX_HP,    32000); // Maks HP
                item->SetForceAttribute (1, APPLY_MAX_SP,    32000); // Maks SP
                item->SetForceAttribute (2, APPLY_RESIST_BELL, 100); // Can Sav.
                item->SetForceAttribute (3, APPLY_RESIST_FAN,  100); // Yelpaze Sav.
                item->SetForceAttribute (4, APPLY_RESIST_BOW,  100); // Ok Sav.
                ch->ChatPacket (CHAT_TYPE_INFO, "<GM> Shoes attr is changed successfully..");
            }
            else
            {
                ch->ChatPacket (CHAT_TYPE_INFO, "<GM Control> You're not wear any shoes!");
            }

            item = ch->GetWear (WEAR_WRIST);
            if (item)
            {
                item->ClearAttribute();
                item->SetForceAttribute (0, APPLY_POISON_REDUCE,           100); // Zehre Karsi Koyma
                item->SetForceAttribute (1, APPLY_ATT_GRADE_BONUS,        1000); // Saldiri Degeri
                item->SetForceAttribute (2, APPLY_MAGIC_DEF_GRADE,         100); // Buyu Sav.
                item->SetForceAttribute (3, APPLY_NORMAL_HIT_DEFEND_BONUS, 100); // Ortalama Zarara Karsi Koyma
                item->SetForceAttribute (4, APPLY_ATTBONUS_MONSTER,        100); // Canavarlara Karsi Guc
                ch->ChatPacket (CHAT_TYPE_INFO, "<GM> Wrist attr is changed successfully..");
            }
            else
            {
                ch->ChatPacket (CHAT_TYPE_INFO, "<GM Control> You're not wear any wrist!");
            }

            item = ch->GetWear (WEAR_NECK);
            if (item)
            {
                item->ClearAttribute();
                item->SetForceAttribute (0, APPLY_ATTBONUS_WARRIOR,    100); // Savascilara Karsi Guclu
                item->SetForceAttribute (1, APPLY_ATTBONUS_ASSASSIN,   100); // Ninjalara Karsi Guclu
                item->SetForceAttribute (2, APPLY_ATTBONUS_SURA,       100); // Suralara Karsi Guclu
                item->SetForceAttribute (3, APPLY_ATTBONUS_SHAMAN,     100); // Samanlara Karsi Guclu
                item->SetForceAttribute (4, APPLY_SKILL_DEFEND_BONUS,  100); // Beceri Hasarina Karsi Koyma
                ch->ChatPacket (CHAT_TYPE_INFO, "<GM> Necklace attr is changed successfully..");
            }
            else
            {
                ch->ChatPacket (CHAT_TYPE_INFO, "<GM Control> You're not wear any necklace!");
            }

            item = ch->GetWear (WEAR_EAR);
            if (item)
            {
                item->ClearAttribute();
                item->SetForceAttribute (0, APPLY_ATTBONUS_HUMAN,   100); // Yari Insanlara Karsi Guclu
                item->SetForceAttribute (1, APPLY_ATTBONUS_ANIMAL,  100); // Hayvanlara Karsi Guclu
                item->SetForceAttribute (2, APPLY_ATTBONUS_ORC,     100); // Orklara Karsi Guclu
                item->SetForceAttribute (3, APPLY_ATTBONUS_DEVIL,   100); // Seytanlara Karsi Guclu
                item->SetForceAttribute (4, APPLY_ATTBONUS_UNDEAD,  100); // Olumsuzlere Karsi Guclu
                ch->ChatPacket (CHAT_TYPE_INFO, "<GM> Earring attr is changed successfully..");
            }
            else
            {
                ch->ChatPacket (CHAT_TYPE_INFO, "<GM Control> You're not wear any earring!");
            }
        }
        break;
    }

    ch->ComputePoints();
}

ACMD (do_full_set)   // DevFix 54
{
    if (ch->GetLevel() < 90) // 90 Lvl is enough for items that i use in the function, if you change vnums in the future, make sure change this level limit! - [MT2Dev Note] - 25/04/2024
    {
        ch->ChatPacket (CHAT_TYPE_INFO, "<GM Control> You need to at least 90 Level for use this command!");
        return;
    }

    do_all_skill_master (ch, NULL, 0, 0);
    do_item_full_set (ch, NULL, 0, 0);
    do_attr_full_set (ch, NULL, 0, 0);
    ch->ChatPacket (CHAT_TYPE_INFO, "<GM> All is DONE!");
}
// END_OF_FULL_SET_COMMAND_RENEWAL
 
Son düzenleme:
taş cevherde yapsaydın 1000 ortalama ile 2 milyar canlı metni nasıl kesicez :D eline sağlık bu arada
 
Kod:
 if (!item || ...
 {
    M2_DESTROY_ITEM (item);
    break;
}

🤨

Konuyu açmadan önce kodu elli defa kontrol ettim, ona rağmen görmemişim, uyku sersemi iş yapmamak lazım. :D Düzenliyorum.

Ne anlatıyor bunlar diyenlere açıklama; Koray'ın gösterdiği bölümde break; olmaması lazım, kodun geri kalanının devam edip tamamlanması için. İlk hali farklıydı, yeni versiyona geçirirken break'i de yapıştırmışım fark etmeden.
 
GÜNCELLEME - 25/04/2024

Metin2.dev'den bir kullanıcının isteği üzerine GM karakterin, kuşanılacak itemlerin seviyesinden düşük olmaması için kontrol eklendi, eğer karakter 90 Lvl'den düşükse, fonksiyon hata verip devam etmeyecektir. Bunun dışında item_attr bölümünde her item için ayrı bilgilendirme mesajı eklendi.​
 
Geri
Üst