aboutsummaryrefslogtreecommitdiff
path: root/game
diff options
context:
space:
mode:
Diffstat (limited to 'game')
-rw-r--r--game/localisation/README.md18
-rw-r--r--game/localisation/en_GB/goods.csv108
-rw-r--r--game/localisation/en_GB/mapmodes.csv14
-rw-r--r--game/localisation/en_GB/menus.csv231
-rw-r--r--game/localisation/en_GB/provinces.csv472
-rw-r--r--game/localisation/en_GB/regions.csv14
-rw-r--r--game/localisation/en_US/menus.csv118
-rw-r--r--game/localisation/fr_FR/menus.csv118
-rw-r--r--game/localisation/ru_RU/goods.csv108
-rw-r--r--game/localisation/ru_RU/mapmodes.csv14
-rw-r--r--game/localisation/ru_RU/menus.csv219
-rw-r--r--game/src/Game/Autoload/Events/Localisation.gd11
-rw-r--r--game/src/Game/Autoload/Resolution.gd145
-rw-r--r--game/src/Game/GameSession/GameSpeedPanel.tscn4
-rw-r--r--game/src/Game/GameSession/MapControlPanel/MapControlPanel.gd1
-rw-r--r--game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn5
-rw-r--r--game/src/Game/GameSession/ProvinceOverviewPanel/ProvinceOverviewPanel.gd18
-rw-r--r--game/src/Game/GameSession/ProvinceOverviewPanel/ProvinceOverviewPanel.tscn1
-rw-r--r--game/src/Game/Menu/CreditsMenu/CreditsMenu.gd5
-rw-r--r--game/src/Game/Menu/MainMenu/ReleaseInfoBox.tscn3
-rw-r--r--game/src/Game/Menu/OptionMenu/MonitorDisplaySelector.gd27
-rw-r--r--game/src/Game/Menu/OptionMenu/OptionsMenu.gd12
-rw-r--r--game/src/Game/Menu/OptionMenu/OptionsMenu.tscn3
-rw-r--r--game/src/Game/Menu/OptionMenu/ResolutionSelector.gd47
-rw-r--r--game/src/Game/Menu/OptionMenu/ScreenModeSelector.gd15
-rw-r--r--game/src/Game/Menu/OptionMenu/SettingNodes/SettingCheckBox.gd53
-rw-r--r--game/src/Game/Menu/OptionMenu/SettingNodes/SettingRevertButton.gd2
-rw-r--r--game/src/Game/Menu/OptionMenu/SettingRevertDialog.gd (renamed from game/src/Game/Menu/OptionMenu/ResolutionRevertDialog.gd)6
-rw-r--r--game/src/Game/Menu/OptionMenu/SoundTab.gd6
-rw-r--r--game/src/Game/Menu/OptionMenu/SoundTab.tscn15
-rw-r--r--game/src/Game/Menu/OptionMenu/VideoTab.tscn38
-rw-r--r--game/src/Game/MusicConductor/MusicConductor.gd26
-rw-r--r--game/src/Game/MusicConductor/MusicConductor.tscn3
-rw-r--r--game/src/Game/MusicConductor/MusicPlayer.tscn6
34 files changed, 1049 insertions, 837 deletions
diff --git a/game/localisation/README.md b/game/localisation/README.md
index 401517f..909e380 100644
--- a/game/localisation/README.md
+++ b/game/localisation/README.md
@@ -1,16 +1,16 @@
# Localisation
-This folder contains localisations for in-game text. Each sub-folder must be named with a standard locale code, e.g. `en_GB`, to which the localisations contained within it shall apply (Godot's supported locale codes are listed [here](https://docs.godotengine.org/en/latest/tutorials/i18n/locales.html)). These folders contain `.csv` files where each line is interpreted as a key-value pair. Empty lines allow for spacing out/separating sections, and any further entries beyond the first two on a line are ignored, which can be used to add comments at the end of lines. Lines with their key and value empty are skipped, allowing free-standing comments with no preceeding localisation, but lines with only one of their key or value empty, while not loaded as a localisation, will still result in warnings about incomplete entries.
+This folder contains localisations for in-game text. Each sub-folder must be named with a standard locale code, e.g. `en_GB`, to which the localisations contained within it shall apply (Godot's supported locale codes are listed [here](https://docs.godotengine.org/en/latest/tutorials/i18n/locales.html)). These folders contain `.csv` files where each line is interpreted as a semicolon-separated key-value pair. Empty lines allow for spacing out/separating sections, and any further entries beyond the first two on a line are ignored, which can be used to add comments at the end of lines. Lines with their key and value empty are skipped, allowing free-standing comments with no preceeding localisation, but lines with only one of their key or value empty, while not loaded as a localisation, will still result in warnings about incomplete entries.
```
-,, Example Localisation Comment
-EXAMPLE_KEY,Example Value
-ANOTHER_EXAMPLE,Another Example, This is a comment
+;; Example Localisation Comment
+EXAMPLE_KEY;Example Value
+ANOTHER_EXAMPLE;Another Example; This is a comment
-,, Entries with empty keys/values are skipped but can still produce warnings
-THIS,, produces a warning!
-,As, does this!
-,, This doesn't!
+;; Entries with empty keys/values are skipped but can still produce warnings
+THIS;; produces a warning!
+;As; does this!
+;; This doesn't!
BUT_THIS_DOES
-AND_THIS,
+AND_THIS;
```
diff --git a/game/localisation/en_GB/goods.csv b/game/localisation/en_GB/goods.csv
index 7e2c63c..9d41b6a 100644
--- a/game/localisation/en_GB/goods.csv
+++ b/game/localisation/en_GB/goods.csv
@@ -1,59 +1,59 @@
-,, Good Categories
-good_category_military,Military
-good_category_raw,Raw
-good_category_industrial,Industrial
-good_category_consumer,Consumer
+;; Good Categories
+good_category_military;Military
+good_category_raw;Raw
+good_category_industrial;Industrial
+good_category_consumer;Consumer
-,, Goods
-good_ammunition,Ammunition
-good_small_arms,Small Arms
-good_artillery,Artillery
-good_canned_food,Canned Food
-good_tanks,Tanks
-good_aeroplanes,Aeroplanes
+;; Goods
+good_ammunition;Ammunition
+good_small_arms;Small Arms
+good_artillery;Artillery
+good_canned_food;Canned Food
+good_tanks;Tanks
+good_aeroplanes;Aeroplanes
-good_coal,Coal
-good_cotton,Cotton
-good_dye,Dye
-good_iron,Iron
-good_oil,Oil
-good_precious_metal,Precious Metal
-good_rubber,Rubber
-good_silk,Silk
-good_sulphur,Sulphur
-good_timber,Timber
-good_tropical_wood,Tropical Wood
-good_wool,Wool
+good_coal;Coal
+good_cotton;Cotton
+good_dye;Dye
+good_iron;Iron
+good_oil;Oil
+good_precious_metal;Precious Metal
+good_rubber;Rubber
+good_silk;Silk
+good_sulphur;Sulphur
+good_timber;Timber
+good_tropical_wood;Tropical Wood
+good_wool;Wool
-good_steel,Steel
-good_cement,Cement
-good_machine_parts,Machine Parts
-good_glass,Glass
-good_fuel,Fuel
-good_fertilizer,Fertilizer
-good_explosives,Explosives
-good_clipper_convoys,Clipper Convoys
-good_steamer_convoys,Steamer Convoys
-good_electric_gears,Electric Gears
-good_fabric,Fabric
-good_lumber,Lumber
+good_steel;Steel
+good_cement;Cement
+good_machine_parts;Machine Parts
+good_glass;Glass
+good_fuel;Fuel
+good_fertilizer;Fertilizer
+good_explosives;Explosives
+good_clipper_convoys;Clipper Convoys
+good_steamer_convoys;Steamer Convoys
+good_electric_gears;Electric Gears
+good_fabric;Fabric
+good_lumber;Lumber
-good_paper,Paper
-good_cattle,Cattle
-good_fish,Fish
-good_fruit,Fruit
-good_grain,Grain
-good_tobacco,Tobacco
-good_tea,Tea
-good_coffee,Coffee
-good_opium,Opium
-good_automobiles,Automobiles
-good_telephones,Telephones
-good_wine,Wine
-good_liquor,Liquor
-good_regular_clothes,Regular Clothes
-good_luxury_clothes,Luxury Clothes
-good_furniture,Furniture
-good_luxury_furniture,Luxury Furniture
-good_radios,Radio
+good_paper;Paper
+good_cattle;Cattle
+good_fish;Fish
+good_fruit;Fruit
+good_grain;Grain
+good_tobacco;Tobacco
+good_tea;Tea
+good_coffee;Coffee
+good_opium;Opium
+good_automobiles;Automobiles
+good_telephones;Telephones
+good_wine;Wine
+good_liquor;Liquor
+good_regular_clothes;Regular Clothes
+good_luxury_clothes;Luxury Clothes
+good_furniture;Furniture
+good_luxury_furniture;Luxury Furniture
+good_radios;Radio
diff --git a/game/localisation/en_GB/mapmodes.csv b/game/localisation/en_GB/mapmodes.csv
index 7c2830d..34c3890 100644
--- a/game/localisation/en_GB/mapmodes.csv
+++ b/game/localisation/en_GB/mapmodes.csv
@@ -1,8 +1,8 @@
-,, Test Mapmodes
-mapmode_province,Province
-mapmode_region,Region
-mapmode_terrain,Terrain
-mapmode_index,Index
-mapmode_rgo,RGO
-mapmode_infrastructure,Infrastructure
+;; Test Mapmodes
+mapmode_province;Province
+mapmode_region;Region
+mapmode_terrain;Terrain
+mapmode_index;Index
+mapmode_rgo;RGO
+mapmode_infrastructure;Infrastructure
diff --git a/game/localisation/en_GB/menus.csv b/game/localisation/en_GB/menus.csv
index 0ae1509..a086e85 100644
--- a/game/localisation/en_GB/menus.csv
+++ b/game/localisation/en_GB/menus.csv
@@ -1,102 +1,131 @@
-,, Main Menu
-MAINMENU_TITLE,OpenVic
-MAINMENU_NEW_GAME,New Game
-MAINMENU_CONTINUE,Continue
-MAINMENU_MULTIPLAYER,Multiplayer
-MAINMENU_OPTIONS,Options
-MAINMENU_CREDITS,Credits
-MAINMENU_EXIT,Exit
-MAINMENU_CHECKSUM,Checksum {checksum}
-
-,, Options
-OPTIONS_RESET,R
-OPTIONS_BACK,X
-
-,, General Tab
-OPTIONS_GENERAL_SAVEFORMAT,Savegame Format
-OPTIONS_GENERAL_BINARY,Binary
-OPTIONS_GENERAL_TEXT,Text
-OPTIONS_GENERAL_AUTOSAVE,Autosave Interval
-OPTIONS_GENERAL_AUTOSAVE_MONTHLY,Monthly
-OPTIONS_GENERAL_AUTOSAVE_BIMONTHLY,Bi-Monthly
-OPTIONS_GENERAL_AUTOSAVE_YEARLY,Yearly
-OPTIONS_GENERAL_AUTOSAVE_BIYEARLY,Bi-Yearly
-OPTIONS_GENERAL_AUTOSAVE_NEVER,Never
-OPTIONS_GENERAL_LANGUAGE,Language
-
-,, Video Tab
-OPTIONS_VIDEO_RESOLUTION,Resolution
-OPTIONS_VIDEO_SCREEN_MODE,Screen Mode
-OPTIONS_VIDEO_FULLSCREEN,Fullscreen
-OPTIONS_VIDEO_BORDERLESS,Borderless
-OPTIONS_VIDEO_WINDOWED,Windowed
-OPTIONS_VIDEO_MONITOR_SELECTION,Monitor Selection
-OPTIONS_VIDEO_REFRESH_RATE,Refresh Rate
-OPTIONS_VIDEO_REFRESH_RATE_TOOLTIP,Only change from VSYNC if you are having issues with screen tearing.
-OPTIONS_VIDEO_QUALITY,Quality Preset
-OPTIONS_VIDEO_GUI_SCALE,Gui Scaling Factor
-OPTIONS_VIDEO_RESOLUTION_DIALOG_TITLE,Keep Resolution?
-OPTIONS_VIDEO_RESOLUTION_DIALOG_TEXT,Reverting resolution in ({time})
-
-,, Sound Tab
-MASTER_BUS,Master Volume
-MUSIC_BUS,Music Volume
-SFX_BUS,SFX Volume
-
-,, Credits Menu
-CREDITS_BACK,Back to Main Menu
-
-,, Game Lobby
-GAMELOBBY_START,Start Game
-GAMELOBBY_BACK,Back
-GAMELOBBY_SESSION_TAG,Session Tag
-GAMELOBBY_SELECT_ALL,All
-GAMELOBBY_DELETE_DIALOG_TITLE,Delete {file_name}
-GAMELOBBY_DELETE_DIALOG_TEXT,Are you sure you want to delete {file_name}?
-GAMELOBBY_SESSIONTAG_DIALOG_TITLE,Override {session_tag}
-GAMELOBBY_SESSIONTAG_DIALOG_TEXT,Are you want to override {session_tag} as a previous session?
-
-,, Game Session Menu
-GAMESESSIONMENU_SAVE,Save Game
-GAMESESSIONMENU_LOAD,Load Game
-GAMESESSIONMENU_OPTIONS,Options
-GAMESESSIONMENU_MAINMENU,Resign
-GAMESESSIONMENU_QUIT,Quit
-GAMESESSIONMENU_CLOSE,Close
-
-GAMESESSIONMENU_MAINMENU_DIALOG_TITLE,Resign Game
-GAMESESSIONMENU_MAINMENU_DIALOG_TEXT,Are you sure you want to resign and return to the main menu?
-GAMESESSIONMENU_QUIT_DIALOG_TITLE,Quit Game
-GAMESESSIONMENU_QUIT_DIALOG_TEXT,Are you sure you want to quit and return to desktop?
-
-,, Save Load Menu
-SAVELOADMENU_SAVE_TITLE,Save Menu
-SAVELOADMENU_LOAD_TITLE,Load Menu
-SAVELOADMENU_SAVE_BUTTON,Save
-SAVELOADMENU_LOAD_BUTTON,Load
-
-SAVELOADMENU_DELETE_DIALOG_TITLE,Delete {file_name}
-SAVELOADMENU_DELETE_DIALOG_TEXT,Are you sure you want to delete {file_name}?
-SAVELOADMENU_OVERWRITE_DIALOG_TITLE,Overwrite {file_name}
-SAVELOADMENU_OVERWRITE_DIALOG_TEXT,Are you want to overwrite {file_name}?
-
-SAVELOADMENU_SESSION,Session:
-
-SAVELOADMENU_TABSELECTIONTABBAR_ALL,All
-
-DIALOG_OK,OK
-DIALOG_CANCEL,Cancel
-DIALOG_SAVE_AND_RESIGN,Save and Resign
-DIALOG_SAVE_AND_QUIT,Save and Quit
-
-,, Province Overview Panel
-province_MISSING,No Province
-region_MISSING,No Region
-LIFE_RATING_TOOLTIP,Liferating: {life_rating}
-rgo_MISSING,No RGO
-building_MISSING,No Building
-building_fort,Fort
-building_naval_base,Naval Base
-building_railroad,Railroad
-EXPAND_PROVINCE_BUILDING,Expand
+;; Main Menu
+MAINMENU_TITLE;OpenVic
+MAINMENU_NEW_GAME;New Game
+MAINMENU_CONTINUE;Continue
+MAINMENU_MULTIPLAYER;Multiplayer
+MAINMENU_OPTIONS;Options
+MAINMENU_CREDITS;Credits
+MAINMENU_EXIT;Exit
+MAINMENU_CHECKSUM;Checksum {checksum}
+
+;; Options
+OPTIONS_RESET;R
+OPTIONS_BACK;X
+
+;; General Tab
+OPTIONS_GENERAL;General
+OPTIONS_GENERAL_SAVEFORMAT;Savegame Format
+OPTIONS_GENERAL_BINARY;Binary
+OPTIONS_GENERAL_TEXT;Text
+OPTIONS_GENERAL_AUTOSAVE;Autosave Interval
+OPTIONS_GENERAL_AUTOSAVE_MONTHLY;Monthly
+OPTIONS_GENERAL_AUTOSAVE_BIMONTHLY;Bi-Monthly
+OPTIONS_GENERAL_AUTOSAVE_YEARLY;Yearly
+OPTIONS_GENERAL_AUTOSAVE_BIYEARLY;Bi-Yearly
+OPTIONS_GENERAL_AUTOSAVE_NEVER;Never
+OPTIONS_GENERAL_LANGUAGE;Language
+
+;; Video Tab
+OPTIONS_VIDEO;Video
+
+OPTIONS_VIDEO_RESOLUTION;Resolution
+OPTIONS_VIDEO_RESOLUTION_DIMS;{width}x{height}
+OPTIONS_VIDEO_RESOLUTION_DIMS_DEFAULT;{width}x{height} (Default)
+OPTIONS_VIDEO_RESOLUTION_DIMS_NAMED;{width}x{height} ({name})
+OPTIONS_VIDEO_RESOLUTION_DIMS_NAMED_DEFAULT;{width}x{height} ({name}, Default)
+
+OPTIONS_VIDEO_RESOLUTION_3840x2160;4K
+OPTIONS_VIDEO_RESOLUTION_2560x1080;UW1080p
+OPTIONS_VIDEO_RESOLUTION_1920x1080;1080p
+OPTIONS_VIDEO_RESOLUTION_1280x720;720p
+
+OPTIONS_VIDEO_SCREEN_MODE;Screen Mode
+OPTIONS_VIDEO_FULLSCREEN;Fullscreen
+OPTIONS_VIDEO_BORDERLESS;Borderless
+OPTIONS_VIDEO_WINDOWED;Windowed
+
+OPTIONS_VIDEO_MONITOR_SELECTION;Monitor Selection
+OPTIONS_VIDEO_MONITOR;Monitor {index}
+
+OPTIONS_VIDEO_REFRESH_RATE;Refresh Rate
+OPTIONS_VIDEO_REFRESH_RATE_TOOLTIP;Only change from VSYNC if you are having issues with screen tearing.
+
+OPTIONS_VIDEO_QUALITY;Quality Preset
+OPTIONS_VIDEO_QUALITY_LOW;Low
+OPTIONS_VIDEO_QUALITY_MEDIUM;Medium
+OPTIONS_VIDEO_QUALITY_HIGH;High
+OPTIONS_VIDEO_QUALITY_ULTRA;Ultra
+OPTIONS_VIDEO_QUALITY_CUSTOM;Custom
+
+OPTIONS_VIDEO_GUI_SCALE;Gui Scaling Factor
+
+OPTIONS_VIDEO_REVERT_DIALOG_TITLE;Keep Video Changes?
+OPTIONS_VIDEO_REVERT_DIALOG_TEXT;Reverting changes in {time} seconds...
+
+;; Sound Tab
+OPTIONS_SOUND;Sound
+MASTER_BUS;Master Volume
+MUSIC_BUS;Music Volume
+SFX_BUS;SFX Volume
+OPTIONS_SOUND_EXPLODE_EARS;Explode Eardrums on Startup?
+
+OPTIONS_CONTROLS;Controls
+OPTIONS_OTHER;Other
+
+;; Credits Menu
+CREDITS_BACK;Back to Main Menu
+
+;; Game Lobby
+GAMELOBBY_START;Start Game
+GAMELOBBY_BACK;Back
+GAMELOBBY_SESSION_TAG;Session Tag
+GAMELOBBY_SELECT_ALL;All
+GAMELOBBY_DELETE_DIALOG_TITLE;Delete {file_name}
+GAMELOBBY_DELETE_DIALOG_TEXT;Are you sure you want to delete {file_name}?
+GAMELOBBY_SESSIONTAG_DIALOG_TITLE;Override {session_tag}
+GAMELOBBY_SESSIONTAG_DIALOG_TEXT;Are you want to override {session_tag} as a previous session?
+
+;; Game Session Menu
+GAMESESSIONMENU_SAVE;Save Game
+GAMESESSIONMENU_LOAD;Load Game
+GAMESESSIONMENU_OPTIONS;Options
+GAMESESSIONMENU_MAINMENU;Resign
+GAMESESSIONMENU_QUIT;Quit
+GAMESESSIONMENU_CLOSE;Close
+
+GAMESESSIONMENU_MAINMENU_DIALOG_TITLE;Resign Game
+GAMESESSIONMENU_MAINMENU_DIALOG_TEXT;Are you sure you want to resign and return to the main menu?
+GAMESESSIONMENU_QUIT_DIALOG_TITLE;Quit Game
+GAMESESSIONMENU_QUIT_DIALOG_TEXT;Are you sure you want to quit and return to desktop?
+
+;; Save Load Menu
+SAVELOADMENU_SAVE_TITLE;Save Menu
+SAVELOADMENU_LOAD_TITLE;Load Menu
+SAVELOADMENU_SAVE_BUTTON;Save
+SAVELOADMENU_LOAD_BUTTON;Load
+
+SAVELOADMENU_DELETE_DIALOG_TITLE;Delete {file_name}
+SAVELOADMENU_DELETE_DIALOG_TEXT;Are you sure you want to delete {file_name}?
+SAVELOADMENU_OVERWRITE_DIALOG_TITLE;Overwrite {file_name}
+SAVELOADMENU_OVERWRITE_DIALOG_TEXT;Are you want to overwrite {file_name}?
+
+SAVELOADMENU_SESSION;Session:
+
+SAVELOADMENU_TABSELECTIONTABBAR_ALL;All
+
+DIALOG_OK;OK
+DIALOG_CANCEL;Cancel
+DIALOG_SAVE_AND_RESIGN;Save and Resign
+DIALOG_SAVE_AND_QUIT;Save and Quit
+
+;; Province Overview Panel
+province_MISSING;No Province
+region_MISSING;No Region
+LIFE_RATING_TOOLTIP;Liferating: {life_rating}
+rgo_MISSING;No RGO
+building_MISSING;No Building
+building_fort;Fort
+building_naval_base;Naval Base
+building_railroad;Railroad
+EXPAND_PROVINCE_BUILDING;Expand
diff --git a/game/localisation/en_GB/provinces.csv b/game/localisation/en_GB/provinces.csv
index 80931c3..39cdae7 100644
--- a/game/localisation/en_GB/provinces.csv
+++ b/game/localisation/en_GB/provinces.csv
@@ -1,245 +1,245 @@
-,, Europe
-prov_britain,Britain
-prov_ireland,Ireland
-prov_iceland,Iceland
-prov_corsica,Corsica
-prov_sardinia,Sardinia
-prov_sicily,Sicily
-prov_malta,Malta
-prov_cyprus,Cyprus
-prov_greenland,Greenland
-prov_baleares,Balearic Islands
-prov_gotland,Gotland
-prov_crete,Crete
-prov_jan_mayen,Jan Mayen
-prov_faroes,Faroe Islands
-prov_mann,Isle of Mann
-prov_shetlands,Shetlands
-prov_orkney,Orkney
-prov_channel_islands,Channel Islands
-prov_madiera,Madiera
-prov_canarias,Canarias
-prov_sjaeland,Sjaeland
-prov_bornholm,Bornholm
-prov_bear_island,Bear Island
-prov_pantelleria,Pantelleria
-prov_iberia,Iberia
-prov_scandinavia,Scandinavia
-prov_jutland,Jutland
-prov_fyn,Fyn
-prov_hiiumaa,Hiiumaa
-prov_saaremaa,Saaremaa
-prov_italy,Italy
-prov_elba,Elba
-prov_france,France
-prov_netherlands,Netherlands
-prov_belgium,Belgium
-prov_luxembourg,Luxembourg
-prov_switzerland,Switzerland
-prov_balkans,Balkans
-prov_crimea,Crimea
-prov_germany,Germany
-prov_poland,Poland
-prov_baltics,Baltics
-prov_finland,Finland
-prov_aland,Åland
-prov_ukraine,Ukraine
-prov_russia,Russia
+;; Europe
+prov_britain;Britain
+prov_ireland;Ireland
+prov_iceland;Iceland
+prov_corsica;Corsica
+prov_sardinia;Sardinia
+prov_sicily;Sicily
+prov_malta;Malta
+prov_cyprus;Cyprus
+prov_greenland;Greenland
+prov_baleares;Balearic Islands
+prov_gotland;Gotland
+prov_crete;Crete
+prov_jan_mayen;Jan Mayen
+prov_faroes;Faroe Islands
+prov_mann;Isle of Mann
+prov_shetlands;Shetlands
+prov_orkney;Orkney
+prov_channel_islands;Channel Islands
+prov_madiera;Madiera
+prov_canarias;Canarias
+prov_sjaeland;Sjaeland
+prov_bornholm;Bornholm
+prov_bear_island;Bear Island
+prov_pantelleria;Pantelleria
+prov_iberia;Iberia
+prov_scandinavia;Scandinavia
+prov_jutland;Jutland
+prov_fyn;Fyn
+prov_hiiumaa;Hiiumaa
+prov_saaremaa;Saaremaa
+prov_italy;Italy
+prov_elba;Elba
+prov_france;France
+prov_netherlands;Netherlands
+prov_belgium;Belgium
+prov_luxembourg;Luxembourg
+prov_switzerland;Switzerland
+prov_balkans;Balkans
+prov_crimea;Crimea
+prov_germany;Germany
+prov_poland;Poland
+prov_baltics;Baltics
+prov_finland;Finland
+prov_aland;Åland
+prov_ukraine;Ukraine
+prov_russia;Russia
-,, North America
-prov_north_america,North America
-prov_cuba,Cuba
-prov_bermuda,Bermuda
-prov_jamaica,Jamaica
-prov_hispaniola,Hispaniola
-prov_aleutians,Aleutian Islands
-prov_bahamas,Bahamas
-prov_turks_and_caicos,Turks and Caicos
-prov_puerto_rico,Puerto Rico
-prov_barbados,Barbados
-prov_grenada,Grenada
-prov_st_vincent,St Vincent
-prov_st_lucia,St Lucia
-prov_martinique,Martinique
-prov_dominica,Dominica
-prov_guadeloupe,Guadeloupe
-prov_montserrat,Montserrat
-prov_antigua,Antigua
-prov_barbuda,Barbuda
-prov_st_kitts,St Kitts
-prov_west_virgin_islands,West Virgin Islands
-prov_east_virgin_islands,East Virgin Islands
-prov_cayman_islands,Cayman Islands
-prov_angulia,Angulia
-prov_central_america,Central America
-prov_mexico,Mexico
+;; North America
+prov_north_america;North America
+prov_cuba;Cuba
+prov_bermuda;Bermuda
+prov_jamaica;Jamaica
+prov_hispaniola;Hispaniola
+prov_aleutians;Aleutian Islands
+prov_bahamas;Bahamas
+prov_turks_and_caicos;Turks and Caicos
+prov_puerto_rico;Puerto Rico
+prov_barbados;Barbados
+prov_grenada;Grenada
+prov_st_vincent;St Vincent
+prov_st_lucia;St Lucia
+prov_martinique;Martinique
+prov_dominica;Dominica
+prov_guadeloupe;Guadeloupe
+prov_montserrat;Montserrat
+prov_antigua;Antigua
+prov_barbuda;Barbuda
+prov_st_kitts;St Kitts
+prov_west_virgin_islands;West Virgin Islands
+prov_east_virgin_islands;East Virgin Islands
+prov_cayman_islands;Cayman Islands
+prov_angulia;Angulia
+prov_central_america;Central America
+prov_mexico;Mexico
-,, Canada
-prov_victoria,Victoria
-prov_calgary,Calgary
-prov_saskatoon,Saskatoon
-prov_winnipeg,Winnipeg
-prov_ottawa,Ottawa
-prov_quebec,Quebec
-prov_new_brunswick,New Brunswick
-prov_prince_edward_island,Prince Edward Island
-prov_nova_scotia,Nova Scotia
-prov_labrador,Labrador
-prov_newfoundland,Newfoundland
-prov_whitehorse,Whitehorse
-prov_yellowknife,Yellowknife
-prov_iqaluit,Iqaluit
+;; Canada
+prov_victoria;Victoria
+prov_calgary;Calgary
+prov_saskatoon;Saskatoon
+prov_winnipeg;Winnipeg
+prov_ottawa;Ottawa
+prov_quebec;Quebec
+prov_new_brunswick;New Brunswick
+prov_prince_edward_island;Prince Edward Island
+prov_nova_scotia;Nova Scotia
+prov_labrador;Labrador
+prov_newfoundland;Newfoundland
+prov_whitehorse;Whitehorse
+prov_yellowknife;Yellowknife
+prov_iqaluit;Iqaluit
-,, South America
-prov_south_america,South America
-prov_galapagos,Galapagos
-prov_falklands,Falklands
-prov_south_georgia,South Georgia
+;; South America
+prov_south_america;South America
+prov_galapagos;Galapagos
+prov_falklands;Falklands
+prov_south_georgia;South Georgia
-,, Africa
-prov_africa,Africa
-prov_madagascar,Madagascar
-prov_socotra,Socotra
-prov_mauritius,Mauritius
-prov_reunion,Réunion
-prov_comoros,Comoros
-prov_sao_tome,Sao Tome
-prov_fernando_po,Fernando Po
-prov_cape_verde,Cape Verde
-prov_ascension,Ascension
-prov_st_helena,St Helena
-prov_tristan_da_cunha,Tristan da Cunha
-prov_seychelles,Seychelles
-prov_prince_edward_islands,Prince Edward Islands
-prov_kerguelen_islands,Kerguelen Islands
-prov_heard_island,Heard Island
-prov_egypt,Egypt
-prov_morocco,Morocco
+;; Africa
+prov_africa;Africa
+prov_madagascar;Madagascar
+prov_socotra;Socotra
+prov_mauritius;Mauritius
+prov_reunion;Réunion
+prov_comoros;Comoros
+prov_sao_tome;Sao Tome
+prov_fernando_po;Fernando Po
+prov_cape_verde;Cape Verde
+prov_ascension;Ascension
+prov_st_helena;St Helena
+prov_tristan_da_cunha;Tristan da Cunha
+prov_seychelles;Seychelles
+prov_prince_edward_islands;Prince Edward Islands
+prov_kerguelen_islands;Kerguelen Islands
+prov_heard_island;Heard Island
+prov_egypt;Egypt
+prov_morocco;Morocco
-,, Asia
-prov_middle_east,Middle East
-prov_ceylon,Ceylon
-prov_formosa,Formosa
-prov_sakhalin,Sakhalin
-prov_maldives,Maldives
-prov_hainan,Hainan
-prov_hokkaido,Hokkaido
-prov_diego_garcia,Diego Garcia
-prov_philippines,Philippines
-prov_india,India
-prov_andamans,Andaman Islands
-prov_nicobar_islands,Nicobar Islands
-prov_indochina,Indochina
-prov_korea,Korea
-prov_okinawa,Okinawa
-prov_yaeyama,Yaeyama
-prov_kyushu,Kyushu
-prov_shikoku,Shikoku
-prov_japan,Japan
-prov_kurils,Kuril Islands
-prov_manchuria,Manchuria
-prov_china,China
-prov_central_asia,Central Asia
-prov_siberia,Siberia
-prov_iran,Iran
-prov_anatolia,Anatolia
+;; Asia
+prov_middle_east;Middle East
+prov_ceylon;Ceylon
+prov_formosa;Formosa
+prov_sakhalin;Sakhalin
+prov_maldives;Maldives
+prov_hainan;Hainan
+prov_hokkaido;Hokkaido
+prov_diego_garcia;Diego Garcia
+prov_philippines;Philippines
+prov_india;India
+prov_andamans;Andaman Islands
+prov_nicobar_islands;Nicobar Islands
+prov_indochina;Indochina
+prov_korea;Korea
+prov_okinawa;Okinawa
+prov_yaeyama;Yaeyama
+prov_kyushu;Kyushu
+prov_shikoku;Shikoku
+prov_japan;Japan
+prov_kurils;Kuril Islands
+prov_manchuria;Manchuria
+prov_china;China
+prov_central_asia;Central Asia
+prov_siberia;Siberia
+prov_iran;Iran
+prov_anatolia;Anatolia
-,, Oceania
-prov_oceania,Oceania
-prov_indonesia,Indonesia
-prov_north_island,North Island
-prov_south_island,South Island
-prov_tasmania,Tasmania
-prov_australia,Australia
-prov_hawaii,Hawaii
+;; Oceania
+prov_oceania;Oceania
+prov_indonesia;Indonesia
+prov_north_island;North Island
+prov_south_island;South Island
+prov_tasmania;Tasmania
+prov_australia;Australia
+prov_hawaii;Hawaii
-,, Lakes
-prov_aral_sea,Aral Sea
-prov_caspian_sea,Caspian Sea
-prov_lake_ladoga,Lake Ladoga
-prov_lake_ontario,Lake Ontario
-prov_lake_erie,Lake Erie
-prov_lake_huron,Lake Huron
-prov_lake_michigan,Lake Michigan
-prov_lake_superior,Lake Superior
-prov_lake_baikal,Lake Baikal
-prov_lake_woods,Lake of the Woods
-prov_lake_manitoba,Lake Manitoba
-prov_reindeer_lake,Reindeer Lake
-prov_lake_ronge,Lac la Ronge
-prov_lake_athabasca,Lake Athabasca
-prov_great_slave_lake,Great Slave Lake
-prov_great_bear_lake,Great Bear Lake
+;; Lakes
+prov_aral_sea;Aral Sea
+prov_caspian_sea;Caspian Sea
+prov_lake_ladoga;Lake Ladoga
+prov_lake_ontario;Lake Ontario
+prov_lake_erie;Lake Erie
+prov_lake_huron;Lake Huron
+prov_lake_michigan;Lake Michigan
+prov_lake_superior;Lake Superior
+prov_lake_baikal;Lake Baikal
+prov_lake_woods;Lake of the Woods
+prov_lake_manitoba;Lake Manitoba
+prov_reindeer_lake;Reindeer Lake
+prov_lake_ronge;Lac la Ronge
+prov_lake_athabasca;Lake Athabasca
+prov_great_slave_lake;Great Slave Lake
+prov_great_bear_lake;Great Bear Lake
-,, Seas and Oceans
-prov_azov_sea,Sea of Azov
-prov_black_sea,Black Sea
-prov_marmara_sea,Sea of Marmara
-prov_agean_sea,Agean Sea
-prov_ionian_sea,Ionian Sea
-prov_adriatic_sea,Adriatic Sea
-prov_tyrrhenian_sea,Tyrrhenian Sea
-prov_east_mediterranean,East Mediterranean Sea
-prov_central_mediterranean,Central Mediterranean Sea
-prov_west_mediterranean,West Mediterranean Sea
-prov_ligurian_sea,Ligurian Sea
-prov_balearic_sea,Balearic Sea
-prov_alboran_sea,Alboran Sea
-prov_gulf_bothnia,Gulf of Bothnia
-prov_gulf_finland,Gulf of Finland
-prov_gulf_riga,Gulf of Riga
-prov_baltic_sea,Baltic Sea
-prov_danish_straits,Danish Straits
-prov_english_channel,English Channel
-prov_irish_sea,Irish Sea
-prov_biscay_bay,Bay of Biscay
-prov_north_sea,North Sea
-prov_red_sea,Red Sea
-prov_arabian_sea,Arabian Sea
-prov_persian_gulf,Persian Gulf
-prov_andaman_sea,Andaman Sea
-prov_bay_bengal,Bay of Bengal
-prov_okhotsk_sea,Sea of Okhotsk
-prov_japan_sea,Sea of Japan
-prov_east_china_sea,East China Sea
-prov_south_china_sea,South China Sea
-prov_philippine_sea,Philippine Sea
-prov_celebes_sea,Celebes Sea
-prov_java_sea,Java Sea
-prov_banda_sea,Banda Sea
-prov_arafura_sea,Arafura Sea
-prov_gulf_mexico,Gulf of Mexico
-prov_caribbean_sea,Caribbean Sea
-prov_mozambique_channel,Mozambique Channel
-prov_zanj_sea,Sea of Zanj
-prov_kara_sea,Kara Sea
-prov_barents_sea,Barents Sea
-prov_norwegian_sea,Norwegian Sea
-prov_greenland_sea,Greenland Sea
-prov_labrador_sea,Labrador Sea
-prov_hudson_bay,Hudson Bay
-prov_gulf_st_lawrence,Gulf of St Lawrence
-prov_gulf_alaska,Gulf of Alaska
-prov_gulf_california,Gulf of California
-prov_east_siberian_sea,East Siberian Sea
-prov_sargasso_sea,Sargasso Sea
-prov_gulf_guinea,Gulf of Guinea
-prov_celtic_sea,Celtic Sea
-prov_argentine_sea,Argentine Sea
-prov_chilean_sea,Chilean Sea
-prov_north_atlantic,North Atlantic Ocean
-prov_central_atlantic,Central Atlantic Ocean
-prov_south_atlantic,South Atlantic Ocean
-prov_indian_ocean,Indian Ocean
-prov_great_australian_bight,Great Australian Bight
-prov_tasman_sea,Tasman Sea
-prov_coral_sea,Coral Sea
-prov_melanesia,Melanesia
-prov_micronesia,Micronesia
-prov_polynesia,Polynesia
-prov_north_pacific,North Pacific Ocean
-prov_south_pacific,South Pacific Ocean
-prov_bering_sea,Bering Sea
-prov_chukchi_sea,Chukchi Sea
-prov_beaufort_sea,Beaufort Sea
+;; Seas and Oceans
+prov_azov_sea;Sea of Azov
+prov_black_sea;Black Sea
+prov_marmara_sea;Sea of Marmara
+prov_agean_sea;Agean Sea
+prov_ionian_sea;Ionian Sea
+prov_adriatic_sea;Adriatic Sea
+prov_tyrrhenian_sea;Tyrrhenian Sea
+prov_east_mediterranean;East Mediterranean Sea
+prov_central_mediterranean;Central Mediterranean Sea
+prov_west_mediterranean;West Mediterranean Sea
+prov_ligurian_sea;Ligurian Sea
+prov_balearic_sea;Balearic Sea
+prov_alboran_sea;Alboran Sea
+prov_gulf_bothnia;Gulf of Bothnia
+prov_gulf_finland;Gulf of Finland
+prov_gulf_riga;Gulf of Riga
+prov_baltic_sea;Baltic Sea
+prov_danish_straits;Danish Straits
+prov_english_channel;English Channel
+prov_irish_sea;Irish Sea
+prov_biscay_bay;Bay of Biscay
+prov_north_sea;North Sea
+prov_red_sea;Red Sea
+prov_arabian_sea;Arabian Sea
+prov_persian_gulf;Persian Gulf
+prov_andaman_sea;Andaman Sea
+prov_bay_bengal;Bay of Bengal
+prov_okhotsk_sea;Sea of Okhotsk
+prov_japan_sea;Sea of Japan
+prov_east_china_sea;East China Sea
+prov_south_china_sea;South China Sea
+prov_philippine_sea;Philippine Sea
+prov_celebes_sea;Celebes Sea
+prov_java_sea;Java Sea
+prov_banda_sea;Banda Sea
+prov_arafura_sea;Arafura Sea
+prov_gulf_mexico;Gulf of Mexico
+prov_caribbean_sea;Caribbean Sea
+prov_mozambique_channel;Mozambique Channel
+prov_zanj_sea;Sea of Zanj
+prov_kara_sea;Kara Sea
+prov_barents_sea;Barents Sea
+prov_norwegian_sea;Norwegian Sea
+prov_greenland_sea;Greenland Sea
+prov_labrador_sea;Labrador Sea
+prov_hudson_bay;Hudson Bay
+prov_gulf_st_lawrence;Gulf of St Lawrence
+prov_gulf_alaska;Gulf of Alaska
+prov_gulf_california;Gulf of California
+prov_east_siberian_sea;East Siberian Sea
+prov_sargasso_sea;Sargasso Sea
+prov_gulf_guinea;Gulf of Guinea
+prov_celtic_sea;Celtic Sea
+prov_argentine_sea;Argentine Sea
+prov_chilean_sea;Chilean Sea
+prov_north_atlantic;North Atlantic Ocean
+prov_central_atlantic;Central Atlantic Ocean
+prov_south_atlantic;South Atlantic Ocean
+prov_indian_ocean;Indian Ocean
+prov_great_australian_bight;Great Australian Bight
+prov_tasman_sea;Tasman Sea
+prov_coral_sea;Coral Sea
+prov_melanesia;Melanesia
+prov_micronesia;Micronesia
+prov_polynesia;Polynesia
+prov_north_pacific;North Pacific Ocean
+prov_south_pacific;South Pacific Ocean
+prov_bering_sea;Bering Sea
+prov_chukchi_sea;Chukchi Sea
+prov_beaufort_sea;Beaufort Sea
diff --git a/game/localisation/en_GB/regions.csv b/game/localisation/en_GB/regions.csv
index 258cce6..70abd1c 100644
--- a/game/localisation/en_GB/regions.csv
+++ b/game/localisation/en_GB/regions.csv
@@ -1,8 +1,8 @@
-,, Regions
-region_europe,Europe
-region_north_america,North America
-region_south_america,South America
-region_africa,Africa
-region_asia,Asia
-region_oceania,Oceania
+;; Regions
+region_europe;Europe
+region_north_america;North America
+region_south_america;South America
+region_africa;Africa
+region_asia;Asia
+region_oceania;Oceania
diff --git a/game/localisation/en_US/menus.csv b/game/localisation/en_US/menus.csv
index 0e86438..1312f3b 100644
--- a/game/localisation/en_US/menus.csv
+++ b/game/localisation/en_US/menus.csv
@@ -1,60 +1,60 @@
-,, Main Menu
-MAINMENU_TITLE,OpenVic
-MAINMENU_NEW_GAME,New Game
-MAINMENU_CONTINUE,Continue
-MAINMENU_MULTIPLAYER,Multiplayer
-MAINMENU_OPTIONS,Options
-MAINMENU_CREDITS,Credits
-MAINMENU_EXIT,Exit
-MAINMENU_CHECKSUM,Checksum {checksum}
-
-,, Options
-OPTIONS_RESET,R
-OPTIONS_BACK,X
-
-,, General Tab
-OPTIONS_GENERAL_SAVEFORMAT,Savegame Format
-OPTIONS_GENERAL_BINARY,Binary
-OPTIONS_GENERAL_TEXT,Text
-OPTIONS_GENERAL_AUTOSAVE,Autosave Interval
-OPTIONS_GENERAL_AUTOSAVE_MONTHLY,Monthly
-OPTIONS_GENERAL_AUTOSAVE_BIMONTHLY,Bi-Monthly
-OPTIONS_GENERAL_AUTOSAVE_YEARLY,Yearly
-OPTIONS_GENERAL_AUTOSAVE_BIYEARLY,Bi-Yearly
-OPTIONS_GENERAL_AUTOSAVE_NEVER,Never
-OPTIONS_GENERAL_LANGUAGE,Language
-
-,, Video Tab
-OPTIONS_VIDEO_RESOLUTION,Resolution
-OPTIONS_VIDEO_SCREEN_MODE,Screen Mode
-OPTIONS_VIDEO_FULLSCREEN,Fullscreen
-OPTIONS_VIDEO_BORDERLESS,Borderless
-OPTIONS_VIDEO_WINDOWED,Windowed
-OPTIONS_VIDEO_MONITOR_SELECTION,Monitor Selection
-OPTIONS_VIDEO_REFRESH_RATE,Refresh Rate
-OPTIONS_VIDEO_REFRESH_RATE_TOOLTIP,Only change from VSYNC if you are having issues with screen tearing.
-OPTIONS_VIDEO_QUALITY,Quality Preset
-OPTIONS_VIDEO_GUI_SCALE,Gui Scaling Factor
-OPTIONS_VIDEO_RESOLUTION_DIALOG_TITLE,Keep Resolution?
-OPTIONS_VIDEO_RESOLUTION_DIALOG_TEXT,Reverting resolution in ({time})
-
-,, Sound Tab
-MASTER_BUS,Master Volume
-MUSIC_BUS,Music Volume
-SFX_BUS,SFX Volume
-
-,, Credits Menu
-CREDITS_BACK,Back to Main Menu
-
-,, Game Lobby
-GAMELOBBY_START,Start Game
-GAMELOBBY_BACK,Back
-
-,, Game Session Menu
-GAMESESSIONMENU_SAVE,Save Game
-GAMESESSIONMENU_LOAD,Load Game
-GAMESESSIONMENU_OPTIONS,Options
-GAMESESSIONMENU_MAINMENU,Resign
-GAMESESSIONMENU_QUIT,Quit
-GAMESESSIONMENU_CLOSE,Close
+;; Main Menu
+MAINMENU_TITLE;OpenVic
+MAINMENU_NEW_GAME;New Game
+MAINMENU_CONTINUE;Continue
+MAINMENU_MULTIPLAYER;Multiplayer
+MAINMENU_OPTIONS;Options
+MAINMENU_CREDITS;Credits
+MAINMENU_EXIT;Exit
+MAINMENU_CHECKSUM;Checksum {checksum}
+
+;; Options
+OPTIONS_RESET;R
+OPTIONS_BACK;X
+
+;; General Tab
+OPTIONS_GENERAL_SAVEFORMAT;Savegame Format
+OPTIONS_GENERAL_BINARY;Binary
+OPTIONS_GENERAL_TEXT;Text
+OPTIONS_GENERAL_AUTOSAVE;Autosave Interval
+OPTIONS_GENERAL_AUTOSAVE_MONTHLY;Monthly
+OPTIONS_GENERAL_AUTOSAVE_BIMONTHLY;Bi-Monthly
+OPTIONS_GENERAL_AUTOSAVE_YEARLY;Yearly
+OPTIONS_GENERAL_AUTOSAVE_BIYEARLY;Bi-Yearly
+OPTIONS_GENERAL_AUTOSAVE_NEVER;Never
+OPTIONS_GENERAL_LANGUAGE;Language
+
+;; Video Tab
+OPTIONS_VIDEO_RESOLUTION;Resolution
+OPTIONS_VIDEO_SCREEN_MODE;Screen Mode
+OPTIONS_VIDEO_FULLSCREEN;Fullscreen
+OPTIONS_VIDEO_BORDERLESS;Borderless
+OPTIONS_VIDEO_WINDOWED;Windowed
+OPTIONS_VIDEO_MONITOR_SELECTION;Monitor Selection
+OPTIONS_VIDEO_REFRESH_RATE;Refresh Rate
+OPTIONS_VIDEO_REFRESH_RATE_TOOLTIP;Only change from VSYNC if you are having issues with screen tearing.
+OPTIONS_VIDEO_QUALITY;Quality Preset
+OPTIONS_VIDEO_GUI_SCALE;Gui Scaling Factor
+OPTIONS_VIDEO_REVERT_DIALOG_TITLE;Keep Video Changes?
+OPTIONS_VIDEO_REVERT_DIALOG_TEXT;Reverting changes in ({time})
+
+;; Sound Tab
+MASTER_BUS;Master Volume
+MUSIC_BUS;Music Volume
+SFX_BUS;SFX Volume
+
+;; Credits Menu
+CREDITS_BACK;Back to Main Menu
+
+;; Game Lobby
+GAMELOBBY_START;Start Game
+GAMELOBBY_BACK;Back
+
+;; Game Session Menu
+GAMESESSIONMENU_SAVE;Save Game
+GAMESESSIONMENU_LOAD;Load Game
+GAMESESSIONMENU_OPTIONS;Options
+GAMESESSIONMENU_MAINMENU;Resign
+GAMESESSIONMENU_QUIT;Quit
+GAMESESSIONMENU_CLOSE;Close
diff --git a/game/localisation/fr_FR/menus.csv b/game/localisation/fr_FR/menus.csv
index 44dd10f..fe0c5c4 100644
--- a/game/localisation/fr_FR/menus.csv
+++ b/game/localisation/fr_FR/menus.csv
@@ -1,60 +1,60 @@
-,, Main Menu
-MAINMENU_TITLE,OpenVic
-MAINMENU_NEW_GAME,Nouveau Jeu
-MAINMENU_CONTINUE,Continuer
-MAINMENU_MULTIPLAYER,Multijouer
-MAINMENU_OPTIONS,Options
-MAINMENU_CREDITS,Credits
-MAINMENU_EXIT,Quitter
-MAINMENU_CHECKSUM,Somme de contrôle {checksum}
-
-,, Options
-OPTIONS_RESET,R
-OPTIONS_BACK,X
-
-,, General Tab
-OPTIONS_GENERAL_SAVEFORMAT,Format de Sauvegarde
-OPTIONS_GENERAL_BINARY,Binaire
-OPTIONS_GENERAL_TEXT,Texte
-OPTIONS_GENERAL_AUTOSAVE,Intervalle d'Enregistrement Automatique
-OPTIONS_GENERAL_AUTOSAVE_MONTHLY,Mensuel
-OPTIONS_GENERAL_AUTOSAVE_BIMONTHLY,Bimensuel
-OPTIONS_GENERAL_AUTOSAVE_YEARLY,Annuel
-OPTIONS_GENERAL_AUTOSAVE_BIYEARLY,Bisannuel
-OPTIONS_GENERAL_AUTOSAVE_NEVER,Jamais
-OPTIONS_GENERAL_LANGUAGE,Langue
-
-,, Video Tab
-OPTIONS_VIDEO_RESOLUTION,Résolution
-OPTIONS_VIDEO_SCREEN_MODE,Mode Écran
-OPTIONS_VIDEO_FULLSCREEN,Plein Écran
-OPTIONS_VIDEO_BORDERLESS,Sans Bordure
-OPTIONS_VIDEO_WINDOWED,Fenêtré
-OPTIONS_VIDEO_MONITOR_SELECTION,Sélection du Moniteur
-OPTIONS_VIDEO_REFRESH_RATE,Taux de Rafraîchissement
-OPTIONS_VIDEO_REFRESH_RATE_TOOLTIP,Ne changez de VSYNC que si vous rencontrez des problèmes de déchirement d'écran.
-OPTIONS_VIDEO_QUALITY,Préréglage de la Qualité
-OPTIONS_VIDEO_GUI_SCALE,Mise à échelle de l'Interface Graphique
-OPTIONS_VIDEO_RESOLUTION_DIALOG_TITLE,Maintenir la résolution?
-OPTIONS_VIDEO_RESOLUTION_DIALOG_TEXT,Reverserai la résolution en ({time})
-
-,, Sound Tab
-MASTER_BUS,Volume Principal
-MUSIC_BUS,Volume de la Musique
-SFX_BUS,Volume d'Effets Spéciaux
-
-,, Credits Menu
-CREDITS_BACK,Retour au Menu Principal
-
-,, Game Lobby
-GAMELOBBY_START,Démarrer Jeu
-GAMELOBBY_BACK,Retourner
-
-,, Game Session Menu
-GAMESESSIONMENU_SAVE,Sauvegarder la Partie
-GAMESESSIONMENU_LOAD,Charger la Partie
-GAMESESSIONMENU_OPTIONS,Options
-GAMESESSIONMENU_MAINMENU,Démissionner
-GAMESESSIONMENU_QUIT,Quitter
-GAMESESSIONMENU_CLOSE,Fermer
+;; Main Menu
+MAINMENU_TITLE;OpenVic
+MAINMENU_NEW_GAME;Nouveau Jeu
+MAINMENU_CONTINUE;Continuer
+MAINMENU_MULTIPLAYER;Multijouer
+MAINMENU_OPTIONS;Options
+MAINMENU_CREDITS;Credits
+MAINMENU_EXIT;Quitter
+MAINMENU_CHECKSUM;Somme de contrôle {checksum}
+
+;; Options
+OPTIONS_RESET;R
+OPTIONS_BACK;X
+
+;; General Tab
+OPTIONS_GENERAL_SAVEFORMAT;Format de Sauvegarde
+OPTIONS_GENERAL_BINARY;Binaire
+OPTIONS_GENERAL_TEXT;Texte
+OPTIONS_GENERAL_AUTOSAVE;Intervalle d'Enregistrement Automatique
+OPTIONS_GENERAL_AUTOSAVE_MONTHLY;Mensuel
+OPTIONS_GENERAL_AUTOSAVE_BIMONTHLY;Bimensuel
+OPTIONS_GENERAL_AUTOSAVE_YEARLY;Annuel
+OPTIONS_GENERAL_AUTOSAVE_BIYEARLY;Bisannuel
+OPTIONS_GENERAL_AUTOSAVE_NEVER;Jamais
+OPTIONS_GENERAL_LANGUAGE;Langue
+
+;; Video Tab
+OPTIONS_VIDEO_RESOLUTION;Résolution
+OPTIONS_VIDEO_SCREEN_MODE;Mode Écran
+OPTIONS_VIDEO_FULLSCREEN;Plein Écran
+OPTIONS_VIDEO_BORDERLESS;Sans Bordure
+OPTIONS_VIDEO_WINDOWED;Fenêtré
+OPTIONS_VIDEO_MONITOR_SELECTION;Sélection du Moniteur
+OPTIONS_VIDEO_REFRESH_RATE;Taux de Rafraîchissement
+OPTIONS_VIDEO_REFRESH_RATE_TOOLTIP;Ne changez de VSYNC que si vous rencontrez des problèmes de déchirement d'écran.
+OPTIONS_VIDEO_QUALITY;Préréglage de la Qualité
+OPTIONS_VIDEO_GUI_SCALE;Mise à échelle de l'Interface Graphique
+OPTIONS_VIDEO_REVERT_DIALOG_TITLE;Maintenir la résolution?
+OPTIONS_VIDEO_REVERT_DIALOG_TEXT;Reverserai la résolution en {time} secondes...
+
+;; Sound Tab
+MASTER_BUS;Volume Principal
+MUSIC_BUS;Volume de la Musique
+SFX_BUS;Volume d'Effets Spéciaux
+
+;; Credits Menu
+CREDITS_BACK;Retour au Menu Principal
+
+;; Game Lobby
+GAMELOBBY_START;Démarrer Jeu
+GAMELOBBY_BACK;Retourner
+
+;; Game Session Menu
+GAMESESSIONMENU_SAVE;Sauvegarder la Partie
+GAMESESSIONMENU_LOAD;Charger la Partie
+GAMESESSIONMENU_OPTIONS;Options
+GAMESESSIONMENU_MAINMENU;Démissionner
+GAMESESSIONMENU_QUIT;Quitter
+GAMESESSIONMENU_CLOSE;Fermer
diff --git a/game/localisation/ru_RU/goods.csv b/game/localisation/ru_RU/goods.csv
index 6a84975..3f8a30c 100644
--- a/game/localisation/ru_RU/goods.csv
+++ b/game/localisation/ru_RU/goods.csv
@@ -1,59 +1,59 @@
-,, Good Categories
-good_category_military,Военные товары
-good_category_raw,Сырье
-good_category_industrial,Промышленные товары
-good_category_consumer,Потребительские товары
+;; Good Categories
+good_category_military;Военные товары
+good_category_raw;Сырье
+good_category_industrial;Промышленные товары
+good_category_consumer;Потребительские товары
-,, Goods
-good_ammunition,Боеприпасы
-good_small_arms,Стрелковое оружие
-good_artillery,Артиллерия
-good_canned_food,Консервы
-good_tanks,Танки
-good_aeroplanes,Самолеты
+;; Goods
+good_ammunition;Боеприпасы
+good_small_arms;Стрелковое оружие
+good_artillery;Артиллерия
+good_canned_food;Консервы
+good_tanks;Танки
+good_aeroplanes;Самолеты
-good_coal,Уголь
-good_cotton,Хлопок
-good_dye,Красители
-good_iron,Железо
-good_oil,ГСМ
-good_precious_metal,Драгоценные металлы
-good_rubber,Резина
-good_silk,Шелк
-good_sulphur,Сера
-good_timber,Древесина
-good_tropical_wood,Тропическое дерево
-good_wool,Шерсть
+good_coal;Уголь
+good_cotton;Хлопок
+good_dye;Красители
+good_iron;Железо
+good_oil;ГСМ
+good_precious_metal;Драгоценные металлы
+good_rubber;Резина
+good_silk;Шелк
+good_sulphur;Сера
+good_timber;Древесина
+good_tropical_wood;Тропическое дерево
+good_wool;Шерсть
-good_steel,Сталь
-good_cement,Цемент
-good_machine_parts,Механические детали
-good_glass,Стекло
-good_fuel,Топливо
-good_fertilizer,Удобрения
-good_explosives,Взрывчатка
-good_clipper_convoys,Конвои Клипперов
-good_steamer_convoys,Конвои Пароходов
-good_electric_gears,Электродетали
-good_fabric,Ткань
-good_lumber,Пиломатериалы
+good_steel;Сталь
+good_cement;Цемент
+good_machine_parts;Механические детали
+good_glass;Стекло
+good_fuel;Топливо
+good_fertilizer;Удобрения
+good_explosives;Взрывчатка
+good_clipper_convoys;Конвои Клипперов
+good_steamer_convoys;Конвои Пароходов
+good_electric_gears;Электродетали
+good_fabric;Ткань
+good_lumber;Пиломатериалы
-good_paper,Бумага
-good_cattle,Скот
-good_fish,Рыба
-good_fruit,Фрукты
-good_grain,Зерно
-good_tobacco,Табак
-good_tea,Чай
-good_coffee,Кофе
-good_opium,Опиум
-good_automobiles,Автомобили
-good_telephones,Телефоны
-good_wine,Вино
-good_liquor,Спирт
-good_regular_clothes,Обычная одежда
-good_luxury_clothes,Роскошная одежда
-good_furniture,Мебель
-good_luxury_furniture,Роскошная мебель
-good_radios,Радио
+good_paper;Бумага
+good_cattle;Скот
+good_fish;Рыба
+good_fruit;Фрукты
+good_grain;Зерно
+good_tobacco;Табак
+good_tea;Чай
+good_coffee;Кофе
+good_opium;Опиум
+good_automobiles;Автомобили
+good_telephones;Телефоны
+good_wine;Вино
+good_liquor;Спирт
+good_regular_clothes;Обычная одежда
+good_luxury_clothes;Роскошная одежда
+good_furniture;Мебель
+good_luxury_furniture;Роскошная мебель
+good_radios;Радио
diff --git a/game/localisation/ru_RU/mapmodes.csv b/game/localisation/ru_RU/mapmodes.csv
index f7829d7..946f29f 100644
--- a/game/localisation/ru_RU/mapmodes.csv
+++ b/game/localisation/ru_RU/mapmodes.csv
@@ -1,8 +1,8 @@
-,, Test Mapmodes
-mapmode_province,Провинции
-mapmode_region,Регионы
-mapmode_terrain,Ландшафт
-mapmode_index,Индекс
-mapmode_rgo,ДП
-mapmode_infrastructure,Инфраструктура
+;; Test Mapmodes
+mapmode_province;Провинции
+mapmode_region;Регионы
+mapmode_terrain;Ландшафт
+mapmode_index;Индекс
+mapmode_rgo;ДП
+mapmode_infrastructure;Инфраструктура
diff --git a/game/localisation/ru_RU/menus.csv b/game/localisation/ru_RU/menus.csv
index 5f6947e..76605d3 100644
--- a/game/localisation/ru_RU/menus.csv
+++ b/game/localisation/ru_RU/menus.csv
@@ -1,102 +1,119 @@
-,, Main Menu
-MAINMENU_TITLE,OpenVic
-MAINMENU_NEW_GAME,Новая игра
-MAINMENU_CONTINUE,Продолжить
-MAINMENU_MULTIPLAYER,Сетевая игра
-MAINMENU_OPTIONS,Настройки
-MAINMENU_CREDITS,Титры
-MAINMENU_EXIT,Выйти из игры
-MAINMENU_CHECKSUM,Контрольная сумма {checksum}
-
-,, Options
-OPTIONS_RESET,R
-OPTIONS_BACK,X
-
-,, General Tab
-OPTIONS_GENERAL_SAVEFORMAT,Формат игровых сохранений
-OPTIONS_GENERAL_BINARY,Двоичный код
-OPTIONS_GENERAL_TEXT,Текст
-OPTIONS_GENERAL_AUTOSAVE,Частота автосохранений
-OPTIONS_GENERAL_AUTOSAVE_MONTHLY,Каждый месяц
-OPTIONS_GENERAL_AUTOSAVE_BIMONTHLY,Каждые два месяца
-OPTIONS_GENERAL_AUTOSAVE_YEARLY,Раз в год
-OPTIONS_GENERAL_AUTOSAVE_BIYEARLY,Каждые два года
-OPTIONS_GENERAL_AUTOSAVE_NEVER,Никогда
-OPTIONS_GENERAL_LANGUAGE,Язык
-
-,, Video Tab
-OPTIONS_VIDEO_RESOLUTION,Разрешение экрана
-OPTIONS_VIDEO_SCREEN_MODE,Экранный режим
-OPTIONS_VIDEO_FULLSCREEN,Полноэкранный
-OPTIONS_VIDEO_BORDERLESS,Окно без рамок
-OPTIONS_VIDEO_WINDOWED,Оконный
-OPTIONS_VIDEO_MONITOR_SELECTION,Выбор монитора
-OPTIONS_VIDEO_REFRESH_RATE,Частота обновления
-OPTIONS_VIDEO_REFRESH_RATE_TOOLTIP,Изменяйте данный параметр с VSYNC, только в том случае, если вы наблюдаете проблемы с разрывом экрана.
-OPTIONS_VIDEO_QUALITY,Заданные настройки качества
-OPTIONS_VIDEO_GUI_SCALE,Масштабирование графического интерфейса
-OPTIONS_VIDEO_RESOLUTION_DIALOG_TITLE,Сохранить данное разрешение?
-OPTIONS_VIDEO_RESOLUTION_DIALOG_TEXT,Возврат к предыдущей настройке через ({time})
-
-,, Sound Tab
-MASTER_BUS,Общая громкость
-MUSIC_BUS,Громкость музыки
-SFX_BUS,Громкость звуковых эффектов
-
-,, Credits Menu
-CREDITS_BACK,Вернуться в главное меню
-
-,, Game Lobby
-GAMELOBBY_START,Начать игру
-GAMELOBBY_BACK,Назад
-GAMELOBBY_SESSION_TAG,Тэг сессии
-GAMELOBBY_SELECT_ALL,Все
-GAMELOBBY_DELETE_DIALOG_TITLE,Удалить {file_name}
-GAMELOBBY_DELETE_DIALOG_TEXT,Вы уверены, что хотите удалить {file_name}?
-GAMELOBBY_SESSIONTAG_DIALOG_TITLE,Переопределить {session_tag}
-GAMELOBBY_SESSIONTAG_DIALOG_TEXT,Вы хотите переопределить {session_tag} как предыдущий сеанс?
-
-,, Game Session Menu
-GAMESESSIONMENU_SAVE,Сохранить игру
-GAMESESSIONMENU_LOAD,Загрузить игру
-GAMESESSIONMENU_OPTIONS,Найстройки
-GAMESESSIONMENU_MAINMENU,Выйти в главное меню
-GAMESESSIONMENU_QUIT,Завершить игру
-GAMESESSIONMENU_CLOSE,Закрыть
-
-GAMESESSIONMENU_MAINMENU_DIALOG_TITLE,Выйти в главное меню
-GAMESESSIONMENU_MAINMENU_DIALOG_TEXT,Вы действительно хотите выйти из текущего сценария в главное меню игры?
-GAMESESSIONMENU_QUIT_DIALOG_TITLE,Завершить игру
-GAMESESSIONMENU_QUIT_DIALOG_TEXT,Вы уверены, что хотите выйти на рабочий стол?
-
-,, Save Load Menu
-SAVELOADMENU_SAVE_TITLE,Сохранить игру
-SAVELOADMENU_LOAD_TITLE,Загрузить игру
-SAVELOADMENU_SAVE_BUTTON,Сохранить
-SAVELOADMENU_LOAD_BUTTON,Загрузить
-
-SAVELOADMENU_DELETE_DIALOG_TITLE,Удалить {file_name}
-SAVELOADMENU_DELETE_DIALOG_TEXT,Вы уверены, что хотите удалить {file_name}?
-SAVELOADMENU_OVERWRITE_DIALOG_TITLE,Перезаписать {file_name}
-SAVELOADMENU_OVERWRITE_DIALOG_TEXT,Вы уверены, что хотите перезаписать {file_name}?
-
-SAVELOADMENU_SESSION,Session:
-
-SAVELOADMENU_TABSELECTIONTABBAR_ALL,Все
-
-DIALOG_OK,Ок
-DIALOG_CANCEL,Отменить
-DIALOG_SAVE_AND_RESIGN,Сохраниться и выйти в главное меню
-DIALOG_SAVE_AND_QUIT,Сохраниться и выйти из игры
-
-,, Province Overview Panel
-province_MISSING,Нет провинции
-region_MISSING,Нет региона
-LIFE_RATING_TOOLTIP,Уровень жизни: {life_rating}
-rgo_MISSING,Нет ДП
-building_MISSING,Нет здания
-building_fort,Форт
-building_naval_base,Морская база
-building_railroad,Железная дорога
-EXPAND_PROVINCE_BUILDING,Расширить
+;; Main Menu
+MAINMENU_TITLE;OpenVic
+MAINMENU_NEW_GAME;Новая игра
+MAINMENU_CONTINUE;Продолжить
+MAINMENU_MULTIPLAYER;Сетевая игра
+MAINMENU_OPTIONS;Настройки
+MAINMENU_CREDITS;Титры
+MAINMENU_EXIT;Выйти из игры
+MAINMENU_CHECKSUM;Контрольная сумма {checksum}
+
+;; Options
+OPTIONS_RESET;R
+OPTIONS_BACK;X
+
+;; General Tab
+OPTIONS_GENERAL;Основные настройки
+OPTIONS_GENERAL_SAVEFORMAT;Формат игровых сохранений
+OPTIONS_GENERAL_BINARY;Двоичный код
+OPTIONS_GENERAL_TEXT;Текст
+OPTIONS_GENERAL_AUTOSAVE;Частота автосохранений
+OPTIONS_GENERAL_AUTOSAVE_MONTHLY;Каждый месяц
+OPTIONS_GENERAL_AUTOSAVE_BIMONTHLY;Каждые два месяца
+OPTIONS_GENERAL_AUTOSAVE_YEARLY;Раз в год
+OPTIONS_GENERAL_AUTOSAVE_BIYEARLY;Каждые два года
+OPTIONS_GENERAL_AUTOSAVE_NEVER;Никогда
+OPTIONS_GENERAL_LANGUAGE;Язык
+
+;; Video Tab
+OPTIONS_VIDEO;Настройки видео
+OPTIONS_VIDEO_RESOLUTION;Разрешение экрана
+OPTIONS_VIDEO_RESOLUTION_DIMS;{width}x{height}
+OPTIONS_VIDEO_RESOLUTION_DIMS_DEFAULT;{width}x{height} (Default)
+OPTIONS_VIDEO_RESOLUTION_DIMS_NAMED;{width}x{height} ({name})
+OPTIONS_VIDEO_RESOLUTION_DIMS_NAMED_DEFAULT;{width}x{height} ({name}, Default)
+OPTIONS_VIDEO_SCREEN_MODE;Экранный режим
+OPTIONS_VIDEO_FULLSCREEN;Полноэкранный
+OPTIONS_VIDEO_BORDERLESS;Окно без рамок
+OPTIONS_VIDEO_WINDOWED;Оконный
+OPTIONS_VIDEO_MONITOR_SELECTION;Выбор монитора
+OPTIONS_VIDEO_MONITOR;Monitor {index}
+OPTIONS_VIDEO_REFRESH_RATE;Частота обновления
+OPTIONS_VIDEO_REFRESH_RATE_TOOLTIP;Изменяйте данный параметр с VSYNC, только в том случае, если вы наблюдаете проблемы с разрывом экрана.
+OPTIONS_VIDEO_QUALITY;Заданные настройки качества
+OPTIONS_VIDEO_QUALITY_LOW;Низкие
+OPTIONS_VIDEO_QUALITY_MEDIUM;Средние
+OPTIONS_VIDEO_QUALITY_HIGH;Высокие
+OPTIONS_VIDEO_QUALITY_ULTRA;Ультра
+OPTIONS_VIDEO_QUALITY_CUSTOM;Настраиваемые
+OPTIONS_VIDEO_GUI_SCALE;Масштабирование графического интерфейса
+OPTIONS_VIDEO_REVERT_DIALOG_TITLE;Сохранить данное разрешение?
+OPTIONS_VIDEO_REVERT_DIALOG_TEXT;Возврат к предыдущей настройке через {time} секунд...
+
+;; Sound Tab
+OPTIONS_SOUND;Звук
+MASTER_BUS;Общая громкость
+MUSIC_BUS;Громкость музыки
+SFX_BUS;Громкость звуковых эффектов
+OPTIONS_SOUND_EXPLODE_EARS;Лопнули барабанные перепонки на запуске?
+
+OPTIONS_CONTROLS;Настройки контроллера
+OPTIONS_OTHER;Другие настройки
+
+;; Credits Menu
+CREDITS_BACK;Вернуться в главное меню
+
+;; Game Lobby
+GAMELOBBY_START;Начать игру
+GAMELOBBY_BACK;Назад
+GAMELOBBY_SESSION_TAG;Метка сессии
+GAMELOBBY_SELECT_ALL;Все
+GAMELOBBY_DELETE_DIALOG_TITLE;Удалить {file_name}
+GAMELOBBY_DELETE_DIALOG_TEXT;Вы уверены, что хотите удалить {file_name}?
+GAMELOBBY_SESSIONTAG_DIALOG_TITLE;Переопределить {session_tag}
+GAMELOBBY_SESSIONTAG_DIALOG_TEXT;Вы хотите переопределить {session_tag} как предыдущий сеанс?
+
+;; Game Session Menu
+GAMESESSIONMENU_SAVE;Сохранить игру
+GAMESESSIONMENU_LOAD;Загрузить игру
+GAMESESSIONMENU_OPTIONS;Найстройки
+GAMESESSIONMENU_MAINMENU;Выйти в главное меню
+GAMESESSIONMENU_QUIT;Завершить игру
+GAMESESSIONMENU_CLOSE;Закрыть
+
+GAMESESSIONMENU_MAINMENU_DIALOG_TITLE;Выйти в главное меню
+GAMESESSIONMENU_MAINMENU_DIALOG_TEXT;Вы действительно хотите выйти из текущего сценария в главное меню игры?
+GAMESESSIONMENU_QUIT_DIALOG_TITLE;Завершить игру
+GAMESESSIONMENU_QUIT_DIALOG_TEXT;Вы уверены, что хотите выйти на рабочий стол?
+
+;; Save Load Menu
+SAVELOADMENU_SAVE_TITLE;Сохранить игру
+SAVELOADMENU_LOAD_TITLE;Загрузить игру
+SAVELOADMENU_SAVE_BUTTON;Сохранить
+SAVELOADMENU_LOAD_BUTTON;Загрузить
+
+SAVELOADMENU_DELETE_DIALOG_TITLE;Удалить {file_name}
+SAVELOADMENU_DELETE_DIALOG_TEXT;Вы уверены, что хотите удалить {file_name}?
+SAVELOADMENU_OVERWRITE_DIALOG_TITLE;Перезаписать {file_name}
+SAVELOADMENU_OVERWRITE_DIALOG_TEXT;Вы уверены, что хотите перезаписать {file_name}?
+
+SAVELOADMENU_SESSION;Session:
+
+SAVELOADMENU_TABSELECTIONTABBAR_ALL;Все
+
+DIALOG_OK;Ок
+DIALOG_CANCEL;Отменить
+DIALOG_SAVE_AND_RESIGN;Сохраниться и выйти в главное меню
+DIALOG_SAVE_AND_QUIT;Сохраниться и выйти из игры
+
+;; Province Overview Panel
+province_MISSING;Нет провинции
+region_MISSING;Нет региона
+LIFE_RATING_TOOLTIP;Уровень жизни: {life_rating}
+rgo_MISSING;Нет ДП
+building_MISSING;Нет здания
+building_fort;Форт
+building_naval_base;Морская база
+building_railroad;Железная дорога
+EXPAND_PROVINCE_BUILDING;Расширить
diff --git a/game/src/Game/Autoload/Events/Localisation.gd b/game/src/Game/Autoload/Events/Localisation.gd
index eda7e51..9048b7a 100644
--- a/game/src/Game/Autoload/Events/Localisation.gd
+++ b/game/src/Game/Autoload/Events/Localisation.gd
@@ -14,10 +14,10 @@ func get_default_locale() -> String:
return ProjectSettings.get_setting("internationalization/locale/fallback", "en_GB")
func load_localisation(dir_path : String) -> void:
- if LoadLocalisation.load_localisation_dir(dir_path) == OK:
- print("loaded locales: ", TranslationServer.get_loaded_locales())
- else:
- push_error("Failed to load localisation directory: ", dir_path)
+ if LoadLocalisation.load_localisation_dir(dir_path) != OK:
+ push_error("Error loading localisation directory: ", dir_path)
+ var loaded_locales : PackedStringArray = TranslationServer.get_loaded_locales()
+ print("Loaded ", loaded_locales.size(), " locales: ", loaded_locales)
# REQUIREMENTS
# * SS-57
@@ -28,3 +28,6 @@ func _init():
push_error("Missing localisation_path setting!")
else:
load_localisation(localisation_dir_path)
+
+func tr_number(num) -> String:
+ return TextServerManager.get_primary_interface().format_number(str(num))
diff --git a/game/src/Game/Autoload/Resolution.gd b/game/src/Game/Autoload/Resolution.gd
index c973ba9..1c7add7 100644
--- a/game/src/Game/Autoload/Resolution.gd
+++ b/game/src/Game/Autoload/Resolution.gd
@@ -1,28 +1,26 @@
extends Node
-signal resolution_added(value : Vector2i, name : StringName, display_name : StringName)
-signal resolution_changed(value : Vector2i)
-signal window_mode_changed(value : Window.Mode)
+signal resolution_added(value : Vector2i)
const error_resolution : Vector2i = Vector2i(-1,-1)
@export
var minimum_resolution : Vector2i = Vector2i(1,1)
-const _starting_resolutions : Dictionary = {
- Vector2i(3840,2160): &"4K",
- Vector2i(2560,1080): &"UW1080p",
- Vector2i(1920,1080): &"1080p",
- Vector2i(1366,768) : &"",
- Vector2i(1536,864) : &"",
- Vector2i(1280,720) : &"720p",
- Vector2i(1440,900) : &"",
- Vector2i(1600,900) : &"",
- Vector2i(1024,600) : &"",
- Vector2i(800,600) : &""
-}
-
-var _resolutions : Dictionary
+const _starting_resolutions : Array[Vector2i] = [
+ Vector2i(3840,2160),
+ Vector2i(2560,1080),
+ Vector2i(1920,1080),
+ Vector2i(1366,768),
+ Vector2i(1536,864),
+ Vector2i(1280,720),
+ Vector2i(1440,900),
+ Vector2i(1600,900),
+ Vector2i(1024,600),
+ Vector2i(800,600)
+]
+
+var _resolutions : Array[Vector2i]
const _regex_pattern : String = "(\\d+)\\s*[xX,]\\s*(\\d+)"
var _regex : RegEx
@@ -30,72 +28,103 @@ var _regex : RegEx
func _ready():
assert(minimum_resolution.x > 0 and minimum_resolution.y > 0, "Minimum resolution must be positive!")
for resolution_value in _starting_resolutions:
- add_resolution(resolution_value, _starting_resolutions[resolution_value])
+ add_resolution(resolution_value)
assert(not _resolutions.is_empty(), "No valid starting resolutions!")
_regex = RegEx.new()
var err := _regex.compile(_regex_pattern)
assert(err == OK, "Resolution RegEx failed to compile!")
-
func has_resolution(resolution_value : Vector2i) -> bool:
return resolution_value in _resolutions
-func add_resolution(resolution_value : Vector2i, resolution_name : StringName = &"") -> bool:
+func add_resolution(resolution_value : Vector2i) -> bool:
if has_resolution(resolution_value): return true
- var res_dict := { value = resolution_value, name = &"" }
- var display_name := "%sx%s" % [resolution_value.x, resolution_value.y]
- if not resolution_name.is_empty():
- res_dict.name = resolution_name
- display_name = "%s (%s)" % [display_name, resolution_name]
- res_dict.display_name = StringName(display_name)
if resolution_value.x < minimum_resolution.x or resolution_value.y < minimum_resolution.y:
- push_error("Resolution %s is smaller than minimum (%sx%s)" % [res_dict.display_name, minimum_resolution.x, minimum_resolution.y])
+ push_error("Resolution %dx%d is smaller than minimum (%dx%d)" % [resolution_value.x, resolution_value.y, minimum_resolution.x, minimum_resolution.y])
return false
- resolution_added.emit(resolution_value, resolution_name, display_name)
- _resolutions[resolution_value] = res_dict
+ _resolutions.append(resolution_value)
+ resolution_added.emit(resolution_value)
return true
-func get_resolution_value_list() -> Array:
- var list := _resolutions.keys()
+func get_resolution_value_list() -> Array[Vector2i]:
+ var list : Array[Vector2i] = []
+ # Return a sorted copy instead of a reference to the private array
+ list.append_array(_resolutions)
list.sort_custom(func(a, b): return a > b)
return list
-func get_resolution_name(resolution_value : Vector2i) -> StringName:
- return _resolutions.get(resolution_value, { name = &"unknown resolution" }).name
-
-func get_resolution_display_name(resolution_value : Vector2i) -> StringName:
- return _resolutions.get(resolution_value, { display_name = &"unknown resolution" }).display_name
-
func get_resolution_value_from_string(resolution_string : String) -> Vector2i:
if not resolution_string.is_empty():
- for resolution in _resolutions.values():
- if resolution_string == resolution.name or resolution_string == resolution.display_name:
- return resolution.value
var result := _regex.search(resolution_string)
if result: return Vector2i(result.get_string(1).to_int(), result.get_string(2).to_int())
return error_resolution
func get_current_resolution() -> Vector2i:
- var window := get_viewport().get_window()
- match window.mode:
- Window.MODE_EXCLUSIVE_FULLSCREEN, Window.MODE_FULLSCREEN:
- return window.content_scale_size
- _:
- return window.size
+ var viewport := get_viewport()
+ if viewport != null:
+ var window := viewport.get_window()
+ if window != null:
+ match window.mode:
+ Window.MODE_EXCLUSIVE_FULLSCREEN, Window.MODE_FULLSCREEN:
+ return window.content_scale_size
+ _:
+ return window.size
+ push_error("Trying to get resolution before window exists!")
+ return error_resolution
func set_resolution(resolution : Vector2i) -> void:
if not has_resolution(resolution):
push_warning("Setting resolution to non-standard value %sx%s" % [resolution.x, resolution.y])
- var window := get_viewport().get_window()
- if get_current_resolution() != resolution:
- resolution_changed.emit(resolution)
- match window.mode:
- Window.MODE_EXCLUSIVE_FULLSCREEN, Window.MODE_FULLSCREEN:
- window.content_scale_size = resolution
- _:
- window.size = resolution
- window.content_scale_size = Vector2i(0,0)
-
-func reset_resolution() -> void:
- set_resolution(get_current_resolution())
+ var viewport := get_viewport()
+ if viewport != null:
+ var window := viewport.get_window()
+ if window != null:
+ match window.mode:
+ Window.MODE_EXCLUSIVE_FULLSCREEN, Window.MODE_FULLSCREEN:
+ window.content_scale_size = resolution
+ _:
+ window.size = resolution
+ window.content_scale_size = Vector2i(0,0)
+ return
+ push_error("Trying to set resolution before window exists!")
+
+func get_current_window_mode() -> Window.Mode:
+ var viewport := get_viewport()
+ if viewport != null:
+ var window := viewport.get_window()
+ if window != null:
+ return window.mode
+ push_error("Trying to get window mode before it exists!")
+ return Window.MODE_WINDOWED
+
+func set_window_mode(mode : Window.Mode) -> void:
+ var viewport := get_viewport()
+ if viewport != null:
+ var window := viewport.get_window()
+ if window != null:
+ var current_resolution := get_current_resolution()
+ var current_monitor := window.current_screen
+ window.mode = mode
+ window.current_screen = current_monitor
+ set_resolution(current_resolution)
+ return
+ push_error("Trying to set window mode before it exists!")
+
+func get_current_monitor() -> int:
+ var viewport := get_viewport()
+ if viewport != null:
+ var window := viewport.get_window()
+ if window != null:
+ return window.current_screen
+ push_error("Trying to get monitor index before window exists!")
+ return 0
+
+func set_monitor(index : int) -> void:
+ var viewport := get_viewport()
+ if viewport != null:
+ var window := viewport.get_window()
+ if window != null:
+ window.current_screen = index
+ return
+ push_error("Trying to set monitor index before window exists!")
diff --git a/game/src/Game/GameSession/GameSpeedPanel.tscn b/game/src/Game/GameSession/GameSpeedPanel.tscn
index fab988e..2ce5042 100644
--- a/game/src/Game/GameSession/GameSpeedPanel.tscn
+++ b/game/src/Game/GameSession/GameSpeedPanel.tscn
@@ -15,21 +15,25 @@ layout_mode = 2
[node name="LongformDateButton" type="Button" parent="ButtonList"]
custom_minimum_size = Vector2(200, 0)
layout_mode = 2
+focus_mode = 0
text = "LONGFORM DATE"
[node name="PlayPauseDisplayButton" type="Button" parent="ButtonList"]
custom_minimum_size = Vector2(30, 0)
layout_mode = 2
+focus_mode = 0
text = "⏸ "
[node name="DecreaseSpeedButton" type="Button" parent="ButtonList"]
custom_minimum_size = Vector2(30, 0)
layout_mode = 2
+focus_mode = 0
text = "-"
[node name="IncreaseSpeedButton" type="Button" parent="ButtonList"]
custom_minimum_size = Vector2(30, 0)
layout_mode = 2
+focus_mode = 0
text = "+"
[connection signal="pressed" from="ButtonList/LongformDateButton" to="." method="_on_longform_date_label_pressed"]
diff --git a/game/src/Game/GameSession/MapControlPanel/MapControlPanel.gd b/game/src/Game/GameSession/MapControlPanel/MapControlPanel.gd
index 0cef057..01e6623 100644
--- a/game/src/Game/GameSession/MapControlPanel/MapControlPanel.gd
+++ b/game/src/Game/GameSession/MapControlPanel/MapControlPanel.gd
@@ -19,6 +19,7 @@ func _add_mapmode_button(identifier : String) -> void:
button.toggle_mode = true
button.button_group = _mapmode_button_group
button.mouse_filter = MOUSE_FILTER_PASS
+ button.focus_mode = FOCUS_NONE
_mapmodes_grid.add_child(button)
if _mapmode_button_group.get_pressed_button() == null:
button.button_pressed = true
diff --git a/game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn b/game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn
index a00f110..2bb62f1 100644
--- a/game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn
+++ b/game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn
@@ -68,6 +68,7 @@ layout_mode = 2
[node name="GameSessionMenuButton" type="Button" parent="MapPanelMargin/MapPanelList/AuxiliaryPanel"]
editor_description = "UI-9"
layout_mode = 2
+focus_mode = 0
mouse_filter = 1
shortcut = SubResource("Shortcut_fc1tk")
text = "ESC"
@@ -75,12 +76,14 @@ text = "ESC"
[node name="LedgerButton" type="Button" parent="MapPanelMargin/MapPanelList/AuxiliaryPanel"]
editor_description = "UI-860"
layout_mode = 2
+focus_mode = 0
mouse_filter = 1
text = "L"
[node name="FindButton" type="Button" parent="MapPanelMargin/MapPanelList/AuxiliaryPanel"]
editor_description = "UI-861"
layout_mode = 2
+focus_mode = 0
mouse_filter = 1
text = "F"
@@ -91,12 +94,14 @@ alignment = 1
[node name="ZoomInButton" type="Button" parent="MapPanelMargin/MapPanelList/AuxiliaryPanel/ZoomButtonsContainer"]
editor_description = "UI-862"
layout_mode = 2
+focus_mode = 0
mouse_filter = 1
text = "+"
[node name="ZoomOutButton" type="Button" parent="MapPanelMargin/MapPanelList/AuxiliaryPanel/ZoomButtonsContainer"]
editor_description = "UI-863"
layout_mode = 2
+focus_mode = 0
mouse_filter = 1
text = "-"
diff --git a/game/src/Game/GameSession/ProvinceOverviewPanel/ProvinceOverviewPanel.gd b/game/src/Game/GameSession/ProvinceOverviewPanel/ProvinceOverviewPanel.gd
index 67060bf..bad093d 100644
--- a/game/src/Game/GameSession/ProvinceOverviewPanel/ProvinceOverviewPanel.gd
+++ b/game/src/Game/GameSession/ProvinceOverviewPanel/ProvinceOverviewPanel.gd
@@ -13,13 +13,18 @@ var _selected_index : int:
get: return _selected_index
set(v):
_selected_index = v
- update_info()
+ _update_info()
var _province_info : Dictionary
func _ready():
GameSingleton.province_selected.connect(_on_province_selected)
- GameSingleton.state_updated.connect(update_info)
- update_info()
+ GameSingleton.state_updated.connect(_update_info)
+ _update_info()
+
+func _notification(what : int):
+ match what:
+ NOTIFICATION_TRANSLATION_CHANGED:
+ _update_info()
enum { CANNOT_EXPAND, CAN_EXPAND, PREPARING, EXPANDING }
@@ -53,6 +58,7 @@ func _add_building_row() -> void:
row.button.text = "EXPAND_PROVINCE_BUILDING"
row.button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
row.button.mouse_filter = Control.MOUSE_FILTER_PASS
+ row.button.focus_mode = FOCUS_NONE
row.button.pressed.connect(func(): _expand_building(row.name.text))
_buildings_container.add_child(row.button)
@@ -91,7 +97,7 @@ func _set_building_row(index : int, building : Dictionary) -> void:
row.button.disabled = expansion_state != CAN_EXPAND
row.button.visible = not show_progress_bar
-func update_info() -> void:
+func _update_info() -> void:
_province_info = GameSingleton.get_province_info_from_index(_selected_index)
if _province_info:
_province_name_label.text = _province_info.get(GameSingleton.get_province_info_province_key(),
@@ -100,7 +106,9 @@ func update_info() -> void:
GameSingleton.get_province_info_region_key() + _missing_suffix)
_life_rating_bar.value = _province_info.get(GameSingleton.get_province_info_life_rating_key(), 0)
- _life_rating_bar.tooltip_text = tr("LIFE_RATING_TOOLTIP").format({ "life_rating": _life_rating_bar.value })
+ _life_rating_bar.tooltip_text = tr("LIFE_RATING_TOOLTIP").format({
+ "life_rating": Events.Localisation.tr_number(_life_rating_bar.value)
+ })
_rgo_name_label.text = _province_info.get(GameSingleton.get_province_info_rgo_key(),
GameSingleton.get_province_info_rgo_key() + _missing_suffix)
diff --git a/game/src/Game/GameSession/ProvinceOverviewPanel/ProvinceOverviewPanel.tscn b/game/src/Game/GameSession/ProvinceOverviewPanel/ProvinceOverviewPanel.tscn
index f8c1e65..896f8e9 100644
--- a/game/src/Game/GameSession/ProvinceOverviewPanel/ProvinceOverviewPanel.tscn
+++ b/game/src/Game/GameSession/ProvinceOverviewPanel/ProvinceOverviewPanel.tscn
@@ -51,6 +51,7 @@ mouse_filter = 1
custom_minimum_size = Vector2(30, 30)
layout_mode = 2
size_flags_vertical = 0
+focus_mode = 0
mouse_filter = 1
text = "X"
diff --git a/game/src/Game/Menu/CreditsMenu/CreditsMenu.gd b/game/src/Game/Menu/CreditsMenu/CreditsMenu.gd
index 0db4d7d..61140c0 100644
--- a/game/src/Game/Menu/CreditsMenu/CreditsMenu.gd
+++ b/game/src/Game/Menu/CreditsMenu/CreditsMenu.gd
@@ -193,6 +193,11 @@ func _ready():
_add_godot_credits()
_add_licenses()
+func _input(event):
+ if self.is_visible_in_tree():
+ if event.is_action_pressed("ui_cancel"):
+ _on_back_button_pressed()
+
# REQUIREMENTS:
# * UI-38
# * UIFUN-37
diff --git a/game/src/Game/Menu/MainMenu/ReleaseInfoBox.tscn b/game/src/Game/Menu/MainMenu/ReleaseInfoBox.tscn
index a10232e..4dc6f4e 100644
--- a/game/src/Game/Menu/MainMenu/ReleaseInfoBox.tscn
+++ b/game/src/Game/Menu/MainMenu/ReleaseInfoBox.tscn
@@ -12,6 +12,7 @@ _checksum_label = NodePath("ChecksumLabel")
[node name="VersionLabel" type="Button" parent="."]
layout_mode = 2
tooltip_text = "VERSION_MISSING"
+focus_mode = 0
theme_type_variation = &"VersionLabel"
text = "VERSION_MISSING"
flat = true
@@ -19,6 +20,7 @@ alignment = 0
[node name="CommitLabel" type="Button" parent="."]
layout_mode = 2
+focus_mode = 0
theme_type_variation = &"CommitLabel"
text = "????????"
flat = true
@@ -28,6 +30,7 @@ alignment = 0
editor_description = "UI-111"
layout_mode = 2
tooltip_text = "CHECKSUM_MISSING"
+focus_mode = 0
theme_type_variation = &"ChecksumLabel"
text = "(????)"
flat = true
diff --git a/game/src/Game/Menu/OptionMenu/MonitorDisplaySelector.gd b/game/src/Game/Menu/OptionMenu/MonitorDisplaySelector.gd
index 7de033a..028b3df 100644
--- a/game/src/Game/Menu/OptionMenu/MonitorDisplaySelector.gd
+++ b/game/src/Game/Menu/OptionMenu/MonitorDisplaySelector.gd
@@ -1,18 +1,29 @@
-extends SettingOptionButton
+extends SettingRevertButton
func _setup_button() -> void:
clear()
for screen_index in DisplayServer.get_screen_count():
- add_item("Monitor %d" % (screen_index + 1))
- default_selected = get_viewport().get_window().current_screen
+ # Placeholder option text awaiting _update_monitor_options_text()
+ add_item(str(screen_index + 1))
+ _update_monitor_options_text()
+ default_selected = Resolution.get_current_monitor()
+
+func _notification(what : int):
+ match what:
+ NOTIFICATION_TRANSLATION_CHANGED:
+ _update_monitor_options_text()
+
+func _update_monitor_options_text() -> void:
+ for index in get_item_count():
+ set_item_text(index, tr("OPTIONS_VIDEO_MONITOR").format({ "index": Events.Localisation.tr_number(index + 1) }))
func _on_option_selected(index : int, by_user : bool) -> void:
if _valid_index(index):
- var window := get_viewport().get_window()
- var mode := window.mode
- window.mode = Window.MODE_WINDOWED
- get_viewport().get_window().set_current_screen(index)
- window.mode = mode
+ if by_user:
+ print("Start Revert Countdown!")
+ revert_dialog.show_dialog.call_deferred(self)
+ previous_index = Resolution.get_current_monitor()
+ Resolution.set_monitor(index)
else:
push_error("Invalid MonitorDisplaySelector index: %d" % index)
reset_setting(not by_user)
diff --git a/game/src/Game/Menu/OptionMenu/OptionsMenu.gd b/game/src/Game/Menu/OptionMenu/OptionsMenu.gd
index 5f6a088..c74c458 100644
--- a/game/src/Game/Menu/OptionMenu/OptionsMenu.gd
+++ b/game/src/Game/Menu/OptionMenu/OptionsMenu.gd
@@ -5,9 +5,17 @@ extends Control
signal back_button_pressed
+@export var _tab_container : TabContainer
+
func _ready():
+ _tab_container.set_tab_title(0, "OPTIONS_GENERAL")
+ _tab_container.set_tab_title(1, "OPTIONS_VIDEO")
+ _tab_container.set_tab_title(2, "OPTIONS_SOUND")
+ _tab_container.set_tab_title(3, "OPTIONS_CONTROLS")
+ _tab_container.set_tab_title(4, "OPTIONS_OTHER")
+
# Prepare options menu before loading user settings
- var tab_bar : TabBar = $Margin/Tab.get_child(0, true)
+ var tab_bar : TabBar = _tab_container.get_child(0, true)
# This ends up easier to manage then trying to manually recreate the TabContainer's behavior
# These buttons can be accessed regardless of the tab
@@ -60,7 +68,7 @@ func _save_overrides() -> void:
var file := ConfigFile.new()
var err_ret := file.load(override_path)
if err_ret != OK: push_error("Failed to load overrides from %s" % override_path)
- file.set_value("display", "window/size/mode", get_viewport().get_window().mode)
+ file.set_value("display", "window/size/mode", Resolution.get_current_window_mode())
var resolution : Vector2i = Resolution.get_current_resolution()
file.set_value("display", "window/size/viewport_width", resolution.x)
file.set_value("display", "window/size/viewport_height", resolution.y)
diff --git a/game/src/Game/Menu/OptionMenu/OptionsMenu.tscn b/game/src/Game/Menu/OptionMenu/OptionsMenu.tscn
index 017629a..3185f63 100644
--- a/game/src/Game/Menu/OptionMenu/OptionsMenu.tscn
+++ b/game/src/Game/Menu/OptionMenu/OptionsMenu.tscn
@@ -8,7 +8,7 @@
[ext_resource type="PackedScene" uid="uid://bq7ibhm0txl5p" path="res://addons/keychain/ShortcutEdit.tscn" id="4_vdhjp"]
[ext_resource type="PackedScene" uid="uid://dp2grvybtecqu" path="res://src/Game/Menu/OptionMenu/OtherTab.tscn" id="5_ahefp"]
-[node name="OptionsMenu" type="PanelContainer"]
+[node name="OptionsMenu" type="PanelContainer" node_paths=PackedStringArray("_tab_container")]
editor_description = "UI-25"
anchors_preset = 15
anchor_right = 1.0
@@ -18,6 +18,7 @@ grow_vertical = 2
theme = ExtResource("1_0up1d")
theme_type_variation = &"BackgroundPanel"
script = ExtResource("1_tlein")
+_tab_container = NodePath("Margin/Tab")
[node name="Margin" type="MarginContainer" parent="."]
layout_mode = 2
diff --git a/game/src/Game/Menu/OptionMenu/ResolutionSelector.gd b/game/src/Game/Menu/OptionMenu/ResolutionSelector.gd
index ebdf718..2791ecb 100644
--- a/game/src/Game/Menu/OptionMenu/ResolutionSelector.gd
+++ b/game/src/Game/Menu/OptionMenu/ResolutionSelector.gd
@@ -14,31 +14,20 @@ func _find_resolution_index_by_value(value : Vector2i) -> int:
return item_index
return -1
-func _sync_resolutions(
- value : Vector2i = Resolution.error_resolution,
- _resolution_name = null,
- _resolution_display_name = null
-) -> void:
+func _sync_resolutions(value : Vector2i = Resolution.error_resolution) -> void:
clear()
default_selected = -1
selected = -1
- var resolution_list := Resolution.get_resolution_value_list()
- if value != Resolution.error_resolution:
- resolution_list.append(value)
- for resolution_value in resolution_list:
- var display_name := "%sx%s" % [resolution_value.x, resolution_value.y]
- var resolution_name := Resolution.get_resolution_name(resolution_value)
- if resolution_name == &"Default":
- display_name = "Default (%s)" % resolution_name
- if not resolution_name.is_empty():
- display_name = "%s (%s)" % [display_name, resolution_name + (", Default" if resolution_value == default_value else "")]
- add_item(display_name)
+ var current_resolution := Resolution.get_current_resolution()
+ for resolution_value in Resolution.get_resolution_value_list():
+ # Placeholder option text awaiting _update_resolution_options_text()
+ add_item(str(resolution_value))
set_item_metadata(item_count - 1, resolution_value)
if resolution_value == default_value:
default_selected = item_count - 1
- if resolution_value == Resolution.get_current_resolution():
+ if resolution_value == current_resolution:
selected = item_count - 1
if default_selected == -1:
@@ -46,6 +35,28 @@ func _sync_resolutions(
if selected == -1:
selected = default_selected
+ _update_resolution_options_text()
+
+func _notification(what : int):
+ match what:
+ NOTIFICATION_TRANSLATION_CHANGED:
+ _update_resolution_options_text()
+
+func _update_resolution_options_text() -> void:
+ for index in get_item_count():
+ var resolution_value : Vector2i = get_item_metadata(index)
+ var format_dict := { "width": resolution_value.x, "height": resolution_value.y }
+ format_dict["name"] = tr("OPTIONS_VIDEO_RESOLUTION_{width}x{height}".format(format_dict))
+ if format_dict["name"].begins_with("OPTIONS"): format_dict["name"] = ""
+ var display_name := "OPTIONS_VIDEO_RESOLUTION_DIMS"
+ if format_dict["name"]:
+ display_name += "_NAMED"
+ if resolution_value == default_value:
+ display_name += "_DEFAULT"
+ format_dict["width"] = Events.Localisation.tr_number(resolution_value.x)
+ format_dict["height"] = Events.Localisation.tr_number(resolution_value.y)
+ display_name = tr(display_name).format(format_dict)
+ set_item_text(index, display_name)
func _setup_button() -> void:
Resolution.resolution_added.connect(_sync_resolutions)
@@ -54,7 +65,7 @@ func _setup_button() -> void:
if default_value.y <= 0:
default_value.y = ProjectSettings.get_setting("display/window/size/viewport_height")
if not Resolution.has_resolution(default_value):
- Resolution.add_resolution(default_value, &"Default")
+ Resolution.add_resolution(default_value)
else:
_sync_resolutions()
diff --git a/game/src/Game/Menu/OptionMenu/ScreenModeSelector.gd b/game/src/Game/Menu/OptionMenu/ScreenModeSelector.gd
index af95901..a1a26a0 100644
--- a/game/src/Game/Menu/OptionMenu/ScreenModeSelector.gd
+++ b/game/src/Game/Menu/OptionMenu/ScreenModeSelector.gd
@@ -5,7 +5,7 @@ extends SettingRevertButton
enum ScreenMode { Unknown = -1, Fullscreen, Borderless, Windowed }
-func get_screen_mode_from_window_mode(window_mode : int) -> ScreenMode:
+func get_screen_mode_from_window_mode(window_mode : Window.Mode) -> ScreenMode:
match window_mode:
Window.MODE_EXCLUSIVE_FULLSCREEN:
return ScreenMode.Fullscreen
@@ -16,7 +16,7 @@ func get_screen_mode_from_window_mode(window_mode : int) -> ScreenMode:
_:
return ScreenMode.Unknown
-func get_window_mode_from_screen_mode(screen_mode : int) -> Window.Mode:
+func get_window_mode_from_screen_mode(screen_mode : ScreenMode) -> Window.Mode:
match screen_mode:
ScreenMode.Fullscreen:
return Window.MODE_EXCLUSIVE_FULLSCREEN
@@ -28,7 +28,7 @@ func get_window_mode_from_screen_mode(screen_mode : int) -> Window.Mode:
return Window.MODE_EXCLUSIVE_FULLSCREEN
func _setup_button():
- default_selected = get_screen_mode_from_window_mode(get_viewport().get_window().mode)
+ default_selected = get_screen_mode_from_window_mode(Resolution.get_current_window_mode())
selected = default_selected
func _on_option_selected(index : int, by_user : bool) -> void:
@@ -36,13 +36,8 @@ func _on_option_selected(index : int, by_user : bool) -> void:
if by_user:
print("Start Revert Countdown!")
revert_dialog.show_dialog.call_deferred(self)
- previous_index = get_screen_mode_from_window_mode(get_viewport().get_window().mode)
-
- var current_resolution := Resolution.get_current_resolution()
- var window_mode := get_window_mode_from_screen_mode(index)
- Resolution.window_mode_changed.emit(window_mode)
- get_viewport().get_window().mode = window_mode
- Resolution.set_resolution(current_resolution)
+ previous_index = get_screen_mode_from_window_mode(Resolution.get_current_window_mode())
+ Resolution.set_window_mode(get_window_mode_from_screen_mode(index))
else:
push_error("Invalid ScreenModeSelector index: %d" % index)
reset_setting(not by_user)
diff --git a/game/src/Game/Menu/OptionMenu/SettingNodes/SettingCheckBox.gd b/game/src/Game/Menu/OptionMenu/SettingNodes/SettingCheckBox.gd
new file mode 100644
index 0000000..fcc411e
--- /dev/null
+++ b/game/src/Game/Menu/OptionMenu/SettingNodes/SettingCheckBox.gd
@@ -0,0 +1,53 @@
+extends CheckBox
+class_name SettingCheckBox
+
+signal option_selected(pressed : bool, by_user : bool)
+
+@export
+var section_name : String = "setting"
+
+@export
+var setting_name : String = "setting_checkbox"
+
+@export
+var default_pressed : bool = true
+
+func _setup_button() -> void:
+ pass
+
+func _ready():
+ Events.Options.load_settings.connect(load_setting)
+ Events.Options.save_settings.connect(save_setting)
+ Events.Options.reset_settings.connect(reset_setting)
+ toggled.connect(func(pressed : bool): option_selected.emit(pressed, true))
+ _setup_button()
+
+func _set_value_from_file(load_value) -> void:
+ match typeof(load_value):
+ TYPE_BOOL, TYPE_INT:
+ set_pressed_no_signal(load_value as bool)
+ return
+ TYPE_STRING, TYPE_STRING_NAME:
+ var load_str := (load_value as String).to_lower()
+ if load_str.is_empty() or load_str.begins_with("f") or load_str.begins_with("n"):
+ set_pressed_no_signal(false)
+ return
+ if load_str.begins_with("t") or load_str.begins_with("y"):
+ set_pressed_no_signal(true)
+ return
+ push_error("Setting value '%s' invalid for setting [%s] \"%s\"" % [load_value, section_name, setting_name])
+ set_pressed_no_signal(default_pressed)
+
+func load_setting(file : ConfigFile) -> void:
+ if file == null: return
+ _set_value_from_file(file.get_value(section_name, setting_name, default_pressed))
+ option_selected.emit(button_pressed, false)
+
+func save_setting(file : ConfigFile) -> void:
+ if file == null: return
+ file.set_value(section_name, setting_name, button_pressed)
+
+func reset_setting(no_emit : bool = false) -> void:
+ set_pressed_no_signal(default_pressed)
+ if not no_emit:
+ option_selected.emit(button_pressed, false)
diff --git a/game/src/Game/Menu/OptionMenu/SettingNodes/SettingRevertButton.gd b/game/src/Game/Menu/OptionMenu/SettingNodes/SettingRevertButton.gd
index 945d35b..431e3e5 100644
--- a/game/src/Game/Menu/OptionMenu/SettingNodes/SettingRevertButton.gd
+++ b/game/src/Game/Menu/OptionMenu/SettingNodes/SettingRevertButton.gd
@@ -2,7 +2,7 @@ extends SettingOptionButton
class_name SettingRevertButton
@export_group("Nodes")
-@export var revert_dialog : ResolutionRevertDialog
+@export var revert_dialog : SettingRevertDialog
var previous_index : int = -1
diff --git a/game/src/Game/Menu/OptionMenu/ResolutionRevertDialog.gd b/game/src/Game/Menu/OptionMenu/SettingRevertDialog.gd
index 4d2b8f2..8cde621 100644
--- a/game/src/Game/Menu/OptionMenu/ResolutionRevertDialog.gd
+++ b/game/src/Game/Menu/OptionMenu/SettingRevertDialog.gd
@@ -1,9 +1,11 @@
extends ConfirmationDialog
-class_name ResolutionRevertDialog
+class_name SettingRevertDialog
signal dialog_accepted(button : SettingRevertButton)
signal dialog_reverted(button : SettingRevertButton)
+@export var dialog_text_key : String = "< reverting in {time} seconds >"
+
@export_group("Nodes")
@export var timer : Timer
@@ -20,7 +22,7 @@ func _notification(what):
if not visible: _revert_node = null
func _process(_delta) -> void:
- dialog_text = tr("OPTIONS_VIDEO_RESOLUTION_DIALOG_TEXT").format({ "time": int(timer.time_left) })
+ dialog_text = tr(dialog_text_key).format({ "time": Events.Localisation.tr_number(int(timer.time_left)) })
func _on_canceled_or_close_requested() -> void:
timer.stop()
diff --git a/game/src/Game/Menu/OptionMenu/SoundTab.gd b/game/src/Game/Menu/OptionMenu/SoundTab.gd
index c707605..e0d9bcf 100644
--- a/game/src/Game/Menu/OptionMenu/SoundTab.gd
+++ b/game/src/Game/Menu/OptionMenu/SoundTab.gd
@@ -1,4 +1,6 @@
extends HBoxContainer
-func _on_ear_exploder_toggled(button_pressed):
- print("KABOOM!!!" if button_pressed else "DEFUSED!!!")
+@export var _startup_music_button : Button
+
+func _ready():
+ _startup_music_button.option_selected.connect(func (pressed : bool, by_user : bool): MusicConductor.set_startup_music(pressed))
diff --git a/game/src/Game/Menu/OptionMenu/SoundTab.tscn b/game/src/Game/Menu/OptionMenu/SoundTab.tscn
index 4bb6948..8bc3679 100644
--- a/game/src/Game/Menu/OptionMenu/SoundTab.tscn
+++ b/game/src/Game/Menu/OptionMenu/SoundTab.tscn
@@ -1,11 +1,13 @@
-[gd_scene load_steps=3 format=3 uid="uid://cbtgwpx2wxi33"]
+[gd_scene load_steps=4 format=3 uid="uid://cbtgwpx2wxi33"]
[ext_resource type="Script" path="res://src/Game/Menu/OptionMenu/SoundTab.gd" id="1_a7k0s"]
[ext_resource type="PackedScene" uid="uid://dy4si8comamnv" path="res://src/Game/Menu/OptionMenu/VolumeGrid.tscn" id="1_okpft"]
+[ext_resource type="Script" path="res://src/Game/Menu/OptionMenu/SettingNodes/SettingCheckBox.gd" id="2_f3aj4"]
-[node name="Sound" type="HBoxContainer"]
+[node name="Sound" type="HBoxContainer" node_paths=PackedStringArray("_startup_music_button")]
alignment = 1
script = ExtResource("1_a7k0s")
+_startup_music_button = NodePath("VBoxContainer/ButtonGrid/EarExploder")
[node name="VBoxContainer" type="VBoxContainer" parent="."]
layout_mode = 2
@@ -27,8 +29,9 @@ columns = 2
layout_mode = 2
size_flags_horizontal = 3
-[node name="EarExploder" type="CheckButton" parent="VBoxContainer/ButtonGrid"]
+[node name="EarExploder" type="CheckBox" parent="VBoxContainer/ButtonGrid"]
layout_mode = 2
-text = "Explode Eardrums on Startup?"
-
-[connection signal="toggled" from="VBoxContainer/ButtonGrid/EarExploder" to="." method="_on_ear_exploder_toggled"]
+text = "OPTIONS_SOUND_EXPLODE_EARS"
+script = ExtResource("2_f3aj4")
+section_name = "audio"
+setting_name = "startup_music"
diff --git a/game/src/Game/Menu/OptionMenu/VideoTab.tscn b/game/src/Game/Menu/OptionMenu/VideoTab.tscn
index 4f5151c..5c58304 100644
--- a/game/src/Game/Menu/OptionMenu/VideoTab.tscn
+++ b/game/src/Game/Menu/OptionMenu/VideoTab.tscn
@@ -7,7 +7,7 @@
[ext_resource type="Script" path="res://src/Game/Menu/OptionMenu/MonitorDisplaySelector.gd" id="3_y6lyb"]
[ext_resource type="Script" path="res://src/Game/Menu/OptionMenu/RefreshRateSelector.gd" id="4_381mg"]
[ext_resource type="Script" path="res://src/Game/Menu/OptionMenu/QualityPresetSelector.gd" id="5_srg4v"]
-[ext_resource type="Script" path="res://src/Game/Menu/OptionMenu/ResolutionRevertDialog.gd" id="8_802cr"]
+[ext_resource type="Script" path="res://src/Game/Menu/OptionMenu/SettingRevertDialog.gd" id="8_ug5mo"]
[node name="Video" type="HBoxContainer" node_paths=PackedStringArray("initial_focus")]
editor_description = "UI-46"
@@ -41,7 +41,7 @@ selected = 0
popup/item_0/text = "MISSING"
popup/item_0/id = 0
script = ExtResource("1_i8nro")
-revert_dialog = NodePath("../../../ResolutionRevertDialog")
+revert_dialog = NodePath("../../../VideoRevertDialog")
section_name = "video"
setting_name = "resolution"
@@ -79,7 +79,7 @@ popup/item_1/id = 1
popup/item_2/text = "OPTIONS_VIDEO_WINDOWED"
popup/item_2/id = 2
script = ExtResource("2_wa7vw")
-revert_dialog = NodePath("../../../ResolutionRevertDialog")
+revert_dialog = NodePath("../../../VideoRevertDialog")
section_name = "video"
setting_name = "mode_selected"
@@ -87,7 +87,7 @@ setting_name = "mode_selected"
layout_mode = 2
text = "OPTIONS_VIDEO_MONITOR_SELECTION"
-[node name="MonitorDisplaySelector" type="OptionButton" parent="VideoSettingList/VideoSettingGrid"]
+[node name="MonitorDisplaySelector" type="OptionButton" parent="VideoSettingList/VideoSettingGrid" node_paths=PackedStringArray("revert_dialog")]
layout_mode = 2
focus_neighbor_top = NodePath("../ScreenModeSelector")
focus_neighbor_bottom = NodePath("../RefreshRateSelector")
@@ -96,6 +96,7 @@ selected = 0
popup/item_0/text = "MISSING"
popup/item_0/id = 0
script = ExtResource("3_y6lyb")
+revert_dialog = NodePath("../../../VideoRevertDialog")
section_name = "video"
setting_name = "current_screen"
@@ -142,32 +143,33 @@ layout_mode = 2
focus_neighbor_top = NodePath("../RefreshRateSelector")
item_count = 5
selected = 1
-popup/item_0/text = "Low"
+popup/item_0/text = "OPTIONS_VIDEO_QUALITY_LOW"
popup/item_0/id = 0
-popup/item_1/text = "Medium"
+popup/item_1/text = "OPTIONS_VIDEO_QUALITY_MEDIUM"
popup/item_1/id = 1
-popup/item_2/text = "High"
+popup/item_2/text = "OPTIONS_VIDEO_QUALITY_HIGH"
popup/item_2/id = 2
-popup/item_3/text = "Ultra"
+popup/item_3/text = "OPTIONS_VIDEO_QUALITY_ULTRA"
popup/item_3/id = 3
-popup/item_4/text = "Custom"
+popup/item_4/text = "OPTIONS_VIDEO_QUALITY_CUSTOM"
popup/item_4/id = 4
script = ExtResource("5_srg4v")
section_name = "video"
setting_name = "quality_preset"
default_selected = 1
-[node name="ResolutionRevertDialog" type="ConfirmationDialog" parent="." node_paths=PackedStringArray("timer")]
+[node name="VideoRevertDialog" type="ConfirmationDialog" parent="." node_paths=PackedStringArray("timer")]
editor_description = "UI-873"
disable_3d = true
-title = "OPTIONS_VIDEO_RESOLUTION_DIALOG_TITLE"
+title = "OPTIONS_VIDEO_REVERT_DIALOG_TITLE"
size = Vector2i(730, 100)
ok_button_text = "DIALOG_OK"
cancel_button_text = "DIALOG_CANCEL"
-script = ExtResource("8_802cr")
-timer = NodePath("ResolutionRevertTimer")
+script = ExtResource("8_ug5mo")
+dialog_text_key = "OPTIONS_VIDEO_REVERT_DIALOG_TEXT"
+timer = NodePath("VideoRevertTimer")
-[node name="ResolutionRevertTimer" type="Timer" parent="ResolutionRevertDialog"]
+[node name="VideoRevertTimer" type="Timer" parent="VideoRevertDialog"]
wait_time = 5.0
one_shot = true
@@ -175,7 +177,7 @@ one_shot = true
[connection signal="option_selected" from="VideoSettingList/VideoSettingGrid/GuiScaleSelector" to="VideoSettingList/VideoSettingGrid/GuiScaleSelector" method="_on_option_selected"]
[connection signal="option_selected" from="VideoSettingList/VideoSettingGrid/ScreenModeSelector" to="VideoSettingList/VideoSettingGrid/ScreenModeSelector" method="_on_option_selected"]
[connection signal="option_selected" from="VideoSettingList/VideoSettingGrid/MonitorDisplaySelector" to="VideoSettingList/VideoSettingGrid/MonitorDisplaySelector" method="_on_option_selected"]
-[connection signal="canceled" from="ResolutionRevertDialog" to="ResolutionRevertDialog" method="_on_canceled_or_close_requested"]
-[connection signal="close_requested" from="ResolutionRevertDialog" to="ResolutionRevertDialog" method="_on_canceled_or_close_requested"]
-[connection signal="confirmed" from="ResolutionRevertDialog" to="ResolutionRevertDialog" method="_on_confirmed"]
-[connection signal="timeout" from="ResolutionRevertDialog/ResolutionRevertTimer" to="ResolutionRevertDialog" method="_on_resolution_revert_timer_timeout"]
+[connection signal="canceled" from="VideoRevertDialog" to="VideoRevertDialog" method="_on_canceled_or_close_requested"]
+[connection signal="close_requested" from="VideoRevertDialog" to="VideoRevertDialog" method="_on_canceled_or_close_requested"]
+[connection signal="confirmed" from="VideoRevertDialog" to="VideoRevertDialog" method="_on_confirmed"]
+[connection signal="timeout" from="VideoRevertDialog/VideoRevertTimer" to="VideoRevertDialog" method="_on_resolution_revert_timer_timeout"]
diff --git a/game/src/Game/MusicConductor/MusicConductor.gd b/game/src/Game/MusicConductor/MusicConductor.gd
index 98dd0eb..da0fb1e 100644
--- a/game/src/Game/MusicConductor/MusicConductor.gd
+++ b/game/src/Game/MusicConductor/MusicConductor.gd
@@ -5,6 +5,8 @@ extends Node
@export_dir var music_directory : String
@export var first_song_name : String
+@export var _audio_stream_player : AudioStreamPlayer
+
var _selected_track = 0
var _available_songs : Array[SongInfo] = []
var _auto_play_next_song : bool = true
@@ -13,6 +15,8 @@ var _auto_play_next_song : bool = true
## Used to keep keep consistency between scene changes
var is_music_player_visible : bool = true
+var _has_startup_happened : bool = false
+
func get_all_song_names() -> Array[String]:
var songNames : Array[String] = []
for si in _available_songs:
@@ -26,21 +30,24 @@ func get_current_song_name() -> String:
return _available_songs[_selected_track].song_name
func scrub_song_by_percentage(percentage: float) -> void:
- var percentInSeconds : float = (percentage / 100.0) * $AudioStreamPlayer.stream.get_length()
- $AudioStreamPlayer.play(percentInSeconds)
+ var percentInSeconds : float = (percentage / 100.0) * _audio_stream_player.stream.get_length()
+ _audio_stream_player.play(percentInSeconds)
func get_current_song_progress_percentage() -> float:
- return 100 * ($AudioStreamPlayer.get_playback_position() / $AudioStreamPlayer.stream.get_length())
+ return 100 * (_audio_stream_player.get_playback_position() / _audio_stream_player.stream.get_length())
func is_paused() -> bool:
- return $AudioStreamPlayer.stream_paused
+ return _audio_stream_player.stream_paused
+
+func set_paused(paused : bool) -> void:
+ _audio_stream_player.stream_paused = paused
func toggle_play_pause() -> void:
- $AudioStreamPlayer.stream_paused = !$AudioStreamPlayer.stream_paused
+ _audio_stream_player.stream_paused = !_audio_stream_player.stream_paused
func start_current_song() -> void:
- $AudioStreamPlayer.stream = _available_songs[_selected_track].song_stream
- $AudioStreamPlayer.play()
+ _audio_stream_player.stream = _available_songs[_selected_track].song_stream
+ _audio_stream_player.play()
# REQUIREMENTS
# * SS-70
@@ -69,7 +76,12 @@ func _ready():
_selected_track = _available_songs.size()
_available_songs.append(SongInfo.new(music_directory, fname))
start_current_song()
+ set_paused(true)
+func set_startup_music(play : bool) -> void:
+ if not _has_startup_happened:
+ _has_startup_happened = true
+ set_paused(not play)
func _on_audio_stream_player_finished():
if _auto_play_next_song:
diff --git a/game/src/Game/MusicConductor/MusicConductor.tscn b/game/src/Game/MusicConductor/MusicConductor.tscn
index 3c288be..a943f24 100644
--- a/game/src/Game/MusicConductor/MusicConductor.tscn
+++ b/game/src/Game/MusicConductor/MusicConductor.tscn
@@ -2,10 +2,11 @@
[ext_resource type="Script" path="res://src/Game/MusicConductor/MusicConductor.gd" id="1_56t1b"]
-[node name="MusicConductor" type="Node"]
+[node name="MusicConductor" type="Node" node_paths=PackedStringArray("_audio_stream_player")]
script = ExtResource("1_56t1b")
music_directory = "res://audio/music"
first_song_name = "The_Crown"
+_audio_stream_player = NodePath("AudioStreamPlayer")
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
bus = &"MUSIC_BUS"
diff --git a/game/src/Game/MusicConductor/MusicPlayer.tscn b/game/src/Game/MusicConductor/MusicPlayer.tscn
index 8d47ba0..498750d 100644
--- a/game/src/Game/MusicConductor/MusicPlayer.tscn
+++ b/game/src/Game/MusicConductor/MusicPlayer.tscn
@@ -20,6 +20,7 @@ _visbility_button = NodePath("MusicUIVisibilityButton")
editor_description = "UI-107"
custom_minimum_size = Vector2(150, 0)
layout_mode = 2
+focus_mode = 0
alignment = 1
text_overrun_behavior = 3
fit_to_longest_item = false
@@ -28,6 +29,7 @@ fit_to_longest_item = false
custom_minimum_size = Vector2(150, 0)
layout_mode = 2
size_flags_vertical = 1
+focus_mode = 0
[node name="ButtonList" type="HBoxContainer" parent="."]
layout_mode = 2
@@ -36,21 +38,25 @@ mouse_filter = 2
[node name="PreviousSongButton" type="Button" parent="ButtonList"]
layout_mode = 2
+focus_mode = 0
text = "<"
[node name="PlayPauseButton" type="Button" parent="ButtonList"]
custom_minimum_size = Vector2(30, 0)
layout_mode = 2
+focus_mode = 0
text = "▶"
[node name="NextSongButton" type="Button" parent="ButtonList"]
layout_mode = 2
+focus_mode = 0
text = ">"
[node name="MusicUIVisibilityButton" type="Button" parent="."]
editor_description = "UI-106"
layout_mode = 2
size_flags_horizontal = 4
+focus_mode = 0
toggle_mode = true
text = "⬆"