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:
Then register enum in luascript.cpp:
item.cpp#Item::getWorth()
replace whole method with this:
in player.cpp#updateSaleShopList method
replace
with
in game.cpp#addMoney method,
after
add
Finally in protocolgame.cpp#sendSaleItemList method
replace whole method with this:
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.
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)) {
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;
}
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: