potinho
Advanced OT User
Hello guys,
Im trying to merge the solution from this post (TFS 0.X - Buy items with money backpack or bank balance 0.4 (https://otland.net/threads/buy-items-with-money-backpack-or-bank-balance-0-4.260563/post-2520072)) into my sources, but im failing. None errors when compiling, but in game it not work, i cant buy anything without money in backpack, even with a lot of money in bank balance. Can u guys point me what im doing wrong and help me to fix?
Here follow my code:
Here's my bank system who work by talkaction:
Im trying to merge the solution from this post (TFS 0.X - Buy items with money backpack or bank balance 0.4 (https://otland.net/threads/buy-items-with-money-backpack-or-bank-balance-0-4.260563/post-2520072)) into my sources, but im failing. None errors when compiling, but in game it not work, i cant buy anything without money in backpack, even with a lot of money in bank balance. Can u guys point me what im doing wrong and help me to fix?
Here follow my code:
C++:
uint64_t Game::getMoney(const Cylinder* cylinder)
{
if (!cylinder)
return 0;
std::list<Container*> listContainer;
Container* tmpContainer = NULL;
Thing* thing = NULL;
Item* item = NULL;
uint64_t moneyCount = 0;
for (int32_t i = cylinder->__getFirstIndex(); i < cylinder->__getLastIndex(); ++i)
{
if (!(thing = cylinder->__getThing(i)) || !(item = thing->getItem()))
continue;
if ((tmpContainer = item->getContainer()))
listContainer.push_back(tmpContainer);
else if (item->getWorth())
moneyCount += item->getWorth();
}
Container* container = NULL;
while (listContainer.size() > 0)
{
container = listContainer.front();
listContainer.pop_front();
for (ItemList::const_iterator it = container->getItems(); it != container->getEnd(); ++it)
{
item = *it;
if ((tmpContainer = item->getContainer()))
listContainer.push_back(tmpContainer);
else if (item->getWorth())
moneyCount += item->getWorth();
}
}
if (const Player* p = dynamic_cast<const Player*>(cylinder))
{
moneyCount += p->balance;
}
return moneyCount;
}
bool Game::removeMoney(Cylinder* cylinder, int64_t money, uint32_t flags /*= 0*/)
{
if (!cylinder)
return false;
if (money <= 0)
return true;
Player* p = dynamic_cast<Player*>(cylinder);
if (p)
{
money += p->balance;
// Not enough money
if (money < 0)
return false;
}
typedef std::multimap<int32_t, Item*, std::less<int32_t> > MoneyMultiMap;
MoneyMultiMap moneyMap;
std::list<Container*> listContainer;
Container* tmpContainer = NULL;
Thing* thing = NULL;
Item* item = NULL;
int64_t moneyCount = 0;
for (int32_t i = cylinder->__getFirstIndex(); i < cylinder->__getLastIndex(); ++i)
{
if (!(thing = cylinder->__getThing(i)) || !(item = thing->getItem()))
continue;
if ((tmpContainer = item->getContainer()))
listContainer.push_back(tmpContainer);
else if (item->getWorth())
{
moneyCount += item->getWorth();
moneyMap.insert(std::make_pair(item->getWorth(), item));
}
}
while (listContainer.size() > 0)
{
Container* container = listContainer.front();
listContainer.pop_front();
for (int32_t i = 0; i < (int32_t)container->size(); ++i)
{
Item* item = container->getItem(i);
if ((tmpContainer = item->getContainer()))
listContainer.push_back(tmpContainer);
else if (item->getWorth())
{
moneyCount += item->getWorth();
moneyMap.insert(std::make_pair(item->getWorth(), item));
}
}
}
// Not enough money
if (moneyCount < money)
return false;
for (MoneyMultiMap::iterator mit = moneyMap.begin(); mit != moneyMap.end() && money > 0; ++mit)
{
if (!(item = mit->second))
continue;
internalRemoveItem(NULL, item);
if (mit->first > money)
{
// Remove a monetary value from an item
addMoney(cylinder, (int64_t)(item->getWorth() - money), flags);
money = 0;
}
else
money -= mit->first;
mit->second = NULL;
}
moneyMap.clear();
if (p)
{
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;
}
Here's my bank system who work by talkaction:
Lua:
<config name="command-bank-config"><![CDATA[
transferDisabledVocations = {0} -- disable non vocation characters
]]></config>
<talkaction words="!bank;/bank" event="script"><![CDATA[
domodlib('command-bank-config')
local config = {
transferDisabledVocations = transferDisabledVocations
}
local function validAmount(amount)
return (isNumber(amount) and amount > 0 and amount < 4294967296)
end
local function getAmount(amount, cid, f)
return (amount == 'all' and f(cid) or tonumber(amount))
end
local function getPlayerVocationByName(name)
local result = db.getResult("SELECT `vocation` FROM `players` WHERE `name` = " .. db.escapeString(name))
if(result:getID() == -1) then
return false
end
local value = result:getDataString("vocation")
result:free()
return value
end
function onSay(cid, words, param, channel)
if(param == '') then
doPlayerPopupFYI(cid,
"Bank management manual.\n\n" ..
"!bank or /bank balance - show your account balance\n" ..
"!bank or /bank deposit 100 - deposit 100 gold\n" ..
"!bank or /bank withdraw 50 - withdraw 50 gold\n" ..
"!bank or /bank transfer 30 God - transfer 30 gold to player God\n\n" ..
"Tip: you can also use 'all' as amount.\n" ..
"!bank or /bank deposit all - deposit all gold you have\n" ..
"!bank or /bank withdraw all - withdraw all gold from your bank account"
)
return true
end
local t = string.explode(param, " ", 2)
local command = t[1]:lower()
if(command == 'balance') then
doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE, "Your account balance is " .. getPlayerBalance(cid) .. " gold.")
elseif(command == 'deposit') then
if(not t[2]) then
doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE,"Amount is required.")
return true
end
local amount = getAmount(t[2], cid, getPlayerMoney)
if(validAmount(amount) and getPlayerMoney(cid) >= amount and doPlayerDepositMoney(cid, amount)) then
doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE,amount .. " gold has been deposited.")
else
doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE,"Not enough money to deposit.")
end
elseif(command == 'withdraw') then
if(not t[2]) then
doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE,"Amount is required.")
return true
end
local amount = getAmount(t[2], cid, getPlayerBalance)
if(validAmount(amount) and getPlayerBalance(cid) >= amount and doPlayerWithdrawMoney(cid, amount)) then
doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE,amount .. " gold has been withdrawn.")
else
doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE,"Not enough money to withdraw.")
end
elseif(command == 'transfer') then
if(not t[2]) then
doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE,"Amount is required.")
return true
end
if(not t[3]) then
doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE,"Player name to transfer is required.")
return true
end
local amount, target = tonumber(t[2]), t[3]
if(getPlayerGUID(cid) == getPlayerGUIDByName(target)) then
doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE,"You cannot transfer money to yourself.")
elseif(isInArray(config.transferDisabledVocations, getPlayerVocation(cid))) then
doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE,"Your vocation cannot transfer money.")
elseif(not validAmount(amount) or getPlayerBalance(cid) < amount) then
doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE,"Not enough money to transfer.")
else
local targetVocation = getPlayerVocationByName(target)
if(not playerExists(target) or not targetVocation or isInArray(config.transferDisabledVocations, targetVocation) or not doPlayerTransferMoneyTo(cid, target, amount)) then
doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE,"This player does not exist on this world or have no vocation.")
else
doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE,"You have transferred " .. amount .. " gold to \"" .. target .."\".")
end
end
else
doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE,"Invalid command usage. Use '!bank' to view manual.")
end
return true
end
]]></talkaction>