The RSG Framework features a comprehensive money system designed for RedM that includes multiple bank types, physical money items, and bloodmoney for illegal activities. Unlike traditional frameworks with a single bank account, RSG provides location-specific banks throughout the map.Version: 2.3.6+
The legacy bank money type is DEPRECATED and set to 0 by default. Use location-specific banks instead!
moneytype (string) - Type of money (โcashโ, โvalbankโ, etc.)
amount (number) - Amount to add
reason (string) - Reason for logging (optional)
Returns: boolean - True if successful, false if failedExample:
Copy
-- SERVER SIDERegisterNetEvent('job:server:payPlayer', function(amount) local src = source local Player = RSGCore.Functions.GetPlayer(src) if not Player then return end -- Add cash if Player.Functions.AddMoney('cash', amount, 'job-payment') then TriggerClientEvent('ox_lib:notify', src, { title = 'Payment Received', description = 'You received $'.. amount, type = 'success', duration = 5000 }) endend)-- Add to Valentine BankPlayer.Functions.AddMoney('valbank', 500, 'bank-deposit')-- Add bloodmoney from robberyPlayer.Functions.AddMoney('bloodmoney', 250, 'store-robbery')
Money over $100,000 triggers special high-value logging for admin monitoring
Returns: boolean - True if successful, false if insufficient fundsExample:
Copy
-- SERVER SIDERegisterNetEvent('shop:server:purchase', function(itemPrice) local src = source local Player = RSGCore.Functions.GetPlayer(src) if not Player then return end -- Check if player has enough cash if Player.Functions.GetMoney('cash') < itemPrice then TriggerClientEvent('ox_lib:notify', src, { title = 'Not Enough Money', description = 'You need $'.. itemPrice, type = 'error', duration = 5000 }) return end -- Remove money if Player.Functions.RemoveMoney('cash', itemPrice, 'shop-purchase') then -- Give item exports['rsg-inventory']:AddItem(src, 'bread', 1, nil, nil, 'purchased') TriggerClientEvent('ox_lib:notify', src, { title = 'Purchase Successful', type = 'success', duration = 5000 }) endend)
Money types in DontAllowMinus config cannot go below 0. Transaction will fail instead.
Returns: boolean - True if successful, false if failedExample:
Copy
-- SERVER SIDE-- Admin command to set player moneyRegisterCommand('setmoney', function(source, args) local src = source if not RSGCore.Functions.HasPermission(src, 'admin') then return end local targetId = tonumber(args[1]) local moneyType = args[2] or 'cash' local amount = tonumber(args[3]) or 0 local Target = RSGCore.Functions.GetPlayer(targetId) if not Target then return end if Target.Functions.SetMoney(moneyType, amount, 'admin-set') then TriggerClientEvent('ox_lib:notify', src, { description = 'Set '.. moneyType ..' to $'.. amount, type = 'success' }) endend, false)
SetMoney completely overwrites the current amount. Use AddMoney/RemoveMoney for relative changes.
Returns: number|boolean - Amount or false if invalid typeExample:
Copy
-- SERVER SIDElocal Player = RSGCore.Functions.GetPlayer(source)-- Check cashlocal cashAmount = Player.Functions.GetMoney('cash')print('Player has $'.. cashAmount ..' cash')-- Check Valentine Bank balancelocal valbankAmount = Player.Functions.GetMoney('valbank')print('Valentine Bank: $'.. valbankAmount)-- Check total money across all accountslocal totalMoney = 0for moneyType, _ in pairs(Player.PlayerData.money) do if moneyType ~= 'bank' then -- Skip deprecated bank totalMoney = totalMoney + Player.Functions.GetMoney(moneyType) endendprint('Total wealth: $'.. totalMoney)
-- SERVER SIDE-- Deposit cash into Valentine BankRegisterNetEvent('bank:server:deposit', function(bankType, amount) local src = source local Player = RSGCore.Functions.GetPlayer(src) if not Player then return end -- Validate bank type local validBanks = { 'valbank', 'rhobank', 'blkbank', 'armbank' } if not lib.table.contains(validBanks, bankType) then return end -- Check player has enough cash if Player.Functions.GetMoney('cash') < amount then TriggerClientEvent('ox_lib:notify', src, { description = 'Not enough cash', type = 'error' }) return end -- Process deposit if Player.Functions.RemoveMoney('cash', amount, 'bank-deposit') then if Player.Functions.AddMoney(bankType, amount, 'bank-deposit') then TriggerClientEvent('ox_lib:notify', src, { description = 'Deposited $'.. amount, type = 'success' }) end endend)-- Withdraw from Rhodes BankRegisterNetEvent('bank:server:withdraw', function(bankType, amount) local src = source local Player = RSGCore.Functions.GetPlayer(src) if not Player then return end -- Check bank balance if Player.Functions.GetMoney(bankType) < amount then TriggerClientEvent('ox_lib:notify', src, { description = 'Insufficient funds', type = 'error' }) return end -- Process withdrawal if Player.Functions.RemoveMoney(bankType, amount, 'bank-withdrawal') then if Player.Functions.AddMoney('cash', amount, 'bank-withdrawal') then TriggerClientEvent('ox_lib:notify', src, { description = 'Withdrew $'.. amount, type = 'success' }) end endend)
-- SERVER SIDE-- Award bloodmoney from robberyRegisterNetEvent('robbery:server:complete', function() local src = source local Player = RSGCore.Functions.GetPlayer(src) if not Player then return end local bloodReward = math.random(100, 500) if Player.Functions.AddMoney('bloodmoney', bloodReward, 'store-robbery') then TriggerClientEvent('ox_lib:notify', src, { description = 'You got $'.. bloodReward ..' in bloodmoney', type = 'error', duration = 5000 }) endend)-- Black market shop accepting bloodmoneyRegisterNetEvent('blackmarket:server:purchase', function(itemName, price) local src = source local Player = RSGCore.Functions.GetPlayer(src) if not Player then return end -- Check bloodmoney balance if Player.Functions.GetMoney('bloodmoney') < price then TriggerClientEvent('ox_lib:notify', src, { description = 'Not enough bloodmoney', type = 'error' }) return end -- Process purchase if Player.Functions.RemoveMoney('bloodmoney', price, 'blackmarket-purchase') then exports['rsg-inventory']:AddItem(src, itemName, 1, nil, nil, 'blackmarket') endend)-- Law enforcement confiscationRegisterNetEvent('police:server:confiscateBloodmoney', function(targetId) local src = source local Officer = RSGCore.Functions.GetPlayer(src) local Target = RSGCore.Functions.GetPlayer(targetId) if not Officer or not Target then return end -- Check officer is law enforcement if Officer.PlayerData.job.type ~= 'leo' then return end local bloodAmount = Target.Functions.GetMoney('bloodmoney') if bloodAmount > 0 then Target.Functions.SetMoney('bloodmoney', 0, 'police-confiscation') TriggerClientEvent('ox_lib:notify', targetId, { description = 'Police confiscated $'.. bloodAmount ..' bloodmoney', type = 'error' }) TriggerClientEvent('ox_lib:notify', src, { description = 'Confiscated $'.. bloodAmount ..' bloodmoney', type = 'success' }) endend)
-- SERVER SIDE-- Automatic paycheck (called by rsg-core every X minutes)function PaycheckInterval() if next(RSGCore.Players) then for _, Player in pairs(RSGCore.Players) do if Player then local job = Player.PlayerData.job local payment = RSGShared.Jobs[job.name]['grades'][tostring(job.grade.level)].payment -- Only pay if on duty (or job allows off-duty pay) if payment > 0 and (RSGShared.Jobs[job.name].offDutyPay or job.onduty) then Player.Functions.AddMoney('cash', payment, 'paycheck') TriggerClientEvent('ox_lib:notify', Player.PlayerData.source, { title = 'Paycheck', description = 'Received $'.. payment, type = 'info', duration = 5000 }) end end end end SetTimeout(RSGCore.Config.Money.PayCheckTimeOut * 60000, PaycheckInterval)end
-- SERVER SIDERegisterNetEvent('bank:server:getBalance', function() local src = source local Player = RSGCore.Functions.GetPlayer(src) if not Player then return end local bankData = { cash = Player.Functions.GetMoney('cash'), valbank = Player.Functions.GetMoney('valbank'), rhobank = Player.Functions.GetMoney('rhobank'), blkbank = Player.Functions.GetMoney('blkbank'), armbank = Player.Functions.GetMoney('armbank'), bloodmoney = Player.Functions.GetMoney('bloodmoney') } TriggerClientEvent('bank:client:displayBalance', src, bankData)end)-- Transfer between accountsRegisterNetEvent('bank:server:transfer', function(fromBank, toBank, amount) local src = source local Player = RSGCore.Functions.GetPlayer(src) if not Player then return end -- Validate if Player.Functions.GetMoney(fromBank) < amount then TriggerClientEvent('ox_lib:notify', src, { description = 'Insufficient funds', type = 'error' }) return end -- Process transfer if Player.Functions.RemoveMoney(fromBank, amount, 'bank-transfer') then if Player.Functions.AddMoney(toBank, amount, 'bank-transfer') then TriggerClientEvent('ox_lib:notify', src, { description = 'Transfer successful', type = 'success' }) end endend)
-- SERVER SIDERegisterNetEvent('player:server:onDeath', function() local src = source local Player = RSGCore.Functions.GetPlayer(src) if not Player then return end -- Drop random percentage of cash (10-30%) local cashAmount = Player.Functions.GetMoney('cash') if cashAmount > 0 then local dropPercent = math.random(10, 30) / 100 local dropAmount = math.floor(cashAmount * dropPercent) if Player.Functions.RemoveMoney('cash', dropAmount, 'death-penalty') then -- Create ground drop local playerPed = GetPlayerPed(src) local coords = GetEntityCoords(playerPed) exports['rsg-inventory']:ForceDropItem(src, 'dollar', dropAmount, {}, 'death') TriggerClientEvent('ox_lib:notify', src, { description = 'You dropped $'.. dropAmount ..' when you died', type = 'error', duration = 5000 }) end endend)
if Player.Functions.GetMoney('cash') >= price then Player.Functions.RemoveMoney('cash', price, 'purchase')end
Handle failures:
Copy
if not Player.Functions.AddMoney('cash', reward, 'quest-reward') then -- Player inventory might be full if money items enabled -- Money will be dropped on ground automaticallyend
If migrating from an older framework with single โbankโ type:
Copy
-- SERVER SIDE - Migration scriptRegisterCommand('migratebanks', function(source) if not RSGCore.Functions.HasPermission(source, 'admin') then return end MySQL.query('SELECT citizenid, money FROM players', {}, function(result) if result then for i = 1, #result do local money = json.decode(result[i].money) if money.bank and money.bank > 0 then -- Transfer old 'bank' to 'valbank' (or chosen default) money.valbank = money.valbank + money.bank money.bank = 0 MySQL.update('UPDATE players SET money = ? WHERE citizenid = ?', { json.encode(money), result[i].citizenid }) end end print('Bank migration complete!') end end)end, false)