dobrograd-13-06-2022/garrysmod/addons/feature-cars/lua/car-dealer/sv_player.lua

349 lines
9.2 KiB
Lua
Raw Normal View History

2023-11-16 15:01:19 +05:00
function carDealer.setCurVeh(ply, veh)
-- use table because 'pon.entityCreated'
ply:SetNetVar('cd.vehicle', { veh })
veh:SetNetVar('cd.owner', nil)
veh:SetNetVar('cd.owner', ply)
end
function carDealer.getCurVehID(ply)
local veh = carDealer.getCurVeh(ply)
return veh and veh:GetNetVar('cd.id') or nil
end
function carDealer.getAvailableCategories(ply)
local result = {}
for k,v in pairs(carDealer.categories) do
if (not isfunction(v.canUse) or v.canUse(ply) ~= false)
and (not isfunction(v.canSee) or v.canSee(ply) ~= false) then
result[#result + 1] = k
end
end
return result
end
function carDealer.clearMarkers(ply)
if IsValid(ply) then
ply:ClearMarkers('car.spawn')
ply:ClearMarkers('car.despawn')
end
end
function carDealer.spawnOwnedVeh(ply, id, callback, force)
callback = callback or octolib.func.zero
local veh = carDealer.getCurVeh(ply)
if IsValid(veh) then
return callback(false, 'Сначала надо загнать свой автомобиль')
end
local class, garage, dbData, cdData
octolib.func.chain({
function(done) -- checks and stuff
carDealer.getVehById(id, done)
end,
function(done, data) -- prepare entity
dbData = data or {}
class, garage = dbData.class, dbData.garage
if not dbData or (garage ~= ply:SteamID() and not force) then
return callback(false, 'Ты не приобрел этот автомобиль')
end
cdData = class and carDealer.vehicles[class]
if not cdData or not carDealer.canUse(ply, class) then return callback(false) end
local catData = cdData.category and carDealer.categories[cdData.category]
if not catData then return callback(false) end
local spawns = catData.spawns[game.GetMap()]
or carDealer.civilSpawns[game.GetMap()]
if not spawns then
return callback(false, 'Напиши админам, что они опростоволосились, и передай привет от автодилера')
end
carDealer.notify(ply, 'Поиск свободного места...')
carDealer.nearestPos({
pPos = ply:GetPos(),
vars = spawns,
check = function()
return IsValid(ply)
end,
callback = done,
})
end,
function(_, pos, ang)
if not IsValid(ply) then return callback(false) end
if not pos then return callback(false, 'Не получилось найти свободное место') end
local veh = carDealer.spawnVeh(class, pos, ang, dbData.data)
if not IsValid(veh) then return callback(false, 'Не получилось создать автомобиль') end
local mins = veh:GetCollisionBounds()
local tr = util.TraceLine({
start = pos,
endpos = pos + Vector(0, 0, -1000),
collisiongroup = COLLISION_GROUP_WORLD,
})
if tr.Hit then
veh:SetPos(tr.HitPos + Vector(0, 0, 20 - mins.z))
end
veh:SetNetVar('cd.id', id)
simfphys.SetOwner(ply, veh)
veh:Lock()
carDealer.setCurVeh(ply, veh)
veh:SetNetVar('cd.plate', dbData.plate)
veh.idleScore = 10
carDealer.clearMarkers(ply)
ply:AddMarker({
id = 'car.spawn',
txt = cdData.name or 'Автомобиль',
pos = veh:GetPos() + Vector(0,0,10),
col = Color(255,92,38),
des = {'timedist', {600, 300}},
icon = 'octoteam/icons-16/car.png',
})
if dbData.plate then
hook.Run('car-dealer.spawnedOwned', veh, ply)
callback(true, veh)
else
carDealer.firstAvailablePlate(function(plate)
veh:SetNetVar('cd.plate', plate)
hook.Run('car-dealer.spawnedOwned', veh, ply)
callback(true, veh)
end)
end
end,
})
end
function carDealer.spawnDepositVeh(ply, class, callback)
callback = callback or octolib.func.zero
local veh = carDealer.getCurVeh(ply)
if IsValid(veh) then
return callback(false, 'Сначала надо загнать свой автомобиль')
end
local cdData = class and carDealer.vehicles[class]
if not cdData or not carDealer.canUse(ply, class) then return callback(false) end
local catData = cdData.category and carDealer.categories[cdData.category]
if not catData then return callback(false) end
local spawns = catData.spawns[game.GetMap()]
or carDealer.civilSpawns[game.GetMap()]
if not spawns then
return callback(false, 'Напиши админам, что они опростоволосились, и передай привет от автодилера')
end
carDealer.nearestPos({
pPos = ply:GetPos(),
vars = spawns,
maxAttempts = 1,
check = function()
return IsValid(ply)
end,
callback = function(pos, ang)
if not pos then
return callback(false, 'Не получилось найти свободное место')
end
local veh = carDealer.spawnVeh(class, pos, ang)
if not IsValid(veh) then return callback(false, 'Не получилось создать автомобиль') end
local mins = veh:GetCollisionBounds()
local tr = util.TraceLine({
start = pos,
endpos = pos + Vector(0, 0, -1000),
collisiongroup = COLLISION_GROUP_WORLD,
})
if tr.Hit then
veh:SetPos(tr.HitPos + Vector(0, 0, 20 - mins.z))
end
simfphys.SetOwner(ply, veh)
veh:Lock()
carDealer.setCurVeh(ply, veh)
veh.steamID = ply:SteamID()
veh.idleScore = 10
carDealer.clearMarkers(ply)
ply:AddMarker({
id = 'car.spawn',
txt = cdData.name or 'Автомобиль',
pos = veh:GetPos() + Vector(0,0,10),
col = Color(255,92,38),
des = {'timedist', {600, 300}},
icon = 'octoteam/icons-16/car.png',
})
carDealer.firstAvailablePlate(function(plate)
veh:SetNetVar('cd.plate', plate)
hook.Run('car-dealer.spawnedDeposit', veh, ply)
callback(true, veh) -- call outer callback
end)
end,
})
end
function carDealer.returnDeposit(ent)
local ply = ent:GetNetVar('cd.owner')
local account = IsValid(ply) and ply or ent.steamID
if not account then return end
local amount = carDealer.getCurVehPrice(ent)
local name = ent.cdData.name
hook.Run('car-dealer.returnedDeposit', ent, ply, amount)
BraxBank.PlayerMoneyAsync(account, function(money)
BraxBank.UpdateMoney(account, money + amount)
if IsValid(ply) then
carDealer.notify(ply, 'hint', 'Возврат залога за ' .. name .. ': ' .. carDealer.formatMoney(amount))
end
end)
end
function carDealer.sync(ply)
if not IsValid(ply) then return end
carDealer.getGarage(ply:SteamID(), function(garage)
local categories = carDealer.getAvailableCategories(ply)
netstream.Start(ply, 'car-dealer.sync', garage, categories)
end)
end
function carDealer.canUseCategory(ply, catID)
if not catID then return false end
local catData = carDealer.categories[catID]
if not catData then return false end
if catData.canUse then
local ok, why = catData.canUse(ply)
if ok == false then
return false, why or 'Ты не можешь использовать эту категорию'
end
end
return true
end
function carDealer.canUse(ply, class)
local cdData = carDealer.vehicles[class]
if not cdData then return false, 'Этой модели автомобиля не существует' end
if cdData.canUse then
local ok, why = cdData.canUse(ply)
if ok == false then
return false, why or 'Ты не можешь использовать этот автомобиль'
end
end
return carDealer.canUseCategory(ply, cdData.category)
end
function carDealer.canBuy(ply, class)
local cdData = carDealer.vehicles[class]
if not cdData then return false, 'Этой модели автомобиля не существует' end
local canUse, canUseWhy = carDealer.canUse(ply, class)
if not canUse then return canUse, canUseWhy end
if cdData.canBuy then
local ok, why = cdData.canBuy(ply)
if ok == false then
return false, why or 'Ты не можешь купить этот автомобиль'
end
end
if cdData.canSee then
local ok, why = cdData.canSee(ply)
if ok == false then
return false, why or 'А-та-та'
end
end
-- dont check for nil as it's done in canUseClass
local catData = carDealer.categories[cdData.category]
if catData.canBuy then
local ok, why = catData.canBuy(ply)
if ok == false then
return false, why or 'Ты не можешь купить этот автомобиль'
end
end
if catData.canSee then
local ok, why = catData.canSee(ply)
if ok == false then
return false, why or 'А-та-та'
end
end
return true
end
function carDealer.resetPlate(ent, returnItem, admin)
local id, owner = ent:GetNetVar('cd.id'), ent:CPPIGetOwner()
if not id or not owner then return end
local oldPlate = ent:GetNetVar('cd.plate')
octolib.func.chain({
carDealer.firstAvailablePlate,
function(done, plate)
carDealer.updateVehData(id, {plate = plate}, function()
done(plate)
end)
end,
function(done, plate)
ent:SetNetVar('cd.plate', plate)
owner:Notify('Администрация сбросила номер ' .. tostring(oldPlate) .. ' на твоем автомобиле')
if returnItem then
owner:osGiveItem('car_plate', function()
owner:Notify('Плюшка "Блатной номер" была возвращена')
done()
end)
else
owner:Notify('Плюшка "Блатной номер" возвращена не будет')
done()
end
end,
function()
if admin then
hook.Run('car-dealer.resetPlate', admin, ent, oldPlate, returnItem)
end
end,
})
end