commit
b17a4391b0
|
@ -189,12 +189,12 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
|||
set(NORMAL_CXX_FLAGS "/wd\"4244\" /wd\"4309\" /wd\"4800\" /wd\"4996\" /wd\"4351\" /EHsc") # disable some useless warnings
|
||||
if(MSVC_STATIC)
|
||||
set(RELEASE_CXX_FLAGS "/MT /Ox")
|
||||
set(DEBUG_CXX_FLAGS "/MTd /ZI")
|
||||
set(DEBUG_CXX_FLAGS "/MTd /Od /ZI")
|
||||
else(MSVC_STATIC)
|
||||
set(RELEASE_CXX_FLAGS "/MD /Ox")
|
||||
set(DEBUG_CXX_FLAGS "/MDd /ZI")
|
||||
set(DEBUG_CXX_FLAGS "/MDd /Od /ZI")
|
||||
endif()
|
||||
set(TEST_CXX_FLAGS "")
|
||||
set(TEST_CXX_FLAGS "${DEBUG_CXX_FLAGS}")
|
||||
add_definitions(-DNOEXCEPT= -DHAS_MSVC_EXCEPTION_BUG)
|
||||
|
||||
# Needed for Debug information (it's set to "No" by default for some reason)
|
||||
|
|
2
data
2
data
|
@ -1 +1 @@
|
|||
Subproject commit 611cbfdd079e97a71f97810636f2ab2358cb4eeb
|
||||
Subproject commit 069fc5bd15b87aaf5b1b301a787f05a99dfc3856
|
|
@ -84,6 +84,9 @@ msgstr ""
|
|||
msgid "Load a saved mission"
|
||||
msgstr ""
|
||||
|
||||
msgid "Mods"
|
||||
msgstr ""
|
||||
|
||||
msgid "Chapters:"
|
||||
msgstr ""
|
||||
|
||||
|
@ -166,6 +169,23 @@ msgstr ""
|
|||
msgid "This menu is for userlevels from mods, but you didn't install any"
|
||||
msgstr ""
|
||||
|
||||
msgid "Could not open the file explorer!"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "The path %s could not be opened in a file explorer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Could not open the web browser!"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "The address %s could not be opened in a web browser."
|
||||
msgstr ""
|
||||
|
||||
msgid "There are unsaved changes. Do you want to save them before leaving?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Keyword help(\\key cbot;)"
|
||||
msgstr ""
|
||||
|
||||
|
@ -280,6 +300,42 @@ msgstr ""
|
|||
msgid "%s: %d pts"
|
||||
msgstr ""
|
||||
|
||||
msgid "Mods:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Information:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Description:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable\\Enable the selected mod"
|
||||
msgstr ""
|
||||
|
||||
msgid "Disable\\Disable the selected mod"
|
||||
msgstr ""
|
||||
|
||||
msgid "Unknown author"
|
||||
msgstr ""
|
||||
|
||||
msgid "by"
|
||||
msgstr ""
|
||||
|
||||
msgid "Version"
|
||||
msgstr ""
|
||||
|
||||
msgid "Website"
|
||||
msgstr ""
|
||||
|
||||
msgid "Changes"
|
||||
msgstr ""
|
||||
|
||||
msgid "No description."
|
||||
msgstr ""
|
||||
|
||||
msgid "No changes."
|
||||
msgstr ""
|
||||
|
||||
msgid "Code battle"
|
||||
msgstr ""
|
||||
|
||||
|
@ -316,6 +372,9 @@ msgstr ""
|
|||
msgid "SatCom"
|
||||
msgstr ""
|
||||
|
||||
msgid "Mods\\Mod manager"
|
||||
msgstr ""
|
||||
|
||||
msgid "Change player\\Change player"
|
||||
msgstr ""
|
||||
|
||||
|
@ -343,6 +402,24 @@ msgstr ""
|
|||
msgid "Play\\Start mission!"
|
||||
msgstr ""
|
||||
|
||||
msgid "Workshop\\Open the workshop to search for mods"
|
||||
msgstr ""
|
||||
|
||||
msgid "Open Directory\\Open the mods directory"
|
||||
msgstr ""
|
||||
|
||||
msgid "Apply\\Apply the current mod configuration"
|
||||
msgstr ""
|
||||
|
||||
msgid "Up\\Move the selected mod up so it's loaded sooner (mods may overwrite files from the mods above them)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Down\\Move the selected mod down so it's loaded later (mods may overwrite files from the mods above them)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Refresh\\Refresh the list of currently installed mods"
|
||||
msgstr ""
|
||||
|
||||
msgid "Device\\Driver and resolution settings"
|
||||
msgstr ""
|
||||
|
||||
|
|
77
po/cs.po
77
po/cs.po
|
@ -125,6 +125,9 @@ msgstr "Vzhled\\Upravte svůj vzhled"
|
|||
msgid "Apply changes\\Activates the changed settings"
|
||||
msgstr "Uložit změny\\Aktivovat změny nastavení"
|
||||
|
||||
msgid "Apply\\Apply the current mod configuration"
|
||||
msgstr ""
|
||||
|
||||
msgid "Appropriate constructor missing"
|
||||
msgstr "Chybí vhodný konstruktor"
|
||||
|
||||
|
@ -371,6 +374,9 @@ msgstr "Změnit kameru\\Přepíná mezi kamerou na robotu a za robotem"
|
|||
msgid "Change player\\Change player"
|
||||
msgstr "Změnit hráče\\Změnit hráče"
|
||||
|
||||
msgid "Changes"
|
||||
msgstr ""
|
||||
|
||||
msgid "Chapters:"
|
||||
msgstr "Kapitoly:"
|
||||
|
||||
|
@ -440,6 +446,12 @@ msgstr "Kopírovat"
|
|||
msgid "Copy (Ctrl+C)"
|
||||
msgstr "Kopírovat (Ctrl+C)"
|
||||
|
||||
msgid "Could not open the file explorer!"
|
||||
msgstr ""
|
||||
|
||||
msgid "Could not open the web browser!"
|
||||
msgstr ""
|
||||
|
||||
msgid "Current mission saved"
|
||||
msgstr "Současná mise uložena"
|
||||
|
||||
|
@ -473,6 +485,9 @@ msgstr "Vrtná věž"
|
|||
msgid "Descend\\Reduces the power of the jet"
|
||||
msgstr "Klesat\\Snížit tah tryskového motoru"
|
||||
|
||||
msgid "Description:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Destroy"
|
||||
msgstr "Zbourat"
|
||||
|
||||
|
@ -485,6 +500,9 @@ msgstr "Drtič"
|
|||
msgid "Device\\Driver and resolution settings"
|
||||
msgstr "Obrazovka\\Nastavení grafické karty a rozlišení"
|
||||
|
||||
msgid "Disable\\Disable the selected mod"
|
||||
msgstr ""
|
||||
|
||||
msgid "Dividing by zero"
|
||||
msgstr "Dělení nulou"
|
||||
|
||||
|
@ -501,6 +519,9 @@ msgstr "Dveře blokuje robot nebo jiný objekt"
|
|||
msgid "Down (\\key gdown;)"
|
||||
msgstr "Dolů (\\key gdown;)"
|
||||
|
||||
msgid "Down\\Move the selected mod down so it's loaded later (mods may overwrite files from the mods above them)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Drawer bot"
|
||||
msgstr "Tužkobot"
|
||||
|
||||
|
@ -528,6 +549,9 @@ msgstr "Vejce"
|
|||
msgid "Empty character constant"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable\\Enable the selected mod"
|
||||
msgstr ""
|
||||
|
||||
msgid "End of block missing"
|
||||
msgstr "Chybí konec bloku"
|
||||
|
||||
|
@ -754,6 +778,9 @@ msgstr "Infikováno virem; dočasně mimo provoz"
|
|||
msgid "Information exchange post"
|
||||
msgstr "Komunikační stanice"
|
||||
|
||||
msgid "Information:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Instruction \"break\" outside a loop"
|
||||
msgstr "Příkaz \"break\" mimo cyklus"
|
||||
|
||||
|
@ -904,6 +931,15 @@ msgstr "Mise na této planetě:"
|
|||
msgid "Missions\\Select mission"
|
||||
msgstr "Mise\\Vyberte misi"
|
||||
|
||||
msgid "Mods"
|
||||
msgstr ""
|
||||
|
||||
msgid "Mods:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Mods\\Mod manager"
|
||||
msgstr ""
|
||||
|
||||
msgid "Mouse inversion X\\Inversion of the scrolling direction on the X axis"
|
||||
msgstr "Vodorovné převrácení posunu\\Při vodorovném posunu kamery myší pousouvat opačným směrem"
|
||||
|
||||
|
@ -952,6 +988,12 @@ msgstr "Další objekt\\Vybere následující objekt"
|
|||
msgid "No"
|
||||
msgstr "Ne"
|
||||
|
||||
msgid "No changes."
|
||||
msgstr ""
|
||||
|
||||
msgid "No description."
|
||||
msgstr ""
|
||||
|
||||
msgid "No energy in the subsoil"
|
||||
msgstr "Pod povrchem není zdroj energie"
|
||||
|
||||
|
@ -1072,6 +1114,9 @@ msgstr "Otevřít"
|
|||
msgid "Open (Ctrl+O)"
|
||||
msgstr "Otevřít (Ctrl+O)"
|
||||
|
||||
msgid "Open Directory\\Open the mods directory"
|
||||
msgstr ""
|
||||
|
||||
msgid "Opening brace missing"
|
||||
msgstr "Chybí levá složená závorka"
|
||||
|
||||
|
@ -1282,6 +1327,9 @@ msgstr "Červená vlajka"
|
|||
msgid "Reflections on the buttons \\Shiny buttons"
|
||||
msgstr "Odlesky na tlačítkách\\Blyštivá tlačítka"
|
||||
|
||||
msgid "Refresh\\Refresh the list of currently installed mods"
|
||||
msgstr ""
|
||||
|
||||
msgid "Remains of Apollo mission"
|
||||
msgstr "Pozůstatky mise Apollo"
|
||||
|
||||
|
@ -1543,6 +1591,10 @@ msgstr "Filtrování textur\\Filtrování textur"
|
|||
msgid "Textures"
|
||||
msgstr "Textury"
|
||||
|
||||
#, c-format
|
||||
msgid "The address %s could not be opened in a web browser."
|
||||
msgstr ""
|
||||
|
||||
msgid "The battle has ended"
|
||||
msgstr "Souboj skončil"
|
||||
|
||||
|
@ -1555,9 +1607,16 @@ msgstr "Funkce nevrátila žádnou hodnotu"
|
|||
msgid "The mission is not accomplished yet (press \\key help; for more details)"
|
||||
msgstr "Mise ještě nebyla splněna (pro podrobnosti stiskněte \\key help;)"
|
||||
|
||||
#, c-format
|
||||
msgid "The path %s could not be opened in a file explorer."
|
||||
msgstr ""
|
||||
|
||||
msgid "The types of the two operands are incompatible"
|
||||
msgstr "Operaci nelze provést s operandy těchto dvou typů"
|
||||
|
||||
msgid "There are unsaved changes. Do you want to save them before leaving?"
|
||||
msgstr ""
|
||||
|
||||
msgid "This class already exists"
|
||||
msgstr "Tato třída již existuje"
|
||||
|
||||
|
@ -1682,6 +1741,9 @@ msgstr "Jednotka"
|
|||
msgid "Unknown Object"
|
||||
msgstr "Neznámý objekt"
|
||||
|
||||
msgid "Unknown author"
|
||||
msgstr ""
|
||||
|
||||
msgid "Unknown command"
|
||||
msgstr "Neznámý příkaz"
|
||||
|
||||
|
@ -1694,6 +1756,9 @@ msgstr "Neznámá funkce"
|
|||
msgid "Up (\\key gup;)"
|
||||
msgstr "Vzhůru (\\key gup;)"
|
||||
|
||||
msgid "Up\\Move the selected mod up so it's loaded sooner (mods may overwrite files from the mods above them)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Uranium deposit (site for derrick)"
|
||||
msgstr "Uranové ložisko (místo pro vrtnou věž)"
|
||||
|
||||
|
@ -1715,6 +1780,9 @@ msgstr "Proměnná nebyla nastavena"
|
|||
msgid "Vault"
|
||||
msgstr "Trezor"
|
||||
|
||||
msgid "Version"
|
||||
msgstr ""
|
||||
|
||||
msgid "Vertical Synchronization\\Limits the number of frames per second to display frequency"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1733,6 +1801,9 @@ msgstr "Vosa byla smrtelně raněna"
|
|||
msgid "Waste"
|
||||
msgstr "Odpad"
|
||||
|
||||
msgid "Website"
|
||||
msgstr ""
|
||||
|
||||
msgid "Wheeled builder"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1766,6 +1837,9 @@ msgstr "Létající detektor"
|
|||
msgid "Withdraw shield (\\key action;)"
|
||||
msgstr "Vypnout štít (\\key action;)"
|
||||
|
||||
msgid "Workshop\\Open the workshop to search for mods"
|
||||
msgstr ""
|
||||
|
||||
msgid "Worm"
|
||||
msgstr "Červ"
|
||||
|
||||
|
@ -1916,6 +1990,9 @@ msgstr "\\Fialové vlajky"
|
|||
msgid "\\Yellow flags"
|
||||
msgstr "\\Žluté vlajky"
|
||||
|
||||
msgid "by"
|
||||
msgstr ""
|
||||
|
||||
msgid "colobot.info"
|
||||
msgstr "colobot.info"
|
||||
|
||||
|
|
77
po/de.po
77
po/de.po
|
@ -126,6 +126,9 @@ msgstr "Aussehen\\Erscheinungsbild des Astronauten einstellen"
|
|||
msgid "Apply changes\\Activates the changed settings"
|
||||
msgstr "Änderungen anwenden\\Getätigte Einstellungen anwenden"
|
||||
|
||||
msgid "Apply\\Apply the current mod configuration"
|
||||
msgstr ""
|
||||
|
||||
msgid "Appropriate constructor missing"
|
||||
msgstr "Es gibt keinen geeigneten Konstruktor"
|
||||
|
||||
|
@ -372,6 +375,9 @@ msgstr "Andere Kamera\\Sichtpunkt einstellen"
|
|||
msgid "Change player\\Change player"
|
||||
msgstr "Anderer Spieler\\Spielername ändern"
|
||||
|
||||
msgid "Changes"
|
||||
msgstr ""
|
||||
|
||||
msgid "Chapters:"
|
||||
msgstr "Liste der Kapitel:"
|
||||
|
||||
|
@ -441,6 +447,12 @@ msgstr "Kopieren"
|
|||
msgid "Copy (Ctrl+C)"
|
||||
msgstr "Kopieren (Ctrl+C)"
|
||||
|
||||
msgid "Could not open the file explorer!"
|
||||
msgstr ""
|
||||
|
||||
msgid "Could not open the web browser!"
|
||||
msgstr ""
|
||||
|
||||
msgid "Current mission saved"
|
||||
msgstr "Mission gespeichert"
|
||||
|
||||
|
@ -474,6 +486,9 @@ msgstr "Bohrturm"
|
|||
msgid "Descend\\Reduces the power of the jet"
|
||||
msgstr "Sinken\\Leistung des Triebwerks drosseln"
|
||||
|
||||
msgid "Description:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Destroy"
|
||||
msgstr "Zerstören"
|
||||
|
||||
|
@ -486,6 +501,9 @@ msgstr "Einstampfer"
|
|||
msgid "Device\\Driver and resolution settings"
|
||||
msgstr "Bildschirm\\Driver und Bildschirmauflösung"
|
||||
|
||||
msgid "Disable\\Disable the selected mod"
|
||||
msgstr ""
|
||||
|
||||
msgid "Dividing by zero"
|
||||
msgstr "Division durch Null"
|
||||
|
||||
|
@ -502,6 +520,9 @@ msgstr "Die Türen werden von einem Gegenstand blockiert"
|
|||
msgid "Down (\\key gdown;)"
|
||||
msgstr "Sinkt (\\key gdown;)"
|
||||
|
||||
msgid "Down\\Move the selected mod down so it's loaded later (mods may overwrite files from the mods above them)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Drawer bot"
|
||||
msgstr "Zeichner"
|
||||
|
||||
|
@ -529,6 +550,9 @@ msgstr "Ei"
|
|||
msgid "Empty character constant"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable\\Enable the selected mod"
|
||||
msgstr ""
|
||||
|
||||
msgid "End of block missing"
|
||||
msgstr "Es fehlt eine geschlossene geschweifte Klammer \"}\" (Ende des Blocks)"
|
||||
|
||||
|
@ -756,6 +780,9 @@ msgstr "Von Virus infiziert, zeitweise außer Betrieb"
|
|||
msgid "Information exchange post"
|
||||
msgstr "Infoserver"
|
||||
|
||||
msgid "Information:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Instruction \"break\" outside a loop"
|
||||
msgstr "Anweisung \"break\" außerhalb einer Schleife"
|
||||
|
||||
|
@ -920,6 +947,15 @@ msgstr "Liste der Missionen des Planeten:"
|
|||
msgid "Missions\\Select mission"
|
||||
msgstr "Missionen\\Aufbruch ins Weltall"
|
||||
|
||||
msgid "Mods"
|
||||
msgstr ""
|
||||
|
||||
msgid "Mods:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Mods\\Mod manager"
|
||||
msgstr ""
|
||||
|
||||
msgid "Mouse inversion X\\Inversion of the scrolling direction on the X axis"
|
||||
msgstr "Umkehr X\\Umkehr der Kameradrehung X-Achse"
|
||||
|
||||
|
@ -968,6 +1004,12 @@ msgstr "Nächstes auswählen\\Nächstes Objekt auswählen"
|
|||
msgid "No"
|
||||
msgstr "Nein"
|
||||
|
||||
msgid "No changes."
|
||||
msgstr ""
|
||||
|
||||
msgid "No description."
|
||||
msgstr ""
|
||||
|
||||
msgid "No energy in the subsoil"
|
||||
msgstr "Kein unterirdisches Energievorkommen"
|
||||
|
||||
|
@ -1088,6 +1130,9 @@ msgstr "Öffnen"
|
|||
msgid "Open (Ctrl+O)"
|
||||
msgstr "Öffnen (Ctrl+O)"
|
||||
|
||||
msgid "Open Directory\\Open the mods directory"
|
||||
msgstr ""
|
||||
|
||||
msgid "Opening brace missing"
|
||||
msgstr "Es fehlt eine offene geschweifte Klammer\"{\""
|
||||
|
||||
|
@ -1299,6 +1344,9 @@ msgstr "Rote Fahne"
|
|||
msgid "Reflections on the buttons \\Shiny buttons"
|
||||
msgstr "Glänzende Tasten\\Glänzende Tasten in den Menüs"
|
||||
|
||||
msgid "Refresh\\Refresh the list of currently installed mods"
|
||||
msgstr ""
|
||||
|
||||
msgid "Remains of Apollo mission"
|
||||
msgstr "Überreste einer Apollo-Mission"
|
||||
|
||||
|
@ -1560,6 +1608,10 @@ msgstr "Texturfilterung\\Texturfilterung"
|
|||
msgid "Textures"
|
||||
msgstr "Texturen"
|
||||
|
||||
#, c-format
|
||||
msgid "The address %s could not be opened in a web browser."
|
||||
msgstr ""
|
||||
|
||||
msgid "The battle has ended"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1572,9 +1624,16 @@ msgstr "Die Funktion hat kein Ergebnis zurückgegeben"
|
|||
msgid "The mission is not accomplished yet (press \\key help; for more details)"
|
||||
msgstr "Mission noch nicht beendet (Drücken Sie auf \\key help; für weitere Informationen)"
|
||||
|
||||
#, c-format
|
||||
msgid "The path %s could not be opened in a file explorer."
|
||||
msgstr ""
|
||||
|
||||
msgid "The types of the two operands are incompatible"
|
||||
msgstr "Die zwei Operanden sind nicht kompatibel"
|
||||
|
||||
msgid "There are unsaved changes. Do you want to save them before leaving?"
|
||||
msgstr ""
|
||||
|
||||
msgid "This class already exists"
|
||||
msgstr "Diese Klasse gibt es schon"
|
||||
|
||||
|
@ -1699,6 +1758,9 @@ msgstr "Einheit"
|
|||
msgid "Unknown Object"
|
||||
msgstr "Das Objekt existiert nicht"
|
||||
|
||||
msgid "Unknown author"
|
||||
msgstr ""
|
||||
|
||||
msgid "Unknown command"
|
||||
msgstr "Befehl unbekannt"
|
||||
|
||||
|
@ -1711,6 +1773,9 @@ msgstr "Unbekannte Funktion"
|
|||
msgid "Up (\\key gup;)"
|
||||
msgstr "Steigt (\\key gup;)"
|
||||
|
||||
msgid "Up\\Move the selected mod up so it's loaded sooner (mods may overwrite files from the mods above them)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Uranium deposit (site for derrick)"
|
||||
msgstr "Markierung für unterirdisches Platinvorkommen"
|
||||
|
||||
|
@ -1732,6 +1797,9 @@ msgstr "Der Wert dieser Variable wurde nicht definiert"
|
|||
msgid "Vault"
|
||||
msgstr "Bunker"
|
||||
|
||||
msgid "Version"
|
||||
msgstr ""
|
||||
|
||||
msgid "Vertical Synchronization\\Limits the number of frames per second to display frequency"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1750,6 +1818,9 @@ msgstr "Wespe tödlich verwundet"
|
|||
msgid "Waste"
|
||||
msgstr "Abfall"
|
||||
|
||||
msgid "Website"
|
||||
msgstr ""
|
||||
|
||||
msgid "Wheeled builder"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1783,6 +1854,9 @@ msgstr "Schnüffler"
|
|||
msgid "Withdraw shield (\\key action;)"
|
||||
msgstr "Schutzschild einholen (\\key action;)"
|
||||
|
||||
msgid "Workshop\\Open the workshop to search for mods"
|
||||
msgstr ""
|
||||
|
||||
msgid "Worm"
|
||||
msgstr "Wurm"
|
||||
|
||||
|
@ -1931,6 +2005,9 @@ msgstr "\\Violette Fahne"
|
|||
msgid "\\Yellow flags"
|
||||
msgstr "\\Gelbe Fahne"
|
||||
|
||||
msgid "by"
|
||||
msgstr ""
|
||||
|
||||
msgid "colobot.info"
|
||||
msgstr "colobot.info"
|
||||
|
||||
|
|
77
po/fr.po
77
po/fr.po
|
@ -125,6 +125,9 @@ msgstr "Aspect\\Choisir votre aspect"
|
|||
msgid "Apply changes\\Activates the changed settings"
|
||||
msgstr "Appliquer les changements\\Active les changements effectués"
|
||||
|
||||
msgid "Apply\\Apply the current mod configuration"
|
||||
msgstr ""
|
||||
|
||||
msgid "Appropriate constructor missing"
|
||||
msgstr "Constructeur approprié manquant"
|
||||
|
||||
|
@ -374,6 +377,9 @@ msgstr "Changement de caméra\\Autre de point de vue"
|
|||
msgid "Change player\\Change player"
|
||||
msgstr "Autre joueur\\Choix du nom du joueur"
|
||||
|
||||
msgid "Changes"
|
||||
msgstr ""
|
||||
|
||||
msgid "Chapters:"
|
||||
msgstr "Liste des chapitres :"
|
||||
|
||||
|
@ -443,6 +449,12 @@ msgstr "Copier"
|
|||
msgid "Copy (Ctrl+C)"
|
||||
msgstr "Copier (Ctrl+C)"
|
||||
|
||||
msgid "Could not open the file explorer!"
|
||||
msgstr ""
|
||||
|
||||
msgid "Could not open the web browser!"
|
||||
msgstr ""
|
||||
|
||||
msgid "Current mission saved"
|
||||
msgstr "Enregistrement effectué"
|
||||
|
||||
|
@ -476,6 +488,9 @@ msgstr "Derrick"
|
|||
msgid "Descend\\Reduces the power of the jet"
|
||||
msgstr "Descendre\\Diminuer la puissance du réacteur"
|
||||
|
||||
msgid "Description:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Destroy"
|
||||
msgstr "Détruire"
|
||||
|
||||
|
@ -488,6 +503,9 @@ msgstr "Destructeur"
|
|||
msgid "Device\\Driver and resolution settings"
|
||||
msgstr "Affichage\\Pilote et résolution d'affichage"
|
||||
|
||||
msgid "Disable\\Disable the selected mod"
|
||||
msgstr ""
|
||||
|
||||
msgid "Dividing by zero"
|
||||
msgstr "Division par zéro"
|
||||
|
||||
|
@ -504,6 +522,9 @@ msgstr "Portes bloquées par un robot ou un objet"
|
|||
msgid "Down (\\key gdown;)"
|
||||
msgstr "Descend (\\key gdown;)"
|
||||
|
||||
msgid "Down\\Move the selected mod down so it's loaded later (mods may overwrite files from the mods above them)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Drawer bot"
|
||||
msgstr "Robot dessinateur"
|
||||
|
||||
|
@ -531,6 +552,9 @@ msgstr "Oeuf"
|
|||
msgid "Empty character constant"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable\\Enable the selected mod"
|
||||
msgstr ""
|
||||
|
||||
msgid "End of block missing"
|
||||
msgstr "Il manque la fin du bloc"
|
||||
|
||||
|
@ -758,6 +782,9 @@ msgstr "Infecté par un virus; ne fonctionne plus temporairement"
|
|||
msgid "Information exchange post"
|
||||
msgstr "Station relais"
|
||||
|
||||
msgid "Information:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Instruction \"break\" outside a loop"
|
||||
msgstr "Instruction \"break\" en dehors d'une boucle"
|
||||
|
||||
|
@ -922,6 +949,15 @@ msgstr "Liste des missions du chapitre :"
|
|||
msgid "Missions\\Select mission"
|
||||
msgstr "Missions\\La grande aventure"
|
||||
|
||||
msgid "Mods"
|
||||
msgstr ""
|
||||
|
||||
msgid "Mods:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Mods\\Mod manager"
|
||||
msgstr ""
|
||||
|
||||
msgid "Mouse inversion X\\Inversion of the scrolling direction on the X axis"
|
||||
msgstr "Inversion souris X\\Inversion de la rotation lorsque la souris touche un bord"
|
||||
|
||||
|
@ -970,6 +1006,12 @@ msgstr "Sélectionner l'objet suivant\\Sélectionner l'objet suivant"
|
|||
msgid "No"
|
||||
msgstr "Non"
|
||||
|
||||
msgid "No changes."
|
||||
msgstr ""
|
||||
|
||||
msgid "No description."
|
||||
msgstr ""
|
||||
|
||||
msgid "No energy in the subsoil"
|
||||
msgstr "Pas d'énergie en sous-sol"
|
||||
|
||||
|
@ -1090,6 +1132,9 @@ msgstr "Ouvrir"
|
|||
msgid "Open (Ctrl+O)"
|
||||
msgstr "Ouvrir (Ctrl+O)"
|
||||
|
||||
msgid "Open Directory\\Open the mods directory"
|
||||
msgstr ""
|
||||
|
||||
msgid "Opening brace missing"
|
||||
msgstr "Début d'un bloc attendu"
|
||||
|
||||
|
@ -1301,6 +1346,9 @@ msgstr "Drapeau rouge"
|
|||
msgid "Reflections on the buttons \\Shiny buttons"
|
||||
msgstr "Reflets sur les boutons\\Boutons brillants"
|
||||
|
||||
msgid "Refresh\\Refresh the list of currently installed mods"
|
||||
msgstr ""
|
||||
|
||||
msgid "Remains of Apollo mission"
|
||||
msgstr "Vestige d'une mission Apollo"
|
||||
|
||||
|
@ -1562,6 +1610,10 @@ msgstr "Filtrage de textures\\Filtrage de textures"
|
|||
msgid "Textures"
|
||||
msgstr "Textures"
|
||||
|
||||
#, c-format
|
||||
msgid "The address %s could not be opened in a web browser."
|
||||
msgstr ""
|
||||
|
||||
msgid "The battle has ended"
|
||||
msgstr "La bataille est terminée"
|
||||
|
||||
|
@ -1574,9 +1626,16 @@ msgstr "La fonction n'a pas retourné de résultat"
|
|||
msgid "The mission is not accomplished yet (press \\key help; for more details)"
|
||||
msgstr "La mission n'est pas terminée (appuyez sur \\key help; pour plus de détails)"
|
||||
|
||||
#, c-format
|
||||
msgid "The path %s could not be opened in a file explorer."
|
||||
msgstr ""
|
||||
|
||||
msgid "The types of the two operands are incompatible"
|
||||
msgstr "Les deux opérandes ne sont pas de types compatibles"
|
||||
|
||||
msgid "There are unsaved changes. Do you want to save them before leaving?"
|
||||
msgstr ""
|
||||
|
||||
msgid "This class already exists"
|
||||
msgstr "Cette classe existe déjà"
|
||||
|
||||
|
@ -1701,6 +1760,9 @@ msgstr "Unité"
|
|||
msgid "Unknown Object"
|
||||
msgstr "Objet inconnu"
|
||||
|
||||
msgid "Unknown author"
|
||||
msgstr ""
|
||||
|
||||
msgid "Unknown command"
|
||||
msgstr "Commande inconnue"
|
||||
|
||||
|
@ -1713,6 +1775,9 @@ msgstr "Routine inconnue"
|
|||
msgid "Up (\\key gup;)"
|
||||
msgstr "Monte (\\key gup;)"
|
||||
|
||||
msgid "Up\\Move the selected mod up so it's loaded sooner (mods may overwrite files from the mods above them)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Uranium deposit (site for derrick)"
|
||||
msgstr "Emplacement pour un derrick (minerai d'uranium)"
|
||||
|
||||
|
@ -1734,6 +1799,9 @@ msgstr "Variable non initialisée"
|
|||
msgid "Vault"
|
||||
msgstr "Coffre-fort"
|
||||
|
||||
msgid "Version"
|
||||
msgstr ""
|
||||
|
||||
msgid "Vertical Synchronization\\Limits the number of frames per second to display frequency"
|
||||
msgstr "Synchronisation verticale :\\Réduit la fréquence d'images par seconde à afficher."
|
||||
|
||||
|
@ -1752,6 +1820,9 @@ msgstr "Guêpe mortellement touchée"
|
|||
msgid "Waste"
|
||||
msgstr "Déchet"
|
||||
|
||||
msgid "Website"
|
||||
msgstr ""
|
||||
|
||||
msgid "Wheeled builder"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1785,6 +1856,9 @@ msgstr "Robot renifleur volant"
|
|||
msgid "Withdraw shield (\\key action;)"
|
||||
msgstr "Refermer le bouclier (\\key action;)"
|
||||
|
||||
msgid "Workshop\\Open the workshop to search for mods"
|
||||
msgstr ""
|
||||
|
||||
msgid "Worm"
|
||||
msgstr "Ver"
|
||||
|
||||
|
@ -1933,6 +2007,9 @@ msgstr "\\Drapeaux violets"
|
|||
msgid "\\Yellow flags"
|
||||
msgstr "\\Drapeaux jaunes"
|
||||
|
||||
msgid "by"
|
||||
msgstr ""
|
||||
|
||||
msgid "colobot.info"
|
||||
msgstr "colobot.info"
|
||||
|
||||
|
|
77
po/pl.po
77
po/pl.po
|
@ -124,6 +124,9 @@ msgstr "Wygląd\\Wybierz swoją postać"
|
|||
msgid "Apply changes\\Activates the changed settings"
|
||||
msgstr "Zastosuj zmiany\\Aktywuje zmienione ustawienia"
|
||||
|
||||
msgid "Apply\\Apply the current mod configuration"
|
||||
msgstr "Zastosuj\\Zastosuj obecną konfigurację modów"
|
||||
|
||||
msgid "Appropriate constructor missing"
|
||||
msgstr "Brak odpowiedniego konstruktora"
|
||||
|
||||
|
@ -370,6 +373,9 @@ msgstr "Zmień kamerę\\Przełącza pomiędzy kamerą pokładową i śledzącą"
|
|||
msgid "Change player\\Change player"
|
||||
msgstr "Zmień gracza\\Zmień gracza"
|
||||
|
||||
msgid "Changes"
|
||||
msgstr "Zmiany"
|
||||
|
||||
msgid "Chapters:"
|
||||
msgstr "Rozdziały:"
|
||||
|
||||
|
@ -439,6 +445,12 @@ msgstr "Kopiuj"
|
|||
msgid "Copy (Ctrl+C)"
|
||||
msgstr "Kopiuj (Ctrl+C)"
|
||||
|
||||
msgid "Could not open the file explorer!"
|
||||
msgstr "Nie udało się otworzyć przeglądarki plików!"
|
||||
|
||||
msgid "Could not open the web browser!"
|
||||
msgstr "Nie udało się otworzyć przeglądarki internetowej!"
|
||||
|
||||
msgid "Current mission saved"
|
||||
msgstr "Bieżąca misja zapisana"
|
||||
|
||||
|
@ -472,6 +484,9 @@ msgstr "Kopalnia"
|
|||
msgid "Descend\\Reduces the power of the jet"
|
||||
msgstr "W dół\\Zmniejsza moc silnika"
|
||||
|
||||
msgid "Description:"
|
||||
msgstr "Opis:"
|
||||
|
||||
msgid "Destroy"
|
||||
msgstr "Zniszcz"
|
||||
|
||||
|
@ -484,6 +499,9 @@ msgstr "Destroyer"
|
|||
msgid "Device\\Driver and resolution settings"
|
||||
msgstr "Urządzenie\\Ustawienia sterownika i rozdzielczości"
|
||||
|
||||
msgid "Disable\\Disable the selected mod"
|
||||
msgstr "Wyłącz\\Wyłącza zaznaczonego moda"
|
||||
|
||||
msgid "Dividing by zero"
|
||||
msgstr "Dzielenie przez zero"
|
||||
|
||||
|
@ -500,6 +518,9 @@ msgstr "Drzwi zablokowane przez robota lub inny obiekt"
|
|||
msgid "Down (\\key gdown;)"
|
||||
msgstr "Dół (\\key gdown;)"
|
||||
|
||||
msgid "Down\\Move the selected mod down so it's loaded later (mods may overwrite files from the mods above them)"
|
||||
msgstr "W dół\\Przenieś zaznaczonego moda w dół, aby był załadowany później (mody mogą nadpisywać pliki modów wyżej)"
|
||||
|
||||
msgid "Drawer bot"
|
||||
msgstr "Robot rysownik"
|
||||
|
||||
|
@ -527,6 +548,9 @@ msgstr "Jajo"
|
|||
msgid "Empty character constant"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable\\Enable the selected mod"
|
||||
msgstr "Włącz\\Włącza zaznaczonego moda"
|
||||
|
||||
msgid "End of block missing"
|
||||
msgstr "Brak końca bloku"
|
||||
|
||||
|
@ -753,6 +777,9 @@ msgstr "Zainfekowane wirusem, chwilowo niesprawne"
|
|||
msgid "Information exchange post"
|
||||
msgstr "Stacja przekaźnikowa informacji"
|
||||
|
||||
msgid "Information:"
|
||||
msgstr "Informacje:"
|
||||
|
||||
msgid "Instruction \"break\" outside a loop"
|
||||
msgstr "Polecenie \"break\" na zewnątrz pętli"
|
||||
|
||||
|
@ -903,6 +930,15 @@ msgstr "Misje na tej planecie:"
|
|||
msgid "Missions\\Select mission"
|
||||
msgstr "Misje\\Wybierz misję"
|
||||
|
||||
msgid "Mods"
|
||||
msgstr "Mody"
|
||||
|
||||
msgid "Mods:"
|
||||
msgstr "Mody:"
|
||||
|
||||
msgid "Mods\\Mod manager"
|
||||
msgstr "Mody\\Zarządzanie modami"
|
||||
|
||||
msgid "Mouse inversion X\\Inversion of the scrolling direction on the X axis"
|
||||
msgstr "Odwrócenie myszy X\\Odwrócenie kierunków przewijania w poziomie"
|
||||
|
||||
|
@ -951,6 +987,12 @@ msgstr "Następny obiekt\\Zaznacza następny obiekt"
|
|||
msgid "No"
|
||||
msgstr "Nie"
|
||||
|
||||
msgid "No changes."
|
||||
msgstr "Brak zmian."
|
||||
|
||||
msgid "No description."
|
||||
msgstr "Brak opisu."
|
||||
|
||||
msgid "No energy in the subsoil"
|
||||
msgstr "Brak energii w ziemi"
|
||||
|
||||
|
@ -1071,6 +1113,9 @@ msgstr "Otwórz"
|
|||
msgid "Open (Ctrl+O)"
|
||||
msgstr "Otwórz (Ctrl+O)"
|
||||
|
||||
msgid "Open Directory\\Open the mods directory"
|
||||
msgstr "Otwórz katalog\\Otwórz katalog z modami"
|
||||
|
||||
msgid "Opening brace missing"
|
||||
msgstr "Brak klamry otwierającej"
|
||||
|
||||
|
@ -1281,6 +1326,9 @@ msgstr "Czerwona flaga"
|
|||
msgid "Reflections on the buttons \\Shiny buttons"
|
||||
msgstr "Odbicia na przyciskach \\Świecące przyciski"
|
||||
|
||||
msgid "Refresh\\Refresh the list of currently installed mods"
|
||||
msgstr "Odśwież\\Odśwież listę obecnie zainstalowanych modów"
|
||||
|
||||
msgid "Remains of Apollo mission"
|
||||
msgstr "Pozostałości z misji Apollo"
|
||||
|
||||
|
@ -1542,6 +1590,10 @@ msgstr "Filtrowanie tekstur\\Filtrowanie tekstur"
|
|||
msgid "Textures"
|
||||
msgstr "Tekstury"
|
||||
|
||||
#, c-format
|
||||
msgid "The address %s could not be opened in a web browser."
|
||||
msgstr "Nie udało się otworzyć adresu %s w przeglądarce internetowej."
|
||||
|
||||
msgid "The battle has ended"
|
||||
msgstr "Bitwa zakończyła się"
|
||||
|
||||
|
@ -1554,9 +1606,16 @@ msgstr "Funkcja nie zwróciła żadnej wartości"
|
|||
msgid "The mission is not accomplished yet (press \\key help; for more details)"
|
||||
msgstr "Misja nie jest wypełniona (naciśnij \\key help; aby uzyskać szczegóły)"
|
||||
|
||||
#, c-format
|
||||
msgid "The path %s could not be opened in a file explorer."
|
||||
msgstr "Nie udało się otworzyć ścieżki %s w przeglądarce plików."
|
||||
|
||||
msgid "The types of the two operands are incompatible"
|
||||
msgstr "Niezgodne typy operatorów"
|
||||
|
||||
msgid "There are unsaved changes. Do you want to save them before leaving?"
|
||||
msgstr "Są niezapisane zmiany. Czy chcesz je zapisać przed wyjściem?"
|
||||
|
||||
msgid "This class already exists"
|
||||
msgstr "Taka klasa już istnieje"
|
||||
|
||||
|
@ -1681,6 +1740,9 @@ msgstr "Jednostka"
|
|||
msgid "Unknown Object"
|
||||
msgstr "Obiekt nieznany"
|
||||
|
||||
msgid "Unknown author"
|
||||
msgstr "Nieznany autor"
|
||||
|
||||
msgid "Unknown command"
|
||||
msgstr "Nieznane polecenie"
|
||||
|
||||
|
@ -1693,6 +1755,9 @@ msgstr "Funkcja nieznana"
|
|||
msgid "Up (\\key gup;)"
|
||||
msgstr "Góra (\\key gup;)"
|
||||
|
||||
msgid "Up\\Move the selected mod up so it's loaded sooner (mods may overwrite files from the mods above them)"
|
||||
msgstr "W górę\\Przenieś zaznaczonego moda w górę, aby był załadowany wcześniej (mody mogą nadpisywać pliki modów wyżej)"
|
||||
|
||||
msgid "Uranium deposit (site for derrick)"
|
||||
msgstr "Złoże uranu (miejsce na kopalnię)"
|
||||
|
||||
|
@ -1714,6 +1779,9 @@ msgstr "Zmienna nie została zainicjalizowana"
|
|||
msgid "Vault"
|
||||
msgstr "Skrytka"
|
||||
|
||||
msgid "Version"
|
||||
msgstr "Wersja"
|
||||
|
||||
msgid "Vertical Synchronization\\Limits the number of frames per second to display frequency"
|
||||
msgstr "Synchronizacja pionowa\\Ogranicza ilość klatek na sekundę do wartości odświeżania ekranu"
|
||||
|
||||
|
@ -1732,6 +1800,9 @@ msgstr "Osa śmiertelnie raniona"
|
|||
msgid "Waste"
|
||||
msgstr "Odpady"
|
||||
|
||||
msgid "Website"
|
||||
msgstr "Strona internetowa"
|
||||
|
||||
msgid "Wheeled builder"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1765,6 +1836,9 @@ msgstr "Szperacz latający"
|
|||
msgid "Withdraw shield (\\key action;)"
|
||||
msgstr "Wyłącz osłonę (\\key action;)"
|
||||
|
||||
msgid "Workshop\\Open the workshop to search for mods"
|
||||
msgstr "Warsztat\\Otwórz warsztat, aby poszukać modów"
|
||||
|
||||
msgid "Worm"
|
||||
msgstr "Robal"
|
||||
|
||||
|
@ -1915,6 +1989,9 @@ msgstr "\\Fioletowe flagi"
|
|||
msgid "\\Yellow flags"
|
||||
msgstr "\\Żółte flagi"
|
||||
|
||||
msgid "by"
|
||||
msgstr "autorstwa"
|
||||
|
||||
msgid "colobot.info"
|
||||
msgstr "colobot.info"
|
||||
|
||||
|
|
77
po/pt.po
77
po/pt.po
|
@ -122,6 +122,9 @@ msgstr "Aparência\\Escolha sua aparência"
|
|||
msgid "Apply changes\\Activates the changed settings"
|
||||
msgstr "Aplicar mudanças\\Ativa as configurações alteradas"
|
||||
|
||||
msgid "Apply\\Apply the current mod configuration"
|
||||
msgstr ""
|
||||
|
||||
msgid "Appropriate constructor missing"
|
||||
msgstr "Construtor apropriado faltando"
|
||||
|
||||
|
@ -368,6 +371,9 @@ msgstr "Mudar câmera\\Alterna entre câmera incorporada e câmera seguidora"
|
|||
msgid "Change player\\Change player"
|
||||
msgstr "Mudar jogador\\Mudar jogador"
|
||||
|
||||
msgid "Changes"
|
||||
msgstr ""
|
||||
|
||||
msgid "Chapters:"
|
||||
msgstr "Capítulos:"
|
||||
|
||||
|
@ -438,6 +444,12 @@ msgstr "Copiar"
|
|||
msgid "Copy (Ctrl+C)"
|
||||
msgstr "Copiar (Ctrl+C)"
|
||||
|
||||
msgid "Could not open the file explorer!"
|
||||
msgstr ""
|
||||
|
||||
msgid "Could not open the web browser!"
|
||||
msgstr ""
|
||||
|
||||
msgid "Current mission saved"
|
||||
msgstr "Missão atual salva"
|
||||
|
||||
|
@ -471,6 +483,9 @@ msgstr "Extrator"
|
|||
msgid "Descend\\Reduces the power of the jet"
|
||||
msgstr "Descer\\Diminui o poder do jato"
|
||||
|
||||
msgid "Description:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Destroy"
|
||||
msgstr "Destruir"
|
||||
|
||||
|
@ -483,6 +498,9 @@ msgstr "Destruidor"
|
|||
msgid "Device\\Driver and resolution settings"
|
||||
msgstr "Dispositivo\\Configurações de driver e resolução"
|
||||
|
||||
msgid "Disable\\Disable the selected mod"
|
||||
msgstr ""
|
||||
|
||||
msgid "Dividing by zero"
|
||||
msgstr "Dividindo por zero"
|
||||
|
||||
|
@ -499,6 +517,9 @@ msgstr "Portas bloqueadas por um robô ou outro objeto"
|
|||
msgid "Down (\\key gdown;)"
|
||||
msgstr "Baixo (\\key gdown;)"
|
||||
|
||||
msgid "Down\\Move the selected mod down so it's loaded later (mods may overwrite files from the mods above them)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Drawer bot"
|
||||
msgstr "Robô cartoonista"
|
||||
|
||||
|
@ -526,6 +547,9 @@ msgstr "Ovo"
|
|||
msgid "Empty character constant"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable\\Enable the selected mod"
|
||||
msgstr ""
|
||||
|
||||
msgid "End of block missing"
|
||||
msgstr "Fim do bloco ausente"
|
||||
|
||||
|
@ -753,6 +777,9 @@ msgstr "Infectado por vírus; temporariamento fora de serviço"
|
|||
msgid "Information exchange post"
|
||||
msgstr "Posto de troca de informação"
|
||||
|
||||
msgid "Information:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Instruction \"break\" outside a loop"
|
||||
msgstr "Intrução \"break\" fora de um laço"
|
||||
|
||||
|
@ -917,6 +944,15 @@ msgstr "Lista de missões neste planeta:"
|
|||
msgid "Missions\\Select mission"
|
||||
msgstr "Missões\\Selecione uma missão"
|
||||
|
||||
msgid "Mods"
|
||||
msgstr ""
|
||||
|
||||
msgid "Mods:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Mods\\Mod manager"
|
||||
msgstr ""
|
||||
|
||||
msgid "Mouse inversion X\\Inversion of the scrolling direction on the X axis"
|
||||
msgstr "Inversão de mouse X\\Inverte a direção da rolagem no eixo X"
|
||||
|
||||
|
@ -965,6 +1001,12 @@ msgstr "Próximo objeto\\Selecionar o próximo objeto"
|
|||
msgid "No"
|
||||
msgstr "Não"
|
||||
|
||||
msgid "No changes."
|
||||
msgstr ""
|
||||
|
||||
msgid "No description."
|
||||
msgstr ""
|
||||
|
||||
msgid "No energy in the subsoil"
|
||||
msgstr "Nenhuma energia no subsolo"
|
||||
|
||||
|
@ -1085,6 +1127,9 @@ msgstr "Abrir"
|
|||
msgid "Open (Ctrl+O)"
|
||||
msgstr "Abrir (Ctrl+O)"
|
||||
|
||||
msgid "Open Directory\\Open the mods directory"
|
||||
msgstr ""
|
||||
|
||||
msgid "Opening brace missing"
|
||||
msgstr "Chave de abertura ausente"
|
||||
|
||||
|
@ -1296,6 +1341,9 @@ msgstr "Bandeira vermelha"
|
|||
msgid "Reflections on the buttons \\Shiny buttons"
|
||||
msgstr "Reflexões nos botões\\Botões brilhantes"
|
||||
|
||||
msgid "Refresh\\Refresh the list of currently installed mods"
|
||||
msgstr ""
|
||||
|
||||
msgid "Remains of Apollo mission"
|
||||
msgstr "Restos da missão Apollo"
|
||||
|
||||
|
@ -1557,6 +1605,10 @@ msgstr "Filtragem de textura\\Filtragem de textura"
|
|||
msgid "Textures"
|
||||
msgstr "Texturas"
|
||||
|
||||
#, c-format
|
||||
msgid "The address %s could not be opened in a web browser."
|
||||
msgstr ""
|
||||
|
||||
msgid "The battle has ended"
|
||||
msgstr "A batalha acabou"
|
||||
|
||||
|
@ -1569,9 +1621,16 @@ msgstr "A função não retornou nenhum valor"
|
|||
msgid "The mission is not accomplished yet (press \\key help; for more details)"
|
||||
msgstr "A missão não foi completada ainda (pressione \\key help; para mais detalhes)"
|
||||
|
||||
#, c-format
|
||||
msgid "The path %s could not be opened in a file explorer."
|
||||
msgstr ""
|
||||
|
||||
msgid "The types of the two operands are incompatible"
|
||||
msgstr "Os tipos dos dois operandos são incompativeis"
|
||||
|
||||
msgid "There are unsaved changes. Do you want to save them before leaving?"
|
||||
msgstr ""
|
||||
|
||||
msgid "This class already exists"
|
||||
msgstr "Esta classe já existe"
|
||||
|
||||
|
@ -1696,6 +1755,9 @@ msgstr "Unidade"
|
|||
msgid "Unknown Object"
|
||||
msgstr "Objeto desconhecido"
|
||||
|
||||
msgid "Unknown author"
|
||||
msgstr ""
|
||||
|
||||
msgid "Unknown command"
|
||||
msgstr "Comando desconhecido"
|
||||
|
||||
|
@ -1708,6 +1770,9 @@ msgstr "Função desconhecida"
|
|||
msgid "Up (\\key gup;)"
|
||||
msgstr "Cima (\\key gup;)"
|
||||
|
||||
msgid "Up\\Move the selected mod up so it's loaded sooner (mods may overwrite files from the mods above them)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Uranium deposit (site for derrick)"
|
||||
msgstr "Depósito de urânio (local para extrator)"
|
||||
|
||||
|
@ -1729,6 +1794,9 @@ msgstr "Variável não inicializada"
|
|||
msgid "Vault"
|
||||
msgstr "Cofre"
|
||||
|
||||
msgid "Version"
|
||||
msgstr ""
|
||||
|
||||
msgid "Vertical Synchronization\\Limits the number of frames per second to display frequency"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1747,6 +1815,9 @@ msgstr "Vespa fatalmente ferida"
|
|||
msgid "Waste"
|
||||
msgstr "Desperdício"
|
||||
|
||||
msgid "Website"
|
||||
msgstr ""
|
||||
|
||||
msgid "Wheeled builder"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1780,6 +1851,9 @@ msgstr "Farejador alado"
|
|||
msgid "Withdraw shield (\\key action;)"
|
||||
msgstr "Retirar escudo (\\key action;)"
|
||||
|
||||
msgid "Workshop\\Open the workshop to search for mods"
|
||||
msgstr ""
|
||||
|
||||
msgid "Worm"
|
||||
msgstr "Verme"
|
||||
|
||||
|
@ -1928,6 +2002,9 @@ msgstr "\\Bandeiras violetas"
|
|||
msgid "\\Yellow flags"
|
||||
msgstr "\\Bandeiras amarelas"
|
||||
|
||||
msgid "by"
|
||||
msgstr ""
|
||||
|
||||
msgid "colobot.info"
|
||||
msgstr "colobot.info"
|
||||
|
||||
|
|
77
po/ru.po
77
po/ru.po
|
@ -124,6 +124,9 @@ msgstr "Внешность\\Настройка внешности"
|
|||
msgid "Apply changes\\Activates the changed settings"
|
||||
msgstr "Принять\\Принять изменения настроек"
|
||||
|
||||
msgid "Apply\\Apply the current mod configuration"
|
||||
msgstr ""
|
||||
|
||||
msgid "Appropriate constructor missing"
|
||||
msgstr "Соответствующий конструктор отсутствует"
|
||||
|
||||
|
@ -375,6 +378,9 @@ msgstr "Изменить вид\\Переключение между борто
|
|||
msgid "Change player\\Change player"
|
||||
msgstr "Новый игрок\\Выберите имя для игрока"
|
||||
|
||||
msgid "Changes"
|
||||
msgstr ""
|
||||
|
||||
msgid "Chapters:"
|
||||
msgstr "Разделы:"
|
||||
|
||||
|
@ -446,6 +452,12 @@ msgstr "Копировать"
|
|||
msgid "Copy (Ctrl+C)"
|
||||
msgstr "Копировать (Ctrl+C)"
|
||||
|
||||
msgid "Could not open the file explorer!"
|
||||
msgstr ""
|
||||
|
||||
msgid "Could not open the web browser!"
|
||||
msgstr ""
|
||||
|
||||
msgid "Current mission saved"
|
||||
msgstr "Текущая миссия сохранена"
|
||||
|
||||
|
@ -480,6 +492,9 @@ msgstr "Космический корабль"
|
|||
msgid "Descend\\Reduces the power of the jet"
|
||||
msgstr "Снижение и посадка\\Понижение мощности реактивного двигателя"
|
||||
|
||||
msgid "Description:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Destroy"
|
||||
msgstr "Уничтожить"
|
||||
|
||||
|
@ -492,6 +507,9 @@ msgstr "Уничтожитель"
|
|||
msgid "Device\\Driver and resolution settings"
|
||||
msgstr "Устройство\\Драйвер и настройки разрешения"
|
||||
|
||||
msgid "Disable\\Disable the selected mod"
|
||||
msgstr ""
|
||||
|
||||
msgid "Dividing by zero"
|
||||
msgstr "Деление на ноль (запрещено!)"
|
||||
|
||||
|
@ -508,6 +526,9 @@ msgstr "Двери заблокированы роботом или другим
|
|||
msgid "Down (\\key gdown;)"
|
||||
msgstr "Вниз (\\key gdown;)"
|
||||
|
||||
msgid "Down\\Move the selected mod down so it's loaded later (mods may overwrite files from the mods above them)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Drawer bot"
|
||||
msgstr "Рисовальщик"
|
||||
|
||||
|
@ -535,6 +556,9 @@ msgstr "Яйцо"
|
|||
msgid "Empty character constant"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable\\Enable the selected mod"
|
||||
msgstr ""
|
||||
|
||||
msgid "End of block missing"
|
||||
msgstr "Отсутствует конец блока"
|
||||
|
||||
|
@ -762,6 +786,9 @@ msgstr "Заражено вирусом. Временно вышел из стр
|
|||
msgid "Information exchange post"
|
||||
msgstr "Пост обмена информацией"
|
||||
|
||||
msgid "Information:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Instruction \"break\" outside a loop"
|
||||
msgstr "Инструкция \"break\" вне цикла"
|
||||
|
||||
|
@ -926,6 +953,15 @@ msgstr "Миссии на этой планете:"
|
|||
msgid "Missions\\Select mission"
|
||||
msgstr "Миссии\\Выбор миссии"
|
||||
|
||||
msgid "Mods"
|
||||
msgstr ""
|
||||
|
||||
msgid "Mods:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Mods\\Mod manager"
|
||||
msgstr ""
|
||||
|
||||
msgid "Mouse inversion X\\Inversion of the scrolling direction on the X axis"
|
||||
msgstr "Инверсия мыши по оси X\\Инверсия прокрутки по оси Х"
|
||||
|
||||
|
@ -976,6 +1012,12 @@ msgstr "Следующий объект\\Выбор следующего объ
|
|||
msgid "No"
|
||||
msgstr "Нет"
|
||||
|
||||
msgid "No changes."
|
||||
msgstr ""
|
||||
|
||||
msgid "No description."
|
||||
msgstr ""
|
||||
|
||||
msgid "No energy in the subsoil"
|
||||
msgstr "Под землей нет запасов энергии"
|
||||
|
||||
|
@ -1096,6 +1138,9 @@ msgstr "Открыть"
|
|||
msgid "Open (Ctrl+O)"
|
||||
msgstr "Открыть (Ctrl+O)"
|
||||
|
||||
msgid "Open Directory\\Open the mods directory"
|
||||
msgstr ""
|
||||
|
||||
msgid "Opening brace missing"
|
||||
msgstr "Открывающая скобка отсутствует"
|
||||
|
||||
|
@ -1308,6 +1353,9 @@ msgstr "Красный флаг"
|
|||
msgid "Reflections on the buttons \\Shiny buttons"
|
||||
msgstr "Отражения на кнопках \\Блестящие кнопки"
|
||||
|
||||
msgid "Refresh\\Refresh the list of currently installed mods"
|
||||
msgstr ""
|
||||
|
||||
msgid "Remains of Apollo mission"
|
||||
msgstr "Остатки миссии Аполлон"
|
||||
|
||||
|
@ -1573,6 +1621,10 @@ msgstr "Фильтрация текстур\\Фильтрация текстур
|
|||
msgid "Textures"
|
||||
msgstr "Текстуры"
|
||||
|
||||
#, c-format
|
||||
msgid "The address %s could not be opened in a web browser."
|
||||
msgstr ""
|
||||
|
||||
msgid "The battle has ended"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1585,9 +1637,16 @@ msgstr "Функция не возвратила значения"
|
|||
msgid "The mission is not accomplished yet (press \\key help; for more details)"
|
||||
msgstr "Миссия еще не выполнена (нажмите \\key help; для более подробной информации)"
|
||||
|
||||
#, c-format
|
||||
msgid "The path %s could not be opened in a file explorer."
|
||||
msgstr ""
|
||||
|
||||
msgid "The types of the two operands are incompatible"
|
||||
msgstr "Типы операндов несовместимы"
|
||||
|
||||
msgid "There are unsaved changes. Do you want to save them before leaving?"
|
||||
msgstr ""
|
||||
|
||||
msgid "This class already exists"
|
||||
msgstr "Этот класс уже существует"
|
||||
|
||||
|
@ -1712,6 +1771,9 @@ msgstr "Юнит"
|
|||
msgid "Unknown Object"
|
||||
msgstr "Неизвестный объект"
|
||||
|
||||
msgid "Unknown author"
|
||||
msgstr ""
|
||||
|
||||
msgid "Unknown command"
|
||||
msgstr "Неизвестная команда"
|
||||
|
||||
|
@ -1724,6 +1786,9 @@ msgstr "Неизвестная функция"
|
|||
msgid "Up (\\key gup;)"
|
||||
msgstr "Вверх (\\key gup;)"
|
||||
|
||||
msgid "Up\\Move the selected mod up so it's loaded sooner (mods may overwrite files from the mods above them)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Uranium deposit (site for derrick)"
|
||||
msgstr "Запасы урана (место для буровой вышки)"
|
||||
|
||||
|
@ -1745,6 +1810,9 @@ msgstr "Переменная не инициализирована"
|
|||
msgid "Vault"
|
||||
msgstr "Хранилище"
|
||||
|
||||
msgid "Version"
|
||||
msgstr ""
|
||||
|
||||
msgid "Vertical Synchronization\\Limits the number of frames per second to display frequency"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1763,6 +1831,9 @@ msgstr "Оса смертельно ранена"
|
|||
msgid "Waste"
|
||||
msgstr "Мусор"
|
||||
|
||||
msgid "Website"
|
||||
msgstr ""
|
||||
|
||||
msgid "Wheeled builder"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1796,6 +1867,9 @@ msgstr "Летающий искатель"
|
|||
msgid "Withdraw shield (\\key action;)"
|
||||
msgstr "Снять щит (\\key action;)"
|
||||
|
||||
msgid "Workshop\\Open the workshop to search for mods"
|
||||
msgstr ""
|
||||
|
||||
msgid "Worm"
|
||||
msgstr "Червь"
|
||||
|
||||
|
@ -1944,6 +2018,9 @@ msgstr "\\Фиолетовый флаг"
|
|||
msgid "\\Yellow flags"
|
||||
msgstr "\\Желтый флаг"
|
||||
|
||||
msgid "by"
|
||||
msgstr ""
|
||||
|
||||
msgid "colobot.info"
|
||||
msgstr "colobot.info"
|
||||
|
||||
|
|
|
@ -145,6 +145,8 @@ set(BASE_SOURCES
|
|||
app/controller.h
|
||||
app/input.cpp
|
||||
app/input.h
|
||||
app/modman.cpp
|
||||
app/modman.h
|
||||
app/pathman.cpp
|
||||
app/pathman.h
|
||||
app/pausemanager.cpp
|
||||
|
@ -568,6 +570,8 @@ set(BASE_SOURCES
|
|||
ui/screen/screen_loading.h
|
||||
ui/screen/screen_main_menu.cpp
|
||||
ui/screen/screen_main_menu.h
|
||||
ui/screen/screen_mod_list.cpp
|
||||
ui/screen/screen_mod_list.h
|
||||
ui/screen/screen_player_select.cpp
|
||||
ui/screen/screen_player_select.h
|
||||
ui/screen/screen_quit.cpp
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "app/controller.h"
|
||||
#include "app/input.h"
|
||||
#include "app/modman.h"
|
||||
#include "app/pathman.h"
|
||||
|
||||
#include "common/config_file.h"
|
||||
|
@ -113,7 +114,8 @@ CApplication::CApplication(CSystemUtils* systemUtils)
|
|||
m_private(MakeUnique<ApplicationPrivate>()),
|
||||
m_configFile(MakeUnique<CConfigFile>()),
|
||||
m_input(MakeUnique<CInput>()),
|
||||
m_pathManager(MakeUnique<CPathManager>(systemUtils))
|
||||
m_pathManager(MakeUnique<CPathManager>(systemUtils)),
|
||||
m_modManager(MakeUnique<CModManager>(this, m_pathManager.get()))
|
||||
{
|
||||
m_exitCode = 0;
|
||||
m_active = false;
|
||||
|
@ -220,6 +222,11 @@ CSoundInterface* CApplication::GetSound()
|
|||
return m_sound.get();
|
||||
}
|
||||
|
||||
CModManager* CApplication::GetModManager()
|
||||
{
|
||||
return m_modManager.get();
|
||||
}
|
||||
|
||||
void CApplication::LoadEnvironmentVariables()
|
||||
{
|
||||
auto dataDir = m_systemUtils->GetEnvVar("COLOBOT_DATA_DIR");
|
||||
|
@ -513,6 +520,10 @@ bool CApplication::Create()
|
|||
GetLogger()->Warn("Config could not be loaded. Default values will be used!\n");
|
||||
}
|
||||
|
||||
m_modManager->FindMods();
|
||||
m_modManager->SaveMods();
|
||||
m_modManager->MountAllMods();
|
||||
|
||||
// Create the sound instance.
|
||||
#ifdef OPENAL_SOUND
|
||||
if (!m_headless)
|
||||
|
@ -698,21 +709,7 @@ bool CApplication::Create()
|
|||
// Create the robot application.
|
||||
m_controller = MakeUnique<CController>();
|
||||
|
||||
CThread musicLoadThread([this]()
|
||||
{
|
||||
GetLogger()->Debug("Cache sounds...\n");
|
||||
SystemTimeStamp* musicLoadStart = m_systemUtils->CreateTimeStamp();
|
||||
m_systemUtils->GetCurrentTimeStamp(musicLoadStart);
|
||||
|
||||
m_sound->CacheAll();
|
||||
|
||||
SystemTimeStamp* musicLoadEnd = m_systemUtils->CreateTimeStamp();
|
||||
m_systemUtils->GetCurrentTimeStamp(musicLoadEnd);
|
||||
float musicLoadTime = m_systemUtils->TimeStampDiff(musicLoadStart, musicLoadEnd, STU_MSEC);
|
||||
GetLogger()->Debug("Sound loading took %.2f ms\n", musicLoadTime);
|
||||
},
|
||||
"Sound loading thread");
|
||||
musicLoadThread.Start();
|
||||
StartLoadingMusic();
|
||||
|
||||
if (m_runSceneCategory == LevelCategory::Max)
|
||||
m_controller->StartApp();
|
||||
|
@ -726,6 +723,15 @@ bool CApplication::Create()
|
|||
return true;
|
||||
}
|
||||
|
||||
void CApplication::ReloadResources()
|
||||
{
|
||||
GetLogger()->Info("Reloading resources\n");
|
||||
m_engine->ReloadAllTextures();
|
||||
StartLoadingMusic();
|
||||
m_controller->GetRobotMain()->UpdateCustomLevelList();
|
||||
}
|
||||
|
||||
|
||||
bool CApplication::CreateVideoSurface()
|
||||
{
|
||||
Uint32 videoFlags = SDL_WINDOW_OPENGL;
|
||||
|
@ -1537,6 +1543,26 @@ void CApplication::InternalResumeSimulation()
|
|||
m_absTimeBase = m_exactAbsTime;
|
||||
}
|
||||
|
||||
void CApplication::StartLoadingMusic()
|
||||
{
|
||||
CThread musicLoadThread([this]()
|
||||
{
|
||||
GetLogger()->Debug("Cache sounds...\n");
|
||||
SystemTimeStamp* musicLoadStart = m_systemUtils->CreateTimeStamp();
|
||||
m_systemUtils->GetCurrentTimeStamp(musicLoadStart);
|
||||
|
||||
m_sound->Reset();
|
||||
m_sound->CacheAll();
|
||||
|
||||
SystemTimeStamp* musicLoadEnd = m_systemUtils->CreateTimeStamp();
|
||||
m_systemUtils->GetCurrentTimeStamp(musicLoadEnd);
|
||||
float musicLoadTime = m_systemUtils->TimeStampDiff(musicLoadStart, musicLoadEnd, STU_MSEC);
|
||||
GetLogger()->Debug("Sound loading took %.2f ms\n", musicLoadTime);
|
||||
},
|
||||
"Sound loading thread");
|
||||
musicLoadThread.Start();
|
||||
}
|
||||
|
||||
bool CApplication::GetSimulationSuspended() const
|
||||
{
|
||||
return m_simulationSuspended;
|
||||
|
|
|
@ -42,6 +42,7 @@ class CEventQueue;
|
|||
class CController;
|
||||
class CSoundInterface;
|
||||
class CInput;
|
||||
class CModManager;
|
||||
class CPathManager;
|
||||
class CConfigFile;
|
||||
class CSystemUtils;
|
||||
|
@ -162,6 +163,8 @@ public:
|
|||
CEventQueue* GetEventQueue();
|
||||
//! Returns the sound subsystem
|
||||
CSoundInterface* GetSound();
|
||||
//! Returns the mod manager
|
||||
CModManager* GetModManager();
|
||||
|
||||
public:
|
||||
//! Loads some data from environment variables
|
||||
|
@ -170,6 +173,8 @@ public:
|
|||
ParseArgsStatus ParseArguments(int argc, char *argv[]);
|
||||
//! Initializes the application
|
||||
bool Create();
|
||||
//! Reloads the application resources, e.g. mods
|
||||
void ReloadResources();
|
||||
//! Main event loop
|
||||
int Run();
|
||||
//! Returns the code to be returned at main() exit
|
||||
|
@ -301,6 +306,9 @@ protected:
|
|||
//! Internal procedure to reset time counters
|
||||
void InternalResumeSimulation();
|
||||
|
||||
//! Loads music in a new thread
|
||||
void StartLoadingMusic();
|
||||
|
||||
protected:
|
||||
//! System utils instance
|
||||
CSystemUtils* m_systemUtils;
|
||||
|
@ -322,6 +330,8 @@ protected:
|
|||
std::unique_ptr<CInput> m_input;
|
||||
//! Path manager
|
||||
std::unique_ptr<CPathManager> m_pathManager;
|
||||
//! Mod manager
|
||||
std::unique_ptr<CModManager> m_modManager;
|
||||
|
||||
//! Code to return at exit
|
||||
int m_exitCode;
|
||||
|
|
|
@ -0,0 +1,358 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2020, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "app/modman.h"
|
||||
|
||||
#include "common/config.h"
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/pathman.h"
|
||||
|
||||
#include "common/config_file.h"
|
||||
#include "common/logger.h"
|
||||
|
||||
#include "common/resources/resourcemanager.h"
|
||||
|
||||
#include "level/parser/parser.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
using namespace boost::filesystem;
|
||||
|
||||
CModManager::CModManager(CApplication* app, CPathManager* pathManager)
|
||||
: m_app{app},
|
||||
m_pathManager{pathManager}
|
||||
{
|
||||
}
|
||||
|
||||
void CModManager::FindMods()
|
||||
{
|
||||
m_mods.clear();
|
||||
m_userChanges = false;
|
||||
|
||||
// Load names from the config file
|
||||
std::vector<std::string> savedModNames;
|
||||
GetConfigFile().GetArrayProperty("Mods", "Names", savedModNames);
|
||||
std::vector<bool> savedEnabled;
|
||||
GetConfigFile().GetArrayProperty("Mods", "Enabled", savedEnabled);
|
||||
|
||||
// Transform the data into Mod structures
|
||||
m_mods.reserve(savedModNames.size());
|
||||
for (size_t i = 0; i < savedModNames.size(); ++i)
|
||||
{
|
||||
Mod mod{};
|
||||
mod.name = savedModNames[i];
|
||||
if (i < savedEnabled.size())
|
||||
{
|
||||
mod.enabled = savedEnabled[i];
|
||||
}
|
||||
mod.path = ""; // Find the path later
|
||||
m_mods.push_back(mod);
|
||||
}
|
||||
|
||||
// Search the folders for mods
|
||||
auto rawPaths = m_pathManager->FindMods();
|
||||
std::map<std::string, std::string> modPaths;
|
||||
for (const auto& path : rawPaths)
|
||||
{
|
||||
auto modName = boost::filesystem::path(path).stem().string();
|
||||
modPaths.insert(std::make_pair(modName, path));
|
||||
}
|
||||
|
||||
// Find paths for already saved mods
|
||||
auto it = m_mods.begin();
|
||||
while (it != m_mods.end())
|
||||
{
|
||||
auto& mod = *it;
|
||||
const auto pathsIt = modPaths.find(mod.name);
|
||||
if (pathsIt != modPaths.end())
|
||||
{
|
||||
mod.path = (*pathsIt).second;
|
||||
modPaths.erase(pathsIt);
|
||||
++it;
|
||||
}
|
||||
else
|
||||
{
|
||||
GetLogger()->Warn("Could not find mod %s, removing it from the list\n", mod.name.c_str());
|
||||
it = m_mods.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the remaining found mods to the end of the list
|
||||
for (const auto& newMod : modPaths)
|
||||
{
|
||||
Mod mod{};
|
||||
mod.name = newMod.first;
|
||||
mod.path = newMod.second;
|
||||
m_mods.push_back(mod);
|
||||
}
|
||||
|
||||
// Load the metadata for each mod
|
||||
|
||||
// Unfortunately, the paths are distinguished by their real paths, not mount points
|
||||
// So we must unmount mods temporarily
|
||||
for (const auto& path : m_mountedModPaths)
|
||||
{
|
||||
UnmountMod(path);
|
||||
}
|
||||
|
||||
for (auto& mod : m_mods)
|
||||
{
|
||||
MountMod(mod, "/temp/mod");
|
||||
LoadModData(mod);
|
||||
UnmountMod(mod);
|
||||
}
|
||||
|
||||
// Mount back
|
||||
for (const auto& path : m_mountedModPaths)
|
||||
{
|
||||
MountMod(path);
|
||||
}
|
||||
}
|
||||
|
||||
void CModManager::ReloadMods()
|
||||
{
|
||||
UnmountAllMountedMods();
|
||||
MountAllMods();
|
||||
ReloadResources();
|
||||
}
|
||||
|
||||
void CModManager::EnableMod(size_t i)
|
||||
{
|
||||
m_mods[i].enabled = true;
|
||||
m_userChanges = true;
|
||||
}
|
||||
|
||||
void CModManager::DisableMod(size_t i)
|
||||
{
|
||||
m_mods[i].enabled = false;
|
||||
m_userChanges = true;
|
||||
}
|
||||
|
||||
size_t CModManager::MoveUp(size_t i)
|
||||
{
|
||||
if (i != 0)
|
||||
{
|
||||
std::swap(m_mods[i - 1], m_mods[i]);
|
||||
m_userChanges = true;
|
||||
return i - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
size_t CModManager::MoveDown(size_t i)
|
||||
{
|
||||
if (i != m_mods.size() - 1)
|
||||
{
|
||||
std::swap(m_mods[i], m_mods[i + 1]);
|
||||
m_userChanges = true;
|
||||
return i + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
bool CModManager::Changes()
|
||||
{
|
||||
std::vector<std::string> paths;
|
||||
for (const auto& mod : m_mods)
|
||||
{
|
||||
if (mod.enabled)
|
||||
{
|
||||
paths.push_back(mod.path);
|
||||
}
|
||||
}
|
||||
return paths != m_mountedModPaths || m_userChanges;
|
||||
}
|
||||
|
||||
void CModManager::MountAllMods()
|
||||
{
|
||||
for (const auto& mod : m_mods)
|
||||
{
|
||||
if (mod.enabled)
|
||||
{
|
||||
MountMod(mod);
|
||||
m_mountedModPaths.push_back(mod.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CModManager::ReloadResources()
|
||||
{
|
||||
m_app->ReloadResources();
|
||||
}
|
||||
|
||||
void CModManager::SaveMods()
|
||||
{
|
||||
std::vector<std::string> savedNames;
|
||||
savedNames.reserve(m_mods.size());
|
||||
std::transform(m_mods.begin(), m_mods.end(), std::back_inserter(savedNames), [](const Mod& mod) { return mod.name; });
|
||||
GetConfigFile().SetArrayProperty("Mods", "Names", savedNames);
|
||||
|
||||
std::vector<bool> savedEnabled;
|
||||
savedEnabled.reserve(m_mods.size());
|
||||
std::transform(m_mods.begin(), m_mods.end(), std::back_inserter(savedEnabled), [](const Mod& mod) { return mod.enabled; });
|
||||
GetConfigFile().SetArrayProperty("Mods", "Enabled", savedEnabled);
|
||||
|
||||
GetConfigFile().Save();
|
||||
|
||||
m_userChanges = false;
|
||||
}
|
||||
|
||||
size_t CModManager::CountMods() const
|
||||
{
|
||||
return m_mods.size();
|
||||
}
|
||||
|
||||
const Mod& CModManager::GetMod(size_t i) const
|
||||
{
|
||||
return m_mods[i];
|
||||
}
|
||||
|
||||
const std::vector<Mod>& CModManager::GetMods() const
|
||||
{
|
||||
return m_mods;
|
||||
}
|
||||
|
||||
void CModManager::LoadModData(Mod& mod)
|
||||
{
|
||||
auto& data = mod.data;
|
||||
|
||||
data.displayName = mod.name;
|
||||
|
||||
try
|
||||
{
|
||||
CLevelParser levelParser("temp/mod/manifest.txt");
|
||||
if (levelParser.Exists())
|
||||
{
|
||||
levelParser.Load();
|
||||
|
||||
CLevelParserLine* line = nullptr;
|
||||
|
||||
// DisplayName
|
||||
line = levelParser.GetIfDefined("DisplayName");
|
||||
if (line != nullptr && line->GetParam("text")->IsDefined())
|
||||
{
|
||||
data.displayName = line->GetParam("text")->AsString();
|
||||
}
|
||||
|
||||
// Author
|
||||
line = levelParser.GetIfDefined("Author");
|
||||
if (line != nullptr && line->GetParam("text")->IsDefined())
|
||||
{
|
||||
data.author = line->GetParam("text")->AsString();
|
||||
}
|
||||
|
||||
// Version
|
||||
line = levelParser.GetIfDefined("Version");
|
||||
if (line != nullptr)
|
||||
{
|
||||
if (line->GetParam("text")->IsDefined())
|
||||
{
|
||||
data.version = line->GetParam("text")->AsString();
|
||||
}
|
||||
else if (line->GetParam("major")->IsDefined() && line->GetParam("minor")->IsDefined() && line->GetParam("patch")->IsDefined())
|
||||
{
|
||||
auto major = boost::lexical_cast<std::string>(line->GetParam("major")->AsInt());
|
||||
auto minor = boost::lexical_cast<std::string>(line->GetParam("minor")->AsInt());
|
||||
auto patch = boost::lexical_cast<std::string>(line->GetParam("patch")->AsInt());
|
||||
data.version = boost::algorithm::join(std::vector<std::string>{ major, minor, patch }, ".");
|
||||
}
|
||||
}
|
||||
|
||||
// Website
|
||||
line = levelParser.GetIfDefined("Website");
|
||||
if (line != nullptr && line->GetParam("text")->IsDefined())
|
||||
{
|
||||
data.website = line->GetParam("text")->AsString();
|
||||
}
|
||||
|
||||
// Summary
|
||||
line = levelParser.GetIfDefined("Summary");
|
||||
if (line != nullptr && line->GetParam("text")->IsDefined())
|
||||
{
|
||||
data.summary = line->GetParam("text")->AsString();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GetLogger()->Warn("No manifest file for mod %s\n", mod.name.c_str());
|
||||
}
|
||||
}
|
||||
catch (CLevelParserException& e)
|
||||
{
|
||||
GetLogger()->Warn("Failed parsing manifest for mod %s: %s\n", mod.name.c_str(), e.what());
|
||||
}
|
||||
|
||||
// Changes
|
||||
data.changes = CResourceManager::ListDirectories("temp/mod");
|
||||
auto levelsIt = std::find(data.changes.begin(), data.changes.end(), "levels");
|
||||
if (levelsIt != data.changes.end())
|
||||
{
|
||||
auto levelsDirs = CResourceManager::ListDirectories("temp/mod/levels");
|
||||
if (!levelsDirs.empty())
|
||||
{
|
||||
std::transform(levelsDirs.begin(), levelsDirs.end(), levelsDirs.begin(), [](const std::string& dir) { return "levels/" + dir; });
|
||||
levelsIt = data.changes.erase(levelsIt);
|
||||
data.changes.insert(levelsIt, levelsDirs.begin(), levelsDirs.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CModManager::MountMod(const Mod& mod, const std::string& mountPoint)
|
||||
{
|
||||
MountMod(mod.path, mountPoint);
|
||||
}
|
||||
|
||||
void CModManager::MountMod(const std::string& path, const std::string& mountPoint)
|
||||
{
|
||||
GetLogger()->Debug("Mounting mod: '%s' at path %s\n", path.c_str(), mountPoint.c_str());
|
||||
CResourceManager::AddLocation(path, true, mountPoint);
|
||||
}
|
||||
|
||||
void CModManager::UnmountMod(const Mod& mod)
|
||||
{
|
||||
UnmountMod(mod.path);
|
||||
}
|
||||
|
||||
void CModManager::UnmountMod(const std::string& path)
|
||||
{
|
||||
if (CResourceManager::LocationExists(path))
|
||||
{
|
||||
GetLogger()->Debug("Unmounting mod: '%s'\n", path.c_str());
|
||||
CResourceManager::RemoveLocation(path);
|
||||
}
|
||||
}
|
||||
|
||||
void CModManager::UnmountAllMountedMods()
|
||||
{
|
||||
for (const auto& path : m_mountedModPaths)
|
||||
{
|
||||
UnmountMod(path);
|
||||
}
|
||||
m_mountedModPaths.clear();
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2020, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
class CApplication;
|
||||
class CPathManager;
|
||||
|
||||
struct ModData
|
||||
{
|
||||
std::string displayName{};
|
||||
std::string author{};
|
||||
std::string version{};
|
||||
std::string website{};
|
||||
std::string summary{};
|
||||
std::vector<std::string> changes{};
|
||||
};
|
||||
|
||||
struct Mod
|
||||
{
|
||||
std::string name{};
|
||||
std::string path{};
|
||||
bool enabled = false;
|
||||
ModData data{};
|
||||
};
|
||||
|
||||
/**
|
||||
* \class CModManager
|
||||
* \brief This class handles the list of mods.
|
||||
*
|
||||
* The order matters since the order in which files are loaded matters,
|
||||
* because some files can be overwritten.
|
||||
*
|
||||
* The changes in the list do not immediately apply.
|
||||
*/
|
||||
class CModManager
|
||||
{
|
||||
public:
|
||||
CModManager(CApplication* app, CPathManager* pathManager);
|
||||
|
||||
//! Finds all the mods along with their metadata
|
||||
void FindMods();
|
||||
|
||||
//! Applies the current configuration and reloads the application
|
||||
void ReloadMods();
|
||||
|
||||
//! Removes a mod from the list of loaded mods
|
||||
void EnableMod(size_t i);
|
||||
|
||||
//! Adds a mod to the list of loaded mods
|
||||
void DisableMod(size_t i);
|
||||
|
||||
//! Moves the selected mod up in the list so that it's loaded sooner than others, returns the new index
|
||||
size_t MoveUp(size_t i);
|
||||
|
||||
//! Moves the selected mod down in the list so that it's loaded later than others, returns the new index
|
||||
size_t MoveDown(size_t i);
|
||||
|
||||
//! Checks if the list of currently used mods differs from the current configuration or there were changes made by the user
|
||||
bool Changes();
|
||||
|
||||
//! Saves the current configuration of mods to the config file
|
||||
void SaveMods();
|
||||
|
||||
//! Number of mods loaded
|
||||
size_t CountMods() const;
|
||||
|
||||
//! Returns the reference to the mod in given position
|
||||
const Mod& GetMod(size_t i) const;
|
||||
|
||||
//! Returns the list of mods
|
||||
const std::vector<Mod>& GetMods() const;
|
||||
|
||||
private:
|
||||
// Allow access to MountAllMods() as CApplication doesn't want to reload itself during initialization
|
||||
friend CApplication;
|
||||
|
||||
//! Reloads application resources so the enabled mods are applied
|
||||
void ReloadResources();
|
||||
|
||||
//! Load mod data into mod
|
||||
void LoadModData(Mod& mod);
|
||||
|
||||
//! Updates the paths in Path Manager according to the current mod configuration
|
||||
void MountAllMods();
|
||||
|
||||
void MountMod(const Mod& mod, const std::string& mountPoint = "");
|
||||
void MountMod(const std::string& path, const std::string& mountPoint = "");
|
||||
void UnmountMod(const Mod& mod);
|
||||
void UnmountMod(const std::string& path);
|
||||
void UnmountAllMountedMods();
|
||||
|
||||
private:
|
||||
CApplication* m_app;
|
||||
CPathManager* m_pathManager;
|
||||
|
||||
//! Paths to mods already in the virtual filesystem
|
||||
std::vector<std::string> m_mountedModPaths;
|
||||
|
||||
//! List of mods
|
||||
std::vector<Mod> m_mods;
|
||||
|
||||
bool m_userChanges = false;
|
||||
};
|
|
@ -41,8 +41,7 @@ CPathManager::CPathManager(CSystemUtils* systemUtils)
|
|||
: m_dataPath(systemUtils->GetDataPath())
|
||||
, m_langPath(systemUtils->GetLangPath())
|
||||
, m_savePath(systemUtils->GetSaveDir())
|
||||
, m_modAutoloadDir{}
|
||||
, m_mods{}
|
||||
, m_modSearchDirs{}
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -65,16 +64,6 @@ void CPathManager::SetSavePath(const std::string &savePath)
|
|||
m_savePath = savePath;
|
||||
}
|
||||
|
||||
void CPathManager::AddModAutoloadDir(const std::string &modAutoloadDirPath)
|
||||
{
|
||||
m_modAutoloadDir.push_back(modAutoloadDirPath);
|
||||
}
|
||||
|
||||
void CPathManager::AddMod(const std::string &modPath)
|
||||
{
|
||||
m_mods.push_back(modPath);
|
||||
}
|
||||
|
||||
const std::string& CPathManager::GetDataPath()
|
||||
{
|
||||
return m_dataPath;
|
||||
|
@ -131,40 +120,18 @@ void CPathManager::InitPaths()
|
|||
GetLogger()->Info("Data path: %s\n", m_dataPath.c_str());
|
||||
GetLogger()->Info("Save path: %s\n", m_savePath.c_str());
|
||||
|
||||
m_modAutoloadDir.push_back(m_dataPath + "/mods");
|
||||
m_modAutoloadDir.push_back(m_savePath + "/mods");
|
||||
m_modSearchDirs.push_back(m_dataPath + "/mods");
|
||||
m_modSearchDirs.push_back(m_savePath + "/mods");
|
||||
|
||||
if (!m_modAutoloadDir.empty())
|
||||
if (!m_modSearchDirs.empty())
|
||||
{
|
||||
GetLogger()->Info("Mod autoload dirs:\n");
|
||||
for(const std::string& modAutoloadDir : m_modAutoloadDir)
|
||||
GetLogger()->Info(" * %s\n", modAutoloadDir.c_str());
|
||||
}
|
||||
if (!m_mods.empty())
|
||||
{
|
||||
GetLogger()->Info("Mods:\n");
|
||||
for(const std::string& modPath : m_mods)
|
||||
GetLogger()->Info(" * %s\n", modPath.c_str());
|
||||
GetLogger()->Info("Mod search dirs:\n");
|
||||
for(const std::string& modSearchDir : m_modSearchDirs)
|
||||
GetLogger()->Info(" * %s\n", modSearchDir.c_str());
|
||||
}
|
||||
|
||||
CResourceManager::AddLocation(m_dataPath);
|
||||
|
||||
for (const std::string& modAutoloadDir : m_modAutoloadDir)
|
||||
{
|
||||
GetLogger()->Trace("Searching for mods in '%s'...\n", modAutoloadDir.c_str());
|
||||
for (const std::string& modPath : FindModsInDir(modAutoloadDir))
|
||||
{
|
||||
GetLogger()->Info("Autoloading mod: '%s'\n", modPath.c_str());
|
||||
CResourceManager::AddLocation(modPath);
|
||||
}
|
||||
}
|
||||
|
||||
for (const std::string& modPath : m_mods)
|
||||
{
|
||||
GetLogger()->Info("Loading mod: '%s'\n", modPath.c_str());
|
||||
CResourceManager::AddLocation(modPath);
|
||||
}
|
||||
|
||||
CResourceManager::SetSaveLocation(m_savePath);
|
||||
CResourceManager::AddLocation(m_savePath);
|
||||
|
||||
|
@ -174,7 +141,45 @@ void CPathManager::InitPaths()
|
|||
GetLogger()->Debug(" * %s\n", path.c_str());
|
||||
}
|
||||
|
||||
std::vector<std::string> CPathManager::FindModsInDir(const std::string &dir)
|
||||
void CPathManager::AddMod(const std::string &path)
|
||||
{
|
||||
m_mods.push_back(path);
|
||||
}
|
||||
|
||||
std::vector<std::string> CPathManager::FindMods() const
|
||||
{
|
||||
std::vector<std::string> mods;
|
||||
GetLogger()->Info("Found mods:\n");
|
||||
for (const auto &searchPath : m_modSearchDirs)
|
||||
{
|
||||
for (const auto &modPath : FindModsInDir(searchPath))
|
||||
{
|
||||
GetLogger()->Info(" * %s\n", modPath.c_str());
|
||||
mods.push_back(modPath);
|
||||
}
|
||||
}
|
||||
GetLogger()->Info("Additional mod paths:\n");
|
||||
for (const auto& modPath : m_mods)
|
||||
{
|
||||
if (boost::filesystem::exists(modPath))
|
||||
{
|
||||
GetLogger()->Info(" * %s\n", modPath.c_str());
|
||||
mods.push_back(modPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetLogger()->Warn("Mod does not exist: %s\n", modPath.c_str());
|
||||
}
|
||||
}
|
||||
return mods;
|
||||
}
|
||||
|
||||
void CPathManager::AddModSearchDir(const std::string &modSearchDirPath)
|
||||
{
|
||||
m_modSearchDirs.push_back(modSearchDirPath);
|
||||
}
|
||||
|
||||
std::vector<std::string> CPathManager::FindModsInDir(const std::string &dir) const
|
||||
{
|
||||
std::vector<std::string> ret;
|
||||
try
|
||||
|
|
|
@ -37,8 +37,6 @@ public:
|
|||
void SetDataPath(const std::string &dataPath);
|
||||
void SetLangPath(const std::string &langPath);
|
||||
void SetSavePath(const std::string &savePath);
|
||||
void AddModAutoloadDir(const std::string &modAutoloadDirPath);
|
||||
void AddMod(const std::string &modPath);
|
||||
|
||||
const std::string& GetDataPath();
|
||||
const std::string& GetLangPath();
|
||||
|
@ -49,9 +47,15 @@ public:
|
|||
//! Loads configured paths
|
||||
void InitPaths();
|
||||
|
||||
//! Adds a path to a mod
|
||||
void AddMod(const std::string& path);
|
||||
//! Find paths to mods in mod search directories
|
||||
std::vector<std::string> FindMods() const;
|
||||
//! Adds a mod search directory
|
||||
void AddModSearchDir(const std::string &modSearchDirPath);
|
||||
|
||||
private:
|
||||
//! Loads all mods from given directory
|
||||
std::vector<std::string> FindModsInDir(const std::string &dir);
|
||||
std::vector<std::string> FindModsInDir(const std::string &dir) const;
|
||||
|
||||
private:
|
||||
//! Data path
|
||||
|
@ -60,8 +64,8 @@ private:
|
|||
std::string m_langPath;
|
||||
//! Save path
|
||||
std::string m_savePath;
|
||||
//! Mod autoload paths
|
||||
std::vector<std::string> m_modAutoloadDir;
|
||||
//! Mod paths
|
||||
//! Mod search paths
|
||||
std::vector<std::string> m_modSearchDirs;
|
||||
//! Additional mod paths
|
||||
std::vector<std::string> m_mods;
|
||||
};
|
||||
|
|
|
@ -26,9 +26,15 @@
|
|||
|
||||
#include "common/singleton.h"
|
||||
|
||||
#include "common/logger.h"
|
||||
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
/**
|
||||
|
@ -100,6 +106,76 @@ public:
|
|||
*/
|
||||
bool GetBoolProperty(std::string section, std::string key, bool &value);
|
||||
|
||||
/** Gets an array of values of type T in section under specified key
|
||||
* The value separator is ','.
|
||||
* \a array will only be changed if key exists
|
||||
* \return return true on success
|
||||
*/
|
||||
template<typename T>
|
||||
bool SetArrayProperty(std::string section, std::string key, const std::vector<T>& array)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::string convertedValue = ArrayToString(array);
|
||||
m_propertyTree.put(section + "." + key, convertedValue);
|
||||
m_needsSave = true;
|
||||
}
|
||||
catch (std::exception & e)
|
||||
{
|
||||
GetLogger()->Error("Error on editing config file: %s\n", e.what());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Sets an array of values of type T in section under specified key.
|
||||
* The value separator is ','.
|
||||
* \a array will only be changed if key exists
|
||||
* \return return true on success
|
||||
*/
|
||||
template<typename T>
|
||||
bool GetArrayProperty(std::string section, std::string key, std::vector<T>& array)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::string readValue = m_propertyTree.get<std::string>(section + "." + key);
|
||||
std::vector<T> convertedValue = StringToArray<T>(readValue);
|
||||
array = std::move(convertedValue);
|
||||
}
|
||||
catch (std::exception & e)
|
||||
{
|
||||
GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s\n", e.what());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename T>
|
||||
std::vector<T> StringToArray(const std::string& s)
|
||||
{
|
||||
std::vector<T> result;
|
||||
std::stringstream ss(s);
|
||||
std::string item;
|
||||
while (std::getline(ss, item, ','))
|
||||
{
|
||||
result.push_back(boost::lexical_cast<T>(item));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::string ArrayToString(const std::vector<T> &array)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
if (!array.empty())
|
||||
{
|
||||
std::copy(array.begin(), array.end() - 1, std::ostream_iterator<T>(oss, ","));
|
||||
oss << array.back();
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
private:
|
||||
boost::property_tree::ptree m_propertyTree;
|
||||
bool m_needsSave;
|
||||
|
|
|
@ -190,6 +190,7 @@ void InitializeEventTypeTexts()
|
|||
EVENT_TYPE_TEXT[EVENT_INTERFACE_ABORT] = "EVENT_INTERFACE_ABORT";
|
||||
EVENT_TYPE_TEXT[EVENT_INTERFACE_USER] = "EVENT_INTERFACE_USER";
|
||||
EVENT_TYPE_TEXT[EVENT_INTERFACE_SATCOM] = "EVENT_INTERFACE_SATCOM";
|
||||
EVENT_TYPE_TEXT[EVENT_INTERFACE_MODS] = "EVENT_INTERFACE_MODS";
|
||||
|
||||
EVENT_TYPE_TEXT[EVENT_INTERFACE_CHAP] = "EVENT_INTERFACE_CHAP";
|
||||
EVENT_TYPE_TEXT[EVENT_INTERFACE_LIST] = "EVENT_INTERFACE_LIST";
|
||||
|
@ -272,6 +273,16 @@ void InitializeEventTypeTexts()
|
|||
EVENT_TYPE_TEXT[EVENT_INTERFACE_JOYSTICK_CAM_Y_INVERT]= "EVENT_INTERFACE_JOYSTICK_CAM_Y_INVERT";
|
||||
EVENT_TYPE_TEXT[EVENT_INTERFACE_JOYSTICK_CAM_Z_INVERT]= "EVENT_INTERFACE_JOYSTICK_CAM_Z_INVERT";
|
||||
|
||||
EVENT_TYPE_TEXT[EVENT_INTERFACE_MOD_LIST] = "EVENT_INTERFACE_MOD_LIST";
|
||||
EVENT_TYPE_TEXT[EVENT_INTERFACE_WORKSHOP] = "EVENT_INTERFACE_WORKSHOP";
|
||||
EVENT_TYPE_TEXT[EVENT_INTERFACE_MODS_DIR] = "EVENT_INTERFACE_MODS_DIR";
|
||||
EVENT_TYPE_TEXT[EVENT_INTERFACE_MOD_ENABLE_OR_DISABLE] = "EVENT_INTERFACE_MOD_ENABLE_OR_DISABLE";
|
||||
EVENT_TYPE_TEXT[EVENT_INTERFACE_MODS_APPLY] = "EVENT_INTERFACE_MODS_APPLY";
|
||||
EVENT_TYPE_TEXT[EVENT_INTERFACE_MOD_DETAILS] = "EVENT_INTERFACE_MOD_DETAILS";
|
||||
EVENT_TYPE_TEXT[EVENT_INTERFACE_MOD_MOVE_UP] = "EVENT_INTERFACE_MOD_MOVE_UP";
|
||||
EVENT_TYPE_TEXT[EVENT_INTERFACE_MOD_MOVE_DOWN] = "EVENT_INTERFACE_MOD_MOVE_DOWN";
|
||||
EVENT_TYPE_TEXT[EVENT_INTERFACE_MODS_REFRESH] = "EVENT_INTERFACE_MODS_REFRESH";
|
||||
|
||||
EVENT_TYPE_TEXT[EVENT_INTERFACE_GLINTl] = "EVENT_INTERFACE_GLINTl";
|
||||
EVENT_TYPE_TEXT[EVENT_INTERFACE_GLINTr] = "EVENT_INTERFACE_GLINTr";
|
||||
EVENT_TYPE_TEXT[EVENT_INTERFACE_GLINTu] = "EVENT_INTERFACE_GLINTu";
|
||||
|
|
|
@ -225,6 +225,7 @@ enum EventType
|
|||
EVENT_INTERFACE_ABORT = 412,
|
||||
EVENT_INTERFACE_USER = 413,
|
||||
EVENT_INTERFACE_SATCOM = 414,
|
||||
EVENT_INTERFACE_MODS = 416,
|
||||
|
||||
EVENT_INTERFACE_CHAP = 420,
|
||||
EVENT_INTERFACE_LIST = 421,
|
||||
|
@ -311,6 +312,17 @@ enum EventType
|
|||
EVENT_INTERFACE_JOYSTICK_CAM_Y_INVERT = 573,
|
||||
EVENT_INTERFACE_JOYSTICK_CAM_Z_INVERT = 574,
|
||||
|
||||
EVENT_INTERFACE_MOD_LIST = 580,
|
||||
EVENT_INTERFACE_WORKSHOP = 581,
|
||||
EVENT_INTERFACE_MODS_DIR = 582,
|
||||
EVENT_INTERFACE_MOD_ENABLE_OR_DISABLE = 583,
|
||||
EVENT_INTERFACE_MODS_APPLY = 584,
|
||||
EVENT_INTERFACE_MOD_SUMMARY = 585,
|
||||
EVENT_INTERFACE_MOD_DETAILS = 586,
|
||||
EVENT_INTERFACE_MOD_MOVE_UP = 587,
|
||||
EVENT_INTERFACE_MOD_MOVE_DOWN = 888,
|
||||
EVENT_INTERFACE_MODS_REFRESH = 589,
|
||||
|
||||
EVENT_INTERFACE_GLINTl = 590,
|
||||
EVENT_INTERFACE_GLINTr = 591,
|
||||
EVENT_INTERFACE_GLINTu = 592,
|
||||
|
|
|
@ -62,9 +62,9 @@ std::string CResourceManager::CleanPath(const std::string& path)
|
|||
}
|
||||
|
||||
|
||||
bool CResourceManager::AddLocation(const std::string &location, bool prepend)
|
||||
bool CResourceManager::AddLocation(const std::string &location, bool prepend, const std::string &mountPoint)
|
||||
{
|
||||
if (!PHYSFS_mount(location.c_str(), nullptr, prepend ? 0 : 1))
|
||||
if (!PHYSFS_mount(location.c_str(), mountPoint.c_str(), prepend ? 0 : 1))
|
||||
{
|
||||
GetLogger()->Error("Error while mounting \"%s\": %s\n", location.c_str(), PHYSFS_getLastError());
|
||||
return false;
|
||||
|
@ -95,6 +95,12 @@ std::vector<std::string> CResourceManager::GetLocations()
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool CResourceManager::LocationExists(const std::string& location)
|
||||
{
|
||||
auto locations = GetLocations();
|
||||
auto it = std::find(locations.cbegin(), locations.cend(), location);
|
||||
return it != locations.cend();
|
||||
}
|
||||
|
||||
bool CResourceManager::SetSaveLocation(const std::string &location)
|
||||
{
|
||||
|
|
|
@ -36,11 +36,13 @@ public:
|
|||
static std::string CleanPath(const std::string &path);
|
||||
|
||||
//! Add a location to the search path
|
||||
static bool AddLocation(const std::string &location, bool prepend = true);
|
||||
static bool AddLocation(const std::string &location, bool prepend = true, const std::string &mountPoint = "");
|
||||
//! Remove a location from the search path
|
||||
static bool RemoveLocation(const std::string &location);
|
||||
//! List all locations in the search path
|
||||
static std::vector<std::string> GetLocations();
|
||||
//! Check if given location is in the search path
|
||||
static bool LocationExists(const std::string &location);
|
||||
|
||||
static bool SetSaveLocation(const std::string &location);
|
||||
static std::string GetSaveLocation();
|
||||
|
|
|
@ -71,12 +71,13 @@ void InitializeRestext()
|
|||
stringsText[RT_TITLE_MISSION] = TR("Missions");
|
||||
stringsText[RT_TITLE_FREE] = TR("Free game");
|
||||
stringsText[RT_TITLE_USER] = TR("User levels");
|
||||
stringsText[RT_TITLE_CODE_BATTLES]=TR("Code battles");
|
||||
stringsText[RT_TITLE_CODE_BATTLES] = TR("Code battles");
|
||||
stringsText[RT_TITLE_SETUP] = TR("Options");
|
||||
stringsText[RT_TITLE_NAME] = TR("Player's name");
|
||||
stringsText[RT_TITLE_PERSO] = TR("Customize your appearance");
|
||||
stringsText[RT_TITLE_WRITE] = TR("Save the current mission");
|
||||
stringsText[RT_TITLE_READ] = TR("Load a saved mission");
|
||||
stringsText[RT_TITLE_MODS] = TR("Mods");
|
||||
|
||||
stringsText[RT_PLAY_CHAP_CHAPTERS] = TR("Chapters:");
|
||||
stringsText[RT_PLAY_CHAP_PLANETS] = TR("Planets:");
|
||||
|
@ -108,6 +109,11 @@ void InitializeRestext()
|
|||
stringsText[RT_DIALOG_OK] = TR("OK");
|
||||
stringsText[RT_DIALOG_NOUSRLVL_TITLE] = TR("No userlevels installed!");
|
||||
stringsText[RT_DIALOG_NOUSRLVL_TEXT] = TR("This menu is for userlevels from mods, but you didn't install any");
|
||||
stringsText[RT_DIALOG_OPEN_PATH_FAILED_TITLE] = TR("Could not open the file explorer!");
|
||||
stringsText[RT_DIALOG_OPEN_PATH_FAILED_TEXT] = TR("The path %s could not be opened in a file explorer.");
|
||||
stringsText[RT_DIALOG_OPEN_WEBSITE_FAILED_TITLE] = TR("Could not open the web browser!");
|
||||
stringsText[RT_DIALOG_OPEN_WEBSITE_FAILED_TEXT] = TR("The address %s could not be opened in a web browser.");
|
||||
stringsText[RT_DIALOG_CHANGES_QUESTION] = TR("There are unsaved changes. Do you want to save them before leaving?");
|
||||
|
||||
stringsText[RT_STUDIO_LISTTT] = TR("Keyword help(\\key cbot;)");
|
||||
stringsText[RT_STUDIO_COMPOK] = TR("Compilation ok (0 errors)");
|
||||
|
@ -153,7 +159,18 @@ void InitializeRestext()
|
|||
stringsText[RT_SCOREBOARD_RESULTS_TIME]= TR("Time: %s");
|
||||
stringsText[RT_SCOREBOARD_RESULTS_LINE]= TR("%s: %d pts");
|
||||
|
||||
|
||||
stringsText[RT_MOD_LIST] = TR("Mods:");
|
||||
stringsText[RT_MOD_DETAILS] = TR("Information:");
|
||||
stringsText[RT_MOD_SUMMARY] = TR("Description:");
|
||||
stringsText[RT_MOD_ENABLE] = TR("Enable\\Enable the selected mod");
|
||||
stringsText[RT_MOD_DISABLE] = TR("Disable\\Disable the selected mod");
|
||||
stringsText[RT_MOD_UNKNOWN_AUTHOR] = TR("Unknown author");
|
||||
stringsText[RT_MOD_AUTHOR_FIELD_NAME] = TR("by");
|
||||
stringsText[RT_MOD_VERSION_FIELD_NAME] = TR("Version");
|
||||
stringsText[RT_MOD_WEBSITE_FIELD_NAME] = TR("Website");
|
||||
stringsText[RT_MOD_CHANGES_FIELD_NAME] = TR("Changes");
|
||||
stringsText[RT_MOD_NO_SUMMARY] = TR("No description.");
|
||||
stringsText[RT_MOD_NO_CHANGES] = TR("No changes.");
|
||||
|
||||
stringsEvent[EVENT_LABEL_CODE_BATTLE] = TR("Code battle");
|
||||
|
||||
|
@ -173,6 +190,7 @@ void InitializeRestext()
|
|||
stringsEvent[EVENT_INTERFACE_CODE_BATTLES] = TR("Code battles\\Program your robot to be the best of them all!");
|
||||
stringsEvent[EVENT_INTERFACE_USER] = TR("Custom levels\\Levels from mods created by the users");
|
||||
stringsEvent[EVENT_INTERFACE_SATCOM] = TR("SatCom");
|
||||
stringsEvent[EVENT_INTERFACE_MODS] = TR("Mods\\Mod manager");
|
||||
stringsEvent[EVENT_INTERFACE_NAME] = TR("Change player\\Change player");
|
||||
stringsEvent[EVENT_INTERFACE_SETUP] = TR("Options\\Preferences");
|
||||
stringsEvent[EVENT_INTERFACE_AGAIN] = TR("Restart\\Restart the mission from the beginning");
|
||||
|
@ -182,6 +200,12 @@ void InitializeRestext()
|
|||
stringsEvent[EVENT_INTERFACE_QUIT] = TR("Quit\\Quit Colobot: Gold Edition");
|
||||
stringsEvent[EVENT_INTERFACE_BACK] = TR("<< Back \\Back to the previous screen");
|
||||
stringsEvent[EVENT_INTERFACE_PLAY] = TR("Play\\Start mission!");
|
||||
stringsEvent[EVENT_INTERFACE_WORKSHOP] = TR("Workshop\\Open the workshop to search for mods");
|
||||
stringsEvent[EVENT_INTERFACE_MODS_DIR] = TR("Open Directory\\Open the mods directory");
|
||||
stringsEvent[EVENT_INTERFACE_MODS_APPLY] = TR("Apply\\Apply the current mod configuration");
|
||||
stringsEvent[EVENT_INTERFACE_MOD_MOVE_UP] = TR("Up\\Move the selected mod up so it's loaded sooner (mods may overwrite files from the mods above them)");
|
||||
stringsEvent[EVENT_INTERFACE_MOD_MOVE_DOWN] = TR("Down\\Move the selected mod down so it's loaded later (mods may overwrite files from the mods above them)");
|
||||
stringsEvent[EVENT_INTERFACE_MODS_REFRESH] = TR("Refresh\\Refresh the list of currently installed mods");
|
||||
stringsEvent[EVENT_INTERFACE_SETUPd] = TR("Device\\Driver and resolution settings");
|
||||
stringsEvent[EVENT_INTERFACE_SETUPg] = TR("Graphics\\Graphics settings");
|
||||
stringsEvent[EVENT_INTERFACE_SETUPp] = TR("Game\\Game settings");
|
||||
|
|
|
@ -71,6 +71,7 @@ enum ResTextType
|
|||
RT_TITLE_WRITE = 50,
|
||||
RT_TITLE_READ = 51,
|
||||
RT_TITLE_USER = 52,
|
||||
RT_TITLE_MODS = 54,
|
||||
|
||||
RT_PLAY_CHAP_CHAPTERS = 60,
|
||||
RT_PLAY_CHAP_PLANETS = 61,
|
||||
|
@ -102,6 +103,11 @@ enum ResTextType
|
|||
RT_DIALOG_OK = 110,
|
||||
RT_DIALOG_NOUSRLVL_TITLE = 111,
|
||||
RT_DIALOG_NOUSRLVL_TEXT = 112,
|
||||
RT_DIALOG_OPEN_PATH_FAILED_TITLE = 113,
|
||||
RT_DIALOG_OPEN_PATH_FAILED_TEXT = 114,
|
||||
RT_DIALOG_OPEN_WEBSITE_FAILED_TITLE = 115,
|
||||
RT_DIALOG_OPEN_WEBSITE_FAILED_TEXT = 116,
|
||||
RT_DIALOG_CHANGES_QUESTION = 117,
|
||||
|
||||
RT_STUDIO_LISTTT = 120,
|
||||
RT_STUDIO_COMPOK = 121,
|
||||
|
@ -147,6 +153,18 @@ enum ResTextType
|
|||
RT_SCOREBOARD_RESULTS_TIME= 232,
|
||||
RT_SCOREBOARD_RESULTS_LINE= 233,
|
||||
|
||||
RT_MOD_LIST = 234,
|
||||
RT_MOD_DETAILS = 235,
|
||||
RT_MOD_SUMMARY = 236,
|
||||
RT_MOD_ENABLE = 237,
|
||||
RT_MOD_DISABLE = 238,
|
||||
RT_MOD_UNKNOWN_AUTHOR = 239,
|
||||
RT_MOD_AUTHOR_FIELD_NAME = 240,
|
||||
RT_MOD_VERSION_FIELD_NAME = 241,
|
||||
RT_MOD_WEBSITE_FIELD_NAME = 242,
|
||||
RT_MOD_CHANGES_FIELD_NAME = 243,
|
||||
RT_MOD_NO_SUMMARY = 244,
|
||||
RT_MOD_NO_CHANGES = 245,
|
||||
|
||||
RT_MAX //! < number of values
|
||||
};
|
||||
|
|
|
@ -215,3 +215,13 @@ std::string CSystemUtils::GetEnvVar(const std::string& name)
|
|||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
bool CSystemUtils::OpenPath(const std::string& path)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSystemUtils::OpenWebsite(const std::string& url)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -145,6 +145,14 @@ public:
|
|||
//! Returns the environment variable with the given name or an empty string if it does not exist
|
||||
virtual std::string GetEnvVar(const std::string &name);
|
||||
|
||||
//! Opens a path with default file browser
|
||||
/** \returns true if successful */
|
||||
virtual bool OpenPath(const std::string& path);
|
||||
|
||||
//! Opens a website with default web browser
|
||||
/** \returns true if successful */
|
||||
virtual bool OpenWebsite(const std::string& url);
|
||||
|
||||
//! Sleep for given amount of microseconds
|
||||
virtual void Usleep(int usecs) = 0;
|
||||
|
||||
|
|
|
@ -150,6 +150,28 @@ std::string CSystemUtilsLinux::GetEnvVar(const std::string& name)
|
|||
return "";
|
||||
}
|
||||
|
||||
bool CSystemUtilsLinux::OpenPath(const std::string& path)
|
||||
{
|
||||
int result = system(("xdg-open \"" + path + "\"").c_str());
|
||||
if (result != 0)
|
||||
{
|
||||
GetLogger()->Error("Failed to open path: %s, error code: %i\n", path.c_str(), result);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSystemUtilsLinux::OpenWebsite(const std::string& url)
|
||||
{
|
||||
int result = system(("xdg-open \"" + url + "\"").c_str());
|
||||
if (result != 0)
|
||||
{
|
||||
GetLogger()->Error("Failed to open website: %s, error code: %i\n", url.c_str(), result);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CSystemUtilsLinux::Usleep(int usec)
|
||||
{
|
||||
usleep(usec);
|
||||
|
|
|
@ -48,6 +48,9 @@ public:
|
|||
|
||||
std::string GetEnvVar(const std::string& name) override;
|
||||
|
||||
bool OpenPath(const std::string& path) override;
|
||||
bool OpenWebsite(const std::string& url) override;
|
||||
|
||||
void Usleep(int usec) override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -119,6 +119,28 @@ std::string CSystemUtilsMacOSX::GetEnvVar(const std::string& str)
|
|||
return std::string();
|
||||
}
|
||||
|
||||
bool CSystemUtilsMacOSX::OpenPath(const std::string& path)
|
||||
{
|
||||
int result = system(("open \"" + path + "\"").c_str()); // TODO: Test on macOS
|
||||
if (result != 0)
|
||||
{
|
||||
GetLogger()->Error("Failed to open path: %s, error code: %i\n", path.c_str(), result);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSystemUtilsMacOSX::OpenWebsite(const std::string& url)
|
||||
{
|
||||
int result = system(("open \"" + url + "\"").c_str()); // TODO: Test on macOS
|
||||
if (result != 0)
|
||||
{
|
||||
GetLogger()->Error("Failed to open website: %s, error code: %i\n", website.c_str(), result);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CSystemUtilsMacOSX::Usleep(int usec)
|
||||
{
|
||||
usleep(usec);
|
||||
|
|
|
@ -38,6 +38,9 @@ public:
|
|||
|
||||
std::string GetEnvVar(const std::string& name) override;
|
||||
|
||||
bool OpenPath(const std::string& path) override;
|
||||
bool OpenWebsite(const std::string& url) override;
|
||||
|
||||
void Usleep(int usec) override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "common/logger.h"
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
|
@ -152,6 +153,28 @@ std::string CSystemUtilsWindows::GetEnvVar(const std::string& name)
|
|||
}
|
||||
}
|
||||
|
||||
bool CSystemUtilsWindows::OpenPath(const std::string& path)
|
||||
{
|
||||
int result = system(("start explorer \"" + boost::filesystem::path(path).make_preferred().string() + "\"").c_str());
|
||||
if (result != 0)
|
||||
{
|
||||
GetLogger()->Error("Failed to open path: %s, error code: %i\n", path.c_str(), result);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSystemUtilsWindows::OpenWebsite(const std::string& url)
|
||||
{
|
||||
int result = system(("rundll32 url.dll,FileProtocolHandler \"" + url + "\"").c_str());
|
||||
if (result != 0)
|
||||
{
|
||||
GetLogger()->Error("Failed to open website: %s, error code: %i\n", url.c_str(), result);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CSystemUtilsWindows::Usleep(int usec)
|
||||
{
|
||||
LARGE_INTEGER ft;
|
||||
|
|
|
@ -46,6 +46,9 @@ public:
|
|||
|
||||
std::string GetEnvVar(const std::string& name) override;
|
||||
|
||||
bool OpenPath(const std::string& path) override;
|
||||
bool OpenWebsite(const std::string& url) override;
|
||||
|
||||
void Usleep(int usec) override;
|
||||
|
||||
public:
|
||||
|
|
|
@ -408,6 +408,7 @@ void CEngine::ReloadAllTextures()
|
|||
{
|
||||
FlushTextureCache();
|
||||
m_text->FlushCache();
|
||||
m_text->ReloadFonts();
|
||||
|
||||
m_app->GetEventQueue()->AddEvent(Event(EVENT_RELOAD_TEXTURES));
|
||||
UpdateGroundSpotTextures();
|
||||
|
|
|
@ -1189,6 +1189,10 @@ public:
|
|||
void EnablePauseBlur();
|
||||
void DisablePauseBlur();
|
||||
|
||||
//! Reloads all textures
|
||||
/** This additionally sends EVENT_RELOAD_TEXTURES to reload all textures not maintained by CEngine **/
|
||||
void ReloadAllTextures();
|
||||
|
||||
protected:
|
||||
//! Resets some states and flushes textures after device was changed (e.g. resoulution changed)
|
||||
/** Instead of calling this directly, send EVENT_RESOLUTION_CHANGED event **/
|
||||
|
@ -1287,10 +1291,6 @@ protected:
|
|||
};
|
||||
static void WriteScreenShotThread(std::unique_ptr<WriteScreenShotData> data);
|
||||
|
||||
//! Reloads all textures
|
||||
/** This additionally sends EVENT_RELOAD_TEXTURES to reload all textures not maintained by CEngine **/
|
||||
void ReloadAllTextures();
|
||||
|
||||
protected:
|
||||
CApplication* m_app;
|
||||
CSystemUtils* m_systemUtils;
|
||||
|
|
|
@ -191,17 +191,32 @@ CText::~CText()
|
|||
|
||||
bool CText::Create()
|
||||
{
|
||||
CFontLoader fontLoader;
|
||||
if (!fontLoader.Init())
|
||||
{
|
||||
GetLogger()->Debug("Error on parsing fonts config file: failed to open file\n");
|
||||
}
|
||||
if (TTF_Init() != 0)
|
||||
{
|
||||
m_error = std::string("TTF_Init error: ") + std::string(TTF_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ReloadFonts())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CText::ReloadFonts()
|
||||
{
|
||||
CFontLoader fontLoader;
|
||||
if (!fontLoader.Init())
|
||||
{
|
||||
GetLogger()->Debug("Error on parsing fonts config file: failed to open file\n");
|
||||
}
|
||||
|
||||
// Backup previous fonts
|
||||
auto fonts = std::move(m_fonts);
|
||||
m_fonts.clear();
|
||||
|
||||
for (auto type : {FONT_COMMON, FONT_STUDIO, FONT_SATCOM})
|
||||
{
|
||||
m_fonts[static_cast<Gfx::FontType>(type)] = MakeUnique<MultisizeFont>(fontLoader.GetFont(type));
|
||||
|
@ -214,7 +229,10 @@ bool CText::Create()
|
|||
FontType type = (*it).first;
|
||||
CachedFont* cf = GetOrOpenFont(type, m_defaultSize);
|
||||
if (cf == nullptr || cf->font == nullptr)
|
||||
{
|
||||
m_fonts = std::move(fonts);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -256,6 +256,8 @@ public:
|
|||
|
||||
//! Flushes cached textures
|
||||
void FlushCache();
|
||||
//! Try to load new font files
|
||||
bool ReloadFonts();
|
||||
|
||||
//@{
|
||||
//! Tab size management
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include <boost/algorithm/string/trim.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
CLevelParser::CLevelParser()
|
||||
{
|
||||
|
@ -172,13 +173,28 @@ void CLevelParser::Load()
|
|||
boost::replace_all(line, "\t", " "); // replace tab by space
|
||||
|
||||
// ignore comments
|
||||
std::size_t comment = line.find("//");
|
||||
if (comment != std::string::npos)
|
||||
line = line.substr(0, comment);
|
||||
size_t pos = 0;
|
||||
std::string linesuffix = line;
|
||||
boost::regex commentRegex{ R"(("[^"]*")|('[^']*')|(//.*$))" };
|
||||
boost::smatch matches;
|
||||
while (boost::regex_search(linesuffix, matches, commentRegex))
|
||||
{
|
||||
if (matches[3].matched)
|
||||
{
|
||||
pos += std::distance(linesuffix.cbegin(), matches.prefix().second);
|
||||
line = line.substr(0, pos);
|
||||
linesuffix = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
pos += std::distance(linesuffix.cbegin(), matches.suffix().first);
|
||||
linesuffix = matches.suffix().str();
|
||||
}
|
||||
}
|
||||
|
||||
boost::algorithm::trim(line);
|
||||
|
||||
std::size_t pos = line.find_first_of(" \t\n");
|
||||
pos = line.find_first_of(" \t\n");
|
||||
std::string command = line.substr(0, pos);
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
|
|
|
@ -320,6 +320,7 @@ std::string PhaseToString(Phase phase)
|
|||
if (phase == PHASE_APPERANCE) return "PHASE_APPERANCE";
|
||||
if (phase == PHASE_MAIN_MENU) return "PHASE_MAIN_MENU";
|
||||
if (phase == PHASE_LEVEL_LIST) return "PHASE_LEVEL_LIST";
|
||||
if (phase == PHASE_MOD_LIST) return "PHASE_MOD_LIST";
|
||||
if (phase == PHASE_SIMUL) return "PHASE_SIMUL";
|
||||
if (phase == PHASE_SETUPd) return "PHASE_SETUPd";
|
||||
if (phase == PHASE_SETUPg) return "PHASE_SETUPg";
|
||||
|
@ -3911,6 +3912,7 @@ void CRobotMain::ChangeColor()
|
|||
m_phase != PHASE_SETUPps &&
|
||||
m_phase != PHASE_SETUPcs &&
|
||||
m_phase != PHASE_SETUPss &&
|
||||
m_phase != PHASE_MOD_LIST &&
|
||||
m_phase != PHASE_WIN &&
|
||||
m_phase != PHASE_LOST &&
|
||||
m_phase != PHASE_APPERANCE ) return;
|
||||
|
|
|
@ -55,6 +55,7 @@ enum Phase
|
|||
PHASE_APPERANCE,
|
||||
PHASE_MAIN_MENU,
|
||||
PHASE_LEVEL_LIST,
|
||||
PHASE_MOD_LIST,
|
||||
PHASE_SIMUL,
|
||||
PHASE_SETUPd,
|
||||
PHASE_SETUPg,
|
||||
|
|
|
@ -47,22 +47,7 @@ void CALSound::CleanUp()
|
|||
if (m_enabled)
|
||||
{
|
||||
GetLogger()->Info("Unloading files and closing device...\n");
|
||||
StopAll();
|
||||
StopMusic();
|
||||
|
||||
m_channels.clear();
|
||||
|
||||
m_currentMusic.reset();
|
||||
|
||||
m_oldMusic.clear();
|
||||
|
||||
m_previousMusic.music.reset();
|
||||
|
||||
m_sounds.clear();
|
||||
|
||||
m_music.clear();
|
||||
|
||||
m_enabled = false;
|
||||
Reset();
|
||||
|
||||
alcDestroyContext(m_context);
|
||||
alcCloseDevice(m_device);
|
||||
|
@ -99,6 +84,24 @@ bool CALSound::Create()
|
|||
return true;
|
||||
}
|
||||
|
||||
void CALSound::Reset()
|
||||
{
|
||||
StopAll();
|
||||
StopMusic();
|
||||
|
||||
m_channels.clear();
|
||||
|
||||
m_currentMusic.reset();
|
||||
|
||||
m_oldMusic.clear();
|
||||
|
||||
m_previousMusic.music.reset();
|
||||
|
||||
m_sounds.clear();
|
||||
|
||||
m_music.clear();
|
||||
}
|
||||
|
||||
bool CALSound::GetEnable()
|
||||
{
|
||||
return m_enabled;
|
||||
|
|
|
@ -84,6 +84,7 @@ public:
|
|||
~CALSound();
|
||||
|
||||
bool Create() override;
|
||||
void Reset() override;
|
||||
bool Cache(SoundType, const std::string &) override;
|
||||
void CacheMusic(const std::string &) override;
|
||||
bool IsCached(SoundType) override;
|
||||
|
|
|
@ -52,6 +52,10 @@ void CSoundInterface::CacheAll()
|
|||
}
|
||||
}
|
||||
|
||||
void CSoundInterface::Reset()
|
||||
{
|
||||
}
|
||||
|
||||
bool CSoundInterface::Cache(SoundType sound, const std::string &file)
|
||||
{
|
||||
return true;
|
||||
|
|
|
@ -72,6 +72,10 @@ public:
|
|||
*/
|
||||
void CacheAll();
|
||||
|
||||
/** Stop all sounds and music and clean cache.
|
||||
*/
|
||||
virtual void Reset();
|
||||
|
||||
/** Function called to cache sound effect file.
|
||||
* This function is called by plugin interface for each file.
|
||||
* \param sound - id of a file, will be used to identify sound files
|
||||
|
|
|
@ -1299,7 +1299,9 @@ void CEdit::SetText(const std::string& text, bool bNew)
|
|||
if( m_len >= GetMaxChar() ) m_len = GetMaxChar();
|
||||
|
||||
m_text.resize( m_len + 1, '\0' );
|
||||
m_text[m_len] = '\0';
|
||||
m_format.resize( m_len + 1, m_fontType );
|
||||
m_format[m_len] = m_fontType;
|
||||
|
||||
font = m_fontType;
|
||||
j = 0;
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "ui/screen/screen_level_list.h"
|
||||
#include "ui/screen/screen_loading.h"
|
||||
#include "ui/screen/screen_main_menu.h"
|
||||
#include "ui/screen/screen_mod_list.h"
|
||||
#include "ui/screen/screen_player_select.h"
|
||||
#include "ui/screen/screen_quit.h"
|
||||
#include "ui/screen/screen_setup_controls.h"
|
||||
|
@ -80,6 +81,7 @@ CMainUserInterface::CMainUserInterface()
|
|||
m_screenIORead = MakeUnique<CScreenIORead>(m_screenLevelList.get());
|
||||
m_screenIOWrite = MakeUnique<CScreenIOWrite>(m_screenLevelList.get());
|
||||
m_screenLoading = MakeUnique<CScreenLoading>();
|
||||
m_screenModList = MakeUnique<CScreenModList>(m_dialog.get(), m_app->GetModManager());
|
||||
m_screenSetupControls = MakeUnique<CScreenSetupControls>();
|
||||
m_screenSetupDisplay = MakeUnique<CScreenSetupDisplay>();
|
||||
m_screenSetupGame = MakeUnique<CScreenSetupGame>();
|
||||
|
@ -184,6 +186,10 @@ void CMainUserInterface::ChangePhase(Phase phase)
|
|||
m_screenLevelList->SetLevelCategory(m_main->GetLevelCategory());
|
||||
m_currentScreen = m_screenLevelList.get();
|
||||
}
|
||||
if (m_phase == PHASE_MOD_LIST)
|
||||
{
|
||||
m_currentScreen = m_screenModList.get();
|
||||
}
|
||||
if (m_phase >= PHASE_SETUPd && m_phase <= PHASE_SETUPs)
|
||||
{
|
||||
CScreenSetup* screenSetup = GetSetupScreen(m_phase);
|
||||
|
@ -531,6 +537,7 @@ void CMainUserInterface::FrameParticle(float rTime)
|
|||
}
|
||||
else if ( m_phase == PHASE_PLAYER_SELECT ||
|
||||
m_phase == PHASE_LEVEL_LIST ||
|
||||
m_phase == PHASE_MOD_LIST ||
|
||||
m_phase == PHASE_SETUPd ||
|
||||
m_phase == PHASE_SETUPg ||
|
||||
m_phase == PHASE_SETUPp ||
|
||||
|
|
|
@ -50,6 +50,7 @@ class CScreenIOWrite;
|
|||
class CScreenLevelList;
|
||||
class CScreenLoading;
|
||||
class CScreenMainMenu;
|
||||
class CScreenModList;
|
||||
class CScreenPlayerSelect;
|
||||
class CScreenQuit;
|
||||
class CScreenSetup;
|
||||
|
@ -114,6 +115,7 @@ protected:
|
|||
std::unique_ptr<CScreenLevelList> m_screenLevelList;
|
||||
std::unique_ptr<CScreenLoading> m_screenLoading;
|
||||
std::unique_ptr<CScreenMainMenu> m_screenMainMenu;
|
||||
std::unique_ptr<CScreenModList> m_screenModList;
|
||||
std::unique_ptr<CScreenPlayerSelect> m_screenPlayerSelect;
|
||||
std::unique_ptr<CScreenQuit> m_screenQuit;
|
||||
std::unique_ptr<CScreenSetupControls> m_screenSetupControls;
|
||||
|
|
|
@ -170,6 +170,13 @@ void CScreenMainMenu::CreateInterface()
|
|||
pb = pw->CreateButton(pos, ddim, 128+60, EVENT_INTERFACE_SATCOM);
|
||||
pb->SetState(STATE_SHADOW);
|
||||
|
||||
// Mods button
|
||||
pos.x = 447.0f/640.0f;
|
||||
pos.y = 313.0f/480.0f;
|
||||
ddim.x = 0.09f;
|
||||
pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_MODS);
|
||||
pb->SetState(STATE_SHADOW);
|
||||
|
||||
SetBackground("textures/interface/interface.png");
|
||||
CreateVersionDisplay();
|
||||
}
|
||||
|
@ -235,6 +242,9 @@ bool CScreenMainMenu::EventProcess(const Event &event)
|
|||
m_main->ChangePhase(PHASE_SATCOM);
|
||||
break;
|
||||
|
||||
case EVENT_INTERFACE_MODS:
|
||||
m_main->ChangePhase(PHASE_MOD_LIST);
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,582 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2020, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "ui/screen/screen_mod_list.h"
|
||||
|
||||
#include "common/config.h"
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/modman.h"
|
||||
|
||||
#include "common/logger.h"
|
||||
#include "common/restext.h"
|
||||
#include "common/stringutils.h"
|
||||
|
||||
#include "common/resources/resourcemanager.h"
|
||||
|
||||
#include "common/system/system.h"
|
||||
|
||||
#include "level/robotmain.h"
|
||||
|
||||
#include "math/func.h"
|
||||
|
||||
#include "sound/sound.h"
|
||||
|
||||
#include "ui/controls/button.h"
|
||||
#include "ui/controls/edit.h"
|
||||
#include "ui/controls/interface.h"
|
||||
#include "ui/controls/label.h"
|
||||
#include "ui/controls/list.h"
|
||||
#include "ui/controls/window.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
|
||||
CScreenModList::CScreenModList(CMainDialog* dialog, CModManager* modManager)
|
||||
: m_dialog(dialog),
|
||||
m_modManager(modManager)
|
||||
{
|
||||
}
|
||||
|
||||
void CScreenModList::CreateInterface()
|
||||
{
|
||||
CWindow* pw;
|
||||
CEdit* pe;
|
||||
CLabel* pl;
|
||||
CButton* pb;
|
||||
CList* pli;
|
||||
Math::Point pos, ddim;
|
||||
std::string name;
|
||||
|
||||
// Display the window
|
||||
pos.x = 0.10f;
|
||||
pos.y = 0.10f;
|
||||
ddim.x = 0.80f;
|
||||
ddim.y = 0.80f;
|
||||
pw = m_interface->CreateWindows(pos, ddim, 12, EVENT_WINDOW5);
|
||||
pw->SetClosable(true);
|
||||
GetResource(RES_TEXT, RT_TITLE_MODS, name);
|
||||
pw->SetName(name);
|
||||
|
||||
pos.x = 0.10f;
|
||||
pos.y = 0.40f;
|
||||
ddim.x = 0.50f;
|
||||
ddim.y = 0.50f;
|
||||
pw->CreateGroup(pos, ddim, 5, EVENT_INTERFACE_GLINTl); // orange corner
|
||||
pos.x = 0.40f;
|
||||
pos.y = 0.10f;
|
||||
ddim.x = 0.50f;
|
||||
ddim.y = 0.50f;
|
||||
pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner
|
||||
|
||||
// Display the list of mods
|
||||
pos.x = ox+sx*3;
|
||||
pos.y = oy+sy*10.5f;
|
||||
ddim.x = dim.x*7.5f;
|
||||
ddim.y = dim.y*0.6f;
|
||||
GetResource(RES_TEXT, RT_MOD_LIST, name);
|
||||
pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL11, name);
|
||||
pl->SetTextAlign(Gfx::TEXT_ALIGN_LEFT);
|
||||
|
||||
pos.y = oy+sy*6.7f;
|
||||
ddim.y = dim.y*4.6f;
|
||||
ddim.x = dim.x*6.5f;
|
||||
pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_MOD_LIST);
|
||||
pli->SetState(STATE_SHADOW);
|
||||
pli->SetState(STATE_EXTEND);
|
||||
|
||||
// Displays the mod details
|
||||
pos.x = ox+sx*9.5f;
|
||||
pos.y = oy+sy*10.5f;
|
||||
ddim.x = dim.x*7.5f;
|
||||
ddim.y = dim.y*0.6f;
|
||||
GetResource(RES_TEXT, RT_MOD_DETAILS, name);
|
||||
pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL12, name);
|
||||
pl->SetTextAlign(Gfx::TEXT_ALIGN_LEFT);
|
||||
|
||||
pos.y = oy+sy*6.7f;
|
||||
ddim.y = dim.y*4.3f;
|
||||
ddim.x = dim.x*6.5f;
|
||||
pe = pw->CreateEdit(pos, ddim, 0, EVENT_INTERFACE_MOD_DETAILS);
|
||||
pe->SetState(STATE_SHADOW);
|
||||
pe->SetMaxChar(500);
|
||||
pe->SetEditCap(false); // just to see
|
||||
pe->SetHighlightCap(true);
|
||||
|
||||
pos = pli->GetPos();
|
||||
ddim = pli->GetDim();
|
||||
|
||||
// Displays the mod summary
|
||||
pos.x = ox+sx*3;
|
||||
pos.y = oy+sy*5.4f;
|
||||
ddim.x = dim.x*6.5f;
|
||||
ddim.y = dim.y*0.6f;
|
||||
GetResource(RES_TEXT, RT_MOD_SUMMARY, name);
|
||||
pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL13, name);
|
||||
pl->SetTextAlign(Gfx::TEXT_ALIGN_LEFT);
|
||||
|
||||
pos.x = ox+sx*3;
|
||||
pos.y = oy+sy*3.6f;
|
||||
ddim.x = dim.x*13.4f;
|
||||
ddim.y = dim.y*1.9f;
|
||||
pe = pw->CreateEdit(pos, ddim, 0, EVENT_INTERFACE_MOD_SUMMARY);
|
||||
pe->SetState(STATE_SHADOW);
|
||||
pe->SetMaxChar(500);
|
||||
pe->SetEditCap(false); // just to see
|
||||
pe->SetHighlightCap(true);
|
||||
|
||||
// Apply button
|
||||
pos.x = ox+sx*13.75f;
|
||||
pos.y = oy+sy*2;
|
||||
ddim.x = dim.x*2.0f;
|
||||
ddim.y = dim.y*1;
|
||||
pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_MODS_APPLY);
|
||||
pb->SetState(STATE_SHADOW);
|
||||
|
||||
// Display the enable/disable button
|
||||
pos.x -= dim.x*2.3f;
|
||||
ddim.x = dim.x*2.0f;
|
||||
pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_MOD_ENABLE_OR_DISABLE);
|
||||
pb->SetState(STATE_SHADOW);
|
||||
|
||||
// Display the move up button
|
||||
pos.x -= dim.x*0.8f;
|
||||
pos.y = oy+sy*2.48;
|
||||
ddim.x = dim.x*0.5;
|
||||
ddim.y = dim.y*0.5;
|
||||
pb = pw->CreateButton(pos, ddim, 49, EVENT_INTERFACE_MOD_MOVE_UP);
|
||||
pb->SetState(STATE_SHADOW);
|
||||
|
||||
// Display the move down button
|
||||
pos.y = oy+sy*2;
|
||||
pb = pw->CreateButton(pos, ddim, 50, EVENT_INTERFACE_MOD_MOVE_DOWN);
|
||||
pb->SetState(STATE_SHADOW);
|
||||
|
||||
// Display the refresh button
|
||||
pos.x -= dim.x*1.3f;
|
||||
pos.y = oy+sy*2;
|
||||
ddim.x = dim.x*1;
|
||||
ddim.y = dim.y*1;
|
||||
pb = pw->CreateButton(pos, ddim, 87, EVENT_INTERFACE_MODS_REFRESH);
|
||||
pb->SetState(STATE_SHADOW);
|
||||
|
||||
// Display the open website button
|
||||
pos.x -= dim.x*1.3f;
|
||||
pb = pw->CreateButton(pos, ddim, 40, EVENT_INTERFACE_WORKSHOP);
|
||||
pb->SetState(STATE_SHADOW);
|
||||
|
||||
// Display the open directory button
|
||||
pos.x -= dim.x*1.3f;
|
||||
pb = pw->CreateButton(pos, ddim, 57, EVENT_INTERFACE_MODS_DIR);
|
||||
pb->SetState(STATE_SHADOW);
|
||||
|
||||
// Back button
|
||||
pos.x = ox+sx*3;
|
||||
ddim.x = dim.x*4;
|
||||
pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_BACK);
|
||||
pb->SetState(STATE_SHADOW);
|
||||
|
||||
FindMods();
|
||||
UpdateAll();
|
||||
|
||||
// Background
|
||||
SetBackground("textures/interface/interface.png");
|
||||
CreateVersionDisplay();
|
||||
}
|
||||
|
||||
bool CScreenModList::EventProcess(const Event &event)
|
||||
{
|
||||
CWindow* pw;
|
||||
CList* pl;
|
||||
|
||||
const std::string workshopUrl = "https://www.moddb.com/games/colobot-gold-edition";
|
||||
const std::string modDir = CResourceManager::GetSaveLocation() + "/mods";
|
||||
|
||||
auto systemUtils = CSystemUtils::Create(); // platform-specific utils
|
||||
|
||||
Mod const * mod;
|
||||
|
||||
pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
|
||||
if (pw == nullptr) return false;
|
||||
|
||||
if (event.type == pw->GetEventTypeClose() ||
|
||||
event.type == EVENT_INTERFACE_BACK ||
|
||||
(event.type == EVENT_KEY_DOWN && event.GetData<KeyEventData>()->key == KEY(ESCAPE)))
|
||||
{
|
||||
if (m_modManager->Changes())
|
||||
{
|
||||
m_dialog->StartQuestion(RT_DIALOG_CHANGES_QUESTION, true, true, false,
|
||||
[this]()
|
||||
{
|
||||
ApplyChanges();
|
||||
CloseWindow();
|
||||
},
|
||||
[this]()
|
||||
{
|
||||
CloseWindow();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
CloseWindow();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
switch( event.type )
|
||||
{
|
||||
case EVENT_INTERFACE_MOD_LIST:
|
||||
pl = static_cast<CList*>(pw->SearchControl(EVENT_INTERFACE_MOD_LIST));
|
||||
if (pl == nullptr) break;
|
||||
m_modSelectedIndex = pl->GetSelect();
|
||||
UpdateModSummary();
|
||||
UpdateModDetails();
|
||||
UpdateEnableDisableButton();
|
||||
UpdateUpDownButtons();
|
||||
break;
|
||||
|
||||
case EVENT_INTERFACE_MOD_ENABLE_OR_DISABLE:
|
||||
mod = &m_modManager->GetMod(m_modSelectedIndex);
|
||||
if (mod->enabled)
|
||||
{
|
||||
m_modManager->DisableMod(m_modSelectedIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_modManager->EnableMod(m_modSelectedIndex);
|
||||
}
|
||||
UpdateModList();
|
||||
UpdateEnableDisableButton();
|
||||
UpdateApplyButton();
|
||||
break;
|
||||
|
||||
case EVENT_INTERFACE_MOD_MOVE_UP:
|
||||
m_modSelectedIndex = m_modManager->MoveUp(m_modSelectedIndex);
|
||||
UpdateModList();
|
||||
UpdateUpDownButtons();
|
||||
UpdateApplyButton();
|
||||
break;
|
||||
|
||||
case EVENT_INTERFACE_MOD_MOVE_DOWN:
|
||||
m_modSelectedIndex = m_modManager->MoveDown(m_modSelectedIndex);
|
||||
UpdateModList();
|
||||
UpdateUpDownButtons();
|
||||
UpdateApplyButton();
|
||||
break;
|
||||
|
||||
case EVENT_INTERFACE_MODS_REFRESH:
|
||||
// Apply any changes before refresh so that the config file
|
||||
// is better synchronized with the state of the game
|
||||
case EVENT_INTERFACE_MODS_APPLY:
|
||||
ApplyChanges();
|
||||
UpdateAll();
|
||||
// Start playing the main menu music again
|
||||
if (!m_app->GetSound()->IsPlayingMusic())
|
||||
{
|
||||
m_app->GetSound()->PlayMusic("music/Intro1.ogg", false);
|
||||
m_app->GetSound()->CacheMusic("music/Intro2.ogg");
|
||||
}
|
||||
break;
|
||||
|
||||
case EVENT_INTERFACE_MODS_DIR:
|
||||
if (!systemUtils->OpenPath(modDir))
|
||||
{
|
||||
std::string title, text;
|
||||
GetResource(RES_TEXT, RT_DIALOG_OPEN_PATH_FAILED_TITLE, title);
|
||||
GetResource(RES_TEXT, RT_DIALOG_OPEN_PATH_FAILED_TEXT, text);
|
||||
|
||||
// Workaround for Windows: the label skips everything after the first \\ character
|
||||
std::string modDirWithoutBackSlashes = modDir;
|
||||
std::replace(modDirWithoutBackSlashes.begin(), modDirWithoutBackSlashes.end(), '\\', '/');
|
||||
|
||||
m_dialog->StartInformation(title, title, StrUtils::Format(text.c_str(), modDirWithoutBackSlashes.c_str()));
|
||||
}
|
||||
break;
|
||||
|
||||
case EVENT_INTERFACE_WORKSHOP:
|
||||
if (!systemUtils->OpenWebsite(workshopUrl))
|
||||
{
|
||||
std::string title, text;
|
||||
GetResource(RES_TEXT, RT_DIALOG_OPEN_WEBSITE_FAILED_TITLE, title);
|
||||
GetResource(RES_TEXT, RT_DIALOG_OPEN_WEBSITE_FAILED_TEXT, text);
|
||||
m_dialog->StartInformation(title, title, StrUtils::Format(text.c_str(), workshopUrl.c_str()));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CScreenModList::FindMods()
|
||||
{
|
||||
m_modManager->FindMods();
|
||||
if (m_modManager->CountMods() != 0)
|
||||
{
|
||||
m_modSelectedIndex = Math::Clamp(m_modSelectedIndex, static_cast<size_t>(0), m_modManager->CountMods() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void CScreenModList::ApplyChanges()
|
||||
{
|
||||
m_modManager->SaveMods();
|
||||
m_modManager->ReloadMods();
|
||||
}
|
||||
|
||||
void CScreenModList::CloseWindow()
|
||||
{
|
||||
m_main->ChangePhase(PHASE_MAIN_MENU);
|
||||
}
|
||||
|
||||
void CScreenModList::UpdateAll()
|
||||
{
|
||||
UpdateModList();
|
||||
UpdateModDetails();
|
||||
UpdateModSummary();
|
||||
UpdateEnableDisableButton();
|
||||
UpdateApplyButton();
|
||||
UpdateUpDownButtons();
|
||||
}
|
||||
|
||||
void CScreenModList::UpdateModList()
|
||||
{
|
||||
CWindow* pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
|
||||
if (pw == nullptr) return;
|
||||
|
||||
CList* pl = static_cast<CList*>(pw->SearchControl(EVENT_INTERFACE_MOD_LIST));
|
||||
if (pl == nullptr) return;
|
||||
|
||||
pl->Flush();
|
||||
|
||||
if (m_modManager->CountMods() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& mods = m_modManager->GetMods();
|
||||
for (size_t i = 0; i < mods.size(); ++i)
|
||||
{
|
||||
const auto& mod = mods[i];
|
||||
const auto& name = mod.data.displayName;
|
||||
pl->SetItemName(i, name);
|
||||
pl->SetCheck(i, mod.enabled);
|
||||
pl->SetEnable(i, true);
|
||||
}
|
||||
|
||||
pl->SetSelect(m_modSelectedIndex);
|
||||
pl->ShowSelect(false);
|
||||
}
|
||||
|
||||
void CScreenModList::UpdateModDetails()
|
||||
{
|
||||
CWindow* pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
|
||||
if (pw == nullptr) return;
|
||||
|
||||
CEdit* pe = static_cast<CEdit*>(pw->SearchControl(EVENT_INTERFACE_MOD_DETAILS));
|
||||
if (pe == nullptr) return;
|
||||
|
||||
if (m_modManager->CountMods() == 0)
|
||||
{
|
||||
pe->SetText("No information");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string details{};
|
||||
|
||||
const auto& mod = m_modManager->GetMod(m_modSelectedIndex);
|
||||
const auto data = mod.data;
|
||||
|
||||
details += "\\b;" + data.displayName + '\n';
|
||||
|
||||
std::string authorFieldName;
|
||||
GetResource(RES_TEXT, RT_MOD_AUTHOR_FIELD_NAME, authorFieldName);
|
||||
details += "\\s;" + authorFieldName + " ";
|
||||
if (!data.author.empty())
|
||||
{
|
||||
details += data.author;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string unknownAuthor;
|
||||
GetResource(RES_TEXT, RT_MOD_UNKNOWN_AUTHOR, unknownAuthor);
|
||||
details += unknownAuthor;
|
||||
}
|
||||
details += '\n';
|
||||
|
||||
details += '\n';
|
||||
|
||||
if (!data.version.empty())
|
||||
{
|
||||
std::string versionFieldName;
|
||||
GetResource(RES_TEXT, RT_MOD_VERSION_FIELD_NAME, versionFieldName);
|
||||
details += "\\t;" + versionFieldName + '\n' + data.version + '\n';
|
||||
}
|
||||
|
||||
if (!data.website.empty())
|
||||
{
|
||||
std::string websiteFieldName;
|
||||
GetResource(RES_TEXT, RT_MOD_WEBSITE_FIELD_NAME, websiteFieldName);
|
||||
details += "\\t;" + websiteFieldName + '\n' + data.website + '\n';
|
||||
}
|
||||
|
||||
std::string changesFieldName;
|
||||
GetResource(RES_TEXT, RT_MOD_CHANGES_FIELD_NAME, changesFieldName);
|
||||
details += "\\t;" + changesFieldName + '\n';
|
||||
if (!data.changes.empty())
|
||||
{
|
||||
for (const auto& change : data.changes)
|
||||
{
|
||||
details += change + '\n';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string noChanges;
|
||||
GetResource(RES_TEXT, RT_MOD_NO_CHANGES, noChanges);
|
||||
details += noChanges;
|
||||
}
|
||||
|
||||
pe->SetText(details);
|
||||
|
||||
pe->SetFirstLine(0);
|
||||
}
|
||||
|
||||
void CScreenModList::UpdateModSummary()
|
||||
{
|
||||
CWindow* pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
|
||||
if (pw == nullptr) return;
|
||||
|
||||
CEdit* pe = static_cast<CEdit*>(pw->SearchControl(EVENT_INTERFACE_MOD_SUMMARY));
|
||||
if (pe == nullptr) return;
|
||||
|
||||
std::string noSummary;
|
||||
GetResource(RES_TEXT, RT_MOD_NO_SUMMARY, noSummary);
|
||||
|
||||
if (m_modManager->CountMods() == 0)
|
||||
{
|
||||
pe->SetText(noSummary);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& mod = m_modManager->GetMod(m_modSelectedIndex);
|
||||
|
||||
if (!mod.data.summary.empty())
|
||||
{
|
||||
pe->SetText(mod.data.summary);
|
||||
}
|
||||
else
|
||||
{
|
||||
pe->SetText(noSummary);
|
||||
}
|
||||
}
|
||||
|
||||
void CScreenModList::UpdateEnableDisableButton()
|
||||
{
|
||||
CWindow* pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
|
||||
if (pw == nullptr) return;
|
||||
|
||||
CButton* pb = static_cast<CButton*>(pw->SearchControl(EVENT_INTERFACE_MOD_ENABLE_OR_DISABLE));
|
||||
if (pb == nullptr) return;
|
||||
|
||||
std::string buttonName{};
|
||||
|
||||
if (m_modManager->CountMods() == 0)
|
||||
{
|
||||
pb->ClearState(STATE_ENABLE);
|
||||
|
||||
// Set some default name
|
||||
GetResource(RES_TEXT, RT_MOD_ENABLE, buttonName);
|
||||
pb->SetName(buttonName);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& mod = m_modManager->GetMod(m_modSelectedIndex);
|
||||
|
||||
if (mod.enabled)
|
||||
{
|
||||
GetResource(RES_TEXT, RT_MOD_DISABLE, buttonName);
|
||||
pb->SetName(buttonName);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetResource(RES_TEXT, RT_MOD_ENABLE, buttonName);
|
||||
pb->SetName(buttonName);
|
||||
}
|
||||
}
|
||||
|
||||
void CScreenModList::UpdateApplyButton()
|
||||
{
|
||||
CWindow* pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
|
||||
if (pw == nullptr) return;
|
||||
|
||||
CButton* pb = static_cast<CButton*>(pw->SearchControl(EVENT_INTERFACE_MODS_APPLY));
|
||||
if (pb == nullptr) return;
|
||||
|
||||
if (m_modManager->Changes())
|
||||
{
|
||||
pb->SetState(STATE_ENABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
pb->ClearState(STATE_ENABLE);
|
||||
}
|
||||
}
|
||||
|
||||
void CScreenModList::UpdateUpDownButtons()
|
||||
{
|
||||
CWindow* pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
|
||||
if (pw == nullptr) return;
|
||||
|
||||
CButton* pb_up = static_cast<CButton*>(pw->SearchControl(EVENT_INTERFACE_MOD_MOVE_UP));
|
||||
if (pb_up == nullptr) return;
|
||||
|
||||
CButton* pb_down = static_cast<CButton*>(pw->SearchControl(EVENT_INTERFACE_MOD_MOVE_DOWN));
|
||||
if (pb_down == nullptr) return;
|
||||
|
||||
if (m_modManager->CountMods() == 0)
|
||||
{
|
||||
pb_up->ClearState(STATE_ENABLE);
|
||||
pb_down->ClearState(STATE_ENABLE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_modSelectedIndex == 0)
|
||||
{
|
||||
pb_up->ClearState(STATE_ENABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
pb_up->SetState(STATE_ENABLE);
|
||||
}
|
||||
|
||||
if (m_modSelectedIndex >= m_modManager->CountMods() - 1)
|
||||
{
|
||||
pb_down->ClearState(STATE_ENABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
pb_down->SetState(STATE_ENABLE);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Ui
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2020, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "app/modman.h"
|
||||
|
||||
#include "ui/maindialog.h"
|
||||
|
||||
#include "ui/screen/screen.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
|
||||
/**
|
||||
* \class CScreenModList
|
||||
* \brief This class is the front-end for the \ref CModManager.
|
||||
*/
|
||||
class CScreenModList : public CScreen
|
||||
{
|
||||
public:
|
||||
CScreenModList(CMainDialog* dialog, CModManager* modManager);
|
||||
|
||||
void CreateInterface() override;
|
||||
bool EventProcess(const Event &event) override;
|
||||
|
||||
protected:
|
||||
void FindMods();
|
||||
void ApplyChanges();
|
||||
void CloseWindow();
|
||||
|
||||
void UpdateAll();
|
||||
void UpdateModList();
|
||||
void UpdateModDetails();
|
||||
void UpdateModSummary();
|
||||
void UpdateEnableDisableButton();
|
||||
void UpdateApplyButton();
|
||||
void UpdateUpDownButtons();
|
||||
|
||||
protected:
|
||||
Ui::CMainDialog* m_dialog;
|
||||
|
||||
CModManager* m_modManager;
|
||||
|
||||
size_t m_modSelectedIndex = 0;
|
||||
};
|
||||
|
||||
} // namespace Ui
|
|
@ -6,3 +6,8 @@ string_value=Hello world
|
|||
|
||||
[test_int]
|
||||
int_value=42
|
||||
|
||||
[test_array]
|
||||
string_array=AAA,Hello world,Gold Edition
|
||||
int_array=2,3,1
|
||||
bool_array=1,0,1
|
||||
|
|
|
@ -52,3 +52,25 @@ TEST_F(CConfigFileTest, ReadTest)
|
|||
ASSERT_TRUE(m_configFile.GetFloatProperty("test_float", "float_value", float_value));
|
||||
ASSERT_FLOAT_EQ(1.5, float_value);
|
||||
}
|
||||
|
||||
TEST_F(CConfigFileTest, ReadArrayTest)
|
||||
{
|
||||
m_configFile.SetUseCurrentDirectory(true);
|
||||
|
||||
ASSERT_TRUE(m_configFile.Init()); // load colobot.ini file
|
||||
|
||||
std::vector<std::string> expected_string_values = { "AAA", "Hello world", "Gold Edition" };
|
||||
std::vector<std::string> string_values;
|
||||
ASSERT_TRUE(m_configFile.GetArrayProperty("test_array", "string_array", string_values));
|
||||
ASSERT_EQ(expected_string_values, string_values);
|
||||
|
||||
std::vector<int> expected_int_values = { 2, 3, 1 };
|
||||
std::vector<int> int_values;
|
||||
ASSERT_TRUE(m_configFile.GetArrayProperty("test_array", "int_array", int_values));
|
||||
ASSERT_EQ(expected_int_values, int_values);
|
||||
|
||||
std::vector<bool> expected_bool_values = { true, false, true };
|
||||
std::vector<bool> bool_values;
|
||||
ASSERT_TRUE(m_configFile.GetArrayProperty("test_array", "bool_array", bool_values));
|
||||
ASSERT_EQ(expected_bool_values, bool_values);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue