dobrograd-13-06-2022/garrysmod/addons/feature-cars/lua/car-dealer/sv_player.lua
Jonny_Bro (Nikita) e4d5311906 first commit
2023-11-16 15:01:19 +05:00

348 lines
9.2 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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