• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!
  • If you're using Gesior 2012 or MyAAC, please review this thread for information about a serious security vulnerability and a fix.

Feature [OTX 6.X] Adding new currency - Gold ingot

fortyy150

New Member
Joined
May 10, 2010
Messages
107
Reaction score
1
I was looking any thread in this forum to add new currency to OTX 6.X and I was able to found something but not fully working so after a deeper research I saw what the problem was so I decided to post the solution in case someone else is trying to add a new currency after Crystal Coins currency.

The first step is to declare constant ITEM_GOLD_INGOT in const.h:
C++:
ITEM_GOLD_COIN = 2148,
ITEM_PLATINUM_COIN = 2152,
ITEM_CRYSTAL_COIN = 2160,
ITEM_GOLD_INGOT = 9971, // <- added this
ITEM_STORE_COIN = 24774,

Then register enum in luascript.cpp:
C++:
registerEnum(ITEM_GOLD_INGOT)

item.cpp#Item::getWorth()
replace whole method with this:
C++:
uint32_t Item::getWorth() const
{
    switch (id) {
        case ITEM_GOLD_COIN:
            return count;

        case ITEM_PLATINUM_COIN:
            return count * 100;

        case ITEM_CRYSTAL_COIN:
            return count * 10000;

        case ITEM_GOLD_INGOT:
            return count * 1000000;

        default:
            return 0;
    }
}

in player.cpp#updateSaleShopList method
replace
C++:
if ((currency == ITEM_GOLD_COIN && itemId != ITEM_GOLD_COIN && itemId != ITEM_PLATINUM_COIN && itemId != ITEM_CRYSTAL_COIN) || (currency != ITEM_GOLD_COIN && itemId != currency)) {
with
Code:
if ((currency == ITEM_GOLD_COIN && itemId != ITEM_GOLD_COIN && itemId != ITEM_PLATINUM_COIN && itemId != ITEM_CRYSTAL_COIN && itemId != ITEM_GOLD_INGOT) || (currency != ITEM_GOLD_COIN && itemId != currency)) {


in game.cpp#addMoney method,
after
C++:
if (money == 0) {
        return;
    }
add
C++:
uint32_t goldIngots = money / 1000000;
money -= goldIngots * 1000000;
while (goldIngots > 0) {
    const uint16_t count = std::min<uint32_t>(100, goldIngots);
    Item* remaindItem = Item::CreateItem(ITEM_GOLD_INGOT, count);
    ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
    if (ret != RETURNVALUE_NOERROR) {
        internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
    }
    goldIngots -= count;
}


Finally in protocolgame.cpp#sendSaleItemList method
replace whole method with this:
C++:
void ProtocolGame::sendSaleItemList(const std::vector<ShopInfo> &shop, const std::map<uint32_t, uint32_t> &inventoryMap)
{
    //Since we already have full inventory map we shouldn't call getMoney here - it is simply wasting cpu power
    uint64_t playerMoney = 0;
    auto it = inventoryMap.find(ITEM_GOLD_INGOT);
    if (it != inventoryMap.end())
    {
        playerMoney += static_cast<uint64_t>(it->second) * 1000000;
    }
    it = inventoryMap.find(ITEM_CRYSTAL_COIN);
    if (it != inventoryMap.end())
    {
        playerMoney += static_cast<uint64_t>(it->second) * 10000;
    }
    it = inventoryMap.find(ITEM_PLATINUM_COIN);
    if (it != inventoryMap.end())
    {
        playerMoney += static_cast<uint64_t>(it->second) * 100;
    }
    it = inventoryMap.find(ITEM_GOLD_COIN);
    if (it != inventoryMap.end())
    {
        playerMoney += static_cast<uint64_t>(it->second);
    }

    NetworkMessage msg;
    msg.addByte(0xEE);
    msg.addByte(0x00);
    msg.add<uint64_t>(player->getBankBalance());
    uint16_t currency = player->getOnlyShopOwner() ? player->getOnlyShopOwner()->getCurrency() : ITEM_GOLD_COIN;
    msg.addByte(0xEE);
    if (currency == ITEM_GOLD_COIN) {
        msg.addByte(0x01);
        msg.add<uint64_t>(playerMoney);
    } else {
        msg.addByte(0x02);
        uint64_t newCurrency = 0;
        auto search = inventoryMap.find(currency);
        if (search != inventoryMap.end()) {
            newCurrency += static_cast<uint64_t>(search->second);
        }
        msg.add<uint64_t>(newCurrency);
    }

    msg.addByte(0x7B);
    msg.add<uint64_t>(playerMoney);

    uint8_t itemsToSend = 0;
    auto msgPosition = msg.getBufferPosition();
    msg.skipBytes(1);

    for (const ShopInfo &shopInfo : shop) {
        if (shopInfo.sellPrice == 0) {
            continue;
        }

        uint32_t index = static_cast<uint32_t>(shopInfo.itemId);
        if (Item::items[shopInfo.itemId].isFluidContainer()) {
            index |= (static_cast<uint32_t>(shopInfo.subType) << 16);
        }

        it = inventoryMap.find(index);
        if (it != inventoryMap.end()) {
            msg.addItemId(shopInfo.itemId);
            msg.addByte(std::min<uint32_t>(it->second, std::numeric_limits<uint8_t>::max()));
            if (++itemsToSend >= 0xFF) {
                break;
            }
        }
    }

    msg.setBufferPosition(msgPosition);
    msg.addByte(itemsToSend);
    writeToOutputBuffer(msg);
}

Compile it and that's it!

Last step is what was missing in other threads like Lua - [TFS 1.2] Crystal Coin -> Gold Nugget (https://otland.net/threads/tfs-1-2-crystal-coin-gold-nugget.253866/#post-2462745) or TFS 1.X+ - coin accept (https://otland.net/threads/coin-accept.269988/#post-2602970) that's why I decided to add new thread with my finding.
 
Last edited:
Top