• 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!

New currency

Dorianek

Member
Joined
Nov 29, 2018
Messages
247
Reaction score
10
Location
Poland
Hello, how to add in (TFS1,3) a new currency? because I was looking for game cpp but I do not see anything

I would like to add two currencies
Scrabcoins
nuggets

and how could someone explain to me how to add it

I mean only the script that adds currency to the game

because I already wrote scripts for other currencies
 
Last edited:
Hello, how to add in (TFS1,3) a new currency? because I was looking for game cpp but I do not see anything

I would like to add two currencies
Scrabcoins
nuggets

and how could someone explain to me how to add it

I mean only the script that adds currency to the game

because I already wrote scripts for other currencies
open chomikuj.pl look for mazurski ots and check the old yurots source there is plenty of code there to take idea from :)
 
find in your game.cpp void::addMoney and exchange the whole function with this one
C++:
void Game::addMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/)
{
    if (money == 0) {
        return;
    }
    uint32_t goldNuggets = money / 100000000;
    money -= goldNuggets * 100000000;
    while (goldNuggets > 0) {
        const uint16_t count = std::min<uint32_t>(100, goldNuggets);
        Item* remaindItem = Item::CreateItem(ITEM_GOLD_NUGGET, count);
        ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
        if (ret != RETURNVALUE_NOERROR) {
            internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
        }
        goldNuggets -= count;
    }
    uint32_t scarabCoins = money / 1000000;
    if (scarabCoins != 0) {
        Item* remaindItem = Item::CreateItem(ITEM_SCARAB_COIN, scarabCoins);
        ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
        if (ret != RETURNVALUE_NOERROR) {
            internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
        }
        money -= scarabCoins * 1000000;
    }
    uint32_t crystalCoins = money / 10000;
    if (crystalCoins != 0) {
        Item* remaindItem = Item::CreateItem(ITEM_CRYSTAL_COIN, crystalCoins);
        ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
        if (ret != RETURNVALUE_NOERROR) {
            internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
        }
        money -= crystalCoins * 10000;
    }
    uint16_t platinumCoins = money / 100;
    if (platinumCoins != 0) {
        Item* remaindItem = Item::CreateItem(ITEM_PLATINUM_COIN, platinumCoins);
        ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
        if (ret != RETURNVALUE_NOERROR) {
            internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
        }
        money -= platinumCoins * 100;
    }
    if (money != 0) {
        Item* remaindItem = Item::CreateItem(ITEM_GOLD_COIN, money);
        ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
        if (ret != RETURNVALUE_NOERROR) {
            internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
        }
    }
}
and find game::removeMoney and change it with this ( whole function )
C++:
bool Game::removeMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/)
{
    if (cylinder == nullptr) {
        return false;
    }
    if (money == 0) {
        return true;
    }
    std::vector<Container*> containers;
    std::multimap<uint64_t, Item*> moneyMap;
    uint64_t moneyCount = 0;
    for (size_t i = cylinder->getFirstIndex(), j = cylinder->getLastIndex(); i < j; ++i) {
        Thing* thing = cylinder->getThing(i);
        if (!thing) {
            continue;
        }
        Item* item = thing->getItem();
        if (!item) {
            continue;
        }
        Container* container = item->getContainer();
        if (container) {
            containers.push_back(container);
        } else {
            const uint64_t worth = item->getWorth();
            if (worth != 0) {
                moneyCount += worth;
                moneyMap.emplace(worth, item);
            }
        }
    }
    size_t i = 0;
    while (i < containers.size()) {
        Container* container = containers[i++];
        for (Item* item : container->getItemList()) {
            Container* tmpContainer = item->getContainer();
            if (tmpContainer) {
                containers.push_back(tmpContainer);
            } else {
                const uint64_t worth = item->getWorth();
                if (worth != 0) {
                    moneyCount += worth;
                    moneyMap.emplace(worth, item);
                }
            }
        }
    }
    if (moneyCount < money) {
        return false;
    }
    for (const auto& moneyEntry : moneyMap) {
        Item* item = moneyEntry.second;
        if (moneyEntry.first < money) {
            internalRemoveItem(item);
            money -= moneyEntry.first;
        } else if (moneyEntry.first > money) {
            const uint64_t worth = moneyEntry.first / item->getItemCount();
            const uint32_t removeCount = std::ceil(money / static_cast<double>(worth));
            addMoney(cylinder, (worth * removeCount) - money, flags);
            internalRemoveItem(item, removeCount);
            break;
        } else {
            internalRemoveItem(item);
            break;
        }
    }
    return true;
}
then go to player.cpp and find line looks like this and add this instead
C++:
if (itemId != ITEM_GOLD_COIN && itemId != ITEM_PLATINUM_COIN && itemId != ITEM_CRYSTAL_COIN && itemId != ITEM_SCARAB_COIN && itemId != ITEM_GOLD_NUGGET) {

in item.cpp change item:getWorth function with this one
C++:
uint64_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_SCARAB_COIN:
        return count * 1000000ULL;
    case ITEM_GOLD_NUGGET:
        return count * 100000000ULL;
    default:
        return 0;
    }
}

since uint_32 maximum value is lower than 100 gold nugget,
open item.h
change this line
C++:
uint32_t getWorth() const;
with this one
C++:
uint64_t getWorth() const;

add those in const.h
C++:
    ITEM_SCARAB_COIN = 2159,
    ITEM_GOLD_NUGGET = 2157,

and those in luascript.cpp
C++:
    registerEnum(ITEM_SCARAB_COIN)
    registerEnum(ITEM_GOLD_NUGGET)

all credits goes to @Sarah Wesker and @Stigma , just simplified thier 2 posts in 1
 
find in your game.cpp void::addMoney and exchange the whole function with this one
C++:
void Game::addMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/)
{
    if (money == 0) {
        return;
    }
    uint32_t goldNuggets = money / 100000000;
    money -= goldNuggets * 100000000;
    while (goldNuggets > 0) {
        const uint16_t count = std::min<uint32_t>(100, goldNuggets);
        Item* remaindItem = Item::CreateItem(ITEM_GOLD_NUGGET, count);
        ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
        if (ret != RETURNVALUE_NOERROR) {
            internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
        }
        goldNuggets -= count;
    }
    uint32_t scarabCoins = money / 1000000;
    if (scarabCoins != 0) {
        Item* remaindItem = Item::CreateItem(ITEM_SCARAB_COIN, scarabCoins);
        ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
        if (ret != RETURNVALUE_NOERROR) {
            internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
        }
        money -= scarabCoins * 1000000;
    }
    uint32_t crystalCoins = money / 10000;
    if (crystalCoins != 0) {
        Item* remaindItem = Item::CreateItem(ITEM_CRYSTAL_COIN, crystalCoins);
        ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
        if (ret != RETURNVALUE_NOERROR) {
            internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
        }
        money -= crystalCoins * 10000;
    }
    uint16_t platinumCoins = money / 100;
    if (platinumCoins != 0) {
        Item* remaindItem = Item::CreateItem(ITEM_PLATINUM_COIN, platinumCoins);
        ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
        if (ret != RETURNVALUE_NOERROR) {
            internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
        }
        money -= platinumCoins * 100;
    }
    if (money != 0) {
        Item* remaindItem = Item::CreateItem(ITEM_GOLD_COIN, money);
        ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags);
        if (ret != RETURNVALUE_NOERROR) {
            internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
        }
    }
}
and find game::removeMoney and change it with this ( whole function )
C++:
bool Game::removeMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/)
{
    if (cylinder == nullptr) {
        return false;
    }
    if (money == 0) {
        return true;
    }
    std::vector<Container*> containers;
    std::multimap<uint64_t, Item*> moneyMap;
    uint64_t moneyCount = 0;
    for (size_t i = cylinder->getFirstIndex(), j = cylinder->getLastIndex(); i < j; ++i) {
        Thing* thing = cylinder->getThing(i);
        if (!thing) {
            continue;
        }
        Item* item = thing->getItem();
        if (!item) {
            continue;
        }
        Container* container = item->getContainer();
        if (container) {
            containers.push_back(container);
        } else {
            const uint64_t worth = item->getWorth();
            if (worth != 0) {
                moneyCount += worth;
                moneyMap.emplace(worth, item);
            }
        }
    }
    size_t i = 0;
    while (i < containers.size()) {
        Container* container = containers[i++];
        for (Item* item : container->getItemList()) {
            Container* tmpContainer = item->getContainer();
            if (tmpContainer) {
                containers.push_back(tmpContainer);
            } else {
                const uint64_t worth = item->getWorth();
                if (worth != 0) {
                    moneyCount += worth;
                    moneyMap.emplace(worth, item);
                }
            }
        }
    }
    if (moneyCount < money) {
        return false;
    }
    for (const auto& moneyEntry : moneyMap) {
        Item* item = moneyEntry.second;
        if (moneyEntry.first < money) {
            internalRemoveItem(item);
            money -= moneyEntry.first;
        } else if (moneyEntry.first > money) {
            const uint64_t worth = moneyEntry.first / item->getItemCount();
            const uint32_t removeCount = std::ceil(money / static_cast<double>(worth));
            addMoney(cylinder, (worth * removeCount) - money, flags);
            internalRemoveItem(item, removeCount);
            break;
        } else {
            internalRemoveItem(item);
            break;
        }
    }
    return true;
}
then go to player.cpp and find line looks like this and add this instead
C++:
if (itemId != ITEM_GOLD_COIN && itemId != ITEM_PLATINUM_COIN && itemId != ITEM_CRYSTAL_COIN && itemId != ITEM_SCARAB_COIN && itemId != ITEM_GOLD_NUGGET) {

in item.cpp change item:getWorth function with this one
C++:
uint64_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_SCARAB_COIN:
        return count * 1000000ULL;
    case ITEM_GOLD_NUGGET:
        return count * 100000000ULL;
    default:
        return 0;
    }
}

since uint_32 maximum value is lower than 100 gold nugget,
open item.h
change this line
C++:
uint32_t getWorth() const;
with this one
C++:
uint64_t getWorth() const;

add those in const.h
C++:
    ITEM_SCARAB_COIN = 2159,
    ITEM_GOLD_NUGGET = 2157,

and those in luascript.cpp
C++:
    registerEnum(ITEM_SCARAB_COIN)
    registerEnum(ITEM_GOLD_NUGGET)

all credits goes to @Sarah Wesker and @Stigma , just simplified thier 2 posts in 1
thats a nice one but this should be turned into /lib/ so you can add /delete easier ;)
 
thats a nice one but this should be turned into /lib/ so you can add /delete easier ;)
add ? delete ? what are you talking about? how you are going to compile and you want to delete ITEM_GOLD_NUGGET = 2197 it will give you error "undeclared identifier"
 
add ? delete ? what are you talking about? how you are going to compile and you want to delete ITEM_GOLD_NUGGET = 2197 it will give you error "undeclared identifier"
im saying to make the code read from lib files for currencies. simplify it by making the structure inside of lua so you can add more when needed on the go because once compiled tfs is really poor with portability of the lua functions.
 
im saying to make the code read from lib files for currencies. simplify it by making the structure inside of lua so you can add more when needed on the go because once compiled tfs is really poor with portability of the lua functions.
then develop your own one and tell me if it worked :D
 
Back
Top