From eb6144ae9488b0afe7aa116d2865d9a7fc7ddc56 Mon Sep 17 00:00:00 2001 From: Nikita Kruglickiy Date: Sat, 3 Apr 2021 21:08:08 +0600 Subject: [PATCH] Cleaning --- koptilnya/car_parts/anchor.txt | 5 - koptilnya/engine_sound.txt | 37 +- koptilnya/engine_sounds/abarth_exterior.txt | 66 +++ koptilnya/engine_sounds/bmw_e30_exterior.txt | 66 +++ koptilnya/engine_sounds/bmw_e30_interior.txt | 68 +++ koptilnya/gui/gui.txt | 4 + koptilnya/joystick_data.txt | 113 ++++ koptilnya/libs/utils.txt | 4 +- koptilnya/libs/workers.txt | 2 +- koptilnya/mesh_loader/cl_builder.txt | 47 +- koptilnya/mesh_loader/obj_parser.txt | 58 +- koptilnya/mesh_loader/sv_builder.txt | 120 +++- koptilnya/mesh_loader2/builder.txt | 7 - koptilnya/mesh_loader2/cl_builder.txt | 57 -- koptilnya/mesh_loader2/obj_parser.txt | 40 -- koptilnya/mesh_loader2/sv_builder.txt | 55 -- koptilnya/models/ford_f-150_raptor.txt | 71 +++ koptilnya/models/jdm_wheels.txt | 74 +++ koptilnya/models/toyota_altezza.txt | 42 ++ koptilnya/models/vaz_2106.txt | 174 ++++++ koptilnya/rpc.txt | 32 - koptilnya/torque_editor.txt | 580 +++++++++++++++++++ 22 files changed, 1440 insertions(+), 282 deletions(-) delete mode 100644 koptilnya/car_parts/anchor.txt create mode 100644 koptilnya/engine_sounds/abarth_exterior.txt create mode 100644 koptilnya/engine_sounds/bmw_e30_exterior.txt create mode 100644 koptilnya/engine_sounds/bmw_e30_interior.txt create mode 100644 koptilnya/joystick_data.txt delete mode 100644 koptilnya/mesh_loader2/builder.txt delete mode 100644 koptilnya/mesh_loader2/cl_builder.txt delete mode 100644 koptilnya/mesh_loader2/obj_parser.txt delete mode 100644 koptilnya/mesh_loader2/sv_builder.txt create mode 100644 koptilnya/models/ford_f-150_raptor.txt create mode 100644 koptilnya/models/jdm_wheels.txt create mode 100644 koptilnya/models/toyota_altezza.txt create mode 100644 koptilnya/models/vaz_2106.txt delete mode 100644 koptilnya/rpc.txt create mode 100644 koptilnya/torque_editor.txt diff --git a/koptilnya/car_parts/anchor.txt b/koptilnya/car_parts/anchor.txt deleted file mode 100644 index 94d37ce..0000000 --- a/koptilnya/car_parts/anchor.txt +++ /dev/null @@ -1,5 +0,0 @@ -Anchor = class("Anchor") - -function Anchor:initialize(pos, ang, parent, relativeTo) - -end \ No newline at end of file diff --git a/koptilnya/engine_sound.txt b/koptilnya/engine_sound.txt index 46e9010..fa99ae9 100644 --- a/koptilnya/engine_sound.txt +++ b/koptilnya/engine_sound.txt @@ -1,6 +1,5 @@ ---@include libs/utils.txt ---@client - +-- @include libs/utils.txt +-- @client require("/koptilnya/libs/utils.txt") EngineSound = class("EngineSound") @@ -10,42 +9,42 @@ accessorFunc(EngineSound, "_parent", "Parent", chip()) local function fadeIn(rpm, range) local fadeIn = 1 - - if range and range[1] != range[2] then + + if range and range[1] ~= range[2] then fadeIn = math.min(math.max((rpm + (range[2] - range[1] * 2)) / (range[2] - range[1]), 1) - 1, 1) elseif range and range[1] == range[2] then fadeIn = rpm >= range[1] and 1 or 0 end - + return fadeIn end local function fadeOut(rpm, range) local fadeOut = 1 - - if range and range[1] != range[2] then + + if range and range[1] ~= range[2] then fadeOut = math.min(math.max((rpm + (range[1] - range[2] * 2)) / (range[1] - range[2]), 1) - 1, 1) elseif range and range[1] == range[2] then fadeOut = rpm >= range[1] and 1 or 0 end - + return fadeOut end function EngineSound:initialize(soundsMap) self.pitchDamping = 0.2 self.volumeDamping = 0.3 - + self._rpm = 0 self._soundsMap = soundsMap - + for k, v in pairs(soundsMap) do bass.loadURL(v.link, "3d noblock", function(snd, err, errtxt) if snd then snd:setPos(self:getParent():getPos()) snd:setLooping(true) snd:setVolume(0) - + v.source = snd v.lastPitch = 1 v.lastVolume = 0 @@ -54,25 +53,25 @@ function EngineSound:initialize(soundsMap) end end) end - - hook.add("think", "EngineSound_think", function() + + hook.add("think", "EngineSound_think", function() for _, v in pairs(self._soundsMap) do if v.source then v.source:setPos(self:getParent():getPos()) - + local fadeIn = fadeIn(self:getRPM(), v.fadeIn) local fadeOut = fadeOut(self:getRPM(), v.fadeOut) local targetVolume = self:getMasterVolume() * (fadeIn + fadeOut - 1) local targetPitch = self:getRPM() / v.rootPitch - + local pitch = math.lerp(self.pitchDamping, v.lastPitch, targetPitch) local volume = math.lerp(self.volumeDamping, v.lastVolume, targetVolume) - + v.source:setVolume(volume) v.source:setPitch(pitch) - + v.lastVolume = volume - v.lastPitch = pitch + v.lastPitch = pitch end end end) diff --git a/koptilnya/engine_sounds/abarth_exterior.txt b/koptilnya/engine_sounds/abarth_exterior.txt new file mode 100644 index 0000000..6cbe849 --- /dev/null +++ b/koptilnya/engine_sounds/abarth_exterior.txt @@ -0,0 +1,66 @@ +--@name Abarth Exterior engine sound +--@shared +--@include /koptilnya/engine_sound.txt + +require("/koptilnya/engine_sound.txt") + +if SERVER then + wire.adjustInputs({"RPM"}, {"NORMAL"}) + + hook.add("input", "wireinput", function(name, value) + if name == "RPM" then + net.start("rpm") + net.writeFloat(value) + net.send() + end + end) +else + function init() + local engineSound = EngineSound:new({ + { + link = "https://dl.dropboxusercontent.com/s/b05fhpa6llc4sjj/ext_fa01_on_1500.ogg", + rootPitch = 1500, + fadeOut = Vector(1400, 1800) + }, + { + link = "https://dl.dropboxusercontent.com/s/cus2007qr25nlqg/ext_fa01_on_4250.ogg", + rootPitch = 4250, + fadeIn = Vector(1400, 1800), + fadeOut = Vector(3400, 3800) + }, + { + link = "https://dl.dropboxusercontent.com/s/ug9n6dtac1ayioi/ext_fa01_on_5250.ogg", + rootPitch = 5250, + fadeIn = Vector(3400, 3800), + fadeOut = Vector(4800, 5200) + }, + { + link = "https://dl.dropboxusercontent.com/s/ihdefqw30pwd059/ext_fa01_on_6000.ogg", + rootPitch = 6000, + fadeIn = Vector(4800, 5200), + fadeOut = Vector(5600, 6000) + }, + { + link = "https://dl.dropboxusercontent.com/s/7m98qruc8bhopyn/ext_fa01_on_6500.ogg", + rootPitch = 6500, + fadeIn = Vector(5600, 6000) + } + }) + + net.receive("rpm", function(len) + engineSound:setRPM(net.readFloat()) + end) + end + + if hasPermission("bass.loadURL") then + init() + else + setupPermissionRequest({"bass.loadURL"}, "", true) + + hook.add("permissionrequest", "permission", function() + if hasPermission("bass.loadURL") then + init() + end + end) + end +end \ No newline at end of file diff --git a/koptilnya/engine_sounds/bmw_e30_exterior.txt b/koptilnya/engine_sounds/bmw_e30_exterior.txt new file mode 100644 index 0000000..fa0dbed --- /dev/null +++ b/koptilnya/engine_sounds/bmw_e30_exterior.txt @@ -0,0 +1,66 @@ +--@name BMW E30 exterior engine sound +--@shared +--@include /koptilnya/engine_sound.txt + +require("/koptilnya/engine_sound.txt") + +if SERVER then + wire.adjustInputs({"RPM"}, {"NORMAL"}) + + hook.add("input", "wireinput", function(name, value) + if name == "RPM" then + net.start("rpm") + net.writeFloat(value) + net.send() + end + end) +else + function init() + local engineSound = EngineSound:new({ + { + link = "https://dl.dropboxusercontent.com/s/5lk7xkrrgozbgl2/ext_e30_idle.ogg", + rootPitch = 1000, + fadeOut = Vector(1000, 1500) + }, + { + link = "https://dl.dropboxusercontent.com/s/oiz3ccf6cenul8t/ext_e30_on_2500.ogg", + rootPitch = 2500, + fadeIn = Vector(1000, 1500), + fadeOut = Vector(2500, 3000) + }, + { + link = "https://dl.dropboxusercontent.com/s/346ly2b0ete839f/ext_e30_on_4500.ogg", + rootPitch = 4500, + fadeIn = Vector(2500, 3000), + fadeOut = Vector(4500, 5000) + }, + { + link = "https://dl.dropboxusercontent.com/s/wlyeqqwhaqe8oo5/ext_e30_on_6000.ogg", + rootPitch = 6000, + fadeIn = Vector(4500, 5000), + fadeOut = Vector(6500, 7000) + }, + { + link = "https://dl.dropboxusercontent.com/s/vijeiwwsgthlxzn/ext_e30_on_8500.ogg", + rootPitch = 8500, + fadeIn = Vector(6500, 7000) + } + }) + + net.receive("rpm", function(len) + engineSound:setRPM(net.readFloat()) + end) + end + + if hasPermission("bass.loadURL") then + init() + else + setupPermissionRequest({"bass.loadURL"}, "", true) + + hook.add("permissionrequest", "permission", function() + if hasPermission("bass.loadURL") then + init() + end + end) + end +end \ No newline at end of file diff --git a/koptilnya/engine_sounds/bmw_e30_interior.txt b/koptilnya/engine_sounds/bmw_e30_interior.txt new file mode 100644 index 0000000..350a1e6 --- /dev/null +++ b/koptilnya/engine_sounds/bmw_e30_interior.txt @@ -0,0 +1,68 @@ +--@name BMW E30 interior engine sound +--@shared +--@include /koptilnya/engine_sound.txt + +require("/koptilnya/engine_sound.txt") + +if SERVER then + wire.adjustInputs({"RPM"}, {"NORMAL"}) + + hook.add("input", "wireinput", function(name, value) + if name == "RPM" then + net.start("rpm") + net.writeFloat(value) + net.send() + end + end) +else + function init() + local engineSound = EngineSound:new({ + { + link = "https://dl.dropboxusercontent.com/s/wwda7cpdsrlsotb/e30_idle.ogg", + rootPitch = 1000, + fadeIn = Vector(0, 1), + fadeOut = Vector(1000, 1500) + }, + { + link = "https://dl.dropboxusercontent.com/s/5e9x082jdjgm2ym/e30_on_3500.ogg", + rootPitch = 3500, + fadeIn = Vector(1000, 1500), + fadeOut = Vector(3500, 4000) + }, + { + link = "https://dl.dropboxusercontent.com/s/83c3v08sjut5a9o/e30_on_5000.ogg", + rootPitch = 5000, + fadeIn = Vector(3500, 4000), + fadeOut = Vector(5000, 5500) + }, + { + link = "https://dl.dropboxusercontent.com/s/a6d3356uc7xstf1/e30_on_7000.ogg", + rootPitch = 7000, + fadeIn = Vector(5000, 5500), + fadeOut = Vector(7000, 7500) + }, + { + link = "https://dl.dropboxusercontent.com/s/pwpuldfs6w93ezb/e30_on_8500.ogg", + rootPitch = 8500, + fadeIn = Vector(7000, 7500) + } + }) + engineSound:setMasterVolume(0.8) + + net.receive("rpm", function(len) + engineSound:setRPM(net.readFloat()) + end) + end + + if hasPermission("bass.loadURL") then + init() + else + setupPermissionRequest({"bass.loadURL"}, "", true) + + hook.add("permissionrequest", "permission", function() + if hasPermission("bass.loadURL") then + init() + end + end) + end +end \ No newline at end of file diff --git a/koptilnya/gui/gui.txt b/koptilnya/gui/gui.txt index 0457464..443931e 100644 --- a/koptilnya/gui/gui.txt +++ b/koptilnya/gui/gui.txt @@ -45,6 +45,10 @@ function GUI:initialize(renderDevice) self._lastMouseX = 0 self._lastMouseY = 0 hook.add("think", "gui_think", function() + if not hasPermission("input") then + return + end + if input.getCursorVisible then local x, y = input.getCursorPos() diff --git a/koptilnya/joystick_data.txt b/koptilnya/joystick_data.txt new file mode 100644 index 0000000..a476fa9 --- /dev/null +++ b/koptilnya/joystick_data.txt @@ -0,0 +1,113 @@ +-- @name Joystick Data +-- @author Opti1337 +JOYSTICK_INPUT_TYPE = {Axis = 1, Button = 2} + +local CONFIG = { + Steer = { + DeviceId = 0, + InputId = 0, + Type = JOYSTICK_INPUT_TYPE.Axis, + Handler = function(value) + return math.remap(value, 0, 65535, -1, 1) + end + }, + Clutch = { + DeviceId = 0, + InputId = 4, + Type = JOYSTICK_INPUT_TYPE.Button, + Handler = function(value) + return math.remap(value, 0, 128, 0, 1) + end + }, + Throttle = { + DeviceId = 0, + InputId = 5, + Type = JOYSTICK_INPUT_TYPE.Button, + Handler = function(value) + return math.remap(value, 0, 128, 0, 1) + end + }, + Brake = { + DeviceId = 0, + InputId = 2, + Type = JOYSTICK_INPUT_TYPE.Button, + Handler = function(value) + return math.remap(value, 0, 128, 0, 1) + end + }, + Handbrake = { + DeviceId = 0, + InputId = 0, + Type = JOYSTICK_INPUT_TYPE.Button, + Handler = function(value) + return math.remap(value, 0, 128, 0, 1) + end + }, + GearUp = { + DeviceId = 0, + InputId = 1, + Type = JOYSTICK_INPUT_TYPE.Button, + Handler = function(value) + return math.remap(value, 0, 128, 0, 1) + end + }, + GearDown = { + DeviceId = 0, + InputId = 3, + Type = JOYSTICK_INPUT_TYPE.Button, + Handler = function(value) + return math.remap(value, 0, 128, 0, 1) + end + } +} + +if CLIENT and player() == owner() then + local data = {} + local isDirty = false + + hook.add("think", "_think", function() + for k, v in pairs(CONFIG) do + local value = 0 + + if v.Type == JOYSTICK_INPUT_TYPE.Axis then + value = joystick.getAxis(v.DeviceId, v.InputId) + elseif v.Type == JOYSTICK_INPUT_TYPE.Button then + value = joystick.getButton(v.DeviceId, v.InputId) + end + + if v.Handler ~= nil and type(v.Handler) == "function" then + value = v.Handler(value) or value + end + + if not isDirty and data[k] ~= value then + isDirty = true + end + + data[k] = value + end + + if isDirty then + net.start("data") + for k in pairs(CONFIG) do + net.writeFloat(data[k]) + end + net.send({}, true) + + isDirty = false + end + end) +elseif SERVER then + local outputs = {} + + for _, v in pairs(table.getKeys(CONFIG)) do + outputs[v] = "NORMAL" + end + + wire.adjustPorts({}, outputs) + + net.receive("data", function() + for k in pairs(CONFIG) do + wire.ports[k] = net.readFloat() + end + end) +end diff --git a/koptilnya/libs/utils.txt b/koptilnya/libs/utils.txt index 411b4b1..e7e1032 100644 --- a/koptilnya/libs/utils.txt +++ b/koptilnya/libs/utils.txt @@ -14,11 +14,11 @@ function accessorFunc(tbl, varName, name, defaultValue) end end -function rotateAround(entity, pivot, angles) +function rotateAround(entity, pivot, angles) local pos = entity:getPos() local localPivotPos = entity:worldToLocal(pivot) entity:setAngles(angles) - pos = pos + (pivot - entity:localToWorld(localPivotPos)) + pos = pos + (pivot - entity:localToWorld(localPivotPos)) entity:setPos(pos) end diff --git a/koptilnya/libs/workers.txt b/koptilnya/libs/workers.txt index 29ada07..83aac53 100644 --- a/koptilnya/libs/workers.txt +++ b/koptilnya/libs/workers.txt @@ -1,5 +1,5 @@ WORKERS = {} -WORKERS_QUOTA = 0.5 +WORKERS_QUOTA = 0.4 local function execWorker(worker) local status diff --git a/koptilnya/mesh_loader/cl_builder.txt b/koptilnya/mesh_loader/cl_builder.txt index adc0df9..b40771f 100644 --- a/koptilnya/mesh_loader/cl_builder.txt +++ b/koptilnya/mesh_loader/cl_builder.txt @@ -6,20 +6,29 @@ require("obj_parser.txt") MeshBuilder = class("MeshBuilder") -function MeshBuilder:initialize(link, maxQuota) +function MeshBuilder:initialize(link) self.link = link self.meshData = {} self._objects = {} - self._parser = ObjParser:new(link, maxQuota) - self._parser.onLoaded = function(parser, objData, meshData, usedTriangles) + self._parser = ObjParser:new(link) + self._parser.onLoaded = function(parser, objData) + self:onObjLoaded(objData) + end + self._parser.onParsed = function(parser, meshData, usedTriangles) + net.start("obj_parsed") + net.send() + + self:onObjParsed(meshData, usedTriangles) + self.meshData = meshData - net.start("ready") - net.send() + self:_applyMeshes() end - net.receive("holograms", function() + net.receive("objects", function() + self._objects = {} + local hasNext = net.readBit() while hasNext == 1 do @@ -27,17 +36,17 @@ function MeshBuilder:initialize(link, maxQuota) net.readEntity(function(ent) local holo = ent:toHologram() + local object = {name = name, holo = holo} - table.insert(self._objects, {name = name, holo = holo}) + table.insert(self._objects, object) end) hasNext = net.readBit() end - - self:_applyMeshes() - - timer.simple(0, function() + + timer.simple(0.5, function() self:onHologramsReceived(self._objects) + self:_applyMeshes() end) end) end @@ -47,9 +56,25 @@ function MeshBuilder:_applyMeshes() if self.meshData[v.name] ~= nil then v.holo:setMesh(self.meshData[v.name]) v.holo:setRenderBounds(Vector(-200), Vector(200)) + v.meshApplied = true end end + + if #self._objects > 0 then + self:onMeshesApplied() + end +end + +-- STUB + +function MeshBuilder:onObjLoaded(objData) +end + +function MeshBuilder:onObjParsed(meshData, usedTriangles) end function MeshBuilder:onHologramsReceived(objects) end + +function MeshBuilder:onMeshesApplied() +end diff --git a/koptilnya/mesh_loader/obj_parser.txt b/koptilnya/mesh_loader/obj_parser.txt index 9ee10d7..4b5276f 100644 --- a/koptilnya/mesh_loader/obj_parser.txt +++ b/koptilnya/mesh_loader/obj_parser.txt @@ -1,4 +1,7 @@ -- @client +-- @include /koptilnya/libs/workers.txt +require("/koptilnya/libs/workers.txt") + ObjParser = class("ObjParser") local initialChipName = chip():getChipName() @@ -6,35 +9,44 @@ local function setStatus(status) setName(string.format("%s (%s)", initialChipName, status)) end -function ObjParser:initialize(link, maxQuota) - self.maxQuota = maxQuota or 0.6 +function ObjParser:initialize(link) + addWorker(coroutine.wrap(function() + setStatus("Getting file...") - local triangles = mesh.trianglesLeft() + while not http.canRequest() do + coroutine.yield(1) + end - setStatus("Getting file...") - http.get(link, function(objData) - objData = string.gsub(objData, "\nl%s%d+%s%d+", "") - - local loadMesh = coroutine.wrap(function() - self.meshData = mesh.createFromObj(objData, true, true) - - return true + local objData + http.get(link, function(response) + objData = response + objData = string.gsub(response, "\nl%s%d+%s%d+", "") end) + while not objData do + coroutine.yield(1) + end + + self:onLoaded(objData) + + local triangles = mesh.trianglesLeft() + setStatus("File received, start parsing...") - hook.add("think", "loadingMesh", function() - while math.max(quotaAverage(), quotaUsed()) < quotaMax() * self.maxQuota do - if loadMesh() then - setName(initialChipName) - self:onLoaded(objData, self.meshData, triangles - mesh.trianglesLeft()) - hook.remove("think", "loadingMesh") - return - end - end - end) - end) + self.meshData = mesh.createFromObj(objData, true) + + self:onParsed(self.meshData, triangles - mesh.trianglesLeft()) + + setName(initialChipName) + + return 2 + end)) end -function ObjParser:onLoaded(objData, meshData, usedTriangles) +-- STUB + +function ObjParser:onLoaded(objData) +end + +function ObjParser:onParsed(meshData, usedTriangles) end diff --git a/koptilnya/mesh_loader/sv_builder.txt b/koptilnya/mesh_loader/sv_builder.txt index 8b8701a..5c59680 100644 --- a/koptilnya/mesh_loader/sv_builder.txt +++ b/koptilnya/mesh_loader/sv_builder.txt @@ -1,54 +1,99 @@ -- @server +-- @include /koptilnya/libs/workers.txt +require("/koptilnya/libs/workers.txt") + MeshBuilder = class("MeshBuilder") function MeshBuilder:initialize(link, modelPlaceholder) self.link = link self.modelPlaceholder = modelPlaceholder or "models/holograms/cube.mdl" - self.isReady = false self._objectsNames = {} self._objects = {} - self._readyPlayers = {} + self._objectsToSend = {} + self._firstTimePlayers = find.allPlayers() + self._firstTimeSended = false - http.get(link, function(response) - for object in string.gmatch(response, "^?\n?o%s([%w_%.%-]+)") do + net.receive("obj_parsed", function(len, ply) + self:onPlayerParsedObj(ply) + end) + + hook.add("ClientInitialized", "MeshBuilder_ClientInitialized", function(ply) + if #self._firstTimePlayers > 0 then + table.removeByValue(self._firstTimePlayers, ply) + + if #self._firstTimePlayers == 0 then + self:_sendObjects(find.allPlayers()) + + self._firstTimeSended = true + end + else + self:_sendObjects(ply) + end + end) + + hook.add("PlayerConnected", "MeshBuilder_PlayerConnected", function(ply) + if not self._firstTimeSended then + table.insert(self._firstTimePlayers, ply) + end + end) + + hook.add("PlayerDisconnected", "MeshBuilder_PlayerDisconnected", function(ply) + table.removeByValue(self._firstTimePlayers, ply) + end) + + addWorker(coroutine.wrap(function() + while not http.canRequest() do + coroutine.yield(1) + end + + local objData + http.get(link, function(response) + objData = response + end) + + while not objData do + coroutine.yield(1) + end + + self:onObjectLoaded(objData) + + for object in string.gmatch(objData, "^?\n?o%s([%w_%.%-]+)") do table.insert(self._objectsNames, object) end - - timer.simple(0, function() - self.isReady = true - self:onReady(self._objectsNames) - end) + self:onObjectParsed(self._objectsNames) - for _, v in pairs(self._readyPlayers) do - self:_sendHolograms(v) - end - end) - - net.receive("ready", function(len, ply) - table.insert(self._readyPlayers, ply) - - self:_sendHolograms(ply) - end) + return 2 + end)) end -function MeshBuilder:_sendHolograms(ply) - if #self._objects == 0 then +function MeshBuilder:_sendObjects(target) + if #self._objectsToSend == 0 then return end - net.start("holograms") - for _, v in pairs(self._objects) do + if type(target) == "table" and #target == 0 or type(target) == "Player" then + return + end + + net.start("objects") + for _, v in pairs(self._objectsToSend) do net.writeBit(1) net.writeString(v.name) net.writeEntity(v.holo) end net.writeBit(0) - net.send(ply) + net.send(target) end -function MeshBuilder:onReady(objectsNames) +function MeshBuilder:reset() + for _, v in pairs(self._objects) do + v.holo:remove() + end + + self._objects = {} + self._objectsToSend = {} end function MeshBuilder:build(name, pos, ang, scale, color, mat, parent, relativeTo) @@ -66,12 +111,27 @@ function MeshBuilder:build(name, pos, ang, scale, color, mat, parent, relativeTo end table.insert(self._objects, {name = name, holo = holo}) - - return name, holo + + return holo end -function MeshBuilder:buildAll(pos, ang, scale, color, mat, parent, relativeTo) - for _, v in pairs(self._objectsNames) do - self:build(v, pos, ang, scale, color, mat, parent, relativeTo) +function MeshBuilder:getResult() + table.copyFromTo(self._objects, self._objectsToSend) + + if self._firstTimeSended then + self:_sendObjects() end + + return self._objectsToSend +end + +-- STUB + +function MeshBuilder:onObjectLoaded(objData) +end + +function MeshBuilder:onObjectParsed(objectsNames) +end + +function MeshBuilder:onPlayerParsedObj(ply) end diff --git a/koptilnya/mesh_loader2/builder.txt b/koptilnya/mesh_loader2/builder.txt deleted file mode 100644 index d4951a2..0000000 --- a/koptilnya/mesh_loader2/builder.txt +++ /dev/null @@ -1,7 +0,0 @@ --- @include sv_builder.txt --- @include cl_builder.txt -if SERVER then - require("sv_builder.txt") -else - require("cl_builder.txt") -end diff --git a/koptilnya/mesh_loader2/cl_builder.txt b/koptilnya/mesh_loader2/cl_builder.txt deleted file mode 100644 index 2f53d79..0000000 --- a/koptilnya/mesh_loader2/cl_builder.txt +++ /dev/null @@ -1,57 +0,0 @@ --- @client --- @include /koptilnya/libs/table.txt --- @include obj_parser.txt -require("/koptilnya/libs/table.txt") -require("obj_parser.txt") - -MeshBuilder = class("MeshBuilder") - -function MeshBuilder:initialize(link, maxQuota) - self.link = link - self.meshData = {} - - self._objects = {} - self._parser = ObjParser:new(link, maxQuota) - self._parser.onLoaded = function(parser, objData, meshData, usedTriangles) - self.meshData = meshData - - self:_applyMeshes() - end - - net.receive("holograms", function() - local newObjects = {} - local hasNext = net.readBit() - - while hasNext == 1 do - local name = net.readString() - - net.readEntity(function(ent) - local holo = ent:toHologram() - local object = {name = name, holo = holo, meshApplied = false} - - table.insert(newObjects, object) - table.insert(self._objects, object) - end) - - hasNext = net.readBit() - end - - timer.simple(0, function() - self:_applyMeshes() - self:onHologramsReceived(newObjects, self._objects) - end) - end) -end - -function MeshBuilder:_applyMeshes() - for _, v in pairs(self._objects) do - if self.meshData[v.name] ~= nil and not v.meshApplied then - v.holo:setMesh(self.meshData[v.name]) - v.holo:setRenderBounds(Vector(-200), Vector(200)) - v.meshApplied = true - end - end -end - -function MeshBuilder:onHologramsReceived(objects) -end diff --git a/koptilnya/mesh_loader2/obj_parser.txt b/koptilnya/mesh_loader2/obj_parser.txt deleted file mode 100644 index 9ee10d7..0000000 --- a/koptilnya/mesh_loader2/obj_parser.txt +++ /dev/null @@ -1,40 +0,0 @@ --- @client -ObjParser = class("ObjParser") - -local initialChipName = chip():getChipName() -local function setStatus(status) - setName(string.format("%s (%s)", initialChipName, status)) -end - -function ObjParser:initialize(link, maxQuota) - self.maxQuota = maxQuota or 0.6 - - local triangles = mesh.trianglesLeft() - - setStatus("Getting file...") - http.get(link, function(objData) - objData = string.gsub(objData, "\nl%s%d+%s%d+", "") - - local loadMesh = coroutine.wrap(function() - self.meshData = mesh.createFromObj(objData, true, true) - - return true - end) - - setStatus("File received, start parsing...") - hook.add("think", "loadingMesh", function() - while math.max(quotaAverage(), quotaUsed()) < quotaMax() * self.maxQuota do - if loadMesh() then - setName(initialChipName) - self:onLoaded(objData, self.meshData, triangles - mesh.trianglesLeft()) - hook.remove("think", "loadingMesh") - - return - end - end - end) - end) -end - -function ObjParser:onLoaded(objData, meshData, usedTriangles) -end diff --git a/koptilnya/mesh_loader2/sv_builder.txt b/koptilnya/mesh_loader2/sv_builder.txt deleted file mode 100644 index 9586dd4..0000000 --- a/koptilnya/mesh_loader2/sv_builder.txt +++ /dev/null @@ -1,55 +0,0 @@ --- @server -MeshBuilder = class("MeshBuilder") - -function MeshBuilder:initialize(link, modelPlaceholder) - self.link = link - self.modelPlaceholder = modelPlaceholder or "models/holograms/cube.mdl" - - self._objects = {} -end - -function MeshBuilder:_sendHolograms() - if #self._objects == 0 then - return - end - - net.start("holograms") - for _, v in pairs(self._objects) do - net.writeBit(1) - net.writeString(v.name) - net.writeEntity(v.holo) - print(v.name) - end - net.writeBit(0) - net.send() -end - -function MeshBuilder:reset() - self._objects = {} -end - -function MeshBuilder:build(name, pos, ang, scale, color, mat, parent, relativeTo) - if isValid(relativeTo) then - pos = relativeTo:localToWorld(pos) - ang = relativeTo:localToWorldAngles(ang) - end - - local holo = holograms.create(pos, ang, self.modelPlaceholder, scale) - holo:setColor(color) - holo:setMaterial(mat) - - if isValid(parent) then - holo:setParent(parent) - end - - table.insert(self._objects, {name = name, holo = holo}) -end - -function MeshBuilder:getResult() - local result = self._objects - - self:_sendHolograms() - self:reset() - - return result -end diff --git a/koptilnya/models/ford_f-150_raptor.txt b/koptilnya/models/ford_f-150_raptor.txt new file mode 100644 index 0000000..e339b05 --- /dev/null +++ b/koptilnya/models/ford_f-150_raptor.txt @@ -0,0 +1,71 @@ +-- @shared +-- @name Ford F-150 Raptor +-- @author Opti1337, .hemp +-- @include /koptilnya/mesh_loader/builder.txt +require("/koptilnya/mesh_loader/builder.txt") + +local LINK = "https://drive.google.com/uc?id=1PvM_NNtdl43L_r2LZz_E9lO_JhWexFxW" +local SCALE = Vector(0.9) + +local builder = {} + +if SERVER then + builder = MeshBuilder:new(LINK) + builder.onPlayerParsedObj = function(builder, ply) + print(ply) + end + + builder:build("Podnojki", Vector(0), Angle(0), SCALE, Color(200, 200, 200), "sprops/textures/sprops_chrome", chip(), chip()) + builder:build("Kenguryatnik", Vector(0), Angle(0), SCALE, Color(200, 200, 200), "sprops/textures/sprops_chrome", chip(), chip()) + builder:build("AntennaSerebro", Vector(0), Angle(0), SCALE, Color(200, 200, 200), "sprops/textures/sprops_chrome", chip(), chip()) + builder:build("Vihlop", Vector(0), Angle(0), SCALE, Color(200, 200, 200), "sprops/textures/sprops_chrome", chip(), chip()) + + builder:build("Podtumanniki", Vector(0), Angle(0), SCALE, Color(100, 100, 100), "models/debug/debugwhite", chip(), chip()) + builder:build("Nomera", Vector(0), Angle(0), SCALE, Color(54, 225, 220), "models/debug/debugwhite", chip(), chip()) + builder:build("Okna", Vector(0), Angle(0), SCALE, Color(0, 0, 0, 200), "models/debug/debugwhite", chip(), chip()) + builder:build("Skobi", Vector(0), Angle(0), SCALE, Color(55, 55, 55, 255), "models/debug/debugwhite", chip(), chip()) + builder:build("Nakladki", Vector(0), Angle(0), SCALE, Color(44, 44, 44, 255), "models/debug/debugwhite", chip(), chip()) + builder:build("Black", Vector(0), Angle(0), SCALE, Color(0, 0, 0), "models/debug/debugwhite", chip(), chip()) + builder:build("SalonKraskiyCvet", Vector(0), Angle(0), SCALE, Color(225, 55, 55), "models/debug/debugwhite", chip(), chip()) + builder:build("Korpus", Vector(0), Angle(0), SCALE, Color(155, 0, 0), "models/debug/debugwhite", chip(), chip()) + builder:build("Salon", Vector(0), Angle(0), SCALE, Color(110, 100, 100), "models/debug/debugwhite", chip(), chip()) + builder:build("Sidushki", Vector(0), Angle(0), SCALE, Color(110, 100, 100), "models/debug/debugwhite", chip(), chip()) + builder:build("Vozduhovodi", Vector(0), Angle(0), SCALE, Color(50, 50, 50), "models/debug/debugwhite", chip(), chip()) + builder:build("Lampochki", Vector(0), Angle(0), SCALE, Color(255, 255, 255), "models/debug/debugwhite", chip(), chip()) + builder:build("Rama", Vector(0), Angle(0), SCALE, Color(80, 80, 80), "models/debug/debugwhite", chip(), chip()) + builder:build("VihlopInner", Vector(0), Angle(0), SCALE, Color(30, 30, 30), "models/debug/debugwhite", chip(), chip()) + builder:build("PerednieFari", Vector(0), Angle(0), SCALE, Color(80, 80, 80), "models/debug/debugwhite", chip(), chip()) + builder:build("Steklo", Vector(0), Angle(0), SCALE, Color(255, 255, 255, 200), "models/debug/debugwhite", chip(), chip()) + builder:build("StekloZadneiFari", Vector(0), Angle(0), SCALE, Color(255, 0, 0), "models/debug/debugwhite", chip(), chip()) + builder:build("StekloZadneiFari2", Vector(0), Angle(0), SCALE, Color(225, 55, 55), "models/debug/debugwhite", chip(), chip()) + builder:build("KorpusZadneiFari", Vector(0), Angle(0), SCALE, Color(225, 55, 55), "models/debug/debugwhite", chip(), chip()) + builder:build("Multimedia", Vector(0), Angle(0), SCALE, Color(225, 255, 255), "models/debug/debugwhite", chip(), chip()) + + builder:build("KorpusAntenni", Vector(0), Angle(0), SCALE, Color(255, 255, 255), "sprops/textures/sprops_rubber2", chip(), chip()) + builder:build("Shnorkel", Vector(0), Angle(0), SCALE, Color(255, 255, 255), "sprops/textures/sprops_rubber2", chip(), chip()) + builder:build("Plastik", Vector(0), Angle(0), SCALE, Color(255, 255, 255), "sprops/textures/sprops_rubber2", chip(), chip()) + builder:build("RailingPlastik", Vector(0), Angle(0), SCALE, Color(255, 255, 255), "sprops/textures/sprops_rubber2", chip(), chip()) + builder:build("SalonGovno", Vector(0), Angle(0), SCALE, Color(255, 255, 255), "sprops/textures/sprops_rubber2", chip(), chip()) + builder:build("Dvorniki", Vector(0), Angle(0), SCALE, Color(255, 255, 255), "sprops/textures/sprops_rubber2", chip(), chip()) + builder:build("Antenna", Vector(0), Angle(0), SCALE, Color(255, 255, 255), "sprops/textures/sprops_rubber2", chip(), chip()) + + builder:build("Railing", Vector(0), Angle(0), SCALE, Color(255, 255, 255), "sprops/trans/wheels/wheel_d_rim1", chip(), chip()) + + local result = builder:getResult() +else + function init() + builder = MeshBuilder:new(LINK) + end + + if hasPermission("http.get") and hasPermission("mesh") and hasPermission("entities.setRenderProperty", chip()) then + init() + else + setupPermissionRequest({"http.get", "mesh", "entities.setRenderProperty"}, "", true) + + hook.add("permissionrequest", "_permissionrequest", function() + if permissionRequestSatisfied() then + init() + end + end) + end +end diff --git a/koptilnya/models/jdm_wheels.txt b/koptilnya/models/jdm_wheels.txt new file mode 100644 index 0000000..4e53bd8 --- /dev/null +++ b/koptilnya/models/jdm_wheels.txt @@ -0,0 +1,74 @@ +--@shared +--@name JDM Wheels +--@author Opti1337, .hemp +--@include /koptilnya/mesh_loader/builder.txt + +require("/koptilnya/mesh_loader/builder.txt") + +local LINK = "https://www.dropbox.com/s/uu2tia6ac13cobu/jdmwheel1.obj?dl=1" +local SCALE = Vector(0.6) +local MATERIALS = { + Center = "models/debug/debugwhite", + Bolt = "sprops/textures/sprops_chrome", + Chrome = "sprops/trans/wheels/wheel_d_rim1", + Plastic = "sprops/textures/sprops_rubber2", + Rim = "sprops/trans/wheels/wheel_d_rim1", + RimAround = "sprops/trans/wheels/wheel_d_rim1" +} +local COLORS = { + Center = Color(45,45,45), + Bolt = Color(255, 255, 255), + Chrome = Color(255, 255, 255), + Plastic = Color(255, 255, 255), + Rim = Color(255, 255, 255), + RimAround = Color(255,255,255) +} +local OFFSET = 1 + +local builder = {} + +if SERVER then + wire.adjustPorts( + { + Wheels = "ARRAY" + }, + { + } + ) + + builder = MeshBuilder:new(LINK) + + hook.add("input", "_input", function(name, value) + if name == "Wheels" then + builder:reset() + + for _, wheel in pairs(wire.ports.Wheels) do + builder:build("center", Vector(0, OFFSET - 0.6, 0), Angle(0), SCALE, COLORS.Center, MATERIALS.Center, wheel, wheel) + builder:build("bolt", Vector(0, OFFSET- 0.6, 0), Angle(0), SCALE, COLORS.Bolt, MATERIALS.Bolt, wheel, wheel) + builder:build("chrome", Vector(0, OFFSET - 1, 0), Angle(0), SCALE, COLORS.Chrome, MATERIALS.Chrome, wheel, wheel) + builder:build("plastic", Vector(0, OFFSET, 0), Angle(0), SCALE, COLORS.Plastic, MATERIALS.Plastic, wheel, wheel) + builder:build("rim1", Vector(0, OFFSET, 0), Angle(0), SCALE - Vector(0, 0.1, 0), COLORS.RimAround, MATERIALS.Rim, wheel, wheel) + builder:build("rimAround", Vector(0, OFFSET, 0), Angle(0), SCALE - Vector(0, 0.1, 0), COLORS.Rim, MATERIALS.RimAround, wheel, wheel) + builder:build("tyre", Vector(0, OFFSET, 0), Angle(0), SCALE - Vector(0, 0.1, 0), Color(255, 255, 255), "sprops/textures/sprops_rubber", wheel, wheel) + end + + builder:getResult() + end + end) +else + function init() + builder = MeshBuilder:new(LINK) + end + + if hasPermission("http.get") and hasPermission("mesh") and hasPermission("entities.setRenderProperty", chip()) then + init() + else + setupPermissionRequest({"http.get", "mesh", "entities.setRenderProperty"}, "", true) + + hook.add("permissionrequest", "_permissionrequest", function() + if permissionRequestSatisfied() then + init() + end + end) + end +end \ No newline at end of file diff --git a/koptilnya/models/toyota_altezza.txt b/koptilnya/models/toyota_altezza.txt new file mode 100644 index 0000000..23eaa3d --- /dev/null +++ b/koptilnya/models/toyota_altezza.txt @@ -0,0 +1,42 @@ +-- @shared +-- @name Toyota Altezza +-- @author Opti1337, .hemp +-- @include /koptilnya/mesh_loader/builder.txt +require("/koptilnya/mesh_loader/builder.txt") + +local LINK = "https://www.dropbox.com/s/ovw7f8q65tlcdy5/is300.obj?dl=1" +local SCALE = Vector(0.8, 0.79, 0.8) + +local builder = {} + +if SERVER then + builder = MeshBuilder:new(LINK) + + builder:build("body_Mesh_0", Vector(0), Angle(0), SCALE, Color(54, 225, 220), "models/debug/debugwhite", chip(), chip()) + builder:build("chrome_Mesh_1", Vector(0), Angle(0), SCALE, Color(255, 255, 255), "sprops/textures/sprops_chrome", chip(), chip()) + builder:build("glass_Mesh_2", Vector(0), Angle(0), SCALE, Color(55, 55, 55, 200), "models/debug/debugwhite", chip(), chip()) + builder:build("hood_Mesh_3", Vector(0), Angle(0), SCALE, Color(255, 255, 255, 255), "sprops/textures/sprops_cfiber2", chip(), chip()) + builder:build("interier_Mesh_4", Vector(0), Angle(0), SCALE, Color(255, 255, 255), "sprops/textures/sprops_rubber2", chip(), chip()) + builder:build("plastic_Mesh_5", Vector(0), Angle(0), SCALE, Color(255, 255, 255), "sprops/textures/sprops_rubber2", chip(), chip()) + builder:build("redGlass_Mesh_6", Vector(0), Angle(0), SCALE, Color(225, 55, 55, 255), "models/debug/debugwhite", chip(), chip()) + builder:build("Reshetka_Mesh_7", Vector(0), Angle(0), SCALE, Color(225, 255, 255, 255), "models/props_interiors/metalfence007a", chip(), chip()) + builder:build("w_plastic_Mesh_8", Vector(0), Angle(0), SCALE, Color(225, 255, 255, 255), "models/combine_scanner/scanner_eye", chip(), chip()) + + builder:getResult() +else + function init() + builder = MeshBuilder:new(LINK) + end + + if hasPermission("http.get") and hasPermission("mesh") and hasPermission("entities.setRenderProperty", chip()) then + init() + else + setupPermissionRequest({"http.get", "mesh", "entities.setRenderProperty"}, "", true) + + hook.add("permissionrequest", "_permissionrequest", function() + if permissionRequestSatisfied() then + init() + end + end) + end +end diff --git a/koptilnya/models/vaz_2106.txt b/koptilnya/models/vaz_2106.txt new file mode 100644 index 0000000..39a3de0 --- /dev/null +++ b/koptilnya/models/vaz_2106.txt @@ -0,0 +1,174 @@ +-- @shared +-- @name VAZ 2106 +-- @author Opti1337, DarkSupah +-- @include /koptilnya/mesh_loader/builder.txt +require("/koptilnya/mesh_loader/builder.txt") + +local LINK = "https://www.dropbox.com/s/x2esgnl33i8if2w/vaz2106.obj?dl=1" +local SCALE = Vector(0.9) +local MATERIALS = { + Exterior = "phoenix_storms/mrref2", + Chrome = "models/shiny", + Plastic = "models/debug/debugwhite", + Glass = "phoenix_storms/mrref2", + Under = "sprops/textures/gear_metal", + DoorInterior = "sprops/textures/sprops_rubber2", + InteriorFloor = "models/debug/debugwhite", + DashboardBase = "models/debug/debugwhite", + Seats = "sprops/textures/sprops_rubber2", + Interior = "models/debug/debugwhite", + DoorHandle = "sprops/textures/sprops_chrome", + Grill = "models/debug/debugwhite", + Shelf = "models/debug/debugwhite", + Sideskirts = "models/debug/debugwhite", + Vent = "models/debug/debugwhite", + InteriorFrame = "models/debug/debugwhite", + LightsContainer = "models/debug/debugwhite", + Lights = "models/debug/debugwhite", + FrontLights = "sprops/trans/wheels/wheel_d_rim2", + Insulation = "models/debug/debugwhite", + DashButtons = "models/debug/debugwhite", + FrontLightsClose = "models/debug/debugwhite", + FrontLightsCloseGlass = "models/debug/debugwhite", + FrontLightsFar = "models/debug/debugwhite", + FrontLightsFarGlass = "models/debug/debugwhite" +} +local COLORS = { + Exterior = Color(30, 30, 30, 255), + Chrome = Color(180, 180, 180, 255), + Plastic = Color(110, 110, 110, 255), + Glass = Color(50, 50, 50, 200), + Under = Color(150, 150, 150, 255), + DoorInterior = Color(120, 120, 120, 255), + InteriorFloor = Color(30, 30, 30, 255), + DashboardBase = Color(30, 30, 30, 255), + Seats = Color(150, 150, 150, 255), + InteriorRoof = Color(30, 30, 30, 255), + DoorHandle = Color(210, 210, 210, 255), + Grill = Color(30, 30, 30, 255), + Shelf = Color(30, 30, 30, 255), + Sideskirts = Color(30, 30, 30, 255), + Vent = Color(40, 40, 40, 255), + InteriorFrame = Color(30, 30, 30, 255), + LightsContainer = Color(50, 50, 50, 255), + ReverseLights = Color(240, 240, 240, 255), + Blinkers = Color(255, 140, 0, 255), + FrontParkingLights = Color(190, 190, 190, 255), + RearParkingLights = Color(180, 80, 50, 255), + StopLights = Color(220, 60, 20, 255), + Insulation = Color(60, 60, 60, 255), + DashButtons = Color(60, 60, 60, 255), + FrontLightsClose = Color(130, 130, 130, 255), + FrontLightsCloseGlass = Color(245, 240, 240, 255), + FrontLightsFar = Color(130, 130, 130, 255), + FrontLightsFarGlass = Color(255, 220, 40, 255) +} + +local builder = {} + +if SERVER then + builder = MeshBuilder:new(LINK) + builder:build("Body__Exterior", Vector(0), Angle(0), SCALE, COLORS.Exterior, MATERIALS.Exterior, chip(), chip()) + + builder:build("Glass", Vector(0), Angle(0), SCALE, COLORS.Glass, MATERIALS.Glass, chip(), chip()) + builder:build("Body__WindowsLine__Rubber", Vector(0), Angle(0), SCALE, COLORS.Insulation, MATERIALS.Insulation, chip(), chip()) + builder:build("Body__TrunkLine__Rubber", Vector(0), Angle(0), SCALE, COLORS.Insulation, MATERIALS.Insulation, chip(), chip()) + + builder:build("Body__DoorLocks__Locks", Vector(0), Angle(0), SCALE, COLORS.Chrome, MATERIALS.Chrome, chip(), chip()) + + builder:build("Body__TrunkPinstripe__Chrome", Vector(0), Angle(0), SCALE, COLORS.Chrome, MATERIALS.Chrome, chip(), chip()) + + builder:build("Body__FuelCapLine__Chrome", Vector(0), Angle(0), SCALE, COLORS.Chrome, MATERIALS.Chrome, chip(), chip()) + + builder:build("Body__Under__Bottom", Vector(0), Angle(0), SCALE, COLORS.Under, MATERIALS.Under, chip(), chip()) + builder:build("Body__Misc__Exterior", Vector(0), Angle(0), SCALE, COLORS.Exterior, MATERIALS.Exterior, chip(), chip()) + builder:build("Interior__Seats__Seat", Vector(0), Angle(0), SCALE, COLORS.Seats, MATERIALS.Seats, chip(), chip()) + builder:build("Interior__RoofCover__InteriorRoof", Vector(0), Angle(0), SCALE, COLORS.InteriorRoof, MATERIALS.Interior, chip(), chip()) + builder:build("Body__Grill__GrillPlastic", Vector(0), Angle(0), SCALE, COLORS.Grill, MATERIALS.Grill, chip(), chip()) + builder:build("Body__FrontLightsFrame__Plastic", Vector(0), Angle(0), SCALE, COLORS.Grill, MATERIALS.Grill, chip(), chip()) + builder:build("Interior__RearPanel__Panel", Vector(0), Angle(0), SCALE, COLORS.Shelf, MATERIALS.Shelf, chip(), chip()) + builder:build("Body__Sideskirts__Plastic", Vector(0), Angle(0), SCALE, COLORS.Sideskirts, MATERIALS.Sideskirts, chip(), chip()) + + builder:build("Body__DoorsFrame__Chrome", Vector(0), Angle(0), SCALE, COLORS.Chrome, MATERIALS.Chrome, chip(), chip()) + + -- builder:build("Body__FrontBumper__Chrome", Vector(0), Angle(0), SCALE, COLORS.Chrome, MATERIALS.Chrome, chip(), chip()) + -- builder:build("Body__FrontBumper__Plastic", Vector(0), Angle(0), SCALE, COLORS.Plastic, MATERIALS.Plastic, chip(), chip()) + + -- builder:build("Body__RearBumper__Chrome", Vector(0), Angle(0), SCALE, COLORS.Chrome, MATERIALS.Chrome, chip(), chip()) + -- builder:build("Body__RearBumper__Plastic", Vector(0), Angle(0), SCALE, COLORS.Plastic, MATERIALS.Plastic, chip(), chip()) + + builder:build("Interior__Floor__InteriorFloor", Vector(0), Angle(0), SCALE, COLORS.InteriorFloor, MATERIALS.InteriorFloor, chip(), chip()) + builder:build("Interior__DashBase__Dashboard", Vector(0), Angle(0), SCALE, COLORS.DashboardBase, MATERIALS.DashboardBase, chip(), chip()) + builder:build("Dashboard__Vents__Vents", Vector(0), Angle(0), SCALE, COLORS.Vent, MATERIALS.Vent, chip(), chip()) + builder:build("Dashboard__Buttons__Buttons", Vector(0), Angle(0), SCALE, COLORS.DashButtons, MATERIALS.DashButtons, chip(), chip()) + + builder:build("Body__InteriorFrame__Plastic", Vector(0), Angle(0), SCALE, COLORS.InteriorFrame, MATERIALS.InteriorFrame, chip(), chip()) + + builder:build("FrontLights__BlinkerBase__Plastic", Vector(0), Angle(0), SCALE, COLORS.LightsContainer, MATERIALS.LightsContainer, chip(), chip()) + builder:build("Body__RearLightsContainer__Plastic", Vector(0), Angle(0), SCALE, COLORS.LightsContainer, MATERIALS.LightsContainer, chip(), chip()) + builder:build("Body__RearLightHolders__Plastic", Vector(0), Angle(0), SCALE, COLORS.LightsContainer, MATERIALS.LightsContainer, chip(), chip()) + + builder:build("Body__FrontLights__CloseLight", Vector(0), Angle(0), SCALE, COLORS.FrontLightsClose, MATERIALS.FrontLightsClose, chip(), chip()) + builder:build("Body__CloseLights__Glass", Vector(0), Angle(0), SCALE, COLORS.FrontLightsCloseGlass, MATERIALS.FrontLightsCloseGlass, chip(), chip()) + + builder:build("Body__FrontLights__FarLight", Vector(0), Angle(0), SCALE, COLORS.FrontLightsFar, MATERIALS.FrontLightsFar, chip(), chip()) + builder:build("Body__FarLights__Glass", Vector(0), Angle(0), SCALE, COLORS.FrontLightsFarGlass, MATERIALS.FrontLightsFarGlass, chip(), chip()) + + builder:build("Body__ReverseLights__ReverseLight", Vector(0), Angle(0), SCALE, COLORS.ReverseLights, MATERIALS.Lights, chip(), chip()) + + builder:build("Body__LeftBlinkers__Blinker", Vector(0), Angle(0), SCALE, COLORS.Blinkers, MATERIALS.Lights, chip(), chip()) + builder:build("Body__RightBlinkers__Blinker", Vector(0), Angle(0), SCALE, COLORS.Blinkers, MATERIALS.Lights, chip(), chip()) + + builder:build("Body__ParkingLights__ParkingLight", Vector(0), Angle(0), SCALE, COLORS.RearParkingLights, MATERIALS.Lights, chip(), chip()) + builder:build("FrontLights__ParkingLights__ParkingLights2", Vector(0), Angle(0), SCALE, COLORS.FrontParkingLights, MATERIALS.Lights, chip(), chip()) + + builder:build("Body__StopLights__StopLights", Vector(0), Angle(0), SCALE, COLORS.StopLights, MATERIALS.Lights, chip(), chip()) + + builder:build("Body__Hood__Exterior", Vector(0), Angle(0), SCALE, COLORS.Exterior, MATERIALS.Exterior, chip(), chip()) + + builder:build("Body__Trunk__Exterior", Vector(0), Angle(0), SCALE, COLORS.Exterior, MATERIALS.Exterior, chip(), chip()) + builder:build("Trunk__Strip__Chrome", Vector(0), Angle(0), SCALE, COLORS.Chrome, MATERIALS.Chrome, chip(), chip()) + builder:build("Trunk__Button__Chrome", Vector(0), Angle(0), SCALE, COLORS.Chrome, MATERIALS.Chrome, chip(), chip()) + + builder:build("Body__LeftFrontDoor__Exterior", Vector(0), Angle(0), SCALE, COLORS.Exterior, MATERIALS.Exterior, chip(), chip()) + builder:build("LeftFrontDoor__Frame__Chrome", Vector(0), Angle(0), SCALE, COLORS.Chrome, MATERIALS.Chrome, chip(), chip()) + builder:build("LeftFrontDoor__Glass__Glass", Vector(0), Angle(0), SCALE, COLORS.Glass, MATERIALS.Glass, chip(), chip()) + builder:build("LeftFrontDoor__Interior__DoorInterior", Vector(0), Angle(0), SCALE, COLORS.DoorInterior, MATERIALS.DoorInterior, chip(), chip()) + builder:build("LeftFrontDoor__Handle__Chrome", Vector(0), Angle(0), SCALE, COLORS.DoorHandle, MATERIALS.DoorHandle, chip(), chip()) + + builder:build("Body__RightFrontDoor__Exterior", Vector(0), Angle(0), SCALE, COLORS.Exterior, MATERIALS.Exterior, chip(), chip()) + builder:build("RightFrontDoor__Frame__Chrome", Vector(0), Angle(0), SCALE, COLORS.Chrome, MATERIALS.Chrome, chip(), chip()) + builder:build("RightFrontDoor__Glass__Glass", Vector(0), Angle(0), SCALE, COLORS.Glass, MATERIALS.Glass, chip(), chip()) + builder:build("RightFrontDoor__Interior__DoorInterior", Vector(0), Angle(0), SCALE, COLORS.DoorInterior, MATERIALS.DoorInterior, chip(), chip()) + builder:build("RightFrontDoor__Handle__Chrome", Vector(0), Angle(0), SCALE, COLORS.DoorHandle, MATERIALS.DoorHandle, chip(), chip()) + + builder:build("Body__LeftRearDoor__Exterior", Vector(0), Angle(0), SCALE, COLORS.Exterior, MATERIALS.Exterior, chip(), chip()) + builder:build("LeftRearDoor__Frame__Chrome", Vector(0), Angle(0), SCALE, COLORS.Chrome, MATERIALS.Chrome, chip(), chip()) + builder:build("LeftRearDoor__Glass__Glass", Vector(0), Angle(0), SCALE, COLORS.Glass, MATERIALS.Glass, chip(), chip()) + builder:build("LeftRearDoor__Interior__DoorInterior", Vector(0), Angle(0), SCALE, COLORS.DoorInterior, MATERIALS.DoorInterior, chip(), chip()) + builder:build("LeftRearDoor__Handle__Chrome", Vector(0), Angle(0), SCALE, COLORS.DoorHandle, MATERIALS.DoorHandle, chip(), chip()) + + builder:build("Body__RightRearDoor__Exterior", Vector(0), Angle(0), SCALE, COLORS.Exterior, MATERIALS.Exterior, chip(), chip()) + builder:build("RightRearDoor__Frame__Chrome", Vector(0), Angle(0), SCALE, COLORS.Chrome, MATERIALS.Chrome, chip(), chip()) + builder:build("RightRearDoor__Glass__Glass", Vector(0), Angle(0), SCALE, COLORS.Glass, MATERIALS.Glass, chip(), chip()) + builder:build("RightRearDoor__Interior__DoorInterior", Vector(0), Angle(0), SCALE, COLORS.DoorInterior, MATERIALS.DoorInterior, chip(), chip()) + builder:build("RightRearDoor__Handle__Chrome", Vector(0), Angle(0), SCALE, COLORS.DoorHandle, MATERIALS.DoorHandle, chip(), chip()) + + builder:getResult() +else + function init() + builder = MeshBuilder:new(LINK) + end + + if hasPermission("http.get") and hasPermission("mesh") and hasPermission("entities.setRenderProperty", chip()) then + init() + else + setupPermissionRequest({"http.get", "mesh", "entities.setRenderProperty"}, "", true) + + hook.add("permissionrequest", "_permissionrequest", function() + if permissionRequestSatisfied() then + init() + end + end) + end +end diff --git a/koptilnya/rpc.txt b/koptilnya/rpc.txt deleted file mode 100644 index a161c98..0000000 --- a/koptilnya/rpc.txt +++ /dev/null @@ -1,32 +0,0 @@ ---@name RPC ---@author Opti1337 ---@shared - -RPC = {} - -function RPC.add(name, cb) - net.receive(name, function() - local result = {} - - for i = 1, net.readInt(8) do - table.insert(result, net.readType()) - end - - if CLIENT then - cb(unpack(result)) - else - RPC.start(name, find.allPlayers(), unpack(result)) - end - end) -end - -function RPC.start(name, target, ...) - net.start(name) - local args = {...} - - net.writeInt(#args, 8) - for _, v in pairs(args) do - net.writeType(v) - end - net.send(target) -end \ No newline at end of file diff --git a/koptilnya/torque_editor.txt b/koptilnya/torque_editor.txt new file mode 100644 index 0000000..668f8cc --- /dev/null +++ b/koptilnya/torque_editor.txt @@ -0,0 +1,580 @@ +-- @name Torque editor +-- @author Opti1337 +-- @shared +-- @include /koptilnya/libs/render.txt +-- @include /koptilnya/gui/render_devices/hud.txt +-- @include /koptilnya/gui/gui.txt +-- @include /koptilnya/gui/elements/panel.txt +-- @include /koptilnya/gui/elements/label.txt +-- @include /koptilnya/gui/elements/shape.txt +-- @include /koptilnya/gui/elements/button.txt +-- @include /koptilnya/gui/segoe_mdl2_assets_icons.txt +local points = {Vector(0, 0)} +local zoom = 1 +local zoomBase = 100 +local scroll = 0 + +if SERVER then + local user + + wire.adjustPorts({Seat = "ENTITY"}, {}) + + local function setUser(ply) + user = ply + + net.start("setUser") + net.writeEntity(ply) + net.send() + end + + local function resetUser() + user = nil + + net.start("resetUser") + net.send() + end + + hook.add("ClientInitialized", "_ClientInitialized", function(ply) + net.start("init") + net.writeFloat(zoom) + net.writeFloat(scroll) + net.writeTable(points) + net.send(ply) + end) + + net.receive("settings", function(len, ply) + zoom = net.readFloat() + scroll = net.readFloat() + + net.start("settings") + net.writeFloat(zoom) + net.writeFloat(scroll) + net.send(find.allPlayers(function(p) + return p ~= ply + end)) + end) + + net.receive("points", function(len, ply) + points = net.readTable() + + net.start("points") + net.writeTable(points) + net.send(find.allPlayers(function(p) + return p ~= ply + end)) + end) + + hook.add("PlayerEnteredVehicle", "_PlayerEnteredVehicle", function(ply, veh) + if veh == wire.ports.Seat then + setUser(ply) + + enableHud(ply, true) + end + end) + + hook.add("PlayerLeaveVehicle", "_PlayerLeaveVehicle", function(ply, veh) + if veh == wire.ports.Seat then + resetUser() + + enableHud(ply, false) + end + end) + + return +end + +require("/koptilnya/libs/render.txt") +require("/koptilnya/gui/render_devices/hud.txt") +require("/koptilnya/gui/gui.txt") +require("/koptilnya/gui/elements/panel.txt") +require("/koptilnya/gui/elements/label.txt") +require("/koptilnya/gui/elements/shape.txt") +require("/koptilnya/gui/elements/button.txt") + +local segoeIcons = require("/koptilnya/gui/segoe_mdl2_assets_icons.txt") + +local labelsFont = render.createFont("Roboto", 16, 400, true) +local numbersFont = render.createFont("Roboto Mono", 20) +local scr = {w = 682, h = 512} +local padding = 61 +local workspace = {x = padding, y = 0, w = scr.w - padding, h = scr.h - padding} +local gridSize = Vector(100, 1) +local zoomSteps = {0.05, 0.1, 0.25, 0.5, 1, 2, 4} + +------------------------------------------------------- + +setupPermissionRequest({"file.write", "file.read", "input"}, "", false) + +local cellSize = Vector((workspace.w - 1) / gridSize.x, workspace.h / gridSize.y) + +local crosshair +local user + +local function sendSettings() + net.start("settings") + net.writeFloat(zoom) + net.writeFloat(scroll) + net.send() +end + +local function sendPoints() + net.start("points") + net.writeTable(points) + net.send() +end + +local function cursorIntersectWorkspace(x, y) + x = x >= workspace.x and x < workspace.x + workspace.w + y = y >= workspace.y and y <= workspace.y + workspace.h + + return x and y +end + +local function fromWorkspacePos(x, y) + return workspace.x + x, workspace.y + workspace.h - 1 - y +end + +local function toWorkspacePos(x, y) + return x - workspace.x, workspace.y + workspace.h - 1 - y +end + +local function getNearestGridPoint(x, y) + x, y = toWorkspacePos(x, y) + + x = math.clamp(x, 0, workspace.w - 1) + y = math.clamp(y, 0, workspace.h - 1) + + x = math.round(x / cellSize.x) * cellSize.x + y = math.round(y / cellSize.y) * cellSize.y + + x, y = fromWorkspacePos(x, y) + + return x, y +end + +local function zoomIn() + local zoomId = table.keyFromValue(zoomSteps, zoom) + + local nextZoom + if zoomId < #zoomSteps then + nextZoom = zoomSteps[zoomId + 1] + zoom = nextZoom + + sendSettings() + end + + return nextZoom +end + +local function zoomOut() + local zoomId = table.keyFromValue(zoomSteps, zoom) + + local prevZoom + if zoomId > 1 then + prevZoom = zoomSteps[zoomId - 1] + zoom = prevZoom + + sendSettings() + end + + return prevZoom +end + +local function scrollUp() + scroll = scroll + 1 + + sendSettings() +end + +local function scrollDown() + scroll = math.max(scroll - 1, 0) + + sendSettings() +end + +local function addPoint() + if crosshair ~= nil then + local x, y = toWorkspacePos(crosshair.x, crosshair.y) + + x = math.round(x / cellSize.x) + y = y / (workspace.h - 1) * (zoomBase / zoom) + (zoomBase / zoom / 10 * scroll) + + --- GOVNO ---------------------------- + + local replaceId + for i, point in ipairs(points) do + if point.x == x then + replaceId = i + + break + end + end + + if replaceId ~= nil then + points[replaceId] = Vector(x, y) + else + table.insert(points, Vector(x, y)) + end + + table.sortByMember(points, "x", true) + + sendPoints() + + --- KONEC GOVNA ---------------------- + end +end + +local function removePoint() + if crosshair ~= nil then + local x, y = toWorkspacePos(crosshair.x, crosshair.y) + + x = math.round(x / cellSize.x) + y = y / (workspace.h - 1) * (zoomBase / zoom) + (zoomBase / zoom / 10 * scroll) + + --- GOVNO ---------------------------- + + local replaceId + for i, point in ipairs(points) do + if point.x == x then + replaceId = i + + break + end + end + + if replaceId ~= nil then + table.remove(points, replaceId) + end + + table.sortByMember(points, "x", true) + + sendPoints() + + --- KONEC GOVNA ---------------------- + end +end + +local function getTorqueAt(t) + if #points == 0 then + return 0 + end + + if t == 0 then + return points[1].y + elseif t == 100 then + return points[#points].y + else + local segment + + local prevPoint + for k, point in pairs(points) do + if t <= point.x then + segment = {prevPoint, point} + + break + end + + prevPoint = point + end + + return math.lerp((t - segment[1].x) / (segment[2].x - segment[1].x), segment[1].y, segment[2].y) + end +end + +local function exportPoints() + if not hasPermission("file.write") then + return + end + + local result = "" + + for k, v in pairs(points) do + result = result .. "\tVector(" .. (v.x / 100) .. ", " .. v.y .. ")" + + if k ~= #points then + result = result .. ",\n" + end + end + + result = "array(\n" .. result + result = result .. "\n)" + + file.write("torque_export_result.txt", result) +end + +local function exportTorqueMap() + if not hasPermission("file.write") then + return + end + + local result = "" + + for i = 0, 100 do + result = result .. "\t" .. getTorqueAt(i) + + if i ~= 100 then + result = result .. ",\n" + end + end + + result = "array(\n" .. result + result = result .. "\n)" + + file.write("torque_export_result.txt", result) +end + +net.receive("setUser", function() + net.readEntity(function(ent) + user = ent + end) +end) + +net.receive("resetUser", function() + user = nil +end) + +net.receive("init", function() + zoom = net.readFloat() + scroll = net.readFloat() + points = net.readTable() +end) + +net.receive("settings", function() + zoom = net.readFloat() + scroll = net.readFloat() +end) + +net.receive("points", function() + points = net.readTable() +end) + +hook.add("hudconnected", "_hudconnected", function() + -- renderDevice:setPlayer() + if not hasPermission("file.write") or not hasPermission("file.read") then + sendPermissionRequest() + end +end) + +hook.add("huddisconnected", "_huddisconnected", function() +end) + +hook.add("inputPressed", "_inputPressed", function(button) + if not hasPermission("input") then + return + end + + if player() == user then + local keyName = input.getKeyName(button) + + if keyName == "t" then + input.enableCursor(input.getCursorVisible()) + elseif keyName == "MOUSE1" then + if not input.getCursorVisible() then + addPoint() + end + elseif keyName == "MOUSE2" then + if not input.getCursorVisible() then + removePoint() + end + elseif keyName == "MWHEELUP" then + if input.isShiftDown() then + zoomIn() + else + scrollUp() + end + elseif keyName == "MWHEELDOWN" then + if input.isShiftDown() then + zoomOut() + else + scrollDown() + end + end + end +end) + +hook.add("render", "_render", function() + local cursorX, cursorY + + if isValid(user) then + cursorX, cursorY = render.cursorPos(user) + end + + local x, y + + --- Background + x, y = fromWorkspacePos(0, workspace.h - 1) + + render.setColor(Color(15, 15, 15)) + render.drawRectFast(x, y, workspace.w, workspace.h) + + render.setColor(Color(40, 40, 40)) + render.setFont(labelsFont) + + --- Throttle axis label + x, y = fromWorkspacePos(30, 31) + + render.drawRectFast(x, y, 20, 1) + render.drawSimpleText(x + 22, y - 8, "RPM") + + --- Torque axis label + x, y = fromWorkspacePos(30, 50) + + render.drawRectFast(x, y, 1, 20) + render.drawRotatedSimpleText(x - 8, y - 2, "Torque", -90) + + render.setColor(Color(255, 255, 255)) + + --- Throttle axis + x, y = fromWorkspacePos(0, 0) + + render.drawRectFast(x, y, workspace.w, 1) + + --- Torque axis + x, y = fromWorkspacePos(0, workspace.h - 1) + + render.drawRectFast(x, y, 1, workspace.h) + + --- Axes lines & numbers + for i = 1, 10 do + + --- Throttle axis + local segmentSize = (workspace.w - 1) / 10 + + x, y = fromWorkspacePos(segmentSize * i, 0) + + local length = 20 + local text = tostring(math.remap(i, 0, 10, 1000, 6000)) -- tostring(i * 10) + + render.drawRect(x, y - 20, 1, 20) + render.drawRect(x - segmentSize / 2, y - 10, 1, 10) + + render.setFont(numbersFont) + render.drawSimpleText(x - (9 * #text), y, text) + + --- Torque axis + segmentSize = (workspace.h - 1) / 10 + x, y = fromWorkspacePos(0, segmentSize * i) + text = tostring(zoomBase / zoom / 10 * (i + scroll)) + + render.drawRect(x, y, 20, 1) + render.drawRect(x, y + segmentSize / 2, 10, 1) + + render.setFont(numbersFont) + render.drawSimpleText(x - (10 * #text), y - 2, text) + end + + --- Zero + x, y = fromWorkspacePos(-40, 0) + + render.setFont(numbersFont) + render.drawSimpleText(x, y, "1000") + + if cursorX ~= nil and cursorIntersectWorkspace(cursorX, cursorY) then + x, y = fromWorkspacePos(0, workspace.h - 1) + cursorX = getNearestGridPoint(cursorX, cursorY) + cursorY = math.clamp(cursorY, workspace.y, workspace.y + workspace.h - 1) + + crosshair = {x = cursorX, y = cursorY} + + render.setColor(Color(60, 60, 60, 200)) + render.drawRect(x, cursorY, workspace.w, 1) + render.drawRect(cursorX, y, 1, workspace.h) + else + crosshair = nil + end + + render.setColor(Color(255, 150, 50)) + + local prevPointData + for _, point in pairs(points) do + x, y = fromWorkspacePos(cellSize.x * point.x, (workspace.h - 1) / (zoomBase / zoom) * point.y - ((workspace.h - 1) / 10 * scroll)) + + if prevPointData ~= nil then + render.drawLine(prevPointData.x, prevPointData.y, x, y) + end + + render.drawRect(x - 1, y - 1, 3, 3) + + prevPointData = {point = point, x = x, y = y} + end + --[[ + local t = (math.cos(timer.curtime() * 0.5) + 1) / 2 * 100 + + x, y = fromWorkspacePos(cellSize.x * t, (workspace.h - 1) / (zoomBase / zoom) * getTorqueAt(t) - ((workspace.h - 1) / 10 * scroll)) + + render.setColor(Color(0, 0, 255, 180)) + render.drawRect(x - 3, y - 3, 7, 7) + + render.drawRect(x, workspace.y, 1, workspace.h) + ]] +end) + +local renderDevice = RenderDeviceHUD:new() +local scrW, scrH = 1920, 1080 + +local gui = GUI:new(renderDevice) + +local panel = EPanel:new() +panel:setTitle("Torque Editor") +panel:setDraggable(false) +panel:setMinimizable(false) +panel:setCloseable(false) +panel:setPos(scrW - 180 - 20, scrH - 226 - 20) +panel:setSize(180, 226) +gui:add(panel) + +local importButton = EButton:new() +importButton:setPos(11, 43) +importButton:setSize(158, 24) +importButton:setText("Import") +importButton.onMousePressed = function(_, x, y, key, keyName) + if keyName == "MOUSE1" then + end +end +panel:addChild(importButton) + +local dividerShape = EShape:new() +dividerShape:setPos(11, 82) +dividerShape:setSize(158, 1) +dividerShape:setColor(Color(60, 60, 60)) +panel:addChild(dividerShape) + +local exportLabel = ELabel:new() +exportLabel:setPos(11, 97) +exportLabel:setText("Export as") +panel:addChild(exportLabel) + +--[[ +local exportCurveButton = EButton:new() +exportCurveButton:setPos(11, 123) +exportCurveButton:setText("Points array") +exportCurveButton:setSize(158, 24) +exportCurveButton.onMousePressed = function(_, x, y, key, keyName) + if keyName == "MOUSE1" then + exportPoints() + end +end +panel:addChild(exportCurveButton) +]] + +local pointsArrayLabel = ELabel:new() +pointsArrayLabel:setPos(11, 123) +pointsArrayLabel:setText("Points array") +pointsArrayLabel:setColorScheme(Color(200, 200, 200)) +panel:addChild(pointsArrayLabel) + +local exportMapButton = EButton:new() +exportMapButton:setPos(11, 157) +exportMapButton:setText("Torque map") +exportMapButton:setSize(158, 24) +exportMapButton.onMousePressed = function(_, x, y, key, keyName) + if keyName == "MOUSE1" then + exportTorqueMap() + end +end +panel:addChild(exportMapButton) + +local pointsCountLabel = ELabel:new() +pointsCountLabel:setPos(11, 200) +pointsCountLabel:setText("Points count: " .. #points) +panel:addChild(pointsCountLabel)