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

266 lines
7.3 KiB
Lua

--
-- OCTOSIMFPHYS
--
function simfphys.GetRight(ent, index, WheelPos)
local Steer = ent:GetTransformedDirection()
local Right = ent.Right
if WheelPos.IsFrontWheel then
Right = (IsValid(ent.SteerMaster) and Steer.Right or ent.Right) * (WheelPos.IsRightWheel and 1 or -1)
else
Right = (IsValid(ent.SteerMaster) and Steer.Right2 or ent.Right) * (WheelPos.IsRightWheel and 1 or -1)
end
return Right
end
function simfphys.SetWheelOffset(ent, offset_front, offset_rear)
if not IsValid(ent) then return end
offset_front = math.Clamp(offset_front, -8, 4)
offset_rear = math.Clamp(offset_rear, -8, 4)
ent.wOffsetF = offset_front
ent.wOffsetR = offset_rear
if not istable(ent.Wheels) or not istable(ent.GhostWheels) then return end
for i = 1, table.Count(ent.GhostWheels) do
local Wheel = ent.Wheels[ i ]
local WheelModel = ent.GhostWheels[i]
local WheelPos = ent:LogicWheelPos(i)
if IsValid(Wheel) and IsValid(WheelModel) then
local Pos = Wheel:GetPos()
local Right = simfphys.GetRight(ent, i, WheelPos)
local offset = WheelPos.IsFrontWheel and offset_front or offset_rear
WheelModel:SetParent(nil)
local physObj = WheelModel:GetPhysicsObject()
if IsValid(physObj) then
physObj:EnableMotion(false)
end
WheelModel:SetPos(Pos + Right * offset)
WheelModel:SetParent(Wheel)
end
end
end
function simfphys.ApplyWheel(ent, camber, front, rear)
rear = rear or front
local aof, aor = simfphys.GetWheelAngle(front), simfphys.GetWheelAngle(rear)
if not aof or not aor then print('Wheel model not registered') return end
ent.wModelF = front
ent.wModelR = rear
ent.waOffsetF = aof
ent.waOffsetR = aor
ent.camber = math.Clamp(camber or 0, -18, 10)
ent.PressedKeys["A"] = nil
ent.PressedKeys["D"] = nil
ent.SmoothAng = 0
ent:SteerVehicle(0)
timer.Simple(0.05, function()
if not IsValid(ent) then return end
for i = 1, table.Count(ent.GhostWheels) do
local Wheel = ent.GhostWheels[i]
if IsValid(Wheel) then
local isfrontwheel = (i == 1 or i == 2)
local swap_y = (i == 2 or i == 4 or i == 6)
local angleoffset = isfrontwheel and ent.waOffsetF or ent.waOffsetR
local model = isfrontwheel and ent.wModelF or ent.wModelR
local fAng = ent:LocalToWorldAngles(ent.VehicleData.LocalAngForward)
local rAng = ent:LocalToWorldAngles(ent.VehicleData.LocalAngRight)
local Forward = fAng:Forward()
local Right = swap_y and -rAng:Forward() or rAng:Forward()
local Up = ent:GetUp()
local ghostAng = Right:Angle()
local mirAng = swap_y and 1 or -1
ghostAng:RotateAroundAxis(Forward,angleoffset.p * mirAng)
ghostAng:RotateAroundAxis(Right,angleoffset.r * mirAng)
ghostAng:RotateAroundAxis(Up,-angleoffset.y)
ghostAng:RotateAroundAxis(Forward, ent.camber * mirAng)
Wheel:SetModelScale(1)
Wheel:SetModel(model)
Wheel:SetAngles(ghostAng)
timer.Simple(0.05, function()
if not IsValid(Wheel) or not IsValid(ent) then return end
local wheelsize = Wheel:OBBMaxs() - Wheel:OBBMins()
local radius = isfrontwheel and ent.FrontWheelRadius or ent.RearWheelRadius
local size = (radius * 2) / math.max(wheelsize.x,wheelsize.y,wheelsize.z)
Wheel:SetModelScale(size)
end)
end
end
end)
end
function simfphys.ValidateModel(model)
local v_list = list.Get("simfphys_vehicles")
for listname, _ in pairs(v_list) do
if v_list[listname].Members.CustomWheels then
local FrontWheel = v_list[listname].Members.CustomWheelModel
local RearWheel = v_list[listname].Members.CustomWheelModel_R
if FrontWheel then
FrontWheel = string.lower(FrontWheel)
end
if RearWheel then
RearWheel = string.lower(RearWheel)
end
if model == FrontWheel or model == RearWheel then
return true
end
end
end
local list = list.Get("simfphys_Wheels")[model]
if list then
return true
end
return false
end
function simfphys.SetupSuspension(ent, susp)
local carData = list.Get("simfphys_vehicles")[ent.VehicleName].Members
susp[1] = math.Clamp(susp[1], -1, 1)
susp[2] = math.Clamp(susp[2], carData.FrontConstant, carData.FrontConstant * 2)
susp[3] = math.Clamp(susp[3], 0, carData.FrontDamping * 1.5)
susp[4] = math.Clamp(susp[4], math.max(susp[1] - 1, -1), math.min(susp[1] + 1, 1))
susp[5] = math.Clamp(susp[5], carData.RearConstant, carData.RearConstant * 2)
susp[6] = math.Clamp(susp[6], 0, carData.RearDamping * 1.5)
local data = {
[1] = {susp[2], susp[3]},
[2] = {susp[2], susp[3]},
[3] = {susp[5], susp[6]},
[4] = {susp[5], susp[6]},
[5] = {susp[5], susp[6]},
[6] = {susp[5], susp[6]}
}
local elastics = ent.Elastics
if (elastics) then
for i = 1, table.Count(elastics) do
local elastic = elastics[i]
if not elastic or not data[i] then continue end
if (ent.StrengthenSuspension == true) then
if (IsValid(elastic)) then
elastic:Fire("SetSpringConstant", data[i][1] * 0.5, 0)
elastic:Fire("SetSpringDamping", data[i][2] * 0.5, 0)
end
local elastic2 = elastics[i * 10]
if (IsValid(elastic2)) then
elastic2:Fire("SetSpringConstant", data[i][1] * 0.5, 0)
elastic2:Fire("SetSpringDamping", data[i][2] * 0.5, 0)
end
else
if (IsValid(elastic)) then
elastic:Fire("SetSpringConstant", data[i][1], 0)
elastic:Fire("SetSpringDamping", data[i][2], 0)
end
end
ent.dampF = data[1][2]
ent.consF = data[1][1]
ent.dampR = data[4][2]
ent.consR = data[4][1]
end
end
ent:SetFrontSuspensionHeight(susp[1])
ent:SetRearSuspensionHeight(susp[4])
end
function simfphys.CanPlayerTune(ply, ent)
if not IsValid(ply) or not IsValid(ent) then return false, L.car_not_found end
if ent:GetIsLocked() then return false, L.car_closed end
local owner = ent:CPPIGetOwner()
if not IsValid(owner) or ply ~= owner and not (owner.Buddies and owner.Buddies[ply] and table.HasValue(owner.Buddies[ply], true)) then return false, L.car_you_need_be_friend end
return true
end
simfphys.postSpawn = simfphys.postSpawn or {}
function simfphys.AddPostSpawnAction(class, func)
simfphys.postSpawn[class] = func
end
function simfphys.GetSeatProperty(seat, property)
if not IsValid(seat) then return end
local car = seat:GetParent()
if not IsValid(car) or car:GetClass() ~= 'gmod_sent_vehicle_fphysics_base' then return end
if seat[property] ~= nil then return seat[property] end
car.spawnlist = car.spawnlist or list.Get('simfphys_vehicles')[car:GetSpawn_List()]
local lst = car.spawnlist.Members
local lPos = car:WorldToLocal(seat:GetPos())
for _,v in ipairs(lst.PassengerSeats) do
if lPos:DistToSqr(v.pos) < 10 then
if v[property] ~= nil then
seat[property] = v[property]
else
seat[property] = false
end
break
end
end
return seat[property]
end
simfphys.fuelPrices = {
[FUELTYPE_DIESEL] = 80,
[FUELTYPE_PETROL] = 120,
[FUELTYPE_ELECTRIC] = 10,
}
util.AddNetworkString 'car.steer'
net.Receive('car.steer', function(len, ply)
local seat = ply:GetVehicle()
if not IsValid(seat) or not IsValid(seat.base) then return end
local car = seat.base
if car:GetDriverSeat() ~= seat then return end
car.wantedSteer = net.ReadFloat()
end)
hook.Add('CanTool', 'octo-cars', function(ply, tr, tool)
local ent = tr.Entity
if tool ~= 'remover' and IsValid(ent) and ent:GetClass() == 'gmod_sent_vehicle_fphysics_base'
and IsValid(ply) and not ply:query('DBG: Изменять автомобили') then
return false
end
end)