feat: locales

This commit is contained in:
Andyyy7666
2025-08-14 01:13:48 +02:00
parent 0bd76ed79f
commit a431a49d8c
9 changed files with 425 additions and 285 deletions

View File

@@ -1,3 +1,4 @@
lib.locale()
NDCore = {} NDCore = {}
Config = { Config = {
@@ -26,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)
@@ -49,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

@@ -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)
@@ -447,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()
@@ -469,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)
@@ -552,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,
@@ -647,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
@@ -670,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
@@ -683,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
@@ -693,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
@@ -709,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
@@ -724,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
@@ -741,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
@@ -756,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

@@ -34,7 +34,8 @@ server_scripts {
files { files {
"init.lua", "init.lua",
"client/vehicle/data.lua", "client/vehicle/data.lua",
"compatibility/**/locale.lua" "compatibility/**/locale.lua",
"locales/*.json"
} }
dependencies { dependencies {

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"
}

View File

@@ -1,16 +1,16 @@
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
} }
@@ -48,7 +48,7 @@ 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
@@ -58,7 +58,7 @@ lib.addCommand("setmoney", {
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,8 +90,8 @@ 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
}) })
@@ -100,7 +100,7 @@ lib.addCommand("setjob", {
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
}) })
@@ -159,7 +159,7 @@ lib.addCommand("setgroup", {
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)
@@ -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,22 +240,22 @@ 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
}) })
@@ -323,12 +323,13 @@ lib.addCommand("dv", {
count = 1 count = 1
end end
local messageLabel = ("%s [dv]"):format(locale("staff_action"))
if count == 0 then if count == 0 then
message = {"Staff action [dv]", "no vehicles found"} message = {messageLabel, "no vehicles found"}
elseif count == 1 then elseif count == 1 then
message = {"Staff action [dv]", "deleted 1 vehicle"} message = {messageLabel, "deleted 1 vehicle"}
else else
message = {"Staff action [dv]", ("deleted %d vehicles"):format(count)} message = {messageLabel, ("deleted %d vehicles"):format(count)}
end end
TriggerClientEvent("chat:addMessage", source, { TriggerClientEvent("chat:addMessage", source, {

View File

@@ -1,3 +1,4 @@
lib.locale()
NDCore = {} NDCore = {}
NDCore.players = {} NDCore.players = {}
PlayersInfo = {} PlayersInfo = {}
@@ -117,12 +118,12 @@ 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 and not Config.sv_lan 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 if Config.sv_lan then
@@ -143,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)
@@ -164,6 +165,7 @@ AddEventHandler("onResourceStop", function(name)
end) end)
MySQL.ready(function() MySQL.ready(function()
Wait(100)
NDCore.loadSQL({ NDCore.loadSQL({
"database/characters.sql", "database/characters.sql",
"database/vehicles.sql" "database/vehicles.sql"

View File

@@ -66,7 +66,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 +74,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

View File

@@ -405,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
@@ -446,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
@@ -504,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
@@ -527,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
@@ -725,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
@@ -767,17 +767,17 @@ RegisterNetEvent("ND_Vehicles:takeVehicle", function(vehId, locations)
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"
}) })