67 Commits

Author SHA1 Message Date
Andyyy7666
d3278e9be1 feat: add more key types to getting all players 2025-09-08 19:15:01 +02:00
Andyyy7666
24229485d9 feat: creataiped callback on ped creation 2025-09-08 19:14:47 +02:00
Andyyy7666
4f9d274c62 feat: function to avoid saving last location on specifc locations 2025-09-08 19:12:43 +02:00
Andyyy7666
73f38c12f6 feat: validate character data upon creation 2025-09-08 19:12:15 +02:00
Andyyy7666
0b39a8c039 feat: customgroup data for setjob function 2025-09-05 04:22:34 +02:00
Andyyy7666
568185ca19 fix(client/peds): models being nil error 2025-08-19 19:58:24 +02:00
Andyyy7666
bc41788cc9 feat(client/peds): disable collision between models 2025-08-18 23:24:00 +02:00
Andyyy7666
8a3502e515 feat: locale for many languages 2025-08-14 18:06:45 +02:00
Andyyy7666
a431a49d8c feat: locales 2025-08-14 01:13:48 +02:00
Andyyy7666
0bd76ed79f fix: ai ped blips showWhenNear hide on spawn 2025-08-13 18:17:44 +02:00
Andyyy7666
3f20d0f918 feat: plate pattern 2025-08-13 16:57:35 +02:00
Andy
31bf86a826 Merge pull request #86 from realneonium/patch-1
fix: missing return
2025-08-13 15:49:28 +02:00
neonium
9bd42fb26e fix: missing return 2025-04-16 22:34:51 -10:00
Andy
085bb71dcc Merge pull request #85 from realneonium/main
feat: add version checking
2025-03-11 00:27:39 +01:00
neonium
35d8d887c8 add version checking 2025-02-22 23:37:30 -10:00
Andy
544ad64779 Update fxmanifest.lua 2025-02-22 23:31:12 +01:00
Andy
43f690e356 Merge pull request #84 from ND-Framework/fix/duplicate-licenses
fix: duplicate character licenses
2025-02-22 23:29:46 +01:00
Andyyy7666
e883c4e64f fix: duplicate character licenses 2025-02-22 23:29:29 +01:00
Andy
5928d89edf Merge pull request #83 from NikartikTheBear/patch-1
fix(fxmanifest typo)
2025-02-16 02:20:21 +01:00
nikartik
9b846dc07e fix(typo) 2025-02-14 22:39:10 +01:00
Andyyy7666
baac4c75dd refactor(server/main): wait for oxmysql 2025-02-05 21:22:26 +01:00
Andyyy7666
fb708cc7e7 Update commands.lua 2025-01-19 18:08:20 +01:00
Andy
1547d310eb Merge pull request #81 from ND-Framework/feat/claim-veh-command
feat(server/comands): claim veh command
2025-01-18 14:41:58 +01:00
Andyyy7666
9d4708f6d9 feat(server/comands): claim veh command 2025-01-18 14:41:41 +01:00
Andy
a7713804f0 Merge pull request #80 from ND-Framework/fix/dv-command-inconsistency
fix(server/commands): dv command inconsistency
2025-01-18 14:40:37 +01:00
Andyyy7666
a9785ce754 fix(server/commands): dv command inconsistency 2025-01-18 14:40:01 +01:00
Andy
fe922e1b98 Merge pull request #79 from ND-Framework/fix/unlock-command-inconsistency
fix(server/commands): unlock command inconsistency
2025-01-18 14:38:42 +01:00
Andyyy7666
b97f42bb0a fix(server/commands): unlock command inconsistency 2025-01-18 14:38:13 +01:00
Andy
d132c12025 Merge pull request #78 from ND-Framework/feat/replace-armor
feat(client): replace armor on revive
2025-01-17 21:13:03 +01:00
Andyyy7666
119b0034bf feat(client): replace armor on revive
When reviving player to heal, replace the armor with the previous amount.
2025-01-17 21:12:43 +01:00
Andyyy7666
622b6fa8b0 tweak: add oxlib as dependency 2025-01-17 20:58:48 +01:00
Andyyy7666
2e6dfa9e5f Update fxmanifest.lua 2025-01-17 20:56:23 +01:00
Andy
4c4166de94 Merge pull request #77 from ND-Framework/feat/lan-identifier
feat(server): lan identifer
2025-01-17 20:53:12 +01:00
Andyyy7666
dea7ac6c8f feat(server): lan identifer
Create fake identifier when using sv_lan
2025-01-17 20:52:28 +01:00
Andy
120d924cae Merge pull request #76 from ND-Framework/tweak/lockpick-tries-convar
tweak(client/vehicle): lockpick tries convar
2025-01-17 20:42:59 +01:00
Andyyy7666
2a263a6c2e tweak(client/vehicle): lockpick tries convar 2025-01-17 20:42:27 +01:00
Andy
4ff4f487a1 Merge pull request #75 from ND-Framework/feat/garage-locations
feat: more default garage locations
2025-01-17 20:36:38 +01:00
Andyyy7666
e26821841b feat: more default garage locations 2025-01-17 20:36:16 +01:00
Andy
e9aafe1f2d Merge pull request #70 from NotSomething0/fix-vehicle-metadata
fix(vehicle): set metadata state for vehicle if non-existent
2024-12-20 21:29:39 +01:00
NotSomething0
6987bb63ae Merge branch 'ND-Framework:main' into fix-vehicle-metadata 2024-05-13 17:17:27 -05:00
NotSomething0
e0c4a8419b fix(vehicle): set metadata state for vehicle if non-existent
- Added debug print for when metadata is storage is skipped
2024-05-11 14:54:57 -05:00
Andyyy7666
66f93bde14 Merge branch 'main' of https://github.com/ND-Framework/ND_Core 2024-03-26 17:08:11 +01:00
Andyyy7666
2460df2f34 feat(server/vehicles): remove vehicles from db 2024-03-26 17:08:09 +01:00
Andy
b79bb6ec7f Merge pull request #68 from Hakkodevelopment/main
small changes
2024-03-25 23:12:04 +01:00
Hakko
eef1bb60f5 bump fxmanifest version 2024-03-25 16:04:43 -06:00
Hakko
1320c4ab7d Update commands.lua 2024-03-25 16:02:24 -06:00
Andyyy7666
2c7aa5723a perf(server/vehicle): getting vehicle types 2024-03-19 01:53:06 +01:00
Andyyy7666
97a8b991ae fix(server/vehicle): taking out impounded vehicle 2024-03-19 01:52:45 +01:00
Andyyy7666
2a3ac3b63b feat(server/player): player group removed event 2024-03-19 01:52:18 +01:00
Andyyy7666
5d3c051149 fix(server/vehicle): calculating time 2024-03-17 14:26:11 +01:00
Andyyy7666
fc82b217e9 fix: clothing not updating 2024-03-16 19:12:34 +01:00
Andyyy7666
284411ce66 fix(server/player): nil group metadata 2024-03-16 16:43:20 +01:00
Andyyy7666
a7257cf68f feat(server/player): group metadata 2024-03-10 00:35:45 +01:00
Andyyy7666
841a5771c5 tweak(server/player): custom group data 2024-03-10 00:01:49 +01:00
Andy
8fd7878ba6 Merge pull request #67 from ND-Framework/tweak/updateCharacter-event
tweak(server/player): also pass which data changed
2024-03-09 19:05:49 +01:00
Andyyy7666
60e86d2038 tweak(server/player): also pass which data changed 2024-03-09 19:05:21 +01:00
Andy
626f0ad06f Merge pull request #66 from ND-Framework/feat/custom-group-info
Feat/custom group info
2024-03-09 19:03:19 +01:00
Andyyy7666
d5c3acbd81 tweak(server/player): adding job group 2024-03-09 19:02:18 +01:00
Andyyy7666
98cba87bec feat(server/player): adding custom group info 2024-03-09 19:00:15 +01:00
Andyyy7666
001fc22ef6 fix: syntax error 2024-02-29 23:17:08 +01:00
Andy
87420e99e9 Merge pull request #65 from ND-Framework/feat/discord-groups
feat: receive groups by discord roles
2024-02-29 22:29:13 +01:00
Andyyy7666
c5597161d9 feat: receive groups by discord roles
Player can receive groups based on the discord roles they have, ace perms are also added when group is received.
2024-02-29 22:28:25 +01:00
Andyyy7666
898b9aefe9 feat(server/player): updatecharacter server event 2024-02-28 14:12:18 +01:00
Andyyy7666
5545650dd5 feat: impound non parked vehicles 2024-02-27 23:13:40 +01:00
Andy
f4f01a5b1c fix: config discord invinte 2024-02-27 20:43:15 +01:00
Andyyy7666
3252118f93 tweak: move clothing menu command to core 2024-02-25 23:54:10 +01:00
Andyyy7666
9d4708a1f8 tweak(server/player): save inventory when character created 2024-02-25 23:43:00 +01:00
25 changed files with 2388 additions and 410 deletions

View File

@@ -1,3 +1,7 @@
RegisterNetEvent("ND:notifyClient", function(...)
NDCore.notify(...)
end)
-- updates the money on the client. -- updates the money on the client.
RegisterNetEvent("ND:updateMoney", function(cash, bank) RegisterNetEvent("ND:updateMoney", function(cash, bank)
if not NDCore.player then return end if not NDCore.player then return end
@@ -23,14 +27,17 @@ end)
RegisterNetEvent("ND:revivePlayer", function() RegisterNetEvent("ND:revivePlayer", function()
if source == "" then return end if source == "" then return end
local veh = GetVehiclePedIsIn(cache.ped) local oldPed = cache.ped
local veh = GetVehiclePedIsIn(oldPed)
local seat = cache.seat local seat = cache.seat
local coords = GetEntityCoords(cache.ped) local coords = GetEntityCoords(oldPed)
NetworkResurrectLocalPlayer(coords.x, coords.y, coords.z, GetEntityHeading(cache.ped), true, true, false) local armor = GetPedArmour(oldPed)
NetworkResurrectLocalPlayer(coords.x, coords.y, coords.z, GetEntityHeading(oldPed), true, true, false)
local ped = PlayerPedId() local ped = PlayerPedId()
if cache.ped ~= ped then if oldPed ~= ped then
DeleteEntity(cache.ped) DeleteEntity(oldPed)
ClearAreaOfPeds(coords.x, coords.y, coords.z, 0.2, false) ClearAreaOfPeds(coords.x, coords.y, coords.z, 0.2, false)
end end
@@ -43,6 +50,7 @@ RegisterNetEvent("ND:revivePlayer", function()
SetBlockingOfNonTemporaryEvents(ped, false) SetBlockingOfNonTemporaryEvents(ped, false)
SetPedCanRagdollFromPlayerImpact(ped, true) SetPedCanRagdollFromPlayerImpact(ped, true)
ClearPedTasksImmediately(ped) ClearPedTasksImmediately(ped)
SetPedArmour(ped, armor)
if veh and veh ~= 0 then if veh and veh ~= 0 then
SetPedIntoVehicle(ped, veh, seat) SetPedIntoVehicle(ped, veh, seat)
@@ -50,3 +58,22 @@ RegisterNetEvent("ND:revivePlayer", function()
end) end)
RegisterNetEvent("ND:characterUnloaded") RegisterNetEvent("ND:characterUnloaded")
RegisterNetEvent("ND:clothingMenu", function()
if GetResourceState("fivem-appearance") ~= "started" then return end
local function customize(appearance)
if not appearance then return end
TriggerServerEvent("ND:updateClothing", appearance)
end
exports["fivem-appearance"]:startPlayerCustomization(customize, {
ped = false,
headBlend = true,
faceFeatures = true,
headOverlays = true,
components = true,
props = true,
tattoos = true
})
end)

View File

@@ -1,3 +1,4 @@
lib.locale()
NDCore = {} NDCore = {}
Config = { Config = {
@@ -7,7 +8,7 @@ Config = {
discordAsset = GetConvar("core:discordAsset", "andyyy"), discordAsset = GetConvar("core:discordAsset", "andyyy"),
discordAssetSmall = GetConvar("core:discordAssetSmall", "andyyy"), discordAssetSmall = GetConvar("core:discordAssetSmall", "andyyy"),
discordActionText = GetConvar("core:discordActionText", "DISCORD"), discordActionText = GetConvar("core:discordActionText", "DISCORD"),
discordActionLink = GetConvar("discordActionLink", "https://discord.gg/Z9Mxu72zZ6"), discordActionLink = GetConvar("core:discordActionLink", "https://discord.gg/Z9Mxu72zZ6"),
discordActionText2 = GetConvar("core:discordActionText2", "STORE"), discordActionText2 = GetConvar("core:discordActionText2", "STORE"),
discordActionLink2 = GetConvar("core:discordActionLink2", "https://andyyy.tebex.io/category/fivem-scripts"), discordActionLink2 = GetConvar("core:discordActionLink2", "https://andyyy.tebex.io/category/fivem-scripts"),
disableVehicleAirControl = GetConvarInt("core:disableVehicleAirControl", 1) == 1, disableVehicleAirControl = GetConvarInt("core:disableVehicleAirControl", 1) == 1,
@@ -15,7 +16,8 @@ Config = {
requireKeys = GetConvarInt("core:requireKeys", 1) == 1, requireKeys = GetConvarInt("core:requireKeys", 1) == 1,
useInventoryForKeys = GetConvarInt("core:useInventoryForKeys", 1) == 1, useInventoryForKeys = GetConvarInt("core:useInventoryForKeys", 1) == 1,
groups = json.decode(GetConvar("core:groups", "[]")), groups = json.decode(GetConvar("core:groups", "[]")),
compatibility = json.decode(GetConvar("core:compatibility", "[]")) compatibility = json.decode(GetConvar("core:compatibility", "[]")),
lockpickTries = GetConvarInt("core:lockpickTries", 3)
} }
-- Discord rich presence. -- Discord rich presence.
@@ -25,11 +27,11 @@ CreateThread(function()
SetDiscordRichPresenceAssetSmall(Config.discordAssetSmall) SetDiscordRichPresenceAssetSmall(Config.discordAssetSmall)
SetDiscordRichPresenceAction(0, Config.discordActionText, Config.discordActionLink) SetDiscordRichPresenceAction(0, Config.discordActionText, Config.discordActionLink)
SetDiscordRichPresenceAction(1, Config.discordActionText2, Config.discordActionLink2) SetDiscordRichPresenceAction(1, Config.discordActionText2, Config.discordActionLink2)
local presenceText = ("Playing: %s"):format(Config.serverName) local presenceText = locale("discord_text_server", Config.serverName)
while true do while true do
if NDCore.player then if NDCore.player then
local presence = ("Playing: %s as %s %s"):format(Config.serverName, NDCore.player.firstname, NDCore.player.lastname) local presence = locale("discord_text", Config.serverName, NDCore.player.firstname, NDCore.player.lastname)
local presenceTextSmall = ("Playing as: %s %s"):format(NDCore.player.firstname, NDCore.player.lastname) local presenceTextSmall = locale("discord_text_small", NDCore.player.firstname, NDCore.player.lastname)
SetRichPresence(presence) SetRichPresence(presence)
SetDiscordRichPresenceAssetText(presenceText) SetDiscordRichPresenceAssetText(presenceText)
SetDiscordRichPresenceAssetSmallText(presenceTextSmall) SetDiscordRichPresenceAssetSmallText(presenceTextSmall)
@@ -48,8 +50,8 @@ CreateThread(function()
sleep = 0 sleep = 0
BeginScaleformMovieMethodOnFrontendHeader("SET_HEADING_DETAILS") BeginScaleformMovieMethodOnFrontendHeader("SET_HEADING_DETAILS")
ScaleformMovieMethodAddParamPlayerNameString(("%s %s"):format(NDCore.player.firstname, NDCore.player.lastname)) ScaleformMovieMethodAddParamPlayerNameString(("%s %s"):format(NDCore.player.firstname, NDCore.player.lastname))
ScaleformMovieMethodAddParamTextureNameString(("Cash: $%d"):format(NDCore.player.cash)) ScaleformMovieMethodAddParamTextureNameString(locale("pause_menu_cash", NDCore.player.cash))
ScaleformMovieMethodAddParamTextureNameString(("Bank: $%d"):format(NDCore.player.bank)) ScaleformMovieMethodAddParamTextureNameString(locale("pause_menu_bank", NDCore.player.bank))
EndScaleformMovieMethod() EndScaleformMovieMethod()
elseif sleep == 0 then elseif sleep == 0 then
sleep = 500 sleep = 500

View File

@@ -101,7 +101,18 @@ local function updateBlips(playerGroups)
end end
end end
function NDCore.createAiPed(info) local function disableCollisionWithModels(ped, models)
if not models then return end
local coords = GetEntityCoords(ped)
for i=1, #models do
local m = models[i]
local model = type(m) == "number" and m or GetHashKey(m)
local obj = GetClosestObjectOfType(coords.x, coords.y, coords.z, 5.0, model, false, false, false)
SetEntityNoCollisionEntity(ped, obj, false)
end
end
function NDCore.createAiPed(info, cb)
local ped local ped
local model = type(info.model) == "string" and GetHashKey(info.model) or info.model local model = type(info.model) == "string" and GetHashKey(info.model) or info.model
local blipInfo = info.blip local blipInfo = info.blip
@@ -111,7 +122,7 @@ function NDCore.createAiPed(info)
local options = info.options local options = info.options
local blip = createBlip(coords, blipInfo) local blip = createBlip(coords, blipInfo)
local point = lib.points.new({ local point = lib.points.new({
coords = vec3(coords.x, coords.y, coords.z), coords = coords.xyz,
distance = info.distance or 25.0 distance = info.distance or 25.0
}) })
@@ -123,6 +134,10 @@ function NDCore.createAiPed(info)
resource = info.resource or GetInvokingResource() resource = info.resource or GetInvokingResource()
} }
if blip and blipInfo and blipInfo.showWhenNear and DoesBlipExist(blip) and #(GetEntityCoords(cache.ped)-coords.xyz) > point.distance then
SetBlipAlpha(blip, 0)
end
function point:onEnter() function point:onEnter()
local found, ground = GetGroundZFor_3dCoord(coords.x, coords.y, coords.z, true) local found, ground = GetGroundZFor_3dCoord(coords.x, coords.y, coords.z, true)
lib.requestModel(model) lib.requestModel(model)
@@ -133,6 +148,11 @@ function NDCore.createAiPed(info)
Wait(100) Wait(100)
end end
if cb then
cb(ped)
end
disableCollisionWithModels(ped, info.disableCollisionWithModels)
configPed(ped) configPed(ped)
setClothing(ped, clothing) setClothing(ped, clothing)
locations[id].ped = ped locations[id].ped = ped

View File

@@ -1,4 +1,14 @@
return { return {
{
garageType = "land",
groups = {"lsfd"},
ped = vector4(370.9027, -593.8090, 28.8681, 73.6009),
vehicleSpawns = {
vec4(366.7840, -591.4883, 28.7261, 339.6823),
vec4(365.0753, -582.8641, 28.7156, 135.0064),
vec4(357.4239, -604.7719, 28.6767, 177.1355),
}
},
{ {
garageType = "land", garageType = "land",
groups = {"sahp", "lspd", "bcso"}, groups = {"sahp", "lspd", "bcso"},
@@ -240,4 +250,52 @@ return {
vector4(216.56, -801.90, 30.79, 69.39) vector4(216.56, -801.90, 30.79, 69.39)
} }
}, },
{
garageType = "land",
ped = vector4(587.5941, 2744.2844, 42.0691, 181.0514),
vehicleSpawns = {
vector4(584.3921, 2721.3599, 41.6483, 184.3260),
vector4(577.1069, 2736.2322, 41.6097, 184.6912),
vector4(577.9459, 2721.0010, 41.6481, 185.1414),
vector4(574.1685, 2735.7288, 41.6397, 184.5562)
}
},
{
garageType = "land",
ped = vector4(2746.1726, 3458.7378, 55.8272, 245.1009),
vehicleSpawns = {
vector4(2768.2136, 3456.2710, 55.2840, 67.7897),
vector4(2759.3218, 3451.1448, 55.4786, 248.0150),
vector4(2763.6526, 3445.0544, 55.4741, 66.9754),
vector4(2787.2947, 3467.1001, 54.9407, 247.4356),
vector4(2773.9514, 3471.6238, 55.0407, 246.8264)
}
},
{
garageType = "land",
ped = vector4(120.4042, 6623.5190, 31.9593, 228.8283),
vehicleSpawns = {
vector4(155.9047, 6593.3252, 31.4343, 359.3789),
vector4(155.7900, 6602.6978, 31.4463, 358.8232),
vector4(145.8267, 6614.0996, 31.4007, 178.7948),
vector4(145.6977, 6602.8950, 31.4397, 181.0616),
vector4(132.4042, 6585.2139, 31.5501, 91.0906)
}
},
{
garageType = "heli",
groups = {"lspd"},
ped = vector4(465.6194, -985.4730, 43.6918, 0.8591),
vehicleSpawns = {
vector4(449.3105, -981.1057, 44.0788, 359.6042)
}
},
{
garageType = "heli",
groups = {"lsfd"},
ped = vector4(339.6271, -581.0325, 74.1656, 267.8232),
vehicleSpawns = {
vector4(351.3463, -588.1304, 74.1698, 108.5617)
}
}
} }

View File

@@ -119,8 +119,8 @@ end
local function parkVehicle(veh) local function parkVehicle(veh)
if not veh or not DoesEntityExist(veh) then if not veh or not DoesEntityExist(veh) then
return NDCore.notify({ return NDCore.notify({
title = "Garage", title = locale("garage"),
description = "No owned vehicle found nearby.", description = locale("no_owned_veh_nearby"),
type = "error", type = "error",
position = "bottom", position = "bottom",
duration = 3000 duration = 3000
@@ -128,8 +128,8 @@ local function parkVehicle(veh)
end end
if GetPedInVehicleSeat(veh, -1) ~= 0 then if GetPedInVehicleSeat(veh, -1) ~= 0 then
NDCore.notify({ NDCore.notify({
title = "Garage", title = locale("garage"),
description = "Player in vehicle!", description = locale("player_in_veh"),
type = "error", type = "error",
position = "bottom", position = "bottom",
duration = 3000 duration = 3000
@@ -156,13 +156,13 @@ end
local function getEngineStatus(health) local function getEngineStatus(health)
if health > 950 then if health > 950 then
return "Perfect" return locale("perfect")
elseif health > 750 then elseif health > 750 then
return "Good" return locale("good")
elseif health > 500 then elseif health > 500 then
return "Bad" return locale("bad")
end end
return "Very bad" return locale("very_bad")
end end
local function createMenuOptions(vehicle, vehicleSpawns) local function createMenuOptions(vehicle, vehicleSpawns)
@@ -174,21 +174,21 @@ local function createMenuOptions(vehicle, vehicleSpawns)
if not makeName or makeName == "NULL" then if not makeName or makeName == "NULL" then
makeName = "" makeName = ""
else else
metadata[#metadata+1] = {label = "Make", value = makeName} metadata[#metadata+1] = {label = locale("veh_make_brand"), value = makeName}
makeName = makeName .. " " makeName = makeName .. " "
end end
if not modelName or modelName == "NULL" then if not modelName or modelName == "NULL" then
modelName = "" modelName = ""
else else
metadata[#metadata+1] = {label = "Model", value = modelName} metadata[#metadata+1] = {label = locale("veh_model"), value = modelName}
end end
if props?.plate then if props?.plate then
metadata[#metadata+1] = {label = "Plate", value = props.plate} metadata[#metadata+1] = {label = locale("veh_plate"), value = props.plate}
end end
if props?.engineHealth then if props?.engineHealth then
metadata[#metadata+1] = { metadata[#metadata+1] = {
label = "Engine status", label = locale("engine_status"),
value = getEngineStatus(props.engineHealth), value = getEngineStatus(props.engineHealth),
progress = props.engineHealth/10, progress = props.engineHealth/10,
colorScheme = "blue" colorScheme = "blue"
@@ -205,7 +205,7 @@ local function createMenuOptions(vehicle, vehicleSpawns)
end end
return { return {
title = ("Vehicle: %s%s\nPlate: %s"):format(makeName, modelName, props?.plate or "not found"), title = ("%s: %s%s\n%s: %s"):format(locale("vehicle"), makeName, modelName, locale("veh_plate"), props?.plate or locale("not_found")),
metadata = metadata, metadata = metadata,
onSelect = function(args) onSelect = function(args)
TriggerServerEvent("ND_Vehicles:takeVehicle", vehicle.id, vehicleSpawns) TriggerServerEvent("ND_Vehicles:takeVehicle", vehicle.id, vehicleSpawns)
@@ -217,7 +217,7 @@ local function createMenu(vehicles, garageType, vehicleSpawns, impound)
local options = {} local options = {}
if not impound then if not impound then
options[#options+1] = { options[#options+1] = {
title = "Park vehicle", title = locale("park_veh"),
onSelect = function(args) onSelect = function(args)
local veh = getClosestOwnedVehicle() local veh = getClosestOwnedVehicle()
parkVehicle(veh) parkVehicle(veh)
@@ -231,13 +231,13 @@ local function createMenu(vehicles, garageType, vehicleSpawns, impound)
end end
if impound and #options == 0 then if impound and #options == 0 then
options[#options+1] = { options[#options+1] = {
title = "No vehicles found", title = locale("no_vehs_found"),
readOnly = true readOnly = true
} }
end end
return { return {
id = ("garage_%s"):format(garageType), id = ("garage_%s"):format(garageType),
title = impound and "Vehicle impound" or "Parking garage", title = impound and locale("vehicle_impound") or locale("parking_garage"),
options = options, options = options,
onExit = function() onExit = function()
garageOpen = false garageOpen = false
@@ -253,7 +253,7 @@ for i=1, #locations do
distance = 45.0, distance = 45.0,
clothing = clothing[math.random(1, #clothing)], clothing = clothing[math.random(1, #clothing)],
blip = { blip = {
label = location.impound and ("Impound (%s)"):format(location.garageType) or ("Parking garage (%s)"):format(location.garageType), label = location.impound and locale("impound_w_location", location.garageType) or locale("garage_w_location", location.garageType),
sprite = location.impound and 285 or sprite[location.garageType], sprite = location.impound and 285 or sprite[location.garageType],
scale = 0.7, scale = 0.7,
color = 3, color = 3,
@@ -267,7 +267,7 @@ for i=1, #locations do
{ {
name = "nd_core:garagePed", name = "nd_core:garagePed",
icon = "fa-solid fa-warehouse", icon = "fa-solid fa-warehouse",
label = location.impound and "View impounded vehicles" or "View garage", label = location.impound and locale("view_impounded_vehs") or locale("view_garage"),
distance = 2.0, distance = 2.0,
canInteract = function(entity, distance, coords, name, bone) canInteract = function(entity, distance, coords, name, bone)
if not location.groups then return true end if not location.groups then return true end

View File

@@ -1,188 +1,188 @@
local vehicleColorNames = { local vehicleColorNames = {
[0] = "Black", [0] = locale("veh_color_black"),
[1] = "Black", [1] = locale("veh_color_black"),
[2] = "Black", [2] = locale("veh_color_black"),
[3] = "Silver", [3] = locale("veh_color_silver"),
[4] = "Silver", [4] = locale("veh_color_silver"),
[5] = "Silver", [5] = locale("veh_color_silver"),
[6] = "Gray", [6] = locale("veh_color_grey"),
[7] = "Silver", [7] = locale("veh_color_silver"),
[8] = "Silver", [8] = locale("veh_color_silver"),
[9] = "Silver", [9] = locale("veh_color_silver"),
[10] = "Metal", [10] = locale("veh_color_metal"),
[11] = "Grey", [11] = locale("veh_color_grey"),
[12] = "Black", [12] = locale("veh_color_black"),
[13] = "Gray", [13] = locale("veh_color_grey"),
[14] = "Grey", [14] = locale("veh_color_grey"),
[15] = "Black", [15] = locale("veh_color_black"),
[16] = "Black", [16] = locale("veh_color_black"),
[17] = "Silver", [17] = locale("veh_color_silver"),
[18] = "Silver", [18] = locale("veh_color_silver"),
[19] = "Metal", [19] = locale("veh_color_metal"),
[20] = "Silver", [20] = locale("veh_color_silver"),
[21] = "Black", [21] = locale("veh_color_black"),
[22] = "Graphite", [22] = locale("veh_color_graphite"),
[23] = "Silver", [23] = locale("veh_color_silver"),
[24] = "Silver", [24] = locale("veh_color_silver"),
[25] = "Silver", [25] = locale("veh_color_silver"),
[26] = "Silver", [26] = locale("veh_color_silver"),
[27] = "Red", [27] = locale("veh_color_red"),
[28] = "Red", [28] = locale("veh_color_red"),
[29] = "Red", [29] = locale("veh_color_red"),
[30] = "Red", [30] = locale("veh_color_red"),
[31] = "Red", [31] = locale("veh_color_red"),
[32] = "Red", [32] = locale("veh_color_red"),
[33] = "Red", [33] = locale("veh_color_red"),
[34] = "Red", [34] = locale("veh_color_red"),
[35] = "Red", [35] = locale("veh_color_red"),
[36] = "Orange", [36] = locale("veh_color_orange"),
[37] = "Gold", [37] = locale("veh_color_gold"),
[38] = "Orange", [38] = locale("veh_color_orange"),
[39] = "Red", [39] = locale("veh_color_red"),
[40] = "Red", [40] = locale("veh_color_red"),
[41] = "Orange", [41] = locale("veh_color_orange"),
[42] = "Yellow", [42] = locale("veh_color_yellow"),
[43] = "Red", [43] = locale("veh_color_red"),
[44] = "Red", [44] = locale("veh_color_red"),
[45] = "Red", [45] = locale("veh_color_red"),
[46] = "Red", [46] = locale("veh_color_red"),
[47] = "Red", [47] = locale("veh_color_red"),
[48] = "Red", [48] = locale("veh_color_red"),
[49] = "Green", [49] = locale("veh_color_green"),
[50] = "Green", [50] = locale("veh_color_green"),
[51] = "Green", [51] = locale("veh_color_green"),
[52] = "Green", [52] = locale("veh_color_green"),
[53] = "Green", [53] = locale("veh_color_green"),
[54] = "Green", [54] = locale("veh_color_green"),
[55] = "Green", [55] = locale("veh_color_green"),
[56] = "Green", [56] = locale("veh_color_green"),
[57] = "Green", [57] = locale("veh_color_green"),
[58] = "Green", [58] = locale("veh_color_green"),
[59] = "Green", [59] = locale("veh_color_green"),
[60] = "Green", [60] = locale("veh_color_green"),
[61] = "Blue", [61] = locale("veh_color_blue"),
[62] = "Blue", [62] = locale("veh_color_blue"),
[63] = "Blue", [63] = locale("veh_color_blue"),
[64] = "Blue", [64] = locale("veh_color_blue"),
[65] = "Blue", [65] = locale("veh_color_blue"),
[66] = "Blue", [66] = locale("veh_color_blue"),
[67] = "Blue", [67] = locale("veh_color_blue"),
[68] = "Blue", [68] = locale("veh_color_blue"),
[69] = "Blue", [69] = locale("veh_color_blue"),
[70] = "Blue", [70] = locale("veh_color_blue"),
[71] = "Blue", [71] = locale("veh_color_blue"),
[72] = "Blue", [72] = locale("veh_color_blue"),
[73] = "Blue", [73] = locale("veh_color_blue"),
[74] = "Blue", [74] = locale("veh_color_blue"),
[75] = "Blue", [75] = locale("veh_color_blue"),
[76] = "Blue", [76] = locale("veh_color_blue"),
[77] = "Blue", [77] = locale("veh_color_blue"),
[78] = "Blue", [78] = locale("veh_color_blue"),
[79] = "Bblue", [79] = locale("veh_color_bblue"),
[80] = "Blue", [80] = locale("veh_color_blue"),
[81] = "Blue", [81] = locale("veh_color_blue"),
[82] = "Blue", [82] = locale("veh_color_blue"),
[83] = "Blue", [83] = locale("veh_color_blue"),
[84] = "Blue", [84] = locale("veh_color_blue"),
[85] = "Blue", [85] = locale("veh_color_blue"),
[86] = "Blue", [86] = locale("veh_color_blue"),
[87] = "Blue", [87] = locale("veh_color_blue"),
[88] = "Yellow", [88] = locale("veh_color_yellow"),
[89] = "Yellow", [89] = locale("veh_color_yellow"),
[90] = "Bronze", [90] = locale("veh_color_bronze"),
[91] = "Yellow", [91] = locale("veh_color_yellow"),
[92] = "Lime", [92] = locale("veh_color_lime"),
[93] = "Champagne", [93] = locale("veh_color_champagne"),
[94] = "Beige", [94] = locale("veh_color_beige"),
[95] = "Ivory", [95] = locale("veh_color_ivory"),
[96] = "Brown", [96] = locale("veh_color_brown"),
[97] = "Brown", [97] = locale("veh_color_brown"),
[98] = "Brown", [98] = locale("veh_color_brown"),
[99] = "Beige", [99] = locale("veh_color_beige"),
[100] = "Brown", [100] = locale("veh_color_brown"),
[101] = "Brown", [101] = locale("veh_color_brown"),
[102] = "Beechwood", [102] = locale("veh_color_beechwood"),
[103] = "Beechwood", [103] = locale("veh_color_beechwood"),
[104] = "Orange", [104] = locale("veh_color_orange"),
[105] = "Sand", [105] = locale("veh_color_sand"),
[106] = "Sand", [106] = locale("veh_color_sand"),
[107] = "Cream", [107] = locale("veh_color_cream"),
[108] = "Brown", [108] = locale("veh_color_brown"),
[109] = "Brown", [109] = locale("veh_color_brown"),
[110] = "Brown", [110] = locale("veh_color_brown"),
[111] = "White", [111] = locale("veh_color_white"),
[112] = "White", [112] = locale("veh_color_white"),
[113] = "Beige", [113] = locale("veh_color_beige"),
[114] = "Brown", [114] = locale("veh_color_brown"),
[115] = "Brown", [115] = locale("veh_color_brown"),
[116] = "Beige", [116] = locale("veh_color_beige"),
[117] = "Steel", [117] = locale("veh_color_steel"),
[118] = "Steel", [118] = locale("veh_color_steel"),
[119] = "Aluminium", [119] = locale("veh_color_aluminium"),
[120] = "Chrome", [120] = locale("veh_color_chrome"),
[121] = "White", [121] = locale("veh_color_white"),
[122] = "White", [122] = locale("veh_color_white"),
[123] = "Orange", [123] = locale("veh_color_orange"),
[124] = "Orange", [124] = locale("veh_color_orange"),
[125] = "Green", [125] = locale("veh_color_green"),
[126] = "Yellow", [126] = locale("veh_color_yellow"),
[127] = "Blue", [127] = locale("veh_color_blue"),
[128] = "Green", [128] = locale("veh_color_green"),
[129] = "Brown", [129] = locale("veh_color_brown"),
[130] = "Orange", [130] = locale("veh_color_orange"),
[131] = "White", [131] = locale("veh_color_white"),
[132] = "White", [132] = locale("veh_color_white"),
[133] = "Green", [133] = locale("veh_color_green"),
[134] = "White", [134] = locale("veh_color_white"),
[135] = "Pink", [135] = locale("veh_color_pink"),
[136] = "pink", [136] = locale("veh_color_pink"),
[137] = "Pink", [137] = locale("veh_color_pink"),
[138] = "Orange", [138] = locale("veh_color_orange"),
[139] = "Green", [139] = locale("veh_color_green"),
[140] = "Blue", [140] = locale("veh_color_blue"),
[141] = "Black", [141] = locale("veh_color_black"),
[142] = "Black", [142] = locale("veh_color_black"),
[143] = "Black", [143] = locale("veh_color_black"),
[144] = "Green", [144] = locale("veh_color_green"),
[145] = "Purple", [145] = locale("veh_color_purple"),
[146] = "Blue", [146] = locale("veh_color_blue"),
[147] = "Black", [147] = locale("veh_color_black"),
[148] = "Purple", [148] = locale("veh_color_purple"),
[149] = "Purple", [149] = locale("veh_color_purple"),
[150] = "Red", [150] = locale("veh_color_red"),
[151] = "Green", [151] = locale("veh_color_green"),
[152] = "Green", [152] = locale("veh_color_green"),
[153] = "Brown", [153] = locale("veh_color_brown"),
[154] = "Tan", [154] = locale("veh_color_tan"),
[155] = "Green", [155] = locale("veh_color_green"),
[156] = "ALLOY", [156] = locale("veh_color_alloy"),
[157] = "Blue", [157] = locale("veh_color_blue"),
} }
local vehicleClassNames = { local vehicleClassNames = {
[0] = "Compact", [0] = locale("veh_class_compact"),
[1] = "Sedan", [1] = locale("veh_class_sedan"),
[2] = "SUV", [2] = locale("veh_class_suv"),
[3] = "Coupe", [3] = locale("veh_class_coupe"),
[4] = "Muscle", [4] = locale("veh_class_muscle"),
[5] = "Sports Classic", [5] = locale("veh_class_sports_classic"),
[6] = "Sport", [6] = locale("veh_class_sport"),
[7] = "Super", [7] = locale("veh_class_super"),
[8] = "Motorcycle", [8] = locale("veh_class_motorcycle"),
[9] = "Off-road", [9] = locale("veh_class_off_road"),
[10] = "Industrial", [10] = locale("veh_class_industrial"),
[11] = "Utility", [11] = locale("veh_class_utility"),
[12] = "Van", [12] = locale("veh_class_van"),
[13] = "Cycle", [13] = locale("veh_class_cycle"),
[14] = "Boat", [14] = locale("veh_class_boat"),
[15] = "Helicopter", [15] = locale("veh_class_helicopter"),
[16] = "Plane", [16] = locale("veh_class_plane"),
[17] = "Service", [17] = locale("veh_class_service"),
[18] = "Emergency", [18] = locale("veh_class_emergency"),
[19] = "Military", [19] = locale("veh_class_military"),
[20] = "Commercial", [20] = locale("veh_class_commercial"),
[21] = "Train", [21] = locale("veh_class_train"),
[22] = "Open wheel" [22] = locale("veh_class_open_wheel")
} }
local cruiseSpeedSet = 0 local cruiseSpeedSet = 0
@@ -264,7 +264,7 @@ RegisterNetEvent("ND_Vehicles:blip", function(netId, status)
SetBlipScale(blip, 0.8) SetBlipScale(blip, 0.8)
SetBlipAsShortRange(blip, true) SetBlipAsShortRange(blip, true)
BeginTextCommandSetBlipName("STRING") BeginTextCommandSetBlipName("STRING")
AddTextComponentSubstringPlayerName("Personal vehicle") AddTextComponentSubstringPlayerName(locale("personal_vehicle"))
EndTextCommandSetBlipName(blip) EndTextCommandSetBlipName(blip)
end) end)
@@ -356,8 +356,9 @@ AddStateBagChangeHandler("locked", nil, function(bagName, key, value, reserved,
end) end)
end) end)
lib.callback.register("ND_Vehicles:getProps", function(netId) local function getProps(veh)
local veh = getVehFromNetId(netId) if not veh or not DoesEntityExist(veh) then return end
local props = lib.getVehicleProperties(veh) local props = lib.getVehicleProperties(veh)
local colorPrimary, colorSecondary = GetVehicleColours(veh) local colorPrimary, colorSecondary = GetVehicleColours(veh)
if not props then return end if not props then return end
@@ -368,7 +369,18 @@ lib.callback.register("ND_Vehicles:getProps", function(netId)
props.className = vehicleClassNames[GetVehicleClass(veh)] props.className = vehicleClassNames[GetVehicleClass(veh)]
props.makeName = GetLabelText(GetMakeNameFromVehicleModel(props.model)) props.makeName = GetLabelText(GetMakeNameFromVehicleModel(props.model))
props.modelName = GetLabelText(GetDisplayNameFromVehicleModel(props.model)) props.modelName = GetLabelText(GetDisplayNameFromVehicleModel(props.model))
return props return props
end
lib.callback.register("ND_Vehicles:getProps", function(netId)
local veh = getVehFromNetId(netId)
return getProps(veh)
end)
lib.callback.register("ND_Vehicles:getPropsFromCurrentVeh", function()
local veh = GetVehiclePedIsIn(cache.ped)
return getProps(veh)
end) end)
lib.callback.register("ND_Vehicles:getVehicleModelMakeLabel", function(model) lib.callback.register("ND_Vehicles:getVehicleModelMakeLabel", function(model)
@@ -435,7 +447,7 @@ end
local vehicleLockKeybind = lib.addKeybind({ local vehicleLockKeybind = lib.addKeybind({
name = "vehicleKey", name = "vehicleKey",
description = "Unlock/lock vehicle (double click)", description = locale("keybind_carkey"),
defaultKey = "E", defaultKey = "E",
onPressed = function(self) onPressed = function(self)
local time = GetCloudTimeAsInt() local time = GetCloudTimeAsInt()
@@ -457,8 +469,8 @@ NDCore.isResourceStarted("ox_inventory", function(started)
Wait(1000) Wait(1000)
vehicleLockKeybind:disable(true) vehicleLockKeybind:disable(true)
exports.ox_inventory:displayMetadata({ exports.ox_inventory:displayMetadata({
vehPlate = "Plate", vehPlate = locale("veh_plate"),
vehModel = "Model" vehModel = locale("veh_model")
}) })
end) end)
@@ -540,7 +552,7 @@ local function hotwireVehicle()
local success = lib.progressCircle({ local success = lib.progressCircle({
duration = math.random(10000, 20000), duration = math.random(10000, 20000),
label = "Hotwiring", label = locale("progress_hotwiring"),
useWhileDead = false, useWhileDead = false,
allowRagdoll = false, allowRagdoll = false,
allowCuffed = false, allowCuffed = false,
@@ -597,7 +609,7 @@ local function lockpickVehicle()
} }
lib.requestAnimDict("veh@break_in@0h@p_m_one@") lib.requestAnimDict("veh@break_in@0h@p_m_one@")
for i=1, 7 do for i=1, Config.lockpickTries do
TaskPlayAnimAdvanced(cache.ped, "veh@break_in@0h@p_m_one@", "std_force_entry_ds", pos.x, pos.y, pos.z+0.025, rot.x, rot.y, rot.z, 8.0, 8.0, 1800, 28, 0.1) TaskPlayAnimAdvanced(cache.ped, "veh@break_in@0h@p_m_one@", "std_force_entry_ds", pos.x, pos.y, pos.z+0.025, rot.x, rot.y, rot.z, 8.0, 8.0, 1800, 28, 0.1)
local dificulty = dificulties[math.random(1, #dificulties)] local dificulty = dificulties[math.random(1, #dificulties)]
local success = lib.skillCheck(dificulty) local success = lib.skillCheck(dificulty)
@@ -635,8 +647,8 @@ exports("keyControl", function(action, slot)
if data.slot == slot then if data.slot == slot then
if metadata and not metadata.keyEnabled then if metadata and not metadata.keyEnabled then
return lib.notify({ return lib.notify({
title = "No signal", title = locale("no_signal"),
description = "Vehicle key disabled.", description = locale("veh_key_disabled"),
type = "error", type = "error",
position = "bottom-right", position = "bottom-right",
duration = 3000 duration = 3000
@@ -658,8 +670,8 @@ exports("keyControl", function(action, slot)
elseif action == "disable" then elseif action == "disable" then
TriggerServerEvent("ND_Vehicles:disableKey", slot) TriggerServerEvent("ND_Vehicles:disableKey", slot)
lib.notify({ lib.notify({
title = "Key disabled", title = locale("veh_key_disabled"),
description = "This vehicle key has been disabled and cannot be used anymore.", description = locale("veh_key_disabled2"),
type = "inform", type = "inform",
position = "bottom-right", position = "bottom-right",
duration = 3000 duration = 3000
@@ -671,8 +683,8 @@ local function cruiseControl()
cruiseSpeedVehicle = GetEntitySpeed(playerVehicle) * 2.236936 cruiseSpeedVehicle = GetEntitySpeed(playerVehicle) * 2.236936
if not playerVehicle then if not playerVehicle then
lib.notify({ lib.notify({
title = "Cruise control", title = locale("cruise_control"),
description = "Vehicle cruise control disabled.", description = locale("cruise_control_disabled"),
type = "inform", type = "inform",
position = "bottom-right", position = "bottom-right",
duration = 3000 duration = 3000
@@ -681,8 +693,8 @@ local function cruiseControl()
end end
if cruiseSpeedVehicle < cruiseSpeedSet/3 then if cruiseSpeedVehicle < cruiseSpeedSet/3 then
lib.notify({ lib.notify({
title = "Cruise control", title = locale("cruise_control"),
description = "Vehicle cruise control disabled.", description = locale("cruise_control_disabled"),
type = "inform", type = "inform",
position = "bottom-right", position = "bottom-right",
duration = 3000 duration = 3000
@@ -697,14 +709,14 @@ end
lib.addKeybind({ lib.addKeybind({
name = "vehicleCruiseControl", name = "vehicleCruiseControl",
description = "Toggle vehicle cruise control", description = locale("cruise_control_toggle"),
defaultKey = "", defaultKey = "",
onPressed = function(self) onPressed = function(self)
if cruiseControlEnabled and cruiseSpeedVehicle-1 > cruiseSpeedSet then if cruiseControlEnabled and cruiseSpeedVehicle-1 > cruiseSpeedSet then
cruiseSpeedSet = cruiseSpeedVehicle cruiseSpeedSet = cruiseSpeedVehicle
return lib.notify({ return lib.notify({
title = "Cruise control", title = locale("cruise_control"),
description = ("Increased to %d mph."):format(math.floor(cruiseSpeedSet)), description = locale("cruise_control_increase"),
type = "inform", type = "inform",
position = "bottom-right", position = "bottom-right",
duration = 3000 duration = 3000
@@ -712,8 +724,8 @@ lib.addKeybind({
elseif cruiseControlEnabled then elseif cruiseControlEnabled then
cruiseControlEnabled = false cruiseControlEnabled = false
return lib.notify({ return lib.notify({
title = "Cruise control", title = locale("cruise_control"),
description = "Vehicle cruise control disabled.", description = locale("cruise_control_disabled"),
type = "inform", type = "inform",
position = "bottom-right", position = "bottom-right",
duration = 3000 duration = 3000
@@ -729,8 +741,8 @@ lib.addKeybind({
cruiseSpeedSet = cruiseSpeedVehicle cruiseSpeedSet = cruiseSpeedVehicle
lib.notify({ lib.notify({
title = "Cruise control", title = locale("cruise_control"),
description = ("Set to %d mph."):format(math.floor(cruiseSpeedSet)), description = locale("cruise_control_enabled"),
type = "inform", type = "inform",
position = "bottom-right", position = "bottom-right",
duration = 3000 duration = 3000
@@ -744,7 +756,7 @@ lib.addKeybind({
lib.addKeybind({ lib.addKeybind({
name = "vehicleShuffleSeat", name = "vehicleShuffleSeat",
description = "Suffle vehicle seat.", description = locale("seat_shuffle"),
defaultKey = "", defaultKey = "",
onPressed = function(self) onPressed = function(self)
if not cache.vehicle then return end if not cache.vehicle then return end

View File

@@ -2,7 +2,7 @@
author "Andyyy#7666" author "Andyyy#7666"
description "ND Framework Core" description "ND Framework Core"
version "2.1.2" version "2.3.2"
fx_version "cerulean" fx_version "cerulean"
game "gta5" game "gta5"
@@ -34,10 +34,14 @@ server_scripts {
files { files {
"init.lua", "init.lua",
"client/vehicle/data.lua", "client/vehicle/data.lua",
"compatibility/**/locale.lua" "compatibility/**/locale.lua",
"locales/*.json"
} }
dependency "oxmysql" dependencies {
"ox_lib",
"oxmysql"
}
-- below were used with backwards compatibility but could interfere with resources checking if the resources are started. -- below were used with backwards compatibility but could interfere with resources checking if the resources are started.
-- provide "es_extended" -- provide "es_extended"

View File

@@ -9,3 +9,5 @@ NDCore = setmetatable({}, {
return self[index] return self[index]
end end
}) })
return NDCore

134
locales/ar.json Normal file
View File

@@ -0,0 +1,134 @@
{
"not_in_discord": "لم يتم العثور على حساب ديسكورد الخاص بك، انضم إلى ديسكورد هنا: %s.",
"connecting": "جارٍ الاتصال...",
"identifier_not_found": "لم يتم العثور على %s الخاص بك.",
"deposit": "إيداع",
"withdraw": "سحب",
"vehicle_ownership_transfered": "تم نقل الملكية",
"vehicle_ownership_transfered2": "تم نقل ملكية المركبة %s.",
"vehicle_ownership_received": "تم استلام الملكية",
"vehicle_ownership_received2": "تم استلام ملكية المركبة %s.",
"keys_shared": "تمت مشاركة المفاتيح",
"keys_shared2": "لقد شاركت مفاتيح المركبة مع %s.",
"keys_received": "تم استلام المفاتيح",
"keys_received2": "لقد استلمت مفاتيح المركبة من %s.",
"no_signal": "لا يوجد إشارة",
"veh_key_disabled": "تم تعطيل مفتاح المركبة.",
"veh_key_disabled2": "تم تعطيل هذا المفتاح ولا يمكن استخدامه بعد الآن.",
"veh_far_away": "المركبة بعيدة جدًا.",
"veh_locked": "مقفول",
"veh_locked2": "تم قفل مركبتك الآن.",
"veh_unlocked": "مفتوح",
"veh_unlocked2": "تم فتح مركبتك الآن.",
"garage": "كراج",
"no_owned_veh_nearby": "لم يتم العثور على مركبة مملوكة بالقرب منك.",
"veh_stored_in_garage": "تم تخزين المركبة في الكراج.",
"impound_reclaim": "استعادة المركبة من الحجز",
"impound": "حجز",
"impound_not_enough": "سعر الاستعادة هو $%d، ليس لديك ما يكفي!",
"impound_paid": "تم دفع $%d لاستعادة المركبة!",
"success": "نجاح",
"staff_action": "إجراء من الموظفين",
"staff_money_removed": "تم إزالة $%d (%s) من %s",
"user_money_removed": "تمت إزالة $%d من %s",
"staff_money_added": "تمت إضافة $%d (%s) إلى %s",
"user_money_added": "تمت إضافة $%d إلى %s",
"staff_money_set": "تم ضبط %s (%s) على $%d",
"user_money_set": "تم ضبط %s على $%d",
"job_updated_noti": "تم تحديث الوظيفة إلى %s، الرتبة %s.",
"group_added_noti": "تمت إضافتك إلى مجموعة %s، الرتبة %s.",
"group_removed_noti": "تمت إزالتك من مجموعة %s.",
"no_player_found": "لم يتم العثور على لاعب",
"not_enough_cash": "ليس لديك ما يكفي من النقود",
"player_not_nearby": "اللاعب ليس بالقرب منك",
"cant_give_money": "تعذر إعطاء المال",
"money_received": "تم استلام المال",
"money_received2": "تم استلام $%d نقدًا",
"money_given": "تم إعطاء المال",
"money_given2": "لقد أعطيت $%d نقدًا",
"player_in_veh": "اللاعب داخل المركبة!",
"perfect": "ممتاز",
"good": "جيد",
"bad": "سيء",
"very_bad": "سيء جدًا",
"veh_make_brand": "الصانع",
"veh_model": "الطراز",
"veh_plate": "اللوحة",
"engine_status": "حالة المحرك",
"vehicle": "مركبة",
"not_found": "غير موجود",
"park_veh": "ركن المركبة",
"no_vehs_found": "لم يتم العثور على مركبات",
"vehicle_impound": "حجز المركبة",
"parking_garage": "كراج سيارات",
"impound_w_location": "الحجز (%s)",
"garage_w_location": "كراج السيارات (%s)",
"view_impounded_vehs": "عرض المركبات المحجوزة",
"view_garage": "عرض الكراج",
"personal_vehicle": "مركبة شخصية",
"keybind_carkey": "فتح/قفل المركبة (نقر مزدوج)",
"progress_hotwiring": "تشغيل المركبة بدون مفتاح",
"cruise_control": "التحكم بالسرعة",
"cruise_control_enabled": "تم تفعيل التحكم بالسرعة",
"cruise_control_disabled": "تم تعطيل التحكم بالسرعة",
"cruise_control_toggle": "تبديل التحكم بالسرعة",
"cruise_control_increase": "زيادة سرعة التحكم",
"seat_shuffle": "تبديل مقعد المركبة",
"discord_text": "تلعب: %s كـ %s %s",
"discord_text_small": "تلعب كـ: %s %s",
"discord_text_server": "تلعب: %s",
"pause_menu_cash": "نقد: $%d",
"pause_menu_bank": "البنك: $%d",
"veh_color_black": "أسود",
"veh_color_silver": "فضي",
"veh_color_grey": "رمادي",
"veh_color_metal": "معدني",
"veh_color_graphite": "جرافيت",
"veh_color_red": "أحمر",
"veh_color_orange": "برتقالي",
"veh_color_gold": "ذهبي",
"veh_color_yellow": "أصفر",
"veh_color_green": "أخضر",
"veh_color_blue": "أزرق",
"veh_color_bblue": "أزرق فاتح",
"veh_color_bronze": "برونزي",
"veh_color_lime": "ليموني",
"veh_color_champagne": "شامبانيا",
"veh_color_beige": "بيج",
"veh_color_ivory": "عاجي",
"veh_color_brown": "بني",
"veh_color_beechwood": "خشب الزان",
"veh_color_sand": "رملي",
"veh_color_cream": "كريمي",
"veh_color_white": "أبيض",
"veh_color_steel": "فولاذي",
"veh_color_aluminium": "ألمنيوم",
"veh_color_chrome": "كروم",
"veh_color_pink": "وردي",
"veh_color_purple": "بنفسجي",
"veh_color_tan": "قمحي",
"veh_color_alloy": "سبيكة",
"veh_class_compact": "مدمجة",
"veh_class_sedan": "سيدان",
"veh_class_suv": "دفع رباعي",
"veh_class_coupe": "كوبيه",
"veh_class_muscle": "عضلية",
"veh_class_sports_classic": "رياضية كلاسيكية",
"veh_class_sport": "رياضية",
"veh_class_super": "سوبر",
"veh_class_motorcycle": "دراجة نارية",
"veh_class_off_road": "طرق وعرة",
"veh_class_industrial": "صناعية",
"veh_class_utility": "خدمية",
"veh_class_van": "فان",
"veh_class_cycle": "دراجة",
"veh_class_boat": "قارب",
"veh_class_helicopter": "مروحية",
"veh_class_plane": "طائرة",
"veh_class_service": "خدمة",
"veh_class_emergency": "طوارئ",
"veh_class_military": "عسكرية",
"veh_class_commercial": "تجارية",
"veh_class_train": "قطار",
"veh_class_open_wheel": "مفتوح العجلات"
}

134
locales/da.json Normal file
View File

@@ -0,0 +1,134 @@
{
"not_in_discord": "Din Discord blev ikke fundet, deltag i vores Discord her: %s.",
"connecting": "Forbinder...",
"identifier_not_found": "Din %s blev ikke fundet.",
"deposit": "Indsæt",
"withdraw": "Hæv",
"vehicle_ownership_transfered": "Ejerskab overført",
"vehicle_ownership_transfered2": "Ejerskab af køretøj %s er blevet overført.",
"vehicle_ownership_received": "Ejerskab modtaget",
"vehicle_ownership_received2": "Modtog ejerskab af køretøj %s.",
"keys_shared": "Nøgler delt",
"keys_shared2": "Du har delt bilnøgler med %s.",
"keys_received": "Nøgler modtaget",
"keys_received2": "Du har modtaget bilnøgler fra %s.",
"no_signal": "Ingen signal",
"veh_key_disabled": "Bilnøgle deaktiveret.",
"veh_key_disabled2": "Denne bilnøgle er blevet deaktiveret og kan ikke bruges længere.",
"veh_far_away": "Køretøj for langt væk.",
"veh_locked": "LÅST",
"veh_locked2": "Dit køretøj er nu låst.",
"veh_unlocked": "ULÅST",
"veh_unlocked2": "Dit køretøj er nu ulåst.",
"garage": "Garage",
"no_owned_veh_nearby": "Ingen ejet køretøj fundet i nærheden.",
"veh_stored_in_garage": "Køretøj gemt i garage.",
"impound_reclaim": "Hent køretøj fra beslaglæggelse",
"impound": "Beslaglæggelse",
"impound_not_enough": "Prisen for at hente er %d kr, du har ikke nok!",
"impound_paid": "Betalt %d kr for at hente køretøj!",
"success": "succes",
"staff_action": "Personalehandling",
"staff_money_removed": "Fjernede %d kr (%s) fra %s",
"user_money_removed": "fjernede %d kr fra %s",
"staff_money_added": "Tilføjede %d kr (%s) til %s",
"user_money_added": "tilføjede %d kr til %s",
"staff_money_set": "Satte %s's (%s) til %d kr",
"user_money_set": "satte %s til %d kr",
"job_updated_noti": "Job opdateret til %s, rang %s.",
"group_added_noti": "Tilføjet til gruppe %s, rang %s.",
"group_removed_noti": "Fjernet fra gruppe %s.",
"no_player_found": "Ingen spiller fundet",
"not_enough_cash": "Du har ikke nok kontanter",
"player_not_nearby": "Spiller ikke i nærheden",
"cant_give_money": "Kunne ikke give penge",
"money_received": "Penge modtaget",
"money_received2": "Modtog %d kr i kontanter",
"money_given": "Penge givet",
"money_given2": "Du gav %d kr i kontanter",
"player_in_veh": "Spiller i køretøj!",
"perfect": "Perfekt",
"good": "God",
"bad": "Dårlig",
"very_bad": "Meget dårlig",
"veh_make_brand": "Mærke",
"veh_model": "Model",
"veh_plate": "Nummerplade",
"engine_status": "Motorstatus",
"vehicle": "Køretøj",
"not_found": "ikke fundet",
"park_veh": "Parkér køretøj",
"no_vehs_found": "Ingen køretøjer fundet",
"vehicle_impound": "Køretøj beslaglagt",
"parking_garage": "Parkeringsgarage",
"impound_w_location": "Beslaglæggelse (%s)",
"garage_w_location": "Parkeringsgarage (%s)",
"view_impounded_vehs": "Se beslaglagte køretøjer",
"view_garage": "Se garage",
"personal_vehicle": "Personligt køretøj",
"keybind_carkey": "Lås/lås op for køretøj (dobbeltklik)",
"progress_hotwiring": "Koble tænding",
"cruise_control": "Fartpilot",
"cruise_control_enabled": "Fartpilot aktiveret",
"cruise_control_disabled": "Fartpilot deaktiveret",
"cruise_control_toggle": "Skift fartpilot",
"cruise_control_increase": "Øget fartpilot hastighed",
"seat_shuffle": "Skift sæde",
"discord_text": "Spiller: %s som %s %s",
"discord_text_small": "Spiller som: %s %s",
"discord_text_server": "Spiller: %s",
"pause_menu_cash": "Kontanter: %d",
"pause_menu_bank": "Bank: %d",
"veh_color_black": "Sort",
"veh_color_silver": "Sølv",
"veh_color_grey": "Grå",
"veh_color_metal": "Metal",
"veh_color_graphite": "Grafit",
"veh_color_red": "Rød",
"veh_color_orange": "Orange",
"veh_color_gold": "Guld",
"veh_color_yellow": "Gul",
"veh_color_green": "Grøn",
"veh_color_blue": "Blå",
"veh_color_bblue": "Lyseblå",
"veh_color_bronze": "Bronze",
"veh_color_lime": "Lime",
"veh_color_champagne": "Champagne",
"veh_color_beige": "Beige",
"veh_color_ivory": "Elfenben",
"veh_color_brown": "Brun",
"veh_color_beechwood": "Bøgetræ",
"veh_color_sand": "Sand",
"veh_color_cream": "Creme",
"veh_color_white": "Hvid",
"veh_color_steel": "Stål",
"veh_color_aluminium": "Aluminium",
"veh_color_chrome": "Krom",
"veh_color_pink": "Pink",
"veh_color_purple": "Lilla",
"veh_color_tan": "Tan",
"veh_color_alloy": "Legering",
"veh_class_compact": "Kompakt",
"veh_class_sedan": "Sedan",
"veh_class_suv": "SUV",
"veh_class_coupe": "Coupé",
"veh_class_muscle": "Muskelbil",
"veh_class_sports_classic": "Klassisk sportsvogn",
"veh_class_sport": "Sport",
"veh_class_super": "Superbil",
"veh_class_motorcycle": "Motorcykel",
"veh_class_off_road": "Off-road",
"veh_class_industrial": "Industriel",
"veh_class_utility": "Utility",
"veh_class_van": "Varevogn",
"veh_class_cycle": "Cykel",
"veh_class_boat": "Båd",
"veh_class_helicopter": "Helikopter",
"veh_class_plane": "Fly",
"veh_class_service": "Service",
"veh_class_emergency": "Nød",
"veh_class_military": "Militær",
"veh_class_commercial": "Kommerciel",
"veh_class_train": "Tog",
"veh_class_open_wheel": "Åben hjul"
}

134
locales/de.json Normal file
View File

@@ -0,0 +1,134 @@
{
"not_in_discord": "Dein Discord wurde nicht gefunden, trete unserem Discord hier bei: %s.",
"connecting": "Verbinde...",
"identifier_not_found": "Dein %s wurde nicht gefunden.",
"deposit": "Einzahlen",
"withdraw": "Abheben",
"vehicle_ownership_transfered": "Besitz übertragen",
"vehicle_ownership_transfered2": "Fahrzeugbesitz von %s wurde übertragen.",
"vehicle_ownership_received": "Besitz erhalten",
"vehicle_ownership_received2": "Fahrzeugbesitz von %s erhalten.",
"keys_shared": "Schlüssel geteilt",
"keys_shared2": "Du hast die Fahrzeugschlüssel an %s gegeben.",
"keys_received": "Schlüssel erhalten",
"keys_received2": "Du hast die Fahrzeugschlüssel von %s erhalten.",
"no_signal": "Kein Signal",
"veh_key_disabled": "Fahrzeugschlüssel deaktiviert.",
"veh_key_disabled2": "Dieser Fahrzeugschlüssel wurde deaktiviert und kann nicht mehr verwendet werden.",
"veh_far_away": "Fahrzeug zu weit entfernt.",
"veh_locked": "GESCHLOSSEN",
"veh_locked2": "Dein Fahrzeug ist jetzt abgeschlossen.",
"veh_unlocked": "GEÖFFNET",
"veh_unlocked2": "Dein Fahrzeug ist jetzt geöffnet.",
"garage": "Garage",
"no_owned_veh_nearby": "Kein eigenes Fahrzeug in der Nähe gefunden.",
"veh_stored_in_garage": "Fahrzeug in Garage gespeichert.",
"impound_reclaim": "Fahrzeug aus dem Abschlepphof zurückholen",
"impound": "Abschlepphof",
"impound_not_enough": "Der Preis zur Rückholung beträgt %d €, du hast nicht genug!",
"impound_paid": "%d € bezahlt, um das Fahrzeug zurückzuholen!",
"success": "Erfolg",
"staff_action": "Mitarbeiteraktion",
"staff_money_removed": "%d € (%s) von %s entfernt",
"user_money_removed": "%d € von %s entfernt",
"staff_money_added": "%d € (%s) zu %s hinzugefügt",
"user_money_added": "%d € zu %s hinzugefügt",
"staff_money_set": "%s's (%s) auf %d € gesetzt",
"user_money_set": "%s auf %d € gesetzt",
"job_updated_noti": "Job auf %s, Rang %s aktualisiert.",
"group_added_noti": "Zur Gruppe %s, Rang %s hinzugefügt.",
"group_removed_noti": "Aus der Gruppe %s entfernt.",
"no_player_found": "Kein Spieler gefunden",
"not_enough_cash": "Du hast nicht genug Bargeld",
"player_not_nearby": "Spieler nicht in der Nähe",
"cant_give_money": "Konnte kein Geld geben",
"money_received": "Geld erhalten",
"money_received2": "%d € in bar erhalten",
"money_given": "Geld gegeben",
"money_given2": "Du hast %d € in bar gegeben",
"player_in_veh": "Spieler im Fahrzeug!",
"perfect": "Perfekt",
"good": "Gut",
"bad": "Schlecht",
"very_bad": "Sehr schlecht",
"veh_make_brand": "Marke",
"veh_model": "Modell",
"veh_plate": "Kennzeichen",
"engine_status": "Motorstatus",
"vehicle": "Fahrzeug",
"not_found": "nicht gefunden",
"park_veh": "Fahrzeug parken",
"no_vehs_found": "Keine Fahrzeuge gefunden",
"vehicle_impound": "Fahrzeugabschlepphof",
"parking_garage": "Parkgarage",
"impound_w_location": "Abschlepphof (%s)",
"garage_w_location": "Parkgarage (%s)",
"view_impounded_vehs": "Abgeschleppte Fahrzeuge anzeigen",
"view_garage": "Garage anzeigen",
"personal_vehicle": "Privatfahrzeug",
"keybind_carkey": "Fahrzeug auf-/zusperren (Doppelklick)",
"progress_hotwiring": "Kurzschließen",
"cruise_control": "Tempomat",
"cruise_control_enabled": "Tempomat aktiviert",
"cruise_control_disabled": "Tempomat deaktiviert",
"cruise_control_toggle": "Tempomat umschalten",
"cruise_control_increase": "Tempomatgeschwindigkeit erhöht",
"seat_shuffle": "Sitz wechseln",
"discord_text": "Spielt: %s als %s %s",
"discord_text_small": "Spielt als: %s %s",
"discord_text_server": "Spielt: %s",
"pause_menu_cash": "Bargeld: €%d",
"pause_menu_bank": "Bank: €%d",
"veh_color_black": "Schwarz",
"veh_color_silver": "Silber",
"veh_color_grey": "Grau",
"veh_color_metal": "Metall",
"veh_color_graphite": "Graphit",
"veh_color_red": "Rot",
"veh_color_orange": "Orange",
"veh_color_gold": "Gold",
"veh_color_yellow": "Gelb",
"veh_color_green": "Grün",
"veh_color_blue": "Blau",
"veh_color_bblue": "Hellblau",
"veh_color_bronze": "Bronze",
"veh_color_lime": "Limette",
"veh_color_champagne": "Champagner",
"veh_color_beige": "Beige",
"veh_color_ivory": "Elfenbein",
"veh_color_brown": "Braun",
"veh_color_beechwood": "Buchenholz",
"veh_color_sand": "Sand",
"veh_color_cream": "Creme",
"veh_color_white": "Weiß",
"veh_color_steel": "Stahl",
"veh_color_aluminium": "Aluminium",
"veh_color_chrome": "Chrom",
"veh_color_pink": "Pink",
"veh_color_purple": "Lila",
"veh_color_tan": "Hellbraun",
"veh_color_alloy": "Legierung",
"veh_class_compact": "Kompakt",
"veh_class_sedan": "Limousine",
"veh_class_suv": "SUV",
"veh_class_coupe": "Coupé",
"veh_class_muscle": "Muscle-Car",
"veh_class_sports_classic": "Klassischer Sportwagen",
"veh_class_sport": "Sportwagen",
"veh_class_super": "Supersportwagen",
"veh_class_motorcycle": "Motorrad",
"veh_class_off_road": "Geländewagen",
"veh_class_industrial": "Industriefahrzeug",
"veh_class_utility": "Nutzfahrzeug",
"veh_class_van": "Van",
"veh_class_cycle": "Fahrrad",
"veh_class_boat": "Boot",
"veh_class_helicopter": "Hubschrauber",
"veh_class_plane": "Flugzeug",
"veh_class_service": "Service",
"veh_class_emergency": "Notfall",
"veh_class_military": "Militär",
"veh_class_commercial": "Gewerblich",
"veh_class_train": "Zug",
"veh_class_open_wheel": "Offenes Rad"
}

135
locales/en.json Normal file
View File

@@ -0,0 +1,135 @@
{
"not_in_discord": "Your discord was not found, join our discord here: %s.",
"connecting": "Connecting...",
"identifier_not_found": "Your %s was not found.",
"deposit": "Deposit",
"withdraw": "Withdraw",
"vehicle_ownership_transfered": "Ownership transfered",
"vehicle_ownership_transfered2": "Vehicle ownership of %s has been transfered.",
"vehicle_ownership_received": "Ownership received",
"vehicle_ownership_received2": "Received vehicle ownership of %s.",
"keys_shared": "Keys shared",
"keys_shared2": "You've shared vehicle keys to %s.",
"keys_received": "Keys received",
"keys_received2": "You've shared vehicle keys to %s.",
"no_signal": "No signal",
"veh_key_disabled": "Vehicle key disabled.",
"veh_key_disabled2": "This vehicle key has been disabled and cannot be used anymore.",
"veh_far_away": "Vehicle to far away.",
"veh_locked": "LOCKED",
"veh_locked2": "Your vehicle has now been locked.",
"veh_unlocked": "UNLOCKED",
"veh_unlocked2": "Your vehicle has now been unlocked.",
"garage": "Garage",
"no_owned_veh_nearby": "No owned vehicle found nearby.",
"veh_stored_in_garage": "Vehicle stored in garage.",
"impound_reclaim": "Vehicle impound reclaim",
"impound": "Impound",
"impound_not_enough": "Price to reclaim is $%d, you don't have enough!",
"impound_paid": "Paid $%d to reclaim vehicle!",
"success": "success",
"staff_action": "Staff action",
"staff_money_removed": "Removed $%d (%s) from %s",
"user_money_removed": "removed $%d from %s",
"staff_money_added": "Added $%d (%s) to %s",
"user_money_added": "added $%d to %s",
"staff_money_set": "Set %s's (%s) to $%d",
"user_money_set": "set %s to $%d",
"job_updated_noti": "Job updated to %s, rank %s.",
"group_added_noti": "Added to group %s, rank %s.",
"group_removed_noti": "Removed from group %s.",
"no_player_found": "No player found",
"not_enough_cash": "You don't have enough cash",
"player_not_nearby": "Player is not nearby",
"cant_give_money": "Couldn't give money",
"money_received": "Money received",
"money_received2": "Received $%d in cash",
"money_given": "Money given",
"money_given2": "You gave $%d in cash",
"player_in_veh": "Player in vehicle!",
"perfect": "Perfect",
"good": "Good",
"bad": "Bad",
"very_bad": "Very bad",
"veh_make_brand": "Make",
"veh_model": "Model",
"veh_plate": "Plate",
"engine_status": "Engine status",
"vehicle": "Vehicle",
"not_found": "not found",
"park_veh": "Park vehicle",
"no_vehs_found": "No vehicles found",
"vehicle_impound": "Vehicle impound",
"parking_garage": "Parking garage",
"impound_w_location": "Impound (%s)",
"garage_w_location": "Parking garage (%s)",
"view_impounded_vehs": "View impounded vehicles",
"view_garage": "View garage",
"personal_vehicle": "Personal vehicle",
"keybind_carkey": "Unlock/lock vehicle (double click)",
"progress_hotwiring": "Hotwiring",
"cruise_control": "Cruise control",
"cruise_control_enabled": "Vehicle cruise control enabled",
"cruise_control_disabled": "Vehicle cruise control disabled",
"cruise_control_toggle": "Toggle vehicle cruise control",
"cruise_control_increase": "Increased cruise control speed",
"seat_shuffle": "Shuffle vehicle seat",
"discord_text": "Playing: %s as %s %s",
"discord_text_small": "Playing as: %s %s",
"discord_text_server": "Playing: %s",
"pause_menu_cash": "Cash: $%d",
"pause_menu_bank": "Bank: $%d",
"veh_color_black": "Black",
"veh_color_silver": "Silver",
"veh_color_grey": "Grey",
"veh_color_metal": "Metal",
"veh_color_graphite": "Graphite",
"veh_color_red": "Red",
"veh_color_orange": "Orange",
"veh_color_gold": "Gold",
"veh_color_yellow": "Yellow",
"veh_color_green": "Green",
"veh_color_blue": "Blue",
"veh_color_bblue": "Bblue",
"veh_color_bronze": "Bronze",
"veh_color_lime": "Lime",
"veh_color_champagne": "Champagne",
"veh_color_beige": "Beige",
"veh_color_ivory": "Ivory",
"veh_color_brown": "Brown",
"veh_color_beechwood": "Beechwood",
"veh_color_sand": "Sand",
"veh_color_cream": "Cream",
"veh_color_white": "White",
"veh_color_steel": "Steel",
"veh_color_aluminium": "Aluminium",
"veh_color_chrome": "Chrome",
"veh_color_pink": "Pink",
"veh_color_purple": "Purple",
"veh_color_tan": "Tan",
"veh_color_alloy": "Alloy",
"veh_class_compact": "Compact",
"veh_class_sedan": "Sedan",
"veh_class_suv": "SUV",
"veh_class_coupe": "Coupe",
"veh_class_muscle": "Muscle",
"veh_class_sports_classic": "Sports Classic",
"veh_class_sport": "Sport",
"veh_class_super": "Super",
"veh_class_motorcycle": "Motorcycle",
"veh_class_off_road": "Off-road",
"veh_class_industrial": "Industrial",
"veh_class_utility": "Utility",
"veh_class_van": "Van",
"veh_class_cycle": "Cycle",
"veh_class_boat": "Boat",
"veh_class_helicopter": "Helicopter",
"veh_class_plane": "Plane",
"veh_class_service": "Service",
"veh_class_emergency": "Emergency",
"veh_class_military": "Military",
"veh_class_commercial": "Commercial",
"veh_class_train": "Train",
"veh_class_open_wheel": "Open wheel"
}

134
locales/es.json Normal file
View File

@@ -0,0 +1,134 @@
{
"not_in_discord": "No se encontró tu Discord, únete a nuestro Discord aquí: %s.",
"connecting": "Conectando...",
"identifier_not_found": "No se encontró tu %s.",
"deposit": "Depositar",
"withdraw": "Retirar",
"vehicle_ownership_transfered": "Propiedad transferida",
"vehicle_ownership_transfered2": "La propiedad del vehículo %s ha sido transferida.",
"vehicle_ownership_received": "Propiedad recibida",
"vehicle_ownership_received2": "Has recibido la propiedad del vehículo %s.",
"keys_shared": "Llaves compartidas",
"keys_shared2": "Has compartido las llaves del vehículo con %s.",
"keys_received": "Llaves recibidas",
"keys_received2": "Has recibido las llaves del vehículo de %s.",
"no_signal": "Sin señal",
"veh_key_disabled": "Llave del vehículo desactivada.",
"veh_key_disabled2": "Esta llave ha sido desactivada y no se puede usar más.",
"veh_far_away": "Vehículo demasiado lejos.",
"veh_locked": "BLOQUEADO",
"veh_locked2": "Tu vehículo ha sido bloqueado.",
"veh_unlocked": "DESBLOQUEADO",
"veh_unlocked2": "Tu vehículo ha sido desbloqueado.",
"garage": "Garaje",
"no_owned_veh_nearby": "No se encontró un vehículo propio cerca.",
"veh_stored_in_garage": "Vehículo guardado en el garaje.",
"impound_reclaim": "Recuperar vehículo del depósito",
"impound": "Depósito",
"impound_not_enough": "El precio para recuperar es %d €, ¡no tienes suficiente!",
"impound_paid": "¡Has pagado %d € para recuperar el vehículo!",
"success": "Éxito",
"staff_action": "Acción del personal",
"staff_money_removed": "Se retiraron %d € (%s) de %s",
"user_money_removed": "se retiraron %d € de %s",
"staff_money_added": "Se añadieron %d € (%s) a %s",
"user_money_added": "se añadieron %d € a %s",
"staff_money_set": "Se estableció %s's (%s) en %d €",
"user_money_set": "se estableció %s en %d €",
"job_updated_noti": "Trabajo actualizado a %s, rango %s.",
"group_added_noti": "Añadido al grupo %s, rango %s.",
"group_removed_noti": "Eliminado del grupo %s.",
"no_player_found": "No se encontró jugador",
"not_enough_cash": "No tienes suficiente dinero en efectivo",
"player_not_nearby": "El jugador no está cerca",
"cant_give_money": "No se pudo dar dinero",
"money_received": "Dinero recibido",
"money_received2": "Has recibido %d € en efectivo",
"money_given": "Dinero entregado",
"money_given2": "Has dado %d € en efectivo",
"player_in_veh": "¡Jugador en el vehículo!",
"perfect": "Perfecto",
"good": "Bueno",
"bad": "Malo",
"very_bad": "Muy malo",
"veh_make_brand": "Marca",
"veh_model": "Modelo",
"veh_plate": "Matrícula",
"engine_status": "Estado del motor",
"vehicle": "Vehículo",
"not_found": "no encontrado",
"park_veh": "Aparcar vehículo",
"no_vehs_found": "No se encontraron vehículos",
"vehicle_impound": "Depósito de vehículos",
"parking_garage": "Aparcamiento",
"impound_w_location": "Depósito (%s)",
"garage_w_location": "Aparcamiento (%s)",
"view_impounded_vehs": "Ver vehículos en el depósito",
"view_garage": "Ver garaje",
"personal_vehicle": "Vehículo personal",
"keybind_carkey": "Bloquear/desbloquear vehículo (doble clic)",
"progress_hotwiring": "Forzando encendido",
"cruise_control": "Control de crucero",
"cruise_control_enabled": "Control de crucero activado",
"cruise_control_disabled": "Control de crucero desactivado",
"cruise_control_toggle": "Alternar control de crucero",
"cruise_control_increase": "Velocidad de control de crucero aumentada",
"seat_shuffle": "Cambiar de asiento",
"discord_text": "Jugando: %s como %s %s",
"discord_text_small": "Jugando como: %s %s",
"discord_text_server": "Jugando: %s",
"pause_menu_cash": "Efectivo: €%d",
"pause_menu_bank": "Banco: €%d",
"veh_color_black": "Negro",
"veh_color_silver": "Plateado",
"veh_color_grey": "Gris",
"veh_color_metal": "Metal",
"veh_color_graphite": "Grafito",
"veh_color_red": "Rojo",
"veh_color_orange": "Naranja",
"veh_color_gold": "Oro",
"veh_color_yellow": "Amarillo",
"veh_color_green": "Verde",
"veh_color_blue": "Azul",
"veh_color_bblue": "Azul claro",
"veh_color_bronze": "Bronce",
"veh_color_lime": "Lima",
"veh_color_champagne": "Champán",
"veh_color_beige": "Beige",
"veh_color_ivory": "Marfil",
"veh_color_brown": "Marrón",
"veh_color_beechwood": "Haya",
"veh_color_sand": "Arena",
"veh_color_cream": "Crema",
"veh_color_white": "Blanco",
"veh_color_steel": "Acero",
"veh_color_aluminium": "Aluminio",
"veh_color_chrome": "Cromo",
"veh_color_pink": "Rosa",
"veh_color_purple": "Púrpura",
"veh_color_tan": "Bronceado",
"veh_color_alloy": "Aleación",
"veh_class_compact": "Compacto",
"veh_class_sedan": "Sedán",
"veh_class_suv": "SUV",
"veh_class_coupe": "Coupé",
"veh_class_muscle": "Muscle car",
"veh_class_sports_classic": "Deportivo clásico",
"veh_class_sport": "Deportivo",
"veh_class_super": "Superdeportivo",
"veh_class_motorcycle": "Motocicleta",
"veh_class_off_road": "Todoterreno",
"veh_class_industrial": "Industrial",
"veh_class_utility": "Utilitario",
"veh_class_van": "Furgoneta",
"veh_class_cycle": "Bicicleta",
"veh_class_boat": "Barco",
"veh_class_helicopter": "Helicóptero",
"veh_class_plane": "Avión",
"veh_class_service": "Servicio",
"veh_class_emergency": "Emergencia",
"veh_class_military": "Militar",
"veh_class_commercial": "Comercial",
"veh_class_train": "Tren",
"veh_class_open_wheel": "Rueda abierta"
}

134
locales/fi.json Normal file
View File

@@ -0,0 +1,134 @@
{
"not_in_discord": "Discord-tiliäsi ei löytynyt, liity Discordiimme täällä: %s.",
"connecting": "Yhdistetään...",
"identifier_not_found": "%s-tunnistetta ei löytynyt.",
"deposit": "Talleta",
"withdraw": "Nosta",
"vehicle_ownership_transfered": "Omistajuus siirretty",
"vehicle_ownership_transfered2": "Ajoneuvon %s omistajuus on siirretty.",
"vehicle_ownership_received": "Omistajuus vastaanotettu",
"vehicle_ownership_received2": "Olet saanut ajoneuvon %s omistajuuden.",
"keys_shared": "Avaimet jaettu",
"keys_shared2": "Olet jakanut ajoneuvon avaimet käyttäjälle %s.",
"keys_received": "Avaimet vastaanotettu",
"keys_received2": "Olet saanut ajoneuvon avaimet käyttäjältä %s.",
"no_signal": "Ei signaalia",
"veh_key_disabled": "Ajoneuvoavain poistettu käytöstä.",
"veh_key_disabled2": "Tämä ajoneuvoavain on poistettu käytöstä eikä sitä voi enää käyttää.",
"veh_far_away": "Ajoneuvo liian kaukana.",
"veh_locked": "LUKITTU",
"veh_locked2": "Ajoneuvosi on nyt lukittu.",
"veh_unlocked": "AVATTU",
"veh_unlocked2": "Ajoneuvosi on nyt avattu.",
"garage": "Autotalli",
"no_owned_veh_nearby": "Lähistöltä ei löytynyt omistamaasi ajoneuvoa.",
"veh_stored_in_garage": "Ajoneuvo tallennettu autotalliin.",
"impound_reclaim": "Ajoneuvon takaisinlunastus varikolta",
"impound": "Varikko",
"impound_not_enough": "Takaisinlunastuksen hinta on %d €, sinulla ei ole tarpeeksi rahaa!",
"impound_paid": "Maksettu %d € ajoneuvon takaisinlunastuksesta!",
"success": "Onnistui",
"staff_action": "Ylläpidon toimenpide",
"staff_money_removed": "Poistettu %d € (%s) käyttäjältä %s",
"user_money_removed": "poistettu %d € käyttäjältä %s",
"staff_money_added": "Lisätty %d € (%s) käyttäjälle %s",
"user_money_added": "lisätty %d € käyttäjälle %s",
"staff_money_set": "Asetettu %s (%s) summaksi %d €",
"user_money_set": "asetettu %s summaksi %d €",
"job_updated_noti": "Työ päivitetty: %s, taso %s.",
"group_added_noti": "Lisätty ryhmään %s, taso %s.",
"group_removed_noti": "Poistettu ryhmästä %s.",
"no_player_found": "Pelaajaa ei löytynyt",
"not_enough_cash": "Sinulla ei ole tarpeeksi käteistä",
"player_not_nearby": "Pelaaja ei ole lähellä",
"cant_give_money": "Rahan antaminen epäonnistui",
"money_received": "Raha vastaanotettu",
"money_received2": "Vastaanotettu %d € käteisenä",
"money_given": "Raha annettu",
"money_given2": "Annoit %d € käteisenä",
"player_in_veh": "Pelaaja ajoneuvossa!",
"perfect": "Täydellinen",
"good": "Hyvä",
"bad": "Huono",
"very_bad": "Todella huono",
"veh_make_brand": "Merkki",
"veh_model": "Malli",
"veh_plate": "Rekisterikilpi",
"engine_status": "Moottorin tila",
"vehicle": "Ajoneuvo",
"not_found": "ei löytynyt",
"park_veh": "Pysäköi ajoneuvo",
"no_vehs_found": "Ajoneuvoja ei löytynyt",
"vehicle_impound": "Ajoneuvovarikko",
"parking_garage": "Pysäköintihalli",
"impound_w_location": "Varikko (%s)",
"garage_w_location": "Pysäköintihalli (%s)",
"view_impounded_vehs": "Näytä varikolla olevat ajoneuvot",
"view_garage": "Näytä autotalli",
"personal_vehicle": "Henkilökohtainen ajoneuvo",
"keybind_carkey": "Lukitse/avaa ajoneuvo (kaksoisklikkaus)",
"progress_hotwiring": "Käynnistetään luvatta",
"cruise_control": "Vakionopeudensäädin",
"cruise_control_enabled": "Vakionopeudensäädin käytössä",
"cruise_control_disabled": "Vakionopeudensäädin pois käytöstä",
"cruise_control_toggle": "Vaihda vakionopeudensäädin päälle/pois",
"cruise_control_increase": "Vakionopeus kasvoi",
"seat_shuffle": "Vaihda istumapaikkaa ajoneuvossa",
"discord_text": "Pelaa: %s hahmona %s %s",
"discord_text_small": "Pelaa hahmona: %s %s",
"discord_text_server": "Pelaa: %s",
"pause_menu_cash": "Käteinen: €%d",
"pause_menu_bank": "Pankki: €%d",
"veh_color_black": "Musta",
"veh_color_silver": "Hopea",
"veh_color_grey": "Harmaa",
"veh_color_metal": "Metalli",
"veh_color_graphite": "Grafiitti",
"veh_color_red": "Punainen",
"veh_color_orange": "Oranssi",
"veh_color_gold": "Kulta",
"veh_color_yellow": "Keltainen",
"veh_color_green": "Vihreä",
"veh_color_blue": "Sininen",
"veh_color_bblue": "Vaaleansininen",
"veh_color_bronze": "Pronssi",
"veh_color_lime": "Lime",
"veh_color_champagne": "Samppanja",
"veh_color_beige": "Beige",
"veh_color_ivory": "Norsunluu",
"veh_color_brown": "Ruskea",
"veh_color_beechwood": "Pyökki",
"veh_color_sand": "Hiekka",
"veh_color_cream": "Kerma",
"veh_color_white": "Valkoinen",
"veh_color_steel": "Teräs",
"veh_color_aluminium": "Alumiini",
"veh_color_chrome": "Kromi",
"veh_color_pink": "Vaaleanpunainen",
"veh_color_purple": "Violetti",
"veh_color_tan": "Vaalea ruskea",
"veh_color_alloy": "Seosmetalli",
"veh_class_compact": "Pieni auto",
"veh_class_sedan": "Sedan",
"veh_class_suv": "SUV",
"veh_class_coupe": "Coupe",
"veh_class_muscle": "Muskeliauto",
"veh_class_sports_classic": "Klassinen urheiluauto",
"veh_class_sport": "Urheiluauto",
"veh_class_super": "Superauto",
"veh_class_motorcycle": "Moottoripyörä",
"veh_class_off_road": "Maastoauto",
"veh_class_industrial": "Teollisuusajoneuvo",
"veh_class_utility": "Hyötyajoneuvo",
"veh_class_van": "Pakettiauto",
"veh_class_cycle": "Polkupyörä",
"veh_class_boat": "Vene",
"veh_class_helicopter": "Helikopteri",
"veh_class_plane": "Lentokone",
"veh_class_service": "Huoltoajoneuvo",
"veh_class_emergency": "Hätäajoneuvo",
"veh_class_military": "Sotilasajoneuvo",
"veh_class_commercial": "Kaupallinen ajoneuvo",
"veh_class_train": "Juna",
"veh_class_open_wheel": "Avoin pyörä"
}

134
locales/fr.json Normal file
View File

@@ -0,0 +1,134 @@
{
"not_in_discord": "Votre Discord n'a pas été trouvé, rejoignez notre Discord ici : %s.",
"connecting": "Connexion...",
"identifier_not_found": "Votre %s n'a pas été trouvé.",
"deposit": "Dépôt",
"withdraw": "Retrait",
"vehicle_ownership_transfered": "Propriété transférée",
"vehicle_ownership_transfered2": "La propriété du véhicule %s a été transférée.",
"vehicle_ownership_received": "Propriété reçue",
"vehicle_ownership_received2": "Vous avez reçu la propriété du véhicule %s.",
"keys_shared": "Clés partagées",
"keys_shared2": "Vous avez partagé les clés du véhicule avec %s.",
"keys_received": "Clés reçues",
"keys_received2": "Vous avez reçu les clés du véhicule de %s.",
"no_signal": "Pas de signal",
"veh_key_disabled": "Clé de véhicule désactivée.",
"veh_key_disabled2": "Cette clé de véhicule a été désactivée et ne peut plus être utilisée.",
"veh_far_away": "Véhicule trop éloigné.",
"veh_locked": "VERROUILLÉ",
"veh_locked2": "Votre véhicule est maintenant verrouillé.",
"veh_unlocked": "DÉVERROUILLÉ",
"veh_unlocked2": "Votre véhicule est maintenant déverrouillé.",
"garage": "Garage",
"no_owned_veh_nearby": "Aucun véhicule possédé trouvé à proximité.",
"veh_stored_in_garage": "Véhicule rangé dans le garage.",
"impound_reclaim": "Récupération de véhicule mis en fourrière",
"impound": "Fourrière",
"impound_not_enough": "Le prix pour récupérer est de %d €, vous n'avez pas assez!",
"impound_paid": "Vous avez payé %d € pour récupérer le véhicule!",
"success": "succès",
"staff_action": "Action du staff",
"staff_money_removed": "%d € (%s) retiré de %s",
"user_money_removed": "%d € retiré de %s",
"staff_money_added": "%d € (%s) ajouté à %s",
"user_money_added": "%d € ajouté à %s",
"staff_money_set": "Solde de %s (%s) défini à %d €",
"user_money_set": "Solde de %s défini à %d €",
"job_updated_noti": "Emploi mis à jour en %s, grade %s.",
"group_added_noti": "Ajouté au groupe %s, grade %s.",
"group_removed_noti": "Retiré du groupe %s.",
"no_player_found": "Aucun joueur trouvé",
"not_enough_cash": "Vous n'avez pas assez d'argent liquide",
"player_not_nearby": "Joueur non à proximité",
"cant_give_money": "Impossible de donner de l'argent",
"money_received": "Argent reçu",
"money_received2": "Vous avez reçu %d € en liquide",
"money_given": "Argent donné",
"money_given2": "Vous avez donné %d € en liquide",
"player_in_veh": "Joueur dans un véhicule!",
"perfect": "Parfait",
"good": "Bon",
"bad": "Mauvais",
"very_bad": "Très mauvais",
"veh_make_brand": "Marque",
"veh_model": "Modèle",
"veh_plate": "Plaque",
"engine_status": "État du moteur",
"vehicle": "Véhicule",
"not_found": "introuvable",
"park_veh": "Garer le véhicule",
"no_vehs_found": "Aucun véhicule trouvé",
"vehicle_impound": "Fourrière",
"parking_garage": "Garage de stationnement",
"impound_w_location": "Fourrière (%s)",
"garage_w_location": "Garage (%s)",
"view_impounded_vehs": "Voir les véhicules en fourrière",
"view_garage": "Voir le garage",
"personal_vehicle": "Véhicule personnel",
"keybind_carkey": "Verrouiller/déverrouiller le véhicule (double clic)",
"progress_hotwiring": "Démarrage forcé",
"cruise_control": "Régulateur de vitesse",
"cruise_control_enabled": "Régulateur de vitesse activé",
"cruise_control_disabled": "Régulateur de vitesse désactivé",
"cruise_control_toggle": "Activer/désactiver le régulateur de vitesse",
"cruise_control_increase": "Vitesse du régulateur augmentée",
"seat_shuffle": "Changer de siège",
"discord_text": "Joue : %s en tant que %s %s",
"discord_text_small": "Joue en tant que : %s %s",
"discord_text_server": "Joue : %s",
"pause_menu_cash": "Argent liquide : €%d",
"pause_menu_bank": "Banque : €%d",
"veh_color_black": "Noir",
"veh_color_silver": "Argent",
"veh_color_grey": "Gris",
"veh_color_metal": "Métal",
"veh_color_graphite": "Graphite",
"veh_color_red": "Rouge",
"veh_color_orange": "Orange",
"veh_color_gold": "Or",
"veh_color_yellow": "Jaune",
"veh_color_green": "Vert",
"veh_color_blue": "Bleu",
"veh_color_bblue": "Bleu clair",
"veh_color_bronze": "Bronze",
"veh_color_lime": "Citron vert",
"veh_color_champagne": "Champagne",
"veh_color_beige": "Beige",
"veh_color_ivory": "Ivoire",
"veh_color_brown": "Marron",
"veh_color_beechwood": "Hêtre",
"veh_color_sand": "Sable",
"veh_color_cream": "Crème",
"veh_color_white": "Blanc",
"veh_color_steel": "Acier",
"veh_color_aluminium": "Aluminium",
"veh_color_chrome": "Chrome",
"veh_color_pink": "Rose",
"veh_color_purple": "Violet",
"veh_color_tan": "Fauve",
"veh_color_alloy": "Alliage",
"veh_class_compact": "Compact",
"veh_class_sedan": "Berline",
"veh_class_suv": "SUV",
"veh_class_coupe": "Coupé",
"veh_class_muscle": "Muscle car",
"veh_class_sports_classic": "Sport classique",
"veh_class_sport": "Sport",
"veh_class_super": "Super",
"veh_class_motorcycle": "Moto",
"veh_class_off_road": "Tout-terrain",
"veh_class_industrial": "Industriel",
"veh_class_utility": "Utilitaire",
"veh_class_van": "Van",
"veh_class_cycle": "Vélo",
"veh_class_boat": "Bateau",
"veh_class_helicopter": "Hélicoptère",
"veh_class_plane": "Avion",
"veh_class_service": "Service",
"veh_class_emergency": "Urgence",
"veh_class_military": "Militaire",
"veh_class_commercial": "Commercial",
"veh_class_train": "Train",
"veh_class_open_wheel": "Monoplace"
}

134
locales/it.json Normal file
View File

@@ -0,0 +1,134 @@
{
"not_in_discord": "Il tuo account Discord non è stato trovato, unisciti al nostro Discord qui: %s.",
"connecting": "Connessione in corso...",
"identifier_not_found": "Il tuo %s non è stato trovato.",
"deposit": "Deposito",
"withdraw": "Prelievo",
"vehicle_ownership_transfered": "Proprietà trasferita",
"vehicle_ownership_transfered2": "La proprietà del veicolo %s è stata trasferita.",
"vehicle_ownership_received": "Proprietà ricevuta",
"vehicle_ownership_received2": "Hai ricevuto la proprietà del veicolo %s.",
"keys_shared": "Chiavi condivise",
"keys_shared2": "Hai condiviso le chiavi del veicolo con %s.",
"keys_received": "Chiavi ricevute",
"keys_received2": "Hai ricevuto le chiavi del veicolo da %s.",
"no_signal": "Nessun segnale",
"veh_key_disabled": "Chiave del veicolo disattivata.",
"veh_key_disabled2": "Questa chiave del veicolo è stata disattivata e non può più essere utilizzata.",
"veh_far_away": "Veicolo troppo lontano.",
"veh_locked": "CHIUSO",
"veh_locked2": "Il tuo veicolo è ora chiuso.",
"veh_unlocked": "APERTO",
"veh_unlocked2": "Il tuo veicolo è ora aperto.",
"garage": "Garage",
"no_owned_veh_nearby": "Nessun veicolo di tua proprietà trovato nelle vicinanze.",
"veh_stored_in_garage": "Veicolo riposto in garage.",
"impound_reclaim": "Riscatto veicolo dal deposito",
"impound": "Deposito",
"impound_not_enough": "Il prezzo per riscattare è %d €, non hai abbastanza soldi!",
"impound_paid": "Hai pagato %d € per riscattare il veicolo!",
"success": "successo",
"staff_action": "Azione staff",
"staff_money_removed": "Rimossi %d € (%s) da %s",
"user_money_removed": "rimossi %d € da %s",
"staff_money_added": "Aggiunti %d € (%s) a %s",
"user_money_added": "aggiunti %d € a %s",
"staff_money_set": "Impostato il saldo di %s (%s) a %d €",
"user_money_set": "impostato %s a %d €",
"job_updated_noti": "Lavoro aggiornato a %s, grado %s.",
"group_added_noti": "Aggiunto al gruppo %s, grado %s.",
"group_removed_noti": "Rimosso dal gruppo %s.",
"no_player_found": "Nessun giocatore trovato",
"not_enough_cash": "Non hai abbastanza contanti",
"player_not_nearby": "Il giocatore non è vicino",
"cant_give_money": "Impossibile dare denaro",
"money_received": "Denaro ricevuto",
"money_received2": "Ricevuti %d € in contanti",
"money_given": "Denaro dato",
"money_given2": "Hai dato %d € in contanti",
"player_in_veh": "Giocatore in veicolo!",
"perfect": "Perfetto",
"good": "Buono",
"bad": "Scarso",
"very_bad": "Molto scarso",
"veh_make_brand": "Marca",
"veh_model": "Modello",
"veh_plate": "Targa",
"engine_status": "Stato motore",
"vehicle": "Veicolo",
"not_found": "non trovato",
"park_veh": "Parcheggia veicolo",
"no_vehs_found": "Nessun veicolo trovato",
"vehicle_impound": "Deposito veicoli",
"parking_garage": "Parcheggio",
"impound_w_location": "Deposito (%s)",
"garage_w_location": "Parcheggio (%s)",
"view_impounded_vehs": "Visualizza veicoli in deposito",
"view_garage": "Visualizza garage",
"personal_vehicle": "Veicolo personale",
"keybind_carkey": "Apri/chiudi veicolo (doppio click)",
"progress_hotwiring": "Avviamento forzato",
"cruise_control": "Cruise control",
"cruise_control_enabled": "Cruise control attivato",
"cruise_control_disabled": "Cruise control disattivato",
"cruise_control_toggle": "Attiva/disattiva cruise control",
"cruise_control_increase": "Velocità cruise control aumentata",
"seat_shuffle": "Cambia posto nel veicolo",
"discord_text": "Giocando: %s come %s %s",
"discord_text_small": "Giocando come: %s %s",
"discord_text_server": "Giocando: %s",
"pause_menu_cash": "Contanti: €%d",
"pause_menu_bank": "Banca: €%d",
"veh_color_black": "Nero",
"veh_color_silver": "Argento",
"veh_color_grey": "Grigio",
"veh_color_metal": "Metallo",
"veh_color_graphite": "Grafite",
"veh_color_red": "Rosso",
"veh_color_orange": "Arancione",
"veh_color_gold": "Oro",
"veh_color_yellow": "Giallo",
"veh_color_green": "Verde",
"veh_color_blue": "Blu",
"veh_color_bblue": "Blu chiaro",
"veh_color_bronze": "Bronzo",
"veh_color_lime": "Lime",
"veh_color_champagne": "Champagne",
"veh_color_beige": "Beige",
"veh_color_ivory": "Avorio",
"veh_color_brown": "Marrone",
"veh_color_beechwood": "Faggio",
"veh_color_sand": "Sabbia",
"veh_color_cream": "Crema",
"veh_color_white": "Bianco",
"veh_color_steel": "Acciaio",
"veh_color_aluminium": "Alluminio",
"veh_color_chrome": "Cromo",
"veh_color_pink": "Rosa",
"veh_color_purple": "Viola",
"veh_color_tan": "Marrone chiaro",
"veh_color_alloy": "Lega",
"veh_class_compact": "Compatta",
"veh_class_sedan": "Berlina",
"veh_class_suv": "SUV",
"veh_class_coupe": "Coupé",
"veh_class_muscle": "Muscle car",
"veh_class_sports_classic": "Sport classico",
"veh_class_sport": "Sport",
"veh_class_super": "Super",
"veh_class_motorcycle": "Motocicletta",
"veh_class_off_road": "Fuoristrada",
"veh_class_industrial": "Industriale",
"veh_class_utility": "Utility",
"veh_class_van": "Furgone",
"veh_class_cycle": "Bicicletta",
"veh_class_boat": "Barca",
"veh_class_helicopter": "Elicottero",
"veh_class_plane": "Aereo",
"veh_class_service": "Servizio",
"veh_class_emergency": "Emergenza",
"veh_class_military": "Militare",
"veh_class_commercial": "Commerciale",
"veh_class_train": "Treno",
"veh_class_open_wheel": "Ruota scoperta"
}

134
locales/nl.json Normal file
View File

@@ -0,0 +1,134 @@
{
"not_in_discord": "Je Discord-account is niet gevonden, sluit je hier aan bij onze Discord: %s.",
"connecting": "Verbinden...",
"identifier_not_found": "Je %s is niet gevonden.",
"deposit": "Storten",
"withdraw": "Opnemen",
"vehicle_ownership_transfered": "Eigendom overgedragen",
"vehicle_ownership_transfered2": "Het eigendom van het voertuig %s is overgedragen.",
"vehicle_ownership_received": "Eigendom ontvangen",
"vehicle_ownership_received2": "Je hebt het eigendom van voertuig %s ontvangen.",
"keys_shared": "Sleutels gedeeld",
"keys_shared2": "Je hebt voertuig sleutels gedeeld met %s.",
"keys_received": "Sleutels ontvangen",
"keys_received2": "Je hebt voertuig sleutels ontvangen van %s.",
"no_signal": "Geen signaal",
"veh_key_disabled": "Voertuigsleutel uitgeschakeld.",
"veh_key_disabled2": "Deze voertuigsleutel is uitgeschakeld en kan niet meer worden gebruikt.",
"veh_far_away": "Voertuig te ver weg.",
"veh_locked": "GESLOTEN",
"veh_locked2": "Je voertuig is nu gesloten.",
"veh_unlocked": "GEOPEND",
"veh_unlocked2": "Je voertuig is nu geopend.",
"garage": "Garage",
"no_owned_veh_nearby": "Geen eigendom voertuig in de buurt gevonden.",
"veh_stored_in_garage": "Voertuig opgeslagen in garage.",
"impound_reclaim": "Voertuig terugvorderen uit beslag",
"impound": "Beslag",
"impound_not_enough": "Prijs voor terugvordering is €%d, je hebt niet genoeg!",
"impound_paid": "€%d betaald om voertuig terug te vorderen!",
"success": "succes",
"staff_action": "Staf actie",
"staff_money_removed": "€%d (%s) verwijderd van %s",
"user_money_removed": "€%d verwijderd van %s",
"staff_money_added": "€%d (%s) toegevoegd aan %s",
"user_money_added": "€%d toegevoegd aan %s",
"staff_money_set": "Saldo van %s (%s) ingesteld op €%d",
"user_money_set": "Saldo van %s ingesteld op €%d",
"job_updated_noti": "Baan bijgewerkt naar %s, rang %s.",
"group_added_noti": "Toegevoegd aan groep %s, rang %s.",
"group_removed_noti": "Verwijderd uit groep %s.",
"no_player_found": "Geen speler gevonden",
"not_enough_cash": "Je hebt niet genoeg contant geld",
"player_not_nearby": "Speler is niet in de buurt",
"cant_give_money": "Kon geen geld geven",
"money_received": "Geld ontvangen",
"money_received2": "€%d contant ontvangen",
"money_given": "Geld gegeven",
"money_given2": "Je hebt €%d contant gegeven",
"player_in_veh": "Speler in voertuig!",
"perfect": "Perfect",
"good": "Goed",
"bad": "Slecht",
"very_bad": "Zeer slecht",
"veh_make_brand": "Merk",
"veh_model": "Model",
"veh_plate": "Kenteken",
"engine_status": "Motorstatus",
"vehicle": "Voertuig",
"not_found": "niet gevonden",
"park_veh": "Voertuig parkeren",
"no_vehs_found": "Geen voertuigen gevonden",
"vehicle_impound": "Voertuigen in beslag",
"parking_garage": "Parkeergarage",
"impound_w_location": "Beslag (%s)",
"garage_w_location": "Parkeergarage (%s)",
"view_impounded_vehs": "Bekijk in beslag genomen voertuigen",
"view_garage": "Bekijk garage",
"personal_vehicle": "Persoonlijk voertuig",
"keybind_carkey": "Voertuig openen/sluiten (dubbelklik)",
"progress_hotwiring": "Hotwiring",
"cruise_control": "Cruise control",
"cruise_control_enabled": "Cruise control ingeschakeld",
"cruise_control_disabled": "Cruise control uitgeschakeld",
"cruise_control_toggle": "Cruise control aan/uit",
"cruise_control_increase": "Cruise control snelheid verhoogd",
"seat_shuffle": "Stoel wisselen",
"discord_text": "Spelend: %s als %s %s",
"discord_text_small": "Spelend als: %s %s",
"discord_text_server": "Spelend: %s",
"pause_menu_cash": "Contant: €%d",
"pause_menu_bank": "Bank: €%d",
"veh_color_black": "Zwart",
"veh_color_silver": "Zilver",
"veh_color_grey": "Grijs",
"veh_color_metal": "Metaal",
"veh_color_graphite": "Grafiet",
"veh_color_red": "Rood",
"veh_color_orange": "Oranje",
"veh_color_gold": "Goud",
"veh_color_yellow": "Geel",
"veh_color_green": "Groen",
"veh_color_blue": "Blauw",
"veh_color_bblue": "Helderblauw",
"veh_color_bronze": "Brons",
"veh_color_lime": "Limoen",
"veh_color_champagne": "Champagne",
"veh_color_beige": "Beige",
"veh_color_ivory": "Ivoor",
"veh_color_brown": "Bruin",
"veh_color_beechwood": "Beukenhout",
"veh_color_sand": "Zand",
"veh_color_cream": "Crème",
"veh_color_white": "Wit",
"veh_color_steel": "Staal",
"veh_color_aluminium": "Aluminium",
"veh_color_chrome": "Chroom",
"veh_color_pink": "Roze",
"veh_color_purple": "Paars",
"veh_color_tan": "Bruin-beige",
"veh_color_alloy": "Alloy",
"veh_class_compact": "Compact",
"veh_class_sedan": "Sedan",
"veh_class_suv": "SUV",
"veh_class_coupe": "Coupe",
"veh_class_muscle": "Muscle",
"veh_class_sports_classic": "Sport Classic",
"veh_class_sport": "Sport",
"veh_class_super": "Super",
"veh_class_motorcycle": "Motorfiets",
"veh_class_off_road": "Off-road",
"veh_class_industrial": "Industrieel",
"veh_class_utility": "Utility",
"veh_class_van": "Bus",
"veh_class_cycle": "Fiets",
"veh_class_boat": "Boot",
"veh_class_helicopter": "Helikopter",
"veh_class_plane": "Vliegtuig",
"veh_class_service": "Dienst",
"veh_class_emergency": "Nooddienst",
"veh_class_military": "Militair",
"veh_class_commercial": "Commercieel",
"veh_class_train": "Trein",
"veh_class_open_wheel": "Open wiel"
}

134
locales/no.json Normal file
View File

@@ -0,0 +1,134 @@
{
"not_in_discord": "Discorden din ble ikke funnet, bli med i vår Discord her: %s.",
"connecting": "Kobler til...",
"identifier_not_found": "Din %s ble ikke funnet.",
"deposit": "Innskudd",
"withdraw": "Ta ut",
"vehicle_ownership_transfered": "Eierskap overført",
"vehicle_ownership_transfered2": "Eierskapet til kjøretøyet %s har blitt overført.",
"vehicle_ownership_received": "Eierskap mottatt",
"vehicle_ownership_received2": "Mottatt eierskap til kjøretøyet %s.",
"keys_shared": "Nøkler delt",
"keys_shared2": "Du har delt kjøretøynøkler med %s.",
"keys_received": "Nøkler mottatt",
"keys_received2": "Du har mottatt kjøretøynøkler fra %s.",
"no_signal": "Ingen signal",
"veh_key_disabled": "Kjøretøynøkkel deaktivert.",
"veh_key_disabled2": "Denne nøkkelen er deaktivert og kan ikke brukes lenger.",
"veh_far_away": "Kjøretøyet er for langt unna.",
"veh_locked": "LÅST",
"veh_locked2": "Kjøretøyet ditt er nå låst.",
"veh_unlocked": "ÅPEN",
"veh_unlocked2": "Kjøretøyet ditt er nå åpnet.",
"garage": "Garasje",
"no_owned_veh_nearby": "Ingen eide kjøretøy i nærheten.",
"veh_stored_in_garage": "Kjøretøy lagret i garasje.",
"impound_reclaim": "Hent kjøretøy fra beslag",
"impound": "Beslag",
"impound_not_enough": "Pris for å hente er %d kr, du har ikke nok!",
"impound_paid": "Betalt %d kr for å hente kjøretøy!",
"success": "suksess",
"staff_action": "Ansatt handling",
"staff_money_removed": "Fjernet %d kr (%s) fra %s",
"user_money_removed": "Fjernet %d kr fra %s",
"staff_money_added": "Lagt til %d kr (%s) til %s",
"user_money_added": "Lagt til %d kr til %s",
"staff_money_set": "Stilt inn %s sin (%s) til %d kr",
"user_money_set": "Stilt inn %s til %d kr",
"job_updated_noti": "Jobb oppdatert til %s, rang %s.",
"group_added_noti": "Lagt til gruppe %s, rang %s.",
"group_removed_noti": "Fjernet fra gruppe %s.",
"no_player_found": "Ingen spiller funnet",
"not_enough_cash": "Du har ikke nok kontanter",
"player_not_nearby": "Spiller er ikke i nærheten",
"cant_give_money": "Kunne ikke gi penger",
"money_received": "Penger mottatt",
"money_received2": "Mottatt %d kr kontant",
"money_given": "Penger gitt",
"money_given2": "Du ga %d kr kontant",
"player_in_veh": "Spiller i kjøretøy!",
"perfect": "Perfekt",
"good": "Bra",
"bad": "Dårlig",
"very_bad": "Veldig dårlig",
"veh_make_brand": "Merke",
"veh_model": "Modell",
"veh_plate": "Skilt",
"engine_status": "Motorstatus",
"vehicle": "Kjøretøy",
"not_found": "ikke funnet",
"park_veh": "Parker kjøretøy",
"no_vehs_found": "Ingen kjøretøy funnet",
"vehicle_impound": "Kjøretøy beslag",
"parking_garage": "Parkeringsgarasje",
"impound_w_location": "Beslag (%s)",
"garage_w_location": "Garasje (%s)",
"view_impounded_vehs": "Se beslaglagte kjøretøy",
"view_garage": "Se garasje",
"personal_vehicle": "Personlig kjøretøy",
"keybind_carkey": "Lås/åpne kjøretøy (dobbeltklikk)",
"progress_hotwiring": "Tjuvstart",
"cruise_control": "Cruise control",
"cruise_control_enabled": "Cruise control aktivert",
"cruise_control_disabled": "Cruise control deaktivert",
"cruise_control_toggle": "Bytt cruise control",
"cruise_control_increase": "Cruise control hastighet økt",
"seat_shuffle": "Bytt plass i kjøretøy",
"discord_text": "Spiller: %s som %s %s",
"discord_text_small": "Spiller som: %s %s",
"discord_text_server": "Spiller: %s",
"pause_menu_cash": "Kontanter: %d",
"pause_menu_bank": "Bank: %d",
"veh_color_black": "Svart",
"veh_color_silver": "Sølv",
"veh_color_grey": "Grå",
"veh_color_metal": "Metall",
"veh_color_graphite": "Grafitt",
"veh_color_red": "Rød",
"veh_color_orange": "Oransje",
"veh_color_gold": "Gull",
"veh_color_yellow": "Gul",
"veh_color_green": "Grønn",
"veh_color_blue": "Blå",
"veh_color_bblue": "Lyseblå",
"veh_color_bronze": "Bronse",
"veh_color_lime": "Lime",
"veh_color_champagne": "Champagne",
"veh_color_beige": "Beige",
"veh_color_ivory": "Elfenben",
"veh_color_brown": "Brun",
"veh_color_beechwood": "Bøk",
"veh_color_sand": "Sand",
"veh_color_cream": "Krem",
"veh_color_white": "Hvit",
"veh_color_steel": "Stål",
"veh_color_aluminium": "Aluminium",
"veh_color_chrome": "Krom",
"veh_color_pink": "Rosa",
"veh_color_purple": "Lilla",
"veh_color_tan": "Brunlig",
"veh_color_alloy": "Aluminiumlegering",
"veh_class_compact": "Kompakt",
"veh_class_sedan": "Sedan",
"veh_class_suv": "SUV",
"veh_class_coupe": "Coupe",
"veh_class_muscle": "Muscle",
"veh_class_sports_classic": "Sports Classic",
"veh_class_sport": "Sport",
"veh_class_super": "Super",
"veh_class_motorcycle": "Motorsykkel",
"veh_class_off_road": "Terreng",
"veh_class_industrial": "Industriell",
"veh_class_utility": "Nyttig",
"veh_class_van": "Varebil",
"veh_class_cycle": "Sykkel",
"veh_class_boat": "Båt",
"veh_class_helicopter": "Helikopter",
"veh_class_plane": "Fly",
"veh_class_service": "Service",
"veh_class_emergency": "Nød",
"veh_class_military": "Militær",
"veh_class_commercial": "Kommersiell",
"veh_class_train": "Tog",
"veh_class_open_wheel": "Åpen hjul"
}

134
locales/ru.json Normal file
View File

@@ -0,0 +1,134 @@
{
"not_in_discord": "Ваш Discord не найден, присоединяйтесь к нашему Discord здесь: %s.",
"connecting": "Подключение...",
"identifier_not_found": "Ваш %s не найден.",
"deposit": "Внести",
"withdraw": "Снять",
"vehicle_ownership_transfered": "Владение передано",
"vehicle_ownership_transfered2": "Владение транспортным средством %s было передано.",
"vehicle_ownership_received": "Владение получено",
"vehicle_ownership_received2": "Вы получили транспортное средство %s.",
"keys_shared": "Ключи переданы",
"keys_shared2": "Вы передали ключи от транспортного средства %s.",
"keys_received": "Ключи получены",
"keys_received2": "Вы получили ключи от транспортного средства %s.",
"no_signal": "Нет сигнала",
"veh_key_disabled": "Ключ от транспортного средства отключен.",
"veh_key_disabled2": "Этот ключ отключен и больше не может использоваться.",
"veh_far_away": "Транспорт слишком далеко.",
"veh_locked": "ЗАПЕРТО",
"veh_locked2": "Ваш транспорт теперь заперт.",
"veh_unlocked": "ОТКРЫТО",
"veh_unlocked2": "Ваш транспорт теперь открыт.",
"garage": "Гараж",
"no_owned_veh_nearby": "Вблизи не найдено вашего транспортного средства.",
"veh_stored_in_garage": "Транспортное средство помещено в гараж.",
"impound_reclaim": "Забрать транспорт из штрафстоянки",
"impound": "Штрафстоянка",
"impound_not_enough": "Цена за возврат %d₽, у вас недостаточно!",
"impound_paid": "Оплачено %d₽ за возврат транспортного средства!",
"success": "успешно",
"staff_action": "Действие персонала",
"staff_money_removed": "Удалено %d₽ (%s) у %s",
"user_money_removed": "Удалено %d₽ у %s",
"staff_money_added": "Добавлено %d₽ (%s) к %s",
"user_money_added": "Добавлено %d₽ к %s",
"staff_money_set": "Баланс %s (%s) установлен на %d₽",
"user_money_set": "Баланс %s установлен на %d₽",
"job_updated_noti": "Работа обновлена до %s, ранг %s.",
"group_added_noti": "Добавлен в группу %s, ранг %s.",
"group_removed_noti": "Удалён из группы %s.",
"no_player_found": "Игрок не найден",
"not_enough_cash": "У вас недостаточно наличных",
"player_not_nearby": "Игрок не рядом",
"cant_give_money": "Не удалось передать деньги",
"money_received": "Деньги получены",
"money_received2": "Получено %d₽ наличными",
"money_given": "Деньги переданы",
"money_given2": "Вы передали %d₽ наличными",
"player_in_veh": "Игрок в транспортном средстве!",
"perfect": "Идеально",
"good": "Хорошо",
"bad": "Плохо",
"very_bad": "Очень плохо",
"veh_make_brand": "Марка",
"veh_model": "Модель",
"veh_plate": "Номер",
"engine_status": "Состояние двигателя",
"vehicle": "Транспортное средство",
"not_found": "не найдено",
"park_veh": "Припарковать транспорт",
"no_vehs_found": "Транспортные средства не найдены",
"vehicle_impound": "Штрафстоянка",
"parking_garage": "Парковка",
"impound_w_location": "Штрафстоянка (%s)",
"garage_w_location": "Гараж (%s)",
"view_impounded_vehs": "Просмотр транспортных средств на штрафстоянке",
"view_garage": "Просмотр гаража",
"personal_vehicle": "Личный транспорт",
"keybind_carkey": "Открыть/закрыть транспорт (двойной клик)",
"progress_hotwiring": "Вскрытие замка",
"cruise_control": "Круиз-контроль",
"cruise_control_enabled": "Круиз-контроль включен",
"cruise_control_disabled": "Круиз-контроль выключен",
"cruise_control_toggle": "Переключить круиз-контроль",
"cruise_control_increase": "Скорость круиз-контроля увеличена",
"seat_shuffle": "Смена места в транспорте",
"discord_text": "Играет: %s как %s %s",
"discord_text_small": "Играет как: %s %s",
"discord_text_server": "Играет: %s",
"pause_menu_cash": "Наличные: ₽%d",
"pause_menu_bank": "Банк: ₽%d",
"veh_color_black": "Черный",
"veh_color_silver": "Серебристый",
"veh_color_grey": "Серый",
"veh_color_metal": "Металлик",
"veh_color_graphite": "Графит",
"veh_color_red": "Красный",
"veh_color_orange": "Оранжевый",
"veh_color_gold": "Золотой",
"veh_color_yellow": "Желтый",
"veh_color_green": "Зеленый",
"veh_color_blue": "Синий",
"veh_color_bblue": "Ярко-синий",
"veh_color_bronze": "Бронзовый",
"veh_color_lime": "Лаймовый",
"veh_color_champagne": "Шампанское",
"veh_color_beige": "Бежевый",
"veh_color_ivory": "Слоновая кость",
"veh_color_brown": "Коричневый",
"veh_color_beechwood": "Бук",
"veh_color_sand": "Песочный",
"veh_color_cream": "Кремовый",
"veh_color_white": "Белый",
"veh_color_steel": "Стальной",
"veh_color_aluminium": "Алюминий",
"veh_color_chrome": "Хром",
"veh_color_pink": "Розовый",
"veh_color_purple": "Фиолетовый",
"veh_color_tan": "Загар",
"veh_color_alloy": "Легкосплавный",
"veh_class_compact": "Компакт",
"veh_class_sedan": "Седан",
"veh_class_suv": "Внедорожник",
"veh_class_coupe": "Купе",
"veh_class_muscle": "Мускул",
"veh_class_sports_classic": "Спорт Классик",
"veh_class_sport": "Спорт",
"veh_class_super": "Супер",
"veh_class_motorcycle": "Мотоцикл",
"veh_class_off_road": "Внедорожник",
"veh_class_industrial": "Промышленный",
"veh_class_utility": "Утилитарный",
"veh_class_van": "Фургон",
"veh_class_cycle": "Велосипед",
"veh_class_boat": "Лодка",
"veh_class_helicopter": "Вертолет",
"veh_class_plane": "Самолет",
"veh_class_service": "Служебный",
"veh_class_emergency": "Экстренный",
"veh_class_military": "Военный",
"veh_class_commercial": "Коммерческий",
"veh_class_train": "Поезд",
"veh_class_open_wheel": "Открытые колеса"
}

135
locales/sv.json Normal file
View File

@@ -0,0 +1,135 @@
{
"not_in_discord": "Din Discord hittades inte, gå med i vår Discord här: %s.",
"connecting": "Ansluter...",
"identifier_not_found": "Din %s hittades inte.",
"deposit": "Sätt in",
"withdraw": "Ta ut",
"vehicle_ownership_transfered": "Ägarskap överfört",
"vehicle_ownership_transfered2": "Fordonets ägarskap för %s har överförts.",
"vehicle_ownership_received": "Ägarskap mottaget",
"vehicle_ownership_received2": "Mottagit fordonets ägarskap för %s.",
"keys_shared": "Nycklar delade",
"keys_shared2": "Du har delat fordonsnycklar med %s.",
"keys_received": "Nycklar mottagna",
"keys_received2": "Du har mottagit fordonsnycklar från %s.",
"no_signal": "Ingen signal",
"veh_key_disabled": "Fordonsnyckel inaktiverad.",
"veh_key_disabled2": "Denna fordonsnyckel har inaktiverats och kan inte längre användas.",
"veh_far_away": "Fordonet är för långt borta.",
"veh_locked": "LÅST",
"veh_locked2": "Ditt fordon är nu låst.",
"veh_unlocked": "OLÅST",
"veh_unlocked2": "Ditt fordon är nu olåst.",
"garage": "Garage",
"no_owned_veh_nearby": "Inget ägt fordon hittades i närheten.",
"veh_stored_in_garage": "Fordonet har placerats i garaget.",
"impound_reclaim": "Återtagning av beslagtaget fordon",
"impound": "Beslag",
"impound_not_enough": "Priset för att återta är %d kr, du har inte tillräckligt!",
"impound_paid": "Betalade %d kr för att återta fordonet!",
"success": "framgång",
"staff_action": "Personalåtgärd",
"staff_money_removed": "Tog bort %d kr (%s) från %s",
"user_money_removed": "tog bort %d kr från %s",
"staff_money_added": "Lade till %d kr (%s) till %s",
"user_money_added": "lade till %d kr till %s",
"staff_money_set": "Satte %s:s (%s) till %d kr",
"user_money_set": "satte %s till %d kr",
"job_updated_noti": "Jobb uppdaterat till %s, rang %s.",
"group_added_noti": "Tillagd i gruppen %s, rang %s.",
"group_removed_noti": "Borttagen från gruppen %s.",
"no_player_found": "Ingen spelare hittades",
"not_enough_cash": "Du har inte tillräckligt med kontanter",
"player_not_nearby": "Spelaren är inte i närheten",
"cant_give_money": "Kunde inte ge pengar",
"money_received": "Pengar mottagna",
"money_received2": "Mottog %d kr kontant",
"money_given": "Pengar givna",
"money_given2": "Du gav %d kr kontant",
"player_in_veh": "Spelaren är i fordon!",
"perfect": "Perfekt",
"good": "Bra",
"bad": "Dålig",
"very_bad": "Mycket dålig",
"veh_make_brand": "Märke",
"veh_model": "Modell",
"veh_plate": "Registreringsskylt",
"engine_status": "Motorstatus",
"vehicle": "Fordon",
"not_found": "hittades inte",
"park_veh": "Parkera fordon",
"no_vehs_found": "Inga fordon hittades",
"vehicle_impound": "Beslagtagna fordon",
"parking_garage": "Parkeringsgarage",
"impound_w_location": "Beslag (%s)",
"garage_w_location": "Parkeringsgarage (%s)",
"view_impounded_vehs": "Visa beslagtagna fordon",
"view_garage": "Visa garage",
"personal_vehicle": "Personligt fordon",
"keybind_carkey": "Lås/öppna fordon (dubbelklick)",
"progress_hotwiring": "Kopplar om",
"cruise_control": "Farthållare",
"cruise_control_enabled": "Fordonets farthållare aktiverad",
"cruise_control_disabled": "Fordonets farthållare avaktiverad",
"cruise_control_toggle": "Växla fordonets farthållare",
"cruise_control_increase": "Ökade farthållarens hastighet",
"seat_shuffle": "Byt plats i fordonet",
"discord_text": "Spelar: %s som %s %s",
"discord_text_small": "Spelar som: %s %s",
"discord_text_server": "Spelar: %s",
"pause_menu_cash": "Kontanter: %d",
"pause_menu_bank": "Bank: %d",
"veh_color_black": "Svart",
"veh_color_silver": "Silver",
"veh_color_grey": "Grå",
"veh_color_metal": "Metall",
"veh_color_graphite": "Grafit",
"veh_color_red": "Röd",
"veh_color_orange": "Orange",
"veh_color_gold": "Guld",
"veh_color_yellow": "Gul",
"veh_color_green": "Grön",
"veh_color_blue": "Blå",
"veh_color_bblue": "Ljusblå",
"veh_color_bronze": "Brons",
"veh_color_lime": "Lime",
"veh_color_champagne": "Champagne",
"veh_color_beige": "Beige",
"veh_color_ivory": "Elfenben",
"veh_color_brown": "Brun",
"veh_color_beechwood": "Bokträ",
"veh_color_sand": "Sand",
"veh_color_cream": "Kräm",
"veh_color_white": "Vit",
"veh_color_steel": "Stål",
"veh_color_aluminium": "Aluminium",
"veh_color_chrome": "Krom",
"veh_color_pink": "Rosa",
"veh_color_purple": "Lila",
"veh_color_tan": "Ljusbrun",
"veh_color_alloy": "Legering",
"veh_class_compact": "Kompakt",
"veh_class_sedan": "Sedan",
"veh_class_suv": "SUV",
"veh_class_coupe": "Coupé",
"veh_class_muscle": "Muskelbil",
"veh_class_sports_classic": "Klassisk sportbil",
"veh_class_sport": "Sport",
"veh_class_super": "Superbil",
"veh_class_motorcycle": "Motorcykel",
"veh_class_off_road": "Terräng",
"veh_class_industrial": "Industri",
"veh_class_utility": "Nyttolast",
"veh_class_van": "Skåpbil",
"veh_class_cycle": "Cykel",
"veh_class_boat": "Båt",
"veh_class_helicopter": "Helikopter",
"veh_class_plane": "Flygplan",
"veh_class_service": "Service",
"veh_class_emergency": "Utryckning",
"veh_class_military": "Militär",
"veh_class_commercial": "Kommersiell",
"veh_class_train": "Tåg",
"veh_class_open_wheel": "Öppen hjulbil"
}

View File

@@ -1,21 +1,21 @@
local moneyTypes = {"bank", "cash"} local moneyTypes = {"bank", "cash"}
local moneyActions = { local moneyActions = {
remove = function(player, account, amount) remove = function(player, account, amount)
player.deductMoney(account, amount, "Staff action") player.deductMoney(account, amount, locale("staff_action"))
return ("Removed $%d (%s) to %s"):format(amount, account, player.name), ("removed $%d from %s"):format(amount, account) return locale("staff_money_removed", amount, account, player.name), locale("user_money_removed", amount, account)
end, end,
add = function(player, account, amount) add = function(player, account, amount)
player.addMoney(account, amount, "Staff action") player.addMoney(account, amount, locale("staff_action"))
return ("Added $%d (%s) to %s"):format(amount, account, player.name), ("added $%d to %s"):format(amount, account) return locale("staff_money_added", amount, account, player.name), locale("user_money_added", amount, account)
end, end,
set = function(player, account, amount) set = function(player, account, amount)
player.setData(account, amount, "Staff action") player.setData(account, amount, locale("staff_action"))
return ("Set %s's (%s) to $%d"):format(player.name, account, amount), ("set %s to $%d"):format(account, amount) return locale("staff_money_set", player.name, account, amount), locale("user_money_set", account, amount)
end end
} }
lib.addCommand("setmoney", { lib.addCommand("setmoney", {
help = "Admin command, manage player money.", help = "Admin command, set a players money.",
restricted = "group.admin", restricted = "group.admin",
params = { params = {
{ {
@@ -48,17 +48,17 @@ lib.addCommand("setmoney", {
local staffMessage, userMessage = action(player, moneyType, args.amount) local staffMessage, userMessage = action(player, moneyType, args.amount)
player.notify({ player.notify({
title = "Staff action", title = locale("staff_action"),
description = userMessage, description = userMessage,
type = "inform", type = "inform",
duration = 10000 duration = 10000
}) })
if not source then return end if not source or source == 0 then return end
TriggerClientEvent("chat:addMessage", source, { TriggerClientEvent("chat:addMessage", source, {
color = {50, 100, 235}, color = {50, 100, 235},
multiline = true, multiline = true,
args = {"Staff action", staffMessage} args = {locale("staff_action"), staffMessage}
}) })
end) end)
@@ -90,17 +90,17 @@ lib.addCommand("setjob", {
local jobInfo = player.setJob(job, args.rank) local jobInfo = player.setJob(job, args.rank)
if not player or not jobInfo then return end if not player or not jobInfo then return end
player.notify({ player.notify({
title = "Staff action", title = locale("staff_action"),
description = ("Job updated to %s, rank %s"):format(jobInfo.label, jobInfo.rankName), description = locale("job_updated_noti", jobInfo.label, jobInfo.rankName),
type = "inform", type = "inform",
duration = 10000 duration = 10000
}) })
if not source then return end if not source or source == 0 then return end
TriggerClientEvent("chat:addMessage", source, { TriggerClientEvent("chat:addMessage", source, {
color = {50, 100, 235}, color = {50, 100, 235},
multiline = true, multiline = true,
args = {"Staff action", "success"} args = {locale("staff_action"), locale("success")}
}) })
end) end)
@@ -137,8 +137,8 @@ lib.addCommand("setgroup", {
local groupInfo = player.addGroup(args.group, args.rank) local groupInfo = player.addGroup(args.group, args.rank)
if not groupInfo then return end if not groupInfo then return end
player.notify({ player.notify({
title = "Staff action", title = locale("staff_action"),
description = ("Added to group %s, rank %s."):format(groupInfo.label, groupInfo.rankName), description = locale("group_added_noti", groupInfo.label, groupInfo.rankName),
type = "inform", type = "inform",
duration = 10000 duration = 10000
}) })
@@ -146,8 +146,8 @@ lib.addCommand("setgroup", {
local groupInfo = player.removeGroup(args.group) local groupInfo = player.removeGroup(args.group)
if not groupInfo then return end if not groupInfo then return end
player.notify({ player.notify({
title = "Staff action", title = locale("staff_action"),
description = ("Removed from group %s."):format(groupInfo.label), description = locale("group_removed_noti", groupInfo.label),
type = "inform", type = "inform",
duration = 10000 duration = 10000
}) })
@@ -155,16 +155,16 @@ lib.addCommand("setgroup", {
return return
end end
if not source then return end if not source or source == 0 then return end
TriggerClientEvent("chat:addMessage", source, { TriggerClientEvent("chat:addMessage", source, {
color = {50, 100, 235}, color = {50, 100, 235},
multiline = true, multiline = true,
args = {"Staff action", "success"} args = {locale("staff_action"), locale("success")}
}) })
end) end)
lib.addCommand("skin", { lib.addCommand("skin", {
help = "Admin command, set player into character clothing menu.", help = "Admin command, show character clothing menu for player.",
restricted = "group.admin", restricted = "group.admin",
params = { params = {
{ {
@@ -178,7 +178,7 @@ lib.addCommand("skin", {
end) end)
lib.addCommand("character", { lib.addCommand("character", {
help = "Admin command, set player into character selection menu.", help = "Admin command, show character selection menu for player.",
restricted = "group.admin", restricted = "group.admin",
params = { params = {
{ {
@@ -206,7 +206,7 @@ lib.addCommand("pay", {
} }
} }
}, function(source, args, raw) }, function(source, args, raw)
if not source then return end if not source or source == 0 then return end
local player = NDCore.getPlayer(source) local player = NDCore.getPlayer(source)
local targetPlayer = NDCore.getPlayer(args.target) local targetPlayer = NDCore.getPlayer(args.target)
@@ -214,7 +214,7 @@ lib.addCommand("pay", {
if not player or not targetPlayer then if not player or not targetPlayer then
return player.notify({ return player.notify({
title = "Error", title = "Error",
description = "No player found", description = locale("no_player_found"),
type = "error" type = "error"
}) })
end end
@@ -222,7 +222,7 @@ lib.addCommand("pay", {
if player.cash < args.amount then if player.cash < args.amount then
return player.notify({ return player.notify({
title = "Error", title = "Error",
description = "You don't have enough cash", description = locale("not_enough_cash"),
type = "error" type = "error"
}) })
end end
@@ -232,7 +232,7 @@ lib.addCommand("pay", {
if #(playerCoords-targetCoords) > 2.0 then if #(playerCoords-targetCoords) > 2.0 then
return player.notify({ return player.notify({
title = "Error", title = "Error",
description = "Player is not nearby", description = locale("player_not_nearby"),
type = "error" type = "error"
}) })
end end
@@ -240,60 +240,44 @@ lib.addCommand("pay", {
local success = player.deductMoney("cash", args.amount) and targetPlayer.addMoney("cash", args.amount) local success = player.deductMoney("cash", args.amount) and targetPlayer.addMoney("cash", args.amount)
if not success then if not success then
return player.notify({ return player.notify({
title = "Couldn't give money", title = locale("cant_give_money"),
type = "error", type = "error",
duration = 5000 duration = 5000
}) })
end end
targetPlayer.notify({ targetPlayer.notify({
title = "Money received", title = locale("money_received"),
description = ("Received $%d in cash"):format(args.amount), description = locale("money_received2", args.amount),
type = "inform", type = "inform",
duration = 5000 duration = 5000
}) })
player.notify({ player.notify({
title = "Money given", title = locale("money_given"),
description = ("You gave $%d in cash"):format(args.amount), description = locale("money_given2", args.amount),
type = "inform", type = "inform",
duration = 5000 duration = 5000
}) })
end) end)
lib.addCommand("unlock", { lib.addCommand("unlock", {
help = "Admin Command, force unlock vehicle.", help = "Admin Command, force unlock a vehicle.",
restricted = "group.admin", restricted = "group.admin",
}, function(source, args, raw) }, function(source, args, raw)
local ped = GetPlayerPed(source) local ped = GetPlayerPed(source)
local playerVeh = GetVehiclePedIsIn(ped)
local coords = GetEntityCoords(ped) local coords = GetEntityCoords(ped)
local vehicles = GetAllVehicles() local veh = lib.getClosestVehicle(coords, 2.5, true)
local maxDistance = 2.0
local closestVehicle
if not playerVeh or playerVeh == 0 or not DoesEntityExist(playerVeh) then if not veh then return end
for i=1, #vehicles do
local vehicle = vehicles[i] local state = Entity(veh).state
local vehicleCoords = GetEntityCoords(vehicle) state.hotwired = true
local distance = #(coords-vehicleCoords) state.locked = false
if distance < maxDistance then
maxDistance = distance
closestVehicle = vehicle
end
end
if not closestVehicle or not DoesEntityExist(closestVehicle) then return end
local state = Entity(closestVehicle).state
state.locked = false
else
local state = Entity(playerVeh).state
state.hotwired = true
end
end) end)
lib.addCommand("revive", { lib.addCommand("revive", {
help = "Admin command, revive player.", help = "Admin command, revive a player.",
restricted = "group.admin", restricted = "group.admin",
params = { params = {
{ {
@@ -321,48 +305,37 @@ lib.addCommand("dv", {
} }
}, function(source, args, raw) }, function(source, args, raw)
local ped = GetPlayerPed(source) local ped = GetPlayerPed(source)
local veh = GetVehiclePedIsIn(ped)
if veh and veh ~= 0 and DoesEntityExist(veh) then
DeleteEntity(veh)
return TriggerClientEvent("chat:addMessage", source, {
color = {50, 100, 235},
multiline = true,
args = {"Staff action", "deleted 1 vehicle"}
})
end
local count = 0
local coords = GetEntityCoords(ped) local coords = GetEntityCoords(ped)
local count = 0
local message = nil
local veh = lib.getClosestVehicle(coords, 3.0)
if args.range then if args.range then
for _, veh in ipairs(GetAllVehicles()) do local vehicles = lib.getNearbyVehicles(coords, args.range)
local vehDist = #(GetEntityCoords(veh) - coords) count = #vehicles
if vehDist < args.range then
DeleteEntity(veh) for i=1, count do
count += 1 local veh = vehicles[i]
end DeleteEntity(veh.vehicle)
end end
return TriggerClientEvent("chat:addMessage", source, { elseif veh then
color = {50, 100, 235}, DeleteEntity(veh)
multiline = true, count = 1
args = {"Staff action", ("deleted %d vehicles"):format(count)}
})
end end
local closest, dist local messageLabel = ("%s [dv]"):format(locale("staff_action"))
for _, veh in ipairs(GetAllVehicles()) do if count == 0 then
local vehDist = #(GetEntityCoords(veh) - coords) message = {messageLabel, "no vehicles found"}
if vehDist < 5.0 and not closest or (dist and dist > vehDist) then elseif count == 1 then
closest = veh message = {messageLabel, "deleted 1 vehicle"}
dist = vehDist else
end message = {messageLabel, ("deleted %d vehicles"):format(count)}
end end
if not closest then return "no vehicle found nearby" end
DeleteEntity(closest)
TriggerClientEvent("chat:addMessage", source, { TriggerClientEvent("chat:addMessage", source, {
color = {50, 100, 235}, color = {50, 100, 235},
multiline = true, multiline = true,
args = {"Staff action", "deleted 1 vehicle"} args = message
}) })
end) end)
@@ -433,7 +406,7 @@ lib.addCommand("unfreeze", {
end) end)
lib.addCommand("vehicle", { lib.addCommand("vehicle", {
help = "Admin command, unfreeze a player.", help = "Admin command, spawn a vehicle.",
restricted = "group.admin", restricted = "group.admin",
params = { params = {
{ {
@@ -466,3 +439,45 @@ lib.addCommand("vehicle", {
Wait(100) Wait(100)
end end
end) end)
lib.addCommand("claim-veh", {
help = "Admin command, add a copy of the vehicle you're inside to players garage.",
restricted = "group.admin",
params = {
{
name = "target",
type = "playerId",
help = "Target player's server id"
}
}
}, function(source, args, raw)
local player = NDCore.getPlayer(source)
if not player then return end
local targetPlayer = NDCore.getPlayer(args.target)
if not targetPlayer then
return player.notify({
title = "Player not found!",
description = "Target player not found, make sure they select a charcter!",
type = "error"
})
end
local properties = lib.callback.await("ND_Vehicles:getPropsFromCurrentVeh", source)
if not properties then
return player.notify({
title = "Vehicle data not found!",
description = "The vehicle properties data was not found!",
type = "error"
})
end
NDCore.setVehicleOwned(targetPlayer.id, properties, true)
player.notify({
title = "Vehicle added!",
description = ("The vehicle has now been added to %s's garage!"):format(targetPlayer.name),
type = "success"
})
end)

View File

@@ -1,3 +1,10 @@
function NDCore.getPlayerIdentifierByType(src, indentifierType)
if Config.sv_lan then
return ("%s:sv_lan"):format(indentifierType)
end
return GetPlayerIdentifierByType(src, indentifierType)
end
---@param src number ---@param src number
---@return table ---@return table
function NDCore.getPlayer(src) function NDCore.getPlayer(src)
@@ -11,7 +18,16 @@ function NDCore.getPlayers(key, value, returnArray)
if not key or not value then return NDCore.players end if not key or not value then return NDCore.players end
local players = {} local players = {}
local keyTypes = {id = "id", firstname = "firstname", lastname = "lastname", gender = "gender", groups = "groups"} local keyTypes = {
id = "id",
firstname = "firstname",
lastname = "lastname",
gender = "gender",
groups = "groups",
job = "job",
gender = "gender"
}
local findBy = keyTypes[key] or "metadata" local findBy = keyTypes[key] or "metadata"
if findBy then if findBy then

View File

@@ -1,3 +1,4 @@
lib.locale()
NDCore = {} NDCore = {}
NDCore.players = {} NDCore.players = {}
PlayersInfo = {} PlayersInfo = {}
@@ -24,14 +25,19 @@ Config = {
groups = json.decode(GetConvar("core:groups", "[]")), groups = json.decode(GetConvar("core:groups", "[]")),
admins = json.decode(GetConvar("core:admins", "[]")), admins = json.decode(GetConvar("core:admins", "[]")),
adminDiscordRoles = json.decode(GetConvar("core:adminDiscordRoles", "[]")), adminDiscordRoles = json.decode(GetConvar("core:adminDiscordRoles", "[]")),
groupRoles = json.decode(GetConvar("core:groupRoles", "[]")),
multiCharacter = false, multiCharacter = false,
compatibility = json.decode(GetConvar("core:compatibility", "[]")) compatibility = json.decode(GetConvar("core:compatibility", "[]")),
sv_lan = GetConvar("sv_lan", "false") == "true",
platePattern = GetConvar("core:platePattern", "11AAA111")
} }
SetConvarServerInfo("Discord", Config.discordInvite) SetConvarServerInfo("Discord", Config.discordInvite)
SetConvarServerInfo("NDCore", GetResourceMetadata(resourceName, "version", 0) or "invalid") SetConvarServerInfo("NDCore", GetResourceMetadata(resourceName, "version", 0) or "invalid")
SetConvarReplicated("inventory:framework", "nd") SetConvarReplicated("inventory:framework", "nd")
lib.versionCheck('ND-Framework/ND_Core')
local function getIdentifierList(src) local function getIdentifierList(src)
local list = {} local list = {}
for i=0, GetNumPlayerIdentifiers(src) do for i=0, GetNumPlayerIdentifiers(src) do
@@ -42,6 +48,11 @@ local function getIdentifierList(src)
list[identifierType] = identifier list[identifierType] = identifier
end end
end end
if Config.sv_lan then
list[Config.characterIdentifier] = NDCore.getPlayerIdentifierByType(src, Config.characterIdentifier)
end
return list return list
end end
@@ -51,6 +62,10 @@ AddEventHandler("playerJoining", function(oldId)
PlayersInfo[src] = tempPlayersInfo[oldTempId] PlayersInfo[src] = tempPlayersInfo[oldTempId]
tempPlayersInfo[oldTempId] = nil tempPlayersInfo[oldTempId] = nil
if Config.sv_lan then
lib.addPrincipal(("player.%s"):format(src), "group.admin")
end
if Config.multiCharacter then return end if Config.multiCharacter then return end
Wait(3000) Wait(3000)
@@ -102,15 +117,26 @@ AddEventHandler("playerConnecting", function(name, setKickReason, deferrals)
if mainIdentifier and Config.discordBotToken ~= "false" and Config.discordGuildId ~= "false" then if mainIdentifier and Config.discordBotToken ~= "false" and Config.discordGuildId ~= "false" then
discordInfo = checkDiscordIdentifier(identifiers) discordInfo = checkDiscordIdentifier(identifiers)
if not discordInfo and Config.discordMemeberRequired then if not discordInfo and Config.discordMemeberRequired and not Config.sv_lan then
deferrals.done(("Your discord was not found, join our discord here: %s."):format(Config.discordInvite)) deferrals.done(locale("not_in_discord", Config.discordInvite))
Wait(0) Wait(0)
end end
end end
deferrals.update("Connecting...") deferrals.update(locale("connecting"))
Wait(0) Wait(0)
if Config.sv_lan then
tempPlayersInfo[tempSrc] = {
identifiers = {
[Config.characterIdentifier] = "sv_lan"
},
discord = discordInfo
}
deferrals.done()
return
end
if mainIdentifier then if mainIdentifier then
tempPlayersInfo[tempSrc] = { tempPlayersInfo[tempSrc] = {
identifiers = identifiers, identifiers = identifiers,
@@ -118,7 +144,7 @@ AddEventHandler("playerConnecting", function(name, setKickReason, deferrals)
} }
deferrals.done() deferrals.done()
else else
deferrals.done(("Your %s was not found."):format(Config.characterIdentifier)) deferrals.done(locale("identifier_not_found", Config.characterIdentifier))
Wait(0) Wait(0)
end end
end) end)
@@ -138,7 +164,8 @@ AddEventHandler("onResourceStop", function(name)
end end
end) end)
SetTimeout(500, function() MySQL.ready(function()
Wait(100)
NDCore.loadSQL({ NDCore.loadSQL({
"database/characters.sql", "database/characters.sql",
"database/vehicles.sql" "database/vehicles.sql"
@@ -154,3 +181,10 @@ RegisterNetEvent("ND:playerEliminated", function(info)
deathInfo = info deathInfo = info
}) })
end) end)
RegisterNetEvent("ND:updateClothing", function(clothing)
local src = source
local player = NDCore.getPlayer(src)
if not player or not clothing or type(clothing) ~= "table" then return end
player.setMetadata("clothing", clothing)
end)

View File

@@ -1,3 +1,5 @@
local avoidSavingLastLocations = {}
local function removeCharacterFunctions(character) local function removeCharacterFunctions(character)
local newData = {} local newData = {}
for k, v in pairs(character) do for k, v in pairs(character) do
@@ -66,7 +68,7 @@ local function createCharacterTable(info)
function self.depositMoney(amount) function self.depositMoney(amount)
local amount = tonumber(amount) local amount = tonumber(amount)
if not amount or self.cash < amount or amount <= 0 then return end if not amount or self.cash < amount or amount <= 0 then return end
return self.deductMoney("cash", amount, "Deposit") and self.addMoney("bank", amount, "Deposit") return self.deductMoney("cash", amount, locale("deposit")) and self.addMoney("bank", amount, locale("deposit"))
end end
---@param amount number ---@param amount number
@@ -74,7 +76,7 @@ local function createCharacterTable(info)
function self.withdrawMoney(amount) function self.withdrawMoney(amount)
local amount = tonumber(amount) local amount = tonumber(amount)
if not amount or self.bank < amount or amount <= 0 then return end if not amount or self.bank < amount or amount <= 0 then return end
return self.deductMoney("bank", amount, "Withdraw") and self.addMoney("cash", amount, "Withdraw") return self.deductMoney("bank", amount, locale("withdraw")) and self.addMoney("cash", amount, locale("withdraw"))
end end
---@param data string ---@param data string
@@ -113,7 +115,8 @@ local function createCharacterTable(info)
TriggerEvent("ND:moneyChange", self.source, key, value, "set", reason) TriggerEvent("ND:moneyChange", self.source, key, value, "set", reason)
end end
end end
self.triggerEvent("ND:updateCharacter", removeCharacterFunctions(self)) self.triggerEvent("ND:updateCharacter", removeCharacterFunctions(self), key)
TriggerEvent("ND:updateCharacter", self, key)
end end
---@param key string|table ---@param key string|table
@@ -127,7 +130,8 @@ local function createCharacterTable(info)
else else
self.metadata[key] = value self.metadata[key] = value
end end
self.triggerEvent("ND:updateCharacter", removeCharacterFunctions(self)) self.triggerEvent("ND:updateCharacter", removeCharacterFunctions(self), "metadata")
TriggerEvent("ND:updateCharacter", self, "metadata")
return self.metadata return self.metadata
end end
@@ -143,24 +147,40 @@ local function createCharacterTable(info)
-- Unload and save character -- Unload and save character
function self.unload() function self.unload()
if not NDCore.players[self.source] then return end if not NDCore.players[self.source] then return end
for name, _ in pairs(self.groups) do for name, _ in pairs(self.groups) do
lib.removePrincipal(self.source, ("group.%s"):format(name)) lib.removePrincipal(self.source, ("group.%s"):format(name))
end end
local ped = GetPlayerPed(self.source) local ped = GetPlayerPed(self.source)
if ped then if ped then
local coords = GetEntityCoords(ped) local coords = GetEntityCoords(ped)
local heading = GetEntityHeading(ped) local heading = GetEntityHeading(ped)
self.setMetadata("location", { local saveLocation = true
x = coords.x,
y = coords.y, for i=1, #avoidSavingLastLocations do
z = coords.z, local loc = avoidSavingLastLocations[i]
w = heading if #(loc.coords-coords) < loc.dist then
}) saveLocation = false
end
end
if saveLocation then
self.setMetadata("location", {
x = coords.x,
y = coords.y,
z = coords.z,
w = heading
})
end
end end
self.triggerEvent("ND:characterUnloaded") self.triggerEvent("ND:characterUnloaded")
TriggerEvent("ND:characterUnloaded", self.source, self) TriggerEvent("ND:characterUnloaded", self.source, self)
local saved = self.save() local saved = self.save()
NDCore.players[self.source] = nil NDCore.players[self.source] = nil
return saved return saved
end end
@@ -219,11 +239,24 @@ local function createCharacterTable(info)
} }
if licenses then if licenses then
self.metadata.licenses[#licenses+1] = license local found = false
for i=1, #licenses do
if licenses[i].type == licenseType then
self.metadata.licenses[i] = license
found = true
break
end
end
if not found then
self.metadata.licenses[#licenses+1] = license
end
else else
self.metadata.licenses = {license} self.metadata.licenses = {license}
end end
self.triggerEvent("ND:updateCharacter", removeCharacterFunctions(self)) self.triggerEvent("ND:updateCharacter", removeCharacterFunctions(self), "metadata")
TriggerEvent("ND:updateCharacter", self, "metadata")
end end
function self.getLicense(identifier) function self.getLicense(identifier)
@@ -306,6 +339,12 @@ local function createCharacterTable(info)
self.addGroup("admin") self.addGroup("admin")
end end
end end
for group, role in pairs(Config.groupRoles) do
if lib.table.contains(roles, role) then
self.addGroup(group)
end
end
end end
for name, _ in pairs(self.groups) do for name, _ in pairs(self.groups) do
@@ -320,12 +359,15 @@ local function createCharacterTable(info)
---@param rank number ---@param rank number
---@param isJob boolean ---@param isJob boolean
---@return boolean ---@return boolean
function self.addGroup(name, rank, isJob) function self.addGroup(name, rank, customGroup, isJob)
local groupRank = tonumber(rank) or 1 local groupRank = tonumber(rank) or 1
local groupInfo = Config.groups?[name] local groupInfo = lib.table.deepclone(Config.groups?[name] or {})
local bossRank = groupInfo and groupInfo.minimumBossRank local bossRank = groupInfo?.minimumBossRank
for k, v in pairs(customGroup or {}) do
groupInfo[k] = v
end
-- if not groupInfo then return end
if isJob then if isJob then
for _, group in pairs(self.groups) do for _, group in pairs(self.groups) do
group.isJob = nil group.isJob = nil
@@ -334,17 +376,21 @@ local function createCharacterTable(info)
self.groups[name] = { self.groups[name] = {
name = name, name = name,
label = groupInfo and groupInfo.label or name, label = groupInfo?.label or name,
rankName = groupInfo and groupInfo.ranks[groupRank] or groupRank, rankName = groupInfo?.ranks?[groupRank] or groupRank,
rank = groupRank, rank = groupRank,
isJob = isJob, isJob = isJob,
isBoss = bossRank and groupRank >= bossRank isBoss = bossRank and groupRank >= bossRank,
metadata = groupInfo.metadata or {}
} }
if not isJob then if not isJob then
self.triggerEvent("ND:updateCharacter", removeCharacterFunctions(self)) self.triggerEvent("ND:updateCharacter", removeCharacterFunctions(self), "groups")
TriggerEvent("ND:updateCharacter", self, "groups")
end end
lib.addPrincipal(self.source, ("group.%s"):format(name)) lib.addPrincipal(self.source, ("group.%s"):format(name))
return self.groups[name] return self.groups[name]
end end
@@ -365,7 +411,9 @@ local function createCharacterTable(info)
end end
self.groups[name] = nil self.groups[name] = nil
self.triggerEvent("ND:updateCharacter", removeCharacterFunctions(self)) self.triggerEvent("ND:updateCharacter", removeCharacterFunctions(self), "groups")
TriggerEvent("ND:updateCharacter", self, "groups")
TriggerEvent("ND:groupRemoved", self, group)
lib.removePrincipal(self.source, ("group.%s"):format(name)) lib.removePrincipal(self.source, ("group.%s"):format(name))
return group return group
end end
@@ -373,14 +421,15 @@ local function createCharacterTable(info)
---@param name string ---@param name string
---@param rank number ---@param rank number
---@return boolean ---@return boolean
function self.setJob(name, rank) function self.setJob(name, rank, customGroup)
self.removeGroup(self.job) self.removeGroup(self.job)
local job = self.addGroup(name, rank, true) local job = self.addGroup(name, rank, customGroup, true)
if job then if job then
self.job = job.name self.job = job.name
self.jobInfo = job self.jobInfo = job
end end
self.triggerEvent("ND:updateCharacter", removeCharacterFunctions(self)) self.triggerEvent("ND:updateCharacter", removeCharacterFunctions(self), "job")
TriggerEvent("ND:updateCharacter", self, "job")
return job return job
end end
@@ -403,11 +452,40 @@ local function createCharacterTable(info)
return self return self
end end
function NDCore.avoidSavingLocation(coords, dist)
avoidSavingLastLocations[#avoidSavingLastLocations+1] = { coords = coords, dist = dist}
end
function NDCore.validateCharacterData(charInfo)
local errors = {}
local function checkLength(field, value, maxLength)
if type(value) ~= "string" then return end
if #value > maxLength then
table.insert(errors, string.format("%s is too long (max %d, got %d)", field, maxLength, #value))
end
end
if charInfo.name then checkLength("game name", charInfo.name, 50) end
if charInfo.firstname then checkLength("firstname", charInfo.firstname, 50) end
if charInfo.lastname then checkLength("lastname", charInfo.lastname, 50) end
if charInfo.dob then checkLength("dob", charInfo.dob, 50) end
if charInfo.gender then checkLength("gender", charInfo.gender, 50) end
if type(charInfo.cash) ~= "number" then table.insert(errors, "cash must be a number") end
if type(charInfo.bank) ~= "number" then table.insert(errors, "bank must be a number") end
if #errors > 0 then
return false, errors
else
return true, {}
end
end
---@param src number ---@param src number
---@param info table ---@param info table
---@return table ---@return table
function NDCore.newCharacter(src, info) function NDCore.newCharacter(src, info)
local identifier = GetPlayerIdentifierByType(src, Config.characterIdentifier) local identifier = NDCore.getPlayerIdentifierByType(src, Config.characterIdentifier)
if not identifier then return end if not identifier then return end
local charInfo = { local charInfo = {
@@ -426,7 +504,19 @@ function NDCore.newCharacter(src, info)
inventory = info.inventory or {} inventory = info.inventory or {}
} }
charInfo.id = MySQL.insert.await("INSERT INTO nd_characters (identifier, name, firstname, lastname, dob, gender, cash, bank, phonenumber, `groups`, metadata) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", { local valid, issues = NDCore.validateCharacterData(charInfo)
if not valid then
for _, err in ipairs(issues) do
Wait(100)
TriggerClientEvent("ND:notifyClient", src, {
description = err,
type = "error"
})
end
return
end
charInfo.id = MySQL.insert.await("INSERT INTO nd_characters (identifier, name, firstname, lastname, dob, gender, cash, bank, phonenumber, `groups`, metadata, inventory) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", {
identifier, identifier,
charInfo.name, charInfo.name,
charInfo.firstname, charInfo.firstname,
@@ -437,7 +527,8 @@ function NDCore.newCharacter(src, info)
charInfo.bank, charInfo.bank,
charInfo.phonenumber, charInfo.phonenumber,
json.encode(charInfo.groups), json.encode(charInfo.groups),
json.encode(charInfo.metadata) json.encode(charInfo.metadata),
json.encode(charInfo.inventory)
}) })
return createCharacterTable(charInfo) return createCharacterTable(charInfo)
@@ -448,7 +539,7 @@ end
function NDCore.fetchCharacter(id, src) function NDCore.fetchCharacter(id, src)
local result local result
if src then if src then
result = MySQL.query.await("SELECT * FROM nd_characters WHERE charid = ? and identifier = ?", {id, GetPlayerIdentifierByType(src, Config.characterIdentifier)}) result = MySQL.query.await("SELECT * FROM nd_characters WHERE charid = ? and identifier = ?", {id, NDCore.getPlayerIdentifierByType(src, Config.characterIdentifier)})
else else
result = MySQL.query.await("SELECT * FROM nd_characters WHERE charid = ?", {id}) result = MySQL.query.await("SELECT * FROM nd_characters WHERE charid = ?", {id})
end end
@@ -477,7 +568,7 @@ end
---@return table ---@return table
function NDCore.fetchAllCharacters(src) function NDCore.fetchAllCharacters(src)
local characters = {} local characters = {}
local result = MySQL.query.await("SELECT * FROM nd_characters WHERE identifier = ?", {GetPlayerIdentifierByType(src, Config.characterIdentifier)}) local result = MySQL.query.await("SELECT * FROM nd_characters WHERE identifier = ?", {NDCore.getPlayerIdentifierByType(src, Config.characterIdentifier)})
for i=1, #result do for i=1, #result do
local info = result[i] local info = result[i]

View File

@@ -1,6 +1,7 @@
local ox_inventory local ox_inventory
local inventoryStarted = false local inventoryStarted = false
local spawnedPlayerVehicles = {} local spawnedPlayerVehicles = {}
local vehicleTypes = json.decode(GetResourceKvpString("ND_Core:vehTypes") or "[]")
NDCore.isResourceStarted("ox_inventory", function(started) NDCore.isResourceStarted("ox_inventory", function(started)
inventoryStarted = started inventoryStarted = started
@@ -8,23 +9,62 @@ NDCore.isResourceStarted("ox_inventory", function(started)
ox_inventory = exports.ox_inventory ox_inventory = exports.ox_inventory
end) end)
local function getVehicleType(model) local function getVehicleType(coords, model)
local tempVehicle = CreateVehicle(model, 0, 0, 0, 0, true, true) if vehicleTypes[model] then
return vehicleTypes[model]
end
local tempVehicle = CreateVehicle(model, coords.x, coords.y, coords.z-5.0, coords.w, true, false)
local time = os.time() local time = os.time()
while not DoesEntityExist(tempVehicle) and time-os.time() < 5 do Wait(5) end
while not DoesEntityExist(tempVehicle) and os.time()-time < 5 do Wait(0) end
if not DoesEntityExist(tempVehicle) then return end if not DoesEntityExist(tempVehicle) then return end
local entityType = GetVehicleType(tempVehicle)
local vehType = GetVehicleType(tempVehicle)
DeleteEntity(tempVehicle) DeleteEntity(tempVehicle)
return entityType
vehicleTypes[model] = vehType
SetResourceKvp("ND_Core:vehTypes", json.encode(vehicleTypes))
return vehType
end end
local function generatePlate() local function generatePlate()
local plate = {} local plate = {}
for i=1, 8 do local i = 1
plate[i] = math.random(0, 1) == 1 and string.char(math.random(65, 90)) or math.random(0, 9) local p = 1
-- ensure pattern exists and pad to 8 chars
local pattern = Config.platePattern
if #pattern < 8 then
pattern = pattern .. string.rep(" ", 8 - #pattern)
end end
while i <= 8 do
local char = pattern:sub(p, p)
if char == "^" then
-- literal next character
p = p + 1
plate[i] = pattern:sub(p, p)
elseif char == "1" then
plate[i] = tostring(math.random(0, 9))
elseif char == "A" then
plate[i] = string.char(math.random(65, 90)) -- AZ
elseif char == "." then
if math.random(0, 1) == 0 then
plate[i] = tostring(math.random(0, 9))
else
plate[i] = string.char(math.random(65, 90))
end
else
plate[i] = char
end
i = i + 1
p = p + 1
end
return table.concat(plate) return table.concat(plate)
end end
@@ -99,6 +139,15 @@ function NDCore.getVehicle(entity)
DeleteEntity(entity) DeleteEntity(entity)
end end
-- remvoe vehicle from db.
function self.remove(keepEntity)
if not keepEntity and DoesEntityExist(entity) then
DeleteEntity(entity)
end
MySQL.query("DELETE FROM nd_vehicles WHERE id = ?", {self.id})
end
--- set vehicle properties --- set vehicle properties
---@param props table ---@param props table
function self.setProperties(props) function self.setProperties(props)
@@ -156,13 +205,22 @@ function NDCore.getVehicle(entity)
function self.setMetadata(key, value) function self.setMetadata(key, value)
self.metadata[key] = value self.metadata[key] = value
if DoesEntityExist(entity) then if DoesEntityExist(entity) then
local state = Entity(self.entity).state local state = Entity(self.entity).state
local metadata = state.metadata
metadata[key] = value if not state.metadata then
state.metadata = metadata state.metadata = self.metadata
else
state.metadata[key] = value
end
end end
if not self.id or not self.owner then return end
if not self.id or not self.owner then
lib.print.debug(('Skipped storing metadata for vehicle %s as it does not have an id/owner associated with it.'):format(self.entity))
return
end
MySQL.query("UPDATE nd_vehicles SET metadata = ? WHERE id = ?", {json.encode(self.metadata), self.id}) MySQL.query("UPDATE nd_vehicles SET metadata = ? WHERE id = ?", {json.encode(self.metadata), self.id})
end end
@@ -253,14 +311,14 @@ function NDCore.createVehicle(info)
end end
local model = info.model or properties.model local model = info.model or properties.model
local vehType = getVehicleType(model) local vehType = getVehicleType(spawnCoords, model)
if not vehType then if not vehType then
return Citizen.Trace("NDCore.createVehicle", "vehType not found") return Citizen.Trace("NDCore.createVehicle", "vehType not found")
end end
local veh = CreateVehicleServerSetter(model, vehType, spawnCoords.x, spawnCoords.y, spawnCoords.z, spawnCoords.w) local veh = CreateVehicleServerSetter(model, vehType, spawnCoords.x, spawnCoords.y, spawnCoords.z, spawnCoords.w)
local time = os.time() local time = os.time()
while not DoesEntityExist(veh) and time-os.time() < 5 do Wait(5) end while not DoesEntityExist(veh) and os.time()-time < 5 do Wait(5) end
if not veh or not DoesEntityExist(veh) then if not veh or not DoesEntityExist(veh) then
return Citizen.Trace("NDCore.createVehicle", "vehicle entity doesn't exist") return Citizen.Trace("NDCore.createVehicle", "vehicle entity doesn't exist")
end end
@@ -347,14 +405,14 @@ function NDCore.transferVehicleOwnership(vehicleId, fromSource, toSource)
end end
playerFrom.notify({ playerFrom.notify({
title = "Ownership transfered", title = locale("vehicle_ownership_transfered"),
description = ("Vehicle ownership of %s has been transfered."):format(vehicle.plate), description = locale("vehicle_ownership_transfered2", vehicle.plate),
position = "bottom-right", position = "bottom-right",
type = "success" type = "success"
}) })
playerTo.notify({ playerTo.notify({
title = "Ownership received", title = locale("vehicle_ownership_received"),
description = ("Received vehicle ownership of %s."):format(vehicle.plate), description = locale("vehicle_ownership_received2", vehicle.plate),
position = "bottom-right" position = "bottom-right"
}) })
return true return true
@@ -388,15 +446,15 @@ function NDCore.shareVehicleKeys(source, target, vehicle)
local plate = GetVehicleNumberPlateText(vehicle) local plate = GetVehicleNumberPlateText(vehicle)
player.notify({ player.notify({
title = "Keys shared", title = locale("keys_shared"),
description = ("You've shared vehicle keys to %s."):format(plate), description = locale("keys_shared2", plate),
position = "bottom-right", position = "bottom-right",
type = "success", type = "success"
}) })
targetPlayer.notify({ targetPlayer.notify({
title = "Keys received", title = locale("keys_received"),
description = ("Received vehicle keys to %s."):format(plate), description = locale("keys_received2", plate),
position = "bottom-right", position = "bottom-right"
}) })
return true return true
end end
@@ -411,7 +469,8 @@ function NDCore.spawnOwnedVehicle(source, vehicleId, coords, heading)
if not player then return end if not player then return end
local vehicle = NDCore.getVehicleById(vehicleId) local vehicle = NDCore.getVehicleById(vehicleId)
if not vehicle or not vehicle.available or vehicle.owner ~= player.id then return end if not vehicle or vehicle.owner ~= player.id then return end
if not vehicle.available and not vehicle.impounded then return end
MySQL.query.await("UPDATE nd_vehicles SET stored = ? WHERE id = ?", {0, vehicleId}) MySQL.query.await("UPDATE nd_vehicles SET stored = ? WHERE id = ?", {0, vehicleId})
@@ -445,16 +504,16 @@ local function toggleVehicleLock(source, entity, nearby, metadata)
if metadata and not metadata.keyEnabled then if metadata and not metadata.keyEnabled then
return player.notify({ return player.notify({
title = "No signal", title = locale("no_signal"),
description = "Vehicle key disabled.", description = locale("veh_key_disabled"),
type = "error", type = "error",
position = "bottom-right", position = "bottom-right",
duration = 3000 duration = 3000
}) })
elseif not nearby then elseif not nearby then
return player.notify({ return player.notify({
title = "No signal", title = locale("no_signal"),
description = "Vehicle to far away.", description = locale("veh_far_away"),
type = "error", type = "error",
position = "bottom-right", position = "bottom-right",
duration = 3000 duration = 3000
@@ -468,16 +527,16 @@ local function toggleVehicleLock(source, entity, nearby, metadata)
player.triggerEvent("ND_Vehicles:keyFob", vehicle.netId) player.triggerEvent("ND_Vehicles:keyFob", vehicle.netId)
if locked then if locked then
return player.notify({ return player.notify({
title = "LOCKED", title = locale("veh_locked"),
description = "Your vehicle has now been locked.", description = locale("veh_locked2"),
type = "success", type = "success",
position = "bottom-right", position = "bottom-right",
duration = 3000 duration = 3000
}) })
end end
player.notify({ player.notify({
title = "UNLOCKED", title = locale("veh_unlocked"),
description = "Your vehicle has now been unlocked.", description = locale("veh_unlocked2"),
type = "inform", type = "inform",
position = "bottom-right", position = "bottom-right",
duration = 3000 duration = 3000
@@ -666,16 +725,16 @@ RegisterNetEvent("ND_Vehicles:storeVehicle", function(netId)
local player = NDCore.getPlayer(src) local player = NDCore.getPlayer(src)
if not vehicle.setStatus("stored", true) or not player or player.id ~= vehicle.owner then if not vehicle.setStatus("stored", true) or not player or player.id ~= vehicle.owner then
return player.notify({ return player.notify({
title = "Garage", title = locale("garage"),
description = "No owned vehicle found nearby.", description = locale("no_owned_veh_nearby"),
type = "error", type = "error",
position = "bottom", position = "bottom",
duration = 3000 duration = 3000
}) })
end end
player.notify({ player.notify({
title = "Garage", title = locale("garage"),
description = "Vehicle stored in garage.", description = locale("veh_stored_in_garage"),
type = "success", type = "success",
position = "bottom", position = "bottom",
duration = 3000 duration = 3000
@@ -701,28 +760,29 @@ RegisterNetEvent("ND_Vehicles:takeVehicle", function(vehId, locations)
local vehicle = NDCore.getVehicleById(vehId) local vehicle = NDCore.getVehicleById(vehId)
local player = NDCore.getPlayer(src) local player = NDCore.getPlayer(src)
if not player or not vehicle or vehicle.owner ~= player.id then return end if not player or not vehicle or vehicle.owner ~= player.id then return end
local info = NDCore.spawnOwnedVehicle(src, vehicle.id, isParkingAvailable(locations))
if not info then return end
TriggerClientEvent("ND_Vehicles:blip", src, info.netId, true)
if vehicle.impounded then if vehicle.impounded then
local reclaimPrice = vehicle.metadata.impoundReclaimPrice or 200 local reclaimPrice = vehicle.metadata.impoundReclaimPrice or 200
if not player.deductMoney("bank", reclaimPrice, "Vehicle impound reclaim") then if not player.deductMoney("bank", reclaimPrice, locale("impound_reclaim")) then
return player.notify({ return player.notify({
title = "Impound", title = locale("impound"),
description = ("Price to reclaim is $%d, you don't have enough!"):format(reclaimPrice), description = locale("impound_not_enough", reclaimPrice),
type = "error", type = "error",
position = "bottom" position = "bottom"
}) })
end end
player.notify({ player.notify({
title = "Impound", title = locale("impound"),
description = ("Paid $%d to reclaim vehicle!"):format(reclaimPrice), description = locale("impound_paid", reclaimPrice),
type = "success", type = "success",
position = "bottom" position = "bottom"
}) })
MySQL.query.await("UPDATE nd_vehicles SET impounded = ? WHERE id = ?", {0, vehicle.id}) MySQL.query.await("UPDATE nd_vehicles SET impounded = ? WHERE id = ?", {0, vehicle.id})
end end
local info = NDCore.spawnOwnedVehicle(src, vehicle.id, isParkingAvailable(locations))
if not info then return end
TriggerClientEvent("ND_Vehicles:blip", src, info.netId, true)
end) end)
lib.callback.register("ND_Vehicles:getOwnedVehicles", function(src) lib.callback.register("ND_Vehicles:getOwnedVehicles", function(src)
@@ -730,3 +790,30 @@ lib.callback.register("ND_Vehicles:getOwnedVehicles", function(src)
if not player then return end if not player then return end
return NDCore.getVehicles(player.id) return NDCore.getVehicles(player.id)
end) end)
AddEventHandler("ND:characterLoaded", function(player)
local ownedExistingVehicles = {}
local ownedVehicles = NDCore.getVehicles(player.id)
local vehicles = GetAllVehicles()
local vehiclesToImpound = {}
for i=1, #vehicles do
local veh = vehicles[i]
local state = Entity(veh).state
if state.owner == player.id then
ownedExistingVehicles[#ownedExistingVehicles+1] = state.id
end
end
for i=1, #ownedVehicles do
local veh = ownedVehicles[i]
if veh and not veh.stored and not veh.impounded and not lib.table.contains(ownedExistingVehicles, veh.id) then
vehiclesToImpound[#vehiclesToImpound+1] = veh.id
end
end
if #vehiclesToImpound == 0 then return end
local query = ("UPDATE nd_vehicles SET impounded = ? WHERE owner = ? AND id IN (%s)"):format(table.concat(vehiclesToImpound, ", "))
MySQL.rawExecute(query, {1, player.id})
end)