aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--advtrains/copytool.lua16
-rw-r--r--advtrains/couple.lua4
-rw-r--r--advtrains/init.lua5
-rw-r--r--advtrains/locale/README.md69
-rw-r--r--advtrains/locale/advtrains.de.tr169
-rw-r--r--advtrains/locale/advtrains.fr.tr146
-rw-r--r--advtrains/locale/advtrains.zh_CN.tr135
-rw-r--r--advtrains/locale/advtrains.zh_TW.tr146
-rwxr-xr-xadvtrains/locale/gui638
-rw-r--r--advtrains/locale/template.txt146
-rwxr-xr-xadvtrains/locale/topo.sh4
-rw-r--r--advtrains/po/de.po580
-rw-r--r--advtrains/po/fr.po579
-rw-r--r--advtrains/po/template.pot505
-rwxr-xr-xadvtrains/po/update-translations.sh24
-rw-r--r--advtrains/po/zh_CN.po560
-rw-r--r--advtrains/po/zh_TW.po560
-rw-r--r--advtrains/protection.lua6
-rw-r--r--advtrains/signals.lua13
20 files changed, 4194 insertions, 112 deletions
diff --git a/.gitignore b/.gitignore
index b3180de..2920966 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
## Eclipse project files & directories
.project
.settings
+*~
diff --git a/advtrains/copytool.lua b/advtrains/copytool.lua
index 0c1cdfe..7ad4330 100644
--- a/advtrains/copytool.lua
+++ b/advtrains/copytool.lua
@@ -26,7 +26,7 @@ minetest.register_tool("advtrains:copytool", {
return itemstack
end
if not minetest.check_player_privs(placer, {train_operator = true }) then
- minetest.chat_send_player(pname, "You don't have the train_operator privilege.")
+ minetest.chat_send_player(pname, S("You do not have the @1 privilege.", "train_operator"))
return itemstack
end
if not minetest.check_player_privs(placer, {train_admin = true }) and minetest.is_protected(pointed_thing.under, placer:get_player_name()) then
@@ -38,7 +38,7 @@ minetest.register_tool("advtrains:copytool", {
local prevpos = advtrains.get_adjacent_rail(pointed_thing.under, tconns, plconnid, {default=true})
if not prevpos then
- minetest.chat_send_player(pname, "The track you are trying to place the wagon on is not long enough!")
+ minetest.chat_send_player(pname, attrans("The track you are trying to place the wagon on is not long enough!"))
return
end
@@ -49,12 +49,12 @@ minetest.register_tool("advtrains:copytool", {
end
local clipboard = meta:get_string("clipboard")
if (clipboard == "") then
- minetest.chat_send_player(pname, "The clipboard is empty.");
+ minetest.chat_send_player(pname, attrans("The clipboard is empty."));
return
end
clipboard = minetest.deserialize(clipboard)
if (clipboard.wagons == nil) then
- minetest.chat_send_player(pname, "The clipboard is empty.");
+ minetest.chat_send_player(pname, attrans("The clipboard is empty."));
return
end
@@ -71,7 +71,7 @@ minetest.register_tool("advtrains:copytool", {
local train = advtrains.trains[id]
train.off_track = train.end_index<train.path_trk_b
if (train.off_track) then
- minetest.chat_send_player(pname, "Back of train would end up off track, cancelling.")
+ minetest.chat_send_player(pname, attrans("Back of train would end up off track, cancelling."))
advtrains.remove_train(id)
return
end
@@ -89,19 +89,19 @@ minetest.register_tool("advtrains:copytool", {
local le = pointed_thing.ref:get_luaentity()
if (le == nil) then
- minetest.chat_send_player(user:get_player_name(), "No such lua entity!")
+ minetest.chat_send_player(user:get_player_name(), attrans("No such lua entity!"))
return
end
local wagon = advtrains.wagons[le.id]
if (not (le.id and advtrains.wagons[le.id])) then
- minetest.chat_send_player(user:get_player_name(), string.format("No such wagon: %s", le.id))
+ minetest.chat_send_player(user:get_player_name(), attrans("No such wagon: @1", le.id))
return
end
local train = advtrains.trains[wagon.train_id]
if (not train) then
- minetest.chat_send_player(user:get_player_name(), string.format("No such train: %s", wagon.train_id))
+ minetest.chat_send_player(user:get_player_name(), attrans("No such train: @1", wagon.train_id))
return
end
diff --git a/advtrains/couple.lua b/advtrains/couple.lua
index b6a445e..d82e193 100644
--- a/advtrains/couple.lua
+++ b/advtrains/couple.lua
@@ -184,8 +184,8 @@ end
function advtrains.safe_couple_trains(train1, t1_is_front, train2, t2_is_front, pname)
if pname and not minetest.check_player_privs(pname, "train_operator") then
- minetest.chat_send_player(pname, "Missing train_operator privilege")
- return false
+ minetest.chat_send_player(pname, S("You are not allowed to couple trains without the train_operator privilege."))
+ return false
end
local wck_t1, wck_t2
diff --git a/advtrains/init.lua b/advtrains/init.lua
index 06e456f..f6f8f9b 100644
--- a/advtrains/init.lua
+++ b/advtrains/init.lua
@@ -22,8 +22,7 @@ Copyright (C) 2016-2020 Moritz Blei (orwell96) and contributors
local lot = os.clock()
minetest.log("action", "[advtrains] Loading...")
--- There is no need to support 0.4.x anymore given that the compatitability with it is already broken by 1bb1d825f46af3562554c12fba35a31b9f7973ff
-attrans = minetest.get_translator ("advtrains")
+attrans = minetest.get_translator("advtrains")
--advtrains
advtrains = {trains={}, player_to_train_mapping={}}
@@ -181,7 +180,7 @@ function assertt(var, typ)
end
end
-dofile(advtrains.modpath.."/helpers.lua");
+dofile(advtrains.modpath.."/helpers.lua")
--dofile(advtrains.modpath.."/debugitems.lua");
advtrains.meseconrules =
diff --git a/advtrains/locale/README.md b/advtrains/locale/README.md
new file mode 100644
index 0000000..a54cb6c
--- /dev/null
+++ b/advtrains/locale/README.md
@@ -0,0 +1,69 @@
+# Translations
+**Please note that this document is outdated as transition to `.po`
+files is currently in progress.**
+
+Please read this document before working on any translations.
+
+## Getting Started
+If there is a translation file for your language (e.g. German), you can
+edit the file directly. Please read [the documentation on the
+translation file format][tr-format].
+
+Alternatively, Advtrains provides a script named `gui` that can be used
+to, among other things, edit translation files. The script requires
+Tcl/Tk 8.6, which is provided by most Linux distributions.
+
+If the translation file for your language does not exist, create it by
+copying `template.txt` to `advtrains.XX.tr`, where `XX` is replaced by
+the language code.
+
+Feel free to use the [discussion mailing list][srht-discuss] if you
+have any questions regarding localization.
+
+You can share your `.tr` file directly or [as a patch][gsm] to the [dev
+mailing list][srht-devel]. The latter is encouraged, but, unlike code
+changes, translation files sent directly are also accepted.
+
+[tr-format]: https://minetest.gitlab.io/minetest/translations/#translation-file-format
+[srht-discuss]: https://lists.sr.ht/~gpcf/advtrains-discuss
+[srht-devel]: https://lists.sr.ht/~gpcf/advtrains-devel
+[gsm]: https://git-send-email.io
+
+## Translation Notes
+* Translations should be consistent. You can use other entries or the
+translations in Minetest as a reference.
+* Translations do not have to fully correspond to the original text -
+they only need to provide the same information. In particular,
+translations do not need to have the same linguistical structure as the
+original text.
+* Replacement sequences (`@1`, `@2`, etc) should not be translated.
+* Certain abbreviations or names, such as "Ks" or "Zs 3", should
+generally not be translated.
+
+### (de) German
+* Verwenden Sie die neue Rechtschreibung und die Sie-Form.
+* Mit der deutschen Tastaturbelegung unter Linux können die
+Anführungszeichen „“ mit AltGr-V bzw. AltGr-B eingegeben werden.
+
+### (zh) Chinese
+(This section is written in English to avoid writing the note twice or
+using only one of the variants, as most of this section applies to both
+the traditional and simplified variants.)
+
+* Please use the 「」 quotation marks for Traditional Chinese and “”
+for Simplified Chinese.
+* Please use the fullwidth variants of: , 、 。 ? ! : ;
+* Please use the halfwidth variants of: ( ) [ ] / \ |
+* Please do not leave any space between Han characters (including
+fullwidth punctuation marks).
+* Please leave a space between Han characters (excluding fullwidth
+punctuation marks) and characters from other scripts (including
+halfwidth punctuation marks). However, do not leave any space between
+Han characters and Arabic numerals.
+
+## Notes for developers
+* Avoid word-by-word translations.
+* Avoid manipulating translated strings (except for concatenation). Use
+server-side translations if you have to modify the text sent to users.
+* Avoid truncating strings unless multibyte characters are handled
+properly.
diff --git a/advtrains/locale/advtrains.de.tr b/advtrains/locale/advtrains.de.tr
index cdebdde..1065264 100644
--- a/advtrains/locale/advtrains.de.tr
+++ b/advtrains/locale/advtrains.de.tr
@@ -1,59 +1,140 @@
# textdomain: advtrains
-This wagon is owned by @1, you can't destroy it.=Dieser Waggon gehört @1, du kannst ihn nicht abbauen.
-Warning: If you destroy this wagon, you only get some steel back! If you are sure, hold Sneak and left-click the wagon.=Warnung: Du erhältst nur etwas Stahl zurück. Wenn du sicher bist, dass du den Waggon zerstören willst, halte 'Schleichen' und klicke links.
-Show Inventory=Zeige Inventar
-Select seat:=Wähle einen Sitzplatz aus:
-ATC controller, unconfigured.=Zugbeeinflussungsschiene, nicht konfiguiert.
-ATC controller=Zugbeeinflussungsschiene
-ATC controller, mode @1@nChannel: @2=Zugbeeinflussungsschiene in Betriebsart "@1"@nKanal: @2
-ATC controller, mode @1@nCommand: @2=Zugbeeinflussungsschiene in Betriebsart "@1"@nBefehl: @2
+
+# Advtrains Core (unorganized)
+This wagon is owned by @1, you can't destroy it.=Dieser Waggon gehört @1, Sie dürfen ihn nicht abbauen.
+Warning: If you destroy this wagon, you only get some steel back! If you are sure, hold Sneak and left-click the wagon.=Warnung: Durch den Abbau des Waggons erhalten Sie nur etwas Stahl zurück. Nutzen Sie Schleichen+Linksklick, um dem Waggon abzubauen.
+This position is protected!=Diese Position ist geschützt!
+Can't place: not pointing at node=Es kann nicht platziert werden: Sie zeigen nicht auf einem Block.
+Can't place: space occupied!=Es kann nicht platziert werden: diese Position ist besetzt.
+Can't place: protected position!=Es kann nicht platziert werden: diese Position ist geschützt.
+Can't place: Not enough slope items left (@1 required)=Es kann nicht platziert werden: Sie haben nicht genug Steigungsblöcke, es werden insgesamt @1 benötigt.
+Can't place: There's no slope of length @1=Es kann nicht platziert werden: die Steigung der Länge @1 ist nicht definiert.
+Can't place: no supporting node at upper end.=Es kann nicht platziert werden: es gibt keinen unterstützenden Block am Ende der Steigung.
+Deprecated Track=ausrangiertes Gleis, nicht verwenden.
+Can't get on: wagon full or doors closed!=Sie können nicht einsteigen: der Waggon ist voll oder die Türen sind geschlossen.
+Use Sneak+rightclick to bypass closed doors!=Nutzen Sie Schleichen+Rechtsklick, um trotz geschlossener Türen einzusteigen.
+Doors are closed! Use Sneak+rightclick to ignore the closed doors and get off!=Die Türen sind geschlossen. Nutzen Sie Schleichen+Rechtsklick, um trotz geschlossener Türen auszusteigen.
+Access to @1=Zugang zu @1
+You do not have the @1 privilege.=Ihnen fehlt das „@1“-Privileg.
+The wagon's inventory is not empty!=Das Inventar dieses Waggons ist nicht leer!
+Position is occupied by a train.=Ein Zug steht an dieser Position.
+There's a Track Circuit Break here.=Hier ist eine Gleisabschnittsgrenze (TCB).
+There's a Signal Influence Point here.=Hier ist ein Signal-Beeinflussungspunkt.
+
+# Trackworker, rotation, adjustment
+This node can't be rotated using the trackworker!=Dieser Block kann nicht mit dem Gleiswerkzeug gedreht werden.
+This node can't be changed using the trackworker!=Dieser Block kann nicht mit dem Gleiswerkzeug bearbeitet werden.
+This track can not be changed!=Dieses Gleis kann nicht geändert werden!
+This track can not be rotated!=Dieses Gleis kann nicht gedreht werden!
+This track can not be removed!=Dieses Gleis kann nicht entfernt werden!
+
+# ATC
+ATC controller, unconfigured.=Nicht konfiguierte Zugbeeinflussungsgleis
+ATC controller=Zugbeeinflussungsgleis
+ATC controller, mode @1@nChannel: @2=Zugbeeinflussungsgleis in Betriebsart „@1“@nKanal: @2
+ATC controller, mode @1@nCommand: @2=Zugbeeinflussungsgleis in Betriebsart „@1“@nBefehl: @2
Command=Befehl
-Command (on)=Befehl (wenn ein)
+Command (on)=Befehl (wenn aktiviert)
Digiline channel=Digiline-Kanal
-Save=Speichern
-ATC Reverse command warning: didn't reverse train, train moving!=Zugbeeinflussung - Warnung: Befehl 'R' nicht ausgeführt, Zug in Bewegung!
-ATC command syntax error: I statement not closed: @1=Zugbeeinflussung - Syntaxfehler: I-Anweisung nicht geschlossen: @1
-ATC command parse error: Unknown command: @1=Zugbeeinflussung - Fehler: Unbekannter Befehl: @1
-This position is protected!=Diese Position ist geschützt!
-You need to own at least one neighboring wagon to destroy this couple.=Du musst Besitzer eines angrenzenden Waggons sein, um hier abzukuppeln.
-@1 Platform (low)=Niedriger @1-Bahnsteig
-@1 Platform (high)=Hoher @1-Bahnsteig
-off=aus
-on=ein
-Lampless Signal (@1)=Mechanisches Signal (@1)
-Signal (@1)=Lichtsignal (@1)
-Track Worker Tool@n@nLeft-click: change rail type (straight/curve/switch)@nRight-click: rotate rail/bumper/signal/etc.=Schienenwerkzeug@n@nLinksklick: Schienentyp ändern, Rechtsklick: Objekt drehen.
-This node can't be rotated using the trackworker!=Kann diesen Block nicht mit dem Schienenwerkzeug drehen.
-This node can't be changed using the trackworker!=Kann diesen Block nicht mit dem Schienenwerkzeug bearbeiten.
-Can't place: not pointing at node=Kann nicht platzieren: Du zeigst nicht auf einen Block.
-Can't place: space occupied!=Kann nicht platzieren: Platz besetzt.
-Can't place: protected position!=Kann nicht platzieren: Position geschützt.
-Can't place: Not enough slope items left (@1 required)=Kann nicht platzieren: nicht genug Steigungsblöcke, es werden insgesamt @1 benötigt.
-Can't place: There's no slope of length @1=Kann nicht platzieren: Keine Steigung der Länge @1 definiert.
-Can't place: no supporting node at upper end.=Kann nicht platzieren: kein unterstützender Block am Ende der Steigung.
-Deprecated Track=ausrangierte Schiene, nicht verwenden.
-Track=Schiene
-Bumper=Prellbock
-Detector Rail=Detektorschiene
+ATC Kick command warning: Doors closed=ATC Kick command warning: Doors closed
+ATC Kick command warning: Train moving=ATC Kick command warning: Train moving
+ATC Reverse command warning: didn't reverse train, train moving!=Zugbeeinflussung: der Befehl „R“ wurde nicht ausgeführt, Zug in Bewegung!
+ATC command syntax error: I statement not closed: @1=Zugbeeinflussung: Unvollständiger I-Befehl: @1
+ATC command parse error: Unknown command: @1=Zugbeeinflussung: Unbekannter Befehl: @1
+
+# Coupling
+Lock couples=Kupplungen sperren
+You need to own at least one neighboring wagon to destroy this couple.=Sie müssen Besitzer eines angrenzenden Waggons sein, um hier abzukuppeln.
+Buffer and Chain Coupler=Schraubenkupplung
+Scharfenberg Coupler=Scharfenbergkupplung
+Japanese Train Inter-Wagon Connection=Waggonzwischenverbindung Japanischer Personenzüge
+Can not couple: The couplers of the trains do not match (@1 and @2).=Die Kupplungen der Züge passen nicht zueinander (@1 und @2).
+You are not allowed to couple trains without the train_operator privilege.=Sie dürfen ohne das „train_builder“-Privileg keine Züge ankuppeln.
+
+# Clipboard
+The track you are trying to place the wagon on is not long enough!=Das Gleis, auf dem der Waggon platziert werden woll, ist zu kurz.
+The clipboard couldn't access the metadata. Paste failed.=Wegen des fehlgeschlagenen Zugriffs auf die Metadaten konnte eine Kopie des Zuges nicht eingefügt werden.
+The clipboard couldn't access the metadata. Copy failed.=Wegen des fehlgeschlagenen Zugriffs auf die Metadaten konnte der Zug nicht kopiert werden.
+The clipboard is empty.=Das Clipboard ist leer.
+Back of train would end up off track, cancelling.=Der hinterer Teil dez Zuges wäre nicht auf dem Gleis.
+No such lua entity!=Sie zeigen nicht auf einem Objekt, das mit diesem Werkzeug kopiert werden kann.
+No such wagon: @1=Es gibt keinen mit „@1“ identifizierbaren Waggon.
+No such train: @1=Es gibt keinen mit „@1“ identifizierbaren Zug.
+Train copied!=Der Zug wurde Kopiert.
+
+# Protection
+You are not allowed to build tracks without the track_builder privilege.=Sie dürfen ohne das „track_builder“-Privileg kein Gleis bauen.
+You are not allowed to build near tracks without the track_builder privilege.=Sie dürfen ohne das „track_builder“-Privileg nicht in der Nähe von Gleisen bauen.
+You are not allowed to build tracks at this protected position.=Sie dürfen an geschützten Stellen kein Gleis bauen.
+You are not allowed to build near tracks at this protected position.=Sie dürfen an geschützten Stellen nicht in der Nähe von Gleisen bauen.
+You are not allowed to operate turnouts and signals without the railway_operator privilege.=Sie dürfen ohne das „railway_operator“-Privileg keine Bahnanlage operieren.
+
+# Train HUD/Formspecs
Speed:=Geschw.:
Target:=Zielges.:
-@1 Slope=@1 Steigung
-Can't get on: wagon full or doors closed!=Kann nicht einsteigen: Waggon voll oder Türen geschlossen.
-Use Sneak+rightclick to bypass closed doors!=Nutze Sneak+Rechtsklick, um die Türnotöffnung zu aktivieren und trotzdem einzusteigen.
-Lock couples=Kupplungen sperren
-Save wagon properties=Waggon-Einstellungen speichern
-Doors are closed! Use Sneak+rightclick to ignore the closed doors and get off!=Türen sind geschlossen! Sneak+Rechtsklick, um die Türnotöffnung zu aktivieren und trotzdem auszusteigen.
+Show Inventory=Inventar Zeigen
+Select seat:=Wählen Sie einen Sitzplatz aus:
Wagon properties=Waggon-Einstellungen
+Save wagon properties=Waggon-Einstellungen speichern
+Text displayed outside on train=Äußere Anzeige
+Text displayed inside train=Innere Anzeige
+Line=Linie
+Routingcode=Routingcode
Get off=Aussteigen
-Get off (forced)=Aussteigen (erzwingen)
+Get off (forced)=Ausstieg zwingen
(Doors closed)=(Türen geschlossen)
-Access to @1=Zugang zu @1
+
+# General
+Save=Speichern
+
+# Line automation
+Station Code=Code der Haltestelle
+Station Name=Name der Haltestelle
+Door Delay=Zeit für die Türschließung
+Door Side=Door Side
+Dep. Speed=Zielgeschwindigkeit bei Abfahrt
+Stop Time=Wartezeit
+
+# Items
+Track Worker Tool@n@nLeft-click: change rail type (straight/curve/switch)@nRight-click: rotate rail/bumper/signal/etc.=Gleiswerkzeug@n@nLinksklick: Gleistyp ändern, Rechtsklick: Objekt drehen.
+Passive Component Naming Tool@n@nRight-click to name a passive component.=PC-Benennungswerkzeug@n@nRechtsklick zur Benennung der passiven Komponente
+Train copy/paste tool@n@nLeft-click: copy train@nRight-click: paste train=Werkzeug zur Erstellung von Zugkopien@n@nLinksklick: Zug ins Clipboard kopieren@nRight-click: Kopierten Zug einfügen
+Track=Gleis
+Perpendicular Diamond Crossing Track=Kreuzung mit zueinander orthogonalen Gleisen
+Diagonal Diamond Crossing Track=Diagonale Gleiskreuzung
+90+Angle Diamond Crossing Track=Kreuzung mit einem achsenparallelen Gleis
+Y-turnout=Y-Weiche
+3-way turnout=Dreiwegweiche
+Unloading Track=Abladungsgleis
+Loading Track=Beladungsgleis
+Bumper=Prellbock
+Detector Rail=Detektorgleis
+@1 Slope=@1 Steigung
+@1 Platform (low)=Niedriger @1-Bahnsteig
+@1 Platform (high)=Hoher @1-Bahnsteig
+@1 Platform (low, 45 degree)=Niedriger @1-Bahnsteig (45°)
+@1 Platform (45 degree)=Hoher @1-Bahnsteig (45°)
+Lampless Signal=Mechanisches Signal
+Signal=Lichtsignal
+Wallmounted Signal (l)=An der linken Seite montiertes Signal
+Wallmounted Signal (r)=An der rechten Seite montiertes Signal
+Wallmounted Signal (t)=An der Decke montiertes Signal
+Andrew's Cross=Andrew's Cross
+Boiler=Boiler
+driver's cab=driver's cab
+Wheel=Wheel
+Chimney=Chimney
+
+# Seats
Default Seat=Standardsitzplatz
Default Seat (driver stand)=Standardsitzplatz (Führerstand)
-Driver Stand=Führerstand
+Driver stand=Führerstand
Driver Stand (left)=Führerstand Links
Driver Stand (right)=Führerstand Rechts
+
+# Wagon/engine types
Industrial Train Engine=Industrielle Lokomotive
+Big Industrial Train Engine=Große Industrielle Lokomotive
Industrial tank wagon=Tankwaggon
Industrial wood wagon=Holztransportwaggon
Japanese Train Engine=Japanische Personenzug-Lokomotive
@@ -61,7 +142,7 @@ Japanese Train Wagon=Japanischer Personenzug-Passagierwaggon
Steam Engine=Dampflokomotive
Detailed Steam Engine=detaillierte Dampflokomotive
Passenger Wagon=Passagierwaggon
-Box wagon=Güterwaggon
+Box Wagon=Güterwaggon
Subway Passenger Wagon=U-Bahn-Waggon
The wagon's inventory is not empty!=Das Inventar dieses Waggons ist nicht leer!
This track can not be changed!=Diese Schiene kann nicht geändert werden!
diff --git a/advtrains/locale/advtrains.fr.tr b/advtrains/locale/advtrains.fr.tr
new file mode 100644
index 0000000..0dd6d00
--- /dev/null
+++ b/advtrains/locale/advtrains.fr.tr
@@ -0,0 +1,146 @@
+# textdomain: advtrains
+
+# Advtrains Core (unorganized)
+This wagon is owned by @1, you can't destroy it.=Ce wagon est la propriété de @1, vous ne pouvez pas le détruire.
+Warning: If you destroy this wagon, you only get some steel back! If you are sure, hold Sneak and left-click the wagon.=Attention: Si vous détruisez ce wagon, vous ne récupérerez que de la ferraille ! Si vous êtes sûr de vous, appuyez la touche "Marcher lentement (Sneak)" et Clic-Gauche.
+This position is protected!=Cet emplacement est protégé !
+Can't place: not pointing at node=Placement impossible : ne pointe pas un nœud
+Can't place: space occupied!=Placement impossible : espace occupé
+Can't place: protected position!=Placement impossible : emplacement protégé
+Can't place: Not enough slope items left (@1 required)=Placement impossible : quantité insuffisante de voie pentue (@1 manquant)
+Can't place: There's no slope of length @1=Placement impossible : il n'y a pas de voie pentue de longueur @1
+Can't place: no supporting node at upper end.=Placement impossible : pas de nœud d'appui à l'extrémité supérieure
+Deprecated Track=Voie déconseillée
+Can't get on: wagon full or doors closed!=Embarquement impossible : le wagon est plein ou ses portes sont closes !
+Use Sneak+rightclick to bypass closed doors!=Utilisez "Marcher lentement (Sneak)" et Clic-Droit pour franchir les portes closes !
+Doors are closed! Use Sneak+rightclick to ignore the closed doors and get off!=Portes closes ! Utilisez "Marcher lentement (Sneak)" et Clic-Droit pour franchir les portes et débarquer !
+Access to @1=Accès à @1
+You do not have the @1 privilege.=Vous ne possédez pas le privilège "@1".
+The wagon's inventory is not empty!=Le stock de ce wagon n'est pas vide !
+Position is occupied by a train.=Cet emplacement est occupé par un train.
+There's a Track Circuit Break here.=Il y a un "Track Circuit Break" ici.
+There's a Signal Influence Point here.=Il y a un "Signal Influence Point" ici.
+
+# Trackworker, rotation, adjustment
+This node can't be rotated using the trackworker!=Ce nœud ne peut être tourné avec l'outil "Trackworker" !
+This node can't be changed using the trackworker!=Ce nœud ne peut être modifié avec l'outil "Trackworker" !
+This track can not be changed!=Cette voie ne peut pas être modifiée !
+This track can not be rotated!=Cette voie ne peut pas être tournée !
+This track can not be removed!=Cette voie ne peut pas être enlevée !
+
+# ATC
+ATC controller, unconfigured.=Controlleur ATC, non-configuré
+ATC controller=Controlleur ATC
+ATC controller, mode @1@nChannel: @2=Controlleur ATC, mode @1@nCanal : @2
+ATC controller, mode @1@nCommand: @2=Controlleur ATC, mode @1@nCommande : @2
+Command=Commande
+Command (on)=Commande (marche)
+Digiline channel=Canal Digiline
+ATC Kick command warning: Doors closed=ATC Kick command warning: Doors closed
+ATC Kick command warning: Train moving=ATC Kick command warning: Train moving
+ATC Reverse command warning: didn't reverse train, train moving!=Attention : Commande ATC de renversement impossible car le train se déplace !
+ATC command syntax error: I statement not closed: @1=Erreur de syntaxe de commande ATC : instruction "I" incomplète : @1
+ATC command parse error: Unknown command: @1=Erreur d'analyse de commande ATC : Commande inconnue : @1
+
+# Coupling
+Lock couples=Verrouiller l'accouplement
+You need to own at least one neighboring wagon to destroy this couple.=Vous devez être propriétaire d'au moins un wagon voisin pour supprimer cet attelage.
+Buffer and Chain Coupler=Attelage à tampon et vis
+Scharfenberg Coupler=Attelage Scharfenberg
+Japanese Train Inter-Wagon Connection=Passage inter-voiture de train Japonais
+Can not couple: The couplers of the trains do not match (@1 and @2).=Accouplement impossible: les attelages des trains ne concordent pas (@1 et @2).
+You are not allowed to couple trains without the train_operator privilege.=You are not allowed to couple trains without the train_operator privilege.
+
+# Clipboard
+The track you are trying to place the wagon on is not long enough!=La voie sur laquelle vous tentez de placer le wagon est trop courte !
+The clipboard couldn't access the metadata. Paste failed.=Le presse-papier ne peut accéder aux métadonnées. Échec du collage.
+The clipboard couldn't access the metadata. Copy failed.=Le presse-papier ne peut accéder aux métadonnées. Échec de la copie.
+The clipboard is empty.=Le presse-papier est vide.
+Back of train would end up off track, cancelling.=La fin du train serait hors voie : annulation.
+No such lua entity!=Pas de telle entité lua !
+No such wagon: @1=Pas de tel wagon : @1
+No such train: @1=Pas de tel train : @1
+Train copied!=Train copié !
+
+# Protection
+You are not allowed to build tracks without the track_builder privilege.=Vous ne pouvez pas construire une voie sans le privilège "track_builder"
+You are not allowed to build near tracks without the track_builder privilege.=Vous ne pouvez pas construire à proximité d'une voie sans le privilège "track_builder" (?)
+You are not allowed to build tracks at this protected position.=Vous ne pouvez pas construire une voie à cet emplacement protégé
+You are not allowed to build near tracks at this protected position.=Vous ne pouvez pas construire à proximité d'une voie à cet emplacement protégé
+You are not allowed to operate turnouts and signals without the railway_operator privilege.=Vous ne pouvez pas actionner les aiguillages ou les signaux (privilège "railway_operator" manquant)
+
+# Train HUD/Formspecs
+Speed:=Vitesse :
+Target:=Destination :
+Show Inventory=Montrer le stock
+Select seat:=Choisir le siège
+Wagon properties=Propriétés du wagon
+Save wagon properties=Sauvegarder les propriétés du wagon
+Text displayed outside on train=Texte affiché à l'extérieur du train
+Text displayed inside train=Texte affiché à l'intérieur du train
+Line=Ligne
+Routingcode=Code de routage
+Get off=Débarquer
+Get off (forced)=Débarquer (de force)
+(Doors closed)=(Portes closes)
+
+# General
+Save=Sauvegarder
+
+# Line automation
+Station Code=Code de Station
+Station Name=Nom de Station
+Door Delay=Durée d'ouverture des portes
+Door Side=Door Side
+Dep. Speed=Vitesse de départ
+Stop Time=Durée d'arrêt
+
+# Items
+Track Worker Tool@n@nLeft-click: change rail type (straight/curve/switch)@nRight-click: rotate rail/bumper/signal/etc.=Outil "Trackworker"@n@nClic-Gauche : change le type de rail (droit/courbé/aiguillage)@n@nClic-Droit : tourne le rail/butoir/signal/etc...
+Passive Component Naming Tool@n@nRight-click to name a passive component.=Outil de nommage de composant passif@n@nClic-Droit pour nommer un composant passif.
+Train copy/paste tool@n@nLeft-click: copy train@nRight-click: paste train=Outil de copie/collage de train@n@nClic-Gauche : copie@n@nClic-Droit : collage
+Track=Voie
+Perpendicular Diamond Crossing Track=Croisement perpendiculaire
+Diagonal Diamond Crossing Track=Croisement diagonal
+90+Angle Diamond Crossing Track=Croisement perpendiculo-diagonal
+Y-turnout=Embranchement en Y
+3-way turnout=Embranchement triple
+Unloading Track=Voie de Déchargement
+Loading Track=Voie de Chargement
+Bumper=Heurtoir
+Detector Rail=Voie détectrice
+@1 Slope=Pente @1
+@1 Platform (low)=Quai @1 (bas)
+@1 Platform (high)=Quai @1 (haut)
+@1 Platform (low, 45 degree)=Quai @1 (bas, 45°)
+@1 Platform (45 degree)=Quai @1 (haut, 45°)
+Lampless Signal=Sémaphore
+Signal=Signal
+Wallmounted Signal (l)=Signal mural (gauche)
+Wallmounted Signal (r)=Signal mural (droit)
+Wallmounted Signal (t)=Signal mural (plafond)
+Andrew's Cross=Croix de Saint André
+Boiler=Chaudière à vapeur
+driver's cab=Cabine de pilotage
+Wheel=Roue
+Chimney=Cheminée
+
+# Seats
+Default Seat=Siège par défaut
+Default Seat (driver stand)=Siège par défaut (poste de pilotage)
+Driver stand=Poste de pilotage
+Driver Stand (left)=Poste de pilotage (gauche)
+Driver Stand (right)=Poste de pilotage (droit)
+
+# Wagon/engine types
+Industrial Train Engine=Locomotive industrielle
+Big Industrial Train Engine=Grosse locomotive industrielle
+Industrial tank wagon=Wagon-citerne industriel
+Industrial wood wagon=Wagon grumier industriel
+Japanese Train Engine=Motrice Japonaise
+Japanese Train Wagon=Voiture Japonaise
+Steam Engine=Locomotive à vapeur
+Detailed Steam Engine=Locomotive à vapeur complexe
+Passenger Wagon=Voiture passager
+Box Wagon=Wagon de frêt
+Subway Passenger Wagon=Voiture de Métropolitain
diff --git a/advtrains/locale/advtrains.zh_CN.tr b/advtrains/locale/advtrains.zh_CN.tr
index ef9c99b..6ed4887 100644
--- a/advtrains/locale/advtrains.zh_CN.tr
+++ b/advtrains/locale/advtrains.zh_CN.tr
@@ -1,40 +1,77 @@
# textdomain: advtrains
# Advtrains Core (unorganized)
-This wagon is owned by @1, you can't destroy it.=这是@1的车厢, 你不能摧毁它.
-Warning: If you destroy this wagon, you only get some steel back! If you are sure, hold Sneak and left-click the wagon.=警告: 如果你摧毁此车厢, 你只能拿到一些钢方块. 如果你确定要摧毁这个车厢,请按潜行键并左键单击此车厢.
-ATC controller, unconfigured.=ATC控制器 (未配置)
-ATC controller=ATC控制器
-ATC controller, mode @1@nChannel: @2=ATC控制器@n模式: @1@n频道: @2
-ATC controller, mode @1@nCommand: @2=ATC控制器@n模式: @1@n命令: @2
+This wagon is owned by @1, you can't destroy it.=这是 @1 的车厢,您不能摧毁它。
+Warning: If you destroy this wagon, you only get some steel back! If you are sure, hold Sneak and left-click the wagon.=警告:如果您摧毁此车厢,您只能拿到一些钢方块。如果您确定要摧毁这节车厢,请按潜行键并左键单击此车厢。
+This position is protected!=这里已被保护。
+Can't place: not pointing at node=无法放置:您没有选择任何方块。
+Can't place: space occupied!=无法放置:此区域已被占用。
+Can't place: protected position!=无法放置:此区域已被保护。
+Can't place: Not enough slope items left (@1 required)=无法放置:您没有足够的铁路斜坡放置工具 (您总共需要@1个)
+Can't place: There's no slope of length @1=无法放置:advtrains 不支持长度为@1米的斜坡。
+Can't place: no supporting node at upper end.=无法放置:较高端没有支撑方块。
+Deprecated Track=请不要使用
+Can't get on: wagon full or doors closed!=无法上车:车门已关闭或车厢已满。
+Use Sneak+rightclick to bypass closed doors!=请使用潜行+右键上车。
+Doors are closed! Use Sneak+rightclick to ignore the closed doors and get off!=车门已关闭,请使用潜行+右键单击下车。
+Access to @1=可前往@1
+You do not have the @1 privilege.=您没有“@1”权限。
+The wagon's inventory is not empty!=The wagon's inventory is not empty!
+Position is occupied by a train.=Position is occupied by a train.
+There's a Track Circuit Break here.=There's a Track Circuit Break here.
+There's a Signal Influence Point here.=There's a Signal Influence Point here.
+
+# Trackworker, rotation, adjustment
+This node can't be rotated using the trackworker!=您不能使用铁路调整工具旋转这个方块。
+This node can't be changed using the trackworker!=您不能使用铁路调整工具调整这个方块。
+This track can not be changed!=您不能调整这段轨道。
+This track can not be rotated!=您不能旋转这段轨道。
+This track can not be removed!=您不能移除这段轨道。
+
+# ATC
+ATC controller, unconfigured.=ATC 控制器 (未配置)
+ATC controller=ATC 控制器
+ATC controller, mode @1@nChannel: @2=ATC 控制器@n模式:@1@n频道:@2
+ATC controller, mode @1@nCommand: @2=ATC 控制器@n模式:@1@n命令:@2
Command=命令
-Command (on)=命令(激活时)
+Command (on)=命令 (激活时)
Digiline channel=Digiline 频道
-ATC Reverse command warning: didn't reverse train, train moving!=ATC警告:未执行“R”命令, 火车在移动
-ATC command syntax error: I statement not closed: @1=ATC语法错误: "I"命令不完整: @1
-ATC command parse error: Unknown command: @1=ATC语法错误: 未知命令: @1
-This position is protected!=这里已被保护.
-You need to own at least one neighboring wagon to destroy this couple.=你必须至少拥有其中一个车厢才能解耦这两个车厢.
-This node can't be rotated using the trackworker!=你不能使用铁路调整工具旋转这个方块.
-This node can't be changed using the trackworker!=你不能使用铁路调整工具调整这个方块.
-Can't place: not pointing at node=无法放置: 你没有选择任何方块.
-Can't place: space occupied!=无法放置: 此区域已被占用.
-Can't place: protected position!=无法放置: 此区域已被保护.
-Can't place: Not enough slope items left (@1 required)=无法放置: 你没有足够的铁路斜坡放置工具 (你需要@1个)
-Can't place: There's no slope of length @1=无法放置: advtrains不支持长度为@1m的斜坡.
-Can't place: no supporting node at upper end.=无法放置: 较高端没有支撑方块.
-Deprecated Track=请不要使用
-Can't get on: wagon full or doors closed!=无法上车: 车门已关闭或车厢已满
-Use Sneak+rightclick to bypass closed doors!=请使用潜行+右键上车
+ATC Kick command warning: Doors closed=ATC Kick command warning: Doors closed
+ATC Kick command warning: Train moving=ATC Kick command warning: Train moving
+ATC Reverse command warning: didn't reverse train, train moving!=ATC 警告:未执行“R”命令,火车在移动
+ATC command syntax error: I statement not closed: @1=ATC 语法错误:“I”命令不完整:@1
+ATC command parse error: Unknown command: @1=ATC 语法错误:未知命令:@1
+
+# Coupling
Lock couples=锁定连接处
-Doors are closed! Use Sneak+rightclick to ignore the closed doors and get off!=车门已关闭, 请使用潜行+右键单击下车
-Access to @1=可前往@1
-The clipboard couldn't access the metadata. Paste failed.=无法粘贴: 剪贴板无法访问元数据
-The clipboard couldn't access the metadata. Copy failed.=无法复制: 剪贴板无法访问元数据
+You need to own at least one neighboring wagon to destroy this couple.=您必须至少拥有其中一节车厢才能分开这两节车厢。
+Buffer and Chain Coupler=链式车钩
+Scharfenberg Coupler=Scharfenberg 式车钩
+Japanese Train Inter-Wagon Connection=日本火车车钩
+Can not couple: The couplers of the trains do not match (@1 and @2).=您无法连接这两节车厢:这两节车厢使用不同的车钩 (@1和@2)。
+You are not allowed to couple trains without the train_operator privilege.=您没有“train_operator”权限,不能连接这两节车厢。
+
+# Clipboard
+The track you are trying to place the wagon on is not long enough!=轨道太短。
+The clipboard couldn't access the metadata. Paste failed.=无法粘贴:剪贴板无法访问元数据。
+The clipboard couldn't access the metadata. Copy failed.=无法复制:剪贴板无法访问元数据。
+The clipboard is empty.=剪贴板是空的。
+Back of train would end up off track, cancelling.=火车后部不在轨道上。
+No such lua entity!=您没有指向一个可以用火车复制工具复制的物体。
+No such wagon: @1=ID 为“@1”的车厢不存在。
+No such train: @1=ID 为“@1”的列车不存在。
+Train copied!=已复制
+
+# Protection
+You are not allowed to build tracks without the track_builder privilege.=您没有“train_operator”权限,不能在这里建造铁路。
+You are not allowed to build near tracks without the track_builder privilege.=您没有“train_operator”权限,不能在铁路附近建任何东西。
+You are not allowed to build tracks at this protected position.=这里已被保护,您不能在这里建造铁路。
+You are not allowed to build near tracks at this protected position.=这里已被保护,您不能在这里的铁路附近建任何东西。
+You are not allowed to operate turnouts and signals without the railway_operator privilege.=您没有“railway_operator”权限,不能控制铁路设施。
# Train HUD/Formspecs
-Speed:=速度:
-Target:=目标速度:
+Speed:=速度
+Target:=目标速度
Show Inventory=显示物品栏
Select seat:=请选择座位
Wagon properties=车厢属性
@@ -49,34 +86,36 @@ Get off (forced)=强制下车
# General
Save=保存
-# "off" and "on" can be translated differently depending on the context and are therefore not translated.
-off=off
-on=on
# Line automation
Station Code=车站代码
Station Name=车站名称
Door Delay=车门关闭时间
-Departure Speed=出发速度
+Door Side=Door Side
+Dep. Speed=出发速度
Stop Time=停站时间
# Items
-Track Worker Tool@n@nLeft-click: change rail type (straight/curve/switch)@nRight-click: rotate rail/bumper/signal/etc.=铁路调整工具@n@n左键单击: 切换轨道类型@n右键单击: 旋转方块
-Passive Component Naming Tool@n@nRight-click to name a passive component.=被动元件命名工具@n@n右键单击命名所选元件.
-Train copy/paste tool@n@nLeft-click: copy train@nRight-click: paste train=火车复制工具@n@n左键单击: 复制@n右键单击: 粘帖
-Track=铁轨
-Perpendicular Diamond Crossing Track=垂直交叉铁轨
-45/90 Degree Diamond Crossing Track=45度交叉铁轨
-Unloading Track=卸货铁轨
-Loading Track=装货铁轨
+Track Worker Tool@n@nLeft-click: change rail type (straight/curve/switch)@nRight-click: rotate rail/bumper/signal/etc.=铁路调整工具@n@n左键单击:切换轨道类型@n右键单击:旋转方块
+Passive Component Naming Tool@n@nRight-click to name a passive component.=被动元件命名工具@n@n右键单击命名所选元件
+Train copy/paste tool@n@nLeft-click: copy train@nRight-click: paste train=火车复制工具@n@n左键单击:复制@n右键单击:粘帖
+Track=轨道
+Perpendicular Diamond Crossing Track=垂直交叉轨道
+Diagonal Diamond Crossing Track=交叉轨道
+90+Angle Diamond Crossing Track=交叉轨道 (其中一条轨道与坐标轴平行)
+Y-turnout=对称道岔
+3-way turnout=三开道岔
+Unloading Track=卸货轨道
+Loading Track=装货轨道
Bumper=保险杠
-Detector Rail=探测铁轨
+Detector Rail=探测轨道
@1 Slope=@1斜坡
-@1 Platform (low)=50cm高的@1站台
-@1 Platform (high)=1m高的@1站台
-@1 Platform (45 degree)=1m高的@1站台 (45度)
-Lampless Signal (@1)=臂板信号机 (@1)
-Signal (@1)=信号灯 (@1)
+@1 Platform (low)=较低的@1站台
+@1 Platform (high)=较高的@1站台
+@1 Platform (low, 45 degree)=较低的@1站台 (45°)
+@1 Platform (45 degree)=较高的@1站台 (45°)
+Lampless Signal=臂板信号机
+Signal=信号灯
Wallmounted Signal (l)=壁挂式信号灯 (左侧)
Wallmounted Signal (r)=壁挂式信号灯 (右侧)
Wallmounted Signal (t)=悬挂式信号灯
@@ -89,7 +128,7 @@ Chimney=烟囱
# Seats
Default Seat=默认座位
Default Seat (driver stand)=默认座位 (司机座位)
-Driver Stand=司机座位
+Driver stand=司机座位
Driver Stand (left)=左侧司机座位
Driver Stand (right)=右侧司机座位
diff --git a/advtrains/locale/advtrains.zh_TW.tr b/advtrains/locale/advtrains.zh_TW.tr
new file mode 100644
index 0000000..37cce79
--- /dev/null
+++ b/advtrains/locale/advtrains.zh_TW.tr
@@ -0,0 +1,146 @@
+# textdomain: advtrains
+
+# Advtrains Core (unorganized)
+This wagon is owned by @1, you can't destroy it.=這是 @1 的車廂,您不能摧毀它。
+Warning: If you destroy this wagon, you only get some steel back! If you are sure, hold Sneak and left-click the wagon.=警告:如果您摧毀此車廂,您只能拿到一些鋼方塊。如果您確定要摧毀這節車廂,請按潛行鍵並左鍵單擊此車廂。
+This position is protected!=這裡已被保護。
+Can't place: not pointing at node=無法放置:您沒有選擇任何方塊。
+Can't place: space occupied!=無法放置:此區域已被佔用。
+Can't place: protected position!=無法放置:此區域已被保護。
+Can't place: Not enough slope items left (@1 required)=無法放置:您沒有足夠的鐵路斜坡放置工具 (您總共需要@1個)
+Can't place: There's no slope of length @1=無法放置:advtrains 不支援長度為@1米的斜坡。
+Can't place: no supporting node at upper end.=無法放置:較高階沒有支撐方塊。
+Deprecated Track=請不要使用
+Can't get on: wagon full or doors closed!=無法上車:車門已關閉或車廂已滿。
+Use Sneak+rightclick to bypass closed doors!=請使用潛行+右鍵上車。
+Doors are closed! Use Sneak+rightclick to ignore the closed doors and get off!=車門已關閉,請使用潛行+右鍵單擊下車。
+Access to @1=可前往@1
+You do not have the @1 privilege.=您沒有「@1」許可權。
+The wagon's inventory is not empty!=The wagon's inventory is not empty!
+Position is occupied by a train.=Position is occupied by a train.
+There's a Track Circuit Break here.=There's a Track Circuit Break here.
+There's a Signal Influence Point here.=There's a Signal Influence Point here.
+
+# Trackworker, rotation, adjustment
+This node can't be rotated using the trackworker!=您不能使用鐵路調整工具旋轉這個方塊。
+This node can't be changed using the trackworker!=您不能使用鐵路調整工具調整這個方塊。
+This track can not be changed!=您不能調整這段軌道。
+This track can not be rotated!=您不能旋轉這段軌道。
+This track can not be removed!=您不能移除這段軌道。
+
+# ATC
+ATC controller, unconfigured.=ATC 控制器 (未配置)
+ATC controller=ATC 控制器
+ATC controller, mode @1@nChannel: @2=ATC 控制器@n模式:@1@n頻道:@2
+ATC controller, mode @1@nCommand: @2=ATC 控制器@n模式:@1@n命令:@2
+Command=命令
+Command (on)=命令 (啟用時)
+Digiline channel=Digiline 頻道
+ATC Kick command warning: Doors closed=ATC Kick command warning: Doors closed
+ATC Kick command warning: Train moving=ATC Kick command warning: Train moving
+ATC Reverse command warning: didn't reverse train, train moving!=ATC 警告:未執行「R」命令,火車在移動
+ATC command syntax error: I statement not closed: @1=ATC 語法錯誤:「I」命令不完整:@1
+ATC command parse error: Unknown command: @1=ATC 語法錯誤:未知命令:@1
+
+# Coupling
+Lock couples=鎖定連結處
+You need to own at least one neighboring wagon to destroy this couple.=您必須至少擁有其中一節車廂才能分開這兩節車廂。
+Buffer and Chain Coupler=鏈式連結器
+Scharfenberg Coupler=Scharfenberg 式連結器
+Japanese Train Inter-Wagon Connection=日本火車連結器
+Can not couple: The couplers of the trains do not match (@1 and @2).=您無法連結這兩節車廂:這兩節車廂使用不同的連結器 (@1和@2)。
+You are not allowed to couple trains without the train_operator privilege.=您沒有「train_operator」許可權,不能連結這兩節車廂。
+
+# Clipboard
+The track you are trying to place the wagon on is not long enough!=軌道太短。
+The clipboard couldn't access the metadata. Paste failed.=無法貼上:剪貼簿無法訪問元資料。
+The clipboard couldn't access the metadata. Copy failed.=無法複製:剪貼簿無法訪問元資料。
+The clipboard is empty.=剪貼簿是空的。
+Back of train would end up off track, cancelling.=火車後部不在軌道上。
+No such lua entity!=您沒有指向一個可以用火車複製工具複製的物體。
+No such wagon: @1=ID 為「@1」的車廂不存在。
+No such train: @1=ID 為「@1」的列車不存在。
+Train copied!=已複製
+
+# Protection
+You are not allowed to build tracks without the track_builder privilege.=您沒有「train_operator」許可權,不能在這裡建造鐵路。
+You are not allowed to build near tracks without the track_builder privilege.=您沒有「train_operator」許可權,不能在鐵路附近建任何東西。
+You are not allowed to build tracks at this protected position.=這裡已被保護,您不能在這裡建造鐵路。
+You are not allowed to build near tracks at this protected position.=這裡已被保護,您不能在這裡的鐵路附近建任何東西。
+You are not allowed to operate turnouts and signals without the railway_operator privilege.=您沒有「railway_operator」許可權,不能控制鐵路設施。
+
+# Train HUD/Formspecs
+Speed:=速度
+Target:=目標速度
+Show Inventory=顯示物品欄
+Select seat:=請選擇座位
+Wagon properties=車廂屬性
+Save wagon properties=儲存車廂屬性
+Text displayed outside on train=車廂外部顯示
+Text displayed inside train=車廂內部顯示
+Line=火車線路
+Routingcode=路由碼
+Get off=下車
+Get off (forced)=強制下車
+(Doors closed)=(車門已關閉)
+
+# General
+Save=儲存
+
+# Line automation
+Station Code=車站碼
+Station Name=車站名稱
+Door Delay=車門關閉時間
+Door Side=Door Side
+Dep. Speed=出發速度
+Stop Time=停站時間
+
+# Items
+Track Worker Tool@n@nLeft-click: change rail type (straight/curve/switch)@nRight-click: rotate rail/bumper/signal/etc.=鐵路調整工具@n@n左鍵單擊:切換軌道型別@n右鍵單擊:旋轉方塊
+Passive Component Naming Tool@n@nRight-click to name a passive component.=被動元件命名工具@n@n右鍵單擊命名所選元件
+Train copy/paste tool@n@nLeft-click: copy train@nRight-click: paste train=火車複製工具@n@n左鍵單擊:複製@n右鍵單擊:粘帖
+Track=軌道
+Perpendicular Diamond Crossing Track=垂直交叉軌道
+Diagonal Diamond Crossing Track=交叉軌道
+90+Angle Diamond Crossing Track=交叉軌道 (其中一條軌道與座標軸平行)
+Y-turnout=對稱道岔
+3-way turnout=三開道岔
+Unloading Track=卸貨軌道
+Loading Track=裝貨軌道
+Bumper=保險槓
+Detector Rail=探測軌道
+@1 Slope=@1斜坡
+@1 Platform (low)=較低的@1月臺
+@1 Platform (high)=較高的@1月臺
+@1 Platform (low, 45 degree)=較低的@1月臺 (45°)
+@1 Platform (45 degree)=較高的@1月臺 (45°)
+Lampless Signal=臂木式號誌機
+Signal=色燈號誌機
+Wallmounted Signal (l)=壁掛式色燈號誌機 (左側)
+Wallmounted Signal (r)=壁掛式色燈號誌機 (右側)
+Wallmounted Signal (t)=懸掛式色燈號誌機
+Andrew's Cross=平交道號誌燈
+Boiler=鍋爐
+driver's cab=駕駛室
+Wheel=車輪
+Chimney=煙囪
+
+# Seats
+Default Seat=預設座位
+Default Seat (driver stand)=預設座位 (司機座位)
+Driver stand=司機座位
+Driver Stand (left)=左側司機座位
+Driver Stand (right)=右側司機座位
+
+# Wagon/engine types
+Industrial Train Engine=工業用火車頭
+Big Industrial Train Engine=大型工業用火車頭
+Industrial tank wagon=液體運輸車廂
+Industrial wood wagon=木材運輸車廂
+Japanese Train Engine=高速列車車頭
+Japanese Train Wagon=高速列車車廂
+Steam Engine=蒸汽機車
+Detailed Steam Engine=精細的蒸汽機車
+Passenger Wagon=客車
+Box Wagon=貨運車廂
+Subway Passenger Wagon=地鐵車廂
diff --git a/advtrains/locale/gui b/advtrains/locale/gui
new file mode 100755
index 0000000..7f455e4
--- /dev/null
+++ b/advtrains/locale/gui
@@ -0,0 +1,638 @@
+#!/usr/bin/tclsh
+package require Tk
+
+# Auxiliary functions
+proc maybe_lindex {lst idx fallback} {
+ set val [lindex $lst $idx]
+ if {$val eq {}} {
+ return $fallback
+ } else {
+ return $val
+ }
+}
+
+proc firstupper {str} {
+ return [string cat [string toupper [string index $str 0]] [string range $str 1 end]]
+}
+
+# CLI arguments
+# NOTE: This will likely be changed in the future
+set translationDomain [maybe_lindex $argv 0 "advtrains"]
+set translationDir [maybe_lindex $argv 1 "."]
+
+# Translation file I/O, etc
+
+set translationTemplatePath [file join $translationDir "template.txt"]
+
+proc translationFilePaths {} {
+ global translationDir translationDomain
+ return [glob -path [file join $translationDir $translationDomain] ".*.tr"]
+}
+
+proc readTranslationTemplate {} {
+ global translationTemplate translationTemplatePath
+ set translationTemplate [list]
+ set handle [open $translationTemplatePath "r"]
+ fconfigure $handle -translation lf
+ while {[gets $handle line] >= 0} {
+ if {$line eq ""} {
+ lappend translationTemplate $line
+ } elseif {[string match {#*} $line]} {
+ lappend translationTemplate $line
+ } elseif {[regexp {^(.+[^@])=.+$} $line x str]} {
+ lappend translationTemplate $str
+ }
+ }
+ close $handle
+}
+
+proc readTranslationFiles {} {
+ global translationData translationLangs
+ array set translationData [list]
+ set translationLangs [list]
+ foreach fn [translationFilePaths] {
+ if {[regexp {\.([^.]+)\.tr$} $fn x lang]} {
+ set handle [open $fn "r"]
+ fconfigure $handle -translation lf
+ while {[gets $handle line] >= 0} {
+ if {[regexp {^([^#].+[^@])=(.+)$} $line x ori tr]} {
+ set translationData($lang,$ori) $tr
+ }
+ }
+ lappend translationLangs $lang
+ close $handle
+ }
+ }
+ set translationLangs [lsort $translationLangs]
+}
+
+proc readTranslations {} {
+ readTranslationTemplate
+ readTranslationFiles
+}
+
+proc writeTranslationTemplate {} {
+ global translationTemplate translationTemplatePath
+ set handle [open $translationTemplatePath "w"]
+ fconfigure $handle -translation lf
+ foreach line $translationTemplate {
+ if {$line eq ""} {
+ puts $handle ""
+ } elseif {[string match {#*} $line]} {
+ puts $handle $line
+ } else {
+ puts $handle "$line=$line"
+ }
+ }
+ close $handle
+}
+
+proc writeTranslationFiles {} {
+ global translationDir translationDomain translationData translationLangs translationTemplate
+ foreach lang $translationLangs {
+ set handle [open [file join $translationDir "$translationDomain.$lang.tr"] "w"]
+ fconfigure $handle -translation lf
+ foreach i $translationTemplate {
+ if {$i eq ""} {
+ puts $handle ""
+ } elseif {[string match {#*} $i]} {
+ puts $handle $i
+ } else {
+ puts $handle [format "%s=%s" $i [getTranslationString $lang $i]]
+ }
+ }
+ close $handle
+ }
+}
+
+proc writeTranslations {} {
+ writeTranslationTemplate
+ writeTranslationFiles
+}
+
+proc hasTranslationString {lang str} {
+ return [expr {[getTranslationString $lang $str] ne $str}]
+}
+
+proc maybeGetTranslationString {lang str} {
+ set tr [getTranslationString $lang $str]
+ if {$tr eq $str} {
+ return {}
+ } else {
+ return $tr
+ }
+}
+
+proc getTranslationString {lang str} {
+ global translationData
+ if {[info exists translationData($lang,$str)]} {
+ return $translationData($lang,$str)
+ } else {
+ return $str
+ }
+}
+
+proc setTranslationString {lang ori tr} {
+ global translationData
+ set translationData($lang,$ori) $tr
+}
+
+proc rewordTranslationString {old new} {
+ global translationData translationLangs
+ foreach lang $translationLangs {
+ if {[hasTranslationString $lang $old]} {
+ setTranslationString $lang $new [getTranslationString $lang $old]
+ } else {
+ setTranslationString $lang $new $new
+ }
+ }
+}
+
+# GUI helpers
+proc gAddTab {basename title elems dummies} {
+ global gMainNotebook
+ gAddFrame $basename $elems $dummies
+ $gMainNotebook add "$gMainNotebook.$basename" -text $title
+}
+
+proc gAddFrame {basename elems dummies} {
+ global gMainNotebook
+ set varbase [string cat "g" [firstupper $basename]]
+ set varname "${varbase}Frame"
+ set pathname "$gMainNotebook.$basename"
+ global $varname
+ set $varname $pathname
+ ttk::frame $pathname -padding 5
+ foreach i $elems {
+ set varname [string cat $varbase [firstupper $i]]
+ global $varname
+ set $varname "$pathname.$i"
+ }
+ foreach i $dummies {
+ set varname [string cat $varbase [firstupper $i]]
+ global $varname
+ set $varname {}
+ }
+}
+
+proc gReloadTranslations {} {
+ readTranslations
+ gTrLoadTranslations
+ gTmLoadTranslations
+}
+
+proc gAddMenu {varname parent menuname entries} {
+ global $varname
+ set path "${parent}.${menuname}"
+ set $varname $path
+ $parent configure -menu [menu $path -tearoff false]
+ foreach i $entries {
+ $path add {*}$i
+ }
+ return $parent
+}
+set gMenuItemNotImplemented [list command -state disabled -label "(Not implemented)"]
+
+proc gNotImplemented {args} {
+ tk_messageBox -message "Not implemented" -icon error -type ok
+}
+
+# Main window
+
+set gMainFrame ".f"
+set gMainFrameWidgetCount 0
+foreach i [list readBtn writeBtn notebookTopSeparator notebook] {
+ set [string cat "gMain" [firstupper $i]] "$gMainFrame.$i"
+}
+
+wm title . "Advtrains Translation File Editor"
+grid rowconfigure . 0 -weight 1
+grid columnconfigure . 0 -weight 1
+
+ttk::frame $gMainFrame
+grid $gMainFrame -column 0 -row 0 -sticky nsew
+grid rowconfigure $gMainFrame 2 -weight 1
+
+foreach i [list \
+ [ttk::button $gMainReadBtn -text "Reload translation files" -command gReloadTranslations] \
+ [ttk::button $gMainWriteBtn -text "Write changes" -command writeTranslations] \
+] {
+ grid $i -column $gMainFrameWidgetCount -row 0 -sticky ns
+ incr gMainFrameWidgetCount
+}
+
+grid columnconfigure $gMainFrame $gMainFrameWidgetCount -weight 1
+
+ttk::separator $gMainNotebookTopSeparator -orient horizontal
+grid $gMainNotebookTopSeparator -column 0 -row 1 -columnspan [expr {1+$gMainFrameWidgetCount}] -sticky ew
+
+ttk::notebook $gMainNotebook
+grid $gMainNotebook -column 0 -row 2 -columnspan [expr {1+$gMainFrameWidgetCount}] -sticky nsew
+
+# Translation Manager
+# FIXME?: it seems like Tcl requires -textvariable globals to be set first before they are accessible
+
+gAddTab tr "Translations" \
+ [list langSelect refLangSelect readBtn writeBtn treeviewFrame origTextLabel origTextField translatedTextLabel translatedTextField refTextLabel refTextField] \
+ [list langValue refLangValue origTextValue translatedTextValue refTextValue]
+set gTrTreeview "$gTrTreeviewFrame.main"
+set gTrTreeviewScrollbar "$gTrTreeviewFrame.scrollbar"
+
+grid rowconfigure $gTrFrame 0 -weight 1
+grid columnconfigure $gTrFrame 2 -weight 1
+
+ttk::frame $gTrTreeviewFrame -borderwidth 1 -relief sunken
+grid $gTrTreeviewFrame -column 0 -row 0 -columnspan 3 -sticky nsew
+grid rowconfigure $gTrTreeviewFrame 0 -weight 1
+grid columnconfigure $gTrTreeviewFrame 0 -weight 1
+ttk::treeview $gTrTreeview -selectmode browse -columns {translation} -yscrollcommand {$gTrTreeviewScrollbar set}
+grid $gTrTreeview -column 0 -row 0 -sticky nsew
+bind $gTrTreeview <<TreeviewSelect>> gTrTreeviewSelectionCallback
+ttk::scrollbar $gTrTreeviewScrollbar -orient vertical -command {$gTrTreeview yview}
+grid $gTrTreeviewScrollbar -column 1 -row 0 -sticky ns
+$gTrTreeview heading #0 -text "Original text"
+
+lmap i [list \
+ [list \
+ [ttk::label $gTrOrigTextLabel -text "Original" -anchor w] \
+ {} \
+ [ttk::entry $gTrOrigTextField -state readonly -textvariable gTrOrigTextValue] \
+ ] \
+ [list \
+ [ttk::label $gTrTranslatedTextLabel -text "Translation" -anchor w] \
+ [ttk::combobox $gTrLangSelect -exportselection false -state readonly -textvariable gTrLangValue] \
+ [ttk::entry $gTrTranslatedTextField -textvariable gTrTranslatedTextValue] \
+ ] \
+ [list \
+ [ttk::label $gTrRefTextLabel -text "Reference" -anchor w] \
+ [ttk::combobox $gTrRefLangSelect -exportselection false -state readonly -textvariable gTrRefLangValue] \
+ [ttk::entry $gTrRefTextField -state readonly -textvariable gTrRefTextValue] \
+ ] \
+] row [list 1 2 3] {
+ lmap item $i col [list 0 1 2] {
+ if {$item eq ""} {
+ continue
+ }
+ grid $item -column $col -row $row -sticky nswe
+ }
+ grid rowconfigure $gTrFrame $row -uniform bottom
+ incr gTrRowCount
+}
+
+bind $gTrLangSelect <<ComboboxSelected>> gTrLoadTranslationsToTreeview
+trace add variable gTrTranslatedTextValue write gTrApplyTranslationString
+bind $gTrRefLangSelect <<ComboboxSelected>> gTrTreeviewSelectionCallback
+
+proc gTrLoadTranslationsToTreeview {} {
+ global translationTemplate gTrTreeview gTrLangValue
+ $gTrTreeview heading translation -text "Translation: $gTrLangValue"
+ set prevFocus [$gTrTreeview item [$gTrTreeview focus] -text]
+ array set openedSections [list]
+ foreach i [$gTrTreeview children {}] {
+ if {[$gTrTreeview item $i -open]} {
+ set openedSections([$gTrTreeview item $i -text]) 1
+ }
+ }
+ $gTrTreeview delete [$gTrTreeview children {}]
+ set parent {}
+ foreach i [lrange $translationTemplate 1 end] {
+ if {[regexp {^\#+\s*(.+)} $i x comment]} {
+ set parent [$gTrTreeview insert {} end -text $comment -tags {notranslate}]
+ if {[info exists openedSections($comment)]} {
+ $gTrTreeview item $parent -open true
+ }
+ if {$comment eq $prevFocus} {
+ $gTrTreeview focus $parent
+ $gTrTreeview selection set $parent
+ }
+ } elseif {$i ne ""} {
+ set last [$gTrTreeview insert $parent end -text $i -values [list [maybeGetTranslationString $gTrLangValue $i]]]
+ if {$i eq $prevFocus} {
+ $gTrTreeview focus $last
+ $gTrTreeview selection set $last
+ }
+ }
+ }
+ gTrTreeviewSelectionCallback
+}
+
+proc gTrTreeviewSelectionCallback {} {
+ global gTrOrigTextValue gTrTreeview gTrLangSelect gTrLangValue gTrRefLangSelect gTrRefLangValue gTrTranslatedTextField gTrTranslatedTextValue gTrRefTextField gTrRefTextValue
+ set focused [$gTrTreeview focus]
+ set gTrOrigTextValue [$gTrTreeview item $focused -text]
+ if {$focused eq ""} {
+ $gTrTranslatedTextField state disabled
+ $gTrRefTextField state disabled
+ set gTrTranslatedTextValue "Select an entry to translate"
+ set gTrRefTextValue ""
+ } elseif {[$gTrTreeview tag has notranslate $focused]} {
+ $gTrTranslatedTextField state disabled
+ $gTrRefTextField state disabled
+ set gTrTranslatedTextValue "Category names cannot be translated"
+ set gTrRefTextValue ""
+ } else {
+ $gTrTranslatedTextField state !disabled
+ set gTrTranslatedTextValue [maybeGetTranslationString $gTrLangValue $gTrOrigTextValue]
+ set gTrRefTextValue [maybeGetTranslationString $gTrRefLangValue $gTrOrigTextValue]
+ if {$gTrRefLangValue eq ""} {
+ $gTrRefTextField state disabled
+ set gTrRefTextValue ""
+ } elseif {$gTrRefTextValue eq ""} {
+ $gTrRefTextField state disabled
+ set gTrRefTextValue "The selected string is not yet translated to the reference language"
+ } else {
+ $gTrRefTextField state !disabled
+ }
+ }
+ $gTrLangSelect selection clear
+ $gTrRefLangSelect selection clear
+}
+
+proc gTrLoadTranslations {} {
+ global translationLangs gTrLangSelect gTrLangValue gTrRefLangSelect gTrRefLangValue
+ set prevLang $gTrLangValue
+ set prevRefLang $gTrRefLangValue
+ $gTrLangSelect configure -values $translationLangs
+ $gTrRefLangSelect configure -values [linsert $translationLangs 0 ""]
+ if {[llength $translationLangs] < 1} {
+ tk_messageBox -icon error type ok -title "Error" -message "No translation files present."
+ exit 1
+ }
+ if {$prevLang ni $translationLangs} {
+ $gTrLangSelect current 0
+ }
+ if {$prevRefLang ni $translationLangs} {
+ $gTrRefLangSelect current 0
+ }
+ gTrLoadTranslationsToTreeview
+}
+
+proc gTrApplyTranslationString args {
+ global gTrTreeview gTrLangValue gTrOrigTextValue gTrTranslatedTextValue
+ set focused [$gTrTreeview focus]
+ if {![$gTrTreeview tag has notranslate $focused]} {
+ setTranslationString $gTrLangValue $gTrOrigTextValue $gTrTranslatedTextValue
+ $gTrTreeview item $focused -values [list $gTrTranslatedTextValue]
+ }
+}
+
+# Translation Template Editor
+
+gAddTab tm "Template" \
+ [list addStringMenuBtn addHeadingMenuBtn removeMenuBtn moveMenuBtn textField setMenuBtn treeviewFrame] \
+ [list textValue]
+set gTmTreeview "$gTmTreeviewFrame.main"
+set gTmTreeviewScrollbar "$gTmTreeviewFrame.scrollbar"
+
+set gTmRowCount 0
+foreach i [list \
+ [gAddMenu gTmAddStringMenu [ttk::menubutton $gTmAddStringMenuBtn -text "Add string"] "menu" [list \
+ [list command -label "Insert before current entry" -command {gTmInsertStringAt true 0}] \
+ [list command -label "Insert after current entry" -command {gTmInsertStringAt true 1}] \
+ [list command -label "Insert as the first entry" -command {gTmInsertStringAt false 0}] \
+ [list command -label "Insert as the last entry" -command {gTmInsertStringAt false end}] \
+ ]] \
+ [gAddMenu gTmAddHeadingMenu [ttk::menubutton $gTmAddHeadingMenuBtn -text "Add heading"] "menu" [list \
+ [list command -label "Insert before current section" -command {gTmInsertHeadingAt true 0}] \
+ [list command -label "Insert after current section" -command {gTmInsertHeadingAt true 1}] \
+ ]] \
+ [gAddMenu gTmRemoveMenu [ttk::menubutton $gTmRemoveMenuBtn -text "Remove"] "menu" [list \
+ [list command -label "Remove entry" -command gTmDeleteEntry] \
+ [list command -label "Remove section" -command gTmDeleteEntry] \
+ [list command -label "Merge with previous section" -command gTmMergeWithPrevious] \
+ ]] \
+ [gAddMenu gTmMoveMenu [ttk::menubutton $gTmMoveMenuBtn -text "Move"] "menu" [list \
+ [list command -label "Up" -command {gTmMoveInSection true -1}] \
+ [list command -label "Down" -command {gTmMoveInSection true 1}] \
+ [list command -label "To first" -command {gTmMoveInSection false 0}] \
+ [list command -label "To last" -command {gTmMoveInSection false end}] \
+ ]] \
+] {
+ grid $i -column 1 -row $gTmRowCount -sticky we
+ incr gTmRowCount
+}
+
+ttk::frame $gTmTreeviewFrame -borderwidth 1 -relief sunken
+grid $gTmTreeviewFrame -column 0 -row 0 -rowspan [expr {1+$gTmRowCount}] -sticky nsew
+grid rowconfigure $gTmTreeviewFrame 0 -weight 1
+grid columnconfigure $gTmTreeviewFrame 0 -weight 1
+grid rowconfigure $gTmFrame $gTmRowCount -weight 1
+grid columnconfigure $gTmFrame 0 -weight 1
+ttk::treeview $gTmTreeview -selectmode browse -show tree -yscrollcommand {$gTmTreeviewScrollbar set}
+bind $gTmTreeview <<TreeviewSelect>> gTmTreeviewSelectionCallback
+grid $gTmTreeview -column 0 -row 0 -sticky nsew
+ttk::scrollbar $gTmTreeviewScrollbar -orient vertical -command {$gTmTreeview yview}
+grid $gTmTreeviewScrollbar -column 1 -row 0 -sticky ns
+incr gTmRowCount
+
+ttk::entry $gTmTextField -textvariable gTmTextValue
+grid $gTmTextField -column 0 -row $gTmRowCount -sticky nsew
+
+gAddMenu gTmSetMenu [ttk::menubutton $gTmSetMenuBtn -text "Set"] "menu" [list \
+ [list command -label "Set heading" -command gTmSetEntry] \
+ [list command -label "Set and copy translations" -command gTmSetEntryAndCopy] \
+ [list command -label "Set without copying translations" -command gTmSetEntry] \
+]
+grid $gTmSetMenuBtn -column 1 -row $gTmRowCount -sticky nsew
+
+proc gTmLoadTranslationsToTreeview {} {
+ global translationTemplate gTmTreeview
+ set prevFocus [$gTmTreeview item [$gTmTreeview focus] -text]
+ array set openedSections [list]
+ foreach i [$gTmTreeview children {}] {
+ if {[$gTmTreeview item $i -open]} {
+ set openedSections([$gTmTreeview item $i -text]) 1
+ }
+ }
+ $gTmTreeview delete [$gTmTreeview children {}]
+ set parent {}
+ foreach i [lrange $translationTemplate 1 end] {
+ if {[regexp {^\#+\s*(.+)} $i x comment]} {
+ set parent [$gTmTreeview insert {} end -text $comment -tags {heading}]
+ if {[info exists openedSections($comment)]} {
+ $gTmTreeview item $parent -open true
+ }
+ if {$comment eq $prevFocus} {
+ $gTmTreeview focus $parent
+ $gTmTreeview selection set $parent
+ }
+ } elseif {$i ne ""} {
+ set last [$gTmTreeview insert $parent end -text $i]
+ if {$i eq $prevFocus} {
+ $gTmTreeview focus $last
+ $gTmTreeview selection set $last
+ }
+ }
+ }
+ gTmTreeviewSelectionCallback
+}
+
+proc gTmTreeviewSelectionCallback {} {
+ global gTmTreeview gTmTextField gTmTextValue gTmAddStringMenu gTmAddHeadingMenu gTmRemoveMenu gTmMoveMenu gTmSetMenu
+ set focused [$gTmTreeview focus]
+ if {$focused eq {}} {
+ $gTmTextField state disabled
+ set gTmTextValue "Select an entry to edit"
+ foreach m [list $gTmAddStringMenu $gTmAddHeadingMenu $gTmRemoveMenu $gTmMoveMenu $gTmSetMenu] {
+ for {set i 0} {$i <= [$m index end]} {incr i} { $m entryconfigure $i -state disabled}
+ }
+ } else {
+ $gTmTextField state !disabled
+ set headingSetState disabled
+ set entrySetState normal
+ if {[$gTmTreeview tag has heading $focused]} {
+ set headingSetState normal
+ set entrySetState disabled
+ }
+ foreach ent [list \
+ [list $gTmAddStringMenu \
+ [list 0 -state $entrySetState] \
+ [list 1 -state $entrySetState] \
+ [list 2 -state normal] \
+ [list 3 -state normal] \
+ ] \
+ [list $gTmAddHeadingMenu \
+ [list 0 -state normal] \
+ [list 1 -state normal] \
+ ] \
+ [list $gTmMoveMenu \
+ [list 0 -state normal] \
+ [list 1 -state normal] \
+ [list 2 -state normal] \
+ [list 3 -state normal] \
+ ] \
+ [list $gTmRemoveMenu \
+ [list 0 -state $entrySetState] \
+ [list 1 -state $headingSetState] \
+ [list 2 -state $headingSetState] \
+ ] \
+ [list $gTmSetMenu \
+ [list 0 -state $headingSetState] \
+ [list 1 -state $entrySetState] \
+ [list 2 -state $entrySetState] \
+ ] \
+ ] {
+ set m [lindex $ent 0]
+ lmap i [lrange $ent 1 end] {
+ $m entryconfigure {*}$i
+ }
+ }
+ set gTmTextValue [$gTmTreeview item $focused -text]
+ }
+}
+
+proc gTmUpdateTemplateAux {parent} {
+ global translationTemplate gTmTreeview
+ foreach i [$gTmTreeview children $parent] {
+ set tval [$gTmTreeview item $i -text]
+ if {[$gTmTreeview tag has heading $i]} {
+ lappend translationTemplate {}
+ set tval "# $tval"
+ }
+ lappend translationTemplate $tval
+ gTmUpdateTemplateAux $i
+ }
+}
+
+proc gTmUpdateTemplate {} {
+ global translationTemplate translationDomain
+ set translationTemplate [list "# textdomain: $translationDomain"]
+ gTmUpdateTemplateAux {}
+ gTrLoadTranslations
+ gTmLoadTranslationsToTreeview
+}
+
+proc gTmSetEntry {} {
+ global gTmTreeview gTmTextValue
+ $gTmTreeview item [$gTmTreeview focus] -text $gTmTextValue
+ gTmUpdateTemplate
+}
+
+proc gTmSetEntryAndCopy {} {
+ global gTmTreeview gTmTextValue
+ set focus [$gTmTreeview focus]
+ rewordTranslationString [$gTmTreeview item $focus -text] $gTmTextValue
+ gTmSetEntry
+}
+
+proc gTmInsertStringAt {relative idx} {
+ global gTmTreeview
+ set focus [$gTmTreeview focus]
+ set parent [$gTmTreeview parent $focus]
+ set relidx [$gTmTreeview index $focus]
+ if {[$gTmTreeview tag has heading $focus]} {
+ set parent $focus
+ set relindex 0
+ }
+ set newidx $idx
+ if {$relative} {
+ set newidx [expr {$idx+$relidx}]
+ }
+ set item [$gTmTreeview insert $parent $newidx -text {}]
+ $gTmTreeview focus $item
+ $gTmTreeview selection set $item
+}
+
+proc gTmInsertHeadingAt {relative idx} {
+ global gTmTreeview
+ set focus [$gTmTreeview focus]
+ if {![$gTmTreeview tag has heading $focus]} {
+ set focus [$gTmTreeview parent $focus]
+ }
+ set parent [$gTmTreeview parent $focus]
+ set relidx [$gTmTreeview index $focus]
+ if {$focus eq {}} {
+ set parent {}
+ set relidx 0
+ }
+ set newidx $idx
+ if {$relative} {
+ set newidx [expr {$idx+$relidx}]
+ }
+ set item [$gTmTreeview insert $parent $newidx -text {} -tags {heading}]
+ $gTmTreeview focus $item
+ $gTmTreeview selection set $item
+}
+
+proc gTmMoveInSection {relative idx} {
+ global gTmTreeview
+ set focus [$gTmTreeview focus]
+ set parent [$gTmTreeview parent $focus]
+ set relidx [$gTmTreeview index $focus]
+ set newidx $idx
+ if {$relative} {
+ set newidx [expr {$idx+$relidx}]
+ }
+ $gTmTreeview move $focus $parent $newidx
+ gTmUpdateTemplate
+}
+
+proc gTmDeleteEntry {} {
+ global gTmTreeview
+ $gTmTreeview delete [$gTmTreeview focus]
+ gTmUpdateTemplate
+}
+
+proc gTmMergeWithPrevious {} {
+ global gTmTreeview
+ set parent [$gTmTreeview focus]
+ set prev [$gTmTreeview prev $parent]
+ set newindex end
+ if {$prev eq {}} {
+ set prev [$gTmTreeview parent $parent]
+ set newindex 0
+ }
+ foreach i [$gTmTreeview children $parent] {
+ $gTmTreeview move $i $prev $newindex
+ }
+ $gTmTreeview delete $parent
+ gTmUpdateTemplate
+}
+
+proc gTmLoadTranslations {} {
+ gTmLoadTranslationsToTreeview
+}
+
+# Initialization
+
+gReloadTranslations
diff --git a/advtrains/locale/template.txt b/advtrains/locale/template.txt
new file mode 100644
index 0000000..8c8b859
--- /dev/null
+++ b/advtrains/locale/template.txt
@@ -0,0 +1,146 @@
+# textdomain: advtrains
+
+# Advtrains Core (unorganized)
+This wagon is owned by @1, you can't destroy it.=This wagon is owned by @1, you can't destroy it.
+Warning: If you destroy this wagon, you only get some steel back! If you are sure, hold Sneak and left-click the wagon.=Warning: If you destroy this wagon, you only get some steel back! If you are sure, hold Sneak and left-click the wagon.
+This position is protected!=This position is protected!
+Can't place: not pointing at node=Can't place: not pointing at node
+Can't place: space occupied!=Can't place: space occupied!
+Can't place: protected position!=Can't place: protected position!
+Can't place: Not enough slope items left (@1 required)=Can't place: Not enough slope items left (@1 required)
+Can't place: There's no slope of length @1=Can't place: There's no slope of length @1
+Can't place: no supporting node at upper end.=Can't place: no supporting node at upper end.
+Deprecated Track=Deprecated Track
+Can't get on: wagon full or doors closed!=Can't get on: wagon full or doors closed!
+Use Sneak+rightclick to bypass closed doors!=Use Sneak+rightclick to bypass closed doors!
+Doors are closed! Use Sneak+rightclick to ignore the closed doors and get off!=Doors are closed! Use Sneak+rightclick to ignore the closed doors and get off!
+Access to @1=Access to @1
+You do not have the @1 privilege.=You do not have the @1 privilege.
+The wagon's inventory is not empty!=The wagon's inventory is not empty!
+Position is occupied by a train.=Position is occupied by a train.
+There's a Track Circuit Break here.=There's a Track Circuit Break here.
+There's a Signal Influence Point here.=There's a Signal Influence Point here.
+
+# Trackworker, rotation, adjustment
+This node can't be rotated using the trackworker!=This node can't be rotated using the trackworker!
+This node can't be changed using the trackworker!=This node can't be changed using the trackworker!
+This track can not be changed!=This track can not be changed!
+This track can not be rotated!=This track can not be rotated!
+This track can not be removed!=This track can not be removed!
+
+# ATC
+ATC controller, unconfigured.=ATC controller, unconfigured.
+ATC controller=ATC controller
+ATC controller, mode @1@nChannel: @2=ATC controller, mode @1@nChannel: @2
+ATC controller, mode @1@nCommand: @2=ATC controller, mode @1@nCommand: @2
+Command=Command
+Command (on)=Command (on)
+Digiline channel=Digiline channel
+ATC Kick command warning: Doors closed=ATC Kick command warning: Doors closed
+ATC Kick command warning: Train moving=ATC Kick command warning: Train moving
+ATC Reverse command warning: didn't reverse train, train moving!=ATC Reverse command warning: didn't reverse train, train moving!
+ATC command syntax error: I statement not closed: @1=ATC command syntax error: I statement not closed: @1
+ATC command parse error: Unknown command: @1=ATC command parse error: Unknown command: @1
+
+# Coupling
+Lock couples=Lock couples
+You need to own at least one neighboring wagon to destroy this couple.=You need to own at least one neighboring wagon to destroy this couple.
+Buffer and Chain Coupler=Buffer and Chain Coupler
+Scharfenberg Coupler=Scharfenberg Coupler
+Japanese Train Inter-Wagon Connection=Japanese Train Inter-Wagon Connection
+Can not couple: The couplers of the trains do not match (@1 and @2).=Can not couple: The couplers of the trains do not match (@1 and @2).
+You are not allowed to couple trains without the train_operator privilege.=You are not allowed to couple trains without the train_operator privilege.
+
+# Clipboard
+The track you are trying to place the wagon on is not long enough!=The track you are trying to place the wagon on is not long enough!
+The clipboard couldn't access the metadata. Paste failed.=The clipboard couldn't access the metadata. Paste failed.
+The clipboard couldn't access the metadata. Copy failed.=The clipboard couldn't access the metadata. Copy failed.
+The clipboard is empty.=The clipboard is empty.
+Back of train would end up off track, cancelling.=Back of train would end up off track, cancelling.
+No such lua entity!=No such lua entity!
+No such wagon: @1=No such wagon: @1
+No such train: @1=No such train: @1
+Train copied!=Train copied!
+
+# Protection
+You are not allowed to build tracks without the track_builder privilege.=You are not allowed to build tracks without the track_builder privilege.
+You are not allowed to build near tracks without the track_builder privilege.=You are not allowed to build near tracks without the track_builder privilege.
+You are not allowed to build tracks at this protected position.=You are not allowed to build tracks at this protected position.
+You are not allowed to build near tracks at this protected position.=You are not allowed to build near tracks at this protected position.
+You are not allowed to operate turnouts and signals without the railway_operator privilege.=You are not allowed to operate turnouts and signals without the railway_operator privilege.
+
+# Train HUD/Formspecs
+Speed:=Speed:
+Target:=Target:
+Show Inventory=Show Inventory
+Select seat:=Select seat:
+Wagon properties=Wagon properties
+Save wagon properties=Save wagon properties
+Text displayed outside on train=Text displayed outside on train
+Text displayed inside train=Text displayed inside train
+Line=Line
+Routingcode=Routingcode
+Get off=Get off
+Get off (forced)=Get off (forced)
+(Doors closed)=(Doors closed)
+
+# General
+Save=Save
+
+# Line automation
+Station Code=Station Code
+Station Name=Station Name
+Door Delay=Door Delay
+Door Side=Door Side
+Dep. Speed=Dep. Speed
+Stop Time=Stop Time
+
+# Items
+Track Worker Tool@n@nLeft-click: change rail type (straight/curve/switch)@nRight-click: rotate rail/bumper/signal/etc.=Track Worker Tool@n@nLeft-click: change rail type (straight/curve/switch)@nRight-click: rotate rail/bumper/signal/etc.
+Passive Component Naming Tool@n@nRight-click to name a passive component.=Passive Component Naming Tool@n@nRight-click to name a passive component.
+Train copy/paste tool@n@nLeft-click: copy train@nRight-click: paste train=Train copy/paste tool@n@nLeft-click: copy train@nRight-click: paste train
+Track=Track
+Perpendicular Diamond Crossing Track=Perpendicular Diamond Crossing Track
+Diagonal Diamond Crossing Track=Diagonal Diamond Crossing Track
+90+Angle Diamond Crossing Track=90+Angle Diamond Crossing Track
+Y-turnout=Y-turnout
+3-way turnout=3-way turnout
+Unloading Track=Unloading Track
+Loading Track=Loading Track
+Bumper=Bumper
+Detector Rail=Detector Rail
+@1 Slope=@1 Slope
+@1 Platform (low)=@1 Platform (low)
+@1 Platform (high)=@1 Platform (high)
+@1 Platform (low, 45 degree)=@1 Platform (low, 45 degree)
+@1 Platform (45 degree)=@1 Platform (45 degree)
+Lampless Signal=Lampless Signal
+Signal=Signal
+Wallmounted Signal (l)=Wallmounted Signal (l)
+Wallmounted Signal (r)=Wallmounted Signal (r)
+Wallmounted Signal (t)=Wallmounted Signal (t)
+Andrew's Cross=Andrew's Cross
+Boiler=Boiler
+driver's cab=driver's cab
+Wheel=Wheel
+Chimney=Chimney
+
+# Seats
+Default Seat=Default Seat
+Default Seat (driver stand)=Default Seat (driver stand)
+Driver stand=Driver stand
+Driver Stand (left)=Driver Stand (left)
+Driver Stand (right)=Driver Stand (right)
+
+# Wagon/engine types
+Industrial Train Engine=Industrial Train Engine
+Big Industrial Train Engine=Big Industrial Train Engine
+Industrial tank wagon=Industrial tank wagon
+Industrial wood wagon=Industrial wood wagon
+Japanese Train Engine=Japanese Train Engine
+Japanese Train Wagon=Japanese Train Wagon
+Steam Engine=Steam Engine
+Detailed Steam Engine=Detailed Steam Engine
+Passenger Wagon=Passenger Wagon
+Box Wagon=Box Wagon
+Subway Passenger Wagon=Subway Passenger Wagon
diff --git a/advtrains/locale/topo.sh b/advtrains/locale/topo.sh
new file mode 100755
index 0000000..23f81b1
--- /dev/null
+++ b/advtrains/locale/topo.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+head -n18 ../po/template.pot | sed 's/charset=CHARSET/charset=UTF-8/'
+sed -En 's/@n/\\n/g;s/@\n/\\n/g;s/\"/\\"/g;s/^([^=]+)=\1$/\1=/;s/^([^=]+)=([^=]*)$/\nmsgid "\1"\nmsgstr "\2"/gp'
diff --git a/advtrains/po/de.po b/advtrains/po/de.po
new file mode 100644
index 0000000..ebd6339
--- /dev/null
+++ b/advtrains/po/de.po
@@ -0,0 +1,580 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: advtrains\n"
+"Report-Msgid-Bugs-To: advtrains-discuss@lists.sr.ht\n"
+"POT-Creation-Date: 2023-10-04 15:40+0200\n"
+"PO-Revision-Date: 2022-11-02 15:08+0100\n"
+"Last-Translator: Y. Wang <yw05@forksworld.de>\n"
+"Language-Team: German\n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: advtrains/atc.lua:109
+msgid "ATC controller, unconfigured."
+msgstr "Nicht konfiguierte Zugbeeinflussungsgleis"
+
+#: advtrains/atc.lua:150
+msgid ""
+"ATC controller, mode @1\n"
+"Command: @2"
+msgstr ""
+"Zugbeeinflussungsgleis in Betriebsart „@1“\n"
+"Befehl: @2"
+
+#: advtrains/atc.lua:180
+msgid "Command"
+msgstr "Befehl"
+
+#: advtrains/atc.lua:184
+msgid "Command (on)"
+msgstr "Befehl (wenn aktiviert)"
+
+#: advtrains/atc.lua:187
+msgid "Digiline channel"
+msgstr "Digiline-Kanal"
+
+#: advtrains/atc.lua:189 advtrains_line_automation/stoprail.lua:65
+msgid "Save"
+msgstr "Speichern"
+
+#: advtrains/atc.lua:236
+msgid "ATC Reverse command warning: didn't reverse train, train moving!"
+msgstr ""
+"Zugbeeinflussung: der Befehl „R“ wurde nicht ausgeführt, Zug in Bewegung!"
+
+#: advtrains/atc.lua:248
+msgid "ATC Kick command warning: Doors closed"
+msgstr ""
+
+#: advtrains/atc.lua:252
+msgid "ATC Kick command warning: Train moving"
+msgstr ""
+
+#: advtrains/atc.lua:322
+msgid "ATC command syntax error: I statement not closed: @1"
+msgstr "Zugbeeinflussung: Unvollständiger I-Befehl: @1"
+
+#: advtrains/atc.lua:385
+msgid "ATC command parse error: Unknown command: @1"
+msgstr "Zugbeeinflussung: Unbekannter Befehl: @1"
+
+#: advtrains/craft_items.lua:3
+msgid "Boiler"
+msgstr ""
+
+#: advtrains/craft_items.lua:9
+msgid "driver's cab"
+msgstr ""
+
+#: advtrains/craft_items.lua:15
+msgid "Wheel"
+msgstr ""
+
+#: advtrains/craft_items.lua:21
+msgid "Chimney"
+msgstr ""
+
+#: advtrains/misc_nodes.lua:16
+msgid "@1 Platform (low)"
+msgstr "Niedriger @1-Bahnsteig"
+
+#: advtrains/misc_nodes.lua:33
+msgid "@1 Platform (high)"
+msgstr "Hoher @1-Bahnsteig"
+
+#: advtrains/misc_nodes.lua:59
+msgid "@1 Platform (45 degree)"
+msgstr "Hoher @1-Bahnsteig (45°)"
+
+#: advtrains/misc_nodes.lua:81
+msgid "@1 Platform (low, 45 degree)"
+msgstr "Niedriger @1-Bahnsteig (45°)"
+
+#: advtrains/trackplacer.lua:313
+msgid ""
+"Track Worker Tool\n"
+"\n"
+"Left-click: change rail type (straight/curve/switch)\n"
+"Right-click: rotate rail/bumper/signal/etc."
+msgstr ""
+"Gleiswerkzeug\n"
+"\n"
+"Linksklick: Gleistyp ändern, Rechtsklick: Objekt drehen."
+
+#: advtrains/trackplacer.lua:340 advtrains/trackplacer.lua:377
+msgid "This node can't be rotated using the trackworker!"
+msgstr "Dieser Block kann nicht mit dem Gleiswerkzeug gedreht werden."
+
+#: advtrains/trackplacer.lua:350
+msgid "This track can not be rotated!"
+msgstr "Dieses Gleis kann nicht gedreht werden!"
+
+#: advtrains/trackplacer.lua:404
+msgid "This node can't be changed using the trackworker!"
+msgstr "Dieser Block kann nicht mit dem Gleiswerkzeug bearbeitet werden."
+
+#: advtrains/trackplacer.lua:414
+msgid "This track can not be changed!"
+msgstr "Dieses Gleis kann nicht geändert werden!"
+
+#: advtrains/wagons.lua:179
+msgid "This wagon is owned by @1, you can't destroy it."
+msgstr "Dieser Waggon gehört @1, Sie dürfen ihn nicht abbauen."
+
+#: advtrains/wagons.lua:203
+msgid "The wagon's inventory is not empty!"
+msgstr "Das Inventar dieses Waggons ist nicht leer!"
+
+#: advtrains/wagons.lua:210
+msgid "Wagon needs to be decoupled from other wagons in order to destroy it."
+msgstr ""
+
+#: advtrains/wagons.lua:216
+msgid ""
+"Warning: If you destroy this wagon, you only get some steel back! If you are "
+"sure, hold Sneak and left-click the wagon."
+msgstr ""
+"Warnung: Durch den Abbau des Waggons erhalten Sie nur etwas Stahl zurück. "
+"Nutzen Sie Schleichen+Linksklick, um dem Waggon abzubauen."
+
+#: advtrains/wagons.lua:649 advtrains/wagons.lua:850
+msgid "Show Inventory"
+msgstr "Inventar Zeigen"
+
+#: advtrains/wagons.lua:652
+msgid "Onboard Computer"
+msgstr ""
+
+#: advtrains/wagons.lua:655 advtrains/wagons.lua:1328
+msgid "Wagon properties"
+msgstr "Waggon-Einstellungen"
+
+#: advtrains/wagons.lua:658
+msgid "Get off"
+msgstr "Aussteigen"
+
+#: advtrains/wagons.lua:661
+msgid "Get off (forced)"
+msgstr "Ausstieg zwingen"
+
+#: advtrains/wagons.lua:663
+msgid "(Doors closed)"
+msgstr "(Türen geschlossen)"
+
+#: advtrains/wagons.lua:712
+msgid "Can't get on: "
+msgstr ""
+
+#: advtrains/wagons.lua:838
+msgid "Select seat:"
+msgstr "Wählen Sie einen Sitzplatz aus:"
+
+#: advtrains/wagons.lua:880
+msgid "Save wagon properties"
+msgstr "Waggon-Einstellungen speichern"
+
+#: advtrains/wagons.lua:965
+msgid "Text displayed outside on train"
+msgstr "Äußere Anzeige"
+
+#: advtrains/wagons.lua:966
+msgid "Text displayed inside train"
+msgstr "Innere Anzeige"
+
+#: advtrains/wagons.lua:967
+msgid "Line"
+msgstr "Linie"
+
+#: advtrains/wagons.lua:968
+msgid "Routingcode"
+msgstr ""
+
+#: advtrains/wagons.lua:1241
+msgid ""
+"Doors are closed! Use Sneak+rightclick to ignore the closed doors and get "
+"off!"
+msgstr ""
+"Die Türen sind geschlossen. Nutzen Sie Schleichen+Rechtsklick, um trotz "
+"geschlossener Türen auszusteigen."
+
+#: advtrains/trainhud.lua:305
+msgid "OVERRUN RED SIGNAL! Examine situation and reverse train to move again."
+msgstr ""
+
+#: advtrains/tracks.lua:449
+msgid "This track can not be removed!"
+msgstr "Dieses Gleis kann nicht entfernt werden!"
+
+#: advtrains/tracks.lua:616
+msgid "Position is occupied by a train."
+msgstr "Ein Zug steht an dieser Position."
+
+#: advtrains/tracks.lua:622
+msgid "There's a Track Circuit Break here."
+msgstr "Hier ist eine Gleisabschnittsgrenze (TCB)."
+
+#: advtrains/tracks.lua:626
+msgid "There's a Signal Influence Point here."
+msgstr "Hier ist ein Signal-Beeinflussungspunkt."
+
+#: advtrains/tracks.lua:637
+msgid "@1 Slope"
+msgstr "@1 Steigung"
+
+#: advtrains/tracks.lua:648 advtrains/tracks.lua:653
+msgid "Can't place: not pointing at node"
+msgstr "Es kann nicht platziert werden: Sie zeigen nicht auf einem Block."
+
+#: advtrains/tracks.lua:658
+msgid "Can't place: space occupied!"
+msgstr "Es kann nicht platziert werden: diese Position ist besetzt."
+
+#: advtrains/tracks.lua:711
+msgid "Can't place: Not enough slope items left (@1 required)"
+msgstr ""
+"Es kann nicht platziert werden: Sie haben nicht genug Steigungsblöcke, es "
+"werden insgesamt @1 benötigt."
+
+#: advtrains/tracks.lua:714
+msgid "Can't place: There's no slope of length @1"
+msgstr ""
+"Es kann nicht platziert werden: die Steigung der Länge @1 ist nicht "
+"definiert."
+
+#: advtrains/tracks.lua:721
+msgid "Can't place: no supporting node at upper end."
+msgstr ""
+"Es kann nicht platziert werden: es gibt keinen unterstützenden Block am Ende "
+"der Steigung."
+
+#: advtrains/signals.lua:63
+msgid "Lampless Signal"
+msgstr "Mechanisches Signal"
+
+#: advtrains/signals.lua:127
+msgid "Signal"
+msgstr "Lichtsignal"
+
+#: advtrains/signals.lua:191
+msgid "Wallmounted Signal (l)"
+msgstr "An der linken Seite montiertes Signal"
+
+#: advtrains/signals.lua:192
+msgid "Wallmounted Signal (r)"
+msgstr "An der rechten Seite montiertes Signal"
+
+#: advtrains/signals.lua:193
+msgid "Wallmounted Signal (t)"
+msgstr "An der Decke montiertes Signal"
+
+#: advtrains/signals.lua:281 advtrains/signals.lua:322
+msgid "Andrew's Cross"
+msgstr ""
+
+#: advtrains/couple.lua:28
+msgid "Buffer and Chain Coupler"
+msgstr "Schraubenkupplung"
+
+#: advtrains/couple.lua:29
+msgid "Scharfenberg Coupler"
+msgstr "Scharfenbergkupplung"
+
+#: advtrains/couple.lua:185
+msgid ""
+"You are not allowed to couple trains without the train_operator privilege."
+msgstr "Sie dürfen ohne das „train_builder“-Privileg keine Züge ankuppeln."
+
+#: advtrains/couple.lua:329 advtrains/couple.lua:333
+msgid "<none>"
+msgstr ""
+
+#: advtrains/couple.lua:334
+msgid "Can not couple: The couplers of the trains do not match (@1 and @2)."
+msgstr "Die Kupplungen der Züge passen nicht zueinander (@1 und @2)."
+
+#: advtrains/copytool.lua:8
+msgid ""
+"Train copy/paste tool\n"
+"\n"
+"Left-click: copy train\n"
+"Right-click: paste train"
+msgstr ""
+"Werkzeug zur Erstellung von Zugkopien\n"
+"\n"
+"Linksklick: Zug ins Clipboard kopieren\n"
+"Right-click: Kopierten Zug einfügen"
+
+#: advtrains/copytool.lua:29
+msgid "You do not have the @1 privilege."
+msgstr "Ihnen fehlt das „@1“-Privileg."
+
+#: advtrains/copytool.lua:41
+msgid "The track you are trying to place the wagon on is not long enough!"
+msgstr "Das Gleis, auf dem der Waggon platziert werden woll, ist zu kurz."
+
+#: advtrains/copytool.lua:47
+msgid "The clipboard couldn't access the metadata. Paste failed."
+msgstr ""
+"Wegen des fehlgeschlagenen Zugriffs auf die Metadaten konnte eine Kopie des "
+"Zuges nicht eingefügt werden."
+
+#: advtrains/copytool.lua:52 advtrains/copytool.lua:57
+msgid "The clipboard is empty."
+msgstr "Das Clipboard ist leer."
+
+#: advtrains/copytool.lua:74
+msgid "Back of train would end up off track, cancelling."
+msgstr "Der hinterer Teil dez Zuges wäre nicht auf dem Gleis."
+
+#: advtrains/copytool.lua:92
+msgid "No such lua entity!"
+msgstr ""
+"Sie zeigen nicht auf einem Objekt, das mit diesem Werkzeug kopiert werden "
+"kann."
+
+#: advtrains/copytool.lua:98
+msgid "No such wagon: @1"
+msgstr "Es gibt keinen mit „@1“ identifizierbaren Waggon."
+
+#: advtrains/copytool.lua:104
+msgid "No such train: @1"
+msgstr "Es gibt keinen mit „@1“ identifizierbaren Zug."
+
+#: advtrains/copytool.lua:176
+msgid "The clipboard couldn't access the metadata. Copy failed."
+msgstr ""
+"Wegen des fehlgeschlagenen Zugriffs auf die Metadaten konnte der Zug nicht "
+"kopiert werden."
+
+#: advtrains/copytool.lua:180
+msgid "Train copied!"
+msgstr "Der Zug wurde Kopiert."
+
+#: advtrains/protection.lua:148
+msgid ""
+"You are not allowed to build near tracks without the track_builder privilege."
+msgstr ""
+"Sie dürfen ohne das „track_builder“-Privileg nicht in der Nähe von Gleisen "
+"bauen."
+
+#: advtrains/protection.lua:148
+msgid ""
+"You are not allowed to build tracks without the track_builder privilege."
+msgstr "Sie dürfen ohne das „track_builder“-Privileg kein Gleis bauen."
+
+#: advtrains/protection.lua:153
+msgid "You are not allowed to build near tracks at this protected position."
+msgstr "Sie dürfen an geschützten Stellen nicht in der Nähe von Gleisen bauen."
+
+#: advtrains/protection.lua:153
+msgid "You are not allowed to build tracks at this protected position."
+msgstr "Sie dürfen an geschützten Stellen kein Gleis bauen."
+
+#: advtrains/protection.lua:184
+msgid ""
+"You are not allowed to operate turnouts and signals without the "
+"railway_operator privilege."
+msgstr ""
+"Sie dürfen ohne das „railway_operator“-Privileg keine Bahnanlage operieren."
+
+#: advtrains_line_automation/stoprail.lua:54
+msgid "Station Code"
+msgstr "Code der Haltestelle"
+
+#: advtrains_line_automation/stoprail.lua:55
+msgid "Station Name"
+msgstr "Name der Haltestelle"
+
+#: advtrains_line_automation/stoprail.lua:56
+msgid "Door Delay"
+msgstr "Zeit für die Türschließung"
+
+#: advtrains_line_automation/stoprail.lua:57
+msgid "Dep. Speed"
+msgstr "Zielgeschwindigkeit bei Abfahrt"
+
+#: advtrains_line_automation/stoprail.lua:58 advtrains_train_track/init.lua:11
+#: advtrains_train_track/init.lua:156
+msgid "Track"
+msgstr "Gleis"
+
+#: advtrains_line_automation/stoprail.lua:59
+msgid "Stop Time"
+msgstr "Wartezeit"
+
+#: advtrains_line_automation/stoprail.lua:60
+msgid "Door Side"
+msgstr ""
+
+#: advtrains_line_automation/stoprail.lua:62
+msgid "Reverse train"
+msgstr ""
+
+#: advtrains_line_automation/stoprail.lua:63
+msgid "Kick out passengers"
+msgstr ""
+
+#: advtrains_luaautomation/pcnaming.lua:26
+msgid ""
+"Passive Component Naming Tool\n"
+"\n"
+"Right-click to name a passive component."
+msgstr ""
+"PC-Benennungswerkzeug\n"
+"\n"
+"Rechtsklick zur Benennung der passiven Komponente"
+
+#: advtrains_train_track/init.lua:31
+msgid "Y-turnout"
+msgstr "Y-Weiche"
+
+#: advtrains_train_track/init.lua:49
+msgid "3-way turnout"
+msgstr "Dreiwegweiche"
+
+#: advtrains_train_track/init.lua:69
+msgid "Perpendicular Diamond Crossing Track"
+msgstr "Kreuzung mit zueinander orthogonalen Gleisen"
+
+#: advtrains_train_track/init.lua:91
+msgid "90+Angle Diamond Crossing Track"
+msgstr "Kreuzung mit einem achsenparallelen Gleis"
+
+#: advtrains_train_track/init.lua:132
+msgid "Diagonal Diamond Crossing Track"
+msgstr "Diagonale Gleiskreuzung"
+
+#: advtrains_train_track/init.lua:179
+msgid "Bumper"
+msgstr "Prellbock"
+
+#: advtrains_train_track/init.lua:201
+msgid "ATC controller"
+msgstr "Zugbeeinflussungsgleis"
+
+#: advtrains_train_track/init.lua:317
+msgid "Unloading Track"
+msgstr "Abladungsgleis"
+
+#: advtrains_train_track/init.lua:342
+msgid "Loading Track"
+msgstr "Beladungsgleis"
+
+#: advtrains_train_track/init.lua:406
+msgid "Detector Rail"
+msgstr "Detektorgleis"
+
+#: advtrains_train_industrial/init.lua:10
+#: advtrains_train_industrial/init.lua:49 advtrains_train_steam/init.lua:20
+#: advtrains_train_steam/init.lua:91
+msgid "Driver Stand (right)"
+msgstr "Führerstand Rechts"
+
+#: advtrains_train_industrial/init.lua:17
+#: advtrains_train_industrial/init.lua:56 advtrains_train_steam/init.lua:14
+#: advtrains_train_steam/init.lua:85
+msgid "Driver Stand (left)"
+msgstr "Führerstand Links"
+
+#: advtrains_train_industrial/init.lua:40
+msgid "Industrial Train Engine"
+msgstr "Industrielle Lokomotive"
+
+#: advtrains_train_industrial/init.lua:79
+msgid "Big Industrial Train Engine"
+msgstr "Große Industrielle Lokomotive"
+
+#: advtrains_train_industrial/init.lua:98
+msgid "Industrial tank wagon"
+msgstr "Tankwaggon"
+
+#: advtrains_train_industrial/init.lua:116
+msgid "Industrial wood wagon"
+msgstr "Holztransportwaggon"
+
+#: advtrains_train_japan/init.lua:4
+msgid "Japanese Train Inter-Wagon Connection"
+msgstr "Waggonzwischenverbindung Japanischer Personenzüge"
+
+#: advtrains_train_japan/init.lua:37
+msgid "Driver stand"
+msgstr "Führerstand"
+
+#: advtrains_train_japan/init.lua:101
+msgid "Japanese Train Engine"
+msgstr "Japanische Personenzug-Lokomotive"
+
+#: advtrains_train_japan/init.lua:176
+msgid "Japanese Train Wagon"
+msgstr "Japanischer Personenzug-Passagierwaggon"
+
+#: advtrains_train_steam/init.lua:75
+msgid "Steam Engine"
+msgstr "Dampflokomotive"
+
+#: advtrains_train_steam/init.lua:159
+msgid "Detailed Steam Engine"
+msgstr "detaillierte Dampflokomotive"
+
+#: advtrains_train_steam/init.lua:206
+msgid "Passenger Wagon"
+msgstr "Passagierwaggon"
+
+#: advtrains_train_steam/init.lua:226
+msgid "Box Wagon"
+msgstr "Güterwaggon"
+
+#: advtrains_train_subway/init.lua:144
+msgid "Subway Passenger Wagon"
+msgstr "U-Bahn-Waggon"
+
+#~ msgid "This position is protected!"
+#~ msgstr "Diese Position ist geschützt!"
+
+#~ msgid "Can't place: protected position!"
+#~ msgstr "Es kann nicht platziert werden: diese Position ist geschützt."
+
+#~ msgid "Deprecated Track"
+#~ msgstr "ausrangiertes Gleis, nicht verwenden."
+
+#~ msgid "Can't get on: wagon full or doors closed!"
+#~ msgstr ""
+#~ "Sie können nicht einsteigen: der Waggon ist voll oder die Türen sind "
+#~ "geschlossen."
+
+#~ msgid "Use Sneak+rightclick to bypass closed doors!"
+#~ msgstr ""
+#~ "Nutzen Sie Schleichen+Rechtsklick, um trotz geschlossener Türen "
+#~ "einzusteigen."
+
+#~ msgid "Access to @1"
+#~ msgstr "Zugang zu @1"
+
+#~ msgid ""
+#~ "ATC controller, mode @1\n"
+#~ "Channel: @2"
+#~ msgstr ""
+#~ "Zugbeeinflussungsgleis in Betriebsart „@1“\n"
+#~ "Kanal: @2"
+
+#~ msgid "Lock couples"
+#~ msgstr "Kupplungen sperren"
+
+#~ msgid ""
+#~ "You need to own at least one neighboring wagon to destroy this couple."
+#~ msgstr ""
+#~ "Sie müssen Besitzer eines angrenzenden Waggons sein, um hier abzukuppeln."
+
+#~ msgid "Speed:"
+#~ msgstr "Geschw.:"
+
+#~ msgid "Target:"
+#~ msgstr "Zielges.:"
+
+#~ msgid "Default Seat"
+#~ msgstr "Standardsitzplatz"
+
+#~ msgid "Default Seat (driver stand)"
+#~ msgstr "Standardsitzplatz (Führerstand)"
diff --git a/advtrains/po/fr.po b/advtrains/po/fr.po
new file mode 100644
index 0000000..9a16799
--- /dev/null
+++ b/advtrains/po/fr.po
@@ -0,0 +1,579 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: advtrains\n"
+"Report-Msgid-Bugs-To: advtrains-discuss@lists.sr.ht\n"
+"POT-Creation-Date: 2023-10-04 15:40+0200\n"
+"PO-Revision-Date: 2022-07-05 10:11+0200\n"
+"Last-Translator: Tanavit <tanavit@posto.ovh>\n"
+"Language-Team: French\n"
+"Language: fr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: advtrains/atc.lua:109
+msgid "ATC controller, unconfigured."
+msgstr "Controlleur ATC, non-configuré "
+
+#: advtrains/atc.lua:150
+msgid ""
+"ATC controller, mode @1\n"
+"Command: @2"
+msgstr ""
+"Controlleur ATC, mode @1\n"
+"Commande : @2"
+
+#: advtrains/atc.lua:180
+msgid "Command"
+msgstr "Commande"
+
+#: advtrains/atc.lua:184
+msgid "Command (on)"
+msgstr "Commande (marche) "
+
+#: advtrains/atc.lua:187
+msgid "Digiline channel"
+msgstr "Canal Digiline"
+
+#: advtrains/atc.lua:189 advtrains_line_automation/stoprail.lua:65
+msgid "Save"
+msgstr "Sauvegarder"
+
+#: advtrains/atc.lua:236
+msgid "ATC Reverse command warning: didn't reverse train, train moving!"
+msgstr ""
+"Attention : Commande ATC de renversement impossible car le train se déplace !"
+
+#: advtrains/atc.lua:248
+msgid "ATC Kick command warning: Doors closed"
+msgstr ""
+
+#: advtrains/atc.lua:252
+msgid "ATC Kick command warning: Train moving"
+msgstr ""
+
+#: advtrains/atc.lua:322
+msgid "ATC command syntax error: I statement not closed: @1"
+msgstr "Erreur de syntaxe de commande ATC : instruction \"I\" incomplète : @1"
+
+#: advtrains/atc.lua:385
+msgid "ATC command parse error: Unknown command: @1"
+msgstr "Erreur d'analyse de commande ATC : Commande inconnue : @1"
+
+#: advtrains/craft_items.lua:3
+msgid "Boiler"
+msgstr "Chaudière à vapeur"
+
+#: advtrains/craft_items.lua:9
+msgid "driver's cab"
+msgstr "Cabine de pilotage"
+
+#: advtrains/craft_items.lua:15
+msgid "Wheel"
+msgstr "Roue"
+
+#: advtrains/craft_items.lua:21
+msgid "Chimney"
+msgstr "Cheminée"
+
+#: advtrains/misc_nodes.lua:16
+msgid "@1 Platform (low)"
+msgstr "Quai @1 (bas)"
+
+#: advtrains/misc_nodes.lua:33
+msgid "@1 Platform (high)"
+msgstr "Quai @1 (haut)"
+
+#: advtrains/misc_nodes.lua:59
+msgid "@1 Platform (45 degree)"
+msgstr "Quai @1 (haut, 45°)"
+
+#: advtrains/misc_nodes.lua:81
+msgid "@1 Platform (low, 45 degree)"
+msgstr "Quai @1 (bas, 45°)"
+
+#: advtrains/trackplacer.lua:313
+msgid ""
+"Track Worker Tool\n"
+"\n"
+"Left-click: change rail type (straight/curve/switch)\n"
+"Right-click: rotate rail/bumper/signal/etc."
+msgstr ""
+"Outil \"Trackworker\"\n"
+"\n"
+"Clic-Gauche : change le type de rail (droit/courbé/aiguillage)\n"
+"\n"
+"Clic-Droit : tourne le rail/butoir/signal/etc..."
+
+#: advtrains/trackplacer.lua:340 advtrains/trackplacer.lua:377
+msgid "This node can't be rotated using the trackworker!"
+msgstr "Ce nœud ne peut être tourné avec l'outil \"Trackworker\" !"
+
+#: advtrains/trackplacer.lua:350
+msgid "This track can not be rotated!"
+msgstr "Cette voie ne peut pas être tournée !"
+
+#: advtrains/trackplacer.lua:404
+msgid "This node can't be changed using the trackworker!"
+msgstr "Ce nœud ne peut être modifié avec l'outil \"Trackworker\" !"
+
+#: advtrains/trackplacer.lua:414
+msgid "This track can not be changed!"
+msgstr "Cette voie ne peut pas être modifiée !"
+
+#: advtrains/wagons.lua:179
+msgid "This wagon is owned by @1, you can't destroy it."
+msgstr "Ce wagon est la propriété de @1, vous ne pouvez pas le détruire."
+
+#: advtrains/wagons.lua:203
+msgid "The wagon's inventory is not empty!"
+msgstr "Le stock de ce wagon n'est pas vide !"
+
+#: advtrains/wagons.lua:210
+msgid "Wagon needs to be decoupled from other wagons in order to destroy it."
+msgstr ""
+
+#: advtrains/wagons.lua:216
+msgid ""
+"Warning: If you destroy this wagon, you only get some steel back! If you are "
+"sure, hold Sneak and left-click the wagon."
+msgstr ""
+"Attention: Si vous détruisez ce wagon, vous ne récupérerez que de la "
+"ferraille ! Si vous êtes sûr de vous, appuyez la touche \"Marcher lentement "
+"(Sneak)\" et Clic-Gauche."
+
+#: advtrains/wagons.lua:649 advtrains/wagons.lua:850
+msgid "Show Inventory"
+msgstr "Montrer le stock"
+
+#: advtrains/wagons.lua:652
+msgid "Onboard Computer"
+msgstr ""
+
+#: advtrains/wagons.lua:655 advtrains/wagons.lua:1328
+msgid "Wagon properties"
+msgstr "Propriétés du wagon"
+
+#: advtrains/wagons.lua:658
+msgid "Get off"
+msgstr "Débarquer"
+
+#: advtrains/wagons.lua:661
+msgid "Get off (forced)"
+msgstr "Débarquer (de force)"
+
+#: advtrains/wagons.lua:663
+msgid "(Doors closed)"
+msgstr "(Portes closes)"
+
+#: advtrains/wagons.lua:712
+msgid "Can't get on: "
+msgstr ""
+
+#: advtrains/wagons.lua:838
+msgid "Select seat:"
+msgstr "Choisir le siège"
+
+#: advtrains/wagons.lua:880
+msgid "Save wagon properties"
+msgstr "Sauvegarder les propriétés du wagon"
+
+#: advtrains/wagons.lua:965
+msgid "Text displayed outside on train"
+msgstr "Texte affiché à l'extérieur du train"
+
+#: advtrains/wagons.lua:966
+msgid "Text displayed inside train"
+msgstr "Texte affiché à l'intérieur du train"
+
+#: advtrains/wagons.lua:967
+msgid "Line"
+msgstr "Ligne "
+
+#: advtrains/wagons.lua:968
+msgid "Routingcode"
+msgstr "Code de routage"
+
+#: advtrains/wagons.lua:1241
+msgid ""
+"Doors are closed! Use Sneak+rightclick to ignore the closed doors and get "
+"off!"
+msgstr ""
+"Portes closes ! Utilisez \"Marcher lentement (Sneak)\" et Clic-Droit pour "
+"franchir les portes et débarquer !"
+
+#: advtrains/trainhud.lua:305
+msgid "OVERRUN RED SIGNAL! Examine situation and reverse train to move again."
+msgstr ""
+
+#: advtrains/tracks.lua:449
+msgid "This track can not be removed!"
+msgstr "Cette voie ne peut pas être enlevée !"
+
+#: advtrains/tracks.lua:616
+msgid "Position is occupied by a train."
+msgstr "Cet emplacement est occupé par un train."
+
+#: advtrains/tracks.lua:622
+msgid "There's a Track Circuit Break here."
+msgstr "Il y a un \"Track Circuit Break\" ici."
+
+#: advtrains/tracks.lua:626
+msgid "There's a Signal Influence Point here."
+msgstr "Il y a un \"Signal Influence Point\" ici."
+
+#: advtrains/tracks.lua:637
+msgid "@1 Slope"
+msgstr "Pente @1"
+
+#: advtrains/tracks.lua:648 advtrains/tracks.lua:653
+msgid "Can't place: not pointing at node"
+msgstr "Placement impossible : ne pointe pas un nœud"
+
+#: advtrains/tracks.lua:658
+msgid "Can't place: space occupied!"
+msgstr "Placement impossible : espace occupé"
+
+#: advtrains/tracks.lua:711
+msgid "Can't place: Not enough slope items left (@1 required)"
+msgstr ""
+"Placement impossible : quantité insuffisante de voie pentue (@1 manquant)"
+
+#: advtrains/tracks.lua:714
+msgid "Can't place: There's no slope of length @1"
+msgstr "Placement impossible : il n'y a pas de voie pentue de longueur @1"
+
+#: advtrains/tracks.lua:721
+msgid "Can't place: no supporting node at upper end."
+msgstr "Placement impossible : pas de nœud d'appui à l'extrémité supérieure"
+
+#: advtrains/signals.lua:63
+msgid "Lampless Signal"
+msgstr "Sémaphore"
+
+#: advtrains/signals.lua:127
+msgid "Signal"
+msgstr ""
+
+#: advtrains/signals.lua:191
+msgid "Wallmounted Signal (l)"
+msgstr "Signal mural (gauche)"
+
+#: advtrains/signals.lua:192
+msgid "Wallmounted Signal (r)"
+msgstr "Signal mural (droit)"
+
+#: advtrains/signals.lua:193
+msgid "Wallmounted Signal (t)"
+msgstr "Signal mural (plafond)"
+
+#: advtrains/signals.lua:281 advtrains/signals.lua:322
+msgid "Andrew's Cross"
+msgstr "Croix de Saint André"
+
+#: advtrains/couple.lua:28
+msgid "Buffer and Chain Coupler"
+msgstr "Attelage à tampon et vis"
+
+#: advtrains/couple.lua:29
+msgid "Scharfenberg Coupler"
+msgstr "Attelage Scharfenberg"
+
+#: advtrains/couple.lua:185
+msgid ""
+"You are not allowed to couple trains without the train_operator privilege."
+msgstr ""
+
+#: advtrains/couple.lua:329 advtrains/couple.lua:333
+msgid "<none>"
+msgstr ""
+
+#: advtrains/couple.lua:334
+msgid "Can not couple: The couplers of the trains do not match (@1 and @2)."
+msgstr ""
+"Accouplement impossible: les attelages des trains ne concordent pas (@1 et "
+"@2)."
+
+#: advtrains/copytool.lua:8
+msgid ""
+"Train copy/paste tool\n"
+"\n"
+"Left-click: copy train\n"
+"Right-click: paste train"
+msgstr ""
+"Outil de copie/collage de train\n"
+"\n"
+"Clic-Gauche : copie\n"
+"\n"
+"Clic-Droit : collage"
+
+#: advtrains/copytool.lua:29
+msgid "You do not have the @1 privilege."
+msgstr "Vous ne possédez pas le privilège \"@1\"."
+
+#: advtrains/copytool.lua:41
+msgid "The track you are trying to place the wagon on is not long enough!"
+msgstr "La voie sur laquelle vous tentez de placer le wagon est trop courte !"
+
+#: advtrains/copytool.lua:47
+msgid "The clipboard couldn't access the metadata. Paste failed."
+msgstr "Le presse-papier ne peut accéder aux métadonnées. Échec du collage."
+
+#: advtrains/copytool.lua:52 advtrains/copytool.lua:57
+msgid "The clipboard is empty."
+msgstr "Le presse-papier est vide."
+
+#: advtrains/copytool.lua:74
+msgid "Back of train would end up off track, cancelling."
+msgstr "La fin du train serait hors voie : annulation."
+
+#: advtrains/copytool.lua:92
+msgid "No such lua entity!"
+msgstr "Pas de telle entité lua !"
+
+#: advtrains/copytool.lua:98
+msgid "No such wagon: @1"
+msgstr "Pas de tel wagon : @1"
+
+#: advtrains/copytool.lua:104
+msgid "No such train: @1"
+msgstr "Pas de tel train : @1"
+
+#: advtrains/copytool.lua:176
+msgid "The clipboard couldn't access the metadata. Copy failed."
+msgstr "Le presse-papier ne peut accéder aux métadonnées. Échec de la copie."
+
+#: advtrains/copytool.lua:180
+msgid "Train copied!"
+msgstr "Train copié !"
+
+#: advtrains/protection.lua:148
+msgid ""
+"You are not allowed to build near tracks without the track_builder privilege."
+msgstr ""
+"Vous ne pouvez pas construire à proximité d'une voie sans le privilège "
+"\"track_builder\" (?)"
+
+#: advtrains/protection.lua:148
+msgid ""
+"You are not allowed to build tracks without the track_builder privilege."
+msgstr ""
+"Vous ne pouvez pas construire une voie sans le privilège \"track_builder\""
+
+#: advtrains/protection.lua:153
+msgid "You are not allowed to build near tracks at this protected position."
+msgstr ""
+"Vous ne pouvez pas construire à proximité d'une voie à cet emplacement "
+"protégé"
+
+#: advtrains/protection.lua:153
+msgid "You are not allowed to build tracks at this protected position."
+msgstr "Vous ne pouvez pas construire une voie à cet emplacement protégé"
+
+#: advtrains/protection.lua:184
+msgid ""
+"You are not allowed to operate turnouts and signals without the "
+"railway_operator privilege."
+msgstr ""
+"Vous ne pouvez pas actionner les aiguillages ou les signaux (privilège "
+"\"railway_operator\" manquant)"
+
+#: advtrains_line_automation/stoprail.lua:54
+msgid "Station Code"
+msgstr "Code de Station"
+
+#: advtrains_line_automation/stoprail.lua:55
+msgid "Station Name"
+msgstr "Nom de Station"
+
+#: advtrains_line_automation/stoprail.lua:56
+msgid "Door Delay"
+msgstr "Durée d'ouverture des portes"
+
+#: advtrains_line_automation/stoprail.lua:57
+msgid "Dep. Speed"
+msgstr "Vitesse de départ"
+
+#: advtrains_line_automation/stoprail.lua:58 advtrains_train_track/init.lua:11
+#: advtrains_train_track/init.lua:156
+msgid "Track"
+msgstr "Voie"
+
+#: advtrains_line_automation/stoprail.lua:59
+msgid "Stop Time"
+msgstr "Durée d'arrêt"
+
+#: advtrains_line_automation/stoprail.lua:60
+msgid "Door Side"
+msgstr ""
+
+#: advtrains_line_automation/stoprail.lua:62
+msgid "Reverse train"
+msgstr ""
+
+#: advtrains_line_automation/stoprail.lua:63
+msgid "Kick out passengers"
+msgstr ""
+
+#: advtrains_luaautomation/pcnaming.lua:26
+msgid ""
+"Passive Component Naming Tool\n"
+"\n"
+"Right-click to name a passive component."
+msgstr ""
+"Outil de nommage de composant passif\n"
+"\n"
+"Clic-Droit pour nommer un composant passif."
+
+#: advtrains_train_track/init.lua:31
+msgid "Y-turnout"
+msgstr "Embranchement en Y"
+
+#: advtrains_train_track/init.lua:49
+msgid "3-way turnout"
+msgstr "Embranchement triple"
+
+#: advtrains_train_track/init.lua:69
+msgid "Perpendicular Diamond Crossing Track"
+msgstr "Croisement perpendiculaire"
+
+#: advtrains_train_track/init.lua:91
+msgid "90+Angle Diamond Crossing Track"
+msgstr "Croisement perpendiculo-diagonal"
+
+#: advtrains_train_track/init.lua:132
+msgid "Diagonal Diamond Crossing Track"
+msgstr "Croisement diagonal"
+
+#: advtrains_train_track/init.lua:179
+msgid "Bumper"
+msgstr "Heurtoir"
+
+#: advtrains_train_track/init.lua:201
+msgid "ATC controller"
+msgstr "Controlleur ATC"
+
+#: advtrains_train_track/init.lua:317
+msgid "Unloading Track"
+msgstr "Voie de Déchargement"
+
+#: advtrains_train_track/init.lua:342
+msgid "Loading Track"
+msgstr "Voie de Chargement"
+
+#: advtrains_train_track/init.lua:406
+msgid "Detector Rail"
+msgstr "Voie détectrice"
+
+#: advtrains_train_industrial/init.lua:10
+#: advtrains_train_industrial/init.lua:49 advtrains_train_steam/init.lua:20
+#: advtrains_train_steam/init.lua:91
+msgid "Driver Stand (right)"
+msgstr "Poste de pilotage (droit)"
+
+#: advtrains_train_industrial/init.lua:17
+#: advtrains_train_industrial/init.lua:56 advtrains_train_steam/init.lua:14
+#: advtrains_train_steam/init.lua:85
+msgid "Driver Stand (left)"
+msgstr "Poste de pilotage (gauche)"
+
+#: advtrains_train_industrial/init.lua:40
+msgid "Industrial Train Engine"
+msgstr "Locomotive industrielle"
+
+#: advtrains_train_industrial/init.lua:79
+msgid "Big Industrial Train Engine"
+msgstr "Grosse locomotive industrielle "
+
+#: advtrains_train_industrial/init.lua:98
+msgid "Industrial tank wagon"
+msgstr "Wagon-citerne industriel"
+
+#: advtrains_train_industrial/init.lua:116
+msgid "Industrial wood wagon"
+msgstr "Wagon grumier industriel"
+
+#: advtrains_train_japan/init.lua:4
+msgid "Japanese Train Inter-Wagon Connection"
+msgstr "Passage inter-voiture de train Japonais"
+
+#: advtrains_train_japan/init.lua:37
+msgid "Driver stand"
+msgstr "Poste de pilotage"
+
+#: advtrains_train_japan/init.lua:101
+msgid "Japanese Train Engine"
+msgstr "Motrice Japonaise"
+
+#: advtrains_train_japan/init.lua:176
+msgid "Japanese Train Wagon"
+msgstr "Voiture Japonaise"
+
+#: advtrains_train_steam/init.lua:75
+msgid "Steam Engine"
+msgstr "Locomotive à vapeur"
+
+#: advtrains_train_steam/init.lua:159
+msgid "Detailed Steam Engine"
+msgstr "Locomotive à vapeur complexe"
+
+#: advtrains_train_steam/init.lua:206
+msgid "Passenger Wagon"
+msgstr "Voiture passager"
+
+#: advtrains_train_steam/init.lua:226
+msgid "Box Wagon"
+msgstr "Wagon de frêt"
+
+#: advtrains_train_subway/init.lua:144
+msgid "Subway Passenger Wagon"
+msgstr "Voiture de Métropolitain"
+
+#~ msgid "This position is protected!"
+#~ msgstr "Cet emplacement est protégé !"
+
+#~ msgid "Can't place: protected position!"
+#~ msgstr "Placement impossible : emplacement protégé"
+
+#~ msgid "Deprecated Track"
+#~ msgstr "Voie déconseillée"
+
+#~ msgid "Can't get on: wagon full or doors closed!"
+#~ msgstr ""
+#~ "Embarquement impossible : le wagon est plein ou ses portes sont closes !"
+
+#~ msgid "Use Sneak+rightclick to bypass closed doors!"
+#~ msgstr ""
+#~ "Utilisez \"Marcher lentement (Sneak)\" et Clic-Droit pour franchir les "
+#~ "portes closes !"
+
+#~ msgid "Access to @1"
+#~ msgstr "Accès à @1"
+
+#~ msgid ""
+#~ "ATC controller, mode @1\n"
+#~ "Channel: @2"
+#~ msgstr ""
+#~ "Controlleur ATC, mode @1\n"
+#~ "Canal : @2"
+
+#~ msgid "Lock couples"
+#~ msgstr "Verrouiller l'accouplement"
+
+#~ msgid ""
+#~ "You need to own at least one neighboring wagon to destroy this couple."
+#~ msgstr ""
+#~ "Vous devez être propriétaire d'au moins un wagon voisin pour supprimer "
+#~ "cet attelage."
+
+#~ msgid "Speed:"
+#~ msgstr "Vitesse : "
+
+#~ msgid "Target:"
+#~ msgstr "Destination : "
+
+#~ msgid "Default Seat"
+#~ msgstr "Siège par défaut"
+
+#~ msgid "Default Seat (driver stand)"
+#~ msgstr "Siège par défaut (poste de pilotage)"
diff --git a/advtrains/po/template.pot b/advtrains/po/template.pot
new file mode 100644
index 0000000..23aaa6a
--- /dev/null
+++ b/advtrains/po/template.pot
@@ -0,0 +1,505 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the advtrains package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: advtrains\n"
+"Report-Msgid-Bugs-To: advtrains-discuss@lists.sr.ht\n"
+"POT-Creation-Date: 2023-10-04 15:40+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: advtrains/atc.lua:109
+msgid "ATC controller, unconfigured."
+msgstr ""
+
+#: advtrains/atc.lua:150
+msgid ""
+"ATC controller, mode @1\n"
+"Command: @2"
+msgstr ""
+
+#: advtrains/atc.lua:180
+msgid "Command"
+msgstr ""
+
+#: advtrains/atc.lua:184
+msgid "Command (on)"
+msgstr ""
+
+#: advtrains/atc.lua:187
+msgid "Digiline channel"
+msgstr ""
+
+#: advtrains/atc.lua:189 advtrains_line_automation/stoprail.lua:65
+msgid "Save"
+msgstr ""
+
+#: advtrains/atc.lua:236
+msgid "ATC Reverse command warning: didn't reverse train, train moving!"
+msgstr ""
+
+#: advtrains/atc.lua:248
+msgid "ATC Kick command warning: Doors closed"
+msgstr ""
+
+#: advtrains/atc.lua:252
+msgid "ATC Kick command warning: Train moving"
+msgstr ""
+
+#: advtrains/atc.lua:322
+msgid "ATC command syntax error: I statement not closed: @1"
+msgstr ""
+
+#: advtrains/atc.lua:385
+msgid "ATC command parse error: Unknown command: @1"
+msgstr ""
+
+#: advtrains/craft_items.lua:3
+msgid "Boiler"
+msgstr ""
+
+#: advtrains/craft_items.lua:9
+msgid "driver's cab"
+msgstr ""
+
+#: advtrains/craft_items.lua:15
+msgid "Wheel"
+msgstr ""
+
+#: advtrains/craft_items.lua:21
+msgid "Chimney"
+msgstr ""
+
+#: advtrains/misc_nodes.lua:16
+msgid "@1 Platform (low)"
+msgstr ""
+
+#: advtrains/misc_nodes.lua:33
+msgid "@1 Platform (high)"
+msgstr ""
+
+#: advtrains/misc_nodes.lua:59
+msgid "@1 Platform (45 degree)"
+msgstr ""
+
+#: advtrains/misc_nodes.lua:81
+msgid "@1 Platform (low, 45 degree)"
+msgstr ""
+
+#: advtrains/trackplacer.lua:313
+msgid ""
+"Track Worker Tool\n"
+"\n"
+"Left-click: change rail type (straight/curve/switch)\n"
+"Right-click: rotate rail/bumper/signal/etc."
+msgstr ""
+
+#: advtrains/trackplacer.lua:340 advtrains/trackplacer.lua:377
+msgid "This node can't be rotated using the trackworker!"
+msgstr ""
+
+#: advtrains/trackplacer.lua:350
+msgid "This track can not be rotated!"
+msgstr ""
+
+#: advtrains/trackplacer.lua:404
+msgid "This node can't be changed using the trackworker!"
+msgstr ""
+
+#: advtrains/trackplacer.lua:414
+msgid "This track can not be changed!"
+msgstr ""
+
+#: advtrains/wagons.lua:179
+msgid "This wagon is owned by @1, you can't destroy it."
+msgstr ""
+
+#: advtrains/wagons.lua:203
+msgid "The wagon's inventory is not empty!"
+msgstr ""
+
+#: advtrains/wagons.lua:210
+msgid "Wagon needs to be decoupled from other wagons in order to destroy it."
+msgstr ""
+
+#: advtrains/wagons.lua:216
+msgid ""
+"Warning: If you destroy this wagon, you only get some steel back! If you are "
+"sure, hold Sneak and left-click the wagon."
+msgstr ""
+
+#: advtrains/wagons.lua:649 advtrains/wagons.lua:850
+msgid "Show Inventory"
+msgstr ""
+
+#: advtrains/wagons.lua:652
+msgid "Onboard Computer"
+msgstr ""
+
+#: advtrains/wagons.lua:655 advtrains/wagons.lua:1328
+msgid "Wagon properties"
+msgstr ""
+
+#: advtrains/wagons.lua:658
+msgid "Get off"
+msgstr ""
+
+#: advtrains/wagons.lua:661
+msgid "Get off (forced)"
+msgstr ""
+
+#: advtrains/wagons.lua:663
+msgid "(Doors closed)"
+msgstr ""
+
+#: advtrains/wagons.lua:712
+msgid "Can't get on: "
+msgstr ""
+
+#: advtrains/wagons.lua:838
+msgid "Select seat:"
+msgstr ""
+
+#: advtrains/wagons.lua:880
+msgid "Save wagon properties"
+msgstr ""
+
+#: advtrains/wagons.lua:965
+msgid "Text displayed outside on train"
+msgstr ""
+
+#: advtrains/wagons.lua:966
+msgid "Text displayed inside train"
+msgstr ""
+
+#: advtrains/wagons.lua:967
+msgid "Line"
+msgstr ""
+
+#: advtrains/wagons.lua:968
+msgid "Routingcode"
+msgstr ""
+
+#: advtrains/wagons.lua:1241
+msgid ""
+"Doors are closed! Use Sneak+rightclick to ignore the closed doors and get "
+"off!"
+msgstr ""
+
+#: advtrains/trainhud.lua:305
+msgid "OVERRUN RED SIGNAL! Examine situation and reverse train to move again."
+msgstr ""
+
+#: advtrains/tracks.lua:449
+msgid "This track can not be removed!"
+msgstr ""
+
+#: advtrains/tracks.lua:616
+msgid "Position is occupied by a train."
+msgstr ""
+
+#: advtrains/tracks.lua:622
+msgid "There's a Track Circuit Break here."
+msgstr ""
+
+#: advtrains/tracks.lua:626
+msgid "There's a Signal Influence Point here."
+msgstr ""
+
+#: advtrains/tracks.lua:637
+msgid "@1 Slope"
+msgstr ""
+
+#: advtrains/tracks.lua:648 advtrains/tracks.lua:653
+msgid "Can't place: not pointing at node"
+msgstr ""
+
+#: advtrains/tracks.lua:658
+msgid "Can't place: space occupied!"
+msgstr ""
+
+#: advtrains/tracks.lua:711
+msgid "Can't place: Not enough slope items left (@1 required)"
+msgstr ""
+
+#: advtrains/tracks.lua:714
+msgid "Can't place: There's no slope of length @1"
+msgstr ""
+
+#: advtrains/tracks.lua:721
+msgid "Can't place: no supporting node at upper end."
+msgstr ""
+
+#: advtrains/signals.lua:63
+msgid "Lampless Signal"
+msgstr ""
+
+#: advtrains/signals.lua:127
+msgid "Signal"
+msgstr ""
+
+#: advtrains/signals.lua:191
+msgid "Wallmounted Signal (l)"
+msgstr ""
+
+#: advtrains/signals.lua:192
+msgid "Wallmounted Signal (r)"
+msgstr ""
+
+#: advtrains/signals.lua:193
+msgid "Wallmounted Signal (t)"
+msgstr ""
+
+#: advtrains/signals.lua:281 advtrains/signals.lua:322
+msgid "Andrew's Cross"
+msgstr ""
+
+#: advtrains/couple.lua:28
+msgid "Buffer and Chain Coupler"
+msgstr ""
+
+#: advtrains/couple.lua:29
+msgid "Scharfenberg Coupler"
+msgstr ""
+
+#: advtrains/couple.lua:185
+msgid ""
+"You are not allowed to couple trains without the train_operator privilege."
+msgstr ""
+
+#: advtrains/couple.lua:329 advtrains/couple.lua:333
+msgid "<none>"
+msgstr ""
+
+#: advtrains/couple.lua:334
+msgid "Can not couple: The couplers of the trains do not match (@1 and @2)."
+msgstr ""
+
+#: advtrains/copytool.lua:8
+msgid ""
+"Train copy/paste tool\n"
+"\n"
+"Left-click: copy train\n"
+"Right-click: paste train"
+msgstr ""
+
+#: advtrains/copytool.lua:29
+msgid "You do not have the @1 privilege."
+msgstr ""
+
+#: advtrains/copytool.lua:41
+msgid "The track you are trying to place the wagon on is not long enough!"
+msgstr ""
+
+#: advtrains/copytool.lua:47
+msgid "The clipboard couldn't access the metadata. Paste failed."
+msgstr ""
+
+#: advtrains/copytool.lua:52 advtrains/copytool.lua:57
+msgid "The clipboard is empty."
+msgstr ""
+
+#: advtrains/copytool.lua:74
+msgid "Back of train would end up off track, cancelling."
+msgstr ""
+
+#: advtrains/copytool.lua:92
+msgid "No such lua entity!"
+msgstr ""
+
+#: advtrains/copytool.lua:98
+msgid "No such wagon: @1"
+msgstr ""
+
+#: advtrains/copytool.lua:104
+msgid "No such train: @1"
+msgstr ""
+
+#: advtrains/copytool.lua:176
+msgid "The clipboard couldn't access the metadata. Copy failed."
+msgstr ""
+
+#: advtrains/copytool.lua:180
+msgid "Train copied!"
+msgstr ""
+
+#: advtrains/protection.lua:148
+msgid ""
+"You are not allowed to build near tracks without the track_builder privilege."
+msgstr ""
+
+#: advtrains/protection.lua:148
+msgid ""
+"You are not allowed to build tracks without the track_builder privilege."
+msgstr ""
+
+#: advtrains/protection.lua:153
+msgid "You are not allowed to build near tracks at this protected position."
+msgstr ""
+
+#: advtrains/protection.lua:153
+msgid "You are not allowed to build tracks at this protected position."
+msgstr ""
+
+#: advtrains/protection.lua:184
+msgid ""
+"You are not allowed to operate turnouts and signals without the "
+"railway_operator privilege."
+msgstr ""
+
+#: advtrains_line_automation/stoprail.lua:54
+msgid "Station Code"
+msgstr ""
+
+#: advtrains_line_automation/stoprail.lua:55
+msgid "Station Name"
+msgstr ""
+
+#: advtrains_line_automation/stoprail.lua:56
+msgid "Door Delay"
+msgstr ""
+
+#: advtrains_line_automation/stoprail.lua:57
+msgid "Dep. Speed"
+msgstr ""
+
+#: advtrains_line_automation/stoprail.lua:58 advtrains_train_track/init.lua:11
+#: advtrains_train_track/init.lua:156
+msgid "Track"
+msgstr ""
+
+#: advtrains_line_automation/stoprail.lua:59
+msgid "Stop Time"
+msgstr ""
+
+#: advtrains_line_automation/stoprail.lua:60
+msgid "Door Side"
+msgstr ""
+
+#: advtrains_line_automation/stoprail.lua:62
+msgid "Reverse train"
+msgstr ""
+
+#: advtrains_line_automation/stoprail.lua:63
+msgid "Kick out passengers"
+msgstr ""
+
+#: advtrains_luaautomation/pcnaming.lua:26
+msgid ""
+"Passive Component Naming Tool\n"
+"\n"
+"Right-click to name a passive component."
+msgstr ""
+
+#: advtrains_train_track/init.lua:31
+msgid "Y-turnout"
+msgstr ""
+
+#: advtrains_train_track/init.lua:49
+msgid "3-way turnout"
+msgstr ""
+
+#: advtrains_train_track/init.lua:69
+msgid "Perpendicular Diamond Crossing Track"
+msgstr ""
+
+#: advtrains_train_track/init.lua:91
+msgid "90+Angle Diamond Crossing Track"
+msgstr ""
+
+#: advtrains_train_track/init.lua:132
+msgid "Diagonal Diamond Crossing Track"
+msgstr ""
+
+#: advtrains_train_track/init.lua:179
+msgid "Bumper"
+msgstr ""
+
+#: advtrains_train_track/init.lua:201
+msgid "ATC controller"
+msgstr ""
+
+#: advtrains_train_track/init.lua:317
+msgid "Unloading Track"
+msgstr ""
+
+#: advtrains_train_track/init.lua:342
+msgid "Loading Track"
+msgstr ""
+
+#: advtrains_train_track/init.lua:406
+msgid "Detector Rail"
+msgstr ""
+
+#: advtrains_train_industrial/init.lua:10
+#: advtrains_train_industrial/init.lua:49 advtrains_train_steam/init.lua:20
+#: advtrains_train_steam/init.lua:91
+msgid "Driver Stand (right)"
+msgstr ""
+
+#: advtrains_train_industrial/init.lua:17
+#: advtrains_train_industrial/init.lua:56 advtrains_train_steam/init.lua:14
+#: advtrains_train_steam/init.lua:85
+msgid "Driver Stand (left)"
+msgstr ""
+
+#: advtrains_train_industrial/init.lua:40
+msgid "Industrial Train Engine"
+msgstr ""
+
+#: advtrains_train_industrial/init.lua:79
+msgid "Big Industrial Train Engine"
+msgstr ""
+
+#: advtrains_train_industrial/init.lua:98
+msgid "Industrial tank wagon"
+msgstr ""
+
+#: advtrains_train_industrial/init.lua:116
+msgid "Industrial wood wagon"
+msgstr ""
+
+#: advtrains_train_japan/init.lua:4
+msgid "Japanese Train Inter-Wagon Connection"
+msgstr ""
+
+#: advtrains_train_japan/init.lua:37
+msgid "Driver stand"
+msgstr ""
+
+#: advtrains_train_japan/init.lua:101
+msgid "Japanese Train Engine"
+msgstr ""
+
+#: advtrains_train_japan/init.lua:176
+msgid "Japanese Train Wagon"
+msgstr ""
+
+#: advtrains_train_steam/init.lua:75
+msgid "Steam Engine"
+msgstr ""
+
+#: advtrains_train_steam/init.lua:159
+msgid "Detailed Steam Engine"
+msgstr ""
+
+#: advtrains_train_steam/init.lua:206
+msgid "Passenger Wagon"
+msgstr ""
+
+#: advtrains_train_steam/init.lua:226
+msgid "Box Wagon"
+msgstr ""
+
+#: advtrains_train_subway/init.lua:144
+msgid "Subway Passenger Wagon"
+msgstr ""
diff --git a/advtrains/po/update-translations.sh b/advtrains/po/update-translations.sh
new file mode 100755
index 0000000..d86c568
--- /dev/null
+++ b/advtrains/po/update-translations.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+# NOTE: Please make sure you also have basic_trains installed, as it uses attrans for historical reasons
+
+ATDIR=`dirname "$0"`/../..
+BTDIR="$ATDIR"/../basic_trains
+
+xgettext \
+ -D "$ATDIR" \
+ -D "$BTDIR" \
+ -d advtrains \
+ -p . \
+ -L lua \
+ --from-code=UTF-8 \
+ --keyword='attrans' \
+ --keyword='S' \
+ --package-name='advtrains' \
+ --msgid-bugs-address='advtrains-discuss@lists.sr.ht' \
+ `find $ATDIR $BTDIR -name '*.lua' -printf '%P\n'` \
+ &&
+mv advtrains.po template.pot &&
+for i in *.po; do
+ msgmerge -U \
+ $i template.pot
+done
diff --git a/advtrains/po/zh_CN.po b/advtrains/po/zh_CN.po
new file mode 100644
index 0000000..c81cf6c
--- /dev/null
+++ b/advtrains/po/zh_CN.po
@@ -0,0 +1,560 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: advtrains\n"
+"Report-Msgid-Bugs-To: advtrains-discuss@lists.sr.ht\n"
+"POT-Creation-Date: 2023-10-04 15:40+0200\n"
+"PO-Revision-Date: 2022-11-02 15:08+0100\n"
+"Last-Translator: Y. Wang <yw05@forksworld.de>\n"
+"Language-Team: Chinese (Simplified)\n"
+"Language: zh_CN\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: advtrains/atc.lua:109
+msgid "ATC controller, unconfigured."
+msgstr "ATC 控制器 (未配置)"
+
+#: advtrains/atc.lua:150
+msgid ""
+"ATC controller, mode @1\n"
+"Command: @2"
+msgstr ""
+"ATC 控制器\n"
+"模式:@1\n"
+"命令:@2"
+
+#: advtrains/atc.lua:180
+msgid "Command"
+msgstr "命令"
+
+#: advtrains/atc.lua:184
+msgid "Command (on)"
+msgstr "命令 (激活时)"
+
+#: advtrains/atc.lua:187
+msgid "Digiline channel"
+msgstr "Digiline 频道"
+
+#: advtrains/atc.lua:189 advtrains_line_automation/stoprail.lua:65
+msgid "Save"
+msgstr "保存"
+
+#: advtrains/atc.lua:236
+msgid "ATC Reverse command warning: didn't reverse train, train moving!"
+msgstr "ATC 警告:未执行“R”命令,火车在移动"
+
+#: advtrains/atc.lua:248
+msgid "ATC Kick command warning: Doors closed"
+msgstr ""
+
+#: advtrains/atc.lua:252
+msgid "ATC Kick command warning: Train moving"
+msgstr ""
+
+#: advtrains/atc.lua:322
+msgid "ATC command syntax error: I statement not closed: @1"
+msgstr "ATC 语法错误:“I”命令不完整:@1"
+
+#: advtrains/atc.lua:385
+msgid "ATC command parse error: Unknown command: @1"
+msgstr "ATC 语法错误:未知命令:@1"
+
+#: advtrains/craft_items.lua:3
+msgid "Boiler"
+msgstr "锅炉"
+
+#: advtrains/craft_items.lua:9
+msgid "driver's cab"
+msgstr "驾驶室"
+
+#: advtrains/craft_items.lua:15
+msgid "Wheel"
+msgstr "车轮"
+
+#: advtrains/craft_items.lua:21
+msgid "Chimney"
+msgstr "烟囱"
+
+#: advtrains/misc_nodes.lua:16
+msgid "@1 Platform (low)"
+msgstr "较低的@1站台"
+
+#: advtrains/misc_nodes.lua:33
+msgid "@1 Platform (high)"
+msgstr "较高的@1站台"
+
+#: advtrains/misc_nodes.lua:59
+msgid "@1 Platform (45 degree)"
+msgstr "较高的@1站台 (45°)"
+
+#: advtrains/misc_nodes.lua:81
+msgid "@1 Platform (low, 45 degree)"
+msgstr "较低的@1站台 (45°)"
+
+#: advtrains/trackplacer.lua:313
+msgid ""
+"Track Worker Tool\n"
+"\n"
+"Left-click: change rail type (straight/curve/switch)\n"
+"Right-click: rotate rail/bumper/signal/etc."
+msgstr ""
+"铁路调整工具\n"
+"\n"
+"左键单击:切换轨道类型\n"
+"右键单击:旋转方块"
+
+#: advtrains/trackplacer.lua:340 advtrains/trackplacer.lua:377
+msgid "This node can't be rotated using the trackworker!"
+msgstr "您不能使用铁路调整工具旋转这个方块。"
+
+#: advtrains/trackplacer.lua:350
+msgid "This track can not be rotated!"
+msgstr "您不能旋转这段轨道。"
+
+#: advtrains/trackplacer.lua:404
+msgid "This node can't be changed using the trackworker!"
+msgstr "您不能使用铁路调整工具调整这个方块。"
+
+#: advtrains/trackplacer.lua:414
+msgid "This track can not be changed!"
+msgstr "您不能调整这段轨道。"
+
+#: advtrains/wagons.lua:179
+msgid "This wagon is owned by @1, you can't destroy it."
+msgstr "这是 @1 的车厢,您不能摧毁它。"
+
+#: advtrains/wagons.lua:203
+msgid "The wagon's inventory is not empty!"
+msgstr ""
+
+#: advtrains/wagons.lua:210
+msgid "Wagon needs to be decoupled from other wagons in order to destroy it."
+msgstr ""
+
+#: advtrains/wagons.lua:216
+msgid ""
+"Warning: If you destroy this wagon, you only get some steel back! If you are "
+"sure, hold Sneak and left-click the wagon."
+msgstr ""
+"警告:如果您摧毁此车厢,您只能拿到一些钢方块。如果您确定要摧毁这节车厢,请按"
+"潜行键并左键单击此车厢。"
+
+#: advtrains/wagons.lua:649 advtrains/wagons.lua:850
+msgid "Show Inventory"
+msgstr "显示物品栏"
+
+#: advtrains/wagons.lua:652
+msgid "Onboard Computer"
+msgstr ""
+
+#: advtrains/wagons.lua:655 advtrains/wagons.lua:1328
+msgid "Wagon properties"
+msgstr "车厢属性"
+
+#: advtrains/wagons.lua:658
+msgid "Get off"
+msgstr "下车"
+
+#: advtrains/wagons.lua:661
+msgid "Get off (forced)"
+msgstr "强制下车"
+
+#: advtrains/wagons.lua:663
+msgid "(Doors closed)"
+msgstr "(车门已关闭)"
+
+#: advtrains/wagons.lua:712
+msgid "Can't get on: "
+msgstr ""
+
+#: advtrains/wagons.lua:838
+msgid "Select seat:"
+msgstr "请选择座位"
+
+#: advtrains/wagons.lua:880
+msgid "Save wagon properties"
+msgstr "保存车厢属性"
+
+#: advtrains/wagons.lua:965
+msgid "Text displayed outside on train"
+msgstr "车厢外部显示"
+
+#: advtrains/wagons.lua:966
+msgid "Text displayed inside train"
+msgstr "车厢内部显示"
+
+#: advtrains/wagons.lua:967
+msgid "Line"
+msgstr "火车线路"
+
+#: advtrains/wagons.lua:968
+msgid "Routingcode"
+msgstr "路由码"
+
+#: advtrains/wagons.lua:1241
+msgid ""
+"Doors are closed! Use Sneak+rightclick to ignore the closed doors and get "
+"off!"
+msgstr "车门已关闭,请使用潜行+右键单击下车。"
+
+#: advtrains/trainhud.lua:305
+msgid "OVERRUN RED SIGNAL! Examine situation and reverse train to move again."
+msgstr ""
+
+#: advtrains/tracks.lua:449
+msgid "This track can not be removed!"
+msgstr "您不能移除这段轨道。"
+
+#: advtrains/tracks.lua:616
+msgid "Position is occupied by a train."
+msgstr ""
+
+#: advtrains/tracks.lua:622
+msgid "There's a Track Circuit Break here."
+msgstr ""
+
+#: advtrains/tracks.lua:626
+msgid "There's a Signal Influence Point here."
+msgstr ""
+
+#: advtrains/tracks.lua:637
+msgid "@1 Slope"
+msgstr "@1斜坡"
+
+#: advtrains/tracks.lua:648 advtrains/tracks.lua:653
+msgid "Can't place: not pointing at node"
+msgstr "无法放置:您没有选择任何方块。"
+
+#: advtrains/tracks.lua:658
+msgid "Can't place: space occupied!"
+msgstr "无法放置:此区域已被占用。"
+
+#: advtrains/tracks.lua:711
+msgid "Can't place: Not enough slope items left (@1 required)"
+msgstr "无法放置:您没有足够的铁路斜坡放置工具 (您总共需要@1个)"
+
+#: advtrains/tracks.lua:714
+msgid "Can't place: There's no slope of length @1"
+msgstr "无法放置:advtrains 不支持长度为@1米的斜坡。"
+
+#: advtrains/tracks.lua:721
+msgid "Can't place: no supporting node at upper end."
+msgstr "无法放置:较高端没有支撑方块。"
+
+#: advtrains/signals.lua:63
+msgid "Lampless Signal"
+msgstr "臂板信号机"
+
+#: advtrains/signals.lua:127
+msgid "Signal"
+msgstr "信号灯"
+
+#: advtrains/signals.lua:191
+msgid "Wallmounted Signal (l)"
+msgstr "壁挂式信号灯 (左侧)"
+
+#: advtrains/signals.lua:192
+msgid "Wallmounted Signal (r)"
+msgstr "壁挂式信号灯 (右侧)"
+
+#: advtrains/signals.lua:193
+msgid "Wallmounted Signal (t)"
+msgstr "悬挂式信号灯"
+
+#: advtrains/signals.lua:281 advtrains/signals.lua:322
+msgid "Andrew's Cross"
+msgstr "铁路道口信号灯"
+
+#: advtrains/couple.lua:28
+msgid "Buffer and Chain Coupler"
+msgstr "链式车钩"
+
+#: advtrains/couple.lua:29
+msgid "Scharfenberg Coupler"
+msgstr "Scharfenberg 式车钩"
+
+#: advtrains/couple.lua:185
+msgid ""
+"You are not allowed to couple trains without the train_operator privilege."
+msgstr "您没有“train_operator”权限,不能连接这两节车厢。"
+
+#: advtrains/couple.lua:329 advtrains/couple.lua:333
+msgid "<none>"
+msgstr ""
+
+#: advtrains/couple.lua:334
+msgid "Can not couple: The couplers of the trains do not match (@1 and @2)."
+msgstr "您无法连接这两节车厢:这两节车厢使用不同的车钩 (@1和@2)。"
+
+#: advtrains/copytool.lua:8
+msgid ""
+"Train copy/paste tool\n"
+"\n"
+"Left-click: copy train\n"
+"Right-click: paste train"
+msgstr ""
+"火车复制工具\n"
+"\n"
+"左键单击:复制\n"
+"右键单击:粘帖"
+
+#: advtrains/copytool.lua:29
+msgid "You do not have the @1 privilege."
+msgstr "您没有“@1”权限。"
+
+#: advtrains/copytool.lua:41
+msgid "The track you are trying to place the wagon on is not long enough!"
+msgstr "轨道太短。"
+
+#: advtrains/copytool.lua:47
+msgid "The clipboard couldn't access the metadata. Paste failed."
+msgstr "无法粘贴:剪贴板无法访问元数据。"
+
+#: advtrains/copytool.lua:52 advtrains/copytool.lua:57
+msgid "The clipboard is empty."
+msgstr "剪贴板是空的。"
+
+#: advtrains/copytool.lua:74
+msgid "Back of train would end up off track, cancelling."
+msgstr "火车后部不在轨道上。"
+
+#: advtrains/copytool.lua:92
+msgid "No such lua entity!"
+msgstr "您没有指向一个可以用火车复制工具复制的物体。"
+
+#: advtrains/copytool.lua:98
+msgid "No such wagon: @1"
+msgstr "ID 为“@1”的车厢不存在。"
+
+#: advtrains/copytool.lua:104
+msgid "No such train: @1"
+msgstr "ID 为“@1”的列车不存在。"
+
+#: advtrains/copytool.lua:176
+msgid "The clipboard couldn't access the metadata. Copy failed."
+msgstr "无法复制:剪贴板无法访问元数据。"
+
+#: advtrains/copytool.lua:180
+msgid "Train copied!"
+msgstr "已复制"
+
+#: advtrains/protection.lua:148
+msgid ""
+"You are not allowed to build near tracks without the track_builder privilege."
+msgstr "您没有“train_operator”权限,不能在铁路附近建任何东西。"
+
+#: advtrains/protection.lua:148
+msgid ""
+"You are not allowed to build tracks without the track_builder privilege."
+msgstr "您没有“train_operator”权限,不能在这里建造铁路。"
+
+#: advtrains/protection.lua:153
+msgid "You are not allowed to build near tracks at this protected position."
+msgstr "这里已被保护,您不能在这里的铁路附近建任何东西。"
+
+#: advtrains/protection.lua:153
+msgid "You are not allowed to build tracks at this protected position."
+msgstr "这里已被保护,您不能在这里建造铁路。"
+
+#: advtrains/protection.lua:184
+msgid ""
+"You are not allowed to operate turnouts and signals without the "
+"railway_operator privilege."
+msgstr "您没有“railway_operator”权限,不能控制铁路设施。"
+
+#: advtrains_line_automation/stoprail.lua:54
+msgid "Station Code"
+msgstr "车站代码"
+
+#: advtrains_line_automation/stoprail.lua:55
+msgid "Station Name"
+msgstr "车站名称"
+
+#: advtrains_line_automation/stoprail.lua:56
+msgid "Door Delay"
+msgstr "车门关闭时间"
+
+#: advtrains_line_automation/stoprail.lua:57
+msgid "Dep. Speed"
+msgstr "出发速度"
+
+#: advtrains_line_automation/stoprail.lua:58 advtrains_train_track/init.lua:11
+#: advtrains_train_track/init.lua:156
+msgid "Track"
+msgstr "轨道"
+
+#: advtrains_line_automation/stoprail.lua:59
+msgid "Stop Time"
+msgstr "停站时间"
+
+#: advtrains_line_automation/stoprail.lua:60
+msgid "Door Side"
+msgstr ""
+
+#: advtrains_line_automation/stoprail.lua:62
+msgid "Reverse train"
+msgstr ""
+
+#: advtrains_line_automation/stoprail.lua:63
+msgid "Kick out passengers"
+msgstr ""
+
+#: advtrains_luaautomation/pcnaming.lua:26
+msgid ""
+"Passive Component Naming Tool\n"
+"\n"
+"Right-click to name a passive component."
+msgstr ""
+"被动元件命名工具\n"
+"\n"
+"右键单击命名所选元件"
+
+#: advtrains_train_track/init.lua:31
+msgid "Y-turnout"
+msgstr "对称道岔"
+
+#: advtrains_train_track/init.lua:49
+msgid "3-way turnout"
+msgstr "三开道岔"
+
+#: advtrains_train_track/init.lua:69
+msgid "Perpendicular Diamond Crossing Track"
+msgstr "垂直交叉轨道"
+
+#: advtrains_train_track/init.lua:91
+msgid "90+Angle Diamond Crossing Track"
+msgstr "交叉轨道 (其中一条轨道与坐标轴平行)"
+
+#: advtrains_train_track/init.lua:132
+msgid "Diagonal Diamond Crossing Track"
+msgstr "交叉轨道"
+
+#: advtrains_train_track/init.lua:179
+msgid "Bumper"
+msgstr "保险杠"
+
+#: advtrains_train_track/init.lua:201
+msgid "ATC controller"
+msgstr "ATC 控制器"
+
+#: advtrains_train_track/init.lua:317
+msgid "Unloading Track"
+msgstr "卸货轨道"
+
+#: advtrains_train_track/init.lua:342
+msgid "Loading Track"
+msgstr "装货轨道"
+
+#: advtrains_train_track/init.lua:406
+msgid "Detector Rail"
+msgstr "探测轨道"
+
+#: advtrains_train_industrial/init.lua:10
+#: advtrains_train_industrial/init.lua:49 advtrains_train_steam/init.lua:20
+#: advtrains_train_steam/init.lua:91
+msgid "Driver Stand (right)"
+msgstr "右侧司机座位"
+
+#: advtrains_train_industrial/init.lua:17
+#: advtrains_train_industrial/init.lua:56 advtrains_train_steam/init.lua:14
+#: advtrains_train_steam/init.lua:85
+msgid "Driver Stand (left)"
+msgstr "左侧司机座位"
+
+#: advtrains_train_industrial/init.lua:40
+msgid "Industrial Train Engine"
+msgstr "工业用火车头"
+
+#: advtrains_train_industrial/init.lua:79
+msgid "Big Industrial Train Engine"
+msgstr "大型工业用火车头"
+
+#: advtrains_train_industrial/init.lua:98
+msgid "Industrial tank wagon"
+msgstr "液体运输车厢"
+
+#: advtrains_train_industrial/init.lua:116
+msgid "Industrial wood wagon"
+msgstr "木材运输车厢"
+
+#: advtrains_train_japan/init.lua:4
+msgid "Japanese Train Inter-Wagon Connection"
+msgstr "日本火车车钩"
+
+#: advtrains_train_japan/init.lua:37
+msgid "Driver stand"
+msgstr "司机座位"
+
+#: advtrains_train_japan/init.lua:101
+msgid "Japanese Train Engine"
+msgstr "高速列车车头"
+
+#: advtrains_train_japan/init.lua:176
+msgid "Japanese Train Wagon"
+msgstr "高速列车车厢"
+
+#: advtrains_train_steam/init.lua:75
+msgid "Steam Engine"
+msgstr "蒸汽机车"
+
+#: advtrains_train_steam/init.lua:159
+msgid "Detailed Steam Engine"
+msgstr "精细的蒸汽机车"
+
+#: advtrains_train_steam/init.lua:206
+msgid "Passenger Wagon"
+msgstr "客车"
+
+#: advtrains_train_steam/init.lua:226
+msgid "Box Wagon"
+msgstr "货运车厢"
+
+#: advtrains_train_subway/init.lua:144
+msgid "Subway Passenger Wagon"
+msgstr "地铁车厢"
+
+#~ msgid "This position is protected!"
+#~ msgstr "这里已被保护。"
+
+#~ msgid "Can't place: protected position!"
+#~ msgstr "无法放置:此区域已被保护。"
+
+#~ msgid "Deprecated Track"
+#~ msgstr "请不要使用"
+
+#~ msgid "Can't get on: wagon full or doors closed!"
+#~ msgstr "无法上车:车门已关闭或车厢已满。"
+
+#~ msgid "Use Sneak+rightclick to bypass closed doors!"
+#~ msgstr "请使用潜行+右键上车。"
+
+#~ msgid "Access to @1"
+#~ msgstr "可前往@1"
+
+#~ msgid ""
+#~ "ATC controller, mode @1\n"
+#~ "Channel: @2"
+#~ msgstr ""
+#~ "ATC 控制器\n"
+#~ "模式:@1\n"
+#~ "频道:@2"
+
+#~ msgid "Lock couples"
+#~ msgstr "锁定连接处"
+
+#~ msgid ""
+#~ "You need to own at least one neighboring wagon to destroy this couple."
+#~ msgstr "您必须至少拥有其中一节车厢才能分开这两节车厢。"
+
+#~ msgid "Speed:"
+#~ msgstr "速度"
+
+#~ msgid "Target:"
+#~ msgstr "目标速度"
+
+#~ msgid "Default Seat"
+#~ msgstr "默认座位"
+
+#~ msgid "Default Seat (driver stand)"
+#~ msgstr "默认座位 (司机座位)"
diff --git a/advtrains/po/zh_TW.po b/advtrains/po/zh_TW.po
new file mode 100644
index 0000000..91a205f
--- /dev/null
+++ b/advtrains/po/zh_TW.po
@@ -0,0 +1,560 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: advtrains\n"
+"Report-Msgid-Bugs-To: advtrains-discuss@lists.sr.ht\n"
+"POT-Creation-Date: 2023-10-04 15:40+0200\n"
+"PO-Revision-Date: 2022-11-02 15:08+0100\n"
+"Last-Translator: Y. Wang <yw05@forksworld.de>\n"
+"Language-Team: Chinese (Traditional)\n"
+"Language: zh_TW\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: advtrains/atc.lua:109
+msgid "ATC controller, unconfigured."
+msgstr "ATC 控制器 (未配置)"
+
+#: advtrains/atc.lua:150
+msgid ""
+"ATC controller, mode @1\n"
+"Command: @2"
+msgstr ""
+"ATC 控制器\n"
+"模式:@1\n"
+"命令:@2"
+
+#: advtrains/atc.lua:180
+msgid "Command"
+msgstr "命令"
+
+#: advtrains/atc.lua:184
+msgid "Command (on)"
+msgstr "命令 (啟用時)"
+
+#: advtrains/atc.lua:187
+msgid "Digiline channel"
+msgstr "Digiline 頻道"
+
+#: advtrains/atc.lua:189 advtrains_line_automation/stoprail.lua:65
+msgid "Save"
+msgstr "儲存"
+
+#: advtrains/atc.lua:236
+msgid "ATC Reverse command warning: didn't reverse train, train moving!"
+msgstr "ATC 警告:未執行「R」命令,火車在移動"
+
+#: advtrains/atc.lua:248
+msgid "ATC Kick command warning: Doors closed"
+msgstr ""
+
+#: advtrains/atc.lua:252
+msgid "ATC Kick command warning: Train moving"
+msgstr ""
+
+#: advtrains/atc.lua:322
+msgid "ATC command syntax error: I statement not closed: @1"
+msgstr "ATC 語法錯誤:「I」命令不完整:@1"
+
+#: advtrains/atc.lua:385
+msgid "ATC command parse error: Unknown command: @1"
+msgstr "ATC 語法錯誤:未知命令:@1"
+
+#: advtrains/craft_items.lua:3
+msgid "Boiler"
+msgstr "鍋爐"
+
+#: advtrains/craft_items.lua:9
+msgid "driver's cab"
+msgstr "駕駛室"
+
+#: advtrains/craft_items.lua:15
+msgid "Wheel"
+msgstr "車輪"
+
+#: advtrains/craft_items.lua:21
+msgid "Chimney"
+msgstr "煙囪"
+
+#: advtrains/misc_nodes.lua:16
+msgid "@1 Platform (low)"
+msgstr "較低的@1月臺"
+
+#: advtrains/misc_nodes.lua:33
+msgid "@1 Platform (high)"
+msgstr "較高的@1月臺"
+
+#: advtrains/misc_nodes.lua:59
+msgid "@1 Platform (45 degree)"
+msgstr "較高的@1月臺 (45°)"
+
+#: advtrains/misc_nodes.lua:81
+msgid "@1 Platform (low, 45 degree)"
+msgstr "較低的@1月臺 (45°)"
+
+#: advtrains/trackplacer.lua:313
+msgid ""
+"Track Worker Tool\n"
+"\n"
+"Left-click: change rail type (straight/curve/switch)\n"
+"Right-click: rotate rail/bumper/signal/etc."
+msgstr ""
+"鐵路調整工具\n"
+"\n"
+"左鍵單擊:切換軌道型別\n"
+"右鍵單擊:旋轉方塊"
+
+#: advtrains/trackplacer.lua:340 advtrains/trackplacer.lua:377
+msgid "This node can't be rotated using the trackworker!"
+msgstr "您不能使用鐵路調整工具旋轉這個方塊。"
+
+#: advtrains/trackplacer.lua:350
+msgid "This track can not be rotated!"
+msgstr "您不能旋轉這段軌道。"
+
+#: advtrains/trackplacer.lua:404
+msgid "This node can't be changed using the trackworker!"
+msgstr "您不能使用鐵路調整工具調整這個方塊。"
+
+#: advtrains/trackplacer.lua:414
+msgid "This track can not be changed!"
+msgstr "您不能調整這段軌道。"
+
+#: advtrains/wagons.lua:179
+msgid "This wagon is owned by @1, you can't destroy it."
+msgstr "這是 @1 的車廂,您不能摧毀它。"
+
+#: advtrains/wagons.lua:203
+msgid "The wagon's inventory is not empty!"
+msgstr ""
+
+#: advtrains/wagons.lua:210
+msgid "Wagon needs to be decoupled from other wagons in order to destroy it."
+msgstr ""
+
+#: advtrains/wagons.lua:216
+msgid ""
+"Warning: If you destroy this wagon, you only get some steel back! If you are "
+"sure, hold Sneak and left-click the wagon."
+msgstr ""
+"警告:如果您摧毀此車廂,您只能拿到一些鋼方塊。如果您確定要摧毀這節車廂,請按"
+"潛行鍵並左鍵單擊此車廂。"
+
+#: advtrains/wagons.lua:649 advtrains/wagons.lua:850
+msgid "Show Inventory"
+msgstr "顯示物品欄"
+
+#: advtrains/wagons.lua:652
+msgid "Onboard Computer"
+msgstr ""
+
+#: advtrains/wagons.lua:655 advtrains/wagons.lua:1328
+msgid "Wagon properties"
+msgstr "車廂屬性"
+
+#: advtrains/wagons.lua:658
+msgid "Get off"
+msgstr "下車"
+
+#: advtrains/wagons.lua:661
+msgid "Get off (forced)"
+msgstr "強制下車"
+
+#: advtrains/wagons.lua:663
+msgid "(Doors closed)"
+msgstr "(車門已關閉)"
+
+#: advtrains/wagons.lua:712
+msgid "Can't get on: "
+msgstr ""
+
+#: advtrains/wagons.lua:838
+msgid "Select seat:"
+msgstr "請選擇座位"
+
+#: advtrains/wagons.lua:880
+msgid "Save wagon properties"
+msgstr "儲存車廂屬性"
+
+#: advtrains/wagons.lua:965
+msgid "Text displayed outside on train"
+msgstr "車廂外部顯示"
+
+#: advtrains/wagons.lua:966
+msgid "Text displayed inside train"
+msgstr "車廂內部顯示"
+
+#: advtrains/wagons.lua:967
+msgid "Line"
+msgstr "火車線路"
+
+#: advtrains/wagons.lua:968
+msgid "Routingcode"
+msgstr "路由碼"
+
+#: advtrains/wagons.lua:1241
+msgid ""
+"Doors are closed! Use Sneak+rightclick to ignore the closed doors and get "
+"off!"
+msgstr "車門已關閉,請使用潛行+右鍵單擊下車。"
+
+#: advtrains/trainhud.lua:305
+msgid "OVERRUN RED SIGNAL! Examine situation and reverse train to move again."
+msgstr ""
+
+#: advtrains/tracks.lua:449
+msgid "This track can not be removed!"
+msgstr "您不能移除這段軌道。"
+
+#: advtrains/tracks.lua:616
+msgid "Position is occupied by a train."
+msgstr ""
+
+#: advtrains/tracks.lua:622
+msgid "There's a Track Circuit Break here."
+msgstr ""
+
+#: advtrains/tracks.lua:626
+msgid "There's a Signal Influence Point here."
+msgstr ""
+
+#: advtrains/tracks.lua:637
+msgid "@1 Slope"
+msgstr "@1斜坡"
+
+#: advtrains/tracks.lua:648 advtrains/tracks.lua:653
+msgid "Can't place: not pointing at node"
+msgstr "無法放置:您沒有選擇任何方塊。"
+
+#: advtrains/tracks.lua:658
+msgid "Can't place: space occupied!"
+msgstr "無法放置:此區域已被佔用。"
+
+#: advtrains/tracks.lua:711
+msgid "Can't place: Not enough slope items left (@1 required)"
+msgstr "無法放置:您沒有足夠的鐵路斜坡放置工具 (您總共需要@1個)"
+
+#: advtrains/tracks.lua:714
+msgid "Can't place: There's no slope of length @1"
+msgstr "無法放置:advtrains 不支援長度為@1米的斜坡。"
+
+#: advtrains/tracks.lua:721
+msgid "Can't place: no supporting node at upper end."
+msgstr "無法放置:較高階沒有支撐方塊。"
+
+#: advtrains/signals.lua:63
+msgid "Lampless Signal"
+msgstr "臂木式號誌機"
+
+#: advtrains/signals.lua:127
+msgid "Signal"
+msgstr "色燈號誌機"
+
+#: advtrains/signals.lua:191
+msgid "Wallmounted Signal (l)"
+msgstr "壁掛式色燈號誌機 (左側)"
+
+#: advtrains/signals.lua:192
+msgid "Wallmounted Signal (r)"
+msgstr "壁掛式色燈號誌機 (右側)"
+
+#: advtrains/signals.lua:193
+msgid "Wallmounted Signal (t)"
+msgstr "懸掛式色燈號誌機"
+
+#: advtrains/signals.lua:281 advtrains/signals.lua:322
+msgid "Andrew's Cross"
+msgstr "平交道號誌燈"
+
+#: advtrains/couple.lua:28
+msgid "Buffer and Chain Coupler"
+msgstr "鏈式連結器"
+
+#: advtrains/couple.lua:29
+msgid "Scharfenberg Coupler"
+msgstr "Scharfenberg 式連結器"
+
+#: advtrains/couple.lua:185
+msgid ""
+"You are not allowed to couple trains without the train_operator privilege."
+msgstr "您沒有「train_operator」許可權,不能連結這兩節車廂。"
+
+#: advtrains/couple.lua:329 advtrains/couple.lua:333
+msgid "<none>"
+msgstr ""
+
+#: advtrains/couple.lua:334
+msgid "Can not couple: The couplers of the trains do not match (@1 and @2)."
+msgstr "您無法連結這兩節車廂:這兩節車廂使用不同的連結器 (@1和@2)。"
+
+#: advtrains/copytool.lua:8
+msgid ""
+"Train copy/paste tool\n"
+"\n"
+"Left-click: copy train\n"
+"Right-click: paste train"
+msgstr ""
+"火車複製工具\n"
+"\n"
+"左鍵單擊:複製\n"
+"右鍵單擊:粘帖"
+
+#: advtrains/copytool.lua:29
+msgid "You do not have the @1 privilege."
+msgstr "您沒有「@1」許可權。"
+
+#: advtrains/copytool.lua:41
+msgid "The track you are trying to place the wagon on is not long enough!"
+msgstr "軌道太短。"
+
+#: advtrains/copytool.lua:47
+msgid "The clipboard couldn't access the metadata. Paste failed."
+msgstr "無法貼上:剪貼簿無法訪問元資料。"
+
+#: advtrains/copytool.lua:52 advtrains/copytool.lua:57
+msgid "The clipboard is empty."
+msgstr "剪貼簿是空的。"
+
+#: advtrains/copytool.lua:74
+msgid "Back of train would end up off track, cancelling."
+msgstr "火車後部不在軌道上。"
+
+#: advtrains/copytool.lua:92
+msgid "No such lua entity!"
+msgstr "您沒有指向一個可以用火車複製工具複製的物體。"
+
+#: advtrains/copytool.lua:98
+msgid "No such wagon: @1"
+msgstr "ID 為「@1」的車廂不存在。"
+
+#: advtrains/copytool.lua:104
+msgid "No such train: @1"
+msgstr "ID 為「@1」的列車不存在。"
+
+#: advtrains/copytool.lua:176
+msgid "The clipboard couldn't access the metadata. Copy failed."
+msgstr "無法複製:剪貼簿無法訪問元資料。"
+
+#: advtrains/copytool.lua:180
+msgid "Train copied!"
+msgstr "已複製"
+
+#: advtrains/protection.lua:148
+msgid ""
+"You are not allowed to build near tracks without the track_builder privilege."
+msgstr "您沒有「train_operator」許可權,不能在鐵路附近建任何東西。"
+
+#: advtrains/protection.lua:148
+msgid ""
+"You are not allowed to build tracks without the track_builder privilege."
+msgstr "您沒有「train_operator」許可權,不能在這裡建造鐵路。"
+
+#: advtrains/protection.lua:153
+msgid "You are not allowed to build near tracks at this protected position."
+msgstr "這裡已被保護,您不能在這裡的鐵路附近建任何東西。"
+
+#: advtrains/protection.lua:153
+msgid "You are not allowed to build tracks at this protected position."
+msgstr "這裡已被保護,您不能在這裡建造鐵路。"
+
+#: advtrains/protection.lua:184
+msgid ""
+"You are not allowed to operate turnouts and signals without the "
+"railway_operator privilege."
+msgstr "您沒有「railway_operator」許可權,不能控制鐵路設施。"
+
+#: advtrains_line_automation/stoprail.lua:54
+msgid "Station Code"
+msgstr "車站碼"
+
+#: advtrains_line_automation/stoprail.lua:55
+msgid "Station Name"
+msgstr "車站名稱"
+
+#: advtrains_line_automation/stoprail.lua:56
+msgid "Door Delay"
+msgstr "車門關閉時間"
+
+#: advtrains_line_automation/stoprail.lua:57
+msgid "Dep. Speed"
+msgstr "出發速度"
+
+#: advtrains_line_automation/stoprail.lua:58 advtrains_train_track/init.lua:11
+#: advtrains_train_track/init.lua:156
+msgid "Track"
+msgstr "軌道"
+
+#: advtrains_line_automation/stoprail.lua:59
+msgid "Stop Time"
+msgstr "停站時間"
+
+#: advtrains_line_automation/stoprail.lua:60
+msgid "Door Side"
+msgstr ""
+
+#: advtrains_line_automation/stoprail.lua:62
+msgid "Reverse train"
+msgstr ""
+
+#: advtrains_line_automation/stoprail.lua:63
+msgid "Kick out passengers"
+msgstr ""
+
+#: advtrains_luaautomation/pcnaming.lua:26
+msgid ""
+"Passive Component Naming Tool\n"
+"\n"
+"Right-click to name a passive component."
+msgstr ""
+"被動元件命名工具\n"
+"\n"
+"右鍵單擊命名所選元件"
+
+#: advtrains_train_track/init.lua:31
+msgid "Y-turnout"
+msgstr "對稱道岔"
+
+#: advtrains_train_track/init.lua:49
+msgid "3-way turnout"
+msgstr "三開道岔"
+
+#: advtrains_train_track/init.lua:69
+msgid "Perpendicular Diamond Crossing Track"
+msgstr "垂直交叉軌道"
+
+#: advtrains_train_track/init.lua:91
+msgid "90+Angle Diamond Crossing Track"
+msgstr "交叉軌道 (其中一條軌道與座標軸平行)"
+
+#: advtrains_train_track/init.lua:132
+msgid "Diagonal Diamond Crossing Track"
+msgstr "交叉軌道"
+
+#: advtrains_train_track/init.lua:179
+msgid "Bumper"
+msgstr "保險槓"
+
+#: advtrains_train_track/init.lua:201
+msgid "ATC controller"
+msgstr "ATC 控制器"
+
+#: advtrains_train_track/init.lua:317
+msgid "Unloading Track"
+msgstr "卸貨軌道"
+
+#: advtrains_train_track/init.lua:342
+msgid "Loading Track"
+msgstr "裝貨軌道"
+
+#: advtrains_train_track/init.lua:406
+msgid "Detector Rail"
+msgstr "探測軌道"
+
+#: advtrains_train_industrial/init.lua:10
+#: advtrains_train_industrial/init.lua:49 advtrains_train_steam/init.lua:20
+#: advtrains_train_steam/init.lua:91
+msgid "Driver Stand (right)"
+msgstr "右側司機座位"
+
+#: advtrains_train_industrial/init.lua:17
+#: advtrains_train_industrial/init.lua:56 advtrains_train_steam/init.lua:14
+#: advtrains_train_steam/init.lua:85
+msgid "Driver Stand (left)"
+msgstr "左側司機座位"
+
+#: advtrains_train_industrial/init.lua:40
+msgid "Industrial Train Engine"
+msgstr "工業用火車頭"
+
+#: advtrains_train_industrial/init.lua:79
+msgid "Big Industrial Train Engine"
+msgstr "大型工業用火車頭"
+
+#: advtrains_train_industrial/init.lua:98
+msgid "Industrial tank wagon"
+msgstr "液體運輸車廂"
+
+#: advtrains_train_industrial/init.lua:116
+msgid "Industrial wood wagon"
+msgstr "木材運輸車廂"
+
+#: advtrains_train_japan/init.lua:4
+msgid "Japanese Train Inter-Wagon Connection"
+msgstr "日本火車連結器"
+
+#: advtrains_train_japan/init.lua:37
+msgid "Driver stand"
+msgstr "司機座位"
+
+#: advtrains_train_japan/init.lua:101
+msgid "Japanese Train Engine"
+msgstr "高速列車車頭"
+
+#: advtrains_train_japan/init.lua:176
+msgid "Japanese Train Wagon"
+msgstr "高速列車車廂"
+
+#: advtrains_train_steam/init.lua:75
+msgid "Steam Engine"
+msgstr "蒸汽機車"
+
+#: advtrains_train_steam/init.lua:159
+msgid "Detailed Steam Engine"
+msgstr "精細的蒸汽機車"
+
+#: advtrains_train_steam/init.lua:206
+msgid "Passenger Wagon"
+msgstr "客車"
+
+#: advtrains_train_steam/init.lua:226
+msgid "Box Wagon"
+msgstr "貨運車廂"
+
+#: advtrains_train_subway/init.lua:144
+msgid "Subway Passenger Wagon"
+msgstr "地鐵車廂"
+
+#~ msgid "This position is protected!"
+#~ msgstr "這裡已被保護。"
+
+#~ msgid "Can't place: protected position!"
+#~ msgstr "無法放置:此區域已被保護。"
+
+#~ msgid "Deprecated Track"
+#~ msgstr "請不要使用"
+
+#~ msgid "Can't get on: wagon full or doors closed!"
+#~ msgstr "無法上車:車門已關閉或車廂已滿。"
+
+#~ msgid "Use Sneak+rightclick to bypass closed doors!"
+#~ msgstr "請使用潛行+右鍵上車。"
+
+#~ msgid "Access to @1"
+#~ msgstr "可前往@1"
+
+#~ msgid ""
+#~ "ATC controller, mode @1\n"
+#~ "Channel: @2"
+#~ msgstr ""
+#~ "ATC 控制器\n"
+#~ "模式:@1\n"
+#~ "頻道:@2"
+
+#~ msgid "Lock couples"
+#~ msgstr "鎖定連結處"
+
+#~ msgid ""
+#~ "You need to own at least one neighboring wagon to destroy this couple."
+#~ msgstr "您必須至少擁有其中一節車廂才能分開這兩節車廂。"
+
+#~ msgid "Speed:"
+#~ msgstr "速度"
+
+#~ msgid "Target:"
+#~ msgstr "目標速度"
+
+#~ msgid "Default Seat"
+#~ msgstr "預設座位"
+
+#~ msgid "Default Seat (driver stand)"
+#~ msgstr "預設座位 (司機座位)"
diff --git a/advtrains/protection.lua b/advtrains/protection.lua
index 7474977..89e15eb 100644
--- a/advtrains/protection.lua
+++ b/advtrains/protection.lua
@@ -145,12 +145,12 @@ function advtrains.check_track_protection(pos, pname, near, prot_p)
--atdebug("CTP: ",pos,pname,near,prot_p,"priv=",priv,"prot=",prot,"dprot=",dprot)
if not priv and (not boo or prot or not dprot) then
- minetest.chat_send_player(pname, "You are not allowed to build "..nears.."tracks without track_builder privilege")
+ minetest.chat_send_player(pname, near and attrans("You are not allowed to build near tracks without the track_builder privilege.") or attrans("You are not allowed to build tracks without the track_builder privilege."))
minetest.log("action", pname.." tried to modify terrain "..nears.."track at "..minetest.pos_to_string(apos).." but is not permitted to (no privilege)")
return false
end
if prot then
- minetest.chat_send_player(pname, "You are not allowed to build "..nears.."tracks at protected position!")
+ minetest.chat_send_player(pname, near and attrans("You are not allowed to build near tracks at this protected position.") or attrans("You are not allowed to build tracks at this protected position."))
minetest.record_protection_violation(pos, pname)
minetest.log("action", pname.." tried to modify "..nears.."track at "..minetest.pos_to_string(apos).." but position is protected!")
return false
@@ -181,7 +181,7 @@ function advtrains.check_turnout_signal_protection(pos, pname)
nocheck=false
return true
else
- minetest.chat_send_player(pname, "You are not allowed to operate turnouts and signals (missing railway_operator privilege)")
+ minetest.chat_send_player(pname, attrans("You are not allowed to operate turnouts and signals without the railway_operator privilege."))
minetest.log("action", pname.." tried to operate turnout/signal at "..minetest.pos_to_string(pos).." but does not have railway_operator")
nocheck=false
return false
diff --git a/advtrains/signals.lua b/advtrains/signals.lua
index b26c950..74841d3 100644
--- a/advtrains/signals.lua
+++ b/advtrains/signals.lua
@@ -60,7 +60,7 @@ for r,f in pairs({on={as="off", ls="green", als="red"}, off={as="on", ls="red",
tiles = {"advtrains_retrosignal.png"},
inventory_image="advtrains_retrosignal_inv.png",
drop="advtrains:retrosignal_off",
- description=attrans("Lampless Signal (@1)", attrans(r..rotation)),
+ description=attrans("Lampless Signal"),
sunlight_propagates=true,
groups = {
cracky=3,
@@ -124,7 +124,7 @@ for r,f in pairs({on={as="off", ls="green", als="red"}, off={as="on", ls="red",
tiles = {"advtrains_signal_"..r..".png"},
inventory_image="advtrains_signal_inv.png",
drop="advtrains:signal_off",
- description=attrans("Signal (@1)", attrans(r..rotation)),
+ description=attrans("Signal"),
groups = {
cracky=3,
not_blocking_trains=1,
@@ -187,6 +187,11 @@ for r,f in pairs({on={as="off", ls="green", als="red"}, off={as="on", ls="red",
if r=="off" then crea=0 end
--tunnel signals. no rotations.
+ local swdesc = { -- needed for xgettext
+ l = attrans("Wallmounted Signal (l)"),
+ r = attrans("Wallmounted Signal (r)"),
+ t = attrans("Wallmounted Signal (t)"),
+ }
for loc, sbox in pairs({l={-1/2, -1/2, -1/4, 0, 1/2, 1/4}, r={0, -1/2, -1/4, 1/2, 1/2, 1/4}, t={-1/2, 0, -1/4, 1/2, 1/2, 1/4}}) do
minetest.register_node("advtrains:signal_wall_"..loc.."_"..r, {
drawtype = "mesh",
@@ -200,7 +205,7 @@ for r,f in pairs({on={as="off", ls="green", als="red"}, off={as="on", ls="red",
mesh = "advtrains_signal_wall_"..loc..".b3d",
tiles = {"advtrains_signal_wall_"..r..".png"},
drop="advtrains:signal_wall_"..loc.."_off",
- description=attrans("Wallmounted Signal ("..loc..")"),
+ description=swdesc[loc],
groups = {
cracky=3,
not_blocking_trains=1,
@@ -314,7 +319,7 @@ minetest.register_node("advtrains:across_on", {
mesh = "advtrains_across.obj",
tiles = {{name="advtrains_across_anim.png", animation={type="vertical_frames", aspect_w=64, aspect_h=64, length=1.0}}},
drop="advtrains:across_off",
- description=attrans("Andrew's Cross (on) (you hacker you)"),
+ description=attrans("Andrew's Cross"),
groups = {
cracky=3,
not_blocking_trains=1,