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

294 lines
8.6 KiB
Lua

carDealer.enabled = true
carDealer.cache = carDealer.cache or {
owned = {},
categories = {},
}
local function attachWheel(ent, mdlOrig, mdl, pos, ang, radius)
local w = octolib.createDummy(mdlOrig)
w:SetParent(ent)
w:SetLocalPos(pos)
w:SetLocalAngles(ang)
w:SetNoDraw(true)
ent.wheels[#ent.wheels + 1] = w
if mdl ~= mdlOrig then
local mins, maxs = w:GetRenderBounds()
local origwheelsize = maxs - mins
if not radius then
radius = math.max(origwheelsize.x, origwheelsize.y, origwheelsize.z) * 0.5
end
w:SetModel(mdl)
local mins, maxs = w:GetRenderBounds()
local wheelsize = maxs - mins
local size = (radius * 2) / math.max(wheelsize.x, wheelsize.y, wheelsize.z)
w:SetModelScale(size)
end
end
local function wheelAngle(members, data, model, right)
local Forward = Vector(0, 1, 0)
local Right = Vector(right and 1 or -1, 0, 0)
local Up = Vector(0, 0, 1)
if members.SpawnAngleOffset then
local ang = Angle(0, members.SpawnAngleOffset, 0)
Forward:Rotate(ang)
Right:Rotate(ang)
Up:Rotate(ang)
end
local angleoffset = members.CustomWheelAngleOffset
local mirAng = right and 1 or -1
local ang = Right:Angle()
ang:RotateAroundAxis(Forward, angleoffset.p * mirAng)
ang:RotateAroundAxis(Right, angleoffset.r * mirAng)
ang:RotateAroundAxis(Up, 90)
ang:RotateAroundAxis(Forward, (data.camber or 0) * mirAng)
local add = simfphys.GetWheelAngle(model)
if add then
ang:RotateAroundAxis(Forward, add.p * mirAng)
ang:RotateAroundAxis(Right, add.r * mirAng)
ang:RotateAroundAxis(Up, -add.y)
end
return ang
end
function carDealer.attachWheels(ent, vehID, data)
data = data or {}
local cdData = carDealer.vehicles[vehID]
if not cdData then return end
local spData = list.Get('simfphys_vehicles')[cdData.simfphysID]
assert(spData ~= nil, 'Wrong simfphysID for ' .. vehID)
ent.wheels = {}
local m = spData.Members
local mdlOrigF, mdlOrigR = m.CustomWheelModel, m.CustomWheelModel_R or m.CustomWheelModel
local mdlF, mdlR =
data.rims and data.rims[1] or m.CustomWheelModel,
data.rims and data.rims[2] or m.CustomWheelModel_R or m.CustomWheelModel
if m.CustomWheelPosFL then
attachWheel(ent, mdlOrigF, mdlF, m.CustomWheelPosFL - Vector(0, 0, m.FrontHeight / 4), wheelAngle(m, data, mdlF, false), m.FrontWheelRadius)
end
if m.CustomWheelPosFR then
attachWheel(ent, mdlOrigF, mdlF, m.CustomWheelPosFR - Vector(0, 0, m.FrontHeight / 4), wheelAngle(m, data, mdlF, true), m.FrontWheelRadius)
end
if m.CustomWheelPosRL then
attachWheel(ent, mdlOrigR, mdlR, m.CustomWheelPosRL - Vector(0, 0, m.RearHeight / 4), wheelAngle(m, data, mdlR, false), m.RearWheelRadius)
end
if m.CustomWheelPosRR then
attachWheel(ent, mdlOrigR, mdlR, m.CustomWheelPosRR - Vector(0, 0, m.RearHeight / 4), wheelAngle(m, data, mdlR, true), m.RearWheelRadius)
end
ent:CallOnRemove('DeleteWheels', function(ent)
if not ent.wheels then return end
for _, w in ipairs(ent.wheels) do
if IsValid(w) and w ~= NULL then w:Remove() end
end
end)
end
function carDealer.attachAccessories(ent, atts)
ent.atts = {}
for _, data in pairs(atts) do
local attEnt = octolib.createDummy(data.model, data.rg)
data.parent = ent
octolib.applyEntData(attEnt, data)
attEnt.col = data.col
attEnt:SetNoDraw(true)
ent.atts[#ent.atts + 1] = attEnt
end
ent:CallOnRemove('DeleteAttachments', function(ent)
if not ent.atts then return end
for _, a in ipairs(ent.atts) do
if IsValid(a) and a ~= NULL then a:Remove() end
end
end)
end
netstream.Hook('car-dealer.sync', function(owned, categories)
for id, veh in pairs(owned) do veh.id = id end
carDealer.cache = {
owned = owned,
categories = categories,
}
hook.Run('car-dealer.sync', carDealer.cache)
end)
hook.Add('InitPostEntity', 'car-dealer', function()
local atts = simfphys.attachments
carDealer.canAttach = function(ent, att)
if not att then return false end
if not IsValid(ent) then return false end
if not ent.vehicleName or not atts[att].cars[ent.vehicleName] then return false end
local t = atts[att].type
if not force and ent.atts and IsValid(ent.atts[t]) and ent.atts[t]:GetModel() == atts[att].mdl then
return false
end
return true
end
carDealer.removeAttachment = function(ent, type)
if ent.atts and IsValid(ent.atts[type]) and ent.atts[type] ~= NULL then
ent.atts[type]:Remove()
ent.atts[type] = nil
end
end
carDealer.addAttachment = function(ent, att)
if not carDealer.canAttach(ent, att) then return end
local t = atts[att].type
carDealer.removeAttachment(ent, t)
local attData = atts[att].cars[ent.vehicleName]
local attEnt = octolib.createDummy(atts[att].mdl)
attEnt:SetParent(ent)
attEnt:SetLocalPos(attData[1] or Vector())
attEnt:SetLocalAngles(attData[2] or Angle())
attEnt:SetModelScale(attData[3] or 1)
attEnt:SetSkin(atts[att].skin or 0)
attEnt.attClass = att
attEnt.noPaint = atts[att].noPaint
if not attEnt.noPaint then attEnt:SetColor(ent:GetColor()) end
attEnt:SetNoDraw(true)
ent.atts = ent.atts or {}
ent.atts[t] = attEnt
end
end)
hook.Add('octogui.f4-tabs', 'car-dealer', function()
octogui.addToF4({
order = 11.6,
id = 'dealer',
name = 'Гараж',
icon = Material('octoteam/icons/car2.png'),
build = function(f)
f:SetSize(800, 600)
f:DockPadding(0, 24, 0, 0)
f:Center()
local br = f:Add 'DButton'
br:SetPos(700, 2)
br:SetSize(60, 20)
br:SetText('Обновить')
function br:DoClick()
netstream.Start('car-dealer.sync')
end
f:Add 'cd_menu'
netstream.Start('car-dealer.sync')
end,
show = function(f, st)
carDealer.menu:SetMinimized(not st)
end
})
end)
surface.CreateFont('car-dealer.plate', {
font = 'License Plate',
size = 64,
weight = 500,
antialias = true,
extended = true,
})
local function roundVector(pos, decimals)
local float = '%.' .. decimals .. 'f'
return table.concat({'(',float,', ',float,', ',float,')'}, ''):format(pos.x, pos.y, pos.z)
end
local function roundAngle(ang, decimals)
local float = '%.' .. decimals .. 'f'
return table.concat({'[',float,', ',float,', ',float,']'}, ''):format(ang.p, ang.y, ang.r)
end
hook.Add('octolib.configLoaded', 'car-dealer', function()
if not CFG.dev then return end
concommand.Add('car_setup', function()
local seat = LocalPlayer():GetVehicle()
local car = IsValid(seat) and seat:GetParent()
if not IsValid(car) then return octolib.notify.show('warning', 'Нужно находиться в автомобиле') end
local radius = car:GetModelRadius()
octolib.flyEditor.start({
parent = car,
props = {
{
name = 'Передний номер',
model = 'models/octoteam/vehicles/attachments/licenceplate_01.mdl',
pos = Vector(radius, 0, 0),
ang = Angle(0, 0, 0),
}, {
name = 'Задний номер',
model = 'models/octoteam/vehicles/attachments/licenceplate_01.mdl',
pos = Vector(-radius, 0, 0),
ang = Angle(0, 180, 0),
}, {
name = 'Приборная панель',
model = 'models/props_c17/gravestone_coffinpiece001a.mdl',
pos = Vector(0, radius / 8, radius / 8),
ang = Angle(0, -90, 90),
size = Vector(0.096, 0.07, 0.0015),
}, {
name = 'Зеркало в салоне',
model = 'models/props/cs_italy/orange.mdl',
pos = Vector(radius / 2, 0, radius / 4),
ang = Angle(0, 0, 0),
}, {
name = 'Левое зеркало',
model = 'models/props/cs_italy/orange.mdl',
pos = Vector(0, radius / 2, 0),
ang = Angle(0, 0, 0),
}, {
name = 'Правое зеркало',
model = 'models/props/cs_italy/orange.mdl',
pos = Vector(0, -radius / 2, 0),
ang = Angle(0, 0, 0),
}, {
name = 'Радио',
model = 'models/props_lab/reciever01d.mdl',
pos = Vector(0, 0, 0),
ang = Angle(0, 180, 0),
},
},
space = octolib.flyEditor.SPACE_PARENT,
vPos = vPos,
vAng = vAng,
maxDist = 500,
anchorEnt = car,
noCopy = true,
noRemove = true,
}, function(data)
local fPlate, rPlate, dash, mMirror, lMirror, rMirror, radio = unpack(data)
chat.AddText('---')
chat.AddText('Автомобиль: ' .. car:GetSpawn_List())
chat.AddText('Передний номер: ' .. roundVector(fPlate.pos, 3) .. roundAngle(fPlate.ang, 1))
chat.AddText('Задний номер: ' .. roundVector(rPlate.pos, 3) .. roundAngle(rPlate.ang, 1))
chat.AddText('Приборная панель: ' .. roundVector(dash.pos, 3) .. roundAngle(dash.ang, 1))
chat.AddText('Зеркало в салоне: ' .. roundVector(mMirror.pos, 3))
chat.AddText('Левое зеркало: ' .. roundVector(lMirror.pos, 3))
chat.AddText('Правое зеркало: ' .. roundVector(rMirror.pos, 3))
chat.AddText('Радио: ' .. roundVector(radio.pos, 3) .. roundAngle(radio.ang, 1))
end)
end)
end)