commit cf5c5cd61e1947df38311dbe9f0634e6b1f7a178
Author: delucecc <31872986+delucecc@users.noreply.github.com>
Date:   Fri May 19 16:51:10 2023 -0700

    init

diff --git a/client/client.lua b/client/client.lua
new file mode 100644
index 0000000..e0cd66b
--- /dev/null
+++ b/client/client.lua
@@ -0,0 +1,123 @@
+local isDrawingLine = false
+
+function ToggleDrawLine()
+    isDrawingLine = not isDrawingLine
+    if isDrawingLine then
+        TriggerEvent('chat:addMessage', {
+            color = { 255, 255, 0 },
+            multiline = true,
+            args = { 'ngd-LineCoords', 'Line On' }
+        })
+    else
+        TriggerEvent('chat:addMessage', {
+            color = { 255, 255, 0 },
+            multiline = true,
+            args = { 'ngd-LineCoords', 'Line Off' }
+        })
+    end
+end
+
+Citizen.CreateThread(function()
+    while true do
+        Citizen.Wait(0)
+        if isDrawingLine then
+            local playerPed = PlayerPedId()
+            local playerCoords = GetEntityCoords(playerPed)
+            local playerHeading = GetEntityHeading(playerPed)
+            local cameraRotation = GetGameplayCamRot(2)
+            local camPitch = math.rad(cameraRotation.x)
+            local camYaw = math.rad(cameraRotation.y)
+            local lineLength = Config.LineLength
+            local forwardVector = vector3(
+                math.sin(-playerHeading * math.pi / 180.0) * math.cos(camPitch),
+                math.cos(-playerHeading * math.pi / 180.0) * math.cos(camPitch),
+                math.sin(camPitch)
+            )
+            local lineEnd = playerCoords + forwardVector * lineLength
+            local rayHandle = StartShapeTestRay(playerCoords.x, playerCoords.y, playerCoords.z, lineEnd.x, lineEnd.y,
+                lineEnd.z, 7, playerPed, 0)
+            local _, hit, hitCoords, _, _ = GetShapeTestResult(rayHandle)
+            DrawLine(playerCoords.x, playerCoords.y, playerCoords.z, lineEnd.x, lineEnd.y, lineEnd.z, 255, 0, 0, 255)
+            if hit then
+                local roundedCoords = {
+                    x = string.format("%.2f", hitCoords.x),
+                    y = string.format("%.2f", hitCoords.y),
+                    z = string.format("%.2f", hitCoords.z)
+                }
+                local heading = playerHeading + 180.0
+                if heading > 360.0 then
+                    heading = heading - 360.0
+                end
+                DrawText3D(hitCoords.x, hitCoords.y, hitCoords.z + 1.0,
+                    string.format('~r~Collision~n~X: %.2f Y: %.2f Z: %.2f~n~Heading: %.2f', hitCoords.x, hitCoords.y,
+                        hitCoords.z, heading))
+            end
+        end
+    end
+end)
+
+function DrawText3D(x, y, z, text)
+    local onScreen, _x, _y = World3dToScreen2d(x, y, z)
+    if onScreen then
+        SetTextScale(0.35, 0.35)
+        SetTextFont(4)
+        SetTextProportional(1)
+        SetTextColour(255, 255, 255, 255)
+        SetTextDropshadow(0, 0, 0, 0, 255)
+        SetTextEdge(2, 0, 0, 0, 150)
+        SetTextDropShadow()
+        SetTextOutline()
+        SetTextEntry("STRING")
+        SetTextCentre(1)
+        AddTextComponentString(text)
+        DrawText(_x, _y)
+    end
+end
+
+RegisterCommand(Config.TDrawLine, function()
+    ToggleDrawLine()
+end)
+
+RegisterCommand(Config.CopyCoord, function()
+    if isDrawingLine then
+        local playerPed = PlayerPedId()
+        local playerCoords = GetEntityCoords(playerPed)
+        local playerHeading = GetEntityHeading(playerPed)
+        local cameraRotation = GetGameplayCamRot(2)
+        local camPitch = math.rad(cameraRotation.x)
+        local camYaw = math.rad(cameraRotation.y)
+        local lineLength = 10.0
+        local forwardVector = vector3(
+            math.sin(-playerHeading * math.pi / 180.0) * math.cos(camPitch),
+            math.cos(-playerHeading * math.pi / 180.0) * math.cos(camPitch),
+            math.sin(camPitch)
+        )
+        local lineEnd = playerCoords + forwardVector * lineLength
+        local rayHandle = StartShapeTestRay(playerCoords.x, playerCoords.y, playerCoords.z, lineEnd.x, lineEnd.y,
+            lineEnd.z, 7, playerPed, 0)
+        local _, hit, hitCoords, _, _ = GetShapeTestResult(rayHandle)
+        if hit then
+            local coords = {
+                x = hitCoords.x,
+                y = hitCoords.y,
+                z = hitCoords.z
+            }
+            local heading = playerHeading + 180.0
+            if heading > 360.0 then
+                heading = heading - 360.0
+            end
+            local data = string.format('vec4(%.2f, %.2f, %.2f, %.2f)', coords.x, coords.y, coords.z, heading)
+            TriggerEvent('chat:addMessage', {
+                args = { '^3Copied to clipboard: ' .. data }
+            })
+            SendNUIMessage({
+                type = 'clipboard',
+                data = data
+            })
+        end
+    else
+        TriggerEvent('chat:addMessage', {
+            args = { '^1DrawLine is not enabled!' }
+        })
+    end
+end)
diff --git a/config.lua b/config.lua
new file mode 100644
index 0000000..005fb1e
--- /dev/null
+++ b/config.lua
@@ -0,0 +1,5 @@
+Config = {}
+
+Config.LineLength = 35   --Line length
+Config.TDrawLine = 'tdl' --Command to toggle line
+Config.CopyCoord = 'cc'  --Command to copy coords to clipboard
diff --git a/fxmanifest.lua b/fxmanifest.lua
new file mode 100644
index 0000000..a862ca8
--- /dev/null
+++ b/fxmanifest.lua
@@ -0,0 +1,20 @@
+Description 'ngd-linecoords | Nemesis Gaming Development'
+author 'deluce#9077'
+fx_version 'cerulean'
+game 'gta5'
+
+shared_scripts {
+    "config.lua",
+}
+
+client_scripts {
+    'client/*.lua',
+  }
+
+ui_page 'index.html'
+
+files {
+    '*.*'
+}
+
+lua54 'yes'
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..8202cd4
--- /dev/null
+++ b/index.html
@@ -0,0 +1 @@
+<script src="script.js"></script>
\ No newline at end of file
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..403c63e
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,12 @@
+# ngd-linecoords
+
+![ngd-linecoords](https://media.discordapp.net/attachments/1077462714902917171/1077462755902247034/Large-Banner.png)
+
+
+**ngd-linecoords** is a simple developer tool that uses drawline and raycasting.  This allows you to get the coords of a collision and then copy them to your clipboard with a command.
+
+This is useful for setting props, zones, peds, whatever else that you don't want to have to try and noclip in and out of to get the correct location.
+
+www.nemesisgd.com
+
+https://discord.gg/AnXx2GVGcM
diff --git a/script.js b/script.js
new file mode 100644
index 0000000..42b4b17
--- /dev/null
+++ b/script.js
@@ -0,0 +1,14 @@
+const copyToClipboard = str => {
+    const el = document.createElement('textarea');
+    el.value = str;
+    document.body.appendChild(el);
+    el.select();
+    document.execCommand('copy');
+    document.body.removeChild(el);
+ };
+
+window.addEventListener('message', (event) => {
+    if (event.data.type === 'clipboard') {
+        copyToClipboard(event.data.data);
+    }
+});