Skip to content

Commit c9daaf8

Browse files
authored
Merge pull request #3 from GoatG33k/master
v1.5.0 - Performance improvements & rewrite
2 parents 585708b + d31d5d3 commit c9daaf8

File tree

9 files changed

+320
-259
lines changed

9 files changed

+320
-259
lines changed

README.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Nearest Postals
22

3-
This script displays a nearest postal next to where PLD would go and also has a command to draw a route to a specific postal
3+
This script displays the nearest postal next to map, and allows you to navigate to specific postal codes with `/postal`
44

55
## Installation
66

@@ -23,6 +23,15 @@ It will automatically remove the route when within 100m of the destination
2323

2424
## Updates
2525

26+
### 1.5
27+
28+
- Major performance improvements
29+
- Added the `refreshRate` configuration option
30+
- Simplified distance calculation logic
31+
- Separated code into separate files
32+
- Prebuild the postal list with vectors at startup
33+
- Use FiveM Lua 5.4
34+
2635
### 1.4
2736

2837
- Performance Improvements
@@ -58,8 +67,8 @@ It will automatically remove the route when within 100m of the destination
5867

5968
This script provides a simple way of working on a new postal map
6069

61-
1. In the script, enabled the local variable `dev` near the bottom
62-
2. Restart the script into game
70+
1. In the resource `fxmanifest.lua` file, uncomment the `cl_dev.lua` requirement line
71+
2. Do `refresh` and `restart nearest-postal` in-game
6372
3. Teleport to the first postal code in numerical order
6473
4. Type `/setnext [postalCode]` where postalCode is the postal that you are at
6574
5. Type `/next` to insert it

cl.lua

Lines changed: 22 additions & 200 deletions
Original file line numberDiff line numberDiff line change
@@ -1,200 +1,22 @@
1-
local raw = LoadResourceFile(GetCurrentResourceName(), GetResourceMetadata(GetCurrentResourceName(), 'postal_file'))
2-
local postals = json.decode(raw)
3-
4-
local nearest = nil
5-
local pBlip = nil
6-
7-
-- thread for nearest and blip
8-
Citizen.CreateThread(
9-
function()
10-
while true do
11-
local x, y = table.unpack(GetEntityCoords(GetPlayerPed(-1)))
12-
13-
local ndm = -1 -- nearest distance magnitude
14-
local ni = -1 -- nearest index
15-
for i, p in ipairs(postals) do
16-
local dm = (x - p.x) ^ 2 + (y - p.y) ^ 2 -- distance magnitude
17-
if ndm == -1 or dm < ndm then
18-
ni = i
19-
ndm = dm
20-
end
21-
end
22-
23-
--setting the nearest
24-
if ni ~= -1 then
25-
local nd = math.sqrt(ndm) -- nearest distance
26-
nearest = {i = ni, d = nd}
27-
end
28-
29-
-- if blip exists
30-
if pBlip then
31-
local b = {x = pBlip.p.x, y = pBlip.p.y} -- blip coords
32-
local dm = (b.x - x) ^ 2 + (b.y - y) ^ 2 -- distance magnitude
33-
if dm < config.blip.distToDelete ^ 2 then
34-
-- delete blip if close
35-
RemoveBlip(pBlip.hndl)
36-
pBlip = nil
37-
end
38-
end
39-
40-
Wait(100)
41-
end
42-
end
43-
)
44-
-- text display thread
45-
Citizen.CreateThread(
46-
function()
47-
while true do
48-
if nearest and not IsHudHidden() then
49-
local text = config.text.format:format(postals[nearest.i].code, nearest.d)
50-
SetTextScale(0.42, 0.42)
51-
SetTextFont(4)
52-
SetTextOutline()
53-
BeginTextCommandDisplayText('STRING')
54-
AddTextComponentSubstringPlayerName(text)
55-
EndTextCommandDisplayText(config.text.posX, config.text.posY)
56-
end
57-
Wait(0)
58-
end
59-
end
60-
)
61-
62-
RegisterCommand(
63-
'postal',
64-
function(source, args, raw)
65-
if #args < 1 then
66-
if pBlip then
67-
RemoveBlip(pBlip.hndl)
68-
pBlip = nil
69-
TriggerEvent(
70-
'chat:addMessage',
71-
{
72-
color = {255, 0, 0},
73-
args = {
74-
'Postals',
75-
config.blip.deleteText
76-
}
77-
}
78-
)
79-
end
80-
return
81-
end
82-
local n = string.upper(args[1])
83-
84-
local fp = nil
85-
for _, p in ipairs(postals) do
86-
if string.upper(p.code) == n then
87-
fp = p
88-
end
89-
end
90-
91-
if fp then
92-
if pBlip then
93-
RemoveBlip(pBlip.hndl)
94-
end
95-
pBlip = {hndl = AddBlipForCoord(fp.x, fp.y, 0.0), p = fp}
96-
SetBlipRoute(pBlip.hndl, true)
97-
SetBlipSprite(pBlip.hndl, config.blip.sprite)
98-
SetBlipColour(pBlip.hndl, config.blip.color)
99-
SetBlipRouteColour(pBlip.hndl, config.blip.color)
100-
BeginTextCommandSetBlipName('STRING')
101-
AddTextComponentSubstringPlayerName(config.blip.blipText:format(pBlip.p.code))
102-
EndTextCommandSetBlipName(pBlip.hndl)
103-
104-
TriggerEvent(
105-
'chat:addMessage',
106-
{
107-
color = {255, 0, 0},
108-
args = {
109-
'Postals',
110-
config.blip.drawRouteText:format(fp.code)
111-
}
112-
}
113-
)
114-
else
115-
TriggerEvent(
116-
'chat:addMessage',
117-
{
118-
color = {255, 0, 0},
119-
args = {
120-
'Postals',
121-
config.blip.notExistText
122-
}
123-
}
124-
)
125-
end
126-
end
127-
)
128-
129-
--[[Development shit]]
130-
local dev = false
131-
if dev then
132-
local devLocal = json.decode(raw)
133-
local next = 0
134-
135-
RegisterCommand(
136-
'setnext',
137-
function(src, args, raw)
138-
local n = tonumber(args[1])
139-
if n ~= nil then
140-
next = n
141-
print('next ' .. next)
142-
return
143-
end
144-
print('invalid ' .. n)
145-
end
146-
)
147-
RegisterCommand(
148-
'next',
149-
function(src, args, raw)
150-
for i, d in ipairs(devLocal) do
151-
if d.code == tostring(next) then
152-
print('duplicate ' .. next)
153-
return
154-
end
155-
end
156-
local coords = GetEntityCoords(GetPlayerPed(-1))
157-
table.insert(devLocal, {code = tostring(next), x = coords.x, y = coords.y})
158-
print('insert ' .. next)
159-
next = next + 1
160-
end
161-
)
162-
RegisterCommand(
163-
'rl',
164-
function(src, args, raw)
165-
if #devLocal > 0 then
166-
local data = table.remove(devLocal, #devLocal)
167-
print('remove ' .. data.code)
168-
print('next ' .. next)
169-
next = next - 1
170-
else
171-
print('invalid')
172-
end
173-
end
174-
)
175-
RegisterCommand(
176-
'remove',
177-
function(src, args, raw)
178-
if #args < 1 then
179-
print('invalid')
180-
else
181-
for i, d in ipairs(devLocal) do
182-
if d.code == args[1] then
183-
table.remove(devLocal, i)
184-
print('remove ' .. d.code)
185-
return
186-
end
187-
end
188-
print('invalid')
189-
end
190-
end
191-
)
192-
RegisterCommand(
193-
'json',
194-
function(src, args, raw)
195-
print(json.encode(devLocal))
196-
end
197-
)
198-
end
199-
200-
exports('getPostal', function() if nearest ~= nil then return postals[nearest.i].code else return nil end end)
1+
---@class PostalData : table<number, vec>
2+
---@field code string
3+
---@type table<number, PostalData>
4+
postals = nil
5+
CreateThread(function()
6+
postals = LoadResourceFile(GetCurrentResourceName(), GetResourceMetadata(GetCurrentResourceName(), 'postal_file'))
7+
postals = json.decode(postals)
8+
for i, postal in ipairs(postals) do postals[i] = { vec(postal.x, postal.y), code = postal.code } end
9+
end)
10+
11+
---@class NearestResult
12+
---@field code string
13+
---@field dist number
14+
nearest = nil
15+
16+
---@class PostalBlip
17+
---@field 1 vec
18+
---@field p PostalData
19+
---@field hndl number
20+
pBlip = nil
21+
22+
exports('getPostal', function() return nearest and nearest.code or nil end)

cl_commands.lua

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
-- optimizations
2+
local ipairs = ipairs
3+
local upper = string.upper
4+
local format = string.format
5+
-- end optimizations
6+
7+
---
8+
--- [[ Nearest Postal Commands ]] ---
9+
---
10+
11+
TriggerEvent('chat:addSuggestion', '/postal', 'Set the GPS to a specific postal',
12+
{ { name = 'Postal Code', help = 'The postal code you would like to go to' } })
13+
14+
RegisterCommand('postal', function(_, args)
15+
if #args < 1 then
16+
if pBlip then
17+
RemoveBlip(pBlip.hndl)
18+
pBlip = nil
19+
TriggerEvent('chat:addMessage', {
20+
color = { 255, 0, 0 },
21+
args = {
22+
'Postals',
23+
config.blip.deleteText
24+
}
25+
})
26+
end
27+
return
28+
end
29+
30+
local userPostal = upper(args[1])
31+
local foundPostal
32+
33+
for _, p in ipairs(postals) do
34+
if upper(p.code) == userPostal then
35+
foundPostal = p
36+
break
37+
end
38+
end
39+
40+
if foundPostal then
41+
if pBlip then RemoveBlip(pBlip.hndl) end
42+
local blip = AddBlipForCoord(foundPostal[1][1], foundPostal[1][2], 0.0)
43+
pBlip = { hndl = blip, p = foundPostal }
44+
SetBlipRoute(blip, true)
45+
SetBlipSprite(blip, config.blip.sprite)
46+
SetBlipColour(blip, config.blip.color)
47+
SetBlipRouteColour(blip, config.blip.color)
48+
BeginTextCommandSetBlipName('STRING')
49+
AddTextComponentSubstringPlayerName(format(config.blip.blipText, pBlip.p.code))
50+
EndTextCommandSetBlipName(blip)
51+
52+
TriggerEvent('chat:addMessage', {
53+
color = { 255, 0, 0 },
54+
args = {
55+
'Postals',
56+
format(config.blip.drawRouteText, foundPostal.code)
57+
}
58+
})
59+
else
60+
TriggerEvent('chat:addMessage', {
61+
color = { 255, 0, 0 },
62+
args = {
63+
'Postals',
64+
config.blip.notExistText
65+
}
66+
})
67+
end
68+
end)
69+

cl_dev.lua

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
--- [[ Development shit ]]
2+
3+
local devLocal = json.decode(raw)
4+
local next = 0
5+
6+
RegisterCommand('setnext', function(_, args)
7+
local n = tonumber(args[1])
8+
if n ~= nil then
9+
next = n
10+
print('next ' .. next)
11+
return
12+
end
13+
print('invalid ' .. n)
14+
end)
15+
16+
RegisterCommand('next', function()
17+
for _, d in ipairs(devLocal) do
18+
if d.code == tostring(next) then
19+
print('duplicate ' .. next)
20+
return
21+
end
22+
end
23+
local coords = GetEntityCoords(PlayerPedId())
24+
insert(devLocal, { code = tostring(next), x = coords.x, y = coords.y })
25+
print('insert ' .. next)
26+
next = next + 1
27+
end)
28+
29+
RegisterCommand('rl', function()
30+
if #devLocal > 0 then
31+
local data = remove(devLocal, #devLocal)
32+
print('remove ' .. data.code)
33+
print('next ' .. next)
34+
next = next - 1
35+
else
36+
print('invalid')
37+
end
38+
end)
39+
40+
RegisterCommand('remove', function(_, args)
41+
if #args < 1 then
42+
print('invalid')
43+
else
44+
for i, d in ipairs(devLocal) do
45+
if d.code == args[1] then
46+
table.remove(devLocal, i)
47+
print('remove ' .. d.code)
48+
return
49+
end
50+
end
51+
print('invalid')
52+
end
53+
end)
54+
55+
RegisterCommand('json', function()
56+
print(json.encode(devLocal))
57+
end)

0 commit comments

Comments
 (0)