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

TFS 0.X Buy items with money backpack or bank balance 0.4

gmstrikker

Well-Known Member
Joined
Jul 30, 2014
Messages
458
Solutions
1
Reaction score
50
Hello guys,

I was looking to a way to make 8.6 servers like 11+
Actual tibia have some changes really nice that should have on 8.6 servers and one of this is this:
When you buy some in stores (hi,trade), if you don't have money on backpack, it check and remove money to your bank balance...
Is anyone here know how to do it?

I mean on default trade system
Code:
<parameter key="shop_buyable" value="jagged sword,8602,300;steel axe,8601,300;daramanian mace,2439,300;crimson sword,7385,3000;barbarian axe,2429,3000;clerical mace,2423,3000" />

Using bank system like the NPC script system (balance,deposit,withdraw):
bank_npc.lua
Code:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

local Topic, count, transfer = {}, {}, {}

function onCreatureAppear(cid)            npcHandler:onCreatureAppear(cid)        end
function onCreatureDisappear(cid)        npcHandler:onCreatureDisappear(cid)        end
function onCreatureSay(cid, type, msg)        npcHandler:onCreatureSay(cid, type, msg)    end
function onThink()                npcHandler:onThink()                end


local function getCount(s)
    local b, e = s:find('%d+')
    return b and e and math.min(4294967295, tonumber(s:sub(b, e))) or -1
end

local function findPlayer(name)
    local resultId = db.storeQuery('SELECT name FROM players WHERE name=' .. db.escapeString(name) .. ' LIMIT 1'), nil
    if resultId == false then
        return
    end
    local r = result.getDataString(resultId, "name")
    result.free(resultId)
    return r
end

local function getTown(name)
    local resultId = db.storeQuery('SELECT town_id FROM players WHERE name=' .. db.escapeString(name) .. ' LIMIT 1'), nil
    if resultId == false then
        return
    end
    local r = result.getDataInt(resultId, "town_id")
    result.free(resultId)
    return r
end

local function vocation(name)
    local resultId = db.storeQuery('SELECT vocation FROM players WHERE name=' .. db.escapeString(name) .. ' LIMIT 1'), nil
    if resultId == false then
        return
    end
    local r = result.getDataInt(resultId, "vocation")
    result.free(resultId)
    return r
end

local function updatePlayerBalance(name, value)
    db.query('UPDATE players SET balance=' .. value .. ' WHERE name=' .. db.escapeString(name) .. ' LIMIT 1')
end

function greet(cid)
    Topic[cid], count[cid], transfer[cid] = nil, nil, nil
    return true
end

function creatureSayCallback(cid, type, msg)
    if not npcHandler:isFocused(cid) then
        return false
    elseif msgcontains(msg, 'balance') then
        npcHandler:say('Your account balance is ' .. getPlayerBalance(cid) .. ' gold.', cid)
        Topic[cid] = nil
    elseif msgcontains(msg, 'deposit') and msgcontains(msg, 'all') then
        if getPlayerMoney(cid) == 0 then
            npcHandler:say('You don\'t have any gold with you.', cid)
            Topic[cid] = nil
        else
            count[cid] = getPlayerMoney(cid)
            npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold?', cid)
            Topic[cid] = 2
        end
    elseif msgcontains(msg, 'deposit') then
        if getCount(msg) == 0 then
            npcHandler:say('You are joking, aren\'t you??', cid)
            Topic[cid] = nil
        elseif getCount(msg) ~= -1 then
            if getPlayerMoney(cid) >= getCount(msg) then
                count[cid] = getCount(msg)
                npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold?', cid)
                Topic[cid] = 2
            else
                npcHandler:say('You do not have enough gold.', cid)
                Topic[cid] = nil
            end
        elseif getPlayerMoney(cid) == 0 then
            npcHandler:say('You don\'t have any gold with you.', cid)
            Topic[cid] = nil
        else
            npcHandler:say('Please tell me how much gold it is you would like to deposit.', cid)
            Topic[cid] = 1
        end
    elseif Topic[cid] == 1 then
        if getCount(msg) == -1 then
            npcHandler:say('Please tell me how much gold it is you would like to deposit.', cid)
            Topic[cid] = 1
        elseif getPlayerMoney(cid) >= getCount(msg) then
            count[cid] = getCount(msg)
            npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold?', cid)
            Topic[cid] = 2
        else
            npcHandler:say('You do not have enough gold.', cid)
            Topic[cid] = nil
        end
    elseif msgcontains(msg, 'yes') and Topic[cid] == 2 then
        if doPlayerRemoveMoney(cid, count[cid]) then
            doPlayerSetBalance(cid, getPlayerBalance(cid) + count[cid])
            updatePlayerBalance(getCreatureByName(cid), getPlayerBalance(cid))
            npcHandler:say('Alright, we have added the amount of ' .. count[cid] .. ' gold to your balance. You can withdraw your money anytime you want to.', cid)
        else
            npcHandler:say('I am inconsolable, but it seems you have lost your gold. I hope you get it back.', cid)
        end
        Topic[cid] = nil
    elseif msgcontains(msg, 'no') and Topic[cid] == 2 then
        npcHandler:say('As you wish. Is there something else I can do for you?', cid)
        Topic[cid] = nil
    elseif msgcontains(msg, 'withdraw') then
        if getCount(msg) == 0 then
            npcHandler:say('Sure, you want nothing you get nothing!', cid)
            Topic[cid] = nil
        elseif getCount(msg) ~= -1 then
            if getPlayerBalance(cid) >= getCount(msg) then
                count[cid] = getCount(msg)
                npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your bank account?', cid)
                Topic[cid] = 4
            else
                npcHandler:say('There is not enough gold on your account.', cid)
                Topic[cid] = nil
            end
        elseif getPlayerBalance(cid) == 0 then
            npcHandler:say('You don\'t have any money on your bank account.', cid)
            Topic[cid] = nil
        else
            npcHandler:say('Please tell me how much gold you would like to withdraw.', cid)
            Topic[cid] = 3
        end
    elseif Topic[cid] == 3 then
        if getCount(msg) == -1 then
            npcHandler:say('Please tell me how much gold you would like to withdraw.', cid)
            Topic[cid] = 3
        elseif getPlayerBalance(cid) >= getCount(msg) then
            count[cid] = getCount(msg)
            npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your bank account?', cid)
            Topic[cid] = 4
        else
            npcHandler:say('There is not enough gold on your account.', cid)
            Topic[cid] = nil
        end
    elseif msgcontains(msg, 'yes') and Topic[cid] == 4 then
        if getPlayerBalance(cid) >= count[cid] then
            doPlayerAddMoney(cid, count[cid])
            doPlayerSetBalance(cid, getPlayerBalance(cid) - count[cid])
            updatePlayerBalance(getCreatureByName(cid), getPlayerBalance(cid))
            npcHandler:say('Here you are, ' .. count[cid] .. ' gold. Please let me know if there is something else I can do for you.', cid)
        else
            npcHandler:say('There is not enough gold on your account.', cid)
        end
        Topic[cid] = nil
    elseif msgcontains(msg, 'no') and Topic[cid] == 4 then
        npcHandler:say('The customer is king! Come back anytime you want to if you wish to withdraw your money.', cid)
        Topic[cid] = nil
    elseif msgcontains(msg, 'transfer') then
        if getCount(msg) == 0 then
            npcHandler:say('Please think about it. Okay?', cid)
            Topic[cid] = nil
        elseif getCount(msg) ~= -1 then
   
            count[cid] = getCount(msg)
            if getPlayerBalance(cid) >= count[cid] then
                npcHandler:say('Who would you like to transfer ' .. count[cid] .. ' gold to?', cid)
                Topic[cid] = 6
            else
                npcHandler:say('There is not enough gold on your account.', cid)
                Topic[cid] = nil
            end

        else
            npcHandler:say('Please tell me the amount of gold you would like to transfer.', cid)
            Topic[cid] = 5
        end
    elseif Topic[cid] == 5 then
        if getCount(msg) == -1 then
            npcHandler:say('Please tell me the amount of gold you would like to transfer.', cid)
            Topic[cid] = 5
        else
            count[cid] = getCount(msg)
            if getPlayerBalance(cid) >= count[cid] then
                npcHandler:say('Who would you like to transfer ' .. count[cid] .. ' gold to?', cid)
                Topic[cid] = 6
            else
                npcHandler:say('There is not enough gold on your account.', cid)
                Topic[cid] = nil
            end
        end
    elseif Topic[cid] == 6 then
        local v = getCreatureByName(msg)
        if getPlayerBalance(cid) >= count[cid] then
            local temp = (v and getCreatureName(v) or false)
            if temp then
                if getPlayerTown(v) == 7 then
                    if getPlayerTown(cid) ~= getPlayerTown(v) then
                        npcHandler:say('You can not transfer money to players from Rookgaardia if you are not from Rookgaardia.', cid)
                        Topic[cid] = nil
                        return true
                    end
                elseif getPlayerTown(v) == 9 then
                    if getPlayerTown(cid) ~= getPlayerTown(v) then
                        npcHandler:say('You can not transfer money to players from Dawn Hills if you are not from Dawn Hills.', cid)
                        Topic[cid] = nil
                        return true
                    end
                end


                transfer[cid] = msg
                npcHandler:say('Would you really like to transfer ' .. count[cid] .. ' gold to ' .. temp .. '?', cid)
                Topic[cid] = 7
            elseif getPlayerGUIDByName(msg:lower()) ~= 0 then
                if getTown(msg:lower()) == 7 then
                    if getPlayerTown(cid) ~= 7 then
                        npcHandler:say('You can not transfer money to players from Rookgaardia if you are not from Rookgaardia.', cid)
                        Topic[cid] = nil
                        return true
                    end
                elseif getTown(msg:lower()) == 9 then
                    if getPlayerTown(cid) ~= 9 then
                        npcHandler:say('You can not transfer money to players from Dawn Hills if you are not from Dawn Hills.', cid)
                        Topic[cid] = nil
                        return true
                    end
                end


                transfer[cid] = msg
                npcHandler:say('Would you really like to transfer ' .. count[cid] .. ' gold to ' .. findPlayer(msg) .. '?', cid)
                Topic[cid] = 7            
            else
                npcHandler:say('This player does not exist on this world!', cid)
                Topic[cid] = nil
            end
        else
            npcHandler:say('There is not enough gold on your account.', cid)
            Topic[cid] = nil
        end
    elseif Topic[cid] == 7 and msgcontains(msg, 'yes') then
        if getPlayerBalance(cid) >= count[cid] then
            local v = getCreatureByName(transfer[cid])
            if v then
                doPlayerSetBalance(cid, getPlayerBalance(cid) - count[cid])
                updatePlayerBalance(getCreatureName(cid), getPlayerBalance(cid))
                doPlayerSetBalance(v, getPlayerBalance(v) + count[cid])
                updatePlayerBalance(getCreatureName(v), getPlayerBalance(v))
                npcHandler:say('Very well. You have transferred ' .. count[cid] .. ' gold to ' .. getCreatureName(v) .. '.', cid)
            elseif findPlayer(transfer[cid]):lower() == transfer[cid]:lower() then
                doPlayerSetBalance(cid, getPlayerBalance(cid) - count[cid])
                updatePlayerBalance(getCreatureName(cid), getPlayerBalance(cid))
                db.query('UPDATE players SET balance=balance+' .. count[cid] .. ' WHERE name=' .. db.escapeString(transfer[cid]) .. ' LIMIT 1')
                npcHandler:say('Very well. You have transferred ' .. count[cid] .. ' gold to ' .. findPlayer(transfer[cid]) .. '.', cid)
            else
                npcHandler:say('This player does not exist.', cid)
            end
        else
            npcHandler:say('There is not enough gold on your account.', cid)
        end
        Topic[cid] = nil
    elseif Topic[cid] == 7 and msgcontains(msg, 'no') then
        npcHandler:say('Alright, is there something else I can do for you?', cid)
        Topic[cid] = nil
    elseif msgcontains(msg, 'change gold') then
        npcHandler:say('How many platinum coins would you like to get?', cid)
        Topic[cid] = 8
    elseif Topic[cid] == 8 then
        if getCount(msg) < 1 then
            npcHandler:say('Hmm, can I help you with something else?', cid)
            Topic[cid] = nil
        else
            count[cid] = math.min(500, getCount(msg))
            npcHandler:say('So you would like me to change ' .. count[cid] * 100 .. ' of your gold coins into ' .. count[cid] .. ' platinum coins?', cid)
            Topic[cid] = 9
        end
    elseif Topic[cid] == 9 then
        if msgcontains(msg, 'yes') then
            if doPlayerRemoveItem(cid, 2148, count[cid] * 100) then
                npcHandler:say('Here you are.', cid)
                doPlayerAddItem(cid, 2152, count[cid])
            else
                npcHandler:say('Sorry, you do not have enough gold coins.', cid)
            end
        else
            npcHandler:say('Well, can I help you with something else?', cid)
        end
        Topic[cid] = nil
    elseif msgcontains(msg, 'change platinum') then
        npcHandler:say('Would you like to change your platinum coins into gold or crystal?', cid)
        Topic[cid] = 10
    elseif Topic[cid] == 10 then
        if msgcontains(msg, 'gold') then
            npcHandler:say('How many platinum coins would you like to change into gold?', cid)
            Topic[cid] = 11
        elseif msgcontains(msg, 'crystal') then
            npcHandler:say('How many crystal coins would you like to get?', cid)
            Topic[cid] = 13
        else
            npcHandler:say('Well, can I help you with something else?', cid)
            Topic[cid] = nil
        end
    elseif Topic[cid] == 11 then
        if getCount(msg) < 1 then
            npcHandler:say('Hmm, can I help you with something else?', cid)
            Topic[cid] = nil
        else
            count[cid] = math.min(500, getCount(msg))
            npcHandler:say('So you would like me to change ' .. count[cid] .. ' of your platinum coins into ' .. count[cid] * 100 .. ' gold coins for you?', cid)
            Topic[cid] = 12
        end
    elseif Topic[cid] == 12 then
        if msgcontains(msg, 'yes') then
            if doPlayerRemoveItem(cid, 2152, count[cid]) then
                npcHandler:say('Here you are.', cid)
                doPlayerAddItem(cid, 2148, count[cid] * 100)
            else
                npcHandler:say('Sorry, you do not have enough platinum coins.', cid)
            end
        else
            npcHandler:say('Well, can I help you with something else?', cid)
        end
        Topic[cid] = nil
    elseif Topic[cid] == 13 then
        if getCount(msg) < 1 then
            npcHandler:say('Hmm, can I help you with something else?', cid)
            Topic[cid] = nil
        else
            count[cid] = math.min(500, getCount(msg))
            npcHandler:say('So you would like me to change ' .. count[cid] * 100 .. ' of your platinum coins into ' .. count[cid] .. ' crystal coins for you?', cid)
            Topic[cid] = 14
        end
    elseif Topic[cid] == 14 then
        if msgcontains(msg, 'yes') then
            if doPlayerRemoveItem(cid, 2152, count[cid] * 100) then
                npcHandler:say('Here you are.', cid)
                doPlayerAddItem(cid, 2160, count[cid])
            else
                npcHandler:say('Sorry, you do not have enough platinum coins.', cid)
            end
        else
            npcHandler:say('Well, can I help you with something else?', cid)
        end
        Topic[cid] = nil
    elseif msgcontains(msg, 'change crystal') then
        npcHandler:say('How many crystal coins would you like to change into platinum?', cid)
        Topic[cid] = 15
    elseif Topic[cid] == 15 then
        if getCount(msg) == -1 or getCount(msg) == 0 then
            npcHandler:say('Hmm, can I help you with something else?', cid)
            Topic[cid] = nil
        else
            count[cid] = math.min(500, getCount(msg))
            npcHandler:say('So you would like me to change ' .. count[cid] .. ' of your crystal coins into ' .. count[cid] * 100 .. ' platinum coins for you?', cid)
            Topic[cid] = 16
        end
    elseif Topic[cid] == 16 then
        if msgcontains(msg, 'yes') then
            if doPlayerRemoveItem(cid, 2160, count[cid]) then
                npcHandler:say('Here you are.', cid)
                doPlayerAddItem(cid, 2152, count[cid] * 100)
            else
                npcHandler:say('Sorry, you do not have enough crystal coins.', cid)
            end
        else
            npcHandler:say('Well, can I help you with something else?', cid)
        end
        Topic[cid] = nil
    elseif msgcontains(msg, 'change') then
        npcHandler:say('There are three different coin types in Tibia: 100 gold coins equal 1 platinum coin, 100 platinum coins equal 1 crystal coin. So if you\'d like to change 100 gold into 1 platinum, simply say \'{change gold}\' and then \'1 platinum\'.', cid)
        Topic[cid] = nil
    elseif msgcontains(msg, 'bank') then
        npcHandler:say('We can change money for you. You can also access your bank account.', cid)
        Topic[cid] = nil
    end
    return true
end

npcHandler:setCallback(CALLBACK_GREET, greet)
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())

It do need sources change?
Fir3element/3777

Or can be done only on LUA?
data\npc\lib\npcsystem\modules.lua
Fir3element/3777
On removemoney lines...

Idk how to do by myself and i don't found nothing here on forum, only ppl asking for this...
Anybody can help?
 
Solution
Modifying getMoney/removeMoney from game.cpp should be enough.

C++:
uint32_t Game::getMoney(const Cylinder* cylinder)
{
[...]

    if(const Player* p = dynamic_cast<const Player*>(cylinder))
    {
        moneyCount += p->balance;
    }

    return moneyCount;
}

C++:
bool Game::removeMoney(Cylinder* cylinder, int32_t money, uint32_t flags /*= 0*/)
{
[...]

    Player* p = dynamic_cast<Player*>(cylinder);
    if(p)
    {
        moneyCount += p->balance;
    }
 
    // Not enough money
    if(moneyCount < money)
    {
        return false;
    }

[...]

    moneyMap.clear();
    if(money > 0 && p && (int32_t)p->balance >= money)
    {
        p->balance -= money;
        std::stringstream ss;
        ss << "Paid...
Modifying getMoney/removeMoney from game.cpp should be enough.

C++:
uint32_t Game::getMoney(const Cylinder* cylinder)
{
[...]

    if(const Player* p = dynamic_cast<const Player*>(cylinder))
    {
        moneyCount += p->balance;
    }

    return moneyCount;
}

C++:
bool Game::removeMoney(Cylinder* cylinder, int32_t money, uint32_t flags /*= 0*/)
{
[...]

    Player* p = dynamic_cast<Player*>(cylinder);
    if(p)
    {
        moneyCount += p->balance;
    }
 
    // Not enough money
    if(moneyCount < money)
    {
        return false;
    }

[...]

    moneyMap.clear();
    if(money > 0 && p && (int32_t)p->balance >= money)
    {
        p->balance -= money;
        std::stringstream ss;
        ss << "Paid " << money << " gold from bank account. Your account balance is now " << p->balance << " gold.";
        p->sendTextMessage(MSG_INFO_DESCR, ss.str());
        return true;
    }
 
    return money == 0;
}

But beware, since balance is u64, players with more than 4294kk in the bank will be actually poor as duck :D
 
Last edited:
Solution
But beware, since balance is u64, players with more than 4294kk in the bank will be actually poor as duck :D

My server have a high loot, so i'm thinking about make a limit on deposit, on LUA NPC...
Or should be more better change money to 64 too? I have no knowledge in C++
 
Get money is already 64 guys (i think so)...

what do i doing wrong?
my game.cpp
hastebin

errors
Code:
game.cpp: In member function ‘uint64_t Game::getMoney(const Cylinder*)’:
game.cpp:1949:50: error: cannot dynamic_cast ‘cylinder’ (of type ‘const class Cylinder*’) to type ‘class Player*’ (conversion casts away constness)
     if(Player* p = dynamic_cast<Player*>(cylinder))
                                                  ^
game.cpp:1949:5: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
     if(Player* p = dynamic_cast<Player*>(cylinder))
     ^~
game.cpp:1952:2: note: ...this statement, but the latter is misleadingly indented as if it is guarded by the ‘if’
  return moneyCount;
  ^~~~~~
game.cpp: In member function ‘bool Game::removeMoney(Cylinder*, int64_t, uint32_t)’:
game.cpp:2006:5: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
     if(p)
     ^~
game.cpp:2010:2: note: ...this statement, but the latter is misleadingly indented as if it is guarded by the ‘if’
  if(moneyCount < money)
  ^~
game.cpp:2034:37: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     if(money > 0 && p && p->balance >= money)
                          ~~~~~~~~~~~^~~~~~~~
Makefile:33: recipe for target 'game.o' failed
make: *** [game.o] Error 1
make: *** Waiting for unfinished jobs....
 
what do i doing wrong?
my game.cpp
hastebin

I've updated my answer, now it should work.
If you really think that a player can have more than 429497cc (that is 4294967295gp, or 215bps filled with stacked cc), you should change getMoney to uint64_t, and I think that there will be more problems with that.
 
I've updated my answer, now it should work.
If you really think that a player can have more than 429497cc (that is 4294967295gp, or 215bps filled with stacked cc), you should change getMoney to uint64_t, and I think that there will be more problems with that.

That was not my point, i dont care about this 4294967295gp limit, players will never have it on my server...
I just was answer him that 3777, 0.4 (atlast mine), is already 64

Now it's working, thank you so much to being help us...

But i need to ask 2 more things to you:
1- When i compile this game.cpp: hastebin
i got a lot warnings:
Code:
CC       = g++
game.cpp: In member function ‘uint64_t Game::getMoney(const Cylinder*)’:
game.cpp:1949:5: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
     if(const Player* p = dynamic_cast<const Player*>(cylinder))
     ^~
game.cpp:1952:2: note: ...this statement, but the latter is misleadingly indented as if it is guarded by the ‘if’
  return moneyCount;
  ^~~~~~
game.cpp: In member function ‘bool Game::removeMoney(Cylinder*, int64_t, uint32_t)’:
game.cpp:2006:5: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
     if(p)
     ^~
game.cpp:2010:2: note: ...this statement, but the latter is misleadingly indented as if it is guarded by the ‘if’
  if(moneyCount < money)
  ^~
game.cpp:2034:37: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     if(money > 0 && p && p->balance >= money)
                          ~~~~~~~~~~~^~~~~~~~
game.cpp: In constructor ‘Game::Game()’:
game.cpp:80:24: warning: iteration 2 invokes undefined behavior [-Waggressive-loop-optimizations]
   globalSaveMessage[i] = false;
   ~~~~~~~~~~~~~~~~~~~~~^~~~~~~
game.cpp:79:23: note: within this loop
  for(int32_t i = 0; i < 3; i++)
                     ~~^~~
In file included from game.cpp:18:0:
game.h: In member function ‘void Game::globalSave()’:
game.h:616:78: warning: iteration 2 invokes undefined behavior [-Waggressive-loop-optimizations]
   void setGlobalSaveMessage(int16_t key, bool value) {globalSaveMessage[key] = value;}
                                                       ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
game.cpp:6356:23: note: within this loop
  for(int16_t i = 0; i < 3; i++)
                     ~~^~~
There is a problem there?

2- How to add a line to show bank balance, after buy something with bank balance?
I've tried this line, but got this errors
Code:
    moneyMap.clear();
    // check bankBalance onBuy 3
    if(money > 0 && p && p->balance >= money)
    {
        p->balance -= money;
        p->sendTextMessage(MSG_INFO_DESCR, "Your bank balance now is: " + p->balance + ".");
        return true;
    }

Code:
game.cpp:2037:86: error: invalid operands of types ‘const char*’ and ‘const char [2]’ to binary ‘operator+’
         p->sendTextMessage(MSG_INFO_DESCR, "Your bank balance now is: " + p->balance + ".");
                                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
Makefile:33: recipe for target 'game.o' failed
make: *** [game.o] Error 1
 
PERFECT thank you so much!
Now everybody who have 8.6 can uses bank money like tibia 11...

Or almost i got one last problem...

I had 2000 gps on bank, withdraw 1000 for my backpack, let 1000 on bank
Said deposit all, to deposit 1000, and got 2k on bank again

But got this message
Code:
12:43 Paid 1000 gold from bank account. Your account balance is now 0 gold.

Says:
Code:
12:43 Kratos [22]: balance
12:43 Bank: Your account balance is 2000 gold.
12:43 Kratos [22]: withdraw 1000
12:43 Bank: Are you sure you wish to withdraw 1000 gold from your bank account?
12:43 Kratos [22]: yes
12:43 Bank: Here you are, 1000 gold. Please let me know if there is something else I can do for you.
12:43 Kratos [22]: deposit all
12:43 Bank: Would you really like to deposit 2000 gold?
12:43 Kratos [22]: yes
12:43 Bank: Alright, we have added the amount of 2000 gold to your balance. You can withdraw your money anytime you want to.

bank_npc.lua
firstpost

I have a idea, but idk how to do, and i even dont know if this the best way to fix it

The problem should be on getPlayerMoney(cid)...

I was thinking in someway do on sources to by defaul getPlayerMoney(cid) have a bank parament bank = false
Everywhere i put getPlayerMoney(cid), send the message:
12:43 Paid 1000 gold from bank account. Your account balance is now 0 gold.

But on bank i put getPlayerMoney(cid, true) to check only backpack money

What do u think? Thats the way? Is it possible? Sorry if its tottally wrong, i just studying...
 
Last edited:
You can edit those functions in luascript.cpp

C++:
int32_t LuaScriptInterface::luaDoPlayerRemoveMoney(lua_State* L)
{
    //doPlayerRemoveMoney(cid,money[, includeBank = true])
 
    bool includeBank = true;
    if(lua_gettop(L) > 2)
        includeBank = popBoolean(L);
 
    uint64_t money = popNumber(L);

    ScriptEnviroment* env = getEnv();
    if(Player* player = env->getPlayerByUID(popNumber(L)))
        lua_pushboolean(L, g_game.removeMoney(player, money, 0, includeBank));
    else
    {
        errorEx(getError(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushboolean(L, false);
    }
    return 1;
}

C++:
int32_t LuaScriptInterface::luaGetPlayerMoney(lua_State* L)
{
    //getPlayerMoney(cid[, includeBank = true])
 
    bool includeBank = true;
    if(lua_gettop(L) > 1)
        includeBank = popBoolean(L);
 
    ScriptEnviroment* env = getEnv();
    if(Player* player = env->getPlayerByUID(popNumber(L)))
        lua_pushnumber(L, g_game.getMoney(player, includeBank));
    else
    {
        errorEx(getError(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushboolean(L, false);
    }
    return 1;
}

then in game.h edit headers
C++:
uint32_t getMoney(const Cylinder* cylinder, bool includeBank = true);
bool removeMoney(Cylinder* cylinder, int32_t money, uint32_t flags = 0, bool includeBank = true);

and in game.cpp
C++:
uint32_t Game::getMoney(const Cylinder* cylinder, bool includeBank /*= true*/)
{
[...]

    if(includeBank)
    {
        if(const Player* p = dynamic_cast<const Player*>(cylinder))
        {
            moneyCount += p->balance;
        }
    }

    return moneyCount;
}

C++:
bool Game::removeMoney(Cylinder* cylinder, int32_t money, uint32_t flags /*= 0*/, bool includeBank /*= true*/)
{
[...]

    Player* p = includeBank ? dynamic_cast<Player*>(cylinder) : NULL;
    if(p)
    {
        moneyCount += p->balance;
    }

    // Not enough money
    if(moneyCount < money)
    {
        return false;
    }

[...]

    moneyMap.clear();
    if(money > 0 && p && (int32_t)p->balance >= money)
    {
        p->balance -= money;
        std::stringstream ss;
        ss << "Paid " << money << " gold from bank account. Your account balance is now " << p->balance << " gold.";
        p->sendTextMessage(MSG_INFO_DESCR, ss.str());
        return true;
    }

    return money == 0;
}

then in your bank script (and anywhere else that you don't want to use the bank), use those two functions like that:
doPlayerRemoveMoney(cid, money, false)
getPlayerMoney(cid, false)
 
Last edited:
You can edit those functions in luascript.cpp

C++:
int32_t LuaScriptInterface::luaDoPlayerRemoveMoney(lua_State* L)
{
    //doPlayerRemoveMoney(cid,money[, includeBank = true])
 
    bool includeBank = true;
    if(lua_gettop(L) > 2)
        includeBank = popBoolean(L);
 
    uint64_t money = popNumber(L);

    ScriptEnviroment* env = getEnv();
    if(Player* player = env->getPlayerByUID(popNumber(L)))
        lua_pushboolean(L, g_game.removeMoney(player, money, 0, includeBank));
    else
    {
        errorEx(getError(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushboolean(L, false);
    }
    return 1;
}

C++:
int32_t LuaScriptInterface::luaGetPlayerMoney(lua_State* L)
{
    //getPlayerMoney(cid[, includeBank = true])
 
    bool includeBank = true;
    if(lua_gettop(L) > 1)
        includeBank = popBoolean(L);
 
    ScriptEnviroment* env = getEnv();
    if(Player* player = env->getPlayerByUID(popNumber(L)))
        lua_pushnumber(L, g_game.getMoney(player, includeBank));
    else
    {
        errorEx(getError(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushboolean(L, false);
    }
    return 1;
}

then in game.h edit headers
C++:
uint32_t getMoney(const Cylinder* cylinder, bool includeBank = true);
bool removeMoney(Cylinder* cylinder, int32_t money, uint32_t flags = 0, bool includeBank = true);

and in game.cpp
C++:
uint32_t Game::getMoney(const Cylinder* cylinder, bool includeBank /*= true*/)
{
[...]

    if(includeBank && const Player* p = dynamic_cast<const Player*>(cylinder))
    {
        moneyCount += p->balance;
    }

    return moneyCount;
}

C++:
bool Game::removeMoney(Cylinder* cylinder, int32_t money, uint32_t flags /*= 0*/, bool includeBank /*= true*/)
{
[...]

    Player* p = includeBank ? dynamic_cast<Player*>(cylinder) : NULL;
    if(p)
    {
        moneyCount += p->balance;
    }

    // Not enough money
    if(moneyCount < money)
    {
        return false;
    }

[...]

    moneyMap.clear();
    if(money > 0 && p && (int32_t)p->balance >= money)
    {
        p->balance -= money;
        std::stringstream ss;
        ss << "Paid " << money << " gold from bank account. Your account balance is now " << p->balance << " gold.";
        p->sendTextMessage(MSG_INFO_DESCR, ss.str());
        return true;
    }

    return money == 0;
}

then in your bank script (and anywhere else that you don't want to use the bank), use those two functions like that:
doPlayerRemoveMoney(cid, money, false)
getPlayerMoney(cid, false)

I did added what u post (i just don't changed what was 64 to 32 scaring to do some shit), but got an error on game.cpp
Code:
game.cpp: In member function ‘uint64_t Game::getMoney(const Cylinder*, bool)’:
game.cpp:1949:23: error: expected primary-expression before ‘const’
     if(includeBank && const Player* p = dynamic_cast<const Player*>(cylinder))
                       ^~~~~
game.cpp:1949:23: error: expected ‘)’ before ‘const’
game.cpp:1951:23: error: ‘p’ was not declared in this scope
         moneyCount += p->balance;
                       ^
Makefile:33: recipe for target 'game.o' failed
make: *** [game.o] Error 1


So i tried to change on game.cpp what i think should fix
Code:
    // check bankBalance onBuy 1
    const Player* p = dynamic_cast<const Player*>(cylinder);
    if(includeBank && p)
    {
        moneyCount += p->balance;
    }

I think that not work...
Code:
CC -o tfs
house.o: In function `Houses::payRent(Player*, House*, unsigned int, long)':
house.cpp:(.text+0x1305): undefined reference to `Game::removeMoney(Cylinder*, long, unsigned int)'
protocolgame.o: In function `ProtocolGame::sendGoods(std::__cxx11::list<ShopInfo, std::allocator<ShopInfo> > const&)':
protocolgame.cpp:(.text+0xedb3): undefined reference to `Game::getMoney(Cylinder const*)'
npc.o: In function `Npc::getResponse(std::__cxx11::list<NpcResponse*, std::allocator<NpcResponse*> > const&, Player const*, NpcState*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool)':
npc.cpp:(.text+0x2e48): undefined reference to `Game::getMoney(Cylinder const*)'
npc.o: In function `Npc::executeResponse(Player*, NpcState*, NpcResponse const*)':
npc.cpp:(.text+0x7a53): undefined reference to `Game::getMoney(Cylinder const*)'
npc.cpp:(.text+0x7d30): undefined reference to `Game::removeMoney(Cylinder*, long, unsigned int)'
talkaction.o: In function `TalkAction::houseBuy(Creature*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
talkaction.cpp:(.text+0x10d2): undefined reference to `Game::getMoney(Cylinder const*)'
talkaction.cpp:(.text+0x10ef): undefined reference to `Game::removeMoney(Cylinder*, long, unsigned int)'
collect2: error: ld returned 1 exit status
Makefile:37: recipe for target 'tfs' failed
make: *** [tfs] Error 1
 
The code looks fine, try to clean and rebuild.

Code:
game.cpp: In member function ‘uint64_t Game::getMoney(const Cylinder*, bool)’:
game.cpp:1949:23: error: expected primary-expression before ‘const’
     if(includeBank && const Player* p = dynamic_cast<const Player*>(cylinder))
                       ^~~~~
game.cpp:1949:23: error: expected ‘)’ before ‘const’
game.cpp:1951:23: error: ‘p’ was not declared in this scope
         moneyCount += p->balance;
                       ^

1949: if(includeBank && const Player* p = dynamic_cast<const Player*>(cylinder))
Code:
    // check bankBalance onBuy 1
    if(includeBank && const Player* p = dynamic_cast<const Player*>(cylinder))
    {
        moneyCount += p->balance;
    }

   return moneyCount;
 
Back
Top