- UID
- 67
- 在线时间
- 小时
- 阅读权限
- 70
- 注册时间
- 2021-3-17
- 最后登录
- 1970-1-1
【高级】合伙人
|
好的,我们现在详细演示一下如何添加银行和ATM功能。为了满足你的需求,我们会分别创建`config.lua`、`client_banking.lua`和`client_atm.lua`,并且确保这些文件都位于同一个资源目录中。这里演示的代码将不使用数据库,而是使用本地变量来存储贷款信息。
### 1. `config.lua`
首先,创建一个`config.lua`文件来保存所有配置:
-- config.lua
Config = {}
-- 所有银行的坐标
Config.Banks = {
{name = "Fleeca Bank", coords = vector3(150.0, -1040.0, 29.0)},
{name = "Blaine County Savings Bank", coords = vector3(-112.1, 6469.2, 31.6)}
-- 添加更多银行信息
}
-- 自动检测的ATM模型,在这里添加ATM模型的哈希值
Config.ATMModels = {
"prop_atm_01",
"prop_atm_02",
"prop_atm_03",
"prop_fleeca_atm"
}
-- 银行卡项目名称
Config.BankCardItem = "bank_card"
-- 可修改的转账金额选项
Config.TransferAmounts = {1000, 2000, 3000, 4000, 5000}
-- 可修改的贷款金额选项
Config.LoanAmounts = {1000, 2000, 3000, 4000, 5000}
-- 最大贷款月份
Config.MaxLoanMonths = 12
-- 每月利息百分比
Config.InterestRate = 0.02
-- 游戏公告提醒
Config.DueNoticeMessage = "您有未还的贷款到期了,请尽快还款!"
### 2. `client_banking.lua`
接下来,创建一个`client_banking.lua`文件来处理银行相关的功能:
local ESX = nil
local isNearBank = false
local playerLoans = {} -- 本地记录玩家贷款信息
Citizen.CreateThread(function()
-- 初始化ESX
while ESX == nil do
TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
Citizen.Wait(10)
end
-- 为所有银行添加Blip
for _, bank in ipairs(Config.Banks) do
local blip = AddBlipForCoord(bank.coords.x, bank.coords.y, bank.coords.z)
SetBlipSprite(blip, 108)
SetBlipDisplay(blip, 4)
SetBlipScale(blip, 1.0)
SetBlipColour(blip, 2)
SetBlipAsShortRange(blip, true)
BeginTextCommandSetBlipName("STRING")
AddTextComponentString(bank.name)
EndTextCommandSetBlipName(blip)
end
-- 添加银行目标区域
Citizen.CreateThread(function()
for _, bank in ipairs(Config.Banks) do
exports.ox_target:addBoxZone({
name = bank.name,
coords = bank.coords,
size = vec3(3, 3, 3),
options = {
{
event = 'bank:openBankMenu',
icon = 'fas fa-university',
label = '打开银行菜单'
}
}
})
end
end)
end)
RegisterNetEvent('bank:openBankMenu')
AddEventHandler('bank:openBankMenu', function()
if hasBankCard() then
openMenu('bank')
else
exports.ox_lib:notify({type = 'error', description = '你没有银行卡'})
end
end)
function hasBankCard()
return exports.ox_inventory:Search('slots', Config.BankCardItem) ~= nil
end
function openMenu(type)
local loan = playerLoans
local elements = {
{label = '转账', value = 'transfer'},
{label = '收款', value = 'withdraw'},
{label = '贷款', value = 'loan'},
{label = '查询贷款信息', value = 'loan_info'}
}
exports.ox_target:openUI({
title = '银行菜单',
align = 'top',
elements = elements,
onSelect = function(data)
if data.value == 'transfer' then
showTransferMenu()
elseif data.value == 'withdraw' then
showWithdrawMenu(type)
elseif data.value == 'loan' then
showLoanMenu()
elseif data.value == 'loan_info' then
showLoanInfoMenu(loan)
end
end
})
end
function showTransferMenu()
local elements = {}
for _, amount in ipairs(Config.TransferAmounts) do
table.insert(elements, {label = tostring(amount), value = amount})
end
table.insert(elements, {label = '自定义金额', value = 'custom'})
exports.ox_target:openUI({
title = '选择转账金额',
align = 'top',
elements = elements,
onSelect = function(data)
if data.value == 'custom' then
exports.ox_target:openInputDialogue({
title = '输入转账金额',
}, function(inputData)
local amount = tonumber(inputData.value)
if amount then
menu.close()
exports.ox_target:openInputDialogue({
title = '输入目标玩家ID'
}, function(data2)
local target_id = tonumber(data2.value)
if target_id then
exports.ox_target:openInputDialogue({
title = '输入目标银行卡号'
}, function(data3)
local target_card = data3.value
if target_card then
TriggerServerEvent('bank:transfer', target_id, target_card, amount)
else
exports.ox_lib:notify({type = 'error', description = '请输入有效的银行卡号'})
end
end)
else
exports.ox_lib:notify({type = 'error', description = '请输入有效的玩家ID'})
end
end)
else
exports.ox_lib:notify({type = 'error', description = '请输入有效金额'})
end
end)
else
local amount = data.value
exports.ox_target:openInputDialogue({
title = '输入目标玩家ID'
}, function(data2)
local target_id = tonumber(data2.value)
if target_id then
exports.ox_target:openInputDialogue({
title = '输入目标银行卡号'
}, function(data3)
local target_card = data3.value
if target_card then
TriggerServerEvent('bank:transfer', target_id, target_card, amount)
else
exports.ox_lib:notify({type = 'error', description = '请输入有效的银行卡号'})
end
end)
else
exports.ox_lib:notify({type = 'error', description = '请输入有效的玩家ID'})
end
end)
end
end
})
end
function showWithdrawMenu(type)
exports.ox_target:openInputDialogue({
title = '输入取款金额',
}, function(data)
local amount = tonumber(data.value)
if amount then
TriggerServerEvent('bank:withdraw', amount, type) -- 传递类型以区分银行和ATM
else
exports.ox_lib:notify({type = 'error', description = '请输入有效金额'})
end
end)
end
function showLoanMenu()
local elements = {}
for _, amount in ipairs(Config.LoanAmounts) do
table.insert(elements, {label = tostring(amount), value = amount})
end
table.insert(elements, {label = '自定义金额', value = 'custom'})
exports.ox_target:openUI({
title = '选择贷款金额',
align = 'top',
elements = elements,
onSelect = function(data)
if data.value == 'custom' then
exports.ox_target:openInputDialogue({
title = '输入贷款金额',
}, function(inputData)
local amount = tonumber(inputData.value)
if amount then
exports.ox_target:openInputDialogue({
title = '输入还款期限(1到'..Config.MaxLoanMonths..'月)',
}, function(data2)
local months = tonumber(data2.value)
if months and months >= 1 and months <= Config.MaxLoanMonths then
local interest = Config.InterestRate * months
local repay = amount * (1 + interest)
playerLoans = {amount = amount, repay = repay, dueDate = os.time() + months * 30 * 24 * 60 * 60}
exports.ox_lib:notify({type = 'success', description = '贷款成功'})
else
exports.ox_lib:notify({type = 'error', description = '请输入有效的还款期限'})
end
end)
else
exports.ox_lib:notify({type = 'error', description = '请输入有效的贷款金额'})
end
end)
else
local amount = data.value
exports.ox_target:openInputDialogue({
title = '输入还款期限(1到'..Config.MaxLoanMonths..'月)',
}, function(data2)
local months = tonumber(data2.value)
if months and months >= 1 and months <= Config.MaxLoanMonths then
local interest = Config.InterestRate * months
local repay = amount * (1 + interest)
playerLoans = {amount = amount, repay = repay, dueDate = os.time() + months * 30 * 24 * 60 * 60}
exports.ox_lib:notify({type = 'success', description = '贷款成功'})
else
exports.ox_lib:notify({type = 'error', description = '请输入有效的还款期限'})
end
end)
end
end
})
end
function showLoanInfoMenu(loan)
if loan.amount then
local timeToRepay = os.date('%Y-%m-%d %H:%M:%S', loan.dueDate)
exports.ox_lib:notify({
type = 'info',
description = string.format('贷款金额: %d\n总还款金额: %d\n还款截止日期: %s', loan.amount, loan.repay, timeToRepay)
})
else
exports.ox_lib:notify({type = 'info', description = '您没有未偿还的贷款.'})
end
end
### `client_atm.lua` (用于自动检测ATM模型和ATM功能)
lua
local ESX = nil
local isNearATM = false
Citizen.CreateThread(function()
while ESX == nil do
TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
Citizen.Wait(10)
end
local atmModels = {}
for i = 1, #Config.ATMModels do
table.insert(atmModels, GetHashKey(Config.ATMModels))
end
exports.ox_target:addModel({
models = atmModels,
options = {
{
event = 'atm:openATMMenu',
icon = 'fas fa-credit-card',
label = '打开ATM菜单'
}
}
})
end)
RegisterNetEvent('atm:openATMMenu')
AddEventHandler('atm:openATMMenu', function()
if hasBankCard() then
openMenu('atm')
else
exports.ox_lib:notify({type = 'error', description = '你没有银行卡'})
end
end)
function hasBankCard()
return exports.ox_inventory:Search('slots', Config.BankCardItem) ~= nil
end
function openMenu(type)
local loan = playerLoans
local elements = {
{label = '转账', value = 'transfer'},
{label = '收款', value = 'withdraw'},
{label = '查询贷款信息', value = 'loan_info'}
}
exports.ox_target:openUI({
title = 'ATM菜单',
align = 'top',
elements = elements,
onSelect = function(data)
if data.value == 'transfer' then
showTransferMenu()
elseif data.value == 'withdraw' then
showWithdrawMenu(type)
elseif data.value == 'loan_info' then
showLoanInfoMenu(loan)
end
end
})
end
function showTransferMenu()
local elements = {}
for _, amount in ipairs(Config.TransferAmounts) do
table.insert(elements, {label = tostring(amount), value = amount})
end
table.insert(elements, {label = '自定义金额', value = 'custom'})
exports.ox_target:openUI({
title = '选择转账金额',
align = 'top',
elements = elements,
onSelect = function(data)
if data.value == 'custom' then
exports.ox_target:openInputDialogue({
title = '输入转账金额',
}, function(inputData)
local amount = tonumber(inputData.value)
if amount then
menu.close()
exports.ox_target:openInputDialogue({
title = '输入目标玩家ID'
}, function(data2)
local target_id = tonumber(data2.value)
if target_id then
exports.ox_target:openInputDialogue({
title = '输入目标银行卡号'
}, function(data3)
local target_card = data3.value
if target_card then
TriggerServerEvent('bank:transfer', target_id, target_card, amount)
else
exports.ox_lib:notify({type = 'error', description = '请输入有效的银行卡号'})
end
end)
else
exports.ox_lib:notify({type = 'error', description = '请输入有效的玩家ID'})
end
end)
else
exports.ox_lib:notify({type = 'error', description = '请输入有效金额'})
end
end)
else
local amount = data.value
exports.ox_target:openInputDialogue({
title = '输入目标玩家ID'
}, function(data2)
local target_id = tonumber(data2.value)
if target_id then
exports.ox_target:openInputDialogue({
title = '输入目标银行卡号'
}, function(data3)
local target_card = data3.value
if target_card then
TriggerServerEvent('bank:transfer', target_id, target_card, amount)
else
exports.ox_lib:notify({type = 'error', description = '请输入有效的银行卡号'})
end
end)
else
exports.ox_lib:notify({type = 'error', description = '请输入有效的玩家ID'})
end
end)
end
end
})
end
function showWithdrawMenu(type)
exports.ox_target:openInputDialogue({
title = '输入取款金额',
}, function(data)
local amount = tonumber(data.value)
if amount then
TriggerServerEvent('bank:withdraw', amount, type)
else
exports.ox_lib:notify({type = 'error', description = '请输入有效金额'})
end
end)
end
function showLoanInfoMenu(loan)
if loan.amount then
local timeToRepay = os.date('%Y-%m-%d %H:%M:%S', loan.dueDate)
exports.ox_lib:notify({
type = 'info',
description = string.format('贷款金额: %d\n总还款金额: %d\n还款截止日期: %s', loan.amount, loan.repay, timeToRepay)
})
else
exports.ox_lib:notify({type = 'info', description = '您没有未偿还的贷款.'})
end
end
### `__resource.lua` (或 `fxmanifest.lua`)
最后,需要编辑 `__resource.lua` 或 `fxmanifest.lua` 文件来加载这些脚本:
-- __resource.lua 或 fxmanifest.lua
resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937'
description 'Banking and ATM System'
client_scripts {
'config.lua',
'client_banking.lua',
'client_atm.lua'
}
server_scripts {
'server.lua'
}
### `server.lua`
此文件将用于处理服务器端的交易逻辑,例如转账和取款:
ESX = nil
TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
RegisterServerEvent('bank:transfer')
AddEventHandler('bank:transfer', function(target_id, target_card, amount)
local xPlayer = ESX.GetPlayerFromId(source)
local targetPlayer = ESX.GetPlayerFromId(target_id)
if xPlayer and targetPlayer then
if xPlayer.getAccount('bank').money >= amount then
xPlayer.removeAccountMoney('bank', amount)
targetPlayer.addAccountMoney('bank', amount)
TriggerClientEvent('ox_lib:notify', xPlayer.source, {type = 'success', description = '转账成功'})
TriggerClientEvent('ox_lib:notify', targetPlayer.source, {type = 'success', description = '您收到了一笔转账'})
else
TriggerClientEvent('ox_lib:notify', xPlayer.source, {type = 'error', description = '银行余额不足'})
end
end
end)
RegisterServerEvent('bank:withdraw')
AddEventHandler('bank:withdraw', function(amount, type)
local xPlayer = ESX.GetPlayerFromId(source)
if xPlayer.getAccount('bank').money >= amount then
xPlayer.removeAccountMoney('bank', amount)
xPlayer.addMoney(amount)
TriggerClientEvent('ox_lib:notify', xPlayer.source, {type = 'success', description = '取款成功'})
else
TriggerClientEvent('ox_lib:notify', xPlayer.source, {type = 'error', description = '银行余额不足'})
end
end)
### 整个文件结构
确保你的文件结构如下:
resource_folder/
├── __resource.lua 或 fxmanifest.lua
├── config.lua
├── client_banking.lua
├── client_atm.lua
└── server.lua
### 启动资源
在你的服务器配置文件 (`server.cfg`) 中添加资源启动命令:
start resource_folder_name
把 `resource_folder_name` 替换为你资源文件夹的实际名字。在启动服务器后,你应该能够在合适的地点使用银行和ATM功能了。 |
|