Skip to content

Commit 21e8b63

Browse files
committed
feat(scripts): add translation generator
- Added a translations generator Python script. - Moved `Class.lua` from /modules to /lib since it's not a module. - Fixed `Vehicle:MaxPerformance()`: Only check Gen9-exclusive mods in Legacy. - Translator: Move the locales field into its own file then require it.
1 parent 914cf0a commit 21e8b63

File tree

16 files changed

+347
-204
lines changed

16 files changed

+347
-204
lines changed

.github/workflows/doc_gen.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88
workflow_dispatch:
99

1010
jobs:
11-
generate:
11+
Generate_Docs:
1212
runs-on: ubuntu-latest
1313
steps:
1414
- name: Checkout

.github/workflows/translations.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: Generate Docs
2+
3+
on:
4+
push:
5+
paths:
6+
- "SmallBase/includes/lib/translations/en-US.lua"
7+
- "SmallBase/includes/lib/translations/locales.lua"
8+
workflow_dispatch:
9+
10+
jobs:
11+
Generate_Translations:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@v4
16+
17+
- name: Set up Python
18+
uses: actions/setup-python@v5
19+
with:
20+
python-version: "3.12.x"
21+
22+
- name: Run Translations Generator
23+
run: |
24+
cd scripts
25+
python generate_translations.py
26+
27+
- name: Commit changes
28+
run: |
29+
git config user.name "github-actions[bot]"
30+
git config user.email "github-actions[bot]@users.noreply.github.com"
31+
git add SmallBase/includes/lib/translations/
32+
git diff --cached --quiet || git commit -m "feat(Translations): update translations"
33+
git push

CONTRIBUTING.md

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,34 @@ You are free to use any style you want, except in these cases:
185185
DoSomething()
186186
```
187187

188-
## What To Avoid
188+
## Translations
189+
190+
- The primary language for all labels is English (US) (`/lib/translations/en-US.lua`).
191+
- To add a new language, add its name and ISO code to `/lib/translations/locales.lua`.
192+
- To add a new label, update `/lib/translations/en-US.lua`.
193+
- All other language files will be automatically generated via GitHub Actions (you can also manually run `/scripts/generate_translations.py`).
194+
195+
**Example usage:**
196+
Suppose you want to draw some text that gets automatically translated:
189197

190-
Avoid adding end-user features directly to the project (example: A drift minigame, a business manager, animations, etc.).
198+
1. Open `/lib/translations/en-US.lua`.
199+
2. Add a key-value pair for your new label:
200+
201+
```lua
202+
return {
203+
...
204+
["MY_LABEL"] = "My label's text in English."
205+
}
206+
```
191207

192-
SmallBase is, as the name suggests, a base. It provides the tools and the foundations to create new scripts.
208+
3. Use the `key` with the `_T` wrapper for the [`Translator:Translate(...)`](docs/services/Translator.md) method:
209+
210+
```lua
211+
ImGui.Text(_T("MY_LABEL"))
212+
```
213+
214+
## What To Avoid
193215

194-
Two scripts can both use this project as a template and offer completely different sets of features.
216+
- Manually editing any language file except `en-US.lua`. They are auto-generated.
195217

196-
If you want to share a feature, make it a standalone module that uses SmallBase.
218+
- Adding end-user features directly to the project *(ex: A drift minigame, a business manager, animations, etc.)*.

SmallBase/includes/gui/settings_ui.lua

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ local selected_l_type_idx = 1
4848
local selected_entity_type = 1
4949
local TVehList = {}
5050
local g_offsets = {}
51-
local l_Offsets = {}
51+
local l_offsets = {}
5252
local state_colors <const> = {
5353
[eThreadState.UNK] = GREY,
5454
[eThreadState.DEAD] = RED,
@@ -243,7 +243,7 @@ local function DrawGlobalsAndLocals()
243243

244244
ImGui.SameLine()
245245

246-
if GUI:Button(("Clear##%s"):format("globals")) then
246+
if GUI:Button("Clear##globals") then
247247
init_g_addr = 0
248248
g_offset_count = 0
249249
g_offsets = {}
@@ -298,11 +298,11 @@ local function DrawGlobalsAndLocals()
298298

299299
ImGui.BeginDisabled(string.isempty(l_scr_name) or init_l_addr == 0)
300300
ImGui.SameLine()
301-
if GUI:Button(("Clear##%s"):format("locals")) then
301+
if GUI:Button("Clear##locals") then
302302
l_scr_name = ""
303303
init_l_addr = 0
304304
l_offset_count = 0
305-
l_Offsets = {}
305+
l_offsets = {}
306306
selected_l_type_idx = 1
307307
end
308308

@@ -315,8 +315,8 @@ local function DrawGlobalsAndLocals()
315315
ImGui.BeginDisabled(l_offset_count == 0)
316316
if GUI:Button("Remove Offset##locals") then
317317
l_offset_count = math.max(0, l_offset_count - 1)
318-
if (#l_Offsets > 0) then
319-
l_Offsets[#l_Offsets] = nil
318+
if (#l_offsets > 0) then
319+
l_offsets[#l_offsets] = nil
320320
end
321321
end
322322
ImGui.EndDisabled()
@@ -326,8 +326,8 @@ local function DrawGlobalsAndLocals()
326326
for i = 1, l_offset_count do
327327
ImGui.Text(".f_")
328328
ImGui.SameLine()
329-
l_Offsets[i], _ = ImGui.InputInt("##test_local_offset" .. i, l_Offsets[i] or 0)
330-
l_Offsets[i] = math.max(0, l_Offsets[i])
329+
l_offsets[i], _ = ImGui.InputInt("##test_local_offset" .. i, l_offsets[i] or 0)
330+
l_offsets[i] = math.max(0, l_offsets[i])
331331
end
332332
end
333333
ImGui.PopItemWidth()
@@ -345,9 +345,9 @@ local function DrawGlobalsAndLocals()
345345
if GUI:Button(("Read %s##locals"):format(selected_L_type or "")) then
346346
local method_name = selected_L_type == "Pointer" and "GetPointer" or "Read" .. selected_L_type
347347
local l = ScriptLocal(init_l_addr, l_scr_name)
348-
if (#l_Offsets > 0) then
349-
for i = 1, #l_Offsets do
350-
l = l:At(l_Offsets[i])
348+
if (#l_offsets > 0) then
349+
for i = 1, #l_offsets do
350+
l = l:At(l_offsets[i])
351351
end
352352
end
353353

@@ -357,7 +357,7 @@ local function DrawGlobalsAndLocals()
357357
end
358358

359359
local function DrawSerializerDebug()
360-
local eState = ThreadManager:GetThreadState("SB_SERIALIZER")
360+
local eState = ThreadManager:GetThreadState("SB_SERIALIZER")
361361

362362
ImGui.BulletText("Thread State:")
363363
ImGui.SameLine()
@@ -404,14 +404,12 @@ local function PopulateVehlistOnce()
404404
end
405405

406406
local function DrawDummyVehSpawnMenu()
407+
ImGui.Text("Lightweight Vehicle Preview Test")
407408
PopulateVehlistOnce()
408409

409410
if ImGui.BeginListBox("##dummyvehlist", -1, 0) then
410411
for _, veh in ipairs(TVehList) do
411-
local is_selected = false
412-
413-
ImGui.Selectable(veh.displayname, is_selected)
414-
412+
ImGui.Selectable(veh.displayname, false)
415413
if ImGui.IsItemHovered() then
416414
local item_min = vec2:new(ImGui.GetItemRectMin())
417415
hovered_y = item_min.y
@@ -420,7 +418,6 @@ local function DrawDummyVehSpawnMenu()
420418
hovered_y = nil
421419
end
422420
end
423-
424421
ImGui.EndListBox()
425422
end
426423

@@ -482,7 +479,6 @@ debug_tab:RegisterGUI(function()
482479
end
483480

484481
if ImGui.BeginTabItem("Preview Test") then
485-
ImGui.Text("Lightweight Vehicle Preview Test")
486482
DrawDummyVehSpawnMenu()
487483
ImGui.EndTabItem()
488484
end

SmallBase/includes/init.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ local DEFAULT_CONFIG <const> = {
2222
}
2323

2424
require("includes.lib.utils")
25-
require("includes.modules.Class")
25+
require("includes.lib.class")
2626
require("includes.backend")
2727
require("includes.modules.Memory")
2828

File renamed without changes.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
-- Only add locales if you have matching files for them under /lib/translations/ otherwise you'll get an error when trying
2+
--
3+
-- to select a new language because `require` falls back to `package.searcher` which is disabled in V1's sandbox (don't know about V2 yet).
4+
--
5+
-- The error is actually just a warning from the API but just to keep things clean and running smoothly, don't add non-existing locales.
6+
return {
7+
{ name = "English", iso = "en-US" },
8+
{ name = "Français", iso = "fr-FR" },
9+
{ name = "Deütsch", iso = "de-DE" },
10+
{ name = "Español", iso = "es-ES" },
11+
{ name = "Italiano", iso = "it-IT" },
12+
{ name = "Português", iso = "pt-BR" },
13+
{ name = "Русский", iso = "ru-RU" },
14+
{ name = "中國人", iso = "zh-TW" },
15+
{ name = "中国人", iso = "zh-CN" },
16+
{ name = "日本語", iso = "ja-JP" },
17+
{ name = "Polski", iso = "pl-PL" },
18+
{ name = "한국인", iso = "ko-KR" },
19+
}

SmallBase/includes/modules/Memory.lua

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,9 @@ function Memory.GetVehicleInfo(vehicle)
129129
end
130130

131131
-- Checks if a vehicle's handling flag is set.
132-
---@param vehicle number
133-
---@param flag number
134-
---@return boolean | nil
132+
---@param vehicle integer
133+
---@param flag eVehicleHandlingFlags
134+
---@return boolean|nil
135135
function Memory.GetVehicleHandlingFlag(vehicle, flag)
136136
if not (ENTITY.DOES_ENTITY_EXIST(vehicle) or ENTITY.IS_ENTITY_A_VEHICLE(vehicle)) then
137137
return
@@ -144,7 +144,7 @@ function Memory.GetVehicleHandlingFlag(vehicle, flag)
144144
end
145145

146146
---@param vehicle integer
147-
---@param flag integer
147+
---@param flag eVehicleModelFlags
148148
---@return boolean
149149
function Memory.GetVehicleModelFlag(vehicle, flag)
150150
local CVehicle = Memory.GetVehicleInfo(vehicle)
@@ -191,7 +191,7 @@ function Memory.GetEntityType(entity)
191191
end
192192

193193
---@param ped integer A Ped ID, not a Player ID.
194-
---@return CPed | nil
194+
---@return CPed|nil
195195
function Memory.GetPedInfo(ped)
196196
if not ENTITY.DOES_ENTITY_EXIST(ped) or not ENTITY.IS_ENTITY_A_PED(ped) then
197197
return
@@ -256,7 +256,8 @@ function Memory.GetPedInfo(ped)
256256
end
257257

258258
--[[
259-
---@deprecated
259+
---@ignore
260+
---@unused
260261
---@param dword integer
261262
function Memory.SetWeaponEffectGroup(dword)
262263
local pedPtr = memory.handle_to_ptr(self.get_ped())

0 commit comments

Comments
 (0)