Register for your free account! | Forgot your password?

Go Back   elitepvpers › MMORPGs › Conquer Online 2
You last visited: Today at 05:15

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



Item Drop Rates

Discussion on Item Drop Rates within the Conquer Online 2 forum part of the MMORPGs category.

Reply
 
Old   #1
 
elite*gold: 0
Join Date: Feb 2025
Posts: 3
Received Thanks: 0
Question Item Drop Rates

Hello, I have been messing around creating a server that i will just localhost.

I have been trying to find information on some rates for Conquer right around 2.0 release, so between 2004-2005. I haven't had much luck, so I have had to rely mostly on memory. But does anyone know, or have a general idea what the rates were for the following?

Refined Item Drop Rate:
Unique Item Drop Rate:
Elite Item Drop Rate:
Super Item Drop Rate:
1-Socket Weapon Drop Rate:
2-Socket Weapon Drop Rate:
+1 Item Drop Rate:
Meteor Drop Rate:
DragonBall Drop Rate:
Normal Gem Rate:
Refined Gem Rate:
Super Gem Rate:
Socket Chance using a Meteor:
Socket Chance using a Dragonball:

Also,

were there different rates for different different classes?

Were there different rates for weapons/armor/accessories?

-------------------------------

I'm under the impression that it was the following, but any feedback helps.

Item Drop Chance: 12%
Refined Item Drop Rate: 0.05% (1 in 2,000 kills)
Unique Item Drop Rate: 0.02% (1 in 5,000 kills)
Elite Item Drop Rate: .005% (1 in 20,000 kills)
Super Item Drop Rate: .0025% (1 in 40,000 kills)
1-Socket Weapon Drop Rate: 20%
2-Socket Weapon Drop Rate: 2%
+1 Item Drop Rate: 0.01% (1 in 10,000 kills)
Meteor Drop Rate: 0.02% (1 in 5,000 kills)
DragonBall Drop Rate: .0025% (1 in 40,000 kills)
Normal Gem Rate: .1736% (Approximately 10 Gems per 24H of Mining)
Refined Gem Rate: .03472% (Approximately 2 Gems per 24H of Mining)
Super Gem Rate: .0116% (Approximately 1 Gems per 36H of Mining)
Socket Chance using a Meteor: 0.25%.
Socket Chance using a Dragonball: 1%

Also,

were there different rates for different classes?
No

Were there different rates for weapons/armor/accessories?
No

Please know, mine are more so an educated guess, based on what I remember things being like from 20 years ago. And can honestly be so far off.

Either way, I am appreciative of any feedback!

Best,
Bree
breeland is offline  
Old   #2
 
pintinho12's Avatar
 
elite*gold: 0
Join Date: Jul 2009
Posts: 952
Received Thanks: 418
I will share you the code I've got from reversing binaries, but ofc this aint from 2005
Code:
void Monster::DropMedicine(uint32_t idOwner)
{
    int roll = FastRandom::NextInt32(100);
    int count;
    if (roll < 2) count = 8;
    else if (roll < 3) count = 6;
    else if (roll < 5) count = 5;
    else if (roll < 8) count = 4;
    else if (roll < 10) count = 3;
    else if (roll < 25) count = 2;
    else count                = 1;

    for (int i = 0; i < count; ++i)
    {
        uint32_t dropMedicine = FastRandom::ChanceCalc(50) ? m_type->dropHp : m_type->dropMp;
        DropItem(dropMedicine, idOwner);
    }
}

bool Monster::GetDropItem(DropItemRecord& itemRecord, uint32_t valueBase, int qualityOverride)
{
    if (valueBase < 1)
    {
        return false;
    }

    int quality;
    if (qualityOverride > -1)
    {
        quality = qualityOverride;
    }
    else
    {
        int random = FastRandom::NextInt32(100);
        if (random < 30)
        {
            quality = 5;
        }
        else if (random < 70)
        {
            quality = 4;
        }
        else
        {
            quality = 3;
        }
    }

    int32_t  itemSubTypeRng = FastRandom::NextInt32(1200);
    uint32_t itemSubType;
    uint32_t itemLev;
    uint8_t  itemColor = 3;
    if (itemSubTypeRng < 20)
    {
        // shoes and talismans
        static constexpr uint32_t specialType[] = {160, 201, 202};
        if (m_type->dropShoes == 99)
        {
            return false;
        }

        itemSubType = specialType[FastRandom::NextInt32(_countof(specialType) - 1)]; // max inclusive
        itemLev     = m_type->dropShoes;
        if (itemSubType == 201 || itemSubType == 202)
        {
            itemLev = 0;
        }
    }
    else if (itemSubTypeRng < 50)
    {
        // necklace and bag
        static constexpr uint32_t dropTypes[] = {120, 121};
        if (m_type->dropNecklace == 99)
        {
            return false;
        }

        itemSubType = dropTypes[FastRandom::NextInt32(_countof(dropTypes) - 1)];
        itemLev     = m_type->dropNecklace;
    }
    else if (itemSubTypeRng < 100)
    {
        // ring, heavy ring and bracelet
        static constexpr uint32_t dropTypes[] = {150, 151, 152};
        if (m_type->dropRing == 99)
        {
            return false;
        }

        itemSubType = dropTypes[FastRandom::NextInt32(_countof(dropTypes) - 1)];
        itemLev     = m_type->dropRing;
    }
    else if (itemSubTypeRng < 400)
    {
        // helmets
        static constexpr uint32_t dropTypes[] = {111, 112, 113, 114, 117, 118, 123, 141, 142};
        if (m_type->dropArmet == 99)
        {
            return false;
        }

        itemSubType = dropTypes[FastRandom::NextInt32(_countof(dropTypes) - 1)];
        itemLev     = m_type->dropArmet;
        itemColor   = static_cast<uint8_t>(FastRandom::NextUInt32(3, 9));
    }
    else if (itemSubTypeRng < 700)
    {
        // armors
        static constexpr uint32_t dropTypes[] = {130, 131, 132, 133, 134, 135};
        if (m_type->dropArmor == 99)
        {
            return false;
        }

        itemSubType = dropTypes[FastRandom::NextInt32(_countof(dropTypes) - 1)];
        itemLev     = m_type->dropArmor;
        itemColor   = static_cast<uint8_t>(FastRandom::NextUInt32(3, 9));
    }
    else
    {
        if (m_type->dropWeapon == 99)
        {
            return false;
        }

        // drop weapons
        int dropRng = FastRandom::NextInt32(100);
        if (dropRng < 20)
        {
            // drop backsword
            itemSubType = 421;
            itemLev     = m_type->dropWeapon;
        }
        else if (dropRng < 40)
        {
            // drop nothing
            return false;
        }
        else if (dropRng < 80)
        {
            // single hand weapons and bow
            static constexpr uint32_t dropTypes[] = {410, 420, 430, 440, 450, 460, 480, 481, 490, 500, 601};
            itemSubType                           = dropTypes[FastRandom::NextInt32(_countof(dropTypes) - 1)];
            itemLev                               = m_type->dropWeapon;
        }
        else
        {
            // double hand and shield
            static constexpr uint32_t dropTypes[] = {510, 530, 560, 580, 900};
            itemSubType                           = dropTypes[FastRandom::NextInt32(_countof(dropTypes) - 1)];
            itemLev                               = m_type->dropWeapon;
        }

        itemColor = static_cast<uint8_t>(FastRandom::NextUInt32(3, 9));
    }

    if (itemLev == 99)
    {
        return false;
    }

    int levelAdustment = FastRandom::NextInt32(100);
    if (levelAdustment < 50)
    {
        int adjusted = (int)itemLev / 3 + FastRandom::NextInt32((int)itemLev / 2);
        itemLev      = adjusted > 0 ? adjusted - 1 : 0;
    }
    else if (levelAdustment < 80)
    {
        // keep level
    }
    else
    {
        bool isLowTier = (itemSubType >= 110 && itemSubType <= 114)
                         || (itemSubType >= 130 && itemSubType <= 134)
                         || (itemSubType >= 900 && itemSubType <= 999);
        uint32_t cap = isLowTier ? 9 : 23;
        itemLev      = __min(itemLev + 1, cap);
    }

    uint32_t           itemTypeId = itemSubType * 1000 + itemLev * 10 + quality;
    const ItemTypeStr* itemType   = ItemManager().GetItemType(itemTypeId);
    if (!itemType)
    {
        return false;
    }

    memset(&itemRecord, 0, sizeof(DropItemRecord));

    itemRecord.type           = itemTypeId;
    float   amountLimit       = (float)itemType->amountLimit;
    int64_t amountLimitScaled = (int64_t)(FastRandom::NextFloat(0.7f, 1.3f) * amountLimit);
    if (amountLimitScaled < 1)
    {
        amountLimitScaled = 1;
    }
    itemRecord.amountLimit = (uint32_t)amountLimitScaled;
    itemRecord.amount      = (uint32_t)amountLimitScaled;

    if (quality <= 5)
    {
        uint32_t price = itemType->price;
        if (price == 0) price = 1;
        uint32_t amount   = 3 * itemType->amount * itemType->amountLimit / price;
        itemRecord.amount = __max(1u, __min(itemRecord.amountLimit, amount));
    }
    else
    {
        itemRecord.amount = itemRecord.amountLimit * (FastRandom::NextUInt32(50) + 50) / 100;
    }

    if (itemTypeId >= 400000 && itemTypeId < 600000)
    {
        int socketChance = FastRandom::NextInt32(100);
        if (socketChance < 5)
        {
            itemRecord.socketNum = 2;
        }
        else if (socketChance < 20)
        {
            itemRecord.socketNum = 1;
        }
    }

    // AddLev 0.33% chance.
    if (FastRandom::NextInt32(300) == 123)
    {
        itemRecord.magic3 = 1;
    }

    if (itemRecord.socketNum == 0)
    {
        int divisor = Item::IsBow(itemTypeId) ? 60 : 300;
        if (FastRandom::NextInt32(divisor) == 13)
        {
            if (FastRandom::ChanceCalc(30))
            {
                itemRecord.bless = 5;
            }
            else
            {
                itemRecord.bless = 3;
            }
        }
    }

    itemRecord.color = itemColor;

    if (itemSubType == 201 || itemSubType == 202)
    {
        itemRecord.bless = 0;
    }
    return true;
}

void Monster::DropEquipment(uint32_t itemTypeId, uint32_t idOwner, int quality)
{
    CHECK(itemTypeId != 0);

    if (itemTypeId < 100)
    {
        DropMoney(itemTypeId, idOwner);
        return;
    }

    DropItemRecord itemRecord{};
    if (!GetDropItem(itemRecord, itemTypeId, quality))
    {
        return;
    }

    POINT pos;
    pos.x = GetMapX();
    pos.y = GetMapY();
    if (!GetMap()->FindDropItemCell(2, pos))
    {
        return;
    }

    itemTypeId    = itemRecord.type;
    User* pKiller = (User*)GetMap()->QueryUser(idOwner);
    if (pKiller)
    {
        bool effect = false;
        if (itemTypeId % 10 == 9)
        {
            pKiller->SendSysMsg("STR_LUCK_ULTRA_EQ");
            effect = true;
        }
        else if (itemTypeId == TYPE_DRAGONBALL)
        {
            pKiller->SendSysMsg("STR_LUCK_DRAGON_BALL");
            effect = true;
        }
        else if (itemTypeId == TYPE_DIVOICEITEM)
        {
            pKiller->SendSysMsg("STR_LUCK_SHT_STAR_TEAR");
            effect = true;
        }

        if (effect)
        {
            pKiller->BroadcastEffect(LUCKY_GUY);
        }

        // A looted +N item (magic3 = add-level > 0) credits the looter's
        // mentor(s) with composition/add-level points. The value comes from
        // cq_student_type.Addlevel; magic3 only gates the event.
        if (itemRecord.magic3 > 0)
        {
            if (IGuideProvider* guide = QueryGuideProvider(ModuleManager().GetProvider(ModuleId::Guide)))
                guide->AwardAddLevel(pKiller, itemRecord.magic3);
        }
    }

    uint32_t newId    = RoleManager().GetNextMapItemId();
    MapItem* pMapItem = MapItem::CreateNew();
    if (pMapItem->Create(newId, GetMap(), pos, itemRecord, idOwner))
    {
        return;
    }

    GM_LOG("gmlog/dropitem", "Monster::DropEquipment(): monster_type[%d], item_type[%u]", GetTypeId(), itemTypeId);
    pMapItem->Release();
    RoleManager().RecycleMapItemId(newId);
}

void Monster::BeKill(IRole* pAttacker)
{
    if (IsDeleted())
    {
        return;
    }

    if (statusSet_)
    {
        statusSet_->AddKeepEffect1(KEEPEFFECT_FADE | KEEPEFFECT_GHOST);
    }

    uint32_t idOwnerItem = 0;
    GameMap* pMap        = GetMap();
    User*    pUser       = nullptr;
    if (pAttacker->QueryObj(OBJ_USER, IPP_OF(pUser)))
    {
        idOwnerItem = pUser->GetId();
    }

    if (GetId() >= CALLPETID_FIRST && GetId() <= CALLPETID_LAST)
    {
        // call pet bomb logic like my_server
    }

    uint32_t dropMoney = m_type->dropMoney;
    int      seed      = (int)dropMoney * 2;
    if (GetLevel() > 60)
    {
        int r = FastRandom::NextInt32(100);
        if (r < 3)
        {
            uint32_t budget = 1320u * seed / 100u;
            int      splits;
            switch (FastRandom::NextInt32(4))
            {
            case 0: splits = 5;
                break;
            case 1: splits = 6;
                break;
            case 2: splits = 7;
                break;
            default: splits = 8;
                break;
            }
            int perPacket = budget / splits;
            for (int i = 0; i < splits; ++i)
            {
                uint32_t amount = (uint32_t)(FastRandom::NextFloat(0.8f) * perPacket);
                if (FastRandom::NextInt32(100) >= 40)
                {
                    DropMoney(amount, idOwnerItem);
                }
                else
                {
                    DropEquipment(amount, idOwnerItem);
                }
            }
        }
        else if (r < 35)
        {
            uint32_t budget = 180 * seed / 100u;

            int r2 = FastRandom::NextInt32(100);
            int splits;
            if (r2 > 40)
            {
                splits = 1;
            }
            else if (r2 >= 10)
            {
                splits = 2;
            }
            else
            {
                splits = 1;
            }

            int perPacket = budget / splits;
            for (int i = 0; i < splits; ++i)
            {
                uint32_t amount = (uint32_t)(FastRandom::NextFloat(0.8f) * perPacket);
                if (FastRandom::NextInt32(100) >= 40)
                {
                    DropMoney(amount, idOwnerItem);
                }
                else
                {
                    DropEquipment(amount, idOwnerItem);
                }
            }
        }
        // no drop at all
    }
    else
    {
        int r = FastRandom::NextInt32(100);
        if (r < 2)
        {
            uint32_t budget = 2000u * seed / 100u;
            int      splits;
            switch (FastRandom::NextInt32(4))
            {
            case 0: splits = 5;
                break;
            case 1: splits = 6;
                break;
            case 2: splits = 7;
                break;
            default: splits = 8;
                break;
            }
            int perPacket = budget / splits;
            for (int i = 0; i < splits; ++i)
            {
                uint32_t amount = (uint32_t)(FastRandom::NextFloat(0.8f) * perPacket);
                if (FastRandom::NextInt32(100) >= 40)
                {
                    DropMoney(amount, idOwnerItem);
                }
                else
                {
                    DropEquipment(amount, idOwnerItem);
                }
            }
        }
        else if (r < 27)
        {
            uint32_t budget = 240 * seed / 100u;
            int      r2     = FastRandom::NextInt32(100);
            int      splits;
            if (r2 > 40)
            {
                splits = 1;
            }
            else if (r2 >= 10)
            {
                splits = 2;
            }
            else
            {
                splits = 1;
            }

            int perPacket = budget / splits;
            for (int i = 0; i < splits; ++i)
            {
                uint32_t amount = (uint32_t)(FastRandom::NextFloat(0.8f) * perPacket);
                if (FastRandom::NextInt32(100) >= 40)
                {
                    DropMoney(amount, idOwnerItem);
                }
                else
                {
                    DropEquipment(amount, idOwnerItem);
                }
            }
        }
        // no drop at all
    }

    // equipment drop
    int qualityItemRng = FastRandom::NextInt32(50000);
    if (qualityItemRng < 1)
    {
        bool doDrop;
        if (GetLevel() <= 80)
        {
            doDrop = FastRandom::NextInt32(3) == 1;
        }
        else
        {
            doDrop = FastRandom::NextInt32(10) == 7;
        }

        if (doDrop)
        {
            uint32_t amount = 100u * GetLevel();
            DropEquipment(amount, idOwnerItem, ITEMQUALITY_SUPER);
        }
    }
    else if (qualityItemRng < 6)
    {
        if (GetLevel() <= 80
            && FastRandom::NextInt32(5) == 3)
        {
            uint32_t amount = 100u * GetLevel();
            DropEquipment(amount, idOwnerItem, ITEMQUALITY_ELITE);
        }
    }
    else if (qualityItemRng < 31)
    {
        if (GetLevel() <= 80
            && FastRandom::NextInt32(3) == 1)
        {
            uint32_t amount = 50u * GetLevel();
            DropEquipment(amount, idOwnerItem, ITEMQUALITY_UNIQUE);
        }
    }
    else if (qualityItemRng < 131)
    {
        uint32_t amount = 30u * GetLevel();
        DropEquipment(amount, idOwnerItem, ITEMQUALITY_REFINED);
    }

    if (FastRandom::ChanceCalc(3))
    {
        DropMedicine(idOwnerItem);
    }

    if (pMap)
    {
        if (FastRandom::NextInt32(750) == 123)
        {
            DropItem(TYPE_SHOOTINGSTAR, idOwnerItem);
        }

        if (FastRandom::NextInt32(300000) == 123)
        {
            DropItem(TYPE_DRAGONBALL, idOwnerItem);

            if (pUser)
            {
                pUser->BroadcastRoomMsg("STR_DRAGON_BALL_DROP", pUser->GetName());
                GM_LOG("gmlog/emoney_buy", "%u\t%s\t%u\t%u", pUser->GetId(), pUser->GetName(), TYPE_DRAGONBALL, 1);
            }
        }
    }

    int gemRandChance;
    if (GetLevel() < 117)
    {
        if (pUser
            && pUser->GetLevel() <= GetLevel() + 5)
        {
            gemRandChance = 900;
        }
        else
        {
            gemRandChance = 9000;
        }
    }
    else
    {
        gemRandChance = 1400;
    }

    if (FastRandom::NextInt32(gemRandChance) == 13)
    {
        int      gemRoll = FastRandom::NextInt32(1200);
        uint32_t itemType;
        if (gemRoll < 100) itemType = 700011;
        else if (gemRoll < 200) itemType = 700001;
        else if (gemRoll < 300) itemType = 700031;
        else if (gemRoll < 400) itemType = 700101;
        else if (gemRoll < 500) itemType = 700121;
        else if (gemRoll < 675) itemType = 700061;
        else if (gemRoll < 850) itemType = 700051;
        else if (gemRoll < 1025) itemType = 700041;
        else itemType                     = 700021;

        DropItem(itemType, idOwnerItem);
    }

    if (GetId() < CALLPETID_FIRST || GetId() > CALLPETID_LAST)
    {
        DropCommonItem(idOwnerItem);
    }

    if (pUser)
    {
        GameAction::ExecuteAction(m_type->action, pUser, this);
    }

    if (m_type->type == 25) // unsure what this would mean
    {
        User* pOwner = (User*)QueryUser();
        if (pOwner)
        {
            pOwner->SetAttributes(USERATTRIB_LIFE, 0, SYNCHRO_TRUE);
            pOwner->BeKill(pAttacker);
        }
    }

    DelMonster(false);
}
glhf
pintinho12 is offline  
Thanks
1 User
Old   #3
 
elite*gold: 0
Join Date: Jan 2009
Posts: 31
Received Thanks: 4
Quote:
Originally Posted by pintinho12 View Post
I will share you the code I've got from reversing binaries, but ofc this aint from 2005
glhf
By any chance do you have the monster spawns and the PVE damage calculations?
dolhabogdan is offline  
Reply


Similar Threads Similar Threads
Querys Navicat! <Drop rates> <Composing rates> AND MORE
06/18/2008 - EO PServer Hosting - 2 Replies
Querys Navicat! Go to Navicat Go to my click at New CLICK AT THE BIG ICON All Click at New Query paste the text and click at run update FIleName(Likecq_drop_item_rule) set <Here The column name>=Here Numbers or letters; Drop rates update cq_dropitemrule set item0=ITEM ID HERE;



All times are GMT +2. The time now is 05:16.


Powered by vBulletin®
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2026 elitepvpers All Rights Reserved.